feat: cache

This commit is contained in:
zc 2025-08-24 23:31:23 +08:00
parent 62159aac25
commit 2e0c7d82c5
8 changed files with 5440 additions and 7304 deletions

View File

@ -21,6 +21,7 @@
"pinia": "^2.1.7",
"trans-config": "^0.0.4",
"vue": "^3.4.21",
"vue-draggable-plus": "^0.6.0",
"vue-router": "^4.3.0",
"vue3-admin-ui": "^0.0.19"
},
@ -56,6 +57,6 @@
},
"volta": {
"node": "20.15.0",
"yarn": "4.3.0"
"yarn": "1.22.22"
}
}

View File

@ -56,3 +56,7 @@
.el-select .select-trigger {
width: 100%;
}
.el-form--inline .el-form-item{
margin-right: 20px;
}

View File

@ -2,12 +2,12 @@ const configData = ref()
export const initConfig = () => {
configData.value = pageConfig({
search: {
commodityTitle: { label: '标题', clearable: true },
commodityCategory: { label: '类目', option: [], clearable: true }
comTitle: { label: '标题', clearable: true },
comCategoryId: { label: '类目', option: [], clearable: true }
},
table: {
id: { label: '产品ID' },
commodityTitle: { label: '标题' },
comTitle: { label: '标题' },
sales: { label: '销量' },
price: { label: '价格' },
btn: {

View File

@ -0,0 +1,15 @@
import type { AtransResult } from '@/utils/page/config'
const configData = ref<AtransResult>()
export const initConfig = () => {
configData.value = pageConfig({
dialog: [
{
comTitle: { label: '商品标题' },
comCategoryId: { label: '类目', slot: 'comCategoryId' },
video: { label: '视频', slot: 'video', class: '!w-full' },
mainImg: { label: '主图', slot: 'mainImg', class: '!w-full' }
}
]
})
return configData
}

View File

@ -0,0 +1,94 @@
<template>
<div id="commodity-detail">
<el-card>
<h4 class="font-bold">基本信息</h4>
<form-wrap :form="$dialog">
<template #comCategoryId>
<el-tree-select
v-model="$dialog.data.comCategoryId"
:data="categoryOptions"
></el-tree-select>
</template>
<template #video>
<span>sdfs</span>
</template>
<template #mainImg>
<p>123</p>
</template>
</form-wrap>
</el-card>
<el-card class="mt-2 sku-info">
<h4 class="font-bold mb-2">SKU信息:</h4>
<dl v-for="item in categoryData" :key="item.typeId">
<dt class="text-sm text-[#666] mb-2">{{ item.typeName }}</dt>
<dd class="flex mb-2">
<div v-for="child in item.options" :key="item.typeId + '-' + child.id">
<el-tag size="large" closable effect="plain" type="info" class="mr-1">{{
child.name
}}</el-tag>
<el-input
v-if="inputVisible"
ref="InputRef"
v-model="inputValue"
class="w-20"
size="small"
@keyup.enter="handleInputConfirm"
@blur="handleInputConfirm"
/>
<el-button v-else class="button-new-tag" size="small" @click="onAddCategoryDataOption">
新增
</el-button>
</div>
</dd>
</dl>
</el-card>
<el-card>
<h4 class="font-bold">SKU信息:</h4>
<dl v-for="item in list" :key="item.typeId" class="flex mb-1 items-center">
<dt>
<el-button plain size="small" class="mr-2">{{ item.name }}</el-button>
</dt>
<dd class="flex">
<img :src="item.img" alt="" />
<p>
<span class="text-xs text-[#666]">原价</span
><el-input v-model="item.sale" size="small" class="w-20 mr-2"></el-input>
</p>
<p>
<span class="text-xs text-[#666]">售价</span
><el-input v-model="item.amount" size="small" class="w-20 mr-2"></el-input>
</p>
</dd>
</dl>
</el-card>
</div>
</template>
<script setup lang="ts">
import { initConfig } from './config'
import { categoryDataMock, categoryOptionsMock } from './mock'
import { generateTargetData } from './use-method'
const { $dialog, dialog1 } = toRefs(initConfig().value!)
$dialog.value.config = dialog1.value
const categoryOptions = ref(categoryOptionsMock)
const categoryData = ref(categoryDataMock)
const list = computed(() => generateTargetData(categoryData.value))
console.warn('----- my data is list.value: ', list.value)
</script>
<style scoped lang="scss">
#commodity-detail {
--el-color-info: #000;
.sku-info {
:deep(.el-card__body) {
padding-bottom: 12px;
}
}
:deep(.el-button) {
color: #666;
}
}
</style>

View File

@ -0,0 +1,87 @@
// 类目options
export const categoryOptionsMock = [
{
value: '1',
label: 'Level one 1',
children: [
{
value: '1-1',
label: 'Level two 1-1'
}
]
},
{
value: '2',
label: 'Level one 2',
children: [
{
value: '2-1',
label: 'Level two 2-1',
children: [
{
value: '2-1-1',
label: 'Level three 2-1-1'
}
]
},
{
value: '2-2',
label: 'Level two 2-2',
children: [
{
value: '2-2-1',
label: 'Level three 2-2-1'
}
]
}
]
}
]
// 类目配置项
export const categoryDataMock = [
{
typeName: '颜色分类',
typeId: 1,
options: [
{ id: 11, name: '国标' },
{ id: 12, name: '省标' }
]
},
{
typeName: '套餐类型',
typeId: 2,
options: [
{ id: 21, name: '无内存' },
{ id: 22, name: '双通道' },
{ id: 23, name: '三通道' }
]
},
{
typeName: '颜色',
typeId: 3,
options: [
{ id: 31, name: '红' },
{ id: 32, name: '绿' },
{ id: 33, name: '黄' }
]
}
]
//
export const a = [
{
typeName: '颜色分类',
typeId: 1,
options: [{ img: '', id: 11, name: '国标', sale: 100, amount: 10 }]
},
{
typeName: '套餐类型',
typeId: 2,
options: [
{ img: '', id: 21, name: '无内存', sale: 100, amount: 10 },
{ img: '', id: 22, name: '双通道', sale: 100, amount: 10 },
{ img: '', id: 23, name: '三通道', sale: 100, amount: 10 }
]
}
]

View File

@ -0,0 +1,68 @@
// 定义源数据的结构类型
interface Option {
id: number
name: string
}
interface Category {
typeName: string
typeId: number
options: Option[]
}
type CategoryDataMock = Category[]
// 定义目标数据的结构类型
interface TargetData {
serialNo: string
name: string
sale: string
img: string
amount: string
}
export const generateTargetData = (categoryData: CategoryDataMock): TargetData[] => {
const result: TargetData[] = []
const optionGroups: Option[][] = categoryData.map((category) => category.options)
// 使用递归生成所有可能的组合
const combine = (index: number, current: Option[]) => {
if (index === optionGroups.length) {
const serialNo = current.map((opt) => opt.id.toString()).join('-')
const name = current.map((opt) => opt.name).join('-')
result.push({
serialNo,
name,
sale: '',
img: '',
amount: ''
})
return
}
for (const option of optionGroups[index]) {
combine(index + 1, [...current, option])
}
}
combine(0, [])
return result
}
export const useCategoryAddOption = (categoryData) => {
const inputVisible = ref(false)
const InputRef = ref()
const inputValue = ref('')
const onAddCategoryDataOption = () => {
inputVisible.value = true
nextTick(() => {
InputRef.value!.input!.focus()
})
}
const handleInputConfirm = () => {
if (inputValue.value) {
dynamicTags.value.push(inputValue.value)
}
inputVisible.value = false
inputValue.value = ''
}
}

12467
yarn.lock

File diff suppressed because it is too large Load Diff