菜品必点配置
This commit is contained in:
1 parent
be639340aa
commit
1afc82492e
7 files changed
+569
-12
No files matched your search
@@ -0,0 +1,44 @@
|
||||
import request from "/@/utils/request"
|
||||
|
||||
/** 分页查询分组(merchantId 不传则按数据权限返回可见范围全部) */
|
||||
export function fetchPage(query?: object) {
|
||||
return request({
|
||||
url: "/canteen/canteenOnlineSpuChoiceGroup/page",
|
||||
method: "get",
|
||||
params: query,
|
||||
})
|
||||
}
|
||||
|
||||
/** 按商户查询分组列表(用于下拉;merchantId 必填) */
|
||||
export function fetchList(merchantId: string | number) {
|
||||
return request({
|
||||
url: "/canteen/canteenOnlineSpuChoiceGroup/list",
|
||||
method: "get",
|
||||
params: { merchantId },
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj?: object) {
|
||||
return request({
|
||||
url: "/canteen/canteenOnlineSpuChoiceGroup",
|
||||
method: "post",
|
||||
data: obj,
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj?: object) {
|
||||
return request({
|
||||
url: "/canteen/canteenOnlineSpuChoiceGroup",
|
||||
method: "put",
|
||||
data: obj,
|
||||
})
|
||||
}
|
||||
|
||||
/** Body:id 数组 */
|
||||
export function delObjs(ids: (string | number)[]) {
|
||||
return request({
|
||||
url: "/canteen/canteenOnlineSpuChoiceGroup",
|
||||
method: "delete",
|
||||
data: ids,
|
||||
})
|
||||
}
|
||||
@@ -154,10 +154,11 @@ export function backEndComponent(routes: any) {
|
||||
*/
|
||||
export function dynamicImport(dynamicViewsModules: Record<string, Function>, component: string) {
|
||||
const keys = Object.keys(dynamicViewsModules)
|
||||
const normalized = component?.startsWith("/") ? component : `/${component}`
|
||||
|
||||
const matchKeys = keys.filter((key) => {
|
||||
const k = key.replace(/..\/views|../, "")
|
||||
return k.startsWith(`${component}.vue`)
|
||||
return k.startsWith(`${normalized}.vue`)
|
||||
})
|
||||
if (matchKeys?.length === 1) {
|
||||
const matchKey = matchKeys[0]
|
||||
|
||||
@@ -78,9 +78,29 @@
|
||||
/>
|
||||
|
||||
<template #footer>
|
||||
<div class="flex items-center w-1/3">
|
||||
<div class="w-16 text-blue-600 text-base font-bold">商户:</div>
|
||||
<select-mch v-model="merchantId" :apiParams="{ types: '1' }" />
|
||||
<div class="footer-batch-row">
|
||||
<div class="footer-field">
|
||||
<span class="footer-label">商户:</span>
|
||||
<select-mch v-model="merchantId" :apiParams="{ types: '1' }" />
|
||||
</div>
|
||||
<div class="footer-field">
|
||||
<span class="footer-label">择一/组合分组:</span>
|
||||
<el-select
|
||||
v-model="batchChoiceGroupId"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="默认不绑定"
|
||||
:disabled="!merchantId"
|
||||
style="width: 260px"
|
||||
>
|
||||
<el-option
|
||||
v-for="g in choiceGroupOptions"
|
||||
:key="String(g.id)"
|
||||
:label="`${g.name}(ID:${g.id})`"
|
||||
:value="String(g.id)"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="dialogConfirm" :disabled="loading">确认</el-button>
|
||||
@@ -96,6 +116,7 @@ import { useDict } from "/@/hooks/dict"
|
||||
import { getAllSimple as getCanteenCategory } from "/@/api/canteen/canteenCategory"
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
import { saveCanteenSpuBatch } from "/@/api/canteen/canteenOnlineSpu"
|
||||
import { fetchList as fetchChoiceGroupList } from "/@/api/canteen/canteenOnlineSpuChoiceGroup"
|
||||
|
||||
const emit = defineEmits(["refresh"])
|
||||
|
||||
@@ -113,6 +134,22 @@ const total = ref<number>(0)
|
||||
const dataList = ref<any[]>([]) // 对话框多选表格数据
|
||||
const categoryOptions = ref<any>([]) // 菜品分类选项
|
||||
const merchantId = ref<string>("")
|
||||
const batchChoiceGroupId = ref<string | null>(null)
|
||||
const choiceGroupOptions = ref<any[]>([])
|
||||
|
||||
watch(merchantId, async (mid) => {
|
||||
batchChoiceGroupId.value = null
|
||||
if (!mid) {
|
||||
choiceGroupOptions.value = []
|
||||
return
|
||||
}
|
||||
try {
|
||||
const res: any = await fetchChoiceGroupList(mid)
|
||||
choiceGroupOptions.value = Array.isArray(res.data) ? res.data : []
|
||||
} catch {
|
||||
choiceGroupOptions.value = []
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
@@ -127,6 +164,7 @@ onMounted(async () => {
|
||||
const openDialog = async () => {
|
||||
dialogVisible.value = true
|
||||
merchantId.value = ""
|
||||
batchChoiceGroupId.value = null
|
||||
getDataList(false)
|
||||
tableRef.value.clearSelection()
|
||||
}
|
||||
@@ -183,6 +221,11 @@ const dialogConfirm = async () => {
|
||||
status: item.status,
|
||||
price: item.price,
|
||||
stock: item.stock,
|
||||
requiredChoice: 0,
|
||||
choiceGroupId:
|
||||
batchChoiceGroupId.value != null && batchChoiceGroupId.value !== ""
|
||||
? String(batchChoiceGroupId.value)
|
||||
: null,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -214,3 +257,24 @@ defineExpose({
|
||||
openDialog,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.footer-batch-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 16px 24px;
|
||||
margin-bottom: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
.footer-field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.footer-label {
|
||||
font-weight: 600;
|
||||
color: var(--el-color-primary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
@@ -54,6 +54,31 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="单品必选" prop="requiredChoice">
|
||||
<el-switch v-model="form.requiredChoice" :active-value="1" :inactive-value="0" inline-prompt active-text="是" inactive-text="否" />
|
||||
<span class="field-hint">与分组规则独立,仅强制本菜品必买时用</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="14" class="mb20">
|
||||
<el-form-item label="择一/组合分组" prop="choiceGroupId">
|
||||
<el-select
|
||||
v-model="form.choiceGroupId"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="不绑定"
|
||||
:disabled="!form.merchantId"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="g in choiceGroupOptions"
|
||||
:key="String(g.id)"
|
||||
:label="`${g.name}(ID:${g.id})`"
|
||||
:value="String(g.id)"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="商品详情" prop="description">
|
||||
<editor v-if="visible" v-model:get-html="form.description" placeholder="请输入商品详情" />
|
||||
@@ -75,10 +100,27 @@
|
||||
import { useDict } from "/@/hooks/dict"
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
import { getObj, addObj, putObj } from "/@/api/canteen/canteenOnlineSpu"
|
||||
import { fetchList as fetchChoiceGroupList } from "/@/api/canteen/canteenOnlineSpuChoiceGroup"
|
||||
import { displayPrice, storePrice } from "/@/utils/formatMoney"
|
||||
|
||||
const emit = defineEmits(["refresh"])
|
||||
|
||||
const choiceGroupOptions = ref<any[]>([])
|
||||
const isHydrating = ref(false)
|
||||
|
||||
async function loadChoiceGroups(merchantId: string) {
|
||||
if (!merchantId) {
|
||||
choiceGroupOptions.value = []
|
||||
return
|
||||
}
|
||||
try {
|
||||
const res: any = await fetchChoiceGroupList(merchantId)
|
||||
choiceGroupOptions.value = Array.isArray(res.data) ? res.data : []
|
||||
} catch {
|
||||
choiceGroupOptions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
@@ -98,6 +140,8 @@ const form = reactive({
|
||||
sliderPicUrls: "",
|
||||
sort: 0,
|
||||
status: "0",
|
||||
requiredChoice: 0,
|
||||
choiceGroupId: null as string | null,
|
||||
price: 0,
|
||||
marketPrice: 0,
|
||||
stock: 0,
|
||||
@@ -108,6 +152,18 @@ const form = reactive({
|
||||
deptId: "",
|
||||
})
|
||||
|
||||
watch(
|
||||
() => form.merchantId,
|
||||
async (mid) => {
|
||||
if (isHydrating.value) {
|
||||
await loadChoiceGroups(String(mid || ""))
|
||||
return
|
||||
}
|
||||
form.choiceGroupId = null
|
||||
await loadChoiceGroups(String(mid || ""))
|
||||
},
|
||||
)
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = ref({
|
||||
merchantId: [{ required: true, message: "商户不能为空", trigger: "blur" }],
|
||||
@@ -142,7 +198,14 @@ const onSubmit = async () => {
|
||||
|
||||
try {
|
||||
loading.value = true
|
||||
const _pa = { ...form, price: storePrice(form.price), marketPrice: storePrice(form.marketPrice) }
|
||||
const _pa = {
|
||||
...form,
|
||||
price: storePrice(form.price),
|
||||
marketPrice: storePrice(form.marketPrice),
|
||||
requiredChoice: form.requiredChoice === 1 ? 1 : 0,
|
||||
choiceGroupId:
|
||||
form.choiceGroupId != null && form.choiceGroupId !== "" ? String(form.choiceGroupId) : null,
|
||||
}
|
||||
form.id ? await putObj(_pa) : await addObj(_pa)
|
||||
useMessage().success(form.id ? "修改成功" : "添加成功")
|
||||
visible.value = false
|
||||
@@ -159,14 +222,24 @@ const getcanteenOnlineSpuData = (id: string) => {
|
||||
// 获取数据
|
||||
loading.value = true
|
||||
getObj(id)
|
||||
.then((res: any) => {
|
||||
.then(async (res: any) => {
|
||||
const d = res.data
|
||||
Object.assign(form, d, {
|
||||
price: Number(displayPrice(d.price, "")),
|
||||
marketPrice: Number(displayPrice(d.marketPrice, "")),
|
||||
status: "" + d.status,
|
||||
description: d.description ?? "",
|
||||
})
|
||||
isHydrating.value = true
|
||||
try {
|
||||
Object.assign(form, d, {
|
||||
price: Number(displayPrice(d.price, "")),
|
||||
marketPrice: Number(displayPrice(d.marketPrice, "")),
|
||||
status: "" + d.status,
|
||||
description: d.description ?? "",
|
||||
requiredChoice: Number(d.requiredChoice) === 1 ? 1 : 0,
|
||||
choiceGroupId: d.choiceGroupId != null && d.choiceGroupId !== "" ? String(d.choiceGroupId) : null,
|
||||
})
|
||||
await nextTick()
|
||||
await loadChoiceGroups(String(form.merchantId || ""))
|
||||
form.choiceGroupId = d.choiceGroupId != null && d.choiceGroupId !== "" ? String(d.choiceGroupId) : null
|
||||
} finally {
|
||||
isHydrating.value = false
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
@@ -178,3 +251,12 @@ defineExpose({
|
||||
openDialog,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.field-hint {
|
||||
margin-left: 12px;
|
||||
font-size: 12px;
|
||||
color: var(--el-text-color-secondary);
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
@@ -100,6 +100,17 @@
|
||||
<dict-tag :options="spu_status" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="requiredChoice" label="单品必选" show-overflow-tooltip min-width="90" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="Number(scope.row.requiredChoice) === 1" type="warning" size="small">是</el-tag>
|
||||
<el-tag v-else type="info" size="small">否</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="choiceGroupId" label="分组ID" show-overflow-tooltip min-width="88" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.choiceGroupId != null && scope.row.choiceGroupId !== "" ? scope.row.choiceGroupId : "-" }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sort" label="排序字段" show-overflow-tooltip min-width="100" />
|
||||
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip min-width="160" />
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<el-dialog :title="form.id ? '编辑分组' : '新增分组'" v-model="visible" width="640px" :close-on-click-modal="false" draggable>
|
||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="130px" v-loading="loading">
|
||||
<el-form-item label="商户" prop="merchantId">
|
||||
<select-mch v-model="form.merchantId" :apiParams="{ types: '1' }" :disabled="!!form.id" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.id && form.deptId !== '' && form.deptId != null" label="部门ID">
|
||||
<el-input :model-value="String(form.deptId)" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="分组名称" prop="name">
|
||||
<el-input v-model.trim="form.name" placeholder="如:主食、饮料" maxlength="64" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item label="种数下限 minKinds" prop="minKinds">
|
||||
<el-input-number v-model="form.minKinds" :min="0" :precision="0" style="width: 100%" />
|
||||
<div class="form-tip">0 表示整组可选(顾客可不选组内任何菜)</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="种数上限 maxKinds" prop="maxKinds">
|
||||
<el-input-number v-model="form.maxKinds" :min="0" :precision="0" style="width: 100%" />
|
||||
<div class="form-tip">0 表示不限制种数上限</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="件数合计下限" prop="minTotalQty">
|
||||
<el-input-number v-model="form.minTotalQty" :min="0" :precision="0" style="width: 100%" />
|
||||
<div class="form-tip">0 表示不校验</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="件数合计上限" prop="maxTotalQty">
|
||||
<el-input-number v-model="form.maxTotalQty" :min="0" :precision="0" style="width: 100%" />
|
||||
<div class="form-tip">0 表示不限制</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="form.sort" :min="0" :precision="0" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="CanteenOnlineSpuChoiceGroupDialog">
|
||||
import type { FormRules } from "element-plus"
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
import { addObj, putObj } from "/@/api/canteen/canteenOnlineSpuChoiceGroup"
|
||||
|
||||
const props = defineProps<{
|
||||
listMerchantId?: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits(["refresh"])
|
||||
|
||||
const dataFormRef = ref()
|
||||
const visible = ref(false)
|
||||
const loading = ref(false)
|
||||
|
||||
const form = reactive({
|
||||
id: "" as string | number | "",
|
||||
merchantId: "",
|
||||
name: "",
|
||||
deptId: "" as string | number | "",
|
||||
minKinds: 0,
|
||||
maxKinds: 0,
|
||||
minTotalQty: 0,
|
||||
maxTotalQty: 0,
|
||||
sort: 0,
|
||||
})
|
||||
|
||||
const ruleKinds = (_rule: unknown, _val: unknown, callback: (e?: Error) => void) => {
|
||||
const maxK = Number(form.maxKinds) || 0
|
||||
const minK = Number(form.minKinds) || 0
|
||||
if (maxK > 0 && minK > maxK) {
|
||||
callback(new Error("maxKinds 不能小于 minKinds"))
|
||||
return
|
||||
}
|
||||
callback()
|
||||
}
|
||||
|
||||
const ruleQty = (_rule: unknown, _val: unknown, callback: (e?: Error) => void) => {
|
||||
const maxQ = Number(form.maxTotalQty) || 0
|
||||
const minQ = Number(form.minTotalQty) || 0
|
||||
if (maxQ > 0 && minQ > maxQ) {
|
||||
callback(new Error("maxTotalQty 不能小于 minTotalQty"))
|
||||
return
|
||||
}
|
||||
callback()
|
||||
}
|
||||
|
||||
const dataRules: FormRules = {
|
||||
merchantId: [{ required: true, message: "请选择商户", trigger: "change" }],
|
||||
name: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||
minKinds: [{ validator: ruleKinds, trigger: "blur" }],
|
||||
maxKinds: [{ validator: ruleKinds, trigger: "blur" }],
|
||||
minTotalQty: [{ validator: ruleQty, trigger: "blur" }],
|
||||
maxTotalQty: [{ validator: ruleQty, trigger: "blur" }],
|
||||
}
|
||||
|
||||
const resetFormModel = () => {
|
||||
form.id = ""
|
||||
form.merchantId = ""
|
||||
form.name = ""
|
||||
form.deptId = ""
|
||||
form.minKinds = 0
|
||||
form.maxKinds = 0
|
||||
form.minTotalQty = 0
|
||||
form.maxTotalQty = 0
|
||||
form.sort = 0
|
||||
}
|
||||
|
||||
/** 编辑传入表格行;新建不传 */
|
||||
const openDialog = (row?: Record<string, unknown>) => {
|
||||
visible.value = true
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields?.()
|
||||
resetFormModel()
|
||||
if (row && row.id != null && row.id !== "") {
|
||||
form.id = row.id as string
|
||||
form.merchantId = row.merchantId != null ? String(row.merchantId) : ""
|
||||
form.name = (row.name as string) ?? ""
|
||||
form.deptId = row.deptId != null ? (row.deptId as string | number) : ""
|
||||
form.minKinds = Number(row.minKinds) || 0
|
||||
form.maxKinds = Number(row.maxKinds) || 0
|
||||
form.minTotalQty = Number(row.minTotalQty) || 0
|
||||
form.maxTotalQty = Number(row.maxTotalQty) || 0
|
||||
form.sort = Number(row.sort) || 0
|
||||
} else {
|
||||
form.merchantId = props.listMerchantId || ""
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const buildPayload = () => {
|
||||
const base = {
|
||||
name: form.name.trim(),
|
||||
merchantId: form.merchantId,
|
||||
minKinds: Number(form.minKinds) || 0,
|
||||
maxKinds: Number(form.maxKinds) || 0,
|
||||
minTotalQty: Number(form.minTotalQty) || 0,
|
||||
maxTotalQty: Number(form.maxTotalQty) || 0,
|
||||
sort: Number(form.sort) || 0,
|
||||
}
|
||||
if (form.id) {
|
||||
return {
|
||||
...base,
|
||||
id: form.id,
|
||||
...(form.deptId !== "" && form.deptId != null ? { deptId: form.deptId } : {}),
|
||||
}
|
||||
}
|
||||
return base
|
||||
}
|
||||
|
||||
const onSubmit = async () => {
|
||||
const valid = await dataFormRef.value?.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
|
||||
try {
|
||||
loading.value = true
|
||||
const payload = buildPayload()
|
||||
if (form.id) {
|
||||
await putObj(payload)
|
||||
} else {
|
||||
await addObj(payload)
|
||||
}
|
||||
useMessage().success(form.id ? "修改成功" : "添加成功")
|
||||
visible.value = false
|
||||
emit("refresh", String(form.merchantId || ""))
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || err.message || "操作失败")
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openDialog,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.form-tip {
|
||||
font-size: 12px;
|
||||
color: var(--el-text-color-secondary);
|
||||
line-height: 1.4;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,169 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div class="layout-padding-auto layout-padding-view">
|
||||
<el-row v-show="showSearch" class="mb8">
|
||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||
<el-form-item label="商户" prop="merchantId">
|
||||
<select-mch v-model="state.queryForm.merchantId" :apiParams="{ types: '1' }" clearable style="width: 260px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分组名称" prop="name">
|
||||
<el-input v-model="state.queryForm.name" placeholder="请输入分组名称" clearable style="width: 220px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="search" type="primary" @click="getDataList" v-auth="'canteen_canteenOnlineSpu_view'">查询</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery" v-auth="'canteen_canteenOnlineSpu_view'">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<div class="mb8" style="width: 100%">
|
||||
<el-button icon="folder-add" type="primary" class="ml10" v-auth="'canteen_canteenOnlineSpu_add'" @click="handleAdd">
|
||||
新增分组
|
||||
</el-button>
|
||||
<el-button
|
||||
plain
|
||||
:disabled="multiple"
|
||||
icon="Delete"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
v-auth="'canteen_canteenOnlineSpu_del'"
|
||||
@click="handleDelete(selectObjs)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10 mr20" style="float: right" @queryTable="getDataList" />
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
@selection-change="selectionChangHandle"
|
||||
>
|
||||
<el-table-column type="selection" width="40" align="center" />
|
||||
<el-table-column type="index" label="#" width="50" />
|
||||
<el-table-column prop="name" label="分组名称" show-overflow-tooltip min-width="120" />
|
||||
<el-table-column prop="merchantId" label="商户" show-overflow-tooltip min-width="140">
|
||||
<template #default="{ row }">
|
||||
{{ merchantNameMap[String(row.merchantId)] ?? row.merchantId }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="minKinds" label="种数下限" width="88" align="center" />
|
||||
<el-table-column prop="maxKinds" label="种数上限" width="88" align="center" />
|
||||
<el-table-column prop="minTotalQty" label="件数下限" width="88" align="center" />
|
||||
<el-table-column prop="maxTotalQty" label="件数上限" width="88" align="center" />
|
||||
<el-table-column prop="sort" label="排序" width="72" align="center" />
|
||||
<el-table-column prop="createTime" label="创建时间" show-overflow-tooltip min-width="160" />
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button icon="edit-pen" text type="primary" v-auth="'canteen_canteenOnlineSpu_edit'" @click="openEdit(scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button icon="delete" text type="primary" v-auth="'canteen_canteenOnlineSpu_del'" @click="handleDelete([scope.row.id])">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
|
||||
</div>
|
||||
|
||||
<FormDialog ref="formDialogRef" :list-merchant-id="state.queryForm.merchantId" @refresh="onRefresh" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="CanteenOnlineSpuChoiceGroup">
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table"
|
||||
import { fetchPage, delObjs } from "/@/api/canteen/canteenOnlineSpuChoiceGroup"
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message"
|
||||
import { select } from "/@/api/wallet/mch-manage"
|
||||
|
||||
const FormDialog = defineAsyncComponent(() => import("./form.vue"))
|
||||
|
||||
const formDialogRef = ref()
|
||||
const queryRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const selectObjs = ref<string[]>([])
|
||||
const multiple = ref(true)
|
||||
const merchantNameMap = ref<Record<string, string>>({})
|
||||
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: { merchantId: undefined, name: "" },
|
||||
pageList: fetchPage,
|
||||
})
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const res = await select({ current: 1, size: 9999, types: 1 })
|
||||
const records: any[] = res?.data?.records ?? []
|
||||
const map: Record<string, string> = {}
|
||||
records.forEach((m: any) => {
|
||||
if (m?.id != null) map[String(m.id)] = m?.name ?? String(m.id)
|
||||
})
|
||||
merchantNameMap.value = map
|
||||
} catch {
|
||||
merchantNameMap.value = {}
|
||||
}
|
||||
})
|
||||
|
||||
const resetQuery = () => {
|
||||
queryRef.value?.resetFields?.()
|
||||
selectObjs.value = []
|
||||
multiple.value = true
|
||||
getDataList()
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
if (!formDialogRef.value?.openDialog) {
|
||||
useMessage().error("页面组件未就绪,请刷新后重试")
|
||||
return
|
||||
}
|
||||
formDialogRef.value.openDialog()
|
||||
}
|
||||
|
||||
const openEdit = (row: any) => {
|
||||
if (!formDialogRef.value?.openDialog) {
|
||||
useMessage().error("页面组件未就绪,请刷新后重试")
|
||||
return
|
||||
}
|
||||
formDialogRef.value.openDialog(row)
|
||||
}
|
||||
|
||||
const selectionChangHandle = (rows: { id: string }[]) => {
|
||||
selectObjs.value = rows.map((r) => r.id)
|
||||
multiple.value = !rows.length
|
||||
}
|
||||
|
||||
const handleDelete = async (ids: string[]) => {
|
||||
try {
|
||||
await useMessageBox().delConfirm(
|
||||
"删除前请先在「在线菜品」中解除绑定该分组的商品(choiceGroupId),否则可能产生脏数据。确定删除所选分组吗?",
|
||||
"提示",
|
||||
)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await delObjs(ids)
|
||||
await getDataList(false)
|
||||
useMessage().success("删除成功")
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg)
|
||||
}
|
||||
}
|
||||
|
||||
const onRefresh = async (merchantId?: string) => {
|
||||
if (state.queryForm && !state.queryForm.merchantId && merchantId) {
|
||||
state.queryForm.merchantId = merchantId
|
||||
}
|
||||
await getDataList(false)
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in new issue
Block a user