Merge branch 'ymf' of https://newgitea.sxczgkj.cn/czg_team/cashier_app into new_gyq
This commit is contained in:
commit
b39b458fe7
3
App.vue
3
App.vue
|
|
@ -160,6 +160,8 @@ App.vue本身不是页面,这里不能编写视图元素,也就是没有<tem
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@import "uview-plus/index.scss";
|
||||||
|
|
||||||
/** 每个页面公共css */
|
/** 每个页面公共css */
|
||||||
@import '@/commons/style/global.scss';
|
@import '@/commons/style/global.scss';
|
||||||
@import '@/commons/style/common.scss';
|
@import '@/commons/style/common.scss';
|
||||||
|
|
@ -167,5 +169,4 @@ App.vue本身不是页面,这里不能编写视图元素,也就是没有<tem
|
||||||
/** uni 组件样式覆盖 */
|
/** uni 组件样式覆盖 */
|
||||||
@import '@/commons/style/uni-overwrite.scss';
|
@import '@/commons/style/uni-overwrite.scss';
|
||||||
|
|
||||||
@import "uview-plus/index.scss";
|
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -1,14 +1,5 @@
|
||||||
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
|
|
||||||
|
|
||||||
// 密钥对生成 http://web.chacuo.net/netrsakeypair
|
|
||||||
|
|
||||||
const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD\n' +
|
|
||||||
'2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ=='
|
|
||||||
|
|
||||||
// 加密
|
|
||||||
export function encrypt(txt) {
|
export function encrypt(txt) {
|
||||||
const encryptor = new JSEncrypt()
|
|
||||||
encryptor.setPublicKey(publicKey) // 设置公钥
|
return txt
|
||||||
return encryptor.encrypt(txt) // 对需要加密的数据进行加密
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import http from "@/http/http.js";
|
||||||
|
const request = http.request;
|
||||||
|
const urlType = "market";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新客立减
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getDiscountByUserId(params) {
|
||||||
|
return request({
|
||||||
|
url: marketUrl + `/admin/consumeDiscount/getDiscountByUserId`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -38,3 +38,18 @@ export function del(id) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 满减活动
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function discountActivity(params) {
|
||||||
|
return request({
|
||||||
|
url: urlType+`/admin/discountActivity`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
...params
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import http from "@/http/http.js";
|
||||||
|
const request = http.request;
|
||||||
|
const urlType = "market";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限时折扣
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function limitTimeDiscount(params) {
|
||||||
|
return request({
|
||||||
|
url: urlType + `/admin/limitTimeDiscount`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ const request = http.request
|
||||||
export function getOrderPayUrl(data, urlType = 'order') {
|
export function getOrderPayUrl(data, urlType = 'order') {
|
||||||
return request({
|
return request({
|
||||||
url: `${urlType}/pay/shopPayApi/orderPayUrl`,
|
url: `${urlType}/pay/shopPayApi/orderPayUrl`,
|
||||||
method: "GET",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
...data
|
...data
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export function getShopTable(data, urlType = 'account') {
|
||||||
*/
|
*/
|
||||||
export function getShopTableDetail(data, urlType = 'account') {
|
export function getShopTableDetail(data, urlType = 'account') {
|
||||||
return request({
|
return request({
|
||||||
url: `${urlType}/admin/shopTable/detail`,
|
url: `/account/admin/shopTable/detail`,
|
||||||
method: "GET",
|
method: "GET",
|
||||||
data: {
|
data: {
|
||||||
...data
|
...data
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import infoBox from "@/commons/utils/infoBox.js"
|
||||||
import go from '@/commons/utils/go.js';
|
import go from '@/commons/utils/go.js';
|
||||||
import { reject } from 'lodash';
|
import { reject } from 'lodash';
|
||||||
// 设置node环境
|
// 设置node环境
|
||||||
|
// envConfig.changeEnv(storageManage.env('production'))
|
||||||
envConfig.changeEnv(storageManage.env('development'))
|
envConfig.changeEnv(storageManage.env('development'))
|
||||||
|
|
||||||
// 测试服
|
// 测试服
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,415 @@
|
||||||
|
// 代课下单
|
||||||
|
import http from '@/http/yskApi/http.js'
|
||||||
|
|
||||||
|
import { accountUrl, marketUrl } from './prveUrl.js'
|
||||||
|
|
||||||
|
const request = http.request
|
||||||
|
|
||||||
|
|
||||||
|
//就餐形式,默认堂食后付费
|
||||||
|
const useType = 'dine-in-after'
|
||||||
|
|
||||||
|
function getUseType() {
|
||||||
|
const type = uni.getStorageSync("useType")
|
||||||
|
return type ? type : useType
|
||||||
|
}
|
||||||
|
// import {
|
||||||
|
// webscoketUtill
|
||||||
|
// } from '../websock.js'
|
||||||
|
// let wxObj = null
|
||||||
|
// wx初始化购物车
|
||||||
|
// export function getWXCart(params) {
|
||||||
|
// let wxUrl = 'ws://192.168.1.31:2348/?' + objectToString(params)
|
||||||
|
// wxObj = new webscoketUtill(wxUrl,3000,9,(e)=>{
|
||||||
|
// console.log('收到消息');
|
||||||
|
// console.log(e);
|
||||||
|
// })
|
||||||
|
// return uni.getStorageSync('wxList')
|
||||||
|
// }
|
||||||
|
// 新增\删除\修改到购物车
|
||||||
|
// export function addWXCart(params) {
|
||||||
|
// wxObj.ws.send(params)
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
function objectToString(obj) {
|
||||||
|
let result = '';
|
||||||
|
for (const key in obj) {
|
||||||
|
if (obj.hasOwnProperty(key)) {
|
||||||
|
result += `${key}=${obj[key]}&`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 去掉最后一个多余的 &
|
||||||
|
return result.slice(0, -1);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取当前台桌订单信息
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getCart(params) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/cart`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
useType: getUseType(),
|
||||||
|
...params
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 已上架商品列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getGoodsLists(params, showLoading = true) {
|
||||||
|
return request({
|
||||||
|
url: `/product/admin/product/list`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...params
|
||||||
|
},
|
||||||
|
showLoading
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点单
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function addCart(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/addCart`,
|
||||||
|
method: "post",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
useType: getUseType(),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空购物车/支付订单
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function $clearCart(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/clearCart`,
|
||||||
|
method: "delete",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
useType: getUseType(),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除购物车某个商品
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function $removeCart(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/removeCart`,
|
||||||
|
method: "delete",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
useType: getUseType(),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 更新规格
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function $updateCart(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/updateCart`,
|
||||||
|
method: "put",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 批量打包
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function $allPack(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/pack`,
|
||||||
|
method: "put",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取取餐号
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function $getMasterId(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/masterId`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
useType: getUseType(),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 支付方式获取
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function $getPayType(data) {
|
||||||
|
return request({
|
||||||
|
url: `/account/admin/payType`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 创建订单
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function $createOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/order`,
|
||||||
|
method: "post",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
useType: getUseType(),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 挂起订单
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function $cacheOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/pending`,
|
||||||
|
method: "post",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
useType: getUseType(),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取已挂起订单
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function $getCacheOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/pending/cart`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
useType: getUseType(),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 会员点单/取消会员点单
|
||||||
|
export function $setUser(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/updateVip`,
|
||||||
|
method: "put",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 删除订单
|
||||||
|
export function $delOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/place/order`,
|
||||||
|
method: "delete",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 支付订单
|
||||||
|
export function $payOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/place/pay',
|
||||||
|
method: "put",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//退单
|
||||||
|
|
||||||
|
export function $returnCart(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/place/returnCart',
|
||||||
|
method: "put",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 选择台桌
|
||||||
|
export function $choseTable(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/place/choseTable',
|
||||||
|
method: "put",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 用餐人数
|
||||||
|
|
||||||
|
export function $choseCount(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/place/choseCount',
|
||||||
|
method: "put",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
useType: getUseType(),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量生成台桌
|
||||||
|
export function $fastCreateTable(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/tbShopTable/generate',
|
||||||
|
method: "post",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//打印当前台桌订单
|
||||||
|
export function $printOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/place/printOrder',
|
||||||
|
method: "post",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//打印当前台桌菜品
|
||||||
|
|
||||||
|
export function $printDishes(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/place/printDishes',
|
||||||
|
method: "post",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 就餐模式切换
|
||||||
|
export function $changeUseType(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/place/choseModel',
|
||||||
|
method: "put",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退款
|
||||||
|
export function $returnOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/place/returnOrder',
|
||||||
|
method: "post",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取用户可用优惠券
|
||||||
|
export function $findCoupon(data) {
|
||||||
|
return request({
|
||||||
|
url: marketUrl+'/admin/coupon/findCoupon',
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//会员积分列表
|
||||||
|
export function $returnMemberPointsList(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/points/member-points/page',
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 会员积分账户信息
|
||||||
|
export function $returnMemberPoints(memberId) {
|
||||||
|
return request({
|
||||||
|
url: '/api/points/member-points/' + memberId,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//002-获取订单可用积分及抵扣金额(支付页面使用)
|
||||||
|
export function $calcUsablePoints(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/points/member-points/calc-usable-points',
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 003-根据积分计算可抵扣金额
|
||||||
|
export function $calcDeDuctionPoints(data) {
|
||||||
|
return request({
|
||||||
|
url: '/api/points/member-points/calc-deduction-amount',
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync("shopId"),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,235 @@
|
||||||
|
/**
|
||||||
|
* HTTP的封装, 基于uni.request
|
||||||
|
* 包括: 通用响应结果的处理 和 业务的增删改查函数
|
||||||
|
*
|
||||||
|
* @author terrfly
|
||||||
|
* @site https://www.jeequan.com
|
||||||
|
* @date 2021/12/16 18:35
|
||||||
|
*/
|
||||||
|
// 设置env配置文件
|
||||||
|
import envConfig from '@/env/config.js'
|
||||||
|
// 导入全局属性
|
||||||
|
import appConfig from '@/config/appConfig.js'
|
||||||
|
import storageManage from '@/commons/utils/storageManage.js'
|
||||||
|
import infoBox from "@/commons/utils/infoBox.js"
|
||||||
|
import go from '@/commons/utils/go.js';
|
||||||
|
import { reject } from 'lodash';
|
||||||
|
// 设置node环境
|
||||||
|
// envConfig.changeEnv(storageManage.env('production'))
|
||||||
|
envConfig.changeEnv(storageManage.env('development'))
|
||||||
|
|
||||||
|
// 测试服
|
||||||
|
// #ifdef H5
|
||||||
|
let baseUrl = '/api/'
|
||||||
|
// #endif
|
||||||
|
// #ifndef H5
|
||||||
|
// let baseUrl = 'https://tapi.cashier.sxczgkj.cn/'
|
||||||
|
//预发布
|
||||||
|
// let baseUrl = 'https://pre-cashieradmin.sxczgkj.cn'
|
||||||
|
|
||||||
|
//正式
|
||||||
|
// let baseUrl = 'https://cashier.sxczgkj.com/'
|
||||||
|
let baseUrl = appConfig.env.JEEPAY_BASE_URL
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
const loadingShowTime = 200
|
||||||
|
|
||||||
|
function getHeader(){
|
||||||
|
const headerObject={}
|
||||||
|
headerObject["token"] = storageManage.token()
|
||||||
|
headerObject["shopId"] = uni.getStorageSync("shopInfo").id
|
||||||
|
headerObject["platformType"] = 'APP'
|
||||||
|
|
||||||
|
return headerObject
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通用处理逻辑
|
||||||
|
function commonsProcess(showLoading, httpReqCallback) {
|
||||||
|
|
||||||
|
// 判断是否请求完成(用作 是否loading )
|
||||||
|
// 包括: 'ing', 'ingLoading', 'finish'
|
||||||
|
let reqState = 'ing'
|
||||||
|
|
||||||
|
// 是否已经提示的错误信息
|
||||||
|
let isShowErrorToast = false
|
||||||
|
|
||||||
|
|
||||||
|
// 请求完成, 需要处理的动作
|
||||||
|
let reqFinishFunc = () => {
|
||||||
|
|
||||||
|
if (reqState == 'ingLoading') { // 关闭loading弹层
|
||||||
|
infoBox.hideLoading()
|
||||||
|
}
|
||||||
|
reqState = 'finish' // 请求完毕
|
||||||
|
}
|
||||||
|
|
||||||
|
// 明确显示loading
|
||||||
|
if (showLoading) {
|
||||||
|
// xx ms内响应完成,不提示loading
|
||||||
|
setTimeout(() => {
|
||||||
|
if (reqState == 'ing') {
|
||||||
|
reqState = 'ingLoading'
|
||||||
|
infoBox.showLoading()
|
||||||
|
}
|
||||||
|
}, loadingShowTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpReqCallback().then((httpData) => {
|
||||||
|
reqFinishFunc(); // 请求完毕的动作
|
||||||
|
// 从http响应数据中解构响应数据 [ 响应码、 bodyData ]
|
||||||
|
let {
|
||||||
|
statusCode,
|
||||||
|
data
|
||||||
|
} = httpData
|
||||||
|
// 避免混淆重新命名
|
||||||
|
let bodyData = data
|
||||||
|
if (statusCode == 500) {
|
||||||
|
isShowErrorToast = true
|
||||||
|
return Promise.reject(bodyData) // 跳转到catch函数
|
||||||
|
}
|
||||||
|
if (statusCode == 501) {
|
||||||
|
// storageManage.token(null, true)
|
||||||
|
// 提示信息
|
||||||
|
isShowErrorToast = true
|
||||||
|
// infoBox.showErrorToast('请登录').then(() => {
|
||||||
|
// go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH)
|
||||||
|
// })
|
||||||
|
return Promise.reject(bodyData) // 跳转到catch函数
|
||||||
|
}
|
||||||
|
// http响应码不正确
|
||||||
|
if (statusCode != 200 && statusCode != 204 && statusCode != 201) {
|
||||||
|
isShowErrorToast = true
|
||||||
|
bodyData.msg=bodyData.msg=='Bad credentials'?'用户名或密码错误':bodyData.msg
|
||||||
|
infoBox.showToast(bodyData.msg || '服务器异常')
|
||||||
|
return Promise.reject(bodyData) // 跳转到catch函数
|
||||||
|
}
|
||||||
|
|
||||||
|
// // 业务响应异常
|
||||||
|
if (bodyData.hasOwnProperty('code') && bodyData.code != 200) {
|
||||||
|
isShowErrorToast = true
|
||||||
|
infoBox.showToast(bodyData.msg)
|
||||||
|
// if (bodyData.code == 5005) { // 密码已过期, 直接跳转到更改密码页面
|
||||||
|
// uni.reLaunch({
|
||||||
|
// url: '/pageUser/setting/updatePwd'
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// if(bodyData.code == 500){ // 密码已过期, 直接跳转到更改密码页面
|
||||||
|
// uni.redirectTo({url: '/pages/login/index'})
|
||||||
|
// }
|
||||||
|
return Promise.reject(bodyData) // 跳转到catch函数
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造请求成功的响应数据
|
||||||
|
return Promise.resolve(bodyData.data)
|
||||||
|
|
||||||
|
}).catch(res => {
|
||||||
|
console.log(res)
|
||||||
|
if(res.code==501){
|
||||||
|
storageManage.token(null, true)
|
||||||
|
infoBox.showToast('登录过期,请重新登录').then(() => {
|
||||||
|
uni.redirectTo({url: '/pages/login/index'})
|
||||||
|
reject()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// if(res.status==400){
|
||||||
|
// storageManage.token(null, true)
|
||||||
|
// infoBox.showErrorToast('').then(() => {
|
||||||
|
// go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
if(res.code==500){
|
||||||
|
infoBox.showToast(res.msg||'服务器异常').then(() => {})
|
||||||
|
}
|
||||||
|
// if(res&&res.msg){
|
||||||
|
// infoBox.showErrorToast(res.msg)
|
||||||
|
// }
|
||||||
|
reqFinishFunc(); // 请求完毕的动作
|
||||||
|
|
||||||
|
// 如果没有提示错误, 那么此处提示 异常。
|
||||||
|
if (!isShowErrorToast) {
|
||||||
|
infoBox.showToast(`请求网络异常`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(res)
|
||||||
|
|
||||||
|
}).finally(() => { // finally 是 then结束后再执行, 此处不适用。 需要在请求完成后立马调用: reqFinishFunc()
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 默认 显示loading(控制 xxs 内 不提示loading )
|
||||||
|
function req(uri, data, method = "GET", showLoading = true, extParams = {}) {
|
||||||
|
// headerObject[appConfig.tokenKey] = storageManage.token()
|
||||||
|
return commonsProcess(showLoading, () => {
|
||||||
|
return uni.request(
|
||||||
|
Object.assign({
|
||||||
|
url: baseUrl + uri,
|
||||||
|
data: data,
|
||||||
|
method: method,
|
||||||
|
header: getHeader()
|
||||||
|
}, extParams)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 默认 显示loading(控制 xxs 内 不提示loading )
|
||||||
|
function request(args) {
|
||||||
|
const {
|
||||||
|
url,
|
||||||
|
data,
|
||||||
|
params,
|
||||||
|
method = "GET",
|
||||||
|
showLoading = true,
|
||||||
|
extParams = {}
|
||||||
|
} = args
|
||||||
|
let headerObject = {}
|
||||||
|
// headerObject[appConfig.tokenKey] = storageManage.token()
|
||||||
|
return commonsProcess(showLoading, () => {
|
||||||
|
return uni.request(
|
||||||
|
Object.assign({
|
||||||
|
url: baseUrl + url,
|
||||||
|
data: params||data,
|
||||||
|
method: method,
|
||||||
|
header: getHeader()
|
||||||
|
}, extParams)
|
||||||
|
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 上传
|
||||||
|
function upload(uri, data, file, showLoading = true, extParams = {}) {
|
||||||
|
// 放置token
|
||||||
|
let headerObject = {}
|
||||||
|
// headerObject[appConfig.tokenKey] = storageManage.token()
|
||||||
|
|
||||||
|
return commonsProcess(showLoading, () => {
|
||||||
|
return uni.uploadFile(
|
||||||
|
Object.assign({
|
||||||
|
url: baseUrl + uri,
|
||||||
|
formData: data,
|
||||||
|
name: "file",
|
||||||
|
filePath: file.path||file.url,
|
||||||
|
header: getHeader()
|
||||||
|
}, extParams)
|
||||||
|
).then((httpData) => {
|
||||||
|
// uni.upload 返回bodyData 的是 string类型。 需要解析。
|
||||||
|
httpData.data = JSON.parse(httpData.data)
|
||||||
|
return Promise.resolve(httpData)
|
||||||
|
}).catch(err=>{
|
||||||
|
uni.hideLoading()
|
||||||
|
infoBox.showErrorToast(`上传失败`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
req: req,
|
||||||
|
request,
|
||||||
|
upload: upload
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
import http from '@/http/yskApi/http.js'
|
||||||
|
const request = http.request
|
||||||
|
import {marketUrl} from './prveUrl.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限时折扣
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function limitTimeDiscount(params) {
|
||||||
|
return request({
|
||||||
|
url: marketUrl+`/admin/limitTimeDiscount`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync('shopInfo').id,
|
||||||
|
...params
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
import http from '@/http/yskApi/http.js'
|
||||||
|
|
||||||
|
const request = http.request
|
||||||
|
import {marketUrl} from '../prveUrl.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新客立减
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function getDiscountByUserId(params) {
|
||||||
|
return request({
|
||||||
|
url: marketUrl+`/admin/consumeDiscount/getDiscountByUserId`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync('shopInfo').id,
|
||||||
|
...params
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import http from '@/http/yskApi/http.js'
|
||||||
|
|
||||||
|
const request = http.request
|
||||||
|
import {marketUrl} from '../prveUrl.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 满减活动
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function discountActivity(params) {
|
||||||
|
console.log(uni.getStorageSync('shopInfo').id)
|
||||||
|
return request({
|
||||||
|
url: marketUrl+`/admin/discountActivity`,
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync('shopInfo').id,
|
||||||
|
...params
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
import http from '@/http/yskApi/http.js'
|
||||||
|
|
||||||
|
const request = http.request
|
||||||
|
import {orderUrl} from './prveUrl.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询订单
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function tbOrderInfoData(data) {
|
||||||
|
return request({
|
||||||
|
url: "/order/admin/order",
|
||||||
|
method: "get",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync('shopId'),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出数据
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function tbOrderInfoDownload(data) {
|
||||||
|
return request({
|
||||||
|
url: "/api/tbOrderInfo/download",
|
||||||
|
method: "post",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync('shopId'),
|
||||||
|
...data
|
||||||
|
},
|
||||||
|
responseType: "blob"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
export function createOrder(data, urlType = 'order') {
|
||||||
|
return request({
|
||||||
|
url: `/${urlType}/admin/order/createOrder`,
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 通过Id查询订单
|
||||||
|
* @param {*} id
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function tbOrderInfoDetail(id) {
|
||||||
|
return request({
|
||||||
|
url: orderUrl+ `/admin/order/historyOrder?orderId=${id}`,
|
||||||
|
method: "get"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过Id查询订单
|
||||||
|
* @param {*} createdAt
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function payCount(createdAt) {
|
||||||
|
console.log(createdAt);
|
||||||
|
return request({
|
||||||
|
url: `/api/tbOrderInfo/payCount`,
|
||||||
|
method: "post",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync('shopId'),
|
||||||
|
createdAt: createdAt
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单列表
|
||||||
|
* @param {*} createdAt
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function tbGroupOrderInfo(params) {
|
||||||
|
return request({
|
||||||
|
url: `/api/tbGroupOrderInfo`,
|
||||||
|
method: "post",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync('shopId'),
|
||||||
|
...params
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退单
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function returnGpOrder(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/tbGroupOrderInfo/returnGpOrder`,
|
||||||
|
method: "post",
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 店铺订单支付获取链接
|
||||||
|
*/
|
||||||
|
export function $getOrderPayUrl(data) {
|
||||||
|
return request({
|
||||||
|
url: `/api/shopPayApi/getOrderPayUrl`,
|
||||||
|
method: "get",
|
||||||
|
data: {
|
||||||
|
shopId: uni.getStorageSync('shopId'),
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
export const marketUrl = '/market'
|
||||||
|
export const accountUrl = '/account'
|
||||||
|
export const orderUrl = '/order'
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
// 用户管理
|
||||||
|
import http from './http.js'
|
||||||
|
import {accountUrl} from './prveUrl.js'
|
||||||
|
|
||||||
|
|
||||||
|
const request=http.request
|
||||||
|
|
||||||
|
// 获取店铺会员二维码
|
||||||
|
export function getwxacode(data) {
|
||||||
|
return request({
|
||||||
|
url: `/shop/storage/getwxacode`,
|
||||||
|
method: "post",
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 商家用户列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function queryAllShopUser(params) {
|
||||||
|
return request({
|
||||||
|
url: accountUrl+`/admin/shopUser`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync('shopId'),
|
||||||
|
...params
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 查询商家用户概述信息
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function queryAllShopInfo(params) {
|
||||||
|
return request({
|
||||||
|
url: `/api/tbShopUser/summary`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync('shopId'),
|
||||||
|
isVip:1,
|
||||||
|
...params
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取店铺用户详情
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function shopUserDetail(params) {
|
||||||
|
return request({
|
||||||
|
url: accountUrl+`/admin/shopUser/detail`,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
shopId: uni.getStorageSync('shopId'),
|
||||||
|
...params
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,852 @@
|
||||||
|
import { BigNumber } from "bignumber.js";
|
||||||
|
import _ from "lodash";
|
||||||
|
|
||||||
|
import {
|
||||||
|
ShopInfo,
|
||||||
|
couponCalcParams,
|
||||||
|
BaseCartItem,
|
||||||
|
TimeLimitDiscountConfig,
|
||||||
|
CanDikouGoodsArrArgs,
|
||||||
|
Coupon,
|
||||||
|
ShopUserInfo,
|
||||||
|
GoodsType,
|
||||||
|
BackendCoupon,
|
||||||
|
ExchangeCalculationResult,
|
||||||
|
PointDeductionRule,
|
||||||
|
OrderCostSummary,
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
|
import { getCompatibleFieldValue } from "./utils";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回商品单价
|
||||||
|
* @param goods 商品
|
||||||
|
* @param user 用户信息
|
||||||
|
* @param {Object} shopInfo
|
||||||
|
*/
|
||||||
|
export function returnGoodsPrice(
|
||||||
|
goods: BaseCartItem,
|
||||||
|
user: ShopUserInfo,
|
||||||
|
shopInfo: ShopInfo,
|
||||||
|
limitTimeDiscount: TimeLimitDiscountConfig | null | undefined
|
||||||
|
) {
|
||||||
|
if (!goods) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//是否可以使用会员价
|
||||||
|
const canUseVipPrice =
|
||||||
|
user &&
|
||||||
|
user.isVip &&
|
||||||
|
user.isMemberPrice &&
|
||||||
|
goods.memberPrice * 1 > 0 &&
|
||||||
|
shopInfo &&
|
||||||
|
shopInfo.isMemberPrice;
|
||||||
|
// 商家改价
|
||||||
|
if (goods.discount_sale_amount && goods.discount_sale_amount * 1 > 0) {
|
||||||
|
return goods.salePrice;
|
||||||
|
}
|
||||||
|
// 限时折扣
|
||||||
|
if (limitTimeDiscount && limitTimeDiscount.id) {
|
||||||
|
//优先使用
|
||||||
|
// 兼容 isTimeDiscount/is_time_discount(这里顺便处理该字段的命名兼容)
|
||||||
|
const isTimeDiscount = getCompatibleFieldValue(
|
||||||
|
goods,
|
||||||
|
"isTimeDiscount",
|
||||||
|
"is_time_discount"
|
||||||
|
);
|
||||||
|
if (isTimeDiscount) {
|
||||||
|
return new BigNumber(goods.salePrice)
|
||||||
|
.times(limitTimeDiscount.discountRate / 100)
|
||||||
|
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||||
|
.toNumber();
|
||||||
|
}
|
||||||
|
const canUseFoods = limitTimeDiscount.foods.split(",");
|
||||||
|
const canUseLimit =
|
||||||
|
limitTimeDiscount.foodType == 1 ||
|
||||||
|
canUseFoods.includes(`${goods.productId}`);
|
||||||
|
if (canUseLimit && limitTimeDiscount.discountPriority == "limit-time") {
|
||||||
|
return new BigNumber(goods.salePrice)
|
||||||
|
.times(limitTimeDiscount.discountRate / 100)
|
||||||
|
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||||
|
.toNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canUseLimit && limitTimeDiscount.discountPriority == "vip-price") {
|
||||||
|
if (canUseVipPrice) {
|
||||||
|
return goods.memberPrice;
|
||||||
|
} else {
|
||||||
|
return new BigNumber(goods.salePrice)
|
||||||
|
.times(limitTimeDiscount.discountRate / 100)
|
||||||
|
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||||
|
.toNumber();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (canUseVipPrice) {
|
||||||
|
return goods.memberPrice;
|
||||||
|
}
|
||||||
|
return goods.salePrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回商品分组
|
||||||
|
* @param arr 商品列表
|
||||||
|
*/
|
||||||
|
export function returnGoodsGroupMap(arr: BaseCartItem[]) {
|
||||||
|
let map: { [key: string]: BaseCartItem[] } = {};
|
||||||
|
arr.forEach((v) => {
|
||||||
|
const key = v.productId + "_" + v.skuId;
|
||||||
|
if (!map[key]) {
|
||||||
|
map[key] = [];
|
||||||
|
}
|
||||||
|
map[key].push(v);
|
||||||
|
});
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CouponTypes {
|
||||||
|
1: "满减券";
|
||||||
|
2: "商品券";
|
||||||
|
3: "折扣券";
|
||||||
|
4: "第二件半价券";
|
||||||
|
5: "消费送券";
|
||||||
|
6: "买一送一券";
|
||||||
|
7: "固定价格券";
|
||||||
|
8: "免配送费券";
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 优惠券类型:1-满减券,2-商品兑换券,3-折扣券,4-第二件半价券,5-消费送券,6-买一送一券,7-固定价格券,8-免配送费券
|
||||||
|
* @param coupon
|
||||||
|
*/
|
||||||
|
export function returnCoupType(coupon: Coupon) {
|
||||||
|
const couponTypes: CouponTypes = {
|
||||||
|
1: "满减券",
|
||||||
|
2: "商品券",
|
||||||
|
3: "折扣券",
|
||||||
|
4: "第二件半价券",
|
||||||
|
5: "消费送券",
|
||||||
|
6: "买一送一券",
|
||||||
|
7: "固定价格券",
|
||||||
|
8: "免配送费券",
|
||||||
|
};
|
||||||
|
return couponTypes[coupon.type as keyof CouponTypes] || "未知类型";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回商品券抵扣后的商品列表
|
||||||
|
* @param canDikouGoodsArr 可抵扣商品列表
|
||||||
|
* @param selCoupon 已选择的优惠券列表
|
||||||
|
* @param user 用户信息
|
||||||
|
*/
|
||||||
|
export function returnCanDikouGoodsArr(args: CanDikouGoodsArrArgs) {
|
||||||
|
const { canDikouGoodsArr, selCoupon, user, shopInfo, limitTimeDiscount } =
|
||||||
|
args;
|
||||||
|
const types = [2, 4, 6];
|
||||||
|
// 收集已抵扣商品并关联对应的优惠券类型
|
||||||
|
const goodsCouponGoods = selCoupon
|
||||||
|
.filter((v) => types.includes(v.type))
|
||||||
|
.reduce((prev: BaseCartItem[], cur) => {
|
||||||
|
// 给每个抵扣商品添加所属优惠券类型
|
||||||
|
if (cur && cur.discount) {
|
||||||
|
const goodsWithType = cur.discount.hasDiscountGoodsArr.map((goods) => ({
|
||||||
|
...goods,
|
||||||
|
couponType: cur.type, // 记录该商品是被哪种类型的优惠券抵扣的
|
||||||
|
}));
|
||||||
|
prev.push(...goodsWithType);
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
}, []);
|
||||||
|
const arr = _.cloneDeep(canDikouGoodsArr)
|
||||||
|
.map((v) => {
|
||||||
|
const findCart = goodsCouponGoods.find((carts) => carts.id == v.id);
|
||||||
|
if (findCart) {
|
||||||
|
// 根据优惠券类型判断扣减数量
|
||||||
|
if ([4, 6].includes(findCart.couponType ?? 0)) {
|
||||||
|
// 类型4(第二件半价)或6(买一送一),数量减2
|
||||||
|
if (v.num) {
|
||||||
|
v.num -= 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 其他类型(如类型2商品券),按原逻辑扣减对应数量
|
||||||
|
if (v.num) {
|
||||||
|
v.num -= findCart.num ?? 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
})
|
||||||
|
.filter((v) => {
|
||||||
|
const canUseNum = (v.num ?? 0) - (v.returnNum || 0);
|
||||||
|
// 兼容 is_temporary/isTemporary 和 is_gift/isGift
|
||||||
|
const isTemporary = getCompatibleFieldValue(
|
||||||
|
v,
|
||||||
|
"isTemporary",
|
||||||
|
"is_temporary"
|
||||||
|
);
|
||||||
|
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||||
|
|
||||||
|
if (canUseNum <= 0 || isTemporary || isGift) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}); // 过滤掉数量<=0的商品,赠菜,临时菜
|
||||||
|
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回商品是否享用了会员价/会员折扣
|
||||||
|
* @param {*} goods
|
||||||
|
*/
|
||||||
|
function returnGoodsIsUseVipPrice(
|
||||||
|
shopInfo: ShopInfo,
|
||||||
|
user: ShopUserInfo,
|
||||||
|
goods: BaseCartItem
|
||||||
|
) {
|
||||||
|
// 兼容 isTimeDiscount/is_time_discount
|
||||||
|
const isTimeDiscount = getCompatibleFieldValue(
|
||||||
|
goods,
|
||||||
|
"isTimeDiscount",
|
||||||
|
"is_time_discount"
|
||||||
|
);
|
||||||
|
if (isTimeDiscount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (shopInfo.isMemberPrice != 1 || user.isVip != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (shopInfo.isMemberPrice == 1 && user.isVip == 1) {
|
||||||
|
if (goods.memberPrice <= 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回可以计算抵扣金额的商品列表
|
||||||
|
*/
|
||||||
|
function returnCanCalcGoodsList(
|
||||||
|
canCalcGoodsArr: BaseCartItem[],
|
||||||
|
coupon: Coupon,
|
||||||
|
shopInfo: ShopInfo,
|
||||||
|
user: ShopUserInfo
|
||||||
|
) {
|
||||||
|
return canCalcGoodsArr.filter((goods) => {
|
||||||
|
// 兼容 isTimeDiscount/is_time_discount
|
||||||
|
const isTimeDiscount = getCompatibleFieldValue(
|
||||||
|
goods,
|
||||||
|
"isTimeDiscount",
|
||||||
|
"is_time_discount"
|
||||||
|
);
|
||||||
|
if (!coupon.discountShare && isTimeDiscount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!coupon.vipPriceShare &&
|
||||||
|
returnGoodsIsUseVipPrice(shopInfo, user, goods)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断优惠券是否可使用,并返回不可用原因
|
||||||
|
*
|
||||||
|
* @param {Object} args - 函数参数集合
|
||||||
|
* @param {Array} args.canDikouGoodsArr - 可参与抵扣的商品列表
|
||||||
|
* @param {Object} args.coupon - 优惠券信息对象
|
||||||
|
* @param {boolean} args.coupon.use - 优惠券是否启用
|
||||||
|
* @param {Array} args.coupon.useFoods - 优惠券适用的商品ID列表
|
||||||
|
* @param {number} args.coupon.fullAmount - 优惠券使用门槛金额
|
||||||
|
* @param {number} args.coupon.type - 优惠券类型
|
||||||
|
* @param {number} args.goodsOrderPrice - 订单中所有商品的总金额
|
||||||
|
* @param {Object} args.user - 用户信息对象
|
||||||
|
* @param {Object} args.selCoupon - 已经选择的优惠券信息对象
|
||||||
|
* @param {Object} args.shopInfo
|
||||||
|
* @param {boolean} args.limitTimeDiscount - 限时折扣
|
||||||
|
* @returns {Object} - { canUse: boolean, reason: string } 可用状态及不可用原因
|
||||||
|
*/
|
||||||
|
export function returnCouponCanUse(args: couponCalcParams) {
|
||||||
|
let {
|
||||||
|
canDikouGoodsArr,
|
||||||
|
coupon,
|
||||||
|
goodsOrderPrice,
|
||||||
|
user,
|
||||||
|
selCoupon,
|
||||||
|
shopInfo,
|
||||||
|
isMemberPrice,
|
||||||
|
limitTimeDiscount,
|
||||||
|
} = args;
|
||||||
|
// 优惠券未启用
|
||||||
|
if (!coupon.use) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: coupon.noUseRestrictions || "不在可用时间段内",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
limitTimeDiscount &&
|
||||||
|
limitTimeDiscount.id &&
|
||||||
|
limitTimeDiscount.foodType == 1 &&
|
||||||
|
!coupon.discountShare
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: coupon.noUseRestrictions || "不可与限时折扣同享",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算门槛金额
|
||||||
|
let fullAmount = goodsOrderPrice;
|
||||||
|
canDikouGoodsArr = returnCanDikouGoodsArr(args);
|
||||||
|
//优惠券指定门槛商品列表
|
||||||
|
let canCalcGoodsArr = [...canDikouGoodsArr];
|
||||||
|
//部分商品参与门槛计算
|
||||||
|
if (coupon.thresholdFoods.length) {
|
||||||
|
canCalcGoodsArr = canDikouGoodsArr.filter((v) => {
|
||||||
|
return coupon.thresholdFoods.find((food) => food.id == v.productId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
canCalcGoodsArr = returnCanCalcGoodsList(
|
||||||
|
canCalcGoodsArr,
|
||||||
|
coupon,
|
||||||
|
shopInfo,
|
||||||
|
user
|
||||||
|
);
|
||||||
|
|
||||||
|
fullAmount = canCalcGoodsArr.reduce((pre, cur) => {
|
||||||
|
return (
|
||||||
|
pre +
|
||||||
|
returnGoodsPrice(cur, user, shopInfo, limitTimeDiscount) * (cur.num || 0)
|
||||||
|
);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
// 是否全部商品可用
|
||||||
|
const isDikouAll = coupon.useFoods.length === 0;
|
||||||
|
// 订单可用商品列表
|
||||||
|
let canUseGoodsArr: BaseCartItem[] = [];
|
||||||
|
if (!isDikouAll) {
|
||||||
|
canUseGoodsArr = canDikouGoodsArr.filter((v) => {
|
||||||
|
return coupon.useFoods.find((food) => food.id == v.productId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// if (user.isVip && !coupon.vipPriceShare) {
|
||||||
|
// return {
|
||||||
|
// canUse: false,
|
||||||
|
// reason: "非会员可用",
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
if (selCoupon.length > 0 && !selCoupon[0].otherCouponShare) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: "当前选中的券不可与其他券同享",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (selCoupon.length > 0 && !coupon.otherCouponShare) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: "当前选中的券不可与其他券同享",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 满减券和折扣券计算门槛金额是否满足
|
||||||
|
if ([1, 3].includes(coupon.type)) {
|
||||||
|
if (canCalcGoodsArr.length <= 0) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: "没有可参与计算门槛的商品",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// 不满足门槛金额
|
||||||
|
if (fullAmount < (coupon.fullAmount || 0)) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: `满${coupon.fullAmount}元可用,当前可参与金额${fullAmount}元`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 商品兑换券,第二件半价和买一送一判断是否有可用商品
|
||||||
|
if ([2, 4, 5].includes(coupon.type)) {
|
||||||
|
// 没有符合条件的商品
|
||||||
|
if (isDikouAll && canDikouGoodsArr.length === 0) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: "没有符合条件的商品",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!isDikouAll && canUseGoodsArr.length === 0) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: "没有符合条件的商品",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (coupon.type == 2) {
|
||||||
|
if (canCalcGoodsArr.length <= 0) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: "没有符合计算门槛条件的商品",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (fullAmount < (coupon.fullAmount || 0)) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: `满${coupon.fullAmount}元可用,当前可参与金额${fullAmount}元`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//商品兑换券是否达到门槛金额
|
||||||
|
if (coupon.type == 2 && goodsOrderPrice < (coupon.fullAmount || 0)) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: `满${coupon.fullAmount}元可用,当前可参与金额${fullAmount}元`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 买一送一券特殊验证
|
||||||
|
if (coupon.type === 6) {
|
||||||
|
let canUse = false;
|
||||||
|
if (isDikouAll) {
|
||||||
|
canUse = canDikouGoodsArr.some((v) => (v.num || 0) >= 2);
|
||||||
|
} else if (canUseGoodsArr.length > 0) {
|
||||||
|
canUse = canUseGoodsArr.some((v) => (v.num || 0) >= 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canUse) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: "需要购买至少2件相同的商品才能使用",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第二件半价券特殊验证
|
||||||
|
if (coupon.type === 4) {
|
||||||
|
let canUse = false;
|
||||||
|
if (isDikouAll) {
|
||||||
|
canUse = canDikouGoodsArr.some((v) => (v.num || 0) >= 2);
|
||||||
|
} else if (canUseGoodsArr.length > 0) {
|
||||||
|
canUse = canUseGoodsArr.some((v) => (v.num || 0) >= 2);
|
||||||
|
}
|
||||||
|
if (!canUse) {
|
||||||
|
return {
|
||||||
|
canUse: false,
|
||||||
|
reason: "需要购买至少2件相同的商品才能使用",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 所有条件都满足
|
||||||
|
return {
|
||||||
|
canUse: true,
|
||||||
|
reason: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算抵扣商品金额
|
||||||
|
* @param discountGoodsArr 可抵扣商品列表
|
||||||
|
* @param discountNum 抵扣数量
|
||||||
|
* @param user 用户信息
|
||||||
|
* @param {Object} shopInfo 店铺信息
|
||||||
|
*/
|
||||||
|
export function calcDiscountGoodsArrPrice(
|
||||||
|
discountGoodsArr: BaseCartItem[],
|
||||||
|
discountNum: number,
|
||||||
|
user: ShopUserInfo,
|
||||||
|
shopInfo: ShopInfo,
|
||||||
|
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||||
|
) {
|
||||||
|
let hasCountNum = 0;
|
||||||
|
let discountPrice = 0;
|
||||||
|
let hasDiscountGoodsArr:BaseCartItem[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < discountGoodsArr.length; i++) {
|
||||||
|
if (hasCountNum >= discountNum) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const goods = discountGoodsArr[i];
|
||||||
|
const shengyuNum = discountNum - hasCountNum;
|
||||||
|
const num = Math.min(goods.num || 0, shengyuNum);
|
||||||
|
const realPrice = returnGoodsPrice(
|
||||||
|
goods,
|
||||||
|
user,
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
|
||||||
|
discountPrice += realPrice * num;
|
||||||
|
|
||||||
|
hasCountNum += num;
|
||||||
|
if(goods){
|
||||||
|
hasDiscountGoodsArr.push({
|
||||||
|
...goods,
|
||||||
|
num,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
discountPrice,
|
||||||
|
hasDiscountGoodsArr,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算优惠券抵扣金额
|
||||||
|
* @param arr 可抵扣商品列表
|
||||||
|
* @param coupon 优惠券
|
||||||
|
* @param user 用户信息
|
||||||
|
* @param goodsOrderPrice 商品订单金额
|
||||||
|
* @param selCoupon 已选择的优惠券列表
|
||||||
|
* @param shopInfo 店铺信息
|
||||||
|
* @param limitTimeDiscount 限时折扣
|
||||||
|
*/
|
||||||
|
export function returnCouponDiscount(
|
||||||
|
arr: BaseCartItem[],
|
||||||
|
coupon: Coupon,
|
||||||
|
user: ShopUserInfo,
|
||||||
|
goodsOrderPrice: number,
|
||||||
|
selCoupon: Coupon[],
|
||||||
|
shopInfo: ShopInfo,
|
||||||
|
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||||
|
) {
|
||||||
|
arr = returnCanDikouGoods(arr, user, shopInfo, limitTimeDiscount);
|
||||||
|
const canDikouGoodsArr = returnCanDikouGoodsArr({
|
||||||
|
canDikouGoodsArr: arr,
|
||||||
|
selCoupon,
|
||||||
|
user,
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount,
|
||||||
|
});
|
||||||
|
if (coupon.type == 2) {
|
||||||
|
return returnCouponProductDiscount(
|
||||||
|
canDikouGoodsArr,
|
||||||
|
coupon,
|
||||||
|
user,
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (coupon.type == 6) {
|
||||||
|
const result = returnCouponBuyOneGiveOneDiscount(
|
||||||
|
canDikouGoodsArr,
|
||||||
|
coupon,
|
||||||
|
user,
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (coupon.type == 4) {
|
||||||
|
return returnSecoendDiscount(
|
||||||
|
canDikouGoodsArr,
|
||||||
|
coupon,
|
||||||
|
user,
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (coupon.type == 3) {
|
||||||
|
return returnCouponZhekouDiscount(
|
||||||
|
canDikouGoodsArr,
|
||||||
|
coupon,
|
||||||
|
user,
|
||||||
|
goodsOrderPrice,
|
||||||
|
selCoupon,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 折扣券抵扣金额
|
||||||
|
* @param canDikouGoodsArr 可抵扣商品列表
|
||||||
|
* @param coupon 优惠券
|
||||||
|
* @param user 用户信息
|
||||||
|
* @param goodsOrderPrice 商品订单金额
|
||||||
|
* @param selCoupon 已选择的优惠券列表
|
||||||
|
* @param limitTimeDiscount 限时折扣
|
||||||
|
*/
|
||||||
|
export function returnCouponZhekouDiscount(
|
||||||
|
canDikouGoodsArr: BaseCartItem[],
|
||||||
|
coupon: Coupon,
|
||||||
|
user: ShopUserInfo,
|
||||||
|
goodsOrderPrice: number,
|
||||||
|
selCoupon: Coupon[],
|
||||||
|
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||||
|
) {
|
||||||
|
let { discountRate, maxDiscountAmount } = coupon;
|
||||||
|
maxDiscountAmount = maxDiscountAmount || 0;
|
||||||
|
// 计算商品优惠券折扣总和,使用BigNumber避免精度问题
|
||||||
|
const goodsCouponDiscount = selCoupon
|
||||||
|
.filter((v) => v.type == 2)
|
||||||
|
.reduce((prve, cur) => {
|
||||||
|
return new BigNumber(prve).plus(
|
||||||
|
new BigNumber(cur?.discount?.discountPrice || 0)
|
||||||
|
);
|
||||||
|
}, new BigNumber(0));
|
||||||
|
|
||||||
|
// 将商品订单价格转换为BigNumber并减去优惠券折扣
|
||||||
|
const adjustedGoodsOrderPrice = new BigNumber(goodsOrderPrice).minus(
|
||||||
|
goodsCouponDiscount
|
||||||
|
);
|
||||||
|
|
||||||
|
// 计算优惠比例:(100 - 折扣率) / 100
|
||||||
|
const discountAmountRatio = new BigNumber(100)
|
||||||
|
.minus(discountRate || 0)
|
||||||
|
.dividedBy(100);
|
||||||
|
|
||||||
|
// 计算折扣金额:调整后的商品订单金额 × 优惠比例
|
||||||
|
let discountPrice = adjustedGoodsOrderPrice
|
||||||
|
.times(discountAmountRatio)
|
||||||
|
.decimalPlaces(2, BigNumber.ROUND_FLOOR)
|
||||||
|
.toNumber();
|
||||||
|
|
||||||
|
// 应用最大折扣金额限制
|
||||||
|
if (maxDiscountAmount !== 0) {
|
||||||
|
discountPrice =
|
||||||
|
discountPrice >= maxDiscountAmount ? maxDiscountAmount : discountPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
discountPrice, // 折扣抵扣金额(即优惠的金额)
|
||||||
|
hasDiscountGoodsArr: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品券抵扣金额
|
||||||
|
* @param canDikouGoodsArr 可抵扣商品列表
|
||||||
|
* @param coupon 优惠券
|
||||||
|
* @param user 用户信息
|
||||||
|
* @param shopInfo 店铺信息
|
||||||
|
*/
|
||||||
|
export function returnCouponProductDiscount(
|
||||||
|
canDikouGoodsArr: BaseCartItem[],
|
||||||
|
coupon: Coupon,
|
||||||
|
user: ShopUserInfo,
|
||||||
|
shopInfo: ShopInfo,
|
||||||
|
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||||
|
) {
|
||||||
|
let { useFoods, discountNum, useRule } = coupon;
|
||||||
|
discountNum = discountNum || 0;
|
||||||
|
//抵扣商品数组
|
||||||
|
let discountGoodsArr:BaseCartItem[] = [];
|
||||||
|
|
||||||
|
//抵扣全部商品
|
||||||
|
if (useFoods.length === 0) {
|
||||||
|
if (useRule == "price_asc") {
|
||||||
|
discountGoodsArr = canDikouGoodsArr.slice(discountNum * -1).reverse();
|
||||||
|
} else {
|
||||||
|
discountGoodsArr = canDikouGoodsArr.slice(0, discountNum);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//抵扣选中商品
|
||||||
|
const discountSelGoodsArr = canDikouGoodsArr.filter((v) =>
|
||||||
|
useFoods.find((food) => food.id == v.productId)
|
||||||
|
);
|
||||||
|
if (useRule == "price_asc") {
|
||||||
|
discountGoodsArr = discountSelGoodsArr.slice(discountNum * -1).reverse();
|
||||||
|
} else {
|
||||||
|
discountGoodsArr = discountSelGoodsArr.slice(0, discountNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = calcDiscountGoodsArrPrice(
|
||||||
|
discountGoodsArr,
|
||||||
|
discountNum,
|
||||||
|
user,
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回买一送一券抵扣详情
|
||||||
|
* @param canDikouGoodsArr 可抵扣商品列表
|
||||||
|
* @param coupon 优惠券
|
||||||
|
* @param user 用户信息
|
||||||
|
* @param shopInfo 店铺信息
|
||||||
|
*/
|
||||||
|
function returnCouponBuyOneGiveOneDiscount(
|
||||||
|
canDikouGoodsArr: BaseCartItem[],
|
||||||
|
coupon: Coupon,
|
||||||
|
user: ShopUserInfo,
|
||||||
|
shopInfo: ShopInfo,
|
||||||
|
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||||
|
) {
|
||||||
|
const { useFoods, useRule } = coupon;
|
||||||
|
//抵扣商品
|
||||||
|
let discountGoods:BaseCartItem | undefined = undefined;
|
||||||
|
//符合买一送一条件的商品(数量>=2 + 非临时/非赠品)
|
||||||
|
const canUseGoods = canDikouGoodsArr.filter((v) => {
|
||||||
|
const isTemporary = getCompatibleFieldValue(
|
||||||
|
v,
|
||||||
|
"isTemporary",
|
||||||
|
"is_temporary"
|
||||||
|
);
|
||||||
|
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||||
|
return (v.num || 0) >= 2 && !isTemporary && !isGift;
|
||||||
|
});
|
||||||
|
//抵扣全部商品
|
||||||
|
if (useFoods.length === 0) {
|
||||||
|
if (useRule == "price_asc") {
|
||||||
|
discountGoods = canUseGoods[canUseGoods.length - 1];
|
||||||
|
} else {
|
||||||
|
discountGoods = canUseGoods[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//符合抵扣条件的商品
|
||||||
|
const canUseGoods1 = canUseGoods.filter((v) =>
|
||||||
|
useFoods.find((food) => food.id == v.productId)
|
||||||
|
);
|
||||||
|
if (useRule == "price_asc") {
|
||||||
|
discountGoods = canUseGoods1[canUseGoods1.length - 1];
|
||||||
|
} else {
|
||||||
|
discountGoods = canUseGoods1[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let discountPrice = 0;
|
||||||
|
let hasDiscountGoodsArr: BaseCartItem[] = [];
|
||||||
|
if (discountGoods) {
|
||||||
|
discountPrice = returnGoodsPrice(
|
||||||
|
discountGoods,
|
||||||
|
user,
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
hasDiscountGoodsArr = [discountGoods];
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
discountPrice: discountPrice <= 0 ? 0 : discountPrice,
|
||||||
|
hasDiscountGoodsArr,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回第二件半价券抵扣详情
|
||||||
|
* @param canDikouGoodsArr 可抵扣商品列表
|
||||||
|
* @param coupon 优惠券
|
||||||
|
* @param user 用户信息
|
||||||
|
* @param shopInfo 店铺信息
|
||||||
|
*/
|
||||||
|
function returnSecoendDiscount(
|
||||||
|
canDikouGoodsArr: BaseCartItem[],
|
||||||
|
coupon: Coupon,
|
||||||
|
user: ShopUserInfo,
|
||||||
|
shopInfo: ShopInfo,
|
||||||
|
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||||
|
) {
|
||||||
|
const { useFoods, useRule } = coupon;
|
||||||
|
//抵扣商品
|
||||||
|
let discountGoods:BaseCartItem | undefined = undefined;
|
||||||
|
//符合条件的商品(数量>=2 + 非临时/非赠品)
|
||||||
|
const canUseGoods = canDikouGoodsArr.filter((v) => {
|
||||||
|
const isTemporary = getCompatibleFieldValue(
|
||||||
|
v,
|
||||||
|
"isTemporary",
|
||||||
|
"is_temporary"
|
||||||
|
);
|
||||||
|
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||||
|
return (v.num || 0) >= 2 && !isTemporary && !isGift;
|
||||||
|
});
|
||||||
|
//抵扣全部商品
|
||||||
|
if (useFoods.length === 0) {
|
||||||
|
if (useRule == "price_asc") {
|
||||||
|
discountGoods = canUseGoods[canUseGoods.length - 1];
|
||||||
|
} else {
|
||||||
|
discountGoods = canUseGoods[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//符合抵扣条件的商品
|
||||||
|
const canUseGoods1 = canUseGoods.filter((v) =>
|
||||||
|
useFoods.find((food) => food.id == v.productId)
|
||||||
|
);
|
||||||
|
if (useRule == "price_asc") {
|
||||||
|
discountGoods = canUseGoods1[canUseGoods1.length - 1];
|
||||||
|
} else {
|
||||||
|
discountGoods = canUseGoods1[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let discountPrice = 0;
|
||||||
|
let hasDiscountGoodsArr: BaseCartItem[] = [];
|
||||||
|
if (discountGoods) {
|
||||||
|
discountPrice = returnGoodsPrice(
|
||||||
|
discountGoods,
|
||||||
|
user,
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
hasDiscountGoodsArr = [discountGoods];
|
||||||
|
}
|
||||||
|
//返回半价价格
|
||||||
|
return {
|
||||||
|
discountPrice:
|
||||||
|
discountPrice <= 0
|
||||||
|
? 0
|
||||||
|
: new BigNumber(discountPrice).dividedBy(2).toNumber(),
|
||||||
|
hasDiscountGoodsArr,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回可以抵扣优惠券的商品列表,过滤掉赠品、临时商品,价格从高到低排序
|
||||||
|
* @param arr 商品列表
|
||||||
|
* @param user 用户信息
|
||||||
|
* @param shopInfo 店铺信息
|
||||||
|
* @param limitTimeDiscount 限时折扣
|
||||||
|
*/
|
||||||
|
export function returnCanDikouGoods(
|
||||||
|
arr: BaseCartItem[],
|
||||||
|
user: ShopUserInfo,
|
||||||
|
shopInfo: ShopInfo,
|
||||||
|
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||||
|
) {
|
||||||
|
const result = arr
|
||||||
|
.filter((v) => {
|
||||||
|
// 兼容 is_temporary/isTemporary 和 is_gift/isGift
|
||||||
|
const isTemporary = getCompatibleFieldValue(
|
||||||
|
v,
|
||||||
|
"isTemporary",
|
||||||
|
"is_temporary"
|
||||||
|
);
|
||||||
|
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||||
|
return !isTemporary && !isGift;
|
||||||
|
})
|
||||||
|
.filter((v) => {
|
||||||
|
return (v.num || 0) > 0;
|
||||||
|
})
|
||||||
|
.sort((a, b) => {
|
||||||
|
return (
|
||||||
|
returnGoodsPrice(b, user, shopInfo, limitTimeDiscount) -
|
||||||
|
returnGoodsPrice(a, user, shopInfo, limitTimeDiscount)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const utils = {
|
||||||
|
returnGoodsPrice,
|
||||||
|
returnGoodsGroupMap,
|
||||||
|
returnCoupType,
|
||||||
|
returnCanDikouGoods,
|
||||||
|
returnCanDikouGoodsArr,
|
||||||
|
returnCouponCanUse,
|
||||||
|
calcDiscountGoodsArrPrice,
|
||||||
|
returnCouponDiscount,
|
||||||
|
returnCouponProductDiscount,
|
||||||
|
returnCouponZhekouDiscount,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default utils;
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,11 @@
|
||||||
|
export * from "./types";
|
||||||
|
import OrderPriceCalculator from "./goods";
|
||||||
|
import couponUtils from "./coupon";
|
||||||
|
import limitUtils from "./limit";
|
||||||
|
|
||||||
|
export { OrderPriceCalculator, couponUtils, limitUtils };
|
||||||
|
export default {
|
||||||
|
OrderPriceCalculator,
|
||||||
|
couponUtils,
|
||||||
|
limitUtils,
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,216 @@
|
||||||
|
import BigNumber from "bignumber.js";
|
||||||
|
|
||||||
|
import _ from "lodash";
|
||||||
|
|
||||||
|
import {
|
||||||
|
BaseCartItem,
|
||||||
|
ShopUserInfo,
|
||||||
|
ShopInfo,
|
||||||
|
TimeLimitDiscountConfig,
|
||||||
|
CanReturnMemberPriceArgs,
|
||||||
|
returnPriceArgs,
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断商品是否可以使用限时折扣
|
||||||
|
* @param goods 商品对象
|
||||||
|
* @param limitTimeDiscountRes 限时折扣配置
|
||||||
|
* @param shopInfo 店铺信息
|
||||||
|
* @param shopUserInfo 店铺用户信息
|
||||||
|
* @param idKey 商品ID键名,默认"id"
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function canUseLimitTimeDiscount(
|
||||||
|
goods: BaseCartItem,
|
||||||
|
limitTimeDiscountRes: TimeLimitDiscountConfig | null | undefined,
|
||||||
|
shopInfo: ShopInfo,
|
||||||
|
shopUserInfo: ShopUserInfo,
|
||||||
|
idKey = "id" as keyof BaseCartItem
|
||||||
|
) {
|
||||||
|
shopInfo = shopInfo || {};
|
||||||
|
shopUserInfo = shopUserInfo || {};
|
||||||
|
if(shopInfo.isMemberPrice){
|
||||||
|
shopUserInfo.isMemberPrice=1
|
||||||
|
}
|
||||||
|
if (!limitTimeDiscountRes || !limitTimeDiscountRes.id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const canUseFoods = (limitTimeDiscountRes.foods || "").split(",");
|
||||||
|
|
||||||
|
const goodsCanUse =
|
||||||
|
limitTimeDiscountRes.foodType == 1 ||
|
||||||
|
canUseFoods.includes(`${goods[idKey]}`);
|
||||||
|
if (!goodsCanUse) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (limitTimeDiscountRes.discountPriority == "limit-time") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (limitTimeDiscountRes.discountPriority == "vip-price") {
|
||||||
|
if (
|
||||||
|
shopUserInfo.isVip == 1 &&
|
||||||
|
shopUserInfo.isMemberPrice == 1 &&
|
||||||
|
goods.memberPrice * 1 > 0
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回商品显示价格
|
||||||
|
* @params {*} args 参数对象
|
||||||
|
* @params {*} args.goods 商品对象
|
||||||
|
* @params {*} args.shopInfo 店铺信息
|
||||||
|
* @params {*} args.limitTimeDiscountRes 限时折扣信息
|
||||||
|
* @params {*} args.shopUserInfo 店铺用户信息
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function returnPrice(args: returnPriceArgs) {
|
||||||
|
let {
|
||||||
|
goods,
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscountRes,
|
||||||
|
shopUserInfo,
|
||||||
|
idKey = "product_id",
|
||||||
|
} = args;
|
||||||
|
limitTimeDiscountRes = limitTimeDiscountRes || {
|
||||||
|
foods: "",
|
||||||
|
foodType: 2,
|
||||||
|
discountPriority: "",
|
||||||
|
discountRate: 0,
|
||||||
|
id: 0,
|
||||||
|
shopId: 0,
|
||||||
|
useType: "",
|
||||||
|
};
|
||||||
|
const canUseFoods = (limitTimeDiscountRes.foods || "").split(",");
|
||||||
|
const includesGoods =
|
||||||
|
limitTimeDiscountRes.foodType == 1 ||
|
||||||
|
canUseFoods.includes("" + goods[idKey]);
|
||||||
|
shopInfo = shopInfo || {};
|
||||||
|
shopUserInfo = shopUserInfo || {};
|
||||||
|
if (
|
||||||
|
shopUserInfo.isMemberPrice == 1 &&
|
||||||
|
shopUserInfo.isVip == 1 &&
|
||||||
|
shopInfo.isMemberPrice == 1
|
||||||
|
) {
|
||||||
|
const memberPrice = goods.memberPrice || goods.salePrice;
|
||||||
|
|
||||||
|
//是会员而且启用会员价
|
||||||
|
if (limitTimeDiscountRes) {
|
||||||
|
//使用限时折扣
|
||||||
|
//限时折扣优先
|
||||||
|
if (limitTimeDiscountRes.discountPriority == "limit-time") {
|
||||||
|
if (includesGoods) {
|
||||||
|
return returnLimitPrice({
|
||||||
|
price: goods.salePrice,
|
||||||
|
limitTimeDiscountRes,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return memberPrice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
limitTimeDiscountRes.discountPriority == "vip-price" &&
|
||||||
|
includesGoods
|
||||||
|
) {
|
||||||
|
if (goods.memberPrice * 1 > 0) {
|
||||||
|
//会员优先
|
||||||
|
return memberPrice;
|
||||||
|
} else {
|
||||||
|
const price = returnLimitPrice({
|
||||||
|
price: goods.salePrice,
|
||||||
|
limitTimeDiscountRes,
|
||||||
|
goods: goods,
|
||||||
|
});
|
||||||
|
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return memberPrice;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//是会员没有限时折扣
|
||||||
|
return memberPrice;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//不是会员或者没有启用会员价
|
||||||
|
if (limitTimeDiscountRes && limitTimeDiscountRes.id && includesGoods) {
|
||||||
|
const price = returnLimitPrice({
|
||||||
|
price: goods.salePrice,
|
||||||
|
limitTimeDiscountRes,
|
||||||
|
goods: goods,
|
||||||
|
});
|
||||||
|
|
||||||
|
return price;
|
||||||
|
} else {
|
||||||
|
return goods.salePrice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface returnLimitPriceArgs {
|
||||||
|
limitTimeDiscountRes: TimeLimitDiscountConfig | null | undefined;
|
||||||
|
price: number;
|
||||||
|
goods?: BaseCartItem;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 返回限时折扣价格
|
||||||
|
* @params {*} args 参数对象
|
||||||
|
* @params {*} args.limitTimeDiscountRes 限时折扣信息
|
||||||
|
* @params {*} args.price 商品价格
|
||||||
|
* @param {*} args.goods 商品对象
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function returnLimitPrice(args: returnLimitPriceArgs) {
|
||||||
|
const { limitTimeDiscountRes, price, goods } = args;
|
||||||
|
const discountRate = new BigNumber(
|
||||||
|
limitTimeDiscountRes ? limitTimeDiscountRes.discountRate : 100
|
||||||
|
).dividedBy(100);
|
||||||
|
|
||||||
|
const result = BigNumber(price)
|
||||||
|
.times(discountRate)
|
||||||
|
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||||
|
.toNumber();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否返回会员价
|
||||||
|
* @param {*} args 参数对象
|
||||||
|
* @param {*} args.shopInfo 店铺信息
|
||||||
|
* @param {*} args.shopUserInfo 店铺用户信息
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function canReturnMemberPrice(args: CanReturnMemberPriceArgs) {
|
||||||
|
const { shopInfo, shopUserInfo } = args;
|
||||||
|
if (shopUserInfo.isMemberPrice == 1 && shopUserInfo.isVip == 1) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回会员价格
|
||||||
|
* @param {*} goods
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function returnMemberPrice(goods: BaseCartItem) {
|
||||||
|
return goods.memberPrice || goods.salePrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const utils = {
|
||||||
|
returnPrice,
|
||||||
|
canUseLimitTimeDiscount,
|
||||||
|
returnLimitPrice,
|
||||||
|
canReturnMemberPrice,
|
||||||
|
returnMemberPrice,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default utils;
|
||||||
|
|
@ -0,0 +1,430 @@
|
||||||
|
/** 商品类型枚举 */
|
||||||
|
export enum GoodsType {
|
||||||
|
NORMAL = "normal", // 普通商品
|
||||||
|
WEIGHT = "weight", // 称重商品
|
||||||
|
GIFT = "gift", // 赠菜(继承普通商品逻辑,标记用)
|
||||||
|
EMPTY = "", // 空字符串类型(后端未返回时默认归类为普通商品)
|
||||||
|
PACKAGE = "package", // 打包商品(如套餐/预打包商品,按普通商品逻辑处理,可扩展特殊规则)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 优惠券计算结果类型(新增细分字段) */
|
||||||
|
export interface CouponResult {
|
||||||
|
deductionAmount: number; // 抵扣金额
|
||||||
|
excludedProductIds: string[]; // 不适用商品ID列表(注意:是商品ID,非购物车ID)
|
||||||
|
usedCoupon: Coupon | undefined; // 实际使用的优惠券
|
||||||
|
productCouponDeduction: number; // 新增:商品优惠券抵扣(兑换券等)
|
||||||
|
fullCouponDeduction: number; // 新增:满减优惠券抵扣
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 兑换券计算结果类型(新增细分字段) */
|
||||||
|
export interface ExchangeCalculationResult {
|
||||||
|
deductionAmount: number;
|
||||||
|
excludedProductIds: string[]; // 不适用商品ID列表(商品ID)
|
||||||
|
productCouponDeduction: number; // 新增:兑换券属于商品券,同步记录
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CouponTypes {
|
||||||
|
1: "满减券";
|
||||||
|
2: "商品券";
|
||||||
|
3: "折扣券";
|
||||||
|
4: "第二件半价券";
|
||||||
|
5: "消费送券";
|
||||||
|
6: "买一送一券";
|
||||||
|
7: "固定价格券";
|
||||||
|
8: "免配送费券";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 优惠券类型枚举 */
|
||||||
|
export enum CouponType {
|
||||||
|
FULL_REDUCTION = "full_reduction", // 满减券
|
||||||
|
DISCOUNT = "discount", // 折扣券
|
||||||
|
SECOND_HALF = "second_half", // 第二件半价券
|
||||||
|
BUY_ONE_GET_ONE = "buy_one_get_one", // 买一送一券
|
||||||
|
EXCHANGE = "exchange", // 商品兑换券
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 后端返回的优惠券原始字段类型 */
|
||||||
|
export interface BackendCoupon {
|
||||||
|
id?: number; // 自增主键(int64)
|
||||||
|
shopId?: number; // 店铺ID(int64)
|
||||||
|
syncId?: number; // 同步Id(int64)
|
||||||
|
type?: number; // 优惠券类型:1-满减券,2-商品兑换券,3-折扣券,4-第二件半价券,5-消费送券,6-买一送一券,7-固定价格券,8-免配送费券
|
||||||
|
name?: string; // 券名称
|
||||||
|
useShopType?: string; // 可用门店类型:only-仅本店;all-所有门店,custom-指定门店
|
||||||
|
useShops?: string; // 可用门店(逗号分隔字符串,如"1,2,3")
|
||||||
|
useType?: string; // 可使用类型:dine堂食/pickup自取/deliv配送/express快递
|
||||||
|
validType?: string; // 有效期类型:fixed(固定时间),custom(自定义时间)
|
||||||
|
validDays?: number; // 有效期(天)
|
||||||
|
validStartTime?: string; // 有效期开始时间(如"2024-01-01 00:00:00")
|
||||||
|
validEndTime?: string; // 有效期结束时间
|
||||||
|
daysToTakeEffect?: number; // 隔天生效
|
||||||
|
useDays?: string; // 可用周期(如"周一,周二")
|
||||||
|
useTimeType?: string; // 可用时间段类型:all-全时段,custom-指定时段
|
||||||
|
useStartTime?: string; // 可用开始时间(每日)
|
||||||
|
useEndTime?: string; // 可用结束时间(每日)
|
||||||
|
getType?: string; // 发放设置:不可自行领取/no,可领取/yes
|
||||||
|
getMode?: string; // 用户领取方式
|
||||||
|
giveNum?: number; // 总发放数量,-10086为不限量
|
||||||
|
getUserType?: string; // 可领取用户:全部/all,新用户一次/new,仅会员/vip
|
||||||
|
getLimit?: number; // 每人领取限量,-10086为不限量
|
||||||
|
useLimit?: number; // 每人每日使用限量,-10086为不限量
|
||||||
|
discountShare?: number; // 与限时折扣同享:0-否,1-是
|
||||||
|
vipPriceShare?: number; // 与会员价同享:0-否,1-是
|
||||||
|
ruleDetails?: string; // 附加规则说明
|
||||||
|
status?: number; // 状态:0-禁用,1-启用
|
||||||
|
useNum?: number; // 已使用数量
|
||||||
|
leftNum?: number; // 剩余数量
|
||||||
|
foods?: string; // 指定门槛商品(逗号分隔字符串,如"101,102",此处为商品ID)
|
||||||
|
fullAmount?: number; // 使用门槛:满多少金额(元)
|
||||||
|
discountAmount?: number; // 使用门槛:减多少金额(元)
|
||||||
|
discountRate?: number; // 折扣%(如90=9折)
|
||||||
|
maxDiscountAmount?: number; // 可抵扣最大金额(元)
|
||||||
|
useRule?: string; // 使用规则:price_asc-价格低到高,price_desc-高到低
|
||||||
|
discountNum?: number; // 抵扣数量
|
||||||
|
otherCouponShare?: number; // 与其它优惠共享:0-否,1-是
|
||||||
|
createTime?: string; // 创建时间
|
||||||
|
updateTime?: string; // 更新时间
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 营销活动类型枚举 */
|
||||||
|
export enum ActivityType {
|
||||||
|
TIME_LIMIT_DISCOUNT = "time_limit_discount", // 限时折扣
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 基础购物车商品项(核心修正:新增product_id,明确各ID含义) */
|
||||||
|
export interface BaseCartItem {
|
||||||
|
id: string | number; // 购物车ID(唯一标识购物车中的条目,如购物车项主键)
|
||||||
|
product_id: string | number; // 商品ID(唯一标识商品,用于优惠券/活动匹配,必选)
|
||||||
|
productId?: string | number; // 商品ID
|
||||||
|
salePrice: number; // 商品原价(元)
|
||||||
|
number: number; // 商品数量
|
||||||
|
num?: number; // 商品数量
|
||||||
|
isTimeDiscount?: boolean; // 是否限时折扣商品(默认false)
|
||||||
|
is_time_discount?: boolean; // 是否限时折扣商品(默认false)
|
||||||
|
product_type: GoodsType; // 商品类型
|
||||||
|
is_temporary?: boolean; // 是否临时菜(默认false)
|
||||||
|
isTemporary?: boolean; // 是否临时菜(默认false)
|
||||||
|
is_gift?: boolean; // 是否赠菜(默认false)
|
||||||
|
isGift?: boolean; // 是否赠菜(默认false)
|
||||||
|
returnNum?: number; // 退货数量(历史订单用,默认0)
|
||||||
|
memberPrice: number; // 商品会员价(元,优先级:商品会员价 > 会员折扣)
|
||||||
|
discountSaleAmount?: number; // 商家改价后单价(元,优先级最高)
|
||||||
|
discount_sale_amount?: number; // 商家改价后单价(元,优先级最高)
|
||||||
|
packFee?: number; // 单份打包费(元,默认0)
|
||||||
|
packNumber?: number; // 堂食打包数量(默认0)
|
||||||
|
activityInfo?: {
|
||||||
|
// 商品参与的营销活动(如限时折扣)
|
||||||
|
type: ActivityType;
|
||||||
|
discountRate: number; // 折扣率(如0.8=8折)
|
||||||
|
vipPriceShare: boolean; // 是否与会员优惠同享(默认false)
|
||||||
|
};
|
||||||
|
skuData?: {
|
||||||
|
// SKU扩展数据(可选)
|
||||||
|
id: string | number; // SKU ID(唯一标识商品规格,如颜色/尺寸)
|
||||||
|
memberPrice: number; // SKU会员价
|
||||||
|
salePrice?: number; // SKU原价
|
||||||
|
};
|
||||||
|
skuId?: string | number; // SKU ID(唯一标识商品规格,如颜色/尺寸)
|
||||||
|
couponType?: number; // 优惠券类型:1-满减券,2-商品兑换券,3-折扣券,4-第二件半价券,5-消费送券,6-买一送一券,7-固定价格券,8-免配送费券
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CouponFoods {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
images: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 基础优惠券接口(所有券类型继承,包含统一门槛商品字段) */
|
||||||
|
export interface BaseCoupon {
|
||||||
|
otherCouponShare?: number; // 与其它优惠共享:0-否,1-是
|
||||||
|
id: string | number; // 优惠券ID
|
||||||
|
type: number; // 工具库字符串枚举(由后端couponType转换)
|
||||||
|
name: string; // 对应后端title
|
||||||
|
available: boolean; // 基于BackendCoupon字段计算的可用性
|
||||||
|
useShopType?: string; // only-仅本店;all-所有门店,custom-指定门店
|
||||||
|
useShops: string[]; // 可用门店ID列表
|
||||||
|
discountShare: boolean; // 与限时折扣同享:0-否,1-是(后端字段转换为布尔值)
|
||||||
|
vipPriceShare: boolean; // 与会员价同享:0-否,1-是(后端字段转换为布尔值)
|
||||||
|
useType?: string[]; // 可使用类型:dine堂食/pickup自取/deliv配送/express快递
|
||||||
|
isValid: boolean; // 是否在有效期内
|
||||||
|
discountAmount?: number; // 减免金额 (满减券有)
|
||||||
|
fullAmount?: number; // 使用门槛:满多少金额
|
||||||
|
maxDiscountAmount?: number; // 可抵扣最大金额 元
|
||||||
|
use: boolean;
|
||||||
|
discountNum?: number; // 抵扣数量
|
||||||
|
useRule?: string; // 使用规则:price_asc-价格低到高,price_desc-高到低
|
||||||
|
discountRate?: number; // 折扣%(如90=9折)
|
||||||
|
noUseRestrictions?: boolean; // 是不可用原因
|
||||||
|
thresholdFoods: CouponFoods[]; // 门槛商品ID列表(空数组=全部商品,非空=指定商品ID)
|
||||||
|
useFoods: CouponFoods[]; // 可用商品ID列表(空数组=全部商品,非空=指定商品ID)
|
||||||
|
}
|
||||||
|
export interface couponDiscount {
|
||||||
|
discountPrice: number;
|
||||||
|
hasDiscountGoodsArr: BaseCartItem[];
|
||||||
|
}
|
||||||
|
/** 满减券(适配后端字段) */
|
||||||
|
export interface FullReductionCoupon extends BaseCoupon {
|
||||||
|
fullAmount: number; // 对应后端fullAmount(满减门槛)
|
||||||
|
discountAmount: number; // 对应后端discountAmount(减免金额)
|
||||||
|
maxDiscountAmount?: number; // 对应后端maxDiscountAmount(最大减免)
|
||||||
|
discount?: couponDiscount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 折扣券(适配后端字段) */
|
||||||
|
export interface DiscountCoupon extends BaseCoupon {
|
||||||
|
discountRate: number; // 后端discountRate(%)转小数(如90→0.9)
|
||||||
|
maxDiscountAmount: number; // 对应后端maxDiscountAmount(最大减免)
|
||||||
|
discount?: couponDiscount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 第二件半价券(适配后端字段) */
|
||||||
|
export interface SecondHalfPriceCoupon extends BaseCoupon {
|
||||||
|
maxUseCountPerOrder?: number; // 对应后端useLimit(-10086=不限)
|
||||||
|
discount?: couponDiscount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 买一送一券(适配后端字段) */
|
||||||
|
export interface BuyOneGetOneCoupon extends BaseCoupon {
|
||||||
|
maxUseCountPerOrder?: number; // 对应后端useLimit(-10086=不限)
|
||||||
|
discount?: couponDiscount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 商品兑换券(适配后端字段) */
|
||||||
|
export interface ExchangeCoupon extends BaseCoupon {
|
||||||
|
deductCount: number; // 对应后端discountNum(抵扣数量)
|
||||||
|
sortRule: "low_price_first" | "high_price_first"; // 后端useRule转换
|
||||||
|
discount?: couponDiscount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 所有优惠券类型联合 */
|
||||||
|
export type Coupon =
|
||||||
|
| FullReductionCoupon
|
||||||
|
| DiscountCoupon
|
||||||
|
| SecondHalfPriceCoupon
|
||||||
|
| BuyOneGetOneCoupon
|
||||||
|
| ExchangeCoupon;
|
||||||
|
|
||||||
|
/** 营销活动配置(如限时折扣,applicableProductIds为商品ID列表) */
|
||||||
|
export interface ActivityConfig {
|
||||||
|
type: ActivityType;
|
||||||
|
applicableProductIds?: string[]; // 适用商品ID列表(与BaseCartItem.product_id匹配)
|
||||||
|
discountRate: number; // 折扣率(如0.8=8折)
|
||||||
|
vipPriceShare: boolean; // 是否与会员优惠同享
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 积分抵扣规则 */
|
||||||
|
export interface PointDeductionRule {
|
||||||
|
pointsPerYuan: number; // X积分=1元(如100=100积分抵1元)
|
||||||
|
maxDeductionAmount?: number; // 最大抵扣金额(元,默认不限)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 餐位费配置 */
|
||||||
|
export interface SeatFeeConfig {
|
||||||
|
pricePerPerson: number; // 每人餐位费(元)
|
||||||
|
personCount: number; // 用餐人数(默认1)
|
||||||
|
isEnabled: boolean; // 是否启用餐位费(默认false)
|
||||||
|
}
|
||||||
|
/** 商家减免类型枚举 */
|
||||||
|
export enum MerchantReductionType {
|
||||||
|
FIXED_AMOUNT = "fixed_amount", // 固定金额减免(如直接减 10 元)
|
||||||
|
DISCOUNT_RATE = "discount_rate", // 比例折扣减免(如打 9 折,即减免 10%)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 商家减免配置(新增,替代原单一金额字段) */
|
||||||
|
export interface MerchantReductionConfig {
|
||||||
|
type: MerchantReductionType; // 减免类型(二选一)
|
||||||
|
fixedAmount?: number; // 固定减免金额(元,仅 FIXED_AMOUNT 生效,≥0)
|
||||||
|
discountRate?: number; // 折扣率(%,仅 DISCOUNT_RATE 生效,0-100,如 90 代表 9 折)
|
||||||
|
}
|
||||||
|
/**商家霸王餐配置 */
|
||||||
|
export interface FreeDineConfig {
|
||||||
|
enable: boolean; //是否开启
|
||||||
|
rechargeThreshold: number; //订单满多少元可以使用
|
||||||
|
rechargeTimes: number; //充值多少倍免单
|
||||||
|
withCoupon: boolean; //与优惠券同享
|
||||||
|
withPoints: boolean; //与积分同享
|
||||||
|
useType?: string[]; //使用类型 dine-in店内 takeout 自取 post快递,takeaway外卖
|
||||||
|
useShopType?: string; //all 全部 part部分
|
||||||
|
shopIdList?: number[]; //可用门店id
|
||||||
|
}
|
||||||
|
|
||||||
|
//限时折扣配置
|
||||||
|
export interface TimeLimitDiscountConfig {
|
||||||
|
/**
|
||||||
|
* 折扣优先级 limit-time/vip-price
|
||||||
|
*/
|
||||||
|
discountPriority: string;
|
||||||
|
/**
|
||||||
|
* 折扣% 范围1-99
|
||||||
|
*/
|
||||||
|
discountRate: number;
|
||||||
|
/**
|
||||||
|
* 参与商品
|
||||||
|
*/
|
||||||
|
foods: string;
|
||||||
|
/**
|
||||||
|
* 参与商品 1全部 2部分
|
||||||
|
*/
|
||||||
|
foodType: number;
|
||||||
|
/**
|
||||||
|
* 自增主键
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
/**
|
||||||
|
* 店铺ID
|
||||||
|
*/
|
||||||
|
shopId: number;
|
||||||
|
/**
|
||||||
|
* 可使用类型:堂食 dine-in 外带 take-out 外卖 take-away 配送 post
|
||||||
|
*/
|
||||||
|
useType: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
//用户信息
|
||||||
|
export interface ShopUserInfo {
|
||||||
|
isVip: number | null; //是否会员
|
||||||
|
discount: number | null; //用户折扣
|
||||||
|
isMemberPrice: number | null; //会员折扣与会员价是否同时使用
|
||||||
|
id?: number; //用户ID
|
||||||
|
}
|
||||||
|
/** 订单额外费用配置 */
|
||||||
|
export interface OrderExtraConfig {
|
||||||
|
// merchantReduction: number; // 商家减免金额(元,默认0)
|
||||||
|
// 替换原单一金额字段,支持两种减免形式
|
||||||
|
merchantReduction: MerchantReductionConfig;
|
||||||
|
additionalFee: number; // 附加费(元,如余额充值、券包,默认0)
|
||||||
|
pointDeductionRule: PointDeductionRule; // 积分抵扣规则
|
||||||
|
seatFeeConfig: SeatFeeConfig; // 餐位费配置
|
||||||
|
currentStoreId: string; // 当前门店ID(用于验证优惠券适用门店)
|
||||||
|
userPoints: number; // 用户当前积分(用于积分抵扣)
|
||||||
|
isMember: boolean; // 用户是否会员(用于会员优惠)
|
||||||
|
memberDiscountRate?: number; // 会员折扣率(如0.95=95折,无会员价时用)
|
||||||
|
newUserDiscount?: number; // 新用户减免金额(元,默认0)
|
||||||
|
fullReductionActivities: FullReductionActivity[]; // 当前店铺的满减活动列表(后端返回结构)
|
||||||
|
currentDinnerType: "dine-in" | "take-out" | "take-away" | "post"; // 当前就餐类型(匹配useType)
|
||||||
|
isFreeDine?: boolean; //是否霸王餐
|
||||||
|
freeDineConfig?: FreeDineConfig;
|
||||||
|
limitTimeDiscount?: TimeLimitDiscountConfig; //限时折扣
|
||||||
|
shopUserInfo: ShopUserInfo; // 用户信息
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 订单费用汇总(修改:补充商家减免类型和明细) */
|
||||||
|
export interface OrderCostSummary {
|
||||||
|
goodsList: BaseCartItem[];
|
||||||
|
// 商品总件数
|
||||||
|
goodsTotal: number;
|
||||||
|
totalDiscountAmount: number;
|
||||||
|
goodsRealAmount: number; // 商品真实原价总和
|
||||||
|
goodsOriginalAmount: number; // 商品原价总和
|
||||||
|
goodsDiscountAmount: number; // 商品折扣金额
|
||||||
|
couponDeductionAmount: number; // 优惠券总抵扣
|
||||||
|
productCouponDeduction: number; // 商品优惠券抵扣
|
||||||
|
fullCouponDeduction: number; // 满减优惠券抵扣
|
||||||
|
pointDeductionAmount: number; // 积分抵扣金额
|
||||||
|
seatFee: number; // 餐位费
|
||||||
|
packFee: number; // 打包费
|
||||||
|
scoreMaxMoney: number; // 积分最大可抵扣金额
|
||||||
|
// 新增:商家减免明细
|
||||||
|
merchantReduction: {
|
||||||
|
type: MerchantReductionType; // 实际使用的减免类型
|
||||||
|
originalConfig: MerchantReductionConfig; // 原始配置(便于前端展示)
|
||||||
|
actualAmount: number; // 实际减免金额(计算后的值,≥0)
|
||||||
|
};
|
||||||
|
additionalFee: number; // 附加费
|
||||||
|
finalPayAmount: number; // 最终实付金额
|
||||||
|
couponUsed?: Coupon; // 实际使用的优惠券
|
||||||
|
pointUsed: number; // 实际使用的积分
|
||||||
|
newUserDiscount: number; // 新用户减免金额(元,默认0)
|
||||||
|
dinnerType?: "dine-in" | "take-out"; // 就餐类型(堂食/自取/配送/快递)
|
||||||
|
config: OrderExtraConfig; // 订单额外费用配置
|
||||||
|
//满减活动
|
||||||
|
fullReduction: {
|
||||||
|
usedFullReductionActivityFullAmount: number; // 计算出的满减活动的门槛金额
|
||||||
|
usedActivity?: FullReductionActivity; // 实际使用的满减活动
|
||||||
|
usedThreshold?: FullReductionThreshold; // 实际使用的满减阈值(多门槛中选最优)
|
||||||
|
actualAmount: number; // 满减实际减免金额(元)
|
||||||
|
};
|
||||||
|
vipDiscountAmount: number; //会员折扣减免金额
|
||||||
|
// 订单原支付金额
|
||||||
|
orderOriginFinalPayAmount: number; //订单原金额(包含打包费+餐位费)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 满减活动阈值(单条满减规则:满X减Y)- 对应 MkDiscountThresholdInsertGroupDefaultGroup */
|
||||||
|
export interface FullReductionThreshold {
|
||||||
|
activityId?: number; // 关联满减活动ID
|
||||||
|
fullAmount?: number; // 满多少金额(元,必填)
|
||||||
|
discountAmount?: number; // 减多少金额(元,必填)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 满减活动主表 - 对应 Request 接口(后端真实字段) */
|
||||||
|
export interface FullReductionActivity {
|
||||||
|
id?: number; // 自增主键(后端字段:id)
|
||||||
|
shopId?: number; // 店铺ID(后端字段:shopId)
|
||||||
|
status?: number; // 活动状态:1=未开始,2=进行中,3=已结束(后端字段:status)
|
||||||
|
sort?: number; // 排序值(越大优先级越高,后端字段:sort)
|
||||||
|
createTime?: string; // 创建时间(后端字段:createTime,格式如"2025-10-14 13:56:07")
|
||||||
|
updateTime?: string; // 最新修改时间(后端字段:updateTime,用于优先级排序)
|
||||||
|
validStartTime?: string; // 有效期开始时间(后端字段:validStartTime,格式如"2025-10-14")
|
||||||
|
validEndTime?: string; // 有效期结束时间(后端字段:validEndTime,格式如"2025-12-14")
|
||||||
|
useType?: string; // 可使用类型(后端字段:useType,如"dine,pickup,deliv,express")
|
||||||
|
useDays?: string; // 可用周期(后端字段:useDays,如"周一,周二,周三,周四,周五,周六,周日")
|
||||||
|
useTimeType?: string; // 可用时间段类型(后端字段:useTimeType,all=全时段,custom=指定时段)
|
||||||
|
useStartTime?: string; // 每日可用开始时间(后端字段:useStartTime,如"09:00:00",仅custom时有效)
|
||||||
|
useEndTime?: string; // 每日可用结束时间(后端字段:useEndTime,如"22:00:00",仅custom时有效)
|
||||||
|
couponShare?: number; // 与优惠券同享:0=否,1=是(后端字段:couponShare)
|
||||||
|
discountShare?: number; // 与限时折扣同享:0=否,1=是(后端字段:discountShare)
|
||||||
|
vipPriceShare?: number; // 与会员价同享:0=否,1=是(后端字段:vipPriceShare)
|
||||||
|
pointsShare?: number; // 与积分抵扣同享:0=否,1=是(后端字段:pointsShare)
|
||||||
|
thresholds?: FullReductionThreshold[]; // 满减阈值列表(多门槛,后端字段:thresholds)
|
||||||
|
isDel?: boolean; // 是否删除:0=否,1=是(后端字段:isDel,默认false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 辅助枚举:星期映射(用于useDays校验)
|
||||||
|
export const WEEKDAY_MAP = {
|
||||||
|
周一: 1,
|
||||||
|
周二: 2,
|
||||||
|
周三: 3,
|
||||||
|
周四: 4,
|
||||||
|
周五: 5,
|
||||||
|
周六: 6,
|
||||||
|
周日: 0, // JS中getDay()返回0=周日
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface ShopInfo {
|
||||||
|
isMemberPrice: number; // 是否开启会员价 1是开启
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface couponCalcParams {
|
||||||
|
canDikouGoodsArr: BaseCartItem[];
|
||||||
|
coupon: Coupon;
|
||||||
|
user: ShopUserInfo;
|
||||||
|
shopInfo: ShopInfo;
|
||||||
|
selCoupon: Coupon[];
|
||||||
|
goodsOrderPrice: number; //商品订单总价
|
||||||
|
isMemberPrice: number; // 是否开启会员价 1是开启
|
||||||
|
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined;
|
||||||
|
}
|
||||||
|
export interface CanDikouGoodsArrArgs {
|
||||||
|
canDikouGoodsArr: BaseCartItem[];
|
||||||
|
selCoupon: Coupon[];
|
||||||
|
user: ShopUserInfo;
|
||||||
|
shopInfo: ShopInfo;
|
||||||
|
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined;
|
||||||
|
}
|
||||||
|
export interface returnPriceArgs {
|
||||||
|
goods: BaseCartItem;
|
||||||
|
selCoupon: Coupon[];
|
||||||
|
user: ShopUserInfo;
|
||||||
|
shopInfo: ShopInfo;
|
||||||
|
shopUserInfo: ShopUserInfo;
|
||||||
|
limitTimeDiscountRes?: TimeLimitDiscountConfig | null | undefined;
|
||||||
|
idKey?: keyof BaseCartItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface CanReturnMemberPriceArgs {
|
||||||
|
shopInfo?: ShopInfo;
|
||||||
|
shopUserInfo: ShopUserInfo;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
* 通用字段兼容工具函数:处理驼峰/下划线命名的字段取值
|
||||||
|
* @param obj 目标对象(如商品信息 BaseCartItem)
|
||||||
|
* @param camelCaseKey 驼峰命名字段(如 'isTemporary')
|
||||||
|
* @param snakeCaseKey 下划线命名字段(如 'is_temporary')
|
||||||
|
* @param defaultValue 默认值(默认 false,适配布尔类型字段)
|
||||||
|
* @returns 字段值(优先取存在的字段,无则返回默认值)
|
||||||
|
*/
|
||||||
|
export function getCompatibleFieldValue(
|
||||||
|
obj: Record<string, any>,
|
||||||
|
camelCaseKey: string,
|
||||||
|
snakeCaseKey: string,
|
||||||
|
defaultValue: boolean = false
|
||||||
|
): boolean {
|
||||||
|
// 优先判断驼峰字段(如果存在且不是 undefined/null)
|
||||||
|
if (
|
||||||
|
obj.hasOwnProperty(camelCaseKey) &&
|
||||||
|
obj[camelCaseKey] !== undefined &&
|
||||||
|
obj[camelCaseKey] !== null
|
||||||
|
) {
|
||||||
|
return Boolean(obj[camelCaseKey]);
|
||||||
|
}
|
||||||
|
// 再判断下划线字段
|
||||||
|
if (
|
||||||
|
obj.hasOwnProperty(snakeCaseKey) &&
|
||||||
|
obj[snakeCaseKey] !== undefined &&
|
||||||
|
obj[snakeCaseKey] !== null
|
||||||
|
) {
|
||||||
|
return Boolean(obj[snakeCaseKey]);
|
||||||
|
}
|
||||||
|
// 都不存在时返回默认值(布尔类型字段默认 false)
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
7
main.js
7
main.js
|
|
@ -7,6 +7,9 @@ import dict from '@/commons/utils/dict.js'
|
||||||
import {utils} from '@/commons/utils/index.js'
|
import {utils} from '@/commons/utils/index.js'
|
||||||
import uviewPlus from 'uview-plus'
|
import uviewPlus from 'uview-plus'
|
||||||
import * as Pinia from 'pinia';
|
import * as Pinia from 'pinia';
|
||||||
|
import {
|
||||||
|
createUnistorage
|
||||||
|
} from "pinia-plugin-unistorage";
|
||||||
// 设置node环境
|
// 设置node环境
|
||||||
envConfig.changeEnv(storageManage.env())
|
envConfig.changeEnv(storageManage.env())
|
||||||
|
|
||||||
|
|
@ -39,7 +42,9 @@ export function createApp() {
|
||||||
const app = createSSRApp(App)
|
const app = createSSRApp(App)
|
||||||
|
|
||||||
app.use(uviewPlus)
|
app.use(uviewPlus)
|
||||||
app.use(Pinia.createPinia());
|
const store = Pinia.createPinia();
|
||||||
|
store.use(createUnistorage());
|
||||||
|
app.use(store)
|
||||||
app.config.globalProperties.$appName = appConfig.appName
|
app.config.globalProperties.$appName = appConfig.appName
|
||||||
uni.$appName = appConfig.appName
|
uni.$appName = appConfig.appName
|
||||||
app.config.globalProperties.$utils = utils
|
app.config.globalProperties.$utils = utils
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bignumber.js": "^9.3.1",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"gm-crypto": "^0.1.8",
|
"gm-crypto": "^0.1.8",
|
||||||
|
|
@ -8,8 +9,10 @@
|
||||||
"jsbn": "^1.1.0",
|
"jsbn": "^1.1.0",
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"pinia-plugin-unistorage": "^0.1.2",
|
||||||
"to-arraybuffer": "^1.0.1",
|
"to-arraybuffer": "^1.0.1",
|
||||||
"uview-plus": "^3.3.32"
|
"uview-plus": "^3.3.32",
|
||||||
|
"ysk-utils": "^1.0.78"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"copy-webpack-plugin": "^12.0.2",
|
"copy-webpack-plugin": "^12.0.2",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<view class="goods">
|
<view class="goods">
|
||||||
<view class="u-m-t-24 u-flex u-col-top u-relative">
|
<view class="u-m-t-24 u-flex u-col-top u-relative">
|
||||||
<view class="img">
|
<view class="img">
|
||||||
<up--image :width="63" :height="63" :radius="3" :src="data.coverImg"></up--image>
|
<up-image :width="63" :height="63" :radius="3" :src="data.coverImg"></up-image>
|
||||||
</view>
|
</view>
|
||||||
<view class="w-full info u-p-l-30">
|
<view class="w-full info u-p-l-30">
|
||||||
<view class="color-333 u-flex u-row-between">
|
<view class="color-333 u-flex u-row-between">
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,10 @@
|
||||||
<view class="u-flex u-row-between u-m-b-32">
|
<view class="u-flex u-row-between u-m-b-32">
|
||||||
<text class="font-bold color-333">活动日期</text>
|
<text class="font-bold color-333">活动日期</text>
|
||||||
</view>
|
</view>
|
||||||
<timeArea
|
<my-time-area
|
||||||
v-model:startDate="form.validStartTime"
|
v-model:startDate="form.validStartTime"
|
||||||
v-model:endDate="form.validEndTime"
|
v-model:endDate="form.validEndTime"
|
||||||
></timeArea>
|
></my-time-area>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-m-t-32">
|
<view class="u-m-t-32">
|
||||||
<up-line ></up-line>
|
<up-line ></up-line>
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
<view class="u-flex u-row-between">
|
<view class="u-flex u-row-between">
|
||||||
<text class="font-bold color-333 u-m-b-32">可用周期</text>
|
<text class="font-bold color-333 u-m-b-32">可用周期</text>
|
||||||
</view>
|
</view>
|
||||||
<weekSel v-model="form.useDays"></weekSel>
|
<my-week-sel v-model="form.useDays"></my-week-sel>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
@ -61,11 +61,11 @@
|
||||||
<view class="u-flex u-row-between">
|
<view class="u-flex u-row-between">
|
||||||
<text class="font-bold color-333 u-m-b-32">指定时间段</text>
|
<text class="font-bold color-333 u-m-b-32">指定时间段</text>
|
||||||
</view>
|
</view>
|
||||||
<hourSel
|
<my-hour-area
|
||||||
v-model:useTimeType="form.useTimeType"
|
v-model:useTimeType="form.useTimeType"
|
||||||
v-model:startValue="form.useStartTime"
|
v-model:startValue="form.useStartTime"
|
||||||
v-model:endValue="form.useEndTime"
|
v-model:endValue="form.useEndTime"
|
||||||
></hourSel>
|
></my-hour-area>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-m-t-32 container">
|
<view class="u-m-t-32 container">
|
||||||
<view class="u-flex u-row-between">
|
<view class="u-flex u-row-between">
|
||||||
|
|
@ -144,15 +144,11 @@
|
||||||
></up-switch>
|
></up-switch>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<bottomBtnGroup @save="save" @cancel="cancel"></bottomBtnGroup>
|
<my-bottom-btn-group @save="save" @cancel="cancel"></my-bottom-btn-group>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import timeArea from "./components/time-area.vue";
|
|
||||||
import weekSel from "./components/week-sel.vue";
|
|
||||||
import hourSel from "./components/hour-area.vue";
|
|
||||||
import bottomBtnGroup from "./components/bottom-btn-group.vue";
|
|
||||||
import { reactive } from "vue";
|
import { reactive } from "vue";
|
||||||
import * as discountActivityApi from "@/http/api/market/discountActivity.js";
|
import * as discountActivityApi from "@/http/api/market/discountActivity.js";
|
||||||
import {
|
import {
|
||||||
|
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
<template>
|
|
||||||
<view>
|
|
||||||
<view style="height: 180rpx"></view>
|
|
||||||
|
|
||||||
<view class="fixed-bottom u-flex gap-20">
|
|
||||||
<view class="u-flex-1">
|
|
||||||
<my-button type="primary" @click="save" shape="circle">
|
|
||||||
保存
|
|
||||||
</my-button>
|
|
||||||
</view>
|
|
||||||
<view class="u-flex-1">
|
|
||||||
<my-button bgColor="#fff" type="default" @click="cancel" shape="circle">
|
|
||||||
取消
|
|
||||||
</my-button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
const emit= defineEmits(["save", "cancel"]);
|
|
||||||
|
|
||||||
function save() {
|
|
||||||
emit("save");
|
|
||||||
}
|
|
||||||
function cancel() {
|
|
||||||
emit("cancel");
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
</label>
|
</label>
|
||||||
</view>
|
</view>
|
||||||
<view class="img">
|
<view class="img">
|
||||||
<up--image :width="63" :height="63" :radius="3" :src="data.coverImg"></up--image>
|
<up-image :width="63" :height="63" :radius="3" :src="data.coverImg"></up-image>
|
||||||
</view>
|
</view>
|
||||||
<view class="w-full info">
|
<view class="w-full info">
|
||||||
<view class="info-p-l color-333 u-flex u-row-between">
|
<view class="info-p-l color-333 u-flex u-row-between">
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<view class="row" v-for="(item, index) in menuList" :key="index">
|
<view class="row" v-for="(item, index) in computedMenus" :key="index">
|
||||||
<view class="header">
|
<view class="header">
|
||||||
<text class="t">{{ item.label }}</text>
|
<text class="t">{{ item.label }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="menu-wrap">
|
<view class="menu-wrap">
|
||||||
<view class="item" v-for="(val, i) in item.menus" :key="i" @click="go.to(val.pageUrl)">
|
<view
|
||||||
<image :src="`/static/applocation/${val.icon}.png`" mode="aspectFit" class="icon"></image>
|
class="item"
|
||||||
|
v-for="(val, i) in item.menus"
|
||||||
|
:key="i"
|
||||||
|
@click="go.to(val.pageUrl)"
|
||||||
|
>
|
||||||
|
<image :src="val.icon" mode="aspectFit" class="icon"></image>
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<view class="title">
|
<view class="title">
|
||||||
<text class="t">{{ val.title }}</text>
|
<text class="t">{{ val.title }}</text>
|
||||||
|
|
@ -22,78 +27,147 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from "vue";
|
||||||
import go from '@/commons/utils/go.js';
|
import go from "@/commons/utils/go.js";
|
||||||
import { useMenusStore } from '@/store/menus.js';
|
import { useMenusStore } from "@/store/menus.js";
|
||||||
const menusStore = useMenusStore();
|
const menusStore = useMenusStore();
|
||||||
|
|
||||||
const menuList = ref([
|
const menuList = ref([
|
||||||
{
|
{
|
||||||
label: '营销',
|
label: "营销",
|
||||||
menus: [
|
menus: [
|
||||||
{
|
{
|
||||||
icon: 'xszk',
|
title: "霸王餐",
|
||||||
pageUrl: 'PAGES_LIMIT_DISCOUNT',
|
icon: "",
|
||||||
title: '限时折扣',
|
intro: "设置充值消费的N倍,当前订单立即免单",
|
||||||
intro: '批量设置商品折扣'
|
pageUrl: "PAGES_BWC",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'czdhm',
|
title: "积分锁客",
|
||||||
pageUrl: 'LIMIT_DISCOUNT',
|
icon: "",
|
||||||
title: '充值兑换码',
|
pageUrl: "",
|
||||||
intro: '兑换码直充余额,可当作礼品赠送'
|
intro: "设置充值消费的N倍,当前订单立即免单",
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
title: '优惠券',
|
|
||||||
icon: '/static/indexImg/icon-order.svg',
|
|
||||||
pageUrl: 'PAGES_ORDER_INDEX'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '霸王餐',
|
title: "弹窗广告",
|
||||||
icon: '/static/indexImg/icon-order.svg',
|
icon: "",
|
||||||
pageUrl: 'PAGES_ORDER_INDEX'
|
pageUrl: "PAGES_ORDER_INDEX",
|
||||||
|
intro: "设置弹窗广告",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '邀请裂变',
|
title: "超级会员",
|
||||||
icon: '/static/indexImg/icon-order.svg',
|
icon: "",
|
||||||
pageUrl: 'PAGES_ORDER_INDEX'
|
pageUrl: "PAGES_ORDER_INDEX",
|
||||||
|
intro: "用户会员管理设置",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '积分锁客',
|
title: "新客立减",
|
||||||
icon: '/static/indexImg/icon-order.svg',
|
icon: "",
|
||||||
pageUrl: 'PAGES_ORDER_INDEX'
|
pageUrl: "PAGES_ORDER_INDEX",
|
||||||
|
intro: "首单下单减免金额",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '满减活动',
|
title: "智慧充值",
|
||||||
icon: '/static/indexImg/icon-order.svg',
|
icon: "",
|
||||||
pageUrl: 'PAGES_MARKET_DISCOUNT_ACTIVITY'
|
pageUrl: "PAGES_ORDER_INDEX",
|
||||||
|
intro: "允许客户充值并使用余额支付",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '私域引流',
|
title: "分销",
|
||||||
icon: '/static/indexImg/icon-order.svg',
|
icon: "",
|
||||||
pageUrl: 'PAGES_MARKET_DRAINAGE_CONFIG'
|
pageUrl: "PAGES_PAY",
|
||||||
|
intro: "用户成为业务员,可促进消费",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '消费返现',
|
title: "消费返现",
|
||||||
icon: '/static/indexImg/icon-order.svg',
|
icon: "",
|
||||||
pageUrl: 'PAGES_MARKET_CONSUME_CASHBACK'
|
pageUrl: "PAGES_MARKET_CONSUME_CASHBACK",
|
||||||
|
intro: "用户下单后返现一定的金额到余额,可促进复购",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '分销',
|
title: "私域引流",
|
||||||
icon: '/static/indexImg/icon-order.svg',
|
icon: "",
|
||||||
pageUrl: 'PAGES_PAY'
|
pageUrl: "PAGES_MARKET_DRAINAGE_CONFIG",
|
||||||
}
|
intro: "可设置用户下单成功后的群二维码",
|
||||||
]
|
},
|
||||||
}
|
{
|
||||||
|
title: "满减活动",
|
||||||
|
icon: "",
|
||||||
|
pageUrl: "PAGES_MARKET_DISCOUNT_ACTIVITY",
|
||||||
|
intro: "达到指定支付金额享受减价",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "生日有礼",
|
||||||
|
icon: "",
|
||||||
|
pageUrl: "",
|
||||||
|
intro: "用户生日管理设置",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "点餐智能推荐",
|
||||||
|
icon: "",
|
||||||
|
pageUrl: "",
|
||||||
|
intro: "进入点单页X秒未点自动推荐商品,此推荐设置启用即生效",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "超值券包",
|
||||||
|
icon: "",
|
||||||
|
pageUrl: "",
|
||||||
|
intro: "下单加购",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "套餐推广",
|
||||||
|
icon: "",
|
||||||
|
pageUrl: "",
|
||||||
|
intro: "下单通过用户邀请好友减免金额的方式裂变宣传套餐加购",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "充值兑换码",
|
||||||
|
icon: "",
|
||||||
|
pageUrl: "",
|
||||||
|
intro: "兑换码直充余额,可当作礼品赠送",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "券兑换码",
|
||||||
|
icon: "",
|
||||||
|
pageUrl: "",
|
||||||
|
intro: "可添加多券组合兑换",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "xszk",
|
||||||
|
pageUrl: "PAGES_LIMIT_DISCOUNT",
|
||||||
|
title: "限时折扣",
|
||||||
|
intro: "批量设置商品折扣",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "xszk",
|
||||||
|
pageUrl: "PAGES_LIMIT_DISCOUNT",
|
||||||
|
title: "商品拼团",
|
||||||
|
intro: "拼团",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
console.log(menusStore.adminPages);
|
console.log(menusStore.adminPages);
|
||||||
|
|
||||||
const computedMenus = computed(() => {
|
const computedMenus = computed(() => {
|
||||||
const arr = menusStore.adminPages.filter((v) => {
|
// const arr = menusStore.adminPages.filter((v) => {
|
||||||
return navList.find((navItem) => navItem.title == v.title);
|
// return navList.find((navItem) => navItem.title == v.title);
|
||||||
|
// });
|
||||||
|
return menuList.value.map((v) => {
|
||||||
|
v.menus = v.menus.filter((menu) => {
|
||||||
|
const hasPermission = menusStore.adminPages.find(
|
||||||
|
(navItem) => navItem.title == menu.title
|
||||||
|
);
|
||||||
|
console.log("hasPermission", hasPermission);
|
||||||
|
if (hasPermission) {
|
||||||
|
menu.icon = hasPermission.miniIcon;
|
||||||
|
console.log(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasPermission;
|
||||||
|
});
|
||||||
|
return v;
|
||||||
});
|
});
|
||||||
console.log(arr);
|
|
||||||
return arr;
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,6 @@
|
||||||
name: '',
|
name: '',
|
||||||
totalElements: 0,
|
totalElements: 0,
|
||||||
size: 10,
|
size: 10,
|
||||||
isVip: 1
|
|
||||||
})
|
})
|
||||||
const list = reactive([])
|
const list = reactive([])
|
||||||
let hasAjax = ref(false)
|
let hasAjax = ref(false)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,610 @@
|
||||||
|
<template>
|
||||||
|
<view
|
||||||
|
class="bg-fff border-r-24 u-m-t-32"
|
||||||
|
v-if="orderInfo && orderInfo.detailMap"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-m-b-20"
|
||||||
|
v-for="(goods, orderIndex) in orderInfo.detailMap"
|
||||||
|
:key="orderIndex"
|
||||||
|
>
|
||||||
|
<view class="u-p-t-24"> 第{{ orderIndex }}次下单 </view>
|
||||||
|
<view class="u-m-t-24 list">
|
||||||
|
<view class="item u-m-b-32" v-for="(item, index) in goods" :key="index">
|
||||||
|
<view class="u-flex u-col-top">
|
||||||
|
<view class="u-flex u-relative">
|
||||||
|
<view class="limit-discount" v-if="item.isTimeDiscount"
|
||||||
|
>限时折扣</view
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
v-if="item.isTemporary == 0"
|
||||||
|
class="img"
|
||||||
|
:src="item.coverImg || item.productImg"
|
||||||
|
mode=""
|
||||||
|
></image>
|
||||||
|
<view
|
||||||
|
v-else
|
||||||
|
style="
|
||||||
|
background-color: #3f9eff;
|
||||||
|
width: 152rpx;
|
||||||
|
height: 152rpx;
|
||||||
|
line-height: 152rpx;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
临时菜
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="u-p-l-32 u-flex-1">
|
||||||
|
<view class="u-flex u-row-between u-col-top">
|
||||||
|
<view class="">
|
||||||
|
<view class="u-flex">
|
||||||
|
<view class="tui" v-if="isTui(item)">
|
||||||
|
{{
|
||||||
|
item.status == "part_refund" ? "部分已退" : "全部已退"
|
||||||
|
}}
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
:class="{
|
||||||
|
'line-th':
|
||||||
|
item.status == 'return' ||
|
||||||
|
item.status == 'refund' ||
|
||||||
|
item.status == 'refunding',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ item.name || item.productName }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="u-flex u-m-t-8"
|
||||||
|
style="flex-direction: column; align-items: flex-start"
|
||||||
|
>
|
||||||
|
<view class="u-flex u-m-b-8">
|
||||||
|
<view class="u-m-r-20 u-flex" v-if="item.isGift">
|
||||||
|
<uni-tag
|
||||||
|
text="赠送"
|
||||||
|
custom-style="background-color: #FFF0DF; border-color: #FFF0DF; color: #FF9F2E;"
|
||||||
|
>
|
||||||
|
</uni-tag>
|
||||||
|
</view>
|
||||||
|
<view class="u-m-r-20 u-flex" v-if="item.userCouponId">
|
||||||
|
<uni-tag
|
||||||
|
:text="productCouponDikou(item)"
|
||||||
|
custom-style="background-color: #FFF0DF; border-color: #FFF0DF; color: #FF9F2E;"
|
||||||
|
>
|
||||||
|
</uni-tag>
|
||||||
|
</view>
|
||||||
|
<view class="u-m-r-20 u-flex" v-if="item.packNumber > 0">
|
||||||
|
<uni-tag
|
||||||
|
custom-style="background-color: #E6F0FF; border-color: #E6F0FF; color: #318AFE;"
|
||||||
|
size="small"
|
||||||
|
text="打包"
|
||||||
|
inverted
|
||||||
|
type="success"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="u-flex u-m-t-8">
|
||||||
|
<view
|
||||||
|
class="u-m-r-20 u-font-24 u-flex"
|
||||||
|
v-if="item.refundNum > 0"
|
||||||
|
>
|
||||||
|
<view class="color-666">退款金额:</view>
|
||||||
|
<view class="color-999 u-m-l-6">{{
|
||||||
|
item.refundNum * item.unitPrice
|
||||||
|
}}</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="u-m-r-20 u-font-24 u-flex"
|
||||||
|
v-if="item.returnNum"
|
||||||
|
>
|
||||||
|
<view class="color-666">退菜数量:</view>
|
||||||
|
<view class="color-999 u-m-l-6">{{
|
||||||
|
item.returnNum
|
||||||
|
}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="color-999 u-font-24 u-m-t-8">{{
|
||||||
|
item.skuName || ""
|
||||||
|
}}</view>
|
||||||
|
|
||||||
|
<view class="u-m-t-12 color-666 u-font-24" v-if="item.remark">
|
||||||
|
备注:{{ item.remark }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="u-text-right u-m-t-28">
|
||||||
|
<view class="u-relative">
|
||||||
|
<template v-if="item.isGift">
|
||||||
|
<text class="line-th color-999"
|
||||||
|
>¥{{ toFixed(item.price * item.num, item) }}</text
|
||||||
|
>
|
||||||
|
<view class="u-absolute" style="right: 0; bottom: 100%">
|
||||||
|
<text class="font-bold">¥0</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
item.discountSaleAmount &&
|
||||||
|
item.discountSaleAmount * 1 > 0
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<text class="line-th color-999"
|
||||||
|
>¥{{ toFixed(item.price * item.num, item) }}</text
|
||||||
|
>
|
||||||
|
<view class="u-absolute" style="right: 0; bottom: 100%">
|
||||||
|
<text class="font-bold"
|
||||||
|
>¥{{
|
||||||
|
toFixed(item.discountSaleAmount * item.num, item)
|
||||||
|
}}</text
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="item.isTimeDiscount">
|
||||||
|
<text class="line-th color-999"
|
||||||
|
>¥{{ toFixed(item.price * item.num, item) }}</text
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="u-absolute xianshi"
|
||||||
|
style="right: 0; bottom: 100%"
|
||||||
|
>
|
||||||
|
<text class="font-bold"
|
||||||
|
>¥{{ returnLimitTotalMoney(item) }}</text
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template
|
||||||
|
v-else-if="
|
||||||
|
isVip &&
|
||||||
|
item.price &&
|
||||||
|
item.price * 1 != item.memberPrice * 1
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<text class="line-th color-999"
|
||||||
|
>¥{{ toFixed(item.price * item.num, item) }}</text
|
||||||
|
>
|
||||||
|
<view class="u-absolute" style="right: 0; bottom: 100%">
|
||||||
|
<text class="font-bold"
|
||||||
|
>¥{{
|
||||||
|
toFixed(item.memberPrice * item.num, item)
|
||||||
|
}}</text
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<view class="font-bold">
|
||||||
|
<text>¥</text>
|
||||||
|
<text class="">{{
|
||||||
|
toFixed(item.price * item.num, item)
|
||||||
|
}}</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
<view class="u-m-t-22 color-999 u-font-24"
|
||||||
|
>X{{ item.num || item.num }}</view
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- <template v-if="canTuicai(orderInfo, item)"> -->
|
||||||
|
<template v-if="false">
|
||||||
|
<view
|
||||||
|
class="u-flex u-row-right gap-20 u-m-t-24"
|
||||||
|
v-if="item.returnNum * item.unitPrice < item.num * item.unitPrice"
|
||||||
|
>
|
||||||
|
<my-button
|
||||||
|
:width="128"
|
||||||
|
:height="48"
|
||||||
|
plain
|
||||||
|
shape="circle"
|
||||||
|
@tap="tuicai(item, index)"
|
||||||
|
><text class="no-wrap">退菜</text></my-button
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed, reactive,inject } from "vue";
|
||||||
|
import BigNumber from "bignumber.js";
|
||||||
|
import { hasPermission } from "@/commons/utils/hasPermission.js";
|
||||||
|
import {
|
||||||
|
isTui,
|
||||||
|
isTuiCai,
|
||||||
|
isGift,
|
||||||
|
canTuiKuan,
|
||||||
|
canTuicai,
|
||||||
|
mathFloorPrice,
|
||||||
|
} from "@/commons/utils/goodsUtil.js";
|
||||||
|
|
||||||
|
const emits = defineEmits(["tuicai", "tuikuan", "printOrder"]);
|
||||||
|
const yskUtils = inject("yskUtils");
|
||||||
|
const shopInfo = inject("shopInfo");
|
||||||
|
const pageData = inject("pageData");
|
||||||
|
const pop = reactive({
|
||||||
|
youhui: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
orderInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
seatFee: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
id: "",
|
||||||
|
isVip: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算菜品数量
|
||||||
|
*/
|
||||||
|
const goodsNumber = computed(() => {
|
||||||
|
let result = 0;
|
||||||
|
result = props.data.reduce((a, b) => {
|
||||||
|
const bTotal = b.info.length;
|
||||||
|
return a + bTotal;
|
||||||
|
}, 0);
|
||||||
|
return result.toFixed(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 桌位费
|
||||||
|
*/
|
||||||
|
const seatFeePrice = computed(() => {
|
||||||
|
const n =
|
||||||
|
props.orderInfo.seatNum > 0
|
||||||
|
? props.orderInfo.seatNum * uni.getStorageSync("shopInfo").tableFee
|
||||||
|
: 0;
|
||||||
|
return n.toFixed(2);
|
||||||
|
});
|
||||||
|
function toFixed(price, item) {
|
||||||
|
if (item) {
|
||||||
|
if (item.productType == "weight" || item.type == "weight") {
|
||||||
|
return (Math.floor(price * 100) / 100).toFixed(2);
|
||||||
|
} else {
|
||||||
|
return parseFloat(price).toFixed(2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return parseFloat(price).toFixed(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 判断是否是会员
|
||||||
|
*/
|
||||||
|
const isVip = computed(() => {
|
||||||
|
return (
|
||||||
|
uni.getStorageSync("shopInfo").isMemberPrice &&
|
||||||
|
props.user &&
|
||||||
|
props.user.id &&
|
||||||
|
props.user.isVip
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
function returnLimitTotalMoney(data) {
|
||||||
|
const price = yskUtils.limitUtils.returnPrice({
|
||||||
|
goods: data,
|
||||||
|
shopInfo: pageData.shopInfo,
|
||||||
|
limitTimeDiscountRes: pageData.limitTimeDiscount,
|
||||||
|
shopUserInfo: pageData.user,
|
||||||
|
idKey: "product_id",
|
||||||
|
});
|
||||||
|
return BigNumber(price).times(data.number).toNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
const vipDiscountPrice = computed(() => {
|
||||||
|
if (!isVip.value) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||||
|
const curTotal = cur.info
|
||||||
|
.filter(
|
||||||
|
(v) =>
|
||||||
|
v.discountSaleAmount <= 0 &&
|
||||||
|
v.isGift != 1 &&
|
||||||
|
v.status !== "return" &&
|
||||||
|
v.price != v.unitPrice &&
|
||||||
|
v.memberPrice != v.price
|
||||||
|
)
|
||||||
|
.reduce((a, b) => {
|
||||||
|
return a + b.num * (b.price - b.memberPrice);
|
||||||
|
}, 0);
|
||||||
|
return prve + curTotal;
|
||||||
|
}, 0);
|
||||||
|
return goodsPrice.toFixed(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单品打折优惠
|
||||||
|
*/
|
||||||
|
const discountSaleAmount = computed(() => {
|
||||||
|
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||||
|
const curTotal = cur.info
|
||||||
|
.filter(
|
||||||
|
(v) =>
|
||||||
|
v.discountSaleAmount > 0 && v.isGift != 1 && v.status !== "return"
|
||||||
|
)
|
||||||
|
.reduce((a, b) => {
|
||||||
|
return a + b.num * (b.price - b.discountSaleAmount);
|
||||||
|
}, 0);
|
||||||
|
return prve + curTotal;
|
||||||
|
}, 0);
|
||||||
|
return goodsPrice.toFixed(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打折优惠
|
||||||
|
*/
|
||||||
|
const discountAmount = computed(() => {
|
||||||
|
return props.orderInfo.discountAmount || 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总优惠金额
|
||||||
|
*/
|
||||||
|
const discountsPrice = computed(() => {
|
||||||
|
// 满减券优惠
|
||||||
|
let fullCouponDiscountAmount =
|
||||||
|
props.orderInfo.status == "done"
|
||||||
|
? props.orderInfo.fullCouponDiscountAmount
|
||||||
|
: 0;
|
||||||
|
// 商品券优惠
|
||||||
|
let productCouponDiscountAmount =
|
||||||
|
props.orderInfo.status == "done"
|
||||||
|
? props.orderInfo.productCouponDiscountAmount
|
||||||
|
: 0;
|
||||||
|
// 积分抵扣优惠
|
||||||
|
let pointsDiscountAmount =
|
||||||
|
props.orderInfo.status == "done" ? props.orderInfo.pointsDiscountAmount : 0;
|
||||||
|
return (
|
||||||
|
parseFloat(vipDiscountPrice.value) +
|
||||||
|
parseFloat(discountSaleAmount.value) +
|
||||||
|
discountAmount.value +
|
||||||
|
fullCouponDiscountAmount +
|
||||||
|
productCouponDiscountAmount +
|
||||||
|
pointsDiscountAmount
|
||||||
|
).toFixed(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 菜品金额
|
||||||
|
const productCoupPrice = computed(() => {
|
||||||
|
if (props.orderInfo.status == "done") {
|
||||||
|
return props.orderInfo.productCouponDiscountAmount;
|
||||||
|
}
|
||||||
|
const goodsPrice = props.data.reduce((a, b) => {
|
||||||
|
const curTotal = b.info
|
||||||
|
.filter((v) => !v.isGift)
|
||||||
|
.reduce((prve, cur) => {
|
||||||
|
let memberPrice = cur.memberPrice ? cur.memberPrice : cur.price;
|
||||||
|
let tPrice = isVip.value ? memberPrice : cur.price;
|
||||||
|
tPrice =
|
||||||
|
cur.memberPrice != cur.unitPrice && cur.price != cur.unitPrice
|
||||||
|
? cur.unitPrice
|
||||||
|
: tPrice;
|
||||||
|
let Total = Math.floor(tPrice * cur.num * 100) / 100;
|
||||||
|
|
||||||
|
return (
|
||||||
|
prve + Total - cur.returnNum * tPrice - cur.refundNum * cur.unitPrice
|
||||||
|
);
|
||||||
|
}, 0);
|
||||||
|
return a + curTotal;
|
||||||
|
}, 0);
|
||||||
|
// console.log("菜品金额==",goodsPrice)
|
||||||
|
return goodsPrice.toFixed(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
const allPpackFee = computed(() => {
|
||||||
|
//不是退菜只要有打包费的都计算,包括赠送
|
||||||
|
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||||
|
const curTotal = cur.info
|
||||||
|
.filter((v) => v.packNumber > 0)
|
||||||
|
.reduce((a, b) => {
|
||||||
|
return a + parseFloat(b.packAmount * b.packNumber).toFixed(2) * 1;
|
||||||
|
}, 0);
|
||||||
|
return prve + curTotal;
|
||||||
|
}, 0);
|
||||||
|
return goodsPrice.toFixed(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
const packFee = computed(() => {
|
||||||
|
//不是退菜只要有打包费的都计算,包括赠送
|
||||||
|
const goodsPrice = props.data.reduce((prve, cur) => {
|
||||||
|
const curTotal = cur.info
|
||||||
|
.filter((v) => v.status !== "return" && v.returnNum + v.refundNum < v.num)
|
||||||
|
.reduce((a, b) => {
|
||||||
|
return (
|
||||||
|
a +
|
||||||
|
parseFloat(
|
||||||
|
(
|
||||||
|
b.packAmount *
|
||||||
|
(b.num - (b.returnNum + b.refundNum) > b.packNumber
|
||||||
|
? b.packNumber
|
||||||
|
: b.num - (b.returnNum + b.refundNum))
|
||||||
|
).toFixed(2)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}, 0);
|
||||||
|
return prve + curTotal;
|
||||||
|
}, 0);
|
||||||
|
return goodsPrice.toFixed(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
const allPrice = computed(() => {
|
||||||
|
let seatAmount = props.orderInfo.seatAmount || 0;
|
||||||
|
const total = productCoupPrice.value * 1 + seatAmount * 1 + packFee.value * 1;
|
||||||
|
return (total <= 0 ? 0 : total).toFixed(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已优惠金额
|
||||||
|
*/
|
||||||
|
const youhuiAllPrice = computed(() => {
|
||||||
|
const n = vipDiscountPrice.value * 1;
|
||||||
|
return (n < 0 ? 0 : n).toFixed(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
function youhuiDetailShow() {
|
||||||
|
pop.youhui = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function productCouponDikou(item) {
|
||||||
|
return "商品券抵扣¥" + returnProductCoupPrice(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
function youhuiDetailHide() {
|
||||||
|
pop.youhui = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转桌/并桌
|
||||||
|
*/
|
||||||
|
function rotatingTables() {
|
||||||
|
let arr = [];
|
||||||
|
props.data.forEach((ele) => {
|
||||||
|
ele.info.forEach((res) => {
|
||||||
|
// 头像 coverImg
|
||||||
|
res.coverImg = res.productImg;
|
||||||
|
// 名字 name
|
||||||
|
res.name = res.productName;
|
||||||
|
// 金额 price
|
||||||
|
res.price = res.price;
|
||||||
|
// 数量 number
|
||||||
|
res.number = res.num;
|
||||||
|
res.masterId = props.orderInfo.masterId;
|
||||||
|
res.useType = props.orderInfo.useType;
|
||||||
|
res.tableId = props.orderInfo.tableId;
|
||||||
|
arr.push(res);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
uni.navigateTo({
|
||||||
|
url:
|
||||||
|
"/pagesCreateOrder/confirm-order/rotatingTables?item=" +
|
||||||
|
JSON.stringify(arr) +
|
||||||
|
"&tableId=" +
|
||||||
|
props.orderInfo.tableId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function returnProductCoupPrice(item) {
|
||||||
|
if (!item.isMember) {
|
||||||
|
return item.price * item.num;
|
||||||
|
}
|
||||||
|
const price = item.memberPrice ? item.memberPrice : item.price;
|
||||||
|
return price * item.num;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function returnCanTuiMoney(item) {
|
||||||
|
// if (props.orderInfo.status == 'unpaid') {
|
||||||
|
// return returnTotalMoney(item)
|
||||||
|
// } else {
|
||||||
|
if (
|
||||||
|
props.orderInfo.pointsDiscountAmount > 0 ||
|
||||||
|
props.orderInfo.fullCouponDiscountAmount > 0
|
||||||
|
) {
|
||||||
|
return item.canReturnAmount;
|
||||||
|
} else if (item.price != item.unitPrice) {
|
||||||
|
return item.price * item.num;
|
||||||
|
} else {
|
||||||
|
return (Math.floor(item.num * item.unitPrice * 100) / 100).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function tuicai(item, index) {
|
||||||
|
emits("tuicai", item, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.img {
|
||||||
|
width: 152rpx;
|
||||||
|
height: 152rpx;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-top {
|
||||||
|
border-color: #f6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-r-24 {
|
||||||
|
border-radius: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-bottom {
|
||||||
|
// border-color: rgb(240, 240, 240);
|
||||||
|
border-color: #f6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-th {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
padding: 4rpx 8rpx 2rpx 10rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
|
||||||
|
&.no-pay {
|
||||||
|
background-color: rgb(170, 170, 170);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.refund {
|
||||||
|
background-color: #fce7e7;
|
||||||
|
padding: 8rpx 20rpx 6rpx 22rpx;
|
||||||
|
color: #eb4f4f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tui {
|
||||||
|
background-color: rgb(239, 239, 239);
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-right: 6rpx;
|
||||||
|
color: #666;
|
||||||
|
padding: 0 4rpx;
|
||||||
|
font-size: 20rpx;
|
||||||
|
}
|
||||||
|
.limit-discount {
|
||||||
|
background-color: #cc5617;
|
||||||
|
padding: 2rpx 10rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #ffffff;
|
||||||
|
border-radius: 20rpx 0rpx 20rpx 0rpx;
|
||||||
|
z-index: 9;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -3,16 +3,31 @@
|
||||||
<view class="mask" @tap="hideGoods" v-if="switchGoods"></view>
|
<view class="mask" @tap="hideGoods" v-if="switchGoods"></view>
|
||||||
<view class="car border-top u-flex u-row-between u-col-bottom u-relative">
|
<view class="car border-top u-flex u-row-between u-col-bottom u-relative">
|
||||||
<view class="u-absolute goods bg-fff">
|
<view class="u-absolute goods bg-fff">
|
||||||
<view class="u-p-t-32 color-666 border-bottom bg-fff u-absolute total u-p-r-28 u-p-b-32 u-p-l-28 u-flex u-row-between">
|
<view
|
||||||
|
class="u-p-t-32 color-666 border-bottom bg-fff u-absolute total u-p-r-28 u-p-b-32 u-p-l-28 u-flex u-row-between"
|
||||||
|
>
|
||||||
<view>已添加{{ goodsNumber.toFixed(0) }}件商品</view>
|
<view>已添加{{ goodsNumber.toFixed(0) }}件商品</view>
|
||||||
<view class="color-666">
|
<view class="color-666">
|
||||||
<uni-icons color="#666" type="trash"></uni-icons>
|
<uni-icons color="#666" type="trash"></uni-icons>
|
||||||
<text class="u-m-l-10" @tap="setModalShow('clear', true, 'cart', '是否清空全部已添加的商品')">清空购物车</text>
|
<text
|
||||||
|
class="u-m-l-10"
|
||||||
|
@tap="
|
||||||
|
setModalShow('clear', true, 'cart', '是否清空全部已添加的商品')
|
||||||
|
"
|
||||||
|
>清空购物车</text
|
||||||
|
>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<scroll-view scroll-y="true" class="tranistion" :style="{ height: switchGoods ? '50vh' : 0 }">
|
<scroll-view
|
||||||
|
scroll-y="true"
|
||||||
|
class="tranistion"
|
||||||
|
:style="{ height: switchGoods ? '50vh' : 0 }"
|
||||||
|
>
|
||||||
<!-- 占位 -->
|
<!-- 占位 -->
|
||||||
<view class="u-p-t-32 color-666 border-bottom u-p-r-28 u-p-b-32 u-p-l-28 u-flex u-row-between" style="opacity: 0">
|
<view
|
||||||
|
class="u-p-t-32 color-666 border-bottom u-p-r-28 u-p-b-32 u-p-l-28 u-flex u-row-between"
|
||||||
|
style="opacity: 0"
|
||||||
|
>
|
||||||
<view>已添加{{ goodsNumber.toFixed(0) }}件商品</view>
|
<view>已添加{{ goodsNumber.toFixed(0) }}件商品</view>
|
||||||
<view class="color-666">
|
<view class="color-666">
|
||||||
<uni-icons color="#666" type="trash"></uni-icons>
|
<uni-icons color="#666" type="trash"></uni-icons>
|
||||||
|
|
@ -20,15 +35,32 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 占位 -->
|
<!-- 占位 -->
|
||||||
<view class="color-333 item border-top u-flex u-row-center u-row-between" v-for="(item, index) in data" :key="index">
|
<view
|
||||||
|
class="color-333 item border-top u-flex u-row-center u-row-between"
|
||||||
|
v-for="(item, index) in data"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
<view>
|
<view>
|
||||||
<view class="up-line-1">{{ item.name }}</view>
|
<view class="up-line-1">{{ item.name }}</view>
|
||||||
<view class="u-m-t-10 u-font-24 color-666 up-line-1">{{ item.specInfo || '' }}</view>
|
<view class="u-m-t-10 u-font-24 color-666 up-line-1">{{
|
||||||
|
item.specInfo || ""
|
||||||
|
}}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-flex" style="flex-shrink: 0">
|
<view class="u-flex" style="flex-shrink: 0">
|
||||||
<view class="font-bold red u-m-r-32">¥{{ formatPrice(item.lowPrice * item.number) }}</view>
|
<view class="font-bold red" v-if="item.is_time_discount"
|
||||||
|
>¥{{ returnLimitTotalPrice(item) }}
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="font-bold red u-m-r-32"
|
||||||
|
:class="[item.is_time_discount ? 'old-price' : '']"
|
||||||
|
>¥{{ formatPrice(item.lowPrice * item.number) }}</view
|
||||||
|
>
|
||||||
<view class="u-flex" @tap="updateNumber(false, index, item)">
|
<view class="u-flex" @tap="updateNumber(false, index, item)">
|
||||||
<image src="/pagesCreateOrder/static/images/icon-reduce-black.svg" class="icon" mode="" />
|
<image
|
||||||
|
src="/pagesCreateOrder/static/images/icon-reduce-black.svg"
|
||||||
|
class="icon"
|
||||||
|
mode=""
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-m-l-30 u-m-r-30 color-333">
|
<view class="u-m-l-30 u-m-r-30 color-333">
|
||||||
{{ item.number.toFixed(2) }}
|
{{ item.number.toFixed(2) }}
|
||||||
|
|
@ -37,7 +69,11 @@
|
||||||
<image
|
<image
|
||||||
src="/pagesCreateOrder/static/images/icon-add-black.svg"
|
src="/pagesCreateOrder/static/images/icon-add-black.svg"
|
||||||
class="icon"
|
class="icon"
|
||||||
:class="{ grayscale: item.type == 'package' && item.groupType == 1 }"
|
:class="[
|
||||||
|
item.type == 'package' && item.groupType == 1
|
||||||
|
? grayscale
|
||||||
|
: '',
|
||||||
|
]"
|
||||||
mode=""
|
mode=""
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -47,24 +83,55 @@
|
||||||
<my-empty text="暂未有添加商品"></my-empty>
|
<my-empty text="暂未有添加商品"></my-empty>
|
||||||
</view>
|
</view>
|
||||||
<!-- 历史订单 -->
|
<!-- 历史订单 -->
|
||||||
<view v-if="historyOrder.length > 0" class="u-p-t-32 u-p-b-32 u-p-r-28 u-p-l-28 u-m-t-40 bg-fff u-flex u-row-between">
|
<view
|
||||||
|
v-if="historyOrder.length > 0"
|
||||||
|
class="u-p-t-32 u-p-b-32 u-p-r-28 u-p-l-28 u-m-t-40 bg-fff u-flex u-row-between"
|
||||||
|
>
|
||||||
<view class="color-333" style="font-weight: bold">历史订单</view>
|
<view class="color-333" style="font-weight: bold">历史订单</view>
|
||||||
<view class="color-666">
|
<view class="color-666">
|
||||||
<uni-icons color="#666" type="trash"></uni-icons>
|
<uni-icons color="#666" type="trash"></uni-icons>
|
||||||
<text class="u-m-l-10" @tap="setModalShow('clear', true, 'allHistoryOrder', '清空历史订单')">清空历史订单</text>
|
<text
|
||||||
|
class="u-m-l-10"
|
||||||
|
@tap="
|
||||||
|
setModalShow('clear', true, 'allHistoryOrder', '清空历史订单')
|
||||||
|
"
|
||||||
|
>清空历史订单</text
|
||||||
|
>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-for="(item, index) in historyOrder" :key="index">
|
<view v-for="(item, index) in historyOrder" :key="index">
|
||||||
<view v-if="historyOrder.length > 0" class="u-p-t-32 border-top bg-fff u-p-r-28 u-p-b-32 u-p-l-28 u-flex u-row-between">
|
<view
|
||||||
<view class="color-333" style="font-size: 30rpx">第{{ item.placeNum }}次下单</view>
|
v-if="historyOrder.length > 0"
|
||||||
|
class="u-p-t-32 border-top bg-fff u-p-r-28 u-p-b-32 u-p-l-28 u-flex u-row-between"
|
||||||
|
>
|
||||||
|
<view class="color-333" style="font-size: 30rpx"
|
||||||
|
>第{{ item.placeNum }}次下单</view
|
||||||
|
>
|
||||||
<view class="color-666">
|
<view class="color-666">
|
||||||
<uni-icons color="#666" type="trash"></uni-icons>
|
<uni-icons color="#666" type="trash"></uni-icons>
|
||||||
<text class="u-m-l-10" @tap="setModalShow('clear', true, item.placeNum, '清空第' + item.placeNum + '次下单历史订单')">清空</text>
|
<text
|
||||||
|
class="u-m-l-10"
|
||||||
|
@tap="
|
||||||
|
setModalShow(
|
||||||
|
'clear',
|
||||||
|
true,
|
||||||
|
item.placeNum,
|
||||||
|
'清空第' + item.placeNum + '次下单历史订单'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>清空</text
|
||||||
|
>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="color-333 item border-top u-flex u-row-center u-row-between" v-for="(v, i) in item.info" :key="i">
|
<view
|
||||||
|
class="color-333 item border-top u-flex u-row-center u-row-between"
|
||||||
|
v-for="(v, i) in item.info"
|
||||||
|
:key="i"
|
||||||
|
>
|
||||||
<view style="display: flex; align-items: center">
|
<view style="display: flex; align-items: center">
|
||||||
<view class="up-line-1" style="margin-right: 10rpx">{{ v.productName }}</view>
|
<view class="up-line-1" style="margin-right: 10rpx">{{
|
||||||
|
v.productName
|
||||||
|
}}</view>
|
||||||
<uni-tag
|
<uni-tag
|
||||||
v-if="v.returnNum > 0"
|
v-if="v.returnNum > 0"
|
||||||
:text="'退菜X' + v.returnNum"
|
:text="'退菜X' + v.returnNum"
|
||||||
|
|
@ -72,15 +139,22 @@
|
||||||
></uni-tag>
|
></uni-tag>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-flex" style="flex-shrink: 0">
|
<view class="u-flex" style="flex-shrink: 0">
|
||||||
<view class="font-bold red u-m-r-32">¥{{ formatPrice(v.price * (v.num - v.returnNum)) }}</view>
|
<view class="font-bold red u-m-r-32"
|
||||||
<view class="u-m-l-30 u-m-r-30 color-333">X{{ v.num.toFixed(2) }}</view>
|
>¥{{ formatPrice(v.price * (v.num - v.returnNum)) }}</view
|
||||||
|
>
|
||||||
|
<view class="u-m-l-30 u-m-r-30 color-333"
|
||||||
|
>X{{ v.num.toFixed(2) }}</view
|
||||||
|
>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<view class="icon-car-box" @tap="toggleGoods">
|
<view class="icon-car-box" @tap="toggleGoods">
|
||||||
<image src="/pagesCreateOrder/static/images/icon-car.svg" class="icon-car" />
|
<image
|
||||||
|
src="/pagesCreateOrder/static/images/icon-car.svg"
|
||||||
|
class="icon-car"
|
||||||
|
/>
|
||||||
<view class="dot" v-if="goodsNumber > 0">{{ goodsNumber }}</view>
|
<view class="dot" v-if="goodsNumber > 0">{{ goodsNumber }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="price font-bold u-flex">
|
<view class="price font-bold u-flex">
|
||||||
|
|
@ -88,7 +162,9 @@
|
||||||
<view>{{ allPrice }}</view>
|
<view>{{ allPrice }}</view>
|
||||||
</view>
|
</view>
|
||||||
<my-button shape="circle" height="80" width="220" @tap="toConfimOrder">
|
<my-button shape="circle" height="80" width="220" @tap="toConfimOrder">
|
||||||
<text class="u-font-32 font-bold">{{ table.type == 'add' ? '确认加菜' : '去下单' }}</text>
|
<text class="u-font-32 font-bold">{{
|
||||||
|
table.type == "add" ? "确认加菜" : "去下单"
|
||||||
|
}}</text>
|
||||||
</my-button>
|
</my-button>
|
||||||
</view>
|
</view>
|
||||||
<up-modal
|
<up-modal
|
||||||
|
|
@ -106,59 +182,100 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, reactive, ref, watch } from 'vue';
|
import { computed, reactive, ref, watch, inject } from "vue";
|
||||||
import myButton from '@/components/my-components/my-button.vue';
|
import myButton from "@/components/my-components/my-button.vue";
|
||||||
import go from '@/commons/utils/go.js';
|
import go from "@/commons/utils/go.js";
|
||||||
import infoBox from '@/commons/utils/infoBox.js';
|
import BigNumber from "bignumber.js";
|
||||||
import { formatPrice } from '@/commons/utils/format.js';
|
|
||||||
import { $trturnPayAfter } from '../util.js'
|
|
||||||
|
|
||||||
|
import infoBox from "@/commons/utils/infoBox.js";
|
||||||
|
import { formatPrice } from "@/commons/utils/format.js";
|
||||||
|
import { $trturnPayAfter } from "../util.js";
|
||||||
|
const yskUtils = inject("yskUtils");
|
||||||
|
const shopInfo = uni.getStorageSync("shopInfo");
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => {
|
default: () => {
|
||||||
return [];
|
return [];
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
historyOrder: {
|
historyOrder: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => {
|
default: () => {
|
||||||
return [];
|
return [];
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
isCreateOrderToDetail: {
|
isCreateOrderToDetail: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
orderInfo: {
|
orderInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {
|
default: () => {
|
||||||
return {
|
return {
|
||||||
id: ''
|
id: "",
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
table: {
|
table: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {
|
default: () => {
|
||||||
return {
|
return {
|
||||||
tableId: ''
|
tableId: "",
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
limitTimeDiscount: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function returnLimitPrice(data) {
|
||||||
|
const price = yskUtils.limitUtils.returnPrice({
|
||||||
|
goods: data,
|
||||||
|
shopInfo: shopInfo,
|
||||||
|
limitTimeDiscountRes: props.limitTimeDiscount,
|
||||||
|
shopUserInfo: null,
|
||||||
|
idKey: "product_id",
|
||||||
|
});
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
function returnLimitTotalPrice(data) {
|
||||||
|
console.log('returnLimitTotalPrice',data)
|
||||||
|
const price = yskUtils.limitUtils.returnPrice({
|
||||||
|
goods: data,
|
||||||
|
shopInfo: shopInfo,
|
||||||
|
limitTimeDiscountRes: props.limitTimeDiscount,
|
||||||
|
shopUserInfo: null,
|
||||||
|
idKey: "product_id",
|
||||||
|
});
|
||||||
|
return BigNumber(price).times(data.number).toNumber();
|
||||||
|
}
|
||||||
let allHistoryOrder = ref([]);
|
let allHistoryOrder = ref([]);
|
||||||
const allPrice = computed(() => {
|
const allPrice = computed(() => {
|
||||||
let cartPrice = props.data.reduce((prve, cur) => {
|
let cartPrice = props.data.reduce((prve, cur) => {
|
||||||
let price = Math.floor(cur.lowPrice * cur.number * 100) / 100;
|
let price =
|
||||||
return prve + price;
|
(cur.is_time_discount ? returnLimitPrice(cur) : cur.lowPrice) *
|
||||||
|
cur.number;
|
||||||
|
return BigNumber(prve).plus(price);
|
||||||
}, 0);
|
}, 0);
|
||||||
let historyOrderPrice = allHistoryOrder.value.reduce((prve, cur) => {
|
let historyOrderPrice = allHistoryOrder.value.reduce((prve, cur) => {
|
||||||
let price = Math.floor(cur.price * (cur.num - cur.returnNum) * 100) / 100;
|
let price =
|
||||||
return prve + price;
|
(cur.isTimeDiscount
|
||||||
|
? returnLimitPrice({ ...cur, salePrice: cur.price })
|
||||||
|
: cur.price) *
|
||||||
|
(cur.num - cur.returnNum);
|
||||||
|
return BigNumber(prve).plus(price);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
return BigNumber(cartPrice)
|
||||||
return (cartPrice + historyOrderPrice).toFixed(2);
|
.plus(historyOrderPrice)
|
||||||
|
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||||
|
.toNumber();
|
||||||
});
|
});
|
||||||
|
|
||||||
const goodsNumber = computed(() => {
|
const goodsNumber = computed(() => {
|
||||||
|
|
@ -184,19 +301,19 @@ watch(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const modal = reactive({
|
const modal = reactive({
|
||||||
key: '',
|
key: "",
|
||||||
title: '',
|
title: "",
|
||||||
type: '',
|
type: "",
|
||||||
clear: false
|
clear: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
function confirmModelConfirm() {
|
function confirmModelConfirm() {
|
||||||
if (modal.key == 'clear') {
|
if (modal.key == "clear") {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setModalShow(key = 'show', show = true, type = '', title = '') {
|
function setModalShow(key = "show", show = true, type = "", title = "") {
|
||||||
// if (key == 'clear' && show && props.data.length <= 0) {
|
// if (key == 'clear' && show && props.data.length <= 0) {
|
||||||
// return infoBox.showToast('购物车是空的!')
|
// return infoBox.showToast('购物车是空的!')
|
||||||
// }
|
// }
|
||||||
|
|
@ -211,7 +328,7 @@ function setModalShow(key = 'show', show = true, type = '', title = '') {
|
||||||
console.log(modal);
|
console.log(modal);
|
||||||
}
|
}
|
||||||
|
|
||||||
const edmits = defineEmits(['clear', 'updateNumber']);
|
const edmits = defineEmits(["clear", "updateNumber"]);
|
||||||
|
|
||||||
// mask
|
// mask
|
||||||
let switchGoods = ref(false);
|
let switchGoods = ref(false);
|
||||||
|
|
@ -230,56 +347,56 @@ function toggleGoods() {
|
||||||
|
|
||||||
function toConfimOrder() {
|
function toConfimOrder() {
|
||||||
if (props.data.length <= 0 && allHistoryOrder.value.length <= 0) {
|
if (props.data.length <= 0 && allHistoryOrder.value.length <= 0) {
|
||||||
return infoBox.showToast('还没有选择商品');
|
return infoBox.showToast("还没有选择商品");
|
||||||
}
|
}
|
||||||
const { name, status, type } = props.table;
|
const { name, status, type } = props.table;
|
||||||
if (props.data.length <= 0 && allHistoryOrder.value.length > 0) {
|
if (props.data.length <= 0 && allHistoryOrder.value.length > 0) {
|
||||||
go.to('PAGES_ORDER_PAY', {
|
go.to("PAGES_ORDER_PAY", {
|
||||||
orderId: props.orderInfo.id
|
orderId: props.orderInfo.id,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.table.id == '' && props.table.tableCode == '') {
|
if (props.table.id == "" && props.table.tableCode == "") {
|
||||||
go.to('PAGES_CONFIRM_ORDER', {
|
go.to("PAGES_CONFIRM_ORDER", {
|
||||||
isCreateOrderToDetail: props.isCreateOrderToDetail ? 1 : 0
|
isCreateOrderToDetail: props.isCreateOrderToDetail ? 1 : 0,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let shopInfo = uni.getStorageSync('shopInfo');
|
let shopInfo = uni.getStorageSync("shopInfo");
|
||||||
console.log($trturnPayAfter(shopInfo));
|
console.log($trturnPayAfter(shopInfo));
|
||||||
|
|
||||||
go.to('PAGES_CONFIRM_ORDER', {
|
go.to("PAGES_CONFIRM_ORDER", {
|
||||||
type: type,
|
type: type,
|
||||||
tableId: props.table.id,
|
tableId: props.table.id,
|
||||||
tableCode: props.table.tableCode,
|
tableCode: props.table.tableCode,
|
||||||
name: name,
|
name: name,
|
||||||
status: status,
|
status: status,
|
||||||
isCreateOrderToDetail: props.isCreateOrderToDetail ? 1 : 0
|
isCreateOrderToDetail: props.isCreateOrderToDetail ? 1 : 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateNumber(isAdd, index, goods) {
|
function updateNumber(isAdd, index, goods) {
|
||||||
const step = isAdd ? 1 : -1;
|
const step = isAdd ? 1 : -1;
|
||||||
const newval = goods.number + step;
|
const newval = goods.number + step;
|
||||||
if (goods.type == 'package' && goods.groupType == 1 && isAdd) {
|
if (goods.type == "package" && goods.groupType == 1 && isAdd) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const par = {
|
const par = {
|
||||||
num: newval,
|
num: newval,
|
||||||
index: index,
|
index: index,
|
||||||
goods: goods
|
goods: goods,
|
||||||
};
|
};
|
||||||
edmits('updateNumber', par);
|
edmits("updateNumber", par);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clear() {
|
function clear() {
|
||||||
if (modal.type == 'cart') {
|
if (modal.type == "cart") {
|
||||||
hideGoods();
|
hideGoods();
|
||||||
}
|
}
|
||||||
setModalShow('clear', false);
|
setModalShow("clear", false);
|
||||||
edmits('clear', modal.type);
|
edmits("clear", modal.type);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -388,4 +505,8 @@ $car-top: -16rpx;
|
||||||
height: $car-size;
|
height: $car-size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.old-price {
|
||||||
|
color: #999;
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,23 @@
|
||||||
<template>
|
<template>
|
||||||
<my-model ref="model" borderRadius="12" :title="title">
|
<my-model ref="model" borderRadius="12" :title="title">
|
||||||
<template #desc>
|
<template #desc>
|
||||||
<scroll-view scroll-y="true" style="height: 50vh;" class="u-p-30 guigeModel">
|
<scroll-view
|
||||||
|
scroll-y="true"
|
||||||
|
style="height: 50vh"
|
||||||
|
class="u-p-30 guigeModel"
|
||||||
|
>
|
||||||
<view class="u-m-b-40" v-for="(item, index) in skus" :key="index">
|
<view class="u-m-b-40" v-for="(item, index) in skus" :key="index">
|
||||||
<view class="u-text-left">
|
<view class="u-text-left">
|
||||||
<view class="color-333 up-line-1">{{ item.name }}</view>
|
<view class="color-333 up-line-1">{{ item.name }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-flex u-m-t-20 u-flex-wrap">
|
<view class="u-flex u-m-t-20 u-flex-wrap">
|
||||||
<view class="item" @tap="chooseSkd(index,skd)"
|
<view
|
||||||
|
class="item"
|
||||||
|
@tap="chooseSkd(index, skd)"
|
||||||
:class="{ active: item.sel === skd.name, disabled: skd.disabled }"
|
:class="{ active: item.sel === skd.name, disabled: skd.disabled }"
|
||||||
v-for="(skd,skdIndex) in item.values" :key="skdIndex">
|
v-for="(skd, skdIndex) in item.values"
|
||||||
|
:key="skdIndex"
|
||||||
|
>
|
||||||
{{ skd.name }}
|
{{ skd.name }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -21,20 +29,32 @@
|
||||||
<view class="u-flex u-p-b-30 u-row-between">
|
<view class="u-flex u-p-b-30 u-row-between">
|
||||||
<view class="price">
|
<view class="price">
|
||||||
<template v-if="goods && goods.isGrounding">
|
<template v-if="goods && goods.isGrounding">
|
||||||
<text>¥</text>
|
<text v-if="is_time_discount"
|
||||||
<text>{{to2(goods.salePrice*number) }}</text>
|
>¥{{ returnLimitPrice() }}</text
|
||||||
|
>
|
||||||
|
<text :class="{ oldPrice: is_time_discount }"
|
||||||
|
>¥{{ goods.salePrice }}</text
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-flex">
|
<view class="u-flex">
|
||||||
<view class="u-flex" @tap="reduce">
|
<view class="u-flex" @tap="reduce">
|
||||||
<image src="/pagesCreateOrder/static/images/icon-reduce-black.svg" class="icon" mode="">
|
<image
|
||||||
|
src="/pagesCreateOrder/static/images/icon-reduce-black.svg"
|
||||||
|
class="icon"
|
||||||
|
mode=""
|
||||||
|
>
|
||||||
</image>
|
</image>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-m-l-30 u-m-r-30 color-333">
|
<view class="u-m-l-30 u-m-r-30 color-333">
|
||||||
{{ number }}
|
{{ number }}
|
||||||
</view>
|
</view>
|
||||||
<view class="u-flex" @tap="add">
|
<view class="u-flex" @tap="add">
|
||||||
<image src="/pagesCreateOrder/static/images/icon-add-black.svg" class="icon" mode="">
|
<image
|
||||||
|
src="/pagesCreateOrder/static/images/icon-add-black.svg"
|
||||||
|
class="icon"
|
||||||
|
mode=""
|
||||||
|
>
|
||||||
</image>
|
</image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -51,74 +71,87 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, reactive, ref, watch } from 'vue';
|
import { computed, reactive, ref, watch,inject } from "vue";
|
||||||
import util from '../util.js';
|
import util from "../util.js";
|
||||||
import infobox from '@/commons/utils/infoBox.js'
|
import infobox from "@/commons/utils/infoBox.js";
|
||||||
import myModel from '@/components/my-components/my-model.vue'
|
import myModel from "@/components/my-components/my-model.vue";
|
||||||
import myButton from '@/components/my-components/my-button.vue'
|
import myButton from "@/components/my-components/my-button.vue";
|
||||||
|
import BigNumber from "bignumber.js";
|
||||||
|
const yskUtils = inject("yskUtils");
|
||||||
|
const shopInfo = uni.getStorageSync("shopInfo");
|
||||||
|
const shopUserInfo = uni.getStorageSync("shopUserInfo");
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
goodsData: {
|
goodsData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {}
|
default: () => {},
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: "",
|
||||||
},
|
},
|
||||||
skuMap: {
|
skuMap: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {
|
default: () => {
|
||||||
return {}
|
return {};
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
skus: {
|
skus: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => {
|
default: () => {
|
||||||
return []
|
return [];
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
})
|
limitTimeDiscount: {
|
||||||
const emits = defineEmits(['confirm', 'updateSku'])
|
type: Object,
|
||||||
const model = ref(null)
|
default: () => {
|
||||||
let number = ref(1)
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["confirm", "updateSku"]);
|
||||||
|
const model = ref(null);
|
||||||
|
let number = ref(1);
|
||||||
function to2(number) {
|
function to2(number) {
|
||||||
return Number(number).toFixed(2)
|
return Number(number).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
const selSku = computed(() => {
|
const selSku = computed(() => {
|
||||||
return props.skus.reduce((prve, cur) => {
|
return props.skus
|
||||||
prve.push(cur.sel)
|
.reduce((prve, cur) => {
|
||||||
return prve
|
prve.push(cur.sel);
|
||||||
}, []).join()
|
return prve;
|
||||||
})
|
}, [])
|
||||||
|
.join();
|
||||||
|
});
|
||||||
|
|
||||||
const goods = computed(() => {
|
const goods = computed(() => {
|
||||||
return props.skuMap[selSku.value]
|
return props.skuMap[selSku.value];
|
||||||
})
|
});
|
||||||
watch(() => goods.value, (newval) => {
|
watch(
|
||||||
number.value = newval.suitNum || 1
|
() => goods.value,
|
||||||
})
|
(newval) => {
|
||||||
|
number.value = newval.suitNum || 1;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const isCanBuy = computed(() => {
|
const isCanBuy = computed(() => {
|
||||||
if (!goods.value) {
|
if (!goods.value) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
return util.isCanBuy(
|
return util.isCanBuy(goods.value, props.goodsData);
|
||||||
goods.value,
|
});
|
||||||
props.goodsData
|
|
||||||
)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全部规格是否都无法使用
|
* 全部规格是否都无法使用
|
||||||
*/
|
*/
|
||||||
const isAllDisabled = computed(() => {
|
const isAllDisabled = computed(() => {
|
||||||
return props.skus.reduce((prve, cur) => {
|
return props.skus.reduce((prve, cur) => {
|
||||||
return prve && cur.values.filter(v => v.disabled).length === cur.values.length
|
return (
|
||||||
}, true)
|
prve && cur.values.filter((v) => v.disabled).length === cur.values.length
|
||||||
})
|
);
|
||||||
|
}, true);
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 规格选择
|
* 规格选择
|
||||||
|
|
@ -126,12 +159,12 @@
|
||||||
* @param {Object} skd
|
* @param {Object} skd
|
||||||
*/
|
*/
|
||||||
function chooseSkd(skusIndex, skd) {
|
function chooseSkd(skusIndex, skd) {
|
||||||
const { name, disabled } = skd
|
const { name, disabled } = skd;
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (props.skus[skusIndex].sel != name) {
|
if (props.skus[skusIndex].sel != name) {
|
||||||
emits('updateSku', skusIndex, name)
|
emits("updateSku", skusIndex, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -139,22 +172,22 @@
|
||||||
* 禁止操作
|
* 禁止操作
|
||||||
*/
|
*/
|
||||||
const isDisabled = computed(() => {
|
const isDisabled = computed(() => {
|
||||||
return isAllDisabled.value || !isCanBuy.value
|
return isAllDisabled.value || !isCanBuy.value;
|
||||||
})
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数量减少
|
* 数量减少
|
||||||
*/
|
*/
|
||||||
function reduce() {
|
function reduce() {
|
||||||
if (isDisabled.value) {
|
if (isDisabled.value) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
const suitNum = goods.value.suitNum || 1
|
const suitNum = goods.value.suitNum || 1;
|
||||||
const newval = number.value - 1
|
const newval = number.value - 1;
|
||||||
if (newval < suitNum) {
|
if (newval < suitNum) {
|
||||||
return infobox.showToast(suitNum + '个起售')
|
return infobox.showToast(suitNum + "个起售");
|
||||||
}
|
}
|
||||||
number.value = newval <= 1 ? 1 : newval
|
number.value = newval <= 1 ? 1 : newval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -162,38 +195,68 @@
|
||||||
*/
|
*/
|
||||||
function add() {
|
function add() {
|
||||||
if (isDisabled.value) {
|
if (isDisabled.value) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
number.value = number.value + 1
|
number.value = number.value + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 都规格选择确认
|
* 都规格选择确认
|
||||||
*/
|
*/
|
||||||
function confirm() {
|
function confirm() {
|
||||||
close()
|
close();
|
||||||
if (isDisabled.value) {
|
if (isDisabled.value) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
emits('confirm', goods.value, number.value)
|
emits("confirm", goods.value, number.value,is_time_discount.value?1:0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function open() {
|
function open() {
|
||||||
model.value.open()
|
model.value.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
model.value.close()
|
model.value.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const is_time_discount = computed(() => {
|
||||||
|
if (!props.limitTimeDiscount || !props.limitTimeDiscount.id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const isCanuse = yskUtils.limitUtils.canUseLimitTimeDiscount(
|
||||||
|
goods.value,
|
||||||
|
props.limitTimeDiscount,
|
||||||
|
shopInfo,
|
||||||
|
shopUserInfo,
|
||||||
|
"productId"
|
||||||
|
);
|
||||||
|
console.log('isCanuse');
|
||||||
|
console.log( goods.value);
|
||||||
|
return isCanuse;
|
||||||
|
|
||||||
|
});
|
||||||
|
function returnLimitPrice() {
|
||||||
|
const price = yskUtils.limitUtils.returnPrice({
|
||||||
|
goods: goods.value,
|
||||||
|
shopInfo: shopInfo,
|
||||||
|
limitTimeDiscountRes: props.limitTimeDiscount,
|
||||||
|
shopUserInfo: shopUserInfo,
|
||||||
|
idKey: "productId",
|
||||||
|
});
|
||||||
|
|
||||||
|
return BigNumber(price).times(number.value).toNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open,
|
open,
|
||||||
close
|
close,
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.border-top {}
|
.border-top {
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 40rpx;
|
width: 40rpx;
|
||||||
|
|
@ -205,11 +268,11 @@
|
||||||
color: #666;
|
color: #666;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
padding: 4rpx 28rpx;
|
padding: 4rpx 28rpx;
|
||||||
border: 1px solid #E5E5E5;
|
border: 1px solid #e5e5e5;
|
||||||
border-radius: 8rpx;
|
border-radius: 8rpx;
|
||||||
margin-right: 20rpx;
|
margin-right: 20rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
transition: all .2s ease-in-out;
|
transition: all 0.2s ease-in-out;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
border-color: $my-main-color;
|
border-color: $my-main-color;
|
||||||
|
|
@ -224,10 +287,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.price {
|
.price {
|
||||||
color: #EB4F4F;
|
color: #eb4f4f;
|
||||||
|
}
|
||||||
|
.oldPrice {
|
||||||
|
color: #999;
|
||||||
|
text-decoration: line-through;
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-top {
|
.border-top {
|
||||||
border-top: 1px solid #E5E5E5;
|
border-top: 1px solid #e5e5e5;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -1,55 +1,106 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="u-relative u-flex item">
|
<view class="u-relative u-flex item">
|
||||||
|
<up-image
|
||||||
<up-image :src="data.coverImg" mode="aspectFill" :width="img.width" :height="img.height"></up-image>
|
:src="data.coverImg"
|
||||||
|
mode="aspectFill"
|
||||||
|
:width="img.width"
|
||||||
|
:height="img.height"
|
||||||
|
></up-image>
|
||||||
<view class="info u-flex u-row-between u-col-top u-flex-col">
|
<view class="info u-flex u-row-between u-col-top u-flex-col">
|
||||||
|
<view class="limit-discount" v-if="is_time_discount">限时折扣</view>
|
||||||
|
|
||||||
<view>
|
<view>
|
||||||
<view>
|
<view>
|
||||||
<text class="up-line-1">{{ data.name }}</text>
|
<text class="up-line-1">{{ data.name }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-font-32 font-bold u-m-t-16">
|
<view>
|
||||||
|
<text class="u-font-32 font-bold u-m-t-16" v-if="is_time_discount"> ¥{{ limitPrice }} </text>
|
||||||
|
<text
|
||||||
|
class="u-font-32 font-bold u-m-t-16"
|
||||||
|
:class="[is_time_discount ? 'line-through' : '']"
|
||||||
|
>
|
||||||
¥{{ data.lowPrice }}
|
¥{{ data.lowPrice }}
|
||||||
|
</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<template v-if="data.type == 'weight'">
|
<template v-if="data.type == 'weight'">
|
||||||
<view class="btnweigh">称重</view>
|
<view class="btnweigh">称重</view>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-flex" v-if="!isSellout">
|
<view class="u-flex" v-if="!isSellout">
|
||||||
<template v-if="data.type == 'sku' || data.groupType == 1">
|
<template v-if="data.type == 'sku' || data.groupType == 1">
|
||||||
<button class="btn" hover-class="btn-hover-class" @tap="emitEvent('chooseGuige')">选规格</button>
|
<button
|
||||||
|
class="btn"
|
||||||
|
hover-class="btn-hover-class"
|
||||||
|
@tap="emitEvent('chooseGuige')"
|
||||||
|
>
|
||||||
|
选规格
|
||||||
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<view class="u-flex icon-btn">
|
<view class="u-flex icon-btn">
|
||||||
<view class="u-flex" @tap.stop="emitEvent(data.type=='weight'?'tapweigh':'add')">
|
<view
|
||||||
<image src="/pagesCreateOrder/static/images/icon-add.svg" class="icon" mode=""></image>
|
class="u-flex"
|
||||||
|
@tap.stop="emitEvent(data.type == 'weight' ? 'tapweigh' : 'add')"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
src="/pagesCreateOrder/static/images/icon-add.svg"
|
||||||
|
class="icon"
|
||||||
|
mode=""
|
||||||
|
></image>
|
||||||
</view>
|
</view>
|
||||||
<template v-if="data.chooseNumber">
|
<template v-if="data.chooseNumber">
|
||||||
<view class="u-font-32">
|
<view class="u-font-32">
|
||||||
{{(data.chooseNumber).toFixed(2)}}
|
{{ data.chooseNumber.toFixed(2) }}
|
||||||
</view>
|
</view>
|
||||||
<view class="u-flex" @tap.stop="emitEvent('reduce')">
|
<view class="u-flex" @tap.stop="emitEvent('reduce')">
|
||||||
<image src="/pagesCreateOrder/static/images/icon-reduce.svg" class="icon" mode="">
|
<image
|
||||||
|
src="/pagesCreateOrder/static/images/icon-reduce.svg"
|
||||||
|
class="icon"
|
||||||
|
mode=""
|
||||||
|
>
|
||||||
</image>
|
</image>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
<template v-if="isSellout">
|
<template v-if="isSellout">
|
||||||
<view class="isSellout" v-if="data.isSale == 0">
|
<view class="isSellout" v-if="data.isSale == 0">
|
||||||
<image class="isSellout_icon" src="/pagesCreateOrder/static/images/no-toDown.svg" mode=""></image>
|
<image
|
||||||
|
class="isSellout_icon"
|
||||||
|
src="/pagesCreateOrder/static/images/no-toDown.svg"
|
||||||
|
mode=""
|
||||||
|
></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="isSellout" v-else-if="!isProductAvailable(data.days,data.startTime,data.endTime)" >
|
<view
|
||||||
<image class="isSellout_icon" src="/pagesCreateOrder/static/images/no-saleTime.svg" mode=""></image>
|
class="isSellout"
|
||||||
|
v-else-if="
|
||||||
|
!isProductAvailable(data.days, data.startTime, data.endTime)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
class="isSellout_icon"
|
||||||
|
src="/pagesCreateOrder/static/images/no-saleTime.svg"
|
||||||
|
mode=""
|
||||||
|
></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="isSellout" v-else-if="data.isSoldStock == 1">
|
<view class="isSellout" v-else-if="data.isSoldStock == 1">
|
||||||
<image class="isSellout_icon" src="/pagesCreateOrder/static/images/no-sold.svg" mode=""></image>
|
<image
|
||||||
|
class="isSellout_icon"
|
||||||
|
src="/pagesCreateOrder/static/images/no-sold.svg"
|
||||||
|
mode=""
|
||||||
|
></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="isSellout" v-else-if="data.isStock == 1 && data.stockNumber <= 0" >
|
<view
|
||||||
<image class="isSellout_icon" src="/pagesCreateOrder/static/images/no-stock.svg" mode=""></image>
|
class="isSellout"
|
||||||
|
v-else-if="data.isStock == 1 && data.stockNumber <= 0"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
class="isSellout_icon"
|
||||||
|
src="/pagesCreateOrder/static/images/no-stock.svg"
|
||||||
|
mode=""
|
||||||
|
></image>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -57,19 +108,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, toRef } from 'vue';
|
import { computed, toRef, inject } from "vue";
|
||||||
import util from '../util.js';
|
import util from "../util.js";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import isBetween from "dayjs/plugin/isBetween.js";
|
import isBetween from "dayjs/plugin/isBetween.js";
|
||||||
dayjs.extend(isBetween)
|
const yskUtils = inject("yskUtils");
|
||||||
|
const shopInfo = inject("shopInfo");
|
||||||
|
dayjs.extend(isBetween);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
img: {
|
img: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {
|
default: {
|
||||||
width: '250rpx',
|
width: "250rpx",
|
||||||
height: '272rpx'
|
height: "272rpx",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
index: {
|
index: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
|
|
@ -77,76 +130,117 @@
|
||||||
isSeatFee: {
|
isSeatFee: {
|
||||||
//是否为餐位费
|
//是否为餐位费
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {
|
default: () => {
|
||||||
return {
|
return {
|
||||||
chooseNumber: 0
|
chooseNumber: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
limitTimeDiscount: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//判断是否是时间折扣商品
|
||||||
|
const is_time_discount = computed(() => {
|
||||||
|
if (!props.limitTimeDiscount || !props.limitTimeDiscount.id) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isCanuse = yskUtils.limitUtils.canUseLimitTimeDiscount(
|
||||||
|
props.data,
|
||||||
|
props.limitTimeDiscount,
|
||||||
|
shopInfo,
|
||||||
|
null,
|
||||||
|
"id"
|
||||||
|
);
|
||||||
|
return isCanuse;
|
||||||
|
});
|
||||||
|
|
||||||
|
const limitPrice = computed(() => {
|
||||||
|
if (!is_time_discount.value) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
console.log("props.data", props.data);
|
||||||
})
|
const price = yskUtils.limitUtils.returnPrice({
|
||||||
|
goods: props.data,
|
||||||
|
shopInfo: shopInfo,
|
||||||
|
limitTimeDiscountRes: props.limitTimeDiscount,
|
||||||
|
shopUserInfo: null,
|
||||||
|
idKey: "id",
|
||||||
|
});
|
||||||
|
return price;
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否是菜品
|
* 判断是否是菜品
|
||||||
*/
|
*/
|
||||||
function isGoods() {
|
function isGoods() {
|
||||||
return props.data.hasOwnProperty('id')
|
return props.data.hasOwnProperty("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断商品是否售尽
|
* 判断商品是否售尽
|
||||||
*/
|
*/
|
||||||
const isSellout = computed(() => {
|
const isSellout = computed(() => {
|
||||||
const item = props.data
|
const item = props.data;
|
||||||
if (!isGoods()) {
|
if (!isGoods()) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
(item.isStock == 1 && item.stockNumber <= 0) || item.isSoldStock == 1 || item.isSale == 0 || !isProductAvailable(item.days,item.startTime,item.endTime)
|
(item.isStock == 1 && item.stockNumber <= 0) ||
|
||||||
|
item.isSoldStock == 1 ||
|
||||||
|
item.isSale == 0 ||
|
||||||
|
!isProductAvailable(item.days, item.startTime, item.endTime)
|
||||||
);
|
);
|
||||||
})
|
});
|
||||||
// 判断商品是否在可售时间内
|
// 判断商品是否在可售时间内
|
||||||
function isProductAvailable(sellDaysStr, startTimeStr, endTimeStr) {
|
function isProductAvailable(sellDaysStr, startTimeStr, endTimeStr) {
|
||||||
// 将后端返回的字符串转换为数组
|
// 将后端返回的字符串转换为数组
|
||||||
const sellDays = sellDaysStr.split(',');
|
const sellDays = sellDaysStr.split(",");
|
||||||
const now = dayjs();
|
const now = dayjs();
|
||||||
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
const days = [
|
||||||
|
"Sunday",
|
||||||
|
"Monday",
|
||||||
|
"Tuesday",
|
||||||
|
"Wednesday",
|
||||||
|
"Thursday",
|
||||||
|
"Friday",
|
||||||
|
"Saturday",
|
||||||
|
];
|
||||||
const currentDay = days[now.day()];
|
const currentDay = days[now.day()];
|
||||||
const currentTime = now.format('HH:mm:ss');
|
const currentTime = now.format("HH:mm:ss"); // 检查当前周几是否在可售周几列表中
|
||||||
|
|
||||||
// console.log('当前日期:', currentDay);
|
// console.log('当前日期:', currentDay);
|
||||||
// console.log('可售日期列表:', sellDays);
|
// console.log('可售日期列表:', sellDays);
|
||||||
// 检查当前周几是否在可售周几列表中
|
if (!sellDays.includes(currentDay)) {
|
||||||
if (!sellDays.includes(currentDay)) {
|
// console.log('当前日期不在可售日期列表中');
|
||||||
// console.log('当前日期不在可售日期列表中');
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
const startTime = dayjs(`${now.format("YYYY-MM-DD")} ${startTimeStr}`);
|
||||||
const startTime = dayjs(`${now.format('YYYY-MM-DD')} ${startTimeStr}`);
|
let endTime = dayjs(`${now.format("YYYY-MM-DD")} ${endTimeStr}`);
|
||||||
let endTime = dayjs(`${now.format('YYYY-MM-DD')} ${endTimeStr}`);
|
|
||||||
// 处理跨天情况
|
// 处理跨天情况
|
||||||
if (endTime.isBefore(startTime)) {
|
if (endTime.isBefore(startTime)) {
|
||||||
endTime = endTime.add(1, 'day');
|
endTime = endTime.add(1, "day");
|
||||||
}
|
} // console.log('开始时间:', startTime.format('YYYY-MM-DD HH:mm:ss')); // console.log('结束时间:', endTime.format('YYYY-MM-DD HH:mm:ss'));
|
||||||
|
|
||||||
// console.log('当前时间:', now.format('YYYY-MM-DD HH:mm:ss'));
|
// console.log('当前时间:', now.format('YYYY-MM-DD HH:mm:ss'));
|
||||||
// console.log('开始时间:', startTime.format('YYYY-MM-DD HH:mm:ss'));
|
const isInRange = now.isBetween(startTime, endTime, null, "[)"); // console.log('当前时间是否在可售时间范围内:', isInRange);
|
||||||
// console.log('结束时间:', endTime.format('YYYY-MM-DD HH:mm:ss'));
|
return isInRange;
|
||||||
|
|
||||||
const isInRange = now.isBetween(startTime, endTime, null, '[)');
|
|
||||||
// console.log('当前时间是否在可售时间范围内:', isInRange);
|
|
||||||
|
|
||||||
return isInRange;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const emits = defineEmits(['add', 'reduce', 'chooseGuige','tapweigh'])
|
const emits = defineEmits(["add", "reduce", "chooseGuige", "tapweigh"]);
|
||||||
|
|
||||||
function emitEvent(emitName) {
|
function emitEvent(emitName) {
|
||||||
if (isGoods()) {
|
if (isGoods()) {
|
||||||
emits(emitName, props.index)
|
emits(emitName, props.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -162,7 +256,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
background: #EB4F4F;
|
background: #eb4f4f;
|
||||||
border-radius: 100rpx;
|
border-radius: 100rpx;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
height: 56rpx;
|
height: 56rpx;
|
||||||
|
|
@ -181,17 +275,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-hover-class {
|
.btn-hover-class {
|
||||||
opacity: .6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
image {
|
image {
|
||||||
will-change: transform
|
will-change: transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
// width: 250rpx;
|
// width: 250rpx;
|
||||||
// height: 272rpx;
|
// height: 272rpx;
|
||||||
background: #F9B798;
|
background: #f9b798;
|
||||||
border-radius: 8rpx 8rpx 8rpx 8rpx;
|
border-radius: 8rpx 8rpx 8rpx 8rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
|
@ -206,7 +300,7 @@
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 32rpx 24rpx 24rpx 24rpx;
|
padding: 52rpx 24rpx 24rpx 24rpx;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: rgba(37, 22, 15, 0.5);
|
background: rgba(37, 22, 15, 0.5);
|
||||||
border-radius: 8rpx 8rpx 8rpx 8rpx;
|
border-radius: 8rpx 8rpx 8rpx 8rpx;
|
||||||
|
|
@ -229,4 +323,23 @@
|
||||||
width: 60%;
|
width: 60%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.limit-discount {
|
||||||
|
background-color: #cc5617;
|
||||||
|
padding: 10rpx 20rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #ffffff;
|
||||||
|
border-radius: 0 0rpx 20rpx 0rpx;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.line-through{
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -4,6 +4,8 @@ export function getNowCart(carItem,goodsList,user) {
|
||||||
// console.log("carItem===",carItem)
|
// console.log("carItem===",carItem)
|
||||||
// console.log("goodsList===",goodsList)
|
// console.log("goodsList===",goodsList)
|
||||||
// const nowCart = records.find(v => v.placeNum == 0)
|
// const nowCart = records.find(v => v.placeNum == 0)
|
||||||
|
console.log("carItem===",carItem)
|
||||||
|
|
||||||
const arr = []
|
const arr = []
|
||||||
if( carItem.is_temporary != 1 ){
|
if( carItem.is_temporary != 1 ){
|
||||||
carItem.isGrounding = false;
|
carItem.isGrounding = false;
|
||||||
|
|
@ -13,8 +15,9 @@ export function getNowCart(carItem,goodsList,user) {
|
||||||
if(carItem.sku_id == item.id){
|
if(carItem.sku_id == item.id){
|
||||||
carItem.lowPrice = item.salePrice
|
carItem.lowPrice = item.salePrice
|
||||||
carItem.lowMemberPrice = item.memberPrice
|
carItem.lowMemberPrice = item.memberPrice
|
||||||
|
carItem.memberPrice = item.memberPrice
|
||||||
carItem.specInfo = item.specInfo
|
carItem.specInfo = item.specInfo
|
||||||
carItem.suitNum = item.suitNum
|
carItem.salePrice = item.salePrice
|
||||||
|
|
||||||
if( uni.getStorageSync('shopInfo').isMemberPrice && user && user.id && user.isVip ){
|
if( uni.getStorageSync('shopInfo').isMemberPrice && user && user.id && user.isVip ){
|
||||||
carItem.salePrice = item.memberPrice
|
carItem.salePrice = item.memberPrice
|
||||||
|
|
@ -38,8 +41,10 @@ export function getNowCart(carItem,goodsList,user) {
|
||||||
carItem.number = parseFloat(carItem.number)
|
carItem.number = parseFloat(carItem.number)
|
||||||
carItem.name = carItem.product_name
|
carItem.name = carItem.product_name
|
||||||
carItem.lowPrice = carItem.discount_sale_amount
|
carItem.lowPrice = carItem.discount_sale_amount
|
||||||
carItem.discount_sale_amount = 0
|
carItem.discount_sale_amount = carItem.discount_sale_amount?carItem.discount_sale_amount*1:0
|
||||||
}
|
carItem.discountSaleAmount = carItem.discount_sale_amount
|
||||||
|
|
||||||
|
// carItem.discount_sale_amount = 0
|
||||||
|
}
|
||||||
return carItem
|
return carItem
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,27 +1,41 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="u-p-l-30 u-p-r-30 u-p-t-30 u-font-28">
|
<view class="u-p-l-30 u-p-r-30 u-p-t-30 u-font-28">
|
||||||
<up-sticky offset-top="0">
|
<up-sticky offset-top="0">
|
||||||
<my-tabs v-model="pageData.types.sel" @change="tabChange" :list="pageData.types.list"></my-tabs>
|
<my-tabs v-model="myQuan.types.sel" :list="myQuan.types.list"></my-tabs>
|
||||||
</up-sticky>
|
</up-sticky>
|
||||||
<view class="u-m-t-32">
|
<view class="u-m-t-32">
|
||||||
<template v-if="pageData.types.sel==0">
|
<view
|
||||||
<view class="" @click="changeFullReductionCouponSel(item)"
|
class=""
|
||||||
v-for="(item,index) in pageData.fullReductionCoupon" :class="{filtergray:!item.use}" :key="index">
|
@click="changeSelCoupon(item)"
|
||||||
<view class="quan u-row-between u-flex u-col-center u-m-b-32 border-r-10 ">
|
v-for="(item, index) in list.canUseCoupons"
|
||||||
|
:class="{ filtergray: !item.use }"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="quan u-row-between u-flex u-col-center u-m-b-32 border-r-10"
|
||||||
|
>
|
||||||
<view class="no-use" v-if="!item.use">
|
<view class="no-use" v-if="!item.use">
|
||||||
<image class="img" src="/pagesOrder/static/image/no-use.svg" mode=""></image>
|
<image
|
||||||
|
class="img"
|
||||||
|
src="/pagesOrder/static/image/no-use.svg"
|
||||||
|
mode=""
|
||||||
|
></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="sel u-abso" v-if="item.id == pageData.fullReductionCouponSel.id ">
|
<view class="sel u-abso" v-if="isActive(item)">
|
||||||
<up-icon name="checkbox-mark" color="#fff"></up-icon>
|
<up-icon name="checkbox-mark" color="#fff"></up-icon>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-p-t-32 u-p-b-32 u-p-l-24 u-p-r-24 left">
|
<view class="u-p-t-32 u-p-b-32 u-p-l-24 u-p-r-24 left">
|
||||||
<view class="u-flex">
|
<view class="u-flex" v-if="item.type != 2">
|
||||||
<view class="hui">减</view>
|
<view class="hui">减</view>
|
||||||
<view class="u-m-l-18">{{ item.name }}</view>
|
<view class="u-m-l-18">{{ item.name }}</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view v-else>{{ item.name }}</view>
|
||||||
<view class="u-m-t-20 u-flex">
|
<view class="u-m-t-20 u-flex">
|
||||||
<view>有效期:</view>
|
<view>有效期:</view>
|
||||||
<view class="u-font-24 u-m-l-6"> {{dayjs(item.endTime).format('YYYY-MM-DD HH:mm:ss') }}
|
<view class="u-font-24 u-m-l-6">
|
||||||
|
{{ dayjs(item.effectStartTime).format("YYYY-MM-DD HH:mm:ss") }}
|
||||||
|
-
|
||||||
|
{{ dayjs(item.effectEndTime).format("YYYY-MM-DD HH:mm:ss") }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-m-t-10 color-999 u-font-24">
|
<view class="u-m-t-10 color-999 u-font-24">
|
||||||
|
|
@ -29,67 +43,86 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="right u-flex u-flex-col u-row-between">
|
<view class="right u-flex u-flex-col u-row-between">
|
||||||
<view class="u-flex u-row-center u-font-36 ">
|
<view class="u-flex u-row-center u-font-36" v-if="item.type != 2">
|
||||||
¥{{ item.discountAmount }}
|
¥{{ item.discountAmount }}
|
||||||
</view>
|
</view>
|
||||||
<view class="u-flex u-font-24">
|
<view class="u-flex u-font-24"> 满{{ item.fullAmount }}可用 </view>
|
||||||
满{{item.fullAmount}}可用
|
|
||||||
</view>
|
|
||||||
<view class="u-flex">
|
<view class="u-flex">
|
||||||
<view class="use-btn" @click.stop="toEmitChooseQuan(item)">去使用</view>
|
<!-- <view class="use-btn" @click.stop="toEmitChooseQuan(item)"
|
||||||
|
>去使用</view
|
||||||
|
> -->
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<template v-if="pageData.fullReductionCoupon.length <= 0 && pageData.hasAjax">
|
<template v-if="list.canUseCoupons.length <= 0 && myQuan.hasAjax">
|
||||||
<my-img-empty tips="暂无可用优惠券"></my-img-empty>
|
<my-img-empty tips="暂无可用优惠券"></my-img-empty>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
<view style="height: 40rpx"></view>
|
||||||
|
<view
|
||||||
<template v-if="pageData.types.sel==1">
|
v-for="(item, index) in list.noCanUseCoupons"
|
||||||
<view class="" @click="changeProductCoupon(item)" v-for="(item,index) in pageData.productCoupon"
|
class="filtergray"
|
||||||
:class="{filtergray:!item.use}" :key="index">
|
:key="index"
|
||||||
<view class="quan goods u-row-between u-flex u-col-center u-m-b-32 border-r-10 u-relative">
|
>
|
||||||
<view class="no-use" v-if="!item.use">
|
<view
|
||||||
<image class="img" src="/pagesOrder/static/image/no-use.svg" mode=""></image>
|
class="quan u-row-between u-flex u-col-center u-m-b-32 border-r-10"
|
||||||
|
>
|
||||||
|
<view class="no-use">
|
||||||
|
<image
|
||||||
|
class="img"
|
||||||
|
src="/pagesOrder/static/image/no-use.svg"
|
||||||
|
mode=""
|
||||||
|
></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="sel u-abso" v-if="item.checked">
|
<view class="sel u-abso" v-if="isActive(item)">
|
||||||
<up-icon name="checkbox-mark" color="#fff"></up-icon>
|
<up-icon name="checkbox-mark" color="#fff"></up-icon>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-p-t-32 u-p-b-32 u-p-l-24 u-p-r-24">
|
<view class="u-p-t-32 u-p-b-32 u-p-l-24 u-p-r-24 left">
|
||||||
|
<view class="u-flex" v-if="item.type != 2">
|
||||||
|
<view class="hui">减</view>
|
||||||
|
<view class="u-m-l-18">{{ item.name }}</view>
|
||||||
|
</view>
|
||||||
|
<template v-else>
|
||||||
<view class="u-flex">
|
<view class="u-flex">
|
||||||
<up-image width="80rpx" height="80rpx" :src="item.productCover"></up-image>
|
{{ item.foods }}
|
||||||
<view class="u-m-l-18">
|
|
||||||
<view class="u-m-l-18">{{item.name}}{{item.productName?' | '+item.productName : ''}}</view>
|
|
||||||
<!-- <view class="u-m-l-18 u-m-t-10 u-font-24 color-666">x{{item.num}}</view> -->
|
|
||||||
</view>
|
</view>
|
||||||
|
<view class="u-flex">
|
||||||
|
{{ item.name }}
|
||||||
</view>
|
</view>
|
||||||
<view class=" u-m-t-14 u-flex">
|
</template>
|
||||||
|
|
||||||
|
<view class="u-m-t-20 u-flex">
|
||||||
<view>有效期:</view>
|
<view>有效期:</view>
|
||||||
<view class="u-font-24 u-m-l-6"> {{dayjs(item.endTime).format('YYYY-MM-DD HH:mm:ss') }}
|
<view class="u-font-24 u-m-l-6">
|
||||||
|
{{ dayjs(item.effectStartTime).format("YYYY-MM-DD HH:mm:ss") }}
|
||||||
|
-
|
||||||
|
{{ dayjs(item.effectEndTime).format("YYYY-MM-DD HH:mm:ss") }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-m-t-10 color-999 u-font-24">
|
<view class="u-m-t-10 color-999 u-font-24">
|
||||||
{{ item.useRestrictions }}
|
{{ formatStr(item.useRestrictions) }}
|
||||||
|
</view>
|
||||||
|
<view class="u-m-t-10 color-999 u-font-24">
|
||||||
|
{{ returnNoUseRestrictions(item) }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="right u-flex u-flex-col u-col-bottom u-row-center" style="flex-shrink: 1;">
|
<view class="right u-flex u-flex-col u-row-between">
|
||||||
<view class="use-btn" @click.stop="toEmitChooseQuan(item)" style="flex-shrink: 1;">去使用</view>
|
<view class="u-flex u-row-center u-font-36" v-if="item.type != 2">
|
||||||
|
¥{{ item.discountAmount }}
|
||||||
|
</view>
|
||||||
|
<view class="u-flex u-font-24"> 满{{ item.fullAmount }}可用 </view>
|
||||||
|
<view class="u-flex">
|
||||||
|
<!-- <view class="use-btn" @click.stop="toEmitChooseQuan(item)"
|
||||||
|
>去使用</view
|
||||||
|
> -->
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
<template v-if="pageData.productCoupon.length <= 0 && pageData.hasAjax">
|
|
||||||
<my-img-empty tips="暂无可用优惠券"></my-img-empty>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view :style="{ height: safebottomHeight + 'px' }"></view>
|
<view :style="{ height: safebottomHeight + 'px' }"></view>
|
||||||
<view class="fixed-b bottom safe-bottom border-top">
|
<view class="fixed-b bottom safe-bottom border-top">
|
||||||
|
|
||||||
<view class="u-m-b-32 u-flex u-row-between u-p-t-10">
|
<view class="u-m-b-32 u-flex u-row-between u-p-t-10">
|
||||||
<view class="u-flex">
|
<view class="u-flex">
|
||||||
<text>抵扣金额:</text>
|
<text>抵扣金额:</text>
|
||||||
|
|
@ -100,8 +133,11 @@
|
||||||
<text>支付金额:</text>
|
<text>支付金额:</text>
|
||||||
<text class="color-red">¥</text>
|
<text class="color-red">¥</text>
|
||||||
<text class="color-red">{{ payPrice }}</text>
|
<text class="color-red">{{ payPrice }}</text>
|
||||||
<view class="u-absolute u-flex u-row-between" style="bottom: 100%;right: 0;"
|
<view
|
||||||
v-if="payPrice*1!=option.orderPrice*1">
|
class="u-absolute u-flex u-row-between"
|
||||||
|
style="bottom: 100%; right: 0"
|
||||||
|
v-if="payPrice * 1 != option.orderPrice * 1"
|
||||||
|
>
|
||||||
<view class="u-flex line-th color-999">
|
<view class="u-flex line-th color-999">
|
||||||
<text class="">¥</text>
|
<text class="">¥</text>
|
||||||
<text class="">{{ option.orderPrice }}</text>
|
<text class="">{{ option.orderPrice }}</text>
|
||||||
|
|
@ -117,289 +153,456 @@
|
||||||
<view class="font-bold">确定</view>
|
<view class="font-bold">确定</view>
|
||||||
</up-button>
|
</up-button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<up-modal :title="modal.title" :content="modal.content" :show="modal.clear" :confirmText="modal.confirmText"
|
<up-modal
|
||||||
:cancelText="modal.cancelText" showCancelButton closeOnClickOverlay @confirm="confirmModelConfirm"
|
:title="modal.title"
|
||||||
@cancel="confirmModelCancel" @close="setModalShow('clear',false)" width="300px" />
|
:content="modal.content"
|
||||||
|
:show="modal.clear"
|
||||||
|
:confirmText="modal.confirmText"
|
||||||
|
:cancelText="modal.cancelText"
|
||||||
|
showCancelButton
|
||||||
|
closeOnClickOverlay
|
||||||
|
@confirm="confirmModelConfirm"
|
||||||
|
@cancel="confirmModelCancel"
|
||||||
|
@close="setModalShow('clear', false)"
|
||||||
|
width="300px"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onLoad, onReady } from '@dcloudio/uni-app'
|
import { ref, reactive, watch, computed, onMounted, toRaw } from "vue";
|
||||||
import { ref, reactive, watch, computed, onMounted } from 'vue';
|
import dayjs from "dayjs";
|
||||||
import dayjs from 'dayjs';
|
import { getSafeBottomHeight } from "@/commons/utils/safe-bottom.js";
|
||||||
import { getSafeBottomHeight } from '@/commons/utils/safe-bottom.js'
|
import go from "@/commons/utils/go.js";
|
||||||
import go from '@/commons/utils/go.js'
|
import { onLoad, onReady } from "@dcloudio/uni-app";
|
||||||
import infoBox from '@/commons/utils/infoBox.js'
|
import * as orderApi from "@/http/yskApi/order.js";
|
||||||
import {
|
import { $findCoupon } from "@/http/yskApi/Instead.js";
|
||||||
returnNewGoodsList,
|
import infoBox from "@/commons/utils/infoBox.js";
|
||||||
returnCoupCanUse,
|
import { queryAllShopUser, shopUserDetail } from "@/http/yskApi/shop-user.js";
|
||||||
returnCouponAllPrice,
|
// import {
|
||||||
returnProductCoupon,
|
// returnNewGoodsList,
|
||||||
returnCanUseFullReductionCoupon,
|
// returnCoupCanUse,
|
||||||
returnProductAllCoup
|
// returnCouponAllPrice,
|
||||||
} from '../quan_util.js'
|
// returnProductCoupon,
|
||||||
import { getHistoryOrder } from '@/http/api/order.js'
|
// returnCanUseFullReductionCoupon,
|
||||||
import { shopUserDetail } from '@/http/api/shopUser.js'
|
// } from "../quan_util.js";
|
||||||
import { getFindCoupon } from '@/http/api/coupon.js'
|
// const yskUtils = {
|
||||||
|
// couponUtils,
|
||||||
|
// };
|
||||||
|
|
||||||
|
import yskUtils from "ysk-utils";
|
||||||
|
// import {couponUtils} from "@/lib/index";
|
||||||
|
// const yskUtils={
|
||||||
|
// couponUtils
|
||||||
|
// }
|
||||||
|
|
||||||
const modal = reactive({
|
const modal = reactive({
|
||||||
title: '提示',
|
title: "提示",
|
||||||
cancelText: '取消',
|
cancelText: "取消",
|
||||||
confirmText: '确定',
|
confirmText: "确定",
|
||||||
content: '',
|
content: "",
|
||||||
key: '',
|
key: "",
|
||||||
clear: false,
|
clear: false,
|
||||||
data: ''
|
data: "",
|
||||||
})
|
});
|
||||||
|
|
||||||
const option = reactive({
|
|
||||||
orderId: '',
|
|
||||||
shopUserId: '',
|
|
||||||
orderPrice: 0
|
|
||||||
})
|
|
||||||
const pageData = reactive({
|
|
||||||
order: null,
|
|
||||||
user: null,
|
|
||||||
types: {
|
|
||||||
list: ['满减券(单选)', '商品券(多选)'],
|
|
||||||
sel: 0
|
|
||||||
},
|
|
||||||
fullReductionCouponSel: {
|
|
||||||
id: ''
|
|
||||||
},
|
|
||||||
fullReductionCoupon: [],
|
|
||||||
productCoupon: [],
|
|
||||||
hasAjax: false
|
|
||||||
})
|
|
||||||
let canDikouGoodsArr = []
|
|
||||||
let safebottomHeight = ref(0)
|
|
||||||
|
|
||||||
onLoad((opt) => {
|
|
||||||
Object.assign(option, opt)
|
|
||||||
getQuan()
|
|
||||||
})
|
|
||||||
watch(() => pageData.types.sel, (newval) => {
|
|
||||||
if (newval == 0) {
|
|
||||||
pageData.fullReductionCoupon = returnCanUseFullReductionCoupon(pageData.fullReductionCoupon, payPrice.value,
|
|
||||||
pageData.fullReductionCouponSel)
|
|
||||||
}
|
|
||||||
if (newval == 1) {
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
onReady(() => {
|
|
||||||
getSafeBottomHeight('bottom', 0).then(height => {
|
|
||||||
safebottomHeight.value = height
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
function tabChange () {
|
|
||||||
getQuan()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 抵扣金额
|
|
||||||
*/
|
|
||||||
const discountAmount = computed(() => {
|
|
||||||
const goodsQuan = pageData.productCoupon.filter(v => v.checked)
|
|
||||||
const fullReductionCoupon = pageData.fullReductionCouponSel.id ? [pageData.fullReductionCouponSel] : []
|
|
||||||
let coupArr = [...fullReductionCoupon, ...goodsQuan]
|
|
||||||
return returnCouponAllPrice(coupArr, canDikouGoodsArr, pageData.user)
|
|
||||||
})
|
|
||||||
const payPrice = computed(() => {
|
|
||||||
const pay = option.orderPrice - discountAmount.value
|
|
||||||
return (pay < 0 ? 0 : pay).toFixed(2)
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取优惠券
|
|
||||||
*/
|
|
||||||
async function getQuan() {
|
|
||||||
shopUserDetail({ id: option.shopUserId }).then(res=>{
|
|
||||||
pageData.user = res
|
|
||||||
})
|
|
||||||
pageData.order = await getHistoryOrder({orderId:option.orderId})
|
|
||||||
|
|
||||||
const res = await getFindCoupon({
|
|
||||||
shopUserId: option.shopUserId,
|
|
||||||
type: pageData.types.sel+1
|
|
||||||
})
|
|
||||||
let fullReductionCoupon = res ? res.filter(v => v.type == 1) : []
|
|
||||||
let productCoupon = res ? res.filter(v => v.type == 2) : []
|
|
||||||
|
|
||||||
canDikouGoodsArr = returnNewGoodsList(pageData.order.detailMap || [])
|
|
||||||
fullReductionCoupon = fullReductionCoupon.map((v) => {
|
|
||||||
if(option.orderPrice<=0){
|
|
||||||
return {...v,use:false}
|
|
||||||
}else{
|
|
||||||
return{
|
|
||||||
...v,
|
|
||||||
use:v.use && option.orderPrice * 1 >= v
|
|
||||||
.fullAmount * 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
productCoupon = productCoupon.map(v => {
|
|
||||||
const calcCoup = returnProductCoupon(v, pageData.order.detailMap, pageData.user)
|
|
||||||
return {
|
|
||||||
...calcCoup,
|
|
||||||
checked: false,
|
|
||||||
use: option.orderPrice<=0?false:v.use
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// .filter((v) => v.use);
|
|
||||||
pageData.fullReductionCoupon = fullReductionCoupon
|
|
||||||
pageData.productCoupon = productCoupon
|
|
||||||
pageData.hasAjax = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function confirmModelCancel() {
|
function confirmModelCancel() {
|
||||||
setModalShow('clear', false, '')
|
setModalShow("clear", false, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 继续选择
|
|
||||||
*/
|
|
||||||
async function confirmModelConfirm() {
|
async function confirmModelConfirm() {
|
||||||
if (modal.key == 'clear') {
|
if (modal.key == "clear") {
|
||||||
if( modal.data ){
|
myQuan.fullReductionCouponSel = {
|
||||||
pageData.fullReductionCouponSel = {
|
id: "",
|
||||||
id: ''
|
};
|
||||||
}
|
const item = modal.data;
|
||||||
const item = modal.data
|
item.checked = !item.checked;
|
||||||
item.checked = !item.checked
|
const CheckedArr = myQuan.res.productCoupon.filter((v) => v.checked);
|
||||||
const CheckedArr = pageData.productCoupon.filter(v => v.checked)
|
const noCheckedArr = myQuan.res.productCoupon.filter((v) => !v.checked);
|
||||||
const noCheckedArr = pageData.productCoupon.filter(v => !v.checked)
|
noCheckedArr.map((v) => {
|
||||||
noCheckedArr.map(v => {
|
console.log(returnCoupCanUse(canDikouGoodsArr, v, CheckedArr));
|
||||||
v.use = returnCoupCanUse(canDikouGoodsArr, v, CheckedArr)
|
v.use = returnCoupCanUse(canDikouGoodsArr, v, CheckedArr);
|
||||||
})
|
});
|
||||||
}
|
setModalShow("clear", false, "");
|
||||||
|
|
||||||
setModalShow('clear', false, '')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setModalShow(key = 'show', show = true, data) {
|
function setModalShow(key = "show", show = true, data) {
|
||||||
modal.key = key
|
modal.key = key;
|
||||||
modal[key] = show
|
modal[key] = show;
|
||||||
modal.data = data
|
modal.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
function back() {
|
function back() {
|
||||||
uni.navigateBack()
|
uni.navigateBack();
|
||||||
}
|
}
|
||||||
|
let order = ref({});
|
||||||
|
let canDikouGoodsArr = [];
|
||||||
|
const myQuan = reactive({
|
||||||
|
fullReductionCouponSel: {
|
||||||
|
id: "",
|
||||||
|
},
|
||||||
|
res: {
|
||||||
|
fullReductionCoupon: [],
|
||||||
|
productCoupon: [],
|
||||||
|
},
|
||||||
|
types: {
|
||||||
|
list: ["优惠券(单选)", "商品券(单选)"],
|
||||||
|
sel: 0,
|
||||||
|
},
|
||||||
|
list: [],
|
||||||
|
sel: -1,
|
||||||
|
hasAjax: false,
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
function changeSelCoupon(item) {
|
||||||
* 商品券选择
|
if (myQuan.types.sel == 0) {
|
||||||
* @param {Object} item
|
if (couponSel.value.id == item.id) {
|
||||||
*/
|
couponSel.value = {
|
||||||
function changeProductCoupon(item) {
|
id: "",
|
||||||
if (!item.use) { return }
|
};
|
||||||
if ( payPrice.value <= 0 ) {
|
} else {
|
||||||
modal.content = '当前支付金额不满足选择商品券的最低使用需求,无法选择'
|
couponSel.value = item;
|
||||||
modal.cancelText = '取消'
|
|
||||||
modal.confirmText = '确定'
|
|
||||||
setModalShow('clear', true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!item.checked) {
|
|
||||||
const goodsQuan = pageData.productCoupon.filter(v => v.checked)
|
|
||||||
let coupArr = [...goodsQuan, item]
|
|
||||||
const payPrice = option.orderPrice - returnCouponAllPrice(coupArr, canDikouGoodsArr, pageData.user)
|
|
||||||
if (payPrice<=0) {
|
|
||||||
modal.content = '选择该商品券后支付金额将为0,继续选择将取消选择的满减券'
|
|
||||||
modal.cancelText = '取消'
|
|
||||||
modal.confirmText = '继续选择'
|
|
||||||
setModalShow('clear', true, item)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (pageData.fullReductionCouponSel.fullAmount > payPrice) {
|
|
||||||
modal.content = '选择该商品券后将不满足选择抵扣券的最低满减需求,继续选择将取消选择的满减券'
|
|
||||||
modal.cancelText = '取消'
|
|
||||||
modal.confirmText = '继续选择'
|
|
||||||
setModalShow('clear', true, item)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
item.checked = !item.checked
|
|
||||||
const CheckedArr = pageData.productCoupon.filter(v => v.checked)
|
|
||||||
if (CheckedArr.length <= 0) {
|
|
||||||
return pageData.productCoupon.map(v => {
|
|
||||||
v.use = true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const noCheckedArr = pageData.productCoupon.filter(v => !v.checked)
|
|
||||||
noCheckedArr.map(v => {
|
|
||||||
v.use = returnCoupCanUse(canDikouGoodsArr, v, CheckedArr)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 优惠券选择
|
|
||||||
* @param {Object} item
|
|
||||||
*/
|
|
||||||
function changeFullReductionCouponSel(item) {
|
|
||||||
if (!item.use) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (item.id == pageData.fullReductionCouponSel.id) {
|
|
||||||
pageData.fullReductionCouponSel = {
|
|
||||||
id: ''
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pageData.fullReductionCouponSel = item
|
if (goodsCouponSel.value.id == item.id) {
|
||||||
|
goodsCouponSel.value = {
|
||||||
|
id: "",
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
goodsCouponSel.value = item;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pageData.fullReductionCoupon = returnCanUseFullReductionCoupon(pageData.fullReductionCoupon, payPrice.value, pageData
|
|
||||||
.fullReductionCouponSel)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatStr(str) {
|
function formatStr(str) {
|
||||||
// return str.replaceAll('"', '')
|
console.log(str);
|
||||||
|
if (!str) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const reg = /^[,]+|[,]+$/g;
|
||||||
|
return `${str}`.replace(reg, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function isActive(item) {
|
||||||
* 优惠券选择确认
|
if (myQuan.types.sel == 0) {
|
||||||
* @param {Object} item
|
return couponSel.value.id == item.id;
|
||||||
*/
|
|
||||||
function toEmitChooseQuan(item) {
|
|
||||||
let arr = []
|
|
||||||
let discountAmount = 0;
|
|
||||||
if (item) {
|
|
||||||
arr = [item]
|
|
||||||
} else {
|
} else {
|
||||||
if (pageData.fullReductionCouponSel.id) {
|
return goodsCouponSel.value.id == item.id;
|
||||||
arr.push(pageData.fullReductionCouponSel)
|
|
||||||
}
|
}
|
||||||
let goodsQuan = pageData.productCoupon.filter(v => v.checked)
|
|
||||||
arr.push(...goodsQuan)
|
|
||||||
}
|
|
||||||
arr.map(item=>{
|
|
||||||
discountAmount += item.discountAmount
|
|
||||||
})
|
|
||||||
if( discountAmount > option.orderPrice){
|
|
||||||
|
|
||||||
}
|
|
||||||
console.log(arr)
|
|
||||||
uni.$emit('choose-quan', arr)
|
|
||||||
back()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const shopUserInfo = ref(null);
|
||||||
|
|
||||||
|
// 将订单商品转换为一维数组返回全部商品
|
||||||
|
function returnAllGoodsList() {
|
||||||
|
let goodsArr = [];
|
||||||
|
for (let key in order.value.detailMap) {
|
||||||
|
console.log(order.value.detailMap[key]);
|
||||||
|
for (let goods of order.value.detailMap[key]) {
|
||||||
|
goods.salePrice = goods.salePrice || goods.price;
|
||||||
|
goods.number = goods.num || 0;
|
||||||
|
goodsArr.push(toRaw(goods));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return goodsArr;
|
||||||
|
}
|
||||||
|
//返回不可用原因
|
||||||
|
function returnNoUseRestrictions(item) {
|
||||||
|
if (item.noUseRestrictions) {
|
||||||
|
return item.noUseRestrictions;
|
||||||
|
}
|
||||||
|
if (item.canuseResult) {
|
||||||
|
return item.canuseResult.reason;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//优惠券列表
|
||||||
|
const couponList = ref([]);
|
||||||
|
//已选商品抵扣券
|
||||||
|
const goodsCouponSel = ref({
|
||||||
|
id: "",
|
||||||
|
});
|
||||||
|
//已选优惠券
|
||||||
|
const couponSel = ref({
|
||||||
|
id: "",
|
||||||
|
});
|
||||||
|
//限时折扣
|
||||||
|
const limitTimeDiscount = reactive({ id: "" });
|
||||||
|
//已选优惠券列表
|
||||||
|
const quansSelArr = computed(() => {
|
||||||
|
return [couponSel.value, goodsCouponSel.value].filter((v) => v.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
const list = reactive({
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
status: "nomore",
|
||||||
|
data: [],
|
||||||
|
noCanUseCoupons: [],
|
||||||
|
canUseCoupons: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
//返回优惠券可用与不可用的,计算优惠券抵扣金额
|
||||||
|
function formatCoupon() {
|
||||||
|
let canUseGoodsCoupon = [];
|
||||||
|
let canUseDiscountCoupon = [];
|
||||||
|
|
||||||
|
let noUseGoodsCoupon = [];
|
||||||
|
let noUseDiscountCoupon = [];
|
||||||
|
const user = shopUserInfo.value;
|
||||||
|
let shopInfo = uni.getStorageSync("shopInfo") || {};
|
||||||
|
const goodsOrderPrice = option.orderPrice || 0;
|
||||||
|
const dinnerType = option.dinnerType || "dine-in";
|
||||||
|
let goodsArr = returnAllGoodsList();
|
||||||
|
|
||||||
|
const canDikouGoodsArr = yskUtils.couponUtils.returnCanDikouGoods(
|
||||||
|
goodsArr,
|
||||||
|
user,
|
||||||
|
shopInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
for (let i = 0; i < couponList.value.length; i++) {
|
||||||
|
const coupon = couponList.value[i];
|
||||||
|
console.log('quansSelArr',quansSelArr.value)
|
||||||
|
const selCoupon =
|
||||||
|
myQuan.types.sel ==1
|
||||||
|
? quansSelArr.value.filter((v) => v.type != 2)
|
||||||
|
: quansSelArr.value.filter((v) => v.type == 2);
|
||||||
|
const canuseResult = yskUtils.couponUtils.returnCouponCanUse({
|
||||||
|
canDikouGoodsArr,
|
||||||
|
coupon,
|
||||||
|
goodsOrderPrice,
|
||||||
|
user,
|
||||||
|
selCoupon: selCoupon,
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount: limitTimeDiscount,
|
||||||
|
});
|
||||||
|
const { canUse, reason } = canuseResult;
|
||||||
|
if (coupon.type == 2) {
|
||||||
|
if (canUse || goodsCouponSel.value.id == coupon.id) {
|
||||||
|
canUseGoodsCoupon.push(coupon);
|
||||||
|
} else {
|
||||||
|
noUseGoodsCoupon.push({
|
||||||
|
...coupon,
|
||||||
|
canuseResult,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (canUse || couponSel.value.id == coupon.id) {
|
||||||
|
canUseDiscountCoupon.push(coupon);
|
||||||
|
} else {
|
||||||
|
noUseDiscountCoupon.push({
|
||||||
|
...coupon,
|
||||||
|
canuseResult,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//商品券
|
||||||
|
canUseGoodsCoupon = canUseGoodsCoupon.map((v) => {
|
||||||
|
const discount = yskUtils.couponUtils.returnCouponDiscount(
|
||||||
|
canDikouGoodsArr,
|
||||||
|
v,
|
||||||
|
user,
|
||||||
|
goodsOrderPrice,
|
||||||
|
quansSelArr.value.filter((v) => v.type != 2),
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
discount,
|
||||||
|
discountAmount: discount ? discount.discountPrice : v.discountAmount,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
//非商品券
|
||||||
|
canUseDiscountCoupon = canUseDiscountCoupon.map((v) => {
|
||||||
|
const discount = yskUtils.couponUtils.returnCouponDiscount(
|
||||||
|
canDikouGoodsArr,
|
||||||
|
v,
|
||||||
|
user,
|
||||||
|
goodsOrderPrice,
|
||||||
|
quansSelArr.value.filter((v) => v.type == 2),
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
discount,
|
||||||
|
discountAmount: discount ? discount.discountPrice : v.discountAmount,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
if (myQuan.types.sel == 1) {
|
||||||
|
list.noCanUseCoupons = noUseGoodsCoupon;
|
||||||
|
list.canUseCoupons = canUseGoodsCoupon;
|
||||||
|
} else {
|
||||||
|
list.noCanUseCoupons = noUseDiscountCoupon;
|
||||||
|
list.canUseCoupons = canUseDiscountCoupon;
|
||||||
|
}
|
||||||
|
console.log("list", list);
|
||||||
|
|
||||||
|
console.log("canUseGoodsCoupon", canUseGoodsCoupon);
|
||||||
|
console.log("noUseGoodsCoupon", noUseGoodsCoupon);
|
||||||
|
console.log("canUseDiscountCoupon", canUseDiscountCoupon);
|
||||||
|
console.log("noUseDiscountCoupon", noUseDiscountCoupon);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getQuan() {
|
||||||
|
const orderRes = await orderApi.tbOrderInfoDetail(option.orderId);
|
||||||
|
if (orderRes) {
|
||||||
|
order.value = orderRes;
|
||||||
|
Object.assign(limitTimeDiscount,orderRes.limitRate)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(order.value);
|
||||||
|
|
||||||
|
const res = await $findCoupon({
|
||||||
|
shopUserId: option.shopUserId,
|
||||||
|
});
|
||||||
|
couponList.value = res || [];
|
||||||
|
formatCoupon();
|
||||||
|
myQuan.hasAjax = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const option = reactive({
|
||||||
|
orderId: "",
|
||||||
|
shopUserId: "",
|
||||||
|
orderPrice: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
function toEmitChooseQuan(item) {
|
||||||
|
let arr = [];
|
||||||
|
if (item) {
|
||||||
|
arr = [item];
|
||||||
|
} else {
|
||||||
|
if (myQuan.fullReductionCouponSel.id) {
|
||||||
|
arr.push(myQuan.fullReductionCouponSel);
|
||||||
|
}
|
||||||
|
const goodsQuan = myQuan.res.productCoupon.filter((v) => v.checked);
|
||||||
|
arr.push(...goodsQuan);
|
||||||
|
}
|
||||||
|
uni.$emit("choose-quan", arr);
|
||||||
|
back();
|
||||||
|
}
|
||||||
|
const discountAmount = computed(() => {
|
||||||
|
return quansSelArr.value.reduce((pre, cur) => pre + cur.discountAmount, 0);
|
||||||
|
});
|
||||||
|
const payPrice = computed(() => {
|
||||||
|
const pay = option.orderPrice - discountAmount.value;
|
||||||
|
return (pay < 0 ? 0 : pay).toFixed(2);
|
||||||
|
});
|
||||||
|
watch(
|
||||||
|
() => myQuan.types.sel,
|
||||||
|
(newval) => {
|
||||||
|
formatCoupon();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => couponSel.value.id,
|
||||||
|
(newval) => {
|
||||||
|
formatCoupon();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => goodsCouponSel.value.id,
|
||||||
|
(newval) => {
|
||||||
|
formatCoupon();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => quansSelArr.value,
|
||||||
|
(newval) => {
|
||||||
|
const user = shopUserInfo.value;
|
||||||
|
let shopInfo = uni.getStorageSync("shopInfo") || {};
|
||||||
|
const goodsOrderPrice = option.orderPrice || 0;
|
||||||
|
const dinnerType = option.dinnerType || "dine-in";
|
||||||
|
let goodsArr = returnAllGoodsList();
|
||||||
|
const canDikouGoodsArr = yskUtils.couponUtils.returnCanDikouGoods(
|
||||||
|
goodsArr,
|
||||||
|
user,
|
||||||
|
shopInfo
|
||||||
|
);
|
||||||
|
console.log('canDikouGoodsArr');
|
||||||
|
console.log(canDikouGoodsArr);
|
||||||
|
|
||||||
|
let goodsCoupon = newval.filter((v) => v.type == 2);
|
||||||
|
let otherCoupon = newval.filter((v) => v.type != 2);
|
||||||
|
goodsCoupon = goodsCoupon.map((v) => {
|
||||||
|
const discount = yskUtils.couponUtils.returnCouponDiscount(
|
||||||
|
canDikouGoodsArr,
|
||||||
|
v,
|
||||||
|
user,
|
||||||
|
goodsOrderPrice,
|
||||||
|
[],
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
discount,
|
||||||
|
discountAmount: discount ? discount.discountPrice : v.discountAmount,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
otherCoupon = otherCoupon.map((v) => {
|
||||||
|
const discount = yskUtils.couponUtils.returnCouponDiscount(
|
||||||
|
canDikouGoodsArr,
|
||||||
|
v,
|
||||||
|
user,
|
||||||
|
goodsOrderPrice,
|
||||||
|
goodsCoupon,
|
||||||
|
shopInfo,
|
||||||
|
limitTimeDiscount
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
discount,
|
||||||
|
discountAmount: discount ? discount.discountPrice : v.discountAmount,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
uni.$emit("selCoupon", [...goodsCoupon, ...otherCoupon]);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
async function getShopUser() {
|
||||||
|
const res = await shopUserDetail({
|
||||||
|
id: option.shopUserId,
|
||||||
|
});
|
||||||
|
if (res) {
|
||||||
|
shopUserInfo.value = res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onLoad(async (opt) => {
|
||||||
|
Object.assign(option, opt);
|
||||||
|
const selCoupon=uni.getStorageSync("selCoupon")||[];
|
||||||
|
for(let i=0;i<selCoupon.length;i++){
|
||||||
|
if(selCoupon[i].type==2){
|
||||||
|
goodsCouponSel.value=selCoupon[i];
|
||||||
|
}else{
|
||||||
|
couponSel.value=selCoupon[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await getShopUser();
|
||||||
|
getQuan();
|
||||||
|
});
|
||||||
|
let safebottomHeight = ref(0);
|
||||||
|
onReady(() => {
|
||||||
|
getSafeBottomHeight("bottom", 0).then((height) => {
|
||||||
|
console.log(height);
|
||||||
|
safebottomHeight.value = height;
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
// $quan-color:rgb(233, 77, 60);
|
// $quan-color:rgb(233, 77, 60);
|
||||||
$quan-color: #318AFE;
|
$quan-color: #318afe;
|
||||||
|
|
||||||
.no-use {
|
.no-use {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -445,7 +648,6 @@
|
||||||
height: 40rpx;
|
height: 40rpx;
|
||||||
border-radius: 40rpx;
|
border-radius: 40rpx;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
|
|
@ -459,7 +661,7 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -30rpx;
|
left: -30rpx;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
@ -483,7 +685,8 @@
|
||||||
height: 40rpx;
|
height: 40rpx;
|
||||||
border-radius: 40rpx;
|
border-radius: 40rpx;
|
||||||
|
|
||||||
&.active {}
|
&.active {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.use-btn {
|
.use-btn {
|
||||||
|
|
@ -522,7 +725,11 @@
|
||||||
|
|
||||||
.hui {
|
.hui {
|
||||||
// background-color: $quan-color;
|
// background-color: $quan-color;
|
||||||
background-image: linear-gradient(to right bottom, rgb(254, 103, 4), rgb(241, 50, 42));
|
background-image: linear-gradient(
|
||||||
|
to right bottom,
|
||||||
|
rgb(254, 103, 4),
|
||||||
|
rgb(241, 50, 42)
|
||||||
|
);
|
||||||
padding: 4rpx 10rpx;
|
padding: 4rpx 10rpx;
|
||||||
border-radius: 10rpx;
|
border-radius: 10rpx;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
|
|
@ -536,7 +743,7 @@
|
||||||
box-shadow: 0 0 5px #eee;
|
box-shadow: 0 0 5px #eee;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
.left {
|
.left {
|
||||||
max-width: 80%;
|
max-width: 70%;
|
||||||
}
|
}
|
||||||
.sel {
|
.sel {
|
||||||
padding: 2rpx 4rpx;
|
padding: 2rpx 4rpx;
|
||||||
|
|
@ -558,11 +765,13 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background-color: $quan-color;
|
background-color: $quan-color;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
min-width: 180rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.goods {
|
&.goods {
|
||||||
.right {
|
.right {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
position: initial;
|
||||||
|
|
||||||
.use-btn {
|
.use-btn {
|
||||||
padding: 10rpx 40rpx;
|
padding: 10rpx 40rpx;
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -64,4 +64,6 @@ export const useMenusStore = defineStore('menus', {
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
unistorage: true, // 开启后对 state 的数据读写都将持久化
|
||||||
|
}
|
||||||
|
);
|
||||||
Loading…
Reference in New Issue