Merge branch 'master' of http://gitea.zianxin.com/zianxin-tec/biz-mobile-react-cloud
# Conflicts: # .env
No files matched your search
@@ -1,120 +1,183 @@
|
||||
<script lang="ts">
|
||||
import isDevEnv from "./sheep/utils/isDevEnv"
|
||||
|
||||
// import { onLaunch, onShow, onHide } from "@dcloudio/uni-app"
|
||||
// onLaunch(() => {})
|
||||
// onShow(() => {})
|
||||
// onHide(() => {})
|
||||
|
||||
// zhezhengding:浙政钉 | shihua:诗画
|
||||
const tabbar = [
|
||||
interface TabbarItem {
|
||||
pagePath: string
|
||||
text: string
|
||||
iconPath: string
|
||||
selectedIconPath: string
|
||||
launchParam: string[]
|
||||
auth: string[]
|
||||
}
|
||||
|
||||
const tabbar: TabbarItem[] = [
|
||||
{
|
||||
pagePath: "pages/tabbar/canteen",
|
||||
text: "食堂",
|
||||
iconPath: "/static/tabbar/canteen.png",
|
||||
selectedIconPath: "/static/tabbar/canteen-select.png",
|
||||
auth: ["zhezhengding", "shihua"],
|
||||
launchParam: ["canteen"],
|
||||
auth: [],
|
||||
},
|
||||
{
|
||||
pagePath: "pages/tabbar/shop",
|
||||
text: "超市",
|
||||
iconPath: "/static/tabbar/shop.png",
|
||||
selectedIconPath: "/static/tabbar/shop-select.png",
|
||||
auth: ["zhezhengding", "shihua"],
|
||||
pagePath: "pages/tabbar/selfMerchant",
|
||||
text: "自营商家",
|
||||
iconPath: "/static/tabbar/selfMerchant.png",
|
||||
selectedIconPath: "/static/tabbar/selfMerchant-select.png",
|
||||
launchParam: ["selfMerchant"],
|
||||
auth: [],
|
||||
},
|
||||
{
|
||||
pagePath: "pages/tabbar/coopShop",
|
||||
pagePath: "pages/tabbar/coopMerchant",
|
||||
text: "合作商家",
|
||||
iconPath: "/static/tabbar/coopShop.png",
|
||||
selectedIconPath: "/static/tabbar/coopShop-select.png",
|
||||
auth: ["zhezhengding"],
|
||||
iconPath: "/static/tabbar/coopMerchant.png",
|
||||
selectedIconPath: "/static/tabbar/coopMerchant-select.png",
|
||||
launchParam: ["selfMerchant"],
|
||||
auth: ["user"],
|
||||
},
|
||||
{
|
||||
pagePath: "pages/tabbar/order",
|
||||
text: "订单",
|
||||
iconPath: "/static/tabbar/order.png",
|
||||
selectedIconPath: "/static/tabbar/order-select.png",
|
||||
auth: ["zhezhengding"],
|
||||
launchParam: ["canteen", "selfMerchant"],
|
||||
auth: ["user"],
|
||||
},
|
||||
{
|
||||
pagePath: "pages/tabbar/flowStatistics",
|
||||
text: "流水统计",
|
||||
iconPath: "/static/tabbar/order.png",
|
||||
selectedIconPath: "/static/tabbar/order-select.png",
|
||||
auth: ["shihua"],
|
||||
launchParam: [],
|
||||
auth: ["merchant"],
|
||||
},
|
||||
{
|
||||
pagePath: "pages/tabbar/individualOrder",
|
||||
text: "订单",
|
||||
iconPath: "/static/tabbar/order.png",
|
||||
selectedIconPath: "/static/tabbar/order-select.png",
|
||||
auth: ["shihua"],
|
||||
launchParam: [],
|
||||
auth: ["merchant"],
|
||||
},
|
||||
{
|
||||
pagePath: "pages/tabbar/my",
|
||||
text: "我的",
|
||||
iconPath: "/static/tabbar/my.png",
|
||||
selectedIconPath: "/static/tabbar/my-select.png",
|
||||
auth: ["zhezhengding", "shihua"],
|
||||
launchParam: ["canteen", "selfMerchant"],
|
||||
auth: ["user", "merchant"],
|
||||
},
|
||||
]
|
||||
|
||||
// 获取启动参数
|
||||
const getLaunchParam = () => {
|
||||
return new URL(window.location.href).searchParams.get("launchParam")
|
||||
}
|
||||
|
||||
// 设置tabbar项目
|
||||
const setTabbarItem = (index: number, item: TabbarItem, visible: boolean) => {
|
||||
uni.setTabBarItem({
|
||||
index,
|
||||
pagePath: item.pagePath,
|
||||
text: item.text,
|
||||
iconPath: item.iconPath,
|
||||
selectedIconPath: item.selectedIconPath,
|
||||
visible,
|
||||
})
|
||||
}
|
||||
|
||||
// 根据启动参数设置tabbar项目
|
||||
const setTabbarByLaunchParam = (launchParam: string) => {
|
||||
tabbar.forEach((item, index) => {
|
||||
const visible = item.launchParam.includes(launchParam)
|
||||
setTabbarItem(index, item, visible)
|
||||
})
|
||||
}
|
||||
|
||||
// 根据用户角色设置tabbar项目
|
||||
const setTabbarByUserRole = (role: string) => {
|
||||
tabbar.forEach((item, index) => {
|
||||
const visible = item.auth.includes(role)
|
||||
setTabbarItem(index, item, visible)
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
onLaunch() {},
|
||||
async onLaunch() {
|
||||
if (isDevEnv()) return
|
||||
|
||||
uni.setNavigationBarTitle({ title: "" })
|
||||
|
||||
// 环境判断
|
||||
const res = await (window as any).CP2.getAppInfo()
|
||||
if (res.code == 0) {
|
||||
// 不是诗画环境
|
||||
const launchParam = getLaunchParam()
|
||||
|
||||
console.log("app launch 启动路径参数", launchParam)
|
||||
|
||||
switch (launchParam) {
|
||||
case "canteen":
|
||||
uni.switchTab({ url: "/pages/tabbar/canteen" })
|
||||
break
|
||||
case "selfMerchant":
|
||||
uni.switchTab({ url: "/pages/tabbar/selfMerchant" })
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
} else {
|
||||
// 是诗画环境
|
||||
const userRole = uni.getStorageSync("userRole")
|
||||
if (!userRole) return uni.redirectTo({ url: "/pages/user/userRole" })
|
||||
if (userRole === "user") return uni.switchTab({ url: "/pages/tabbar/coopMerchant" })
|
||||
if (userRole === "merchant") return uni.switchTab({ url: "/pages/tabbar/individualOrder" })
|
||||
}
|
||||
},
|
||||
onShow() {},
|
||||
onHide() {},
|
||||
|
||||
methods: {
|
||||
_initTabbar() {
|
||||
console.log("环境判断")
|
||||
async _initTabbar() {
|
||||
if (isDevEnv()) {
|
||||
tabbar.forEach((item, index) => {
|
||||
setTabbarItem(index, item, true)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
let appEnv = 1 // 1:浙政钉 2:诗画
|
||||
const launchParam = getLaunchParam()
|
||||
console.log("tabbar launch 启动路径参数", launchParam)
|
||||
|
||||
switch (appEnv) {
|
||||
case 1:
|
||||
tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, auth }, index) => {
|
||||
if (auth.includes("zhezhengding")) {
|
||||
uni.setTabBarItem({
|
||||
index,
|
||||
pagePath,
|
||||
text,
|
||||
iconPath,
|
||||
selectedIconPath,
|
||||
visible: true,
|
||||
})
|
||||
} else {
|
||||
uni.setTabBarItem({
|
||||
index,
|
||||
pagePath,
|
||||
text,
|
||||
iconPath,
|
||||
selectedIconPath,
|
||||
visible: false,
|
||||
})
|
||||
}
|
||||
})
|
||||
break
|
||||
case 2:
|
||||
tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, auth }, index) => {
|
||||
if (auth.includes("shihua")) {
|
||||
uni.setTabBarItem({
|
||||
index,
|
||||
pagePath,
|
||||
text,
|
||||
iconPath,
|
||||
selectedIconPath,
|
||||
visible: true,
|
||||
})
|
||||
} else {
|
||||
uni.setTabBarItem({
|
||||
index,
|
||||
pagePath,
|
||||
text,
|
||||
iconPath,
|
||||
selectedIconPath,
|
||||
visible: false,
|
||||
})
|
||||
}
|
||||
})
|
||||
break
|
||||
const res = await (window as any).CP2.getAppInfo()
|
||||
if (res.code == 0) {
|
||||
// 不是诗画环境
|
||||
if (launchParam) {
|
||||
setTabbarByLaunchParam(launchParam)
|
||||
} else {
|
||||
uni.hideTabBar()
|
||||
uni.showToast({ title: "启动参数不合法", icon: "none" })
|
||||
}
|
||||
} else {
|
||||
// 是诗画环境
|
||||
const userRole = uni.getStorageSync("userRole")
|
||||
switch (userRole) {
|
||||
case "user":
|
||||
setTabbarByUserRole("user")
|
||||
break
|
||||
case "merchant":
|
||||
setTabbarByUserRole("merchant")
|
||||
break
|
||||
default:
|
||||
uni.hideTabBar()
|
||||
uni.showToast({ title: "用户身份未确认", icon: "none" })
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,79 +1,80 @@
|
||||
{
|
||||
"name" : "",
|
||||
"appid" : "",
|
||||
"description" : "浦江县机关事务智慧后勤一体化平台",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules" : {},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
/* android打包配置 */
|
||||
"android" : {
|
||||
"permissions" : [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"ios" : {},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : false
|
||||
},
|
||||
"vueVersion" : "3",
|
||||
"h5" : {
|
||||
"router" : {
|
||||
"base" : "/h5/",
|
||||
"mode" : "hash"
|
||||
},
|
||||
"title" : "浦江县机关事务智慧后勤一体化平台"
|
||||
}
|
||||
"name": "",
|
||||
"appid": "",
|
||||
"description": "浦江县机关事务智慧后勤一体化平台",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": "100",
|
||||
"transformPx": false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus": {
|
||||
"usingComponents": true,
|
||||
"nvueStyleCompiler": "uni-app",
|
||||
"compilerVersion": 3,
|
||||
"splashscreen": {
|
||||
"alwaysShowBeforeRender": true,
|
||||
"waiting": true,
|
||||
"autoclose": true,
|
||||
"delay": 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules": {},
|
||||
/* 应用发布信息 */
|
||||
"distribute": {
|
||||
/* android打包配置 */
|
||||
"android": {
|
||||
"permissions": [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>"
|
||||
]
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"ios": {},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs": {}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp": {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin": {
|
||||
"appid": "",
|
||||
"setting": {
|
||||
"urlCheck": false
|
||||
},
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-alipay": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-baidu": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-toutiao": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
},
|
||||
"vueVersion": "3",
|
||||
"h5": {
|
||||
"router": {
|
||||
"base": "/h5/",
|
||||
"mode": "hash"
|
||||
},
|
||||
"title": "浦江县机关事务智慧后勤一体化平台"
|
||||
}
|
||||
}
|
||||
@@ -17,14 +17,14 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tabbar/shop",
|
||||
"path": "pages/tabbar/selfMerchant",
|
||||
"style": {
|
||||
"navigationBarTitleText": "超市",
|
||||
"navigationBarTitleText": "自营商家",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tabbar/coopShop",
|
||||
"path": "pages/tabbar/coopMerchant",
|
||||
"style": {
|
||||
"navigationBarTitleText": "合作商家",
|
||||
"disableScroll": true
|
||||
@@ -74,6 +74,13 @@
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "brandDetail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "product-detail",
|
||||
"style": {
|
||||
@@ -278,6 +285,18 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"root": "pages/user",
|
||||
"pages": [
|
||||
{
|
||||
"path": "userRole",
|
||||
"style": {
|
||||
"navigationBarTitleText": "用户身份",
|
||||
"disableScroll": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"root": "pages/pay",
|
||||
"pages": [
|
||||
@@ -287,6 +306,20 @@
|
||||
"navigationBarTitleText": "支付",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "payComplete",
|
||||
"style": {
|
||||
"navigationBarTitleText": "支付完成",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "transferMoney",
|
||||
"style": {
|
||||
"navigationBarTitleText": "转账",
|
||||
"disableScroll": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -318,13 +351,13 @@
|
||||
"selectedIconPath": ""
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/tabbar/shop",
|
||||
"pagePath": "pages/tabbar/selfMerchant",
|
||||
"text": "",
|
||||
"iconPath": "",
|
||||
"selectedIconPath": ""
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/tabbar/coopShop",
|
||||
"pagePath": "pages/tabbar/coopMerchant",
|
||||
"text": "",
|
||||
"iconPath": "",
|
||||
"selectedIconPath": ""
|
||||
@@ -353,7 +386,6 @@
|
||||
"iconPath": "",
|
||||
"selectedIconPath": ""
|
||||
}
|
||||
|
||||
// {
|
||||
// "pagePath": "pages/tabbar/canteen",
|
||||
// "text": "食堂",
|
||||
@@ -361,16 +393,16 @@
|
||||
// "selectedIconPath": "static/tabbar/canteen-select.png"
|
||||
// },
|
||||
// {
|
||||
// "pagePath": "pages/tabbar/shop",
|
||||
// "text": "超市",
|
||||
// "iconPath": "static/tabbar/shop.png",
|
||||
// "selectedIconPath": "static/tabbar/shop-select.png"
|
||||
// "pagePath": "pages/tabbar/selfMerchant",
|
||||
// "text": "自营商家",
|
||||
// "iconPath": "static/tabbar/selfMerchant.png",
|
||||
// "selectedIconPath": "static/tabbar/selfMerchant-select.png"
|
||||
// },
|
||||
// {
|
||||
// pagePath: "pages/tabbar/coopShop",
|
||||
// pagePath: "pages/tabbar/coopMerchant",
|
||||
// text: "合作商家",
|
||||
// iconPath: "static/tabbar/coopShop.png",
|
||||
// selectedIconPath: "static/tabbar/coopShop-select.png",
|
||||
// iconPath: "static/tabbar/coopMerchant.png",
|
||||
// selectedIconPath: "static/tabbar/coopMerchant-select.png",
|
||||
// },
|
||||
// {
|
||||
// "pagePath": "pages/tabbar/order",
|
||||
@@ -378,21 +410,18 @@
|
||||
// "iconPath": "static/tabbar/order.png",
|
||||
// "selectedIconPath": "static/tabbar/order-select.png"
|
||||
// },
|
||||
|
||||
// {
|
||||
// "pagePath": "pages/tabbar/flowStatistics",
|
||||
// "text": "流水统计",
|
||||
// "iconPath": "static/tabbar/order.png",
|
||||
// "selectedIconPath": "static/tabbar/order-select.png"
|
||||
// },
|
||||
|
||||
// {
|
||||
// "pagePath": "pages/tabbar/individualOrder",
|
||||
// "text": "订单",
|
||||
// "iconPath": "static/tabbar/order.png",
|
||||
// "selectedIconPath": "static/tabbar/order-select.png"
|
||||
// },
|
||||
|
||||
// {
|
||||
// "pagePath": "pages/tabbar/my",
|
||||
// "text": "我的",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { isEmpty } from 'radash'
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { applyApi } from "@@/api"
|
||||
@@ -9,56 +9,69 @@ import { applyApi } from "@@/api"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
id: null,
|
||||
pagesize: 15,
|
||||
},
|
||||
pa: {
|
||||
id: null,
|
||||
pagesize: 15,
|
||||
},
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, applyApi.codeList, null, 'data.records')
|
||||
const pageHook = hooks.usePage(pageRef, applyApi.codeList, null, "data.records")
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa);
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad((options: any) => {
|
||||
if (!isEmpty(options.id)) {
|
||||
state.pa.id = options.id
|
||||
}
|
||||
});
|
||||
onShow(() => {
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
if (!isEmpty(options.id)) {
|
||||
state.pa.id = options.id
|
||||
}
|
||||
})
|
||||
onShow(() => {
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<crud-layout title="外来人员就餐" bg="/static/page/blue-bg.png">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="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">
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
</template>
|
||||
<view class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx"
|
||||
v-for="(v, i) in pageHook.list" :key="i" @tap="hooks.usePreviewImage(v.code)">
|
||||
<view class="flex-row items-center">
|
||||
<view class="flex-row items-center">
|
||||
<tm-tag v-if="v.status == 0" size="m" color="info">未使用</tm-tag>
|
||||
<tm-tag v-if="v.status == 1" size="m" color="success">已使用</tm-tag>
|
||||
</view>
|
||||
<view class="flex-row items-center sub-text-28">
|
||||
<text class="m-l-30rpx">{{ v.username }}</text>
|
||||
<text class="m-l-10rpx second-text-26">{{ v.userMobile }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="iconfont icon-erweima font-size-40rpx! color-blue" />
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
<crud-layout title="外来人员就餐" bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
</template>
|
||||
<view
|
||||
class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx"
|
||||
v-for="(v, i) in pageHook.list"
|
||||
:key="i"
|
||||
@tap="hooks.usePreviewImage(v.code)"
|
||||
>
|
||||
<view class="flex-row items-center">
|
||||
<view class="flex-row items-center">
|
||||
<tm-tag v-if="v.status == 0" size="m" color="info">未使用</tm-tag>
|
||||
<tm-tag v-if="v.status == 1" size="m" color="success">已使用</tm-tag>
|
||||
</view>
|
||||
<view class="flex-row items-center sub-text-28">
|
||||
<text class="m-l-30rpx">{{ v.username }}</text>
|
||||
<text class="m-l-10rpx second-text-26">{{ v.userMobile }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="iconfont icon-erweima font-size-40rpx! color-blue" />
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { applyApi } from "@@/api"
|
||||
@@ -8,128 +8,132 @@ import { applyApi } from "@@/api"
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
|
||||
const data = {
|
||||
tabs: [
|
||||
{ id: null, name: '全部', disabled: false },
|
||||
{ id: 1, name: '待审核', disabled: false },
|
||||
{ id: 2, name: '已通过', disabled: false },
|
||||
{ id: 3, name: '已拒绝', disabled: false },
|
||||
]
|
||||
tabs: [
|
||||
{ id: null, name: "全部", disabled: false },
|
||||
{ id: 1, name: "待审核", disabled: false },
|
||||
{ id: 2, name: "已通过", disabled: false },
|
||||
{ id: 3, name: "已拒绝", disabled: false },
|
||||
],
|
||||
}
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
processStatus: data.tabs[0].id,
|
||||
},
|
||||
pa: {
|
||||
processStatus: data.tabs[0].id,
|
||||
},
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, applyApi.foreignList, null, 'data.records')
|
||||
const pageHook = hooks.usePage(pageRef, applyApi.foreignList, null, "data.records")
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa);
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
|
||||
});
|
||||
onLoad(() => {})
|
||||
onShow(() => {
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
})
|
||||
|
||||
const doTab = (e: any) => {
|
||||
const target = data.tabs[e];
|
||||
state.pa.processStatus = target.id
|
||||
pageRef.value.reload(true)
|
||||
const target = data.tabs[e]
|
||||
state.pa.processStatus = target.id
|
||||
pageRef.value.reload(true)
|
||||
}
|
||||
|
||||
const doApply = async () => {
|
||||
router.jump("/pages/apply/foreign-apply", { type: 'add' })
|
||||
router.jump("/pages/apply/foreign-apply", { type: "add" })
|
||||
}
|
||||
|
||||
const doCard = (v: any) => {
|
||||
if (v.processStatus == 2) {
|
||||
router.jump("/pages/apply/foreign-items", { id: v.id })
|
||||
} else {
|
||||
router.jump("/pages/apply/foreign-apply", { type: 'view', id: v.id })
|
||||
}
|
||||
if (v.processStatus == 2) {
|
||||
router.jump("/pages/apply/foreign-items", { id: v.id })
|
||||
} else {
|
||||
router.jump("/pages/apply/foreign-apply", { type: "view", id: v.id })
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<crud-layout title="外来人员就餐" bg="/static/page/blue-bg.png">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="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">
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
<view class="bg-white rounded-16rpx px-20rpx">
|
||||
<z-tabs :list="data.tabs" @change="doTab" />
|
||||
</view>
|
||||
</template>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-col card p-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i"
|
||||
@tap="doCard(v)">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="sub-text-30">电子餐券</view>
|
||||
<view class="flex-row items-center">
|
||||
<view class="second-text-26">{{ hooks.useTime(v.createTime, "") }}</view>
|
||||
<view class="flex-row-center m-l-20rpx">
|
||||
<tm-tag v-if="v.processStatus == 1" size="xs" color="info">待审核</tm-tag>
|
||||
<tm-tag v-if="v.processStatus == 2" size="xs" color="success">已通过</tm-tag>
|
||||
<tm-tag v-if="v.processStatus == 3" size="xs" color="error">已拒绝</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
|
||||
<view class="flex items-center justify-between second-text-26">
|
||||
<view class="flex items-center">
|
||||
<text>数量</text>
|
||||
<text class="m-l-10rpx">{{ v.count }}</text>
|
||||
</view>
|
||||
<view class="color-red">
|
||||
<text>已使用</text>
|
||||
<text class="m-l-10rpx">{{ v.useCount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center m-t-20rpx second-text-26">
|
||||
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
|
||||
<text>有效期</text>
|
||||
<text class="m-l-10rpx">
|
||||
{{ hooks.useTime(v.applyStartTime, " {y}-{m}-{d}") }}
|
||||
~
|
||||
{{ hooks.useTime(v.applyEndTime, "{y}-{m}-{d}") }}
|
||||
</text>
|
||||
</view>
|
||||
<view v-if="v.processStatus != 1 && false">
|
||||
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
|
||||
<view class="flex items-center justify-between second-text-26">
|
||||
<view class="flex items-center">
|
||||
<text>审核人</text>
|
||||
<text class="m-l-10rpx">{{ v.checkUserName }}</text>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<text>审核时间</text>
|
||||
<text class="m-l-10rpx"> {{ hooks.useTime(v.checkTime, "") }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center justify-end m-t-25rpx">
|
||||
<text v-if="v.processStatus == 2" class="botder_btn">使用</text>
|
||||
<text v-else class="botder_btn">查看</text>
|
||||
</view>
|
||||
</view>
|
||||
<template #bottom>
|
||||
<view
|
||||
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!"
|
||||
@tap="doApply">
|
||||
申请
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
</template>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
<crud-layout title="外来人员就餐" bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
<view class="bg-white rounded-16rpx px-20rpx">
|
||||
<z-tabs :list="data.tabs" @change="doTab" />
|
||||
</view>
|
||||
</template>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-col card p-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="doCard(v)">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="sub-text-30">电子餐券</view>
|
||||
<view class="flex-row items-center">
|
||||
<view class="second-text-26">{{ hooks.useTime(v.createTime, "") }}</view>
|
||||
<view class="flex-row-center m-l-20rpx">
|
||||
<tm-tag v-if="v.processStatus == 1" size="xs" color="info">待审核</tm-tag>
|
||||
<tm-tag v-if="v.processStatus == 2" size="xs" color="success">已通过</tm-tag>
|
||||
<tm-tag v-if="v.processStatus == 3" size="xs" color="error">已拒绝</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
|
||||
<view class="flex items-center justify-between second-text-26">
|
||||
<view class="flex items-center">
|
||||
<text>数量</text>
|
||||
<text class="m-l-10rpx">{{ v.count }}</text>
|
||||
</view>
|
||||
<view class="color-red">
|
||||
<text>已使用</text>
|
||||
<text class="m-l-10rpx">{{ v.useCount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center m-t-20rpx second-text-26">
|
||||
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
|
||||
<text>有效期</text>
|
||||
<text class="m-l-10rpx">
|
||||
{{ hooks.useTime(v.applyStartTime, " {y}-{m}-{d}") }}
|
||||
~
|
||||
{{ hooks.useTime(v.applyEndTime, "{y}-{m}-{d}") }}
|
||||
</text>
|
||||
</view>
|
||||
<view v-if="v.processStatus != 1 && false">
|
||||
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
|
||||
<view class="flex items-center justify-between second-text-26">
|
||||
<view class="flex items-center">
|
||||
<text>审核人</text>
|
||||
<text class="m-l-10rpx">{{ v.checkUserName }}</text>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<text>审核时间</text>
|
||||
<text class="m-l-10rpx"> {{ hooks.useTime(v.checkTime, "") }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center justify-end m-t-25rpx">
|
||||
<text v-if="v.processStatus == 2" class="botder_btn">使用</text>
|
||||
<text v-else class="botder_btn">查看</text>
|
||||
</view>
|
||||
</view>
|
||||
<template #bottom>
|
||||
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!" @tap="doApply">
|
||||
申请
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
</template>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -1,60 +1,71 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { isEmpty } from 'radash'
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { applyApi } from "@@/api"
|
||||
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
bizId: null,
|
||||
pagesize: 99,
|
||||
},
|
||||
pa: {
|
||||
bizId: null,
|
||||
pagesize: 99,
|
||||
},
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, applyApi.codeList, null, 'data.records')
|
||||
const pageHook = hooks.usePage(pageRef, applyApi.codeList, null, "data.records")
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa);
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad((options: any) => {
|
||||
if (!isEmpty(options.id)) {
|
||||
state.pa.bizId = options.id
|
||||
}
|
||||
});
|
||||
onShow(() => {
|
||||
|
||||
if (!isEmpty(options.id)) {
|
||||
state.pa.bizId = options.id
|
||||
}
|
||||
})
|
||||
|
||||
onShow(() => {})
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<crud-layout title="跨单位就餐" bg="/static/page/blue-bg.png">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="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">
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
</template>
|
||||
<view class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx"
|
||||
v-for="(v, i) in pageHook.list" :key="i" @tap="hooks.usePreviewImage(v.code)">
|
||||
<view class="flex-row items-center">
|
||||
<view class="flex-row items-center">
|
||||
<tm-tag v-if="v.status == 0" size="m" color="info">未使用</tm-tag>
|
||||
<tm-tag v-if="v.status == 1" size="m" color="success">已使用</tm-tag>
|
||||
</view>
|
||||
<view class="flex-row items-center sub-text-26">
|
||||
<text class="m-l-30rpx">{{ v.username }}</text>
|
||||
<text class="m-l-10rpx second-text-26">{{ v.userMobile }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="iconfont icon-erweima font-size-40rpx! color-blue" />
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
<crud-layout title="跨单位就餐" bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
</template>
|
||||
<view
|
||||
class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx"
|
||||
v-for="(v, i) in pageHook.list"
|
||||
:key="i"
|
||||
@tap="hooks.usePreviewImage(v.code)"
|
||||
>
|
||||
<view class="flex-row items-center">
|
||||
<view class="flex-row items-center">
|
||||
<tm-tag v-if="v.status == 0" size="m" color="info">未使用</tm-tag>
|
||||
<tm-tag v-if="v.status == 1" size="m" color="success">已使用</tm-tag>
|
||||
</view>
|
||||
<view class="flex-row items-center sub-text-26">
|
||||
<text class="m-l-30rpx">{{ v.username }}</text>
|
||||
<text class="m-l-10rpx second-text-26">{{ v.userMobile }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="iconfont icon-erweima font-size-40rpx! color-blue" />
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { applyApi } from "@@/api"
|
||||
@@ -8,119 +8,123 @@ import { applyApi } from "@@/api"
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
|
||||
const data = {
|
||||
tabs: [
|
||||
{ id: null, name: '全部', disabled: false },
|
||||
{ id: 1, name: '待审核', disabled: false },
|
||||
{ id: 2, name: '已通过', disabled: false },
|
||||
{ id: 3, name: '已拒绝', disabled: false },
|
||||
]
|
||||
tabs: [
|
||||
{ id: null, name: "全部", disabled: false },
|
||||
{ id: 1, name: "待审核", disabled: false },
|
||||
{ id: 2, name: "已通过", disabled: false },
|
||||
{ id: 3, name: "已拒绝", disabled: false },
|
||||
],
|
||||
}
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
processStatus: data.tabs[0].id,
|
||||
},
|
||||
pa: {
|
||||
processStatus: data.tabs[0].id,
|
||||
},
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, applyApi.strideList, null, 'data.records')
|
||||
const pageHook = hooks.usePage(pageRef, applyApi.strideList, null, "data.records")
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa);
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
|
||||
});
|
||||
onLoad(() => {})
|
||||
onShow(() => {
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
})
|
||||
|
||||
const doTab = (e: any) => {
|
||||
const target = data.tabs[e];
|
||||
state.pa.processStatus = target.id
|
||||
pageRef.value.reload(true)
|
||||
const target = data.tabs[e]
|
||||
state.pa.processStatus = target.id
|
||||
pageRef.value.reload(true)
|
||||
}
|
||||
|
||||
const doApply = async () => {
|
||||
router.jump("/pages/apply/stride-apply")
|
||||
router.jump("/pages/apply/stride-apply")
|
||||
}
|
||||
|
||||
const doCard = (v: any) => {
|
||||
if (v.processStatus == 2) {
|
||||
router.jump("/pages/apply/stride-items", { id: v.id })
|
||||
} else {
|
||||
router.jump("/pages/apply/stride-apply", { type: 'view', id: v.id })
|
||||
}
|
||||
if (v.processStatus == 2) {
|
||||
router.jump("/pages/apply/stride-items", { id: v.id })
|
||||
} else {
|
||||
router.jump("/pages/apply/stride-apply", { type: "view", id: v.id })
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<crud-layout title="跨单位就餐" bg="/static/page/blue-bg.png">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="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">
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
<view class="bg-white rounded-16rpx px-20rpx">
|
||||
<z-tabs :list="data.tabs" @change="doTab" />
|
||||
</view>
|
||||
</template>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-col card p-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i"
|
||||
@tap="doCard(v)">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="sub-text-30">跨单位就餐</view>
|
||||
<view class="flex-row items-center">
|
||||
<view class="second-text-26">{{ hooks.useTime(v.createTime, "") }}</view>
|
||||
<view class="flex-row-center m-l-20rpx">
|
||||
<tm-tag v-if="v.processStatus == 1" size="xs" color="info">待审核</tm-tag>
|
||||
<tm-tag v-if="v.processStatus == 2" size="xs" color="success">已通过</tm-tag>
|
||||
<tm-tag v-if="v.processStatus == 3" size="xs" color="error">已拒绝</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
|
||||
<view class="flex items-center justify-between second-text-26">
|
||||
<view class="flex items-center">
|
||||
<text>数量</text>
|
||||
<text class="m-l-10rpx">{{ v.count }}</text>
|
||||
</view>
|
||||
<view class="color-red">
|
||||
<text>已使用</text>
|
||||
<text class="m-l-10rpx">{{ v.useCount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="v.processStatus != 1 && false">
|
||||
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
|
||||
<view class="flex items-center justify-between second-text-26">
|
||||
<view class="flex items-center">
|
||||
<text>审核人</text>
|
||||
<text class="m-l-10rpx">{{ v.checkUserName }}</text>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<text>审核时间</text>
|
||||
<text class="m-l-10rpx"> {{ hooks.useTime(v.checkTime, "") }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center justify-end m-t-25rpx">
|
||||
<text v-if="v.processStatus == 2" class="botder_btn">使用</text>
|
||||
<text v-else class="botder_btn">查看</text>
|
||||
</view>
|
||||
</view>
|
||||
<template #bottom>
|
||||
<view
|
||||
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!"
|
||||
@tap="doApply">
|
||||
申请
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
</template>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
<crud-layout title="跨单位就餐" bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
<view class="bg-white rounded-16rpx px-20rpx">
|
||||
<z-tabs :list="data.tabs" @change="doTab" />
|
||||
</view>
|
||||
</template>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-col card p-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="doCard(v)">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="sub-text-30">跨单位就餐</view>
|
||||
<view class="flex-row items-center">
|
||||
<view class="second-text-26">{{ hooks.useTime(v.createTime, "") }}</view>
|
||||
<view class="flex-row-center m-l-20rpx">
|
||||
<tm-tag v-if="v.processStatus == 1" size="xs" color="info">待审核</tm-tag>
|
||||
<tm-tag v-if="v.processStatus == 2" size="xs" color="success">已通过</tm-tag>
|
||||
<tm-tag v-if="v.processStatus == 3" size="xs" color="error">已拒绝</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
|
||||
<view class="flex items-center justify-between second-text-26">
|
||||
<view class="flex items-center">
|
||||
<text>数量</text>
|
||||
<text class="m-l-10rpx">{{ v.count }}</text>
|
||||
</view>
|
||||
<view class="color-red">
|
||||
<text>已使用</text>
|
||||
<text class="m-l-10rpx">{{ v.useCount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="v.processStatus != 1 && false">
|
||||
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
|
||||
<view class="flex items-center justify-between second-text-26">
|
||||
<view class="flex items-center">
|
||||
<text>审核人</text>
|
||||
<text class="m-l-10rpx">{{ v.checkUserName }}</text>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<text>审核时间</text>
|
||||
<text class="m-l-10rpx"> {{ hooks.useTime(v.checkTime, "") }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center justify-end m-t-25rpx">
|
||||
<text v-if="v.processStatus == 2" class="botder_btn">使用</text>
|
||||
<text v-else class="botder_btn">查看</text>
|
||||
</view>
|
||||
</view>
|
||||
<template #bottom>
|
||||
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!" @tap="doApply">
|
||||
申请
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
</template>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { boxesApi } from "@@/api"
|
||||
@@ -8,119 +8,124 @@ import { boxesApi } from "@@/api"
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
|
||||
const data = {
|
||||
tabs: [
|
||||
{ id: null, name: '全部', disabled: false },
|
||||
{ id: "0", name: '预约成功', disabled: false },
|
||||
{ id: "1", name: '预约失败', disabled: false },
|
||||
{ id: "2", name: '取消预约', disabled: false },
|
||||
],
|
||||
tabs: [
|
||||
{ id: null, name: "全部", disabled: false },
|
||||
{ id: "0", name: "预约成功", disabled: false },
|
||||
{ id: "1", name: "预约失败", disabled: false },
|
||||
{ id: "2", name: "取消预约", disabled: false },
|
||||
],
|
||||
}
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
status: data.tabs[0].id,
|
||||
},
|
||||
pa: {
|
||||
status: data.tabs[0].id,
|
||||
},
|
||||
})
|
||||
|
||||
onLoad(() => {
|
||||
|
||||
});
|
||||
onLoad(() => {})
|
||||
onShow(() => {
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, boxesApi.MyBookingPage, null, 'data.list')
|
||||
const pageHook = hooks.usePage(pageRef, boxesApi.MyBookingPage, null, "data.list")
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa);
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
const doTab = (e: any) => {
|
||||
const target = data.tabs[e];
|
||||
state.pa.status = target.id
|
||||
pageRef.value.reload(true)
|
||||
const target = data.tabs[e]
|
||||
state.pa.status = target.id
|
||||
pageRef.value.reload(true)
|
||||
}
|
||||
|
||||
const doCard = (v: any) => {
|
||||
router.jump('/pages/boxes/detail', { id: v.id })
|
||||
router.jump("/pages/boxes/detail", { id: v.id })
|
||||
}
|
||||
|
||||
const doCancelApply = async (v: any) => {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '是否确定取消预约',
|
||||
confirmColor: '#0094ff',
|
||||
success: async (res) => {
|
||||
if (!res.confirm) return
|
||||
try {
|
||||
uni.showLoading({ title: '取消预约中...', mask: true });
|
||||
const _pa = { id: v.id }
|
||||
const { data, code }: any = await boxesApi.cancel(_pa)
|
||||
if (code != 0) throw new Error()
|
||||
pageRef.value.reload(true)
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '取消预约成功', icon: "none" });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
})
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "是否确定取消预约",
|
||||
confirmColor: "#0094ff",
|
||||
success: async (res) => {
|
||||
if (!res.confirm) return
|
||||
try {
|
||||
uni.showLoading({ title: "取消预约中...", mask: true })
|
||||
const _pa = { id: v.id }
|
||||
const { data, code }: any = await boxesApi.cancel(_pa)
|
||||
if (code != 0) throw new Error()
|
||||
pageRef.value.reload(true)
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "取消预约成功", icon: "none" })
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
uni.hideLoading()
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<crud-layout title="包厢预约" bg="/static/page/blue-bg.png">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="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">
|
||||
<template #top>
|
||||
<view class="bg-white rounded-16rpx px-20rpx m-x-10rpx m-t-15rpx">
|
||||
<z-tabs :list="data.tabs" @change="doTab" />
|
||||
</view>
|
||||
</template>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-col card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="doCard(v)">
|
||||
<view>
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="main-text-28">{{ v.boxesName }}</view>
|
||||
<view>
|
||||
<tm-tag v-if="v.status == 0" color="success" size="xs">预约成功</tm-tag>
|
||||
<tm-tag v-if="v.status == 1" color="error" size="xs">预约失败</tm-tag>
|
||||
<tm-tag v-if="v.status == 2" color="info" size="xs">取消预约</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
<view class="m-t-10rpx second-text-26">
|
||||
<text>预约时间</text>
|
||||
<text class="m-l-5rpx">
|
||||
{{ v.bookingDate }} {{ hooks.useTime(v.startTime, "{h}:{i}") }} ~ {{
|
||||
hooks.useTime(v.endTime, "{h}:{i}")
|
||||
}}
|
||||
</text>
|
||||
</view>
|
||||
<view class="m-t-10rpx second-text-26">
|
||||
<text>提交时间</text>
|
||||
<text class="m-l-5rpx">
|
||||
{{ hooks.useTime(v.createTime, "") }}
|
||||
</text>
|
||||
</view>
|
||||
<view>
|
||||
<text class="main-text-28">审批状态:</text>
|
||||
<tm-tag v-if="v.checkStatus == '1'" color="info" size="xs">审批中</tm-tag>
|
||||
<tm-tag v-if="v.checkStatus == '2'" color="success" size="xs">审批通过</tm-tag>
|
||||
<tm-tag v-if="v.checkStatus == '3'" color="error" size="xs">审批不通过</tm-tag>
|
||||
<tm-tag v-if="v.checkStatus == '4'" color="info" size="xs">已取消</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-row items-center justify-end p-t-10rpx">
|
||||
<view class="botder_btn" @tap.stop="doCancelApply(v)">取消预约</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
<crud-layout title="包厢预约" bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<template #top>
|
||||
<view class="bg-white rounded-16rpx px-20rpx m-x-10rpx m-t-15rpx">
|
||||
<z-tabs :list="data.tabs" @change="doTab" />
|
||||
</view>
|
||||
</template>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-col card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="doCard(v)">
|
||||
<view>
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="main-text-28">{{ v.boxesName }}</view>
|
||||
<view>
|
||||
<tm-tag v-if="v.status == 0" color="success" size="xs">预约成功</tm-tag>
|
||||
<tm-tag v-if="v.status == 1" color="error" size="xs">预约失败</tm-tag>
|
||||
<tm-tag v-if="v.status == 2" color="info" size="xs">取消预约</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
<view class="m-t-10rpx second-text-26">
|
||||
<text>预约时间</text>
|
||||
<text class="m-l-5rpx">
|
||||
{{ v.bookingDate }} {{ hooks.useTime(v.startTime, "{h}:{i}") }} ~ {{ hooks.useTime(v.endTime, "{h}:{i}") }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="m-t-10rpx second-text-26">
|
||||
<text>提交时间</text>
|
||||
<text class="m-l-5rpx">
|
||||
{{ hooks.useTime(v.createTime, "") }}
|
||||
</text>
|
||||
</view>
|
||||
<view>
|
||||
<text class="main-text-28">审批状态:</text>
|
||||
<tm-tag v-if="v.checkStatus == '1'" color="info" size="xs">审批中</tm-tag>
|
||||
<tm-tag v-if="v.checkStatus == '2'" color="success" size="xs">审批通过</tm-tag>
|
||||
<tm-tag v-if="v.checkStatus == '3'" color="error" size="xs">审批不通过</tm-tag>
|
||||
<tm-tag v-if="v.checkStatus == '4'" color="info" size="xs">已取消</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-row items-center justify-end p-t-10rpx">
|
||||
<view class="botder_btn" @tap.stop="doCancelApply(v)">取消预约</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -6,8 +6,6 @@ import { isEmpty } from "radash"
|
||||
import { router } from "@@/index"
|
||||
import { boxesApi } from "@@/api"
|
||||
|
||||
import zSwiper from "@zebra-ui/swiper/components/z-swiper/z-swiper.vue"
|
||||
import zSwiperItem from "@zebra-ui/swiper/components/z-swiper-item/z-swiper-item.vue"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
|
||||
const state = reactive<any>({
|
||||
@@ -38,12 +36,20 @@ const doSubmit = () => {
|
||||
|
||||
<template>
|
||||
<crud-layout mainIsScroll tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
|
||||
<z-swiper>
|
||||
<z-swiper-item v-for="(v, i) in state.detail.imagesArray" :key="i">
|
||||
<image class="w-100vw" :src="filePath(v)" mode="widthFix" />
|
||||
</z-swiper-item>
|
||||
</z-swiper>
|
||||
<view class="p-x-15rpx">
|
||||
<swiper
|
||||
class="w-100vw h-30vh"
|
||||
circular
|
||||
:indicator-dots="true"
|
||||
indicator-active-color="#0779FD"
|
||||
indicator-color="#ffffff"
|
||||
:autoplay="true"
|
||||
>
|
||||
<swiper-item v-for="(v, i) in state.detail?.imagesArray" :key="i">
|
||||
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<view class="p-15rpx">
|
||||
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row items-center">
|
||||
|
||||
@@ -2,27 +2,23 @@
|
||||
import { reactive, nextTick } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { merchantApi, foodApi, payApi } from "@@/api"
|
||||
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
import zSwiper from "@zebra-ui/swiper/components/z-swiper/z-swiper.vue"
|
||||
import zSwiperItem from "@zebra-ui/swiper/components/z-swiper-item/z-swiper-item.vue"
|
||||
|
||||
import ProductRow from "./components/product-row.vue"
|
||||
import ProductCar from "./components/product-car.vue"
|
||||
import ProductTotal from "./components/product-total.vue"
|
||||
|
||||
const state = reactive<any>({
|
||||
detailId: null,
|
||||
canteenDetail: {},
|
||||
|
||||
totPrice: 0,
|
||||
totCount: 0,
|
||||
currentClassifyIndex: 0,
|
||||
showCarDialog: false,
|
||||
|
||||
detail: {},
|
||||
carList: [],
|
||||
classifyList: [],
|
||||
shopList: [],
|
||||
@@ -39,20 +35,16 @@ onShow(() => {
|
||||
getClassify()
|
||||
})
|
||||
|
||||
// 获取食堂详情信息
|
||||
const getDetail = async () => {
|
||||
uni.showLoading({
|
||||
title: "加载中...",
|
||||
mask: true,
|
||||
})
|
||||
const _pa = { id: state.detailId }
|
||||
const { data } = await merchantApi.detail(_pa)
|
||||
state.detail = data
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
const { code, data } = await merchantApi.detail({ id: state.detailId })
|
||||
if (code == 0) state.canteenDetail = data
|
||||
uni.hideLoading()
|
||||
}
|
||||
|
||||
const getShopCar = async () => {
|
||||
const _pa = { merchantId: state.detailId, hardType: "CANTEEN" }
|
||||
const { data } = await foodApi.getShopCar(_pa)
|
||||
const { data } = await foodApi.getShopCar({ merchantId: state.detailId, hardType: "CANTEEN" })
|
||||
state.carList = data ?? []
|
||||
if (isEmpty(state.carList)) {
|
||||
state.shopList.forEach((v: any) => {
|
||||
@@ -204,11 +196,11 @@ const getHeight = () => {
|
||||
}
|
||||
|
||||
const doPhone = () => {
|
||||
if (isEmpty(state.detail.phone)) {
|
||||
if (isEmpty(state.canteenDetail.phone)) {
|
||||
uni.showToast({ title: "该商户没有预留电话", icon: "none" })
|
||||
return
|
||||
}
|
||||
hooks.useMakePhoneCall(state.detail.phone)
|
||||
hooks.useMakePhoneCall(state.canteenDetail.phone)
|
||||
}
|
||||
const doFood = () => {
|
||||
router.jump("/pages/merchant/food", { merchantId: state.detailId })
|
||||
@@ -218,43 +210,49 @@ const doFood = () => {
|
||||
<template>
|
||||
<crud-layout mainIsScroll tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
|
||||
<tm-sticky>
|
||||
<!-- start 轮播 start -->
|
||||
<z-swiper>
|
||||
<z-swiper-item v-for="(v, i) in state.detail.swiperPic?.split(',')" :key="i">
|
||||
<image class="w-100vw h-400rpx" :src="filePath(v)" mode="aspectFill" />
|
||||
</z-swiper-item>
|
||||
</z-swiper>
|
||||
<!-- end 轮播 end -->
|
||||
<swiper
|
||||
class="w-100vw h-30vh"
|
||||
circular
|
||||
:indicator-dots="true"
|
||||
indicator-active-color="#0779FD"
|
||||
indicator-color="#ffffff"
|
||||
:autoplay="true"
|
||||
>
|
||||
<swiper-item v-for="(v, i) in state.canteenDetail?.swiperPic?.split(',')" :key="i">
|
||||
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<tm-sticky-header>
|
||||
<view class="m-x-30rpx">
|
||||
<!-- start 简介 start -->
|
||||
<view class="h-15rpx" />
|
||||
<view flex-row card p-20rpx>
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(state.detail.logoPic)" mode="aspectFill" />
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(state.canteenDetail.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-34">
|
||||
<text>{{ state.detail.name }}</text>
|
||||
<text>{{ state.canteenDetail.name }}</text>
|
||||
</view>
|
||||
<view>
|
||||
<tm-tag size="s">{{ state.detail.deptName }}</tm-tag>
|
||||
<tm-tag size="s">{{ state.canteenDetail.deptName }}</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
<view class="second-text-24">
|
||||
<view class="second-text-28">营业时间:</view>
|
||||
<view>
|
||||
{{ state.detail.jobTime?.split(",")[0] ? "早:" + state.detail.jobTime?.split(",")[0] : "" }}
|
||||
{{ state.canteenDetail.jobTime?.split(",")[0] ? "早:" + state.canteenDetail.jobTime?.split(",")[0] : "" }}
|
||||
</view>
|
||||
<view>
|
||||
{{ state.detail.jobTime?.split(",")[1] ? "中:" + state.detail.jobTime?.split(",")[1] : "" }}
|
||||
{{ state.canteenDetail.jobTime?.split(",")[1] ? "中:" + state.canteenDetail.jobTime?.split(",")[1] : "" }}
|
||||
</view>
|
||||
<view>
|
||||
{{ state.detail.jobTime?.split(",")[2] ? "晚:" + state.detail.jobTime?.split(",")[2] : "" }}
|
||||
{{ state.canteenDetail.jobTime?.split(",")[2] ? "晚:" + state.canteenDetail.jobTime?.split(",")[2] : "" }}
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="state.detail.addressDes" class="m-t-10rpx second-text-28">
|
||||
<view v-if="state.canteenDetail.addressDes" class="m-t-10rpx second-text-28">
|
||||
<text>食堂地址:</text>
|
||||
<text class="m-l-10rpx">{{ state.detail.addressDes }}</text>
|
||||
<text class="m-l-10rpx">{{ state.canteenDetail.addressDes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -287,8 +285,9 @@ const doFood = () => {
|
||||
</view>
|
||||
</tm-sticky-header>
|
||||
|
||||
<!-- start 商品 start -->
|
||||
<view class="h-15rpx" />
|
||||
|
||||
<!-- start 商品 start -->
|
||||
<view class="flex-row">
|
||||
<scroll-view
|
||||
v-if="state.classifyList.length > 0"
|
||||
|
||||
@@ -138,9 +138,9 @@ const doProduct = (v: any) => {
|
||||
:list="foodList"
|
||||
:gutter="10"
|
||||
:breakpoints="{
|
||||
1200: { rowPerView: 4 },
|
||||
800: { rowPerView: 3 },
|
||||
375: { rowPerView: 2 },
|
||||
1800: { rowPerView: 4 },
|
||||
1400: { rowPerView: 3 },
|
||||
975: { rowPerView: 2 },
|
||||
}"
|
||||
:hasAroundGutter="false"
|
||||
backgroundColor="#ffffff00"
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { hooks } from "@@/index"
|
||||
import { foodApi } from "@@/api"
|
||||
|
||||
const data = {}
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
status: 1,
|
||||
},
|
||||
})
|
||||
|
||||
onLoad(() => {})
|
||||
onShow(() => {})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="订单详情" bg="/static/page/blue-bg.png"> </crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -2,11 +2,8 @@
|
||||
import { reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
import { hooks } from "@@/index"
|
||||
import { productApi } from "@@/api"
|
||||
import { filePath } from "@@/utils/file"
|
||||
import zSwiper from "@zebra-ui/swiper/components/z-swiper/z-swiper.vue"
|
||||
import zSwiperItem from "@zebra-ui/swiper/components/z-swiper-item/z-swiper-item.vue"
|
||||
|
||||
const state = reactive<any>({
|
||||
detailId: null,
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
|
||||
import { hooks, constant, router } from "@@/index"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { orderApi, refundApi } from "@@/api"
|
||||
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const data = {}
|
||||
const state = reactive<any>({
|
||||
detailId: null,
|
||||
detail: {},
|
||||
@@ -77,11 +76,7 @@ const doCancelRefund = async () => {
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
<view class="relative flex-col justify-center overflow-hidden card p-x-20rpx p-y-30rpx m-b-20rpx">
|
||||
<image
|
||||
class="absolute top--20rpx right--60rpx w-160rpx h-160rpx"
|
||||
src="/static/icon/guarantee.png"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<image class="absolute top--20rpx right--60rpx w-160rpx h-160rpx" src="/static/icon/guarantee.png" mode="widthFix" />
|
||||
<view class="sub-text-32">订单信息</view>
|
||||
<view class="m-t-15rpx">
|
||||
<view class="info_cell">
|
||||
@@ -94,7 +89,7 @@ const doCancelRefund = async () => {
|
||||
</view>
|
||||
<view class="info_cell">
|
||||
<view>商户</view>
|
||||
<view>{{ state.detail.merchantStr }}</view>
|
||||
<view>{{ state.detail.merchantName }}</view>
|
||||
</view>
|
||||
<view class="m-t-15rpx h-1px bg-#999 bg-opacity-5" />
|
||||
<view class="info_cell">
|
||||
@@ -184,10 +179,7 @@ const doCancelRefund = async () => {
|
||||
<view>{{ state.refundDetail.applyDescription }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="state.refundDetail.status == 62"
|
||||
class="card p-x-20rpx p-y-30rpx space-y-10rpx m-b-20rpx second-text-24"
|
||||
>
|
||||
<view v-if="state.refundDetail.status == 62" class="card p-x-20rpx p-y-30rpx space-y-10rpx m-b-20rpx second-text-24">
|
||||
<view class="flex-row items-center">
|
||||
<view>审核人:</view>
|
||||
<view>{{ state.refundDetail.auditUsername }}</view>
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<view class="w-full h-full">
|
||||
<view class="flex-col-center p-30rpx">
|
||||
<view class="flex-col-center m-y-50rpx">
|
||||
<svg
|
||||
t="1742978804614"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="1708"
|
||||
width="64"
|
||||
height="64"
|
||||
>
|
||||
<path
|
||||
d="M512 0C230.4 0 0 230.4 0 512s230.4 512 512 512 512-230.4 512-512S793.6 0 512 0z m288 371.2L460.8 710.4c-6.4 6.4-19.2 12.8-25.6 12.8-12.8 0-19.2-6.4-25.6-12.8L224 531.2c-12.8-12.8-12.8-38.4 0-57.6 12.8-12.8 38.4-12.8 57.6 0l147.2 147.2L736 313.6c12.8-12.8 38.4-12.8 57.6 0 19.2 19.2 19.2 44.8 6.4 57.6z"
|
||||
fill="#2BCDA3"
|
||||
p-id="1709"
|
||||
data-spm-anchor-id="a313x.search_index.0.i2.beb13a81SVstw0"
|
||||
class="selected"
|
||||
></path>
|
||||
</svg>
|
||||
<text class="text-36 mt-3 font-bold c-#333333!">支付成功</text>
|
||||
</view>
|
||||
|
||||
<view class="flex-col-center m-b-60rpx">
|
||||
<text class="text-90 c-#333333!">¥{{ payData.customPrice }}</text>
|
||||
</view>
|
||||
|
||||
<view class="w-full p-10rpx flex-col justify-center">
|
||||
<view class="flex-row justify-between m-15rpx">
|
||||
<text class="sub-text-30 c-#333333!">商家</text>
|
||||
<text class="sub-text-30">{{ payData.name }}</text>
|
||||
</view>
|
||||
<hr />
|
||||
<view class="flex-row justify-between m-15rpx">
|
||||
<text class="sub-text-30 c-#333333!">支付方式</text>
|
||||
<text class="sub-text-30">扫一扫</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="p-40rpx fixed bottom-30rpx left-0 right-0 font-bold">
|
||||
<tm-button :block="true" @click="goBack">完成</tm-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue"
|
||||
import { onShow } from "@dcloudio/uni-app"
|
||||
import { router } from "@@/index"
|
||||
import { usePayStore } from "@/sheep/stores/pay"
|
||||
|
||||
const payData = ref<{ id?: string; name?: string; customPrice?: number }>({})
|
||||
|
||||
onShow(() => {
|
||||
if (!usePayStore().payData.id) return uni.showToast({ title: "支付信息不存在", icon: "none" })
|
||||
payData.value = usePayStore().payData
|
||||
})
|
||||
|
||||
const goBack = () => {
|
||||
router.jump("/pages/tabbar/my", {}, 2)
|
||||
}
|
||||
</script>
|
||||
@@ -1,71 +1,36 @@
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<view class="h-screen flex flex-col position-relative">
|
||||
<view class="mx-auto text-34 py-2">{{ scanData.name }}</view>
|
||||
<view class="mx-auto text-34 py-2 h-80rpx">{{ scanData.name }}</view>
|
||||
|
||||
<tm-sheet class="flex flex-row">
|
||||
<span class="text-2xl text-[#333] mr-1 line-height-normal">¥</span>
|
||||
<span class="text-3xl font-medium text-[#333]">{{ displayAmount }}</span>
|
||||
</tm-sheet>
|
||||
<tm-button class="mt-40" :block="true" @click="disabled ? '' : handlePay()" :disabled="disabled">支付</tm-button>
|
||||
|
||||
<view class="bg-[#f5f5f5] px-1 py-2 rounded-4 absolute bottom-0 w-full">
|
||||
<view class="flex mb-2.5" v-for="(row, rowIndex) in keyboardLayout" :key="rowIndex">
|
||||
<view
|
||||
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
v-for="(key, keyIndex) in row"
|
||||
:key="keyIndex"
|
||||
@click="handleKeyPress(key)"
|
||||
>
|
||||
{{ key }}
|
||||
<tm-sheet v-if="walletList.length > 0" class="flex flex-col">
|
||||
<view class="text-gray-700 font-bold text-sm mb-1">选择支付钱包:</view>
|
||||
<view
|
||||
v-for="(v, index) in walletList"
|
||||
:key="index"
|
||||
class="card relative border-4 border-solid my-1 duration-200 border-#efefef flex justify-between items-center p-3"
|
||||
:class="{ 'border-4 border-solid border-blue!': curWalletId == v.id }"
|
||||
@click="curWalletId = v.id"
|
||||
>
|
||||
<view class="flex items-center">
|
||||
<image class="w-70 h-70 mr-2" :src="filePath(v.walletTypeIcon)" />
|
||||
<view class="main-text-32">{{ v.walletTypeName }}</view>
|
||||
</view>
|
||||
<view class="main-text-28 flex items-center">
|
||||
<view>余额:{{ hooks.useMoney(v.balance) }}</view>
|
||||
<text>元</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex mb-0">
|
||||
<view
|
||||
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
@click="handleKeyPress('.')"
|
||||
>
|
||||
.
|
||||
</view>
|
||||
<view
|
||||
class="flex-auto h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
@click="handleKeyPress('0')"
|
||||
>
|
||||
0
|
||||
</view>
|
||||
<view
|
||||
class="flex-1 h-[60px] flex items-center justify-center bg-white mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
@click="handleDelete"
|
||||
>
|
||||
<svg
|
||||
t="1742457305987"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="4499"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path
|
||||
d="M897.706667 831.146667H286.72c-8.533333 0-15.36-3.413333-20.48-10.24L39.253333 527.36c-6.826667-8.533333-6.826667-22.186667 0-30.72l226.986667-293.546667c5.12-6.826667 11.946667-10.24 20.48-10.24h610.986667c51.2 0 92.16 40.96 92.16 92.16v453.973334c0 51.2-40.96 92.16-92.16 92.16z m-599.04-51.2h599.04c22.186667 0 40.96-18.773333 40.96-40.96V285.013333c0-22.186667-18.773333-40.96-40.96-40.96H298.666667L92.16 512l206.506667 267.946667z"
|
||||
fill="#333333"
|
||||
p-id="4500"
|
||||
></path>
|
||||
<path
|
||||
d="M670.72 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667L426.666667 416.426667c-10.24-10.24-10.24-25.6 0-35.84 10.24-10.24 25.6-10.24 35.84 0l226.986666 226.986666c10.24 10.24 10.24 25.6 0 35.84-6.826667 5.12-11.946667 6.826667-18.773333 6.826667z"
|
||||
fill="#333333"
|
||||
p-id="4501"
|
||||
></path>
|
||||
<path
|
||||
d="M443.733333 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667-10.24-10.24-10.24-25.6 0-35.84l226.986667-226.986666c10.24-10.24 25.6-10.24 35.84 0 10.24 10.24 10.24 25.6 0 35.84L462.506667 643.413333c-5.12 5.12-11.946667 6.826667-18.773334 6.826667z"
|
||||
fill="#333333"
|
||||
p-id="4502"
|
||||
></path>
|
||||
</svg>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
<tm-button class="mt-1" :block="true" @click="disabled ? '' : handlePay()" :disabled="disabled">支付</tm-button>
|
||||
|
||||
<numberKeyboard v-model="amount" />
|
||||
</view>
|
||||
</crud-layout>
|
||||
</template>
|
||||
@@ -77,24 +42,38 @@ import { usePayStore } from "@/sheep/stores/pay"
|
||||
import payApi from "@@/api/pay"
|
||||
import { storePrice } from "@/sheep/utils/formatMoney"
|
||||
import { router } from "@/sheep"
|
||||
import { merchantApi, walletApi } from "@/sheep/api"
|
||||
import numberKeyboard from "@/sheep/components/numberKeyboard.vue"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
import { hooks } from "@@/index"
|
||||
|
||||
const amount = ref("")
|
||||
const keyboardLayout = ref([
|
||||
["1", "2", "3"],
|
||||
["4", "5", "6"],
|
||||
["7", "8", "9"],
|
||||
])
|
||||
const scanData = ref<{ id?: string; name?: string }>({})
|
||||
const disabled = ref(false)
|
||||
const walletList = ref<any>([])
|
||||
const curWalletId = ref("")
|
||||
|
||||
onShow(() => {
|
||||
scanData.value = usePayStore().payData
|
||||
if (scanData.value.id && scanData.value.name) {
|
||||
onShow(async () => {
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
scanData.value.id = usePayStore().payData.id
|
||||
if (scanData.value.id) {
|
||||
const { data } = await merchantApi.detail({ id: scanData.value.id })
|
||||
scanData.value.name = data.name
|
||||
usePayStore().setPayData(scanData.value)
|
||||
disabled.value = false
|
||||
} else {
|
||||
uni.showToast({ title: "扫码信息不存在", icon: "none" })
|
||||
disabled.value = true
|
||||
}
|
||||
|
||||
const res = await walletApi.all()
|
||||
if (res.code == 0) {
|
||||
walletList.value = res.data.records
|
||||
if (walletList.value.length > 0) {
|
||||
curWalletId.value = walletList.value.find((v: any) => v.walletTypeUniqueCode == "1").id
|
||||
}
|
||||
}
|
||||
uni.hideLoading()
|
||||
})
|
||||
|
||||
const displayAmount = computed(() => {
|
||||
@@ -107,27 +86,6 @@ const displayAmount = computed(() => {
|
||||
)
|
||||
})
|
||||
|
||||
// 按下键盘
|
||||
const handleKeyPress = (key) => {
|
||||
if (key === "." && amount.value.includes(".")) return
|
||||
if (key === "." && !amount.value) {
|
||||
amount.value = "0."
|
||||
return
|
||||
}
|
||||
|
||||
if (amount.value.includes(".")) {
|
||||
const decimalPlaces = amount.value.split(".")[1]
|
||||
if (decimalPlaces && decimalPlaces.length >= 2) return
|
||||
}
|
||||
|
||||
amount.value += key
|
||||
}
|
||||
|
||||
// 点击删除
|
||||
const handleDelete = () => {
|
||||
amount.value = amount.value.slice(0, -1)
|
||||
}
|
||||
|
||||
// 点击支付
|
||||
const handlePay = () => {
|
||||
if (!scanData.value.id || !scanData.value.name) return uni.showToast({ title: "扫码信息不存在", icon: "none" })
|
||||
@@ -156,19 +114,17 @@ const pay = async () => {
|
||||
const res = await payApi.createQrCodeOrder({
|
||||
merchantId: scanData.value.id,
|
||||
customPrice: storePrice(Number(amount.value)),
|
||||
walletId: curWalletId.value,
|
||||
})
|
||||
if (res.code != 0) {
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
uni.showToast({ title: "支付成功", icon: "success" })
|
||||
usePayStore().payData = {}
|
||||
setTimeout(() => {
|
||||
router.back()
|
||||
uni.showToast({ title: res.msg || "支付失败", icon: "error" })
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
}, 1000)
|
||||
usePayStore().setPayData({ ...scanData.value, customPrice: Number(amount.value).toFixed(2) })
|
||||
router.jump("/pages/pay/payComplete", {}, 2)
|
||||
}
|
||||
} catch (error: any) {
|
||||
// uni.showToast({ title: "错误", icon: "error" })
|
||||
uni.showToast({ title: "错误", icon: "error" })
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
<template>
|
||||
<view class="bg-gray-100 flex-col min-h-screen">
|
||||
<view class="bg-white p-4 card mx-3 my-1 mt-2 flex items-center justify-between">
|
||||
<view class="flex items-center">
|
||||
<image class="w-64 h-64 mr-2" :src="filePath(transferMoney.sourceWalletType.walletTypeIcon)" />
|
||||
<view>{{ transferMoney.sourceWalletType.walletTypeName }}</view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<view class="main-text-28">余额:</view>
|
||||
<view class="main-text-28 mr-1">{{ hooks.useMoney(transferMoney.sourceWalletType.balance) + "元" }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bg-white p-4 card mx-3 my-1 flex items-center justify-between active:bg-[#f0f0f0]" @click="targetWalletSelect">
|
||||
<view class="flex items-center">
|
||||
<image class="w-64 h-64 rounded-full mr-2" src="@/static/page/money-cny-circle-fill.svg" />
|
||||
<view>转入到</view>
|
||||
</view>
|
||||
<view class="flex items-center">
|
||||
<view class="second-text-28 mr-1">{{ state.targetWalletTypeName }}</view>
|
||||
<image class="w-38 h-38 rounded-full c-blueGray" src="@/static/page/arrow-right.svg" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="bg-white p-4 card mx-3 my-1">
|
||||
<text class="text-gray-700 font-bold text-lg">转账金额</text>
|
||||
<view class="flex-row items-center">
|
||||
<text class="text-3xl text-[#333] mr-2">¥</text>
|
||||
<text v-if="!amount" class="text-xl text-gray-300">转账金额</text>
|
||||
<text v-else class="text-3xl">{{ formattedAmount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 金额限制提示 -->
|
||||
<view class="h-30rpx">
|
||||
<view v-if="storePrice(amount) > transferMoney.sourceWalletType?.balance" class="text-xs c-red px-8">
|
||||
注:转账金额不能超过钱包余额
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="p-4 font-bold mt-1">
|
||||
<tm-button block @click="confirmTransfer" v-if="transferMoney.sourceWalletType.walletTypeId">确定转账</tm-button>
|
||||
</view>
|
||||
|
||||
<number-keyboard v-model="amount" />
|
||||
|
||||
<!-- 选择转入方式 -->
|
||||
<tm-drawer v-model:show="show" title="选择钱包" size="50%" bg-color="#efefef" position="bottom" :show-footer="true" :showClose="true">
|
||||
<view class="m-4">
|
||||
<view
|
||||
v-for="(v, index) in state.walletList"
|
||||
:key="index"
|
||||
class="card mb-2 overflow-hidden relative border-4 border-solid border-white duration-200 flex justify-between items-center p-4"
|
||||
:class="{ 'border-4 border-solid border-blue!': state.targetWalletTypeId == v.walletTypeId }"
|
||||
@click="state.targetWalletTypeId = v.walletTypeId"
|
||||
>
|
||||
<view class="flex items-center">
|
||||
<image class="w-70 h-70 mr-2" :src="filePath(v.walletTypeIcon)" />
|
||||
<view class="flex flex-col">
|
||||
<view class="main-text-32">{{ v.walletTypeName }}</view>
|
||||
<view class="text-gray-500 text-sm">{{ v.cardNumber }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="main-text-32">余额:{{ hooks.useMoney(v.balance) + "元" }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<template #footer>
|
||||
<view class="font-bold px-5">
|
||||
<tm-button block @click="confirmTargetWallet">确 定</tm-button>
|
||||
</view>
|
||||
</template>
|
||||
</tm-drawer>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, reactive } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import NumberKeyboard from "@/sheep/components/numberKeyboard.vue"
|
||||
import { payApi, walletApi } from "@/sheep/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
import { storePrice } from "@/sheep/utils/formatMoney"
|
||||
import { useTransferMoney } from "@/sheep/stores/transferMoney"
|
||||
|
||||
const transferMoney = useTransferMoney()
|
||||
const amount = ref("")
|
||||
const show = ref(false)
|
||||
const state = reactive<any>({
|
||||
sourceWalletTypeId: "",
|
||||
sourceWalletTypeName: "",
|
||||
walletList: [],
|
||||
targetWalletTypeId: "",
|
||||
targetWalletTypeName: "",
|
||||
})
|
||||
const curTargetWallet = ref()
|
||||
|
||||
onLoad(async () => {
|
||||
if (!transferMoney.sourceWalletType.walletTypeId) return uni.showToast({ title: "钱包类型id不存在", icon: "none" })
|
||||
state.sourceWalletTypeId = transferMoney.sourceWalletType.walletTypeId
|
||||
state.sourceWalletTypeName = transferMoney.sourceWalletType.walletTypeName
|
||||
uni.setNavigationBarTitle({ title: state.sourceWalletTypeName || "源钱包" })
|
||||
|
||||
const res = await walletApi.all()
|
||||
if (res.code == 0) {
|
||||
state.walletList = res.data.records.filter((item: any) => item.walletTypeId != state.sourceWalletTypeId)
|
||||
}
|
||||
if (!curTargetWallet.value) {
|
||||
curTargetWallet.value = state.walletList[0]
|
||||
state.targetWalletTypeId = state.walletList[0]?.walletTypeId
|
||||
state.targetWalletTypeName = state.walletList[0]?.walletTypeName
|
||||
}
|
||||
})
|
||||
|
||||
// 目标钱包选择
|
||||
const targetWalletSelect = () => {
|
||||
// state.sourceWalletTypeId = ""
|
||||
show.value = true
|
||||
}
|
||||
|
||||
// 确认目标钱包
|
||||
const confirmTargetWallet = () => {
|
||||
// state.sourceWalletTypeName = state.walletList.find((item: any) => item.walletTypeId != state.sourceWalletTypeId).walletTypeName
|
||||
show.value = false
|
||||
}
|
||||
|
||||
// 格式化金额显示
|
||||
const formattedAmount = computed(() => {
|
||||
if (!amount.value) return ""
|
||||
|
||||
// 处理小数点情况
|
||||
if (amount.value.endsWith(".")) {
|
||||
return amount.value
|
||||
}
|
||||
|
||||
const parts = amount.value.split(".")
|
||||
// 添加千位分隔符
|
||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",")
|
||||
|
||||
// 处理小数部分
|
||||
if (parts.length > 1) {
|
||||
// 如果小数部分不足两位,不自动补零
|
||||
return `${parts[0]}.${parts[1]}`
|
||||
}
|
||||
|
||||
return parts[0]
|
||||
})
|
||||
|
||||
const numAmount = computed(() => storePrice(parseFloat(amount.value.endsWith(".") ? amount.value.slice(0, -1) : amount.value)))
|
||||
|
||||
// 确认转账
|
||||
const confirmTransfer = async () => {
|
||||
if (!amount.value || amount.value === "0" || amount.value === "0." || parseFloat(amount.value) === 0) {
|
||||
return uni.showToast({ title: "金额不能为零", icon: "none" })
|
||||
}
|
||||
if (numAmount.value > transferMoney.sourceWalletType.balance) {
|
||||
return uni.showToast({ title: "转账金额不能超过钱包余额", icon: "none" })
|
||||
}
|
||||
|
||||
// console.log("state.sourceWalletTypeId", state.sourceWalletTypeId)
|
||||
// console.log("state.targetWalletTypeId", state.targetWalletTypeId)
|
||||
// console.log("金额", numAmount.value)
|
||||
|
||||
uni.showModal({
|
||||
title: "确定转入吗?",
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
await confirmTransferAgain()
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
// 二次确认转账
|
||||
const confirmTransferAgain = async () => {
|
||||
try {
|
||||
uni.showLoading({ title: "正在转入...", mask: true })
|
||||
const res = await payApi.transferMoney({
|
||||
sourceWalletTypeId: state.sourceWalletTypeId,
|
||||
targetWalletTypeId: state.targetWalletTypeId,
|
||||
balance: numAmount.value,
|
||||
})
|
||||
if (res.code == 0) {
|
||||
uni.showToast({ title: "转账成功", icon: "success" })
|
||||
transferMoney.setSourceWalletType({})
|
||||
// router.jump("/pages/wallet/list", {}, 2)
|
||||
router.back()
|
||||
} else {
|
||||
uni.showToast({ title: res.msg, icon: "none" })
|
||||
}
|
||||
} catch (error: any) {
|
||||
uni.showToast({
|
||||
title: error.message,
|
||||
icon: "none",
|
||||
})
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -119,34 +119,34 @@ const doSubmit = async () => {
|
||||
<crud-layout title="申请售后" mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<view class="h-30rpx" />
|
||||
<view class="flex-col justify-center card p-x-20rpx p-y-30rpx m-b-20rpx">
|
||||
<view class="m-t-15rpx">
|
||||
<view
|
||||
class="flex-row items-start justify-between"
|
||||
v-for="(v, i) in state.shopCarList"
|
||||
:key="i"
|
||||
@tap.stop="router.jump('/pages/merchant/product-detail', { id: v.productId })"
|
||||
>
|
||||
<view class="flex-row items-center">
|
||||
<image class="w-160rpx h-160rpx rounded-8rpx" :src="filePath(v.productPic)" mode="aspectFill" />
|
||||
<view class="flex-col m-l-15rpx second-text-26">
|
||||
<view class="sub-text-28">{{ v.productName }}</view>
|
||||
<view class="m-t-5rpx">¥ {{ hooks.useMoney(v.productPrice) }}</view>
|
||||
<view class="m-t-5rpx">x {{ v.productCount }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-row-center">
|
||||
<view class="sub-text-32">¥ {{ hooks.useMoney(v.totalPrice) }}</view>
|
||||
<!-- <view class="m-t-15rpx"> -->
|
||||
<view
|
||||
class="flex-row items-start justify-between"
|
||||
v-for="(v, i) in state.shopCarList"
|
||||
:key="i"
|
||||
@tap.stop="router.jump('/pages/merchant/product-detail', { id: v.productId })"
|
||||
>
|
||||
<view class="flex-row items-center">
|
||||
<image class="w-160rpx h-160rpx rounded-8rpx" :src="filePath(v.productPic)" mode="aspectFill" />
|
||||
<view class="flex-col m-l-15rpx second-text-26">
|
||||
<view class="sub-text-28">{{ v.productName }}</view>
|
||||
<view class="m-t-5rpx">¥ {{ hooks.useMoney(v.productPrice) }}</view>
|
||||
<view class="m-t-5rpx">x {{ v.productCount }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="m-y-15rpx h-1px bg-#999 bg-opacity-5" />
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="sub-text-28">实付款</view>
|
||||
<view class="flex-row items-end">
|
||||
<view class="sub-text-28">¥</view>
|
||||
<view class="m-l-5rpx sub-text-28">{{ hooks.useMoney(state.detail.payPrice) }}</view>
|
||||
</view>
|
||||
<view class="flex-row-center">
|
||||
<view class="sub-text-32">¥ {{ hooks.useMoney(v.totalPrice) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="m-y-15rpx h-1px bg-#999 bg-opacity-5" /> -->
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="sub-text-28">实付款</view>
|
||||
<view class="flex-row items-end">
|
||||
<view class="sub-text-28">¥</view>
|
||||
<view class="m-l-5rpx sub-text-28">{{ hooks.useMoney(state.detail.payPrice) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- </view> -->
|
||||
</view>
|
||||
<view class="card p-x-20rpx p-y-30rpx m-b-20rpx">
|
||||
<view class="sub-text-28">售后类型</view>
|
||||
@@ -208,5 +208,3 @@ const doSubmit = async () => {
|
||||
</template>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -0,0 +1,152 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { merchantApi } from "@@/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
pagesize: 10,
|
||||
type: "2",
|
||||
parentId: "",
|
||||
},
|
||||
})
|
||||
const pageHook = hooks.usePage(pageRef, merchantApi.childrenPage, null, "data.records")
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad((options: any) => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
|
||||
if (options.parentId) {
|
||||
state.pa.parentId = options.parentId
|
||||
}
|
||||
})
|
||||
onShow(async () => {
|
||||
pageRef.value && pageRef.value.reload(false)
|
||||
uni.showLoading({
|
||||
title: "加载中...",
|
||||
mask: true,
|
||||
})
|
||||
try {
|
||||
await getDetail()
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: "加载失败",
|
||||
icon: "error",
|
||||
})
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
uni.setNavigationBarTitle({ title: state.detail.name })
|
||||
})
|
||||
|
||||
const getDetail = async () => {
|
||||
const { data } = await merchantApi.detail({ id: state.pa.parentId })
|
||||
state.detail = data
|
||||
}
|
||||
|
||||
const toDetail = async (v: any) => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
router.jump("/pages/shop/detail", { id: v.id })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view class="h-full overflow-hidden">
|
||||
<swiper
|
||||
class="w-100vw h-30vh"
|
||||
circular
|
||||
:indicator-dots="true"
|
||||
indicator-active-color="#0779FD"
|
||||
indicator-color="#ffffff"
|
||||
:autoplay="true"
|
||||
>
|
||||
<swiper-item v-for="(v, i) in state.detail?.swiperPic?.split(',')" :key="i">
|
||||
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<crud-layout>
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="70%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-34">{{ v.name.length > 7 ? v.name.substring(0, 7) + "..." : v.name }}</view>
|
||||
<tm-tag size="s">{{ v.deptName.length > 5 ? v.deptName.substring(0, 5) + "..." : v.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="m-t-10rpx">
|
||||
<view v-if="v.phone" class="flex items-center">
|
||||
<svg
|
||||
t="1743075703202"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="2684"
|
||||
width="12"
|
||||
height="12"
|
||||
>
|
||||
<path
|
||||
d="M575.7 647.1l69.4-69.2 13.3 2.3c1.7 0.3 4.9 0.9 9.4 1.7 7.4 1.3 15.7 2.9 24.6 4.5 25.5 4.8 50.9 9.8 74.8 14.9 17.3 3.7 33.1 7.3 47 10.7 27.6 6.8 47.3 12.9 59.1 18.6 43 20.8 60 65.5 53.4 122-9.7 81.3-97 174.3-204.4 175.4-121 1.2-291.4-87.7-411.9-214.7C165.3 560.4 81.8 406.9 98 278.3c8.5-67.1 40.2-115.9 87.8-147.2 32.4-21.3 69.4-32.5 97.9-34.6 38.2-2.8 69.6 9.6 92.5 38 9.7 12 19.7 36.1 32.2 73.3 3.6 10.9 7.4 22.8 11.3 35.4 7 23 14.1 47.6 20.9 72.2 2.4 8.6 4.5 16.6 6.4 23.7 1.1 4.3 2 7.4 2.4 9.1l3.7 14.2-80.4 81.8c44.5 89 122.6 169.8 203 202.9z m13.5 60l-15.3-5.1c-105.4-35.6-205.4-139.4-256.3-252.3l-7.3-16.2 85-86.4c-1.5-5.6-3.1-11.6-4.9-17.9-6.6-24.1-13.5-48.2-20.4-70.7-3.8-12.3-7.4-23.7-10.9-34.2-10.2-30.5-19.1-52-23.3-57.2-11.8-14.6-26.4-20.4-48.2-18.8-20.2 1.5-48.7 10.1-73.1 26.2-35.2 23.2-58.3 58.6-64.8 110.3-13.8 108.7 63.1 250.2 198.4 392.7C459.5 794.9 617 877 721.8 876c79.2-0.8 146.4-72.5 153.2-129.4 4.3-36.6-4.3-59.4-24.4-69.1-7.5-3.6-24.7-8.9-48.9-14.9-13.4-3.3-28.6-6.8-45.4-10.4-23.3-5-48.4-10-73.5-14.7-7.2-1.3-13.9-2.6-20.1-3.7l-73.5 73.3z"
|
||||
fill="#666666"
|
||||
p-id="2685"
|
||||
></path>
|
||||
</svg>
|
||||
<view class="second-text-28 ml-1">{{ v.phone }}</view>
|
||||
</view>
|
||||
<view class="second-text-24">
|
||||
<view v-if="v.jobTime != ',,'" class="second-text-28">营业时间:</view>
|
||||
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
|
||||
</view>
|
||||
<view v-if="v.addressDes" class="second-text-28">
|
||||
<svg
|
||||
t="1743075857752"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="3808"
|
||||
width="12"
|
||||
height="11"
|
||||
>
|
||||
<path
|
||||
d="M512 1012.8c-253.6 0-511.2-54.4-511.2-158.4 0-92.8 198.4-131.2 283.2-143.2h3.2c12 0 22.4 8.8 24 20.8 0.8 6.4-0.8 12.8-4.8 17.6-4 4.8-9.6 8.8-16 9.6-176.8 25.6-242.4 72-242.4 96 0 44.8 180.8 110.4 463.2 110.4s463.2-65.6 463.2-110.4c0-24-66.4-70.4-244.8-96-6.4-0.8-12-4-16-9.6-4-4.8-5.6-11.2-4.8-17.6 1.6-12 12-20.8 24-20.8h3.2c85.6 12 285.6 50.4 285.6 143.2 0.8 103.2-256 158.4-509.6 158.4z m-16.8-169.6c-12-11.2-288.8-272.8-288.8-529.6 0-168 136.8-304.8 304.8-304.8S816 145.6 816 313.6c0 249.6-276.8 517.6-288.8 528.8l-16 16-16-15.2zM512 56.8c-141.6 0-256.8 115.2-256.8 256.8 0 200.8 196 416 256.8 477.6 61.6-63.2 257.6-282.4 257.6-477.6C768.8 172.8 653.6 56.8 512 56.8z m0 392.8c-80 0-144.8-64.8-144.8-144.8S432 160 512 160c80 0 144.8 64.8 144.8 144.8 0 80-64.8 144.8-144.8 144.8zM512 208c-53.6 0-96.8 43.2-96.8 96.8S458.4 401.6 512 401.6c53.6 0 96.8-43.2 96.8-96.8S564.8 208 512 208z"
|
||||
fill="#707070"
|
||||
p-id="3809"
|
||||
></path>
|
||||
</svg>
|
||||
<text class="ml-1">地址:</text>
|
||||
<text class="m-l-10rpx">{{ v.addressDes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</view>
|
||||
</template>
|
||||
@@ -1,47 +1,114 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
|
||||
<tm-sticky>
|
||||
<!-- start 轮播 start -->
|
||||
<z-swiper>
|
||||
<z-swiper-item v-for="(v, i) in state.detail.swiperPic?.split(',')" :key="i">
|
||||
<image class="w-100vw h-400rpx" :src="filePath(v)" mode="aspectFill" />
|
||||
</z-swiper-item>
|
||||
</z-swiper>
|
||||
<!-- end 轮播 end -->
|
||||
<swiper
|
||||
class="w-100vw h-30vh"
|
||||
circular
|
||||
:indicator-dots="true"
|
||||
indicator-active-color="#0779FD"
|
||||
indicator-color="#ffffff"
|
||||
:autoplay="true"
|
||||
>
|
||||
<swiper-item v-for="(v, i) in state.detail?.swiperPic?.split(',')" :key="i">
|
||||
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<tm-sticky-header>
|
||||
<view class="m-x-30rpx">
|
||||
<view class="h-15rpx" />
|
||||
<!-- start 简介 start -->
|
||||
<view flex-row card p-20rpx>
|
||||
<view class="flex-row card p-20rpx m-b-20rpx">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(state.detail.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-32">{{ state.detail.name }}</view>
|
||||
<tm-tag size="s">{{ state.detail.deptName }}</tm-tag>
|
||||
<view class="flex-row-center sub-text-34">
|
||||
{{ state.detail.name?.length > 7 ? state.detail.name.substring(0, 7) + "..." : state.detail.name }}
|
||||
</view>
|
||||
<tm-tag size="s">
|
||||
{{ state.detail.deptName?.length > 5 ? state.detail.deptName.substring(0, 5) + "..." : state.detail.deptName }}
|
||||
</tm-tag>
|
||||
</view>
|
||||
<view class="second-text-24">{{ state.detail.phone }}</view>
|
||||
<view class="second-text-24">
|
||||
<view class="second-text-28">营业时间:</view>
|
||||
<view>{{ state.detail.jobTime?.split(",")[0] ? "早:" + state.detail.jobTime?.split(",")[0] : "" }}</view>
|
||||
<view>{{ state.detail.jobTime?.split(",")[1] ? "中:" + state.detail.jobTime?.split(",")[1] : "" }}</view>
|
||||
<view>{{ state.detail.jobTime?.split(",")[2] ? "晚:" + state.detail.jobTime?.split(",")[2] : "" }}</view>
|
||||
</view>
|
||||
<view v-if="state.detail.addressDes" class="m-t-10rpx second-text-28">
|
||||
<text>地址</text>
|
||||
<text class="m-l-10rpx">{{ state.detail.addressDes }}</text>
|
||||
<view class="m-t-10rpx">
|
||||
<view v-if="state.detail.phone" class="flex items-center">
|
||||
<svg
|
||||
t="1743075703202"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="2684"
|
||||
width="12"
|
||||
height="12"
|
||||
>
|
||||
<path
|
||||
d="M575.7 647.1l69.4-69.2 13.3 2.3c1.7 0.3 4.9 0.9 9.4 1.7 7.4 1.3 15.7 2.9 24.6 4.5 25.5 4.8 50.9 9.8 74.8 14.9 17.3 3.7 33.1 7.3 47 10.7 27.6 6.8 47.3 12.9 59.1 18.6 43 20.8 60 65.5 53.4 122-9.7 81.3-97 174.3-204.4 175.4-121 1.2-291.4-87.7-411.9-214.7C165.3 560.4 81.8 406.9 98 278.3c8.5-67.1 40.2-115.9 87.8-147.2 32.4-21.3 69.4-32.5 97.9-34.6 38.2-2.8 69.6 9.6 92.5 38 9.7 12 19.7 36.1 32.2 73.3 3.6 10.9 7.4 22.8 11.3 35.4 7 23 14.1 47.6 20.9 72.2 2.4 8.6 4.5 16.6 6.4 23.7 1.1 4.3 2 7.4 2.4 9.1l3.7 14.2-80.4 81.8c44.5 89 122.6 169.8 203 202.9z m13.5 60l-15.3-5.1c-105.4-35.6-205.4-139.4-256.3-252.3l-7.3-16.2 85-86.4c-1.5-5.6-3.1-11.6-4.9-17.9-6.6-24.1-13.5-48.2-20.4-70.7-3.8-12.3-7.4-23.7-10.9-34.2-10.2-30.5-19.1-52-23.3-57.2-11.8-14.6-26.4-20.4-48.2-18.8-20.2 1.5-48.7 10.1-73.1 26.2-35.2 23.2-58.3 58.6-64.8 110.3-13.8 108.7 63.1 250.2 198.4 392.7C459.5 794.9 617 877 721.8 876c79.2-0.8 146.4-72.5 153.2-129.4 4.3-36.6-4.3-59.4-24.4-69.1-7.5-3.6-24.7-8.9-48.9-14.9-13.4-3.3-28.6-6.8-45.4-10.4-23.3-5-48.4-10-73.5-14.7-7.2-1.3-13.9-2.6-20.1-3.7l-73.5 73.3z"
|
||||
fill="#666666"
|
||||
p-id="2685"
|
||||
></path>
|
||||
</svg>
|
||||
<view class="second-text-28 ml-1">{{ state.detail.phone }}</view>
|
||||
<view
|
||||
class="second-text-20 bg-#f8f8f8 ml-1 p-0.3 flex items-center rounded-1 border border-solid border-b-coolGray"
|
||||
@tap="doPhone"
|
||||
>
|
||||
联系商家
|
||||
</view>
|
||||
</view>
|
||||
<view class="second-text-24">
|
||||
<view class="second-text-28">{{ state.detail.jobTime == ",," ? "" : "营业时间:" }}</view>
|
||||
<view>{{ state.detail.jobTime?.split(",")[0] ? "早:" + state.detail.jobTime?.split(",")[0] : "" }}</view>
|
||||
<view>{{ state.detail.jobTime?.split(",")[1] ? "中:" + state.detail.jobTime?.split(",")[1] : "" }}</view>
|
||||
<view>{{ state.detail.jobTime?.split(",")[2] ? "晚:" + state.detail.jobTime?.split(",")[2] : "" }}</view>
|
||||
</view>
|
||||
<view v-if="state.detail.addressDes" class="second-text-28">
|
||||
<svg
|
||||
t="1743075857752"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="3808"
|
||||
width="12"
|
||||
height="11"
|
||||
>
|
||||
<path
|
||||
d="M512 1012.8c-253.6 0-511.2-54.4-511.2-158.4 0-92.8 198.4-131.2 283.2-143.2h3.2c12 0 22.4 8.8 24 20.8 0.8 6.4-0.8 12.8-4.8 17.6-4 4.8-9.6 8.8-16 9.6-176.8 25.6-242.4 72-242.4 96 0 44.8 180.8 110.4 463.2 110.4s463.2-65.6 463.2-110.4c0-24-66.4-70.4-244.8-96-6.4-0.8-12-4-16-9.6-4-4.8-5.6-11.2-4.8-17.6 1.6-12 12-20.8 24-20.8h3.2c85.6 12 285.6 50.4 285.6 143.2 0.8 103.2-256 158.4-509.6 158.4z m-16.8-169.6c-12-11.2-288.8-272.8-288.8-529.6 0-168 136.8-304.8 304.8-304.8S816 145.6 816 313.6c0 249.6-276.8 517.6-288.8 528.8l-16 16-16-15.2zM512 56.8c-141.6 0-256.8 115.2-256.8 256.8 0 200.8 196 416 256.8 477.6 61.6-63.2 257.6-282.4 257.6-477.6C768.8 172.8 653.6 56.8 512 56.8z m0 392.8c-80 0-144.8-64.8-144.8-144.8S432 160 512 160c80 0 144.8 64.8 144.8 144.8 0 80-64.8 144.8-144.8 144.8zM512 208c-53.6 0-96.8 43.2-96.8 96.8S458.4 401.6 512 401.6c53.6 0 96.8-43.2 96.8-96.8S564.8 208 512 208z"
|
||||
fill="#707070"
|
||||
p-id="3809"
|
||||
></path>
|
||||
</svg>
|
||||
<text class="ml-1">地址:</text>
|
||||
<text class="m-l-10rpx">{{ state.detail.addressDes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- end 简介 end -->
|
||||
</view>
|
||||
</tm-sticky-header>
|
||||
|
||||
<view class="h-30rpx" />
|
||||
<tm-alert
|
||||
v-if="state.detail?.discountsPrice"
|
||||
color="#0779FD"
|
||||
icon="notification-line"
|
||||
closeIcon="close-line"
|
||||
:border="['2']"
|
||||
:borderColor="['#89c0ff']"
|
||||
>
|
||||
<marquee class="flex items-center">{{ state.detail.discountsPrice }}</marquee>
|
||||
<!-- <view class="w-full overflow-hidden flex">
|
||||
<view class="scroll-text">{{ state.detail.discountsPrice }}</view>
|
||||
</view> -->
|
||||
</tm-alert>
|
||||
|
||||
<!-- start 商品 start -->
|
||||
<view class="flex-row">
|
||||
<scroll-view scroll-y :style="{ height: getHeight() }" class="menu w-200rpx h-full p-l-12rpx p-b-20rpx bg-#f6f6f6">
|
||||
<scroll-view
|
||||
v-if="state.classifyList?.length > 0"
|
||||
scroll-y
|
||||
:style="{ height: getHeight() }"
|
||||
class="menu w-200rpx h-full p-l-12rpx p-b-20rpx bg-#f6f6f6"
|
||||
>
|
||||
<view
|
||||
class="menu_item flex-row-center"
|
||||
v-for="(v, i) in state.classifyList"
|
||||
@@ -55,7 +122,7 @@
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<scroll-view scroll-y :style="{ height: getHeight() }" class="flex-1 p-b-20rpx">
|
||||
<scroll-view v-if="state.shopList?.length > 0" scroll-y :style="{ height: getHeight() }" class="flex-1 p-b-20rpx">
|
||||
<view class="m-x-15rpx">
|
||||
<product-row
|
||||
v-for="goodsItem in state.goodsList"
|
||||
@@ -75,7 +142,7 @@
|
||||
<!-- end 商品 end -->
|
||||
|
||||
<template #main-bottom>
|
||||
<view class="car z-200 p-x-30rpx p-y-30rpx bg-white">
|
||||
<view v-if="false" class="car z-200 p-x-30rpx p-y-30rpx bg-white">
|
||||
<product-total :totPrice="state.totPrice" :totCount="state.totCount" @doContainer="doVisibleCar" @doPay="doPay" />
|
||||
</view>
|
||||
</template>
|
||||
@@ -99,15 +166,13 @@
|
||||
import { reactive, nextTick, ref } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { router } from "@@/index"
|
||||
import { foodApi, merchantApi, payApi, shopApi } from "@@/api"
|
||||
import zSwiper from "@zebra-ui/swiper/components/z-swiper/z-swiper.vue"
|
||||
import zSwiperItem from "@zebra-ui/swiper/components/z-swiper-item/z-swiper-item.vue"
|
||||
import { filePath } from "@@/utils/file"
|
||||
import ProductRow from "./components/product-row.vue"
|
||||
import ProductCar from "./components/product-car.vue"
|
||||
import ProductTotal from "./components/product-total.vue"
|
||||
import ProductSku from "./components/product-sku.vue"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
// 商品详情相关数据
|
||||
const state = reactive<any>({
|
||||
@@ -140,8 +205,8 @@ onShow(async () => {
|
||||
})
|
||||
try {
|
||||
await getDetail()
|
||||
await getShopCar()
|
||||
await getClassify()
|
||||
// await getShopCar()
|
||||
// await getClassify()
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: "加载失败",
|
||||
@@ -217,6 +282,20 @@ const doClassify = async (i: any) => {
|
||||
await getPorduct()
|
||||
}
|
||||
|
||||
// 联系商家
|
||||
const doPhone = () => {
|
||||
if (isEmpty(state.detail.phone)) {
|
||||
uni.showToast({ title: "该商户没有预留电话", icon: "none" })
|
||||
return
|
||||
}
|
||||
;(window as any).dd
|
||||
.callPhone({
|
||||
phoneNum: state.detail.phone,
|
||||
})
|
||||
.then((res) => {})
|
||||
.catch((err) => {})
|
||||
}
|
||||
|
||||
const getHeight = () => {
|
||||
const rpx = 480
|
||||
return `calc(100vh - ${uni.upx2px(rpx)}px)`
|
||||
@@ -414,4 +493,17 @@ const submitPay = async () => {
|
||||
.car {
|
||||
box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.scroll-text {
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
animation: scroll-left 10s linear infinite;
|
||||
}
|
||||
@keyframes scroll-left {
|
||||
0% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,71 +1,76 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { isEmpty } from "radash";
|
||||
import { shopApi } from "@@/api";
|
||||
import zSwiper from "@zebra-ui/swiper/components/z-swiper/z-swiper.vue";
|
||||
import zSwiperItem from "@zebra-ui/swiper/components/z-swiper-item/z-swiper-item.vue";
|
||||
import { filePath } from "@/sheep/utils/file";
|
||||
import { reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
import { shopApi } from "@@/api"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
|
||||
const state = reactive<any>({
|
||||
detailId: null,
|
||||
detail: null,
|
||||
});
|
||||
detailId: null,
|
||||
detail: null,
|
||||
})
|
||||
|
||||
onLoad((options: any) => {
|
||||
if (!isEmpty(options.id)) {
|
||||
state.detailId = options.id;
|
||||
}
|
||||
});
|
||||
if (!isEmpty(options.id)) {
|
||||
state.detailId = options.id
|
||||
}
|
||||
})
|
||||
onShow(() => {
|
||||
getDetail();
|
||||
});
|
||||
getDetail()
|
||||
})
|
||||
|
||||
const getDetail = async () => {
|
||||
const { data } = await shopApi.getSupermarketSpuDetail({ id: state.detailId });
|
||||
state.detail = data;
|
||||
};
|
||||
const { data } = await shopApi.getSupermarketSpuDetail({ id: state.detailId })
|
||||
state.detail = data
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="订单详情" tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
|
||||
<!-- <z-swiper> -->
|
||||
<!-- <z-swiper-item v-for="(v, i) in state.detail.sliderPicUrls" :key="i"> -->
|
||||
<image class="w-100vw" :src="filePath(state.detail.picUrl)" mode="widthFix" />
|
||||
<!-- </z-swiper-item> -->
|
||||
<!-- </z-swiper> -->
|
||||
<crud-layout title="订单详情" tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
|
||||
<swiper
|
||||
class="w-100vw h-30vh"
|
||||
circular
|
||||
:indicator-dots="true"
|
||||
indicator-active-color="#0779FD"
|
||||
indicator-color="#ffffff"
|
||||
:autoplay="true"
|
||||
>
|
||||
<swiper-item v-for="(v, i) in state.detail?.sliderPicUrls?.split(',')" :key="i">
|
||||
<image class="w-full h-full" :src="filePath(state.detail.picUrl)" mode="aspectFill" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<view class="p-x-15rpx">
|
||||
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<!-- <view class="flex-row items-center"> -->
|
||||
<!-- <view class="second-text-46 color-#f63a36!">¥{{ state.detail.price }}</view> -->
|
||||
<!-- <view class="m-l-20rpx second-text-28 line-through">¥{{ state.detail.marketPrice }}</view> -->
|
||||
<!-- </view> -->
|
||||
<view class="second-text-26">已售{{ state.detail.salesCount }}</view>
|
||||
</view>
|
||||
<view class="flex-col m-t-15rpx">
|
||||
<view class="sub-text-32">{{ state.detail.productName }}</view>
|
||||
<view class="m-t-15rpx second-text-26">{{ state.detail.introduction }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="h-15rpx" />
|
||||
<view class="flex-row items-center justify-between card p-y-20rpx p-x-30rpx">
|
||||
<view class="prefix_title">评价</view>
|
||||
</view>
|
||||
<view class="h-15rpx" />
|
||||
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
|
||||
<view class="prefix_title">详情</view>
|
||||
<view class="m-t-15rpx" v-html="state.detail.description"></view>
|
||||
</view>
|
||||
</view>
|
||||
</crud-layout>
|
||||
<view class="p-x-15rpx">
|
||||
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<!-- <view class="flex-row items-center"> -->
|
||||
<!-- <view class="second-text-46 color-#f63a36!">¥{{ state.detail.price }}</view> -->
|
||||
<!-- <view class="m-l-20rpx second-text-28 line-through">¥{{ state.detail.marketPrice }}</view> -->
|
||||
<!-- </view> -->
|
||||
<view class="second-text-26">已售{{ state.detail.salesCount }}</view>
|
||||
</view>
|
||||
<view class="flex-col m-t-15rpx">
|
||||
<view class="sub-text-32">{{ state.detail.productName }}</view>
|
||||
<view class="m-t-15rpx second-text-26">{{ state.detail.introduction }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="h-15rpx" />
|
||||
<view class="flex-row items-center justify-between card p-y-20rpx p-x-30rpx">
|
||||
<view class="prefix_title">评价</view>
|
||||
</view>
|
||||
<view class="h-15rpx" />
|
||||
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
|
||||
<view class="prefix_title">详情</view>
|
||||
<view class="m-t-15rpx" v-html="state.detail.description"></view>
|
||||
</view>
|
||||
</view>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep() {
|
||||
.layout_main > scroll-view {
|
||||
padding: 0 !important;
|
||||
}
|
||||
.layout_main > scroll-view {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,119 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { merchantApi } from "@@/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
pagesize: 10,
|
||||
type: "2",
|
||||
},
|
||||
})
|
||||
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
})
|
||||
onShow(() => {
|
||||
// pageRef.value && pageRef.value.reload(false)
|
||||
})
|
||||
|
||||
const toDetail = async (v: any) => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
if (v.supType && v.supType == "10") return router.jump("/pages/shop/brandDetail", { parentId: v.id })
|
||||
if (v.supType && v.supType == "20") return router.jump("/pages/shop/detail", { id: v.id })
|
||||
uni.showToast({ title: "合作商家类型未知", icon: "none" })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-34">{{ v.name.length > 7 ? v.name.substring(0, 6) + "..." : v.name }}</view>
|
||||
<tm-tag size="s">{{ v.deptName.length > 5 ? v.deptName.substring(0, 5) + "..." : v.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="m-t-10rpx">
|
||||
<view class="flex items-center justify-between">
|
||||
<view>
|
||||
<view v-if="v.phone" class="flex items-center">
|
||||
<svg
|
||||
t="1743075703202"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="2684"
|
||||
width="12"
|
||||
height="12"
|
||||
>
|
||||
<path
|
||||
d="M575.7 647.1l69.4-69.2 13.3 2.3c1.7 0.3 4.9 0.9 9.4 1.7 7.4 1.3 15.7 2.9 24.6 4.5 25.5 4.8 50.9 9.8 74.8 14.9 17.3 3.7 33.1 7.3 47 10.7 27.6 6.8 47.3 12.9 59.1 18.6 43 20.8 60 65.5 53.4 122-9.7 81.3-97 174.3-204.4 175.4-121 1.2-291.4-87.7-411.9-214.7C165.3 560.4 81.8 406.9 98 278.3c8.5-67.1 40.2-115.9 87.8-147.2 32.4-21.3 69.4-32.5 97.9-34.6 38.2-2.8 69.6 9.6 92.5 38 9.7 12 19.7 36.1 32.2 73.3 3.6 10.9 7.4 22.8 11.3 35.4 7 23 14.1 47.6 20.9 72.2 2.4 8.6 4.5 16.6 6.4 23.7 1.1 4.3 2 7.4 2.4 9.1l3.7 14.2-80.4 81.8c44.5 89 122.6 169.8 203 202.9z m13.5 60l-15.3-5.1c-105.4-35.6-205.4-139.4-256.3-252.3l-7.3-16.2 85-86.4c-1.5-5.6-3.1-11.6-4.9-17.9-6.6-24.1-13.5-48.2-20.4-70.7-3.8-12.3-7.4-23.7-10.9-34.2-10.2-30.5-19.1-52-23.3-57.2-11.8-14.6-26.4-20.4-48.2-18.8-20.2 1.5-48.7 10.1-73.1 26.2-35.2 23.2-58.3 58.6-64.8 110.3-13.8 108.7 63.1 250.2 198.4 392.7C459.5 794.9 617 877 721.8 876c79.2-0.8 146.4-72.5 153.2-129.4 4.3-36.6-4.3-59.4-24.4-69.1-7.5-3.6-24.7-8.9-48.9-14.9-13.4-3.3-28.6-6.8-45.4-10.4-23.3-5-48.4-10-73.5-14.7-7.2-1.3-13.9-2.6-20.1-3.7l-73.5 73.3z"
|
||||
fill="#666666"
|
||||
p-id="2685"
|
||||
></path>
|
||||
</svg>
|
||||
<view class="second-text-28 ml-1">{{ v.phone }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<tm-tag v-if="v.supType == '10' && Number(v.mchCount) > 0" size="xs" skin="thin">共{{ v.mchCount }}家</tm-tag>
|
||||
</view>
|
||||
<view class="second-text-24">
|
||||
<view v-if="v.jobTime != ',,'" class="second-text-28">营业时间:</view>
|
||||
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
|
||||
</view>
|
||||
<view v-if="v.addressDes" class="second-text-28">
|
||||
<svg
|
||||
t="1743075857752"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="3808"
|
||||
width="12"
|
||||
height="11"
|
||||
>
|
||||
<path
|
||||
d="M512 1012.8c-253.6 0-511.2-54.4-511.2-158.4 0-92.8 198.4-131.2 283.2-143.2h3.2c12 0 22.4 8.8 24 20.8 0.8 6.4-0.8 12.8-4.8 17.6-4 4.8-9.6 8.8-16 9.6-176.8 25.6-242.4 72-242.4 96 0 44.8 180.8 110.4 463.2 110.4s463.2-65.6 463.2-110.4c0-24-66.4-70.4-244.8-96-6.4-0.8-12-4-16-9.6-4-4.8-5.6-11.2-4.8-17.6 1.6-12 12-20.8 24-20.8h3.2c85.6 12 285.6 50.4 285.6 143.2 0.8 103.2-256 158.4-509.6 158.4z m-16.8-169.6c-12-11.2-288.8-272.8-288.8-529.6 0-168 136.8-304.8 304.8-304.8S816 145.6 816 313.6c0 249.6-276.8 517.6-288.8 528.8l-16 16-16-15.2zM512 56.8c-141.6 0-256.8 115.2-256.8 256.8 0 200.8 196 416 256.8 477.6 61.6-63.2 257.6-282.4 257.6-477.6C768.8 172.8 653.6 56.8 512 56.8z m0 392.8c-80 0-144.8-64.8-144.8-144.8S432 160 512 160c80 0 144.8 64.8 144.8 144.8 0 80-64.8 144.8-144.8 144.8zM512 208c-53.6 0-96.8 43.2-96.8 96.8S458.4 401.6 512 401.6c53.6 0 96.8-43.2 96.8-96.8S564.8 208 512 208z"
|
||||
fill="#707070"
|
||||
p-id="3809"
|
||||
></path>
|
||||
</svg>
|
||||
<text class="ml-1">地址:</text>
|
||||
<text class="m-l-10rpx">{{ v.addressDes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
@@ -1,79 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { merchantApi } from "@@/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
pagesize: 10,
|
||||
type: "2",
|
||||
},
|
||||
})
|
||||
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
})
|
||||
onShow(() => {
|
||||
pageRef.value && pageRef.value.reload(false)
|
||||
})
|
||||
|
||||
const toDetail = async (v: any) => {
|
||||
return
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
router.jump("/pages/shop/detail", { id: v.id })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-col card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<view class="flex-row-center">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
|
||||
<tm-tag size="s">{{ v.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="second-text-24">{{ v.phone }}</view>
|
||||
<view class="second-text-24">
|
||||
<view v-if="v.jobTime != ',,'" class="second-text-28">营业时间:</view>
|
||||
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
|
||||
</view>
|
||||
<view v-if="v.addressDes" class="m-t-10rpx second-text-28">
|
||||
<text>地址</text>
|
||||
<text class="m-l-10rpx">{{ v.addressDes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
@@ -3,7 +3,7 @@
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
:fixed="false"
|
||||
v-model="list"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
@@ -11,7 +11,7 @@
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="scroll"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
@@ -21,7 +21,7 @@
|
||||
<view class="flex items-center cursor-pointer">
|
||||
<tm-between-time
|
||||
start="2020-1-1"
|
||||
end="2040-1-1"
|
||||
end="2050-1-1"
|
||||
v-model="state.date"
|
||||
v-model:model-str="state.formatVal"
|
||||
@confirm="datePickerConfirm"
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
<view class="h-20rpx" />
|
||||
|
||||
<view class="bg-white rounded-16rpx p-2 mb-1 shadow-md" v-for="(v, i) in list" :key="i">
|
||||
<view class="bg-white rounded-16rpx p-3 mb-2 shadow-md" v-for="(v, i) in pageHook.list" :key="i">
|
||||
<view class="flex justify-between items-center text-sm text-gray-800 mb-1">
|
||||
<view class="flex items-center">
|
||||
<image class="w-50rpx h-50rpx rounded-8rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
@@ -58,33 +58,33 @@
|
||||
</view>
|
||||
<view>{{ v.day }}</view>
|
||||
</view>
|
||||
<view class="bg-gray-100 rounded-12rpx p-1">
|
||||
<view class="flex justify-between mb-1">
|
||||
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx">
|
||||
<view class="bg-gray-100 rounded-12rpx p-2">
|
||||
<view class="flex justify-between mb-2">
|
||||
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx">
|
||||
<text class="flex-1 text-sm text-center text-gray-600">流水金额</text>
|
||||
<text class="flex-1 text-sm text-center text-gray-800">¥ {{ hooks.useMoney(v.totalPayPrice) }}</text>
|
||||
</view>
|
||||
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx ml-1">
|
||||
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx ml-2">
|
||||
<text class="flex-1 text-sm text-center text-gray-600">流水次数</text>
|
||||
<text class="flex-1 text-sm text-center text-gray-800">{{ v.totalPayCount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex justify-between mb-1">
|
||||
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx">
|
||||
<view class="flex justify-between mb-2">
|
||||
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx">
|
||||
<text class="flex-1 text-sm text-center text-gray-600">盈利金额</text>
|
||||
<text class="flex-1 text-sm text-center text-green-500">¥ {{ hooks.useMoney(v.totalProfitPrice) }}</text>
|
||||
</view>
|
||||
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx ml-1">
|
||||
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx ml-2">
|
||||
<text class="flex-1 text-sm text-center text-gray-600">盈利次数</text>
|
||||
<text class="flex-1 text-sm text-center text-green-500">{{ v.totalProfitCount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex justify-between mb-0">
|
||||
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx">
|
||||
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx">
|
||||
<text class="flex-1 text-sm text-center text-gray-600">退款金额</text>
|
||||
<text class="flex-1 text-sm text-center text-red-500">¥ {{ hooks.useMoney(v.totalRefundPrice) }}</text>
|
||||
</view>
|
||||
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx ml-1">
|
||||
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx ml-2">
|
||||
<text class="flex-1 text-sm text-center text-gray-600">退款次数</text>
|
||||
<text class="flex-1 text-sm text-center text-red-500">{{ v.totalRefundCount || 0 }}</text>
|
||||
</view>
|
||||
@@ -111,7 +111,7 @@ const state = reactive<any>({
|
||||
date: "",
|
||||
})
|
||||
const formatVal = computed(() => (state.date.length === 2 ? state.formatVal : ""))
|
||||
const { list, startPage, scroll } = hooks.usePage(pageRef, flowStatisticsApi.page, null, "data")
|
||||
const pageHook = hooks.usePage(pageRef, flowStatisticsApi.page, null, "data")
|
||||
|
||||
onLoad(() => {
|
||||
const app = getApp()
|
||||
@@ -128,12 +128,12 @@ onShow(() => {
|
||||
const query = (page: number, pagesize: number) => {
|
||||
const isLogin = hooks.useStaticCheckLogin()
|
||||
if (!isLogin) return
|
||||
startPage(page, pagesize, false, state.pa)
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
// 时间范围选择器确认
|
||||
const datePickerConfirm = (date: any) => {
|
||||
state.pa.createTimeList = date.map((v: any) => hooks.useTime(v, "{y}-{m}-{d}"))
|
||||
state.pa.createTimeList = formatVal.value.split("~")
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
</script>
|
||||
@@ -3,7 +3,7 @@
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
:fixed="false"
|
||||
v-model="list"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
@@ -11,7 +11,7 @@
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="scroll"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
<view class="h-20rpx" />
|
||||
|
||||
<view class="flex-col justify-center card p-x-15rpx p-y-25rpx m-b-10rpx" v-for="(v, i) in list" :key="i">
|
||||
<view class="flex-col justify-center card p-3 m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i">
|
||||
<view class="flex-row items-center">
|
||||
<image class="w-100rpx h-100rpx rounded-8rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
@@ -38,11 +38,11 @@
|
||||
</view>
|
||||
<view class="flex justify-between items-center">
|
||||
<view class="flex flex-col">
|
||||
<view class="second-text-20">
|
||||
<view class="second-text-22">
|
||||
<text>{{ v.username }}</text>
|
||||
<text class="m-l-10rpx">{{ v.userMobile }}</text>
|
||||
</view>
|
||||
<view class="second-text-20">
|
||||
<view class="second-text-22">
|
||||
<text>下单时间</text>
|
||||
<text class="m-l-10rpx">
|
||||
{{ hooks.useTime(v.createTime, "{y}-{m}-{d} {h}:{i}:{s}") }}
|
||||
@@ -50,7 +50,7 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex flex-col items-end justify-center m-t-5rpx">
|
||||
<view class="second-text-22">{{ hooks.useEnum("hardwareRefundStatusEnum", v.refundStatus) }}</view>
|
||||
<view class="second-text-22 h-30rpx">{{ hooks.useEnum("hardwareRefundStatusEnum", v.refundStatus) }}</view>
|
||||
<view class="flex">
|
||||
<view v-if="v.carList?.length" class="m-t-4rpx m-r-10rpx second-text-26">共 {{ v.carList.length }} 件</view>
|
||||
<view class="main-text-30 color-red!">¥ {{ hooks.useMoney(v.totalPrice) }}</view>
|
||||
@@ -59,8 +59,8 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="v.orderStatus == 10 && v.refundStatus == 0" class="h-50rpx mt-1 flex justify-end items-center">
|
||||
<view class="botder_btn" @tap.stop="doIndividualRefund(v)">退款</view>
|
||||
<view v-if="v.orderStatus == '5' && v.orderType == '1'" class="h-50rpx mt-1 flex justify-end items-center">
|
||||
<view class="botder_btn" @tap.stop="doIndividualRefund(v)">申请退款</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
@@ -220,7 +220,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { hooks } from "@@/index"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
import { individualOrderApi, refundApi } from "@@/api"
|
||||
@@ -242,7 +242,8 @@ const state = reactive<any>({
|
||||
refundDetail: {},
|
||||
remark: "",
|
||||
})
|
||||
const { list, startPage, scroll } = hooks.usePage(pageRef, individualOrderApi.page, null, "data.records")
|
||||
|
||||
const pageHook = hooks.usePage(pageRef, individualOrderApi.page, null, "data.records")
|
||||
|
||||
onLoad(() => {
|
||||
const app = getApp()
|
||||
@@ -251,9 +252,9 @@ onLoad(() => {
|
||||
onShow(() => {
|
||||
const isLogin = hooks.useCheckLogin()
|
||||
if (!isLogin) return
|
||||
// if (pageRef.value) {
|
||||
// pageRef.value.reload(false)
|
||||
// }
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
})
|
||||
|
||||
// 切换选项卡
|
||||
@@ -265,7 +266,7 @@ const tabChange = (e: number) => {
|
||||
const query = (page: number, pagesize: number) => {
|
||||
// const isLogin = hooks.useStaticCheckLogin()
|
||||
// if (!isLogin) return
|
||||
startPage(page, pagesize, false, state.pa)
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
// 重置状态
|
||||
@@ -278,6 +279,8 @@ const resetState = () => {
|
||||
|
||||
// 点击退款
|
||||
const doIndividualRefund = async (v: any) => {
|
||||
return router.jump("/pages/refund/apply", { id: v.id })
|
||||
|
||||
if (!v.id) return uni.showToast({ title: "订单id不存在", icon: "none" })
|
||||
|
||||
resetState()
|
||||
|
||||
@@ -37,31 +37,39 @@
|
||||
退出登录
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="state.appInfo == 'sh'" class="flex-col-center m-t-40rpx m-x-30rpx">
|
||||
<view class="w-full text-center sub-text-28 p-y-20rpx rounded-40rpx border-solid border border-#0094ff" @tap="doChangeRole">
|
||||
切换角色
|
||||
</view>
|
||||
</view>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive } from "vue"
|
||||
import { reactive, ref } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
import { filePath } from "@@/utils/file"
|
||||
import { getAppInfo } from "@@/utils/getAppInfo"
|
||||
import { hooks, router, constant } from "@@/index"
|
||||
import { userApi } from "@@/api"
|
||||
import isDevEnv from "@/sheep/utils/isDevEnv"
|
||||
import { usePayStore } from "@/sheep/stores/pay"
|
||||
// import dd from "gdt-jsapi"
|
||||
|
||||
interface MenuItem {
|
||||
text: string
|
||||
icon: string
|
||||
router: string
|
||||
}
|
||||
|
||||
const state = reactive<{ wallet: any; userInfo: any; menuList: MenuItem[] }>({
|
||||
const state = reactive<{
|
||||
wallet: any[]
|
||||
userInfo: any
|
||||
menuList: {
|
||||
text: string
|
||||
icon: string
|
||||
router: string
|
||||
}[]
|
||||
appInfo: string
|
||||
}>({
|
||||
wallet: [],
|
||||
userInfo: {},
|
||||
menuList: [
|
||||
{ text: "扫一扫", icon: "/static/icon/scan.png", router: "" },
|
||||
{ text: "钱包管理", icon: "/static/icon/service_3.png", router: "/pages/wallet/list" },
|
||||
// { text: "包厢预定", icon: "/static/icon/service_4.png", router: "/pages/boxes/apply-list" },
|
||||
// { text: "外来人员就餐", icon: "/static/icon/service_1.png", router: "/pages/apply/foreign-list" },
|
||||
@@ -69,213 +77,316 @@ const state = reactive<{ wallet: any; userInfo: any; menuList: MenuItem[] }>({
|
||||
{ text: "人脸管理", icon: "/static/icon/service_5.png", router: "/pages/human-face/list" },
|
||||
// { text: "意见反馈", icon: "/static/icon/service_5.png", router: "/pages/integrated/feedback/index" }
|
||||
],
|
||||
appInfo: "",
|
||||
})
|
||||
|
||||
const onTabLogin = () => (isDevEnv() ? router.jump("/pages/test/login") : checkAppInfo())
|
||||
// 常量
|
||||
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" })
|
||||
}
|
||||
},
|
||||
|
||||
// 登录相关方法
|
||||
const loginMethods = {
|
||||
// 诗画环境登录
|
||||
async shihuaLogin() {
|
||||
// const appInfo = await (window as any).CP2.getAppInfo()
|
||||
// if (appInfo.code !== 0) return false
|
||||
shihuaLogin: async () => {
|
||||
const appInfo = await (window as any).CP2.getAppInfo()
|
||||
if (appInfo.code == 0) return false
|
||||
|
||||
// const userInfo = await (window as any).CP2.getUserInfo()
|
||||
// const { accountId, sessionId } = userInfo.data
|
||||
// return doLogin(1, null, accountId, sessionId)
|
||||
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() {
|
||||
zhengdingLogin: () => {
|
||||
const params = new URL(window.location.href).searchParams
|
||||
const token = params.get("uabaseToken")
|
||||
if (token) {
|
||||
return doLogin(2, token, null, null)
|
||||
return login.doLogin(2, token, "", "")
|
||||
}
|
||||
return false
|
||||
},
|
||||
}
|
||||
|
||||
// 检查应用环境并登录
|
||||
const checkAppInfo = async () => {
|
||||
try {
|
||||
// 先尝试诗画登录
|
||||
const shihuaResult = await loginMethods.shihuaLogin()
|
||||
if (shihuaResult) return
|
||||
// 尝试浙政钉登录
|
||||
const zhengdingResult = loginMethods.zhengdingLogin()
|
||||
if (zhengdingResult) return
|
||||
// 执行登录操作 - 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)
|
||||
|
||||
uni.showToast({ title: "当前登录环境未知", icon: "none" })
|
||||
} catch (error) {
|
||||
console.error("登录失败:", error)
|
||||
uni.showToast({ title: "登录失败", icon: "none" })
|
||||
}
|
||||
}
|
||||
switch (loginType) {
|
||||
case 1: // 诗画登录
|
||||
uni.showLoading({ title: "登录中...", mask: true })
|
||||
const response = await userApi.authsh({ accountId, sessionId })
|
||||
|
||||
// loginType 1:诗画登录 2:浙政钉登录
|
||||
const doLogin = async (loginType: number, token: string, accountId: string | null, sessionId: string | null) => {
|
||||
const tokenKey = constant.storageConstant.TOKEN
|
||||
const userInfoKey = constant.storageConstant.USERINFO
|
||||
const tokenStorage = uni.getStorageSync(tokenKey)
|
||||
const userStorage = uni.getStorageSync(userInfoKey)
|
||||
switch (loginType) {
|
||||
case 1:
|
||||
// 诗画
|
||||
// const params = {
|
||||
// accountId: accountId,
|
||||
// sessionId: sessionId,
|
||||
// }
|
||||
// const response = await userApi.authsh(params)
|
||||
// authData = response.data
|
||||
break
|
||||
case 2:
|
||||
if (isEmpty(tokenStorage) || isEmpty(userStorage)) {
|
||||
try {
|
||||
uni.showLoading({ title: "登录中...", mask: true })
|
||||
const res = await userApi.auth(token)
|
||||
if (res.code == 0) {
|
||||
uni.setStorageSync(tokenKey, res.data)
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "登录成功", icon: "none" })
|
||||
const { data: userData } = await userApi.userInfo()
|
||||
uni.setStorageSync(userInfoKey, userData)
|
||||
getStorageUserInfo()
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "获取浙政钉用户信息失败", icon: "none" })
|
||||
}
|
||||
} catch (error) {
|
||||
if (response.code == 0) {
|
||||
storage.saveToken({ accessToken: response.data.accessToken })
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "错误", icon: "none" })
|
||||
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
|
||||
default:
|
||||
uni.showToast({ title: "当前登录环境未知", icon: "none" })
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
const doLogout = async () => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (!isLogin) return
|
||||
uni.showLoading({
|
||||
title: "退出登录中...",
|
||||
mask: true,
|
||||
})
|
||||
const tokenKey = constant.storageConstant.TOKEN
|
||||
const userInfoKey = constant.storageConstant.USERINFO
|
||||
uni.removeStorageSync(tokenKey)
|
||||
uni.removeStorageSync(userInfoKey)
|
||||
state.userInfo = {}
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "退出登录成功", icon: "none" })
|
||||
}
|
||||
case 2: // 浙政钉登录
|
||||
if (isEmpty(tokenStorage) || isEmpty(userStorage)) {
|
||||
try {
|
||||
uni.showLoading({ title: "登录中...", mask: true })
|
||||
const res = await userApi.auth(token)
|
||||
|
||||
// 扫一扫
|
||||
const doScanCode = async () => {
|
||||
usePayStore().setPayData({})
|
||||
try {
|
||||
let decodedString: string | undefined = ""
|
||||
if (isDevEnv()) {
|
||||
decodedString = decodeBase64("eyJpZCI6IjE4ODk0ODM5Mzg0ODQ1MzEyMDEiLCJuYW1lIjoi5rWL6K+V6LaF5biCIn0=")
|
||||
uni.showToast({ title: "开发环境不是浙政钉环境,扫码仅供测试", icon: "none" })
|
||||
} else {
|
||||
const res: any = await (window as any).dd.scan({ type: "all" })
|
||||
decodedString = decodeBase64(res.text)
|
||||
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" })
|
||||
}
|
||||
},
|
||||
|
||||
if (decodedString) {
|
||||
// 退出登录
|
||||
logout: async () => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (!isLogin) return
|
||||
|
||||
uni.showLoading({ title: "退出登录中...", mask: true })
|
||||
storage.clearUserStorage()
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "退出登录成功", icon: "none" })
|
||||
},
|
||||
|
||||
// 切换角色
|
||||
changeRole: () => {
|
||||
router.jump("/pages/user/userRole")
|
||||
},
|
||||
}
|
||||
|
||||
const scanCode = {
|
||||
// 扫一扫
|
||||
scan: async () => {
|
||||
usePayStore().setPayData({})
|
||||
try {
|
||||
const decodedString = await scanCode.getScanResult()
|
||||
|
||||
if (decodedString) {
|
||||
scanCode.processScanResult(decodedString)
|
||||
}
|
||||
// else {
|
||||
// uni.showToast({ title: "无效的二维码", icon: "none" })
|
||||
// }
|
||||
} catch (error: any) {
|
||||
// if (error) {
|
||||
// uni.showToast({ title: error, icon: "none" })
|
||||
// }
|
||||
}
|
||||
},
|
||||
|
||||
// 获取扫码结果
|
||||
getScanResult: async (): Promise<string | undefined> => {
|
||||
if (isDevEnv()) {
|
||||
// 开发环境模拟扫码
|
||||
// const testQrCode = "eyJpZCI6IjE4OTYxNTcyMDc2NDQwNTM1MDYiLCJuYW1lIjoi5rWL6K+V5ZWG5oi3In0=" // 线上-测试超市-收款码
|
||||
// const testQrCode = "eyJpZCI6IjE5MDU4MTY3NTEwNDM0NTI5MzAiLCJuYW1lIjoi5paw5Y6/5bqc6LaF5biCIn0=" // 测试环境-邓本地-新县府超市-收款码
|
||||
const testQrCode = "eyJpZCI6IjE5MDc2ODQwNTY4NDA4NDMyNjYiLCJuYW1lIjoi5pm66IO95p+c6Ieq6JCl5ZWG5oi3MSJ9" // 测试环境-邓本地-智能柜自营商户1-收款码
|
||||
uni.showToast({ title: "开发环境不是浙政钉环境,扫码仅供测试,收款商家为测试商户超市", icon: "none" })
|
||||
return scanCode.decodeBase64(testQrCode)
|
||||
} else if (state.appInfo == "dd") {
|
||||
// 浙政钉扫码
|
||||
const res: any = await (window as any).dd.scan({ type: "all" })
|
||||
return scanCode.decodeBase64(res.text)
|
||||
} else if (state.appInfo == "sh") {
|
||||
// 诗画扫码
|
||||
const res = await (window as any).CP2.showScanQr({ needResult: 1 })
|
||||
if (res.code == 1) return scanCode.decodeBase64(res.data.qrCode)
|
||||
} else {
|
||||
uni.showToast({ title: "当前环境未知", icon: "none" })
|
||||
}
|
||||
},
|
||||
|
||||
// 处理扫码结果
|
||||
processScanResult: (decodedString: string) => {
|
||||
try {
|
||||
const decodedJson = JSON.parse(decodedString)
|
||||
if (decodedJson?.id && decodedJson?.name) {
|
||||
usePayStore().setPayData(decodedJson)
|
||||
router.jump("/pages/pay/scanPay")
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "无效的二维码",
|
||||
icon: "none",
|
||||
})
|
||||
uni.showToast({ title: "无效的二维码", icon: "none" })
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "无效的二维码",
|
||||
icon: "none",
|
||||
})
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "无效的二维码内容", icon: "none" })
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (error) {
|
||||
uni.showToast({
|
||||
title: error,
|
||||
icon: "none",
|
||||
})
|
||||
},
|
||||
|
||||
// 解码base64
|
||||
decodeBase64: (base64String: string): string | undefined => {
|
||||
try {
|
||||
const decodedBinaryString = atob(base64String)
|
||||
const uint8Array = new Uint8Array(decodedBinaryString.length)
|
||||
for (let i = 0; i < decodedBinaryString.length; i++) {
|
||||
uint8Array[i] = decodedBinaryString.charCodeAt(i)
|
||||
}
|
||||
const decoder = new TextDecoder("utf-8")
|
||||
const decodedString = decoder.decode(uint8Array)
|
||||
console.log("解码结果", decodedString)
|
||||
return decodedString
|
||||
} catch (error) {
|
||||
console.error("Base64 解码失败:", error)
|
||||
uni.showToast({ title: "无效的二维码", icon: "none" })
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const onTabMenu = async (v: MenuItem, i: number) => {
|
||||
if (i == state.menuList.length - 1) {
|
||||
router.jump(v.router)
|
||||
const onTabLogin = () => (isDevEnv() ? router.jump("/pages/test/login") : login.checkAppInfo())
|
||||
|
||||
const onTabMenu = async (item: any, index: number) => {
|
||||
if (index == state.menuList.length - 1) {
|
||||
router.jump(item.router)
|
||||
return
|
||||
}
|
||||
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
if (v.text === "扫一扫") {
|
||||
await doScanCode()
|
||||
if (item.text === "扫一扫") {
|
||||
await scanCode.scan()
|
||||
} else {
|
||||
router.jump(v.router)
|
||||
router.jump(item.router)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 解码base64
|
||||
const decodeBase64 = (base64String: string) => {
|
||||
try {
|
||||
const decodedBinaryString = atob(base64String)
|
||||
const uint8Array = new Uint8Array(decodedBinaryString.length)
|
||||
for (let i = 0; i < decodedBinaryString.length; i++) {
|
||||
uint8Array[i] = decodedBinaryString.charCodeAt(i)
|
||||
}
|
||||
const decoder = new TextDecoder("utf-8")
|
||||
const decodedString = decoder.decode(uint8Array)
|
||||
console.log("解码结果", decodedString)
|
||||
return decodedString
|
||||
} catch (error) {
|
||||
console.error("Base64 解码失败:", error)
|
||||
uni.showToast({
|
||||
title: "解码失败,无效的二维码",
|
||||
icon: "none",
|
||||
// 退出登录
|
||||
const doLogout = async () => {
|
||||
await login.logout()
|
||||
}
|
||||
|
||||
// 切换角色
|
||||
const doChangeRole = () => {
|
||||
login.changeRole()
|
||||
}
|
||||
|
||||
// 初始化配置菜单
|
||||
const initMenuConfig = () => {
|
||||
if (isDevEnv()) {
|
||||
state.menuList.push({
|
||||
text: "测试-登录",
|
||||
icon: "/static/icon/login.png",
|
||||
router: "/pages/test/login",
|
||||
})
|
||||
state.menuList.push({
|
||||
text: "测试-角色选择",
|
||||
icon: "/static/icon/login.png",
|
||||
router: "/pages/user/userRole",
|
||||
})
|
||||
}
|
||||
|
||||
// 根据启动参数添加扫一扫菜单项
|
||||
const launchParam = new URL(window.location.href).searchParams.get("launchParam")
|
||||
if (launchParam === "selfMerchant") {
|
||||
state.menuList.unshift({
|
||||
text: "扫一扫",
|
||||
icon: "/static/icon/scan.png",
|
||||
router: "",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const getStorageUserInfo = () => {
|
||||
const tokenKey = constant.storageConstant.TOKEN
|
||||
const userInfoKey = constant.storageConstant.USERINFO
|
||||
const tokenStorage = uni.getStorageSync(tokenKey)
|
||||
const userStorage = uni.getStorageSync(userInfoKey)
|
||||
if (!isEmpty(userStorage) && !isEmpty(tokenStorage)) {
|
||||
state.userInfo = userStorage
|
||||
} else {
|
||||
state.userInfo = {}
|
||||
}
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
onLoad(async () => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
|
||||
isDevEnv()
|
||||
? state.menuList.push({
|
||||
text: "测试登录",
|
||||
icon: "/static/icon/login.png",
|
||||
router: "/pages/test/login",
|
||||
})
|
||||
: ""
|
||||
// checkAppInfo()
|
||||
// 初始化配置菜单
|
||||
initMenuConfig()
|
||||
|
||||
// 获取应用信息
|
||||
state.appInfo = await getAppInfo()
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
getStorageUserInfo()
|
||||
// 获取存储中的用户信息
|
||||
storage.getUserInfo()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from "vue"
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
@@ -31,9 +31,9 @@ onLoad(() => {
|
||||
onShow(async () => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (!isLogin) return
|
||||
// if (pageRef.value) {
|
||||
// pageRef.value.reload(false)
|
||||
// }
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
})
|
||||
const doTab = (e: any) => {
|
||||
const target = data.tabs[e]
|
||||
@@ -42,7 +42,16 @@ const doTab = (e: any) => {
|
||||
}
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, orderApi.page, null, "data.records")
|
||||
const pageHook = hooks.usePage(
|
||||
pageRef,
|
||||
new URL(window.location.href).searchParams.get("launchParam") == "canteen"
|
||||
? orderApi.caneenPage
|
||||
: new URL(window.location.href).searchParams.get("launchParam") == "selfMerchant"
|
||||
? orderApi.supPage
|
||||
: null,
|
||||
null,
|
||||
"data.records",
|
||||
)
|
||||
const query = (page: number, pagesize: number) => {
|
||||
const isLogin = hooks.useStaticCheckLogin()
|
||||
console.log(isLogin, "isLogin")
|
||||
@@ -69,7 +78,7 @@ const doRefund = (v: any) => {
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="5"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@@ -85,12 +94,7 @@ const doRefund = (v: any) => {
|
||||
</view>
|
||||
</template>
|
||||
<view class="h-20rpx" />
|
||||
<view
|
||||
class="flex-col justify-center card p-x-15rpx p-y-25rpx m-b-20rpx"
|
||||
v-for="(v, i) in pageHook.list"
|
||||
:key="i"
|
||||
@tap="doToDetail(v)"
|
||||
>
|
||||
<view class="flex-col justify-center card p-3 m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="doToDetail(v)">
|
||||
<view class="flex-row items-center">
|
||||
<image class="w-80rpx h-80rpx rounded-8rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { merchantApi } from "@@/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
pagesize: 10,
|
||||
type: "3",
|
||||
},
|
||||
})
|
||||
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
})
|
||||
onShow(() => {
|
||||
// pageRef.value && pageRef.value.reload(false)
|
||||
})
|
||||
|
||||
const toDetail = async (v: any) => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
router.jump("/pages/shop/detail", { id: v.id })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
|
||||
<tm-tag size="s">{{ v.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="m-t-10rpx">
|
||||
<view v-if="v.phone" class="flex items-center">
|
||||
<svg
|
||||
t="1743075703202"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="2684"
|
||||
width="12"
|
||||
height="12"
|
||||
>
|
||||
<path
|
||||
d="M575.7 647.1l69.4-69.2 13.3 2.3c1.7 0.3 4.9 0.9 9.4 1.7 7.4 1.3 15.7 2.9 24.6 4.5 25.5 4.8 50.9 9.8 74.8 14.9 17.3 3.7 33.1 7.3 47 10.7 27.6 6.8 47.3 12.9 59.1 18.6 43 20.8 60 65.5 53.4 122-9.7 81.3-97 174.3-204.4 175.4-121 1.2-291.4-87.7-411.9-214.7C165.3 560.4 81.8 406.9 98 278.3c8.5-67.1 40.2-115.9 87.8-147.2 32.4-21.3 69.4-32.5 97.9-34.6 38.2-2.8 69.6 9.6 92.5 38 9.7 12 19.7 36.1 32.2 73.3 3.6 10.9 7.4 22.8 11.3 35.4 7 23 14.1 47.6 20.9 72.2 2.4 8.6 4.5 16.6 6.4 23.7 1.1 4.3 2 7.4 2.4 9.1l3.7 14.2-80.4 81.8c44.5 89 122.6 169.8 203 202.9z m13.5 60l-15.3-5.1c-105.4-35.6-205.4-139.4-256.3-252.3l-7.3-16.2 85-86.4c-1.5-5.6-3.1-11.6-4.9-17.9-6.6-24.1-13.5-48.2-20.4-70.7-3.8-12.3-7.4-23.7-10.9-34.2-10.2-30.5-19.1-52-23.3-57.2-11.8-14.6-26.4-20.4-48.2-18.8-20.2 1.5-48.7 10.1-73.1 26.2-35.2 23.2-58.3 58.6-64.8 110.3-13.8 108.7 63.1 250.2 198.4 392.7C459.5 794.9 617 877 721.8 876c79.2-0.8 146.4-72.5 153.2-129.4 4.3-36.6-4.3-59.4-24.4-69.1-7.5-3.6-24.7-8.9-48.9-14.9-13.4-3.3-28.6-6.8-45.4-10.4-23.3-5-48.4-10-73.5-14.7-7.2-1.3-13.9-2.6-20.1-3.7l-73.5 73.3z"
|
||||
fill="#666666"
|
||||
p-id="2685"
|
||||
></path>
|
||||
</svg>
|
||||
<view class="second-text-28 ml-1">{{ v.phone }}</view>
|
||||
</view>
|
||||
<view class="second-text-24">
|
||||
<view class="second-text-28">{{ v.jobTime == ",," ? "" : "营业时间:" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
|
||||
</view>
|
||||
<view v-if="v.addressDes" class="second-text-28">
|
||||
<svg
|
||||
t="1743075857752"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="3808"
|
||||
width="12"
|
||||
height="11"
|
||||
>
|
||||
<path
|
||||
d="M512 1012.8c-253.6 0-511.2-54.4-511.2-158.4 0-92.8 198.4-131.2 283.2-143.2h3.2c12 0 22.4 8.8 24 20.8 0.8 6.4-0.8 12.8-4.8 17.6-4 4.8-9.6 8.8-16 9.6-176.8 25.6-242.4 72-242.4 96 0 44.8 180.8 110.4 463.2 110.4s463.2-65.6 463.2-110.4c0-24-66.4-70.4-244.8-96-6.4-0.8-12-4-16-9.6-4-4.8-5.6-11.2-4.8-17.6 1.6-12 12-20.8 24-20.8h3.2c85.6 12 285.6 50.4 285.6 143.2 0.8 103.2-256 158.4-509.6 158.4z m-16.8-169.6c-12-11.2-288.8-272.8-288.8-529.6 0-168 136.8-304.8 304.8-304.8S816 145.6 816 313.6c0 249.6-276.8 517.6-288.8 528.8l-16 16-16-15.2zM512 56.8c-141.6 0-256.8 115.2-256.8 256.8 0 200.8 196 416 256.8 477.6 61.6-63.2 257.6-282.4 257.6-477.6C768.8 172.8 653.6 56.8 512 56.8z m0 392.8c-80 0-144.8-64.8-144.8-144.8S432 160 512 160c80 0 144.8 64.8 144.8 144.8 0 80-64.8 144.8-144.8 144.8zM512 208c-53.6 0-96.8 43.2-96.8 96.8S458.4 401.6 512 401.6c53.6 0 96.8-43.2 96.8-96.8S564.8 208 512 208z"
|
||||
fill="#707070"
|
||||
p-id="3809"
|
||||
></path>
|
||||
</svg>
|
||||
<text class="ml-1">地址:</text>
|
||||
<text class="m-l-10rpx">{{ v.addressDes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
@@ -1,79 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { merchantApi } from "@@/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
pagesize: 10,
|
||||
type: "3",
|
||||
},
|
||||
})
|
||||
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
})
|
||||
onShow(() => {
|
||||
pageRef.value && pageRef.value.reload(false)
|
||||
})
|
||||
|
||||
const toDetail = async (v: any) => {
|
||||
return
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
router.jump("/pages/shop/detail", { id: v.id })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-col card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<view class="flex-row-center">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
|
||||
<tm-tag size="s">{{ v.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="second-text-24">{{ v.phone }}</view>
|
||||
<view class="second-text-24">
|
||||
<view v-if="v.jobTime != ',,'" class="second-text-28">营业时间:</view>
|
||||
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
|
||||
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
|
||||
</view>
|
||||
<view v-if="v.addressDes" class="m-t-10rpx second-text-28">
|
||||
<text>地址</text>
|
||||
<text class="m-l-10rpx">{{ v.addressDes }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
@@ -1,11 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { hooks, constant, router } from "@@/index"
|
||||
import { onShow } from "@dcloudio/uni-app"
|
||||
import { constant, router } from "@@/index"
|
||||
import { userApi } from "@@/api"
|
||||
|
||||
const data = {}
|
||||
const state = reactive<any>({
|
||||
userInfo: null,
|
||||
})
|
||||
@@ -18,8 +16,6 @@ const applyFormRules = reactive<any>({
|
||||
password: [{ required: true, message: "请输入密码" }],
|
||||
})
|
||||
|
||||
onLoad(() => {})
|
||||
|
||||
onShow(() => {
|
||||
const userInfoKey = constant.storageConstant.USERINFO
|
||||
state.userInfo = uni.getStorageSync(userInfoKey)
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<view class="flex-col min-h-screen bg-gray-100">
|
||||
<view class="text-center py-12">
|
||||
<view class="main-text-40 mb-2">请选择您的身份</view>
|
||||
</view>
|
||||
|
||||
<view class="px-6 my-20">
|
||||
<view
|
||||
class="card mb-6 overflow-hidden relative border-8 border-solid border-white duration-200"
|
||||
:class="{ 'border-8 border-solid border-blue!': userRole === 'user' }"
|
||||
@click="selectRole('user')"
|
||||
>
|
||||
<view class="flex-row items-center p-6">
|
||||
<view class="w-64 h-64 rounded-full flex-col-center mr-8">
|
||||
<image src="@/static/page/userRole.svg" />
|
||||
</view>
|
||||
<view class="main-text-32 mb-1">我是用户</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="card overflow-hidden relative border-8 border-solid border-white duration-200"
|
||||
:class="{ 'border-8 border-solid border-blue!': userRole === 'merchant' }"
|
||||
@click="selectRole('merchant')"
|
||||
>
|
||||
<view class="flex-row items-center p-6">
|
||||
<view class="w-64 h-64 rounded-full flex-col-center mr-8">
|
||||
<image src="@/static/page/merchantRole.svg" />
|
||||
</view>
|
||||
<view class="main-text-32 mb-1">我是商户</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="flex-row-center px-10 mt-auto pb-10 font-bold">
|
||||
<tm-button block @click="confirmRole">确 定</tm-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import user from "@/sheep/api/user"
|
||||
import { ref } from "vue"
|
||||
|
||||
const userRole = ref("user")
|
||||
|
||||
const selectRole = (role: "user" | "merchant") => (userRole.value = role)
|
||||
|
||||
// 确认选择
|
||||
const confirmRole = async () => {
|
||||
if (userRole.value === "user") {
|
||||
uni.setStorageSync("userRole", userRole.value)
|
||||
uni.reLaunch({ url: "/pages/tabbar/coopMerchant" })
|
||||
return
|
||||
}
|
||||
if (userRole.value === "merchant") {
|
||||
uni.showLoading({ title: "正在验证身份", mask: true })
|
||||
const res = await user.isMerchant().finally(() => uni.hideLoading())
|
||||
if (res.code == 0) {
|
||||
if (res.data) {
|
||||
uni.setStorageSync("userRole", userRole.value)
|
||||
uni.reLaunch({ url: "/pages/tabbar/individualOrder" })
|
||||
return
|
||||
} else {
|
||||
uni.showToast({ title: "您不是商户", icon: "none" })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -49,7 +49,7 @@ const doTab = (e: any) => {
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="5"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@@ -63,11 +63,7 @@ const doTab = (e: any) => {
|
||||
<z-tabs :list="data.tabs" @change="doTab" />
|
||||
</view>
|
||||
<view class="h-20rpx" />
|
||||
<view
|
||||
class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx"
|
||||
v-for="(v, i) in pageHook.list"
|
||||
:key="i"
|
||||
>
|
||||
<view class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i">
|
||||
<view class="flex">
|
||||
<view class="w-200rpx flex justify-left p-r-25rpx">
|
||||
<tm-tag v-if="v.title == '更新余额'" size="m">{{ v.title }}</tm-tag>
|
||||
@@ -75,6 +71,8 @@ const doTab = (e: any) => {
|
||||
<tm-tag v-if="v.title == '充值'" size="m">{{ v.title }}</tm-tag>
|
||||
<tm-tag v-if="v.title == '支付'" color="error" size="m">{{ v.title }}</tm-tag>
|
||||
<tm-tag v-if="v.title == '退款'" color="info" size="m">{{ v.title }}</tm-tag>
|
||||
<tm-tag v-if="v.title == '转账'" color="success" size="m">{{ v.title }}</tm-tag>
|
||||
<tm-tag v-if="v.title == '转账退款'" color="info" size="m">{{ v.title }}</tm-tag>
|
||||
</view>
|
||||
<view class="flex-row-center">
|
||||
<text class="sub-text-30">{{ hooks.useMoney(v.price) }}元</text>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
import uqrcode from "@@/utils/uqrcode"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { merchantApi, walletApi } from "@@/api"
|
||||
import { walletApi } from "@@/api"
|
||||
|
||||
import { filePath } from "@@/utils/file"
|
||||
import { useTransferMoney } from "@/sheep/stores/transferMoney"
|
||||
|
||||
const state = reactive<any>({
|
||||
showBindDialog: false,
|
||||
@@ -30,7 +30,13 @@ const freezeForm = reactive<any>({
|
||||
})
|
||||
|
||||
onLoad(() => {})
|
||||
onShow(() => {})
|
||||
onShow(async () => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (!isLogin) return
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, walletApi.all, null, "data.records")
|
||||
@@ -119,6 +125,16 @@ const doFreeze = async () => {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 转账
|
||||
const doTransferMoney = (v: any) => {
|
||||
if (v.walletTypeId) {
|
||||
useTransferMoney().setSourceWalletType(v)
|
||||
router.jump("/pages/pay/transferMoney")
|
||||
return
|
||||
}
|
||||
uni.showToast({ title: "钱包类型id不存在", icon: "none" })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -173,10 +189,15 @@ const doFreeze = async () => {
|
||||
</view>
|
||||
<view class="flex-row items-center justify-end space-x-20rpx m-t-10rpx">
|
||||
<!-- <view v-if="v.walletTypeUniqueCode == 1 && !v.cardNumber" class="botder_btn" @tap.stop="openBindDialog(v)">绑定</view> -->
|
||||
<view v-if="v.isRule == '1'" class="botder_btn" @tap.stop="doTransferMoney(v)">转账</view>
|
||||
<view v-if="v.walletTypeUniqueCode == 1 && v.cardNumber && v.isFreeze != 1" class="botder_btn" @tap.stop="openFreezeDialog(v)">
|
||||
申请冻结
|
||||
</view>
|
||||
<view v-if="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>
|
||||
|
||||
@@ -1,22 +1,31 @@
|
||||
import request from "@/sheep/utils/request";
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
page: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/mch-manage/app/page-join",
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
detail: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/mch-manage/app/detail",
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
};
|
||||
page: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/mch-manage/app/page-join",
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
childrenPage: (params: any) =>
|
||||
request({
|
||||
url: "/wallet/mch-manage/app/children-page-join",
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
detail: (params: any): Promise<any> =>
|
||||
request({
|
||||
url: "/wallet/mch-manage/app/detail",
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
}
|
||||
@@ -1,31 +1,40 @@
|
||||
import request from "@/sheep/utils/request";
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
page: (params: any) =>
|
||||
request({
|
||||
url: `/hard/hard-order/app/page-join`,
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
detail: (params: any) =>
|
||||
request({
|
||||
url: `/hard/hard-order/app/detail`,
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
shopCarList: (params: any) =>
|
||||
request({
|
||||
url: `/hard/hard-car/app/order-id`,
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
};
|
||||
caneenPage: (params: any) =>
|
||||
request({
|
||||
url: `/hard/hard-order/app/caneen-page-join`,
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
supPage: (params: any) =>
|
||||
request({
|
||||
url: `/hard/hard-order/app/sup-page-join`,
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
detail: (params: any) =>
|
||||
request({
|
||||
url: `/hard/hard-order/app/detail`,
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
shopCarList: (params: any) =>
|
||||
request({
|
||||
url: `/hard/hard-car/app/order-id`,
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
}
|
||||
@@ -61,4 +61,15 @@ export default {
|
||||
},
|
||||
})
|
||||
},
|
||||
// 转账
|
||||
transferMoney: (data): Promise<any> => {
|
||||
return request({
|
||||
url: "/wallet/wallet-rule-transaction/app/transfer-accounts",
|
||||
method: "POST",
|
||||
data,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -29,8 +29,9 @@ export default {
|
||||
// 浙政钉授权
|
||||
auth: (token: string): Promise<any> =>
|
||||
request({
|
||||
url: `/thirdparty/thirdPartyOAth2/zzdsso/${token}`,
|
||||
method: "GET",
|
||||
url: "/thirdparty/thirdPartyOAth2/zzdsso",
|
||||
method: "POST",
|
||||
data: { token },
|
||||
custom: {
|
||||
showLoading: false,
|
||||
loadingMsg: "授权中",
|
||||
@@ -38,9 +39,9 @@ export default {
|
||||
}),
|
||||
|
||||
// 诗画授权
|
||||
authsh: (params: { accountId: string; sessionId: string }) =>
|
||||
authsh: (params: { accountId: string; sessionId: string }): Promise<any> =>
|
||||
request({
|
||||
url: `/sys/auth/shjnsso`,
|
||||
url: `/thirdparty/thirdPartyOAth2/shjnsso`,
|
||||
method: "POST",
|
||||
custom: {
|
||||
showLoading: false,
|
||||
@@ -87,4 +88,13 @@ export default {
|
||||
},
|
||||
})
|
||||
},
|
||||
// 判断是否是商户角色
|
||||
isMerchant: (): Promise<any> =>
|
||||
request({
|
||||
url: "/admin/role/isMchUser",
|
||||
method: "GET",
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
}),
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
all: () =>
|
||||
all: (): Promise<any> =>
|
||||
request({
|
||||
url: "/wallet/wallet-manage/app/get-all",
|
||||
method: "GET",
|
||||
|
||||
@@ -151,7 +151,7 @@ page {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
padding: 0 30rpx;
|
||||
// background: #ecf4f9;
|
||||
background: #ecf4f9;
|
||||
}
|
||||
|
||||
&_bottom {
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<view class="bg-[#f5f5f5] px-1 py-2 rounded-4 absolute bottom-0 w-full">
|
||||
<view class="flex mb-2.5" v-for="(row, rowIndex) in keyboardLayout" :key="rowIndex">
|
||||
<view
|
||||
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
v-for="(key, keyIndex) in row"
|
||||
:key="keyIndex"
|
||||
@click="handleKeyPress(key.toString())"
|
||||
>
|
||||
{{ key }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex mb-0">
|
||||
<view
|
||||
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
@click="handleKeyPress('.')"
|
||||
>
|
||||
.
|
||||
</view>
|
||||
<view
|
||||
class="flex-auto h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
@click="handleKeyPress('0')"
|
||||
>
|
||||
0
|
||||
</view>
|
||||
<view
|
||||
class="flex-1 h-[60px] flex items-center justify-center bg-white mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
|
||||
@click="handleDelete"
|
||||
>
|
||||
<image class="w-[30px] h-[30px]" src="@/static/page/keyboardDelete.svg" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue"
|
||||
|
||||
const amount = defineModel<string>("modelValue", { default: "" })
|
||||
|
||||
const keyboardLayout = ref([
|
||||
["1", "2", "3"],
|
||||
["4", "5", "6"],
|
||||
["7", "8", "9"],
|
||||
])
|
||||
|
||||
// 按下键盘
|
||||
const handleKeyPress = (key) => {
|
||||
if (key === "." && amount.value.includes(".")) return
|
||||
if (key === "." && !amount.value) {
|
||||
amount.value = "0."
|
||||
return
|
||||
}
|
||||
// 特殊处理:如果当前为0,新输入不是小数点,则替换0
|
||||
if (amount.value == "0" && key != ".") {
|
||||
amount.value = key
|
||||
return
|
||||
}
|
||||
|
||||
// 特殊处理:如果有小数点且已有两位小数,不再添加数字
|
||||
if (amount.value.includes(".")) {
|
||||
const decimalPlaces = amount.value.split(".")[1]
|
||||
if (decimalPlaces && decimalPlaces.length >= 2) return
|
||||
}
|
||||
|
||||
amount.value += key
|
||||
}
|
||||
|
||||
// 点击删除
|
||||
const handleDelete = () => {
|
||||
if (amount.value.length > 0) {
|
||||
amount.value = amount.value.slice(0, -1)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,4 +1,5 @@
|
||||
export default {
|
||||
TOKEN: "token",
|
||||
USERINFO: "user_info",
|
||||
};
|
||||
TOKEN: "token",
|
||||
USERINFO: "user_info",
|
||||
USERROLE: "userRole",
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { defineStore } from "pinia"
|
||||
|
||||
export const usePayStore = defineStore("pay", {
|
||||
state: (): { payData: { id?: string; name?: string } } => {
|
||||
state: (): { payData: { id?: string; name?: string; customPrice?: number } } => {
|
||||
return {
|
||||
payData: {},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { defineStore } from "pinia"
|
||||
|
||||
export const useTransferMoney = defineStore("transferMoney", {
|
||||
state: (): any => {
|
||||
return {
|
||||
sourceWalletType: {},
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setSourceWalletType(data: any) {
|
||||
this.sourceWalletType = data
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -1,5 +1,7 @@
|
||||
import isDevEnv from "./isDevEnv"
|
||||
|
||||
export const filePath = (path?: string) => {
|
||||
const imageBaseUrl = import.meta.env.VITE_IMAGE_BASE_PATH;
|
||||
if (!path) return "";
|
||||
return imageBaseUrl + path;
|
||||
};
|
||||
const imageBaseUrl = isDevEnv() ? import.meta.env.VITE_IMAGE_DEV_PATH : import.meta.env.VITE_APP_PROD_IMAGE
|
||||
if (!path) return ""
|
||||
return imageBaseUrl + path
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// 检测app信息判断运行环境
|
||||
export const getAppInfo = async (): Promise<string> => {
|
||||
try {
|
||||
const res = await (window as any).CP2.getAppInfo()
|
||||
// 浙政钉环境
|
||||
if (res.code === 0) {
|
||||
return "dd"
|
||||
} else {
|
||||
// 诗画环境
|
||||
return "sh"
|
||||
}
|
||||
} catch (error) {
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
@@ -4,22 +4,180 @@ import isDevEnv from "./isDevEnv"
|
||||
import { router, constant } from "@@/index"
|
||||
import { userApi } from "../api"
|
||||
|
||||
// 定义常量
|
||||
// 常量定义
|
||||
const TOKEN_KEY = constant.storageConstant.TOKEN
|
||||
const USER_INFO_KEY = constant.storageConstant.USERINFO
|
||||
|
||||
// Loading 管理
|
||||
const LoadingInstance: { target: any; count: number } = {
|
||||
// Loading 状态管理
|
||||
const LoadingInstance = {
|
||||
target: null,
|
||||
count: 0,
|
||||
}
|
||||
|
||||
// 关闭 loading
|
||||
// 关闭加载提示
|
||||
function closeLoading() {
|
||||
if (LoadingInstance.count > 0) LoadingInstance.count--
|
||||
if (LoadingInstance.count === 0) uni.hideLoading()
|
||||
}
|
||||
|
||||
// 显示加载提示
|
||||
function showLoading(message: string) {
|
||||
LoadingInstance.count++
|
||||
if (LoadingInstance.count === 1) {
|
||||
uni.showLoading({
|
||||
title: message,
|
||||
mask: true,
|
||||
fail: () => uni.hideLoading(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 读取token并处理Authorization请求头
|
||||
const getAuthHeader = (tokenStorage: any) => {
|
||||
if (isDevEnv()) {
|
||||
return tokenStorage?.access_token ? `Bearer ${tokenStorage.access_token}` : null
|
||||
}
|
||||
return tokenStorage?.accessToken?.tokenValue ? `Bearer ${tokenStorage.accessToken.tokenValue}` : null
|
||||
}
|
||||
|
||||
// 浙政钉登录 登录成功返回true,否则返回false
|
||||
async function handleZzdLogin(): Promise<boolean> {
|
||||
try {
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
const params = new URL(window.location.href).searchParams
|
||||
const token = params.get("uabaseToken")
|
||||
|
||||
if (!token) return false
|
||||
|
||||
const res = await userApi.auth(token)
|
||||
if (res?.code == 0) {
|
||||
uni.setStorageSync(TOKEN_KEY, res.data)
|
||||
const { data: userData } = await userApi.userInfo()
|
||||
uni.setStorageSync(USER_INFO_KEY, userData)
|
||||
return true
|
||||
} else {
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
if (res.msg == "token已失效") {
|
||||
uni.showToast({ title: "用户凭证已失效,请退出并重新进入智慧后勤应用", icon: "none", duration: 6000 })
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || "登录失败", icon: "none" })
|
||||
}
|
||||
return false
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "登录错误", icon: "none" })
|
||||
return false
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 诗画登录 登录成功返回true,否则返回false
|
||||
async function handleShLogin(): Promise<boolean> {
|
||||
try {
|
||||
uni.showLoading({ title: "登录中...", mask: true })
|
||||
const userInfo = await (window as any).CP2.getUserInfo()
|
||||
|
||||
if (userInfo.code == 0) {
|
||||
uni.showToast({ title: "获取诗画用户信息失败", icon: "none" })
|
||||
return false
|
||||
}
|
||||
|
||||
const { accountId, sessionId } = userInfo.data
|
||||
const response = await userApi.authsh({ accountId, sessionId })
|
||||
|
||||
if (response.code == 0) {
|
||||
uni.setStorageSync(TOKEN_KEY, { accessToken: response.data.accessToken })
|
||||
const { data: userData } = await userApi.userInfo()
|
||||
uni.setStorageSync(USER_INFO_KEY, userData)
|
||||
uni.showToast({ title: "登录成功", icon: "none" })
|
||||
return true
|
||||
} else {
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
if (response.msg == "token已失效") {
|
||||
uni.showToast({ title: "用户凭证已失效,请退出并重新进入智慧后勤应用", icon: "none", duration: 6000 })
|
||||
} else {
|
||||
uni.showToast({ title: response.msg || "登录失败", icon: "none" })
|
||||
}
|
||||
return false
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "登录错误", icon: "none" })
|
||||
return false
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
// 根据应用环境自动登录 返回登录结果
|
||||
async function autoLogin(): Promise<boolean> {
|
||||
const appInfo = await (window as any).CP2.getAppInfo()
|
||||
|
||||
// 浙政钉环境
|
||||
if (appInfo.code == 0) {
|
||||
return await handleZzdLogin()
|
||||
}
|
||||
// 诗画环境
|
||||
else {
|
||||
return await handleShLogin()
|
||||
}
|
||||
}
|
||||
|
||||
// token过期刷新检查
|
||||
async function checkAndRefreshToken(tokenStorage: any) {
|
||||
const { accessToken } = tokenStorage
|
||||
if (!accessToken) return
|
||||
|
||||
const expiresDate = new Date(accessToken.expiresAt).getTime()
|
||||
|
||||
// console.log("过期时间", expiresDate)
|
||||
// console.log("现在时间", new Date().getTime())
|
||||
// console.log("现在时间大于过期时间吗", new Date().getTime() >= expiresDate)
|
||||
|
||||
// token已过期,尝试刷新
|
||||
if (new Date().getTime() >= expiresDate) {
|
||||
await autoLogin()
|
||||
}
|
||||
}
|
||||
|
||||
// 处理错误响应
|
||||
function handleErrorResponse(response: any) {
|
||||
if (!response.config?.custom?.showError) return
|
||||
|
||||
switch (response.data.code) {
|
||||
case 401:
|
||||
// 处理未授权情况
|
||||
setTimeout(() => {
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
}, 500)
|
||||
break
|
||||
case 424:
|
||||
// 处理token过期
|
||||
autoLogin()
|
||||
break
|
||||
default:
|
||||
uni.showToast({
|
||||
title: response.data.msg || "服务器开小差啦,请稍后再试~",
|
||||
icon: "none",
|
||||
mask: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 处理成功提示
|
||||
function handleSuccessMessage(response: any) {
|
||||
const { data, config } = response
|
||||
if (data.code === 0 && data.message && config?.custom?.showSuccess) {
|
||||
uni.showToast({
|
||||
title: config.custom.successMsg || data.message,
|
||||
icon: "none",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 创建请求实例
|
||||
const http = new Request({
|
||||
baseURL: import.meta.env.VITE_API_URL,
|
||||
@@ -31,90 +189,18 @@ const http = new Request({
|
||||
},
|
||||
withCredentials: true,
|
||||
custom: {
|
||||
showSuccess: false,
|
||||
// 成功提醒 默认使用后端返回值
|
||||
successMsg: "",
|
||||
// 显示失败消息 默认显示
|
||||
showError: true,
|
||||
// 失败提醒 默认使用后端返回信息
|
||||
errorMsg: "",
|
||||
// 显示请求时loading模态框 默认显示
|
||||
showLoading: true,
|
||||
// loading提醒文字
|
||||
loadingMsg: "加载中",
|
||||
// 需要授权才能请求 默认放开
|
||||
auth: false,
|
||||
showSuccess: false, // 成功提醒 默认使用后端返回值
|
||||
successMsg: "", // 成功消息
|
||||
showError: true, // 显示失败消息 默认显示
|
||||
errorMsg: "", // 失败提醒 默认使用后端返回信息
|
||||
showLoading: true, // 显示请求时loading模态框 默认显示
|
||||
loadingMsg: "加载中", // loading提醒文字
|
||||
auth: false, // 需要授权才能请求 默认放开
|
||||
},
|
||||
})
|
||||
|
||||
// 处理请求头 Authorization
|
||||
const getAuthHeader = (tokenStorage: any) => {
|
||||
if (isDevEnv()) {
|
||||
return tokenStorage?.access_token ? `Bearer ${tokenStorage.access_token}` : null
|
||||
}
|
||||
return tokenStorage?.accessToken?.tokenValue ? `Bearer ${tokenStorage.accessToken.tokenValue}` : null
|
||||
}
|
||||
|
||||
// token过期刷新检查
|
||||
const checkAndRefreshToken = async (tokenStorage: any) => {
|
||||
const { accessToken } = tokenStorage
|
||||
if (!accessToken) return
|
||||
|
||||
const expiresDate = new Date(accessToken.expiresAt).getTime()
|
||||
console.log("现在的时间大于过期时间吗:", new Date().getTime() >= expiresDate)
|
||||
|
||||
if (new Date().getTime() >= expiresDate) {
|
||||
// try {
|
||||
// const refreshData: any = await request({
|
||||
// url: "/auth/oauth2/token",
|
||||
// method: "POST",
|
||||
// params: { grant_type: "refresh_token" },
|
||||
// data: JSON.stringify({
|
||||
// scope: "server",
|
||||
// refresh_token: tokenStorage.refreshToken.tokenValue,
|
||||
// }),
|
||||
// header: {
|
||||
// skipToken: true,
|
||||
// Authorization: "Basic " + window.btoa(import.meta.env.VITE_OAUTH2_APP_CLIENT),
|
||||
// "content-type": "application/x-www-form-urlencoded",
|
||||
// },
|
||||
// })
|
||||
|
||||
// if (refreshData.code === 0 && !isEmpty(refreshData.data)) {
|
||||
// console.log("refreshData.data", refreshData.data)
|
||||
|
||||
// // 刷新成功,更新token并重试请求
|
||||
// uni.setStorageSync(TOKEN_KEY, refreshData.data)
|
||||
// }
|
||||
// } catch (refreshError) {
|
||||
// console.error("Token refresh failed:", refreshError)
|
||||
// }
|
||||
try {
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
const params = new URL(window.location.href).searchParams
|
||||
const token = params.get("uabaseToken")
|
||||
if (token) {
|
||||
const res = await userApi.auth(token)
|
||||
if (res?.code === 0) {
|
||||
uni.setStorageSync(TOKEN_KEY, res.data)
|
||||
} else {
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
uni.showToast({ title: res.msg, icon: "none" })
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "错误", icon: "none" })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 请求拦截器
|
||||
http.interceptors.request.use(async (config) => {
|
||||
console.log("请求之前")
|
||||
|
||||
const tokenStorage = uni.getStorageSync(TOKEN_KEY)
|
||||
const config_header: any = config?.header || {}
|
||||
|
||||
@@ -126,25 +212,19 @@ http.interceptors.request.use(async (config) => {
|
||||
|
||||
// 处理 loading
|
||||
if (config.custom?.showLoading) {
|
||||
LoadingInstance.count++
|
||||
if (LoadingInstance.count === 1) {
|
||||
uni.showLoading({
|
||||
title: config.custom.loadingMsg,
|
||||
mask: true,
|
||||
fail: () => uni.hideLoading(),
|
||||
})
|
||||
}
|
||||
showLoading(config.custom.loadingMsg)
|
||||
}
|
||||
|
||||
// 设置认证头
|
||||
if (
|
||||
!config.url?.startsWith("/thirdparty/thirdPartyOAth2/zzdsso") &&
|
||||
config.url !== "/sys/auth/refresh-token" &&
|
||||
config.url !== "/auth/oauth2/token"
|
||||
) {
|
||||
// 不需要设置认证头的接口
|
||||
const skipAuthUrls = ["/thirdparty/thirdPartyOAth2", "/sys/auth/refresh-token", "/auth/oauth2/token"]
|
||||
|
||||
// 判断是否需要设置认证头
|
||||
const needAuth = !skipAuthUrls.some((url) => config.url?.startsWith(url))
|
||||
|
||||
if (needAuth) {
|
||||
if (!isEmpty(tokenStorage)) {
|
||||
// token过期刷新检查
|
||||
checkAndRefreshToken(tokenStorage)
|
||||
await checkAndRefreshToken(tokenStorage)
|
||||
|
||||
const authHeader = getAuthHeader(tokenStorage)
|
||||
if (authHeader) {
|
||||
@@ -152,30 +232,13 @@ http.interceptors.request.use(async (config) => {
|
||||
}
|
||||
} else {
|
||||
// token不存在,则发起登录
|
||||
const params = new URL(window.location.href).searchParams
|
||||
const token = params.get("uabaseToken")
|
||||
await autoLogin()
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
const res = await userApi.auth(token)
|
||||
if (res.code == 0) {
|
||||
uni.setStorageSync(TOKEN_KEY, res.data)
|
||||
const { data: userData } = await userApi.userInfo()
|
||||
uni.setStorageSync(USER_INFO_KEY, userData)
|
||||
|
||||
const authHeader = getAuthHeader(tokenStorage)
|
||||
if (authHeader) {
|
||||
config_header.Authorization = authHeader
|
||||
}
|
||||
} else {
|
||||
uni.showToast({ title: "获取浙政钉用户信息失败", icon: "none" })
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "错误", icon: "none" })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
// 登录后重新获取token
|
||||
const newTokenStorage = uni.getStorageSync(TOKEN_KEY)
|
||||
const authHeader = getAuthHeader(newTokenStorage)
|
||||
if (authHeader) {
|
||||
config_header.Authorization = authHeader
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,64 +246,6 @@ http.interceptors.request.use(async (config) => {
|
||||
return config
|
||||
}, Promise.reject)
|
||||
|
||||
// 处理错误响应
|
||||
const handleErrorResponse = (response: any) => {
|
||||
if (!response.config?.custom?.showError) return
|
||||
|
||||
switch (response.data.code) {
|
||||
case 401:
|
||||
// 处理未授权情况
|
||||
setTimeout(() => {
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
console.log("未授权")
|
||||
}, 500)
|
||||
break
|
||||
case 424:
|
||||
try {
|
||||
const params = new URL(window.location.href).searchParams
|
||||
const token = params.get("uabaseToken")
|
||||
if (token) {
|
||||
userApi.auth(token).then((res) => {
|
||||
if (res?.code === 0) {
|
||||
uni.setStorageSync(TOKEN_KEY, res.data)
|
||||
} else {
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
// uni.showToast({ title: "登录已过期", icon: "none" })
|
||||
return Promise.resolve({
|
||||
code: 1,
|
||||
data: "登录已过期",
|
||||
msg: "登录已过期",
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "错误", icon: "none" })
|
||||
}
|
||||
break
|
||||
default:
|
||||
uni.showToast({
|
||||
title: response.data.msg || "服务器开小差啦,请稍后再试~",
|
||||
icon: "none",
|
||||
mask: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 处理成功提示
|
||||
const handleSuccessMessage = (response: any) => {
|
||||
const { data, config } = response
|
||||
if (data.code === 0 && data.message && config?.custom?.showSuccess) {
|
||||
uni.showToast({
|
||||
title: config.custom.successMsg || data.message,
|
||||
icon: "none",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 响应拦截器
|
||||
http.interceptors.response.use(
|
||||
async (response) => {
|
||||
@@ -269,7 +274,12 @@ http.interceptors.response.use(
|
||||
|
||||
return Promise.resolve(response.data)
|
||||
},
|
||||
(error) => {
|
||||
async (error) => {
|
||||
// 处理 loading
|
||||
if (error.config?.custom?.showLoading) {
|
||||
closeLoading()
|
||||
}
|
||||
|
||||
// 处理 424 错误(token过期)
|
||||
if (error.statusCode === 424) {
|
||||
if (isDevEnv()) {
|
||||
@@ -280,31 +290,7 @@ http.interceptors.response.use(
|
||||
router.jump("/pages/test/login")
|
||||
return false
|
||||
} else {
|
||||
try {
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
const params = new URL(window.location.href).searchParams
|
||||
const token = params.get("uabaseToken")
|
||||
if (token) {
|
||||
userApi.auth(token).then((res) => {
|
||||
if (res?.code === 0) {
|
||||
uni.setStorageSync(TOKEN_KEY, res.data)
|
||||
} else {
|
||||
uni.removeStorageSync(TOKEN_KEY)
|
||||
uni.removeStorageSync(USER_INFO_KEY)
|
||||
// uni.showToast({ title: "登录已过期", icon: "none" })
|
||||
return Promise.resolve({
|
||||
code: 1,
|
||||
data: "登录已过期",
|
||||
msg: "登录已过期",
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({ title: "错误", icon: "none" })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
await autoLogin()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,10 +302,11 @@ http.interceptors.response.use(
|
||||
mask: true,
|
||||
})
|
||||
}
|
||||
return false
|
||||
return Promise.resolve(error.data)
|
||||
},
|
||||
)
|
||||
|
||||
// 请求函数
|
||||
const request = (config: any) => {
|
||||
return http.middleware(config)
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1743643959336" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2508" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M334.08 192a47.36 47.36 0 0 0 0 64l256 256-256 256a47.36 47.36 0 1 0 64 64l288.64-288.64A50.56 50.56 0 0 0 704 512a47.36 47.36 0 0 0-14.08-33.28L401.28 192a47.36 47.36 0 0 0-67.2 0z" p-id="2509" fill="#C5BFBF"></path></svg>
|
||||
|
After Width: | Height: | Size: 554 B |
@@ -0,0 +1,26 @@
|
||||
<svg
|
||||
t="1742457305987"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="4499"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path
|
||||
d="M897.706667 831.146667H286.72c-8.533333 0-15.36-3.413333-20.48-10.24L39.253333 527.36c-6.826667-8.533333-6.826667-22.186667 0-30.72l226.986667-293.546667c5.12-6.826667 11.946667-10.24 20.48-10.24h610.986667c51.2 0 92.16 40.96 92.16 92.16v453.973334c0 51.2-40.96 92.16-92.16 92.16z m-599.04-51.2h599.04c22.186667 0 40.96-18.773333 40.96-40.96V285.013333c0-22.186667-18.773333-40.96-40.96-40.96H298.666667L92.16 512l206.506667 267.946667z"
|
||||
fill="#333333"
|
||||
p-id="4500"
|
||||
></path>
|
||||
<path
|
||||
d="M670.72 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667L426.666667 416.426667c-10.24-10.24-10.24-25.6 0-35.84 10.24-10.24 25.6-10.24 35.84 0l226.986666 226.986666c10.24 10.24 10.24 25.6 0 35.84-6.826667 5.12-11.946667 6.826667-18.773333 6.826667z"
|
||||
fill="#333333"
|
||||
p-id="4501"
|
||||
></path>
|
||||
<path
|
||||
d="M443.733333 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667-10.24-10.24-10.24-25.6 0-35.84l226.986667-226.986666c10.24-10.24 25.6-10.24 35.84 0 10.24 10.24 10.24 25.6 0 35.84L462.506667 643.413333c-5.12 5.12-11.946667 6.826667-18.773334 6.826667z"
|
||||
fill="#333333"
|
||||
p-id="4502"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,33 @@
|
||||
<svg
|
||||
t="1743474372390"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="23753"
|
||||
width="48"
|
||||
height="48"
|
||||
>
|
||||
<path d="M0 0h1024v1024H0z" fill="#FFFFFF" p-id="23754"></path>
|
||||
<path
|
||||
d="M842 984H182c-33.084 0-60-26.916-60-60V510c0-33.084 26.916-60 60-60h660c33.084 0 60 26.916 60 60v414c0 33.084-26.916 60-60 60z"
|
||||
fill="#D8DDE3"
|
||||
p-id="23755"
|
||||
></path>
|
||||
<path
|
||||
d="M182 490c-11.028 0-20 8.972-20 20v414c0 11.028 8.972 20 20 20h660c11.028 0 20-8.972 20-20V510c0-11.028-8.972-20-20-20H182m0-80h660c55.228 0 100 44.772 100 100v414c0 55.228-44.772 100-100 100H182c-55.228 0-100-44.772-100-100V510c0-55.228 44.772-100 100-100z"
|
||||
fill="#505873"
|
||||
p-id="23756"
|
||||
></path>
|
||||
<path
|
||||
d="M835.348 566.004c-30.586 0-60.34-9.472-83.784-26.672l-23.66-17.36-23.66 17.356c-23.454 17.204-53.214 26.676-83.8 26.676-30.956 0-60.98-9.668-84.54-27.226L512 520.968l-23.9 17.81c-23.562 17.558-53.586 27.226-84.544 27.226-30.584 0-60.346-9.472-83.8-26.676l-23.66-17.356-23.66 17.36c-23.442 17.2-53.196 26.672-83.782 26.672-72.044 0-130.656-51.26-130.656-114.274 0-2.03 0.06-4.046 0.18-6.05l0.14-2.406-0.146-2.402c-0.056-0.946-0.1-1.9-0.13-2.852L106.44 139.59l0.516-3.18v-3.222c0-51.618 60.894-93.184 111.312-93.184h587.46c50.42 0 111.32 41.566 111.32 93.184v3.222l0.516 3.18 48.386 298.426c-0.03 0.956-0.074 1.906-0.132 2.856l-0.146 2.4 0.142 2.408c0.12 2.004 0.182 4.02 0.182 6.05 0 63.012-58.608 114.274-130.648 114.274z"
|
||||
fill="#FFFFFF"
|
||||
p-id="23757"
|
||||
></path>
|
||||
<path
|
||||
d="M835.348 526.004c49.984 0 90.648-33.32 90.648-74.274 0-1.234-0.038-2.46-0.112-3.68l-0.284-4.808 0.184-3.028-47.704-294.22-1.032-6.36v-6.446c0-24.852-37.994-53.184-71.32-53.184h-587.46c-33.324 0-71.312 28.332-71.312 53.184v6.444l-1.032 6.36-47.714 294.23 0.184 3.02-0.286 4.808c-0.072 1.22-0.108 2.446-0.108 3.68 0 40.954 40.666 74.274 90.656 74.274 22.138 0 43.49-6.72 60.12-18.922l47.316-34.714 47.324 34.706c16.644 12.208 38.004 18.93 60.142 18.93 22.404 0 43.94-6.856 60.642-19.3l47.802-35.622 47.8 35.62c16.704 12.446 38.24 19.302 60.644 19.302 22.138 0 43.498-6.722 60.14-18.93l47.322-34.706 47.316 34.714c16.634 12.204 37.986 18.922 60.124 18.922m0 80c-40.722 0-78.116-12.902-107.446-34.422-29.34 21.52-66.732 34.422-107.456 34.422-41.188 0-78.962-13.184-108.444-35.152-29.48 21.968-67.256 35.152-108.444 35.152-40.724 0-78.116-12.902-107.456-34.422-29.33 21.52-66.732 34.422-107.446 34.422C94.404 606.004 18 536.938 18 451.73c0-2.828 0.084-5.632 0.25-8.426A135.136 135.136 0 0 1 18 435.08L66.956 133.188c0-73.556 77.574-133.184 151.312-133.184h587.46c73.736 0 151.32 59.628 151.32 133.184l48.948 301.89c0 2.76-0.086 5.504-0.252 8.226 0.166 2.794 0.252 5.6 0.252 8.426 0 85.208-76.396 154.274-170.648 154.274z"
|
||||
fill="#505873"
|
||||
p-id="23758"
|
||||
></path>
|
||||
<path d="M262 362h500a40 40 0 0 1 0 80H262a40 40 0 0 1 0-80z" fill="#FF402A" p-id="23759"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1743596095932" class="icon" viewBox="0 0 1042 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7038" width="65.125" height="64" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M515.657143 54.857143c-252.342857 0-457.142857 204.8-457.142857 457.142857s204.8 457.142857 457.142857 457.142857 457.142857-204.8 457.142857-457.142857S768 54.857143 515.657143 54.857143z m182.857143 442.514286h-146.285715v36.571428h146.285715v73.142857h-146.285715v109.714286h-73.142857v-109.714286h-146.285714v-73.142857h146.285714v-36.571428h-146.285714v-73.142858h91.428571l-65.828571-65.828571 51.2-51.2 104.228571 104.228571 104.228572-104.228571 51.2 51.2-65.828572 65.828571h91.428572v73.142858h3.657143z" fill="#0779FD" p-id="7039"></path></svg>
|
||||
|
After Width: | Height: | Size: 890 B |
@@ -0,0 +1,21 @@
|
||||
<svg
|
||||
t="1743474000421"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="28044"
|
||||
width="48"
|
||||
height="48"
|
||||
>
|
||||
<path
|
||||
d="M564.63 935.61c-23.13 0-41.94-18.82-41.94-41.94 0-38.83 10.32-76.93 29.86-110.19 18.97-32.3 46.16-59.24 78.76-78.08-31.95-29.91-50.18-71.95-50.14-115.86 0-87.62 71.29-158.9 158.91-158.9S899 501.92 899 589.55c0 43.86-18.24 85.91-50.14 115.86 32.61 18.83 59.8 45.77 78.77 78.07 19.53 33.25 29.86 71.36 29.86 110.19 0 23.13-18.82 41.94-41.94 41.94H564.63z m302.26-83.88c-17.57-53.47-66.78-90.11-123.4-91.53l-3.43-0.03c-57.2 0.01-108.88 37.51-126.76 91.57h253.59z m-126.8-337.21c-41.37 0-75.02 33.66-75.02 75.03 0 41.37 33.66 75.03 75.02 75.03s75.02-33.66 75.02-75.03c0-41.37-33.65-75.03-75.02-75.03zM155.24 935.61c-23.13 0-45.03-8.85-61.66-24.92-16.63-16.07-26.23-37.65-27.02-60.77l-0.05-2.93V180.16c0-23.13 8.85-45.03 24.92-61.66 16.07-16.63 37.65-26.23 60.77-27.02l2.93-0.05h620.04c23.13 0 45.03 8.85 61.66 24.92 16.63 16.07 26.23 37.65 27.02 60.77l0.05 2.93v187.26c0.03 22.86-17.86 41.29-40.71 41.96-0.42 0.01-0.84 0.02-1.25 0.02-22.19 0-40.57-17.36-41.86-39.53l-0.07-2.39V180.15c0-2.39-1.77-4.44-4.12-4.79l-0.92-0.05H155.24c-2.39 0-4.44 1.76-4.79 4.12l-0.06 0.93v666.52c0 2.39 1.77 4.44 4.12 4.79l0.93 0.06h292.21c22.86 0 41.29 17.88 41.96 40.71 0.67 22.86-16.69 41.79-39.51 43.11l-2.35 0.07H155.24z"
|
||||
fill="#303133"
|
||||
p-id="28045"
|
||||
></path>
|
||||
<path
|
||||
d="M258.25 672.43v-0.06c-21.8-1.12-39.05-18.58-39.69-40.66-0.67-22.85 16.68-41.78 39.51-43.1l2.39-0.07h234c22.86 0 41.29 17.88 41.96 40.72 0.67 22.85-16.68 41.78-39.51 43.11l-2.35 0.07H258.25z m0-263.18v-0.06c-21.8-1.12-39.05-18.57-39.69-40.66-0.67-22.85 16.68-41.78 39.51-43.1l2.39-0.07h350.97c22.86 0 41.29 17.88 41.96 40.71 0.67 22.85-16.68 41.79-39.51 43.11l-2.36 0.07H258.25z"
|
||||
fill="#FF6F26"
|
||||
p-id="28046"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 498 B After Width: | Height: | Size: 498 B |
|
Before Width: | Height: | Size: 493 B After Width: | Height: | Size: 493 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, watch, type PropType } from 'vue';
|
||||
import { useTmConfig } from "../../libs/config";
|
||||
import { tmDate, type tmDateTypeTime, createDate } from '../../libs/tmDate';
|
||||
import { getDefaultColor } from "../../libs/colors";
|
||||
import { ref, computed, onMounted, watch, type PropType } from "vue"
|
||||
import { useTmConfig } from "../../libs/config"
|
||||
import { tmDate, type tmDateTypeTime, createDate } from "../../libs/tmDate"
|
||||
import { getDefaultColor } from "../../libs/colors"
|
||||
|
||||
type PICKER_ITEM_INFO = Record<string, any>
|
||||
|
||||
@@ -16,161 +16,161 @@ type PICKER_ITEM_INFO = Record<string, any>
|
||||
| --- | --- | --- | --- |
|
||||
| ☑️| ☑️ | ☑️ | ☑️ | ☑️ | 1.0.0 |
|
||||
*/
|
||||
defineOptions({ name: 'TmBetweenTime' });
|
||||
defineOptions({ name: "TmBetweenTime" })
|
||||
const { config } = useTmConfig()
|
||||
|
||||
type coverValue = {
|
||||
value: string[],
|
||||
str: string
|
||||
value: string[]
|
||||
str: string
|
||||
}
|
||||
type ModelType = "year" | "month" | "day" | "hour" | "minute" | "second";
|
||||
type ModelType = "year" | "month" | "day" | "hour" | "minute" | "second"
|
||||
|
||||
const props = defineProps({
|
||||
/**
|
||||
* 当前时间,与modelStr不同,此提供的值必须是正常的时间格式
|
||||
* 否则报错,无法运行。
|
||||
*/
|
||||
modelValue: {
|
||||
type: [Array<string>],
|
||||
default: (): string[] => [] as string[]
|
||||
},
|
||||
/**
|
||||
* 当前时间经过format格式化后输出的值。
|
||||
* 此值不会处理输入,只输出显示。
|
||||
*/
|
||||
modelStr: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
/**
|
||||
* 当前打开的状态。
|
||||
* 等同v-model:model-show
|
||||
*/
|
||||
modelShow: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* 顶部标题
|
||||
*/
|
||||
title: {
|
||||
type: String,
|
||||
default: "请选择时间"
|
||||
},
|
||||
/**
|
||||
* 开始时间,请提供正确的时间格式
|
||||
*/
|
||||
start: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
/**
|
||||
* 结束时间,请提供正确的时间格式
|
||||
*/
|
||||
end: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
/**
|
||||
* 精确到的级别,这里只是展示,具体的返回值还是完整的值。
|
||||
* year:年
|
||||
* month:年月
|
||||
* day:年月日
|
||||
* hour:年月日小时
|
||||
* minute:年月日小时分钟
|
||||
* second:年月日小时分钟秒
|
||||
*/
|
||||
type: {
|
||||
type: String as PropType<ModelType>,
|
||||
default: "day"
|
||||
},
|
||||
/**
|
||||
* 输出时间格式,只对v-model:modelStr及输入框展示有效
|
||||
* 因此它可能不是一个标准时间,比如YY SS ,所以不能作为modelValue使用
|
||||
* 有效格式:
|
||||
* YYYY年
|
||||
* MM月
|
||||
* DD日
|
||||
* hh小时
|
||||
* mm分钟
|
||||
* ss秒
|
||||
*/
|
||||
format: {
|
||||
type: String,
|
||||
default: "YYYY-MM-DD"
|
||||
},
|
||||
/**
|
||||
* 上方的单位名称
|
||||
*/
|
||||
cellUnits: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: (): string[] => ['年', '月', '日', '时', '分', '秒'] as string[]
|
||||
},
|
||||
/**
|
||||
* 快速时间区间选择,如果直接填写数字字符,会以你提供的数字最近多少来天来算。
|
||||
* d:本日
|
||||
* w:本周
|
||||
* m:本月
|
||||
* y:本年
|
||||
* q:本季度
|
||||
* 7:最近7天,后面的依此类推,数字的就是最近xx天。
|
||||
*/
|
||||
quickDate: {
|
||||
type: [Array<string>],
|
||||
default: (): string[] => ['d', 'w', 'm', 'y', 'q'] as string[]
|
||||
},
|
||||
/**
|
||||
* 是否懒加载内部内容。
|
||||
* 当前你的列表内容非常多,且影响打开的动画性能时,请务必
|
||||
* 设置此项为true,以获得流畅视觉效果。如果选择数据较少没有必要打开
|
||||
*/
|
||||
lazyContent: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* 如果你的快捷选择较多可能会让高度不足,需要自行设置下高。
|
||||
*/
|
||||
drawerSize: {
|
||||
type: String,
|
||||
default: '1020'
|
||||
}
|
||||
/**
|
||||
* 当前时间,与modelStr不同,此提供的值必须是正常的时间格式
|
||||
* 否则报错,无法运行。
|
||||
*/
|
||||
modelValue: {
|
||||
type: [Array<string>],
|
||||
default: (): string[] => [] as string[],
|
||||
},
|
||||
/**
|
||||
* 当前时间经过format格式化后输出的值。
|
||||
* 此值不会处理输入,只输出显示。
|
||||
*/
|
||||
modelStr: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
/**
|
||||
* 当前打开的状态。
|
||||
* 等同v-model:model-show
|
||||
*/
|
||||
modelShow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 顶部标题
|
||||
*/
|
||||
title: {
|
||||
type: String,
|
||||
default: "请选择时间",
|
||||
},
|
||||
/**
|
||||
* 开始时间,请提供正确的时间格式
|
||||
*/
|
||||
start: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
/**
|
||||
* 结束时间,请提供正确的时间格式
|
||||
*/
|
||||
end: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
/**
|
||||
* 精确到的级别,这里只是展示,具体的返回值还是完整的值。
|
||||
* year:年
|
||||
* month:年月
|
||||
* day:年月日
|
||||
* hour:年月日小时
|
||||
* minute:年月日小时分钟
|
||||
* second:年月日小时分钟秒
|
||||
*/
|
||||
type: {
|
||||
type: String as PropType<ModelType>,
|
||||
default: "day",
|
||||
},
|
||||
/**
|
||||
* 输出时间格式,只对v-model:modelStr及输入框展示有效
|
||||
* 因此它可能不是一个标准时间,比如YY SS ,所以不能作为modelValue使用
|
||||
* 有效格式:
|
||||
* YYYY年
|
||||
* MM月
|
||||
* DD日
|
||||
* hh小时
|
||||
* mm分钟
|
||||
* ss秒
|
||||
*/
|
||||
format: {
|
||||
type: String,
|
||||
default: "YYYY-MM-DD",
|
||||
},
|
||||
/**
|
||||
* 上方的单位名称
|
||||
*/
|
||||
cellUnits: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: (): string[] => ["年", "月", "日", "时", "分", "秒"] as string[],
|
||||
},
|
||||
/**
|
||||
* 快速时间区间选择,如果直接填写数字字符,会以你提供的数字最近多少来天来算。
|
||||
* d:本日
|
||||
* w:本周
|
||||
* m:本月
|
||||
* y:本年
|
||||
* q:本季度
|
||||
* 7:最近7天,后面的依此类推,数字的就是最近xx天。
|
||||
*/
|
||||
quickDate: {
|
||||
type: [Array<string>],
|
||||
default: (): string[] => ["d", "w", "m", "y", "q"] as string[],
|
||||
},
|
||||
/**
|
||||
* 是否懒加载内部内容。
|
||||
* 当前你的列表内容非常多,且影响打开的动画性能时,请务必
|
||||
* 设置此项为true,以获得流畅视觉效果。如果选择数据较少没有必要打开
|
||||
*/
|
||||
lazyContent: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 如果你的快捷选择较多可能会让高度不足,需要自行设置下高。
|
||||
*/
|
||||
drawerSize: {
|
||||
type: String,
|
||||
default: "1020",
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits([
|
||||
/**
|
||||
* 取消时触发
|
||||
*/
|
||||
'cancel',
|
||||
/**
|
||||
* 确认触发
|
||||
* @param {string} date 当前选中时间
|
||||
*/
|
||||
'confirm',
|
||||
/**
|
||||
* 滑动变换时触发
|
||||
* @param {string} date - 当前选中时间
|
||||
*/
|
||||
'change',
|
||||
/**
|
||||
* 变量控制打开状态
|
||||
* 等同v-model:model-show
|
||||
*/
|
||||
'update:modelShow',
|
||||
/**
|
||||
* 经格式化后的值。等同v-model:model-str
|
||||
*/
|
||||
'update:modelStr',
|
||||
'update:modelValue'
|
||||
]);
|
||||
/**
|
||||
* 取消时触发
|
||||
*/
|
||||
"cancel",
|
||||
/**
|
||||
* 确认触发
|
||||
* @param {string} date 当前选中时间
|
||||
*/
|
||||
"confirm",
|
||||
/**
|
||||
* 滑动变换时触发
|
||||
* @param {string} date - 当前选中时间
|
||||
*/
|
||||
"change",
|
||||
/**
|
||||
* 变量控制打开状态
|
||||
* 等同v-model:model-show
|
||||
*/
|
||||
"update:modelShow",
|
||||
/**
|
||||
* 经格式化后的值。等同v-model:model-str
|
||||
*/
|
||||
"update:modelStr",
|
||||
"update:modelValue",
|
||||
])
|
||||
|
||||
let startValue = new tmDate()
|
||||
let endValue = new tmDate()
|
||||
startValue.subtraction(1, 'y')
|
||||
startValue.subtraction(1, "y")
|
||||
|
||||
const show = ref(false)
|
||||
const nowValue = ref<string[]>(['', ''])
|
||||
const nowModelValue = ref<string[]>(['', ''])
|
||||
const nowValue = ref<string[]>(["", ""])
|
||||
const nowModelValue = ref<string[]>(["", ""])
|
||||
const startDate = ref(startValue)
|
||||
const endDate = ref(endValue)
|
||||
const changeIndex = ref(0)
|
||||
@@ -179,338 +179,405 @@ const quicklist = ref<coverValue[]>([])
|
||||
|
||||
const _lazyContent = computed(() => props.lazyContent)
|
||||
|
||||
const _start_date = computed(() => props.start === "" ? startDate.value : new tmDate(props.start))
|
||||
const _end_date = computed(() => props.end === "" ? endDate.value : new tmDate(props.end))
|
||||
const _start_date = computed(() => (props.start === "" ? startDate.value : new tmDate(props.start)))
|
||||
const _end_date = computed(() => (props.end === "" ? endDate.value : new tmDate(props.end)))
|
||||
const _start_date_str = computed(() => _start_date.value.format())
|
||||
const _end_date_str = computed(() => _end_date.value.format())
|
||||
const _start_date_str_format = computed(() => nowValue.value[0] === '' ? '开始时间' : (new tmDate(nowValue.value[0])).format(props.format))
|
||||
const _end_date_str_format = computed(() => nowValue.value[1] === '' ? '结束时间' : (new tmDate(nowValue.value[1])).format(props.format))
|
||||
const _start_date_str_format = computed(() => (nowValue.value[0] === "" ? "开始时间" : new tmDate(nowValue.value[0]).format(props.format)))
|
||||
const _end_date_str_format = computed(() => (nowValue.value[1] === "" ? "结束时间" : new tmDate(nowValue.value[1]).format(props.format)))
|
||||
|
||||
const _backgroundColor = computed(() => config.mode === 'dark' ? getDefaultColor(config.inputDarkColor) : getDefaultColor('#f5f5f5'))
|
||||
const _borderColor = computed(() => config.mode === 'dark' ? getDefaultColor(config.borderDarkColor) : getDefaultColor('#eaeaea'))
|
||||
const _backgroundColor = computed(() => (config.mode === "dark" ? getDefaultColor(config.inputDarkColor) : getDefaultColor("#f5f5f5")))
|
||||
const _borderColor = computed(() => (config.mode === "dark" ? getDefaultColor(config.borderDarkColor) : getDefaultColor("#eaeaea")))
|
||||
const _activeBorderColor = computed(() => getDefaultColor(config.color))
|
||||
const _placeStyle = computed(() => config.mode === 'dark' ? "color:#c7c7c7;" : "color:#838383;")
|
||||
const _fontColor = computed(() => config.mode === 'dark' ? "#efefef" : "#333")
|
||||
const _isDark = computed(() => config.mode === 'dark')
|
||||
const _placeStyle = computed(() => (config.mode === "dark" ? "color:#c7c7c7;" : "color:#838383;"))
|
||||
const _fontColor = computed(() => (config.mode === "dark" ? "#efefef" : "#333"))
|
||||
const _isDark = computed(() => config.mode === "dark")
|
||||
|
||||
watch(() => props.modelValue, (newvalue: string[]) => {
|
||||
let sortvalue = sorDateVaild(validTimeDate(newvalue))
|
||||
let newvaluestr = sortvalue.join('')
|
||||
if (newvaluestr === nowModelValue.value.join('')) return
|
||||
nowValue.value = sortvalue
|
||||
nowModelValue.value = sortvalue
|
||||
tongbuModelStr()
|
||||
})
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newvalue: string[]) => {
|
||||
let sortvalue = sorDateVaild(validTimeDate(newvalue))
|
||||
let newvaluestr = sortvalue.join("")
|
||||
if (newvaluestr === nowModelValue.value.join("")) return
|
||||
nowValue.value = sortvalue
|
||||
nowModelValue.value = sortvalue
|
||||
tongbuModelStr()
|
||||
},
|
||||
)
|
||||
|
||||
watch(() => props.modelShow, (newValue: boolean) => {
|
||||
if (newValue === show.value) return
|
||||
show.value = newValue
|
||||
})
|
||||
watch(
|
||||
() => props.modelShow,
|
||||
(newValue: boolean) => {
|
||||
if (newValue === show.value) return
|
||||
show.value = newValue
|
||||
},
|
||||
)
|
||||
|
||||
watch(() => props.quickDate, (newvalue: string[]) => {
|
||||
quicklist.value = getQuickDateType()
|
||||
})
|
||||
watch(
|
||||
() => props.quickDate,
|
||||
(newvalue: string[]) => {
|
||||
quicklist.value = getQuickDateType()
|
||||
},
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
yanchiDuration.value = _lazyContent.value ? false : true
|
||||
yanchiDuration.value = _lazyContent.value ? false : true
|
||||
|
||||
let str = validTimeDate(props.modelValue)
|
||||
nowValue.value = str
|
||||
nowModelValue.value = str
|
||||
quicklist.value = getQuickDateType()
|
||||
tongbuModelStr()
|
||||
let str = validTimeDate(props.modelValue)
|
||||
nowValue.value = str
|
||||
nowModelValue.value = str
|
||||
quicklist.value = getQuickDateType()
|
||||
tongbuModelStr()
|
||||
})
|
||||
|
||||
function clearDate() {
|
||||
let dst = ['', ''] as string[]
|
||||
nowValue.value = dst
|
||||
let dst = ["", ""] as string[]
|
||||
nowValue.value = dst
|
||||
}
|
||||
|
||||
function tongbuModelStr() {
|
||||
let str = coverStrVal()
|
||||
/**
|
||||
* 经格式化后的值。等同v-model:model-str
|
||||
*/
|
||||
emit('update:modelStr', str === '~' ? '' : str)
|
||||
let str = coverStrVal()
|
||||
/**
|
||||
* 经格式化后的值。等同v-model:model-str
|
||||
*/
|
||||
emit("update:modelStr", str === "~" ? "" : str)
|
||||
}
|
||||
|
||||
function dateChangeView(datestr: string) {
|
||||
let nowvalu = nowValue.value.slice(0)
|
||||
nowvalu[changeIndex.value] = datestr
|
||||
let strStart = nowvalu[0]
|
||||
let strEnd = nowvalu[1]
|
||||
let types = getTypes()
|
||||
if (strEnd !== '' && strStart !== '') {
|
||||
if (changeIndex.value === 0) {
|
||||
if (new tmDate(strStart).isBetweenOf(new tmDate(strEnd), '>', types)) {
|
||||
strEnd = strStart
|
||||
}
|
||||
} else if (changeIndex.value === 1) {
|
||||
if (new tmDate(strEnd).isBetweenOf(new tmDate(strStart), '<', types)) {
|
||||
strStart = strEnd
|
||||
}
|
||||
}
|
||||
}
|
||||
let nowvalu = nowValue.value.slice(0)
|
||||
nowvalu[changeIndex.value] = datestr
|
||||
let strStart = nowvalu[0]
|
||||
let strEnd = nowvalu[1]
|
||||
let types = getTypes()
|
||||
if (strEnd !== "" && strStart !== "") {
|
||||
if (changeIndex.value === 0) {
|
||||
if (new tmDate(strStart).isBetweenOf(new tmDate(strEnd), ">", types)) {
|
||||
strEnd = strStart
|
||||
}
|
||||
} else if (changeIndex.value === 1) {
|
||||
if (new tmDate(strEnd).isBetweenOf(new tmDate(strStart), "<", types)) {
|
||||
strStart = strEnd
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nowValue.value = [strStart, strEnd]
|
||||
nowValue.value = [strStart, strEnd]
|
||||
}
|
||||
|
||||
function tagsClick(item: coverValue) {
|
||||
nowValue.value = item.value
|
||||
nowValue.value = item.value
|
||||
}
|
||||
|
||||
function inputClick(index: number) {
|
||||
changeIndex.value = index
|
||||
changeIndex.value = index
|
||||
|
||||
let nowvalu = nowValue.value.slice(0)
|
||||
let strStart = nowvalu[0]
|
||||
let strEnd = nowvalu[1]
|
||||
let nowvalu = nowValue.value.slice(0)
|
||||
let strStart = nowvalu[0]
|
||||
let strEnd = nowvalu[1]
|
||||
|
||||
if (changeIndex.value === 0) {
|
||||
if (strStart === '') {
|
||||
strStart = strEnd !== '' ? strEnd : (endDate.value.format())
|
||||
nowValue.value = [strStart, strEnd]
|
||||
}
|
||||
} else if (changeIndex.value === 1) {
|
||||
if (strEnd === '') {
|
||||
strEnd = strStart !== '' ? strStart : (endDate.value.format())
|
||||
nowValue.value = [strStart, strEnd]
|
||||
}
|
||||
}
|
||||
if (changeIndex.value === 0) {
|
||||
if (strStart === "") {
|
||||
strStart = strEnd !== "" ? strEnd : endDate.value.format()
|
||||
nowValue.value = [strStart, strEnd]
|
||||
}
|
||||
} else if (changeIndex.value === 1) {
|
||||
if (strEnd === "") {
|
||||
strEnd = strStart !== "" ? strStart : endDate.value.format()
|
||||
nowValue.value = [strStart, strEnd]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getQuickDateType(): coverValue[] {
|
||||
let typelist: coverValue[] = []
|
||||
if (props.quickDate.length === 0) return typelist
|
||||
let list = props.quickDate
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let item: string = list[i]
|
||||
if (!isNaN(parseInt(item))) {
|
||||
let dshi = parseInt(item)! as number
|
||||
let date = new tmDate()
|
||||
let start = date.format()
|
||||
date.subtraction(dshi, 'd')
|
||||
let end = date.format()
|
||||
let typelist: coverValue[] = []
|
||||
if (props.quickDate.length === 0) return typelist
|
||||
let list = props.quickDate
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let item: string = list[i]
|
||||
if (!isNaN(parseInt(item))) {
|
||||
let dshi = parseInt(item)! as number
|
||||
let date = new tmDate()
|
||||
let start = date.format()
|
||||
date.subtraction(dshi, "d")
|
||||
let end = date.format()
|
||||
|
||||
typelist.push({ value: [end, start], str: '最近' + item + '天' } as coverValue)
|
||||
} else {
|
||||
let date = new tmDate()
|
||||
let startFDate = "YYYY/DD/MM 00:00:00"
|
||||
let endFDate = "YYYY/DD/MM 23:59:59"
|
||||
let start = date.format(startFDate)
|
||||
let end = date.format(endFDate)
|
||||
let desc = "本日"
|
||||
if (item === 'w') {
|
||||
start = date.getDateStartOf('w').format(startFDate)
|
||||
end = date.getDateEndOf('w').format(endFDate)
|
||||
desc = "本周"
|
||||
} else if (item === 'm') {
|
||||
start = date.getDateStartOf('m').format(startFDate)
|
||||
end = date.getDateEndOf('m').format(endFDate)
|
||||
desc = "本月"
|
||||
} else if (item === 'y') {
|
||||
start = date.getDateStartOf('y').format(startFDate)
|
||||
end = date.getDateEndOf('y').format(endFDate)
|
||||
desc = "本年"
|
||||
} else if (item === 'q') {
|
||||
let nowq = date.getQuarter('')
|
||||
let itemqatar = nowq[0]
|
||||
start = itemqatar.start
|
||||
end = itemqatar.end
|
||||
desc = "本季度"
|
||||
}
|
||||
typelist.push({ value: [end, start], str: "最近" + item + "天" } as coverValue)
|
||||
} else {
|
||||
let date = new tmDate()
|
||||
let startFDate = "YYYY/DD/MM 00:00:00"
|
||||
let endFDate = "YYYY/DD/MM 23:59:59"
|
||||
let start = date.format(startFDate)
|
||||
let end = date.format(endFDate)
|
||||
let desc = "本日"
|
||||
if (item === "w") {
|
||||
start = date.getDateStartOf("w").format(startFDate)
|
||||
end = date.getDateEndOf("w").format(endFDate)
|
||||
desc = "本周"
|
||||
} else if (item === "m") {
|
||||
start = date.getDateStartOf("m").format(startFDate)
|
||||
end = date.getDateEndOf("m").format(endFDate)
|
||||
desc = "本月"
|
||||
} else if (item === "y") {
|
||||
start = date.getDateStartOf("y").format(startFDate)
|
||||
end = date.getDateEndOf("y").format(endFDate)
|
||||
desc = "本年"
|
||||
} else if (item === "q") {
|
||||
let nowq = date.getQuarter("")
|
||||
let itemqatar = nowq[0]
|
||||
start = itemqatar.start
|
||||
end = itemqatar.end
|
||||
desc = "本季度"
|
||||
}
|
||||
|
||||
typelist.push({ value: [start, end], str: desc } as coverValue)
|
||||
}
|
||||
}
|
||||
return typelist
|
||||
typelist.push({ value: [start, end], str: desc } as coverValue)
|
||||
}
|
||||
}
|
||||
return typelist
|
||||
}
|
||||
|
||||
// 获取精确单位
|
||||
function getTypes(): tmDateTypeTime {
|
||||
if (props.type === 'year') {
|
||||
return 'y' as tmDateTypeTime
|
||||
} else if (props.type === 'month') {
|
||||
return 'm' as tmDateTypeTime
|
||||
} else if (props.type === 'day') {
|
||||
return 'd' as tmDateTypeTime
|
||||
} else if (props.type === 'hour') {
|
||||
return 'h' as tmDateTypeTime
|
||||
} else if (props.type === 'minute') {
|
||||
return 'M' as tmDateTypeTime
|
||||
} else if (props.type === 'second') {
|
||||
return 's' as tmDateTypeTime
|
||||
}
|
||||
return 's' as tmDateTypeTime
|
||||
if (props.type === "year") {
|
||||
return "y" as tmDateTypeTime
|
||||
} else if (props.type === "month") {
|
||||
return "m" as tmDateTypeTime
|
||||
} else if (props.type === "day") {
|
||||
return "d" as tmDateTypeTime
|
||||
} else if (props.type === "hour") {
|
||||
return "h" as tmDateTypeTime
|
||||
} else if (props.type === "minute") {
|
||||
return "M" as tmDateTypeTime
|
||||
} else if (props.type === "second") {
|
||||
return "s" as tmDateTypeTime
|
||||
}
|
||||
return "s" as tmDateTypeTime
|
||||
}
|
||||
|
||||
//验证提供的值是否合法,并纠正为合法值。
|
||||
function validTimeDate(val: string[]): string[] {
|
||||
let str = ['', '']
|
||||
if (val.length >= 1) {
|
||||
str[0] = val[0]!
|
||||
}
|
||||
if (val.length >= 2) {
|
||||
str[1] = val[1]!
|
||||
}
|
||||
let str = ["", ""]
|
||||
if (val.length >= 1) {
|
||||
str[0] = val[0]!
|
||||
}
|
||||
if (val.length >= 2) {
|
||||
str[1] = val[1]!
|
||||
}
|
||||
|
||||
return sorDateVaild(str)
|
||||
return sorDateVaild(str)
|
||||
}
|
||||
|
||||
function sorDateVaild(str: string[]): string[] {
|
||||
let types = getTypes()
|
||||
str.sort((a: string, b: string): number => {
|
||||
return new tmDate(a).getTime(types) - new tmDate(b).getTime(types)
|
||||
})
|
||||
return str
|
||||
let types = getTypes()
|
||||
str.sort((a: string, b: string): number => {
|
||||
return new tmDate(a).getTime(types) - new tmDate(b).getTime(types)
|
||||
})
|
||||
return str
|
||||
}
|
||||
|
||||
function openShow() {
|
||||
show.value = true
|
||||
/**
|
||||
* 变量控制打开状态
|
||||
* 等同v-model:model-show
|
||||
*/
|
||||
emit('update:modelShow', true)
|
||||
show.value = true
|
||||
/**
|
||||
* 变量控制打开状态
|
||||
* 等同v-model:model-show
|
||||
*/
|
||||
emit("update:modelShow", true)
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
/**
|
||||
* 变量控制打开状态
|
||||
* 等同v-model:model-show
|
||||
*/
|
||||
emit('update:modelShow', false)
|
||||
cancelResetDataCol()
|
||||
if (_lazyContent.value) {
|
||||
yanchiDuration.value = false
|
||||
}
|
||||
/**
|
||||
* 变量控制打开状态
|
||||
* 等同v-model:model-show
|
||||
*/
|
||||
emit("update:modelShow", false)
|
||||
cancelResetDataCol()
|
||||
if (_lazyContent.value) {
|
||||
yanchiDuration.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function onOpen() {
|
||||
yanchiDuration.value = true
|
||||
yanchiDuration.value = true
|
||||
}
|
||||
|
||||
function onCancel() {
|
||||
emit('cancel')
|
||||
cancelResetDataCol()
|
||||
emit("cancel")
|
||||
show.value = false
|
||||
cancelResetDataCol()
|
||||
}
|
||||
|
||||
function cancelResetDataCol() {
|
||||
nowValue.value = nowModelValue.value.slice(0)
|
||||
nowValue.value = nowModelValue.value.slice(0)
|
||||
}
|
||||
|
||||
function coverStrVal(): string {
|
||||
let estrt = nowValue.value[0]
|
||||
let eend = nowValue.value[1]
|
||||
let start = estrt === '' ? '' : (new tmDate(estrt)).format(props.format)
|
||||
let ebd = eend === '' ? '' : (new tmDate(eend)).format(props.format)
|
||||
return start + '~' + ebd
|
||||
let estrt = nowValue.value[0]
|
||||
let eend = nowValue.value[1]
|
||||
let start = estrt === "" ? "" : new tmDate(estrt).format(props.format)
|
||||
let ebd = eend === "" ? "" : new tmDate(eend).format(props.format)
|
||||
return start + "~" + ebd
|
||||
}
|
||||
|
||||
function onConfirm() {
|
||||
let str = coverStrVal()
|
||||
let tmdate: string[] = []
|
||||
if (nowValue.value[0] !== '' && nowValue.value[1] !== '') {
|
||||
tmdate = nowValue.value.slice(0)
|
||||
nowModelValue.value = tmdate
|
||||
}
|
||||
/**
|
||||
* 点击确认时同步。等同v-model
|
||||
*/
|
||||
emit('update:modelValue', tmdate)
|
||||
let str = coverStrVal()
|
||||
let tmdate: string[] = []
|
||||
if (nowValue.value[0] !== "" && nowValue.value[1] !== "") {
|
||||
tmdate = nowValue.value.slice(0)
|
||||
nowModelValue.value = tmdate
|
||||
}
|
||||
/**
|
||||
* 点击确认时同步。等同v-model
|
||||
*/
|
||||
emit("update:modelValue", tmdate)
|
||||
|
||||
/**
|
||||
* 经格式化后的值。等同v-model:model-str
|
||||
*/
|
||||
emit('update:modelStr', str === '~' ? '' : str)
|
||||
/**
|
||||
* 经格式化后的值。等同v-model:model-str
|
||||
*/
|
||||
emit("update:modelStr", str === "~" ? "" : str)
|
||||
|
||||
emit('confirm', tmdate)
|
||||
emit("confirm", tmdate)
|
||||
|
||||
show.value = false
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<view @click="openShow">
|
||||
<!--
|
||||
<view @click="openShow">
|
||||
<!--
|
||||
@slot 插槽,默认触发打开选择器。你的默认布局可以放置在这里。
|
||||
-->
|
||||
<slot></slot>
|
||||
</view>
|
||||
<tm-drawer @open="onOpen" :widthCoverCenter="true" :disabledScroll="true" @close="onClose" @confirm="onConfirm"
|
||||
@cancel="onCancel" :showFooter="true" v-model:show="show" :size="drawerSize" :showClose="false">
|
||||
<template v-slot:title>
|
||||
<view
|
||||
style="padding: 0 20px;flex:1;display: flex;flex-direction: row;justify-content: space-between;align-items: center;height: 100%;">
|
||||
<tm-text>{{ title }}</tm-text>
|
||||
<tm-text @click="clearDate" style="opacity: 0.5;">清空</tm-text>
|
||||
</view>
|
||||
</template>
|
||||
<view v-if="yanchiDuration" class="tmPickerDateWrap">
|
||||
<view v-if="quicklist.length > 0" class="tmPickerDateWrapQuickTags">
|
||||
<tm-tag font-size="26" :font-color="(_isDark ? 'white' : '')" @click="tagsClick(item)" skin='thin'
|
||||
size="m" style="margin-right:10px;margin-bottom: 5px;" v-for="(item, index) in quicklist"
|
||||
:key="index">{{
|
||||
item.str }}</tm-tag>
|
||||
</view>
|
||||
<view v-if="quicklist.length > 0" style="height: 8px;"></view>
|
||||
<view class="tmPickerDateWrapQuickInput">
|
||||
<view @click="inputClick(0)" style="flex:1;height: 40px;">
|
||||
<input :placeholder-style="_placeStyle"
|
||||
:style="{ color: changeIndex == 0 ? _activeBorderColor : _fontColor, border: `2px solid ${changeIndex == 0 ? _activeBorderColor : _borderColor}`, backgroundColor: _backgroundColor }"
|
||||
class="tmPickerInput" :disabled="true" :value="_start_date_str_format" />
|
||||
</view>
|
||||
<tm-text style="width: 64px;text-align: center;">至</tm-text>
|
||||
<view @click="inputClick(1)" style="flex:1;height: 40px;">
|
||||
<input :placeholder-style="_placeStyle"
|
||||
:style="{ color: changeIndex == 1 ? _activeBorderColor : _fontColor, border: `2px solid ${changeIndex == 1 ? _activeBorderColor : _borderColor}`, backgroundColor: _backgroundColor }"
|
||||
class="tmPickerInput" :disabled="true" :value="_end_date_str_format" />
|
||||
</view>
|
||||
</view>
|
||||
<tm-date-view v-if="show" @change="dateChangeView" :format="format" :type="type" :cell-units="cellUnits"
|
||||
:start="_start_date_str" :end="_end_date_str" :model-value='nowValue[changeIndex]'></tm-date-view>
|
||||
</view>
|
||||
<tm-icon v-if="!yanchiDuration" size="42" spin name="loader-line"></tm-icon>
|
||||
</tm-drawer>
|
||||
<slot></slot>
|
||||
</view>
|
||||
<tm-drawer
|
||||
@open="onOpen"
|
||||
:widthCoverCenter="true"
|
||||
:disabledScroll="true"
|
||||
@close="onClose"
|
||||
:showFooter="true"
|
||||
v-model:show="show"
|
||||
:size="drawerSize"
|
||||
:showClose="false"
|
||||
>
|
||||
<template v-slot:title>
|
||||
<view
|
||||
style="
|
||||
padding: 0 20px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
"
|
||||
>
|
||||
<tm-text>{{ title }}</tm-text>
|
||||
<tm-text @click="clearDate" style="opacity: 0.5">清空</tm-text>
|
||||
</view>
|
||||
</template>
|
||||
<view v-if="yanchiDuration" class="tmPickerDateWrap">
|
||||
<view v-if="quicklist.length > 0" class="tmPickerDateWrapQuickTags">
|
||||
<tm-tag
|
||||
font-size="26"
|
||||
:font-color="_isDark ? 'white' : ''"
|
||||
@click="tagsClick(item)"
|
||||
skin="thin"
|
||||
size="m"
|
||||
style="margin-right: 10px; margin-bottom: 5px"
|
||||
v-for="(item, index) in quicklist"
|
||||
:key="index"
|
||||
>{{ item.str }}</tm-tag
|
||||
>
|
||||
</view>
|
||||
<view v-if="quicklist.length > 0" style="height: 8px"></view>
|
||||
<view class="tmPickerDateWrapQuickInput">
|
||||
<view @click="inputClick(0)" style="flex: 1; height: 40px">
|
||||
<input
|
||||
:placeholder-style="_placeStyle"
|
||||
:style="{
|
||||
color: changeIndex == 0 ? _activeBorderColor : _fontColor,
|
||||
border: `2px solid ${changeIndex == 0 ? _activeBorderColor : _borderColor}`,
|
||||
backgroundColor: _backgroundColor,
|
||||
}"
|
||||
class="tmPickerInput"
|
||||
:disabled="true"
|
||||
:value="_start_date_str_format"
|
||||
/>
|
||||
</view>
|
||||
<tm-text style="width: 64px; text-align: center">至</tm-text>
|
||||
<view @click="inputClick(1)" style="flex: 1; height: 40px">
|
||||
<input
|
||||
:placeholder-style="_placeStyle"
|
||||
:style="{
|
||||
color: changeIndex == 1 ? _activeBorderColor : _fontColor,
|
||||
border: `2px solid ${changeIndex == 1 ? _activeBorderColor : _borderColor}`,
|
||||
backgroundColor: _backgroundColor,
|
||||
}"
|
||||
class="tmPickerInput"
|
||||
:disabled="true"
|
||||
:value="_end_date_str_format"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<tm-date-view
|
||||
v-if="show"
|
||||
@change="dateChangeView"
|
||||
:format="format"
|
||||
:type="type"
|
||||
:cell-units="cellUnits"
|
||||
:start="_start_date_str"
|
||||
:end="_end_date_str"
|
||||
:model-value="nowValue[changeIndex]"
|
||||
></tm-date-view>
|
||||
</view>
|
||||
<tm-icon v-if="!yanchiDuration" size="42" spin name="loader-line"></tm-icon>
|
||||
|
||||
<template #footer>
|
||||
<view class="flex px-4">
|
||||
<tm-button @click="onCancel" :block="true" skin="thin">取消</tm-button>
|
||||
|
||||
<tm-button @click="onConfirm" :block="true">确认</tm-button>
|
||||
</view>
|
||||
</template>
|
||||
</tm-drawer>
|
||||
</template>
|
||||
<style scoped>
|
||||
.tmPickerDateText {
|
||||
text-align: left;
|
||||
transition-duration: 350ms;
|
||||
transition-timing-function: linear;
|
||||
transition-property: transform, opacity;
|
||||
transform: translateY(100%) scale(0);
|
||||
opacity: 0;
|
||||
|
||||
text-align: left;
|
||||
transition-duration: 350ms;
|
||||
transition-timing-function: linear;
|
||||
transition-property: transform, opacity;
|
||||
transform: translateY(100%) scale(0);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.tmPickerDateWrapQuickInputPlackeTips {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
pointer-events: none;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tmPickerInput {
|
||||
border-radius: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 80rpx;
|
||||
height: 80rpx;
|
||||
|
||||
padding: 0 20rpx;
|
||||
font-size: 30rpx;
|
||||
flex: 1;
|
||||
pointer-events: none;
|
||||
text-align: center;
|
||||
padding: 0 20rpx;
|
||||
font-size: 30rpx;
|
||||
flex: 1;
|
||||
pointer-events: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tmPickerDateWrapQuickInput {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.tmPickerDateWrapQuickTags {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 16rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,74 +1,89 @@
|
||||
<template>
|
||||
<!-- @vue-ignore -->
|
||||
<view @click="onclick" :hover-start-time="_isLinksHover ? 50 : 0" :hover-stay-time="_isLinksHover ? 100 : 0"
|
||||
:hover-class="_isLinksHover ? 'cellHover' : ''" class="tmCell "
|
||||
:class="[_allAttr.card == true ? 'cellCard' : 'cardInset']" :style="{
|
||||
backgroundColor: _color,
|
||||
borderRadius: _cardRadius,
|
||||
minHeight: _minHeight,
|
||||
borderBottom: _allAttr.bottom && !_allAttr.card && !bottomBorderInsert ? `1px solid ${_bottomBorderColor}` : 'none',
|
||||
padding: `0px ${_lrPadding}`
|
||||
}">
|
||||
|
||||
<view v-if="_icon != ''" class="tmCellAvatar"
|
||||
:style="{ width: _leftSize, height: _leftSize, borderRadius: _avatarRound }">
|
||||
<!--
|
||||
<!-- @vue-ignore -->
|
||||
<view
|
||||
@click="onclick"
|
||||
:hover-start-time="_isLinksHover ? 50 : 0"
|
||||
:hover-stay-time="_isLinksHover ? 100 : 0"
|
||||
:hover-class="_isLinksHover ? 'cellHover' : ''"
|
||||
class="tmCell"
|
||||
:class="[_allAttr.card == true ? 'cellCard' : 'cardInset']"
|
||||
:style="{
|
||||
backgroundColor: _color,
|
||||
borderRadius: _cardRadius,
|
||||
minHeight: _minHeight,
|
||||
borderBottom: _allAttr.bottom && !_allAttr.card && !bottomBorderInsert ? `1px solid ${_bottomBorderColor}` : 'none',
|
||||
padding: `0px ${_lrPadding}`,
|
||||
}"
|
||||
>
|
||||
<view v-if="_icon != ''" class="tmCellAvatar" :style="{ width: _leftSize, height: _leftSize, borderRadius: _avatarRound }">
|
||||
<!--
|
||||
@slot 头像图标
|
||||
@binding {string} icon 图标名称
|
||||
-->
|
||||
<slot name="avatar" :icon="_icon">
|
||||
<tm-icon :color="_allAttr.iconColor" :size="_iconSize" :name="_icon"></tm-icon>
|
||||
</slot>
|
||||
</view>
|
||||
<slot name="avatar" :icon="_icon">
|
||||
<tm-icon :color="_allAttr.iconColor" :size="_iconSize" :name="_icon"></tm-icon>
|
||||
</slot>
|
||||
</view>
|
||||
|
||||
<view class="tmCellWrap" :style="{
|
||||
padding: `${_tbPadding} 0px `,
|
||||
borderBottom: _allAttr.bottom && !_allAttr.card && bottomBorderInsert ? `1px solid ${_bottomBorderColor}` : 'none'
|
||||
}">
|
||||
<view class="center">
|
||||
<!--
|
||||
<view
|
||||
class="tmCellWrap"
|
||||
:style="{
|
||||
padding: `${_tbPadding} 0px `,
|
||||
borderBottom: _allAttr.bottom && !_allAttr.card && bottomBorderInsert ? `1px solid ${_bottomBorderColor}` : 'none',
|
||||
}"
|
||||
>
|
||||
<view class="center">
|
||||
<!--
|
||||
@slot 默认标题插槽
|
||||
-->
|
||||
<slot>
|
||||
<text class="title" :style="{ color: _titleColor, fontSize: _titleSize }">{{ _allAttr.title
|
||||
}}</text>
|
||||
</slot>
|
||||
<!--
|
||||
<slot>
|
||||
<text class="title" :style="{ color: _titleColor, fontSize: _titleSize }">{{ _allAttr.title }}</text>
|
||||
</slot>
|
||||
<!--
|
||||
@slot 简介
|
||||
@binding {string} desc 简介
|
||||
-->
|
||||
<slot name="desc" :desc="_allAttr.desc">
|
||||
<tm-text v-if="_allAttr.desc != ''" size="28" color='#bfbfbf' dark-color='#bfbfbf' class="desc">{{
|
||||
_allAttr.desc }}</tm-text>
|
||||
</slot>
|
||||
</view>
|
||||
<view class="tmCellRight">
|
||||
<!--
|
||||
<slot name="desc" :desc="_allAttr.desc">
|
||||
<tm-text v-if="_allAttr.desc != ''" size="28" color="#bfbfbf" dark-color="#bfbfbf" class="desc">{{ _allAttr.desc }}</tm-text>
|
||||
</slot>
|
||||
</view>
|
||||
<view class="tmCellRight">
|
||||
<!--
|
||||
@slot 右边文字
|
||||
@binding {string} label 标签内容
|
||||
-->
|
||||
<slot name="label" :label="_allAttr.label">
|
||||
<text v-if="_allAttr.label != ''" :style="{ color: _allAttr.labelColor, fontSize: _rightLableSize }"
|
||||
class="rightLabel">{{ _allAttr.label }}</text>
|
||||
|
||||
</slot>
|
||||
<!--
|
||||
<slot name="label" :label="_allAttr.label">
|
||||
<text v-if="_allAttr.label != ''" :style="{ color: _allAttr.labelColor, fontSize: _rightLableSize }" class="rightLabel">{{
|
||||
_allAttr.label
|
||||
}}</text>
|
||||
</slot>
|
||||
<!--
|
||||
@slot 右插槽
|
||||
-->
|
||||
<slot name="right"></slot>
|
||||
<tm-icon v-if="_allAttr.url != '' || _allAttr.link" color="#bfbfbf" size="36" :name="attrs.linkIcon"
|
||||
_style="paddingLeft:12rpx"></tm-icon>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<slot name="right"></slot>
|
||||
<tm-icon
|
||||
v-if="_allAttr.url != '' || _allAttr.link"
|
||||
color="#bfbfbf"
|
||||
size="36"
|
||||
:name="attrs.linkIcon"
|
||||
_style="paddingLeft:12rpx"
|
||||
></tm-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, onMounted, PropType } from "vue"
|
||||
import { arrayNumberValid, arrayNumberValidByStyleMP, covetUniNumber, arrayNumberValidByStyleBorderColor, linearValid, getUnit } from "../../libs/tool";
|
||||
import { getDefaultColor, getDefaultColorObj, getOutlineColorObj, getTextColorObj, getThinColorObj } from "../../libs/colors";
|
||||
import { useTmConfig } from "../../libs/config";
|
||||
import { computed, ref, onMounted } from "vue"
|
||||
import {
|
||||
arrayNumberValid,
|
||||
arrayNumberValidByStyleMP,
|
||||
covetUniNumber,
|
||||
arrayNumberValidByStyleBorderColor,
|
||||
linearValid,
|
||||
getUnit,
|
||||
} from "../../libs/tool"
|
||||
import { getDefaultColor, getDefaultColorObj, getOutlineColorObj, getTextColorObj, getThinColorObj } from "../../libs/colors"
|
||||
import { useTmConfig } from "../../libs/config"
|
||||
/**
|
||||
* @displayName 列表
|
||||
* @exportName tm-cell
|
||||
@@ -79,233 +94,231 @@ import { useTmConfig } from "../../libs/config";
|
||||
| --- | --- | --- | --- |
|
||||
| ☑️| ☑️ | ☑️ | ☑️ | ☑️ | 1.0.0 |
|
||||
*/
|
||||
defineOptions({ name: 'TmCell' });
|
||||
defineOptions({ name: "TmCell" })
|
||||
const { config } = useTmConfig()
|
||||
type tmCellItemType = {
|
||||
icon: string,
|
||||
title: string,
|
||||
desc: string,
|
||||
label: string,
|
||||
bottom: boolean,
|
||||
link: boolean,
|
||||
url: string,
|
||||
iconColor: string,
|
||||
labelColor: string,
|
||||
card: boolean
|
||||
icon: string
|
||||
title: string
|
||||
desc: string
|
||||
label: string
|
||||
bottom: boolean
|
||||
link: boolean
|
||||
url: string
|
||||
iconColor: string
|
||||
labelColor: string
|
||||
card: boolean
|
||||
}
|
||||
const emits = defineEmits(
|
||||
[
|
||||
/**
|
||||
* 项目点击
|
||||
*/
|
||||
"click"
|
||||
]
|
||||
)
|
||||
const emits = defineEmits([
|
||||
/**
|
||||
* 项目点击
|
||||
*/
|
||||
"click",
|
||||
])
|
||||
const attrs = defineProps({
|
||||
/**
|
||||
* 左图标
|
||||
*/
|
||||
icon: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
/**
|
||||
* 左侧图标、头像圆角。默认为8
|
||||
*/
|
||||
avatarRound: {
|
||||
type: String,
|
||||
default: "8"
|
||||
},
|
||||
/**
|
||||
* 背景的主题色
|
||||
*/
|
||||
color: {
|
||||
type: String,
|
||||
default: 'white'
|
||||
},
|
||||
/**
|
||||
* 暗黑背景的主题色,空值时取sheetDarkColor
|
||||
*/
|
||||
darkColor: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
/**
|
||||
* 图标色,空值时取全局主题值。
|
||||
*/
|
||||
iconColor: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
title: {
|
||||
type: String,
|
||||
default: "标题"
|
||||
},
|
||||
/**
|
||||
* 标题颜色
|
||||
*/
|
||||
titleColor: {
|
||||
type: String,
|
||||
default: "black"
|
||||
},
|
||||
/**
|
||||
* 暗黑标题颜色,如果不填写取白
|
||||
*/
|
||||
darkTitleColor: {
|
||||
type: String,
|
||||
default: "white"
|
||||
},
|
||||
/**
|
||||
* 标题大小
|
||||
*/
|
||||
titleSize: {
|
||||
type: [String, Number],
|
||||
default: "32"
|
||||
},
|
||||
/**
|
||||
* 左边图标大小
|
||||
*/
|
||||
iconSize: {
|
||||
type: [String, Number],
|
||||
default: "42"
|
||||
},
|
||||
/**
|
||||
* 右边文本
|
||||
*/
|
||||
label: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
/**
|
||||
* 右边文本颜色
|
||||
*/
|
||||
labelColor: {
|
||||
type: String,
|
||||
default: "#bfbfbf"
|
||||
},
|
||||
/**
|
||||
* 右侧label文字大小
|
||||
*/
|
||||
labelSize: {
|
||||
type: [String, Number],
|
||||
default: "24"
|
||||
},
|
||||
/**
|
||||
* 标题正文的简介文本
|
||||
*/
|
||||
desc: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
/**
|
||||
* 是否显示下边线
|
||||
*/
|
||||
showBottomBorder: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
/**
|
||||
* 是否让下边线显示居右,不贯穿到左边。
|
||||
*/
|
||||
bottomBorderInsert: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* 下边线的颜色。如果你设定了的话。
|
||||
* 暗黑的边颜色失效,采用你自定的颜色。
|
||||
*/
|
||||
bottomBorderColor: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
/**
|
||||
* 是否显示链接状态,有点按效果。包括出现右边跳转指示。
|
||||
* 关闭的话,事件反应和跳转会更快。
|
||||
* 如果true右侧箭头图标会显示
|
||||
*/
|
||||
link: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
/**
|
||||
* 需要跳转的页面地址。
|
||||
* 如果填写了右侧箭头图标会显示
|
||||
*/
|
||||
url: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
openType: {
|
||||
type: String as PropType<"navigate" | "redirect" | "switchTab" | "reLaunch" | "navigateBack" | "exit">,
|
||||
default: "navigate"
|
||||
},
|
||||
/**
|
||||
* 是否是卡片模式
|
||||
*/
|
||||
card: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
/**
|
||||
* 卡片模式圆角,不填写采用全局的cardRadius属性值.
|
||||
*/
|
||||
round: {
|
||||
type: [String, Number],
|
||||
default: ""
|
||||
},
|
||||
/**
|
||||
* 左边图标区域宽和高的大小。
|
||||
*/
|
||||
leftSize: {
|
||||
type: [String, Number],
|
||||
default: '60'
|
||||
},
|
||||
/**
|
||||
* 最小高度,主要是用来统一风格高度不至于让点击范围过小
|
||||
* 如果你需要紧凑型可以设置为auto
|
||||
*/
|
||||
minHeight: {
|
||||
type: [String, Number],
|
||||
default: "88"
|
||||
},
|
||||
/**
|
||||
* 左右的间隙。
|
||||
*/
|
||||
lrPadding: {
|
||||
type: [String, Number],
|
||||
default: "32"
|
||||
},
|
||||
linkIcon: {
|
||||
type: String,
|
||||
default: "arrow-right-s-line"
|
||||
},
|
||||
/**
|
||||
* 上下间隙
|
||||
*/
|
||||
tbPadding: {
|
||||
type: [String, Number],
|
||||
default: "32"
|
||||
}
|
||||
/**
|
||||
* 左图标
|
||||
*/
|
||||
icon: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
/**
|
||||
* 左侧图标、头像圆角。默认为8
|
||||
*/
|
||||
avatarRound: {
|
||||
type: String,
|
||||
default: "8",
|
||||
},
|
||||
/**
|
||||
* 背景的主题色
|
||||
*/
|
||||
color: {
|
||||
type: String,
|
||||
default: "white",
|
||||
},
|
||||
/**
|
||||
* 暗黑背景的主题色,空值时取sheetDarkColor
|
||||
*/
|
||||
darkColor: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
/**
|
||||
* 图标色,空值时取全局主题值。
|
||||
*/
|
||||
iconColor: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
title: {
|
||||
type: String,
|
||||
default: "标题",
|
||||
},
|
||||
/**
|
||||
* 标题颜色
|
||||
*/
|
||||
titleColor: {
|
||||
type: String,
|
||||
default: "black",
|
||||
},
|
||||
/**
|
||||
* 暗黑标题颜色,如果不填写取白
|
||||
*/
|
||||
darkTitleColor: {
|
||||
type: String,
|
||||
default: "white",
|
||||
},
|
||||
/**
|
||||
* 标题大小
|
||||
*/
|
||||
titleSize: {
|
||||
type: [String, Number],
|
||||
default: "32",
|
||||
},
|
||||
/**
|
||||
* 左边图标大小
|
||||
*/
|
||||
iconSize: {
|
||||
type: [String, Number],
|
||||
default: "42",
|
||||
},
|
||||
/**
|
||||
* 右边文本
|
||||
*/
|
||||
label: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
/**
|
||||
* 右边文本颜色
|
||||
*/
|
||||
labelColor: {
|
||||
type: String,
|
||||
default: "#bfbfbf",
|
||||
},
|
||||
/**
|
||||
* 右侧label文字大小
|
||||
*/
|
||||
labelSize: {
|
||||
type: [String, Number],
|
||||
default: "24",
|
||||
},
|
||||
/**
|
||||
* 标题正文的简介文本
|
||||
*/
|
||||
desc: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
/**
|
||||
* 是否显示下边线
|
||||
*/
|
||||
showBottomBorder: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/**
|
||||
* 是否让下边线显示居右,不贯穿到左边。
|
||||
*/
|
||||
bottomBorderInsert: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* 下边线的颜色。如果你设定了的话。
|
||||
* 暗黑的边颜色失效,采用你自定的颜色。
|
||||
*/
|
||||
bottomBorderColor: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
/**
|
||||
* 是否显示链接状态,有点按效果。包括出现右边跳转指示。
|
||||
* 关闭的话,事件反应和跳转会更快。
|
||||
* 如果true右侧箭头图标会显示
|
||||
*/
|
||||
link: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/**
|
||||
* 需要跳转的页面地址。
|
||||
* 如果填写了右侧箭头图标会显示
|
||||
*/
|
||||
url: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
openType: {
|
||||
type: String,
|
||||
default: "navigate",
|
||||
},
|
||||
/**
|
||||
* 是否是卡片模式
|
||||
*/
|
||||
card: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/**
|
||||
* 卡片模式圆角,不填写采用全局的cardRadius属性值.
|
||||
*/
|
||||
round: {
|
||||
type: [String, Number],
|
||||
default: "",
|
||||
},
|
||||
/**
|
||||
* 左边图标区域宽和高的大小。
|
||||
*/
|
||||
leftSize: {
|
||||
type: [String, Number],
|
||||
default: "60",
|
||||
},
|
||||
/**
|
||||
* 最小高度,主要是用来统一风格高度不至于让点击范围过小
|
||||
* 如果你需要紧凑型可以设置为auto
|
||||
*/
|
||||
minHeight: {
|
||||
type: [String, Number],
|
||||
default: "88",
|
||||
},
|
||||
/**
|
||||
* 左右的间隙。
|
||||
*/
|
||||
lrPadding: {
|
||||
type: [String, Number],
|
||||
default: "32",
|
||||
},
|
||||
linkIcon: {
|
||||
type: String,
|
||||
default: "arrow-right-s-line",
|
||||
},
|
||||
/**
|
||||
* 上下间隙
|
||||
*/
|
||||
tbPadding: {
|
||||
type: [String, Number],
|
||||
default: "32",
|
||||
},
|
||||
})
|
||||
|
||||
const _color = computed(() => {
|
||||
if (config.mode === 'dark') {
|
||||
if (attrs.darkColor !== '') return getDefaultColor(attrs.darkColor)
|
||||
return getDefaultColor(config.sheetDarkColor)
|
||||
}
|
||||
return getDefaultColor(attrs.color)
|
||||
if (config.mode === "dark") {
|
||||
if (attrs.darkColor !== "") return getDefaultColor(attrs.darkColor)
|
||||
return getDefaultColor(config.sheetDarkColor)
|
||||
}
|
||||
return getDefaultColor(attrs.color)
|
||||
})
|
||||
|
||||
const _titleColor = computed(() => {
|
||||
if (config.mode === 'dark') {
|
||||
if (attrs.darkTitleColor !== '') return getDefaultColor(attrs.darkTitleColor)
|
||||
return '#ffffff'
|
||||
}
|
||||
return getDefaultColor(attrs.titleColor)
|
||||
if (config.mode === "dark") {
|
||||
if (attrs.darkTitleColor !== "") return getDefaultColor(attrs.darkTitleColor)
|
||||
return "#ffffff"
|
||||
}
|
||||
return getDefaultColor(attrs.titleColor)
|
||||
})
|
||||
|
||||
const _leftSize = computed(() => covetUniNumber(attrs.leftSize))
|
||||
@@ -317,189 +330,183 @@ const _avatarRound = computed(() => covetUniNumber(attrs.avatarRound))
|
||||
const _minHeight = computed(() => covetUniNumber(attrs.minHeight))
|
||||
|
||||
const _bottomBorderColor = computed(() => {
|
||||
if (attrs.bottomBorderColor !== '') return getDefaultColor(attrs.bottomBorderColor)
|
||||
if (config.mode === 'dark') return config.borderDarkColor
|
||||
return "#f5f5f5"
|
||||
if (attrs.bottomBorderColor !== "") return getDefaultColor(attrs.bottomBorderColor)
|
||||
if (config.mode === "dark") return config.borderDarkColor
|
||||
return "#f5f5f5"
|
||||
})
|
||||
|
||||
const icon = ref('')
|
||||
const icon = ref("")
|
||||
|
||||
const _allAttr = computed(() => {
|
||||
let iconColor = attrs.iconColor;
|
||||
if (iconColor === '') {
|
||||
iconColor = config.color;
|
||||
}
|
||||
let p = {
|
||||
icon: icon.value,
|
||||
title: attrs.title,
|
||||
desc: attrs.desc,
|
||||
label: attrs.label,
|
||||
bottom: attrs.showBottomBorder,
|
||||
link: attrs.link,
|
||||
url: attrs.url,
|
||||
iconColor: getDefaultColor(iconColor),
|
||||
labelColor: getDefaultColor(attrs.labelColor),
|
||||
card: attrs.card
|
||||
} as tmCellItemType
|
||||
return p
|
||||
let iconColor = attrs.iconColor
|
||||
if (iconColor === "") {
|
||||
iconColor = config.color
|
||||
}
|
||||
let p = {
|
||||
icon: icon.value,
|
||||
title: attrs.title,
|
||||
desc: attrs.desc,
|
||||
label: attrs.label,
|
||||
bottom: attrs.showBottomBorder,
|
||||
link: attrs.link,
|
||||
url: attrs.url,
|
||||
iconColor: getDefaultColor(iconColor),
|
||||
labelColor: getDefaultColor(attrs.labelColor),
|
||||
card: attrs.card,
|
||||
} as tmCellItemType
|
||||
return p
|
||||
})
|
||||
|
||||
const _cardRadius = computed(() => {
|
||||
if (attrs.round === '') return arrayNumberValidByStyleMP(config.cellRadius)
|
||||
return arrayNumberValidByStyleMP(attrs.round, config.unit)
|
||||
if (attrs.round === "") return arrayNumberValidByStyleMP(config.cellRadius)
|
||||
return arrayNumberValidByStyleMP(attrs.round, config.unit)
|
||||
})
|
||||
|
||||
const _titleSize = computed(() => {
|
||||
let fontSize = covetUniNumber(attrs.titleSize, config.unit);
|
||||
if (config.fontSizeScale === 1) return fontSize;
|
||||
let sizeNumber = parseInt(fontSize)
|
||||
if (isNaN(sizeNumber)) {
|
||||
sizeNumber = 16
|
||||
}
|
||||
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
|
||||
let fontSize = covetUniNumber(attrs.titleSize, config.unit)
|
||||
if (config.fontSizeScale === 1) return fontSize
|
||||
let sizeNumber = parseInt(fontSize)
|
||||
if (isNaN(sizeNumber)) {
|
||||
sizeNumber = 16
|
||||
}
|
||||
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
|
||||
})
|
||||
|
||||
const _iconSize = computed(() => {
|
||||
let fontSize = covetUniNumber(attrs.iconSize, config.unit);
|
||||
if (config.fontSizeScale === 1) return fontSize;
|
||||
let sizeNumber = parseInt(fontSize)
|
||||
if (isNaN(sizeNumber)) {
|
||||
sizeNumber = 17
|
||||
}
|
||||
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
|
||||
let fontSize = covetUniNumber(attrs.iconSize, config.unit)
|
||||
if (config.fontSizeScale === 1) return fontSize
|
||||
let sizeNumber = parseInt(fontSize)
|
||||
if (isNaN(sizeNumber)) {
|
||||
sizeNumber = 17
|
||||
}
|
||||
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
|
||||
})
|
||||
|
||||
const _rightLableSize = computed(() => {
|
||||
let fontSize = covetUniNumber(attrs.labelSize, config.unit);
|
||||
let fontSize = covetUniNumber(attrs.labelSize, config.unit)
|
||||
|
||||
if (config.fontSizeScale === 1) return fontSize;
|
||||
let sizeNumber = parseInt(fontSize)
|
||||
if (isNaN(sizeNumber)) {
|
||||
sizeNumber = 13
|
||||
}
|
||||
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
|
||||
if (config.fontSizeScale === 1) return fontSize
|
||||
let sizeNumber = parseInt(fontSize)
|
||||
if (isNaN(sizeNumber)) {
|
||||
sizeNumber = 13
|
||||
}
|
||||
return (sizeNumber * config.fontSizeScale).toString() + getUnit(fontSize)
|
||||
})
|
||||
|
||||
const _isLinksHover = computed(() => attrs.link)
|
||||
const _icon = computed(() => attrs.icon)
|
||||
|
||||
const onclick = () => {
|
||||
/**
|
||||
* 整个列表被点击
|
||||
*/
|
||||
emits("click");
|
||||
if (attrs.url != "") {
|
||||
if (attrs.openType == 'navigate') {
|
||||
uni.navigateTo({
|
||||
url: attrs.url
|
||||
})
|
||||
} else if (attrs.openType == 'navigateBack') {
|
||||
uni.navigateBack({})
|
||||
} else if (attrs.openType == 'reLaunch') {
|
||||
uni.reLaunch({
|
||||
url: attrs.url
|
||||
})
|
||||
} else if (attrs.openType == 'redirect') {
|
||||
uni.redirectTo({
|
||||
url: attrs.url
|
||||
})
|
||||
} else if (attrs.openType == 'switchTab') {
|
||||
uni.switchTab({
|
||||
url: attrs.url
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 整个列表被点击
|
||||
*/
|
||||
emits("click")
|
||||
if (attrs.url != "") {
|
||||
if (attrs.openType == "navigate") {
|
||||
uni.navigateTo({
|
||||
url: attrs.url,
|
||||
})
|
||||
} else if (attrs.openType == "navigateBack") {
|
||||
uni.navigateBack({})
|
||||
} else if (attrs.openType == "reLaunch") {
|
||||
uni.reLaunch({
|
||||
url: attrs.url,
|
||||
})
|
||||
} else if (attrs.openType == "redirect") {
|
||||
uni.redirectTo({
|
||||
url: attrs.url,
|
||||
})
|
||||
} else if (attrs.openType == "switchTab") {
|
||||
uni.switchTab({
|
||||
url: attrs.url,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
options: {
|
||||
styleIsolation: "apply-shared",
|
||||
virtualHost: true,
|
||||
addGlobalClass: true,
|
||||
multipleSlots: true,
|
||||
},
|
||||
};
|
||||
options: {
|
||||
styleIsolation: "apply-shared",
|
||||
virtualHost: true,
|
||||
addGlobalClass: true,
|
||||
multipleSlots: true,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.cellHover {
|
||||
filter: contrast(90%);
|
||||
filter: contrast(90%);
|
||||
}
|
||||
|
||||
.tmCell {
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cardInset {
|
||||
// padding: 0 32rpx;
|
||||
// padding: 0 32rpx;
|
||||
}
|
||||
|
||||
.cellCard {
|
||||
// padding: 0 32rpx;
|
||||
margin-bottom: 12rpx;
|
||||
margin-left: 24rpx;
|
||||
margin-right: 24rpx;
|
||||
// padding: 0 32rpx;
|
||||
margin-bottom: 12rpx;
|
||||
margin-left: 24rpx;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
|
||||
.tmCellWrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
// padding: 32rpx 0rpx;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
// padding: 32rpx 0rpx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.title {
|
||||
line-clamp: 2;
|
||||
display: -webkit-box;
|
||||
text-overflow: ellipsis;
|
||||
flex: 1;
|
||||
line-clamp: 2;
|
||||
display: -webkit-box;
|
||||
text-overflow: ellipsis;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 24rpx;
|
||||
padding-top: 4rpx;
|
||||
font-size: 24rpx;
|
||||
padding-top: 4rpx;
|
||||
}
|
||||
|
||||
.tmCellAvatar {
|
||||
margin-right: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
margin-right: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.center {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.tmCellRight {
|
||||
padding-left: 32rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding-left: 32rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.rightLabel {
|
||||
line-clamp: 1;
|
||||
display: -webkit-box;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 24rpx;
|
||||
text-align: right;
|
||||
max-width: 200rpx;
|
||||
line-clamp: 1;
|
||||
display: -webkit-box;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 24rpx;
|
||||
text-align: right;
|
||||
max-width: 200rpx;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,48 +1,48 @@
|
||||
import path from "path";
|
||||
import path from "path"
|
||||
|
||||
import { defineConfig, loadEnv } from "vite";
|
||||
import uni from "@dcloudio/vite-plugin-uni";
|
||||
import Unocss from "unocss/vite";
|
||||
import { defineConfig, loadEnv } from "vite"
|
||||
import uni from "@dcloudio/vite-plugin-uni"
|
||||
import Unocss from "unocss/vite"
|
||||
|
||||
import { useRouter } from "./src/sheep";
|
||||
import { useRouter } from "./src/sheep"
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
const { NODE_ENV, VITE_APP_DEV_SERVICE, VITE_APP_PROD_SERVICE, VITE_IMAGE_BASE_PATH } = loadEnv(mode, process.cwd(), "");
|
||||
const baseUrl = NODE_ENV == "development" ? VITE_APP_DEV_SERVICE : VITE_APP_PROD_SERVICE;
|
||||
return {
|
||||
build: {
|
||||
target: "es6",
|
||||
},
|
||||
plugins: [
|
||||
uni(),
|
||||
Unocss(),
|
||||
{
|
||||
...useRouter({
|
||||
pagesJsonDir: path.resolve(__dirname, "./src/pages.json"),
|
||||
includes: ["meta"],
|
||||
}),
|
||||
enforce: "post",
|
||||
},
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
"@@": path.resolve(__dirname, "./src/sheep"),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
host: "0.0.0.0",
|
||||
port: 8888,
|
||||
hmr: true,
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: baseUrl,
|
||||
ws: true,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, ""),
|
||||
},
|
||||
},
|
||||
},
|
||||
define: {},
|
||||
};
|
||||
});
|
||||
const { NODE_ENV, VITE_APP_DEV_SERVICE, VITE_APP_PROD_SERVICE, VITE_IMAGE_DEV_PATH } = loadEnv(mode, process.cwd(), "")
|
||||
const baseUrl = NODE_ENV == "development" ? VITE_APP_DEV_SERVICE : VITE_APP_PROD_SERVICE
|
||||
return {
|
||||
build: {
|
||||
target: "es6",
|
||||
},
|
||||
plugins: [
|
||||
uni(),
|
||||
Unocss(),
|
||||
{
|
||||
...useRouter({
|
||||
pagesJsonDir: path.resolve(__dirname, "./src/pages.json"),
|
||||
includes: ["meta"],
|
||||
}),
|
||||
enforce: "post",
|
||||
},
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
"@@": path.resolve(__dirname, "./src/sheep"),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
host: "0.0.0.0",
|
||||
port: 8888,
|
||||
hmr: true,
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: baseUrl,
|
||||
ws: true,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, ""),
|
||||
},
|
||||
},
|
||||
},
|
||||
define: {},
|
||||
}
|
||||
})
|
||||