|
|
@@ -46,6 +46,7 @@
|
|
|
format="YYYY/MM/DD"
|
|
|
value-format="YYYY-MM-DD"
|
|
|
placeholder="请选择开始售卖时间"
|
|
|
+ :disabled-date="disabledStartDate"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
<!-- 结束售卖时间 -->
|
|
|
@@ -55,6 +56,7 @@
|
|
|
format="YYYY/MM/DD"
|
|
|
value-format="YYYY-MM-DD"
|
|
|
placeholder="请选择结束售卖时间"
|
|
|
+ :disabled-date="disabledEndDate"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
<!-- 库存数量 -->
|
|
|
@@ -74,13 +76,13 @@
|
|
|
<el-input v-model="storeInfoModel.quotaValue" maxlength="15" placeholder="请填写自定义限购数量" clearable />
|
|
|
</el-form-item>
|
|
|
<!-- 套餐内容 -->
|
|
|
- <el-form-item label="套餐内容" prop="packageContent" class="package-content-item">
|
|
|
+ <el-form-item label="套餐内容" prop="lifeGroupBuyThalis" class="package-content-item">
|
|
|
<div class="package-content-wrapper">
|
|
|
<div class="package-content-header">
|
|
|
<el-button type="primary" @click="addGroup" class="add-group-btn"> 添加分组 </el-button>
|
|
|
</div>
|
|
|
<div class="package-content-container">
|
|
|
- <div v-for="(group, groupIndex) in storeInfoModel.packageContent" :key="groupIndex" class="package-group">
|
|
|
+ <div v-for="(group, groupIndex) in storeInfoModel.lifeGroupBuyThalis" :key="groupIndex" class="package-group">
|
|
|
<div class="package-group-header">
|
|
|
<div class="header-right">
|
|
|
<el-button
|
|
|
@@ -88,7 +90,7 @@
|
|
|
link
|
|
|
@click="removeGroup(groupIndex)"
|
|
|
:icon="Delete"
|
|
|
- v-show="storeInfoModel.packageContent.length > 1"
|
|
|
+ v-show="storeInfoModel.lifeGroupBuyThalis.length > 1"
|
|
|
>
|
|
|
删除
|
|
|
</el-button>
|
|
|
@@ -112,7 +114,7 @@
|
|
|
<span class="label">菜品</span>
|
|
|
<div class="dish-select-block" @click="openDishDialog(groupIndex, dishIndex)">
|
|
|
<span v-if="dish.dishName" class="dish-selected-name"
|
|
|
- >{{ dish.dishName }},¥{{ dish.dishPrice }}/份</span
|
|
|
+ >{{ dish.dishName }},¥{{ dish.dishPrice }}/{{ dish.dishesUnit }}</span
|
|
|
>
|
|
|
<span v-else class="dish-placeholder">请选择</span>
|
|
|
</div>
|
|
|
@@ -174,6 +176,7 @@
|
|
|
range-separator="-"
|
|
|
start-placeholder="开始时间"
|
|
|
end-placeholder="结束时间"
|
|
|
+ :disabled-date="disabledEffectiveDate"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="不可用日期" prop="disableDateType">
|
|
|
@@ -235,6 +238,7 @@
|
|
|
start-placeholder="开始时间"
|
|
|
end-placeholder="结束时间"
|
|
|
class="date-picker"
|
|
|
+ :disabled-date="disabledCustomUnavailableDate"
|
|
|
/>
|
|
|
<el-button
|
|
|
:icon="Delete"
|
|
|
@@ -319,20 +323,30 @@
|
|
|
@input="filterDishList"
|
|
|
/>
|
|
|
<div class="dish-list-container">
|
|
|
- <div v-for="dish in filteredDishList" :key="dish.id" class="dish-item" @click="selectDish(dish)">
|
|
|
- <div class="dish-image">
|
|
|
- <el-image v-if="dish.image" :src="dish.image" fit="cover" class="dish-img" />
|
|
|
- <div v-else class="dish-image-placeholder">
|
|
|
- <el-icon><Picture /></el-icon>
|
|
|
+ <template v-if="filteredDishList.length > 0">
|
|
|
+ <div
|
|
|
+ v-for="dish in filteredDishList"
|
|
|
+ :key="dish.id"
|
|
|
+ :class="['dish-item', { 'dish-item-selected': selectedDishId === dish.id }]"
|
|
|
+ @click="selectDish(dish)"
|
|
|
+ >
|
|
|
+ <div class="dish-image">
|
|
|
+ <el-image v-if="dish.imgUrl" :src="dish.imgUrl" fit="cover" class="dish-img" />
|
|
|
+ <div v-else class="dish-image-placeholder">
|
|
|
+ <el-icon><Picture /></el-icon>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- <div class="dish-info">
|
|
|
- <div class="dish-name">
|
|
|
- {{ dish.name }}
|
|
|
+ <div class="dish-info">
|
|
|
+ <div class="dish-name">
|
|
|
+ {{ dish.name }}
|
|
|
+ </div>
|
|
|
+ <div class="dish-price">¥{{ dish.dishPrice }}/{{ dish.dishesUnit }}</div>
|
|
|
</div>
|
|
|
- <div class="dish-price">¥{{ dish.price }}/份</div>
|
|
|
</div>
|
|
|
- <el-radio v-model="selectedDishId" :label="dish.id" @click.stop="selectDish(dish)" />
|
|
|
+ </template>
|
|
|
+ <div v-else class="dish-empty-state">
|
|
|
+ <div class="empty-text">暂无可选择菜品</div>
|
|
|
+ <div class="empty-hint">请去全部-门店装修-菜品管理中添加</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -352,14 +366,15 @@
|
|
|
*/
|
|
|
import { ref, reactive, onMounted, watch, nextTick } from "vue";
|
|
|
import { ElMessage, ElMessageBox } from "element-plus";
|
|
|
-import { Plus, Delete, ArrowDown, ArrowUp, Picture } from "@element-plus/icons-vue";
|
|
|
+import { Plus, Delete, ArrowDown, ArrowUp, Picture, Check } from "@element-plus/icons-vue";
|
|
|
import {
|
|
|
saveStoreInfo,
|
|
|
editStoreInfo,
|
|
|
getDetail,
|
|
|
getStoreDetail,
|
|
|
getHolidayList,
|
|
|
- getUserByPhone
|
|
|
+ getUserByPhone,
|
|
|
+ getMenuByStoreId
|
|
|
} from "@/api/modules/groupPackageManagement";
|
|
|
import { useRouter, useRoute } from "vue-router";
|
|
|
import type { UploadProps, FormInstance } from "element-plus";
|
|
|
@@ -388,8 +403,64 @@ const rules = reactive({
|
|
|
imageList: [{ required: true, message: "请上传图片" }],
|
|
|
groupName: [{ required: true, message: "请填写团购名称" }],
|
|
|
startTimeType: [{ required: true, message: "请选择开始售卖时间" }],
|
|
|
- saleTimeStr: [{ required: true, message: "请选择开始售卖时间" }],
|
|
|
- endTime: [{ required: true, message: "请选择结束售卖时间" }],
|
|
|
+ saleTimeStr: [
|
|
|
+ { required: true, message: "请选择开始售卖时间" },
|
|
|
+ {
|
|
|
+ validator: (rule: any, value: any, callback: any) => {
|
|
|
+ if (storeInfoModel.value.startTimeType === 1) {
|
|
|
+ if (!value) {
|
|
|
+ callback(new Error("请选择开始售卖时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const selectedDate = new Date(value);
|
|
|
+ const today = new Date();
|
|
|
+ today.setHours(0, 0, 0, 0);
|
|
|
+ if (selectedDate < today) {
|
|
|
+ callback(new Error("开始售卖时间不能早于当前时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 如果结束时间已设置,验证开始时间必须早于结束时间
|
|
|
+ if (storeInfoModel.value.endTime) {
|
|
|
+ const endDate = new Date(storeInfoModel.value.endTime);
|
|
|
+ if (selectedDate >= endDate) {
|
|
|
+ callback(new Error("开始售卖时间必须早于结束售卖时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ callback();
|
|
|
+ },
|
|
|
+ trigger: "change"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ endTime: [
|
|
|
+ { required: true, message: "请选择结束售卖时间" },
|
|
|
+ {
|
|
|
+ validator: (rule: any, value: any, callback: any) => {
|
|
|
+ if (!value) {
|
|
|
+ callback(new Error("请选择结束售卖时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const selectedDate = new Date(value);
|
|
|
+ const today = new Date();
|
|
|
+ today.setHours(0, 0, 0, 0);
|
|
|
+ if (selectedDate < today) {
|
|
|
+ callback(new Error("结束售卖时间不能早于当前时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 如果开始时间已设置,验证结束时间必须晚于开始时间
|
|
|
+ if (storeInfoModel.value.startTimeType === 1 && storeInfoModel.value.saleTimeStr) {
|
|
|
+ const startDate = new Date(storeInfoModel.value.saleTimeStr);
|
|
|
+ if (selectedDate <= startDate) {
|
|
|
+ callback(new Error("结束售卖时间必须晚于开始售卖时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ callback();
|
|
|
+ },
|
|
|
+ trigger: "change"
|
|
|
+ }
|
|
|
+ ],
|
|
|
inventoryNum: [
|
|
|
{ required: true, message: "请填写库存数量" },
|
|
|
{
|
|
|
@@ -437,7 +508,7 @@ const rules = reactive({
|
|
|
trigger: "blur"
|
|
|
}
|
|
|
],
|
|
|
- // packageContent: [
|
|
|
+ // lifeGroupBuyThalis: [
|
|
|
// {
|
|
|
// required: true,
|
|
|
// validator: (rule: any, value: any, callback: any) => {
|
|
|
@@ -541,15 +612,33 @@ const rules = reactive({
|
|
|
{
|
|
|
required: true,
|
|
|
validator: (rule: any, value: any, callback: any) => {
|
|
|
- if (storeInfoModel.value.expirationDate === 1) {
|
|
|
+ if (storeInfoModel.value.effectiveDateType === 1) {
|
|
|
if (!value || value.length !== 2) {
|
|
|
callback(new Error("请选择指定时间段"));
|
|
|
return;
|
|
|
}
|
|
|
+ // 验证开始时间和结束时间不能早于当前时间
|
|
|
+ const today = new Date();
|
|
|
+ today.setHours(0, 0, 0, 0);
|
|
|
+ const startDate = new Date(value[0]);
|
|
|
+ const endDate = new Date(value[1]);
|
|
|
+ if (startDate < today) {
|
|
|
+ callback(new Error("开始时间不能早于当前时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (endDate < today) {
|
|
|
+ callback(new Error("结束时间不能早于当前时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 验证开始时间必须早于结束时间
|
|
|
+ if (startDate >= endDate) {
|
|
|
+ callback(new Error("开始时间必须早于结束时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
callback();
|
|
|
},
|
|
|
- trigger: "blur"
|
|
|
+ trigger: "change"
|
|
|
}
|
|
|
],
|
|
|
disableDateType: [{ required: true, message: "请选择不可用日期" }],
|
|
|
@@ -587,22 +676,40 @@ const rules = reactive({
|
|
|
{
|
|
|
required: true,
|
|
|
validator: (rule: any, value: any, callback: any) => {
|
|
|
- if (storeInfoModel.value.unavailableDates === 2) {
|
|
|
+ if (storeInfoModel.value.disableDateType === 2) {
|
|
|
if (!dates.value || dates.value.length === 0) {
|
|
|
callback(new Error("至少需要添加一个自定义不可用日期"));
|
|
|
return;
|
|
|
}
|
|
|
+ const today = new Date();
|
|
|
+ today.setHours(0, 0, 0, 0);
|
|
|
// 验证每个日期项是否已填写
|
|
|
for (let i = 0; i < dates.value.length; i++) {
|
|
|
if (!dates.value[i] || dates.value[i].length !== 2) {
|
|
|
callback(new Error(`第${i + 1}个日期项未完整填写`));
|
|
|
return;
|
|
|
}
|
|
|
+ // 验证开始时间和结束时间不能早于当前时间
|
|
|
+ const startDate = new Date(dates.value[i][0]);
|
|
|
+ const endDate = new Date(dates.value[i][1]);
|
|
|
+ if (startDate < today) {
|
|
|
+ callback(new Error(`第${i + 1}个日期项的开始时间不能早于当前时间`));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (endDate < today) {
|
|
|
+ callback(new Error(`第${i + 1}个日期项的结束时间不能早于当前时间`));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 验证开始时间必须早于结束时间
|
|
|
+ if (startDate >= endDate) {
|
|
|
+ callback(new Error(`第${i + 1}个日期项的开始时间必须早于结束时间`));
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
callback();
|
|
|
},
|
|
|
- trigger: "blur"
|
|
|
+ trigger: "change"
|
|
|
}
|
|
|
],
|
|
|
reservationRules: [{ required: true, message: "请输入预约规则" }],
|
|
|
@@ -653,7 +760,7 @@ const storeInfoModel = ref<any>({
|
|
|
// 自定义限购数量(当quotaType为1时必填)
|
|
|
quotaValue: 0,
|
|
|
// 套餐内容(数组,每个元素是一个分组)
|
|
|
- packageContent: [
|
|
|
+ lifeGroupBuyThalis: [
|
|
|
{
|
|
|
category: "", // 类别
|
|
|
collapsed: false, // 是否收起
|
|
|
@@ -700,29 +807,29 @@ const storeInfoModel = ref<any>({
|
|
|
// ==================== 下拉选项数据 ====================
|
|
|
|
|
|
// 发票类型列表
|
|
|
-const businessTypes = ref<any[]>([
|
|
|
+const businessTypes = ref([
|
|
|
{ value: 0, label: "提供电子发票" },
|
|
|
{ value: 1, label: "提供纸质发票" }
|
|
|
]);
|
|
|
|
|
|
// 开始售卖时间设置方式列表
|
|
|
-const storeStatusList = ref<any[]>([
|
|
|
+const storeStatusList = ref([
|
|
|
{ value: 0, label: "审核通过后立即开始" },
|
|
|
{ value: 1, label: "设置售卖时间" }
|
|
|
]);
|
|
|
|
|
|
// 每人限购设置列表
|
|
|
-const perList = ref<any[]>([
|
|
|
+const perList = ref([
|
|
|
{ value: 0, label: "不限量" },
|
|
|
{ value: 1, label: "自定义限购数量" }
|
|
|
]);
|
|
|
// 每人限购设置列表
|
|
|
-const expirationDateList = ref<any[]>([
|
|
|
+const expirationDateList = ref([
|
|
|
{ value: 0, label: "指定天数" },
|
|
|
{ value: 1, label: "指定时间段内可用" }
|
|
|
]);
|
|
|
// 每人限购设置列表
|
|
|
-const unavailableDatesList = ref<any[]>([
|
|
|
+const unavailableDatesList = ref([
|
|
|
{ value: 0, label: "全部日期可用" },
|
|
|
{ value: 1, label: "限制日期" },
|
|
|
{ value: 2, label: "自定义不可用日期" }
|
|
|
@@ -730,10 +837,10 @@ const unavailableDatesList = ref<any[]>([
|
|
|
//图片集合
|
|
|
const videoUrlList = ref<string[]>([]);
|
|
|
// 自定义不可用日期列表
|
|
|
-const dates = ref<any[]>([]);
|
|
|
+const dates = ref([]);
|
|
|
|
|
|
// 星期选项列表
|
|
|
-const weekdayList = ref<any[]>([
|
|
|
+const weekdayList = ref([
|
|
|
{ name: "周一", id: "0", oName: "星期一" },
|
|
|
{ name: "周二", id: "1", oName: "星期二" },
|
|
|
{ name: "周三", id: "2", oName: "星期三" },
|
|
|
@@ -744,7 +851,7 @@ const weekdayList = ref<any[]>([
|
|
|
]);
|
|
|
|
|
|
// 节日选项列表
|
|
|
-const holidayList = ref<any[]>([
|
|
|
+const holidayList = ref([
|
|
|
{ value: 1, label: "元旦" },
|
|
|
{ value: 2, label: "春节" },
|
|
|
{ value: 3, label: "情人节" },
|
|
|
@@ -762,17 +869,12 @@ const holidayList = ref<any[]>([
|
|
|
]);
|
|
|
|
|
|
// 菜品选项列表(这里需要根据实际API获取,暂时使用示例数据)
|
|
|
-const dishOptions = ref<any[]>([
|
|
|
- { id: 1, name: "辣炒牛肉", price: 58, image: "" },
|
|
|
- { id: 2, name: "辣炒牛肉", price: 58, image: "" },
|
|
|
- { id: 3, name: "宫保鸡丁", price: 45, image: "" },
|
|
|
- { id: 4, name: "麻婆豆腐", price: 32, image: "" }
|
|
|
-]);
|
|
|
+const dishOptions = ref([]);
|
|
|
|
|
|
// 菜品选择对话框相关
|
|
|
const dishDialogVisible = ref(false);
|
|
|
const dishSearchKeyword = ref("");
|
|
|
-const filteredDishList = ref<any[]>([]);
|
|
|
+const filteredDishList = ref([]);
|
|
|
const selectedDishId = ref<number | null>(null);
|
|
|
const currentDishGroupIndex = ref<number>(-1);
|
|
|
const currentDishIndex = ref<number>(-1);
|
|
|
@@ -796,6 +898,36 @@ watch(
|
|
|
{ immediate: true }
|
|
|
);
|
|
|
|
|
|
+/**
|
|
|
+ * 监听开始售卖时间变化
|
|
|
+ * 当开始时间改变时,重新验证结束时间
|
|
|
+ */
|
|
|
+watch(
|
|
|
+ () => storeInfoModel.value.saleTimeStr,
|
|
|
+ () => {
|
|
|
+ if (storeInfoModel.value.endTime) {
|
|
|
+ nextTick(() => {
|
|
|
+ ruleFormRef.value?.validateField("endTime");
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+/**
|
|
|
+ * 监听结束售卖时间变化
|
|
|
+ * 当结束时间改变时,重新验证开始时间
|
|
|
+ */
|
|
|
+watch(
|
|
|
+ () => storeInfoModel.value.endTime,
|
|
|
+ () => {
|
|
|
+ if (storeInfoModel.value.startTimeType === 1 && storeInfoModel.value.saleTimeStr) {
|
|
|
+ nextTick(() => {
|
|
|
+ ruleFormRef.value?.validateField("saleTimeStr");
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
// ==================== 生命周期钩子 ====================
|
|
|
|
|
|
/**
|
|
|
@@ -833,7 +965,7 @@ onMounted(async () => {
|
|
|
};
|
|
|
let res = await getHolidayList(params);
|
|
|
if (res && res.code == 200) {
|
|
|
- holidayList.value = res.data.records;
|
|
|
+ holidayList.value = res.data;
|
|
|
}
|
|
|
if (type.value != "add") {
|
|
|
let res: any = await getStoreDetail({ id: id.value } as any);
|
|
|
@@ -850,8 +982,8 @@ onMounted(async () => {
|
|
|
storeInfoModel.value.unavailableHolidays = [];
|
|
|
}
|
|
|
// 确保套餐内容字段存在
|
|
|
- if (!storeInfoModel.value.packageContent || storeInfoModel.value.packageContent.length === 0) {
|
|
|
- storeInfoModel.value.packageContent = [
|
|
|
+ if (!storeInfoModel.value.lifeGroupBuyThalis || storeInfoModel.value.lifeGroupBuyThalis.length === 0) {
|
|
|
+ storeInfoModel.value.lifeGroupBuyThalis = [
|
|
|
{
|
|
|
category: "",
|
|
|
collapsed: false,
|
|
|
@@ -868,7 +1000,7 @@ onMounted(async () => {
|
|
|
];
|
|
|
} else {
|
|
|
// 确保每个分组都有必要的字段
|
|
|
- storeInfoModel.value.packageContent.forEach((group: any) => {
|
|
|
+ storeInfoModel.value.lifeGroupBuyThalis.forEach((group: any) => {
|
|
|
if (group.collapsed === undefined) {
|
|
|
group.collapsed = false;
|
|
|
}
|
|
|
@@ -1020,10 +1152,10 @@ const toggleHoliday = value => {
|
|
|
* 添加套餐分组
|
|
|
*/
|
|
|
const addGroup = () => {
|
|
|
- if (!storeInfoModel.value.packageContent) {
|
|
|
- storeInfoModel.value.packageContent = [];
|
|
|
+ if (!storeInfoModel.value.lifeGroupBuyThalis) {
|
|
|
+ storeInfoModel.value.lifeGroupBuyThalis = [];
|
|
|
}
|
|
|
- storeInfoModel.value.packageContent.push({
|
|
|
+ storeInfoModel.value.lifeGroupBuyThalis.push({
|
|
|
category: "",
|
|
|
collapsed: false,
|
|
|
dishes: [
|
|
|
@@ -1043,7 +1175,7 @@ const addGroup = () => {
|
|
|
* @param groupIndex 分组索引
|
|
|
*/
|
|
|
const removeGroup = (groupIndex: number) => {
|
|
|
- if (storeInfoModel.value.packageContent.length <= 1) {
|
|
|
+ if (storeInfoModel.value.lifeGroupBuyThalis.length <= 1) {
|
|
|
ElMessage.warning("至少需要保留一个分组");
|
|
|
return;
|
|
|
}
|
|
|
@@ -1053,7 +1185,7 @@ const removeGroup = (groupIndex: number) => {
|
|
|
type: "warning"
|
|
|
})
|
|
|
.then(() => {
|
|
|
- storeInfoModel.value.packageContent.splice(groupIndex, 1);
|
|
|
+ storeInfoModel.value.lifeGroupBuyThalis.splice(groupIndex, 1);
|
|
|
ElMessage.success("删除成功");
|
|
|
})
|
|
|
.catch(() => {});
|
|
|
@@ -1064,7 +1196,7 @@ const removeGroup = (groupIndex: number) => {
|
|
|
* @param groupIndex 分组索引
|
|
|
*/
|
|
|
const toggleGroupCollapse = (groupIndex: number) => {
|
|
|
- storeInfoModel.value.packageContent[groupIndex].collapsed = !storeInfoModel.value.packageContent[groupIndex].collapsed;
|
|
|
+ storeInfoModel.value.lifeGroupBuyThalis[groupIndex].collapsed = !storeInfoModel.value.lifeGroupBuyThalis[groupIndex].collapsed;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
@@ -1072,10 +1204,10 @@ const toggleGroupCollapse = (groupIndex: number) => {
|
|
|
* @param groupIndex 分组索引
|
|
|
*/
|
|
|
const addDish = (groupIndex: number) => {
|
|
|
- if (!storeInfoModel.value.packageContent[groupIndex].dishes) {
|
|
|
- storeInfoModel.value.packageContent[groupIndex].dishes = [];
|
|
|
+ if (!storeInfoModel.value.lifeGroupBuyThalis[groupIndex].dishes) {
|
|
|
+ storeInfoModel.value.lifeGroupBuyThalis[groupIndex].dishes = [];
|
|
|
}
|
|
|
- storeInfoModel.value.packageContent[groupIndex].dishes.push({
|
|
|
+ storeInfoModel.value.lifeGroupBuyThalis[groupIndex].dishes.push({
|
|
|
dishId: "",
|
|
|
dishName: "",
|
|
|
dishPrice: "",
|
|
|
@@ -1090,7 +1222,7 @@ const addDish = (groupIndex: number) => {
|
|
|
* @param dishIndex 菜品索引
|
|
|
*/
|
|
|
const removeDish = (groupIndex: number, dishIndex: number) => {
|
|
|
- const dishes = storeInfoModel.value.packageContent[groupIndex].dishes;
|
|
|
+ const dishes = storeInfoModel.value.lifeGroupBuyThalis[groupIndex].dishes;
|
|
|
if (dishes.length <= 1) {
|
|
|
ElMessage.warning("至少需要保留一个菜品");
|
|
|
return;
|
|
|
@@ -1103,13 +1235,22 @@ const removeDish = (groupIndex: number, dishIndex: number) => {
|
|
|
* @param groupIndex 分组索引
|
|
|
* @param dishIndex 菜品索引
|
|
|
*/
|
|
|
-const openDishDialog = (groupIndex: number, dishIndex: number) => {
|
|
|
+const openDishDialog = async (groupIndex: number, dishIndex: number) => {
|
|
|
currentDishGroupIndex.value = groupIndex;
|
|
|
currentDishIndex.value = dishIndex;
|
|
|
dishSearchKeyword.value = "";
|
|
|
+ const params = {
|
|
|
+ storeId: 361,
|
|
|
+ phoneId: 18641153170,
|
|
|
+ dishType: 0
|
|
|
+ };
|
|
|
+ const res = await getMenuByStoreId(params);
|
|
|
+ if (res && res.code == 200) {
|
|
|
+ dishOptions.value = res.data;
|
|
|
+ }
|
|
|
filterDishList();
|
|
|
// 如果已有选中的菜品,设置选中状态
|
|
|
- const currentDish = storeInfoModel.value.packageContent[groupIndex].dishes[dishIndex];
|
|
|
+ const currentDish = storeInfoModel.value.lifeGroupBuyThalis[groupIndex].dishes[dishIndex];
|
|
|
selectedDishId.value = currentDish?.dishId || null;
|
|
|
dishDialogVisible.value = true;
|
|
|
};
|
|
|
@@ -1132,7 +1273,7 @@ const confirmDishSelection = () => {
|
|
|
}
|
|
|
const selectedDish = dishOptions.value.find(dish => dish.id === selectedDishId.value);
|
|
|
if (selectedDish && currentDishGroupIndex.value >= 0 && currentDishIndex.value >= 0) {
|
|
|
- const dish = storeInfoModel.value.packageContent[currentDishGroupIndex.value].dishes[currentDishIndex.value];
|
|
|
+ const dish = storeInfoModel.value.lifeGroupBuyThalis[currentDishGroupIndex.value].dishes[currentDishIndex.value];
|
|
|
dish.dishId = selectedDish.id;
|
|
|
dish.dishName = selectedDish.name;
|
|
|
dish.dishPrice = selectedDish.price;
|
|
|
@@ -1190,6 +1331,64 @@ const handleSubmit = type => {
|
|
|
// ==================== 工具函数 ====================
|
|
|
|
|
|
/**
|
|
|
+ * 禁用开始售卖时间的日期
|
|
|
+ * 不能选择早于当前时间的日期
|
|
|
+ * @param time 日期对象
|
|
|
+ * @returns 是否禁用该日期
|
|
|
+ */
|
|
|
+const disabledStartDate = (time: Date) => {
|
|
|
+ const today = new Date();
|
|
|
+ today.setHours(0, 0, 0, 0);
|
|
|
+ return time.getTime() < today.getTime();
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 禁用结束售卖时间的日期
|
|
|
+ * 不能选择早于当前时间的日期,也不能选择早于或等于开始售卖时间的日期
|
|
|
+ * @param time 日期对象
|
|
|
+ * @returns 是否禁用该日期
|
|
|
+ */
|
|
|
+const disabledEndDate = (time: Date) => {
|
|
|
+ const today = new Date();
|
|
|
+ today.setHours(0, 0, 0, 0);
|
|
|
+ // 不能早于当前时间
|
|
|
+ if (time.getTime() < today.getTime()) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ // 如果开始售卖时间已设置,不能早于或等于开始时间
|
|
|
+ if (storeInfoModel.value.startTimeType === 1 && storeInfoModel.value.saleTimeStr) {
|
|
|
+ const startDate = new Date(storeInfoModel.value.saleTimeStr);
|
|
|
+ startDate.setHours(0, 0, 0, 0);
|
|
|
+ return time.getTime() <= startDate.getTime();
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 禁用指定时间段内可用的日期
|
|
|
+ * 不能选择早于当前时间的日期
|
|
|
+ * @param time 日期对象
|
|
|
+ * @returns 是否禁用该日期
|
|
|
+ */
|
|
|
+const disabledEffectiveDate = (time: Date) => {
|
|
|
+ const today = new Date();
|
|
|
+ today.setHours(0, 0, 0, 0);
|
|
|
+ return time.getTime() < today.getTime();
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 禁用自定义不可用日期的日期
|
|
|
+ * 不能选择早于当前时间的日期
|
|
|
+ * @param time 日期对象
|
|
|
+ * @returns 是否禁用该日期
|
|
|
+ */
|
|
|
+const disabledCustomUnavailableDate = (time: Date) => {
|
|
|
+ const today = new Date();
|
|
|
+ today.setHours(0, 0, 0, 0);
|
|
|
+ return time.getTime() < today.getTime();
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
* 处理图片结果
|
|
|
* 将上传组件的文件对象或URL字符串转换为URL数组
|
|
|
* @param list 图片列表(可能是文件对象或URL字符串)
|
|
|
@@ -1498,7 +1697,25 @@ const handleImageParam = (list: any[], result: any[]) => {
|
|
|
max-height: 400px;
|
|
|
overflow-y: auto;
|
|
|
}
|
|
|
+.dish-empty-state {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 60px 20px;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+.empty-text {
|
|
|
+ margin-bottom: 8px;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #909399;
|
|
|
+}
|
|
|
+.empty-hint {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #c0c4cc;
|
|
|
+}
|
|
|
.dish-item {
|
|
|
+ position: relative;
|
|
|
display: flex;
|
|
|
gap: 12px;
|
|
|
align-items: center;
|
|
|
@@ -1512,6 +1729,14 @@ const handleImageParam = (list: any[], result: any[]) => {
|
|
|
background-color: #f5f7fa;
|
|
|
border-color: #409eff;
|
|
|
}
|
|
|
+.dish-item-selected {
|
|
|
+ background-color: #ecf5ff;
|
|
|
+ border-color: #409eff;
|
|
|
+ border-width: 2px;
|
|
|
+}
|
|
|
+.dish-item-selected:hover {
|
|
|
+ background-color: #d9ecff;
|
|
|
+}
|
|
|
.dish-image {
|
|
|
flex-shrink: 0;
|
|
|
width: 60px;
|
|
|
@@ -1548,6 +1773,18 @@ const handleImageParam = (list: any[], result: any[]) => {
|
|
|
font-size: 14px;
|
|
|
color: #909399;
|
|
|
}
|
|
|
+.dish-selected-icon {
|
|
|
+ display: flex;
|
|
|
+ flex-shrink: 0;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 24px;
|
|
|
+ height: 24px;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #ffffff;
|
|
|
+ background-color: #409eff;
|
|
|
+ border-radius: 50%;
|
|
|
+}
|
|
|
.dialog-footer {
|
|
|
display: flex;
|
|
|
justify-content: center;
|