|
|
@@ -13,21 +13,21 @@
|
|
|
<div class="model">
|
|
|
<h3 style="font-weight: bold">基础信息:</h3>
|
|
|
<!-- 代金券名称 -->
|
|
|
- <el-form-item label="代金券名称" prop="voucherName">
|
|
|
- <el-input maxlength="50" v-model="voucherModel.voucherName" placeholder="请输入" clearable />
|
|
|
+ <el-form-item label="代金券名称" prop="name">
|
|
|
+ <el-input maxlength="50" v-model="voucherModel.name" placeholder="请输入" clearable />
|
|
|
</el-form-item>
|
|
|
<!-- 抵扣价格 -->
|
|
|
- <el-form-item label="抵扣价格(¥)" prop="discountPrice">
|
|
|
- <el-input v-model="voucherModel.discountPrice" maxlength="15" placeholder="请输入" clearable />
|
|
|
+ <el-form-item label="抵扣价格(¥)" prop="offprice">
|
|
|
+ <el-input v-model="voucherModel.offprice" maxlength="15" placeholder="请输入" clearable />
|
|
|
</el-form-item>
|
|
|
<!-- 售卖价格 -->
|
|
|
- <el-form-item label="售卖价格(¥)" prop="sellingPrice">
|
|
|
- <el-input v-model="voucherModel.sellingPrice" maxlength="15" placeholder="请输入" clearable />
|
|
|
+ <el-form-item label="售卖价格(¥)" prop="price">
|
|
|
+ <el-input v-model="voucherModel.price" maxlength="15" placeholder="请输入" clearable />
|
|
|
</el-form-item>
|
|
|
<!-- 开始售卖时间 -->
|
|
|
- <el-form-item label="开始售卖时间" prop="startSellingTime">
|
|
|
+ <el-form-item label="开始售卖时间" prop="startDate">
|
|
|
<el-date-picker
|
|
|
- v-model="voucherModel.startSellingTime"
|
|
|
+ v-model="voucherModel.startDate"
|
|
|
format="YYYY/MM/DD"
|
|
|
value-format="YYYY-MM-DD"
|
|
|
placeholder="请选择开始售卖时间"
|
|
|
@@ -35,9 +35,9 @@
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
<!-- 结束售卖时间 -->
|
|
|
- <el-form-item label="结束售卖时间" prop="endSellingTime">
|
|
|
+ <el-form-item label="结束售卖时间" prop="endDate">
|
|
|
<el-date-picker
|
|
|
- v-model="voucherModel.endSellingTime"
|
|
|
+ v-model="voucherModel.endDate"
|
|
|
format="YYYY/MM/DD"
|
|
|
value-format="YYYY-MM-DD"
|
|
|
placeholder="请选择结束售卖时间"
|
|
|
@@ -50,28 +50,28 @@
|
|
|
<h3 style="font-weight: bold">购买须知:</h3>
|
|
|
<!-- 使用时间 -->
|
|
|
<el-form-item label="使用时间" prop="usageTime">
|
|
|
- <el-date-picker
|
|
|
- v-model="voucherModel.usageTime"
|
|
|
- type="daterange"
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
- range-separator="-"
|
|
|
- start-placeholder="开始时间"
|
|
|
- end-placeholder="结束时间"
|
|
|
- :disabled-date="disabledUsageDate"
|
|
|
- />
|
|
|
+ <div class="time-range-container">
|
|
|
+ <el-select v-model="voucherModel.buyUseStartTime" placeholder="开始时间" class="time-picker">
|
|
|
+ <el-option v-for="hour in hourOptions" :key="hour.value" :label="hour.label" :value="hour.value" />
|
|
|
+ </el-select>
|
|
|
+ <span class="time-separator">至</span>
|
|
|
+ <el-select v-model="voucherModel.buyUseEndTime" placeholder="结束时间" class="time-picker">
|
|
|
+ <el-option v-for="hour in hourOptions" :key="hour.value" :label="hour.label" :value="hour.value" />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
|
<!-- 有效期 -->
|
|
|
- <el-form-item label="有效期" prop="validityPeriodType">
|
|
|
- <el-radio-group v-model="voucherModel.validityPeriodType" class="ml-4">
|
|
|
+ <el-form-item label="有效期" prop="expirationType">
|
|
|
+ <el-radio-group v-model="voucherModel.expirationType" class="ml-4">
|
|
|
<el-radio v-for="status in validityPeriodList" :value="status.value" :key="status.value">
|
|
|
{{ status.label }}
|
|
|
</el-radio>
|
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="" prop="validityDays" v-if="voucherModel.validityPeriodType == 0">
|
|
|
+ <el-form-item label="" prop="validityDays" v-if="voucherModel.expirationType == 0">
|
|
|
<div class="expiration-date-container">
|
|
|
<span class="expiration-label">用户购买</span>
|
|
|
- <el-input-number v-model="voucherModel.validityDays" placeholder="请输入" :min="1" class="expiration-input" />
|
|
|
+ <el-input-number v-model="voucherModel.validityDays" placeholder="请输入" :min="0" class="expiration-input" />
|
|
|
<span class="expiration-label">天内有效</span>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
@@ -87,14 +87,14 @@
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
<!-- 不可用日期 -->
|
|
|
- <el-form-item label="不可用日期" prop="unavailableDateType">
|
|
|
- <el-radio-group v-model="voucherModel.unavailableDateType" class="ml-4">
|
|
|
+ <el-form-item label="不可用日期" prop="unusedType">
|
|
|
+ <el-radio-group v-model="voucherModel.unusedType" class="ml-4">
|
|
|
<el-radio v-for="status in unavailableDateTypeList" :value="status.value" :key="status.value">
|
|
|
{{ status.label }}
|
|
|
</el-radio>
|
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
|
- <template v-if="voucherModel.unavailableDateType == 1">
|
|
|
+ <template v-if="voucherModel.unusedType == 1">
|
|
|
<el-form-item label="" prop="unavailableWeekdays">
|
|
|
<div class="unavailable-dates-container">
|
|
|
<!-- 星期选择 -->
|
|
|
@@ -123,7 +123,7 @@
|
|
|
<el-button
|
|
|
v-for="holiday in holidayList"
|
|
|
:key="holiday.id"
|
|
|
- :type="voucherModel.unavailableHolidays?.includes(holiday.id) ? 'primary' : ''"
|
|
|
+ :type="voucherModel.unavailableHolidays?.includes(String(holiday.id)) ? 'primary' : ''"
|
|
|
class="date-select-btn"
|
|
|
@click="toggleHoliday(holiday.id)"
|
|
|
>
|
|
|
@@ -134,12 +134,12 @@
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
</template>
|
|
|
- <el-form-item label="" prop="customUnavailableDates" v-else-if="voucherModel.unavailableDateType == 2">
|
|
|
+ <el-form-item label="" prop="customUnavailableDates" v-else-if="voucherModel.unusedType == 2">
|
|
|
<div class="date-picker-container">
|
|
|
<el-button :icon="Plus" class="add-date-btn" type="primary" @click="addDate"> 添加日期 </el-button>
|
|
|
- <div v-for="(item, index) in dates" :key="index" class="date-item">
|
|
|
+ <div v-for="(item, index) in voucherModel.disableDateList" :key="index" class="date-item">
|
|
|
<el-date-picker
|
|
|
- v-model="dates[index]"
|
|
|
+ v-model="voucherModel.disableDateList[index]"
|
|
|
type="daterange"
|
|
|
value-format="YYYY-MM-DD"
|
|
|
range-separator="-"
|
|
|
@@ -155,7 +155,7 @@
|
|
|
size="small"
|
|
|
class="delete-btn"
|
|
|
@click="removeDate(index)"
|
|
|
- v-show="dates.length > 1"
|
|
|
+ v-show="voucherModel.disableDateList.length > 1"
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -167,33 +167,33 @@
|
|
|
<!-- 库存模块 -->
|
|
|
<div class="model">
|
|
|
<h3 style="font-weight: bold">库存:</h3>
|
|
|
- <el-form-item label="库存" prop="inventory">
|
|
|
- <el-input v-model="voucherModel.inventory" maxlength="15" placeholder="请输入" clearable />
|
|
|
+ <el-form-item label="库存" prop="singleQty">
|
|
|
+ <el-input v-model="voucherModel.singleQty" maxlength="15" placeholder="请输入" clearable />
|
|
|
</el-form-item>
|
|
|
</div>
|
|
|
<!-- 使用规则模块 -->
|
|
|
<div class="model">
|
|
|
<h3 style="font-weight: bold">使用规则:</h3>
|
|
|
<!-- 单日可用数量 -->
|
|
|
- <el-form-item label="单日可用数量" prop="dailyAvailableQuantity">
|
|
|
- <el-input v-model="voucherModel.dailyAvailableQuantity" maxlength="15" placeholder="请输入" clearable />
|
|
|
+ <el-form-item label="单日可用数量" prop="singleCanUse">
|
|
|
+ <el-input v-model="voucherModel.singleCanUse" maxlength="15" placeholder="请输入" clearable />
|
|
|
</el-form-item>
|
|
|
<!-- 限购数量 -->
|
|
|
- <el-form-item label="限购数量" prop="purchaseLimitQuantity">
|
|
|
- <el-input v-model="voucherModel.purchaseLimitQuantity" maxlength="15" placeholder="请输入" clearable />
|
|
|
+ <el-form-item label="限购数量" prop="purchaseLimitCode">
|
|
|
+ <el-input v-model="voucherModel.purchaseLimitCode" maxlength="15" placeholder="请输入" clearable />
|
|
|
</el-form-item>
|
|
|
<!-- 适用范围 -->
|
|
|
- <el-form-item label="适用范围" prop="applicableScopeType">
|
|
|
- <el-radio-group v-model="voucherModel.applicableScopeType" class="ml-4">
|
|
|
+ <el-form-item label="适用范围" prop="applyType">
|
|
|
+ <el-radio-group v-model="voucherModel.applyType" class="ml-4">
|
|
|
<el-radio v-for="status in applicableScopeList" :value="status.value" :key="status.value">
|
|
|
{{ status.label }}
|
|
|
</el-radio>
|
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="" prop="applicableScope" v-if="voucherModel.applicableScopeType == 1">
|
|
|
+ <el-form-item label="" prop="applyDesc" v-if="voucherModel.applyType == 2">
|
|
|
<el-input
|
|
|
maxlength="50"
|
|
|
- v-model="voucherModel.applicableScope"
|
|
|
+ v-model="voucherModel.applyDesc"
|
|
|
:rows="3"
|
|
|
type="textarea"
|
|
|
placeholder="请输入"
|
|
|
@@ -204,10 +204,10 @@
|
|
|
<!-- 补充说明模块 -->
|
|
|
<div class="model">
|
|
|
<h3 style="font-weight: bold">补充说明:</h3>
|
|
|
- <el-form-item label="补充说明" prop="additionalInstructions">
|
|
|
+ <el-form-item label="补充说明" prop="supplement">
|
|
|
<el-input
|
|
|
maxlength="300"
|
|
|
- v-model="voucherModel.additionalInstructions"
|
|
|
+ v-model="voucherModel.supplement"
|
|
|
:rows="4"
|
|
|
type="textarea"
|
|
|
placeholder="请输入"
|
|
|
@@ -221,7 +221,7 @@
|
|
|
<!-- 底部按钮区域 -->
|
|
|
<div class="button-container">
|
|
|
<el-button @click="handleSubmit('draft')"> 存草稿 </el-button>
|
|
|
- <el-button type="primary" @click="handleSubmit"> 新建代金券 </el-button>
|
|
|
+ <el-button type="primary" @click="handleSubmit()"> 新建代金券 </el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
@@ -233,9 +233,10 @@
|
|
|
*/
|
|
|
import { ref, reactive, watch, nextTick, onMounted } from "vue";
|
|
|
import { ElMessage } from "element-plus";
|
|
|
+import { Plus, Delete } from "@element-plus/icons-vue";
|
|
|
import { useRoute, useRouter } from "vue-router";
|
|
|
import type { FormInstance } from "element-plus";
|
|
|
-import { getVoucherDetail } from "@/api/modules/voucherManagement";
|
|
|
+import { getVoucherDetail, getHolidayList } from "@/api/modules/voucherManagement";
|
|
|
import {
|
|
|
validatePositiveNumber,
|
|
|
validatePositiveInteger,
|
|
|
@@ -258,27 +259,27 @@ const id = ref<string>(""); // 页面ID参数
|
|
|
|
|
|
// ==================== 表单验证规则 ====================
|
|
|
const rules = reactive({
|
|
|
- voucherName: [{ required: true, message: "请输入代金券名称" }],
|
|
|
- discountPrice: [
|
|
|
+ name: [{ required: true, message: "请输入代金券名称" }],
|
|
|
+ offprice: [
|
|
|
{ required: true, message: "请输入抵扣价格" },
|
|
|
{
|
|
|
validator: validatePositiveNumber("抵扣价格必须为正数"),
|
|
|
trigger: "blur"
|
|
|
}
|
|
|
],
|
|
|
- sellingPrice: [
|
|
|
+ price: [
|
|
|
{ required: true, message: "请输入售卖价格" },
|
|
|
{
|
|
|
validator: validatePositiveNumber("售卖价格必须为正数"),
|
|
|
trigger: "blur"
|
|
|
}
|
|
|
],
|
|
|
- startSellingTime: [
|
|
|
+ startDate: [
|
|
|
{ required: true, message: "请选择开始售卖时间" },
|
|
|
{
|
|
|
validator: validateDateRange(
|
|
|
- () => voucherModel.value.startSellingTime,
|
|
|
- () => voucherModel.value.endSellingTime,
|
|
|
+ () => voucherModel.value.startDate,
|
|
|
+ () => voucherModel.value.endDate,
|
|
|
"开始售卖时间不能早于当前时间",
|
|
|
"结束售卖时间不能早于当前时间",
|
|
|
"开始售卖时间必须早于结束售卖时间",
|
|
|
@@ -287,12 +288,12 @@ const rules = reactive({
|
|
|
trigger: "change"
|
|
|
}
|
|
|
],
|
|
|
- endSellingTime: [
|
|
|
+ endDate: [
|
|
|
{ required: true, message: "请选择结束售卖时间" },
|
|
|
{
|
|
|
validator: validateDateRange(
|
|
|
- () => voucherModel.value.startSellingTime,
|
|
|
- () => voucherModel.value.endSellingTime,
|
|
|
+ () => voucherModel.value.startDate,
|
|
|
+ () => voucherModel.value.endDate,
|
|
|
"开始售卖时间不能早于当前时间",
|
|
|
"结束售卖时间不能早于当前时间",
|
|
|
"开始售卖时间必须早于结束售卖时间",
|
|
|
@@ -302,28 +303,36 @@ const rules = reactive({
|
|
|
}
|
|
|
],
|
|
|
usageTime: [
|
|
|
- { required: true, message: "请选择使用时间" },
|
|
|
{
|
|
|
- validator: validateDateRangeArray("使用开始时间必须早于结束时间"),
|
|
|
- trigger: "change"
|
|
|
+ required: true,
|
|
|
+ validator: (rule: any, value: any, callback: any) => {
|
|
|
+ if (!voucherModel.value.buyUseStartTime || !voucherModel.value.buyUseEndTime) {
|
|
|
+ callback(new Error("请选择使用时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ callback();
|
|
|
+ },
|
|
|
+ trigger: []
|
|
|
}
|
|
|
],
|
|
|
- validityPeriodType: [{ required: true, message: "请选择有效期类型" }],
|
|
|
+ expirationType: [{ required: true, message: "请选择有效期类型" }],
|
|
|
validityDays: [
|
|
|
{
|
|
|
required: true,
|
|
|
validator: (rule: any, value: any, callback: any) => {
|
|
|
- if (voucherModel.value.validityPeriodType === 0) {
|
|
|
+ if (voucherModel.value.expirationType == 0) {
|
|
|
if (value === null || value === undefined || value === "") {
|
|
|
callback(new Error("请输入用户购买天数"));
|
|
|
return;
|
|
|
}
|
|
|
- if (value <= 0) {
|
|
|
- callback(new Error("天数必须大于0"));
|
|
|
- return;
|
|
|
- }
|
|
|
+ validatePositiveInteger("用户购买天数必须为正整数", { required: false, checkLeadingZero: false })(
|
|
|
+ rule,
|
|
|
+ value,
|
|
|
+ callback
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ callback();
|
|
|
}
|
|
|
- callback();
|
|
|
},
|
|
|
trigger: "blur"
|
|
|
}
|
|
|
@@ -331,13 +340,13 @@ const rules = reactive({
|
|
|
validityPeriod: [
|
|
|
{
|
|
|
required: true,
|
|
|
- validator: validateConditionalRequired(() => voucherModel.value.validityPeriodType === 1, "请选择指定时间段"),
|
|
|
- trigger: "change"
|
|
|
- },
|
|
|
- {
|
|
|
validator: (rule: any, value: any, callback: any) => {
|
|
|
- if (voucherModel.value.validityPeriodType === 1 && value && value.length === 2) {
|
|
|
- validateDateRangeArray("开始时间必须早于结束时间")(rule, value, callback);
|
|
|
+ if (voucherModel.value.expirationType == 1) {
|
|
|
+ if (!value || value.length !== 2) {
|
|
|
+ callback(new Error("请选择指定时间段"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ validateDateRangeArray("开始时间必须早于结束时间", true, "时间不能早于当前时间")(rule, value, callback);
|
|
|
} else {
|
|
|
callback();
|
|
|
}
|
|
|
@@ -345,55 +354,72 @@ const rules = reactive({
|
|
|
trigger: "change"
|
|
|
}
|
|
|
],
|
|
|
- unavailableDateType: [{ required: true, message: "请选择不可用日期类型" }],
|
|
|
+ unusedType: [{ required: true, message: "请选择不可用日期类型" }],
|
|
|
unavailableWeekdays: [
|
|
|
{
|
|
|
- validator: validateConditionalRequired(() => voucherModel.value.unavailableDateType === 1, "至少需要选择一个星期"),
|
|
|
+ validator: validateConditionalRequired(() => voucherModel.value.unusedType == 1, "至少需要选择一个星期"),
|
|
|
trigger: "change"
|
|
|
}
|
|
|
],
|
|
|
unavailableHolidays: [
|
|
|
{
|
|
|
- validator: validateConditionalRequired(() => voucherModel.value.unavailableDateType === 1, "至少需要选择一个节日"),
|
|
|
+ validator: validateConditionalRequired(() => voucherModel.value.unusedType == 1, "至少需要选择一个节日"),
|
|
|
trigger: "change"
|
|
|
}
|
|
|
],
|
|
|
customUnavailableDates: [
|
|
|
{
|
|
|
- validator: validateConditionalRequired(
|
|
|
- () => voucherModel.value.unavailableDateType === 2,
|
|
|
- "至少需要添加一个自定义不可用日期"
|
|
|
- ),
|
|
|
- trigger: "change"
|
|
|
- },
|
|
|
- {
|
|
|
- validator: validateDateListArray(() => dates.value, "日期项未完整填写", "开始时间必须早于结束时间", false),
|
|
|
+ required: true,
|
|
|
+ validator: (rule: any, value: any, callback: any) => {
|
|
|
+ if (voucherModel.value.unusedType == 2) {
|
|
|
+ if (!voucherModel.value.disableDateList || voucherModel.value.disableDateList.length === 0) {
|
|
|
+ callback(new Error("至少需要添加一个自定义不可用日期"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ validateDateListArray(
|
|
|
+ () => voucherModel.value.disableDateList,
|
|
|
+ "日期项未完整填写",
|
|
|
+ "开始时间必须早于结束时间",
|
|
|
+ true
|
|
|
+ )(rule, value, callback);
|
|
|
+ } else {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ },
|
|
|
trigger: "change"
|
|
|
}
|
|
|
],
|
|
|
- inventory: [
|
|
|
+ singleQty: [
|
|
|
{ required: true, message: "请输入库存" },
|
|
|
{
|
|
|
validator: validatePositiveInteger("库存必须为正整数", { required: false }),
|
|
|
trigger: "blur"
|
|
|
}
|
|
|
],
|
|
|
- dailyAvailableQuantity: [
|
|
|
+ singleCanUse: [
|
|
|
{
|
|
|
validator: validatePositiveInteger("单日可用数量必须为正整数", { required: false }),
|
|
|
trigger: "blur"
|
|
|
}
|
|
|
],
|
|
|
- purchaseLimitQuantity: [
|
|
|
+ purchaseLimitCode: [
|
|
|
{
|
|
|
validator: validatePositiveInteger("限购数量必须为正整数", { required: false }),
|
|
|
trigger: "blur"
|
|
|
}
|
|
|
],
|
|
|
- applicableScopeType: [{ required: true, message: "请选择适用范围类型" }],
|
|
|
- applicableScope: [
|
|
|
+ applyDesc: [
|
|
|
{
|
|
|
- validator: validateConditionalRequired(() => voucherModel.value.applicableScopeType === 1, "请输入适用范围"),
|
|
|
+ required: true,
|
|
|
+ validator: (rule: any, value: any, callback: any) => {
|
|
|
+ if (voucherModel.value.applyType == 2) {
|
|
|
+ if (!value || value.toString().trim() === "") {
|
|
|
+ callback(new Error("请输入适用范围"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ callback();
|
|
|
+ },
|
|
|
trigger: "blur"
|
|
|
}
|
|
|
]
|
|
|
@@ -402,45 +428,59 @@ const rules = reactive({
|
|
|
// ==================== 代金券信息数据模型 ====================
|
|
|
const voucherModel = ref<any>({
|
|
|
// 代金券名称
|
|
|
- voucherName: "",
|
|
|
+ name: "",
|
|
|
// 抵扣价格
|
|
|
- discountPrice: "",
|
|
|
+ offprice: "",
|
|
|
// 售卖价格
|
|
|
- sellingPrice: "",
|
|
|
+ price: "",
|
|
|
// 开始售卖时间
|
|
|
- startSellingTime: "",
|
|
|
+ startDate: "",
|
|
|
// 结束售卖时间
|
|
|
- endSellingTime: "",
|
|
|
- // 使用时间
|
|
|
- usageTime: [],
|
|
|
+ endDate: "",
|
|
|
+ // 使用时间 - 开始时间
|
|
|
+ buyUseStartTime: "",
|
|
|
+ // 使用时间 - 结束时间
|
|
|
+ buyUseEndTime: "",
|
|
|
+ // 使用时间(虚拟字段,用于表单验证)
|
|
|
+ usageTime: null,
|
|
|
// 有效期类型:0-指定天数,1-指定时间段内可用
|
|
|
- validityPeriodType: 0,
|
|
|
- // 有效期天数(当validityPeriodType为0时使用)
|
|
|
- validityDays: 90,
|
|
|
- // 有效期时间段(当validityPeriodType为1时使用)
|
|
|
+ expirationType: 0,
|
|
|
+ // 有效期天数(当expirationType为0时使用)
|
|
|
+ validityDays: 0,
|
|
|
+ // 有效期时间段(当expirationType为1时使用)
|
|
|
validityPeriod: [],
|
|
|
- // 不可用日期类型:0-全部日期可用,1-限制日期,2-自定义不可用日期
|
|
|
- unavailableDateType: 0,
|
|
|
+ // 不可用日期类型:0-全部日期可用,1-限制日期
|
|
|
+ unusedType: 0,
|
|
|
// 限制日期 - 星期选择(数组,存储选中的星期值)
|
|
|
unavailableWeekdays: [],
|
|
|
// 限制日期 - 节日选择(数组,存储选中的节日值)
|
|
|
unavailableHolidays: [],
|
|
|
+ // 自定义不可用日期列表(数组,每个元素是一个日期范围 [startDate, endDate])
|
|
|
+ disableDateList: [],
|
|
|
// 库存
|
|
|
- inventory: "",
|
|
|
+ singleQty: "",
|
|
|
// 单日可用数量
|
|
|
- dailyAvailableQuantity: "",
|
|
|
+ singleCanUse: "",
|
|
|
// 限购数量
|
|
|
- purchaseLimitQuantity: "",
|
|
|
+ purchaseLimitCode: "",
|
|
|
// 适用范围类型:0-全场通用,1-部分不可用
|
|
|
- applicableScopeType: 0,
|
|
|
- // 适用范围(当applicableScopeType为1时使用)
|
|
|
- applicableScope: "",
|
|
|
+ applyType: 1,
|
|
|
+ // 适用范围(当applyType为1时使用)
|
|
|
+ applyDesc: "",
|
|
|
// 补充说明
|
|
|
- additionalInstructions: ""
|
|
|
+ supplement: ""
|
|
|
});
|
|
|
|
|
|
// ==================== 下拉选项数据 ====================
|
|
|
|
|
|
+// 小时选项列表(0-23点)
|
|
|
+const hourOptions = ref(
|
|
|
+ Array.from({ length: 24 }, (_, i) => ({
|
|
|
+ value: String(i),
|
|
|
+ label: `${i}点`
|
|
|
+ }))
|
|
|
+);
|
|
|
+
|
|
|
// 有效期类型列表
|
|
|
const validityPeriodList = ref([
|
|
|
{ value: 0, label: "指定天数" },
|
|
|
@@ -456,13 +496,10 @@ const unavailableDateTypeList = ref([
|
|
|
|
|
|
// 适用范围类型列表
|
|
|
const applicableScopeList = ref([
|
|
|
- { value: 0, label: "全场通用" },
|
|
|
- { value: 1, label: "部分不可用" }
|
|
|
+ { value: 1, label: "全场通用" },
|
|
|
+ { value: 2, label: "部分不可用" }
|
|
|
]);
|
|
|
|
|
|
-// 自定义不可用日期列表
|
|
|
-const dates = ref([]);
|
|
|
-
|
|
|
// 星期选项列表
|
|
|
const weekdayList = ref([
|
|
|
{ name: "周一", id: "0", oName: "星期一" },
|
|
|
@@ -480,31 +517,15 @@ const holidayList: any = ref([]);
|
|
|
// ==================== 监听器 ====================
|
|
|
|
|
|
/**
|
|
|
- * 监听不可用日期选项变化
|
|
|
- * 当切换到自定义不可用日期时,确保至少有一个日期项
|
|
|
- */
|
|
|
-watch(
|
|
|
- () => voucherModel.value.unavailableDateType,
|
|
|
- newVal => {
|
|
|
- if (newVal === 2) {
|
|
|
- if (!dates.value || dates.value.length === 0) {
|
|
|
- dates.value = [null];
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- { immediate: true }
|
|
|
-);
|
|
|
-
|
|
|
-/**
|
|
|
* 监听开始售卖时间变化
|
|
|
* 当开始时间改变时,重新验证结束时间
|
|
|
*/
|
|
|
watch(
|
|
|
- () => voucherModel.value.startSellingTime,
|
|
|
+ () => voucherModel.value.startDate,
|
|
|
() => {
|
|
|
- if (voucherModel.value.endSellingTime) {
|
|
|
+ if (voucherModel.value.endDate) {
|
|
|
nextTick(() => {
|
|
|
- ruleFormRef.value?.validateField("endSellingTime");
|
|
|
+ ruleFormRef.value?.validateField("endDate");
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
@@ -515,16 +536,63 @@ watch(
|
|
|
* 当结束时间改变时,重新验证开始时间
|
|
|
*/
|
|
|
watch(
|
|
|
- () => voucherModel.value.endSellingTime,
|
|
|
+ () => voucherModel.value.endDate,
|
|
|
() => {
|
|
|
- if (voucherModel.value.startSellingTime) {
|
|
|
+ if (voucherModel.value.startDate) {
|
|
|
nextTick(() => {
|
|
|
- ruleFormRef.value?.validateField("startSellingTime");
|
|
|
+ ruleFormRef.value?.validateField("startDate");
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
);
|
|
|
|
|
|
+/**
|
|
|
+ * 监听使用开始时间变化
|
|
|
+ * 更新虚拟字段以支持表单验证
|
|
|
+ */
|
|
|
+watch(
|
|
|
+ () => voucherModel.value.buyUseStartTime,
|
|
|
+ () => {
|
|
|
+ // 更新虚拟字段
|
|
|
+ voucherModel.value.usageTime =
|
|
|
+ voucherModel.value.buyUseStartTime && voucherModel.value.buyUseEndTime
|
|
|
+ ? [voucherModel.value.buyUseStartTime, voucherModel.value.buyUseEndTime]
|
|
|
+ : null;
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+/**
|
|
|
+ * 监听使用结束时间变化
|
|
|
+ * 更新虚拟字段以支持表单验证
|
|
|
+ */
|
|
|
+watch(
|
|
|
+ () => voucherModel.value.buyUseEndTime,
|
|
|
+ () => {
|
|
|
+ // 更新虚拟字段
|
|
|
+ voucherModel.value.usageTime =
|
|
|
+ voucherModel.value.buyUseStartTime && voucherModel.value.buyUseEndTime
|
|
|
+ ? [voucherModel.value.buyUseStartTime, voucherModel.value.buyUseEndTime]
|
|
|
+ : null;
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+/**
|
|
|
+ * 监听不可用日期类型变化
|
|
|
+ * 当切换到自定义不可用日期时,确保至少有一个日期项
|
|
|
+ */
|
|
|
+watch(
|
|
|
+ () => voucherModel.value.unusedType,
|
|
|
+ newVal => {
|
|
|
+ if (newVal == 2) {
|
|
|
+ // 切换到自定义不可用日期时,如果disableDateList为空,则添加一个默认项
|
|
|
+ if (!voucherModel.value.disableDateList || voucherModel.value.disableDateList.length === 0) {
|
|
|
+ voucherModel.value.disableDateList = [null];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { immediate: true }
|
|
|
+);
|
|
|
+
|
|
|
// ==================== 生命周期钩子 ====================
|
|
|
|
|
|
/**
|
|
|
@@ -534,13 +602,40 @@ watch(
|
|
|
onMounted(async () => {
|
|
|
id.value = (route.query.id as string) || "";
|
|
|
type.value = (route.query.type as string) || "";
|
|
|
+
|
|
|
+ // 加载节日列表
|
|
|
+ let params = {
|
|
|
+ year: new Date().getFullYear(),
|
|
|
+ page: 1,
|
|
|
+ size: 500,
|
|
|
+ openFlag: 1,
|
|
|
+ holidayName: ""
|
|
|
+ };
|
|
|
+ let res: any = await getHolidayList(params);
|
|
|
+ if (res && res.code == 200) {
|
|
|
+ holidayList.value = res.data.records;
|
|
|
+ }
|
|
|
+
|
|
|
// 编辑模式下加载数据
|
|
|
if (type.value != "add") {
|
|
|
// TODO: 加载代金券详情数据
|
|
|
// let res: any = await getVoucherDetail({ id: id.value });
|
|
|
// voucherModel.value = res.data;
|
|
|
+ // 确保星期和节日字段存在
|
|
|
+ // if (voucherModel.value.unusedType == 1) {
|
|
|
+ // const listVal = voucherModel.value.unusedDate ? voucherModel.value.unusedDate.split(";") : [];
|
|
|
+ // voucherModel.value.unavailableWeekdays = listVal[0] ? listVal[0].split(",").filter((item: string) => item) : [];
|
|
|
+ // voucherModel.value.unavailableHolidays = listVal[1] ? listVal[1].split(",").filter((item: string) => item) : [];
|
|
|
+ // }
|
|
|
+ // 确保自定义不可用日期字段存在
|
|
|
+ // if (voucherModel.value.unusedType === 2) {
|
|
|
+ // if (!voucherModel.value.disableDateList || voucherModel.value.disableDateList.length === 0) {
|
|
|
+ // voucherModel.value.disableDateList = [null];
|
|
|
+ // }
|
|
|
+ // }
|
|
|
}
|
|
|
});
|
|
|
+
|
|
|
// ==================== 事件处理函数 ====================
|
|
|
|
|
|
/**
|
|
|
@@ -551,25 +646,6 @@ const goBack = () => {
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * 添加自定义不可用日期
|
|
|
- */
|
|
|
-const addDate = () => {
|
|
|
- dates.value.push(null);
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * 删除自定义不可用日期
|
|
|
- * @param index 要删除的日期索引
|
|
|
- */
|
|
|
-const removeDate = (index: number) => {
|
|
|
- if (dates.value.length <= 1) {
|
|
|
- ElMessage.warning("至少需要保留一个日期项");
|
|
|
- return;
|
|
|
- }
|
|
|
- dates.value.splice(index, 1);
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
* 切换星期选择
|
|
|
* @param value 星期值
|
|
|
*/
|
|
|
@@ -597,11 +673,13 @@ const toggleHoliday = (value: string | number) => {
|
|
|
if (!voucherModel.value.unavailableHolidays) {
|
|
|
voucherModel.value.unavailableHolidays = [];
|
|
|
}
|
|
|
- const index = voucherModel.value.unavailableHolidays.indexOf(value);
|
|
|
+ // 统一转换为字符串进行比较
|
|
|
+ const valueStr = String(value);
|
|
|
+ const index = voucherModel.value.unavailableHolidays.findIndex((item: any) => String(item) === valueStr);
|
|
|
if (index > -1) {
|
|
|
voucherModel.value.unavailableHolidays.splice(index, 1);
|
|
|
} else {
|
|
|
- voucherModel.value.unavailableHolidays.push(value);
|
|
|
+ voucherModel.value.unavailableHolidays.push(valueStr);
|
|
|
}
|
|
|
// 触发表单验证
|
|
|
nextTick(() => {
|
|
|
@@ -609,6 +687,32 @@ const toggleHoliday = (value: string | number) => {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * 添加自定义不可用日期
|
|
|
+ */
|
|
|
+const addDate = () => {
|
|
|
+ if (!voucherModel.value.disableDateList) {
|
|
|
+ voucherModel.value.disableDateList = [];
|
|
|
+ }
|
|
|
+ voucherModel.value.disableDateList.push(null);
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 删除自定义不可用日期
|
|
|
+ * @param index 要删除的日期索引
|
|
|
+ */
|
|
|
+const removeDate = (index: number) => {
|
|
|
+ if (voucherModel.value.disableDateList.length <= 1) {
|
|
|
+ ElMessage.warning("至少需要保留一个日期项");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ voucherModel.value.disableDateList.splice(index, 1);
|
|
|
+ // 删除日期项后,重新验证表单以清除旧的验证错误
|
|
|
+ nextTick(() => {
|
|
|
+ ruleFormRef.value?.validateField("customUnavailableDates");
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
// ==================== 表单引用 ====================
|
|
|
const ruleFormRef = ref<FormInstance>(); // 表单引用
|
|
|
|
|
|
@@ -617,34 +721,36 @@ const ruleFormRef = ref<FormInstance>(); // 表单引用
|
|
|
* 验证表单,通过后调用相应的API接口
|
|
|
*/
|
|
|
const handleSubmit = (submitType?: string) => {
|
|
|
- // 验证表单
|
|
|
- ruleFormRef.value!.validate(async (valid: boolean) => {
|
|
|
- if (!valid) return;
|
|
|
-
|
|
|
- // 组装提交参数
|
|
|
- let params: any = { ...voucherModel.value };
|
|
|
-
|
|
|
- // 处理有效期
|
|
|
- if (params.validityPeriodType === 0) {
|
|
|
- params.validityPeriodStr = `用户购买${params.validityDays}天内有效`;
|
|
|
- } else {
|
|
|
- params.validityPeriodStr = params.validityPeriod.join(",");
|
|
|
- }
|
|
|
-
|
|
|
- // 处理不可用日期
|
|
|
- if (params.unavailableDateType === 1) {
|
|
|
- params.unavailableDateValue = params.unavailableWeekdays.join(",") + ";" + params.unavailableHolidays.join(",");
|
|
|
- } else if (params.unavailableDateType === 2) {
|
|
|
- params.unavailableDateValue = dates.value.map((subArray: any) => subArray.join(",")).join(";");
|
|
|
+ // 组装提交参数
|
|
|
+ let params: any = { ...voucherModel.value };
|
|
|
+ // 处理有效期
|
|
|
+ if (params.expirationType == 1) {
|
|
|
+ params.validityPeriod = params.validityPeriod.join(",");
|
|
|
+ }
|
|
|
+ // 处理不可用日期
|
|
|
+ if (params.unusedType == 1) {
|
|
|
+ params.unusedDate = params.unavailableWeekdays.join(",") + ";" + params.unavailableHolidays.join(",");
|
|
|
+ } else if (params.unusedType == 2) {
|
|
|
+ // 处理自定义不可用日期
|
|
|
+ if (params.disableDateList && params.disableDateList.length > 0) {
|
|
|
+ params.unusedDate = params.disableDateList
|
|
|
+ .map((dateRange: any) => (dateRange && dateRange.length === 2 ? dateRange.join(",") : ""))
|
|
|
+ .filter((item: string) => item)
|
|
|
+ .join(";");
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- // 处理使用时间
|
|
|
- if (params.usageTime && params.usageTime.length === 2) {
|
|
|
- params.usageStartTime = params.usageTime[0];
|
|
|
- params.usageEndTime = params.usageTime[1];
|
|
|
- }
|
|
|
+ delete params.unavailableWeekdays;
|
|
|
+ delete params.unavailableHolidays;
|
|
|
+ delete params.disableDateList;
|
|
|
+ console.log("提交参数:", params);
|
|
|
+ if (submitType) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- console.log("提交参数:", params);
|
|
|
+ // 验证表单
|
|
|
+ ruleFormRef.value!.validate(async (valid: boolean) => {
|
|
|
+ if (!valid) return;
|
|
|
|
|
|
// TODO: 调用API保存数据
|
|
|
// if (submitType === 'draft') {
|
|
|
@@ -684,8 +790,8 @@ const disabledEndDate = (time: Date) => {
|
|
|
if (time.getTime() < today.getTime()) {
|
|
|
return true;
|
|
|
}
|
|
|
- if (voucherModel.value.startSellingTime) {
|
|
|
- const startDate = new Date(voucherModel.value.startSellingTime);
|
|
|
+ if (voucherModel.value.startDate) {
|
|
|
+ const startDate = new Date(voucherModel.value.startDate);
|
|
|
startDate.setHours(0, 0, 0, 0);
|
|
|
return time.getTime() <= startDate.getTime();
|
|
|
}
|
|
|
@@ -693,24 +799,27 @@ const disabledEndDate = (time: Date) => {
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * 禁用使用时间的日期
|
|
|
- */
|
|
|
-const disabledUsageDate = (time: Date) => {
|
|
|
- return false; // 可以根据需要添加限制
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
* 禁用有效期时间段的日期
|
|
|
+ * 不能选择早于当前时间的日期
|
|
|
+ * @param time 日期对象
|
|
|
+ * @returns 是否禁用该日期
|
|
|
*/
|
|
|
const disabledValidityDate = (time: Date) => {
|
|
|
- return false; // 可以根据需要添加限制
|
|
|
+ const today = new Date();
|
|
|
+ today.setHours(0, 0, 0, 0);
|
|
|
+ return time.getTime() < today.getTime();
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 禁用自定义不可用日期的日期
|
|
|
+ * 不能选择早于当前时间的日期
|
|
|
+ * @param time 日期对象
|
|
|
+ * @returns 是否禁用该日期
|
|
|
*/
|
|
|
const disabledCustomUnavailableDate = (time: Date) => {
|
|
|
- return false; // 可以根据需要添加限制
|
|
|
+ const today = new Date();
|
|
|
+ today.setHours(0, 0, 0, 0);
|
|
|
+ return time.getTime() < today.getTime();
|
|
|
};
|
|
|
</script>
|
|
|
|
|
|
@@ -780,44 +889,6 @@ const disabledCustomUnavailableDate = (time: Date) => {
|
|
|
margin-top: 20px;
|
|
|
}
|
|
|
|
|
|
-/* 日期选择器容器 */
|
|
|
-.date-picker-container {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- gap: 12px;
|
|
|
- width: 100%;
|
|
|
-}
|
|
|
-
|
|
|
-/* 添加日期按钮 */
|
|
|
-.add-date-btn {
|
|
|
- width: fit-content;
|
|
|
- margin-bottom: 8px;
|
|
|
-}
|
|
|
-
|
|
|
-/* 日期项容器 */
|
|
|
-.date-item {
|
|
|
- display: flex;
|
|
|
- gap: 12px;
|
|
|
- align-items: center;
|
|
|
- padding: 8px;
|
|
|
- border-radius: 4px;
|
|
|
- transition: background-color 0.3s;
|
|
|
- &:hover {
|
|
|
- background-color: #ecf5ff;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/* 日期选择器 */
|
|
|
-.date-item .date-picker {
|
|
|
- flex: 1;
|
|
|
- max-width: 500px;
|
|
|
-}
|
|
|
-
|
|
|
-/* 删除按钮 */
|
|
|
-.date-item .delete-btn {
|
|
|
- flex-shrink: 0;
|
|
|
-}
|
|
|
-
|
|
|
/* 有效期天数容器 */
|
|
|
.expiration-date-container {
|
|
|
display: flex;
|
|
|
@@ -877,6 +948,65 @@ const disabledCustomUnavailableDate = (time: Date) => {
|
|
|
margin: 0;
|
|
|
font-size: 14px;
|
|
|
border-radius: 4px;
|
|
|
- transition: all 0.3s;
|
|
|
+ transition: all 0.1s;
|
|
|
+}
|
|
|
+
|
|
|
+/* 日期选择器容器 */
|
|
|
+.date-picker-container {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12px;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+/* 添加日期按钮 */
|
|
|
+.add-date-btn {
|
|
|
+ width: fit-content;
|
|
|
+ margin-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 日期项容器 */
|
|
|
+.date-item {
|
|
|
+ display: flex;
|
|
|
+ gap: 12px;
|
|
|
+ align-items: center;
|
|
|
+ padding: 8px;
|
|
|
+ border-radius: 4px;
|
|
|
+ transition: background-color 0.1s;
|
|
|
+ &:hover {
|
|
|
+ background-color: #ecf5ff;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 日期选择器 */
|
|
|
+.date-item .date-picker {
|
|
|
+ flex: 1;
|
|
|
+ max-width: 500px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 删除按钮 */
|
|
|
+.date-item .delete-btn {
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* 时间范围容器 */
|
|
|
+.time-range-container {
|
|
|
+ display: flex;
|
|
|
+ gap: 12px;
|
|
|
+ align-items: center;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+/* 时间选择器 */
|
|
|
+.time-picker {
|
|
|
+ flex: 1;
|
|
|
+ max-width: 200px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 时间分隔符 */
|
|
|
+.time-separator {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #606266;
|
|
|
+ white-space: nowrap;
|
|
|
}
|
|
|
</style>
|