mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-13 04:18:55 +08:00
refactor: 四端完成 Options API → script setup + vuex → pinia 迁移
- buyer(95) / seller(169) / im(53) / manager(280) 共 597 个组件全部从 Options API 转换为 <script setup> - 四端 vuex 全部移除,状态管理统一迁移至 pinia 4(stores/ 目录) - util.js 等基础设施去除 vm 首参依赖;全局属性($Message/$filters 等)在 script 内改为具名导入 - 被外部 ref 访问的公共组件均已补齐 defineExpose(清单见各端 MIGRATION-VUE3.md) - 各端 eslint 启用 vue/component-api-style 防止新代码回退 Options API - 四端 yarn build 全部通过;迁移约定与注意事项已更新至各端 MIGRATION-VUE3.md
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<div class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
ref="searchFormRef"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
@@ -216,7 +216,7 @@
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="modalVisible" title="下架操作" width="500px" :close-on-click-modal="false">
|
||||
<el-form ref="underForm" :model="underForm" label-width="100px">
|
||||
<el-form ref="underFormRef" :model="underForm" label-width="100px">
|
||||
<el-form-item label="下架原因" prop="reason">
|
||||
<el-input v-model="underForm.reason" clearable />
|
||||
</el-form-item>
|
||||
@@ -255,7 +255,7 @@
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form ref="batchAuditForm" :model="batchAuditForm" label-width="100px">
|
||||
<el-form ref="batchAuditFormRef" :model="batchAuditForm" label-width="100px">
|
||||
<el-form-item label="审核结果" prop="auth_flag">
|
||||
<el-radio-group v-model="batchAuditForm.auth_flag">
|
||||
<el-radio :value="1">审核通过</el-radio>
|
||||
@@ -278,7 +278,7 @@
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="goodsGroupFlag" title="批量设置商品分组" width="420px">
|
||||
<el-form ref="goodsGroupForm" :model="goodsGroupForm" :rules="goodsGroupRule" label-width="90px">
|
||||
<el-form ref="goodsGroupFormRef" :model="goodsGroupForm" :rules="goodsGroupRule" label-width="90px">
|
||||
<el-form-item label="商品分组" prop="groupId">
|
||||
<el-select v-model="goodsGroupForm.groupId" clearable filterable style="width: 240px">
|
||||
<el-option
|
||||
@@ -298,7 +298,8 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { computed, nextTick, onMounted, reactive, ref } from "vue";
|
||||
import {
|
||||
getGoodsListData,
|
||||
getGoodsNumerData,
|
||||
@@ -310,421 +311,423 @@ import {
|
||||
} from "@/api/goods";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { unitPrice, customRouterPush } from "@/utils/filters";
|
||||
export default {
|
||||
name: "goods",
|
||||
data() {
|
||||
return {
|
||||
id: "", //要操作的id
|
||||
loading: true, // 表单加载状态
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "create_time", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
groupId: "",
|
||||
},
|
||||
underForm: {
|
||||
// 下架原因
|
||||
reason: "",
|
||||
},
|
||||
goodsAuditForm: {
|
||||
// 商品审核表单
|
||||
auth_flag: 1,
|
||||
},
|
||||
auditModalVisible: false, // 审核弹框显示状态
|
||||
auditSubmitLoading: false,
|
||||
currentAuditGoods: null, // 当前审核的商品
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
currentStatus: "ALL",
|
||||
goodsNumerData: {},
|
||||
selectedRows: [], // 选中的行数据
|
||||
selectAll: false, // 全选状态
|
||||
batchAuditModalVisible: false, // 批量审核弹框显示状态
|
||||
batchAuditSubmitLoading: false,
|
||||
batchAuditForm: {
|
||||
auth_flag: 1,
|
||||
reason: ''
|
||||
},
|
||||
goodsGroupFlag: false,
|
||||
goodsGroupLoading: false,
|
||||
goodsGroupList: [],
|
||||
goodsGroupForm: {
|
||||
groupId: ""
|
||||
},
|
||||
goodsGroupRule: {
|
||||
groupId: [{ required: true, message: "请选择商品分组", trigger: "change" }]
|
||||
}
|
||||
|
||||
defineOptions({ name: "goods" });
|
||||
|
||||
// 模板 ref(searchFormRef/underFormRef/batchAuditFormRef/goodsGroupFormRef 因与 data 同名改为 xxxRef)
|
||||
const searchFormRef = ref(null);
|
||||
const table = ref(null);
|
||||
const underFormRef = ref(null);
|
||||
const auditForm = ref(null);
|
||||
const batchAuditFormRef = ref(null);
|
||||
const goodsGroupFormRef = ref(null);
|
||||
|
||||
const id = ref(""); //要操作的id
|
||||
const loading = ref(true); // 表单加载状态
|
||||
const modalVisible = ref(false); // 添加或编辑显示
|
||||
const searchForm = reactive({
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "create_time", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
groupId: "",
|
||||
});
|
||||
const underForm = reactive({
|
||||
// 下架原因
|
||||
reason: "",
|
||||
});
|
||||
const goodsAuditForm = reactive({
|
||||
// 商品审核表单
|
||||
auth_flag: 1,
|
||||
});
|
||||
const auditModalVisible = ref(false); // 审核弹框显示状态
|
||||
const auditSubmitLoading = ref(false);
|
||||
const currentAuditGoods = ref(null); // 当前审核的商品
|
||||
const submitLoading = ref(false); // 添加或编辑提交状态
|
||||
const data = ref([]); // 表单数据
|
||||
const total = ref(0); // 表单数据总数
|
||||
const currentStatus = ref("ALL");
|
||||
const goodsNumerData = ref({});
|
||||
const selectedRows = ref([]); // 选中的行数据
|
||||
const selectAll = ref(false); // 全选状态
|
||||
const batchAuditModalVisible = ref(false); // 批量审核弹框显示状态
|
||||
const batchAuditSubmitLoading = ref(false);
|
||||
const batchAuditForm = ref({
|
||||
auth_flag: 1,
|
||||
reason: ''
|
||||
});
|
||||
const goodsGroupFlag = ref(false);
|
||||
const goodsGroupLoading = ref(false);
|
||||
const goodsGroupList = ref([]);
|
||||
const goodsGroupForm = ref({
|
||||
groupId: ""
|
||||
});
|
||||
const goodsGroupRule = reactive({
|
||||
groupId: [{ required: true, message: "请选择商品分组", trigger: "change" }]
|
||||
});
|
||||
|
||||
const goodsStatusWithCount = computed(() => {
|
||||
return [
|
||||
{title: '全部', value: 'ALL'},
|
||||
{title: `出售中${goodsNumerData.value.upperGoodsNum ? '(' + goodsNumerData.value.upperGoodsNum + ')' : ''}`, value: 'UPPER'},
|
||||
{title: `仓库中${goodsNumerData.value.downGoodsNum ? '(' + goodsNumerData.value.downGoodsNum + ')' : ''}`, value: 'DOWN'},
|
||||
{title: `待审核${goodsNumerData.value.auditGoodsNum ? '(' + goodsNumerData.value.auditGoodsNum + ')' : ''}`, value: 'TOBEAUDITED'},
|
||||
{title: `审核未通过${goodsNumerData.value.refuseGoodsNum ? '(' + goodsNumerData.value.refuseGoodsNum + ')' : ''}`, value: 'REFUSE'}
|
||||
];
|
||||
});
|
||||
|
||||
function clearTableSelection() {
|
||||
table.value?.clearSelection?.();
|
||||
}
|
||||
function onStatusTabClick(tab) {
|
||||
const status = tab.paneName ?? tab.props?.name;
|
||||
goodsStatusClick(status);
|
||||
}
|
||||
function salesModelText(v) {
|
||||
if (v === "RETAIL") return "零售";
|
||||
if (v === "WHOLESALE") return "批发";
|
||||
return "其他类型";
|
||||
}
|
||||
function goodsTypeText(v) {
|
||||
if (v === "PHYSICAL_GOODS") return "实物商品";
|
||||
if (v === "VIRTUAL_GOODS") return "虚拟商品";
|
||||
if (v === "E_COUPON") return "电子卡券"; // 卡密商品
|
||||
if (v === "APPOINTMENT_GOODS") return "预约商品";
|
||||
return v || "—";
|
||||
}
|
||||
function marketEnableText(v) {
|
||||
if (v === "DOWN") return "下架";
|
||||
if (v === "UPPER") return "上架";
|
||||
return "";
|
||||
}
|
||||
function authFlagText(v) {
|
||||
if (v === "TOBEAUDITED") return "待审核";
|
||||
if (v === "PASS") return "通过";
|
||||
if (v === "REFUSE") return "拒绝";
|
||||
return "";
|
||||
}
|
||||
// 初始化数据
|
||||
function init() {
|
||||
getDataList();
|
||||
getNumberData();
|
||||
loadGoodsGroupList();
|
||||
}
|
||||
// 分页 改变页码
|
||||
function changePage(v) {
|
||||
searchForm.pageNumber = v;
|
||||
getDataList();
|
||||
}
|
||||
// 分页 改变页数
|
||||
function changePageSize(v) {
|
||||
searchForm.pageSize = v;
|
||||
getDataList();
|
||||
}
|
||||
// 搜索
|
||||
function handleSearch() {
|
||||
searchForm.pageNumber = 1;
|
||||
searchForm.pageSize = 20;
|
||||
getDataList();
|
||||
getNumberData();
|
||||
}
|
||||
// 获取数据
|
||||
function getDataList() {
|
||||
loading.value = true;
|
||||
getGoodsListData(searchForm).then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
data.value = res.result.records;
|
||||
total.value = res.result.total;
|
||||
}
|
||||
});
|
||||
}
|
||||
function getNumberData() {
|
||||
// 创建一个不包含goodsStatus字段的搜索参数
|
||||
const { goodsStatus, ...searchParams } = searchForm;
|
||||
getGoodsNumerData(searchParams).then((res) => {
|
||||
if (res.success) {
|
||||
goodsNumerData.value = res.result;
|
||||
}
|
||||
})
|
||||
}
|
||||
// 编辑
|
||||
function edit(v) {
|
||||
id.value = v.id;
|
||||
if (v.underMessage) {
|
||||
underForm.reason = v.underMessage;
|
||||
} else {
|
||||
underForm.reason = "";
|
||||
}
|
||||
modalVisible.value = true;
|
||||
}
|
||||
// 下架
|
||||
function lower() {
|
||||
const reason = underForm.reason ? underForm.reason.trim() : "";
|
||||
if (!reason) {
|
||||
ElMessage.error("下架原因不能为空");
|
||||
return;
|
||||
}
|
||||
let params = {
|
||||
goodsId: id.value,
|
||||
reason
|
||||
};
|
||||
lowGoods(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("操作成功");
|
||||
modalVisible.value = false;
|
||||
getDataList();
|
||||
getNumberData(); // 添加这行
|
||||
}
|
||||
});
|
||||
}
|
||||
// 上架
|
||||
function upper(v) {
|
||||
ElMessageBox.confirm("您确认要上架 " + v.goodsName + " ?", "确认上架", { type: "warning" }).then(() => {
|
||||
let params = {
|
||||
goodsId: v.id
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
goodsStatusWithCount() {
|
||||
return [
|
||||
{title: '全部', value: 'ALL'},
|
||||
{title: `出售中${this.goodsNumerData.upperGoodsNum ? '(' + this.goodsNumerData.upperGoodsNum + ')' : ''}`, value: 'UPPER'},
|
||||
{title: `仓库中${this.goodsNumerData.downGoodsNum ? '(' + this.goodsNumerData.downGoodsNum + ')' : ''}`, value: 'DOWN'},
|
||||
{title: `待审核${this.goodsNumerData.auditGoodsNum ? '(' + this.goodsNumerData.auditGoodsNum + ')' : ''}`, value: 'TOBEAUDITED'},
|
||||
{title: `审核未通过${this.goodsNumerData.refuseGoodsNum ? '(' + this.goodsNumerData.refuseGoodsNum + ')' : ''}`, value: 'REFUSE'}
|
||||
];
|
||||
return upGoods(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("上架成功");
|
||||
getDataList();
|
||||
getNumberData(); // 添加这行
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
//查看商品详情
|
||||
function showDetail(v) {
|
||||
customRouterPush({
|
||||
name: "goods-detail",
|
||||
query: { id: v.id },
|
||||
});
|
||||
}
|
||||
|
||||
// 商品状态筛选
|
||||
function goodsStatusClick(name) {
|
||||
if (name === "ALL" || name === "" || name === undefined || name === null) {
|
||||
delete searchForm.goodsStatus;
|
||||
currentStatus.value = "ALL";
|
||||
} else {
|
||||
searchForm.goodsStatus = name;
|
||||
currentStatus.value = name;
|
||||
}
|
||||
selectedRows.value = [];
|
||||
clearTableSelection();
|
||||
getDataList();
|
||||
}
|
||||
function examine(v, authFlag) {
|
||||
// 审核商品
|
||||
let examine = "通过";
|
||||
goodsAuditForm.authFlag = "PASS";
|
||||
if (authFlag != 1) {
|
||||
examine = "拒绝";
|
||||
goodsAuditForm.authFlag = "REFUSE";
|
||||
}
|
||||
|
||||
ElMessageBox.confirm("您确认要审核" + examine + " " + v.goodsName + " ?", "确认审核", { type: "warning" }).then(() => {
|
||||
goodsAuditForm.goodsIds=v.id;
|
||||
let formData = new FormData();
|
||||
formData.append('goodsIds', v.id);
|
||||
formData.append('authFlag', goodsAuditForm.authFlag);
|
||||
|
||||
return authGoods(formData).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("审核成功");
|
||||
getDataList();
|
||||
getNumberData();
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
// 打开审核弹框
|
||||
function openAuditModal(goods) {
|
||||
currentAuditGoods.value = goods;
|
||||
goodsAuditForm.auth_flag = 1;
|
||||
goodsAuditForm.reason = '';
|
||||
auditSubmitLoading.value = false;
|
||||
auditModalVisible.value = true;
|
||||
}
|
||||
|
||||
// 提交审核
|
||||
function submitAudit() {
|
||||
if (!currentAuditGoods.value) {
|
||||
return;
|
||||
}
|
||||
auditSubmitLoading.value = true;
|
||||
const formData = new FormData();
|
||||
formData.append('goodsIds', currentAuditGoods.value.id);
|
||||
formData.append('authFlag', goodsAuditForm.auth_flag === 1 ? 'PASS' : 'REFUSE');
|
||||
authGoods(formData).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success('审核成功');
|
||||
auditModalVisible.value = false;
|
||||
getDataList();
|
||||
getNumberData();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
unitPrice,
|
||||
clearTableSelection() {
|
||||
this.$refs.table?.clearSelection?.();
|
||||
},
|
||||
onStatusTabClick(tab) {
|
||||
const status = tab.paneName ?? tab.props?.name;
|
||||
this.goodsStatusClick(status);
|
||||
},
|
||||
salesModelText(v) {
|
||||
if (v === "RETAIL") return "零售";
|
||||
if (v === "WHOLESALE") return "批发";
|
||||
return "其他类型";
|
||||
},
|
||||
goodsTypeText(v) {
|
||||
if (v === "PHYSICAL_GOODS") return "实物商品";
|
||||
if (v === "VIRTUAL_GOODS") return "虚拟商品";
|
||||
if (v === "E_COUPON") return "电子卡券"; // 卡密商品
|
||||
if (v === "APPOINTMENT_GOODS") return "预约商品";
|
||||
return v || "—";
|
||||
},
|
||||
marketEnableText(v) {
|
||||
if (v === "DOWN") return "下架";
|
||||
if (v === "UPPER") return "上架";
|
||||
return "";
|
||||
},
|
||||
authFlagText(v) {
|
||||
if (v === "TOBEAUDITED") return "待审核";
|
||||
if (v === "PASS") return "通过";
|
||||
if (v === "REFUSE") return "拒绝";
|
||||
return "";
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
this.getNumberData();
|
||||
this.loadGoodsGroupList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
this.getNumberData();
|
||||
},
|
||||
// 获取数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getGoodsListData(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
getNumberData() {
|
||||
// 创建一个不包含goodsStatus字段的搜索参数
|
||||
const { goodsStatus, ...searchParams } = this.searchForm;
|
||||
getGoodsNumerData(searchParams).then((res) => {
|
||||
if (res.success) {
|
||||
this.goodsNumerData = res.result;
|
||||
}
|
||||
})
|
||||
},
|
||||
// 编辑
|
||||
edit(v) {
|
||||
this.id = v.id;
|
||||
if (v.underMessage) {
|
||||
this.underForm.reason = v.underMessage;
|
||||
} else {
|
||||
this.underForm.reason = "";
|
||||
}).finally(() => {
|
||||
auditSubmitLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function onSelectionChange(selection) {
|
||||
selectedRows.value = selection;
|
||||
}
|
||||
|
||||
// 批量上架
|
||||
function batchUpper() {
|
||||
if (selectedRows.value.length === 0) {
|
||||
ElMessage.warning('请先选择要上架的商品');
|
||||
return;
|
||||
}
|
||||
|
||||
const goodsNames = selectedRows.value.map(item => item.goodsName).join('、');
|
||||
ElMessageBox.confirm(`您确认要上架以下商品吗?\n${goodsNames}`, "确认批量上架", { type: "warning" }).then(() => {
|
||||
const goodsIds = selectedRows.value.map(item => item.id);
|
||||
const params = {
|
||||
goodsId: goodsIds
|
||||
};
|
||||
|
||||
return upGoods(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success('批量上架成功');
|
||||
selectedRows.value = [];
|
||||
selectAll.value = false;
|
||||
getDataList();
|
||||
getNumberData();
|
||||
}
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 下架
|
||||
lower() {
|
||||
const reason = this.underForm.reason ? this.underForm.reason.trim() : "";
|
||||
if (!reason) {
|
||||
ElMessage.error("下架原因不能为空");
|
||||
return;
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
// 批量下架
|
||||
function batchLower() {
|
||||
if (selectedRows.value.length === 0) {
|
||||
ElMessage.warning('请先选择要下架的商品');
|
||||
return;
|
||||
}
|
||||
|
||||
const goodsNames = selectedRows.value.map(item => item.goodsName).join('、');
|
||||
ElMessageBox.confirm(`您确认要下架以下商品吗?\n${goodsNames}`, "确认批量下架", { type: "warning" }).then(() => {
|
||||
const goodsIds = selectedRows.value.map(item => item.id);
|
||||
const params = {
|
||||
goodsId: goodsIds,
|
||||
reason: '批量下架操作'
|
||||
};
|
||||
|
||||
return lowGoods(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success('批量下架成功');
|
||||
selectedRows.value = [];
|
||||
selectAll.value = false;
|
||||
getDataList();
|
||||
getNumberData();
|
||||
}
|
||||
let params = {
|
||||
goodsId: this.id,
|
||||
reason
|
||||
};
|
||||
lowGoods(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("操作成功");
|
||||
this.modalVisible = false;
|
||||
this.getDataList();
|
||||
this.getNumberData(); // 添加这行
|
||||
}
|
||||
});
|
||||
},
|
||||
// 上架
|
||||
upper(v) {
|
||||
ElMessageBox.confirm("您确认要上架 " + v.goodsName + " ?", "确认上架", { type: "warning" }).then(() => {
|
||||
let params = {
|
||||
goodsId: v.id
|
||||
};
|
||||
return upGoods(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("上架成功");
|
||||
this.getDataList();
|
||||
this.getNumberData(); // 添加这行
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
//查看商品详情
|
||||
showDetail(v) {
|
||||
customRouterPush({
|
||||
name: "goods-detail",
|
||||
query: { id: v.id },
|
||||
});
|
||||
},
|
||||
// 批量审核
|
||||
function batchAudit() {
|
||||
if (selectedRows.value.length === 0) {
|
||||
ElMessage.warning('请先选择要审核的商品');
|
||||
return;
|
||||
}
|
||||
|
||||
// 商品状态筛选
|
||||
goodsStatusClick(name) {
|
||||
if (name === "ALL" || name === "" || name === undefined || name === null) {
|
||||
delete this.searchForm.goodsStatus;
|
||||
this.currentStatus = "ALL";
|
||||
} else {
|
||||
this.searchForm.goodsStatus = name;
|
||||
this.currentStatus = name;
|
||||
}
|
||||
this.selectedRows = [];
|
||||
this.clearTableSelection();
|
||||
this.getDataList();
|
||||
},
|
||||
examine(v, authFlag) {
|
||||
// 审核商品
|
||||
let examine = "通过";
|
||||
this.goodsAuditForm.authFlag = "PASS";
|
||||
if (authFlag != 1) {
|
||||
examine = "拒绝";
|
||||
this.goodsAuditForm.authFlag = "REFUSE";
|
||||
}
|
||||
// 重置批量审核表单
|
||||
batchAuditForm.value = {
|
||||
auth_flag: 1,
|
||||
reason: ''
|
||||
};
|
||||
batchAuditModalVisible.value = true;
|
||||
}
|
||||
|
||||
ElMessageBox.confirm("您确认要审核" + examine + " " + v.goodsName + " ?", "确认审核", { type: "warning" }).then(() => {
|
||||
this.goodsAuditForm.goodsIds=v.id;
|
||||
let formData = new FormData();
|
||||
formData.append('goodsIds', v.id);
|
||||
formData.append('authFlag', this.goodsAuditForm.authFlag);
|
||||
// 提交批量审核
|
||||
function submitBatchAudit() {
|
||||
if (selectedRows.value.length === 0) {
|
||||
ElMessage.warning('请先选择要审核的商品');
|
||||
return;
|
||||
}
|
||||
|
||||
return authGoods(formData).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("审核成功");
|
||||
this.getDataList();
|
||||
this.getNumberData();
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
// 如果是拒绝审核,必须填写原因
|
||||
if (batchAuditForm.value.auth_flag === 2 && !batchAuditForm.value.reason.trim()) {
|
||||
ElMessage.warning('审核拒绝时必须填写拒绝原因');
|
||||
return;
|
||||
}
|
||||
|
||||
// 打开审核弹框
|
||||
openAuditModal(goods) {
|
||||
this.currentAuditGoods = goods;
|
||||
this.goodsAuditForm.auth_flag = 1;
|
||||
this.goodsAuditForm.reason = '';
|
||||
this.auditSubmitLoading = false;
|
||||
this.auditModalVisible = true;
|
||||
},
|
||||
const actionText = batchAuditForm.value.auth_flag === 1 ? '通过' : '拒绝';
|
||||
const goodsIds = selectedRows.value.map(item => item.id);
|
||||
const formData = new FormData();
|
||||
formData.append('goodsIds', goodsIds.join(','));
|
||||
formData.append('authFlag', batchAuditForm.value.auth_flag === 1 ? 'PASS' : 'REFUSE');
|
||||
if (batchAuditForm.value.reason) {
|
||||
formData.append('reason', batchAuditForm.value.reason);
|
||||
}
|
||||
|
||||
// 提交审核
|
||||
submitAudit() {
|
||||
if (!this.currentAuditGoods) {
|
||||
return;
|
||||
}
|
||||
this.auditSubmitLoading = true;
|
||||
const formData = new FormData();
|
||||
formData.append('goodsIds', this.currentAuditGoods.id);
|
||||
formData.append('authFlag', this.goodsAuditForm.auth_flag === 1 ? 'PASS' : 'REFUSE');
|
||||
authGoods(formData).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success('审核成功');
|
||||
this.auditModalVisible = false;
|
||||
this.getDataList();
|
||||
this.getNumberData();
|
||||
}
|
||||
}).finally(() => {
|
||||
this.auditSubmitLoading = false;
|
||||
});
|
||||
},
|
||||
|
||||
onSelectionChange(selection) {
|
||||
this.selectedRows = selection;
|
||||
},
|
||||
|
||||
// 批量上架
|
||||
batchUpper() {
|
||||
if (this.selectedRows.length === 0) {
|
||||
ElMessage.warning('请先选择要上架的商品');
|
||||
return;
|
||||
}
|
||||
|
||||
const goodsNames = this.selectedRows.map(item => item.goodsName).join('、');
|
||||
ElMessageBox.confirm(`您确认要上架以下商品吗?\n${goodsNames}`, "确认批量上架", { type: "warning" }).then(() => {
|
||||
const goodsIds = this.selectedRows.map(item => item.id);
|
||||
const params = {
|
||||
goodsId: goodsIds
|
||||
};
|
||||
|
||||
return upGoods(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success('批量上架成功');
|
||||
this.selectedRows = [];
|
||||
this.selectAll = false;
|
||||
this.getDataList();
|
||||
this.getNumberData();
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
|
||||
// 批量下架
|
||||
batchLower() {
|
||||
if (this.selectedRows.length === 0) {
|
||||
ElMessage.warning('请先选择要下架的商品');
|
||||
return;
|
||||
}
|
||||
|
||||
const goodsNames = this.selectedRows.map(item => item.goodsName).join('、');
|
||||
ElMessageBox.confirm(`您确认要下架以下商品吗?\n${goodsNames}`, "确认批量下架", { type: "warning" }).then(() => {
|
||||
const goodsIds = this.selectedRows.map(item => item.id);
|
||||
const params = {
|
||||
goodsId: goodsIds,
|
||||
reason: '批量下架操作'
|
||||
};
|
||||
|
||||
return lowGoods(params).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success('批量下架成功');
|
||||
this.selectedRows = [];
|
||||
this.selectAll = false;
|
||||
this.getDataList();
|
||||
this.getNumberData();
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
|
||||
// 批量审核
|
||||
batchAudit() {
|
||||
if (this.selectedRows.length === 0) {
|
||||
ElMessage.warning('请先选择要审核的商品');
|
||||
return;
|
||||
}
|
||||
|
||||
// 重置批量审核表单
|
||||
this.batchAuditForm = {
|
||||
auth_flag: 1,
|
||||
reason: ''
|
||||
};
|
||||
this.batchAuditModalVisible = true;
|
||||
},
|
||||
|
||||
// 提交批量审核
|
||||
submitBatchAudit() {
|
||||
if (this.selectedRows.length === 0) {
|
||||
ElMessage.warning('请先选择要审核的商品');
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是拒绝审核,必须填写原因
|
||||
if (this.batchAuditForm.auth_flag === 2 && !this.batchAuditForm.reason.trim()) {
|
||||
ElMessage.warning('审核拒绝时必须填写拒绝原因');
|
||||
return;
|
||||
}
|
||||
|
||||
const actionText = this.batchAuditForm.auth_flag === 1 ? '通过' : '拒绝';
|
||||
const goodsIds = this.selectedRows.map(item => item.id);
|
||||
const formData = new FormData();
|
||||
formData.append('goodsIds', goodsIds.join(','));
|
||||
formData.append('authFlag', this.batchAuditForm.auth_flag === 1 ? 'PASS' : 'REFUSE');
|
||||
if (this.batchAuditForm.reason) {
|
||||
formData.append('reason', this.batchAuditForm.reason);
|
||||
}
|
||||
|
||||
this.batchAuditSubmitLoading = true;
|
||||
authGoods(formData).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success(`批量审核${actionText}成功`);
|
||||
this.selectedRows = [];
|
||||
this.selectAll = false;
|
||||
this.batchAuditModalVisible = false;
|
||||
this.clearTableSelection();
|
||||
this.getDataList();
|
||||
this.getNumberData();
|
||||
}
|
||||
}).finally(() => {
|
||||
this.batchAuditSubmitLoading = false;
|
||||
});
|
||||
},
|
||||
loadGoodsGroupList() {
|
||||
getGoodsGroupByPage({ pageNumber: 1, pageSize: 1000 }).then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
this.goodsGroupList = res.result.records || [];
|
||||
}
|
||||
});
|
||||
},
|
||||
openSetGoodsGroup() {
|
||||
if (this.selectedRows.length === 0) {
|
||||
ElMessage.warning("请先选择商品");
|
||||
return;
|
||||
}
|
||||
this.goodsGroupFlag = true;
|
||||
this.goodsGroupLoading = false;
|
||||
this.goodsGroupForm = { groupId: "" };
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.goodsGroupForm) this.$refs.goodsGroupForm.resetFields();
|
||||
});
|
||||
this.loadGoodsGroupList();
|
||||
},
|
||||
submitSetGoodsGroup() {
|
||||
this.$refs.goodsGroupForm.validate((valid) => {
|
||||
if (!valid) return;
|
||||
const goodsIds = this.selectedRows.map((item) => item.id);
|
||||
this.goodsGroupLoading = true;
|
||||
addGoodsGroupItems(this.goodsGroupForm.groupId, goodsIds).then((res) => {
|
||||
this.goodsGroupLoading = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("设置成功");
|
||||
this.goodsGroupFlag = false;
|
||||
this.selectedRows = [];
|
||||
this.selectAll = false;
|
||||
this.clearTableSelection();
|
||||
this.getDataList();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
}
|
||||
}).catch(() => {
|
||||
this.goodsGroupLoading = false;
|
||||
ElMessage.error("设置失败,请检查权限或后端接口");
|
||||
});
|
||||
});
|
||||
batchAuditSubmitLoading.value = true;
|
||||
authGoods(formData).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success(`批量审核${actionText}成功`);
|
||||
selectedRows.value = [];
|
||||
selectAll.value = false;
|
||||
batchAuditModalVisible.value = false;
|
||||
clearTableSelection();
|
||||
getDataList();
|
||||
getNumberData();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
}).finally(() => {
|
||||
batchAuditSubmitLoading.value = false;
|
||||
});
|
||||
}
|
||||
function loadGoodsGroupList() {
|
||||
getGoodsGroupByPage({ pageNumber: 1, pageSize: 1000 }).then((res) => {
|
||||
if (res && res.success && res.result) {
|
||||
goodsGroupList.value = res.result.records || [];
|
||||
}
|
||||
});
|
||||
}
|
||||
function openSetGoodsGroup() {
|
||||
if (selectedRows.value.length === 0) {
|
||||
ElMessage.warning("请先选择商品");
|
||||
return;
|
||||
}
|
||||
goodsGroupFlag.value = true;
|
||||
goodsGroupLoading.value = false;
|
||||
goodsGroupForm.value = { groupId: "" };
|
||||
nextTick(() => {
|
||||
if (goodsGroupFormRef.value) goodsGroupFormRef.value.resetFields();
|
||||
});
|
||||
loadGoodsGroupList();
|
||||
}
|
||||
function submitSetGoodsGroup() {
|
||||
goodsGroupFormRef.value.validate((valid) => {
|
||||
if (!valid) return;
|
||||
const goodsIds = selectedRows.value.map((item) => item.id);
|
||||
goodsGroupLoading.value = true;
|
||||
addGoodsGroupItems(goodsGroupForm.value.groupId, goodsIds).then((res) => {
|
||||
goodsGroupLoading.value = false;
|
||||
if (res && res.success) {
|
||||
ElMessage.success("设置成功");
|
||||
goodsGroupFlag.value = false;
|
||||
selectedRows.value = [];
|
||||
selectAll.value = false;
|
||||
clearTableSelection();
|
||||
getDataList();
|
||||
} else if (res && res.message) {
|
||||
ElMessage.error(res.message);
|
||||
}
|
||||
}).catch(() => {
|
||||
goodsGroupLoading.value = false;
|
||||
ElMessage.error("设置失败,请检查权限或后端接口");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// Tab组件样式
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="search">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
ref="searchFormRef"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
@@ -87,104 +87,103 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { onMounted, ref } from "vue";
|
||||
import { authGoods, getAuthGoodsListData } from "@/api/goods";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { unitPrice, customRouterPush } from "@/utils/filters";
|
||||
|
||||
export default {
|
||||
name: "goodsApply",
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
searchForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
},
|
||||
goodsAuditForm: {
|
||||
auth_flag: 1,
|
||||
},
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
unitPrice,
|
||||
authFlagText(v) {
|
||||
const map = {
|
||||
TOBEAUDITED: "待审核",
|
||||
PASS: "审核通过",
|
||||
REFUSE: "审核拒绝",
|
||||
};
|
||||
return map[v] || v || "-";
|
||||
},
|
||||
authFlagTagType(v) {
|
||||
const map = {
|
||||
TOBEAUDITED: "warning",
|
||||
PASS: "success",
|
||||
REFUSE: "danger",
|
||||
};
|
||||
return map[v] || "info";
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
this.searchForm.authFlag = 0;
|
||||
getAuthGoodsListData(this.searchForm)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
examine(v, authFlag) {
|
||||
const examine = authFlag === 1 ? "通过" : "拒绝";
|
||||
this.goodsAuditForm.authFlag = authFlag === 1 ? "PASS" : "REFUSE";
|
||||
ElMessageBox.confirm(`您确认要审核${examine} ${v.goodsName} ?`, "确认审核", { type: "warning" }).then(() => {
|
||||
const formData = new FormData();
|
||||
formData.append("goodsIds", v.id);
|
||||
formData.append("authFlag", this.goodsAuditForm.authFlag);
|
||||
return authGoods(formData).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("审核成功");
|
||||
this.getDataList();
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
showDetail(v) {
|
||||
customRouterPush({
|
||||
name: "goods-detail",
|
||||
query: { id: v.id },
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
};
|
||||
defineOptions({ name: "goodsApply" });
|
||||
|
||||
// 模板中 el-form 的 ref 与数据 searchForm 同名,避免相互覆盖改名
|
||||
const searchFormRef = ref(null);
|
||||
const table = ref(null);
|
||||
|
||||
const loading = ref(true);
|
||||
const searchForm = ref({
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
});
|
||||
const goodsAuditForm = ref({
|
||||
auth_flag: 1,
|
||||
});
|
||||
const data = ref([]);
|
||||
const total = ref(0);
|
||||
|
||||
function authFlagText(v) {
|
||||
const map = {
|
||||
TOBEAUDITED: "待审核",
|
||||
PASS: "审核通过",
|
||||
REFUSE: "审核拒绝",
|
||||
};
|
||||
return map[v] || v || "-";
|
||||
}
|
||||
function authFlagTagType(v) {
|
||||
const map = {
|
||||
TOBEAUDITED: "warning",
|
||||
PASS: "success",
|
||||
REFUSE: "danger",
|
||||
};
|
||||
return map[v] || "info";
|
||||
}
|
||||
function init() {
|
||||
getDataList();
|
||||
}
|
||||
function changePage(v) {
|
||||
searchForm.value.pageNumber = v;
|
||||
getDataList();
|
||||
}
|
||||
function changePageSize(v) {
|
||||
searchForm.value.pageSize = v;
|
||||
getDataList();
|
||||
}
|
||||
function handleSearch() {
|
||||
searchForm.value.pageNumber = 1;
|
||||
searchForm.value.pageSize = 20;
|
||||
getDataList();
|
||||
}
|
||||
function getDataList() {
|
||||
loading.value = true;
|
||||
searchForm.value.authFlag = 0;
|
||||
getAuthGoodsListData(searchForm.value)
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
if (res.success) {
|
||||
data.value = res.result.records;
|
||||
total.value = res.result.total;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
function examine(v, authFlag) {
|
||||
const examine = authFlag === 1 ? "通过" : "拒绝";
|
||||
goodsAuditForm.value.authFlag = authFlag === 1 ? "PASS" : "REFUSE";
|
||||
ElMessageBox.confirm(`您确认要审核${examine} ${v.goodsName} ?`, "确认审核", { type: "warning" }).then(() => {
|
||||
const formData = new FormData();
|
||||
formData.append("goodsIds", v.id);
|
||||
formData.append("authFlag", goodsAuditForm.value.authFlag);
|
||||
return authGoods(formData).then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("审核成功");
|
||||
getDataList();
|
||||
}
|
||||
});
|
||||
}).catch(() => {});
|
||||
}
|
||||
function showDetail(v) {
|
||||
customRouterPush({
|
||||
name: "goods-detail",
|
||||
query: { id: v.id },
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -376,307 +376,304 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { computed, nextTick, onMounted, reactive, ref } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { View } from "@element-plus/icons-vue";
|
||||
import { authGoods, getBrandListData, getGoodsDetail } from "@/api/goods";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
export default {
|
||||
name: "goodsDetail",
|
||||
components: { View },
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
goods: {},
|
||||
brandList: [],
|
||||
previewGoodsPicture: "",
|
||||
goodsPictureVisible: false,
|
||||
wholesaleData: [],
|
||||
skuData: [],
|
||||
activeTab: "basic",
|
||||
slotCapacityVisible: false,
|
||||
currentSlotCapacities: [],
|
||||
goodsAuditForm: {
|
||||
auth_flag: 1,
|
||||
},
|
||||
auditModalVisible: false,
|
||||
auditSubmitLoading: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isAppointmentGoods() {
|
||||
return this.goods.goodsType === "APPOINTMENT_GOODS";
|
||||
},
|
||||
needsLogistics() {
|
||||
return this.goods.goodsType === "PHYSICAL_GOODS";
|
||||
},
|
||||
salesModelDisplayText() {
|
||||
const type = this.goods.goodsType;
|
||||
const model = this.goods.salesModel;
|
||||
if (type === "APPOINTMENT_GOODS") return "预约型";
|
||||
if (type === "E_COUPON") return "电子卡券";
|
||||
if (type === "VIRTUAL_GOODS") return "虚拟型";
|
||||
if (model === "WHOLESALE") return "批发型";
|
||||
if (model === "RETAIL") return "零售型";
|
||||
return model || "—";
|
||||
},
|
||||
sectionTabs() {
|
||||
const tabs = [
|
||||
{ name: "basic", label: "基础信息" },
|
||||
{ name: "media", label: "图文信息" },
|
||||
];
|
||||
if (this.isAppointmentGoods) {
|
||||
tabs.push({ name: "appointment", label: "预约规则" });
|
||||
}
|
||||
tabs.push(
|
||||
{ name: "price", label: "价格库存" },
|
||||
{ name: "other", label: "其他信息" },
|
||||
);
|
||||
return tabs;
|
||||
},
|
||||
categoryText() {
|
||||
const names = this.goods.categoryName;
|
||||
if (!names || !names.length) return "—";
|
||||
return names.join(" > ");
|
||||
},
|
||||
/** 兼容扁平列表与历史嵌套分组两种 params 结构 */
|
||||
displayGoodsParams() {
|
||||
let list = this.goods.goodsParamsDTOList;
|
||||
if ((!Array.isArray(list) || !list.length) && this.goods.params) {
|
||||
list = this.parseParamsJson(this.goods.params);
|
||||
}
|
||||
if (!Array.isArray(list) || !list.length) return [];
|
||||
const flat = [];
|
||||
list.forEach((item) => {
|
||||
if (Array.isArray(item?.goodsParamsItemDTOList) && item.goodsParamsItemDTOList.length) {
|
||||
item.goodsParamsItemDTOList.forEach((child) => {
|
||||
if (child?.paramName) flat.push(child);
|
||||
});
|
||||
} else if (item?.paramName) {
|
||||
flat.push(item);
|
||||
}
|
||||
defineOptions({ name: "goodsDetail" });
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const loading = ref(false);
|
||||
const goods = ref({});
|
||||
const brandList = ref([]);
|
||||
const previewGoodsPicture = ref("");
|
||||
const goodsPictureVisible = ref(false);
|
||||
const wholesaleData = ref([]);
|
||||
const skuData = ref([]);
|
||||
const activeTab = ref("basic");
|
||||
const slotCapacityVisible = ref(false);
|
||||
const currentSlotCapacities = ref([]);
|
||||
const goodsAuditForm = reactive({
|
||||
auth_flag: 1,
|
||||
});
|
||||
const auditModalVisible = ref(false);
|
||||
const auditSubmitLoading = ref(false);
|
||||
|
||||
const isAppointmentGoods = computed(() => {
|
||||
return goods.value.goodsType === "APPOINTMENT_GOODS";
|
||||
});
|
||||
const needsLogistics = computed(() => {
|
||||
return goods.value.goodsType === "PHYSICAL_GOODS";
|
||||
});
|
||||
const salesModelDisplayText = computed(() => {
|
||||
const type = goods.value.goodsType;
|
||||
const model = goods.value.salesModel;
|
||||
if (type === "APPOINTMENT_GOODS") return "预约型";
|
||||
if (type === "E_COUPON") return "电子卡券";
|
||||
if (type === "VIRTUAL_GOODS") return "虚拟型";
|
||||
if (model === "WHOLESALE") return "批发型";
|
||||
if (model === "RETAIL") return "零售型";
|
||||
return model || "—";
|
||||
});
|
||||
const sectionTabs = computed(() => {
|
||||
const tabs = [
|
||||
{ name: "basic", label: "基础信息" },
|
||||
{ name: "media", label: "图文信息" },
|
||||
];
|
||||
if (isAppointmentGoods.value) {
|
||||
tabs.push({ name: "appointment", label: "预约规则" });
|
||||
}
|
||||
tabs.push(
|
||||
{ name: "price", label: "价格库存" },
|
||||
{ name: "other", label: "其他信息" },
|
||||
);
|
||||
return tabs;
|
||||
});
|
||||
const categoryText = computed(() => {
|
||||
const names = goods.value.categoryName;
|
||||
if (!names || !names.length) return "—";
|
||||
return names.join(" > ");
|
||||
});
|
||||
/** 兼容扁平列表与历史嵌套分组两种 params 结构 */
|
||||
const displayGoodsParams = computed(() => {
|
||||
let list = goods.value.goodsParamsDTOList;
|
||||
if ((!Array.isArray(list) || !list.length) && goods.value.params) {
|
||||
list = parseParamsJson(goods.value.params);
|
||||
}
|
||||
if (!Array.isArray(list) || !list.length) return [];
|
||||
const flat = [];
|
||||
list.forEach((item) => {
|
||||
if (Array.isArray(item?.goodsParamsItemDTOList) && item.goodsParamsItemDTOList.length) {
|
||||
item.goodsParamsItemDTOList.forEach((child) => {
|
||||
if (child?.paramName) flat.push(child);
|
||||
});
|
||||
return flat;
|
||||
},
|
||||
appointmentSettings() {
|
||||
return this.goods.appointmentSettings || null;
|
||||
},
|
||||
appointmentSlotTemplate() {
|
||||
return this.goods.appointmentSlotTemplate || null;
|
||||
},
|
||||
appointmentSlots() {
|
||||
return this.appointmentSlotTemplate?.slots || [];
|
||||
},
|
||||
bookableDateText() {
|
||||
const s = this.appointmentSettings;
|
||||
if (!s) return "—";
|
||||
if (s.bookableDateMode === "CUSTOM") {
|
||||
const parts = [];
|
||||
if (s.bookableCustomStartDate && s.bookableCustomEndDate) {
|
||||
parts.push(`${s.bookableCustomStartDate} ~ ${s.bookableCustomEndDate}`);
|
||||
}
|
||||
const weekdays = this.formatWeekdays(s.bookableWeekdays);
|
||||
if (weekdays) parts.push(weekdays);
|
||||
return parts.length ? parts.join(";") : "自定义";
|
||||
} else if (item?.paramName) {
|
||||
flat.push(item);
|
||||
}
|
||||
});
|
||||
return flat;
|
||||
});
|
||||
const appointmentSettings = computed(() => {
|
||||
return goods.value.appointmentSettings || null;
|
||||
});
|
||||
const appointmentSlotTemplate = computed(() => {
|
||||
return goods.value.appointmentSlotTemplate || null;
|
||||
});
|
||||
const appointmentSlots = computed(() => {
|
||||
return appointmentSlotTemplate.value?.slots || [];
|
||||
});
|
||||
const bookableDateText = computed(() => {
|
||||
const s = appointmentSettings.value;
|
||||
if (!s) return "—";
|
||||
if (s.bookableDateMode === "CUSTOM") {
|
||||
const parts = [];
|
||||
if (s.bookableCustomStartDate && s.bookableCustomEndDate) {
|
||||
parts.push(`${s.bookableCustomStartDate} ~ ${s.bookableCustomEndDate}`);
|
||||
}
|
||||
const weekdays = formatWeekdays(s.bookableWeekdays);
|
||||
if (weekdays) parts.push(weekdays);
|
||||
return parts.length ? parts.join(";") : "自定义";
|
||||
}
|
||||
if (s.bookableDateMode === "EVERY_DAY") return "每天";
|
||||
return "—";
|
||||
});
|
||||
const bookableDaysText = computed(() => {
|
||||
const s = appointmentSettings.value;
|
||||
if (!s || s.bookableDays == null) return "—";
|
||||
return `对用户展示 ${s.bookableDays} 天内的可预约日期`;
|
||||
});
|
||||
const advanceBookingText = computed(() => {
|
||||
const s = appointmentSettings.value;
|
||||
if (!s) return "—";
|
||||
if (s.advanceMode === "NONE") return "无需提前预约";
|
||||
if (s.advanceMode === "REQUIRE_HOURS" && s.advanceHours != null) {
|
||||
return `需提前 ${s.advanceHours} 小时进行预约`;
|
||||
}
|
||||
return "—";
|
||||
});
|
||||
const cancelRuleText = computed(() => {
|
||||
const s = appointmentSettings.value;
|
||||
if (!s) return "—";
|
||||
if (s.cancelMode === "NOT_ALLOWED") return "不允许取消";
|
||||
if (s.cancelMode === "ALLOW_BEFORE_HOURS" && s.cancelAheadHours != null) {
|
||||
return `服务开始 ${s.cancelAheadHours} 小时之前,允许取消并自动退款`;
|
||||
}
|
||||
return "—";
|
||||
});
|
||||
const formSubmitText = computed(() => {
|
||||
const s = appointmentSettings.value;
|
||||
if (!s) return "—";
|
||||
if (s.formSubmitMode === "PER_APPOINTMENT") return "每个预约提交一次";
|
||||
if (s.formSubmitMode === "PER_ORDER") return "每单提交一次";
|
||||
return "—";
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
loadBrandList();
|
||||
initGoods(route.query.id);
|
||||
});
|
||||
|
||||
function sectionNo(name) {
|
||||
const index = sectionTabs.value.findIndex((tab) => tab.name === name);
|
||||
return index >= 0 ? index + 1 : "";
|
||||
}
|
||||
function parseParamsJson(paramsJson) {
|
||||
if (!paramsJson) return [];
|
||||
try {
|
||||
const array = JSON.parse(paramsJson);
|
||||
if (!Array.isArray(array)) return [];
|
||||
const items = [];
|
||||
array.forEach((element) => {
|
||||
if (Array.isArray(element?.goodsParamsItemDTOList)) {
|
||||
items.push(...element.goodsParamsItemDTOList);
|
||||
} else if (element?.paramName) {
|
||||
items.push(element);
|
||||
}
|
||||
if (s.bookableDateMode === "EVERY_DAY") return "每天";
|
||||
return "—";
|
||||
},
|
||||
bookableDaysText() {
|
||||
const s = this.appointmentSettings;
|
||||
if (!s || s.bookableDays == null) return "—";
|
||||
return `对用户展示 ${s.bookableDays} 天内的可预约日期`;
|
||||
},
|
||||
advanceBookingText() {
|
||||
const s = this.appointmentSettings;
|
||||
if (!s) return "—";
|
||||
if (s.advanceMode === "NONE") return "无需提前预约";
|
||||
if (s.advanceMode === "REQUIRE_HOURS" && s.advanceHours != null) {
|
||||
return `需提前 ${s.advanceHours} 小时进行预约`;
|
||||
}
|
||||
return "—";
|
||||
},
|
||||
cancelRuleText() {
|
||||
const s = this.appointmentSettings;
|
||||
if (!s) return "—";
|
||||
if (s.cancelMode === "NOT_ALLOWED") return "不允许取消";
|
||||
if (s.cancelMode === "ALLOW_BEFORE_HOURS" && s.cancelAheadHours != null) {
|
||||
return `服务开始 ${s.cancelAheadHours} 小时之前,允许取消并自动退款`;
|
||||
}
|
||||
return "—";
|
||||
},
|
||||
formSubmitText() {
|
||||
const s = this.appointmentSettings;
|
||||
if (!s) return "—";
|
||||
if (s.formSubmitMode === "PER_APPOINTMENT") return "每个预约提交一次";
|
||||
if (s.formSubmitMode === "PER_ORDER") return "每单提交一次";
|
||||
return "—";
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.loadBrandList();
|
||||
this.initGoods(this.$route.query.id);
|
||||
},
|
||||
methods: {
|
||||
sectionNo(name) {
|
||||
const index = this.sectionTabs.findIndex((tab) => tab.name === name);
|
||||
return index >= 0 ? index + 1 : "";
|
||||
},
|
||||
parseParamsJson(paramsJson) {
|
||||
if (!paramsJson) return [];
|
||||
try {
|
||||
const array = JSON.parse(paramsJson);
|
||||
if (!Array.isArray(array)) return [];
|
||||
const items = [];
|
||||
array.forEach((element) => {
|
||||
if (Array.isArray(element?.goodsParamsItemDTOList)) {
|
||||
items.push(...element.goodsParamsItemDTOList);
|
||||
} else if (element?.paramName) {
|
||||
items.push(element);
|
||||
}
|
||||
});
|
||||
return items;
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
jumpToTab(name) {
|
||||
this.activeTab = name;
|
||||
this.$nextTick(() => {
|
||||
const el = document.getElementById(`goods-section-${name}`);
|
||||
el?.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
});
|
||||
},
|
||||
loadBrandList() {
|
||||
getBrandListData().then((res) => {
|
||||
this.brandList = Array.isArray(res) ? res : res?.result || [];
|
||||
});
|
||||
},
|
||||
initGoods(id) {
|
||||
if (!id) return;
|
||||
this.loading = true;
|
||||
getGoodsDetail(id)
|
||||
.then((res) => {
|
||||
if (!res?.success) return;
|
||||
this.goods = res.result || {};
|
||||
this.skuData = (res.result?.skuList || []).map((sku) => ({
|
||||
id: sku.id,
|
||||
specs: sku.simpleSpecs || sku.goodsName,
|
||||
sn: sku.sn,
|
||||
weight: sku.weight,
|
||||
price: sku.price,
|
||||
image: sku.goodsGalleryList,
|
||||
quantity: sku.quantity,
|
||||
slotCapacities: sku.slotCapacities,
|
||||
}));
|
||||
this.wholesaleData = res.result?.wholesaleList || [];
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
brandText(brandId) {
|
||||
if (!brandId || brandId === "0") return "—";
|
||||
const brand = this.brandList.find((item) => String(item.id) === String(brandId));
|
||||
return brand?.name || brandId;
|
||||
},
|
||||
goodsTypeText(v) {
|
||||
if (v === "PHYSICAL_GOODS") return "实物商品";
|
||||
if (v === "VIRTUAL_GOODS") return "虚拟商品";
|
||||
if (v === "E_COUPON") return "电子卡券";
|
||||
if (v === "APPOINTMENT_GOODS") return "预约商品";
|
||||
return v || "—";
|
||||
},
|
||||
normalizeSlotCapacities(caps) {
|
||||
if (!Array.isArray(caps) || !caps.length) return [];
|
||||
return caps.map((item) => ({
|
||||
startTime: item.startTime || "",
|
||||
endTime: item.endTime || "",
|
||||
capacity: item.slotCapacity ?? item.capacity ?? 0,
|
||||
});
|
||||
return items;
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
function jumpToTab(name) {
|
||||
activeTab.value = name;
|
||||
nextTick(() => {
|
||||
const el = document.getElementById(`goods-section-${name}`);
|
||||
el?.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
});
|
||||
}
|
||||
function loadBrandList() {
|
||||
getBrandListData().then((res) => {
|
||||
brandList.value = Array.isArray(res) ? res : res?.result || [];
|
||||
});
|
||||
}
|
||||
function initGoods(id) {
|
||||
if (!id) return;
|
||||
loading.value = true;
|
||||
getGoodsDetail(id)
|
||||
.then((res) => {
|
||||
if (!res?.success) return;
|
||||
goods.value = res.result || {};
|
||||
skuData.value = (res.result?.skuList || []).map((sku) => ({
|
||||
id: sku.id,
|
||||
specs: sku.simpleSpecs || sku.goodsName,
|
||||
sn: sku.sn,
|
||||
weight: sku.weight,
|
||||
price: sku.price,
|
||||
image: sku.goodsGalleryList,
|
||||
quantity: sku.quantity,
|
||||
slotCapacities: sku.slotCapacities,
|
||||
}));
|
||||
},
|
||||
hasSlotCapacities(row) {
|
||||
return this.slotCapacityCount(row) > 0;
|
||||
},
|
||||
slotCapacityCount(row) {
|
||||
return this.normalizeSlotCapacities(row?.slotCapacities).length;
|
||||
},
|
||||
openSlotCapacityDialog(row) {
|
||||
this.currentSlotCapacities = this.normalizeSlotCapacities(row?.slotCapacities);
|
||||
this.slotCapacityVisible = true;
|
||||
},
|
||||
formatSlotCapacity(capacity) {
|
||||
const value = Number(capacity);
|
||||
if (!value) return "不限制";
|
||||
return String(value);
|
||||
},
|
||||
marketEnableText(v) {
|
||||
if (v === "UPPER") return "上架";
|
||||
if (v === "DOWN") return "下架";
|
||||
return "—";
|
||||
},
|
||||
authFlagText(v) {
|
||||
if (v === "TOBEAUDITED") return "待审核";
|
||||
if (v === "PASS") return "通过";
|
||||
if (v === "REFUSE") return "拒绝";
|
||||
return v || "—";
|
||||
},
|
||||
authFlagTagType(v) {
|
||||
if (v === "PASS") return "success";
|
||||
if (v === "TOBEAUDITED") return "warning";
|
||||
if (v === "REFUSE") return "danger";
|
||||
return "info";
|
||||
},
|
||||
formatServiceModes(modes) {
|
||||
if (!modes || !modes.length) return "—";
|
||||
const map = {
|
||||
IN_STORE: "到店服务",
|
||||
ON_SITE: "上门服务",
|
||||
};
|
||||
return modes.map((m) => map[m] || m).join("、");
|
||||
},
|
||||
formatWeekdays(weekdays) {
|
||||
if (!Array.isArray(weekdays) || !weekdays.length) return "";
|
||||
const map = {
|
||||
1: "周一",
|
||||
2: "周二",
|
||||
3: "周三",
|
||||
4: "周四",
|
||||
5: "周五",
|
||||
6: "周六",
|
||||
7: "周日",
|
||||
};
|
||||
return weekdays.map((d) => map[d] || d).join("、");
|
||||
},
|
||||
handleViewGoodsPicture(url) {
|
||||
this.previewGoodsPicture = url;
|
||||
this.goodsPictureVisible = true;
|
||||
},
|
||||
openAuditModal() {
|
||||
this.goodsAuditForm.auth_flag = 1;
|
||||
this.auditSubmitLoading = false;
|
||||
this.auditModalVisible = true;
|
||||
},
|
||||
submitAudit() {
|
||||
if (!this.goods.id) return;
|
||||
this.auditSubmitLoading = true;
|
||||
const formData = new FormData();
|
||||
formData.append("goodsIds", this.goods.id);
|
||||
formData.append("authFlag", this.goodsAuditForm.auth_flag === 1 ? "PASS" : "REFUSE");
|
||||
authGoods(formData)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("审核成功");
|
||||
this.auditModalVisible = false;
|
||||
this.initGoods(this.goods.id);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.auditSubmitLoading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
wholesaleData.value = res.result?.wholesaleList || [];
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
function brandText(brandId) {
|
||||
if (!brandId || brandId === "0") return "—";
|
||||
const brand = brandList.value.find((item) => String(item.id) === String(brandId));
|
||||
return brand?.name || brandId;
|
||||
}
|
||||
function goodsTypeText(v) {
|
||||
if (v === "PHYSICAL_GOODS") return "实物商品";
|
||||
if (v === "VIRTUAL_GOODS") return "虚拟商品";
|
||||
if (v === "E_COUPON") return "电子卡券";
|
||||
if (v === "APPOINTMENT_GOODS") return "预约商品";
|
||||
return v || "—";
|
||||
}
|
||||
function normalizeSlotCapacities(caps) {
|
||||
if (!Array.isArray(caps) || !caps.length) return [];
|
||||
return caps.map((item) => ({
|
||||
startTime: item.startTime || "",
|
||||
endTime: item.endTime || "",
|
||||
capacity: item.slotCapacity ?? item.capacity ?? 0,
|
||||
}));
|
||||
}
|
||||
function hasSlotCapacities(row) {
|
||||
return slotCapacityCount(row) > 0;
|
||||
}
|
||||
function slotCapacityCount(row) {
|
||||
return normalizeSlotCapacities(row?.slotCapacities).length;
|
||||
}
|
||||
function openSlotCapacityDialog(row) {
|
||||
currentSlotCapacities.value = normalizeSlotCapacities(row?.slotCapacities);
|
||||
slotCapacityVisible.value = true;
|
||||
}
|
||||
function formatSlotCapacity(capacity) {
|
||||
const value = Number(capacity);
|
||||
if (!value) return "不限制";
|
||||
return String(value);
|
||||
}
|
||||
function marketEnableText(v) {
|
||||
if (v === "UPPER") return "上架";
|
||||
if (v === "DOWN") return "下架";
|
||||
return "—";
|
||||
}
|
||||
function authFlagText(v) {
|
||||
if (v === "TOBEAUDITED") return "待审核";
|
||||
if (v === "PASS") return "通过";
|
||||
if (v === "REFUSE") return "拒绝";
|
||||
return v || "—";
|
||||
}
|
||||
function authFlagTagType(v) {
|
||||
if (v === "PASS") return "success";
|
||||
if (v === "TOBEAUDITED") return "warning";
|
||||
if (v === "REFUSE") return "danger";
|
||||
return "info";
|
||||
}
|
||||
function formatServiceModes(modes) {
|
||||
if (!modes || !modes.length) return "—";
|
||||
const map = {
|
||||
IN_STORE: "到店服务",
|
||||
ON_SITE: "上门服务",
|
||||
};
|
||||
return modes.map((m) => map[m] || m).join("、");
|
||||
}
|
||||
function formatWeekdays(weekdays) {
|
||||
if (!Array.isArray(weekdays) || !weekdays.length) return "";
|
||||
const map = {
|
||||
1: "周一",
|
||||
2: "周二",
|
||||
3: "周三",
|
||||
4: "周四",
|
||||
5: "周五",
|
||||
6: "周六",
|
||||
7: "周日",
|
||||
};
|
||||
return weekdays.map((d) => map[d] || d).join("、");
|
||||
}
|
||||
function handleViewGoodsPicture(url) {
|
||||
previewGoodsPicture.value = url;
|
||||
goodsPictureVisible.value = true;
|
||||
}
|
||||
function openAuditModal() {
|
||||
goodsAuditForm.auth_flag = 1;
|
||||
auditSubmitLoading.value = false;
|
||||
auditModalVisible.value = true;
|
||||
}
|
||||
function submitAudit() {
|
||||
if (!goods.value.id) return;
|
||||
auditSubmitLoading.value = true;
|
||||
const formData = new FormData();
|
||||
formData.append("goodsIds", goods.value.id);
|
||||
formData.append("authFlag", goodsAuditForm.auth_flag === 1 ? "PASS" : "REFUSE");
|
||||
authGoods(formData)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
ElMessage.success("审核成功");
|
||||
auditModalVisible.value = false;
|
||||
initGoods(goods.value.id);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
auditSubmitLoading.value = false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
Reference in New Issue
Block a user