feat:迁移过去一部分
No files matched your search
@@ -38,6 +38,34 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"subPackages": [
|
||||
{
|
||||
"root": "pages/wallet",
|
||||
"pages": [
|
||||
{
|
||||
"path": "list",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "recharge",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"disableScroll": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "浦江县机关事务智慧后勤一体化平台app",
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { merchantApi } from "@@/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
pagesize: 10,
|
||||
type: "2",
|
||||
parentId: "",
|
||||
},
|
||||
})
|
||||
const pageHook = hooks.usePage(pageRef, merchantApi.childrenPage, null, "data.records")
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad((options: any) => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
|
||||
if (options.parentId) {
|
||||
state.pa.parentId = options.parentId
|
||||
}
|
||||
})
|
||||
onShow(async () => {
|
||||
pageRef.value && pageRef.value.reload(false)
|
||||
uni.showLoading({
|
||||
title: "加载中...",
|
||||
mask: true,
|
||||
})
|
||||
try {
|
||||
await getDetail()
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: "加载失败",
|
||||
icon: "error",
|
||||
})
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
uni.setNavigationBarTitle({ title: state.detail.name })
|
||||
})
|
||||
|
||||
const getDetail = async () => {
|
||||
const { data } = await merchantApi.detail({ id: state.pa.parentId })
|
||||
state.detail = data
|
||||
}
|
||||
|
||||
const toDetail = async (v: any) => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
router.jump("/pages/merchant/detail", { id: v.id })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="h-full overflow-hidden">
|
||||
<swiper class="w-100vw h-30vh" circular :indicator-dots="true" indicator-active-color="#0779FD"
|
||||
indicator-color="#ffffff" :autoplay="true">
|
||||
<swiper-item v-for="(v, i) in state.detail?.swiperPic?.split(',')" :key="i">
|
||||
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<crud-layout>
|
||||
<z-paging ref="pageRef" height="70%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i"
|
||||
@tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx my-auto" :src="filePath(v.logoPic)"
|
||||
mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="sub-text-34">{{ v.name }}</view>
|
||||
<view class="m-t-10rpx">
|
||||
<view class="flex justify-between items-center">
|
||||
<view class="flex-1">
|
||||
<view v-if="v.phone" class="flex items-center">
|
||||
<image class="w-24rpx h-24rpx" src="@/static/page/phone.svg" />
|
||||
<view class="second-text-28 ml-1">{{ v.phone }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<tm-tag class="max-w-160rpx" size="xs">
|
||||
{{ v.deptName.length > 5 ? v.deptName.substring(0, 5) + "..." : v.deptName }}
|
||||
</tm-tag>
|
||||
</view>
|
||||
<view class="second-text-24">
|
||||
<view v-if="v.jobTime != ',,'" class="second-text-28">营业时间:</view>
|
||||
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
|
||||
</view>
|
||||
<view v-if="v.addressDes" class="second-text-28">
|
||||
<image class="w-24rpx h-24rpx" src="@/static/page/address.svg" />
|
||||
<text class="ml-1">地址:</text>
|
||||
<text class="m-l-10rpx">{{ v.addressDes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</view>
|
||||
</template>
|
||||
@@ -0,0 +1,80 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, computed } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import uqrcode from "@@/utils/uqrcode"
|
||||
|
||||
import { applyApi } from "@@/api"
|
||||
|
||||
const showQrCodeDialog = ref(false)
|
||||
|
||||
const state = reactive({
|
||||
actId: ''
|
||||
})
|
||||
|
||||
onLoad((options: any) => {
|
||||
state.actId = options.actId
|
||||
getQrcodeDetail()
|
||||
})
|
||||
|
||||
const getQrcodeDetail = async () => {
|
||||
const { data = {} } = await applyApi.getCodeById({ id: state.actId })
|
||||
if (!data.shortCode) {
|
||||
uni.showToast({ title: "优惠券错误", icon: "none" })
|
||||
return
|
||||
}
|
||||
uqrcode.make({
|
||||
canvasId: "qrcodeId",
|
||||
text: data.shortCode,
|
||||
size: 100,
|
||||
margin: 0,
|
||||
success: (res) => { },
|
||||
complete: () => { },
|
||||
})
|
||||
}
|
||||
|
||||
const doViewQrcode = async () => {
|
||||
const { data = {} } = await applyApi.getCodeById({ id: state.actId })
|
||||
if (!data.shortCode) {
|
||||
uni.showToast({ title: "优惠券错误", icon: "none" })
|
||||
return
|
||||
}
|
||||
showQrCodeDialog.value = true
|
||||
uqrcode.make({
|
||||
canvasId: "viewQrcodeId",
|
||||
text: data.shortCode,
|
||||
size: 200,
|
||||
margin: 0,
|
||||
success: (res) => { },
|
||||
complete: () => { },
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
|
||||
<view class="h-30rpx"></view>
|
||||
<view class="size-full relative">
|
||||
<image class="w-650rpx h-1030rpx p-10rpx rounded-12rpx" src="/static/icon/birthday_coupon.jpg"
|
||||
mode="aspectFit" />
|
||||
<view class="z-100 size-120px absolute left-20rpx top-600rpx flex-row-center bg-white p-20rpx rounded-12rpx"
|
||||
@tap="doViewQrcode">
|
||||
<canvas canvas-id="qrcodeId" class="size-100px" />
|
||||
</view>
|
||||
</view>
|
||||
<tm-drawer z-index="100" v-model:show="showQrCodeDialog" title="兑换券核销二维码" :show-close="true" position="bottom"
|
||||
size="60%">
|
||||
<view class="flex-col-center">
|
||||
<view class="h-80rpx" />
|
||||
<canvas canvas-id="viewQrcodeId" class="size-200px" />
|
||||
</view>
|
||||
</tm-drawer>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.layout_main {
|
||||
padding: 0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,215 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, computed } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { serviceEnum } from "@@/constant"
|
||||
|
||||
const { actCouponTypeEnum } = serviceEnum
|
||||
|
||||
const emit = defineEmits(["doVisibleQrcode"])
|
||||
|
||||
const props = withDefaults(defineProps<{ detail: any }>(), {
|
||||
detail: {},
|
||||
})
|
||||
|
||||
const doVisibleQrcode = () => {
|
||||
emit("doVisibleQrcode", { type: 'ACT_CANCEL', detail: props.detail })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="coupon-item">
|
||||
<!-- 左侧主体 -->
|
||||
<view class="coupon-left relative">
|
||||
<view class="size-140rpx rounded-8rpx flex-row-center flex-shrink-0 bg-#f0f0f0 m-r-10rpx">
|
||||
<image class="size-110rpx" src="/static/icon/act_cancel.png" mode="aspectFill" />
|
||||
</view>
|
||||
<view class="absolute top-0rpx right-80rpx">
|
||||
<!-- 未使用 -->
|
||||
<view v-if="detail.actStatus == 1"
|
||||
class="iconfont icon-weishiyong absolute font-size-80rpx! color-blue" />
|
||||
<!-- 已使用 -->
|
||||
<view v-if="detail.actStatus == 2"
|
||||
class="iconfont icon-weishiyong1 absolute font-size-80rpx! color-#cccccc" />
|
||||
<!-- 已过期 -->
|
||||
<view v-if="detail.actStatus == 3"
|
||||
class="iconfont icon-yiguoqi absolute font-size-80rpx! color-#cccccc" />
|
||||
</view>
|
||||
<view class="info-box">
|
||||
<view class="price-row">
|
||||
<view v-if="detail.faceValue" class="flex items-center">
|
||||
<text class="symbol">¥</text>
|
||||
<text class="amount">{{ detail.faceValue }}</text>
|
||||
</view>
|
||||
<text class="name">{{ detail.actTitlel }}</text>
|
||||
</view>
|
||||
<view class="condition">
|
||||
活动商户:{{ detail.mchName }}
|
||||
</view>
|
||||
<view class="scope-text flex-col">
|
||||
<text>{{ actCouponTypeEnum[detail.couponType] }}</text>
|
||||
<text>有限期至 {{ detail.expireTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 虚线分割与缺口 -->
|
||||
<view class="split-line">
|
||||
<view class="circle-top"></view>
|
||||
<view class="dashed-line"></view>
|
||||
<view class="circle-bottom"></view>
|
||||
</view>
|
||||
<!-- 右侧按钮 -->
|
||||
<view class="coupon-right">
|
||||
<view v-if="detail.actStatus == 1" class="action-btn" @tap="doVisibleQrcode">核销码</view>
|
||||
<view v-if="detail.actStatus == 2" class="action-btn disabled">已使用</view>
|
||||
<view v-if="detail.actStatus == 3" class="action-btn disabled">已过期</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.coupon-item {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
background-color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 148, 255, 0.08);
|
||||
}
|
||||
|
||||
/* 左侧布局 */
|
||||
.coupon-left {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 24rpx 0 24rpx 24rpx;
|
||||
background: radial-gradient(circle at right top, transparent 12rpx, #fff 0) top left / 100% 51% no-repeat,
|
||||
radial-gradient(circle at right bottom, transparent 12rpx, #fff 0) bottom left / 100% 51% no-repeat;
|
||||
/* 备用背景色,防止渐变失效 */
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.goods-img {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
border-radius: 8rpx;
|
||||
background-color: #f0f0f0;
|
||||
margin-right: 20rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 140rpx;
|
||||
}
|
||||
|
||||
.price-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
color: #0094ff;
|
||||
}
|
||||
|
||||
.symbol {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
margin: 0 8rpx 0 2rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 200rpx;
|
||||
}
|
||||
|
||||
.condition {
|
||||
font-size: 24rpx;
|
||||
color: #0094ff;
|
||||
opacity: 0.8;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.scope-text {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
/* 中间分割线区域 */
|
||||
.split-line {
|
||||
width: 30rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.dashed-line {
|
||||
width: 0;
|
||||
height: 80%;
|
||||
border-left: 2rpx dashed #0094ff44;
|
||||
}
|
||||
|
||||
.circle-top {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #f5f5f5;
|
||||
/* 假设页面背景接近此色,或者设为透明如果用 mask */
|
||||
}
|
||||
|
||||
.circle-bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 50%);
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 右侧按钮区 */
|
||||
.coupon-right {
|
||||
width: 160rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: radial-gradient(circle at left top, transparent 12rpx, #fff 0) top left / 100% 51% no-repeat,
|
||||
radial-gradient(circle at left bottom, transparent 12rpx, #fff 0) bottom left / 100% 51% no-repeat;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
background: #0094ff;
|
||||
color: #fff;
|
||||
font-size: 26rpx;
|
||||
padding: 10rpx 24rpx;
|
||||
border-radius: 30rpx;
|
||||
font-weight: 500;
|
||||
|
||||
&.disabled {
|
||||
background: #cccccc;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,212 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, computed } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { serviceEnum } from "@@/constant"
|
||||
|
||||
const { actCouponTypeEnum } = serviceEnum
|
||||
|
||||
const emit = defineEmits(["doVisibleQrcode"])
|
||||
|
||||
const props = withDefaults(defineProps<{ detail: any }>(), {
|
||||
detail: {},
|
||||
})
|
||||
|
||||
const doVisibleQrcode = () => {
|
||||
emit("doVisibleQrcode", { type: 'ACT_COUPON', detail: props.detail })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="coupon-item">
|
||||
<!-- 左侧主体 -->
|
||||
<view class="coupon-left relative">
|
||||
<image class="size-140rpx rounded-8rpx flex-shrink-0 m-r-10rpx bg-#f0f0f0" src="/static/icon/act_coupon.png"
|
||||
mode="aspectFill" />
|
||||
<view class="absolute top-0rpx right-80rpx">
|
||||
<!-- 未使用 -->
|
||||
<view v-if="detail.status == 1" class="iconfont icon-weishiyong absolute font-size-80rpx! color-blue" />
|
||||
<!-- 已使用 -->
|
||||
<view v-if="detail.status == 2"
|
||||
class="iconfont icon-weishiyong1 absolute font-size-80rpx! color-#cccccc" />
|
||||
<!-- 已过期 -->
|
||||
<view v-if="detail.status == 3" class="iconfont icon-yiguoqi absolute font-size-80rpx! color-#cccccc" />
|
||||
</view>
|
||||
<view class="info-box">
|
||||
<view class="price-row">
|
||||
<view v-if="detail.faceValue" class="flex items-center">
|
||||
<text class="symbol">¥</text>
|
||||
<text class="amount">{{ detail.faceValue }}</text>
|
||||
</view>
|
||||
<text class="name">{{ detail.couponName }}</text>
|
||||
</view>
|
||||
<view v-if="detail.minPoint" class="condition">
|
||||
满{{ detail.minPoint }}可用
|
||||
</view>
|
||||
<view class="scope-text flex-col">
|
||||
<text>{{ actCouponTypeEnum[detail.couponType] }}</text>
|
||||
<text>在{{ detail.startTime }}至{{ detail.endTime }}时间段使用</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 虚线分割与缺口 -->
|
||||
<view class="split-line">
|
||||
<view class="circle-top"></view>
|
||||
<view class="dashed-line"></view>
|
||||
<view class="circle-bottom"></view>
|
||||
</view>
|
||||
<!-- 右侧按钮 -->
|
||||
<view class="coupon-right">
|
||||
<view v-if="detail.status == 1" class="action-btn" @tap="doVisibleQrcode">核销码</view>
|
||||
<view v-if="detail.status == 2" class="action-btn disabled">已使用</view>
|
||||
<view v-if="detail.status == 3" class="action-btn disabled">已过期</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.coupon-item {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
background-color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 148, 255, 0.08);
|
||||
}
|
||||
|
||||
/* 左侧布局 */
|
||||
.coupon-left {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 24rpx 0 24rpx 24rpx;
|
||||
background: radial-gradient(circle at right top, transparent 12rpx, #fff 0) top left / 100% 51% no-repeat,
|
||||
radial-gradient(circle at right bottom, transparent 12rpx, #fff 0) bottom left / 100% 51% no-repeat;
|
||||
/* 备用背景色,防止渐变失效 */
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.goods-img {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
border-radius: 8rpx;
|
||||
background-color: #f0f0f0;
|
||||
margin-right: 20rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 140rpx;
|
||||
}
|
||||
|
||||
.price-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
color: #0094ff;
|
||||
}
|
||||
|
||||
.symbol {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
margin: 0 8rpx 0 2rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 200rpx;
|
||||
}
|
||||
|
||||
.condition {
|
||||
font-size: 24rpx;
|
||||
color: #0094ff;
|
||||
opacity: 0.8;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.scope-text {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
/* 中间分割线区域 */
|
||||
.split-line {
|
||||
width: 30rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.dashed-line {
|
||||
width: 0;
|
||||
height: 80%;
|
||||
border-left: 2rpx dashed #0094ff44;
|
||||
}
|
||||
|
||||
.circle-top {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #f5f5f5;
|
||||
/* 假设页面背景接近此色,或者设为透明如果用 mask */
|
||||
}
|
||||
|
||||
.circle-bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 50%);
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 右侧按钮区 */
|
||||
.coupon-right {
|
||||
width: 160rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: radial-gradient(circle at left top, transparent 12rpx, #fff 0) top left / 100% 51% no-repeat,
|
||||
radial-gradient(circle at left bottom, transparent 12rpx, #fff 0) bottom left / 100% 51% no-repeat;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
background: #0094ff;
|
||||
color: #fff;
|
||||
font-size: 26rpx;
|
||||
padding: 10rpx 24rpx;
|
||||
border-radius: 30rpx;
|
||||
font-weight: 500;
|
||||
|
||||
&.disabled {
|
||||
background: #cccccc;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
<template #top>
|
||||
<tm-input class="mt-2" v-model="params.receiverUserName" type="text" height="72" minHeight="72"
|
||||
fontSize="28" :showClear="true" :focus="false" placeholder="请输入领取人姓名"
|
||||
style="border: 4rpx solid #0779fd; border-radius: 14rpx" :focus-highlight="false" color="#ECF4F9"
|
||||
@clear="inputClear">
|
||||
<template v-slot:rightIcon>
|
||||
<tm-button class="mr-1 px-3 py-26rpx text-30rpx!" size="xs" @click="search">搜 索</tm-button>
|
||||
</template>
|
||||
</tm-input>
|
||||
<view class="bg-white rounded-16rpx my-20rpx">
|
||||
<z-tabs :list="tabs" @change="doTab" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view class="card w-full h-400rpx relative activity-card overflow-hidden mb-2 py-2"
|
||||
:style="{ backgroundColor: getActStatus(item.actStatus)?.color }" v-for="(item, index) in pageHook.list"
|
||||
:key="index">
|
||||
<view class="ribbon" :style="{ backgroundColor: getActStatus(item.actStatus)?.color }">
|
||||
{{ getActStatus(item.actStatus)?.name }}
|
||||
</view>
|
||||
<view class="text-28 c-#fff text-right px-2">ID {{ item.id }}</view>
|
||||
<view class="flex justify-between font-bold mt-1 px-8">
|
||||
<text class="text-32 c-#FFD941">限时领取</text>
|
||||
<text class="text-30 c-#FFD941 px-1 rounded-full bg-#eeeeee44">
|
||||
{{ (item.actStartTime?.split(" ")[0] || "") + "~" + (item.actExpireTime?.split(" ")[0] || "") }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="w-4/5 py-2 text-28 c-#fff px-8">{{ item.actTitlel }}</view>
|
||||
<view class="absolute bottom-100 left-60 text-28 bg-#eeeeee44 c-#fff px-2 rounded-full">限量领取 先领先得</view>
|
||||
<view v-if="item.receiverTime" class="absolute bottom-40 right-20 text-22 c-#fff">
|
||||
<text class="mr-2">领取人 {{ item.receiverUsername }}</text>
|
||||
<text>领取时间 {{ item.receiverTime }}</text>
|
||||
</view>
|
||||
<view v-if="item.cancelTime" class="absolute bottom-10 right-20 text-22 c-#fff">
|
||||
<text class="mr-2">核销人 {{ item.cancelUsername }}</text>
|
||||
<text>核销时间 {{ item.cancelTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { actCancel } from "@/sheep/api"
|
||||
import { reactive, ref } from "vue"
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
import { hooks } from "@/sheep"
|
||||
|
||||
const tabs = [
|
||||
{ id: null, name: "全部", disabled: false, color: "#7f7f7f77" },
|
||||
{ id: 1, name: "未核销", disabled: false, color: "#1879ff77" },
|
||||
{ id: 2, name: "已核销", disabled: false, color: "#25944577" },
|
||||
{ id: 3, name: "已过期", disabled: false, color: "#FF672B77" },
|
||||
]
|
||||
const params = reactive({
|
||||
actStatus: tabs[0].id,
|
||||
receiverUserName: "",
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, actCancel.appMchPage, null, "data.records")
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, params)
|
||||
}
|
||||
|
||||
const doTab = (e: any) => {
|
||||
params.actStatus = tabs[e].id
|
||||
pageRef.value && pageRef.value.reload(false)
|
||||
}
|
||||
|
||||
const getActStatus = (actStatus: string | number) => {
|
||||
return tabs.find((item: any) => item.id == actStatus)
|
||||
}
|
||||
|
||||
const search = () => {
|
||||
pageRef.value && pageRef.value.reload(false)
|
||||
}
|
||||
|
||||
const inputClear = () => {
|
||||
pageRef.value && pageRef.value.reload(false)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.activity-card {
|
||||
background-image: url("../../static/page/activity-card-bg.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: 150%;
|
||||
}
|
||||
|
||||
.ribbon {
|
||||
width: 160rpx;
|
||||
height: 40rpx;
|
||||
position: absolute;
|
||||
left: -40rpx;
|
||||
top: 20rpx;
|
||||
transform: rotateZ(-45deg);
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,420 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
|
||||
<tm-sticky>
|
||||
<swiper class="w-100vw h-30vh" circular :indicator-dots="true" indicator-active-color="#0779FD"
|
||||
indicator-color="#ffffff" :autoplay="true">
|
||||
<swiper-item v-for="(v, i) in state.detail?.swiperPic?.split(',')" :key="i">
|
||||
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<tm-sticky-header>
|
||||
<view class="m-x-30rpx">
|
||||
<view class="h-15rpx" />
|
||||
<!-- start 简介 start -->
|
||||
<view class="flex-row card p-20rpx m-b-20rpx">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx my-auto" :src="filePath(state.detail.logoPic)"
|
||||
mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="sub-text-34">{{ state.detail.name }}</view>
|
||||
<view class="m-t-10rpx">
|
||||
<view class="flex justify-between items-center">
|
||||
<view class="flex-1">
|
||||
<view v-if="state.detail.phone"
|
||||
v-for="(item, index) in state.detail.phone.split('/')" :key="index"
|
||||
class="flex items-center">
|
||||
<image class="w-24rpx h-24rpx" src="@/static/page/phone.svg" />
|
||||
<view class="second-text-28 ml-1">{{ item.trim() }}</view>
|
||||
<view
|
||||
class="second-text-20 bg-#f8f8f8 ml-1 p-0.3 flex items-center rounded-1 border border-solid border-b-coolGray"
|
||||
@tap="doPhone(item)">
|
||||
联系商家
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<tm-tag class="max-w-160rpx" size="xs">
|
||||
{{ state.detail.deptName?.length > 5 ? state.detail.deptName.substring(0, 5) +
|
||||
"..." : state.detail.deptName }}
|
||||
</tm-tag>
|
||||
</view>
|
||||
<view class="second-text-24">
|
||||
<view class="second-text-28">{{ state.detail.jobTime == ",," ? "" : "营业时间:" }}
|
||||
</view>
|
||||
<view>{{ state.detail.jobTime?.split(",")[0] ? "早:" +
|
||||
state.detail.jobTime?.split(",")[0] : "" }}</view>
|
||||
<view>{{ state.detail.jobTime?.split(",")[1] ? "中:" +
|
||||
state.detail.jobTime?.split(",")[1] : "" }}</view>
|
||||
<view>{{ state.detail.jobTime?.split(",")[2] ? "晚:" +
|
||||
state.detail.jobTime?.split(",")[2] : "" }}</view>
|
||||
</view>
|
||||
<view v-if="state.detail.addressDes" class="second-text-28">
|
||||
<image class="w-24rpx h-24rpx" src="@/static/page/address.svg" />
|
||||
<text class="ml-1">地址:</text>
|
||||
<text class="m-l-10rpx">{{ state.detail.addressDes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- end 简介 end -->
|
||||
</view>
|
||||
</tm-sticky-header>
|
||||
<tm-alert v-if="state.detail?.discountsPrice" color="#0779FD" icon="notification-line"
|
||||
closeIcon="close-line" :border="['2']" :borderColor="['#89c0ff']">
|
||||
<marquee class="flex items-center">{{ state.detail.discountsPrice }}</marquee>
|
||||
</tm-alert>
|
||||
|
||||
<!-- start 商品 start -->
|
||||
<view v-if="false" class="flex-row">
|
||||
<scroll-view v-if="state.classifyList.length" scroll-y :style="{ height: getHeight() }"
|
||||
class="menu w-200rpx h-full p-l-12rpx p-b-20rpx bg-#f6f6f6">
|
||||
<view class="menu_item flex-row-center" v-for="(v, i) in state.classifyList" :key="v.id"
|
||||
:class="[{ menu_item_active: i == state.currentClassifyIndex }]" @tap="doClassify(i)">
|
||||
<view class="menu_item_title show-line">{{ v.name }}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<scroll-view v-if="state.goodsList.length" scroll-y :style="{ height: getHeight() }"
|
||||
class="flex-1 p-b-20rpx p-x-15rpx">
|
||||
<!-- <product-row
|
||||
v-for="goodsItem in state.goodsList"
|
||||
:key="goodsItem.id"
|
||||
:productId="goodsItem.id"
|
||||
:merchantId="goodsItem.merchantId"
|
||||
:picUrl="filePath(goodsItem.picUrl)"
|
||||
:productName="goodsItem.productName"
|
||||
:salesCount="goodsItem.salesCount"
|
||||
:stock="goodsItem.stock"
|
||||
:unit="goodsItem.unit"
|
||||
:retailPrice="goodsItem.retailPrice"
|
||||
:promotionPrice="goodsItem.promotionPrice"
|
||||
@onClickAddToCart="onClickAddToCart(goodsItem)"
|
||||
/> -->
|
||||
</scroll-view>
|
||||
</view>
|
||||
</tm-sticky>
|
||||
<!-- end 商品 end -->
|
||||
|
||||
<template #main-bottom>
|
||||
<view v-if="false && state.classifyList.length" class="car z-200 p-x-30rpx p-y-30rpx bg-white">
|
||||
<!-- <product-total :totPrice="state.totPrice" :totCount="state.totCount" @doContainer="doVisibleCart" @submit="doBuy" /> -->
|
||||
</view>
|
||||
</template>
|
||||
</crud-layout>
|
||||
|
||||
<!-- 购物车弹框 -->
|
||||
<!-- <product-cart
|
||||
v-model="state.showCartDialog"
|
||||
:cartList="state.cartList"
|
||||
:totPrice="state.totPrice"
|
||||
:totCount="state.totCount"
|
||||
@add="doAdd"
|
||||
@remove="doRemove"
|
||||
@submit="doBuy"
|
||||
/> -->
|
||||
<!-- 规格与数量弹框 -->
|
||||
<!-- <product-sku v-model="state.showSkuDialog" :productData="state.curProductData" @onSkuAddToCart="onSkuAddToCart" /> -->
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, nextTick } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { foodApi, merchantApi, orderApi, payApi, shopApi } from "@@/api"
|
||||
import { filePath } from "@@/utils/file"
|
||||
// import ProductRow from "./components/product-row.vue"
|
||||
// import ProductCart from "./components/product-cart.vue"
|
||||
// import ProductTotal from "./components/product-total.vue"
|
||||
// import ProductSku from "./components/product-sku.vue"
|
||||
import { getAppInfo } from "@/sheep/utils/app"
|
||||
import { APPENV } from "@/sheep/constant"
|
||||
|
||||
// 商品详情相关数据
|
||||
const state = reactive<any>({
|
||||
merchantId: null,
|
||||
detail: {},
|
||||
|
||||
goodsList: [],
|
||||
|
||||
cartList: [],
|
||||
totPrice: 0,
|
||||
totCount: 0,
|
||||
|
||||
classifyList: [],
|
||||
currentClassifyIndex: 0,
|
||||
|
||||
showCartDialog: false,
|
||||
showSkuDialog: false,
|
||||
|
||||
curProductData: {}, // 当前点击加入到购物车的商品信息
|
||||
})
|
||||
|
||||
onLoad((options: any) => {
|
||||
if (!isEmpty(options.id)) {
|
||||
state.merchantId = options.id
|
||||
}
|
||||
})
|
||||
onShow(async () => {
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
try {
|
||||
await getDetail()
|
||||
// await getShopCart()
|
||||
// await getClassify()
|
||||
} catch (error: any) {
|
||||
uni.showToast({ title: error, icon: "error" })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
})
|
||||
|
||||
const getHeight = () => {
|
||||
const rpx = 480
|
||||
return `calc(100vh - ${uni.upx2px(rpx)}px)`
|
||||
}
|
||||
|
||||
const getDetail = async () => {
|
||||
const { data } = await merchantApi.detail({ id: state.merchantId })
|
||||
state.detail = data
|
||||
}
|
||||
|
||||
const getShopCart = async () => {
|
||||
const { data } = await orderApi.getShopCar({ merchantId: state.merchantId, hardType: "SUPERMARKET" })
|
||||
state.cartList = data ?? []
|
||||
state.totPrice = state.cartList.map((v) => Number(v.totalPrice)).reduce((pre, next) => pre + next, 0)
|
||||
state.totCount = state.cartList.map((v) => v.productCount).reduce((pre, next) => pre + next, 0)
|
||||
}
|
||||
|
||||
const getClassify = async () => {
|
||||
if (state.merchantId) {
|
||||
const { data } = await shopApi.getSupermarketSpuCategory({ merchantId: state.merchantId })
|
||||
state.classifyList = data ?? []
|
||||
if (!isEmpty(state.classifyList)) {
|
||||
getPorductList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getPorductList = async () => {
|
||||
const target = state.classifyList[state.currentClassifyIndex]
|
||||
if (isEmpty(target)) return
|
||||
try {
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
const { code, data }: any = await shopApi.getSupermarketSpuList({
|
||||
merchantId: state.merchantId,
|
||||
categoryId: target.id,
|
||||
current: 1,
|
||||
size: 99999,
|
||||
})
|
||||
if (code == 0) {
|
||||
state.goodsList = data.records
|
||||
return
|
||||
}
|
||||
state.goodsList = []
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
const doClassify = async (i: any) => {
|
||||
state.currentClassifyIndex = i
|
||||
await getPorductList()
|
||||
}
|
||||
|
||||
// 点击添加到购物车
|
||||
const onClickAddToCart = (goodsItem: any) => {
|
||||
state.curProductData = goodsItem
|
||||
state.showSkuDialog = true
|
||||
}
|
||||
|
||||
// 选择sku加入到购物车
|
||||
const onSkuAddToCart = (skuGoodsInfo: any) => {
|
||||
chentProductCount(skuGoodsInfo) // 同步购物车中的数据
|
||||
state.showSkuDialog = false
|
||||
}
|
||||
|
||||
// 同步购物车中的数据
|
||||
const chentProductCount = async (item: any, type?: "add" | "remove") => {
|
||||
try {
|
||||
uni.showLoading({ title: "加载中", mask: true })
|
||||
|
||||
// 在购物车中增减商品数量
|
||||
let count = item.productCount
|
||||
if (type === "add") {
|
||||
count += 1
|
||||
const { code }: any = await shopApi.checkSpuStock({ spuId: item.spuId, incrCount: count })
|
||||
if (code != 0) throw new Error()
|
||||
} else if (type === "remove") {
|
||||
count -= 1
|
||||
}
|
||||
|
||||
const targetIndex = state.cartList.findIndex((v: any) => v.productId == item.productId)
|
||||
if (targetIndex !== -1) {
|
||||
state.cartList[targetIndex].productCount = count
|
||||
state.cartList[targetIndex].productId = item.productId
|
||||
state.cartList[targetIndex].spuId = item.spuId
|
||||
} else {
|
||||
state.cartList.push(item)
|
||||
}
|
||||
|
||||
nextTick(async () => await updateShopCart()) // 保存购物车数据
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 保存购物车数据
|
||||
const updateShopCart = async () => {
|
||||
if (isEmpty(state.cartList)) return
|
||||
const list = state.cartList
|
||||
.filter((v) => v.productCount && v.productCount > 0)
|
||||
.map((v) => {
|
||||
return {
|
||||
productCount: v.productCount,
|
||||
productId: v.productId,
|
||||
}
|
||||
})
|
||||
const { code }: any = await orderApi.updateShopCar({ merchantId: state.merchantId, list, hardType: "SUPERMARKET" })
|
||||
if (code == 0) await getShopCart()
|
||||
}
|
||||
|
||||
// 打开购物车
|
||||
const doVisibleCart = () => (state.showCartDialog = true)
|
||||
|
||||
const doAdd = async (item: any) => {
|
||||
chentProductCount(item, "add")
|
||||
}
|
||||
const doRemove = async (item: any) => {
|
||||
chentProductCount(item, "remove")
|
||||
}
|
||||
|
||||
// 点击提交订单
|
||||
const doBuy = async () => {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "是否确定购买",
|
||||
confirmColor: "#0094ff",
|
||||
success: async (res) => {
|
||||
if (!res.confirm) return
|
||||
submitPay() // 提交订单
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 提交订单
|
||||
const submitPay = async () => {
|
||||
try {
|
||||
if (isEmpty(state.cartList)) return uni.showToast({ title: "请至少购买一件商品", icon: "none" })
|
||||
|
||||
uni.showLoading({ title: "支付中...", mask: false })
|
||||
const { data, code }: any = await payApi.createHardwareOrder({ carParentId: state.cartList[0].parentCarId, hardType: "SUPERMARKET" })
|
||||
if (code != 0) throw new Error()
|
||||
uni.showToast({ title: "支付成功", icon: "none" })
|
||||
router.jump("/pages/tabbar/order")
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 联系商家
|
||||
const doPhone = async (item: string) => {
|
||||
if (isEmpty(item)) return uni.showToast({ title: "该商户没有预留电话", icon: "none" })
|
||||
hooks.useMakePhoneCall(item.trim())
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep() {
|
||||
.layout_main>scroll-view {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.menu {
|
||||
&_item {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
position: relative;
|
||||
transition: all linear 0.2s;
|
||||
|
||||
&_title {
|
||||
width: 100%;
|
||||
line-height: 32rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
margin-left: 28rpx;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
width: 64rpx;
|
||||
height: 12rpx;
|
||||
background: linear-gradient(90deg, #0094ff, #e9f5fe) !important;
|
||||
position: absolute;
|
||||
left: -64rpx;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
transition: all linear 0.2s;
|
||||
}
|
||||
}
|
||||
|
||||
&.menu_item_active {
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx 0 0 20rpx;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -20rpx;
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
background: radial-gradient(circle at 0 100%, transparent 20rpx, #fff 0);
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -20rpx;
|
||||
right: 0;
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
background: radial-gradient(circle at 0% 0%, transparent 20rpx, #fff 0);
|
||||
}
|
||||
|
||||
.menu_item_title {
|
||||
font-weight: 600;
|
||||
|
||||
&::before {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.car {
|
||||
box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.scroll-text {
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
animation: scroll-left 10s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes scroll-left {
|
||||
0% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<view v-if="state.actId" class="px-2 py-4">
|
||||
<view v-if="state.actType == 'CANCEL_ACT'"
|
||||
class="card rounded-lb-0! rounded-rb-0! w-full h-400rpx relative activity-card overflow-hidden">
|
||||
<view class="ribbon">兑换券</view>
|
||||
<view class="px-8 pt-5 flex justify-between items-center font-bold">
|
||||
<text class="text-32 c-#FF4F3F">限时领取</text>
|
||||
<text class="text-30 c-#FF4F3F px-1 rounded-full bg-#eeeeee44">
|
||||
{{ (state.actDetail.startTime?.split(" ")[0] || "") + "~" +
|
||||
(state.actDetail.expireTime?.split(" ")[0] || "") }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="w-4/5 px-8 pt-4 text-28 c-#fff">{{ state.actDetail.actTitle }}</view>
|
||||
<view class="absolute bottom-100 left-60 text-40 italic">
|
||||
<text class="color-red mr-2">¥{{ hooks.useMoney(state.actDetail.activeCancelPrice) }}</text>
|
||||
<text class="text-30 line-through color-red">¥{{ hooks.useMoney(state.actDetail.activeOrgPrice)
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="absolute bottom-40 left-60 text-28 bg-#eeeeee44 c-#fff px-2 rounded-full">限量领取 先领先得</view>
|
||||
</view>
|
||||
<view class="card relative rounded-lb-0! rounded-rb-0! w-full activity-sr-card overflow-hidden"
|
||||
v-if="state.actType == 'COUPON_ACT' && state.actDetail.uniqueCode === '1qRgFo'">
|
||||
<image class="w-full block" src="/static/page/act_li_quan.jpg" mode="widthFix" />
|
||||
<view class="absolute top-0 left-0 w-full h-full">
|
||||
<view class="ribbon">{{ actCouponTypeEnum[state.actDetail.type] }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else-if="state.actType == 'COUPON_ACT'"
|
||||
class="card relative rounded-lb-0! rounded-rb-0! w-full activity-card overflow-hidden">
|
||||
<view class="ribbon">{{ actCouponTypeEnum[state.actDetail.type] }}</view>
|
||||
<view class="px-8 pt-5 flex justify-between items-center font-bold">
|
||||
<text class="text-32 c-#FF4F3F">{{ state.actDetail.name }}</text>
|
||||
<text class="text-30 c-#FF4F3F px-1 rounded-full bg-#eeeeee44">
|
||||
<view v-if="state.actDetail.validType == 1" class="flex items-center">
|
||||
<text>{{ state.actDetail.validStartTime }}</text>
|
||||
<text>~</text>
|
||||
<text>{{ state.actDetail.validEndTime }}</text>
|
||||
</view>
|
||||
</text>
|
||||
</view>
|
||||
<view class="w-4/5 px-8 pt-4 text-28 c-#fff">
|
||||
<view v-if="state.actDetail.validType == '1'">
|
||||
<text>领取后请在</text>
|
||||
<text>{{ state.actDetail.validStartTime }}</text>
|
||||
<text>~</text>
|
||||
<text>{{ state.actDetail.validEndTime }}</text>
|
||||
<text>时间段内使用</text>
|
||||
</view>
|
||||
<view v-if="state.actDetail.validType == '2'">
|
||||
<text>领取后请在</text>
|
||||
<text>{{ state.actDetail.validDays }}</text>
|
||||
<text>天内使用</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="state.actDetail.description"
|
||||
class="m-l-20rpx m-y-20rpx w-55% text-28 bg-#eeeeee44 c-#fff p-2 rounded-16rpx">
|
||||
{{ state.actDetail.description }}
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="state.couponInfo.actStatus == '2'"
|
||||
class="text-center card rounded-lt-0! rounded-rt-0! p-3 sub-text-30">
|
||||
已 核 销
|
||||
</view>
|
||||
<template v-else>
|
||||
<view v-if="state.actUserReceiveStatus == '99'"
|
||||
class="text-center card rounded-lt-0! rounded-rt-0! p-3 sub-text-30" @tap="doReceive">立 即 领 取</view>
|
||||
<view v-else class="text-center card rounded-lt-0! rounded-rt-0! p-3 sub-text-30">
|
||||
{{ actUserReceiveEnum[state.actUserReceiveStatus] || "未知状态" }}
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<template #main-bottom>
|
||||
<view class="text-center">
|
||||
<tm-button class="px-32 m-2" @click="doQrcode">我的礼券</tm-button>
|
||||
</view>
|
||||
</template>
|
||||
</crud-layout>
|
||||
<modify-user ref="modifyUserRef" warnText="填写出生日期即可领取生日兑换券" @close="modifyUserClose" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, nextTick } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
|
||||
import { actCancel, actComApi, actCouponApi, userApi } from "@/sheep/api"
|
||||
import { hooks, router } from "@/sheep"
|
||||
import { serviceEnum, storageConstant } from "@@/constant"
|
||||
|
||||
import ModifyUser from "@@/components/modify-user.vue"
|
||||
|
||||
const { actUserReceiveEnum, actCouponTypeEnum } = serviceEnum
|
||||
|
||||
const modifyUserRef = ref<any>(null)
|
||||
const state = reactive<any>({
|
||||
actId: "",
|
||||
actType: "",
|
||||
actUserReceiveStatus: "", // 是否已领取
|
||||
actDetail: {}, // 优惠券详情
|
||||
couponInfo: {}, // 优惠券信息
|
||||
userDetail: {},
|
||||
})
|
||||
|
||||
onLoad((option: any) => {
|
||||
const { actId, actType } = option
|
||||
if (!actId || !actType) return uni.showToast({ title: "参数错误", icon: "error" })
|
||||
state.actId = actId
|
||||
state.actType = actType
|
||||
getActDetail()
|
||||
getIsEligibleForAct()
|
||||
if (actType == "CANCEL_ACT") {
|
||||
getCouponInfo()
|
||||
}
|
||||
if (actType == "COUPON_ACT") {
|
||||
specialDispose()
|
||||
}
|
||||
})
|
||||
|
||||
// 获取优惠券详情
|
||||
const getActDetail = async () => {
|
||||
try {
|
||||
const { data } = await actComApi.getActDetail({
|
||||
actId: state.actId,
|
||||
actType: state.actType,
|
||||
})
|
||||
state.actDetail = data?.detail
|
||||
} catch (error: any) {
|
||||
uni.showToast({ title: error, icon: "error" })
|
||||
}
|
||||
}
|
||||
|
||||
const getIsEligibleForAct = async () => {
|
||||
try {
|
||||
const { data } = await actComApi.isEligibleForAct({
|
||||
actId: state.actId,
|
||||
actType: state.actType,
|
||||
})
|
||||
state.actUserReceiveStatus = data
|
||||
} catch (error: any) {
|
||||
uni.showToast({ title: error, icon: "error" })
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户的唯一优惠券信息
|
||||
const getCouponInfo = async () => {
|
||||
try {
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
const { code, data }: any = await actCancel.appFindUnique({ actId: state.actId })
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
state.couponInfo = data
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "加载失败", icon: "none" })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 领取优惠券
|
||||
const doReceive = () => {
|
||||
// 核销活动
|
||||
if (state.actType == 'CANCEL_ACT') {
|
||||
getCancelReceive()
|
||||
}
|
||||
// 优惠券活动
|
||||
if (state.actType == 'COUPON_ACT') {
|
||||
getCouponReceive()
|
||||
}
|
||||
}
|
||||
|
||||
// 核销活动
|
||||
const getCancelReceive = async () => {
|
||||
try {
|
||||
uni.showLoading({ title: "正在领取...", mask: true })
|
||||
const { code, msg }: any = await actCancel.appGet({
|
||||
receiverUserId: uni.getStorageSync("user_info")?.sysUser?.userId,
|
||||
actId: state.actId,
|
||||
mchId: state.actDetail.mchId,
|
||||
})
|
||||
if (code != 0) return uni.showToast({ title: msg || "领取失败", icon: "none", mask: true })
|
||||
uni.showToast({ title: "领取成功", icon: "success" })
|
||||
await getCouponInfo()
|
||||
await getIsEligibleForAct()
|
||||
} catch (error: any) {
|
||||
uni.showToast({ title: "领取失败", icon: "none" })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 优惠券活动
|
||||
const getCouponReceive = async () => {
|
||||
// 特殊处理
|
||||
if (state.actDetail.uniqueCode == "1qRgFo") {
|
||||
// 判断用户有没有输入生日
|
||||
const isEligible = await specialDispose()
|
||||
if (!isEligible) return
|
||||
}
|
||||
try {
|
||||
uni.showLoading({ title: "正在领取...", mask: true })
|
||||
const { code, msg }: any = await actCouponApi.receive({
|
||||
couponId: state.actId,
|
||||
receiveUserId: state.userDetail.userId,
|
||||
})
|
||||
if (code != 0) return uni.showToast({ title: msg || "领取失败", icon: "none", mask: true })
|
||||
uni.showToast({ title: "领取成功", icon: "success" })
|
||||
await getIsEligibleForAct()
|
||||
} catch (error: any) {
|
||||
uni.showToast({ title: "领取失败", icon: "none" })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
const specialDispose = async (): Promise<boolean> => {
|
||||
await getUserInfo()
|
||||
if (!state.userDetail.birthday) {
|
||||
nextTick(() => {
|
||||
modifyUserRef.value.open()
|
||||
})
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const getUserInfo = async () => {
|
||||
const { data: userData } = await userApi.userInfo()
|
||||
state.userDetail = userData?.sysUser ?? {}
|
||||
uni.setStorageSync(storageConstant.USERINFO, userData)
|
||||
}
|
||||
|
||||
const doQrcode = () => {
|
||||
router.jump("/pages/merchant/my-act-list")
|
||||
}
|
||||
|
||||
const modifyUserClose = () => {
|
||||
getIsEligibleForAct()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.activity-card {
|
||||
background-image: url("../../static/page/activity-card-bg.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: 150%;
|
||||
background-color: #1879ff77;
|
||||
}
|
||||
|
||||
.activity-sr-card {
|
||||
/* background-image: url("../../static/page/act_li_quan.jpg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: 150%;
|
||||
background-color: red; */
|
||||
}
|
||||
|
||||
.ribbon {
|
||||
width: 160rpx;
|
||||
height: 40rpx;
|
||||
background: #dd0d1f;
|
||||
position: absolute;
|
||||
left: -40rpx;
|
||||
top: 20rpx;
|
||||
transform: rotateZ(-45deg);
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,173 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, computed } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { router } from "@/sheep"
|
||||
|
||||
import uqrcode from "@@/utils/uqrcode"
|
||||
import * as CryptoJS from "crypto-js"
|
||||
|
||||
import { actCancel, actComApi, actCouponApi, applyApi } from "@@/api"
|
||||
import { hooks } from "@/sheep"
|
||||
import { serviceEnum } from "@@/constant"
|
||||
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
|
||||
import CancelCard from "./components/cancel-card.vue"
|
||||
import CouponCard from "./components/coupon-card.vue"
|
||||
|
||||
const { actCouponTypeEnum } = serviceEnum
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
|
||||
const showQrCodeDialog = ref(false)
|
||||
const params = reactive({
|
||||
})
|
||||
const state = reactive({
|
||||
tabs: [
|
||||
{
|
||||
id: 1,
|
||||
name: "优惠券活动",
|
||||
badge: {
|
||||
count: 6
|
||||
},
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "核销券活动",
|
||||
badge: {
|
||||
count: 6
|
||||
},
|
||||
disabled: false
|
||||
},
|
||||
],
|
||||
tabId: 1,
|
||||
})
|
||||
|
||||
const dynamicPageHook = computed(() => {
|
||||
if (state.tabId == 1) {
|
||||
return hooks.usePage(pageRef, actCouponApi.userList, null, "data.records")
|
||||
}
|
||||
if (state.tabId == 2) {
|
||||
return hooks.usePage(pageRef, actCancel.userList, null, "data.records")
|
||||
}
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
getUserTotal()
|
||||
})
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
dynamicPageHook.value?.startPage(page, pagesize, false, params)
|
||||
getUserTotal()
|
||||
}
|
||||
|
||||
const doTab = (e: any) => {
|
||||
const target = state.tabs[e]
|
||||
state.tabId = target.id
|
||||
pageRef.value.reload(false)
|
||||
getUserTotal()
|
||||
}
|
||||
|
||||
const doVisibleQrcode = async (detail: any) => {
|
||||
const { type, detail: actDetail } = detail
|
||||
console.log("生成二维码:", type, actDetail);
|
||||
// 查询优惠券对应的短码
|
||||
if (type == "ACT_COUPON") {
|
||||
// 判断核销时间 必须在`actDetail.startTime`和`actDetail.endTime`之间
|
||||
const now = new Date().getTime()
|
||||
const startTime = new Date(actDetail.startTime).getTime()
|
||||
const endTime = new Date(actDetail.endTime).getTime()
|
||||
if (now < startTime || now > endTime) {
|
||||
uni.showToast({ title: "核销时间不在活动时间范围内", icon: "none" })
|
||||
return
|
||||
}
|
||||
// 特殊情况
|
||||
// 1. 生日
|
||||
if (actDetail.actUniquecode == "1qRgFo") {
|
||||
// 生日活动,直接跳转
|
||||
router.jump("/pages/merchant/cancel-qrcode", { actId: actDetail.id })
|
||||
return
|
||||
}
|
||||
try {
|
||||
const { data = {} } = await applyApi.getCodeById({ id: actDetail.id })
|
||||
if (!data.shortCode) {
|
||||
uni.showToast({ title: "优惠券错误", icon: "none" })
|
||||
return
|
||||
}
|
||||
showQrCodeDialog.value = true
|
||||
uqrcode.make({
|
||||
canvasId: "qrcodeId",
|
||||
text: data.shortCode,
|
||||
size: 200,
|
||||
margin: 0,
|
||||
success: (res) => { },
|
||||
complete: () => { },
|
||||
})
|
||||
} catch (error) {
|
||||
console.log("|查询优惠券对应的短码|意外的错误error:", error);
|
||||
}
|
||||
}
|
||||
if (type == "ACT_CANCEL") {
|
||||
genVerificationCode({ cancelId: actDetail.id })
|
||||
}
|
||||
}
|
||||
|
||||
// 用户参加活动的数量统计
|
||||
const getUserTotal = async () => {
|
||||
try {
|
||||
const { data = {} }: any = await actComApi.userTotal({})
|
||||
state.tabs[0].badge.count = data?.couponCount ?? null
|
||||
state.tabs[1].badge.count = data?.cancelCount ?? null
|
||||
} catch (error) {
|
||||
console.log("|用户参加活动的数量统计|意外的错误error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// 生成核销二维码
|
||||
const genVerificationCode = async (params: Record<string, any>) => {
|
||||
showQrCodeDialog.value = true
|
||||
const words = CryptoJS.enc.Utf8.parse(JSON.stringify(params))
|
||||
uqrcode.make({
|
||||
canvasId: "qrcodeId",
|
||||
text: CryptoJS.enc.Base64.stringify(words),
|
||||
size: 200,
|
||||
margin: 0,
|
||||
success: (res) => { },
|
||||
complete: () => { },
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="dynamicPageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false"
|
||||
@scroll="dynamicPageHook.scroll">
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
<view class="bg-white rounded-16rpx">
|
||||
<z-tabs :list="state.tabs" @change="doTab" />
|
||||
</view>
|
||||
</template>
|
||||
<view class="h-20rpx" />
|
||||
<view v-if="state.tabId == 1">
|
||||
<coupon-card v-for="item in dynamicPageHook.list" :key="item.id" :detail="item"
|
||||
@do-visible-qrcode="doVisibleQrcode" />
|
||||
</view>
|
||||
<view v-if="state.tabId == 2">
|
||||
<cancel-card v-for="item in dynamicPageHook.list" :key="item.id" :detail="item"
|
||||
@do-visible-qrcode="doVisibleQrcode" />
|
||||
</view>
|
||||
</z-paging>
|
||||
<tm-drawer z-index="100" v-model:show="showQrCodeDialog" title="兑换券核销二维码" :show-close="true" position="bottom"
|
||||
size="60%">
|
||||
<view class="flex-col-center">
|
||||
<view class="h-80rpx" />
|
||||
<canvas canvas-id="qrcodeId" class="size-200px" />
|
||||
</view>
|
||||
</tm-drawer>
|
||||
</crud-layout>
|
||||
</template>
|
||||
@@ -34,10 +34,12 @@ const minAppGetphone = async (e) => {
|
||||
}
|
||||
try {
|
||||
uni.showLoading({ title: '登录中...', mask: true })
|
||||
const { code: loginCode }: any = await uni.login({ provider: 'weixin' });
|
||||
// 获取用户手机号
|
||||
const { data, code }: any = await miniPlatformApi.autoAdminLogin({
|
||||
miniPlatformType: await getAppInfo(),
|
||||
code: phoneDetail.code,
|
||||
phoneCode: phoneDetail.code,
|
||||
userCode: loginCode,
|
||||
})
|
||||
if (data.errorCode) {
|
||||
state.loginErrorCode = data.errorCode
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
|
||||
import { hooks } from "@@/index"
|
||||
import { walletApi } from "@@/api"
|
||||
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
|
||||
const data = {
|
||||
tabs: ["全部", "收入", "支出"],
|
||||
}
|
||||
const state = reactive<any>({
|
||||
walletId: null,
|
||||
pa: {
|
||||
createTime: null,
|
||||
type: 0,
|
||||
walletId: null,
|
||||
},
|
||||
})
|
||||
|
||||
onLoad((options: any) => {
|
||||
if (!isEmpty(options.id)) {
|
||||
state.walletId = options.id
|
||||
state.pa.walletId = options.id
|
||||
}
|
||||
})
|
||||
onShow(() => { })
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, walletApi.transaction, null, "data.records")
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
const doTab = (e: any) => {
|
||||
if (state.pa.type != e) {
|
||||
state.pa.type = e
|
||||
pageRef.value.reload(true)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="饭卡" bg="/static/page/blue-bg.png">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
<view class="h-30rpx" />
|
||||
<view class="bg-white rounded-16rpx px-20rpx">
|
||||
<z-tabs :list="data.tabs" @change="doTab" />
|
||||
</view>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx"
|
||||
v-for="(v, i) in pageHook.list" :key="i">
|
||||
<view class="flex">
|
||||
<view class="w-200rpx flex justify-left p-r-25rpx">
|
||||
<tm-tag v-if="v.title == '更新余额'" size="m">{{ v.title }}</tm-tag>
|
||||
<tm-tag v-if="v.title == '批量更新余额'" size="m">{{ v.title }}</tm-tag>
|
||||
<tm-tag v-if="v.title == '充值'" size="m">{{ v.title }}</tm-tag>
|
||||
<tm-tag v-if="v.title == '支付'" color="error" size="m">{{ v.title }}</tm-tag>
|
||||
<tm-tag v-if="v.title == '退款'" color="info" size="m">{{ v.title }}</tm-tag>
|
||||
<tm-tag v-if="v.title == '转账'" color="success" size="m">{{ v.title }}</tm-tag>
|
||||
<tm-tag v-if="v.title == '转账退款'" color="info" size="m">{{ v.title }}</tm-tag>
|
||||
</view>
|
||||
<view class="flex-row-center">
|
||||
<text class="sub-text-30">{{ hooks.useMoney(v.price) }}元</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="sub-text-24 text-right">
|
||||
{{ hooks.useTime(v.createTime, "") }}
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
@@ -0,0 +1,223 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import uqrcode from "@@/utils/uqrcode"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { walletApi } from "@@/api"
|
||||
|
||||
import { filePath } from "@@/utils/file"
|
||||
import { usePayStore } from "@/sheep/stores/pay"
|
||||
|
||||
const state = reactive<any>({
|
||||
showBindDialog: false,
|
||||
showFreezeDialog: false,
|
||||
showQrCodeDialog: false,
|
||||
currentCard: {},
|
||||
})
|
||||
const bindForm = reactive<any>({
|
||||
cardNumber: "",
|
||||
})
|
||||
const bindFormRules = reactive<any>({
|
||||
cardNumber: [
|
||||
{ required: true, message: "请输入卡号" },
|
||||
{ required: true, min: 12, message: "饭卡长度在12位" },
|
||||
{ required: true, max: 12, message: "饭卡长度在12位" },
|
||||
],
|
||||
})
|
||||
const freezeForm = reactive<any>({
|
||||
remark: "",
|
||||
})
|
||||
|
||||
onLoad(() => { })
|
||||
onShow(async () => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (!isLogin) return
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, walletApi.all, null, "data.records")
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
const openBindDialog = (v: any) => {
|
||||
state.showBindDialog = true
|
||||
state.currentCard = v
|
||||
}
|
||||
|
||||
const closeBindDialog = () => {
|
||||
state.showBindDialog = false
|
||||
}
|
||||
|
||||
const bindFormRef = ref<any>(null)
|
||||
const doBind = async () => {
|
||||
bindFormRef.value.submit()
|
||||
const { isPass } = bindFormRef.value.validate()
|
||||
if (!isPass) return
|
||||
try {
|
||||
uni.showLoading({ title: "绑定中...", mask: false })
|
||||
const _pa = {
|
||||
walletId: state.currentCard.id,
|
||||
cardNumber: bindForm.cardNumber,
|
||||
}
|
||||
const { data, code }: any = await walletApi.bind(_pa)
|
||||
if (code != 0) throw new Error()
|
||||
closeBindDialog()
|
||||
pageRef.value.reload(true)
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "绑定成功", icon: "none" })
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
const openFreezeDialog = (v: any) => {
|
||||
state.showFreezeDialog = true
|
||||
state.currentCard = v
|
||||
}
|
||||
const closeFreezeDialog = () => {
|
||||
state.showFreezeDialog = false
|
||||
}
|
||||
const doPreviewQrCode = async (v: any) => {
|
||||
uni.showLoading({ title: "生成中...", mask: false })
|
||||
const _pa = { walletId: v.id }
|
||||
try {
|
||||
const { data, code }: any = await walletApi.getQrCode(_pa)
|
||||
if (code != 0) throw new Error()
|
||||
uni.hideLoading()
|
||||
state.showQrCodeDialog = true
|
||||
uqrcode.make({
|
||||
canvasId: "qrcodeId",
|
||||
text: data,
|
||||
size: 200,
|
||||
margin: 0,
|
||||
success: (res) => {
|
||||
console.log(res, "res")
|
||||
},
|
||||
complete: () => {
|
||||
uni.hideLoading()
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
const doFreeze = async () => {
|
||||
try {
|
||||
uni.showLoading({ title: "申请中...", mask: false })
|
||||
const _pa = {
|
||||
walletTypeId: state.currentCard.walletTypeId,
|
||||
remark: freezeForm.remark,
|
||||
}
|
||||
const { data, code }: any = await walletApi.freeze(_pa)
|
||||
if (code != 0) throw new Error()
|
||||
closeFreezeDialog()
|
||||
pageRef.value.reload(true)
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "申请成功", icon: "none" })
|
||||
freezeForm.remark = ""
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 转账
|
||||
const doTransferMoney = (v: any) => {
|
||||
if (v.walletTypeId) {
|
||||
usePayStore().setSourceWalletData(v)
|
||||
router.jump("/pages/pay/transferMoney")
|
||||
return
|
||||
}
|
||||
uni.showToast({ title: "钱包类型id不存在", icon: "none" })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="5"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
<view class="h-30rpx" />
|
||||
<view class="card flex-col rounded-20rpx p-x-30rpx p-y-20rpx m-b-30rpx" v-for="(v, i) in pageHook.list"
|
||||
:key="i" @tap="router.jump('/pages/wallet/detail', { id: v.id })">
|
||||
<view class="flex-col">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center">
|
||||
<text v-if="v.cardNumber" class="second-text-28">卡号: {{ v.cardNumber }}</text>
|
||||
</view>
|
||||
<view class="second-text-50">
|
||||
<text v-if="v.cardNumber" class="iconfont icon-fuzhi"
|
||||
@tap.stop="hooks.useCopy(v.cardNumber)" />
|
||||
<text v-if="v.walletTypeUniqueCode != '2'" class="m-l-20rpx iconfont icon-erweima"
|
||||
@tap.stop="doPreviewQrCode(v)" />
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="v.cardNumber" class="h-1px m-t-10rpx bg-#999 bg-opacity-5" />
|
||||
</view>
|
||||
<view class="flex-row items-center justify-between m-t-10rpx">
|
||||
<view class="flex-row items-center">
|
||||
<image class="size-50rpx rounded-full" :src="filePath(v.walletTypeIcon)" mode="aspectFill" />
|
||||
<text class="m-l-25rpx sub-text-28">
|
||||
{{ v.walletTypeName }}
|
||||
</text>
|
||||
</view>
|
||||
<view v-if="v.cardNumber">
|
||||
<tm-tag v-if="v.isFreeze == 0" size="s" color="success">正常</tm-tag>
|
||||
<tm-tag v-if="v.isFreeze == 1" size="s" color="error">已冻结</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-row items-center justify-between m-t-10rpx">
|
||||
<text class="sub-text-40 color-red!"> ¥{{ hooks.useMoney(v.balance) }} </text>
|
||||
</view>
|
||||
<view class="flex-row items-center justify-end space-x-20rpx m-t-10rpx">
|
||||
<!-- <view v-if="v.walletTypeUniqueCode == 1 && !v.cardNumber" class="botder_btn" @tap.stop="openBindDialog(v)">绑定</view> -->
|
||||
<view v-if="v.isRule == '1'" class="botder_btn" @tap.stop="doTransferMoney(v)">转账</view>
|
||||
<view v-if="v.walletTypeUniqueCode == 1 && v.cardNumber && v.isFreeze != 1" class="botder_btn"
|
||||
@tap.stop="openFreezeDialog(v)">
|
||||
申请冻结
|
||||
</view>
|
||||
<view v-if="false && v.walletTypeUniqueCode == 2" class="botder_btn"
|
||||
@tap.stop="router.jump('/pages/wallet/recharge', { id: v.id })">
|
||||
去充值
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
|
||||
<tm-drawer z-index="100" v-model:show="state.showBindDialog" :overlayClick="false" title="绑定饭卡" :show-close="true"
|
||||
position="bottom" size="40%">
|
||||
<view class="h-50rpx" />
|
||||
<tm-form ref="bindFormRef" v-model="bindForm" :rules="bindFormRules">
|
||||
<tm-form-item name="cardNumber" :showLabel="false" :showBottom="false">
|
||||
<tm-input v-model="bindForm.cardNumber" showClear placeholder="请输入卡号..." />
|
||||
</tm-form-item>
|
||||
</tm-form>
|
||||
<view class="h-50rpx" />
|
||||
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx sub-text-30 color-white!" @tap="doBind">绑定</view>
|
||||
</tm-drawer>
|
||||
<tm-drawer z-index="100" v-model:show="state.showFreezeDialog" :overlayClick="true" title="申请冻结" :show-close="true"
|
||||
position="bottom" size="40%">
|
||||
<view class="h-50rpx" />
|
||||
<tm-form ref="bindFormRef" v-model="freezeForm">
|
||||
<tm-form-item name="remark" :showLabel="false" :showBottom="false">
|
||||
<tm-input v-model="freezeForm.remark" type="textarea" showClear placeholder="请输入备注.." />
|
||||
</tm-form-item>
|
||||
</tm-form>
|
||||
<view class="h-50rpx" />
|
||||
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx sub-text-30 color-white!" @tap="doFreeze">冻结</view>
|
||||
</tm-drawer>
|
||||
<tm-drawer z-index="100" v-model:show="state.showQrCodeDialog" :overlayClick="false" title="钱包二维码"
|
||||
:show-close="true" position="bottom" size="50%">
|
||||
<view class="flex-col-center">
|
||||
<view class="h-80rpx" />
|
||||
<canvas canvas-id="qrcodeId" class="size-200px" />
|
||||
</view>
|
||||
</tm-drawer>
|
||||
</template>
|
||||
@@ -0,0 +1,162 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
|
||||
import { hooks, constant } from "@@/index"
|
||||
import { walletApi, payApi } from "@@/api"
|
||||
|
||||
const data = {
|
||||
payType: [
|
||||
// { text: "模拟支付", disabled: false, type: "0", value: "mock" },
|
||||
{ text: "微信支付", disabled: true, type: "1", value: "wx_pub" },
|
||||
{ text: "支付宝支付", disabled: true, type: "2", value: "alipay_wap" },
|
||||
],
|
||||
}
|
||||
|
||||
const state = reactive<any>({
|
||||
walletId: null,
|
||||
currentPayType: null,
|
||||
currentRecharge: 0,
|
||||
userInfo: {},
|
||||
detail: {},
|
||||
rechargeList: [],
|
||||
})
|
||||
|
||||
onLoad((options: any) => {
|
||||
if (!isEmpty(options.id)) {
|
||||
state.walletId = options.id
|
||||
}
|
||||
})
|
||||
onShow(() => {
|
||||
getUserInfo()
|
||||
getDetail()
|
||||
getRechargeList()
|
||||
})
|
||||
|
||||
const getDetail = async () => {
|
||||
const _pa = { walletId: state.walletId }
|
||||
const { data } = await walletApi.detail(_pa)
|
||||
state.detail = data
|
||||
}
|
||||
const getUserInfo = () => {
|
||||
const userInfoKey = constant.storageConstant.USERINFO
|
||||
const userStorage = uni.getStorageSync(userInfoKey)
|
||||
if (!isEmpty(userStorage)) {
|
||||
state.userInfo = userStorage
|
||||
}
|
||||
}
|
||||
const getRechargeList = async () => {
|
||||
const _pa = {}
|
||||
const { data } = await walletApi.rechargeList(_pa)
|
||||
state.rechargeList = data
|
||||
}
|
||||
const doPay = async () => {
|
||||
if (state.currentRecharge == -1) {
|
||||
uni.showToast({ title: "请选择充值金额", icon: "none" })
|
||||
return
|
||||
}
|
||||
if (state.currentPayType == undefined) {
|
||||
uni.showToast({ title: "请选择支付方式", icon: "none" })
|
||||
return
|
||||
}
|
||||
try {
|
||||
uni.showLoading({ title: "充值中...", mask: true })
|
||||
const targetRecharge = state.rechargeList[state.currentRecharge]
|
||||
const targetPayType = data.payType[state.currentPayType]
|
||||
if (isEmpty(targetRecharge)) throw new Error()
|
||||
const _pa = {
|
||||
payPrice: targetRecharge.payPrice,
|
||||
walletId: state.walletId,
|
||||
packageId: targetRecharge.id,
|
||||
}
|
||||
const { data: createData, code: createCode }: any = await walletApi.recharge(_pa)
|
||||
console.log(createCode, "createCode")
|
||||
|
||||
if (createCode != 0) throw new Error()
|
||||
const _payPa = {
|
||||
id: createData.payOrderId,
|
||||
walletId: state.walletId,
|
||||
channelCode: targetPayType.value,
|
||||
channelExtras: {},
|
||||
}
|
||||
getDetail()
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "充值成功", icon: "none" })
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "充值失败", icon: "none" })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="充值" bg="/static/page/blue-bg.png">
|
||||
<view class="h-30rpx" />
|
||||
<view class="flex-row items-center justify-between h-120rpx p-x-30rpx bg-#222222 rounded-20rpx">
|
||||
<view class="flex-row items-center">
|
||||
<view class="flex-row-center size-60rpx bg-white rounded-full">
|
||||
<image class="size-50rpx rounded-full" :src="state.detail.walletIcon" mode="aspectFill" />
|
||||
</view>
|
||||
<view class="flex-row-center">
|
||||
<view class="m-l-25rpx main-text-32 color-#fbddb0!">
|
||||
{{ state.detail.walletTypeName }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="main-text-30 color-#fbddb0!"> ¥{{ hooks.useMoney(state.detail.balance) }} </view>
|
||||
</view>
|
||||
|
||||
<view class="prefix_title m-t-35rpx">充值</view>
|
||||
<view class="recharge p-30rpx bg-white rounded-20rpx m-t-20rpx shadow-main">
|
||||
<view
|
||||
:class="[state.currentRecharge == i ? 'recharge_item_active' : '']"
|
||||
class="recharge_item"
|
||||
v-for="(v, i) in state.rechargeList"
|
||||
:key="i"
|
||||
@tap="state.currentRecharge = i"
|
||||
>
|
||||
<text class="sub-text-30 text-center">¥{{ hooks.useMoney(v.payPrice) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="prefix_title m-t-35rpx">支付</view>
|
||||
<view class="p-30rpx p-b-40rpx bg-white rounded-20rpx m-t-20rpx shadow-main">
|
||||
<tm-radio-group direction="column" gap="40" v-model="state.currentPayType">
|
||||
<tm-radio :disabled="v.disabled" v-for="(v, i) in data.payType" :key="i" :value="v.type" :label="v.text" />
|
||||
</tm-radio-group>
|
||||
</view>
|
||||
<view
|
||||
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!"
|
||||
@tap="doPay"
|
||||
>
|
||||
确认充值
|
||||
</view>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.recharge_item_active {
|
||||
background: #e9f5fe;
|
||||
border: 1px solid #e9f5fe !important;
|
||||
|
||||
& > text {
|
||||
color: #0094ff !important;
|
||||
}
|
||||
}
|
||||
|
||||
.recharge {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-gap: 20rpx;
|
||||
border-bottom: 1px solid #f9f9f9;
|
||||
|
||||
&_item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 16rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,73 @@
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
/**
|
||||
* app领取优惠券
|
||||
*/
|
||||
appGet: (data: any) =>
|
||||
request({
|
||||
url: "/wallet/act/cancel-item/app/get",
|
||||
method: "POST",
|
||||
data,
|
||||
}),
|
||||
/**
|
||||
* app查询用户的唯一优惠券
|
||||
* @param params.actId 活动id
|
||||
*/
|
||||
appFindUnique: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/act/cancel-item/app/find-unique",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
/**
|
||||
* app查询本店优惠券列表
|
||||
* @param params.actStatus 核销类型
|
||||
*/
|
||||
appMchPage: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/act/cancel-item/app/mch/page",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
/**
|
||||
* app创建活动订单
|
||||
* @param data.actId 活动id
|
||||
* @param data.totalPrice 总金额
|
||||
*/
|
||||
appCreateActOrder: (data: any) =>
|
||||
request({
|
||||
url: "/hard/hard-order/app/create-act-order",
|
||||
method: "POST",
|
||||
data,
|
||||
}),
|
||||
/**
|
||||
* 根据公告id查询活动详情
|
||||
* @param data.id 公告id
|
||||
*/
|
||||
getDetailByNoticeId: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/act/act-cancel/app/detail-by-notice-id",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
/**
|
||||
* 根据活动id查询核销活动
|
||||
* @param data.id 活动id
|
||||
*/
|
||||
getDetailById: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/act/act-cancel/app/detail-by-id",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
/**
|
||||
* 用户领取核销券列表
|
||||
*/
|
||||
userList: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/act/cancel-item/app/user-list",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
}
|
||||
@@ -61,4 +61,13 @@ export default {
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
/**
|
||||
* 用户领取核销券列表
|
||||
*/
|
||||
userList: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/act/cancel-item/app/user-list",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
/**
|
||||
* 根据公告id查询对应的活动
|
||||
*/
|
||||
getActByNotifyId: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/act/com/app/get-act-by-notify-id",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
/**
|
||||
* 获取活动详情
|
||||
*/
|
||||
getActDetail: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/act/com/app/get-act-detail",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
/**
|
||||
* 判断用户是否可以参加活动
|
||||
*/
|
||||
isEligibleForAct: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/act/com/app/is-eligible-for-act",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
/**
|
||||
* 用户参加活动的数量统计
|
||||
*/
|
||||
userTotal: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/act/com/app/user-total",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
/**
|
||||
* 领取优惠券
|
||||
*/
|
||||
receive: (data: any) =>
|
||||
request({
|
||||
url: "/wallet/act-coupon-record/app/receive",
|
||||
method: "POST",
|
||||
data,
|
||||
}),
|
||||
/**
|
||||
* 用户领取核销券列表
|
||||
*/
|
||||
userList: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/act-coupon-record/app/user-list",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
foreignList: (params: any) =>
|
||||
request({
|
||||
url: "wallet/wallet-foreign/app/page-join",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
foreignDetail: (params: any) =>
|
||||
request({
|
||||
url: "wallet/wallet-foreign/app/detail",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
codeList: (params: any) =>
|
||||
request({
|
||||
url: "wallet/wallet-code-use/app/code-list",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
getCodeById: (params: any) =>
|
||||
request({
|
||||
url: "wallet/wallet-code-use/app/user-code",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
foreignApply: (data: any) =>
|
||||
request({
|
||||
url: "wallet/wallet-foreign/app/apply",
|
||||
method: "POST",
|
||||
data,
|
||||
}),
|
||||
strideList: (params: any) =>
|
||||
request({
|
||||
url: "wallet/wallet-stride/app/page-join",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
strideDetail: (params: any) =>
|
||||
request({
|
||||
url: "wallet/wallet-stride/app/detail",
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
strideApply: (data: any) =>
|
||||
request({
|
||||
url: "wallet/wallet-stride/app/apply",
|
||||
method: "POST",
|
||||
data,
|
||||
}),
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
export { default as accessStatsApi } from "./access-stats"
|
||||
export { default as actCancel } from "./act-cancel"
|
||||
export { default as actComApi } from "./act-com"
|
||||
export { default as actCouponApi } from "./act-coupon"
|
||||
export { default as actCancelApi } from "./act-cancel"
|
||||
export { default as applyApi } from "./apply"
|
||||
export { default as adApi } from "./ad"
|
||||
export { default as boxesApi } from "./boxes"
|
||||
export { default as faceApi } from "./face"
|
||||
@@ -10,6 +14,7 @@ export { default as orderApi } from "./order"
|
||||
export { default as payApi } from "./pay"
|
||||
export { default as productApi } from "./product"
|
||||
export { default as refundApi } from "./refund"
|
||||
export { default as shopApi } from "./shop"
|
||||
export { default as totalApi } from "./total"
|
||||
export { default as userCarApi } from "./user-car"
|
||||
export { default as userApi } from "./user"
|
||||
|
||||
@@ -2,7 +2,8 @@ import request from "@/sheep/utils/request"
|
||||
|
||||
type AutoAdminLoginDto = {
|
||||
miniPlatformType?: string
|
||||
code?: string
|
||||
phoneCode?: string
|
||||
userCode?: string
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
getSupermarketSpuCategory: (params: any) =>
|
||||
request({
|
||||
url: `/supermarket/supermarketCategory/app/simpleAll`,
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
getSupermarketSpuList: (data: any) =>
|
||||
request({
|
||||
url: `/supermarket/supermarketSpu/app/selectListAll`,
|
||||
method: "POST",
|
||||
data,
|
||||
}),
|
||||
getSupermarketSpuDetail: (params: any) =>
|
||||
request({
|
||||
url: `/supermarket/supermarketSpu/app/SpuDetails`,
|
||||
method: "GET",
|
||||
params,
|
||||
}),
|
||||
checkSpuStock: (params) => {
|
||||
return request({
|
||||
url: "/supermarket/supermarketSpu/app/checkSpuStock",
|
||||
method: "GET",
|
||||
params,
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -61,6 +61,28 @@ const errorMsginiPlatformLoginErrorEnum = {
|
||||
"30": "登录错误",
|
||||
}
|
||||
|
||||
const actCouponTypeEnum = {
|
||||
"1": "满减券",
|
||||
"2": "折扣券",
|
||||
"3": "立减券",
|
||||
"4": "兑换券",
|
||||
}
|
||||
|
||||
// 用户活动状态
|
||||
const actUserReceiveEnum = {
|
||||
"1": "活动不在进行中",
|
||||
"2": "活动不存在",
|
||||
"3": "活动未开启",
|
||||
"4": "已领取,核销码在我的礼券中",
|
||||
"5": "用户不能参加此活动",
|
||||
"6": "其他错误",
|
||||
"99": "用户可以参加活动",
|
||||
// 特殊
|
||||
"-100": "仅限生日当月使用",
|
||||
"-101": "请填写出生日期",
|
||||
"-102": "生日已结束",
|
||||
}
|
||||
|
||||
export default {
|
||||
hardwareOrderStatusEnum,
|
||||
hardwareOrderTypeEnum,
|
||||
@@ -71,4 +93,6 @@ export default {
|
||||
carTypeEnum,
|
||||
actCancelStatusEnum,
|
||||
errorMsginiPlatformLoginErrorEnum,
|
||||
actCouponTypeEnum,
|
||||
actUserReceiveEnum,
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 4.5 KiB |