feat:设备验证

This commit is contained in:
dzc committed 2026-04-17 14:54:47 +08:00
1 parent d1127ab5f8
commit 552a006e25
27 files changed
+962 -820

No files matched your search

+4 -4
View File
@@ -17,13 +17,13 @@ VITE_PWD_ENC_KEY='pigxpigxpigxpigx'
VITE_OAUTH2_APP_CLIENT='mini:mini'
# --------------------------- start 开发环境 start ----------------------------------
VITE_APP_DEV_SERVICE = https://stgl.pj.gov.cn/api
# VITE_APP_DEV_SERVICE = https://stgl.pj.gov.cn/api
# VITE_APP_DEV_SERVICE = http://localhost:9999
# VITE_APP_DEV_SERVICE = https://dzc-test-1.fy.takin.cc
VITE_APP_DEV_SERVICE = https://dzc-test-1.fy.takin.cc
# VITE_IMAGE_DEV_PATH = http://localhost:9999
# VITE_IMAGE_DEV_PATH = https://dzc-test-1.fy.takin.cc/api
VITE_IMAGE_DEV_PATH = https://stgl.pj.gov.cn/api
VITE_IMAGE_DEV_PATH = https://dzc-test-1.fy.takin.cc/api
# VITE_IMAGE_DEV_PATH = https://stgl.pj.gov.cn/api
# ----------------------------- end 开发环境 end ------------------------------------
# --------------------------- start 生产环境 start ----------------------------------
+2
View File
@@ -14,7 +14,9 @@ export default {
console.log("App Launch");
const _this = this;
uni.hideTabBar()
// #ifdef MP-WEIXIN
wx.onAppRoute(_this.watchRouter)
// #endif
},
onShow() {
console.log("App Show");
-7
View File
@@ -158,13 +158,6 @@
"navigationBarTitleText": "",
"disableScroll": true
}
},
{
"path": "recharge-record",
"style": {
"navigationBarTitleText": "充值记录",
"disableScroll": true
}
}
]
},
+8 -3
View File
@@ -1,5 +1,5 @@
<template>
<crud-layout :title="scanPayState.mchName" :bg="filePath(SERVICE_IMAGE.blueBg)">
<crud-layout :title="scanPayState.mchName" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<view class="h-screen flex flex-col">
<tm-sheet :margin="[0, 10]" class="flex flex-row">
<span class="text-2xl text-[#333] mr-8rpx line-height-normal">¥</span>
@@ -31,7 +31,7 @@
</template>
<script setup lang="ts">
import { ref, computed, reactive } from "vue"
import { ref, computed, reactive, onMounted, nextTick } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import payApi from "@@/api/pay"
@@ -45,6 +45,7 @@ import { isEmpty } from "radash"
import NumberKeyboard from "@/sheep/components/number-keyboard.vue"
import { SERVICE_IMAGE } from "@@/constant/index"
const crudLayoutRef = ref<any>(null)
const loading = ref(false)
const scanPayState = reactive({
mchId: "", // 商户id
@@ -83,7 +84,6 @@ onLoad(async (options: any) => {
return uni.showToast({ title: "扫码参数错误", icon: "none" })
})
onShow(async () => {
try {
await getWalletList()
@@ -91,6 +91,11 @@ onShow(async () => {
uni.hideLoading()
}
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
// 获取商户名
const getMchDetail = async (mchId: string) => {
+9 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { reactive, computed } from "vue"
import { ref, reactive, computed, defineAsyncComponent, nextTick, onMounted } from "vue"
import { onHide, onShow } from "@dcloudio/uni-app"
import { router } from "@@/index"
@@ -13,6 +13,7 @@ import Empty from "@@/components/empty/empty.vue"
const tabbarStore = useTabbarStore()
const crudLayoutRef = ref()
const state = reactive<any>({
swiperList: [
{
@@ -45,6 +46,12 @@ onShow(() => {
getAppMenuList()
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
onHide(() => {
})
@@ -93,7 +100,7 @@ const getAppMenuList = async () => {
</script>
<template>
<crud-layout title="智慧后勤系统" :bg="filePath(SERVICE_IMAGE.blueBg)">
<crud-layout title="智慧后勤系统" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<view class="h-20rpx" />
<swiper class="w-full h-280rpx rounded-16rpx overflow-hidden" circular :indicator-dots="true"
indicator-active-color="#0779FD" indicator-color="#ffffff" :autoplay="true">
+12 -1
View File
@@ -2,7 +2,7 @@
import { ref, reactive } from "vue"
import { onShow } from "@dcloudio/uni-app"
import { constant, router } from "@@/index"
import { userApi, miniPlatformApi } from "@@/api"
import { userApi, miniPlatformApi, walletApi } from "@@/api"
import { getAppInfo } from "@@/utils/app"
import { SERVICE_IMAGE } from "@@/constant/index"
import { filePath } from "@@/utils/file"
@@ -57,6 +57,7 @@ const minAppGetphone = async (e) => {
// 查询用户信息
const { data: userData } = await userApi.userInfo()
uni.setStorageSync(constant.storageConstant.USERINFO, userData)
await createWallet()
uni.hideLoading()
uni.showToast({ title: "登录成功", icon: "success" })
router.jump("/pages/root/dashboard", {}, 3)
@@ -74,6 +75,16 @@ const doLogin = () => {
}
}
// 创建钱包
const createWallet = async () => {
try {
const { data, code }: any = await walletApi.createTopupWallet()
if (code != 0) throw new Error()
} catch (error) {
console.error("创建钱包意外的错误error:", error)
}
}
const affirmConfirm = () => {
state.isAgree = true
}
+13 -1
View File
@@ -2,12 +2,13 @@
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { constant, router } from "@@/index"
import { userApi } from "@@/api"
import { userApi, walletApi } from "@@/api"
import { SERVICE_IMAGE } from "@@/constant/index"
import { filePath } from "@@/utils/file"
import AffirmCheck from "@/sheep/components/common/affirm-check.vue"
import AffirmModal from "@/sheep/components/common/affirm-modal.vue"
import VerifyDeviceImpModel from "@/sheep/components/verify-device-imp-model.vue"
const affirmModalRef = ref()
const state = reactive<any>({
@@ -69,11 +70,22 @@ const doSubmit = async () => {
username: applyForm.username,
password: applyForm.password,
} as GlobalSetting.RememberUser)
await createWallet()
uni.hideLoading()
uni.showToast({ title: "登录成功", icon: "none" })
router.jump("/pages/root/dashboard", {}, 3)
}
// 创建钱包
const createWallet = async () => {
try {
const { data, code }: any = await walletApi.createTopupWallet()
if (code != 0) throw new Error()
} catch (error) {
console.error("创建钱包意外的错误error:", error)
}
}
const disposeLogin = () => {
applyFormRef.value.submit()
const { isPass } = applyFormRef.value.validate()
+13 -2
View File
@@ -1,5 +1,5 @@
<template>
<crud-layout :bg="filePath(SERVICE_IMAGE.blueBg)">
<crud-layout :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<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">
@@ -28,21 +28,32 @@
</template>
<script setup lang="ts">
import { ref } from "vue"
import { ref, onMounted, nextTick } from "vue"
import { hooks, router } from "@/sheep"
import { doorApi } from "@/sheep/api"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { filePath } from "@@/utils/file"
import { SERVICE_IMAGE } from "@@/constant/index"
const pageRef = ref<any>(null)
const crudLayoutRef = ref<any>(null)
onLoad(() => {
})
onShow(() => {
if (pageRef.value) {
pageRef.value.reload(false)
}
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
const pageHook = hooks.usePage(pageRef, doorApi.hardDoorPage, null, "data.records")
const query = (page: number, pagesize: number) => {
+9 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, reactive, nextTick } from "vue"
import { ref, reactive, nextTick, onMounted } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import dayjs from "dayjs"
@@ -8,6 +8,7 @@ import { accessStatsApi, merchantApi } from "@@/api"
import { filePath } from "@@/utils/file"
import { SERVICE_IMAGE } from "@@/constant/index"
const crudLayoutRef = ref<any>(null)
const state = reactive<any>({
pa: {
pagesize: 10,
@@ -24,6 +25,12 @@ onShow(async () => {
}
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
const pageRef = ref<any>(null)
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
const STORAGE_KEYS = {
@@ -43,7 +50,7 @@ const toDetail = async (v: any) => {
</script>
<template>
<crud-layout title="食堂" :bg="filePath(SERVICE_IMAGE.blueBg)">
<crud-layout title="食堂" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<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">
+9 -2
View File
@@ -1,5 +1,5 @@
<template>
<crud-layout title="喜好分析" :bg="filePath(SERVICE_IMAGE.blueBg)">
<crud-layout title="喜好分析" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<z-paging ref="pageRef" height="100%" :fixed="false" 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" hide-empty-view>
@@ -79,7 +79,7 @@
<script setup lang="ts">
import { onLoad } from "@dcloudio/uni-app"
import { ref } from "vue"
import { ref, onMounted, nextTick } from "vue"
import qiunDataCharts from "@/components/qiun-data-charts/qiun-data-charts.vue"
import { totalApi } from "@/sheep/api"
@@ -87,6 +87,7 @@ import { hooks } from "@/sheep"
import { SERVICE_IMAGE } from "@@/constant/index"
import { filePath } from "@@/utils/file"
const crudLayoutRef = ref<any>(null)
const pieChartData = ref({})
const areaChartData = ref({})
const productLikeTopList = ref<any>([])
@@ -158,6 +159,12 @@ const areaChartOpts = {
}
onLoad(() => {
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
const pageRef = ref<any>(null)
+8 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { ref, reactive, onMounted, nextTick } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { merchantApi } from "@@/api"
@@ -8,6 +8,7 @@ import { filePath } from "@@/utils/file"
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
import { SERVICE_IMAGE } from "@@/constant/index"
const crudLayoutRef = ref<any>(null)
const pageRef = ref<any>(null)
const state = reactive<any>({
pa: {
@@ -44,6 +45,11 @@ onShow(() => {
const search = () => {
pageRef.value && pageRef.value.reload(true)
}
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
const doTab = (e: any) => {
const target = state.tabs[e]
@@ -63,7 +69,7 @@ const toDetail = async (v: any) => {
</script>
<template>
<crud-layout title="合作商家" :bg="filePath(SERVICE_IMAGE.blueBg)">
<crud-layout title="合作商家" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<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">
+8 -3
View File
@@ -1,5 +1,5 @@
<template>
<crud-layout :bg="filePath(SERVICE_IMAGE.blueBg)">
<crud-layout :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<div class="integrated-title-card">
<div class="integrated-title">综合服务</div>
</div>
@@ -30,7 +30,7 @@
<script setup lang="ts">
import { onLoad } from "@dcloudio/uni-app"
import { ref, onMounted } from "vue"
import { ref, onMounted, nextTick } from "vue"
import { filePath } from "@@/utils/file"
import { SERVICE_IMAGE } from "@@/constant/index"
@@ -39,6 +39,7 @@ import integratedApi from "@/sheep/api/integrated"
import { hooks } from "@@/index"
const todoCount = ref(0)
const crudLayoutRef = ref<any>(null)
const services = [
{
@@ -101,7 +102,11 @@ async function fetchTodoCount() {
onLoad(() => {
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
onMounted(() => {
fetchTodoCount()
})
+8 -3
View File
@@ -1,5 +1,5 @@
<template>
<crud-layout title="我的" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
<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">
@@ -76,7 +76,7 @@
</template>
<script setup lang="ts">
import { ref, reactive, computed } from "vue"
import { ref, reactive, computed, onMounted, nextTick } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import dayjs from "dayjs"
@@ -89,6 +89,7 @@ import { SERVICE_IMAGE } from "@@/constant/index"
import ModifyUser from "@@/components/modify-user.vue"
const crudLayoutRef = ref<any>(null)
const modifyUserRef = ref(null)
const state = reactive<any>({
wallet: [],
@@ -375,7 +376,11 @@ onShow(() => {
// 获取存储中的用户信息
storage.getUserInfo()
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
const isMallMchUser = async () => {
const { data } = await userApi.isMallMchUser()
+9 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { ref, reactive, onMounted, nextTick } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { hooks, router } from "@@/index"
@@ -13,6 +13,7 @@ import { useTabbarStore } from "@@/stores/tabbar"
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
import { getLaunchParam } from "@/sheep/utils/app"
const crudLayoutRef = ref<any>(null)
const tabbarStore = useTabbarStore()
const data = {
tabs: [
@@ -38,6 +39,12 @@ onShow(async () => {
pageRef.value.reload(false)
}
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
const doTab = (e: any) => {
const target = data.tabs[e]
state.pa.orderStatus = target.id
@@ -78,7 +85,7 @@ const doRefund = (v: any) => {
</script>
<template>
<crud-layout title="订单" :bg="filePath(SERVICE_IMAGE.blueBg)">
<crud-layout title="订单" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<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">
+8 -2
View File
@@ -1,5 +1,5 @@
<template>
<crud-layout title="共富商城" :bg="filePath(SERVICE_IMAGE.blueBg)">
<crud-layout title="共富商城" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<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">
@@ -75,12 +75,13 @@ import { hooks, router } from "@/sheep"
import { prosperityShopApi } from "@/sheep/api"
import { onLoad } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import { reactive, ref } from "vue"
import { reactive, ref, onMounted, nextTick } from "vue"
import { filePath } from "@@/utils/file"
import { displayPrice } from "@/sheep/utils/format-money"
import { SERVICE_IMAGE } from "@@/constant/index"
const crudLayoutRef = ref<any>(null)
const state = reactive<any>({
params: {
keyword: "",
@@ -96,6 +97,11 @@ const query = (page: number, pagesize: number) => {
onLoad(async () => {
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
// 切换分类
// const doClassify = async (categoryId: string) => {
+9 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { ref, reactive, onMounted, nextTick } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { merchantApi } from "@@/api"
@@ -8,7 +8,9 @@ import { filePath } from "@@/utils/file"
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
import { SERVICE_IMAGE } from "@@/constant/index"
const crudLayoutRef = ref<any>(null)
const pageRef = ref<any>(null)
const state = reactive<any>({
pa: {
pagesize: 10,
@@ -45,6 +47,11 @@ onLoad(async () => {
onShow(() => {
pageRef.value && pageRef.value.reload(false)
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
const search = () => {
pageRef.value && pageRef.value.reload(true)
@@ -71,7 +78,7 @@ const toDetail = async (v: any) => {
</script>
<template>
<crud-layout title="共富商家" :bg="filePath(SERVICE_IMAGE.blueBg)">
<crud-layout title="共富商家" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<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">
+8 -2
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { ref, reactive, onMounted, nextTick } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { merchantApi } from "@@/api"
@@ -7,6 +7,7 @@ import { hooks, router } from "@@/index"
import { filePath } from "@@/utils/file"
import { SERVICE_IMAGE } from "@@/constant/index"
const crudLayoutRef = ref<any>(null)
const pageRef = ref<any>(null)
const state = reactive<any>({
pa: {
@@ -26,6 +27,11 @@ onLoad(() => {
onShow(async () => {
pageRef.value && pageRef.value.reload(false)
})
onMounted(() => {
nextTick(() => {
crudLayoutRef.value?.checkVerifyDevice?.()
})
})
const toDetail = async (v: any) => {
const isLogin = await hooks.useCheckLogin()
@@ -36,7 +42,7 @@ const toDetail = async (v: any) => {
</script>
<template>
<crud-layout title="自营商家" :bg="filePath(SERVICE_IMAGE.blueBg)">
<crud-layout title="自营商家" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
<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">
+2 -3
View File
@@ -102,8 +102,7 @@ const doPay = async () => {
}
const toRechargeRecord = () => {
return
router.jump("/pages/wallet/recharge-record", { walletId: state.walletId })
router.jump("/pages/wallet/detail", { id: state.walletId })
}
</script>
@@ -124,7 +123,7 @@ const toRechargeRecord = () => {
</view>
</view>
<view class="main-text-30 color-#fbddb0!"> ¥{{ hooks.useMoney(state.detail.balance) }} </view>
<view v-if="false" class="recharge-record-tag">
<view class="recharge-record-tag">
<text class="recharge-record-tag__text">充值记录</text>
</view>
</view>
+8
View File
@@ -119,6 +119,14 @@ export default {
data,
}),
// 判断该设备是否被验证
isVerifyDevice: (data: { mobile: string; userId: string }) =>
request({
url: "/thirdparty/thirdPartyOAth2/is-verify-device",
method: "POST",
data,
}),
// 用户注册
register: (data: any) =>
request({
+5
View File
@@ -1,6 +1,11 @@
import request from "@/sheep/utils/request"
export default {
createTopupWallet: (): Promise<any> =>
request({
url: "/wallet/wallet-manage/app/topup-wallet",
method: "GET",
}),
all: (): Promise<any> =>
request({
url: "/wallet/wallet-manage/app/get-all",
@@ -1,9 +1,12 @@
<script setup lang="ts">
import { watch, reactive, onMounted, computed } from "vue"
import { ref, watch, reactive, onMounted, computed } from "vue"
import { router } from "@@/index"
import { router, constant } from "@@/index"
import { useTabbarStore } from "@@/stores/tabbar"
import { jump } from "@/sheep/router";
import { userApi } from "@@/api/index"
import VerifyDeviceImpModel from "../../verify-device-imp-model.vue"
const tabbarStore = useTabbarStore()
@@ -18,6 +21,7 @@ export type Props = {
bg: string
}
const verifyDeviceImpModelRef = ref()
const props = withDefaults(defineProps<Props>(), {
tabBarType: "default",
title: "",
@@ -88,6 +92,41 @@ function tabbarChange(index: number) {
if (!target) return
jump(target.pagePath, {}, 3)
}
// 校验该设备是否被验证
async function checkVerifyDevice() {
// 从本地存储中获取用户信息
const userInfo = uni.getStorageSync(constant.storageConstant.USERINFO)
if (!userInfo || !userInfo.sysUser || !userInfo.sysUser.userId) return
// 是否在白名单中
if (constant.DEVICE_VERIFY_WRITE_LIST.includes(userInfo.sysUser.phone)) {
return
}
const _params = {
mobile: userInfo.sysUser.phone,
userId: userInfo.sysUser.userId,
}
try {
const { data, code }: any = await userApi.isVerifyDevice(_params)
if (code != 0) {
throw new Error()
}
if (data === false) {
verifyDeviceImpModelRef.value?.openDialog(userInfo.sysUser.phone)
}
} catch (error: any) {
console.log("校验该设备是否被验证意外的错误error:", error)
uni.showToast({ title: error.msg ?? "设备验证错误", icon: "none", })
}
}
function verifyDeviceImpModelClose() {
}
defineExpose({
checkVerifyDevice
})
</script>
<template>
@@ -118,6 +157,7 @@ function tabbarChange(index: number) {
borderColor="#DBDDDE" color="#8E8E8E" selected-color="#0094ff" position="fixed" @change="tabbarChange">
</tm-tabbar>
</view>
<VerifyDeviceImpModel ref="verifyDeviceImpModelRef" :close="verifyDeviceImpModelClose" />
</view>
</template>
+2
View File
@@ -5,3 +5,5 @@ export { default as storageConstant } from "./storage-constant"
export { default as APPENV } from "./app-env"
export * from "./service-image"
export * from "./write-list"
+3
View File
@@ -0,0 +1,3 @@
export const DEVICE_VERIFY_WRITE_LIST = [
"17683843144",
]
@@ -3,8 +3,8 @@ import { ref, computed, onMounted, onBeforeUnmount, watch, PropType, getCurrentI
import { arrayNumberValid, arrayNumberValidByStyleMP, covetUniNumber, arrayNumberValidByStyleBorderColor, linearValid, getUnit, getUid } from "../../libs/tool";
import { getDefaultColor, getDefaultColorObj, getOutlineColorObj, getTextColorObj, getThinColorObj } from "../../libs/colors";
import { useTmConfig } from "../../libs/config";
import {onLoad, onPageScroll,onReady} from '@dcloudio/uni-app';
import {$i18n} from "@/uni_modules/tm-ui"
import { onLoad, onPageScroll, onReady } from '@dcloudio/uni-app';
import { $i18n } from "@/uni_modules/tm-ui"
/**
* @displayName 抽屉
* @exportName tm-drawer
@@ -12,8 +12,8 @@ import {$i18n} from "@/uni_modules/tm-ui"
* @description 提供四个方向的弹出。
* @constant 平台兼容
* | H5 | uniAPP | 小程序 | version |
| --- | --- | --- | --- |
| ☑️| ☑️ | ☑️ | ☑️ | ☑️ | 1.0.0 |
| --- | --- | --- | --- |
| ☑️| ☑️ | ☑️ | ☑️ | ☑️ | 1.0.0 |
*/
defineOptions({ name: 'TmDrawer' });
const { config } = useTmConfig()
@@ -195,15 +195,15 @@ const props = defineProps({
* 关闭前执行,可以是异步函数,只有当用户点击confirm时才会触发。如果返回false将阻止关闭。true允许关闭。
*/
beforeClose: {
type: [Function,Boolean] as PropType<() => Promise<boolean>>,
type: [Function, Boolean] as PropType<() => Promise<boolean>>,
default: true
},
/**
* 是否禁用弹层
*/
disabled: {
type: Boolean,
default: false
type: Boolean,
default: false
},
/**
* 是否禁用teleport(H5平台)
@@ -272,30 +272,30 @@ const teleportElH5 = ref("#app")
const teleportTarget = ref<string | null>(null)
// #ifdef H5
const getTeleportTarget = () => {
try {
// 优先尝试 uni-page
if (document.querySelector('#uni-page')) {
return '#uni-page'
}
// 备用方案:尝试 app
if (document.querySelector('#app')) {
return '#app'
}
// 最后备用:body
return 'body'
} catch (error) {
console.warn('Failed to get teleport target:', error)
return 'body'
}
try {
// 优先尝试 uni-page
if (document.querySelector('#uni-page')) {
return '#uni-page'
}
// 备用方案:尝试 app
if (document.querySelector('#app')) {
return '#app'
}
// 最后备用:body
return 'body'
} catch (error) {
console.warn('Failed to get teleport target:', error)
return 'body'
}
}
// 检查teleport目标是否可用
const isTeleportTargetValid = (target: string) => {
try {
return !!document.querySelector(target)
} catch {
return false
}
try {
return !!document.querySelector(target)
} catch {
return false
}
}
// #endif
watch(() => props.show, (newVal) => {
@@ -378,27 +378,27 @@ const __height = computed(() => {
})
const _titleFontSize = computed(() => (config.fontSizeScale * 16).toString() + 'px')
const _isDark = computed(() => config.mode == 'dark')
const setDomHeight = ()=>{
let sys = uni.getWindowInfo()
// #ifdef WEB
_width.value = sys.windowWidth
_height.value = sys.windowHeight
const setDomHeight = () => {
let sys = uni.getWindowInfo()
// #ifdef WEB
_width.value = sys.windowWidth
_height.value = sys.windowHeight
windtop.value = sys.windowTop + (_position.value=='bottom'?0:_offset.value)
windtopReal.value = _position.value=='bottom'?(sys.windowTop +_offset.value):sys.windowTop
// #endif
// #ifdef APP
_width.value = sys.windowWidth
_height.value = sys.windowHeight
windtop.value = _offset.value
// #endif
safeFooterHeight.value = (sys.safeAreaInsets?.bottom??0) == 0 ? 16 : sys.safeAreaInsets.bottom
windtop.value = sys.windowTop + (_position.value == 'bottom' ? 0 : _offset.value)
windtopReal.value = _position.value == 'bottom' ? (sys.windowTop + _offset.value) : sys.windowTop
// #endif
// #ifdef APP
_width.value = sys.windowWidth
_height.value = sys.windowHeight
windtop.value = _offset.value
// #endif
safeFooterHeight.value = (sys.safeAreaInsets?.bottom ?? 0) == 0 ? 16 : sys.safeAreaInsets.bottom
}
onMounted(()=>{
onMounted(() => {
setDomHeight()
uni.$on('onReady',setDomHeight)
uni.$on('onReady', setDomHeight)
lezyShowModal.value = props.lazy ? false : true
// #ifdef H5
nextTick(() => {
@@ -412,17 +412,17 @@ onMounted(()=>{
// 监听页面变化,重新获取teleport目标
onUpdated(() => {
// #ifdef H5
if (teleportTarget.value && !isTeleportTargetValid(teleportTarget.value)) {
teleportTarget.value = getTeleportTarget()
}
// #endif
// #ifdef H5
if (teleportTarget.value && !isTeleportTargetValid(teleportTarget.value)) {
teleportTarget.value = getTeleportTarget()
}
// #endif
})
onBeforeUnmount(() => {
clearTimeout(tid.value)
clearTimeout(tid2.value)
uni.$off('onReady',setDomHeight)
uni.$off('onReady', setDomHeight)
})
const cancelEvt = () => {
@@ -442,8 +442,8 @@ const confirmEvt = async () => {
return;
}
/**
* 确认时触发
*/
* 确认时触发
*/
emit('confirm')
closeAlert()
}
@@ -504,7 +504,7 @@ const showAlert = () => {
}
function openDrawer() {
if(_disabled.value) return;
if (_disabled.value) return;
showAlert();
}
@@ -561,8 +561,8 @@ export default {
<root-portal>
<!-- #endif -->
<!-- 备用渲染方案:当teleport失败或被禁用时 -->
<view v-if="(props.disableTeleport || !teleportTarget) && showOverflay" class="tmDrawerWrap tmDrawerWrap_fallback"
:class="[
<view v-if="(props.disableTeleport || !teleportTarget) && showOverflay"
class="tmDrawerWrap tmDrawerWrap_fallback" :class="[
status == 'open' ? 'tmModalWrap_on' : 'tmModalWrap_off',
(_position == 'top' || _position == 'bottom') && _widthCoverCenter ? 'tmDrawerWrapContentMinwidthWrapDir' : '',
'tmDrawerWrap_' + _position
@@ -575,7 +575,7 @@ export default {
}, _customStyle]">
<!-- 备用内容 -->
</view>
<view @click="onClickOverflowy" @touchmove="maskerMove" v-if="showOverflay" :id="id" ref="tmDrawerWrap"
class="tmDrawerWrap" :class="[
status == 'open' ? 'tmModalWrap_on' : 'tmModalWrap_off',
@@ -598,14 +598,13 @@ export default {
height: _position == 'left' || _position == 'right' ? '100%' : _size,
borderRadius: _round,
maxHeight: _maxHeight != '' ? _maxHeight : '100%',
minHeight:_size == 'auto'?'350rpx':'0px',
minHeight: _size == 'auto' ? '350rpx' : '0px',
'transition-timing-function': _animationFun,
backgroundColor: _bgColor
}">
<view v-if="_showClose" class="tmDrawerXclose">
<tm-icon @click="closeAlert" color="#dcdcdc" size="52"
name="close-circle-fill"></tm-icon>
<tm-icon @click="closeAlert" color="#dcdcdc" size="52" name="close-circle-fill"></tm-icon>
</view>
<view>
<view v-if="_showTitle" class="tmDrawerTitleBox">
@@ -655,10 +654,10 @@ export default {
skin="thin" style="margin-right: 16px;flex:1">{{ _cancelText }}</tm-button>
<tm-button :loading="isLoading" width="0px" @click="confirmEvt" style="flex:1">{{
_confirmText
}}</tm-button>
}}</tm-button>
</view>
</slot>
<view :style="{ height: (safeFooterHeight||20) + 'px' }"></view>
<view :style="{ height: (safeFooterHeight || 20) + 'px' }"></view>
</view>
</view>
@@ -692,7 +691,7 @@ export default {
flex-direction: row;
align-items: center;
justify-content: center;
font-weight: bold;
font-weight: bold;
}
.tmDrawertitleBox {
@@ -1,9 +1,9 @@
<script setup lang="ts">
import {computed, getCurrentInstance, inject, onBeforeUnmount, onMounted, PropType, ref, watch} from 'vue';
import {useTmConfig} from "../../libs/config";
import { computed, getCurrentInstance, inject, onBeforeUnmount, onMounted, PropType, ref, watch } from 'vue';
import { useTmConfig } from "../../libs/config";
import TmForm from '../tm-form/tm-form.vue';
import {covetUniNumber} from '../../libs/tool';
import {getDefaultColor} from '../../libs/colors';
import { covetUniNumber } from '../../libs/tool';
import { getDefaultColor } from '../../libs/colors';
/**
* @displayName 表单子组件
@@ -17,8 +17,8 @@ import {getDefaultColor} from '../../libs/colors';
| --- | --- | --- | --- |
| ☑️| ☑️ | ☑️ | ☑️ | ☑️ | 1.0.0 |
*/
defineOptions({name: "TmFormItem"});
const {config} = useTmConfig();
defineOptions({ name: "TmFormItem" });
const { config } = useTmConfig();
const props = defineProps({
/**
@@ -147,7 +147,7 @@ watch(() => tmFormModelValue.value?.[props.name], (val: any, oldVal: any) => {
tid = setTimeout(() => {
_validFun(val)
}, 200);
}, {deep: true})
}, { deep: true })
watch(tmFormVaildType, (val: string) => {
if (val == 'reset' || val == '') {
@@ -225,10 +225,10 @@ export default {
<template>
<view class="tmFormItem" :style="{ marginBottom: _tmFormGap }">
<view :class="[_tmFormDirection == 'horizontal' ? 'tmFormItemWrapRow' : 'tmFormItemWrapCol']"
class="tmFormItemWrap">
class="tmFormItemWrap">
<view v-if="_showLabel" class="tmFormItemLabel"
:style="{ width: _tmFormDirection == 'horizontal' ? _labelWidth : 'auto', fontSize: _tmFormLabelFontSize, color: _tmFormLabelFontColor }">
:style="{ width: _tmFormDirection == 'horizontal' ? _labelWidth : 'auto', fontSize: _tmFormLabelFontSize, color: _tmFormLabelFontColor }">
<text class="tmFormRequired" v-if="_required">{{ _required }}</text>
<slot name="label">
{{ _label }}
@@ -1,30 +1,19 @@
<template>
<text
@tap="onclick"
v-if="!isImg"
:class="['tmIcon', `${prefix}${iconName}`, isSpin?'tmIconSpin':'',_class]"
:style="[
{
fontSize: iconSize,
color: fontColor,
fontFamily: fontFamily,
fontStyle: 'normal',
},
rotateDeg ? { transform: `rotate(${rotateDeg})` } : {},
_style
]"
></text>
<image
v-if="isImg"
@tap="onclick"
:src="iconName"
:class="['tmIcon', isSpin?'tmIconSpin':'',_class]"
:style="[
{ width: iconSize, height: iconSize },
rotateDeg ? { transform: `rotate(${rotateDeg})` } : {},
_style
]"
></image>
<text @tap="onclick" v-if="!isImg" :class="['tmIcon', `${prefix}${iconName}`, isSpin ? 'tmIconSpin' : '', _class]" :style="[
{
fontSize: iconSize,
color: fontColor,
fontFamily: fontFamily,
fontStyle: 'normal',
},
rotateDeg ? { transform: `rotate(${rotateDeg})` } : {},
_style
]"></text>
<image v-if="isImg" @tap="onclick" :src="iconName" :class="['tmIcon', isSpin ? 'tmIconSpin' : '', _class]" :style="[
{ width: iconSize, height: iconSize },
rotateDeg ? { transform: `rotate(${rotateDeg})` } : {},
_style
]"></image>
</template>
<script setup lang="ts">
//@ts-nocheck
@@ -42,8 +31,8 @@ import { getDefaultColor } from "../../libs/colors";
* ->复制到你的app.vue全局中即可.然后使用图标时,font-family是你的图标名称比如myicon,prefix是图标前缀比如myicon-
* @constant 平台兼容
* | H5 | uniAPP | 小程序 | version |
| --- | --- | --- | --- |
| ☑️| ☑️ | ☑️ | ☑️ | ☑️ | 1.0.0 |
| --- | --- | --- | --- |
| ☑️| ☑️ | ☑️ | ☑️ | ☑️ | 1.0.0 |
*/
defineOptions({ name: "TmIcon" });
const { config } = useTmConfig();
@@ -54,13 +43,13 @@ const emits = defineEmits([
"click",
]);
const attrs = defineProps({
_style:{
type:[Object,String] as PropType<CSSStyleDeclaration|string>,
default:""
_style: {
type: [Object, String] as PropType<CSSStyleDeclaration | string>,
default: ""
},
_class:{
type: String,
default:""
_class: {
type: String,
default: ""
},
/**
* 图标名称,可以是图片地址
File diff suppressed because it is too large. Load diff