code review 商品管理的实现

(cherry picked from commit e92361ed40)
This commit is contained in:
YunaiV 2023-05-06 22:54:41 +08:00 committed by shizhong
parent fc4b46de2e
commit 7a5993c584
13 changed files with 108 additions and 48 deletions

View File

@ -1,30 +1,38 @@
import request from '@/config/axios' import request from '@/config/axios'
import type { SpuType } from './type/spuType' import type { SpuType } from './type/spuType' // TODO @puhui999: type 和 api 一起放,简单一点哈~
// 获得spu列表 // TODO @puhui999中英文之间有空格
export const getSpuList = (params: any) => {
// 获得spu列表 TODO @puhui999这个是 getSpuPage 哈
export const getSpuList = (params: PageParam) => {
return request.get({ url: '/product/spu/page', params }) return request.get({ url: '/product/spu/page', params })
} }
// 获得spu列表tabsCount // 获得spu列表tabsCount
export const getTabsCount = () => { export const getTabsCount = () => {
return request.get({ url: '/product/spu/tabsCount' }) return request.get({ url: '/product/spu/tabsCount' })
} }
// 创建商品spu // 创建商品spu
export const createSpu = (data: SpuType) => { export const createSpu = (data: SpuType) => {
return request.post({ url: '/product/spu/create', data }) return request.post({ url: '/product/spu/create', data })
} }
// 更新商品spu // 更新商品spu
export const updateSpu = (data: SpuType) => { export const updateSpu = (data: SpuType) => {
return request.put({ url: '/product/spu/update', data }) return request.put({ url: '/product/spu/update', data })
} }
// 更新商品spu status // 更新商品spu status
export const updateStatus = (data: { id: number; status: number }) => { export const updateStatus = (data: { id: number; status: number }) => {
return request.put({ url: '/product/spu/updateStatus', data }) return request.put({ url: '/product/spu/updateStatus', data })
} }
// 获得商品spu
// 获得商品 spu
export const getSpu = (id: number) => { export const getSpu = (id: number) => {
return request.get({ url: `/product/spu/get-detail?id=${id}` }) return request.get({ url: `/product/spu/get-detail?id=${id}` })
} }
// 删除商品Spu // 删除商品Spu
export const deleteSpu = (id: number) => { export const deleteSpu = (id: number) => {
return request.delete({ url: `/product/spu/delete?id=${id}` }) return request.delete({ url: `/product/spu/delete?id=${id}` })

View File

@ -367,8 +367,8 @@ const remainingRouter: AppRouteRecordRaw[] = [
}, },
children: [ children: [
{ {
path: 'productManagementAdd', path: 'productManagementAdd', // TODO @puhui999最好拆成 add 和 edit 两个路由;添加商品;修改商品
component: () => import('@/views/mall/product/management/addForm.vue'), component: () => import('@/views/mall/product/spu/addForm.vue'),
name: 'ProductManagementAdd', name: 'ProductManagementAdd',
meta: { meta: {
noCache: true, noCache: true,

View File

@ -216,6 +216,7 @@ export const PayRefundStatusEnum = {
name: '退款关闭' name: '退款关闭'
} }
} }
/** /**
* SPU枚举类 * SPU枚举类
*/ */

View File

@ -1,3 +1,4 @@
// TODO @puhui999这个方法可以考虑放到 index.js
/** /**
* target: {a:1} source:{a:2,b:3} {a:2} * target: {a:1} source:{a:2,b:3} {a:2}
* @param target * @param target

View File

@ -37,7 +37,6 @@ import { BasicInfoForm, DescriptionForm, OtherSettingsForm } from './components'
import type { SpuType } from '@/api/mall/product/management/type/spuType' // api import type { SpuType } from '@/api/mall/product/management/type/spuType' // api
import * as managementApi from '@/api/mall/product/management/spu' import * as managementApi from '@/api/mall/product/management/spu'
import * as PropertyApi from '@/api/mall/product/property' import * as PropertyApi from '@/api/mall/product/property'
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() // const message = useMessage() //
const { push, currentRoute } = useRouter() // const { push, currentRoute } = useRouter() //
@ -69,7 +68,7 @@ const formData = ref<SpuType>({
skus: [ skus: [
{ {
/** /**
* 商品价格单位 * 商品价格单位 TODO @puhui999注释放在尾巴哈简洁一点~
*/ */
price: 0, price: 0,
/** /**
@ -120,6 +119,7 @@ const formData = ref<SpuType>({
recommendNew: false, // recommendNew: false, //
recommendGood: false // recommendGood: false //
}) })
/** 获得详情 */ /** 获得详情 */
const getDetail = async () => { const getDetail = async () => {
const id = query.id as unknown as number const id = query.id as unknown as number
@ -129,6 +129,7 @@ const getDetail = async () => {
const res = (await managementApi.getSpu(id)) as SpuType const res = (await managementApi.getSpu(id)) as SpuType
formData.value = res formData.value = res
// id // id
// TODO @puhui999 propertyName id + uniapp
const propertyIds = res.skus[0]?.properties.map((item) => item.propertyId) const propertyIds = res.skus[0]?.properties.map((item) => item.propertyId)
const PropertyS = await PropertyApi.getPropertyListAndValue({ propertyIds }) const PropertyS = await PropertyApi.getPropertyListAndValue({ propertyIds })
await nextTick() await nextTick()
@ -151,6 +152,7 @@ const submitForm = async () => {
await unref(BasicInfoRef)?.validate() await unref(BasicInfoRef)?.validate()
await unref(DescriptionRef)?.validate() await unref(DescriptionRef)?.validate()
await unref(OtherSettingsRef)?.validate() await unref(OtherSettingsRef)?.validate()
// TODO @puhui server
// //
formData.value.skus.forEach((item) => { formData.value.skus.forEach((item) => {
// sku name // sku name
@ -166,6 +168,7 @@ const submitForm = async () => {
const newSliderPicUrls = [] const newSliderPicUrls = []
formData.value.sliderPicUrls.forEach((item) => { formData.value.sliderPicUrls.forEach((item) => {
// //
// TODO @puhui999 object
if (typeof item === 'object') { if (typeof item === 'object') {
newSliderPicUrls.push(item.url) newSliderPicUrls.push(item.url)
} else { } else {
@ -224,6 +227,7 @@ const resetForm = async () => {
} }
/** 关闭按钮 */ /** 关闭按钮 */
const close = () => { const close = () => {
// TODO @puhui999 reset close
resetForm() resetForm()
delView(unref(currentRoute)) delView(unref(currentRoute))
push('/product/product-management') push('/product/product-management')

View File

@ -7,6 +7,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<!-- TODO @puhui999只能选根节点 -->
<el-form-item label="商品分类" prop="categoryId"> <el-form-item label="商品分类" prop="categoryId">
<el-tree-select <el-tree-select
v-model="formData.categoryId" v-model="formData.categoryId"
@ -15,6 +16,7 @@
check-strictly check-strictly
node-key="id" node-key="id"
placeholder="请选择商品分类" placeholder="请选择商品分类"
class="w-1/1"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -25,7 +27,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="单位" prop="unit"> <el-form-item label="单位" prop="unit">
<el-select v-model="formData.unit" placeholder="请选择单位"> <el-select v-model="formData.unit" placeholder="请选择单位" class="w-1/1">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.PRODUCT_UNIT)" v-for="dict in getIntDictOptions(DICT_TYPE.PRODUCT_UNIT)"
:key="dict.value" :key="dict.value"
@ -57,7 +59,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="运费模板" prop="deliveryTemplateId"> <el-form-item label="运费模板" prop="deliveryTemplateId">
<el-select v-model="formData.deliveryTemplateId" placeholder="请选择" style="width: 100%"> <el-select v-model="formData.deliveryTemplateId" placeholder="请选择" class="w-1/1">
<el-option v-for="item in []" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in []" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -84,9 +86,8 @@
<!-- 多规格添加--> <!-- 多规格添加-->
<el-col :span="24"> <el-col :span="24">
<el-form-item v-if="formData.specType" label="商品属性"> <el-form-item v-if="formData.specType" label="商品属性">
<el-button class="mr-15px mb-10px" @click="AttributesAddFormRef.open()" <!-- TODO @puhui999参考 https://admin.java.crmeb.net/store/list/creatProduct -->
>添加规格 <el-button class="mr-15px mb-10px" @click="AttributesAddFormRef.open">添加规格</el-button>
</el-button>
<ProductAttributes :attribute-data="attributeList" /> <ProductAttributes :attribute-data="attributeList" />
</el-form-item> </el-form-item>
<template v-if="formData.specType && attributeList.length > 0"> <template v-if="formData.specType && attributeList.length > 0">
@ -108,17 +109,15 @@
<script lang="ts" name="ProductManagementBasicInfoForm" setup> <script lang="ts" name="ProductManagementBasicInfoForm" setup>
import { PropType } from 'vue' import { PropType } from 'vue'
import { defaultProps, handleTree } from '@/utils/tree' import { defaultProps, handleTree } from '@/utils/tree'
import { ElInput } from 'element-plus'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import type { SpuType } from '@/api/mall/product/management/type/spuType' import type { SpuType } from '@/api/mall/product/management/type/spuType'
import { UploadImg, UploadImgs } from '@/components/UploadFile' import { UploadImg, UploadImgs } from '@/components/UploadFile'
import { copyValueToTarget } from '@/utils/object' import { copyValueToTarget } from '@/utils/object'
import { ProductAttributes, ProductAttributesAddForm, SkuList } from './index' import { ProductAttributes, ProductAttributesAddForm, SkuList } from './index'
// Api
import * as ProductCategoryApi from '@/api/mall/product/category' import * as ProductCategoryApi from '@/api/mall/product/category'
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
const message = useMessage() // const message = useMessage() //
const props = defineProps({ const props = defineProps({
propFormData: { propFormData: {
type: Object as PropType<SpuType>, type: Object as PropType<SpuType>,
@ -126,10 +125,11 @@ const props = defineProps({
}, },
activeName: propTypes.string.def('') activeName: propTypes.string.def('')
}) })
const AttributesAddFormRef = ref() // const AttributesAddFormRef = ref() // TODO @puhui999
const ProductManagementBasicInfoRef = ref() // Ref const ProductManagementBasicInfoRef = ref() // Ref TODO @puhui999
// TODO @puhui999attributeList propertyList
const attributeList = ref([]) // const attributeList = ref([]) //
/** 添加商品属性 */ /** 添加商品属性 */ // TODO @puhui999propFormData
const addAttribute = (property: any) => { const addAttribute = (property: any) => {
if (Array.isArray(property)) { if (Array.isArray(property)) {
attributeList.value = property attributeList.value = property
@ -162,8 +162,9 @@ const rules = reactive({
specType: [required], specType: [required],
subCommissionType: [required] subCommissionType: [required]
}) })
/** /**
* 将传进来的值赋值给formData * 将传进来的值赋值给 formData
*/ */
watch( watch(
() => props.propFormData, () => props.propFormData,
@ -176,10 +177,11 @@ watch(
immediate: true immediate: true
} }
) )
const emit = defineEmits(['update:activeName'])
/** /**
* 表单校验 * 表单校验
*/ */
const emit = defineEmits(['update:activeName'])
const validate = async () => { const validate = async () => {
// //
if (!ProductManagementBasicInfoRef) return if (!ProductManagementBasicInfoRef) return
@ -197,7 +199,7 @@ const validate = async () => {
} }
defineExpose({ validate, addAttribute }) defineExpose({ validate, addAttribute })
// /** 分销类型 */
const changeSubCommissionType = () => { const changeSubCommissionType = () => {
// //
for (const item of formData.skus) { for (const item of formData.skus) {
@ -205,7 +207,8 @@ const changeSubCommissionType = () => {
item.subCommissionSecondPrice = 0 item.subCommissionSecondPrice = 0
} }
} }
//
/** 选择规格 */
const onChangeSpec = () => { const onChangeSpec = () => {
// //
attributeList.value = [] attributeList.value = []

View File

@ -25,6 +25,11 @@ const DescriptionFormRef = ref() // 表单Ref
const formData = ref<SpuType>({ const formData = ref<SpuType>({
description: '' // description: '' //
}) })
//
const rules = reactive({
description: [required]
})
/** /**
* 富文本编辑器如果输入过再清空会有残留需再重置一次 * 富文本编辑器如果输入过再清空会有残留需再重置一次
*/ */
@ -40,10 +45,7 @@ watch(
immediate: true immediate: true
} }
) )
//
const rules = reactive({
description: [required]
})
/** /**
* 将传进来的值赋值给formData * 将传进来的值赋值给formData
*/ */
@ -58,10 +60,11 @@ watch(
immediate: true immediate: true
} }
) )
const emit = defineEmits(['update:activeName'])
/** /**
* 表单校验 * 表单校验
*/ */
const emit = defineEmits(['update:activeName'])
const validate = async () => { const validate = async () => {
// //
if (!DescriptionFormRef) return if (!DescriptionFormRef) return

View File

@ -1,6 +1,7 @@
<template> <template>
<el-form ref="OtherSettingsFormRef" :model="formData" :rules="rules" label-width="120px"> <el-form ref="OtherSettingsFormRef" :model="formData" :rules="rules" label-width="120px">
<el-row> <el-row>
<!-- TODO @puhui999横着三个哈 -->
<el-col :span="24"> <el-col :span="24">
<el-col :span="8"> <el-col :span="8">
<el-form-item label="商品排序" prop="sort"> <el-form-item label="商品排序" prop="sort">
@ -40,6 +41,7 @@
<el-tag class="ml-2" type="warning">拼团</el-tag> <el-tag class="ml-2" type="warning">拼团</el-tag>
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- TODO @puhui999等优惠劵 ok 在搞 -->
<el-col :span="24"> <el-col :span="24">
<el-form-item label="赠送优惠劵"> <el-form-item label="赠送优惠劵">
<el-button>选择优惠券</el-button> <el-button>选择优惠券</el-button>
@ -49,13 +51,12 @@
</el-form> </el-form>
</template> </template>
<script lang="ts" name="OtherSettingsForm" setup> <script lang="ts" name="OtherSettingsForm" setup>
//
import type { SpuType } from '@/api/mall/product/management/type/spuType' import type { SpuType } from '@/api/mall/product/management/type/spuType'
import { PropType } from 'vue' import { PropType } from 'vue'
import { copyValueToTarget } from '@/utils/object' import { copyValueToTarget } from '@/utils/object'
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
const message = useMessage() // const message = useMessage() //
const props = defineProps({ const props = defineProps({
propFormData: { propFormData: {
type: Object as PropType<SpuType>, type: Object as PropType<SpuType>,
@ -63,7 +64,7 @@ const props = defineProps({
}, },
activeName: propTypes.string.def('') activeName: propTypes.string.def('')
}) })
// // TODO @puhui999 recommendOptions
const recommend = [ const recommend = [
{ name: '是否热卖', value: 'recommendHot' }, { name: '是否热卖', value: 'recommendHot' },
{ name: '是否优惠', value: 'recommendBenefit' }, { name: '是否优惠', value: 'recommendBenefit' },
@ -71,10 +72,10 @@ const recommend = [
{ name: '是否新品', value: 'recommendNew' }, { name: '是否新品', value: 'recommendNew' },
{ name: '是否优品', value: 'recommendGood' } { name: '是否优品', value: 'recommendGood' }
] ]
// const checkboxGroup = ref<string[]>(['recommendHot']) //
const checkboxGroup = ref<string[]>(['recommendHot']) /** 选择商品后赋值 */
//
const onChangeGroup = () => { const onChangeGroup = () => {
// TODO @puhui999 recommend
checkboxGroup.value.includes('recommendHot') checkboxGroup.value.includes('recommendHot')
? (formData.value.recommendHot = true) ? (formData.value.recommendHot = true)
: (formData.value.recommendHot = false) : (formData.value.recommendHot = false)
@ -109,6 +110,7 @@ const rules = reactive({
giveIntegral: [required], giveIntegral: [required],
virtualSalesCount: [required] virtualSalesCount: [required]
}) })
/** /**
* 将传进来的值赋值给formData * 将传进来的值赋值给formData
*/ */
@ -130,10 +132,11 @@ watch(
immediate: true immediate: true
} }
) )
const emit = defineEmits(['update:activeName'])
/** /**
* 表单校验 * 表单校验
*/ */
const emit = defineEmits(['update:activeName'])
const validate = async () => { const validate = async () => {
// //
if (!OtherSettingsFormRef) return if (!OtherSettingsFormRef) return
@ -149,6 +152,5 @@ const validate = async () => {
} }
}) })
} }
defineExpose({ validate }) defineExpose({ validate })
</script> </script>

View File

@ -71,16 +71,19 @@ watch(
immediate: true immediate: true
} }
) )
/** 删除标签 tagValue 标签值*/ /** 删除标签 tagValue 标签值*/
const handleClose = (index, valueIndex) => { const handleClose = (index, valueIndex) => {
attributeList.value[index].values?.splice(valueIndex, 1) attributeList.value[index].values?.splice(valueIndex, 1)
} }
/** 显示输入框并获取焦点 */ /** 显示输入框并获取焦点 */
const showInput = async (index) => { const showInput = async (index) => {
attributeIndex.value = index attributeIndex.value = index
// refRef // refRef
InputRef.value[index]!.input!.focus() InputRef.value[index]!.input!.focus()
} }
/** 输入框失去焦点或点击回车时触发 */ /** 输入框失去焦点或点击回车时触发 */
const handleInputConfirm = async (index, propertyId) => { const handleInputConfirm = async (index, propertyId) => {
if (inputValue.value) { if (inputValue.value) {

View File

@ -25,11 +25,13 @@
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
<!-- TODO @puhui999 controls-position="right" 可以去掉哈不然太长了手动输入更方便 -->
<el-table-column align="center" label="商品条码" min-width="168"> <el-table-column align="center" label="商品条码" min-width="168">
<template #default="{ row }"> <template #default="{ row }">
<el-input v-model="row.barCode" class="w-100%" /> <el-input v-model="row.barCode" class="w-100%" />
</template> </template>
</el-table-column> </el-table-column>
<!-- TODO @puhui999用户输入的时候是按照元分主要是我们自己用 -->
<el-table-column align="center" label="销售价(分)" min-width="168"> <el-table-column align="center" label="销售价(分)" min-width="168">
<template #default="{ row }"> <template #default="{ row }">
<el-input-number v-model="row.price" :min="0" class="w-100%" controls-position="right" /> <el-input-number v-model="row.price" :min="0" class="w-100%" controls-position="right" />
@ -94,15 +96,14 @@
</template> </template>
<el-table-column v-if="formData.specType" align="center" fixed="right" label="操作" width="80"> <el-table-column v-if="formData.specType" align="center" fixed="right" label="操作" width="80">
<template #default> <template #default>
<el-button v-if="isBatch" link size="small" type="primary" @click="batchAdd" <el-button v-if="isBatch" link size="small" type="primary" @click="batchAdd">
>批量添加 批量添加
</el-button> </el-button>
<el-button v-else link size="small" type="primary">删除</el-button> <el-button v-else link size="small" type="primary">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</template> </template>
<script lang="ts" name="SkuList" setup> <script lang="ts" name="SkuList" setup>
import { UploadImg } from '@/components/UploadFile' import { UploadImg } from '@/components/UploadFile'
import { PropType } from 'vue' import { PropType } from 'vue'
@ -123,7 +124,7 @@ const props = defineProps({
isBatch: propTypes.bool.def(false) // isBatch: propTypes.bool.def(false) //
}) })
const formData = ref<SpuType>() // const formData = ref<SpuType>() //
// // TODO @puhui999
const SkuData = ref<SkuType[]>([ const SkuData = ref<SkuType[]>([
{ {
/** /**
@ -168,13 +169,16 @@ const SkuData = ref<SkuType[]>([
subCommissionSecondPrice: 0 subCommissionSecondPrice: 0
} }
]) ])
/** 批量添加 */ /** 批量添加 */
const batchAdd = () => { const batchAdd = () => {
formData.value.skus.forEach((item) => { formData.value.skus.forEach((item) => {
copyValueToTarget(item, SkuData.value[0]) copyValueToTarget(item, SkuData.value[0])
}) })
} }
const tableHeaderList = ref<{ prop: string; label: string }[]>([]) const tableHeaderList = ref<{ prop: string; label: string }[]>([])
/** /**
* 将传进来的值赋值给SkuData * 将传进来的值赋值给SkuData
*/ */
@ -189,6 +193,8 @@ watch(
immediate: true immediate: true
} }
) )
// TODO @ chatgpt
/** 生成表数据 */ /** 生成表数据 */
const generateTableData = (data: any[]) => { const generateTableData = (data: any[]) => {
// //
@ -237,6 +243,7 @@ const generateTableData = (data: any[]) => {
formData.value.skus.push(row) formData.value.skus.push(row)
}) })
} }
/** 构建所有排列组合 */ /** 构建所有排列组合 */
const build = (list: any[]) => { const build = (list: any[]) => {
if (list.length === 0) { if (list.length === 0) {
@ -259,6 +266,7 @@ const build = (list: any[]) => {
return result return result
} }
} }
/** 监听属性列表生成相关参数和表头 */ /** 监听属性列表生成相关参数和表头 */
watch( watch(
() => props.attributeList, () => props.attributeList,

View File

@ -8,6 +8,7 @@
class="-mb-15px" class="-mb-15px"
label-width="68px" label-width="68px"
> >
<!-- TODO @puhui999https://admin.java.crmeb.net/store/index使 + -->
<el-form-item label="品牌名称" prop="name"> <el-form-item label="品牌名称" prop="name">
<el-input <el-input
v-model="queryParams.name" v-model="queryParams.name"
@ -51,6 +52,7 @@
<Icon class="mr-5px" icon="ep:plus" /> <Icon class="mr-5px" icon="ep:plus" />
新增 新增
</el-button> </el-button>
<!-- TODO @puhui999增加一个导出操作 -->
</el-form-item> </el-form-item>
</el-form> </el-form>
</ContentWrap> </ContentWrap>
@ -66,6 +68,7 @@
/> />
</el-tabs> </el-tabs>
<el-table v-loading="loading" :data="list"> <el-table v-loading="loading" :data="list">
<!-- TODO puhui999: ID 编号的展示 -->
<!-- TODO 暂时不做折叠数据 --> <!-- TODO 暂时不做折叠数据 -->
<!-- <el-table-column type="expand">--> <!-- <el-table-column type="expand">-->
<!-- <template #default="{ row }">--> <!-- <template #default="{ row }">-->
@ -92,6 +95,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :show-overflow-tooltip="true" label="商品名称" min-width="300" prop="name" /> <el-table-column :show-overflow-tooltip="true" label="商品名称" min-width="300" prop="name" />
<!-- TODO 价格 / 100.0 -->
<el-table-column align="center" label="商品售价" min-width="90" prop="price" /> <el-table-column align="center" label="商品售价" min-width="90" prop="price" />
<el-table-column align="center" label="销量" min-width="90" prop="salesCount" /> <el-table-column align="center" label="销量" min-width="90" prop="salesCount" />
<el-table-column align="center" label="库存" min-width="90" prop="stock" /> <el-table-column align="center" label="库存" min-width="90" prop="stock" />
@ -105,6 +109,7 @@
/> />
<el-table-column fixed="right" label="状态" min-width="80"> <el-table-column fixed="right" label="状态" min-width="80">
<template #default="{ row }"> <template #default="{ row }">
<!-- TODO @puhui是不是不用 Number(row.status) 去比较哈直接 row.status < 0 -->
<el-switch <el-switch
v-model="row.status" v-model="row.status"
:active-value="1" :active-value="1"
@ -119,6 +124,7 @@
</el-table-column> </el-table-column>
<el-table-column align="center" fixed="right" label="操作" min-width="150"> <el-table-column align="center" fixed="right" label="操作" min-width="150">
<template #default="{ row }"> <template #default="{ row }">
<!-- TODO @puhui999详情可以后面点做哈 -->
<template v-if="queryParams.tabType === 4"> <template v-if="queryParams.tabType === 4">
<el-button <el-button
v-hasPermi="['product:spu:delete']" v-hasPermi="['product:spu:delete']"
@ -166,6 +172,7 @@
@pagination="getList" @pagination="getList"
/> />
</ContentWrap> </ContentWrap>
<!-- https://kailong110120130.gitee.io/vue-element-plus-admin-doc/components/image-viewer.html -->
<!-- 必须在表格外面展示不然单元格会遮挡图层 --> <!-- 必须在表格外面展示不然单元格会遮挡图层 -->
<el-image-viewer <el-image-viewer
v-if="imgViewVisible" v-if="imgViewVisible"
@ -173,20 +180,21 @@
@close="imgViewVisible = false" @close="imgViewVisible = false"
/> />
</template> </template>
<script lang="ts" name="ProductManagement" setup> <script lang="ts" name="ProductList" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime' // api import { dateFormatter } from '@/utils/formatTime'
// TODO @puhui999managementApi=ProductSpuApi
import * as managementApi from '@/api/mall/product/management/spu' import * as managementApi from '@/api/mall/product/management/spu'
import { ProductSpuStatusEnum } from '@/utils/constants' import { ProductSpuStatusEnum } from '@/utils/constants'
import { TabsPaneContext } from 'element-plus' import { TabsPaneContext } from 'element-plus'
const message = useMessage() // const message = useMessage() //
const { t } = useI18n() // const { t } = useI18n() //
const { currentRoute, push } = useRouter() // const { currentRoute, push } = useRouter() //
const loading = ref(false) // const loading = ref(false) //
const total = ref(0) // const total = ref(0) //
const list = ref<any[]>([]) // const list = ref<any[]>([]) //
// tabs // tabs
const tabsData = ref([ const tabsData = ref([
{ {
count: 0, count: 0,
@ -214,7 +222,10 @@ const tabsData = ref([
type: 4 type: 4
} }
]) ])
/** 获得每个 Tab 的数量 */
const getTabsCount = async () => { const getTabsCount = async () => {
// TODO @puhui999 try catch
try { try {
const res = await managementApi.getTabsCount() const res = await managementApi.getTabsCount()
for (let objName in res) { for (let objName in res) {
@ -222,6 +233,7 @@ const getTabsCount = async () => {
} }
} catch {} } catch {}
} }
const imgViewVisible = ref(false) // const imgViewVisible = ref(false) //
const imageViewerList = ref<string[]>([]) // const imageViewerList = ref<string[]>([]) //
const queryParams = ref({ const queryParams = ref({
@ -230,10 +242,13 @@ const queryParams = ref({
tabType: 0 tabType: 0
}) })
const queryFormRef = ref() // const queryFormRef = ref() //
// TODO @puhui999 handleTabClick
const handleClick = (tab: TabsPaneContext) => { const handleClick = (tab: TabsPaneContext) => {
queryParams.value.tabType = tab.paneName queryParams.value.tabType = tab.paneName
getList() getList()
} }
/** 查询列表 */ /** 查询列表 */
const getList = async () => { const getList = async () => {
loading.value = true loading.value = true
@ -246,8 +261,10 @@ const getList = async () => {
} }
} }
// TODO @puhui999 changeStatus addToTrash
/** /**
* 更改SPU状态 * 更改 SPU 状态
*
* @param row * @param row
* @param status 更改前的值 * @param status 更改前的值
*/ */
@ -271,7 +288,7 @@ const changeStatus = async (row, status?: number) => {
) )
await managementApi.updateStatus({ id: row.id, status: row.status }) await managementApi.updateStatus({ id: row.id, status: row.status })
message.success('更新状态成功') message.success('更新状态成功')
// tabs // tabs
await getTabsCount() await getTabsCount()
// //
await getList() await getList()
@ -288,8 +305,10 @@ const changeStatus = async (row, status?: number) => {
: ProductSpuStatusEnum.DISABLE.status : ProductSpuStatusEnum.DISABLE.status
} }
} }
/** /**
* 加入回收站 * 加入回收站
*
* @param row * @param row
* @param status * @param status
*/ */
@ -299,6 +318,7 @@ const addToTrash = (row, status) => {
row.status = status row.status = status
changeStatus(row, num) changeStatus(row, num)
} }
/** 删除按钮操作 */ /** 删除按钮操作 */
const handleDelete = async (id: number) => { const handleDelete = async (id: number) => {
try { try {
@ -313,6 +333,7 @@ const handleDelete = async (id: number) => {
await getList() await getList()
} catch {} } catch {}
} }
/** /**
* 商品图预览 * 商品图预览
* @param imgUrl * @param imgUrl
@ -321,6 +342,7 @@ const imagePreview = (imgUrl: string) => {
imageViewerList.value = [imgUrl] imageViewerList.value = [imgUrl]
imgViewVisible.value = true imgViewVisible.value = true
} }
/** 搜索按钮操作 */ /** 搜索按钮操作 */
const handleQuery = () => { const handleQuery = () => {
getList() getList()
@ -334,16 +356,20 @@ const resetQuery = () => {
/** /**
* 新增或修改 * 新增或修改
* @param id *
* @param id 商品 SPU 编号
*/ */
const openForm = (id?: number) => { const openForm = (id?: number) => {
//
if (typeof id === 'number') { if (typeof id === 'number') {
push('/product/productManagementAdd?id=' + id) push('/product/productManagementAdd?id=' + id)
return return
} }
//
push('/product/productManagementAdd') push('/product/productManagementAdd')
} }
//
// TODO @puhui999
watch( watch(
() => currentRoute.value, () => currentRoute.value,
() => { () => {
@ -353,6 +379,7 @@ watch(
immediate: true immediate: true
} }
) )
/** 初始化 **/ /** 初始化 **/
onMounted(() => { onMounted(() => {
getTabsCount() getTabsCount()