共富商城

This commit is contained in:
zjf committed 2025-09-08 15:52:46 +08:00
1 parent cf514a5b1c
commit 20dc9d7f91
6 files changed
+114 -27

No files matched your search

+2 -2
View File
@@ -39,10 +39,10 @@ export function putObj(obj?: Object) {
})
}
export function tree(obj?: Object) {
export function tree(params?: Object) {
return request({
url: '/supermarket/mallCategory/tree',
method: 'get',
data: obj
params: params
})
}
+31 -2
View File
@@ -3,6 +3,19 @@
:close-on-click-modal="false" draggable>
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item label="商户" prop="merchantId" required>
<el-select v-model="form.merchantId" placeholder="请选择商户" clearable>
<el-option
v-for="merchant in merchantOptions"
:key="merchant.value"
:label="merchant.label"
:value="merchant.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="父级分类" prop="parentId">
<el-select v-model="form.parentId" clearable placeholder="请选择父级分类">
@@ -58,6 +71,7 @@
import { useDict } from '/@/hooks/dict';
import { useMessage } from "/@/hooks/message";
import { getObj, addObj, putObj, fetchList } from '/@/api/supermarket/mallCategory'
import { selectOption as fetchMerchantSelect } from '/@/api/supermarket/mallMerchant';
import { rule } from '/@/utils/validate';
import { ref, reactive, nextTick, onMounted } from 'vue';
const emit = defineEmits(['refresh']);
@@ -72,6 +86,7 @@ const { status } = useDict('status')
// 提交表单数据
const form = reactive({
id:'',
merchantId: '',
parentId: '',
name: '',
sort: 0,
@@ -81,12 +96,16 @@ const form = reactive({
// 定义校验规则
const dataRules = ref({
merchantId: [{ required: true, message: '商户不能为空', trigger: 'change' }],
name: [{required: true, message: '分类名称不能为空', trigger: 'blur'}],
})
// 分类选项
const categoryOptions = ref<any[]>([]);
// 商户选项
const merchantOptions = ref<any[]>([]);
// 获取所有分类(排除自身)
const loadCategories = async () => {
const res = await fetchList({ size: 9999 });
@@ -96,8 +115,15 @@ const loadCategories = async () => {
}
};
// 加载商户选项
const loadMerchantOptions = async () => {
const res = await fetchMerchantSelect();
merchantOptions.value = res.data || [];
};
onMounted(() => {
loadCategories();
loadMerchantOptions();
});
// 打开弹窗
@@ -108,6 +134,7 @@ const openDialog = (id: string) => {
// 重置表单数据
nextTick(() => {
dataFormRef.value?.resetFields();
form.merchantId = '';
form.status = '0';
});
@@ -116,8 +143,9 @@ const openDialog = (id: string) => {
form.id = id
getmallCategoryData(id)
} else {
// 新增时直接加载分类
// 新增时直接加载分类和商户
loadCategories();
loadMerchantOptions();
}
};
@@ -146,8 +174,9 @@ const getmallCategoryData = (id: string) => {
loading.value = true
getObj(id).then((res: any) => {
Object.assign(form, res.data)
// 编辑时加载分类并排除自己
// 编辑时加载分类和商户并排除自己
loadCategories();
loadMerchantOptions();
}).finally(() => {
loading.value = false
})
@@ -33,6 +33,21 @@
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="12" class="mb20">
<el-form-item label="营业时间" prop="businessHours">
<el-time-picker
v-model="businessHoursRange"
is-range
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
format="HH:mm"
value-format="HH:mm"
placeholder="请选择营业时间"
/>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
@@ -82,6 +97,7 @@ import { useDict } from '/@/hooks/dict';
import { useMessage } from "/@/hooks/message";
import { getObj, addObj, putObj } from '/@/api/supermarket/mallMerchant'
import { rule } from '/@/utils/validate';
import { ref, reactive, nextTick, watch } from 'vue';
const emit = defineEmits(['refresh']);
// 定义变量内容
@@ -99,6 +115,7 @@ const form = reactive({
contactName: '',
contactPhone: '',
email: '',
businessHours: '', // 营业时间
status: 1, // 默认正常状态
licenseNo: '',
address: '',
@@ -107,11 +124,24 @@ const form = reactive({
deptId: '',
});
// 营业时间范围选择器
const businessHoursRange = ref<[string, string] | null>(null);
// 监听营业时间范围变化,转换为数据库格式
watch(businessHoursRange, (newRange) => {
if (newRange && newRange.length === 2) {
form.businessHours = `${newRange[0]}-${newRange[1]}`;
} else {
form.businessHours = '';
}
}, { immediate: true });
// 定义校验规则
const dataRules = ref({
name: [{required: true, message: '商户名称不能为空', trigger: 'blur'}],
contactName: [{required: true, message: '联系人不能为空', trigger: 'blur'}],
contactPhone: [{required: true, message: '联系电话不能为空', trigger: 'blur'}, { validator: rule.mobilePhone, trigger: 'blur' }],
businessHours: [{required: true, message: '营业时间不能为空', trigger: 'change'}],
})
// 打开弹窗
@@ -126,6 +156,8 @@ const openDialog = (id: string) => {
if (!id) {
form.status = 1;
}
// 重置营业时间
businessHoursRange.value = null;
});
// 获取mallMerchant信息
@@ -160,6 +192,14 @@ const getmallMerchantData = (id: string) => {
loading.value = true
getObj(id).then((res: any) => {
Object.assign(form, res.data)
// 处理营业时间回显
if (res.data.businessHours) {
const timeRange = res.data.businessHours.split('-');
if (timeRange.length === 2) {
businessHoursRange.value = [timeRange[0], timeRange[1]];
}
}
}).finally(() => {
loading.value = false
})
@@ -45,6 +45,7 @@
<el-table-column prop="shortName" label="商户简称" show-overflow-tooltip/>
<el-table-column prop="contactName" label="联系人" show-overflow-tooltip/>
<el-table-column prop="contactPhone" label="联系电话" show-overflow-tooltip/>
<el-table-column prop="businessHours" label="营业时间" show-overflow-tooltip/>
<!-- <el-table-column prop="email" label="邮箱" show-overflow-tooltip/>-->
<el-table-column prop="status" label="状态" show-overflow-tooltip>
<template #default="scope">
+36 -19
View File
@@ -8,7 +8,7 @@
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item label="商户" prop="merchantId" required>
<el-select v-model="form.merchantId" placeholder="请选择商户" clearable>
<el-select v-model="form.merchantId" placeholder="请选择商户" clearable @change="onMerchantChange">
<el-option
v-for="merchant in merchantOptions"
:key="merchant.value"
@@ -25,8 +25,9 @@
v-model="form.categoryId"
:options="categoryOptions"
:props="{ value: 'id', label: 'name', children: 'children', checkStrictly: true }"
:disabled="!form.merchantId"
clearable
placeholder="请选择商品分类"
placeholder="请先选择商户"
/>
</el-form-item>
</el-col>
@@ -55,8 +56,8 @@
<el-col :span="12" class="mb20">
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio :label="1">上架</el-radio>
<el-radio :label="0">下架</el-radio>
<el-radio label="1">上架</el-radio>
<el-radio label="0">下架</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
@@ -222,8 +223,8 @@
<template #default="scope">
<div class="sku-cell">
<el-radio-group v-model="scope.row.status" size="small">
<el-radio :label="1">启用</el-radio>
<el-radio :label="0">停用</el-radio>
<el-radio label="1">启用</el-radio>
<el-radio label="0">停用</el-radio>
</el-radio-group>
</div>
</template>
@@ -281,8 +282,12 @@ const categoryOptions = ref<any[]>([]);
const merchantOptions = ref<any[]>([]);
// 加载分类树
const loadCategoryTree = async () => {
const res = await fetchCategoryTree();
const loadCategoryTree = async (merchantId?: string) => {
if (!merchantId) {
categoryOptions.value = [];
return;
}
const res = await fetchCategoryTree({ merchantId });
categoryOptions.value = res.data || [];
};
@@ -292,6 +297,14 @@ const loadMerchantOptions = async () => {
merchantOptions.value = res.data || [];
};
// 商户选择变化处理
const onMerchantChange = (merchantId: string) => {
// 清空分类选择
form.categoryId = '';
// 根据商户ID加载对应的分类树
loadCategoryTree(merchantId);
};
// 提交表单数据
const form = reactive({
id: '',
@@ -304,7 +317,7 @@ const form = reactive({
spuPrice: 0,
originalPrice: 0,
unit: '',
status: 1, // 默认上架
status: '1', // 默认上架
saleStartTime: '',
saleEndTime: '',
description: '',
@@ -350,7 +363,7 @@ const addSku = () => {
stock: 0,
barcode: '',
weightG: 0,
status: 1
status: '1'
});
};
@@ -408,7 +421,7 @@ const openDialog = (id: string) => {
spuPrice: 0,
originalPrice: 0,
unit: '',
status: 1,
status: '1',
saleStartTime: '',
saleEndTime: '',
description: '',
@@ -418,8 +431,7 @@ const openDialog = (id: string) => {
addSku();
});
// 重新加载分类树和商户选项
loadCategoryTree();
// 重新加载商户选项
loadMerchantOptions();
// 获取mallProduct信息
@@ -492,12 +504,18 @@ const onSubmit = async () => {
};
// 初始化表单数据
const getmallProductData = (id: string) => {
const getmallProductData = async (id: string) => {
// 获取数据
loading.value = true
getObj(id).then((res: any) => {
try {
const res = await getObj(id);
Object.assign(form, res.data);
// 先根据商户ID加载分类树
if (form.merchantId) {
await loadCategoryTree(form.merchantId);
}
// 处理分类ID回显为数组
if (res.data.categoryId && categoryOptions.value.length) {
form.categoryId = findCategoryPath(categoryOptions.value, res.data.categoryId);
@@ -509,9 +527,9 @@ const getmallProductData = (id: string) => {
addSku();
}
}
}).finally(() => {
} finally {
loading.value = false
})
}
};
// 工具函数:根据分类id查找路径
@@ -527,9 +545,8 @@ function findCategoryPath(options: any[], targetId: any, path: any[] = []): any[
return [];
}
// 组件挂载时加载分类树和商户选项
// 组件挂载时加载商户选项
onMounted(() => {
loadCategoryTree();
loadMerchantOptions();
});
+4 -4
View File
@@ -99,8 +99,8 @@
<el-table-column prop="status" label="状态" width="100" align="center">
<template #default="scope">
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
{{ scope.row.status === 1 ? '上架' : '下架' }}
<el-tag :type="scope.row.status === '1' ? 'success' : 'danger'">
{{ scope.row.status === '1' ? '上架' : '下架' }}
</el-tag>
</template>
</el-table-column>
@@ -158,8 +158,8 @@
<el-table-column prop="weightG" label="重量(克)" width="120" align="center"/>
<el-table-column prop="status" label="状态" width="100" align="center">
<template #default="scope">
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
{{ scope.row.status === 1 ? '启用' : '停用' }}
<el-tag :type="scope.row.status === '1' ? 'success' : 'danger'">
{{ scope.row.status === '1' ? '启用' : '停用' }}
</el-tag>
</template>
</el-table-column>