共富商城
This commit is contained in:
1 parent
96184b023f
commit
2d9d60cd0a
7 files changed
+962
-475
No files matched your search
@@ -39,3 +39,14 @@ export function putObj(obj?: Object) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户下拉
|
||||||
|
*/
|
||||||
|
export function selectOption(query?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/supermarket/selectOption/merchant',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -27,14 +27,14 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<!-- <el-col :span="12" class="mb20">-->
|
||||||
<el-form-item label="邮箱" prop="email">
|
<!-- <el-form-item label="邮箱" prop="email">-->
|
||||||
<el-input v-model="form.email" placeholder="请输入邮箱"/>
|
<!-- <el-input v-model="form.email" placeholder="请输入邮箱"/>-->
|
||||||
</el-form-item>
|
<!-- </el-form-item>-->
|
||||||
</el-col>
|
<!-- </el-col>-->
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item label="状态(1启用 0停用)" prop="status">
|
<el-form-item label="状态" prop="status">
|
||||||
<el-radio-group v-model="form.status">
|
<el-radio-group v-model="form.status">
|
||||||
<el-radio :label="item.value" v-for="(item, index) in common_data_status" border :key="index">{{ item.label }}
|
<el-radio :label="item.value" v-for="(item, index) in common_data_status" border :key="index">{{ item.label }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item label="商户图片URL(逗号分隔)" prop="images">
|
<el-form-item label="商户图片" prop="images">
|
||||||
<upload-img v-model="form.images"></upload-img>
|
<upload-img v-model="form.images"></upload-img>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -64,12 +64,6 @@
|
|||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input v-model="form.remark" placeholder="请输入备注"/>
|
<el-input v-model="form.remark" placeholder="请输入备注"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="部门ID" prop="deptId">
|
|
||||||
<el-input v-model="form.deptId" placeholder="请输入部门ID"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -171,4 +165,4 @@ const getmallMerchantData = (id: string) => {
|
|||||||
defineExpose({
|
defineExpose({
|
||||||
openDialog
|
openDialog
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
@queryTable="getDataList"></right-toolbar>
|
@queryTable="getDataList"></right-toolbar>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table :data="state.dataList" v-loading="state.loading" border
|
<el-table :data="state.dataList" v-loading="state.loading" border
|
||||||
:cell-style="tableStyle.cellStyle" :header-cell-style="tableStyle.headerCellStyle"
|
:cell-style="tableStyle.cellStyle" :header-cell-style="tableStyle.headerCellStyle"
|
||||||
@selection-change="selectionChangHandle"
|
@selection-change="selectionChangHandle"
|
||||||
@sort-change="sortChangeHandle">
|
@sort-change="sortChangeHandle">
|
||||||
@@ -45,17 +45,16 @@
|
|||||||
<el-table-column prop="shortName" label="商户简称" show-overflow-tooltip/>
|
<el-table-column prop="shortName" label="商户简称" show-overflow-tooltip/>
|
||||||
<el-table-column prop="contactName" label="联系人" show-overflow-tooltip/>
|
<el-table-column prop="contactName" label="联系人" show-overflow-tooltip/>
|
||||||
<el-table-column prop="contactPhone" label="联系电话" show-overflow-tooltip/>
|
<el-table-column prop="contactPhone" label="联系电话" show-overflow-tooltip/>
|
||||||
<el-table-column prop="email" label="邮箱" show-overflow-tooltip/>
|
<!-- <el-table-column prop="email" label="邮箱" show-overflow-tooltip/>-->
|
||||||
<el-table-column prop="status" label="状态(1启用 0停用)" show-overflow-tooltip>
|
<el-table-column prop="status" label="状态" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :options="common_data_status" :value="scope.row.status"></dict-tag>
|
<dict-tag :options="common_data_status" :value="scope.row.status"></dict-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="licenseNo" label="营业执照号" show-overflow-tooltip/>
|
<el-table-column prop="licenseNo" label="营业执照号" show-overflow-tooltip/>
|
||||||
<el-table-column prop="address" label="详细地址" show-overflow-tooltip/>
|
<el-table-column prop="address" label="详细地址" show-overflow-tooltip/>
|
||||||
<el-table-column prop="images" label="商户图片URL(逗号分隔)" show-overflow-tooltip/>
|
<el-table-column prop="images" label="商户图片" show-overflow-tooltip/>
|
||||||
<el-table-column prop="remark" label="备注" show-overflow-tooltip/>
|
<el-table-column prop="remark" label="备注" show-overflow-tooltip/>
|
||||||
<el-table-column prop="deptId" label="部门ID" show-overflow-tooltip/>
|
|
||||||
<el-table-column label="操作" width="150">
|
<el-table-column label="操作" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button icon="edit-pen" text type="primary" v-auth="'supermarket_mallMerchant_edit'"
|
<el-button icon="edit-pen" text type="primary" v-auth="'supermarket_mallMerchant_edit'"
|
||||||
@@ -144,4 +143,4 @@ const handleDelete = async (ids: string[]) => {
|
|||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -1,115 +1,250 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible"
|
<el-dialog :title="form.id ? '编辑商品' : '新增商品'" v-model="visible"
|
||||||
:close-on-click-modal="false" draggable>
|
:close-on-click-modal="false" draggable width="90%">
|
||||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="120px" v-loading="loading">
|
||||||
<el-row :gutter="24">
|
<!-- 基本信息 -->
|
||||||
<el-col :span="12" class="mb20">
|
<el-tabs v-model="activeTab" type="border-card">
|
||||||
<el-form-item label="商户ID" prop="merchantId">
|
<el-tab-pane label="基本信息" name="basic">
|
||||||
<el-select v-model="form.merchantId" placeholder="请选择商户ID">
|
<el-row :gutter="24">
|
||||||
<el-option label="请选择">0</el-option>
|
<el-col :span="12" class="mb20">
|
||||||
</el-select>
|
<el-form-item label="商户" prop="merchantId" required>
|
||||||
</el-form-item>
|
<el-select v-model="form.merchantId" placeholder="请选择商户" clearable>
|
||||||
</el-col>
|
<el-option
|
||||||
|
v-for="merchant in merchantOptions"
|
||||||
|
:key="merchant.value"
|
||||||
|
:label="merchant.label"
|
||||||
|
:value="merchant.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item label="类目ID" prop="categoryId">
|
<el-form-item label="商品分类" prop="categoryId" required>
|
||||||
<el-select v-model="form.categoryId" placeholder="请选择类目ID">
|
<el-cascader
|
||||||
<el-option label="请选择">0</el-option>
|
v-model="form.categoryId"
|
||||||
</el-select>
|
:options="categoryOptions"
|
||||||
</el-form-item>
|
:props="{ value: 'id', label: 'name', children: 'children', checkStrictly: true }"
|
||||||
</el-col>
|
clearable
|
||||||
|
placeholder="请选择商品分类"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item label="商品标题" prop="title">
|
<el-form-item label="商品标题" prop="title">
|
||||||
<el-input v-model="form.title" placeholder="请输入商品标题"/>
|
<el-input v-model="form.title" placeholder="请输入商品标题" maxlength="100" show-word-limit/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item label="副标题" prop="subTitle">
|
<el-form-item label="计量单位" prop="unit">
|
||||||
<el-input v-model="form.subTitle" placeholder="请输入副标题"/>
|
<el-input v-model="form.unit" placeholder="请输入计量单位"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item label="品牌" prop="brand">
|
<el-form-item label="定价方式" prop="priceType">
|
||||||
<el-input v-model="form.brand" placeholder="请输入品牌"/>
|
<el-radio-group v-model="form.priceType" @change="onPriceTypeChange">
|
||||||
</el-form-item>
|
<el-radio :label="1">多SKU模式</el-radio>
|
||||||
</el-col>
|
<el-radio :label="2">单价SPU模式</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item label="主图" prop="coverImage">
|
<el-form-item label="状态" prop="status">
|
||||||
<el-input v-model="form.coverImage" placeholder="请输入主图"/>
|
<el-radio-group v-model="form.status">
|
||||||
</el-form-item>
|
<el-radio :label="1">上架</el-radio>
|
||||||
</el-col>
|
<el-radio :label="0">下架</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<!-- 单价SPU模式的价格设置 -->
|
||||||
<el-form-item label="SPU轮播图URL(逗号分隔,按顺序)" prop="carouselImages">
|
<template v-if="form.priceType === 2">
|
||||||
<el-input v-model="form.carouselImages" placeholder="请输入SPU轮播图URL(逗号分隔,按顺序)"/>
|
<el-col :span="12" class="mb20">
|
||||||
</el-form-item>
|
<el-form-item label="SPU售价" prop="spuPrice">
|
||||||
</el-col>
|
<el-input-number v-model="form.spuPrice" :precision="2" :min="0" placeholder="请输入SPU售价" style="width: 100%"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item label="定价方式(1多SKU 2单价SPU)" prop="priceType">
|
<el-form-item label="划线价" prop="originalPrice">
|
||||||
<el-input v-model="form.priceType" placeholder="请输入定价方式(1多SKU 2单价SPU)"/>
|
<el-input-number v-model="form.originalPrice" :precision="2" :min="0" placeholder="请输入划线价" style="width: 100%"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
</template>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item label="SPU售价(当price_type=2有效)" prop="spuPrice">
|
<el-form-item label="开售时间" prop="saleStartTime">
|
||||||
<el-input v-model="form.spuPrice" placeholder="请输入SPU售价(当price_type=2有效)"/>
|
<el-date-picker v-model="form.saleStartTime" type="datetime" placeholder="请选择开售时间" style="width: 100%"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item label="划线价" prop="originalPrice">
|
<el-form-item label="停售时间" prop="saleEndTime">
|
||||||
<el-input v-model="form.originalPrice" placeholder="请输入划线价"/>
|
<el-date-picker v-model="form.saleEndTime" type="datetime" placeholder="请选择停售时间" style="width: 100%"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item label="总库存(冗余)" prop="totalStock">
|
<el-form-item label="主图" prop="coverImage">
|
||||||
<el-input v-model="form.totalStock" placeholder="请输入总库存(冗余)"/>
|
<upload-img v-model:imageUrl="form.coverImage"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item label="计量单位" prop="unit">
|
<el-form-item label="轮播图" prop="carouselImages">
|
||||||
<el-input v-model="form.unit" placeholder="请输入计量单位"/>
|
<upload-img v-model:imageUrl="form.carouselImages"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item label="状态(1上架 0下架)" prop="status">
|
<el-form-item label="详情描述" prop="description">
|
||||||
<el-input v-model="form.status" placeholder="请输入状态(1上架 0下架)"/>
|
<editor v-if="visible" v-model:get-html="form.description" placeholder="请输入详情描述"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<!-- SKU信息 -->
|
||||||
<el-form-item label="开售时间" prop="saleStartTime">
|
<el-tab-pane label="SKU信息" name="sku" v-if="form.priceType === 1">
|
||||||
<el-input v-model="form.saleStartTime" placeholder="请输入开售时间"/>
|
<div class="sku-header">
|
||||||
</el-form-item>
|
<el-button type="primary" @click="addSku" :disabled="loading">
|
||||||
</el-col>
|
<el-icon><Plus /></el-icon>
|
||||||
|
添加SKU
|
||||||
|
</el-button>
|
||||||
|
<span class="sku-tip">多SKU模式:支持不同规格的商品(如不同颜色、尺寸、配置等)</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<div class="sku-table-container">
|
||||||
<el-form-item label="停售时间" prop="saleEndTime">
|
<el-table :data="form.skuList" border class="sku-table" v-loading="loading">
|
||||||
<el-input v-model="form.saleEndTime" placeholder="请输入停售时间"/>
|
<el-table-column type="index" label="#" width="60" align="center"/>
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-table-column label="SKU编码" width="140" align="center">
|
||||||
<el-form-item label="详情描述(HTML/文本)" prop="description">
|
<template #header>
|
||||||
<editor v-if="visible" v-model:get-html="form.description" placeholder="请输入详情描述(HTML/文本)"></editor>
|
<span class="required">*</span> SKU编码
|
||||||
</el-form-item>
|
</template>
|
||||||
</el-col>
|
<template #default="scope">
|
||||||
|
<div class="sku-cell">
|
||||||
|
<el-input
|
||||||
|
v-model="scope.row.skuCode"
|
||||||
|
placeholder="请输入SKU编码"
|
||||||
|
size="small"
|
||||||
|
:class="{ 'is-error': !scope.row.skuCode && form.skuList.length > 0 }"
|
||||||
|
@blur="validateSkuField(scope.$index, 'skuCode')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-table-column label="SKU名称" min-width="220" align="center" show-overflow-tooltip>
|
||||||
<el-form-item label="部门ID" prop="deptId">
|
<template #header>
|
||||||
<el-input v-model="form.deptId" placeholder="请输入部门ID"/>
|
<span class="required">*</span> SKU名称
|
||||||
</el-form-item>
|
</template>
|
||||||
</el-col>
|
<template #default="scope">
|
||||||
|
<div class="sku-cell">
|
||||||
|
<el-input
|
||||||
|
v-model="scope.row.skuName"
|
||||||
|
placeholder="请输入SKU名称"
|
||||||
|
size="small"
|
||||||
|
:class="{ 'is-error': !scope.row.skuName && form.skuList.length > 0 }"
|
||||||
|
@blur="validateSkuField(scope.$index, 'skuName')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
</el-row>
|
<el-table-column label="售价" width="140" align="center">
|
||||||
|
<template #header>
|
||||||
|
<span class="required">*</span> 售价
|
||||||
|
</template>
|
||||||
|
<template #default="scope">
|
||||||
|
<div class="sku-cell">
|
||||||
|
<el-input-number
|
||||||
|
v-model="scope.row.price"
|
||||||
|
:precision="2"
|
||||||
|
:min="0"
|
||||||
|
size="small"
|
||||||
|
placeholder="0.00"
|
||||||
|
:class="{ 'is-error': (!scope.row.price || scope.row.price <= 0) && form.skuList.length > 0 }"
|
||||||
|
@blur="validateSkuField(scope.$index, 'price')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="库存" width="150" align="center">
|
||||||
|
<template #header>
|
||||||
|
<span class="required">*</span> 库存
|
||||||
|
</template>
|
||||||
|
<template #default="scope">
|
||||||
|
<div class="sku-cell">
|
||||||
|
<el-input-number
|
||||||
|
v-model="scope.row.stock"
|
||||||
|
:min="0"
|
||||||
|
size="small"
|
||||||
|
placeholder="0"
|
||||||
|
:class="{ 'is-error': (scope.row.stock === undefined || scope.row.stock < 0) && form.skuList.length > 0 }"
|
||||||
|
@blur="validateSkuField(scope.$index, 'stock')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="条码" min-width="150" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<div class="sku-cell">
|
||||||
|
<el-input
|
||||||
|
v-model="scope.row.barcode"
|
||||||
|
placeholder="请输入条码"
|
||||||
|
size="small"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="重量(克)" min-width="120" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<div class="sku-cell">
|
||||||
|
<el-input-number
|
||||||
|
v-model="scope.row.weightG"
|
||||||
|
:min="0"
|
||||||
|
size="small"
|
||||||
|
placeholder="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="状态" min-width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<div class="sku-cell">
|
||||||
|
<el-radio-group v-model="scope.row.status" size="small">
|
||||||
|
<el-radio :label="1">启用</el-radio>
|
||||||
|
<el-radio :label="0">停用</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="操作" width="70" fixed="right" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
size="small"
|
||||||
|
@click="removeSku(scope.$index)"
|
||||||
|
:disabled="form.skuList.length <= 1"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
@@ -124,96 +259,491 @@
|
|||||||
import { useDict } from '/@/hooks/dict';
|
import { useDict } from '/@/hooks/dict';
|
||||||
import { useMessage } from "/@/hooks/message";
|
import { useMessage } from "/@/hooks/message";
|
||||||
import { getObj, addObj, putObj } from '/@/api/supermarket/mallProduct'
|
import { getObj, addObj, putObj } from '/@/api/supermarket/mallProduct'
|
||||||
import { rule } from '/@/utils/validate';
|
import { Plus } from '@element-plus/icons-vue';
|
||||||
|
import { tree as fetchCategoryTree } from '/@/api/supermarket/mallCategory';
|
||||||
|
import { selectOption as fetchMerchantSelect } from '/@/api/supermarket/mallMerchant';
|
||||||
|
|
||||||
const emit = defineEmits(['refresh']);
|
const emit = defineEmits(['refresh']);
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const dataFormRef = ref();
|
const dataFormRef = ref();
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
const activeTab = ref('basic')
|
||||||
|
|
||||||
// 定义字典
|
// 定义字典
|
||||||
const { spu_status } = useDict('spu_status')
|
const { spu_status } = useDict('spu_status')
|
||||||
|
|
||||||
|
// 分类选项
|
||||||
|
const categoryOptions = ref<any[]>([]);
|
||||||
|
|
||||||
|
// 商户选项
|
||||||
|
const merchantOptions = ref<any[]>([]);
|
||||||
|
|
||||||
|
// 加载分类树
|
||||||
|
const loadCategoryTree = async () => {
|
||||||
|
const res = await fetchCategoryTree();
|
||||||
|
categoryOptions.value = res.data || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载商户选项
|
||||||
|
const loadMerchantOptions = async () => {
|
||||||
|
const res = await fetchMerchantSelect();
|
||||||
|
merchantOptions.value = res.data || [];
|
||||||
|
};
|
||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
id:'',
|
id: '',
|
||||||
merchantId: '',
|
merchantId: '',
|
||||||
categoryId: '',
|
categoryId: '',
|
||||||
title: '',
|
title: '',
|
||||||
subTitle: '',
|
coverImage: '',
|
||||||
brand: '',
|
carouselImages: '',
|
||||||
coverImage: '',
|
priceType: 1, // 默认多SKU模式
|
||||||
carouselImages: '',
|
spuPrice: 0,
|
||||||
priceType: '',
|
originalPrice: 0,
|
||||||
spuPrice: '',
|
unit: '',
|
||||||
originalPrice: '',
|
status: 1, // 默认上架
|
||||||
totalStock: '',
|
saleStartTime: '',
|
||||||
unit: '',
|
saleEndTime: '',
|
||||||
status: '',
|
description: '',
|
||||||
saleStartTime: '',
|
skuList: [] as any[] // SKU列表
|
||||||
saleEndTime: '',
|
|
||||||
description: '',
|
|
||||||
deptId: '',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// SKU验证规则
|
||||||
|
const skuRules = {
|
||||||
|
skuCode: [{ required: true, message: 'SKU编码不能为空', trigger: 'blur' }],
|
||||||
|
skuName: [{ required: true, message: 'SKU名称不能为空', trigger: 'blur' }],
|
||||||
|
price: [{ required: true, message: '售价不能为空', trigger: 'blur' }],
|
||||||
|
stock: [{ required: true, message: '库存不能为空', trigger: 'blur' }]
|
||||||
|
};
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = ref({
|
const dataRules = ref({
|
||||||
merchantId: [{required: true, message: '商户ID不能为空', trigger: 'blur'}],
|
merchantId: [{ required: true, message: '商户不能为空', trigger: 'change' }],
|
||||||
categoryId: [{required: true, message: '类目ID不能为空', trigger: 'blur'}],
|
categoryId: [{ required: true, message: '商品分类不能为空', trigger: 'change' }],
|
||||||
title: [{required: true, message: '商品标题不能为空', trigger: 'blur'}],
|
title: [{ required: true, message: '商品标题不能为空', trigger: 'blur' }],
|
||||||
coverImage: [{required: true, message: '主图不能为空', trigger: 'blur'}],
|
coverImage: [{ required: true, message: '主图不能为空', trigger: 'blur' }],
|
||||||
status: [{required: true, message: '状态(1上架 0下架)不能为空', trigger: 'blur'}],
|
priceType: [{ required: true, message: '定价方式不能为空', trigger: 'change' }],
|
||||||
})
|
spuPrice: [
|
||||||
|
{
|
||||||
|
validator: (rule: any, value: any, callback: any) => {
|
||||||
|
if (form.priceType === 2 && (!value || value <= 0)) {
|
||||||
|
callback(new Error('单价SPU模式下,SPU售价不能为空且必须大于0'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加SKU
|
||||||
|
const addSku = () => {
|
||||||
|
form.skuList.push({
|
||||||
|
skuCode: '',
|
||||||
|
skuName: '',
|
||||||
|
price: 0,
|
||||||
|
stock: 0,
|
||||||
|
barcode: '',
|
||||||
|
weightG: 0,
|
||||||
|
status: 1
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除SKU
|
||||||
|
const removeSku = (index: number) => {
|
||||||
|
if (form.skuList.length > 1) {
|
||||||
|
form.skuList.splice(index, 1);
|
||||||
|
} else {
|
||||||
|
useMessage().warning('至少需要保留一个SKU');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 定价方式改变
|
||||||
|
const onPriceTypeChange = (value: number) => {
|
||||||
|
if (value === 1) {
|
||||||
|
// 多SKU模式:确保至少有一个SKU
|
||||||
|
if (form.skuList.length === 0) {
|
||||||
|
addSku();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 单价SPU模式:清空SKU列表
|
||||||
|
form.skuList = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// SKU字段验证
|
||||||
|
const validateSkuField = (index: number, field: string) => {
|
||||||
|
const sku = form.skuList[index];
|
||||||
|
if (!sku) return;
|
||||||
|
|
||||||
|
// 清除之前的错误状态
|
||||||
|
nextTick(() => {
|
||||||
|
// 这里可以添加具体的验证逻辑
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openDialog = (id: string) => {
|
const openDialog = (id: string) => {
|
||||||
visible.value = true
|
visible.value = true
|
||||||
form.id = ''
|
form.id = ''
|
||||||
|
activeTab.value = 'basic'
|
||||||
|
|
||||||
// 重置表单数据
|
// 重置表单数据
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
dataFormRef.value?.resetFields();
|
dataFormRef.value?.resetFields();
|
||||||
|
// 重置表单对象
|
||||||
|
Object.assign(form, {
|
||||||
|
id: '',
|
||||||
|
merchantId: '',
|
||||||
|
categoryId: '',
|
||||||
|
title: '',
|
||||||
|
coverImage: '',
|
||||||
|
carouselImages: '',
|
||||||
|
priceType: 1,
|
||||||
|
spuPrice: 0,
|
||||||
|
originalPrice: 0,
|
||||||
|
unit: '',
|
||||||
|
status: 1,
|
||||||
|
saleStartTime: '',
|
||||||
|
saleEndTime: '',
|
||||||
|
description: '',
|
||||||
|
skuList: []
|
||||||
|
});
|
||||||
|
// 默认添加一个SKU
|
||||||
|
addSku();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 获取mallProduct信息
|
// 重新加载分类树和商户选项
|
||||||
if (id) {
|
loadCategoryTree();
|
||||||
form.id = id
|
loadMerchantOptions();
|
||||||
getmallProductData(id)
|
|
||||||
}
|
// 获取mallProduct信息
|
||||||
|
if (id) {
|
||||||
|
form.id = id
|
||||||
|
getmallProductData(id)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
|
// 验证基本信息
|
||||||
const valid = await dataFormRef.value.validate().catch(() => {});
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
if (!valid) return false;
|
if (!valid) return false;
|
||||||
|
|
||||||
|
// 多SKU模式下的额外验证
|
||||||
|
if (form.priceType === 1) {
|
||||||
|
if (!form.skuList || form.skuList.length === 0) {
|
||||||
|
useMessage().error('多SKU模式下至少需要添加一个SKU');
|
||||||
|
activeTab.value = 'sku';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证SKU数据
|
||||||
|
for (let i = 0; i < form.skuList.length; i++) {
|
||||||
|
const sku = form.skuList[i];
|
||||||
|
if (!sku.skuCode || !sku.skuName || !sku.price || sku.stock === undefined) {
|
||||||
|
useMessage().error(`第${i + 1}个SKU信息不完整,请检查必填项`);
|
||||||
|
activeTab.value = 'sku';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
form.id ? await putObj(form) : await addObj(form);
|
|
||||||
|
// 准备提交数据
|
||||||
|
const submitData = { ...form };
|
||||||
|
|
||||||
|
// 处理分类ID:如果是数组,取最后一个值
|
||||||
|
if (Array.isArray(form.categoryId)) {
|
||||||
|
submitData.categoryId = form.categoryId.slice(-1)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是单价SPU模式,清空SKU列表
|
||||||
|
if (form.priceType === 2) {
|
||||||
|
submitData.skuList = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
form.id ? await putObj(submitData) : await addObj(submitData);
|
||||||
useMessage().success(form.id ? '修改成功' : '添加成功');
|
useMessage().success(form.id ? '修改成功' : '添加成功');
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
emit('refresh');
|
emit('refresh');
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 初始化表单数据
|
// 初始化表单数据
|
||||||
const getmallProductData = (id: string) => {
|
const getmallProductData = (id: string) => {
|
||||||
// 获取数据
|
// 获取数据
|
||||||
loading.value = true
|
loading.value = true
|
||||||
getObj(id).then((res: any) => {
|
getObj(id).then((res: any) => {
|
||||||
Object.assign(form, res.data)
|
Object.assign(form, res.data);
|
||||||
}).finally(() => {
|
|
||||||
loading.value = false
|
// 处理分类ID回显为数组
|
||||||
})
|
if (res.data.categoryId && categoryOptions.value.length) {
|
||||||
|
form.categoryId = findCategoryPath(categoryOptions.value, res.data.categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有SKU数据,根据定价方式初始化
|
||||||
|
if (!form.skuList || form.skuList.length === 0) {
|
||||||
|
if (form.priceType === 1) {
|
||||||
|
addSku();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 工具函数:根据分类id查找路径
|
||||||
|
function findCategoryPath(options: any[], targetId: any, path: any[] = []): any[] {
|
||||||
|
for (const item of options) {
|
||||||
|
const newPath = path.concat(item.id);
|
||||||
|
if (item.id === targetId) return newPath;
|
||||||
|
if (item.children) {
|
||||||
|
const childPath = findCategoryPath(item.children, targetId, newPath);
|
||||||
|
if (childPath.length) return childPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组件挂载时加载分类树和商户选项
|
||||||
|
onMounted(() => {
|
||||||
|
loadCategoryTree();
|
||||||
|
loadMerchantOptions();
|
||||||
|
});
|
||||||
|
|
||||||
// 暴露变量
|
// 暴露变量
|
||||||
defineExpose({
|
defineExpose({
|
||||||
openDialog
|
openDialog
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.sku-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sku-tip {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.required {
|
||||||
|
color: #f56c6c;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SKU表格容器样式
|
||||||
|
.sku-table-container {
|
||||||
|
margin-top: 20px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SKU表格样式
|
||||||
|
.sku-table {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
:deep(.el-table__header) {
|
||||||
|
background: #f5f7fa;
|
||||||
|
|
||||||
|
th {
|
||||||
|
background: #f5f7fa !important;
|
||||||
|
border-bottom: 1px solid #e4e7ed;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-table__body) {
|
||||||
|
tr {
|
||||||
|
&:hover {
|
||||||
|
background: #f5f7fa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 8px 0;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保表格占满容器宽度
|
||||||
|
:deep(.el-table__header-wrapper),
|
||||||
|
:deep(.el-table__body-wrapper) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SKU单元格样式
|
||||||
|
.sku-cell {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 32px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
|
||||||
|
// 输入框样式
|
||||||
|
:deep(.el-input) {
|
||||||
|
.el-input__wrapper {
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 0 0 1px #dcdfe6 inset;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 0 0 1px #c0c4cc inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-focus {
|
||||||
|
box-shadow: 0 0 0 1px #409eff inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-error {
|
||||||
|
box-shadow: 0 0 0 1px #f56c6c inset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input__inner {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数字输入框样式
|
||||||
|
:deep(.el-input-number) {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.el-input__wrapper {
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 0 0 1px #dcdfe6 inset;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 0 0 1px #c0c4cc inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-focus {
|
||||||
|
box-shadow: 0 0 0 1px #409eff inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-error {
|
||||||
|
box-shadow: 0 0 0 1px #f56c6c inset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input__inner {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 13px;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input-number__decrease,
|
||||||
|
.el-input-number__increase {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 10px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input-number__decrease {
|
||||||
|
left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input-number__increase {
|
||||||
|
right: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单选框组样式
|
||||||
|
:deep(.el-radio-group) {
|
||||||
|
.el-radio {
|
||||||
|
margin-right: 8px;
|
||||||
|
|
||||||
|
.el-radio__label {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按钮样式
|
||||||
|
:deep(.el-button) {
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
height: 24px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 错误状态样式
|
||||||
|
.is-error {
|
||||||
|
:deep(.el-input__wrapper) {
|
||||||
|
box-shadow: 0 0 0 1px #f56c6c inset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-input-number__wrapper) {
|
||||||
|
box-shadow: 0 0 0 1px #f56c6c inset !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表格响应式处理
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
.sku-table-container {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sku-table {
|
||||||
|
min-width: 800px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除背景水印影响
|
||||||
|
:deep(.el-dialog) {
|
||||||
|
background: #fff;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-dialog__body) {
|
||||||
|
background: #fff;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2001;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 优化表单项间距
|
||||||
|
:deep(.el-form-item) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-form-item__error) {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10;
|
||||||
|
background: #fff;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border: 1px solid #f56c6c;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -38,28 +38,91 @@
|
|||||||
@sort-change="sortChangeHandle">
|
@sort-change="sortChangeHandle">
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
<el-table-column type="selection" width="40" align="center" />
|
||||||
<el-table-column type="index" label="#" width="40" />
|
<el-table-column type="index" label="#" width="40" />
|
||||||
<el-table-column prop="merchantId" label="商户ID" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="categoryId" label="类目ID" show-overflow-tooltip/>
|
<el-table-column prop="title" label="商品标题" width="200" show-overflow-tooltip/>
|
||||||
<el-table-column prop="title" label="商品标题" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="subTitle" label="副标题" show-overflow-tooltip/>
|
<el-table-column prop="merchantId" label="商户" width="150" show-overflow-tooltip>
|
||||||
<el-table-column prop="brand" label="品牌" show-overflow-tooltip/>
|
<template #default="scope">
|
||||||
<el-table-column prop="coverImage" label="主图" show-overflow-tooltip/>
|
{{ getMerchantName(scope.row.merchantId) }}
|
||||||
<el-table-column prop="carouselImages" label="SPU轮播图URL(逗号分隔,按顺序)" show-overflow-tooltip/>
|
</template>
|
||||||
<el-table-column prop="priceType" label="定价方式(1多SKU 2单价SPU)" show-overflow-tooltip/>
|
</el-table-column>
|
||||||
<el-table-column prop="spuPrice" label="SPU售价(当price_type=2有效)" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="originalPrice" label="划线价" show-overflow-tooltip/>
|
<el-table-column prop="categoryId" label="商品分类" width="150" show-overflow-tooltip>
|
||||||
<el-table-column prop="totalStock" label="总库存(冗余)" show-overflow-tooltip/>
|
<template #default="scope">
|
||||||
<el-table-column prop="unit" label="计量单位" show-overflow-tooltip/>
|
{{ getCategoryName(scope.row.categoryId) }}
|
||||||
<el-table-column prop="status" label="状态(1上架 0下架)" show-overflow-tooltip>
|
</template>
|
||||||
<template #default="scope">
|
</el-table-column>
|
||||||
<dict-tag :options="spu_status" :value="scope.row.status"></dict-tag>
|
|
||||||
</template>
|
<el-table-column prop="priceType" label="定价方式" width="120" align="center">
|
||||||
</el-table-column>
|
<template #default="scope">
|
||||||
<el-table-column prop="saleStartTime" label="开售时间" show-overflow-tooltip/>
|
<el-tag :type="scope.row.priceType === 1 ? 'primary' : 'success'">
|
||||||
<el-table-column prop="saleEndTime" label="停售时间" show-overflow-tooltip/>
|
{{ scope.row.priceType === 1 ? '多SKU' : '单价SPU' }}
|
||||||
<el-table-column prop="description" label="详情描述(HTML/文本)" show-overflow-tooltip/>
|
</el-tag>
|
||||||
<el-table-column prop="deptId" label="部门ID" show-overflow-tooltip/>
|
</template>
|
||||||
<el-table-column label="操作" width="150">
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="价格信息" width="200">
|
||||||
|
<template #default="scope">
|
||||||
|
<div v-if="scope.row.priceType === 1">
|
||||||
|
<div v-if="scope.row.skuList && scope.row.skuList.length > 0">
|
||||||
|
<div class="price-range">
|
||||||
|
<span class="min-price">¥{{ getMinPrice(scope.row.skuList) }}</span>
|
||||||
|
<span v-if="getMinPrice(scope.row.skuList) !== getMaxPrice(scope.row.skuList)"> - ¥{{ getMaxPrice(scope.row.skuList) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="sku-count">{{ scope.row.skuList.length }}个SKU</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="no-sku">暂无SKU</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div class="spu-price">¥{{ scope.row.spuPrice || 0 }}</div>
|
||||||
|
<div v-if="scope.row.originalPrice" class="original-price">¥{{ scope.row.originalPrice }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="库存信息" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<div v-if="scope.row.priceType === 1">
|
||||||
|
<div v-if="scope.row.skuList && scope.row.skuList.length > 0">
|
||||||
|
<div class="total-stock">{{ getTotalStock(scope.row.skuList) }}</div>
|
||||||
|
<div class="sku-count">{{ scope.row.skuList.length }}个SKU</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="no-stock">0</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div class="spu-stock">{{ scope.row.totalStock || 0 }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="unit" label="单位" width="80" align="center"/>
|
||||||
|
|
||||||
|
<el-table-column prop="status" label="状态" width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
|
||||||
|
{{ scope.row.status === 1 ? '上架' : '下架' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="saleStartTime" label="开售时间" width="160" show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column prop="saleEndTime" label="停售时间" width="160" show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column label="SKU详情" width="120" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
v-if="scope.row.priceType === 1 && scope.row.skuList && scope.row.skuList.length > 0"
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
@click="showSkuDetail(scope.row)">
|
||||||
|
查看SKU
|
||||||
|
</el-button>
|
||||||
|
<span v-else class="no-sku-detail">-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="操作" width="180" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button icon="edit-pen" text type="primary" v-auth="'supermarket_mallProduct_edit'"
|
<el-button icon="edit-pen" text type="primary" v-auth="'supermarket_mallProduct_edit'"
|
||||||
@click="formDialogRef.openDialog(scope.row.id)">编辑</el-button>
|
@click="formDialogRef.openDialog(scope.row.id)">编辑</el-button>
|
||||||
@@ -73,6 +136,43 @@
|
|||||||
<!-- 编辑、新增 -->
|
<!-- 编辑、新增 -->
|
||||||
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
|
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
|
||||||
|
|
||||||
|
<!-- SKU详情弹窗 -->
|
||||||
|
<el-dialog v-model="skuDetailVisible" title="SKU详情" width="80%" :close-on-click-modal="false">
|
||||||
|
<div v-if="currentProduct">
|
||||||
|
<div class="product-info">
|
||||||
|
<h3>{{ currentProduct.title }}</h3>
|
||||||
|
<p class="product-desc">{{ currentProduct.subTitle }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table :data="currentProduct.skuList" border style="margin-top: 20px;">
|
||||||
|
<el-table-column type="index" label="#" width="60" align="center"/>
|
||||||
|
<el-table-column prop="skuCode" label="SKU编码" width="150"/>
|
||||||
|
<el-table-column prop="skuName" label="SKU名称" width="200"/>
|
||||||
|
<el-table-column prop="price" label="售价" width="120" align="right">
|
||||||
|
<template #default="scope">
|
||||||
|
<span class="price">¥{{ scope.row.price }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="stock" label="库存" width="100" align="center"/>
|
||||||
|
<el-table-column prop="barcode" label="条码" width="150"/>
|
||||||
|
<el-table-column prop="weightG" label="重量(克)" width="120" align="center"/>
|
||||||
|
<el-table-column prop="status" label="状态" width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
|
||||||
|
{{ scope.row.status === 1 ? '启用' : '停用' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="skuDetailVisible = false">关闭</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -81,14 +181,38 @@ import { BasicTableProps, useTable } from "/@/hooks/table";
|
|||||||
import { fetchList, delObjs } from "/@/api/supermarket/mallProduct";
|
import { fetchList, delObjs } from "/@/api/supermarket/mallProduct";
|
||||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||||
import { useDict } from '/@/hooks/dict';
|
import { useDict } from '/@/hooks/dict';
|
||||||
|
import { tree as fetchCategoryTree } from '/@/api/supermarket/mallCategory';
|
||||||
|
import { selectOption as fetchMerchantSelect } from '/@/api/supermarket/mallMerchant';
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
// 定义查询字典
|
|
||||||
|
|
||||||
|
// 定义查询字典
|
||||||
const { spu_status } = useDict('spu_status')
|
const { spu_status } = useDict('spu_status')
|
||||||
|
|
||||||
|
// 分类选项
|
||||||
|
const categoryOptions = ref<any[]>([]);
|
||||||
|
|
||||||
|
// 商户选项
|
||||||
|
const merchantOptions = ref<any[]>([]);
|
||||||
|
|
||||||
|
// 加载分类树
|
||||||
|
const loadCategoryTree = async () => {
|
||||||
|
const res = await fetchCategoryTree();
|
||||||
|
categoryOptions.value = res.data || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载商户选项
|
||||||
|
const loadMerchantOptions = async () => {
|
||||||
|
const res = await fetchMerchantSelect();
|
||||||
|
merchantOptions.value = res.data || [];
|
||||||
|
};
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const formDialogRef = ref()
|
const formDialogRef = ref()
|
||||||
|
const skuDetailVisible = ref(false)
|
||||||
|
const currentProduct = ref(null)
|
||||||
|
|
||||||
// 搜索变量
|
// 搜索变量
|
||||||
const queryRef = ref()
|
const queryRef = ref()
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true)
|
||||||
@@ -111,6 +235,56 @@ const {
|
|||||||
tableStyle
|
tableStyle
|
||||||
} = useTable(state)
|
} = useTable(state)
|
||||||
|
|
||||||
|
// 获取SKU最低价格
|
||||||
|
const getMinPrice = (skuList: any[]) => {
|
||||||
|
if (!skuList || skuList.length === 0) return 0;
|
||||||
|
return Math.min(...skuList.map(sku => sku.price || 0));
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取SKU最高价格
|
||||||
|
const getMaxPrice = (skuList: any[]) => {
|
||||||
|
if (!skuList || skuList.length === 0) return 0;
|
||||||
|
return Math.max(...skuList.map(sku => sku.price || 0));
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取SKU总库存
|
||||||
|
const getTotalStock = (skuList: any[]) => {
|
||||||
|
if (!skuList || skuList.length === 0) return 0;
|
||||||
|
return skuList.reduce((total, sku) => total + (sku.stock || 0), 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据分类ID查找分类名称
|
||||||
|
const getCategoryName = (categoryId: any) => {
|
||||||
|
if (!categoryId || !categoryOptions.value.length) return '-';
|
||||||
|
|
||||||
|
const findCategory = (options: any[], targetId: any): any => {
|
||||||
|
for (const item of options) {
|
||||||
|
if (item.id === targetId) return item;
|
||||||
|
if (item.children) {
|
||||||
|
const found = findCategory(item.children, targetId);
|
||||||
|
if (found) return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const category = findCategory(categoryOptions.value, categoryId);
|
||||||
|
return category ? category.name : '-';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据商户ID查找商户名称
|
||||||
|
const getMerchantName = (merchantId: any) => {
|
||||||
|
if (!merchantId || !merchantOptions.value.length) return '-';
|
||||||
|
const merchant = merchantOptions.value.find(item => item.value === merchantId);
|
||||||
|
return merchant ? merchant.label : '-';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 显示SKU详情
|
||||||
|
const showSkuDetail = (product: any) => {
|
||||||
|
currentProduct.value = product;
|
||||||
|
skuDetailVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
// 清空搜索条件
|
// 清空搜索条件
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
// 清空搜索条件
|
// 清空搜索条件
|
||||||
@@ -147,4 +321,73 @@ const handleDelete = async (ids: string[]) => {
|
|||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
|
||||||
|
// 组件挂载时加载分类树和商户选项
|
||||||
|
onMounted(() => {
|
||||||
|
loadCategoryTree();
|
||||||
|
loadMerchantOptions();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.price-range {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #e6a23c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.min-price {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spu-price {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.original-price {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-stock, .spu-stock {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #67c23a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sku-count {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-sku, .no-stock, .no-sku-detail {
|
||||||
|
color: #c0c4cc;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-info {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 15px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-desc {
|
||||||
|
margin: 0;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
color: #f56c6c;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible"
|
|
||||||
:close-on-click-modal="false" draggable>
|
|
||||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
|
|
||||||
<el-row :gutter="24">
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="SPU ID" prop="productId">
|
|
||||||
<el-input v-model="form.productId" placeholder="请输入SPU ID"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="SKU编码" prop="skuCode">
|
|
||||||
<el-input v-model="form.skuCode" placeholder="请输入SKU编码"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="SKU名称(规格组合)" prop="skuName">
|
|
||||||
<el-input v-model="form.skuName" placeholder="请输入SKU名称(规格组合)"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="售价" prop="price">
|
|
||||||
<el-input v-model="form.price" placeholder="请输入售价"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="成本价" prop="costPrice">
|
|
||||||
<el-input v-model="form.costPrice" placeholder="请输入成本价"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="库存" prop="stock">
|
|
||||||
<el-input v-model="form.stock" placeholder="请输入库存"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="条码" prop="barcode">
|
|
||||||
<el-input v-model="form.barcode" placeholder="请输入条码"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="重量(克)" prop="weightG">
|
|
||||||
<el-input v-model="form.weightG" placeholder="请输入重量(克)"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="体积(立方厘米)" prop="volumeCm3">
|
|
||||||
<el-input v-model="form.volumeCm3" placeholder="请输入体积(立方厘米)"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="状态(1启用 0停用)" prop="status">
|
|
||||||
<el-input v-model="form.status" placeholder="请输入状态(1启用 0停用)"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
|
||||||
<el-form-item label="部门ID" prop="deptId">
|
|
||||||
<el-input v-model="form.deptId" placeholder="请输入部门ID"/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="visible = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确认</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="MallProductSkuDialog">
|
|
||||||
import { useDict } from '/@/hooks/dict';
|
|
||||||
import { useMessage } from "/@/hooks/message";
|
|
||||||
import { getObj, addObj, putObj } from '/@/api/supermarket/mallProductSku'
|
|
||||||
import { rule } from '/@/utils/validate';
|
|
||||||
const emit = defineEmits(['refresh']);
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const dataFormRef = ref();
|
|
||||||
const visible = ref(false)
|
|
||||||
const loading = ref(false)
|
|
||||||
// 定义字典
|
|
||||||
|
|
||||||
// 提交表单数据
|
|
||||||
const form = reactive({
|
|
||||||
id:'',
|
|
||||||
productId: '',
|
|
||||||
skuCode: '',
|
|
||||||
skuName: '',
|
|
||||||
price: '',
|
|
||||||
costPrice: '',
|
|
||||||
stock: '',
|
|
||||||
barcode: '',
|
|
||||||
weightG: '',
|
|
||||||
volumeCm3: '',
|
|
||||||
status: '',
|
|
||||||
deptId: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 定义校验规则
|
|
||||||
const dataRules = ref({
|
|
||||||
})
|
|
||||||
|
|
||||||
// 打开弹窗
|
|
||||||
const openDialog = (id: string) => {
|
|
||||||
visible.value = true
|
|
||||||
form.id = ''
|
|
||||||
|
|
||||||
// 重置表单数据
|
|
||||||
nextTick(() => {
|
|
||||||
dataFormRef.value?.resetFields();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取mallProductSku信息
|
|
||||||
if (id) {
|
|
||||||
form.id = id
|
|
||||||
getmallProductSkuData(id)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 提交
|
|
||||||
const onSubmit = async () => {
|
|
||||||
const valid = await dataFormRef.value.validate().catch(() => {});
|
|
||||||
if (!valid) return false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
loading.value = true;
|
|
||||||
form.id ? await putObj(form) : await addObj(form);
|
|
||||||
useMessage().success(form.id ? '修改成功' : '添加成功');
|
|
||||||
visible.value = false;
|
|
||||||
emit('refresh');
|
|
||||||
} catch (err: any) {
|
|
||||||
useMessage().error(err.msg);
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// 初始化表单数据
|
|
||||||
const getmallProductSkuData = (id: string) => {
|
|
||||||
// 获取数据
|
|
||||||
loading.value = true
|
|
||||||
getObj(id).then((res: any) => {
|
|
||||||
Object.assign(form, res.data)
|
|
||||||
}).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// 暴露变量
|
|
||||||
defineExpose({
|
|
||||||
openDialog
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-padding">
|
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
|
||||||
<el-row>
|
|
||||||
<div class="mb8" style="width: 100%">
|
|
||||||
<el-button icon="folder-add" type="primary" class="ml10" @click="formDialogRef.openDialog()"
|
|
||||||
v-auth="'supermarket_mallProductSku_add'">
|
|
||||||
新 增
|
|
||||||
</el-button>
|
|
||||||
<el-button plain :disabled="multiple" icon="Delete" type="primary"
|
|
||||||
v-auth="'supermarket_mallProductSku_del'" @click="handleDelete(selectObjs)">
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
<right-toolbar v-model:showSearch="showSearch" :export="'supermarket_mallProductSku_export'"
|
|
||||||
@exportExcel="exportExcel" class="ml10 mr20" style="float: right;"
|
|
||||||
@queryTable="getDataList"></right-toolbar>
|
|
||||||
</div>
|
|
||||||
</el-row>
|
|
||||||
<el-table :data="state.dataList" v-loading="state.loading" border
|
|
||||||
:cell-style="tableStyle.cellStyle" :header-cell-style="tableStyle.headerCellStyle"
|
|
||||||
@selection-change="selectionChangHandle"
|
|
||||||
@sort-change="sortChangeHandle">
|
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
|
||||||
<el-table-column type="index" label="#" width="40" />
|
|
||||||
<el-table-column prop="productId" label="SPU ID" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="skuCode" label="SKU编码" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="skuName" label="SKU名称(规格组合)" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="price" label="售价" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="costPrice" label="成本价" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="stock" label="库存" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="barcode" label="条码" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="weightG" label="重量(克)" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="volumeCm3" label="体积(立方厘米)" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="status" label="状态(1启用 0停用)" show-overflow-tooltip/>
|
|
||||||
<el-table-column prop="deptId" label="部门ID" show-overflow-tooltip/>
|
|
||||||
<el-table-column label="操作" width="150">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button icon="edit-pen" text type="primary" v-auth="'supermarket_mallProductSku_edit'"
|
|
||||||
@click="formDialogRef.openDialog(scope.row.id)">编辑</el-button>
|
|
||||||
<el-button icon="delete" text type="primary" v-auth="'supermarket_mallProductSku_del'" @click="handleDelete([scope.row.id])">删除</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 编辑、新增 -->
|
|
||||||
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="systemMallProductSku">
|
|
||||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
|
||||||
import { fetchList, delObjs } from "/@/api/supermarket/mallProductSku";
|
|
||||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
|
||||||
import { useDict } from '/@/hooks/dict';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
|
||||||
// 定义查询字典
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const formDialogRef = ref()
|
|
||||||
// 搜索变量
|
|
||||||
const queryRef = ref()
|
|
||||||
const showSearch = ref(true)
|
|
||||||
// 多选变量
|
|
||||||
const selectObjs = ref([]) as any
|
|
||||||
const multiple = ref(true)
|
|
||||||
|
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
|
||||||
queryForm: {},
|
|
||||||
pageList: fetchList
|
|
||||||
})
|
|
||||||
|
|
||||||
// table hook
|
|
||||||
const {
|
|
||||||
getDataList,
|
|
||||||
currentChangeHandle,
|
|
||||||
sizeChangeHandle,
|
|
||||||
sortChangeHandle,
|
|
||||||
downBlobFile,
|
|
||||||
tableStyle
|
|
||||||
} = useTable(state)
|
|
||||||
|
|
||||||
// 清空搜索条件
|
|
||||||
const resetQuery = () => {
|
|
||||||
// 清空搜索条件
|
|
||||||
queryRef.value?.resetFields()
|
|
||||||
// 清空多选
|
|
||||||
selectObjs.value = []
|
|
||||||
getDataList()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导出excel
|
|
||||||
const exportExcel = () => {
|
|
||||||
downBlobFile('/supermarket/mallProductSku/export', Object.assign(state.queryForm, { ids: selectObjs }), 'mallProductSku.xlsx')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 多选事件
|
|
||||||
const selectionChangHandle = (objs: { id: string }[]) => {
|
|
||||||
selectObjs.value = objs.map(({ id }) => id);
|
|
||||||
multiple.value = !objs.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除操作
|
|
||||||
const handleDelete = async (ids: string[]) => {
|
|
||||||
try {
|
|
||||||
await useMessageBox().confirm('此操作将永久删除');
|
|
||||||
} catch {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await delObjs(ids);
|
|
||||||
getDataList();
|
|
||||||
useMessage().success('删除成功');
|
|
||||||
} catch (err: any) {
|
|
||||||
useMessage().error(err.msg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
Reference in new issue
Block a user