Files
pj_mini_app_cloud/src/pages/tabbar/my.vue
T
2026-05-18 18:35:35 +08:00

421 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<crud-layout title="我的" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<template #main-top>
<view class="flex items-center py-24rpx px-40rpx" @tap="doUserArea">
<view class="flex items-center" v-if="state.userInfo?.sysUser?.userId">
<image v-if="state.userInfo?.sysUser?.userId" 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>
<text class="iconfont icon-youjiantou" />
</view>
</view>
</template>
<view class="mt-30rpx 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="flex-row-center">
<image class="size-40rpx" :src="v.icon" mode="aspectFill" />
<text class="sub-text-28 m-l-20rpx">{{ v.text }}</text>
</view>
<view class="iconfont icon-youjiantou" />
</view>
</view>
<view 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-#0094ff"
@tap="doLogout">
退出登录
</view>
</view>
<view class="h-30rpx" />
<view v-if="false" 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-#0094ff"
@tap="doChangeRole">
切换角色
</view>
</view>
<view class="second-text-26 text-center flex items-center justify-center">
<view>联系热线:</view>
<view @click="doPhone('18367908152')">18367908152</view>
<view class="w-10rpx" />
<view @click="doPhone('15657370065')">15657370065</view>
</view>
<view class="h-60rpx" />
</crud-layout>
<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>
<view class="w-full flex justify-center gap-48rpx">
<tm-button skin="thin" @tap="actModalCancel">取 消</tm-button>
<tm-button color="primary" @tap="actModalConfirm">确 认</tm-button>
</view>
</template>
</tm-modal>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import dayjs from "dayjs"
import { filePath } from "@@/utils/file"
import { getAppInfo } from "@@/utils/app"
import * as hooks from "@@/hooks"
import * as router from "@@/router"
import * as constant from "@@/constant"
import { accessStatsApi, actCancelApi, userApi } from "@@/api"
import { APPENV } from "@/sheep/constant"
import { SERVICE_IMAGE } from "@@/constant/index"
import ModifyUser from "@@/components/modify-user.vue"
const crudLayoutRef = ref<any>(null)
const modifyUserRef = ref<InstanceType<typeof ModifyUser> | null>(null)
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/user-car/list" },
{ text: "清除缓存", icon: "/static/icon/clear-storage.png", path: "" },
],
appInfo: "",
actModalShow: false,
actVal: {},
})
// 常量
const STORAGE_KEYS = {
TOKEN: constant.storageConstant.TOKEN,
USER_INFO: constant.storageConstant.USERINFO,
}
const storage = {
// 获取存储的用户信息
getUserInfo: () => {
const tokenStorage = uni.getStorageSync(STORAGE_KEYS.TOKEN)
const userStorage = uni.getStorageSync(STORAGE_KEYS.USER_INFO)
if (!isEmpty(userStorage) && !isEmpty(tokenStorage)) {
state.userInfo = userStorage
} else {
state.userInfo = {}
}
},
// 保存用户信息到存储
saveUserInfo: (userData: any) => {
uni.setStorageSync(STORAGE_KEYS.USER_INFO, userData)
storage.getUserInfo()
},
// 保存token到存储
saveToken: (tokenData: any) => {
uni.setStorageSync(STORAGE_KEYS.TOKEN, tokenData)
},
// 清除用户登录相关的存储
clearUserStorage: () => {
uni.removeStorageSync(STORAGE_KEYS.TOKEN)
uni.removeStorageSync(STORAGE_KEYS.USER_INFO)
state.userInfo = {}
},
}
const login = {
// 检查应用环境并登录
checkAppInfo: async () => {
try {
// 先尝试诗画登录
const shihuaResult = await login.shihuaLogin()
if (shihuaResult) return
// 尝试浙政钉登录
const zhengdingResult = login.zhengdingLogin()
if (zhengdingResult) return
uni.showToast({ title: "当前登录环境未知", icon: "none" })
} catch (error) {
console.error("登录失败:", error)
uni.showToast({ title: "登录失败", icon: "none" })
}
},
// 诗画环境登录
shihuaLogin: async () => {
const appInfo = await (window as any).CP2.getAppInfo()
if (appInfo.code == 0) return false
const userInfo = await (window as any).CP2.getUserInfo()
if (userInfo.code == 0) {
uni.showToast({ title: "获取诗画用户信息失败", icon: "none" })
return false
} else {
const { accountId, sessionId } = userInfo.data
return login.doLogin(1, "", accountId, sessionId)
// return login.doLogin(1, "", "67186e49d63fea141aad6772", "67186e49d63fea141aad6776")
}
},
// 浙政钉登录
zhengdingLogin: () => {
const params = new URL(window.location.href).searchParams
const token = params.get("uabaseToken")
if (token) {
return login.doLogin(2, token, "", "")
}
return false
},
// 执行登录操作 - loginType 1:诗画登录 2:浙政钉登录
doLogin: async (loginType: number, token: string, accountId: string, sessionId: string) => {
const tokenStorage = uni.getStorageSync(STORAGE_KEYS.TOKEN)
const userStorage = uni.getStorageSync(STORAGE_KEYS.USER_INFO)
switch (loginType) {
case 1: // 诗画登录
uni.showLoading({ title: "登录中...", mask: true })
const response = await userApi.authsh({ accountId, sessionId })
if (response.code == 0) {
storage.saveToken({ accessToken: response.data.accessToken })
uni.hideLoading()
uni.showToast({ title: "登录成功", icon: "none" })
const { data: userData } = await userApi.userInfo()
storage.saveUserInfo(userData)
} else {
uni.hideLoading()
storage.clearUserStorage()
if (response.msg == "token已失效") {
uni.showToast({ title: "用户凭证已失效,请退出并重新进入浦江县机关事务智慧后勤一体化平台", icon: "none", duration: 6000 })
} else {
uni.showToast({ title: response.msg || "登录失败", icon: "none" })
}
}
break
case 2: // 浙政钉登录
if (isEmpty(tokenStorage) || isEmpty(userStorage)) {
try {
uni.showLoading({ title: "登录中...", mask: true })
const res = await userApi.auth(token)
if (res.code == 0) {
storage.saveToken(res.data)
uni.hideLoading()
uni.showToast({ title: "登录成功", icon: "none" })
const { data: userData } = await userApi.userInfo()
storage.saveUserInfo(userData)
} else {
storage.clearUserStorage()
if (res.msg == "token已失效") {
uni.showToast({ title: "用户凭证已失效,请退出并重新进入浦江县机关事务智慧后勤一体化平台", icon: "none", duration: 6000 })
} else {
uni.showToast({ title: res.msg || "登录失败", icon: "none" })
}
}
} catch (error) {
uni.showToast({ title: "登录错误", icon: "none" })
} finally {
uni.hideLoading()
}
}
break
default:
uni.showToast({ title: "当前登录环境未知", icon: "none" })
}
},
// 退出登录
logout: async () => {
const isLogin = await hooks.useCheckLogin()
if (!isLogin) return
uni.showLoading({ title: "退出登录中...", mask: true })
storage.clearUserStorage()
uni.hideLoading()
router.jump("/pages/root/login")
uni.showToast({ title: "退出登录成功", icon: "none" })
},
// 切换角色
changeRole: () => {
router.jump("/pages/user/userRole")
},
}
// 打开活动核销对话框
const actModalShow = (v) => {
state.actModalShow = true
state.actVal = v
}
// 确认核销
const actModalConfirm = async () => {
try {
uni.showLoading({ title: "核销中...", mask: true })
const { code, msg }: any = await actCancelApi.appCreateActOrder(state.actVal)
if (code != 0) return uni.showToast({ title: msg || "核销失败", icon: "none", duration: 4000 })
uni.showToast({ title: "核销成功", icon: "success" })
state.actModalShow = false
state.actVal = {}
} catch (error) {
uni.showToast({ title: "核销失败", icon: "none" })
} finally {
uni.hideLoading()
}
}
// 取消核销
const actModalCancel = () => {
state.actModalShow = false
state.actVal = {}
}
const { scanCodeAction, processUrlScanResult, processBase64ScanResult } = hooks.useScanCode(actModalShow)
// 扫一扫
const appScanCode = async () => {
const scanResult = await scanCodeAction()
if (!scanResult) {
// uni.showToast({ title: "扫码错误", icon: "none" })
return
}
// 判断扫码结果
if (scanResult.startsWith("http")) {
// 扫码结果是url链接
processUrlScanResult(scanResult.replace("/#", ""))
} else {
// 扫码结果是base64字符串
processBase64ScanResult(scanResult)
}
}
const onTabLogin = () => {
router.jump("/pages/root/login")
}
const onTabMenu = async (item: any) => {
const isLogin = await hooks.useCheckLogin()
if (isLogin) {
if (item.path == "/pages/tabbar/index") return uni.switchTab({ url: item.path })
switch (item.text) {
case "扫一扫":
await appScanCode()
break
case "清除缓存":
uni.showLoading({ title: "清除中...", mask: true })
uni.clearStorageSync()
uni.hideLoading()
uni.showToast({ title: "清除缓存成功", icon: "success" })
uni.navigateTo({ url: "/pages/root/login" })
break
default:
router.jump(item.path)
}
}
}
const doUserArea = () => {
modifyUserRef.value?.open()
}
// 退出登录
const doLogout = async () => {
await login.logout()
}
// 切换角色
const doChangeRole = () => {
login.changeRole()
}
// 初始化配置菜单
const initMenuConfig = () => {
// if (isPreview.value) {
// state.menuList.push(
// { text: "dev-✨导航✨", icon: "/static/icon/service_1.png", path: "/pages/tabbar/index" },
// { text: "dev-外来人员就餐", icon: "/static/icon/service_1.png", path: "/pages/apply/foreign-list" },
// { text: "dev-跨单位就餐", icon: "/static/icon/service_1.png", path: "/pages/apply/stride-list" },
// { text: "dev-包厢预定", icon: "/static/icon/service_4.png", path: "/pages/boxes/apply-list" },
// { text: "dev-第三方应用", icon: "/static/icon/login.png", path: "/pages/thirdApp/happyMall" },
// { text: "dev-登录", icon: "/static/icon/login.png", path: "/pages/root/login" },
// { text: "dev-角色选择", icon: "/static/icon/login.png", path: "/pages/user/userRole" },
// )
// }
}
onLoad(async () => {
// 初始化配置菜单
initMenuConfig()
// 获取应用信息
state.appInfo = await getAppInfo()
await userApi.userRole()
// await isMallMchUser()
// await isMchUser()
// 获取存储中的用户信息
storage.getUserInfo()
})
onShow(() => {
// 获取存储中的用户信息
storage.getUserInfo()
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
const isMallMchUser = async () => {
const { data } = await userApi.isMallMchUser()
if (data) {
state.menuList.unshift({ text: "共富商城商品管理", icon: "/static/icon/service_4.png", path: "/pages/prosperity-shop/goods-manage" })
}
}
const isMchUser = async () => {
const { data } = await userApi.isMerchant()
// 商家查看优惠券列表
if (data) {
state.menuList.unshift({ text: "查看用户领取的优惠券列表", icon: "/static/icon/service_1.png", path: "/pages/merchant/coupon-list" })
}
}
// 联系客服
const doPhone = (phone: string) => {
hooks.useMakePhoneCall(phone)
}
</script>
<style lang="scss" scoped>
.service_item:not(:last-child) {
padding-bottom: 40rpx;
border-bottom: 1px solid #fafafa;
margin-bottom: 40rpx;
}
</style>