新增限时折扣模块
This commit is contained in:
parent
71c852fcaa
commit
dae7ced23c
|
|
@ -576,6 +576,33 @@ export function couponRedemptionCodeExport(params) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 限时折扣-分页
|
||||||
|
export function limitTimeDiscountPage(params) {
|
||||||
|
return request({
|
||||||
|
url: `${Market_BaseUrl}/admin/limitTimeDiscount/page`,
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 限时折扣-新增
|
||||||
|
export function limitTimeDiscount(data, method = 'post') {
|
||||||
|
return request({
|
||||||
|
url: `${Market_BaseUrl}/admin/limitTimeDiscount`,
|
||||||
|
method: method,
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 限时折扣-删除
|
||||||
|
export function limitTimeDiscountDel(params) {
|
||||||
|
return request({
|
||||||
|
url: `${Market_BaseUrl}/admin/limitTimeDiscount`,
|
||||||
|
method: 'DELETE',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ const accountList = reactive([
|
||||||
{ username: "admin", type: 'primary' },
|
{ username: "admin", type: 'primary' },
|
||||||
{ username: "19191703856", type: 'warning' },
|
{ username: "19191703856", type: 'warning' },
|
||||||
{ username: "19107220837", type: 'danger' },
|
{ username: "19107220837", type: 'danger' },
|
||||||
|
{ username: "18199991111", type: 'info' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 快捷模拟登录
|
// 快捷模拟登录
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,517 @@
|
||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" :title="form.id ? '编辑限时活动' : '添加限时活动'" width="700px" top="4vh"
|
||||||
|
@closed="closedReset">
|
||||||
|
<div class="scroll" ref="scrollRef">
|
||||||
|
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px" class="dialog-form">
|
||||||
|
<el-form-item label="活动名称" prop="title">
|
||||||
|
<el-input v-model="form.title" :maxlength="20" show-word-limit placeholder="请输入活动名称" style="width: 300px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="可用门店" prop="useShopType" v-if="shopInfo.isHeadShop && shopInfo.shopType != 'only'">
|
||||||
|
<el-radio-group v-model="form.useShopType">
|
||||||
|
<el-radio label="仅本店可用" value="only"></el-radio>
|
||||||
|
<el-radio label="全部门店" value="all"></el-radio>
|
||||||
|
<el-radio label="指定门店可用" value="custom"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="选择门店" v-if="form.useShopType == 'custom'">
|
||||||
|
<el-select v-model="shops" multiple clearable placeholder="请选择门店" @change="shopsChange" style="width: 300px">
|
||||||
|
<el-option :label="item.shopName" :value="item.id" v-for="item in branchList" :key="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="活动日期" :rules="[{ required: true, message: '请选择活动日期', trigger: 'change' }]">
|
||||||
|
<div style="width: 200px">
|
||||||
|
<el-date-picker v-model="validityScope" type="daterange" range-separator="至" start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束时间" @change="validityScopeChange" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="可用周期" prop="useDays">
|
||||||
|
<el-checkbox-group v-model="form.useDays">
|
||||||
|
<el-checkbox value="周一" label="周一" />
|
||||||
|
<el-checkbox value="周二" label="周二" />
|
||||||
|
<el-checkbox value="周三" label="周三" />
|
||||||
|
<el-checkbox value="周四" label="周四" />
|
||||||
|
<el-checkbox value="周五" label="周五" />
|
||||||
|
<el-checkbox value="周六" label="周六" />
|
||||||
|
<el-checkbox value="周七" label="周日" />
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="指定时间段">
|
||||||
|
<el-radio-group v-model="form.useTimeType">
|
||||||
|
<el-radio label="全时段可用" value="all"></el-radio>
|
||||||
|
<el-radio label="指定时间段可用" value="custom"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="form.useTimeType == 'custom'" prop="useTimeType">
|
||||||
|
<div style="width: 200px">
|
||||||
|
<el-time-picker v-model="useTimeScope" is-range range-separator="至" start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束时间" @change="useTimeScopeChange" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="可使用类型" prop="useType">
|
||||||
|
<el-checkbox-group v-model="form.useType">
|
||||||
|
<el-checkbox value="dine-in" label="堂食" />
|
||||||
|
<el-checkbox value="take-out" label="外带" />
|
||||||
|
<el-checkbox value="take-away" label="外卖" />
|
||||||
|
<el-checkbox value="post" label="配送" />
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="折扣" prop="discountRate">
|
||||||
|
<div class="column">
|
||||||
|
<div class="center">
|
||||||
|
<el-input v-model="form.discountRate" placeholder="请输入折扣" style="width: 200px" @input="discountRateInput">
|
||||||
|
<template #append>%</template>
|
||||||
|
</el-input>
|
||||||
|
<span style="color: #999;">范围:1-99%</span>
|
||||||
|
</div>
|
||||||
|
<div class="tips">例如:填写90,那么折扣后价格=原价*90%</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="优先级">
|
||||||
|
<el-input v-model="form.sort" placeholder="请输入" style="width: 200px"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="限时折扣优先级">
|
||||||
|
<el-radio-group v-model="form.discountPriority">
|
||||||
|
<el-radio label="优先使用限时折扣价" value="limit-time"></el-radio>
|
||||||
|
<el-radio label="优先使用会员价/会员折扣" value="vip-price"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="参与商品" prop="goodsType">
|
||||||
|
<el-radio-group v-model="form.foodType" @change="goodRadioChnage">
|
||||||
|
<el-radio label="全部商品可用" :value="1"></el-radio>
|
||||||
|
<el-radio label="部分商品可用" :value="2"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="form.foodType == 2">
|
||||||
|
<el-cascader v-model="goodsTypeCascaderValue" :options="goodsList" :props="cascaderProps"
|
||||||
|
:show-all-levels="false" :max-collapse-tags="3" collapse-tags clearable style="width: 300px"
|
||||||
|
@change="selectFoodsConfirm"></el-cascader>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer" v-if="(shopInfo.isHeadShop && shopInfo.shopType != 'only') || !form.syncId">
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" :loading="loading" @click="submitHandle">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import _ from "lodash";
|
||||||
|
import { filterNumberInput } from "@/utils";
|
||||||
|
import { dayjs, ElNotification } from "element-plus";
|
||||||
|
import { ref, reactive, onMounted, nextTick } from "vue";
|
||||||
|
import { getBranchPage, getProductList, getCategoryList, limitTimeDiscount } from "@/api/coupon/index.js";
|
||||||
|
|
||||||
|
const shopInfo = ref("");
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
|
||||||
|
const cascaderProps = ref({
|
||||||
|
multiple: true,
|
||||||
|
emitPath: false,
|
||||||
|
value: "id",
|
||||||
|
label: "name",
|
||||||
|
});
|
||||||
|
|
||||||
|
// 选择指定商品
|
||||||
|
const goodsType = ref(1);
|
||||||
|
const goodsTypeCascaderValue = ref([]);
|
||||||
|
function selectFoodsConfirm(e) {
|
||||||
|
console.log(JSON.stringify(e));
|
||||||
|
form.value.foods = e.join(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换商品类型
|
||||||
|
function goodRadioChnage(e) {
|
||||||
|
console.log(e);
|
||||||
|
form.value.foods = '';
|
||||||
|
goodsTypeCascaderValue.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择的店铺列表
|
||||||
|
const shops = ref([]);
|
||||||
|
function shopsChange(e) {
|
||||||
|
form.value.useShops = e.join(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 有效期时间
|
||||||
|
const validityScope = ref([]);
|
||||||
|
function validityScopeChange(e) {
|
||||||
|
console.log("validityScopeChange===", e);
|
||||||
|
if (e && e.length) {
|
||||||
|
form.value.validStartTime = dayjs(e[0]).format("YYYY-MM-DD");
|
||||||
|
form.value.validEndTime = dayjs(e[1]).format("YYYY-MM-DD");
|
||||||
|
} else {
|
||||||
|
form.value.validStartTime = "";
|
||||||
|
form.value.validEndTime = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可用时间
|
||||||
|
const useTimeScope = ref([]);
|
||||||
|
function useTimeScopeChange(e) {
|
||||||
|
console.log("useTimeScopeChange===", e);
|
||||||
|
if (e && e.length) {
|
||||||
|
form.value.useStartTime = dayjs(e[0]).format("HH:mm:00");
|
||||||
|
form.value.useEndTime = dayjs(e[1]).format("HH:mm:00");
|
||||||
|
} else {
|
||||||
|
form.value.useStartTime = "";
|
||||||
|
form.value.useEndTime = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const formRef = ref(null);
|
||||||
|
// 仅保留组件中实际使用到的字段,减少冗余
|
||||||
|
const form = ref({
|
||||||
|
id: "",
|
||||||
|
shopId: "",
|
||||||
|
syncId: "",
|
||||||
|
title: "", // 活动名称
|
||||||
|
useShopType: "only", // only/all/custom
|
||||||
|
useShops: "", // 指定门店 id 拼接字符串
|
||||||
|
foodType: 1, // 参与商品类型 1-全部 2-部分
|
||||||
|
foods: "", // 指定商品 id 拼接
|
||||||
|
useType: ["dine-in"],
|
||||||
|
useDays: ["周一", "周二", "周三", "周四", "周五", "周六", "周七"],
|
||||||
|
useTimeType: "all",
|
||||||
|
useStartTime: "",
|
||||||
|
useEndTime: "",
|
||||||
|
validType: "fixed",
|
||||||
|
validStartTime: "",
|
||||||
|
validEndTime: "",
|
||||||
|
discountRate: "",
|
||||||
|
sort: '',
|
||||||
|
discountPriority: 'limit-time',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 折扣输入处理
|
||||||
|
const discountRateInput = _.debounce(function (value) {
|
||||||
|
form.value.discountRate = filterNumberInput(value, true);
|
||||||
|
if (form.value.discountRate > 99) {
|
||||||
|
form.value.discountRate = 99;
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
const resetForm = ref(null);
|
||||||
|
function reset() {
|
||||||
|
goodsType.value = 1;
|
||||||
|
goodsTypeCascaderValue.value = [];
|
||||||
|
shops.value = [];
|
||||||
|
validityScope.value = [];
|
||||||
|
useTimeScope.value = [];
|
||||||
|
form.value = { ...resetForm.value };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自定义校验选择门店(用于模板中 useShopType)
|
||||||
|
const useShopTypeValidate = (rule, value, callback) => {
|
||||||
|
if (form.value.useShopType == "custom" && form.value.useShops === "") {
|
||||||
|
callback(new Error("请选择门店"));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 自定义校验参与商品(用于模板中 goodsType 判断)
|
||||||
|
const goodsTypeValidate = (rule, value, callback) => {
|
||||||
|
if (goodsType.value == 2 && form.value.foods === "") {
|
||||||
|
callback(new Error("请选择商品"));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 自定义校验指定可用时间段(用于模板中 useTimeType 判断)
|
||||||
|
const useTimeTypeValidate = (rule, value, callback) => {
|
||||||
|
if (!form.value.useStartTime) {
|
||||||
|
callback(new Error("请选择指定可用时间段"));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const formRules = reactive({
|
||||||
|
title: [{ required: true, message: "请输入优惠券名称", trigger: "blur" }],
|
||||||
|
useShopType: [
|
||||||
|
{
|
||||||
|
validator: useShopTypeValidate,
|
||||||
|
trigger: "change",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
goodsType: [
|
||||||
|
{
|
||||||
|
validator: goodsTypeValidate,
|
||||||
|
trigger: "change",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
discountRate: [{ required: true, message: "输入折扣(%)", trigger: "blur" }],
|
||||||
|
useType: [{ required: true, message: "请选择可使用类型", trigger: "change" }],
|
||||||
|
useDays: [{ required: true, message: "请选择可用周期", trigger: "change" }],
|
||||||
|
useTimeType: [
|
||||||
|
{
|
||||||
|
validator: useTimeTypeValidate,
|
||||||
|
trigger: "change",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// 开始提交
|
||||||
|
const emits = defineEmits(["success"]);
|
||||||
|
const loading = ref(false);
|
||||||
|
function submitHandle() {
|
||||||
|
formRef.value.validate(async (valid) => {
|
||||||
|
try {
|
||||||
|
if (valid) {
|
||||||
|
loading.value = true;
|
||||||
|
const data = { ...form.value };
|
||||||
|
data.shopId = shopInfo.value.shopId;
|
||||||
|
data.useDays = form.value.useDays.join(",");
|
||||||
|
data.useType = form.value.useType.join(",");
|
||||||
|
await limitTimeDiscount(data, form.value.id ? "put" : "post");
|
||||||
|
ElNotification({
|
||||||
|
title: "注意",
|
||||||
|
message: "保存成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
emits("success");
|
||||||
|
dialogVisible.value = false;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从本地获取商户信息
|
||||||
|
function getLocalShopInfo() {
|
||||||
|
shopInfo.value = JSON.parse(localStorage.getItem("userInfo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取分店列表
|
||||||
|
const branchList = ref([]);
|
||||||
|
async function getBranchPageAjax() {
|
||||||
|
try {
|
||||||
|
const res = await getBranchPage();
|
||||||
|
branchList.value = res.records;
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取商品列表
|
||||||
|
const goodsList = ref([]);
|
||||||
|
async function getProductListAjax() {
|
||||||
|
try {
|
||||||
|
const categorys = await getCategoryList();
|
||||||
|
const products = await getProductList();
|
||||||
|
goodsList.value = formatCategoryWithProducts(categorys, products);
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 给分类组合相应的商品
|
||||||
|
function formatCategoryWithProducts(categories, products) {
|
||||||
|
// 步骤1:遍历所有分类,为每个分类匹配对应的商品
|
||||||
|
const allCategoriesWithProducts = categories.map((category) => {
|
||||||
|
// 匹配当前分类下的商品(通过category.id === product.categoryId关联)
|
||||||
|
const matchedProducts = products
|
||||||
|
.filter((product) => product.categoryId === category.id) // 关键:按分类ID匹配商品
|
||||||
|
.map((product) => ({
|
||||||
|
id: product.id,
|
||||||
|
name: product.name, // 提取商品的id和name
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 组装单个分类的结构
|
||||||
|
return {
|
||||||
|
id: category.id,
|
||||||
|
name: category.name,
|
||||||
|
children: matchedProducts, // 该分类下的商品(空数组表示无商品)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// 步骤2:过滤掉“无商品”的分类(children为空数组的分类)
|
||||||
|
return allCategoriesWithProducts.filter((item) => item.children.length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示弹窗
|
||||||
|
const scrollRef = ref(null);
|
||||||
|
function show(obj = null) {
|
||||||
|
console.log(obj);
|
||||||
|
// return
|
||||||
|
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
if (scrollRef.value) {
|
||||||
|
setTimeout(() => {
|
||||||
|
scrollRef.value.scrollTop = 0;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (obj && obj.id) {
|
||||||
|
form.value = { ...obj };
|
||||||
|
|
||||||
|
form.value.useDays = form.value.useDays.split(",");
|
||||||
|
form.value.useType = form.value.useType.split(",");
|
||||||
|
|
||||||
|
validityScope.value = [
|
||||||
|
form.value.validStartTime,
|
||||||
|
form.value.validEndTime,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!!form.value.syncId) {
|
||||||
|
form.value.useShopType = "only";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (form.value.foods != "") {
|
||||||
|
goodsType.value = 2;
|
||||||
|
goodsTypeCascaderValue.value = form.value.foods.split(",");
|
||||||
|
} else {
|
||||||
|
goodsType.value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (form.value.useShops != "" && form.value.useShopType == "custom") {
|
||||||
|
shops.value = form.value.useShops.split(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (form.value.validType == "custom") {
|
||||||
|
validityScope.value = [form.value.validStartTime, form.value.validEndTime];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (form.value.useTimeType == "custom") {
|
||||||
|
useTimeScope.value = [
|
||||||
|
convertTimeToDate(form.value.useStartTime),
|
||||||
|
convertTimeToDate(form.value.useEndTime),
|
||||||
|
];
|
||||||
|
|
||||||
|
console.log(useTimeScope.value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
dialogVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭后重置表单验证
|
||||||
|
function closedReset() {
|
||||||
|
formRef.value.resetFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将时分秒字符串转换为完整日期格式
|
||||||
|
* @param {string} timeStr - 时分秒字符串,格式需为 HH:mm:ss(如 '00:53:00')
|
||||||
|
* @param {Object} options - 可选配置项
|
||||||
|
* @param {string} [options.customDate] - 自定义日期,格式为 YYYY-MM-DD(默认使用当前日期)
|
||||||
|
* @param {string} [options.format='YYYY-MM-DD HH:mm:ss'] - 输出的日期格式
|
||||||
|
* @returns {string|null} 转换后的日期字符串,失败时返回 null
|
||||||
|
*/
|
||||||
|
function convertTimeToDate(timeStr, options = {}) {
|
||||||
|
// 解构配置项,设置默认值
|
||||||
|
const { customDate, format = "YYYY-MM-DD HH:mm:ss" } = options;
|
||||||
|
|
||||||
|
// 1. 校验时分秒格式(必须为 HH:mm:ss,允许数字1-2位)
|
||||||
|
const timeRegex = /^\d{1,2}:\d{1,2}:\d{1,2}$/;
|
||||||
|
if (!timeRegex.test(timeStr)) {
|
||||||
|
console.error("时分秒格式错误,请使用 HH:mm:ss 格式(如 00:53:00)");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 确定日期部分(自定义日期或当前日期)
|
||||||
|
let datePart;
|
||||||
|
if (customDate) {
|
||||||
|
// 校验自定义日期格式
|
||||||
|
if (!dayjs(customDate, "YYYY-MM-DD", true).isValid()) {
|
||||||
|
console.error("自定义日期格式错误,请使用 YYYY-MM-DD 格式(如 2024-05-20)");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
datePart = customDate;
|
||||||
|
} else {
|
||||||
|
// 使用当前日期(格式:YYYY-MM-DD)
|
||||||
|
datePart = dayjs().format("YYYY-MM-DD");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 组合日期和时分秒,生成完整日期对象
|
||||||
|
const fullDateTime = `${datePart} ${timeStr}`;
|
||||||
|
const dateObj = dayjs(fullDateTime);
|
||||||
|
|
||||||
|
// 4. 校验完整日期是否有效(如避免 2024-02-30 这种无效日期)
|
||||||
|
if (!dateObj.isValid()) {
|
||||||
|
console.error("生成的日期无效,请检查日期或时分秒是否合理");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 按指定格式返回日期字符串
|
||||||
|
return dateObj.format(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show,
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
resetForm.value = { ...form.value };
|
||||||
|
getLocalShopInfo();
|
||||||
|
getBranchPageAjax();
|
||||||
|
getProductListAjax();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.title {
|
||||||
|
color: #000;
|
||||||
|
padding: 14px;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll {
|
||||||
|
height: 76vh;
|
||||||
|
padding-bottom: 60px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: calc(100% + var(--el-dialog-padding-primary));
|
||||||
|
z-index: 9;
|
||||||
|
background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.textarea-num {
|
||||||
|
color: #999;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
<!-- 限时折扣 -->
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<div class="gyq_container">
|
||||||
|
<div class="gyq_content">
|
||||||
|
<HeaderCard name="限时折扣" intro="批量设置商品折扣" icon="xszk"></HeaderCard>
|
||||||
|
<div class="row mt14">
|
||||||
|
<el-button type="primary" @click="addRef.show()">添加</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="row mt14">
|
||||||
|
<el-table :data="tableData.list" stripe border v-loading="tableData.loading" height="58vh">
|
||||||
|
<el-table-column label="ID" prop="id" width="80"></el-table-column>
|
||||||
|
<el-table-column label="活动时间" prop="validStartTime" width="250">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.validStartTime }} ~ {{ scope.row.validEndTime }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="生效周期" prop="useDays" width="250"></el-table-column>
|
||||||
|
<el-table-column label="生效时段" prop="useStartTime" width="250">
|
||||||
|
<template #default="scope">
|
||||||
|
<div v-if="scope.row.useTimeType == 'all'">全时段可用</div>
|
||||||
|
<div v-else>{{ scope.row.useStartTime }} ~ {{ scope.row.useEndTime }}</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="折扣%" prop="discountRate"></el-table-column>
|
||||||
|
<el-table-column label="优先级" prop="sort"></el-table-column>
|
||||||
|
<el-table-column label="状态" prop="status" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag :type="statusList.find(item => item.value === scope.row.status)?.type || 'info'">
|
||||||
|
{{statusList.find(item => item.value === scope.row.status)?.label || '未知'}}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" fixed="right" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" @click="addRef.show(scope.row)">编辑</el-button>
|
||||||
|
<el-popconfirm title="确认要删除吗?" @confirm="delHandle(scope.row)">
|
||||||
|
<template #reference>
|
||||||
|
<el-button type="danger" link>删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div class="row mt14">
|
||||||
|
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
||||||
|
:page-sizes="[10, 30, 50, 100]" background layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:total="tableData.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<add ref="addRef" @success="getTableData" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ElNotification } from "element-plus";
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
import HeaderCard from '../components/headerCard.vue'
|
||||||
|
import add from './components/add.vue'
|
||||||
|
import { limitTimeDiscountPage, limitTimeDiscountDel } from '@/api/coupon/index.js'
|
||||||
|
|
||||||
|
const addRef = ref(null);
|
||||||
|
|
||||||
|
// 1未开始,2进行中,3已结束 -1当前时间不可用
|
||||||
|
const statusList = ref([
|
||||||
|
{ label: '未开始', value: 1, type: 'info' },
|
||||||
|
{ label: '进行中', value: 2, type: 'success' },
|
||||||
|
{ label: '已结束', value: 3, type: 'default' },
|
||||||
|
{ label: '不可用', value: -1, type: 'danger' },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const tableData = reactive({
|
||||||
|
loading: true,
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
total: 0,
|
||||||
|
list: []
|
||||||
|
})
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
async function delHandle(row) {
|
||||||
|
try {
|
||||||
|
await limitTimeDiscountDel({ id: row.id });
|
||||||
|
ElNotification({
|
||||||
|
title: '成功',
|
||||||
|
message: '删除成功',
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
|
getTableData();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除失败', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页大小发生变化
|
||||||
|
function handleSizeChange(e) {
|
||||||
|
tableData.pageSize = e;
|
||||||
|
consumeCashbackRecordAjax();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页发生变化
|
||||||
|
function handleCurrentChange(e) {
|
||||||
|
tableData.page = e;
|
||||||
|
consumeCashbackRecordAjax();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表格数据
|
||||||
|
async function getTableData() {
|
||||||
|
tableData.loading = true;
|
||||||
|
try {
|
||||||
|
const res = await limitTimeDiscountPage({
|
||||||
|
page: tableData.page,
|
||||||
|
size: tableData.size
|
||||||
|
});
|
||||||
|
tableData.list = res.records;
|
||||||
|
tableData.total = res.totalRow;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取数据失败', error);
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
tableData.loading = false;
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getTableData();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.gyq_container {
|
||||||
|
padding: 14px;
|
||||||
|
|
||||||
|
.gyq_content {
|
||||||
|
padding: 14px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
&.mt14 {
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -97,7 +97,7 @@ const menus = ref([
|
||||||
intro: "兑换码直充余额,可当作礼品赠送",
|
intro: "兑换码直充余额,可当作礼品赠送",
|
||||||
},
|
},
|
||||||
{ name: "券兑换码", icon: "qdhm", pathName: "coupon_exchange_code", intro: "可添加多券组合兑换" },
|
{ name: "券兑换码", icon: "qdhm", pathName: "coupon_exchange_code", intro: "可添加多券组合兑换" },
|
||||||
{ name: "限时折扣", icon: "xszk", pathName: "", intro: "批量设置商品折扣" },
|
{ name: "限时折扣", icon: "xszk", pathName: "discount_limit", intro: "批量设置商品折扣" },
|
||||||
{ name: "商品拼团", icon: "sppt", pathName: "", intro: "拼团" },
|
{ name: "商品拼团", icon: "sppt", pathName: "", intro: "拼团" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="金额" prop="amount">
|
<el-form-item label="金额" prop="amount">
|
||||||
<el-input v-model="form.amount" placeholder="请输入" :maxlength="8" show-word-limit
|
<el-input v-model="form.amount" placeholder="请输入" :maxlength="8" show-word-limit style="width: 350px;"
|
||||||
style="width: 350px;"></el-input>
|
@input="e => form.amount = filterNumberInput(e)"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="发行数量" prop="total">
|
<el-form-item label="发行数量" prop="total">
|
||||||
<el-input v-model="form.total" placeholder="请输入" :maxlength="4" show-word-limit style="width: 350px;"
|
<el-input v-model="form.total" placeholder="请输入" :maxlength="4" show-word-limit style="width: 350px;"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue