代客下单修改
This commit is contained in:
parent
e40b4fe8cc
commit
08e76b8897
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;
|
||||||
|
}
|
||||||
|
|
@ -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",
|
||||||
|
|
@ -9,7 +10,8 @@
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"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">
|
||||||
|
|
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
@ -1,285 +1,402 @@
|
||||||
<template>
|
<template>
|
||||||
<view>
|
<view>
|
||||||
<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
|
||||||
<view>已添加{{ goodsNumber.toFixed(0) }}件商品</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="color-666">
|
>
|
||||||
<uni-icons color="#666" type="trash"></uni-icons>
|
<view>已添加{{ goodsNumber.toFixed(0) }}件商品</view>
|
||||||
<text class="u-m-l-10" @tap="setModalShow('clear', true, 'cart', '是否清空全部已添加的商品')">清空购物车</text>
|
<view class="color-666">
|
||||||
</view>
|
<uni-icons color="#666" type="trash"></uni-icons>
|
||||||
</view>
|
<text
|
||||||
<scroll-view scroll-y="true" class="tranistion" :style="{ height: switchGoods ? '50vh' : 0 }">
|
class="u-m-l-10"
|
||||||
<!-- 占位 -->
|
@tap="
|
||||||
<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">
|
setModalShow('clear', true, 'cart', '是否清空全部已添加的商品')
|
||||||
<view>已添加{{ goodsNumber.toFixed(0) }}件商品</view>
|
"
|
||||||
<view class="color-666">
|
>清空购物车</text
|
||||||
<uni-icons color="#666" type="trash"></uni-icons>
|
>
|
||||||
<text class="u-m-l-10">清空</text>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<scroll-view
|
||||||
<!-- 占位 -->
|
scroll-y="true"
|
||||||
<view class="color-333 item border-top u-flex u-row-center u-row-between" v-for="(item, index) in data" :key="index">
|
class="tranistion"
|
||||||
<view>
|
:style="{ height: switchGoods ? '50vh' : 0 }"
|
||||||
<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>
|
<view
|
||||||
<view class="u-flex" style="flex-shrink: 0">
|
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"
|
||||||
<view class="font-bold red u-m-r-32">¥{{ formatPrice(item.lowPrice * item.number) }}</view>
|
style="opacity: 0"
|
||||||
<view class="u-flex" @tap="updateNumber(false, index, item)">
|
>
|
||||||
<image src="/pagesCreateOrder/static/images/icon-reduce-black.svg" class="icon" mode="" />
|
<view>已添加{{ goodsNumber.toFixed(0) }}件商品</view>
|
||||||
</view>
|
<view class="color-666">
|
||||||
<view class="u-m-l-30 u-m-r-30 color-333">
|
<uni-icons color="#666" type="trash"></uni-icons>
|
||||||
{{ item.number.toFixed(2) }}
|
<text class="u-m-l-10">清空</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-flex" @tap="updateNumber(true, index, item)">
|
</view>
|
||||||
<image
|
<!-- 占位 -->
|
||||||
src="/pagesCreateOrder/static/images/icon-add-black.svg"
|
<view
|
||||||
class="icon"
|
class="color-333 item border-top u-flex u-row-center u-row-between"
|
||||||
:class="{ grayscale: item.type == 'package' && item.groupType == 1 }"
|
v-for="(item, index) in data"
|
||||||
mode=""
|
:key="index"
|
||||||
/>
|
>
|
||||||
</view>
|
<view>
|
||||||
</view>
|
<view class="up-line-1">{{ item.name }}</view>
|
||||||
</view>
|
<view class="u-m-t-10 u-font-24 color-666 up-line-1">{{
|
||||||
<view style="margin: 50rpx auto 110rpx auto" v-if="!data.length">
|
item.specInfo || ""
|
||||||
<my-empty text="暂未有添加商品"></my-empty>
|
}}</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 历史订单 -->
|
<view class="u-flex" style="flex-shrink: 0">
|
||||||
<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="font-bold red" v-if="item.is_time_discount"
|
||||||
<view class="color-333" style="font-weight: bold">历史订单</view>
|
>¥{{ returnLimitTotalPrice(item) }}
|
||||||
<view class="color-666">
|
</view>
|
||||||
<uni-icons color="#666" type="trash"></uni-icons>
|
<view
|
||||||
<text class="u-m-l-10" @tap="setModalShow('clear', true, 'allHistoryOrder', '清空历史订单')">清空历史订单</text>
|
class="font-bold red u-m-r-32"
|
||||||
</view>
|
:class="[item.is_time_discount ? 'old-price' : '']"
|
||||||
</view>
|
>¥{{ formatPrice(item.lowPrice * item.number) }}</view
|
||||||
<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 class="u-flex" @tap="updateNumber(false, index, item)">
|
||||||
<view class="color-333" style="font-size: 30rpx">第{{ item.placeNum }}次下单</view>
|
<image
|
||||||
<view class="color-666">
|
src="/pagesCreateOrder/static/images/icon-reduce-black.svg"
|
||||||
<uni-icons color="#666" type="trash"></uni-icons>
|
class="icon"
|
||||||
<text class="u-m-l-10" @tap="setModalShow('clear', true, item.placeNum, '清空第' + item.placeNum + '次下单历史订单')">清空</text>
|
mode=""
|
||||||
</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="u-m-l-30 u-m-r-30 color-333">
|
||||||
<view style="display: flex; align-items: center">
|
{{ item.number.toFixed(2) }}
|
||||||
<view class="up-line-1" style="margin-right: 10rpx">{{ v.productName }}</view>
|
</view>
|
||||||
<uni-tag
|
<view class="u-flex" @tap="updateNumber(true, index, item)">
|
||||||
v-if="v.returnNum > 0"
|
<image
|
||||||
:text="'退菜X' + v.returnNum"
|
src="/pagesCreateOrder/static/images/icon-add-black.svg"
|
||||||
custom-style="background-color: #EB4F4F; border-color: #EB4F4F; color: #fff;"
|
class="icon"
|
||||||
></uni-tag>
|
:class="[
|
||||||
</view>
|
item.type == 'package' && item.groupType == 1
|
||||||
<view class="u-flex" style="flex-shrink: 0">
|
? grayscale
|
||||||
<view class="font-bold red u-m-r-32">¥{{ 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>
|
mode=""
|
||||||
</view>
|
/>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="icon-car-box" @tap="toggleGoods">
|
<view style="margin: 50rpx auto 110rpx auto" v-if="!data.length">
|
||||||
<image src="/pagesCreateOrder/static/images/icon-car.svg" class="icon-car" />
|
<my-empty text="暂未有添加商品"></my-empty>
|
||||||
<view class="dot" v-if="goodsNumber > 0">{{ goodsNumber }}</view>
|
</view>
|
||||||
</view>
|
<!-- 历史订单 -->
|
||||||
<view class="price font-bold u-flex">
|
<view
|
||||||
<view>¥</view>
|
v-if="historyOrder.length > 0"
|
||||||
<view>{{ allPrice }}</view>
|
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>
|
>
|
||||||
<my-button shape="circle" height="80" width="220" @tap="toConfimOrder">
|
<view class="color-333" style="font-weight: bold">历史订单</view>
|
||||||
<text class="u-font-32 font-bold">{{ table.type == 'add' ? '确认加菜' : '去下单' }}</text>
|
<view class="color-666">
|
||||||
</my-button>
|
<uni-icons color="#666" type="trash"></uni-icons>
|
||||||
</view>
|
<text
|
||||||
<up-modal
|
class="u-m-l-10"
|
||||||
title="提示"
|
@tap="
|
||||||
:content="modal.title"
|
setModalShow('clear', true, 'allHistoryOrder', '清空历史订单')
|
||||||
:show="modal.clear"
|
"
|
||||||
showCancelButton
|
>清空历史订单</text
|
||||||
closeOnClickOverlay
|
>
|
||||||
@confirm="confirmModelConfirm"
|
</view>
|
||||||
@cancel="setModalShow('clear', false)"
|
</view>
|
||||||
@close="setModalShow('clear', false)"
|
<view v-for="(item, index) in historyOrder" :key="index">
|
||||||
width="300px"
|
<view
|
||||||
></up-modal>
|
v-if="historyOrder.length > 0"
|
||||||
</view>
|
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">
|
||||||
|
<uni-icons color="#666" type="trash"></uni-icons>
|
||||||
|
<text
|
||||||
|
class="u-m-l-10"
|
||||||
|
@tap="
|
||||||
|
setModalShow(
|
||||||
|
'clear',
|
||||||
|
true,
|
||||||
|
item.placeNum,
|
||||||
|
'清空第' + item.placeNum + '次下单历史订单'
|
||||||
|
)
|
||||||
|
"
|
||||||
|
>清空</text
|
||||||
|
>
|
||||||
|
</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 style="display: flex; align-items: center">
|
||||||
|
<view class="up-line-1" style="margin-right: 10rpx">{{
|
||||||
|
v.productName
|
||||||
|
}}</view>
|
||||||
|
<uni-tag
|
||||||
|
v-if="v.returnNum > 0"
|
||||||
|
:text="'退菜X' + v.returnNum"
|
||||||
|
custom-style="background-color: #EB4F4F; border-color: #EB4F4F; color: #fff;"
|
||||||
|
></uni-tag>
|
||||||
|
</view>
|
||||||
|
<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="u-m-l-30 u-m-r-30 color-333"
|
||||||
|
>X{{ v.num.toFixed(2) }}</view
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
<view class="icon-car-box" @tap="toggleGoods">
|
||||||
|
<image
|
||||||
|
src="/pagesCreateOrder/static/images/icon-car.svg"
|
||||||
|
class="icon-car"
|
||||||
|
/>
|
||||||
|
<view class="dot" v-if="goodsNumber > 0">{{ goodsNumber }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="price font-bold u-flex">
|
||||||
|
<view>¥</view>
|
||||||
|
<view>{{ allPrice }}</view>
|
||||||
|
</view>
|
||||||
|
<my-button shape="circle" height="80" width="220" @tap="toConfimOrder">
|
||||||
|
<text class="u-font-32 font-bold">{{
|
||||||
|
table.type == "add" ? "确认加菜" : "去下单"
|
||||||
|
}}</text>
|
||||||
|
</my-button>
|
||||||
|
</view>
|
||||||
|
<up-modal
|
||||||
|
title="提示"
|
||||||
|
:content="modal.title"
|
||||||
|
:show="modal.clear"
|
||||||
|
showCancelButton
|
||||||
|
closeOnClickOverlay
|
||||||
|
@confirm="confirmModelConfirm"
|
||||||
|
@cancel="setModalShow('clear', false)"
|
||||||
|
@close="setModalShow('clear', false)"
|
||||||
|
width="300px"
|
||||||
|
></up-modal>
|
||||||
|
</view>
|
||||||
</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) *
|
||||||
}, 0);
|
cur.number;
|
||||||
let historyOrderPrice = allHistoryOrder.value.reduce((prve, cur) => {
|
return BigNumber(prve).plus(price);
|
||||||
let price = Math.floor(cur.price * (cur.num - cur.returnNum) * 100) / 100;
|
}, 0);
|
||||||
return prve + price;
|
let historyOrderPrice = allHistoryOrder.value.reduce((prve, cur) => {
|
||||||
}, 0);
|
let price =
|
||||||
|
(cur.isTimeDiscount
|
||||||
return (cartPrice + historyOrderPrice).toFixed(2);
|
? returnLimitPrice({ ...cur, salePrice: cur.price })
|
||||||
|
: cur.price) *
|
||||||
|
(cur.num - cur.returnNum);
|
||||||
|
return BigNumber(prve).plus(price);
|
||||||
|
}, 0);
|
||||||
|
return BigNumber(cartPrice)
|
||||||
|
.plus(historyOrderPrice)
|
||||||
|
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||||
|
.toNumber();
|
||||||
});
|
});
|
||||||
|
|
||||||
const goodsNumber = computed(() => {
|
const goodsNumber = computed(() => {
|
||||||
let result = 0;
|
let result = 0;
|
||||||
let cart = props.data.reduce((prve, cur) => {
|
let cart = props.data.reduce((prve, cur) => {
|
||||||
return prve + cur.number;
|
return prve + cur.number;
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
// let historyOrderNum = allHistoryOrder.value.reduce((prve, cur) => {
|
// let historyOrderNum = allHistoryOrder.value.reduce((prve, cur) => {
|
||||||
// return prve + cur.num;
|
// return prve + cur.num;
|
||||||
// }, 0);
|
// }, 0);
|
||||||
result = cart;
|
result = cart;
|
||||||
result = result > 0 ? result.toFixed(2) : 0;
|
result = result > 0 ? result.toFixed(2) : 0;
|
||||||
return result >= 99 ? 99 : parseFloat(result);
|
return result >= 99 ? 99 : parseFloat(result);
|
||||||
});
|
});
|
||||||
watch(
|
watch(
|
||||||
() => props.historyOrder,
|
() => props.historyOrder,
|
||||||
(newval) => {
|
(newval) => {
|
||||||
allHistoryOrder.value = [];
|
allHistoryOrder.value = [];
|
||||||
newval.forEach((item) => {
|
newval.forEach((item) => {
|
||||||
allHistoryOrder.value = [...allHistoryOrder.value, ...item.info];
|
allHistoryOrder.value = [...allHistoryOrder.value, ...item.info];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
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('购物车是空的!')
|
||||||
// }
|
// }
|
||||||
if (title) {
|
if (title) {
|
||||||
modal.title = title;
|
modal.title = title;
|
||||||
}
|
}
|
||||||
if (type) {
|
if (type) {
|
||||||
modal.type = type;
|
modal.type = type;
|
||||||
}
|
}
|
||||||
modal.key = key;
|
modal.key = key;
|
||||||
modal[key] = show;
|
modal[key] = show;
|
||||||
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);
|
||||||
|
|
||||||
function hideGoods() {
|
function hideGoods() {
|
||||||
switchGoods.value = false;
|
switchGoods.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showGoods() {
|
function showGoods() {
|
||||||
switchGoods.value = true;
|
switchGoods.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleGoods() {
|
function toggleGoods() {
|
||||||
switchGoods.value = !switchGoods.value;
|
switchGoods.value = !switchGoods.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
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>
|
||||||
|
|
||||||
|
|
@ -288,104 +405,108 @@ $car-size: 96rpx;
|
||||||
$car-top: -16rpx;
|
$car-top: -16rpx;
|
||||||
|
|
||||||
@mixin fixedAll {
|
@mixin fixedAll {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.total {
|
.total {
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 40rpx;
|
width: 40rpx;
|
||||||
height: 40rpx;
|
height: 40rpx;
|
||||||
}
|
}
|
||||||
.grayscale {
|
.grayscale {
|
||||||
filter: opacity(60%);
|
filter: opacity(60%);
|
||||||
}
|
}
|
||||||
.mask {
|
.mask {
|
||||||
@include fixedAll;
|
@include fixedAll;
|
||||||
background: rgba(51, 51, 51, 0.5);
|
background: rgba(51, 51, 51, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods {
|
.goods {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 100%;
|
bottom: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
transition: all 0.2s ease-in-out;
|
transition: all 0.2s ease-in-out;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
padding: 32rpx 28rpx;
|
padding: 32rpx 28rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-bottom {
|
.border-bottom {
|
||||||
border-bottom: 1px solid #e5e5e5;
|
border-bottom: 1px solid #e5e5e5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-top {
|
.border-top {
|
||||||
border-top: 1px solid #e5e5e5;
|
border-top: 1px solid #e5e5e5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.red {
|
.red {
|
||||||
color: #eb4f4f;
|
color: #eb4f4f;
|
||||||
}
|
}
|
||||||
|
|
||||||
.car {
|
.car {
|
||||||
padding: 0 28rpx;
|
padding: 0 28rpx;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
padding-top: 10rpx;
|
padding-top: 10rpx;
|
||||||
padding-bottom: calc(40rpx + env(safe-area-inset-bottom));
|
padding-bottom: calc(40rpx + env(safe-area-inset-bottom));
|
||||||
/* #ifdef H5 */
|
/* #ifdef H5 */
|
||||||
padding-bottom: 68rpx;
|
padding-bottom: 68rpx;
|
||||||
|
|
||||||
/* #endif */
|
/* #endif */
|
||||||
.icon-car-box {
|
.icon-car-box {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 28rpx;
|
left: 28rpx;
|
||||||
top: $car-top;
|
top: $car-top;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: $car-size;
|
width: $car-size;
|
||||||
height: $car-size;
|
height: $car-size;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
.dot {
|
.dot {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 28rpx;
|
width: 28rpx;
|
||||||
height: 28rpx;
|
height: 28rpx;
|
||||||
background: #eb4f4f;
|
background: #eb4f4f;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 20rpx;
|
font-size: 20rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.price {
|
.price {
|
||||||
color: #eb4f4f;
|
color: #eb4f4f;
|
||||||
margin-left: calc(38rpx + $car-size);
|
margin-left: calc(38rpx + $car-size);
|
||||||
transform: translateY(calc($car-top / 2));
|
transform: translateY(calc($car-top / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-car {
|
.icon-car {
|
||||||
width: $car-size;
|
width: $car-size;
|
||||||
height: $car-size;
|
height: $car-size;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
.old-price {
|
||||||
|
color: #999;
|
||||||
|
text-decoration: line-through;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,233 +1,299 @@
|
||||||
<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
|
||||||
<view class="u-m-b-40" v-for="(item,index) in skus" :key="index">
|
scroll-y="true"
|
||||||
<view class="u-text-left">
|
style="height: 50vh"
|
||||||
<view class="color-333 up-line-1" >{{item.name}}</view>
|
class="u-p-30 guigeModel"
|
||||||
</view>
|
>
|
||||||
<view class="u-flex u-m-t-20 u-flex-wrap">
|
<view class="u-m-b-40" v-for="(item, index) in skus" :key="index">
|
||||||
<view class="item" @tap="chooseSkd(index,skd)"
|
<view class="u-text-left">
|
||||||
:class="{active:item.sel===skd.name,disabled:skd.disabled}"
|
<view class="color-333 up-line-1">{{ item.name }}</view>
|
||||||
v-for="(skd,skdIndex) in item.values" :key="skdIndex">
|
</view>
|
||||||
{{skd.name}}
|
<view class="u-flex u-m-t-20 u-flex-wrap">
|
||||||
</view>
|
<view
|
||||||
</view>
|
class="item"
|
||||||
</view>
|
@tap="chooseSkd(index, skd)"
|
||||||
</scroll-view>
|
:class="{ active: item.sel === skd.name, disabled: skd.disabled }"
|
||||||
</template>
|
v-for="(skd, skdIndex) in item.values"
|
||||||
<template #btn>
|
:key="skdIndex"
|
||||||
<view class="u-p-30 border-top ">
|
>
|
||||||
<view class="u-flex u-p-b-30 u-row-between">
|
{{ skd.name }}
|
||||||
<view class="price">
|
</view>
|
||||||
<template v-if="goods&&goods.isGrounding">
|
</view>
|
||||||
<text>¥</text>
|
</view>
|
||||||
<text>{{to2(goods.salePrice*number) }}</text>
|
</scroll-view>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
<template #btn>
|
||||||
<view class="u-flex">
|
<view class="u-p-30 border-top">
|
||||||
<view class="u-flex" @tap="reduce">
|
<view class="u-flex u-p-b-30 u-row-between">
|
||||||
<image src="/pagesCreateOrder/static/images/icon-reduce-black.svg" class="icon" mode="">
|
<view class="price">
|
||||||
</image>
|
<template v-if="goods && goods.isGrounding">
|
||||||
</view>
|
<text v-if="is_time_discount"
|
||||||
<view class="u-m-l-30 u-m-r-30 color-333">
|
>¥{{ returnLimitPrice() }}</text
|
||||||
{{number}}
|
>
|
||||||
</view>
|
<text :class="{ oldPrice: is_time_discount }"
|
||||||
<view class="u-flex" @tap="add">
|
>¥{{ goods.salePrice }}</text
|
||||||
<image src="/pagesCreateOrder/static/images/icon-add-black.svg" class="icon" mode="">
|
>
|
||||||
</image>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<view class="u-flex">
|
||||||
</view>
|
<view class="u-flex" @tap="reduce">
|
||||||
<view class="u-m-t-10">
|
<image
|
||||||
<my-button @tap="close" type="cancel" v-if="isDisabled">
|
src="/pagesCreateOrder/static/images/icon-reduce-black.svg"
|
||||||
<view class="color-999">已下架/售罄</view>
|
class="icon"
|
||||||
</my-button>
|
mode=""
|
||||||
<my-button @tap="confirm" v-else>添加</my-button>
|
>
|
||||||
</view>
|
</image>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
<view class="u-m-l-30 u-m-r-30 color-333">
|
||||||
</my-model>
|
{{ number }}
|
||||||
|
</view>
|
||||||
|
<view class="u-flex" @tap="add">
|
||||||
|
<image
|
||||||
|
src="/pagesCreateOrder/static/images/icon-add-black.svg"
|
||||||
|
class="icon"
|
||||||
|
mode=""
|
||||||
|
>
|
||||||
|
</image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="u-m-t-10">
|
||||||
|
<my-button @tap="close" type="cancel" v-if="isDisabled">
|
||||||
|
<view class="color-999">已下架/售罄</view>
|
||||||
|
</my-button>
|
||||||
|
<my-button @tap="confirm" v-else>添加</my-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</my-model>
|
||||||
</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";
|
||||||
const props = defineProps({
|
import BigNumber from "bignumber.js";
|
||||||
goodsData: {
|
const yskUtils = inject("yskUtils");
|
||||||
type: Object,
|
const shopInfo = uni.getStorageSync("shopInfo");
|
||||||
default: () => {}
|
const shopUserInfo = uni.getStorageSync("shopUserInfo");
|
||||||
},
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
skuMap: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
skus: {
|
|
||||||
type: Array,
|
|
||||||
default: () => {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
})
|
|
||||||
const emits = defineEmits(['confirm', 'updateSku'])
|
|
||||||
const model = ref(null)
|
|
||||||
let number = ref(1)
|
|
||||||
function to2(number) {
|
|
||||||
return Number(number).toFixed(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
const selSku = computed(() => {
|
const props = defineProps({
|
||||||
return props.skus.reduce((prve, cur) => {
|
goodsData: {
|
||||||
prve.push(cur.sel)
|
type: Object,
|
||||||
return prve
|
default: () => {},
|
||||||
}, []).join()
|
},
|
||||||
})
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
skuMap: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
skus: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
limitTimeDiscount: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const emits = defineEmits(["confirm", "updateSku"]);
|
||||||
|
const model = ref(null);
|
||||||
|
let number = ref(1);
|
||||||
|
function to2(number) {
|
||||||
|
return Number(number).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
const goods = computed(() => {
|
const selSku = computed(() => {
|
||||||
return props.skuMap[selSku.value]
|
return props.skus
|
||||||
})
|
.reduce((prve, cur) => {
|
||||||
watch(() => goods.value, (newval) => {
|
prve.push(cur.sel);
|
||||||
number.value = newval.suitNum || 1
|
return prve;
|
||||||
})
|
}, [])
|
||||||
|
.join();
|
||||||
|
});
|
||||||
|
|
||||||
const isCanBuy = computed(() => {
|
const goods = computed(() => {
|
||||||
if (!goods.value) {
|
return props.skuMap[selSku.value];
|
||||||
return false
|
});
|
||||||
}
|
watch(
|
||||||
return util.isCanBuy(
|
() => goods.value,
|
||||||
goods.value,
|
(newval) => {
|
||||||
props.goodsData
|
number.value = newval.suitNum || 1;
|
||||||
)
|
}
|
||||||
|
);
|
||||||
|
|
||||||
})
|
const isCanBuy = computed(() => {
|
||||||
|
if (!goods.value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return util.isCanBuy(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);
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 规格选择
|
* 规格选择
|
||||||
* @param {Object} skusIndex
|
* @param {Object} skusIndex
|
||||||
* @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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 禁止操作
|
* 禁止操作
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数量增加
|
* 数量增加
|
||||||
*/
|
*/
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
open,
|
const is_time_discount = computed(() => {
|
||||||
close
|
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({
|
||||||
|
open,
|
||||||
|
close,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.border-top {}
|
.border-top {
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 40rpx;
|
width: 40rpx;
|
||||||
height: 40rpx;
|
height: 40rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.guigeModel {
|
.guigeModel {
|
||||||
.item {
|
.item {
|
||||||
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;
|
||||||
color: $my-main-color;
|
color: $my-main-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
border-color: #eee;
|
border-color: #eee;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.price {
|
.price {
|
||||||
color: #EB4F4F;
|
color: #eb4f4f;
|
||||||
}
|
}
|
||||||
|
.oldPrice {
|
||||||
.border-top {
|
color: #999;
|
||||||
border-top: 1px solid #E5E5E5;
|
text-decoration: line-through;
|
||||||
}
|
}
|
||||||
|
.border-top {
|
||||||
|
border-top: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -1,232 +1,345 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="u-relative u-flex item">
|
<view class="u-relative u-flex item">
|
||||||
|
<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="limit-discount" v-if="is_time_discount">限时折扣</view>
|
||||||
|
|
||||||
<up-image :src="data.coverImg" mode="aspectFill" :width="img.width" :height="img.height"></up-image>
|
<view>
|
||||||
<view class="info u-flex u-row-between u-col-top u-flex-col" >
|
<view>
|
||||||
<view >
|
<text class="up-line-1">{{ data.name }}</text>
|
||||||
<view >
|
</view>
|
||||||
<text class="up-line-1">{{data.name}}</text>
|
<view>
|
||||||
</view>
|
<text class="u-font-32 font-bold u-m-t-16" v-if="is_time_discount"> ¥{{ limitPrice }} </text>
|
||||||
<view class="u-font-32 font-bold u-m-t-16">
|
<text
|
||||||
¥{{data.lowPrice}}
|
class="u-font-32 font-bold u-m-t-16"
|
||||||
</view>
|
:class="[is_time_discount ? 'line-through' : '']"
|
||||||
<template v-if="data.type=='weight'">
|
>
|
||||||
<view class="btnweigh">称重</view>
|
¥{{ data.lowPrice }}
|
||||||
</template>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="u-flex" v-if="!isSellout">
|
|
||||||
<template v-if="data.type == 'sku'||data.groupType==1">
|
|
||||||
<button class="btn" hover-class="btn-hover-class" @tap="emitEvent('chooseGuige')">选规格</button>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<view class="u-flex icon-btn">
|
|
||||||
<view class="u-flex" @tap.stop="emitEvent(data.type=='weight'?'tapweigh':'add')">
|
|
||||||
<image src="/pagesCreateOrder/static/images/icon-add.svg" class="icon" mode=""></image>
|
|
||||||
</view>
|
|
||||||
<template v-if="data.chooseNumber">
|
|
||||||
<view class="u-font-32">
|
|
||||||
{{(data.chooseNumber).toFixed(2)}}
|
|
||||||
</view>
|
|
||||||
<view class="u-flex" @tap.stop="emitEvent('reduce')">
|
|
||||||
<image src="/pagesCreateOrder/static/images/icon-reduce.svg" class="icon" mode="">
|
|
||||||
</image>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
|
<template v-if="data.type == 'weight'">
|
||||||
</view>
|
<view class="btnweigh">称重</view>
|
||||||
<template v-if="isSellout">
|
</template>
|
||||||
<view class="isSellout" v-if="data.isSale == 0" >
|
</view>
|
||||||
<image class="isSellout_icon" src="/pagesCreateOrder/static/images/no-toDown.svg" mode=""></image>
|
<view class="u-flex" v-if="!isSellout">
|
||||||
</view>
|
<template v-if="data.type == 'sku' || data.groupType == 1">
|
||||||
<view class="isSellout" v-else-if="!isProductAvailable(data.days,data.startTime,data.endTime)" >
|
<button
|
||||||
<image class="isSellout_icon" src="/pagesCreateOrder/static/images/no-saleTime.svg" mode=""></image>
|
class="btn"
|
||||||
</view>
|
hover-class="btn-hover-class"
|
||||||
<view class="isSellout" v-else-if="data.isSoldStock == 1" >
|
@tap="emitEvent('chooseGuige')"
|
||||||
<image class="isSellout_icon" src="/pagesCreateOrder/static/images/no-sold.svg" mode=""></image>
|
>
|
||||||
</view>
|
选规格
|
||||||
<view class="isSellout" v-else-if="data.isStock == 1 && data.stockNumber <= 0" >
|
</button>
|
||||||
<image class="isSellout_icon" src="/pagesCreateOrder/static/images/no-stock.svg" mode=""></image>
|
</template>
|
||||||
</view>
|
<template v-else>
|
||||||
</template>
|
<view class="u-flex icon-btn">
|
||||||
</view>
|
<view
|
||||||
</view>
|
class="u-flex"
|
||||||
|
@tap.stop="emitEvent(data.type == 'weight' ? 'tapweigh' : 'add')"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
src="/pagesCreateOrder/static/images/icon-add.svg"
|
||||||
|
class="icon"
|
||||||
|
mode=""
|
||||||
|
></image>
|
||||||
|
</view>
|
||||||
|
<template v-if="data.chooseNumber">
|
||||||
|
<view class="u-font-32">
|
||||||
|
{{ data.chooseNumber.toFixed(2) }}
|
||||||
|
</view>
|
||||||
|
<view class="u-flex" @tap.stop="emitEvent('reduce')">
|
||||||
|
<image
|
||||||
|
src="/pagesCreateOrder/static/images/icon-reduce.svg"
|
||||||
|
class="icon"
|
||||||
|
mode=""
|
||||||
|
>
|
||||||
|
</image>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
<template v-if="isSellout">
|
||||||
|
<view class="isSellout" v-if="data.isSale == 0">
|
||||||
|
<image
|
||||||
|
class="isSellout_icon"
|
||||||
|
src="/pagesCreateOrder/static/images/no-toDown.svg"
|
||||||
|
mode=""
|
||||||
|
></image>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
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 class="isSellout" v-else-if="data.isSoldStock == 1">
|
||||||
|
<image
|
||||||
|
class="isSellout_icon"
|
||||||
|
src="/pagesCreateOrder/static/images/no-sold.svg"
|
||||||
|
mode=""
|
||||||
|
></image>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
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>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</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");
|
||||||
const props = defineProps({
|
dayjs.extend(isBetween);
|
||||||
img: {
|
|
||||||
type: Object,
|
|
||||||
default: {
|
|
||||||
width: '250rpx',
|
|
||||||
height: '272rpx'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
index: {
|
|
||||||
type: [Number, String],
|
|
||||||
},
|
|
||||||
isSeatFee: {
|
|
||||||
//是否为餐位费
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return {
|
|
||||||
chooseNumber: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
const props = defineProps({
|
||||||
* 判断是否是菜品
|
img: {
|
||||||
*/
|
type: Object,
|
||||||
function isGoods() {
|
default: {
|
||||||
return props.data.hasOwnProperty('id')
|
width: "250rpx",
|
||||||
}
|
height: "272rpx",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
index: {
|
||||||
|
type: [Number, String],
|
||||||
|
},
|
||||||
|
isSeatFee: {
|
||||||
|
//是否为餐位费
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
chooseNumber: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
limitTimeDiscount: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
//判断是否是时间折扣商品
|
||||||
* 判断商品是否售尽
|
const is_time_discount = computed(() => {
|
||||||
*/
|
if (!props.limitTimeDiscount || !props.limitTimeDiscount.id) {
|
||||||
const isSellout = computed(() => {
|
return false;
|
||||||
const item = props.data
|
}
|
||||||
if (!isGoods()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
(item.isStock == 1 && item.stockNumber <= 0) || item.isSoldStock == 1 || item.isSale == 0 || !isProductAvailable(item.days,item.startTime,item.endTime)
|
|
||||||
);
|
|
||||||
})
|
|
||||||
// 判断商品是否在可售时间内
|
|
||||||
function isProductAvailable(sellDaysStr, startTimeStr, endTimeStr) {
|
|
||||||
// 将后端返回的字符串转换为数组
|
|
||||||
const sellDays = sellDaysStr.split(',');
|
|
||||||
const now = dayjs();
|
|
||||||
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
||||||
const currentDay = days[now.day()];
|
|
||||||
const currentTime = now.format('HH:mm:ss');
|
|
||||||
|
|
||||||
// console.log('当前日期:', currentDay);
|
|
||||||
// console.log('可售日期列表:', sellDays);
|
|
||||||
// 检查当前周几是否在可售周几列表中
|
|
||||||
if (!sellDays.includes(currentDay)) {
|
|
||||||
// console.log('当前日期不在可售日期列表中');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const startTime = dayjs(`${now.format('YYYY-MM-DD')} ${startTimeStr}`);
|
|
||||||
let endTime = dayjs(`${now.format('YYYY-MM-DD')} ${endTimeStr}`);
|
|
||||||
// 处理跨天情况
|
|
||||||
if (endTime.isBefore(startTime)) {
|
|
||||||
endTime = endTime.add(1, 'day');
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log('当前时间:', now.format('YYYY-MM-DD HH:mm:ss'));
|
|
||||||
// console.log('开始时间:', startTime.format('YYYY-MM-DD HH:mm:ss'));
|
|
||||||
// console.log('结束时间:', endTime.format('YYYY-MM-DD HH:mm:ss'));
|
|
||||||
|
|
||||||
const isInRange = now.isBetween(startTime, endTime, null, '[)');
|
const isCanuse = yskUtils.limitUtils.canUseLimitTimeDiscount(
|
||||||
// console.log('当前时间是否在可售时间范围内:', isInRange);
|
props.data,
|
||||||
|
props.limitTimeDiscount,
|
||||||
|
shopInfo,
|
||||||
|
null,
|
||||||
|
"id"
|
||||||
|
);
|
||||||
|
return isCanuse;
|
||||||
|
});
|
||||||
|
|
||||||
return isInRange;
|
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() {
|
||||||
|
return props.data.hasOwnProperty("id");
|
||||||
|
}
|
||||||
|
|
||||||
const emits = defineEmits(['add', 'reduce', 'chooseGuige','tapweigh'])
|
/**
|
||||||
|
* 判断商品是否售尽
|
||||||
|
*/
|
||||||
|
const isSellout = computed(() => {
|
||||||
|
const item = props.data;
|
||||||
|
if (!isGoods()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
(item.isStock == 1 && item.stockNumber <= 0) ||
|
||||||
|
item.isSoldStock == 1 ||
|
||||||
|
item.isSale == 0 ||
|
||||||
|
!isProductAvailable(item.days, item.startTime, item.endTime)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
// 判断商品是否在可售时间内
|
||||||
|
function isProductAvailable(sellDaysStr, startTimeStr, endTimeStr) {
|
||||||
|
// 将后端返回的字符串转换为数组
|
||||||
|
const sellDays = sellDaysStr.split(",");
|
||||||
|
const now = dayjs();
|
||||||
|
const days = [
|
||||||
|
"Sunday",
|
||||||
|
"Monday",
|
||||||
|
"Tuesday",
|
||||||
|
"Wednesday",
|
||||||
|
"Thursday",
|
||||||
|
"Friday",
|
||||||
|
"Saturday",
|
||||||
|
];
|
||||||
|
const currentDay = days[now.day()];
|
||||||
|
const currentTime = now.format("HH:mm:ss"); // 检查当前周几是否在可售周几列表中
|
||||||
|
|
||||||
function emitEvent(emitName) {
|
// console.log('当前日期:', currentDay);
|
||||||
if (isGoods()) {
|
// console.log('可售日期列表:', sellDays);
|
||||||
emits(emitName, props.index)
|
if (!sellDays.includes(currentDay)) {
|
||||||
}
|
// console.log('当前日期不在可售日期列表中');
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
const startTime = dayjs(`${now.format("YYYY-MM-DD")} ${startTimeStr}`);
|
||||||
|
let endTime = dayjs(`${now.format("YYYY-MM-DD")} ${endTimeStr}`);
|
||||||
|
// 处理跨天情况
|
||||||
|
if (endTime.isBefore(startTime)) {
|
||||||
|
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'));
|
||||||
|
const isInRange = now.isBetween(startTime, endTime, null, "[)"); // console.log('当前时间是否在可售时间范围内:', isInRange);
|
||||||
|
return isInRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
const emits = defineEmits(["add", "reduce", "chooseGuige", "tapweigh"]);
|
||||||
|
|
||||||
|
function emitEvent(emitName) {
|
||||||
|
if (isGoods()) {
|
||||||
|
emits(emitName, props.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.icon {
|
.icon {
|
||||||
width: 48rpx;
|
width: 48rpx;
|
||||||
height: 48rpx;
|
height: 48rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-btn {
|
.icon-btn {
|
||||||
gap: 14rpx;
|
gap: 14rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
background: #EB4F4F;
|
background: #eb4f4f;
|
||||||
border-radius: 100rpx;
|
border-radius: 100rpx;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
height: 56rpx;
|
height: 56rpx;
|
||||||
line-height: 56rpx;
|
line-height: 56rpx;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btnweigh {
|
.btnweigh {
|
||||||
margin: 5rpx 0;
|
margin: 5rpx 0;
|
||||||
width: 100rpx;
|
width: 100rpx;
|
||||||
background: linear-gradient(124deg, #73c969 6%, #27921b 93%);
|
background: linear-gradient(124deg, #73c969 6%, #27921b 93%);
|
||||||
border-radius: 10rpx;
|
border-radius: 10rpx;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
padding: 6rpx 0;
|
padding: 6rpx 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.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;
|
||||||
|
|
||||||
.img {
|
.img {
|
||||||
width: 250rpx;
|
width: 250rpx;
|
||||||
height: 272rpx;
|
height: 272rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
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;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.isSellout{
|
.isSellout {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
background-color: rgba(0, 0, 0, 0.6);
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.isSellout_icon{
|
.isSellout_icon {
|
||||||
height: 60%;
|
height: 60%;
|
||||||
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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue