diff --git a/common/api/order/gbOrder.js b/common/api/order/gbOrder.js new file mode 100644 index 0000000..16f2edc --- /dev/null +++ b/common/api/order/gbOrder.js @@ -0,0 +1,80 @@ +// 引入 request 文件 +import request from '@/common/api/request.js' +const url = '/order' + +let platformType = ''; +let payType=''; +// #ifdef MP-WEIXIN +platformType = 'wechat' +payType='wechatPay' +// #endif +// #ifdef MP-ALIPAY +platformType = 'alipay' +payType='aliPay' +// #endif + +export const warePage = (data) => { + return request({ + url: url + '/user/gbOrder/ware/page', + method: 'get', + data: data + }) +} + +export const wareDetail = (data) => { + return request({ + url: url + '/user/gbOrder/ware/detail', + method: 'get', + data: data + }) +} +export const record = (data) => { + return request({ + url: url + '/user/gbOrder/record/page', + method: 'get', + data: data + }) +} +export const recordDetail = (data) => { + return request({ + url: url + '/user/gbOrder/record/detail', + method: 'get', + data: data + }) +} + + + + +export const exchange = (data) => { + // #ifdef MP-WEIXIN + const openId=uni.cache.get('userInfo').wechatOpenId; + // #endif + // #ifdef MP-ALIPAY + const openId=uni.cache.get('userInfo').alipayOpenId; + // #endif + return request({ + url: url + '/user/gbOrder/exchange', + method: 'post', + data: { + platformType, + payType, + openId, + ...data + } + }) +} +export const applyRefund = (data) => { + return request({ + url: url + '/user/gbOrder/applyRefund', + method: 'post', + data: data + }) +} +export const cancelRefund = (data) => { + return request({ + url: url + '/user/gbOrder/cancelRefund', + method: 'post', + data: data + }) +} \ No newline at end of file diff --git a/groupBuying/components/modal.vue b/groupBuying/components/modal.vue new file mode 100644 index 0000000..5d90202 --- /dev/null +++ b/groupBuying/components/modal.vue @@ -0,0 +1,97 @@ + + + + diff --git a/groupBuying/components/status.vue b/groupBuying/components/status.vue new file mode 100644 index 0000000..8ce3dfd --- /dev/null +++ b/groupBuying/components/status.vue @@ -0,0 +1,61 @@ + + + + + \ No newline at end of file diff --git a/groupBuying/detail/index.vue b/groupBuying/detail/index.vue index a881b51..393f30f 100644 --- a/groupBuying/detail/index.vue +++ b/groupBuying/detail/index.vue @@ -1,59 +1,261 @@ @@ -69,243 +271,217 @@ font-weight: 700; } - .map { - width: 48rpx; - height: 48rpx; - } + } - .steps { - display: flex; - padding: 20rpx 20rpx; - gap: 20rpx; - border-radius: 14rpx 14rpx 0 0; - background: linear-gradient(90deg, #FFF5E6 0%, #FFD2CA 100%); + .bottom { + margin: 0 28rpx; + transform: translateY(-160rpx); - .step { + .time { + padding: 18rpx 24rpx; + background: #FFF4E2; display: flex; - } + align-items: center; + border-radius: 16rpx 16rpx 0 0; - .index { - border-radius: 60rpx; - color: #fff; - width: 44rpx; - height: 44rpx; - line-height: 44rpx; - text-align: center; - background: #E55626; - } - - .text { - color: #5A352F; - margin-left: 10rpx; - margin-right: 22rpx; - white-space: nowrap; - } - - .icon { - color: rgba(90, 53, 47, 0.42); - } - - .icon1 { - color: #5A352F; - } - } - - .lists { - padding: 18rpx 10rpx; - - .item { - display: flex; - padding: 32rpx 16rpx; - border-radius: 32rpx; - background: #FFF; - margin-bottom: 14rpx; - - .numbers { - background: #4C2828; - padding: 8rpx 18rpx; - border-radius: 10rpx; - font-weight: 700; - color: #FAEAC6; - white-space: nowrap; - } - - .name { - max-width: 334rpx; - } - - .members { - margin-top: 26rpx; - background: #FDF1CB; - padding: 4rpx 18rpx; - border-radius: 10rpx 10rpx 10rpx 0; - width: fit-content; - font-size: 24rpx; - font-weight: 700; - color: #ED5A2E; - } - - .info { - background-image: url(https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/604c3f917daa41af9239145196c6d3f3.png); - width: 410rpx; - height: 102rpx; - background-size: cover; - transform: translateY(-10rpx); - display: flex; - - .left { - width: 306rpx; - color: #fff; - padding: 16rpx 22rpx; - } - - .right { - padding-left: 16rpx; - margin-top: 30rpx; - - .pin { - width: 76rpx; - height: 54rpx; - } - } - } - } - } - - .filters { - padding: 16rpx 28rpx; - border-radius: 6rpx 6rpx 16rpx 16rpx; - background: #FFF; - } - - .tabs { - display: flex; - justify-content: space-between; - font-size: 24rpx; - color: #999; - padding: 32rpx 88rpx; - - .tabs { - transition: all .3s linear; - } - - .active { - color: #ED5A2E; - font-size: 32rpx; - font-weight: 700; - font-weight: 700; - } - } - - .translateY20 { - transform: translateY(-20rpx); - } - - .orderStatus { - padding: 26rpx 28rpx; - justify-content: space-between; - - .orderState { - color: #999; - transition: all .3s linear; - - &.active { - color: #000; - font-size: 32rpx; - font-weight: 700; - } - } - } - - .orders { - padding: 0 26rpx 36rpx; - - .item { - padding: 32rpx 24rpx; - border-radius: 16rpx; - background: #FFF; - margin-bottom: 32rpx; - - .numbers { - background-color: #ED5A2E; - padding: 16rpx 30rpx; - border-radius: 12rpx; - font-size: 32rpx; + .number { + padding: 6rpx; + border-radius: 16rpx; + background: #ED5A2E; color: #fff; - font-weight: 700; - line-height: 36rpx; + font-size: 32rpx; + margin-left: 18rpx; + margin-right: 18rpx; } - .status { - padding: 8rpx 18rpx; - border-radius: 8rpx; - border: 2rpx solid transparent; + .gap { + font-size: 32rpx; + } + } - &.success { - border-color: rgba(123, 209, 54, 1); - color: rgba(123, 209, 54, 1); - background: rgba(123, 209, 54, 0.12); - } + .goods { + background-color: #fff; + padding: 22rpx 24rpx 0; + border-radius: 0 0 16rpx 16rpx; - &.error { - border-color: #FF1C1C; - color: #FF1C1C; - background: rgba(255, 28, 28, 0.18); - } + .pin { + width: 60rpx; + height: 38rpx; + } + + .tuan-members { + padding: 0 16rpx 0 0; + border-radius: 0 6rpx 6rpx 0; + background: #4C2828; + color: #f5d9ad; + font-weight: 700; } .price { - color: #ED5A2E; - font-weight: 700; - line-height: 36rpx; - font-size: 40rpx; + color: #ed5a2e; } - .info { - padding: 16rpx 34rpx; - flex-direction: column; - align-items: flex-start; - border-radius: 8rpx; - background: #F8F8F8; - - .title { - min-width: 208rpx; - padding-right: 8rpx; - box-sizing: border-box; - } - - .stitle { - color: #666; - - &.price { - font-size: 32rpx; - color: #ed5a2e; - font-weight: 700; - } - } - + .old-price { + color: #666666; } + } - .btns { - margin-top: 28rpx; + .u-font-48 { + font-size: 48rpx; + } + + .shop-box { + background: #fff; + padding: 32rpx 30rpx 28rpx 30rpx; + border-radius: 0 0 16rpx 16rpx; + } + + .copy { + width: 22rpx; + height: 22rpx; + margin-left: 22rpx; + } + + .shop { + border-radius: 8rpx; + background: #F8F8F8; + padding: 16rpx 34rpx; + } + + .relative { + position: relative; + } + + .members { + padding: 26rpx 24rpx; + border-radius: 16rpx; + margin-top: 32rpx; + background-color: #fff; + + .list { display: flex; - justify-content: flex-end; - gap: 34rpx; + } - .btn { - padding: 8rpx 14rpx; - border-radius: 10rpx; - border: 2rpx solid #D9D9D9; - background: #FFF; + .item { + width: calc(100% / 3); + display: flex; - &.black { - border-color: #343030; - background-color: #343030; - color: #fff; + .add-box { + width: 140rpx; + height: 140rpx; + border: 2rpx dashed #D9D9D9; + border-radius: 50%; + overflow: hidden; + position: relative; + + .share { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + opacity: 0; } } + + &:nth-of-type(2n) { + justify-content: center; + } + + &:nth-of-type(3n) { + justify-content: flex-end; + } + + .box { + display: flex; + flex-direction: column; + } + + .absolute { + bottom: 0; + display: flex; + justify-content: center; + left: 0; + right: 0; + } + + .tuanzhang { + padding: 8rpx 18rpx; + border-radius: 20rpx; + background: #ED5A2E; + color: #fff; + bottom: 0; + } } } + + .order { + padding: 32rpx 28rpx; + border-radius: 16rpx; + margin-top: 32rpx; + background-color: #fff; + + .item { + padding: 16rpx 0; + } + } + } + + .btns { + position: fixed; + left: 87rpx; + right: 87rpx; + bottom: 0; + padding-bottom: 60rpx; + display: flex; + gap: 40rpx; + + .btn { + flex: 1; + padding: 16rpx 28rpx; + border-radius: 200rpx; + text-align: center; + font-size: 32rpx; + line-height: 1; + margin: 0; + justify-content: center; + border: 2rpx solid #E8AD7B; + background: #FFF; + color: #E8AD7B; + + &.main { + background-color: #E8AD7B; + color: #fff; + } + } + } + + .guodu { + transition: all .3s; + } + + .pin-btn { + padding: 14rpx 60rpx; + border-radius: 200rpx; + text-align: center; + font-size: 32rpx; + justify-content: center; + border: 2rpx solid #E8AD7B; + background: #E8AD7B; + color: #fff; + margin-top: 32rpx; + } + + .rotate { + transform: rotate(-90deg); + } + + .refund { + padding: 18rpx 164rpx; + border-radius: 0 0 16rpx 16rpx; + background: #FFF4E2; + font-weight: 700; + margin-bottom: 32rpx; } \ No newline at end of file diff --git a/groupBuying/goodsDetail/goodsDetail.vue b/groupBuying/goodsDetail/goodsDetail.vue new file mode 100644 index 0000000..70a13b6 --- /dev/null +++ b/groupBuying/goodsDetail/goodsDetail.vue @@ -0,0 +1,646 @@ + + + + \ No newline at end of file diff --git a/groupBuying/index/components/perpole-number.vue b/groupBuying/index/components/perpole-number.vue new file mode 100644 index 0000000..06511c0 --- /dev/null +++ b/groupBuying/index/components/perpole-number.vue @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/groupBuying/index/index.vue b/groupBuying/index/index.vue index ecad082..2959010 100644 --- a/groupBuying/index/index.vue +++ b/groupBuying/index/index.vue @@ -6,7 +6,7 @@ left-icon-color="#fff" title-color="#fff"> - 这里是店铺名称 + {{shopInfo.shopName||''}} @@ -30,8 +30,10 @@ @click="tabs.sel=index">{{item}} - - + + + - + - + - 3人团 - 这里是商品名称啊啊嗷嗷啊啊 + {{item.groupPeopleNum}}人团 + {{item.wareName}} 已团:9999 拼团到手 - ¥333 + ¥{{item.groupPrice}} 原价 - ¥333 + ¥{{item.originalPrice}} @@ -76,40 +78,41 @@ - + - 3人团 - 待成团 + {{1}}人团 + - + - 这里是商品名称 - ¥999.99 + {{item.wareJson.wareName}} + ¥{{item.payAmount}} - x1 + x{{item.num}} - - + + 可核销门店: - 这里是店铺名称 + {{item.shopName}} 门店地址: - 这里是店铺名称 + {{item.shopAddress}} - + 剩余成团时间: - 00:39:15 + {{returnTime(item)}} - - 申请退款 - 邀请好友 + + 申请退款 + 取消退款 + @@ -119,24 +122,40 @@ \ No newline at end of file diff --git a/groupBuying/static/image/copy.png b/groupBuying/static/image/copy.png new file mode 100644 index 0000000..4c09474 Binary files /dev/null and b/groupBuying/static/image/copy.png differ diff --git a/groupBuying/success/index.vue b/groupBuying/success/index.vue new file mode 100644 index 0000000..a65d478 --- /dev/null +++ b/groupBuying/success/index.vue @@ -0,0 +1,497 @@ + + + + + \ No newline at end of file diff --git a/pages.json b/pages.json index 11aed7a..c6aaa9b 100644 --- a/pages.json +++ b/pages.json @@ -376,6 +376,18 @@ "navigationBarTitleText": "订单详情", "navigationStyle": "custom" } + }, + { + "path": "goodsDetail/goodsDetail", + "style": { + "navigationBarTitleText": "拼团特惠" + } + }, + { + "path": "success/index", + "style": { + "navigationBarTitleText": "支付成功" + } } ] diff --git a/pages/index/indexs.vue b/pages/index/indexs.vue index 131b7fb..d78651d 100644 --- a/pages/index/indexs.vue +++ b/pages/index/indexs.vue @@ -50,7 +50,7 @@ - + 快乐拼单 @@ -139,6 +139,12 @@ const props = defineProps({ } }); +function toGroupBuying(){ + uni.navigateTo({ + url:'/groupBuying/index/index' + }) +} + function toFenxiao() { uni.navigateTo({ url: '/distribution/shop-detail/index?shopId=' + uni.cache.get('shopId') diff --git a/pages/product/index.vue b/pages/product/index.vue index 50796cb..dc6311b 100644 --- a/pages/product/index.vue +++ b/pages/product/index.vue @@ -2438,9 +2438,12 @@ }) const oldOrder = ref(null); onMounted(async () => { + // #ifdef MP-WEIXIN await proxy.$onLaunched; + // #endif // 获取当前页面栈 const pages = getCurrentPages(); + // 获取当前页面实例 const currentPage = pages[pages.length - 1]; // 获取页面参数 diff --git a/src/auto-imports.d.ts b/src/auto-imports.d.ts index dc5e282..e69ecf0 100644 --- a/src/auto-imports.d.ts +++ b/src/auto-imports.d.ts @@ -38,6 +38,7 @@ declare global { const onRenderTriggered: typeof import('vue')['onRenderTriggered'] const onScopeDispose: typeof import('vue')['onScopeDispose'] const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onShareAppMessage: typeof import('@dcloudio/uni-app')['onShareAppMessage'] const onShow: typeof import('@dcloudio/uni-app')['onShow'] const onUnload: typeof import('@dcloudio/uni-app')['onUnload'] const onUnmounted: typeof import('vue')['onUnmounted'] diff --git a/stores/user.js b/stores/user.js index 3d9f50e..2070508 100644 --- a/stores/user.js +++ b/stores/user.js @@ -179,6 +179,13 @@ export const productStore = defineStore("product", { */ async scanCodeactions(q) { console.log("扫码内容", q); + // #ifdef H5 + uni.navigateTo({ + url:'/pages/product/index' + }) + return + // #endif + return new Promise(async (resolve, reject) => { if (q) { console.log(q); @@ -218,7 +225,7 @@ export const productStore = defineStore("product", { } } } else { - // #ifdef APP || MP-WEIXIN || MP-ALIPAY + // #ifdef APP || MP-WEIXIN || MP-ALIPAY uni.scanCode({ success: async (res) => { let tableCode = this.getQueryString( diff --git a/utils/countdown.js b/utils/countdown.js new file mode 100644 index 0000000..fdc7d52 --- /dev/null +++ b/utils/countdown.js @@ -0,0 +1,51 @@ +import dayjs from "dayjs" + +/** + * 计算剩余时间差(毫秒) + * @param {Object} item - 包含groupEndTime的订单/拼团对象 + * @returns {number} 剩余时间(毫秒) + */ +function returnRemainingTime(item) { + if (!item?.groupEndTime) return 0; // 容错:无结束时间则返回0 + return dayjs(item.groupEndTime).valueOf() - dayjs().valueOf(); +} + +/** + * 将毫秒差格式化为 HH:MM:SS(最多72小时) + * @param {number} ms - 时间差(毫秒) + * @returns {string} 格式化后的时分秒(如 09:09:09、72:00:00、00:00:00) + */ +function formatTimeToHMS(ms) { + // 边界1:已过期/无剩余时间 → 显示00:00:00 + if (ms <= 0) return '00:00:00'; + + // 边界2:超过72小时 → 按72小时算(72*60*60*1000 = 259200000毫秒) + const maxMs = 72 * 60 * 60 * 1000; + const validMs = Math.min(ms, maxMs); + + // 转换为总秒数(取整,避免小数) + const totalSeconds = Math.floor(validMs / 1000); + + // 拆解小时、分钟、秒 + const hours = Math.floor(totalSeconds / 3600); + const remainingSeconds = totalSeconds % 3600; + const minutes = Math.floor(remainingSeconds / 60); + const seconds = remainingSeconds % 60; + + // 补零(确保两位数,如 9 → 09) + const pad = (num) => String(num).padStart(2, '0'); + return `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`; +} + + +let timer = null +let nowTime = ref(Date.now()) +timer = setInterval(() => { + nowTime.value = Date.now() +}, 1000) + +// 组合使用:获取格式化后的剩余时间 +export function getRemainingHMS(item) { + const ms = returnRemainingTime(item); + return formatTimeToHMS(ms); +} \ No newline at end of file diff --git a/utils/share.js b/utils/share.js new file mode 100644 index 0000000..0aef716 --- /dev/null +++ b/utils/share.js @@ -0,0 +1,6 @@ +export function wxShare(par) { + return { + ...par, + type: 2 + } +} \ No newline at end of file diff --git a/vite.config.js b/vite.config.js index 0c675b2..9eab6e6 100644 --- a/vite.config.js +++ b/vite.config.js @@ -14,6 +14,7 @@ module.exports = defineConfig({ "vue", { "@dcloudio/uni-app": [ + "onShareAppMessage", "onLoad", "onShow", "onHide",