Merge branch 'ymf' of https://newgitea.sxczgkj.cn/czg_team/cashier-web into gyq
This commit is contained in:
commit
350a314feb
36
README.md
36
README.md
|
|
@ -2,20 +2,42 @@
|
||||||
|
|
||||||
基于 Vue3 + Vite5+ TypeScript5 + Element-Plus + Pinia 等主流技术栈构建
|
基于 Vue3 + Vite5+ TypeScript5 + Element-Plus + Pinia 等主流技术栈构建
|
||||||
|
|
||||||
|
## ysk-utils 工具类包
|
||||||
|
|
||||||
|
安装
|
||||||
|
|
||||||
|
```
|
||||||
|
pnpm install ysk-utils
|
||||||
|
```
|
||||||
|
|
||||||
|
更新
|
||||||
|
|
||||||
|
```
|
||||||
|
pnpm update ysk-utils
|
||||||
|
```
|
||||||
|
|
||||||
|
vscode如果无代码提示
|
||||||
|
重启 VS Code 的 TypeScript 服务器
|
||||||
|
输入
|
||||||
|
```TypeScript: Restart TS Server```
|
||||||
|
|
||||||
## 正式宝塔
|
## 正式宝塔
|
||||||
|
|
||||||
<https://121.40.128.145:38279/mianban/>
|
[正式宝塔](https://121.40.128.145:38279/mianban/)
|
||||||
chaozg
|
|
||||||
chaozg123
|
账号 ***chaozg***
|
||||||
|
|
||||||
|
密码 ***chaozg123***
|
||||||
|
|
||||||
## 本地测试服务器(192.168.1.31)linux部署
|
## 本地测试服务器(192.168.1.31)linux部署
|
||||||
|
|
||||||
映射地址
|
映射地址
|
||||||
<https://fv901fw8033.vicp.fun/>
|
<https://fv901fw8033.vicp.fun/>
|
||||||
上传.zip文件解压到服务器的 /home/web下
|
|
||||||
cd到/home/web下
|
1. 上传.zip文件解压到服务器的 /home/web下
|
||||||
执行命令
|
2. cd到/home/web下
|
||||||
unzip -o dist.zip
|
3. 执行命令
|
||||||
|
```unzip -o dist.zip```
|
||||||
|
|
||||||
数据库
|
数据库
|
||||||
url: jdbc:mysql://192.168.1.31:3306/czg_cashier?useUnicode=true&characterEncoding=utf-8
|
url: jdbc:mysql://192.168.1.31:3306/czg_cashier?useUnicode=true&characterEncoding=utf-8
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,8 @@
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-i18n": "^11.1.0",
|
"vue-i18n": "^11.1.0",
|
||||||
"vue-router": "^4.5.0"
|
"vue-router": "^4.5.0",
|
||||||
|
"ysk-utils": "^1.0.12"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^19.7.1",
|
"@commitlint/cli": "^19.7.1",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import request from "@/utils/request";
|
||||||
|
import { Market_BaseUrl } from "@/api/config";
|
||||||
|
const baseURL = Market_BaseUrl + "/admin/consumeDiscount";
|
||||||
|
const API = {
|
||||||
|
getConfig(params: any) {
|
||||||
|
return request<any>({
|
||||||
|
url: `${baseURL}`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
|
},
|
||||||
|
editConfig(data: any) {
|
||||||
|
return request<any>({
|
||||||
|
url: `${baseURL}`,
|
||||||
|
method: "post",
|
||||||
|
data
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
export default API;
|
||||||
|
|
||||||
|
|
@ -9,6 +9,14 @@ const API = {
|
||||||
params
|
params
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
//优惠券列表/已领取详情
|
||||||
|
getDetail(params: any) {
|
||||||
|
return request<any>({
|
||||||
|
url: `${baseURL}/record`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
export default API;
|
export default API;
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -4,7 +4,9 @@ import orderApi from "@/api/order/order";
|
||||||
import { useUserStoreHook } from "@/store/modules/user";
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
import { customTruncateToTwoDecimals } from '@/utils/tools'
|
import { customTruncateToTwoDecimals } from '@/utils/tools'
|
||||||
import productApi from "@/api/product/index";
|
import productApi from "@/api/product/index";
|
||||||
|
import yskUtils from 'ysk-utils'
|
||||||
|
const { OrderPriceCalculator } = yskUtils
|
||||||
|
console.log(OrderPriceCalculator)
|
||||||
const shopUser = useUserStoreHook();
|
const shopUser = useUserStoreHook();
|
||||||
export interface CartsState {
|
export interface CartsState {
|
||||||
id: string | number;
|
id: string | number;
|
||||||
|
|
@ -22,11 +24,6 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
let dinnerType = ref<string>('dine-in');
|
let dinnerType = ref<string>('dine-in');
|
||||||
|
|
||||||
|
|
||||||
//就餐模式 先付 后付
|
|
||||||
const isPayBefore = computed(() => {
|
|
||||||
return shopUser.userInfo.registerType == 'before' ? true : false;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//是否启用会员价
|
//是否启用会员价
|
||||||
const useVipPrice = computed(() => {
|
const useVipPrice = computed(() => {
|
||||||
|
|
@ -42,22 +39,21 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
//当前购物车数据
|
//当前购物车数据
|
||||||
const list = useStorage<any[]>("carts", []);
|
const list = useStorage<any[]>("carts", []);
|
||||||
//历史订单数据
|
//历史订单数据
|
||||||
// const oldOrder = useStorage<any>("Instead_olold_order", {
|
const oldOrder = useStorage<any>("Instead_olold_order", {
|
||||||
// detailMap: [],
|
|
||||||
// originAmount: 0
|
|
||||||
// });
|
|
||||||
const oldOrder = ref({
|
|
||||||
detailMap: [],
|
detailMap: [],
|
||||||
originAmount: 0
|
originAmount: 0
|
||||||
})
|
});
|
||||||
|
|
||||||
//代客下单页面商品缓存
|
//代客下单页面商品缓存
|
||||||
const goods = useStorage<any[]>("Instead_goods", []);
|
const goods = useStorage<any[]>("Instead_goods", []);
|
||||||
async function getGoods(query: any) {
|
async function getGoods(query: any) {
|
||||||
const res = await productApi.list({
|
const res = await productApi.getPage({
|
||||||
|
page: 1,
|
||||||
|
size: 999,
|
||||||
|
status: "on_sale",
|
||||||
...query,
|
...query,
|
||||||
});
|
});
|
||||||
goods.value = res.filter((v: { type: string }) => v.type != 'coupon');
|
goods.value = res.records;
|
||||||
setGoodsMap(goods.value)
|
setGoodsMap(goods.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,11 +131,9 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
})
|
})
|
||||||
//返回打包数量(称重商品打包数量最大为1)
|
//返回打包数量(称重商品打包数量最大为1)
|
||||||
function returnCartPackNumber(cur: any) {
|
function returnCartPackNumber(cur: any) {
|
||||||
const maxReturnNum = cur.number - (cur.returnNum || 0);
|
console.log(cur)
|
||||||
let pack_number = (dinnerType.value == 'take-out' ? cur.number : cur.pack_number * 1);
|
let pack_number = (dinnerType.value == 'take-out' ? cur.number : cur.pack_number * 1)
|
||||||
pack_number = (cur.product_type == 'weight' && pack_number > 1) ? 1 : pack_number;
|
pack_number = (cur.product_type == 'weight' && pack_number > 1) ? 1 : pack_number;
|
||||||
pack_number = Math.min(maxReturnNum, pack_number);
|
|
||||||
pack_number = pack_number <= 0 ? 0 : pack_number
|
|
||||||
return pack_number * 1
|
return pack_number * 1
|
||||||
}
|
}
|
||||||
//打包数量
|
//打包数量
|
||||||
|
|
@ -247,7 +241,7 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
const price = (cur.discount_sale_amount * 1 || cur.salePrice || 0)
|
const price = (cur.discount_sale_amount * 1 || cur.salePrice || 0)
|
||||||
return acc + cur.number * (discount_sale_amount || (useVipPrice.value ? memberPrice : price))
|
return acc + cur.number * (discount_sale_amount || (useVipPrice.value ? memberPrice : price))
|
||||||
}, 0)
|
}, 0)
|
||||||
return (money + packFee.value * 1 + oldOrderMoney.value * 1).toFixed(2)
|
return (money + packFee.value + oldOrderMoney.value * 1).toFixed(2)
|
||||||
})
|
})
|
||||||
//只算商品的总价
|
//只算商品的总价
|
||||||
const goodsTotal = computed(() => {
|
const goodsTotal = computed(() => {
|
||||||
|
|
@ -264,7 +258,7 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
const cartNumber = list.value.reduce((acc: number, cur: any) => {
|
const cartNumber = list.value.reduce((acc: number, cur: any) => {
|
||||||
return acc + cur.number * 1
|
return acc + cur.number * 1
|
||||||
}, 0)
|
}, 0)
|
||||||
const giftNumber = giftList.value.reduce((acc: number, cur: any) => {
|
const giftNumber = list.value.reduce((acc: number, cur: any) => {
|
||||||
return acc + cur.number * 1
|
return acc + cur.number * 1
|
||||||
}, 0)
|
}, 0)
|
||||||
let oldNumber = 0
|
let oldNumber = 0
|
||||||
|
|
@ -284,11 +278,11 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const newNumber = item.number * 1 + step * 1;
|
const newNumber = item.number * 1 + step * 1;
|
||||||
let pack_number = newNumber < item.pack_number ? (item.pack_number * 1 + step * 1) : item.pack_number * 1;
|
let pack_number = newNumber < item.pack_number ? (item.pack_number * 1 + step * 1) : item.pack_number;
|
||||||
if (dinnerType.value == 'take-out') {
|
if (dinnerType.value == 'take-out') {
|
||||||
pack_number = newNumber
|
pack_number = newNumber
|
||||||
}
|
}
|
||||||
if (item.product_type == 'weight' && item.pack_number * 1 >= 1) {
|
if (item.product_type == 'weight') {
|
||||||
pack_number = 1
|
pack_number = 1
|
||||||
}
|
}
|
||||||
update({ ...item, number: newNumber, pack_number });
|
update({ ...item, number: newNumber, pack_number });
|
||||||
|
|
@ -308,8 +302,11 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
selPlaceNum.value = -1;
|
if (cart.is_gift) {
|
||||||
isOldOrder.value = false;
|
isSelGift.value = true
|
||||||
|
} else {
|
||||||
|
isSelGift.value = false
|
||||||
|
}
|
||||||
|
|
||||||
if (cart.is_gift) {
|
if (cart.is_gift) {
|
||||||
isSelGift.value = true
|
isSelGift.value = true
|
||||||
|
|
@ -320,7 +317,6 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
isSelGift.value = false
|
isSelGift.value = false
|
||||||
selListIndex.value = list.value.findIndex((item: CartsState) => item.id === cart.id);
|
selListIndex.value = list.value.findIndex((item: CartsState) => item.id === cart.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -336,8 +332,7 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
product_name: "",
|
product_name: "",
|
||||||
remark: "",
|
remark: "",
|
||||||
sku_id: '',
|
sku_id: '',
|
||||||
product_type: '',
|
product_type: ''
|
||||||
suitNum: 1
|
|
||||||
}
|
}
|
||||||
//当前购物车直接添加
|
//当前购物车直接添加
|
||||||
function cartsPush(data: any) {
|
function cartsPush(data: any) {
|
||||||
|
|
@ -377,10 +372,6 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
cart_id
|
cart_id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//清空历史订单
|
|
||||||
function clearHistory() {
|
|
||||||
sendMessage('clearOrder', {});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function del(data: any) {
|
function del(data: any) {
|
||||||
|
|
@ -394,7 +385,7 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
return sendMessage('del', data);
|
return sendMessage('del', data);
|
||||||
}
|
}
|
||||||
const pack_number = dinnerType.value == 'take-out' ? data.number : data.pack_number
|
const pack_number = dinnerType.value == 'take-out' ? data.number : data.pack_number
|
||||||
sendMessage('edit', { ...data, suitNum, pack_number });
|
sendMessage('edit', { ...data, pack_number });
|
||||||
}
|
}
|
||||||
function updateTag(key: string, val: any, cart: CartsState = selCart.value) {
|
function updateTag(key: string, val: any, cart: CartsState = selCart.value) {
|
||||||
const skuData = cart.skuData || { suitNum: 1 }
|
const skuData = cart.skuData || { suitNum: 1 }
|
||||||
|
|
@ -408,7 +399,6 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
const msg = { ...cart, [key]: val }
|
const msg = { ...cart, [key]: val }
|
||||||
if (key == 'number' && dinnerType.value == 'take-out') {
|
if (key == 'number' && dinnerType.value == 'take-out') {
|
||||||
msg.pack_number == val
|
msg.pack_number == val
|
||||||
msg.suitNum == skuData.suitNum
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage('edit', msg);
|
sendMessage('edit', msg);
|
||||||
|
|
@ -462,15 +452,8 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
//获取历史订单
|
//获取历史订单
|
||||||
async function getOldOrder(table_code: string | number) {
|
async function getOldOrder(table_code: string | number) {
|
||||||
const res = await orderApi.getHistoryList({ tableCode: table_code })
|
const res = await orderApi.getHistoryList({ tableCode: table_code })
|
||||||
console.log('getOldOrder');
|
|
||||||
console.log(res);
|
|
||||||
if (res) {
|
if (res) {
|
||||||
setOldOrder(res)
|
setOldOrder(res)
|
||||||
} else {
|
|
||||||
oldOrder.value = {
|
|
||||||
detailMap: [],
|
|
||||||
originAmount: 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -512,22 +495,12 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
for (let i in data) {
|
for (let i in data) {
|
||||||
newData[i] = data[i].map((v: any) => {
|
newData[i] = data[i].map((v: any) => {
|
||||||
const skuData = getProductDetails({ product_id: v.productId, sku_id: v.skuId })
|
const skuData = getProductDetails({ product_id: v.productId, sku_id: v.skuId })
|
||||||
console.log(skuData)
|
|
||||||
console.log(v)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...v,
|
...v,
|
||||||
...skuData,
|
...skuData,
|
||||||
skuData: {
|
|
||||||
...skuData,
|
|
||||||
salePrice: v.price,
|
|
||||||
memberPrice: v.memberPrice
|
|
||||||
},
|
|
||||||
placeNum: v.placeNum,
|
placeNum: v.placeNum,
|
||||||
number: v.num,
|
number: v.num,
|
||||||
id: v.id,
|
id: v.id,
|
||||||
salePrice: v.price,
|
|
||||||
memberPrice: v.memberPrice,
|
|
||||||
pack_number: v.packNumber,
|
pack_number: v.packNumber,
|
||||||
discount_sale_amount: v.discountSaleAmount * 1 || 0,
|
discount_sale_amount: v.discountSaleAmount * 1 || 0,
|
||||||
is_print: v.isPrint,
|
is_print: v.isPrint,
|
||||||
|
|
@ -538,12 +511,10 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
product_name: v.productName,
|
product_name: v.productName,
|
||||||
sku_name: v.skuName,
|
sku_name: v.skuName,
|
||||||
sku_id: v.skuId,
|
sku_id: v.skuId,
|
||||||
product_type: v.productType,
|
product_type: v.productType
|
||||||
packFee: v.packAmount,
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
console.log('newData', newData)
|
|
||||||
return newData
|
return newData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -573,7 +544,7 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
if ($oldOrder) {
|
if ($oldOrder) {
|
||||||
setOldOrder($oldOrder)
|
setOldOrder($oldOrder)
|
||||||
} else {
|
} else {
|
||||||
oldOrder.value = { detailMap: [], originAmount: 0 }
|
oldOrder.value = { detailMap: [] }
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('oldOrder.detailMap', oldOrder.value.detailMap)
|
// console.log('oldOrder.detailMap', oldOrder.value.detailMap)
|
||||||
|
|
@ -593,19 +564,9 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
console.log("初始化参数", initParams);
|
console.log("初始化参数", initParams);
|
||||||
WebSocketManager.subscribeToTopic(initParams, (msg) => {
|
WebSocketManager.subscribeToTopic(initParams, (msg) => {
|
||||||
console.log("收到消息:", msg);
|
console.log("收到消息:", msg);
|
||||||
|
console.log([...list.value, ...giftList.value])
|
||||||
if (msg.hasOwnProperty('status') && msg.status != 1) {
|
if (msg.hasOwnProperty('status') && msg.status != 1) {
|
||||||
if (msg.type === 'no_suit_num' && selListIndex.value != -1) {
|
return ElMessage.error(msg.message || '操作失败')
|
||||||
return ElMessageBox.confirm(`${list.value[selListIndex.value].name}库存不足`, '提示', {
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
|
|
||||||
callback: (action: string) => {
|
|
||||||
if (action == 'confirm') {
|
|
||||||
list.value.splice(selListIndex.value, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return ElMessage.error(msg.message || msg.msg || '操作失败')
|
|
||||||
}
|
}
|
||||||
if (msg && msg.data) {
|
if (msg && msg.data) {
|
||||||
if (Array.isArray(msg.data) && msg.data.length && msg.data[0].table_code) {
|
if (Array.isArray(msg.data) && msg.data.length && msg.data[0].table_code) {
|
||||||
|
|
@ -636,7 +597,7 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
v[key] = skuData[key];
|
v[key] = skuData[key];
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// del({ id: v.id })
|
del({ id: v.id })
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return !v.is_gift
|
return !v.is_gift
|
||||||
|
|
@ -666,13 +627,10 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
return ElMessage.warning(msg.message || '该商品已存在')
|
return ElMessage.warning(msg.message || '该商品已存在')
|
||||||
}
|
}
|
||||||
const skuData = getProductDetails({ product_id: msg.data.product_id, sku_id: msg.data.sku_id })
|
const skuData = getProductDetails({ product_id: msg.data.product_id, sku_id: msg.data.sku_id })
|
||||||
if (skuData || msg.data.is_temporary) {
|
const newGoods = { ...skuData, ...msg.data }
|
||||||
const newGoods = { ...skuData, ...msg.data }
|
console.log('newGoods', newGoods)
|
||||||
console.log('newGoods', newGoods)
|
list.value.push(newGoods)
|
||||||
list.value.push(newGoods)
|
return ElMessage.success(msg.message || '添加成功')
|
||||||
return ElMessage.success(msg.message || '添加成功')
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (msg.operate_type === "manage_edit") {
|
if (msg.operate_type === "manage_edit") {
|
||||||
|
|
@ -723,9 +681,6 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
if (msg.operate_type === "batch") {
|
if (msg.operate_type === "batch") {
|
||||||
concocatSocket({ ...$initParams, table_code: table_code.value })
|
concocatSocket({ ...$initParams, table_code: table_code.value })
|
||||||
}
|
}
|
||||||
if (msg.operate_type === "manage_clearOrder") {
|
|
||||||
getOldOrder(msg.data.table_code)
|
|
||||||
}
|
|
||||||
if (msg.operate_type === "product_update") {
|
if (msg.operate_type === "product_update") {
|
||||||
console.log('商品更新')
|
console.log('商品更新')
|
||||||
init($initParams, oldOrder.value)
|
init($initParams, oldOrder.value)
|
||||||
|
|
@ -747,7 +702,6 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
WebSocketManager.sendMessage(msg);
|
WebSocketManager.sendMessage(msg);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
clearHistory,
|
|
||||||
disconnect,
|
disconnect,
|
||||||
dinnerType,
|
dinnerType,
|
||||||
changePack,
|
changePack,
|
||||||
|
|
@ -781,7 +735,7 @@ export const useCartsStore = defineStore("carts", () => {
|
||||||
changeTable,
|
changeTable,
|
||||||
rotTable,
|
rotTable,
|
||||||
getGoods,
|
getGoods,
|
||||||
setGoodsMap, isPayBefore
|
setGoodsMap
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,210 @@
|
||||||
|
import { OrderPriceCalculator, GoodsType, BackendCoupon, ActivityConfig, CouponType } from "./goods";
|
||||||
|
|
||||||
|
// 修正后的测试数据(严格匹配BaseCartItem类型)
|
||||||
|
const testGoodsList = [
|
||||||
|
{
|
||||||
|
// 核心修正1:product_type使用GoodsType枚举(替代原product_type字符串)
|
||||||
|
product_type: GoodsType.NORMAL, // "sku"类型归类为普通商品
|
||||||
|
// 核心修正2:isTemporary/isGift从数字转为布尔值
|
||||||
|
isTemporary: false,
|
||||||
|
isGift: false,
|
||||||
|
// 核心修正3:discountSaleAmount从字符串转为数字
|
||||||
|
discountSaleAmount: 0,
|
||||||
|
|
||||||
|
// 原有字段(保持不变)
|
||||||
|
salePrice: 2,
|
||||||
|
memberPrice: 2,
|
||||||
|
coverImg: "https://czg-oss.oss-cn-hangzhou.aliyuncs.com/catering/store/9660.png",
|
||||||
|
name: "多规格起售3",
|
||||||
|
specInfo: "常温",
|
||||||
|
packFee: 1,
|
||||||
|
type: "sku",
|
||||||
|
skuData: {
|
||||||
|
barCode: "88888888888888888888",
|
||||||
|
costPrice: 2,
|
||||||
|
coverImg: "",
|
||||||
|
createTime: "2025-03-27 16:23:49",
|
||||||
|
id: "2451",
|
||||||
|
isDel: 0,
|
||||||
|
isGrounding: 1,
|
||||||
|
isPauseSale: 0,
|
||||||
|
isSale: 1,
|
||||||
|
isSoldStock: 0,
|
||||||
|
lowPrice: 2,
|
||||||
|
memberPrice: 2,
|
||||||
|
name: "常温",
|
||||||
|
originPrice: 2,
|
||||||
|
productId: "946",
|
||||||
|
realSalesNumber: 0,
|
||||||
|
salePrice: 2,
|
||||||
|
shopId: "29",
|
||||||
|
specInfo: "常温",
|
||||||
|
suitNum: 3,
|
||||||
|
updateTime: "2025-03-27 16:23:49",
|
||||||
|
weight: 0,
|
||||||
|
},
|
||||||
|
id: 18264,
|
||||||
|
shop_id: 29,
|
||||||
|
table_code: "APC36217948",
|
||||||
|
sku_id: 2451,
|
||||||
|
product_id: 946,
|
||||||
|
product_name: "",
|
||||||
|
sku_name: "",
|
||||||
|
number: 4,
|
||||||
|
pack_number: 0,
|
||||||
|
discount_sale_note: "",
|
||||||
|
is_print: 1,
|
||||||
|
is_wait_call: 0,
|
||||||
|
pro_group_info: "",
|
||||||
|
remark: "",
|
||||||
|
create_time: "2025-09-16 16:00:25",
|
||||||
|
update_time: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 核心修正1:package类型映射为GoodsType.PACKAGE
|
||||||
|
product_type: GoodsType.PACKAGE,
|
||||||
|
// 核心修正2:布尔值转换
|
||||||
|
isTemporary: false,
|
||||||
|
isGift: false,
|
||||||
|
// 核心修正3:字符串转数字
|
||||||
|
discountSaleAmount: 5,
|
||||||
|
|
||||||
|
// 原有字段
|
||||||
|
salePrice: 11,
|
||||||
|
memberPrice: 22,
|
||||||
|
coverImg: "https://czg-oss.oss-cn-hangzhou.aliyuncs.com/catering/store/8351.png",
|
||||||
|
name: "蜜雪冰城",
|
||||||
|
specInfo: "",
|
||||||
|
packFee: 555,
|
||||||
|
type: "package",
|
||||||
|
skuData: {
|
||||||
|
barCode: "291739694712255",
|
||||||
|
costPrice: 0,
|
||||||
|
coverImg: "",
|
||||||
|
createTime: "2025-02-16 16:36:46",
|
||||||
|
id: "2383",
|
||||||
|
isDel: 0,
|
||||||
|
isGrounding: 1,
|
||||||
|
isPauseSale: 0,
|
||||||
|
isSale: 1,
|
||||||
|
isSoldStock: 0,
|
||||||
|
lowPrice: 11,
|
||||||
|
memberPrice: 22,
|
||||||
|
name: "",
|
||||||
|
originPrice: 11,
|
||||||
|
productId: "943",
|
||||||
|
realSalesNumber: 0,
|
||||||
|
salePrice: 11,
|
||||||
|
shopId: "29",
|
||||||
|
specInfo: "",
|
||||||
|
suitNum: 33,
|
||||||
|
updateTime: null,
|
||||||
|
weight: 0,
|
||||||
|
},
|
||||||
|
id: 18263,
|
||||||
|
shop_id: 29,
|
||||||
|
table_code: "APC36217948",
|
||||||
|
sku_id: 2383,
|
||||||
|
product_id: 943,
|
||||||
|
product_name: "",
|
||||||
|
sku_name: "",
|
||||||
|
number: 35,
|
||||||
|
pack_number: 1,
|
||||||
|
discount_sale_note: "",
|
||||||
|
is_print: 1,
|
||||||
|
is_wait_call: 0,
|
||||||
|
pro_group_info: "",
|
||||||
|
remark: "",
|
||||||
|
create_time: "2025-09-16 15:59:59",
|
||||||
|
update_time: "2025-09-16 16:00:48",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 核心修正1:空字符串product_type映射为GoodsType.EMPTY
|
||||||
|
product_type: GoodsType.EMPTY,
|
||||||
|
// 核心修正2:临时菜标记为true
|
||||||
|
isTemporary: true,
|
||||||
|
isGift: false,
|
||||||
|
// 核心修正3:折扣金额为数字
|
||||||
|
discountSaleAmount: 1,
|
||||||
|
// 补充必需字段:salePrice(临时菜原价)
|
||||||
|
salePrice: 1,
|
||||||
|
|
||||||
|
// 原有字段
|
||||||
|
id: 18265,
|
||||||
|
shop_id: 29,
|
||||||
|
table_code: "APC36217948",
|
||||||
|
sku_id: -999,
|
||||||
|
product_id: -18293045,
|
||||||
|
product_name: "临时菜",
|
||||||
|
sku_name: "",
|
||||||
|
number: 1,
|
||||||
|
pack_number: 0,
|
||||||
|
discount_sale_note: "",
|
||||||
|
is_print: 1,
|
||||||
|
is_wait_call: 0,
|
||||||
|
pro_group_info: "",
|
||||||
|
remark: "",
|
||||||
|
create_time: "2025-09-16 16:00:57",
|
||||||
|
update_time: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// 修正testCartOrder的key与商品id匹配(确保排序正确)
|
||||||
|
const testCartOrder = {
|
||||||
|
"18264": 1717200000000, // 对应第一个商品id
|
||||||
|
"18263": 1717200100000, // 对应第二个商品id
|
||||||
|
"18265": 1717200200000, // 对应第三个商品id
|
||||||
|
};
|
||||||
|
|
||||||
|
// 其他配置保持不变
|
||||||
|
const testBackendCoupons: BackendCoupon[] = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: "满减券",
|
||||||
|
couponType: 1,
|
||||||
|
fullAmount: 2,
|
||||||
|
discountAmount: 1,
|
||||||
|
foods: '946',
|
||||||
|
useType: 'dine-in,pickup',
|
||||||
|
useShopType: 'all',
|
||||||
|
validType: 'custom',
|
||||||
|
validStartTime: '2025-09-16 16:00:00',
|
||||||
|
validEndTime: '2025-09-30 16:00:00',
|
||||||
|
useDays: '周一,周二,周三,周四,周五',
|
||||||
|
useTimeType: 'all',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const testOrderConfig = {
|
||||||
|
currentStoreId: "101",
|
||||||
|
isMember: false,
|
||||||
|
memberDiscountRate: 0.95,
|
||||||
|
userPoints: 0,
|
||||||
|
pointDeductionRule: {
|
||||||
|
pointsPerYuan: 100,
|
||||||
|
maxDeductionAmount: 50,
|
||||||
|
},
|
||||||
|
seatFeeConfig: {
|
||||||
|
isEnabled: false,
|
||||||
|
pricePerPerson: 3,
|
||||||
|
personCount: 2,
|
||||||
|
},
|
||||||
|
merchantReduction: 10,
|
||||||
|
additionalFee: 0,
|
||||||
|
};
|
||||||
|
const testActivities: ActivityConfig[] = [];
|
||||||
|
const testCurrentTime = new Date("2024-06-01 12:00:00");
|
||||||
|
|
||||||
|
// 调用函数(此时类型完全匹配)
|
||||||
|
const result = OrderPriceCalculator.calculateOrderCostSummary(
|
||||||
|
testGoodsList,
|
||||||
|
"dine-in",
|
||||||
|
testBackendCoupons,
|
||||||
|
testActivities,
|
||||||
|
testOrderConfig,
|
||||||
|
testCartOrder,
|
||||||
|
testCurrentTime
|
||||||
|
);
|
||||||
|
console.log("计算结果:", result);
|
||||||
|
|
||||||
|
|
||||||
|
export default {}
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="item">
|
<div class="flex justify-between box">
|
||||||
<img :src="getIconPath(props.icon)" class="icon" />
|
<div class="item">
|
||||||
<div class="info">
|
<img :src="getIconPath(props.icon)" class="icon" />
|
||||||
<div class="name">{{ props.name }}</div>
|
<div class="info">
|
||||||
<div class="intro">
|
<div class="name">{{ props.name }}</div>
|
||||||
{{ props.intro }}
|
<div class="intro">
|
||||||
|
{{ props.intro }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-30">
|
<div>
|
||||||
<el-switch v-model="isOpen" v-if="props.showSwitch" />
|
<el-switch v-model="isOpen" v-if="props.showSwitch" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -53,13 +55,15 @@ const getIconPath = (iconName) => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.box {
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
transition: all 0.1s ease-in-out;
|
||||||
|
}
|
||||||
.item {
|
.item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 10px;
|
|
||||||
background-color: #f8f8f8;
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: all 0.1s ease-in-out;
|
|
||||||
|
|
||||||
// &:hover {
|
// &:hover {
|
||||||
// cursor: pointer;
|
// cursor: pointer;
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,24 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="row" v-for="(item, index) in menus" :key="index">
|
<div class="row" v-for="(item, index) in menus" :key="index">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</div>
|
</div>
|
||||||
<div class="menus_wrap">
|
<div class="menus_wrap">
|
||||||
<div class="item" v-for="(val, i) in item.list" :key="i" @click="to(val)">
|
<div class="item" v-for="(val, i) in item.list" :key="i" @click="to(val)">
|
||||||
<img :src="getIconPath(val.icon)" class="icon" @error="handleImageError(val)" />
|
<img :src="getIconPath(val.icon)" class="icon" @error="handleImageError(val)" />
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="name">{{ val.name }}</div>
|
<div class="name">{{ val.name }}</div>
|
||||||
<div class="intro">
|
<div class="intro">
|
||||||
{{ val.intro }}
|
{{ val.intro }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|
@ -27,228 +27,231 @@ import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const to = (item) => {
|
const to = (item) => {
|
||||||
if (!item.pathName) {
|
if (!item.pathName) {
|
||||||
ElMessage.warning("暂未开放");
|
ElMessage.warning("暂未开放");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
router.push({
|
router.push({
|
||||||
name: item.pathName,
|
name: item.pathName,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const menus = ref([
|
const menus = ref([
|
||||||
{
|
{
|
||||||
label: "营销",
|
label: "营销",
|
||||||
list: [
|
list: [
|
||||||
{
|
{
|
||||||
name: "霸王餐",
|
name: "霸王餐",
|
||||||
icon: "bwc",
|
icon: "bwc",
|
||||||
pathName: "bwc",
|
pathName: "bwc",
|
||||||
intro: "设置充值消费的N倍,当前订单立即免单",
|
intro: "设置充值消费的N倍,当前订单立即免单",
|
||||||
},
|
},
|
||||||
{ name: "邀请列表", icon: "yqlb", pathName: "invite", intro: "邀请好友领券" },
|
{ name: "邀请列表", icon: "yqlb", pathName: "invite", intro: "邀请好友领券" },
|
||||||
{
|
{
|
||||||
name: "积分锁客",
|
name: "积分锁客",
|
||||||
icon: "jfsk",
|
icon: "jfsk",
|
||||||
pathName: "points",
|
pathName: "points",
|
||||||
intro: "设置充值消费的N倍,当前订单立即免单",
|
intro: "设置充值消费的N倍,当前订单立即免单",
|
||||||
},
|
},
|
||||||
{ name: "充值活动", icon: "czhd", pathName: "", intro: "允许客户充值并使用余额支付" },
|
{ name: "充值活动", icon: "czhd", pathName: "", intro: "允许客户充值并使用余额支付" },
|
||||||
{ name: "弹窗广告", icon: "tcgg", pathName: "", intro: "设置弹窗广告" },
|
{ name: "弹窗广告", icon: "tcgg", pathName: "", intro: "设置弹窗广告" },
|
||||||
{ name: "超级会员", icon: "cjhy", pathName: "superVip", intro: "用户会员管理设置" },
|
{ name: "超级会员", icon: "cjhy", pathName: "superVip", intro: "用户会员管理设置" },
|
||||||
{ name: "新客立减", icon: "xklj", pathName: "", intro: "首单下单减免金额" },
|
{ name: "新客立减", icon: "xklj", pathName: "newUserDiscount", intro: "首单下单减免金额" },
|
||||||
{ name: "智慧充值", icon: "zhcz", pathName: "", intro: "允许客户充值并使用余额支付" },
|
{ name: "智慧充值", icon: "zhcz", pathName: "", intro: "允许客户充值并使用余额支付" },
|
||||||
{ name: "分销", icon: "zhcz", pathName: "", intro: "允许客户充值并使用余额支付" },
|
{ name: "分销", icon: "zhcz", pathName: "", intro: "允许客户充值并使用余额支付" },
|
||||||
{
|
{
|
||||||
name: "消费返现",
|
name: "消费返现",
|
||||||
icon: "xffx",
|
icon: "xffx",
|
||||||
pathName: "",
|
pathName: "",
|
||||||
intro: "用户下单后返现一定的金额到余额,可促进复购",
|
intro: "用户下单后返现一定的金额到余额,可促进复购",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "私域引流",
|
name: "私域引流",
|
||||||
icon: "syyl",
|
icon: "syyl",
|
||||||
pathName: "",
|
pathName: "",
|
||||||
intro: "可设置用户下单成功后的群二维码",
|
intro: "可设置用户下单成功后的群二维码",
|
||||||
},
|
},
|
||||||
{ name: "满减活动", icon: "mjhd", pathName: "", intro: "达到指定支付金额享受减价" },
|
{ name: "满减活动", icon: "mjhd", pathName: "", intro: "达到指定支付金额享受减价" },
|
||||||
{ name: "生日有礼", icon: "sryl", pathName: "", intro: "用户生日管理设置" },
|
{ name: "生日有礼", icon: "sryl", pathName: "", intro: "用户生日管理设置" },
|
||||||
{
|
{
|
||||||
name: "点餐智能推荐",
|
name: "点餐智能推荐",
|
||||||
icon: "dczntj",
|
icon: "dczntj",
|
||||||
pathName: "",
|
pathName: "",
|
||||||
intro: "进入点单页X秒未点自动推荐商品,此推荐设置启用即生效",
|
intro: "进入点单页X秒未点自动推荐商品,此推荐设置启用即生效",
|
||||||
},
|
},
|
||||||
{ name: "超值券包", icon: "czqb", pathName: "", intro: "下单加购" },
|
{ name: "超值券包", icon: "czqb", pathName: "", intro: "下单加购" },
|
||||||
{
|
{
|
||||||
name: "套餐推广",
|
name: "套餐推广",
|
||||||
icon: "tctg",
|
icon: "tctg",
|
||||||
pathName: "",
|
pathName: "",
|
||||||
intro: "下单通过用户邀请好友减免金额的方式裂变宣传套餐加购",
|
intro: "下单通过用户邀请好友减免金额的方式裂变宣传套餐加购",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "充值兑换码",
|
name: "充值兑换码",
|
||||||
icon: "czdhm",
|
icon: "czdhm",
|
||||||
pathName: "",
|
pathName: "",
|
||||||
intro: "兑换码直充余额,可当作礼品赠送",
|
intro: "兑换码直充余额,可当作礼品赠送",
|
||||||
},
|
},
|
||||||
{ name: "券兑换码", icon: "qdhm", pathName: "", intro: "可添加多券组合兑换" },
|
{ name: "券兑换码", icon: "qdhm", pathName: "", intro: "可添加多券组合兑换" },
|
||||||
{ name: "限时折扣", icon: "xszk", pathName: "", intro: "批量设置商品折扣" },
|
{ name: "限时折扣", icon: "xszk", pathName: "", intro: "批量设置商品折扣" },
|
||||||
{ name: "商品拼团", icon: "sppt", pathName: "", intro: "拼团" },
|
{ name: "商品拼团", icon: "sppt", pathName: "", intro: "拼团" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "优惠券",
|
label: "优惠券",
|
||||||
list: [
|
list: [
|
||||||
{
|
{
|
||||||
name: "满减券",
|
name: "满减券",
|
||||||
icon: "mjq",
|
icon: "mjq",
|
||||||
pathName: "discount_coupon",
|
pathName: "discount_coupon",
|
||||||
intro: "用户满足指定金额后,可使用优惠券立减相应金额,如:设置满100-50券,符合要求的订单满100元后,立减50元。",
|
intro:
|
||||||
},
|
"用户满足指定金额后,可使用优惠券立减相应金额,如:设置满100-50券,符合要求的订单满100元后,立减50元。",
|
||||||
{
|
},
|
||||||
name: "商品兑换券",
|
{
|
||||||
icon: "spdhq",
|
name: "商品兑换券",
|
||||||
pathName: "product_redemption",
|
icon: "spdhq",
|
||||||
intro: "设置可兑换成商品的券",
|
pathName: "product_redemption",
|
||||||
},
|
intro: "设置可兑换成商品的券",
|
||||||
{
|
},
|
||||||
name: "折扣券",
|
{
|
||||||
icon: "zkq",
|
name: "折扣券",
|
||||||
pathName: "rebate_coupon",
|
icon: "zkq",
|
||||||
intro: "下单享折扣但折扣的金额将在券中抵扣。",
|
pathName: "rebate_coupon",
|
||||||
},
|
intro: "下单享折扣但折扣的金额将在券中抵扣。",
|
||||||
{
|
},
|
||||||
name: "第二件半价券",
|
{
|
||||||
icon: "dejbjq",
|
name: "第二件半价券",
|
||||||
pathName: "half_price",
|
icon: "dejbjq",
|
||||||
intro: "设置第二件半价券",
|
pathName: "half_price",
|
||||||
},
|
intro: "设置第二件半价券",
|
||||||
{
|
},
|
||||||
name: "消费赠券",
|
{
|
||||||
icon: "xfzq",
|
name: "消费赠券",
|
||||||
pathName: "consume_ticket",
|
icon: "xfzq",
|
||||||
intro: "达到指定消费金额赠送优惠券",
|
pathName: "consume_ticket",
|
||||||
},
|
intro: "达到指定消费金额赠送优惠券",
|
||||||
{
|
},
|
||||||
name: "买一送一券",
|
{
|
||||||
icon: "myzy",
|
name: "买一送一券",
|
||||||
pathName: "buy_one",
|
icon: "myzy",
|
||||||
intro: "针对营销活动买一送一设置券品",
|
pathName: "buy_one",
|
||||||
},
|
intro: "针对营销活动买一送一设置券品",
|
||||||
{
|
},
|
||||||
name: "固定价格券",
|
{
|
||||||
icon: "gdjkq",
|
name: "固定价格券",
|
||||||
pathName: "",
|
icon: "gdjkq",
|
||||||
intro: "设置该券后,允许用户以固定价格兑换指定商品,如:设置一个固定价格9.9的券,商品20元,用户使用券后只需要9.9元兑换该商品。",
|
pathName: "",
|
||||||
},
|
intro:
|
||||||
{
|
"设置该券后,允许用户以固定价格兑换指定商品,如:设置一个固定价格9.9的券,商品20元,用户使用券后只需要9.9元兑换该商品。",
|
||||||
name: "免配送费券",
|
},
|
||||||
icon: "mfpsq",
|
{
|
||||||
pathName: "",
|
name: "免配送费券",
|
||||||
intro: "可设置一张免除订单配送费的券",
|
icon: "mfpsq",
|
||||||
},
|
pathName: "",
|
||||||
],
|
intro: "可设置一张免除订单配送费的券",
|
||||||
},
|
},
|
||||||
{
|
],
|
||||||
label: "推送功能",
|
},
|
||||||
list: [
|
{
|
||||||
{ name: "推送活动消息", icon: "tshdxx", pathName: "", intro: "给用户推送服务通知" },
|
label: "推送功能",
|
||||||
{ name: "短信推送", icon: "dxts", pathName: "", intro: "给用户推送服务通知" },
|
list: [
|
||||||
],
|
{ name: "推送活动消息", icon: "tshdxx", pathName: "", intro: "给用户推送服务通知" },
|
||||||
},
|
{ name: "短信推送", icon: "dxts", pathName: "", intro: "给用户推送服务通知" },
|
||||||
{
|
],
|
||||||
label: "扩展功能",
|
},
|
||||||
list: [
|
{
|
||||||
{
|
label: "扩展功能",
|
||||||
name: "微信公众号",
|
list: [
|
||||||
icon: "wxgzh",
|
{
|
||||||
pathName: "",
|
name: "微信公众号",
|
||||||
intro: "授权微信公众号后,让你能够在后台查看和维护公众号的粉丝;同时你的店铺也有出现关注公众号的入口。",
|
icon: "wxgzh",
|
||||||
},
|
pathName: "",
|
||||||
],
|
intro:
|
||||||
},
|
"授权微信公众号后,让你能够在后台查看和维护公众号的粉丝;同时你的店铺也有出现关注公众号的入口。",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 动态获取PNG图标路径
|
// 动态获取PNG图标路径
|
||||||
const getIconPath = (iconName) => {
|
const getIconPath = (iconName) => {
|
||||||
try {
|
try {
|
||||||
// 直接导入对应PNG文件
|
// 直接导入对应PNG文件
|
||||||
return new URL(`/src/assets/applocation/${iconName}.png`, import.meta.url).href;
|
return new URL(`/src/assets/applocation/${iconName}.png`, import.meta.url).href;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`图标 ${iconName}.png 不存在`);
|
console.warn(`图标 ${iconName}.png 不存在`);
|
||||||
return defaultIcon; // 图标不存在时使用默认图标
|
return defaultIcon; // 图标不存在时使用默认图标
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理图片加载失败
|
// 处理图片加载失败
|
||||||
const handleImageError = (item) => {
|
const handleImageError = (item) => {
|
||||||
console.error(`图标 ${item.icon}.png 加载失败`);
|
console.error(`图标 ${item.icon}.png 加载失败`);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.app-container {
|
.app-container {
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
padding-bottom: 14px;
|
padding-bottom: 14px;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menus_wrap {
|
.menus_wrap {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
gap: 14px;
|
gap: 14px;
|
||||||
margin-top: 14px;
|
margin-top: 14px;
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: #f8f8f8;
|
background-color: #f8f8f8;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
transition: all 0.1s ease-in-out;
|
transition: all 0.1s ease-in-out;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #d5ebff;
|
background-color: #d5ebff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
.name {
|
.name {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.intro {
|
.intro {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #666;
|
color: #666;
|
||||||
line-height: 1.4em;
|
line-height: 1.4em;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-line-clamp: 1;
|
-webkit-line-clamp: 1;
|
||||||
line-clamp: 1;
|
line-clamp: 1;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-dialog title="购买会员方案" v-model="show" @close="reset" width="60%">
|
||||||
|
<el-form :model="form" label-width="120px">
|
||||||
|
<el-form-item label="周期名称" required>
|
||||||
|
<el-input v-model="form.name" placeholder="周期名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="周期价格" required>
|
||||||
|
<el-input v-model="form.price" placeholder="周期价格" type="number" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="赠送成长值" required>
|
||||||
|
<el-input v-model="form.reward" placeholder="开通后立刻获得经验" type="number" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="周期时间" required>
|
||||||
|
<div class="flex">
|
||||||
|
<el-input-number
|
||||||
|
style="width: 300px"
|
||||||
|
v-model="form.circleTime"
|
||||||
|
placeholder="周期时间"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
<el-select class="ml-2" v-model="form.circleUnit" placeholder="">
|
||||||
|
<el-option label="年" value="年" />
|
||||||
|
<el-option label="月" value="月" />
|
||||||
|
<el-option label="周" value="周" />
|
||||||
|
<el-option label="天" value="天" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div style="text-align: right; margin-top: 20px">
|
||||||
|
<el-button @click="close">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submit">{{ isedit ? "更新" : "提交" }}</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, toRaw } from "vue";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
// 控制主弹窗显示
|
||||||
|
const show = ref(false);
|
||||||
|
|
||||||
|
// 控制优惠券选择弹窗显示
|
||||||
|
const couponDialogVisible = ref(false);
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const form = ref({
|
||||||
|
name: "",
|
||||||
|
price: 0,
|
||||||
|
reward: 0,
|
||||||
|
couponList: [], // 存储已选择的优惠券
|
||||||
|
circleTime: 1, // 会员周期
|
||||||
|
circleUnit: "月", // 会员周期单位
|
||||||
|
});
|
||||||
|
|
||||||
|
// 优惠券列表数据
|
||||||
|
const couponList = ref([
|
||||||
|
{ id: 1, name: "满100减10", value: "10元" },
|
||||||
|
{ id: 2, name: "满200减30", value: "30元" },
|
||||||
|
{ id: 3, name: "满500减100", value: "100元" },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 已选择的优惠券
|
||||||
|
const selectedCoupons = ref([]);
|
||||||
|
|
||||||
|
// 打开优惠券选择弹窗
|
||||||
|
function openCouponDialog() {
|
||||||
|
couponDialogVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭优惠券选择弹窗
|
||||||
|
function closeCouponDialog() {
|
||||||
|
couponDialogVisible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认选择优惠券
|
||||||
|
function confirmCouponSelection() {
|
||||||
|
form.value.couponList = [...selectedCoupons.value];
|
||||||
|
closeCouponDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理优惠券选择
|
||||||
|
function handleCouponSelection(selection) {
|
||||||
|
selectedCoupons.value = selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
function reset() {
|
||||||
|
form.value = {
|
||||||
|
name: "",
|
||||||
|
price: 0,
|
||||||
|
reward: 0,
|
||||||
|
couponList: [],
|
||||||
|
circleTime: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const emits = defineEmits(["submitSuccess"]);
|
||||||
|
// 提交表单
|
||||||
|
function submit() {
|
||||||
|
if (!form.value.name) {
|
||||||
|
ElMessage.error("请输入方案名称");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (form.value.price <= 0) {
|
||||||
|
ElMessage.error("请输入有效的价格");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!form.value.circleTime) {
|
||||||
|
ElMessage.error("请选择会员周期");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ispass = form.value.couponList.every((item) => item.num && item.coupon.id);
|
||||||
|
if (!ispass) {
|
||||||
|
ElMessage.error("请选择优惠券并输入数量");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("提交表单数据:", form.value);
|
||||||
|
emits("submitSuccess", form.value, dataIndex);
|
||||||
|
// 在此处可以添加表单提交逻辑,例如调用 API
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
let isedit = ref(false);
|
||||||
|
let dataIndex = null;
|
||||||
|
function open(data, index) {
|
||||||
|
data = toRaw(data);
|
||||||
|
console.log("data", data);
|
||||||
|
console.log("index", index);
|
||||||
|
if (data) {
|
||||||
|
form.value = data;
|
||||||
|
isedit.value = true;
|
||||||
|
dataIndex = index;
|
||||||
|
} else {
|
||||||
|
isedit.value = false;
|
||||||
|
dataIndex = null;
|
||||||
|
}
|
||||||
|
console.log(data);
|
||||||
|
show.value = true;
|
||||||
|
}
|
||||||
|
function close() {
|
||||||
|
show.value = false;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
defineExpose({ open, close, reset, submit });
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,290 @@
|
||||||
|
<template>
|
||||||
|
<div class="m-4 bg-white p-4">
|
||||||
|
<HeaderCard
|
||||||
|
name="新客立减"
|
||||||
|
intro="首单下单减免金额"
|
||||||
|
icon="new_user_discount"
|
||||||
|
showSwitch
|
||||||
|
v-model:isOpen="isEnable"
|
||||||
|
></HeaderCard>
|
||||||
|
<el-form ref="form" :model="basicForm">
|
||||||
|
<el-form-item label="减免方式">
|
||||||
|
<div>
|
||||||
|
<el-radio-group v-model="basicForm.discountType">
|
||||||
|
<el-radio value="FIXED">固定金额</el-radio>
|
||||||
|
<el-radio value="RANDOM">随机立减</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<div v-if="basicForm.discountType === 'FIXED'">
|
||||||
|
<el-input type="number" v-model="basicForm.discountValue" placeholder="请输入金额">
|
||||||
|
<template #append>元</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- 随机立减 -->
|
||||||
|
<div v-if="basicForm.discountType == 'RANDOM'">
|
||||||
|
<el-form-item label="会员周期列表">
|
||||||
|
<el-button type="primary" @click="refDialogPlans.open()">添加方案</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="">
|
||||||
|
<el-table :data="basicForm.randomDiscountList" border style="width: 60%">
|
||||||
|
<el-table-column prop="amount" label="减免金融(元)" align="center" />
|
||||||
|
<el-table-column prop="probability" label="概率(%)" align="center" />
|
||||||
|
|
||||||
|
<el-table-column label="操作" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="text" @click="refDialogPlans.open(scope.row, scope.$index)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button type="text" style="color: red" @click="deletePlan(scope.row)">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-form-item label="可使用类型">
|
||||||
|
<el-checkbox-group v-model="basicForm.useType">
|
||||||
|
<el-checkbox
|
||||||
|
v-model="item.value"
|
||||||
|
:label="item.value"
|
||||||
|
v-for="item in useTypeList"
|
||||||
|
:key="item.value"
|
||||||
|
>
|
||||||
|
{{ item.label }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="flex mt-10 justify-center gap-10">
|
||||||
|
<el-button style="width: 100px" type="primary" @click="basicSubmit" size="large">
|
||||||
|
保存
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="close" style="width: 100px" size="large">取消</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DialogPlans ref="refDialogPlans" @submitSuccess="submitSuccess"></DialogPlans>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import shopApi from "@/api/account/shop";
|
||||||
|
import consumeDiscountApi from "@/api/market/consumeDiscount";
|
||||||
|
import HeaderCard from "../components/headerCard.vue";
|
||||||
|
import DialogPlans from "./components/dialog-plans.vue";
|
||||||
|
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted } from "vue";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
|
const inputStyle = {
|
||||||
|
width: "340px",
|
||||||
|
};
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
//是否开启超级会员
|
||||||
|
const isEnable = ref(false);
|
||||||
|
|
||||||
|
const refDialogPlans = ref();
|
||||||
|
const configs = [
|
||||||
|
{ name: "basic", label: "会员基础设置" },
|
||||||
|
{ name: "lv", label: "会员等级设置" },
|
||||||
|
{ name: "order", label: "购买会员订单" },
|
||||||
|
];
|
||||||
|
const activeTab = ref("basic");
|
||||||
|
const useTypeList = ref([
|
||||||
|
{ label: "堂食", value: "dine-in" },
|
||||||
|
{ label: "外带", value: "take-out" },
|
||||||
|
{ label: "外卖", value: "take-away" },
|
||||||
|
]);
|
||||||
|
const basicForm = reactive({
|
||||||
|
isEnable: 0,
|
||||||
|
discountType: "RANDOM",
|
||||||
|
discountAmount: 0.0,
|
||||||
|
randomDiscountList: [],
|
||||||
|
useType: [],
|
||||||
|
shopId: 0,
|
||||||
|
});
|
||||||
|
function deletePlan(row) {
|
||||||
|
const index = basicForm.configList.indexOf(row);
|
||||||
|
if (index > -1) {
|
||||||
|
basicForm.configList.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function submitSuccess(plans, index) {
|
||||||
|
if (!basicForm.configList) {
|
||||||
|
basicForm.configList = [];
|
||||||
|
}
|
||||||
|
if (index !== null && index !== undefined) {
|
||||||
|
basicForm.configList[index] = plans;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
basicForm.configList.push(plans);
|
||||||
|
}
|
||||||
|
// 会员基础设置提交
|
||||||
|
function basicSubmit() {
|
||||||
|
const data = toRaw(basicForm);
|
||||||
|
// if (data.openType == "PAY") {
|
||||||
|
// data.conditionList = null;
|
||||||
|
// }
|
||||||
|
// if (data.openType == "CONDITION") {
|
||||||
|
// data.configList = null;
|
||||||
|
// }
|
||||||
|
data.conditionList = useTypes.value
|
||||||
|
.filter((v) => v.checked)
|
||||||
|
.map((v) => {
|
||||||
|
return {
|
||||||
|
code: v.code,
|
||||||
|
value: v.value,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
consumeDiscountApi.editConfig(data).then((res) => {
|
||||||
|
ElMessage.success("保存成功");
|
||||||
|
});
|
||||||
|
// ElMessage.success("保存成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 会员等级列表
|
||||||
|
const levels = ref([]);
|
||||||
|
|
||||||
|
// 当前选中的会员等级
|
||||||
|
const selectedLevel = ref(null);
|
||||||
|
|
||||||
|
// 优惠券列表
|
||||||
|
const couponList = ref([
|
||||||
|
{ id: 1, name: "满100减10" },
|
||||||
|
{ id: 2, name: "满200减30" },
|
||||||
|
]);
|
||||||
|
let activeLevelId = ref(null);
|
||||||
|
// 添加会员等级
|
||||||
|
function addLevel() {
|
||||||
|
const nowLastVip = levels.value[levels.value.length - 1];
|
||||||
|
let name = "VIP1";
|
||||||
|
if (levels.value.length) {
|
||||||
|
name = "VIP" + (levels.value.length + 1);
|
||||||
|
}
|
||||||
|
if (nowLastVip && !nowLastVip.id) {
|
||||||
|
ElMessage.error("请先保存当前等级");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newLevel = {
|
||||||
|
name,
|
||||||
|
experienceValue: 0,
|
||||||
|
discount: 1,
|
||||||
|
logo: "",
|
||||||
|
costRewardPoints: 1,
|
||||||
|
isCostRewardPoints: 1,
|
||||||
|
isCycleReward: 0,
|
||||||
|
cycleTime: 1,
|
||||||
|
cycleUnit: "月",
|
||||||
|
cycleRewardPoints: 1,
|
||||||
|
cycleRewardCouponList: [],
|
||||||
|
};
|
||||||
|
console.log(newLevel);
|
||||||
|
levels.value.push(newLevel);
|
||||||
|
selectedLevel.value = newLevel;
|
||||||
|
activeLevelId.value = levels.value.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑会员等级
|
||||||
|
function editLevel(level) {
|
||||||
|
selectedLevel.value = level;
|
||||||
|
}
|
||||||
|
// 删除会员等级
|
||||||
|
async function removeLevel(index) {
|
||||||
|
const item = levels.value[index];
|
||||||
|
const { id } = item;
|
||||||
|
if (!id) {
|
||||||
|
// 本地删除
|
||||||
|
levels.value.splice(index, 1);
|
||||||
|
const newLevel = levels.value[index - 1];
|
||||||
|
selectedLevel.value = newLevel;
|
||||||
|
activeLevelId.value = index - 1;
|
||||||
|
ElMessage.success("删除成功");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ElMessageBox.confirm("确定要删除吗?", "提示", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning",
|
||||||
|
}).then(async () => {
|
||||||
|
const res = await consumeDiscountApi.levelDel({ id: id });
|
||||||
|
if (res) {
|
||||||
|
levels.value.splice(index, 1);
|
||||||
|
ElMessage.success("删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
const newLevel = levels.value[index - 1];
|
||||||
|
selectedLevel.value = newLevel;
|
||||||
|
activeLevelId.value = index - 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 保存会员等级
|
||||||
|
async function saveLevel(level) {
|
||||||
|
const isPass = level.cycleRewardCouponList.every((item) => item.num && item.coupon.id);
|
||||||
|
if (!isPass) {
|
||||||
|
ElMessage.error("请选择优惠券并输入数量");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const res = level.id
|
||||||
|
? await consumeDiscountApi.levelEdit(level)
|
||||||
|
: await consumeDiscountApi.levelAdd(level);
|
||||||
|
if (res) {
|
||||||
|
ElMessage.success("保存成功");
|
||||||
|
}
|
||||||
|
levelRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
const shops = ref([]);
|
||||||
|
|
||||||
|
async function levelRefresh() {
|
||||||
|
consumeDiscountApi.levelList().then((res) => {
|
||||||
|
if (res && res.length) {
|
||||||
|
levels.value = res;
|
||||||
|
if (res.length != 0) {
|
||||||
|
selectedLevel.value = res[activeLevelId.value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function init() {
|
||||||
|
consumeDiscountApi.getConfig().then((res) => {
|
||||||
|
Object.assign(basicForm, res);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
init();
|
||||||
|
});
|
||||||
|
//计算总优惠券数量
|
||||||
|
function totalCount(arr) {
|
||||||
|
return arr.reduce((total, item) => {
|
||||||
|
return total + item.num * 1;
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
//返回
|
||||||
|
function close() {
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.el-tabs--border-card) {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
:deep(.el-tabs--border-card > .el-tabs__header) {
|
||||||
|
border: none;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item) {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
:deep(.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active) {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -324,6 +324,7 @@ import CouponLists from "./components/coup-lists.vue";
|
||||||
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted } from "vue";
|
import { ref, reactive, watch, toRaw, getCurrentInstance, onMounted } from "vue";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
import a from "@/utils/test";
|
||||||
|
|
||||||
const inputStyle = {
|
const inputStyle = {
|
||||||
width: "340px",
|
width: "340px",
|
||||||
|
|
@ -344,7 +345,7 @@ const activeTab = ref("basic");
|
||||||
const conditionLists = ref([
|
const conditionLists = ref([
|
||||||
{ label: "绑定手机号", checked: false, code: "BIND_PHONE" },
|
{ label: "绑定手机号", checked: false, code: "BIND_PHONE" },
|
||||||
{ label: "订单达成指定次数", checked: false, value: "", code: "ORDER" },
|
{ label: "订单达成指定次数", checked: false, value: "", code: "ORDER" },
|
||||||
{ label: "消费达到指定金额", checked: false, value: "", cpde: "COST_AMOUNT" },
|
{ label: "消费达到指定金额", checked: false, value: "", code: "COST_AMOUNT" },
|
||||||
{ label: "充值达到指定金额", checked: false, value: "", code: "RECHARGE_AMOUNT" },
|
{ label: "充值达到指定金额", checked: false, value: "", code: "RECHARGE_AMOUNT" },
|
||||||
]);
|
]);
|
||||||
const basicForm = reactive({
|
const basicForm = reactive({
|
||||||
|
|
@ -383,6 +384,14 @@ function basicSubmit() {
|
||||||
// if (data.openType == "CONDITION") {
|
// if (data.openType == "CONDITION") {
|
||||||
// data.configList = null;
|
// data.configList = null;
|
||||||
// }
|
// }
|
||||||
|
data.conditionList = conditionLists.value
|
||||||
|
.filter((v) => v.checked)
|
||||||
|
.map((v) => {
|
||||||
|
return {
|
||||||
|
code: v.code,
|
||||||
|
value: v.value,
|
||||||
|
};
|
||||||
|
});
|
||||||
memberApi.editConfig(data).then((res) => {
|
memberApi.editConfig(data).then((res) => {
|
||||||
ElMessage.success("保存成功");
|
ElMessage.success("保存成功");
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-dialog title="优惠券" v-model="visible" width="80%">
|
||||||
|
<el-form :inline="true" :model="form">
|
||||||
|
<el-form-item label="券名称">
|
||||||
|
<el-input v-model="form.name" placeholder="请输入券名称"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-select v-model="form.status" placeholder="请选择" style="width: 140px">
|
||||||
|
<el-option
|
||||||
|
v-for="item in status"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="领取时间">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="form.date"
|
||||||
|
type="daterange"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
style="width: 100%"
|
||||||
|
:data="tableData"
|
||||||
|
:columns="columns"
|
||||||
|
:pagination="pagination"
|
||||||
|
:row-key="getRowKey"
|
||||||
|
>
|
||||||
|
<el-table-column prop="id" label="券ID" />
|
||||||
|
<el-table-column prop="name" label="券名称" />
|
||||||
|
<!-- <el-table-column prop="type" label="券类型" /> -->
|
||||||
|
<el-table-column prop="createTime" label="领取时间" />
|
||||||
|
<el-table-column prop="useTime" label="使用时间" />
|
||||||
|
<el-table-column prop="source" label="领取来源" />
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-link :underline="false" type="primary" size="mini">查看</el-link>
|
||||||
|
<el-button :underline="false" type="danger" size="mini">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<el-pagination
|
||||||
|
v-model:current-page="pagination.currentPage"
|
||||||
|
v-model:page-size="pagination.pageSize"
|
||||||
|
:total="pagination.total"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@current-change="getList"
|
||||||
|
@size-change="getList"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import couponApi from "@/api/market/coupon";
|
||||||
|
|
||||||
|
import { ref, reactive } from "vue";
|
||||||
|
const status = [
|
||||||
|
{ label: "全部", value: "" },
|
||||||
|
{ label: "未使用", value: 0 },
|
||||||
|
{ label: "已使用", value: 1 },
|
||||||
|
{ label: "已过期", value: 2 },
|
||||||
|
];
|
||||||
|
const visible = ref(false);
|
||||||
|
const form = reactive({
|
||||||
|
status: 0,
|
||||||
|
name: "",
|
||||||
|
date: "",
|
||||||
|
userId: "",
|
||||||
|
page: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
function open(data) {
|
||||||
|
console.log(data);
|
||||||
|
data.userId = form.userId;
|
||||||
|
form.page = 1;
|
||||||
|
visible.value = true;
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
function close() {
|
||||||
|
visible.value = false;
|
||||||
|
}
|
||||||
|
function getList() {
|
||||||
|
couponApi.getDetail(form).then((res) => {
|
||||||
|
console.log(res);
|
||||||
|
tableData.value = res.records;
|
||||||
|
pagination.total = res.totalRow;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const tableData = ref([]);
|
||||||
|
const pagination = ref({
|
||||||
|
total: 0,
|
||||||
|
pageSize: 10,
|
||||||
|
currentPage: 1,
|
||||||
|
});
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
close,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -56,6 +56,14 @@ const contentConfig: IContentConfig<any> = {
|
||||||
templet: "custom",
|
templet: "custom",
|
||||||
slotName: "mobile",
|
slotName: "mobile",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "优惠券",
|
||||||
|
align: "center",
|
||||||
|
prop: "coupon",
|
||||||
|
width: 140,
|
||||||
|
templet: "custom",
|
||||||
|
slotName: "coupon",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "余额",
|
label: "余额",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,15 @@
|
||||||
style="margin-left: 2px"
|
style="margin-left: 2px"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #coupon="scope">
|
||||||
|
<div>
|
||||||
|
1张
|
||||||
|
<el-link :underline="false" type="primary" @click="handleViewCoupon(scope.row)">
|
||||||
|
查看详情
|
||||||
|
</el-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</page-content>
|
</page-content>
|
||||||
|
|
||||||
<!-- 新增 -->
|
<!-- 新增 -->
|
||||||
|
|
@ -108,10 +117,14 @@
|
||||||
@formDataChange="formDataChange"
|
@formDataChange="formDataChange"
|
||||||
@submit-click="handleSubmitClick"
|
@submit-click="handleSubmitClick"
|
||||||
></page-modal>
|
></page-modal>
|
||||||
|
|
||||||
|
<!-- 用户优惠券详情 -->
|
||||||
|
<UserCouponDialog ref="userCouponDialogRef"></UserCouponDialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup >
|
<script setup >
|
||||||
|
import UserCouponDialog from "./components/user-coupon-dialog.vue";
|
||||||
import usePage from "@/components/CURD/usePage";
|
import usePage from "@/components/CURD/usePage";
|
||||||
import addModalConfig from "./config/add";
|
import addModalConfig from "./config/add";
|
||||||
import contentConfig from "./config/content";
|
import contentConfig from "./config/content";
|
||||||
|
|
@ -121,6 +134,12 @@ import searchConfig from "./config/search";
|
||||||
import { returnOptionsLabel } from "./config/config";
|
import { returnOptionsLabel } from "./config/config";
|
||||||
import shopUserApi from "@/api/account/shopUser";
|
import shopUserApi from "@/api/account/shopUser";
|
||||||
const editMoneyModalRef = ref(null);
|
const editMoneyModalRef = ref(null);
|
||||||
|
const userCouponDialogRef = ref(null);
|
||||||
|
|
||||||
|
//查看用户优惠券
|
||||||
|
function handleViewCoupon(row) {
|
||||||
|
userCouponDialogRef.value.open(row);
|
||||||
|
}
|
||||||
const {
|
const {
|
||||||
searchRef,
|
searchRef,
|
||||||
contentRef,
|
contentRef,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue