完善商品提交信息
This commit is contained in:
@ -26,6 +26,6 @@ export function apiGoodsDetail(params: any) {
|
||||
}
|
||||
|
||||
// 商品分类列表
|
||||
export function checkCategory(params: any) {
|
||||
return request.post({ url: '/goodsCategory/checkCategory', params })
|
||||
export function checkCategory() {
|
||||
return request.post({ url: '/goodsCategory/checkCategory' })
|
||||
}
|
||||
@ -1,33 +1,18 @@
|
||||
<template>
|
||||
<div class="material-select">
|
||||
<popup
|
||||
ref="popupRef"
|
||||
width="1050px"
|
||||
custom-class="body-padding"
|
||||
:title="`选择${tipsText}`"
|
||||
@confirm="handleConfirm"
|
||||
@close="handleClose"
|
||||
>
|
||||
<popup ref="popupRef" width="1050px" custom-class="body-padding" :title="`选择${tipsText}`"
|
||||
@confirm="handleConfirm" @close="handleClose">
|
||||
<template v-if="!hiddenUpload" #trigger>
|
||||
<div class="material-select__trigger clearfix" @click.stop>
|
||||
<draggable class="draggable" v-model="fileList" animation="300" item-key="id">
|
||||
<template v-slot:item="{ element, index }">
|
||||
<div
|
||||
class="material-preview"
|
||||
:class="{
|
||||
'is-disabled': disabled,
|
||||
'is-one': limit == 1
|
||||
}"
|
||||
@click="showPopup(index)"
|
||||
>
|
||||
<div class="material-preview" :class="{
|
||||
'is-disabled': disabled,
|
||||
'is-one': limit == 1
|
||||
}" @click="showPopup(index)">
|
||||
<del-wrap @close="deleteImg(index)">
|
||||
<file-item
|
||||
:uri="excludeDomain ? getImageUrl(element) : element"
|
||||
:file-size="size"
|
||||
:width="width"
|
||||
:height="height"
|
||||
:type="type"
|
||||
></file-item>
|
||||
<file-item :uri="excludeDomain ? getImageUrl(element) : element" :file-size="size"
|
||||
:width="width" :height="height" :type="type"></file-item>
|
||||
</del-wrap>
|
||||
<div class="operation-btns text-xs text-center">
|
||||
<span>修改</span>
|
||||
@ -37,24 +22,16 @@
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
<div
|
||||
class="material-upload"
|
||||
@click="showPopup(-1)"
|
||||
v-show="showUpload"
|
||||
:class="{
|
||||
'is-disabled': disabled,
|
||||
'is-one': limit == 1,
|
||||
[uploadClass]: true
|
||||
}"
|
||||
>
|
||||
<div class="material-upload" @click="showPopup(-1)" v-show="showUpload" :class="{
|
||||
'is-disabled': disabled,
|
||||
'is-one': limit == 1,
|
||||
[uploadClass]: true
|
||||
}">
|
||||
<slot name="upload">
|
||||
<div
|
||||
class="upload-btn"
|
||||
:style="{
|
||||
width: width || size,
|
||||
height: height || size
|
||||
}"
|
||||
>
|
||||
<div class="upload-btn" :style="{
|
||||
width: width || size,
|
||||
height: height || size
|
||||
}">
|
||||
<icon :size="25" name="el-icon-Plus" />
|
||||
<span>添加</span>
|
||||
</div>
|
||||
@ -64,13 +41,8 @@
|
||||
</template>
|
||||
<el-scrollbar>
|
||||
<div class="material-wrap">
|
||||
<material
|
||||
ref="materialRef"
|
||||
:type="type"
|
||||
:file-size="fileSize"
|
||||
:limit="meterialLimit"
|
||||
@change="selectChange"
|
||||
/>
|
||||
<material ref="materialRef" :type="type" :file-size="fileSize" :limit="meterialLimit"
|
||||
@change="selectChange" />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</popup>
|
||||
@ -272,6 +244,7 @@ export default defineComponent({
|
||||
|
||||
<style scoped lang="scss">
|
||||
.material-select {
|
||||
|
||||
.material-upload,
|
||||
.material-preview {
|
||||
position: relative;
|
||||
@ -281,17 +254,21 @@ export default defineComponent({
|
||||
margin-bottom: 8px;
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
|
||||
&.is-disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.is-one {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.operation-btns {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.operation-btns {
|
||||
display: none;
|
||||
position: absolute;
|
||||
@ -303,12 +280,14 @@ export default defineComponent({
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.material-upload {
|
||||
:deep(.upload-btn) {
|
||||
@apply text-tx-secondary box-border rounded border-br border-dashed border flex flex-col justify-center items-center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.material-wrap {
|
||||
min-width: 720px;
|
||||
height: 560px;
|
||||
|
||||
@ -3,12 +3,127 @@
|
||||
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit"
|
||||
@close="handleClose">
|
||||
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
|
||||
<el-form-item label="商品名称" prop="name">
|
||||
<el-input v-model="formData.name" clearable placeholder="请输入商品名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品编码" prop="code">
|
||||
<el-input v-model="formData.code" clearable placeholder="请输入商品编码" />
|
||||
</el-form-item>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="基础设置">
|
||||
<el-form-item label="商品名称" prop="name" required>
|
||||
<el-input v-model="formData.name" clearable placeholder="请输入商品名称" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品编码" prop="code">
|
||||
<el-input v-model="formData.code" clearable placeholder="请输入商品编码" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品分类" prop="first_category_id" required>
|
||||
<div class="flex w-full">
|
||||
<div class="w-4/12">
|
||||
<el-select v-model="formData.first_category_id" placeholder="请选择分类"
|
||||
@change="selectFirstCategory">
|
||||
<el-option :label="item.name" :value="item.id"
|
||||
v-for="(item, index) in firstCategory" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="w-4/12">
|
||||
<el-select v-model="formData.second_category_id" placeholder="请选择分类"
|
||||
@change="selectSecondCategory">
|
||||
<el-option :label="item.name" :value="item.id"
|
||||
v-for="(item, index) in secondCategory" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="w-4/12">
|
||||
<el-select v-model="formData.third_category_id" placeholder="请选择分类">
|
||||
<el-option :label="item.name" :value="item.id"
|
||||
v-for="(item, index) in thirdCategory" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品卖点" prop="remark">
|
||||
<el-input v-model="formData.remark" clearable placeholder="请输入商品卖点" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品主图" prop="image" required>
|
||||
<material-picker v-model="formData.image" :limit="1" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品轮播图" prop="goods_image" required>
|
||||
<material-picker v-model="formData.goods_image" :limit="8" />
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="价格库存">
|
||||
<el-radio-group v-model="goodsSpec">
|
||||
<el-radio :value="1">统一规格</el-radio>
|
||||
<el-radio :value="2">多规格</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- 单规格 -->
|
||||
<div v-if="goodsSpec === 1">
|
||||
<el-table :data="[{}]" style="width: 100%">
|
||||
<el-table-column label="价格(元)" prop="one_price">
|
||||
<template #default="scope">
|
||||
<el-input v-model="formData.one_price" clearable placeholder="请输入价格(元)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成本价(元)" prop="one_cost_price">
|
||||
<template #default="scope">
|
||||
<el-input v-model="formData.one_cost_price" clearable placeholder="请输入成本价(元)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="请输入库存" prop="one_stock">
|
||||
<template #default="scope">
|
||||
<el-input v-model="formData.one_stock" clearable placeholder="请输入库存" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 单规格 -->
|
||||
<div v-if="goodsSpec === 2">
|
||||
<div>
|
||||
<el-form-item label="规格项" prop="code">
|
||||
<el-input v-model="formData.code" clearable placeholder="请填写规格名" />
|
||||
<div>
|
||||
<el-input v-model="specValue" clearable />
|
||||
</div>
|
||||
<div @click="addSpecValue" style="cursor: pointer;"> + 添加规格值</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-button type="primary">添加规格项目</el-button>
|
||||
|
||||
<!-- <el-table :data="[{}]" style="width: 100%">
|
||||
<el-table-column label="*价格(元)" prop="one_price">
|
||||
<template #default="scope">
|
||||
<el-input v-model="formData.one_price" clearable placeholder="请输入价格(元)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="*成本价(元)" prop="one_cost_price">
|
||||
<template #default="scope">
|
||||
<el-input v-model="formData.one_cost_price" clearable placeholder="请输入成本价(元)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="*请输入库存" prop="one_stock">
|
||||
<template #default="scope">
|
||||
<el-input v-model="formData.one_stock" clearable placeholder="请输入库存" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table> -->
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="商品详情"></el-tab-pane>
|
||||
<el-tab-pane label="销售设置"></el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
<el-dialog v-model="showSpec" title="输入规格值,多个请换行" width="500">
|
||||
<el-input v-model="specValue" type="textarea" clearable :rows="3" />
|
||||
<div class="mt-4">
|
||||
<el-button type="default" @click="closeSpecPopup">取消</el-button>
|
||||
<el-button type="primary" @click="confirmSpec">确定</el-button>
|
||||
</div>
|
||||
|
||||
</el-dialog>
|
||||
<!-- <el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
|
||||
|
||||
|
||||
<el-form-item label="一级分类id" prop="first_category_id">
|
||||
<el-input v-model="formData.first_category_id" clearable placeholder="请输入一级分类id" />
|
||||
</el-form-item>
|
||||
@ -143,7 +258,7 @@
|
||||
<el-form-item label="是否开启上门自提:1-是;0-否;" prop="is_selffetch">
|
||||
<el-input v-model="formData.is_selffetch" clearable placeholder="请输入是否开启上门自提:1-是;0-否;" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-form> -->
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
@ -151,7 +266,7 @@
|
||||
<script lang="ts" setup name="goodsEdit">
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import { apiGoodsAdd, apiGoodsEdit, apiGoodsDetail } from '@/api/goods'
|
||||
import { apiGoodsAdd, apiGoodsEdit, apiGoodsDetail, checkCategory } from '@/api/goods'
|
||||
import { timeFormat } from '@/utils/util'
|
||||
import type { PropType } from 'vue'
|
||||
defineProps({
|
||||
@ -164,13 +279,16 @@ const emit = defineEmits(['success', 'close'])
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
const mode = ref('add')
|
||||
|
||||
const goodsSpec = ref(1)
|
||||
let showSpec = ref(false)
|
||||
let specValue = ref("")
|
||||
|
||||
// 弹窗标题
|
||||
const popupTitle = computed(() => {
|
||||
return mode.value == 'edit' ? '编辑商品主表' : '新增商品主表'
|
||||
})
|
||||
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
id: '',
|
||||
@ -179,13 +297,20 @@ const formData = reactive({
|
||||
first_category_id: '',
|
||||
second_category_id: '',
|
||||
third_category_id: '',
|
||||
remark: '',
|
||||
image: '',
|
||||
goods_image: '',
|
||||
|
||||
one_price: '',
|
||||
one_cost_price: '',
|
||||
one_stock: '',
|
||||
brand_id: '',
|
||||
supplier_id: '',
|
||||
status: '',
|
||||
image: '',
|
||||
|
||||
video: '',
|
||||
one_spec_image: '',
|
||||
poster: '',
|
||||
remark: '',
|
||||
content: '',
|
||||
sort: '',
|
||||
sales_sum: '',
|
||||
@ -232,71 +357,64 @@ const formRules = reactive<any>({
|
||||
}],
|
||||
first_category_id: [{
|
||||
required: true,
|
||||
message: '请输入一级分类id',
|
||||
message: '请选择商品分类',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
second_category_id: [{
|
||||
required: true,
|
||||
message: '请输入二级分类id',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
third_category_id: [{
|
||||
required: true,
|
||||
message: '请输入三级分类id',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
status: [{
|
||||
required: true,
|
||||
message: '请输入商品状态:-1-回收站;0-下架;1-上架',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
image: [{
|
||||
required: true,
|
||||
message: '请输入商品主图',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_show_stock: [{
|
||||
required: true,
|
||||
message: '请输入是否显示库存:1-是;0-否',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
free_shipping_type: [{
|
||||
required: true,
|
||||
message: '请输入运费类型:1-包邮;2-统一运费;3-运费模板',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_commission: [{
|
||||
required: true,
|
||||
message: '请输入分销佣金:1-开启;0-不开启',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_share_bouns: [{
|
||||
required: true,
|
||||
message: '请输入区域股东分红:1-开启;0-不开启',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_team: [{
|
||||
required: true,
|
||||
message: '请输入是否开启拼团[0=否, 1=是]',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_integral: [{
|
||||
required: true,
|
||||
message: '请输入积分抵扣:1-开启;0-不开启',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_member: [{
|
||||
required: true,
|
||||
message: '请输入会员价:1-开启;0-不开启',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
give_integral_type: [{
|
||||
required: true,
|
||||
message: '请输入赠送积分类型:0-不赠送;1-赠送固定积分;2-按比例赠送积分',
|
||||
trigger: ['blur']
|
||||
}]
|
||||
// status: [{
|
||||
// required: true,
|
||||
// message: '请输入商品状态:-1-回收站;0-下架;1-上架',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// image: [{
|
||||
// required: true,
|
||||
// message: '请输入商品主图',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_show_stock: [{
|
||||
// required: true,
|
||||
// message: '请输入是否显示库存:1-是;0-否',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// free_shipping_type: [{
|
||||
// required: true,
|
||||
// message: '请输入运费类型:1-包邮;2-统一运费;3-运费模板',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_commission: [{
|
||||
// required: true,
|
||||
// message: '请输入分销佣金:1-开启;0-不开启',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_share_bouns: [{
|
||||
// required: true,
|
||||
// message: '请输入区域股东分红:1-开启;0-不开启',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_team: [{
|
||||
// required: true,
|
||||
// message: '请输入是否开启拼团[0=否, 1=是]',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_integral: [{
|
||||
// required: true,
|
||||
// message: '请输入积分抵扣:1-开启;0-不开启',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_member: [{
|
||||
// required: true,
|
||||
// message: '请输入会员价:1-开启;0-不开启',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// give_integral_type: [{
|
||||
// required: true,
|
||||
// message: '请输入赠送积分类型:0-不赠送;1-赠送固定积分;2-按比例赠送积分',
|
||||
// trigger: ['blur']
|
||||
// }]
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
category()
|
||||
});
|
||||
|
||||
// 获取详情
|
||||
const setFormData = async (data: Record<any, any>) => {
|
||||
@ -314,12 +432,55 @@ const getDetail = async (row: Record<string, any>) => {
|
||||
})
|
||||
setFormData(data)
|
||||
}
|
||||
//
|
||||
// 创建分类列表
|
||||
let goodsCategory = reactive<any[]>([])
|
||||
let firstCategory = reactive<any[]>([])
|
||||
let secondCategory = reactive<any[]>([])
|
||||
let thirdCategory = reactive<any[]>([])
|
||||
const category = async () => {
|
||||
const res = await checkCategory()
|
||||
goodsCategory = res
|
||||
firstCategory = res.filter((item: { pid: number }) => {
|
||||
if (item.pid === 0) {
|
||||
return item
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 选择第一个分类组,渲染第二个分组
|
||||
const selectFirstCategory = (id: number) => {
|
||||
secondCategory = goodsCategory.filter((item: { pid: number }) => {
|
||||
if (item.pid === id) {
|
||||
return item
|
||||
}
|
||||
})
|
||||
|
||||
if (secondCategory.length === 0) {
|
||||
formData.second_category_id = ''
|
||||
formData.third_category_id = ''
|
||||
}
|
||||
}
|
||||
// 选择第二个分类组,渲染第三个分组
|
||||
const selectSecondCategory = (id: number) => {
|
||||
thirdCategory = goodsCategory.filter((item: { pid: number }) => {
|
||||
if (item.pid === id) {
|
||||
return item
|
||||
}
|
||||
})
|
||||
|
||||
if (thirdCategory.length === 0) {
|
||||
formData.third_category_id = ''
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 提交按钮
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value?.validate()
|
||||
// await formRef.value?.validate()
|
||||
const data = { ...formData, }
|
||||
console.log("data>>>", data);
|
||||
return false;
|
||||
mode.value == 'edit'
|
||||
? await apiGoodsEdit(data)
|
||||
: await apiGoodsAdd(data)
|
||||
@ -339,10 +500,32 @@ const handleClose = () => {
|
||||
}
|
||||
|
||||
|
||||
// 添加规格值
|
||||
const addSpecValue = () => {
|
||||
showSpec.value = true
|
||||
}
|
||||
|
||||
// 关闭规格值弹窗
|
||||
const closeSpecPopup = () => {
|
||||
specValue.value = ''
|
||||
showSpec.value = false
|
||||
}
|
||||
|
||||
const confirmSpec = () => {
|
||||
if (specValue.value) {
|
||||
let specs = specValue.value.split('\n');
|
||||
for (let i in specs) {
|
||||
specs[i] = specs[i].trim();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
setFormData,
|
||||
getDetail
|
||||
getDetail,
|
||||
selectFirstCategory,
|
||||
selectSecondCategory
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -2,184 +2,133 @@
|
||||
<div class="edit-popup">
|
||||
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit"
|
||||
@close="handleClose">
|
||||
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules"></el-form>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="基础设置">
|
||||
<el-form-item label="商品名称" prop="name">
|
||||
<el-input v-model="formData.name" clearable placeholder="请输入商品名称" />
|
||||
</el-form-item>
|
||||
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="基础设置">
|
||||
<el-form-item label="商品名称" prop="name" required>
|
||||
<el-input v-model="formData.name" clearable placeholder="请输入商品名称" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品编码" prop="code">
|
||||
<el-input v-model="formData.code" clearable placeholder="请输入商品编码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品编码" prop="code">
|
||||
<el-input v-model="formData.code" clearable placeholder="请输入商品编码" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品分类" prop="code">
|
||||
<div>
|
||||
<el-select v-model="formData.region" placeholder="please select your zone">
|
||||
<el-option label="请选择分类" value="shanghai" />
|
||||
<el-option label="Zone two" value="beijing" />
|
||||
</el-select>
|
||||
<el-form-item label="商品分类" prop="first_category_id" required>
|
||||
<div class="flex w-full">
|
||||
<div class="w-4/12">
|
||||
<el-select v-model="formData.first_category_id" placeholder="请选择分类"
|
||||
@change="selectFirstCategory">
|
||||
<el-option :label="item.name" :value="item.id"
|
||||
v-for="(item, index) in firstCategory" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="w-4/12">
|
||||
<el-select v-model="formData.second_category_id" placeholder="请选择分类"
|
||||
@change="selectSecondCategory">
|
||||
<el-option :label="item.name" :value="item.id"
|
||||
v-for="(item, index) in secondCategory" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="w-4/12">
|
||||
<el-select v-model="formData.third_category_id" placeholder="请选择分类">
|
||||
<el-option :label="item.name" :value="item.id"
|
||||
v-for="(item, index) in thirdCategory" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品卖点" prop="remark">
|
||||
<el-input v-model="formData.remark" clearable placeholder="请输入商品卖点" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品主图" prop="image" required>
|
||||
<material-picker v-model="formData.image" :limit="1" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品轮播图" prop="goods_image" required>
|
||||
<material-picker v-model="formData.goods_image" :limit="8" />
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="价格库存">
|
||||
<el-radio-group v-model="formData.spec_type">
|
||||
<el-radio :value="1">统一规格</el-radio>
|
||||
<el-radio :value="2">多规格</el-radio>
|
||||
</el-radio-group>
|
||||
<!-- 单规格 -->
|
||||
<div v-if="formData.spec_type === 1">
|
||||
<el-table :data="[{}]" style="width: 100%">
|
||||
<el-table-column label="价格(元)" prop="one_price">
|
||||
<template #default="scope">
|
||||
<el-input v-model="formData.one_price" clearable placeholder="请输入价格(元)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成本价(元)" prop="one_cost_price">
|
||||
<template #default="scope">
|
||||
<el-input v-model="formData.one_cost_price" clearable placeholder="请输入成本价(元)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="请输入库存" prop="one_stock">
|
||||
<template #default="scope">
|
||||
<el-input v-model="formData.one_stock" clearable placeholder="请输入库存" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 多规格 -->
|
||||
<div v-if="formData.spec_type === 2">
|
||||
<div v-for="(spec, specIdx) in specs" :key="specIdx" class="mb-2">
|
||||
<el-form-item :label="'规格名'">
|
||||
<el-input v-model="spec.name" placeholder="如口味/尺寸" style="width: 100px;" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="'规格值'" style="flex:1;">
|
||||
<el-input v-model="spec.valuesStr" type="textarea" :rows="2" placeholder="每行一个规格值"
|
||||
@change="onSpecValueChange(specIdx)" />
|
||||
</el-form-item>
|
||||
<div class="flex justify-end">
|
||||
<el-button type="danger" @click="removeSpec(specIdx)">删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-button type="primary" @click="addSpec" :disabled="specs.length >= 3"
|
||||
class="mb-2">添加规格项</el-button>
|
||||
|
||||
<div>
|
||||
<el-select v-model="formData.region" placeholder="please select your zone">
|
||||
<el-option label="Zone one" value="shanghai" />
|
||||
<el-option label="Zone two" value="beijing" />
|
||||
</el-select>
|
||||
<el-table :data="skuTable" style="width: 100%; margin-top: 10px;">
|
||||
<el-table-column v-for="(spec, idx) in specs" :key="idx"
|
||||
:label="spec.name || `规格${idx + 1}`" :prop="'spec' + idx" />
|
||||
<el-table-column label="价格(元)">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.price" placeholder="价格" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成本价(元)">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.cost_price" placeholder="成本价" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.stock" placeholder="库存" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="商品详情">
|
||||
<Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef"
|
||||
:defaultConfig="toolbarConfig" :mode="mode" />
|
||||
<Editor style="height: 500px; overflow-y: hidden;" v-model="formData.content"
|
||||
:defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="销售设置"></el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-form>
|
||||
|
||||
<div>
|
||||
<el-select v-model="formData.region" placeholder="please select your zone">
|
||||
<el-option label="Zone one" value="shanghai" />
|
||||
<el-option label="Zone two" value="beijing" />
|
||||
</el-select>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="价格库存"></el-tab-pane>
|
||||
<el-tab-pane label="商品详情"></el-tab-pane>
|
||||
<el-tab-pane label="销售设置"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<!-- <el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
|
||||
|
||||
|
||||
<el-form-item label="一级分类id" prop="first_category_id">
|
||||
<el-input v-model="formData.first_category_id" clearable placeholder="请输入一级分类id" />
|
||||
</el-form-item>
|
||||
<el-form-item label="二级分类id" prop="second_category_id">
|
||||
<el-input v-model="formData.second_category_id" clearable placeholder="请输入二级分类id" />
|
||||
</el-form-item>
|
||||
<el-form-item label="三级分类id" prop="third_category_id">
|
||||
<el-input v-model="formData.third_category_id" clearable placeholder="请输入三级分类id" />
|
||||
</el-form-item>
|
||||
<el-form-item label="品牌id" prop="brand_id">
|
||||
<el-input v-model="formData.brand_id" clearable placeholder="请输入品牌id" />
|
||||
</el-form-item>
|
||||
<el-form-item label="供应商id" prop="supplier_id">
|
||||
<el-input v-model="formData.supplier_id" clearable placeholder="请输入供应商id" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品状态:-1-回收站;0-下架;1-上架" prop="status">
|
||||
<el-input v-model="formData.status" clearable placeholder="请输入商品状态:-1-回收站;0-下架;1-上架" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品主图" prop="image">
|
||||
<el-input v-model="formData.image" clearable placeholder="请输入商品主图" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品视频" prop="video">
|
||||
<el-input v-model="formData.video" clearable placeholder="请输入商品视频" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品自定义海报" prop="poster">
|
||||
<el-input v-model="formData.poster" clearable placeholder="请输入商品自定义海报" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品简介" prop="remark">
|
||||
<el-input v-model="formData.remark" clearable placeholder="请输入商品简介" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品详细描述" prop="content">
|
||||
<el-input v-model="formData.content" clearable placeholder="请输入商品详细描述" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input v-model="formData.sort" clearable placeholder="请输入排序" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品销量" prop="sales_sum">
|
||||
<el-input v-model="formData.sales_sum" clearable placeholder="请输入商品销量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="虚拟销量" prop="virtual_sales_sum">
|
||||
<el-input v-model="formData.virtual_sales_sum" clearable placeholder="请输入虚拟销量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品点击量" prop="click_count">
|
||||
<el-input v-model="formData.click_count" clearable placeholder="请输入商品点击量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="虚拟点击量" prop="virtual_click">
|
||||
<el-input v-model="formData.virtual_click" clearable placeholder="请输入虚拟点击量" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品规格:1-统一规格;2-多规格;" prop="spec_type">
|
||||
<el-input v-model="formData.spec_type" clearable placeholder="请输入商品规格:1-统一规格;2-多规格;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最高价格" prop="max_price">
|
||||
<el-input v-model="formData.max_price" clearable placeholder="请输入最高价格" />
|
||||
</el-form-item>
|
||||
<el-form-item label="最低价格" prop="min_price">
|
||||
<el-input v-model="formData.min_price" clearable placeholder="请输入最低价格" />
|
||||
</el-form-item>
|
||||
<el-form-item label="市场价(sku中最高的市场价)" prop="market_price">
|
||||
<el-input v-model="formData.market_price" clearable placeholder="请输入市场价(sku中最高的市场价)" />
|
||||
</el-form-item>
|
||||
<el-form-item label="总库存" prop="stock">
|
||||
<el-input v-model="formData.stock" clearable placeholder="请输入总库存" />
|
||||
</el-form-item>
|
||||
<el-form-item label="库存预警" prop="stock_warn">
|
||||
<el-input v-model="formData.stock_warn" clearable placeholder="请输入库存预警" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否显示库存:1-是;0-否" prop="is_show_stock">
|
||||
<el-input v-model="formData.is_show_stock" clearable placeholder="请输入是否显示库存:1-是;0-否" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运费类型:1-包邮;2-统一运费;3-运费模板" prop="free_shipping_type">
|
||||
<el-input v-model="formData.free_shipping_type" clearable
|
||||
placeholder="请输入运费类型:1-包邮;2-统一运费;3-运费模板" />
|
||||
</el-form-item>
|
||||
<el-form-item label="统一运费金额" prop="free_shipping">
|
||||
<el-input v-model="formData.free_shipping" clearable placeholder="请输入统一运费金额" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运费模板" prop="free_shipping_template_id">
|
||||
<el-input v-model="formData.free_shipping_template_id" clearable placeholder="请输入运费模板" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分销佣金:1-开启;0-不开启" prop="is_commission">
|
||||
<el-input v-model="formData.is_commission" clearable placeholder="请输入分销佣金:1-开启;0-不开启" />
|
||||
</el-form-item>
|
||||
<el-form-item label="一级分销比例" prop="first_ratio">
|
||||
<el-input v-model="formData.first_ratio" clearable placeholder="请输入一级分销比例" />
|
||||
</el-form-item>
|
||||
<el-form-item label="二级分销比例" prop="second_ratio">
|
||||
<el-input v-model="formData.second_ratio" clearable placeholder="请输入二级分销比例" />
|
||||
</el-form-item>
|
||||
<el-form-item label="三级分销比例" prop="three_ratio">
|
||||
<el-input v-model="formData.three_ratio" clearable placeholder="请输入三级分销比例" />
|
||||
</el-form-item>
|
||||
<el-form-item label="区域股东分红:1-开启;0-不开启" prop="is_share_bouns">
|
||||
<el-input v-model="formData.is_share_bouns" clearable placeholder="请输入区域股东分红:1-开启;0-不开启" />
|
||||
</el-form-item>
|
||||
<el-form-item label="区域分红比例" prop="region_ratio">
|
||||
<el-input v-model="formData.region_ratio" clearable placeholder="请输入区域分红比例" />
|
||||
</el-form-item>
|
||||
<el-form-item label="股东分红比例" prop="shareholder_ratio">
|
||||
<el-input v-model="formData.shareholder_ratio" clearable placeholder="请输入股东分红比例" />
|
||||
</el-form-item>
|
||||
<el-form-item label="新品推荐:1-是;0-否" prop="is_new">
|
||||
<el-input v-model="formData.is_new" clearable placeholder="请输入新品推荐:1-是;0-否" />
|
||||
</el-form-item>
|
||||
<el-form-item label="好物优选:1-是;0-否" prop="is_best">
|
||||
<el-input v-model="formData.is_best" clearable placeholder="请输入好物优选:1-是;0-否" />
|
||||
</el-form-item>
|
||||
<el-form-item label="猜你喜欢:1-是;0-否" prop="is_like">
|
||||
<el-input v-model="formData.is_like" clearable placeholder="请输入猜你喜欢:1-是;0-否" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否开启拼团[0=否, 1=是]" prop="is_team">
|
||||
<el-input v-model="formData.is_team" clearable placeholder="请输入是否开启拼团[0=否, 1=是]" />
|
||||
</el-form-item>
|
||||
<el-form-item label="积分抵扣:1-开启;0-不开启" prop="is_integral">
|
||||
<el-input v-model="formData.is_integral" clearable placeholder="请输入积分抵扣:1-开启;0-不开启" />
|
||||
</el-form-item>
|
||||
<el-form-item label="会员价:1-开启;0-不开启" prop="is_member">
|
||||
<el-input v-model="formData.is_member" clearable placeholder="请输入会员价:1-开启;0-不开启" />
|
||||
</el-form-item>
|
||||
<el-form-item label="赠送积分类型:0-不赠送;1-赠送固定积分;2-按比例赠送积分" prop="give_integral_type">
|
||||
<el-input v-model="formData.give_integral_type" clearable
|
||||
placeholder="请输入赠送积分类型:0-不赠送;1-赠送固定积分;2-按比例赠送积分" />
|
||||
</el-form-item>
|
||||
<el-form-item label="赠送积分;" prop="give_integral">
|
||||
<el-input v-model="formData.give_integral" clearable placeholder="请输入赠送积分;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否删除:1-是;0-否" prop="del">
|
||||
<el-input v-model="formData.del" clearable placeholder="请输入是否删除:1-是;0-否" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否开启快递配送:1-是;0-否;" prop="is_express">
|
||||
<el-input v-model="formData.is_express" clearable placeholder="请输入是否开启快递配送:1-是;0-否;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否开启上门自提:1-是;0-否;" prop="is_selffetch">
|
||||
<el-input v-model="formData.is_selffetch" clearable placeholder="请输入是否开启上门自提:1-是;0-否;" />
|
||||
</el-form-item>
|
||||
</el-form> -->
|
||||
<!-- <el-dialog v-model="showImagePicker" title="选择图片" width="800px" @close="showImagePicker = false">
|
||||
<material-picker :limit="10" @change="onImageSelected" />
|
||||
</el-dialog> -->
|
||||
<!-- <material-picker ref="materialPickerRef" :limit="10" @change="onImageSelected" style="display: none;" /> -->
|
||||
</popup>
|
||||
</div>
|
||||
</template>
|
||||
@ -188,8 +137,10 @@
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import { apiGoodsAdd, apiGoodsEdit, apiGoodsDetail, checkCategory } from '@/api/goods'
|
||||
import { timeFormat } from '@/utils/util'
|
||||
import type { PropType } from 'vue'
|
||||
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
||||
import '@wangeditor/editor/dist/css/style.css' // 引入 css
|
||||
|
||||
defineProps({
|
||||
dictData: {
|
||||
type: Object as PropType<Record<string, any[]>>,
|
||||
@ -200,13 +151,14 @@ const emit = defineEmits(['success', 'close'])
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
const mode = ref('add')
|
||||
|
||||
const goodsSpec = ref(2)
|
||||
|
||||
// 弹窗标题
|
||||
const popupTitle = computed(() => {
|
||||
return mode.value == 'edit' ? '编辑商品主表' : '新增商品主表'
|
||||
})
|
||||
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
id: '',
|
||||
@ -215,20 +167,28 @@ const formData = reactive({
|
||||
first_category_id: '',
|
||||
second_category_id: '',
|
||||
third_category_id: '',
|
||||
remark: '',
|
||||
image: '',
|
||||
goods_image: '',
|
||||
one_price: '',
|
||||
one_cost_price: '',
|
||||
one_stock: '',
|
||||
spec_name: '',
|
||||
spec_type: 1,
|
||||
content: '',
|
||||
|
||||
brand_id: '',
|
||||
supplier_id: '',
|
||||
status: '',
|
||||
image: '',
|
||||
|
||||
video: '',
|
||||
one_spec_image: '',
|
||||
poster: '',
|
||||
remark: '',
|
||||
content: '',
|
||||
sort: '',
|
||||
sales_sum: '',
|
||||
virtual_sales_sum: '',
|
||||
click_count: '',
|
||||
virtual_click: '',
|
||||
spec_type: '',
|
||||
max_price: '',
|
||||
min_price: '',
|
||||
market_price: '',
|
||||
@ -268,69 +228,59 @@ const formRules = reactive<any>({
|
||||
}],
|
||||
first_category_id: [{
|
||||
required: true,
|
||||
message: '请输入一级分类id',
|
||||
message: '请选择商品分类',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
second_category_id: [{
|
||||
required: true,
|
||||
message: '请输入二级分类id',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
third_category_id: [{
|
||||
required: true,
|
||||
message: '请输入三级分类id',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
status: [{
|
||||
required: true,
|
||||
message: '请输入商品状态:-1-回收站;0-下架;1-上架',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
image: [{
|
||||
required: true,
|
||||
message: '请输入商品主图',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_show_stock: [{
|
||||
required: true,
|
||||
message: '请输入是否显示库存:1-是;0-否',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
free_shipping_type: [{
|
||||
required: true,
|
||||
message: '请输入运费类型:1-包邮;2-统一运费;3-运费模板',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_commission: [{
|
||||
required: true,
|
||||
message: '请输入分销佣金:1-开启;0-不开启',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_share_bouns: [{
|
||||
required: true,
|
||||
message: '请输入区域股东分红:1-开启;0-不开启',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_team: [{
|
||||
required: true,
|
||||
message: '请输入是否开启拼团[0=否, 1=是]',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_integral: [{
|
||||
required: true,
|
||||
message: '请输入积分抵扣:1-开启;0-不开启',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
is_member: [{
|
||||
required: true,
|
||||
message: '请输入会员价:1-开启;0-不开启',
|
||||
trigger: ['blur']
|
||||
}],
|
||||
give_integral_type: [{
|
||||
required: true,
|
||||
message: '请输入赠送积分类型:0-不赠送;1-赠送固定积分;2-按比例赠送积分',
|
||||
trigger: ['blur']
|
||||
}]
|
||||
// status: [{
|
||||
// required: true,
|
||||
// message: '请输入商品状态:-1-回收站;0-下架;1-上架',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// image: [{
|
||||
// required: true,
|
||||
// message: '请输入商品主图',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_show_stock: [{
|
||||
// required: true,
|
||||
// message: '请输入是否显示库存:1-是;0-否',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// free_shipping_type: [{
|
||||
// required: true,
|
||||
// message: '请输入运费类型:1-包邮;2-统一运费;3-运费模板',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_commission: [{
|
||||
// required: true,
|
||||
// message: '请输入分销佣金:1-开启;0-不开启',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_share_bouns: [{
|
||||
// required: true,
|
||||
// message: '请输入区域股东分红:1-开启;0-不开启',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_team: [{
|
||||
// required: true,
|
||||
// message: '请输入是否开启拼团[0=否, 1=是]',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_integral: [{
|
||||
// required: true,
|
||||
// message: '请输入积分抵扣:1-开启;0-不开启',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// is_member: [{
|
||||
// required: true,
|
||||
// message: '请输入会员价:1-开启;0-不开启',
|
||||
// trigger: ['blur']
|
||||
// }],
|
||||
// give_integral_type: [{
|
||||
// required: true,
|
||||
// message: '请输入赠送积分类型:0-不赠送;1-赠送固定积分;2-按比例赠送积分',
|
||||
// trigger: ['blur']
|
||||
// }]
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
@ -353,18 +303,71 @@ const getDetail = async (row: Record<string, any>) => {
|
||||
})
|
||||
setFormData(data)
|
||||
}
|
||||
|
||||
//
|
||||
// 创建分类列表
|
||||
let goodsCategory = reactive<any[]>([])
|
||||
let firstCategory = reactive<any[]>([])
|
||||
let secondCategory = reactive<any[]>([])
|
||||
let thirdCategory = reactive<any[]>([])
|
||||
const category = async () => {
|
||||
const { data, code } = await checkCategory({})
|
||||
console.log("data,code>>>", data, code);
|
||||
return false;
|
||||
const res = await checkCategory()
|
||||
goodsCategory = res
|
||||
firstCategory = res.filter((item: { pid: number }) => {
|
||||
if (item.pid === 0) {
|
||||
return item
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 选择第一个分类组,渲染第二个分组
|
||||
const selectFirstCategory = (id: number) => {
|
||||
secondCategory = goodsCategory.filter((item: { pid: number }) => {
|
||||
if (item.pid === id) {
|
||||
return item
|
||||
}
|
||||
})
|
||||
|
||||
if (secondCategory.length === 0) {
|
||||
formData.second_category_id = ''
|
||||
formData.third_category_id = ''
|
||||
}
|
||||
}
|
||||
// 选择第二个分类组,渲染第三个分组
|
||||
const selectSecondCategory = (id: number) => {
|
||||
thirdCategory = goodsCategory.filter((item: { pid: number }) => {
|
||||
if (item.pid === id) {
|
||||
return item
|
||||
}
|
||||
})
|
||||
|
||||
if (thirdCategory.length === 0) {
|
||||
formData.third_category_id = ''
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 提交按钮
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value?.validate()
|
||||
// await formRef.value?.validate()
|
||||
const data = { ...formData, }
|
||||
data.price = skuTable.value.map(item => item.price)
|
||||
data.cost_price = skuTable.value.map(item => item.cost_price)
|
||||
data.stock = skuTable.value.map(item => item.stock)
|
||||
data.spec_value_str = skuTable.value.map(item => {
|
||||
const arr = []
|
||||
if ('spec0' in item) arr.push(item.spec0)
|
||||
if ('spec1' in item) arr.push(item.spec1)
|
||||
if ('spec2' in item) arr.push(item.spec2)
|
||||
return arr.join(',')
|
||||
})
|
||||
// data.spec_name = specs.value.map(item => item.name);
|
||||
// data.spec_values = specs.value.map(item => item.valuesStr.replace(/\n/g, ','));
|
||||
console.log("data>>>", data);
|
||||
|
||||
|
||||
// console.log("specs>>>", specs);
|
||||
// console.log("specs>>>", skuTable);
|
||||
return false;
|
||||
mode.value == 'edit'
|
||||
? await apiGoodsEdit(data)
|
||||
: await apiGoodsAdd(data)
|
||||
@ -383,11 +386,151 @@ const handleClose = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
// 多规格相关
|
||||
// const specs = ref([
|
||||
// { name: '', valuesStr: '', values: [] }
|
||||
// ])
|
||||
const specs = ref([])
|
||||
const skuTable = ref<any[]>([])
|
||||
|
||||
// 添加规格项(最多3个)
|
||||
const addSpec = () => {
|
||||
if (specs.value.length < 3) {
|
||||
specs.value.push({ name: '', valuesStr: '', values: [] })
|
||||
syncSpecToFormData()
|
||||
}
|
||||
}
|
||||
|
||||
// 删除规格项
|
||||
const removeSpec = (idx: number) => {
|
||||
specs.value.splice(idx, 1)
|
||||
updateSkuTable()
|
||||
syncSpecToFormData()
|
||||
}
|
||||
|
||||
// 规格值变更
|
||||
const onSpecValueChange = (idx: number) => {
|
||||
const spec = specs.value[idx]
|
||||
spec.values = spec.valuesStr
|
||||
.split('\n')
|
||||
.map(v => v.trim())
|
||||
.filter(v => v)
|
||||
updateSkuTable()
|
||||
syncSpecToFormData()
|
||||
}
|
||||
|
||||
// 计算所有规格组合(笛卡尔积)
|
||||
function cartesianProduct(arr: any[][]) {
|
||||
if (arr.length === 0) return []
|
||||
return arr.reduce((a, b) =>
|
||||
a.flatMap(d => b.map(e => [].concat(d, e)))
|
||||
)
|
||||
}
|
||||
|
||||
// 同步规格数据到formData
|
||||
const syncSpecToFormData = () => {
|
||||
formData.spec_name = specs.value.map(item => item.name)
|
||||
formData.spec_values = specs.value.map(item => item.valuesStr.replace(/\n/g, ','))
|
||||
}
|
||||
|
||||
|
||||
// 更新SKU表格
|
||||
const updateSkuTable = () => {
|
||||
const valueArr = specs.value.map(s => s.values)
|
||||
if (valueArr.some(arr => arr.length === 0)) {
|
||||
skuTable.value = []
|
||||
return
|
||||
}
|
||||
let result: any[] = []
|
||||
if (valueArr.length === 1) {
|
||||
result = valueArr[0].map(v1 => ({
|
||||
spec0: v1,
|
||||
price: '',
|
||||
cost_price: '',
|
||||
stock: ''
|
||||
}))
|
||||
} else if (valueArr.length === 2) {
|
||||
result = cartesianProduct(valueArr).map(([v1, v2]) => ({
|
||||
spec0: v1,
|
||||
spec1: v2,
|
||||
price: '',
|
||||
cost_price: '',
|
||||
stock: ''
|
||||
}))
|
||||
} else if (valueArr.length === 3) {
|
||||
result = cartesianProduct(valueArr).map(([v1, v2, v3]) => ({
|
||||
spec0: v1,
|
||||
spec1: v2,
|
||||
spec2: v3,
|
||||
price: '',
|
||||
cost_price: '',
|
||||
stock: ''
|
||||
}))
|
||||
}
|
||||
skuTable.value = result
|
||||
}
|
||||
|
||||
// 编辑器
|
||||
// 编辑器实例,必须用 shallowRef
|
||||
const editorRef = shallowRef()
|
||||
const toolbarConfig = {}
|
||||
const materialPickerRef = ref()
|
||||
|
||||
const showImagePicker = ref(false)
|
||||
let imageInsertFn: ((url: string) => void) | null = null
|
||||
|
||||
const editorConfig = {
|
||||
placeholder: '请输入内容...',
|
||||
MENU_CONF: {
|
||||
uploadImage: {
|
||||
// 自定义上传图片
|
||||
customBrowseAndUpload(insertFn: (url: string, alt: string, href: string) => void) {
|
||||
showImagePicker.value = true
|
||||
imageInsertFn = (url: string) => {
|
||||
insertFn(url, '', '')
|
||||
// 直接调用 material-picker 的打开方法
|
||||
materialPickerRef.value?.open(-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 图片选择后回调
|
||||
function onImageSelected(val: string | string[]) {
|
||||
const urls = Array.isArray(val) ? val : [val]
|
||||
if (imageInsertFn && urls.length) {
|
||||
urls.forEach(url => {
|
||||
imageInsertFn!(url)
|
||||
})
|
||||
imageInsertFn = null
|
||||
}
|
||||
showImagePicker.value = false
|
||||
}
|
||||
|
||||
// 组件销毁时,也及时销毁编辑器
|
||||
onBeforeUnmount(() => {
|
||||
const editor = editorRef.value
|
||||
if (editor == null) return
|
||||
editor.destroy()
|
||||
})
|
||||
|
||||
const handleCreated = (editor) => {
|
||||
editorRef.value = editor // 记录 editor 实例,重要!
|
||||
}
|
||||
|
||||
// 监听规格变化自动生成表格
|
||||
watch(specs, updateSkuTable, { deep: true })
|
||||
defineExpose({
|
||||
open,
|
||||
setFormData,
|
||||
getDetail
|
||||
getDetail,
|
||||
selectFirstCategory,
|
||||
selectSecondCategory,
|
||||
editorRef,
|
||||
mode: 'default', // 或 'simple'
|
||||
toolbarConfig,
|
||||
editorConfig,
|
||||
handleCreated,
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -1,18 +1,12 @@
|
||||
<template>
|
||||
<div class="edit-popup">
|
||||
<popup
|
||||
ref="popupRef"
|
||||
:title="popupTitle"
|
||||
:async="true"
|
||||
width="550px"
|
||||
@confirm="handleSubmit"
|
||||
@close="handleClose"
|
||||
>
|
||||
<popup ref="popupRef" :title="popupTitle" :async="true" width="550px" @confirm="handleSubmit"
|
||||
@close="handleClose">
|
||||
<el-form ref="formRef" :model="formData" label-width="90px" :rules="formRules">
|
||||
<el-form-item label="分类名称" prop="name">
|
||||
<el-input v-model="formData.name" clearable placeholder="请输入分类名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="父级id" prop="pid">
|
||||
<el-form-item label="父级分类" prop="pid">
|
||||
<el-input v-model="formData.pid" clearable placeholder="请输入父级id" />
|
||||
</el-form-item>
|
||||
<el-form-item label="等级" prop="level">
|
||||
@ -102,8 +96,8 @@ const setFormData = async (data: Record<any, any>) => {
|
||||
formData[key] = data[key]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
const getDetail = async (row: Record<string, any>) => {
|
||||
@ -117,9 +111,9 @@ const getDetail = async (row: Record<string, any>) => {
|
||||
// 提交按钮
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value?.validate()
|
||||
const data = { ...formData, }
|
||||
mode.value == 'edit'
|
||||
? await apiGoodsCategoryEdit(data)
|
||||
const data = { ...formData, }
|
||||
mode.value == 'edit'
|
||||
? await apiGoodsCategoryEdit(data)
|
||||
: await apiGoodsCategoryAdd(data)
|
||||
popupRef.value?.close()
|
||||
emit('success')
|
||||
|
||||
@ -1,38 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-card class="!border-none mb-4" shadow="never">
|
||||
<el-form
|
||||
class="mb-[-16px]"
|
||||
:model="queryParams"
|
||||
inline
|
||||
>
|
||||
<el-form class="mb-[-16px]" :model="queryParams" inline>
|
||||
<el-form-item label="分类名称" prop="name">
|
||||
<el-input class="w-[280px]" v-model="queryParams.name" clearable placeholder="请输入分类名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="父级id" prop="pid">
|
||||
<el-input class="w-[280px]" v-model="queryParams.pid" clearable placeholder="请输入父级id" />
|
||||
</el-form-item>
|
||||
<el-form-item label="等级" prop="level">
|
||||
<el-input class="w-[280px]" v-model="queryParams.level" clearable placeholder="请输入等级" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input class="w-[280px]" v-model="queryParams.sort" clearable placeholder="请输入排序" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否显示:1-是;0-否" prop="is_show">
|
||||
<el-input class="w-[280px]" v-model="queryParams.is_show" clearable placeholder="请输入是否显示:1-是;0-否" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否首页推荐:1-是;0-否" prop="is_recommend">
|
||||
<el-input class="w-[280px]" v-model="queryParams.is_recommend" clearable placeholder="请输入是否首页推荐:1-是;0-否" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分类图片" prop="image">
|
||||
<el-input class="w-[280px]" v-model="queryParams.image" clearable placeholder="请输入分类图片" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分类描述" prop="remark">
|
||||
<el-input class="w-[280px]" v-model="queryParams.remark" clearable placeholder="请输入分类描述" />
|
||||
</el-form-item>
|
||||
<el-form-item label="删除标志:1-是;0-否" prop="del">
|
||||
<el-input class="w-[280px]" v-model="queryParams.del" clearable placeholder="请输入删除标志:1-是;0-否" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||
<el-button @click="resetParams">重置</el-button>
|
||||
@ -46,15 +18,12 @@
|
||||
</template>
|
||||
新增
|
||||
</el-button>
|
||||
<el-button
|
||||
v-perms="['goods_category/delete']"
|
||||
:disabled="!selectData.length"
|
||||
@click="handleDelete(selectData)"
|
||||
>
|
||||
<el-button v-perms="['goods_category/delete']" :disabled="!selectData.length"
|
||||
@click="handleDelete(selectData)">
|
||||
删除
|
||||
</el-button>
|
||||
<div class="mt-4">
|
||||
<el-table :data="pager.lists" @selection-change="handleSelectionChange">
|
||||
<!-- <el-table :data="pager.lists" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="分类名称" prop="name" show-overflow-tooltip />
|
||||
<el-table-column label="父级id" prop="pid" show-overflow-tooltip />
|
||||
@ -85,7 +54,28 @@
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table> -->
|
||||
<el-table :data="pager.lists" row-key="id" border default-expand-all>
|
||||
<el-table-column prop="name" label="分类名称" />
|
||||
<el-table-column prop="id" label="分类图片">
|
||||
<template #default="{ row }">
|
||||
<el-image style="width: 100px; height: 100px" :src="row.image" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sort" label="排序" />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button v-perms="['goods_category/edit']" type="primary" link @click="handleEdit(row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button v-perms="['goods_category/delete']" type="danger" link
|
||||
@click="handleDelete(row.id)">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
</div>
|
||||
<div class="flex mt-4 justify-end">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
@ -111,14 +101,6 @@ const showEdit = ref(false)
|
||||
// 查询条件
|
||||
const queryParams = reactive({
|
||||
name: '',
|
||||
pid: '',
|
||||
level: '',
|
||||
sort: '',
|
||||
is_show: '',
|
||||
is_recommend: '',
|
||||
image: '',
|
||||
remark: '',
|
||||
del: ''
|
||||
})
|
||||
|
||||
// 选中数据
|
||||
@ -138,6 +120,7 @@ const { pager, getLists, resetParams, resetPage } = usePaging({
|
||||
params: queryParams
|
||||
})
|
||||
|
||||
|
||||
// 添加
|
||||
const handleAdd = async () => {
|
||||
showEdit.value = true
|
||||
@ -162,4 +145,3 @@ const handleDelete = async (id: number | any[]) => {
|
||||
|
||||
getLists()
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user