feat: 商品详情编辑
This commit is contained in:
parent
8fc07dd9cd
commit
7099bea338
@ -19,9 +19,10 @@ const useUserStore = defineStore('user', {
|
||||
this.$reset()
|
||||
},
|
||||
// 登录
|
||||
onLogin(data: { tokenValue: string; tokenName: string }) {
|
||||
onLogin(data: { tokenValue: string; tokenName: string; userNickName: string }) {
|
||||
this.tokenValue = data.tokenValue
|
||||
this.tokenName = data.tokenName
|
||||
this.userNickName = data.userNickName
|
||||
},
|
||||
// 获取用户信息(昵称、头像、角色集合、权限集合)
|
||||
getUserRoleInfo() {
|
||||
|
||||
@ -5,6 +5,8 @@ interface PreviewItem {
|
||||
type: 'image' | 'video'
|
||||
}
|
||||
|
||||
export const curPropertyTypeImage = ref(null)
|
||||
|
||||
// 选择资源库图片
|
||||
export const useImportFile = (fileList: Ref<PreviewItem[]>) => {
|
||||
const showFileExplorer = ref(false)
|
||||
@ -18,10 +20,15 @@ export const useImportFile = (fileList: Ref<PreviewItem[]>) => {
|
||||
|
||||
// 处理文件选择
|
||||
const handleChooseResourceFileCallback = (files: PreviewItem[] = []) => {
|
||||
if (curPropertyTypeImage.value) {
|
||||
curPropertyTypeImage.value.imageUrl = files[0].resourceUrl
|
||||
} else {
|
||||
handleChooseFiles(curFileType.value, files, fileList.value)
|
||||
}
|
||||
}
|
||||
|
||||
const onClickChooseResourceBtn = (type: 'mainImageUrl' | 'videoUrl' | 'subImageUrl') => {
|
||||
curPropertyTypeImage.value = null
|
||||
curFileType.value = type
|
||||
showFileExplorer.value = true
|
||||
}
|
||||
|
||||
@ -21,7 +21,11 @@ export const handleGetDialogData = (
|
||||
result.adminCategoryId = defaultCheckedNodes.value.admin.slice(-1)[0]
|
||||
defaultCheckedNodes.value.app = [data.appCategoryId1, data.appCategoryId2]
|
||||
result.isTest = data.isTest
|
||||
result.isNew = data.isNew
|
||||
result.isFlash = data.isFlash
|
||||
result.title = data.title
|
||||
result.frontPage = data.frontPage
|
||||
result.status = data.status
|
||||
result.feature1 = data.feature1
|
||||
result.feature2 = data.feature2
|
||||
result.htmlContent = data.vvProductDetailList.find((item: any) => item.type === 2)?.detail || ''
|
||||
@ -86,7 +90,7 @@ export const handleGetNewAdminCategoryData = (data: any) => {
|
||||
|
||||
// 编辑的时候对sku进行重组
|
||||
export const handleGetNewSkuList = (data: any) => {
|
||||
return data.map((item: any) => {
|
||||
const arr = data.map((item: any) => {
|
||||
let categoryPropertyNames = ''
|
||||
let name = ''
|
||||
item.vvSkuPropertyValueList.forEach((child: any, index: number) => {
|
||||
@ -101,4 +105,45 @@ export const handleGetNewSkuList = (data: any) => {
|
||||
categoryPropertyNames
|
||||
}
|
||||
})
|
||||
return sortByPrefix(arr)
|
||||
}
|
||||
|
||||
/**
|
||||
* 按照 name 字段的前缀进行排序,将前几位相同的项排序到一起
|
||||
* @param arr 要排序的数组
|
||||
* @returns 排序后的新数组
|
||||
*/
|
||||
export const sortByPrefix = <T extends { name?: string }>(arr: T[]): T[] => {
|
||||
if (!Array.isArray(arr) || arr.length === 0) {
|
||||
return arr
|
||||
}
|
||||
|
||||
// 计算前缀:如果 name 包含 "-",取最后一个 "-" 之前的部分作为前缀
|
||||
const getPrefix = (name: string): string => {
|
||||
if (!name) return ''
|
||||
|
||||
// 找到最后一个 "-" 的位置,取之前的部分作为前缀
|
||||
const lastDashIndex = name.lastIndexOf('-')
|
||||
if (lastDashIndex > 0) {
|
||||
return name.substring(0, lastDashIndex + 1) // 包含 "-" 分隔符
|
||||
}
|
||||
|
||||
// 如果没有 "-",返回整个字符串
|
||||
return name
|
||||
}
|
||||
|
||||
// 创建副本并排序
|
||||
return [...arr].sort((a, b) => {
|
||||
const prefixA = getPrefix(a.name || '')
|
||||
const prefixB = getPrefix(b.name || '')
|
||||
|
||||
// 先按前缀排序
|
||||
const prefixCompare = prefixA.localeCompare(prefixB, 'zh-CN')
|
||||
if (prefixCompare !== 0) {
|
||||
return prefixCompare
|
||||
}
|
||||
|
||||
// 如果前缀相同,再按完整的 name 排序
|
||||
return (a.name || '').localeCompare(b.name || '', 'zh-CN')
|
||||
})
|
||||
}
|
||||
|
||||
@ -77,9 +77,6 @@
|
||||
>
|
||||
</el-tree-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="测试商品">
|
||||
<el-switch v-model="$dialog.data.isTest" active-value="1" inactive-value="0" />
|
||||
</el-form-item>
|
||||
<el-form-item label="特色">
|
||||
<div class="flex">
|
||||
<el-input
|
||||
@ -94,6 +91,22 @@
|
||||
></el-input>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<br />
|
||||
<el-form-item label="测试商品">
|
||||
<el-switch v-model="$dialog.data.isTest" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
<el-form-item label="新品">
|
||||
<el-switch v-model="$dialog.data.isNew" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
<el-form-item label="限时秒杀">
|
||||
<el-switch v-model="$dialog.data.isFlash" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
<el-form-item label="上线">
|
||||
<el-switch v-model="$dialog.data.status" active-value="online" inactive-value="down" />
|
||||
</el-form-item>
|
||||
<el-form-item label="加入首页">
|
||||
<el-switch v-model="$dialog.data.frontPage" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-popover
|
||||
:visible="visiblePropertyLine"
|
||||
@ -146,10 +159,47 @@
|
||||
closable
|
||||
effect="plain"
|
||||
:type="colors[index % 4]"
|
||||
class="mr-1"
|
||||
class="mr-1 property-type-tag"
|
||||
size="large"
|
||||
@click="onClickPropertyValue(item, child)"
|
||||
@close="onDeletePropertyValue(index, child.id)"
|
||||
>{{ child.categoryPropertyValue }}</el-tag
|
||||
>
|
||||
<el-popover title="" placement="top-start" :width="280">
|
||||
<template #reference>
|
||||
<el-icon
|
||||
color="#999"
|
||||
class="mr-1"
|
||||
v-if="!child.imageUrl"
|
||||
@click.stop="onChangePropertyTypeImage(child)"
|
||||
><Picture
|
||||
/></el-icon>
|
||||
<img
|
||||
v-else
|
||||
:src="child.imageUrl"
|
||||
alt=""
|
||||
class="w-6 h-6 mr-1"
|
||||
@click.stop="onChangePropertyTypeImage(child)"
|
||||
/>
|
||||
</template>
|
||||
<div>
|
||||
<file-upload-btn
|
||||
class="inline-block"
|
||||
size="small"
|
||||
accept="image/*"
|
||||
@change="(val) => (child.imageUrl = val[0].resourceUrl)"
|
||||
/>
|
||||
<el-button
|
||||
type="success"
|
||||
size="small"
|
||||
class="ml-2"
|
||||
@click="(showFileExplorer = true) && (curPropertyTypeImage = child)"
|
||||
>资源库导入</el-button
|
||||
>
|
||||
<el-button type="danger" size="small" class="ml-2" @click="child.imageUrl = ''"
|
||||
>清空</el-button
|
||||
>
|
||||
</div> </el-popover
|
||||
><span>{{ child.categoryPropertyValue }}</span></el-tag
|
||||
>
|
||||
</div>
|
||||
<el-input
|
||||
@ -233,7 +283,8 @@ import {
|
||||
defaultAdminCategoryTreeProps,
|
||||
defaultCheckedNodes,
|
||||
fileList,
|
||||
TSkuList
|
||||
TSkuList,
|
||||
onChangePropertyTypeImage
|
||||
} from './use-method'
|
||||
import {
|
||||
handleGetDialogData,
|
||||
@ -258,10 +309,11 @@ import categoryConfig from './category-config.vue'
|
||||
import wanEditor from './editor.vue'
|
||||
import fileUploadBtn from '@/components/FileUploadBtn/index.vue'
|
||||
import resourceReview from '@/components/ResourceReview/index.vue'
|
||||
import { useImportFile, handleChooseFiles } from './choose-file-method'
|
||||
import { curPropertyTypeImage, useImportFile, handleChooseFiles } from './choose-file-method'
|
||||
import FileExplorerDialog from '@/components/FileExplorerDialog/index.vue'
|
||||
import { Atrans$DialogRes } from '@/utils/page/config'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Picture } from '@element-plus/icons-vue'
|
||||
|
||||
const route = useRoute()
|
||||
const $dialog = ref<Atrans$DialogRes>({} as Atrans$DialogRes)
|
||||
@ -275,7 +327,11 @@ const init = async () => {
|
||||
appCategoryId: '',
|
||||
adminCategoryId: '',
|
||||
isTest: 0,
|
||||
title: ''
|
||||
isNew: 0,
|
||||
isFlash: 0,
|
||||
title: '',
|
||||
frontPage: 0,
|
||||
status: 'down'
|
||||
}
|
||||
adminCategoryData.value = []
|
||||
skuList.value = []
|
||||
@ -378,5 +434,11 @@ init()
|
||||
}
|
||||
color: #666;
|
||||
}
|
||||
.property-type-tag {
|
||||
:deep(.el-tag__content) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -319,7 +319,7 @@ export const generateSkuList = (categories: CategoryDataMock): TSkuList[] => {
|
||||
return combos.map((combo) => {
|
||||
const serialNo = combo.map((opt) => opt.id.toString()).join('-')
|
||||
const name = combo.map((opt) => String(opt.categoryPropertyValue)).join('-')
|
||||
const categoryPropertyNames = combo.map((opt) => String(opt.categoryPropertyValue)).join('-')
|
||||
const categoryPropertyNames = combo.map((opt) => String(opt.categoryPropertyName)).join('-')
|
||||
const originArray = combo
|
||||
return {
|
||||
serialNo,
|
||||
@ -352,3 +352,7 @@ const generateAddSkuList = (
|
||||
})
|
||||
return generateSkuList(filterCategoryData)
|
||||
}
|
||||
|
||||
export const onChangePropertyTypeImage = (child: any) => {
|
||||
console.log(1111, child)
|
||||
}
|
||||
|
||||
@ -21,7 +21,11 @@ const handleLogin = () => {
|
||||
if (valid) {
|
||||
api.login.login.post(loginData).then((res) => {
|
||||
router.push({ path: '/home' })
|
||||
user.onLogin({ tokenValue: res.data.token, tokenName: 'mmToken' })
|
||||
user.onLogin({
|
||||
tokenValue: res.data.token,
|
||||
tokenName: 'mmToken',
|
||||
userNickName: res.data.username
|
||||
})
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user