refactor(shop): 更新商品管理模块的数据类型和界面显示
- 将商品模型中的 isShow 字段从 number 类型改为 boolean 类型 - 在导航组件中同时显示模型名称和编号信息 - 将商品状态标签从"出售中"改为"已上架"以保持一致性 - 移除经销商提现表单中的微信账户输入字段并更新描述信息 - 调整商品编辑页面的表单项顺序和布局结构 - 新增商品详情编辑功能,支持富文本和 Markdown 编辑器 - 添加商品排序号字段和分销设置相关功能 - 优化佣金百分比计算逻辑,统一数值转换处理 - 修复分佣金额验证规则,将最大值从 1 调整为 100
This commit is contained in:
@@ -149,7 +149,8 @@
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="column.key === 'model'">
|
||||
<text class="ele-text-placeholder">{{ record.model }}</text>
|
||||
|
||||
<text class="ele-text-placeholder"><span>{{ record.modelName }}({{ record.model }})</span></text>
|
||||
</template>
|
||||
<template v-if="column.key === 'type'">
|
||||
<a-tag v-if="isExternalLink(record.path)" color="purple"
|
||||
|
||||
@@ -38,23 +38,23 @@
|
||||
<div v-if="form.payType === 10" class="payment-info wechat-info">
|
||||
<a-alert
|
||||
message="微信收款信息"
|
||||
description="请确保微信账号信息准确,以免影响到账"
|
||||
description="选择审核通过/已打款,立即向用户发起转账"
|
||||
type="success"
|
||||
show-icon
|
||||
style="margin-bottom: 16px"
|
||||
/>
|
||||
<a-form-item label="微信号" name="wechatAccount">
|
||||
<a-input
|
||||
placeholder="请输入微信号"
|
||||
v-model:value="form.wechatAccount"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="微信昵称" name="wechatName">
|
||||
<a-input
|
||||
placeholder="请输入微信昵称"
|
||||
v-model:value="form.wechatName"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="微信号" name="wechatAccount">-->
|
||||
<!-- <a-input-->
|
||||
<!-- placeholder="请输入微信号"-->
|
||||
<!-- v-model:value="form.wechatAccount"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- <a-form-item label="微信昵称" name="wechatName">-->
|
||||
<!-- <a-input-->
|
||||
<!-- placeholder="请输入微信昵称"-->
|
||||
<!-- v-model:value="form.wechatName"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
</div>
|
||||
|
||||
<!-- 支付宝收款信息 -->
|
||||
@@ -171,7 +171,7 @@
|
||||
<a-form-item
|
||||
label="上传支付凭证"
|
||||
name="image"
|
||||
v-if="form.applyStatus === 40"
|
||||
v-if="form.applyStatus === 40 && form.payType !== 10"
|
||||
>
|
||||
<SelectFile
|
||||
:placeholder="`请选择图片`"
|
||||
|
||||
@@ -24,17 +24,9 @@
|
||||
>
|
||||
<a-tabs type="card" v-model:active-key="active" @change="onChange">
|
||||
<a-tab-pane tab="基本信息" key="base">
|
||||
<a-form-item label="商品ID" name="goodsId">
|
||||
{{ form.goodsId }}
|
||||
</a-form-item>
|
||||
<a-form-item label="商品名称" name="name">
|
||||
<a-input
|
||||
allow-clear
|
||||
style="width: 558px"
|
||||
placeholder="请输入商品名称"
|
||||
v-model:value="form.name"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="商品ID" name="goodsId">-->
|
||||
<!-- {{ form.goodsId }}-->
|
||||
<!-- </a-form-item>-->
|
||||
<a-form-item label="所属栏目" name="categoryId">
|
||||
<a-tree-select
|
||||
allow-clear
|
||||
@@ -49,6 +41,14 @@
|
||||
@change="onCategoryId"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="商品名称" name="name">
|
||||
<a-input
|
||||
allow-clear
|
||||
style="width: 558px"
|
||||
placeholder="请输入商品名称"
|
||||
v-model:value="form.name"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="商品卖点" name="comments">
|
||||
<a-textarea
|
||||
:rows="1"
|
||||
@@ -177,13 +177,64 @@
|
||||
</a-button>
|
||||
</a-upload>
|
||||
</a-form-item>
|
||||
<a-form-item label="状态" name="isShow">
|
||||
<a-radio-group v-model:value="form.isShow">
|
||||
<a-radio :value="1">上架</a-radio>
|
||||
<a-radio :value="0">下架</a-radio>
|
||||
<a-form-item label="状态" name="status">
|
||||
<a-radio-group v-model:value="form.status">
|
||||
<a-radio :value="0">上架</a-radio>
|
||||
<a-radio :value="1">下架</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="商品详情" key="content">
|
||||
<!-- 富文本编辑器 -->
|
||||
<div v-if="editor == 1">
|
||||
<tinymce-editor
|
||||
ref="editorRef"
|
||||
class="editor-content"
|
||||
v-model:value="content"
|
||||
:disabled="disabled"
|
||||
:init="config"
|
||||
placeholder="支持直接粘贴或拖拽图片,也可点击工具栏图片按钮从文件库选择"
|
||||
/>
|
||||
<div class="file-selector-tip">
|
||||
💡 提示:工具栏"图片"按钮从图片库选择,"上传"按钮快速上传图片;"视频"按钮从视频库选择,"上传视频"按钮快速上传视频;"一键排版"按钮自动优化文章格式;"首行缩进"按钮切换段落缩进
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Markdown编辑器 -->
|
||||
<div v-if="editor == 2">
|
||||
<!-- 📝 Markdown编辑器工具栏扩展 -->
|
||||
<div class="markdown-toolbar-extension">
|
||||
<a-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="openMarkdownImageSelector"
|
||||
style="margin-right: 8px;"
|
||||
>
|
||||
📷 从图片库选择
|
||||
</a-button>
|
||||
<a-button
|
||||
type="default"
|
||||
size="small"
|
||||
@click="openMarkdownVideoSelector"
|
||||
style="margin-right: 8px;"
|
||||
>
|
||||
🎬 从视频库选择
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
<MdEditor
|
||||
v-model="content"
|
||||
:disabled="disabled"
|
||||
height="500px"
|
||||
:placeholder="'请输入Markdown内容...'"
|
||||
:toolbars="markdownToolbars"
|
||||
:onUploadImg="onMarkdownUploadImg"
|
||||
/>
|
||||
<div class="file-selector-tip">
|
||||
💡 提示:支持Markdown语法,可以使用工具栏按钮从文件库选择图片/视频,也可以直接拖拽上传文件
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="商品规格" key="spec">
|
||||
<a-form-item label="规格类型" name="specs">
|
||||
<a-radio-group v-model:value="form.specs">
|
||||
@@ -326,57 +377,6 @@
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="商品详情" key="content">
|
||||
<!-- 富文本编辑器 -->
|
||||
<div v-if="editor == 1">
|
||||
<tinymce-editor
|
||||
ref="editorRef"
|
||||
class="editor-content"
|
||||
v-model:value="content"
|
||||
:disabled="disabled"
|
||||
:init="config"
|
||||
placeholder="支持直接粘贴或拖拽图片,也可点击工具栏图片按钮从文件库选择"
|
||||
/>
|
||||
<div class="file-selector-tip">
|
||||
💡 提示:工具栏"图片"按钮从图片库选择,"上传"按钮快速上传图片;"视频"按钮从视频库选择,"上传视频"按钮快速上传视频;"一键排版"按钮自动优化文章格式;"首行缩进"按钮切换段落缩进
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Markdown编辑器 -->
|
||||
<div v-if="editor == 2">
|
||||
<!-- 📝 Markdown编辑器工具栏扩展 -->
|
||||
<div class="markdown-toolbar-extension">
|
||||
<a-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="openMarkdownImageSelector"
|
||||
style="margin-right: 8px;"
|
||||
>
|
||||
📷 从图片库选择
|
||||
</a-button>
|
||||
<a-button
|
||||
type="default"
|
||||
size="small"
|
||||
@click="openMarkdownVideoSelector"
|
||||
style="margin-right: 8px;"
|
||||
>
|
||||
🎬 从视频库选择
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
<MdEditor
|
||||
v-model="content"
|
||||
:disabled="disabled"
|
||||
height="500px"
|
||||
:placeholder="'请输入Markdown内容...'"
|
||||
:toolbars="markdownToolbars"
|
||||
:onUploadImg="onMarkdownUploadImg"
|
||||
/>
|
||||
<div class="file-selector-tip">
|
||||
💡 提示:支持Markdown语法,可以使用工具栏按钮从文件库选择图片/视频,也可以直接拖拽上传文件
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="营销设置" key="coupon">
|
||||
<a-form-item label="商品重量" name="goodsWeight">
|
||||
<a-input
|
||||
@@ -423,6 +423,15 @@
|
||||
v-model:value="form.position"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="排序号" name="sortNumber">
|
||||
<a-input-number
|
||||
:min="0"
|
||||
:max="9999"
|
||||
style="width: 250px"
|
||||
placeholder="请输入排序号"
|
||||
v-model:value="form.sortNumber"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="是否可以快递配送">
|
||||
<a-switch
|
||||
size="small"
|
||||
@@ -439,26 +448,26 @@
|
||||
:un-checked-value="0"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="是否开启分红功能" v-if="!merchantId">
|
||||
<a-switch
|
||||
size="small"
|
||||
v-model:checked="form.commissionRole"
|
||||
:checked-value="1"
|
||||
:un-checked-value="0"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="角色分红配置" v-if="form.commissionRole === 1">
|
||||
<a-space>
|
||||
<a-input
|
||||
v-model:value="form.goodsRoleCommission[index].amount"
|
||||
v-for="(item, index) in form.goodsRoleCommission"
|
||||
:key="index"
|
||||
>
|
||||
<template #addonBefore>{{ item.roleName }}</template>
|
||||
<template #addonAfter>元</template>
|
||||
</a-input>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="是否开启分红功能" v-if="!merchantId">-->
|
||||
<!-- <a-switch-->
|
||||
<!-- size="small"-->
|
||||
<!-- v-model:checked="form.commissionRole"-->
|
||||
<!-- :checked-value="1"-->
|
||||
<!-- :un-checked-value="0"-->
|
||||
<!-- />-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- <a-form-item label="角色分红配置" v-if="form.commissionRole === 1">-->
|
||||
<!-- <a-space>-->
|
||||
<!-- <a-input-->
|
||||
<!-- v-model:value="form.goodsRoleCommission[index].amount"-->
|
||||
<!-- v-for="(item, index) in form.goodsRoleCommission"-->
|
||||
<!-- :key="index"-->
|
||||
<!-- >-->
|
||||
<!-- <template #addonBefore>{{ item.roleName }}</template>-->
|
||||
<!-- <template #addonAfter>元</template>-->
|
||||
<!-- </a-input>-->
|
||||
<!-- </a-space>-->
|
||||
<!-- </a-form-item>-->
|
||||
|
||||
<a-divider orientation="left">分销设置</a-divider>
|
||||
<a-form-item label="是否开启分销" name="isOpenCommission">
|
||||
@@ -473,7 +482,7 @@
|
||||
<a-form-item label="分佣类型" name="commissionType">
|
||||
<a-radio-group v-model:value="form.commissionType">
|
||||
<a-radio :value="10">固定金额</a-radio>
|
||||
<a-radio :value="20">百分比(0.1代表10%)</a-radio>
|
||||
<a-radio :value="20">百分比</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
@@ -483,7 +492,7 @@
|
||||
<a-input-number
|
||||
v-model:value="form.firstMoney"
|
||||
:min="0"
|
||||
:max="form.commissionType === 20 ? 1 : undefined"
|
||||
:max="form.commissionType === 20 ? 100 : undefined"
|
||||
:precision="2"
|
||||
style="width: 250px"
|
||||
:placeholder="
|
||||
@@ -493,8 +502,9 @@
|
||||
"
|
||||
>
|
||||
<template #addonAfter>{{
|
||||
form.commissionType === 20 ? '%' : '元'
|
||||
}}</template>
|
||||
form.commissionType === 20 ? '%' : '元'
|
||||
}}
|
||||
</template>
|
||||
</a-input-number>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
@@ -504,7 +514,7 @@
|
||||
<a-input-number
|
||||
v-model:value="form.secondMoney"
|
||||
:min="0"
|
||||
:max="form.commissionType === 20 ? 1 : undefined"
|
||||
:max="form.commissionType === 20 ? 100 : undefined"
|
||||
:precision="2"
|
||||
style="width: 250px"
|
||||
:placeholder="
|
||||
@@ -514,57 +524,60 @@
|
||||
"
|
||||
>
|
||||
<template #addonAfter>{{
|
||||
form.commissionType === 20 ? '%' : '元'
|
||||
}}</template>
|
||||
form.commissionType === 20 ? '%' : '元'
|
||||
}}
|
||||
</template>
|
||||
</a-input-number>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item-->
|
||||
<!-- :label="form.commissionType === 20 ? '三级佣金(%)' : '三级佣金(元)'"-->
|
||||
<!-- name="thirdMoney"-->
|
||||
<!-- >-->
|
||||
<!-- <a-input-number-->
|
||||
<!-- v-model:value="form.thirdMoney"-->
|
||||
<!-- :min="0"-->
|
||||
<!-- :max="form.commissionType === 20 ? 100 : undefined"-->
|
||||
<!-- :precision="2"-->
|
||||
<!-- style="width: 250px"-->
|
||||
<!-- :placeholder="-->
|
||||
<!-- form.commissionType === 20-->
|
||||
<!-- ? '请输入三级佣金百分比'-->
|
||||
<!-- : '请输入三级佣金金额'-->
|
||||
<!-- "-->
|
||||
<!-- >-->
|
||||
<!-- <template #addonAfter>{{-->
|
||||
<!-- form.commissionType === 20 ? '%' : '元'-->
|
||||
<!-- }}</template>-->
|
||||
<!-- </a-input-number>-->
|
||||
<!-- </a-form-item>-->
|
||||
<!-- <a-form-item-->
|
||||
<!-- :label="form.commissionType === 20 ? '三级佣金(%)' : '三级佣金(元)'"-->
|
||||
<!-- name="thirdMoney"-->
|
||||
<!-- >-->
|
||||
<!-- <a-input-number-->
|
||||
<!-- v-model:value="form.thirdMoney"-->
|
||||
<!-- :min="0"-->
|
||||
<!-- :max="form.commissionType === 20 ? 100 : undefined"-->
|
||||
<!-- :precision="2"-->
|
||||
<!-- style="width: 250px"-->
|
||||
<!-- :placeholder="-->
|
||||
<!-- form.commissionType === 20-->
|
||||
<!-- ? '请输入三级佣金百分比'-->
|
||||
<!-- : '请输入三级佣金金额'-->
|
||||
<!-- "-->
|
||||
<!-- >-->
|
||||
<!-- <template #addonAfter>{{-->
|
||||
<!-- form.commissionType === 20 ? '%' : '元'-->
|
||||
<!-- }}</template>-->
|
||||
<!-- </a-input-number>-->
|
||||
<!-- </a-form-item>-->
|
||||
<a-form-item label="一级分红" name="firstDividend">
|
||||
<a-input-number
|
||||
v-model:value="form.firstDividend"
|
||||
:min="0"
|
||||
:max="form.commissionType === 20 ? 1 : undefined"
|
||||
:max="form.commissionType === 20 ? 100 : undefined"
|
||||
:precision="2"
|
||||
style="width: 250px"
|
||||
placeholder="请输入一级分红"
|
||||
>
|
||||
<template #addonAfter>{{
|
||||
form.commissionType === 20 ? '%' : '元'
|
||||
}}</template>
|
||||
}}
|
||||
</template>
|
||||
</a-input-number>
|
||||
</a-form-item>
|
||||
<a-form-item label="二级分红" name="secondDividend">
|
||||
<a-input-number
|
||||
v-model:value="form.secondDividend"
|
||||
:min="0"
|
||||
:max="form.commissionType === 20 ? 1 : undefined"
|
||||
:max="form.commissionType === 20 ? 100 : undefined"
|
||||
:precision="2"
|
||||
style="width: 250px"
|
||||
placeholder="请输入二级分红"
|
||||
>
|
||||
<template #addonAfter>{{
|
||||
form.commissionType === 20 ? '%' : '元'
|
||||
}}</template>
|
||||
}}
|
||||
</template>
|
||||
</a-input-number>
|
||||
</a-form-item>
|
||||
</template>
|
||||
@@ -614,15 +627,6 @@
|
||||
/>
|
||||
</a-form-item>
|
||||
</template>
|
||||
<a-form-item label="排序号" name="sortNumber">
|
||||
<a-input-number
|
||||
:min="0"
|
||||
:max="9999"
|
||||
style="width: 250px"
|
||||
placeholder="请输入排序号"
|
||||
v-model:value="form.sortNumber"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-form>
|
||||
@@ -1827,6 +1831,33 @@ const onPaste = (e) => {
|
||||
|
||||
const {resetFields} = useForm(form, rules);
|
||||
|
||||
const COMMISSION_PERCENT_FIELDS = [
|
||||
'firstMoney',
|
||||
'secondMoney',
|
||||
'thirdMoney',
|
||||
'firstDividend',
|
||||
'secondDividend'
|
||||
] as const;
|
||||
|
||||
type CommissionPercentField = (typeof COMMISSION_PERCENT_FIELDS)[number];
|
||||
|
||||
const toDbPercent = (val: unknown) => {
|
||||
if (val === null || val === undefined) return val as any;
|
||||
const num = Number(val);
|
||||
if (!Number.isFinite(num)) return val as any;
|
||||
return num / 100;
|
||||
};
|
||||
|
||||
// Back-end stores percent as a fraction (e.g. 0.1 = 10%); UI inputs percent (e.g. 10 = 10%).
|
||||
const toUiPercent = (val: unknown) => {
|
||||
if (val === null || val === undefined) return val as any;
|
||||
const num = Number(val);
|
||||
if (!Number.isFinite(num)) return val as any;
|
||||
// If historical data is already stored as 0~1, convert to 0~100 for display.
|
||||
if (num <= 1) return Number((num * 100).toFixed(2));
|
||||
return num;
|
||||
};
|
||||
|
||||
/* 保存编辑 */
|
||||
const save = () => {
|
||||
if (!formRef.value) {
|
||||
@@ -1851,14 +1882,11 @@ const save = () => {
|
||||
form.secondDividend = 0;
|
||||
}
|
||||
if (form.isOpenCommission === 1 && form.commissionType === 20) {
|
||||
// 百分比:约定 0-100(后端如用万分比/小数可再调整)
|
||||
const invalidPercent =
|
||||
(form.firstMoney ?? 0) > 100 ||
|
||||
(form.secondMoney ?? 0) > 100 ||
|
||||
(form.thirdMoney ?? 0) > 100 ||
|
||||
(form.firstMoney ?? 0) < 0 ||
|
||||
(form.secondMoney ?? 0) < 0 ||
|
||||
(form.thirdMoney ?? 0) < 0;
|
||||
// UI 输入:0~100;保存到后端:0~1(例如 10% => 0.1)
|
||||
const invalidPercent = COMMISSION_PERCENT_FIELDS.some((k) => {
|
||||
const v = (form as any)[k] ?? 0;
|
||||
return v < 0 || v > 100;
|
||||
});
|
||||
if (invalidPercent) {
|
||||
return message.error('佣金百分比需在 0~100 之间');
|
||||
}
|
||||
@@ -1890,6 +1918,14 @@ const save = () => {
|
||||
if (isUpdate.value) {
|
||||
formData.type = props.data.type;
|
||||
}
|
||||
if (formData.isOpenCommission === 1 && formData.commissionType === 20) {
|
||||
// Convert percent fields for persistence: 10 => 0.1
|
||||
COMMISSION_PERCENT_FIELDS.forEach((k) => {
|
||||
(formData as any)[k as CommissionPercentField] = toDbPercent(
|
||||
(formData as any)[k]
|
||||
);
|
||||
});
|
||||
}
|
||||
const saveOrUpdate = isUpdate.value ? updateShopGoods : addShopGoods;
|
||||
saveOrUpdate(formData)
|
||||
.then((msg) => {
|
||||
@@ -2018,6 +2054,14 @@ watch(
|
||||
if (form.commissionType === undefined || form.commissionType === null) {
|
||||
form.commissionType = 10;
|
||||
}
|
||||
if (form.isOpenCommission === 1 && form.commissionType === 20) {
|
||||
// Convert historical DB values (0~1) to UI percent (0~100).
|
||||
COMMISSION_PERCENT_FIELDS.forEach((k) => {
|
||||
(form as any)[k as CommissionPercentField] = toUiPercent(
|
||||
(form as any)[k]
|
||||
);
|
||||
});
|
||||
}
|
||||
if (props.data.image) {
|
||||
images.value.push({
|
||||
uid: uuid(),
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
</a-space>
|
||||
</template>
|
||||
<template v-if="column.key === 'status'">
|
||||
<a-tag v-if="record.status === 0" color="green">出售中</a-tag>
|
||||
<a-tag v-if="record.status === 0" color="green">已上架</a-tag>
|
||||
<a-tag v-if="record.status === 1" color="orange">待上架</a-tag>
|
||||
<a-tag v-if="record.status === 2" color="purple">待审核</a-tag>
|
||||
<a-tag v-if="record.status === 3" color="red">审核不通过</a-tag>
|
||||
|
||||
Reference in New Issue
Block a user