Merge branch 'master' of https://gitea.zianxin.com/zax/biz-mobile-react-cloud
# Conflicts: # .env
This commit is contained in:
commit
1211484463
31 files changed
+1274
-340
No files matched your search
@@ -21,14 +21,14 @@ VITE_OAUTH2_APP_CLIENT='mini:mini'
|
||||
#VITE_APP_DEV_SERVICE = http://59.202.170.152:81/api # 信创线上
|
||||
# VITE_APP_DEV_SERVICE = http://192.168.101.174:9999 # 邓-本地
|
||||
VITE_APP_DEV_SERVICE = http://127.0.0.1:9999 # 邓-本地
|
||||
#VITE_APP_DEV_SERVICE = http://123.157.250.162:8089/api # 测试线上
|
||||
# VITE_APP_DEV_SERVICE = http://123.157.250.162:8089/api # 测试线上
|
||||
|
||||
# --------------------------- 开发环境 图片访问基础地址 ---------------------------
|
||||
# VITE_IMAGE_DEV_PATH = https://stgl.pj.gov.cn/api # 域名线上
|
||||
#VITE_IMAGE_DEV_PATH = http://59.202.170.152:81/api # 信创线上
|
||||
# VITE_IMAGE_DEV_PATH = http://192.168.101.174:9999 # 邓-本地
|
||||
VITE_IMAGE_DEV_PATH = http://127.0.0.1:9999
|
||||
#VITE_IMAGE_DEV_PATH = http://123.157.250.162:8089/api # 测试线上
|
||||
#VITE_IMAGE_DEV_PATH = http://127.0.0.1:9999
|
||||
VITE_IMAGE_DEV_PATH = http://123.157.250.162:8089/api # 测试线上
|
||||
|
||||
# --------------------------- 生产环境 api地址 ----------------------------------
|
||||
VITE_APP_PROD_SERVICE = https://stgl.pj.gov.cn/api # 域名线上
|
||||
|
||||
+1
-1
@@ -90,4 +90,4 @@
|
||||
"vite": "5.2.8",
|
||||
"vue-tsc": "^1.0.24"
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
-1
@@ -119,6 +119,20 @@
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "cancel-qrcode",
|
||||
"style": {
|
||||
"navigationBarTitleText": "活动",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "my-act-list",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我参加的活动",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "merchant-activity",
|
||||
"style": {
|
||||
@@ -706,4 +720,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,18 @@
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<view class="bg-white rounded-20rpx my-20rpx font-bold">
|
||||
<z-tabs
|
||||
:list="[
|
||||
{ name: '浙政钉支付', value: 1 },
|
||||
{ name: '支付宝支付', value: 2, disabled: true },
|
||||
]"
|
||||
bar-width="150"
|
||||
:active-style="{
|
||||
<z-tabs :list="[
|
||||
{ name: '浙政钉支付', value: 1 },
|
||||
{ name: '支付宝支付', value: 2, disabled: true },
|
||||
]" bar-width="150" :active-style="{
|
||||
fontSize: '30rpx',
|
||||
}" :inactive-style="{
|
||||
fontSize: '30rpx',
|
||||
}"
|
||||
:inactive-style="{
|
||||
fontSize: '30rpx',
|
||||
}"
|
||||
@change="payMethodTabChange"
|
||||
/>
|
||||
}" @change="payMethodTabChange" />
|
||||
</view>
|
||||
|
||||
<tm-sheet v-if="!state.isUseDoor && state.isUseDoorTip" borderWidth="2" :margin="[0, 20]" padding="10" color="#0094FF22">
|
||||
<tm-sheet v-if="!state.isUseDoor && state.isUseDoorTip" borderWidth="2" :margin="[0, 20]" padding="10"
|
||||
color="#0094FF22">
|
||||
<view class="flex items-center justify-between pl-4">
|
||||
<tm-text font-size="30 " color="#0779FD">{{ state.isUseDoorTip }}</tm-text>
|
||||
<tm-button size="s" @click="goRecharge">去充值</tm-button>
|
||||
@@ -55,18 +50,8 @@
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<tm-modal
|
||||
v-model:show="state.show"
|
||||
:overlayClick="false"
|
||||
title="你是否同意授权"
|
||||
position="bottom"
|
||||
:showCancel="true"
|
||||
height="800rpx"
|
||||
cancelText="拒绝"
|
||||
confirmText="同意"
|
||||
@confirm="appAuthHardDoor(1)"
|
||||
@cancel="appAuthHardDoor(0)"
|
||||
>
|
||||
<tm-modal v-model:show="state.show" :overlayClick="false" title="你是否同意授权" position="bottom" :showCancel="true"
|
||||
height="800rpx" cancelText="拒绝" confirmText="同意" @confirm="appAuthHardDoor(1)" @cancel="appAuthHardDoor(0)">
|
||||
<tm-text color="#999999">{{ state.authDesc }}</tm-text>
|
||||
</tm-modal>
|
||||
</crud-layout>
|
||||
@@ -147,7 +132,7 @@ const openDoor = async () => {
|
||||
}
|
||||
|
||||
// 支付方式tab改变
|
||||
const payMethodTabChange = (e: number) => {}
|
||||
const payMethodTabChange = (e: number) => { }
|
||||
|
||||
// 确认或拒绝协议
|
||||
const appAuthHardDoor = async (type: 1 | 0) => {
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
{{ detail.title }}
|
||||
</view>
|
||||
<view class="meta">
|
||||
<!-- <text class="type-tag" :class="getTypeClass(detail.type)">{{ getTypeLabel(detail.type) }}</text>-->
|
||||
<text v-if="false" class="type-tag" :class="getTypeClass(detail.type)">{{ getTypeLabel(detail.type)
|
||||
}}</text>
|
||||
<text class="time">{{ formatTime(detail.createTime) }}</text>
|
||||
<text class="view-count">浏览 {{ detail.viewCount }}</text>
|
||||
</view>
|
||||
@@ -18,7 +19,8 @@
|
||||
|
||||
<view v-if="detail.attachments && detail.attachments.length > 0" class="attachments">
|
||||
<view class="attachment-title">附件</view>
|
||||
<view v-for="(file, index) in detail.attachments" :key="index" class="attachment-item" @click="downloadFile(file)">
|
||||
<view v-for="(file, index) in detail.attachments" :key="index" class="attachment-item"
|
||||
@click="downloadFile(file)">
|
||||
<text class="file-name">{{ file.name }}</text>
|
||||
<text class="file-size">{{ formatFileSize(file.size) }}</text>
|
||||
</view>
|
||||
@@ -30,21 +32,33 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import { actCancel, noticeApi } from "@/sheep/api"
|
||||
import { actCancel, actComApi, noticeApi } from "@/sheep/api"
|
||||
|
||||
const noticeId = ref("")
|
||||
const detail = ref<any>({})
|
||||
const actDetail = ref<any>({})
|
||||
const actDetail = ref<any>({
|
||||
actId: "",
|
||||
actType: "",
|
||||
detail: {
|
||||
|
||||
onLoad(async (option: any) => {
|
||||
const { id } = option
|
||||
if (!id) return uni.showToast({ title: "参数错误", icon: "error" })
|
||||
const { data = {} }: any = await actCancel.getDetailByNoticeId({ id })
|
||||
actDetail.value = data
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
// 获取活动详情
|
||||
const getActDetail = async () => {
|
||||
if (!noticeId.value) return
|
||||
try {
|
||||
const { data = {} }: any = await actComApi.getActByNotifyId({ notifyId: noticeId.value })
|
||||
actDetail.value = data
|
||||
} catch (error) {
|
||||
console.log("|获取活动详情|,以外的错误error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
const goGetCoupon = () => {
|
||||
uni.navigateTo({ url: `/pages/merchant/merchant-activity?actId=${actDetail.value.id}&mchId=${actDetail.value.mchId}` })
|
||||
uni.navigateTo({ url: `/pages/merchant/merchant-activity?actId=${actDetail.value.actId}&actType=${actDetail.value.actType}` })
|
||||
}
|
||||
|
||||
const nodes = computed(() => {
|
||||
@@ -110,7 +124,7 @@ onLoad(async (options: any) => {
|
||||
const id = options.id
|
||||
if (!id) return
|
||||
noticeId.value = id
|
||||
|
||||
getActDetail()
|
||||
try {
|
||||
// 增加浏览量
|
||||
await noticeApi.addNoticeView(id)
|
||||
|
||||
@@ -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,198 @@
|
||||
<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">
|
||||
<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="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 class="action-btn" @tap="doVisibleQrcode">核销码</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;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,197 @@
|
||||
<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">
|
||||
<image class="size-140rpx rounded-8rpx flex-shrink-0 m-r-10rpx bg-#f0f0f0" src="/static/icon/act_coupon.png"
|
||||
mode="aspectFill" />
|
||||
<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.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 class="action-btn" @tap="doVisibleQrcode">核销码</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;
|
||||
}
|
||||
</style>
|
||||
@@ -1,35 +1,13 @@
|
||||
<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"
|
||||
>
|
||||
<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"
|
||||
>
|
||||
<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>
|
||||
@@ -39,12 +17,9 @@
|
||||
</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="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>
|
||||
|
||||
@@ -1,77 +1,142 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<view v-if="state.actId" class="px-2 py-4">
|
||||
<view class="card rounded-lb-0! rounded-rb-0! w-full h-400rpx relative activity-card overflow-hidden">
|
||||
<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.couponDetail.startTime?.split(" ")[0] || "") + "~" + (state.couponDetail.expireTime?.split(" ")[0] || "") }}
|
||||
{{ (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.couponDetail.actTitle }}</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.couponDetail.activeCancelPrice) }}</text>
|
||||
<text class="text-30 line-through color-red">¥{{ hooks.useMoney(state.couponDetail.activeOrgPrice) }}</text>
|
||||
<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 v-if="state.couponInfo.actStatus == '2'" class="text-center card rounded-lt-0! rounded-rt-0! p-3 sub-text-30">已 核 销</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 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.isGet" class="text-center card rounded-lt-0! rounded-rt-0! p-3 sub-text-30" @tap="getCoupon">立 即 领 取</view>
|
||||
<view v-if="state.isGet" class="text-center card rounded-lt-0! rounded-rt-0! p-3 sub-text-30">已 领 取</view>
|
||||
<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 v-if="state.isGet" class="text-center">
|
||||
<tm-button class="px-32 m-2" @click="genVerificationCode">我的核销码</tm-button>
|
||||
<view class="text-center">
|
||||
<tm-button class="px-32 m-2" @click="doQrcode">我的礼券</tm-button>
|
||||
</view>
|
||||
</template>
|
||||
</crud-layout>
|
||||
|
||||
<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>
|
||||
<modify-user ref="modifyUserRef" warnText="填写出生日期即可领取生日兑换券" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from "vue"
|
||||
import { reactive, ref, nextTick } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import { actCancel } from "@/sheep/api"
|
||||
import uqrcode from "@@/utils/uqrcode"
|
||||
import * as CryptoJS from "crypto-js"
|
||||
import { hooks } from "@/sheep"
|
||||
|
||||
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: "",
|
||||
mchId: "",
|
||||
isGet: false, // 是否已领取
|
||||
couponDetail: {}, // 优惠券详情
|
||||
actType: "",
|
||||
actUserReceiveStatus: "", // 是否已领取
|
||||
actDetail: {}, // 优惠券详情
|
||||
couponInfo: {}, // 优惠券信息
|
||||
userDetail: {},
|
||||
})
|
||||
const showQrCodeDialog = ref(false)
|
||||
|
||||
onLoad((option: any) => {
|
||||
const { actId, mchId } = option
|
||||
if (!actId || !mchId) return uni.showToast({ title: "参数错误", icon: "error" })
|
||||
const { actId, actType } = option
|
||||
if (!actId || !actType) return uni.showToast({ title: "参数错误", icon: "error" })
|
||||
state.actId = actId
|
||||
state.mchId = mchId
|
||||
getCouponDetail()
|
||||
getCouponInfo()
|
||||
state.actType = actType
|
||||
getActDetail()
|
||||
getIsEligibleForAct()
|
||||
if (actType == "CANCEL_ACT") {
|
||||
getCouponInfo()
|
||||
}
|
||||
if (actType == "COUPON_ACT") {
|
||||
specialDispose()
|
||||
}
|
||||
})
|
||||
|
||||
// 获取优惠券详情
|
||||
const getCouponDetail = async () => {
|
||||
const getActDetail = async () => {
|
||||
try {
|
||||
const { data } = await actCancel.getDetailById({
|
||||
id: state.actId,
|
||||
mchId: state.mchId,
|
||||
const { data } = await actComApi.getActDetail({
|
||||
actId: state.actId,
|
||||
actType: state.actType,
|
||||
})
|
||||
state.couponDetail = data
|
||||
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" })
|
||||
}
|
||||
@@ -83,11 +148,9 @@ const getCouponInfo = async () => {
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
const { code, data }: any = await actCancel.appFindUnique({ actId: state.actId })
|
||||
if (!data) {
|
||||
state.isGet = false
|
||||
return
|
||||
}
|
||||
state.couponInfo = data
|
||||
state.isGet = true
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "加载失败", icon: "none" })
|
||||
} finally {
|
||||
@@ -95,19 +158,31 @@ const getCouponInfo = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 领取券
|
||||
const getCoupon = async () => {
|
||||
// 领取优惠券
|
||||
const doReceive = () => {
|
||||
// 核销活动
|
||||
if (state.actType == 'CANCEL_ACT') {
|
||||
getCancelReceive()
|
||||
}
|
||||
// 优惠券活动
|
||||
if (state.actType == 'COUPON_ACT') {
|
||||
getCouponReceive()
|
||||
}
|
||||
}
|
||||
|
||||
// 核销活动
|
||||
const getCancelReceive = async () => {
|
||||
try {
|
||||
uni.showLoading({ title: "正在领取...", mask: true })
|
||||
await new Promise((resolve) => setTimeout(resolve, 2_000))
|
||||
const { code, msg }: any = await actCancel.appGet({
|
||||
receiverUserId: uni.getStorageSync("user_info")?.sysUser?.userId,
|
||||
actId: state.actId,
|
||||
mchId: state.mchId,
|
||||
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 {
|
||||
@@ -115,18 +190,49 @@ const getCoupon = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 生成核销二维码
|
||||
const genVerificationCode = async () => {
|
||||
showQrCodeDialog.value = true
|
||||
const words = CryptoJS.enc.Utf8.parse(JSON.stringify({ cancelId: state.couponInfo.id }))
|
||||
uqrcode.make({
|
||||
canvasId: "qrcodeId",
|
||||
text: CryptoJS.enc.Base64.stringify(words),
|
||||
size: 200,
|
||||
margin: 0,
|
||||
success: (res) => {},
|
||||
complete: () => {},
|
||||
})
|
||||
// 优惠券活动
|
||||
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")
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -139,6 +245,14 @@ const genVerificationCode = async () => {
|
||||
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;
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
<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") {
|
||||
// 特殊情况
|
||||
// 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>
|
||||
+40
-16
@@ -1,17 +1,25 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<template #main-top>
|
||||
<view class="flex items-center py-3 px-5">
|
||||
<image
|
||||
v-if="state.userInfo?.sysUser?.avatar"
|
||||
class="size-100rpx rounded-full"
|
||||
:src="filePath(state.userInfo.sysUser.avatar)"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<image v-else class="w-100rpx h-100rpx rounded-full" src="/static/icon/default-avatar.png" mode="aspectFill" />
|
||||
<view class="ml-30rpx" v-if="state.userInfo?.sysUser?.userId">
|
||||
<view class="sub-text-30">{{ state.userInfo?.sysUser?.name }}</view>
|
||||
<view class="sub-text-26">ID {{ state.userInfo?.sysUser?.userId }}</view>
|
||||
<view class="flex items-center py-3 px-5" @tap="doUserArea">
|
||||
<view class="flex items-center" v-if="state.userInfo?.sysUser?.userId">
|
||||
<image v-if="state.userInfo?.sysUser?.avatar" class="size-100rpx rounded-full"
|
||||
:src="filePath(state.userInfo.sysUser.avatar)" mode="aspectFill" />
|
||||
<image v-else class="w-100rpx h-100rpx rounded-full" src="/static/icon/default-avatar.png"
|
||||
mode="aspectFill" />
|
||||
<view class="ml-30rpx">
|
||||
<view class="flex items-center">
|
||||
<view class="sub-text-30">{{ state.userInfo?.sysUser?.name }}</view>
|
||||
<view v-if="state.userInfo?.sysUser?.birthday"
|
||||
class="ml-20rpx flex items-center bg-#FFFFFF px-16rpx py-6rpx rounded-full shadow-sm">
|
||||
<image class="size-32rpx mr-8rpx" src="/static/icon/birthday.png" mode="aspectFit" />
|
||||
<text class="text-24rpx color-blue font-bold lh-1">
|
||||
{{ dayjs(state.userInfo.sysUser.birthday).format("MM-DD") }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="m-t-5rpx sub-text-26">ID {{ state.userInfo?.sysUser?.userId }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="flex items-center ml-30rpx" @tap="onTabLogin">
|
||||
<text class="sub-text-32">请先登录</text>
|
||||
@@ -21,7 +29,8 @@
|
||||
</template>
|
||||
|
||||
<view class="mt-10rpx rounded-20rpx shadow-main p-30rpx pb-40rpx bg-white">
|
||||
<view class="service_item flex items-center justify-between" v-for="(v, i) in state.menuList" :key="i" @tap="onTabMenu(v)">
|
||||
<view class="service_item flex items-center justify-between" v-for="(v, i) in state.menuList" :key="i"
|
||||
@tap="onTabMenu(v)">
|
||||
<view class="flex-row-center">
|
||||
<image class="size-40rpx" :src="v.icon" mode="aspectFill" />
|
||||
<text class="sub-text-28 m-l-20rpx">{{ v.text }}</text>
|
||||
@@ -31,13 +40,15 @@
|
||||
</view>
|
||||
|
||||
<view v-if="isDevEnv()" class="flex-col-center mt-40rpx mx-30rpx">
|
||||
<view class="w-full text-center sub-text-28 p-y-20rpx rounded-40rpx border-solid border border-#0094ff" @tap="doLogout">
|
||||
<view class="w-full text-center sub-text-28 p-y-20rpx rounded-40rpx border-solid border border-#0094ff"
|
||||
@tap="doLogout">
|
||||
退出登录
|
||||
</view>
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
<view v-if="state.appInfo == APPENV.SH" class="flex-col-center mt-40rpx mx-30rpx">
|
||||
<view class="w-full text-center sub-text-28 p-y-20rpx rounded-40rpx border-solid border border-#0094ff" @tap="doChangeRole">
|
||||
<view class="w-full text-center sub-text-28 p-y-20rpx rounded-40rpx border-solid border border-#0094ff"
|
||||
@tap="doChangeRole">
|
||||
切换角色
|
||||
</view>
|
||||
</view>
|
||||
@@ -50,7 +61,10 @@
|
||||
</view>
|
||||
</crud-layout>
|
||||
|
||||
<tm-modal :show="state.actModalShow" :showCancel="false" title="核销活动兑换券" zIndex="999" @confirm="" @cancel="" @close="">
|
||||
<modify-user ref="modifyUserRef" warnText="填写出生日期即可领取生日兑换券" @close="storage.getUserInfo" />
|
||||
|
||||
<tm-modal :show="state.actModalShow" :showCancel="false" title="核销活动兑换券" zIndex="999" @confirm="" @cancel=""
|
||||
@close="">
|
||||
<view class="text-center text-28">是否核销该活动兑换券?</view>
|
||||
<view class="text-center text-28">确认核销将自动对用户的 消费钱包 扣费</view>
|
||||
<template #footer>
|
||||
@@ -63,7 +77,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive } from "vue"
|
||||
import { reactive, ref } from "vue"
|
||||
import dayjs from "dayjs"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
import { filePath } from "@@/utils/file"
|
||||
@@ -73,11 +88,16 @@ import { actCancel, userApi } from "@@/api"
|
||||
import { isDevEnv } from "@/sheep/utils/app"
|
||||
import { APPENV } from "@/sheep/constant"
|
||||
|
||||
import ModifyUser from "@@/components/modify-user.vue"
|
||||
|
||||
const modifyUserRef = ref<any>()
|
||||
|
||||
const state = reactive<any>({
|
||||
wallet: [],
|
||||
userInfo: {},
|
||||
menuList: [
|
||||
{ text: "扫一扫", icon: "/static/icon/scan.png", path: "" },
|
||||
{ text: "我参加的活动", icon: "/static/icon/act.png", path: "/pages/merchant/my-act-list" },
|
||||
{ text: "我的钱包", icon: "/static/icon/service_3.png", path: "/pages/wallet/list" },
|
||||
{ text: "我的人脸", icon: "/static/icon/service_5.png", path: "/pages/human-face/list" },
|
||||
{ text: "车辆管理", icon: "/static/icon/service_6.png", path: "/pages/car/userCar/list" },
|
||||
@@ -94,6 +114,10 @@ const STORAGE_KEYS = {
|
||||
USER_INFO: constant.storageConstant.USERINFO,
|
||||
}
|
||||
|
||||
const doUserArea = () => {
|
||||
modifyUserRef.value?.open()
|
||||
}
|
||||
|
||||
const storage = {
|
||||
// 获取存储的用户信息
|
||||
getUserInfo: () => {
|
||||
|
||||
+25
-31
@@ -48,14 +48,14 @@ const pageHook = hooks.usePage(
|
||||
getLaunchParam() == "canteen" // 食堂
|
||||
? orderApi.caneenPage
|
||||
: getLaunchParam() == "selfMerchant"
|
||||
? orderApi.supPage
|
||||
: getLaunchParam() == "coopMerchant"
|
||||
? orderApi.supPage
|
||||
: getLaunchParam() == "onlineShop"
|
||||
? orderApi.supPage
|
||||
: getLaunchParam() == "prosperityShop"
|
||||
? orderApi.farmerSpuPage
|
||||
: async () => [],
|
||||
? orderApi.supPage
|
||||
: getLaunchParam() == "coopMerchant"
|
||||
? orderApi.supPage
|
||||
: getLaunchParam() == "onlineShop"
|
||||
? orderApi.supPage
|
||||
: getLaunchParam() == "prosperityShop"
|
||||
? orderApi.farmerSpuPage
|
||||
: async () => [],
|
||||
null,
|
||||
"data.records",
|
||||
)
|
||||
@@ -71,7 +71,7 @@ const doToDetail = (v: any) => {
|
||||
router.jump("/pages/order/detail", { id: v.id })
|
||||
}
|
||||
|
||||
const doAppraise = () => {}
|
||||
const doAppraise = () => { }
|
||||
|
||||
const doRefund = (v: any) => {
|
||||
router.jump("/pages/refund/apply", { id: v.id })
|
||||
@@ -80,20 +80,9 @@ const doRefund = (v: any) => {
|
||||
|
||||
<template>
|
||||
<crud-layout 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"
|
||||
>
|
||||
<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>
|
||||
<view class="bg-white rounded-16rpx px-20rpx my-20rpx">
|
||||
<z-tabs :list="data.tabs" @change="doTab" />
|
||||
@@ -116,15 +105,15 @@ const doRefund = (v: any) => {
|
||||
<view class="flex-row items-center justify-between mt-5rpx second-text-24">
|
||||
<view>
|
||||
<text>下单时间</text>
|
||||
<text class="ml-10rpx">{{ hooks.useTime(v.createTime, "{y}-{m}-{d} {h}:{i}:{s}") }}</text>
|
||||
<text class="ml-10rpx">{{ hooks.useTime(v.createTime, "{y}-{m}-{d} {h}:{i}:{s}")
|
||||
}}</text>
|
||||
</view>
|
||||
<view>{{ hooks.useEnum("hardwareRefundStatusEnum", v.refundStatus) }}</view>
|
||||
</view>
|
||||
<view class="flex-row items-center justify-end mt-1">
|
||||
<text
|
||||
v-if="v.carList?.length && ['5', '20'].includes(v.orderStatus) && ['1', '2'].includes(v.orderType)"
|
||||
class="second-text-30 mr-2"
|
||||
>
|
||||
class="second-text-30 mr-2">
|
||||
共 {{ v.carList.length }} 件
|
||||
</text>
|
||||
<text class="main-text-30 color-red!">¥ {{ hooks.useMoney(v.totalPrice) }}</text>
|
||||
@@ -135,12 +124,16 @@ const doRefund = (v: any) => {
|
||||
<view v-if="['5', '20'].includes(v.orderStatus) && ['1', '2'].includes(v.orderType)">
|
||||
<view class="border-b-2rpx border-dashed border-#eeeeee mt-2"></view>
|
||||
<tm-collapse>
|
||||
<tm-collapse-item :name="i" title="详细购买" titleFontSize="28" activeColor="#000" titleHeight="80" :showBottomLine="false">
|
||||
<view v-if="v.carList.length" class="flex justify-between items-center mb-2 px-3" v-for="(pV, pI) in v.carList" :key="pI">
|
||||
<tm-collapse-item :name="i" title="详细购买" titleFontSize="28" activeColor="#000" titleHeight="80"
|
||||
:showBottomLine="false">
|
||||
<view v-if="v.carList.length" class="flex justify-between items-center mb-2 px-3"
|
||||
v-for="(pV, pI) in v.carList" :key="pI">
|
||||
<view class="flex items-center w-6/10">
|
||||
<view class="size-100rpx">
|
||||
<image v-if="v.payType == '9'" class="size-100rpx rounded-8rpx" :src="pV.productPic" mode="aspectFill" />
|
||||
<image v-else class="size-100rpx rounded-8rpx" :src="filePath(pV.productPic)" mode="aspectFill" />
|
||||
<image v-if="v.payType == '9'" class="size-100rpx rounded-8rpx"
|
||||
:src="pV.productPic" mode="aspectFill" />
|
||||
<image v-else class="size-100rpx rounded-8rpx" :src="filePath(pV.productPic)"
|
||||
mode="aspectFill" />
|
||||
</view>
|
||||
<view class="ml-2 overflow-hidden">
|
||||
<view class="sub-text-26 truncate">{{ pV.productName }}</view>
|
||||
@@ -158,7 +151,8 @@ const doRefund = (v: any) => {
|
||||
|
||||
<view v-if="['5', '10'].includes(v.orderStatus)" class="w-full flex-row items-center justify-end my-1">
|
||||
<!-- <view v-if="v.orderStatus == 5 && v.orderType == 2" class="botder_btn" @tap.stop="doRefund(v)">退款</view> -->
|
||||
<view v-if="v.orderStatus === '5' && ['2', '7'].includes(v.orderType)" class="m-l-20rpx botder_btn" @tap.stop="doToDetail(v)">
|
||||
<view v-if="v.orderStatus === '5' && ['2', '7'].includes(v.orderType)" class="m-l-20rpx botder_btn"
|
||||
@tap.stop="doToDetail(v)">
|
||||
核销码
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -62,11 +62,9 @@ const doSubmit = async () => {
|
||||
</tm-form-item>
|
||||
</tm-form>
|
||||
</view>
|
||||
<view
|
||||
v-if="state.detailType != 'view'"
|
||||
<view v-if="state.detailType != 'view'"
|
||||
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!"
|
||||
@tap="doSubmit"
|
||||
>
|
||||
@tap="doSubmit">
|
||||
登录
|
||||
</view>
|
||||
</crud-layout>
|
||||
|
||||
+20
-56
@@ -29,7 +29,7 @@ const freezeForm = reactive<any>({
|
||||
remark: "",
|
||||
})
|
||||
|
||||
onLoad(() => {})
|
||||
onLoad(() => { })
|
||||
onShow(async () => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (!isLogin) return
|
||||
@@ -140,35 +140,22 @@ const doTransferMoney = (v: any) => {
|
||||
|
||||
<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"
|
||||
>
|
||||
<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="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)" />
|
||||
<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" />
|
||||
@@ -191,14 +178,12 @@ const doTransferMoney = (v: any) => {
|
||||
<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 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 v-if="false && v.walletTypeUniqueCode == 2" class="botder_btn"
|
||||
@tap.stop="router.jump('/pages/wallet/recharge', { id: v.id })">
|
||||
去充值
|
||||
</view>
|
||||
</view>
|
||||
@@ -206,15 +191,8 @@ const doTransferMoney = (v: any) => {
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
|
||||
<tm-drawer
|
||||
z-index="100"
|
||||
v-model:show="state.showBindDialog"
|
||||
:overlayClick="false"
|
||||
title="绑定饭卡"
|
||||
:show-close="true"
|
||||
position="bottom"
|
||||
size="40%"
|
||||
>
|
||||
<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">
|
||||
@@ -224,15 +202,8 @@ const doTransferMoney = (v: any) => {
|
||||
<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%"
|
||||
>
|
||||
<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">
|
||||
@@ -242,15 +213,8 @@ const doTransferMoney = (v: any) => {
|
||||
<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%"
|
||||
>
|
||||
<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" />
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
}
|
||||
@@ -19,6 +19,12 @@ export default {
|
||||
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",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export { default as actCancel } from "./act-cancel"
|
||||
export { default as actComApi } from "./act-com"
|
||||
export { default as actCouponApi } from "./act-coupon"
|
||||
|
||||
export { default as applyApi } from "./apply"
|
||||
|
||||
|
||||
@@ -91,4 +91,11 @@ export default {
|
||||
method: "POST",
|
||||
data,
|
||||
}),
|
||||
// 用户修改个人资料
|
||||
appModifyUser: (data: any) =>
|
||||
request({
|
||||
url: "/admin/user/app/modify",
|
||||
method: "POST",
|
||||
data,
|
||||
}),
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, computed } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { storageConstant } from "@@/constant"
|
||||
import { userApi } from '@@/api'
|
||||
|
||||
const emit = defineEmits(["close"])
|
||||
|
||||
type ModifyUserProps = {
|
||||
warnText?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<ModifyUserProps>(), {
|
||||
warnText: ''
|
||||
})
|
||||
|
||||
const formRef = ref<any>(null)
|
||||
|
||||
const showQrCodeDialog = ref(false)
|
||||
const form = reactive({
|
||||
birthday: ""
|
||||
})
|
||||
|
||||
const rules = {
|
||||
birthday: [{ required: true, message: '请输入生日' }],
|
||||
}
|
||||
|
||||
// 修改用户信息
|
||||
const doFormSubmit = async () => {
|
||||
formRef.value.submit()
|
||||
const { isPass } = formRef.value.validate()
|
||||
if (!isPass) return
|
||||
uni.showLoading({ title: "修改中...", mask: true })
|
||||
try {
|
||||
const res: any = await userApi.appModifyUser({ ...form })
|
||||
if (res.code != 0) {
|
||||
uni.showToast({ title: res.msg ?? "修改失败", icon: "none" })
|
||||
return
|
||||
}
|
||||
uni.showToast({ title: "修改成功", icon: "success" })
|
||||
// 存入缓存
|
||||
const { data: userData } = await userApi.userInfo()
|
||||
uni.setStorageSync(storageConstant.USERINFO, userData)
|
||||
|
||||
showQrCodeDialog.value = false
|
||||
setTimeout(() => uni.hideLoading(), 1000);
|
||||
} catch (error) {
|
||||
console.log("|修改用户信息|意外的错误error:", error);
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
const open = () => {
|
||||
const user = uni.getStorageSync(storageConstant.USERINFO)
|
||||
if (user && user.sysUser) {
|
||||
form.birthday = user.sysUser.birthday
|
||||
}
|
||||
showQrCodeDialog.value = true
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<tm-drawer z-index="100" v-model:show="showQrCodeDialog" title="编辑个人资料" :show-close="true" position="bottom"
|
||||
size="50%" @close="emit('close')">
|
||||
<view v-if="warnText" class="py-20rpx">
|
||||
<tm-alert status="warn" :showClose="false" :margin="[]">{{ warnText }}</tm-alert>
|
||||
</view>
|
||||
<view class="card p-x-30rpx p-y-40rpx">
|
||||
<view class="h-30rpx" />
|
||||
<tm-form ref="formRef" v-model="form" :rules="rules">
|
||||
<tm-form-item name="birthday" label="出生日期" :show-bottom="false">
|
||||
<tm-picker-date v-model="form.birthday" v-model:model-str="form.birthday" format="YYYY-MM-DD"
|
||||
start="1950-1-1" end="2030-12-31">
|
||||
<tm-input v-model="form.birthday" style="pointer-events: none" disabled>
|
||||
</tm-input>
|
||||
</tm-picker-date>
|
||||
</tm-form-item>
|
||||
<view class="h-30rpx" />
|
||||
<tm-button block @tap="doFormSubmit">修改</tm-button>
|
||||
</tm-form>
|
||||
</view>
|
||||
</tm-drawer>
|
||||
</template>
|
||||
@@ -1,3 +1,4 @@
|
||||
// #ifdef WEB
|
||||
import { h, render } from "vue"
|
||||
import VerifyDeviceImpModel from "./verify-device-imp-model.vue"
|
||||
|
||||
@@ -24,3 +25,9 @@ const showVerifyDeviceImpModel = (onClose: () => any = () => null) => {
|
||||
}
|
||||
|
||||
export default showVerifyDeviceImpModel
|
||||
// #endif
|
||||
|
||||
// #ifndef WEB
|
||||
const showVerifyDeviceImpModel = (onClose: () => any = () => null) => {}
|
||||
export default showVerifyDeviceImpModel
|
||||
// #endif
|
||||
@@ -55,6 +55,35 @@ const actCancelStatusEnum = {
|
||||
"3": "已过期",
|
||||
}
|
||||
|
||||
const actCouponLimitTypeEnum = {
|
||||
"1": "活动期间一次",
|
||||
"2": "每天",
|
||||
"3": "每周",
|
||||
"4": "每月",
|
||||
"5": "每年",
|
||||
}
|
||||
|
||||
const actCouponTypeEnum = {
|
||||
"1": "满减券",
|
||||
"2": "折扣券",
|
||||
"3": "立减券",
|
||||
"4": "兑换券",
|
||||
}
|
||||
|
||||
// 用户活动状态
|
||||
const actUserReceiveEnum = {
|
||||
"1": "活动不在进行中",
|
||||
"2": "活动不存在",
|
||||
"3": "活动未开启",
|
||||
"4": "用户参加活动已达上限",
|
||||
"5": "用户不能参加此活动",
|
||||
"6": "其他错误",
|
||||
"99": "用户可以参加活动",
|
||||
// 特殊
|
||||
"-100": "请在生日当月领取",
|
||||
"-101": "请填写出生日期",
|
||||
}
|
||||
|
||||
export default {
|
||||
hardwareOrderStatusEnum,
|
||||
hardwareOrderTypeEnum,
|
||||
@@ -64,4 +93,7 @@ export default {
|
||||
hardwareRefundStatusEnum,
|
||||
carTypeEnum,
|
||||
actCancelStatusEnum,
|
||||
actCouponLimitTypeEnum,
|
||||
actCouponTypeEnum,
|
||||
actUserReceiveEnum,
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
+99
-100
@@ -1,103 +1,102 @@
|
||||
import presetWeapp from "unocss-preset-weapp";
|
||||
import {
|
||||
extractorAttributify,
|
||||
transformerClass,
|
||||
} from "unocss-preset-weapp/transformer";
|
||||
import { defineConfig } from "unocss"
|
||||
import { presetWeapp } from "unocss-preset-weapp"
|
||||
import { extractorAttributify, transformerClass } from "unocss-preset-weapp/transformer"
|
||||
|
||||
const { presetWeappAttributify, transformerAttributify } =
|
||||
extractorAttributify();
|
||||
const { presetWeappAttributify, transformerAttributify } = extractorAttributify()
|
||||
|
||||
export default {
|
||||
presets: [
|
||||
presetWeapp({
|
||||
whRpx: true,
|
||||
}),
|
||||
presetWeappAttributify(),
|
||||
],
|
||||
shortcuts: [
|
||||
{
|
||||
"border-base": "border border-gray-500_10",
|
||||
"flex-col-center": "flex flex-col justify-center items-center",
|
||||
"flex-row-center": "flex flex-row justify-center items-center",
|
||||
"flex-col": "flex flex-col",
|
||||
"flex-row": "flex flex-row",
|
||||
},
|
||||
],
|
||||
theme: {
|
||||
colors: {
|
||||
blue: {
|
||||
DEFAULT: "#0094ff",
|
||||
},
|
||||
red: {
|
||||
DEFAULT: "#f63a36",
|
||||
},
|
||||
yellow: {
|
||||
DEFAULT: "#F2A817",
|
||||
},
|
||||
},
|
||||
},
|
||||
rules: [
|
||||
[
|
||||
/^main-text-(\d+)$/,
|
||||
([, d]) => ({
|
||||
"font-size": `${d}rpx`,
|
||||
"font-weight": 800,
|
||||
color: "#000",
|
||||
"line-height": `1.4em`,
|
||||
}),
|
||||
],
|
||||
[
|
||||
/^sub-text-(\d+)$/,
|
||||
([, d]) => ({
|
||||
"font-size": `${d}rpx`,
|
||||
"font-weight": 500,
|
||||
color: "#333",
|
||||
"line-height": `1.4em`,
|
||||
}),
|
||||
],
|
||||
[
|
||||
/^second-text-(\d+)$/,
|
||||
([, d]) => ({
|
||||
"font-size": `${d}rpx`,
|
||||
"font-weight": 500,
|
||||
color: "#999",
|
||||
"line-height": `1.4em`,
|
||||
}),
|
||||
],
|
||||
[
|
||||
"card",
|
||||
{
|
||||
"background-color": "white",
|
||||
"box-shadow": "0rpx 8rpx 26rpx -4rpx rgba(210,210,210,0.5)",
|
||||
"border-radius": "16rpx",
|
||||
},
|
||||
],
|
||||
[
|
||||
"shadow-main",
|
||||
{
|
||||
"box-shadow": "0rpx 0rpx 4rpx 0rpx rgba(0, 0, 0, 0.1)",
|
||||
},
|
||||
],
|
||||
[
|
||||
/^show-line$/,
|
||||
([, d]) => ({
|
||||
overflow: "hidden",
|
||||
"white-space": "nowrap",
|
||||
"text-overflow": "ellipsis",
|
||||
}),
|
||||
],
|
||||
[
|
||||
/^show-line-(\d+)$/,
|
||||
([, d]) => ({
|
||||
display: "-webkit-box !important",
|
||||
overflow: "hidden",
|
||||
"text-overflow": "ellipsis !important",
|
||||
"word-break": "break-all",
|
||||
"-webkit-line-clamp": d,
|
||||
"-webkit-box-orient": "vertical !important",
|
||||
}),
|
||||
],
|
||||
],
|
||||
|
||||
transformers: [transformerAttributify(), transformerClass()],
|
||||
};
|
||||
content: {
|
||||
filesystem: ["src/**/*.{vue,js,ts,jsx,tsx}"],
|
||||
},
|
||||
presets: [
|
||||
presetWeapp({
|
||||
whRpx: true,
|
||||
}),
|
||||
presetWeappAttributify(),
|
||||
],
|
||||
transformers: [transformerAttributify(), transformerClass()],
|
||||
shortcuts: [
|
||||
{
|
||||
"border-base": "border border-gray-500_10",
|
||||
"flex-col-center": "flex flex-col justify-center items-center",
|
||||
"flex-row-center": "flex flex-row justify-center items-center",
|
||||
"flex-col": "flex flex-col",
|
||||
"flex-row": "flex flex-row",
|
||||
},
|
||||
],
|
||||
theme: {
|
||||
colors: {
|
||||
blue: {
|
||||
DEFAULT: "#0094ff",
|
||||
},
|
||||
red: {
|
||||
DEFAULT: "#f63a36",
|
||||
},
|
||||
yellow: {
|
||||
DEFAULT: "#F2A817",
|
||||
},
|
||||
},
|
||||
},
|
||||
rules: [
|
||||
[
|
||||
/^main-text-(\d+)$/,
|
||||
([, d]) => ({
|
||||
"font-size": `${d}rpx`,
|
||||
"font-weight": 800,
|
||||
color: "#000",
|
||||
"line-height": `1.4em`,
|
||||
}),
|
||||
],
|
||||
[
|
||||
/^sub-text-(\d+)$/,
|
||||
([, d]) => ({
|
||||
"font-size": `${d}rpx`,
|
||||
"font-weight": 500,
|
||||
color: "#333",
|
||||
"line-height": `1.4em`,
|
||||
}),
|
||||
],
|
||||
[
|
||||
/^second-text-(\d+)$/,
|
||||
([, d]) => ({
|
||||
"font-size": `${d}rpx`,
|
||||
"font-weight": 500,
|
||||
color: "#999",
|
||||
"line-height": `1.4em`,
|
||||
}),
|
||||
],
|
||||
[
|
||||
"card",
|
||||
{
|
||||
"background-color": "white",
|
||||
"box-shadow": "0rpx 8rpx 26rpx -4rpx rgba(210,210,210,0.5)",
|
||||
"border-radius": "16rpx",
|
||||
},
|
||||
],
|
||||
[
|
||||
"shadow-main",
|
||||
{
|
||||
"box-shadow": "0rpx 0rpx 4rpx 0rpx rgba(0, 0, 0, 0.1)",
|
||||
},
|
||||
],
|
||||
[
|
||||
/^show-line$/,
|
||||
([, d]) => ({
|
||||
overflow: "hidden",
|
||||
"white-space": "nowrap",
|
||||
"text-overflow": "ellipsis",
|
||||
}),
|
||||
],
|
||||
[
|
||||
/^show-line-(\d+)$/,
|
||||
([, d]) => ({
|
||||
display: "-webkit-box !important",
|
||||
overflow: "hidden",
|
||||
"text-overflow": "ellipsis !important",
|
||||
"word-break": "break-all",
|
||||
"-webkit-line-clamp": d,
|
||||
"-webkit-box-orient": "vertical !important",
|
||||
}),
|
||||
],
|
||||
],
|
||||
}
|
||||
Reference in new issue
Block a user