2025-11-12 21:23:32 +08:00

445 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div id="commodity-detail">
<el-card>
<h4 class="font-bold">基本信息</h4>
<form-wrap :form="$dialog">
<template #appCategoryId>
<el-tree-select
show-checkbox
v-model="$dialog.data.appCategoryId"
:props="defaultAdminCategoryTreeProps"
:render-after-expand="false"
:default-expanded-keys="defaultCheckedNodes.app"
@check="
(checkedNode: any, checkedStatus: any) =>
handleCheckChange(checkedNode, checkedStatus, 'app', $dialog.data)
"
:load="handleLoadNode2"
lazy
>
</el-tree-select>
</template>
<template #mainFile>
<file-upload-btn
accept="image/*"
size="default"
@change="(val) => handleChooseFiles('mainImageUrl', val, fileList)"
/>
<el-button class="ml-2" @click="onClickChooseResourceBtn('mainImageUrl')"
>资源库导入</el-button
>
</template>
<template #videoFile>
<file-upload-btn
size="default"
accept="video/*"
@change="(val) => handleChooseFiles('videoUrl', val, fileList)"
/>
<el-button class="ml-2" @click="onClickChooseResourceBtn('videoUrl')"
>资源库导入</el-button
>
</template>
<template #subFile>
<file-upload-btn
size="default"
multiple
accept="image/*"
@change="(val) => handleChooseFiles('subImageUrl', val, fileList)"
/>
<el-button class="ml-2" @click="onClickChooseResourceBtn('subImageUrl')"
>资源库导入</el-button
>
</template>
<template #fileReviewList>
<resource-review v-model:fileList="fileList" />
</template>
</form-wrap>
</el-card>
<el-card class="mt-2 sku-info">
<h4 class="font-bold mb-2">属性配置:</h4>
<el-form inline>
<el-form-item label="后台类目">
<el-tree-select
show-checkbox
v-model="$dialog.data.adminCategoryId"
:props="defaultAdminCategoryTreeProps"
:render-after-expand="false"
:default-expanded-keys="defaultCheckedNodes.admin"
@check="
(checkedNode: any, checkedStatus: any) =>
handleAfterChangeCategory(
handleCheckChange(checkedNode, checkedStatus, 'admin', $dialog.data)
)
"
:load="handleLoadNode"
lazy
style="width: 240px"
>
</el-tree-select>
</el-form-item>
<el-form-item label="特色">
<div class="flex">
<el-input
class="w-1/2"
v-model="$dialog.data.feature1"
placeholder="请输入特色1"
></el-input>
<el-input
class="w-1/2 ml-2"
v-model="$dialog.data.feature2"
placeholder="请输入特色2"
></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"
placement="bottom"
title="请输入属性类型标题"
:width="200"
trigger="click"
>
<template #reference>
<el-button type="primary" class="ml-2 !text-white" @click="onClickAddPropertyTypeBtn"
>新增属性类型</el-button
>
</template>
<el-input
ref="propertyTypeInputRef"
v-model="inputPropertyLineValue"
@keyup.enter="onAddPropertyLine($dialog.data.adminCategoryId, inputPropertyLineValue)"
@blur="visiblePropertyLine = false"
></el-input>
</el-popover>
</el-form-item>
</el-form>
<div ref="dragRef">
<dl v-for="(item, index) in adminCategoryData" :key="item.id" class="flex items-center">
<dt class="text-sm text-[#666] mb-2">
<span v-if="editPropertyTypeIndex !== index">{{ item.categoryPropertyName }}</span>
<el-input
ref="editPropertyTypeInputRef"
v-else
v-model="editPropertyTypeValue"
size="small"
class="w-20"
@keyup.enter="handleEditPropertyTypeConfirm(item, skuList, adminCategoryData)"
@blur="editPropertyTypeIndex = NaN"
/>
</dt>
<dd class="flex mb-2">
<div v-for="child in item.vvPropertyValueList" :key="item.id + '-' + child.id">
<el-input
v-if="curPropertyValueId === item.id + '_' + child.id"
ref="editPropertyValueInputRef"
class="w-20"
size="small"
v-model="inputEditPropertyValue"
@keyup.enter="onEditPropertyValue(child, skuList, item.vvPropertyValueList)"
@blur="curPropertyValueId = ''"
></el-input>
<el-tag
v-else
closable
effect="plain"
:type="colors[index % 4]"
class="mr-1 property-type-tag"
size="large"
@click="onClickPropertyValue(item, child)"
@close="onDeletePropertyValue(index, child.id)"
>
<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
v-if="inputVisibles[index]"
ref="InputRefs"
v-model="inputValue"
class="w-20"
size="small"
@keyup.enter="handleInputConfirm(index, skuList)"
@blur="handleInputConfirm(index)"
/>
<el-button
v-else
type="primary"
class="button-new-tag ml-1 !text-white"
size="small"
@click="onAddPropertyValue(index)"
>
+ 新增
</el-button>
<el-button
type="warning"
class="button-new-tag ml-1 !text-white"
size="small"
@click="onEditPropertyTypeBtn(index)"
>
修改属性
</el-button>
<el-button
type="danger"
class="button-new-tag ml-1 !text-white"
size="small"
@click="
() => {
onDeletePropertyTypeBtn(index, adminCategoryData, skuList)
skuList = generateSkuList(adminCategoryData)
}
"
>
删除属性
</el-button>
</dd>
</dl>
</div>
<h4 class="my-1">sku配置</h4>
<div
class="flex w-full flex-wrap justify-between p-2 rounded-[5px]"
style="border: 1px dashed #bbb"
>
<category-config :list="skuList.slice(0, Math.floor(skuList.length / 2))" />
<category-config
:startIndex="Math.floor(skuList.length / 2)"
:list="skuList.slice(Math.floor(skuList.length / 2))"
/>
</div>
</el-card>
<el-card>
<h4 class="font-bold mb-2">内容编辑:</h4>
<wan-editor v-model="$dialog.data.htmlContent"></wan-editor>
</el-card>
<el-button class="mt-2 !text-white" type="primary" @click="onSubmit()">提交</el-button>
<FileExplorerDialog
v-model="showFileExplorer"
v-model:initPathArray="currentPathArray"
@select="handleChooseResourceFileCallback"
/>
</div>
</template>
<script setup lang="ts">
import { initConfig } from './config'
import {
generateSkuList,
usePropertyValue,
colors,
useDrag,
handleLoadNode,
handleLoadNode2,
handleCheckChange,
defaultAdminCategoryTreeProps,
defaultCheckedNodes,
fileList,
TSkuList,
onChangePropertyTypeImage
} from './use-method'
import {
handleGetDialogData,
handleGetNewAdminCategoryData,
handleGetNewSkuList
} from './edit-method'
import { handleValidFormData, handleGetSubmitParams } from './submit-method'
import {
editPropertyTypeIndex,
editPropertyTypeValue,
editPropertyTypeInputRef,
onEditPropertyTypeBtn,
handleEditPropertyTypeConfirm,
onDeletePropertyTypeBtn,
inputEditPropertyValue,
editPropertyValueInputRef,
onClickPropertyValue,
onEditPropertyValue,
curPropertyValueId
} from './init-method'
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 { 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)
const init = async () => {
defaultCheckedNodes.value = { admin: [], app: [] }
const data = initConfig().value!
$dialog.value = data.$dialog
$dialog.value.config = data.dialog1
$dialog.value.data = {
htmlContent: '',
appCategoryId: '',
adminCategoryId: '',
isTest: 0,
isNew: 0,
isFlash: 0,
title: '',
frontPage: 0,
status: 'down'
}
adminCategoryData.value = []
skuList.value = []
if (route.query.id) {
const res = await api.commodity.getCommodityDetail.post!<any>({ productId: route.query.id })
handleGetDialogData(res.data, $dialog, fileList, defaultCheckedNodes)
adminCategoryData.value = handleGetNewAdminCategoryData(res.data.vvProductPropertyList)
initPropertyData(adminCategoryData.value)
skuList.value = handleGetNewSkuList(res.data.vvSkuList)
} else {
fileList.value = []
initPropertyData(adminCategoryData.value)
}
}
const {
showFileExplorer,
currentPathArray,
handleChooseResourceFileCallback,
onClickChooseResourceBtn
} = useImportFile(fileList)
const adminCategoryData = ref([])
const {
inputValue,
visiblePropertyLine,
inputPropertyLineValue,
InputRefs,
inputVisibles,
initPropertyData,
onAddPropertyValue,
onClosePropertyValue,
handleInputConfirm,
onAddPropertyLine
} = usePropertyValue()
const { dragRef, createDrag } = useDrag(adminCategoryData)
createDrag()
const skuList = ref<TSkuList[]>([])
// 当改变后台类目的时候进行修改重置sku
const handleAfterChangeCategory = (data: any) => {
console.warn('----- my data is data.vvCategoryPropertyDTOList: ', data)
adminCategoryData.value = data.categoryPropertyList || []
initPropertyData(adminCategoryData.value)
skuList.value = generateSkuList(adminCategoryData.value)
}
const onDeletePropertyValue = (index: number, id: number) =>
onClosePropertyValue(index, id, skuList)
const propertyTypeInputRef = ref()
const onClickAddPropertyTypeBtn = () => {
visiblePropertyLine.value = true
nextTick(() => {
propertyTypeInputRef.value.input!.focus()
})
}
const router = useRouter()
const onSubmit = () => {
const msg = handleValidFormData(
$dialog.value.data,
fileList.value,
adminCategoryData.value,
skuList.value
)
if (msg) return ElMessage.error(msg)
const params = handleGetSubmitParams(
route.query.type === 'add',
$dialog.value.data,
fileList.value,
adminCategoryData.value,
skuList.value,
defaultCheckedNodes
)
console.warn('----- my data is params111: ', params)
if (route.query.type === 'edit') Object.assign(params, { id: route.query.id })
api.commodity.addOrUpdateCommodity.post!(params).then((res) => {
router.replace({ path: '/goods/commodity/index' })
console.warn('----- my data is res: ', res)
})
}
init()
</script>
<style scoped lang="scss">
#commodity-detail {
--el-color-info: #000;
.sku-info {
:deep(.el-card__body) {
padding-bottom: 12px;
}
}
:deep(.el-button) {
&.el-button--small {
padding-top: 5px;
padding-bottom: 5px;
}
color: #666;
}
.property-type-tag {
:deep(.el-tag__content) {
display: flex;
align-items: center;
}
}
}
</style>