Merge branch 'master' of https://gitea.zianxin.com/zax/biz-mobile-react-cloud
# Conflicts: # .env
This commit is contained in:
commit
41d239e574
44 files changed
+1147
-614
No files matched your search
+11
-2
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { getLaunchParam } from "@/sheep/utils/app"
|
||||
import { getAppInfo } from "@@/utils/app"
|
||||
import { APPENV } from "./sheep/constant"
|
||||
|
||||
interface TabbarItem {
|
||||
pagePath: string
|
||||
@@ -60,6 +61,14 @@ const tabbar: TabbarItem[] = [
|
||||
launchParam: ["onlineShop"],
|
||||
auth: ["user"],
|
||||
},
|
||||
{
|
||||
pagePath: "pages/tabbar/prosperityShop",
|
||||
text: "共富商城",
|
||||
iconPath: "/static/tabbar/prosperity-shop.png",
|
||||
selectedIconPath: "/static/tabbar/prosperity-shop-select.png",
|
||||
launchParam: ["onlineShop"],
|
||||
auth: ["user"],
|
||||
},
|
||||
{
|
||||
pagePath: "pages/tabbar/cabinet",
|
||||
text: "智能柜",
|
||||
@@ -152,7 +161,7 @@ export default {
|
||||
const appInfo = await getAppInfo()
|
||||
|
||||
// 浙政钉环境
|
||||
if (appInfo == "zzd") {
|
||||
if (appInfo == APPENV.ZZD) {
|
||||
if (!launchParam) return uni.hideTabBar()
|
||||
|
||||
setTabbar(launchParam)
|
||||
@@ -161,7 +170,7 @@ export default {
|
||||
}
|
||||
|
||||
// 诗画环境
|
||||
if (appInfo == "sh") {
|
||||
if (appInfo == APPENV.SH) {
|
||||
if (!launchParam) return uni.hideTabBar()
|
||||
|
||||
const userRole = uni.getStorageSync("userRole")
|
||||
|
||||
@@ -44,6 +44,13 @@
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tabbar/prosperityShop",
|
||||
"style": {
|
||||
"navigationBarTitleText": "共富商城",
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tabbar/coopMerchant",
|
||||
"style": {
|
||||
@@ -512,6 +519,23 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"root": "pages/car",
|
||||
"pages": [
|
||||
{
|
||||
"path": "userCar/apply",
|
||||
"style": {
|
||||
"navigationBarTitleText": "申请车辆"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "userCar/list",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的车辆"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
@@ -559,6 +583,12 @@
|
||||
"iconPath": "",
|
||||
"selectedIconPath": ""
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/tabbar/prosperityShop",
|
||||
"text": "",
|
||||
"iconPath": "",
|
||||
"selectedIconPath": ""
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/tabbar/cabinet",
|
||||
"text": "",
|
||||
|
||||
@@ -35,7 +35,7 @@ onLoad((options: any) => {
|
||||
getDetail()
|
||||
}
|
||||
})
|
||||
onShow(() => {})
|
||||
onShow(() => { })
|
||||
|
||||
const getDetail = async () => {
|
||||
if (isEmpty(state.detailId)) return
|
||||
@@ -88,18 +88,14 @@ const doSubmit = async () => {
|
||||
<view class="card p-x-30rpx p-y-40rpx">
|
||||
<tm-form ref="applyFormRef" v-model="applyForm" :rules="applyFormRules" direction="vertical">
|
||||
<tm-form-item name="displayTimeRangeStr" label="使用时间" :showBottom="false">
|
||||
<tm-between-time
|
||||
start="2020-1-1"
|
||||
end="2030-1-1"
|
||||
:quickDate="[]"
|
||||
v-model="applyForm.displayTimeRange"
|
||||
v-model:model-str="applyForm.displayTimeRangeStr"
|
||||
format="YYYY-MM-DD"
|
||||
>
|
||||
<tm-between-time start="2020-1-1" end="2030-1-1" :quickDate="[]"
|
||||
v-model="applyForm.displayTimeRange" v-model:model-str="applyForm.displayTimeRangeStr"
|
||||
format="YYYY-MM-DD">
|
||||
<view :style="{ pointerEvents: state.detailType == 'view' ? 'auto' : 'none' }">
|
||||
<tm-input v-model="applyForm.displayTimeRangeStr" disabled placeholder="请选择使用时间..">
|
||||
<template v-slot:rightIcon>
|
||||
<text v-if="state.detailType != 'view'" class="p-0.5rem color-#b1b1b1 iconfont icon-xiangxiajiantouxiao"></text>
|
||||
<text v-if="state.detailType != 'view'"
|
||||
class="p-0.5rem color-#b1b1b1 iconfont icon-xiangxiajiantouxiao"></text>
|
||||
</template>
|
||||
</tm-input>
|
||||
</view>
|
||||
@@ -107,31 +103,20 @@ const doSubmit = async () => {
|
||||
</tm-form-item>
|
||||
<view class="h-30rpx" />
|
||||
<tm-form-item name="count" label="申请数量" :showBottom="false">
|
||||
<tm-input
|
||||
v-model="applyForm.count"
|
||||
type="number"
|
||||
:disabled="state.detailType == 'view'"
|
||||
:showClear="state.detailType != 'view'"
|
||||
placeholder="请输入申请数量.."
|
||||
/>
|
||||
<tm-input v-model="applyForm.count" type="number" :disabled="state.detailType == 'view'"
|
||||
:showClear="state.detailType != 'view'" placeholder="请输入申请数量.." />
|
||||
</tm-form-item>
|
||||
<view class="h-30rpx" />
|
||||
<tm-form-item name="remark" label="备注" :required="false" :showBottom="false">
|
||||
<tm-input
|
||||
v-model="applyForm.remark"
|
||||
type="textarea"
|
||||
:disabled="state.detailType == 'view'"
|
||||
<tm-input v-model="applyForm.remark" type="textarea" :disabled="state.detailType == 'view'"
|
||||
:showClear="state.detailType != 'view'"
|
||||
:placeholder="state.detailType == 'view' ? '' : '请输入备注..'"
|
||||
></tm-input>
|
||||
:placeholder="state.detailType == 'view' ? '' : '请输入备注..'"></tm-input>
|
||||
</tm-form-item>
|
||||
</tm-form>
|
||||
</view>
|
||||
<view
|
||||
v-if="state.detailType != 'view'"
|
||||
<view v-if="state.detailType != 'view'"
|
||||
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!"
|
||||
@tap="doSubmit"
|
||||
>
|
||||
@tap="doSubmit">
|
||||
提交
|
||||
</view>
|
||||
</crud-layout>
|
||||
|
||||
@@ -27,7 +27,7 @@ const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad(() => {})
|
||||
onLoad(() => { })
|
||||
onShow(() => {
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
@@ -55,20 +55,9 @@ const doCard = (v: any) => {
|
||||
|
||||
<template>
|
||||
<crud-layout title="外来人员就餐" bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<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">
|
||||
@@ -76,7 +65,8 @@ const doCard = (v: any) => {
|
||||
</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-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">
|
||||
@@ -127,7 +117,9 @@ const doCard = (v: any) => {
|
||||
</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
|
||||
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" />
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { userCarApi } from "@@/api"
|
||||
import { serviceEnum } from "@/sheep/constant"
|
||||
|
||||
const { carTypeEnum } = serviceEnum
|
||||
|
||||
const applyFormRef = ref<any>(null)
|
||||
|
||||
const visitorReasonList = ref<Array<{ title: string; id: string }>>(Object.keys(carTypeEnum).map((key) => ({
|
||||
title: carTypeEnum[key],
|
||||
id: key,
|
||||
})))
|
||||
|
||||
const applyForm = reactive<any>({
|
||||
id: "",
|
||||
carType: "",
|
||||
carTypeStr: "",
|
||||
carNumber: "",
|
||||
})
|
||||
|
||||
|
||||
const applyFormRules = reactive<any>({
|
||||
carTypeStr: [{ required: true, message: "请选择车辆类型" }],
|
||||
carNumber: [{ required: true, message: "请输入车牌号" }],
|
||||
})
|
||||
|
||||
|
||||
onLoad(() => {
|
||||
// 默认第一个
|
||||
if (!applyForm.carType) {
|
||||
const target = visitorReasonList.value[0]
|
||||
applyForm.carType = target.id
|
||||
applyForm.carTypeStr = target.title
|
||||
}
|
||||
})
|
||||
onShow(() => {
|
||||
})
|
||||
|
||||
// 选择车俩类型
|
||||
const carNumberPickerConfirm = (e) => {
|
||||
const target = visitorReasonList.value.find((item) => item.id == e[0])
|
||||
if (!target) return
|
||||
applyForm.carType = target.id
|
||||
applyForm.carTypeStr = target.title
|
||||
}
|
||||
|
||||
const doSubmit = async () => {
|
||||
applyFormRef.value.submit()
|
||||
const { isPass } = applyFormRef.value.validate()
|
||||
if (!isPass) return
|
||||
try {
|
||||
uni.showLoading({ title: "申请中...", mask: false })
|
||||
const _pa = {
|
||||
...applyForm
|
||||
}
|
||||
const { data, code }: any = await userCarApi.apply(_pa)
|
||||
if (code != 0) throw new Error()
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "申请成功", icon: "none" })
|
||||
router.back()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="申请车辆" bg="/static/page/blue-bg.png">
|
||||
<view class="h-30rpx" />
|
||||
<view class="card p-x-30rpx p-y-40rpx">
|
||||
<tm-form ref="applyFormRef" v-model="applyForm" :rules="applyFormRules" direction="vertical">
|
||||
<tm-form-item name="carTypeStr" label="车辆类型" :showBottom="false">
|
||||
<tm-picker @confirm="carNumberPickerConfirm" :list="visitorReasonList">
|
||||
<tm-input :modelValue="applyForm.carTypeStr" placeholder="请选择车辆类型" style="pointer-events: none">
|
||||
</tm-input>
|
||||
</tm-picker>
|
||||
</tm-form-item>
|
||||
<tm-form-item name="carNumber" label="车牌号" :showBottom="false">
|
||||
<tm-input v-model="applyForm.carNumber" placeholder="请输入" show-char-count></tm-input>
|
||||
</tm-form-item>
|
||||
</tm-form>
|
||||
</view>
|
||||
<view class=" bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!"
|
||||
@tap="doSubmit">
|
||||
提交
|
||||
</view>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep() {
|
||||
.tmFormItemLabel {
|
||||
padding-bottom: 10rpx !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,81 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { userCarApi } from "@@/api"
|
||||
import { serviceEnum } from "@/sheep/constant"
|
||||
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const { carTypeEnum } = serviceEnum
|
||||
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
pagesize: 10,
|
||||
},
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, userCarApi.page, null, "data.records")
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
|
||||
onLoad(() => { })
|
||||
onShow(() => {
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
})
|
||||
|
||||
const doApply = () => {
|
||||
router.jump("/pages/car/userCar/apply")
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="我的车辆" bg="/static/page/blue-bg.png">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
<view class="h-20rpx" />
|
||||
<view class="position-relative card p-x-20rpx p-y-30rpx m-b-20rpx overflow-hidden"
|
||||
v-for="(v, i) in pageHook.list" :key="v.id">
|
||||
<view class="flex justify-between items-center m-t-20rpx">
|
||||
<view>
|
||||
<!-- 私家车 -->
|
||||
<tm-tag v-if="v.carType == 1" size="m">{{ carTypeEnum[v.carType] }}</tm-tag>
|
||||
<!-- 公车 -->
|
||||
<tm-tag v-if="v.carType == 2" size="m">{{ carTypeEnum[v.carType] }}</tm-tag>
|
||||
<!-- 军车 -->
|
||||
<tm-tag v-if="v.carType == 3" size="m">{{ carTypeEnum[v.carType] }}</tm-tag>
|
||||
<!-- 警车 -->
|
||||
<tm-tag v-if="v.carType == 4" size="m">{{ carTypeEnum[v.carType] }}</tm-tag>
|
||||
</view>
|
||||
<view class="flex items-center" @tap.stop="hooks.useCopy(v.carNumber)">
|
||||
<text class="main-text-28 m-r-6rpx">{{ v.carNumber }}</text>
|
||||
<text v-if="v.carNumber" class="iconfont icon-fuzhi" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex justify-end m-t-10rpx">
|
||||
<text class="second-text-26">{{ v.createTime }}</text>
|
||||
</view>
|
||||
<view class="position-absolute right-0 top-0 sub-text-24 color-white!">
|
||||
<view class="p-x-8rpx p-y-6rpx bg-green rounded-bl-16rpx" v-if="v.enableStatus == 1">已启用</view>
|
||||
<view class="p-x-8rpx p-y-6rpx bg-red rounded-bl-16rpx" v-if="v.enableStatus == 0">已禁用</view>
|
||||
</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>
|
||||
@@ -19,7 +19,7 @@ const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad(() => {})
|
||||
onLoad(() => { })
|
||||
onShow(() => {
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
@@ -49,20 +49,9 @@ const doDel = (id: string) => {
|
||||
|
||||
<template>
|
||||
<crud-layout title="人脸管理" bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<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-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="v.id">
|
||||
<view class="flex items-center justify-between second-text-26">
|
||||
@@ -81,7 +70,9 @@ const doDel = (id: string) => {
|
||||
</view>
|
||||
</view>
|
||||
<template #bottom>
|
||||
<view v-if="false" class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!" @tap="doAdd">
|
||||
<view v-if="false"
|
||||
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!"
|
||||
@tap="doAdd">
|
||||
添加
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
|
||||
@@ -1,206 +1,207 @@
|
||||
<template>
|
||||
<view class="notice-detail">
|
||||
<view class="detail-header">
|
||||
<view class="title">
|
||||
<text v-if="detail.isTop === '1'" class="top-tag">置顶</text>
|
||||
{{ detail.title }}
|
||||
</view>
|
||||
<view class="meta">
|
||||
<text class="type-tag" :class="getTypeClass(detail.type)">{{ getTypeLabel(detail.type) }}</text>
|
||||
<text class="time">{{ formatTime(detail.createTime) }}</text>
|
||||
<text class="view-count">浏览 {{ detail.viewCount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="detail-content">
|
||||
<rich-text :nodes="detail.description || ''"></rich-text>
|
||||
</view>
|
||||
|
||||
<view v-if="detail.attachments && detail.attachments.length > 0" class="attachments">
|
||||
<view class="attachment-title">附件</view>
|
||||
<view
|
||||
v-for="(file, index) in detail.attachments"
|
||||
:key="index"
|
||||
class="attachment-item"
|
||||
@click="downloadFile(file)"
|
||||
>
|
||||
<text class="file-name">{{ file.name }}</text>
|
||||
<text class="file-size">{{ formatFileSize(file.size) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="notice-detail">
|
||||
<view class="detail-header">
|
||||
<view class="title">
|
||||
<text v-if="detail.isTop === '1'" class="top-tag">置顶</text>
|
||||
{{ detail.title }}
|
||||
</view>
|
||||
<view class="meta">
|
||||
<text class="type-tag" :class="getTypeClass(detail.type)">{{ getTypeLabel(detail.type) }}</text>
|
||||
<text class="time">{{ formatTime(detail.createTime) }}</text>
|
||||
<text class="view-count">浏览 {{ detail.viewCount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="detail-content">
|
||||
<rich-text :nodes="nodes || ''"></rich-text>
|
||||
</view>
|
||||
|
||||
<view v-if="detail.attachments && detail.attachments.length > 0" class="attachments">
|
||||
<view class="attachment-title">附件</view>
|
||||
<view v-for="(file, index) in detail.attachments" :key="index" class="attachment-item" @click="downloadFile(file)">
|
||||
<text class="file-name">{{ file.name }}</text>
|
||||
<text class="file-size">{{ formatFileSize(file.size) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { noticeApi } from '@/sheep/api'
|
||||
import { computed, ref } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import { noticeApi } from "@/sheep/api"
|
||||
|
||||
const detail = ref<any>({})
|
||||
|
||||
const nodes = computed(() => {
|
||||
return detail.value.description?.replaceAll(`<img src="/api`, `<img src="https://stgl.pj.gov.cn/api`)
|
||||
})
|
||||
|
||||
function getTypeLabel(type: string) {
|
||||
const typeMap: Record<string, string> = {
|
||||
'1': '重要',
|
||||
'2': '一般',
|
||||
'3': '活动'
|
||||
}
|
||||
return typeMap[type] || '一般'
|
||||
const typeMap: Record<string, string> = {
|
||||
"1": "重要",
|
||||
"2": "一般",
|
||||
"3": "活动",
|
||||
}
|
||||
return typeMap[type] || "一般"
|
||||
}
|
||||
|
||||
function getTypeClass(type: string) {
|
||||
const classMap: Record<string, string> = {
|
||||
'1': 'type-important',
|
||||
'2': 'type-general',
|
||||
'3': 'type-activity'
|
||||
}
|
||||
return classMap[type] || 'type-general'
|
||||
const classMap: Record<string, string> = {
|
||||
"1": "type-important",
|
||||
"2": "type-general",
|
||||
"3": "type-activity",
|
||||
}
|
||||
return classMap[type] || "type-general"
|
||||
}
|
||||
|
||||
function formatTime(time: string) {
|
||||
if (!time) return ''
|
||||
return new Date(time).toLocaleString()
|
||||
if (!time) return ""
|
||||
return new Date(time).toLocaleString()
|
||||
}
|
||||
|
||||
function formatFileSize(size: number) {
|
||||
if (size < 1024) {
|
||||
return size + 'B'
|
||||
} else if (size < 1024 * 1024) {
|
||||
return (size / 1024).toFixed(1) + 'KB'
|
||||
} else {
|
||||
return (size / (1024 * 1024)).toFixed(1) + 'MB'
|
||||
}
|
||||
if (size < 1024) {
|
||||
return size + "B"
|
||||
} else if (size < 1024 * 1024) {
|
||||
return (size / 1024).toFixed(1) + "KB"
|
||||
} else {
|
||||
return (size / (1024 * 1024)).toFixed(1) + "MB"
|
||||
}
|
||||
}
|
||||
|
||||
function downloadFile(file: any) {
|
||||
uni.downloadFile({
|
||||
url: file.url,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
uni.openDocument({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => {
|
||||
console.log('打开文档成功')
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: '无法打开此文件', icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: '下载失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
uni.downloadFile({
|
||||
url: file.url,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
uni.openDocument({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => {
|
||||
console.log("打开文档成功")
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: "无法打开此文件", icon: "none" })
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: "下载失败", icon: "none" })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
onLoad(async (options: any) => {
|
||||
const id = options.id
|
||||
if (!id) return
|
||||
|
||||
try {
|
||||
// 增加浏览量
|
||||
await noticeApi.addNoticeView(id)
|
||||
// 获取详情
|
||||
const response: any = await noticeApi.getNoticeDetail(id)
|
||||
if (response.code === 0 && response.data) {
|
||||
detail.value = response.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取公告详情失败:', error)
|
||||
uni.showToast({ title: '获取详情失败', icon: 'none' })
|
||||
}
|
||||
const id = options.id
|
||||
if (!id) return
|
||||
|
||||
try {
|
||||
// 增加浏览量
|
||||
await noticeApi.addNoticeView(id)
|
||||
// 获取详情
|
||||
const response: any = await noticeApi.getNoticeDetail(id)
|
||||
if (response.code === 0 && response.data) {
|
||||
detail.value = response.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取公告详情失败:", error)
|
||||
uni.showToast({ title: "获取详情失败", icon: "none" })
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notice-detail {
|
||||
padding: 32rpx;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
padding: 32rpx;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.detail-header {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-tag {
|
||||
background: #ffebee;
|
||||
color: #d32f2f;
|
||||
font-size: 22rpx;
|
||||
border-radius: 8rpx;
|
||||
padding: 2rpx 12rpx;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.view-count {
|
||||
margin-left: 24rpx;
|
||||
}
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-tag {
|
||||
background: #ffebee;
|
||||
color: #d32f2f;
|
||||
font-size: 22rpx;
|
||||
border-radius: 8rpx;
|
||||
padding: 12rpx 12rpx;
|
||||
margin-right: 12rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.view-count {
|
||||
margin-left: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.detail-content {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 24rpx;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
line-height: 1.8;
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 24rpx;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
line-height: 1.8;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.attachments {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 32rpx;
|
||||
|
||||
.attachment-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.attachment-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
font-size: 28rpx;
|
||||
color: #007aff;
|
||||
flex: 1;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.file-size {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 32rpx;
|
||||
|
||||
.attachment-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.attachment-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
font-size: 28rpx;
|
||||
color: #007aff;
|
||||
flex: 1;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.file-size {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,8 +1,12 @@
|
||||
<template>
|
||||
<crud-layout title="详情" mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<view v-if="detail.id">
|
||||
<tm-sheet :margin="[0, 20]" class="second-text-32">
|
||||
<tm-text font-size="32">访客信息</tm-text>
|
||||
<view class="h-20rpx" />
|
||||
<tm-alert v-if="alertList[detail.checkStatus]" :showClose="false" skin="normal" :color="alertList[detail.checkStatus].color">
|
||||
{{ alertList[detail.checkStatus].text }}
|
||||
</tm-alert>
|
||||
<tm-sheet :margin="[0, 20]" class="second-text-30">
|
||||
<tm-text class="prefix_title" font-size="32">访客信息</tm-text>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>访客姓名:</text>
|
||||
<text>{{ detail.name }}</text>
|
||||
@@ -37,8 +41,8 @@
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
<tm-sheet :margin="[0, 20]" class="second-text-32">
|
||||
<tm-text font-size="32">时间</tm-text>
|
||||
<tm-sheet :margin="[0, 20]" class="second-text-30">
|
||||
<tm-text class="prefix_title" font-size="32">时间</tm-text>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>预计来访时间:</text>
|
||||
<text>{{ detail.vendDate }}</text>
|
||||
@@ -49,8 +53,8 @@
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
<tm-sheet :margin="[0, 20]" class="second-text-32">
|
||||
<tm-text font-size="32">其他</tm-text>
|
||||
<tm-sheet :margin="[0, 20]" class="second-text-30">
|
||||
<tm-text class="prefix_title" font-size="32">其他</tm-text>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>创建方式:</text>
|
||||
<text>{{ detail.type == "1" ? "主动申请" : detail.type == "2" ? "邀约" : "后台创建" }}</text>
|
||||
@@ -67,10 +71,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from "vue"
|
||||
import { ref } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import { invitationApi } from "@/sheep/api"
|
||||
|
||||
const alertList = {
|
||||
1: { color: "#f5a623", text: "访客未接受邀约" },
|
||||
2: { color: "#2db7f5", text: "访客待到访" },
|
||||
3: { color: "#52c41a", text: "访客拒绝了邀约" },
|
||||
5: { color: "#f5222d", text: "访客取消了邀约" },
|
||||
}
|
||||
|
||||
const detail = ref<any>({})
|
||||
const visitorReasonList = ref<{ title: string; id: string }[]>([])
|
||||
|
||||
@@ -78,19 +89,17 @@ onLoad(async (options: any) => {
|
||||
const id = options.id
|
||||
|
||||
try {
|
||||
uni.showLoading({ title: "加载中..." })
|
||||
const { code, data, msg } = await invitationApi.getInvitationDetail(id)
|
||||
if (code == 0) {
|
||||
detail.value = data
|
||||
return
|
||||
}
|
||||
uni.showToast({ title: msg || "获取详情失败", icon: "none" })
|
||||
if (code != 0) return uni.showToast({ title: msg || "获取详情失败", icon: "none" })
|
||||
detail.value = data
|
||||
} catch (error: any) {
|
||||
uni.showToast({ title: error.message, icon: "none" })
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getVisitorReasonList()
|
||||
await getVisitorReasonList()
|
||||
})
|
||||
|
||||
// 获取拜访原因列表
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
</template>
|
||||
</tm-input>
|
||||
</template>
|
||||
<tm-text color="#999999">精致美观的对话框,可全局配置风格</tm-text>
|
||||
<tm-text color="#999999"></tm-text>
|
||||
</tm-drawer>
|
||||
</tm-form-item> -->
|
||||
|
||||
@@ -88,18 +88,22 @@
|
||||
</tm-drawer>
|
||||
|
||||
<tm-modal
|
||||
v-model:show="modalShow"
|
||||
v-model:show="confirmModalShow"
|
||||
:overlayClick="false"
|
||||
title="提示"
|
||||
title="确定提交吗?"
|
||||
position="bottom"
|
||||
height="auto"
|
||||
:showCancel="true"
|
||||
cancelText="取消"
|
||||
confirmText="确定"
|
||||
@confirm="confirmSubmit"
|
||||
@cancel="modalShow = false"
|
||||
@cancel="confirmModalShow = false"
|
||||
>
|
||||
<view class="text-center"><tm-text font-size="30" color="#999999">确认提交吗?</tm-text></view>
|
||||
<view class="text-center">
|
||||
<tm-text font-size="30" color="#999999">提交后系统将会向手机号</tm-text>
|
||||
<tm-text font-size="30" color="#0779FD">{{ form.mobile || "" }}</tm-text>
|
||||
<tm-text font-size="30" color="#999999">发送邀约短信</tm-text>
|
||||
</view>
|
||||
</tm-modal>
|
||||
|
||||
<template #main-bottom>
|
||||
@@ -120,9 +124,17 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from "vue"
|
||||
import { invitationApi } from "@/sheep/api/index"
|
||||
import TimeRangePicker from "@/sheep/components/TimePointPicker.vue"
|
||||
import TimeRangePicker from "@/sheep/components/time-range-picker.vue"
|
||||
|
||||
const form = reactive<any>({
|
||||
interface FormData {
|
||||
mobile: string
|
||||
vStartDate: string
|
||||
vEndDate: string
|
||||
isOtherPeople: boolean | string
|
||||
isDrive: boolean | string
|
||||
}
|
||||
|
||||
const form = reactive<FormData>({
|
||||
// name: "",
|
||||
mobile: "",
|
||||
// companyName: "",
|
||||
@@ -134,8 +146,8 @@ const form = reactive<any>({
|
||||
isDrive: true,
|
||||
})
|
||||
const showDatePicker = ref(false)
|
||||
const curSelectedInputName = ref("")
|
||||
const modalShow = ref(false)
|
||||
const curDateType = ref("")
|
||||
const confirmModalShow = ref(false)
|
||||
// const visitorReasonList = ref<{ title: string; id: string }[]>([])
|
||||
|
||||
// onLoad(() => {
|
||||
@@ -169,20 +181,20 @@ const rules: Record<string, TM.FORM_RULE[]> = {
|
||||
}
|
||||
|
||||
// 开始日期选择
|
||||
const startDatePicker = (key: string) => {
|
||||
const startDatePicker = (dateType: string) => {
|
||||
showDatePicker.value = true
|
||||
curSelectedInputName.value = key
|
||||
curDateType.value = dateType
|
||||
}
|
||||
|
||||
// 离开日期选择
|
||||
const endDatePicker = (key: string) => {
|
||||
const endDatePicker = (dateType: string) => {
|
||||
showDatePicker.value = true
|
||||
curSelectedInputName.value = key
|
||||
curDateType.value = dateType
|
||||
}
|
||||
|
||||
// 日期选择器确认
|
||||
const onDatePickerConfirm = (dateValue: any, timeValue: string) => {
|
||||
form[curSelectedInputName.value] = `${dateValue.fullDate} ${timeValue}`
|
||||
form[curDateType.value] = `${dateValue.fullDate} ${timeValue}`
|
||||
showDatePicker.value = false
|
||||
}
|
||||
|
||||
@@ -190,7 +202,7 @@ const onDatePickerConfirm = (dateValue: any, timeValue: string) => {
|
||||
const onsubmit = (evt: TM.FORM_SUBMIT_RESULT) => {
|
||||
// console.log("校验结果:", evt)
|
||||
if (!evt.isPass) return
|
||||
modalShow.value = true
|
||||
confirmModalShow.value = true
|
||||
}
|
||||
|
||||
// 确认提交
|
||||
@@ -210,15 +222,12 @@ const confirmSubmit = async () => {
|
||||
form.mobile = form.mobile.trim().replace(/\s/g, "")
|
||||
|
||||
try {
|
||||
const { code, data, msg } = await invitationApi.saveInvitation(form)
|
||||
if (code == 0) {
|
||||
uni.showToast({ title: "提交成功", icon: "success" })
|
||||
resetForm()
|
||||
modalShow.value = false
|
||||
uni.navigateTo({ url: "/pages/integrated/visitor/invitationRecord" })
|
||||
return
|
||||
}
|
||||
uni.showToast({ title: msg || "提交失败", icon: "none" })
|
||||
const { code, msg } = await invitationApi.saveInvitation(form)
|
||||
if (code != 0) return uni.showToast({ title: msg || "提交失败", icon: "error" })
|
||||
uni.showToast({ title: "提交成功", icon: "success" })
|
||||
resetForm()
|
||||
confirmModalShow.value = false
|
||||
uni.navigateTo({ url: "/pages/integrated/visitor/invitationRecord" })
|
||||
} catch (error: any) {
|
||||
uni.showToast({ title: error.message || "提交失败", icon: "none" })
|
||||
}
|
||||
@@ -230,8 +239,8 @@ const resetForm = () => {
|
||||
// name: "",
|
||||
mobile: "",
|
||||
// companyName: "",
|
||||
vStartDate: "",
|
||||
vEndDate: "",
|
||||
vstartDate: "",
|
||||
vendDate: "",
|
||||
// reasonValue: "",
|
||||
// reasonText: "",
|
||||
isOtherPeople: true,
|
||||
|
||||
@@ -54,26 +54,21 @@
|
||||
</template>
|
||||
<view class="flex-col justify-center card p-3 m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i">
|
||||
<view class="flex justify-between items-center">
|
||||
<view v-if="v.checkStatus == '1'" class="p-1 c-white! sub-text-26 rounded-1 bg-#f5a623">待接受</view>
|
||||
<view v-if="v.checkStatus == '2'" class="p-1 c-white! sub-text-26 rounded-1 bg-#2db7f5">待到访</view>
|
||||
<view v-if="v.checkStatus == '3'" class="p-1 c-white! sub-text-26 rounded-1 bg-#52c41a">已拒绝</view>
|
||||
<view v-if="v.checkStatus == '5'" class="p-1 c-white! sub-text-26 rounded-1 bg-#f5222d">已取消</view>
|
||||
<view v-if="v.checkStatus == '1'" class="p-1 c-white! sub-text-22 rounded-1 bg-#f5a623">待接受</view>
|
||||
<view v-if="v.checkStatus == '2'" class="p-1 c-white! sub-text-22 rounded-1 bg-#2db7f5">待到访</view>
|
||||
<view v-if="v.checkStatus == '3'" class="p-1 c-white! sub-text-22 rounded-1 bg-#52c41a">已拒绝</view>
|
||||
<view v-if="v.checkStatus == '5'" class="p-1 c-white! sub-text-22 rounded-1 bg-#f5222d">已取消</view>
|
||||
<view class="sub-text-26">{{ v.vstartDate + " ~ " + v.vendDate }}</view>
|
||||
</view>
|
||||
<view class="flex-col my-1 px-4 py-2 bg-#ECF4F9 rounded-4">
|
||||
<view class="flex justify-start sub-text-30 whitespace-nowrap">
|
||||
<view>{{ v.name }}</view>
|
||||
<view class="second-text-28 ml-2">{{ v.mobile }}</view>
|
||||
</view>
|
||||
<view class="flex justify-center sub-text-28 font-italic whitespace-nowrap my-2">
|
||||
<span v-if="v.reasonValue">拜访原因:{{ visitorReasonList.find((item) => item.id == v.reasonValue)?.title || "" }}</span>
|
||||
</view>
|
||||
<!-- <view class="flex justify-end second-text-28 whitespace-nowrap">
|
||||
<span v-if="state.params.type == 1">接待人:{{ v.userName }}</span>
|
||||
</view> -->
|
||||
<view class="m-2 h-1rpx bg-#A0A0A044"></view>
|
||||
<view class="flex justify-between sub-text-26 whitespace-nowrap">
|
||||
<!-- <view>{{ v.name }}</view> -->
|
||||
<view>访客手机号:{{ v.mobile }}</view>
|
||||
<!-- <view v-if="v.reasonValue">拜访原因:{{ visitorReasonList.find((item) => item.id == v.reasonValue)?.title || "" }}</view> -->
|
||||
<tm-button class="px-1" size="xs" @click.stop="goDetail(v)">查看详情</tm-button>
|
||||
</view>
|
||||
<view class="flex justify-end items-center gap-2">
|
||||
<!-- <view v-if="v.checkStatus == 1" class="flex items-center gap-2">
|
||||
<!-- <view class="flex justify-end items-center gap-2"> -->
|
||||
<!-- <view v-if="v.checkStatus == 1" class="flex items-center gap-2">
|
||||
<tm-modal title="确定审核通过吗?" height="auto" @confirm="visitorCheck(v.id, 2)">
|
||||
<template v-slot:trigger><tm-button class="px-1" size="s">审核通过</tm-button></template>
|
||||
</tm-modal>
|
||||
@@ -81,8 +76,7 @@
|
||||
<template v-slot:trigger><tm-button class="px-1" size="s" color="danger">审核拒绝</tm-button></template>
|
||||
</tm-modal>
|
||||
</view> -->
|
||||
<tm-button v-if="v.checkStatus == '2'" class="px-1" size="s" color="success" @click.stop="goDetail(v)">查看详情</tm-button>
|
||||
</view>
|
||||
<!-- </view> -->
|
||||
</view>
|
||||
</z-paging>
|
||||
|
||||
@@ -102,7 +96,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from "vue"
|
||||
import { ref, reactive } from "vue"
|
||||
import { onShow } from "@dcloudio/uni-app"
|
||||
import { hooks, router } from "@@/index"
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
@@ -123,30 +117,12 @@ const state = reactive<any>({
|
||||
},
|
||||
})
|
||||
const pageRef = ref<any>(null)
|
||||
const visitorReasonList = ref<{ title: string; id: string }[]>([])
|
||||
|
||||
onShow(async () => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (!isLogin) return
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getVisitorReasonList()
|
||||
})
|
||||
|
||||
// 获取拜访原因列表
|
||||
const getVisitorReasonList = async () => {
|
||||
const { code, data } = await invitationApi.getDictListByType("1")
|
||||
if (code == 0 && data) {
|
||||
visitorReasonList.value = data.map((item: any) => ({ title: item.label, id: item.value }))
|
||||
return
|
||||
}
|
||||
visitorReasonList.value = []
|
||||
}
|
||||
|
||||
const doTab = (e: any) => {
|
||||
const target = tabs[e]
|
||||
state.params.checkStatus = target.value
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
</view>
|
||||
|
||||
<view class="flex-col-center m-b-60rpx">
|
||||
<text class="text-90 c-#333333!">¥{{ payData.customPrice }}</text>
|
||||
<text class="text-90 c-#333333!">¥{{ scanPayData.payPrice }}</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>
|
||||
<text class="sub-text-30">{{ scanPayData.mchName }}</text>
|
||||
</view>
|
||||
<hr />
|
||||
<view class="flex-row justify-between m-15rpx">
|
||||
@@ -50,11 +50,11 @@ import { ref } from "vue"
|
||||
import { onShow } from "@dcloudio/uni-app"
|
||||
import { usePayStore } from "@/sheep/stores/pay"
|
||||
|
||||
const payData = ref<{ id?: string; name?: string; customPrice?: number }>({})
|
||||
const scanPayData = ref<any>({})
|
||||
|
||||
onShow(() => {
|
||||
if (!usePayStore().payData.id) return uni.showToast({ title: "支付信息不存在", icon: "none" })
|
||||
payData.value = usePayStore().payData
|
||||
if (!usePayStore().scanPayData.mchId) return uni.showToast({ title: "支付信息不存在", icon: "none" })
|
||||
scanPayData.value = usePayStore().scanPayData
|
||||
})
|
||||
|
||||
const goBack = () => {
|
||||
|
||||
+102
-75
@@ -1,36 +1,36 @@
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<view class="h-screen flex flex-col">
|
||||
<view class="mx-auto text-34 py-2 h-80rpx">{{ scanCodeData.name }}</view>
|
||||
<view class="mx-auto text-34 py-2 h-80rpx">{{ scanPayState.mchName }}</view>
|
||||
|
||||
<tm-sheet class="flex flex-row">
|
||||
<tm-sheet :margin="[0, 10]" 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-sheet v-if="walletList.length > 0" class="flex flex-col">
|
||||
<view class="text-gray-700 font-bold text-sm mb-1">选择支付钱包:</view>
|
||||
<tm-sheet v-if="walletList.length > 0" :margin="[0, 10]" class="flex flex-col">
|
||||
<view class="text-gray-700 font-bold text-28 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"
|
||||
class="border-6 border-solid border-#efefef my-2 duration-200 flex justify-between items-center p-3 rounded-2"
|
||||
:class="{ 'border-6 border-solid border-blue!': selectWallet.id == v.id }"
|
||||
@click="selectWallet = v"
|
||||
>
|
||||
<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 class="text-32">{{ v.walletTypeName }}</view>
|
||||
</view>
|
||||
<view class="main-text-28 flex items-center">
|
||||
<view>余额:{{ hooks.useMoney(v.balance) }}</view>
|
||||
<text>元</text>
|
||||
<view class="text-28 flex items-center">
|
||||
<view>余额:</view>
|
||||
<text class="main-text-28">{{ hooks.useMoney(v.balance) }} 元</text>
|
||||
</view>
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
<tm-button class="mt-1" :block="true" @click="disabled ? '' : handlePay()" :disabled="disabled">支 付</tm-button>
|
||||
<tm-button class="mt-1" :block="true" @click="handlePay()" :disabled="loading">支 付</tm-button>
|
||||
|
||||
<numberKeyboard v-model="amount" />
|
||||
<number-keyboard v-if="!scanPayState.action" v-model="amount" />
|
||||
</view>
|
||||
</crud-layout>
|
||||
</template>
|
||||
@@ -39,79 +39,96 @@
|
||||
import { ref, computed, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import payApi from "@@/api/pay"
|
||||
import { merchantApi, walletApi } from "@/sheep/api"
|
||||
import { merchantApi, orderApi, walletApi } from "@/sheep/api"
|
||||
import { hooks } from "@@/index"
|
||||
import { router } from "@/sheep"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
import { storePrice } from "@/sheep/utils/formatMoney"
|
||||
import { displayPrice, storePrice } from "@/sheep/utils/formatMoney"
|
||||
import { usePayStore } from "@/sheep/stores/pay"
|
||||
import { isEmpty } from "radash"
|
||||
import numberKeyboard from "@/sheep/components/numberKeyboard.vue"
|
||||
import NumberKeyboard from "@/sheep/components/number-keyboard.vue"
|
||||
|
||||
const scanCodeData = reactive({
|
||||
id: "",
|
||||
name: "",
|
||||
const loading = ref(false)
|
||||
const scanPayState = reactive({
|
||||
mchId: "", // 商户id
|
||||
mchName: "", // 商户名
|
||||
orderId: "", // 订单id
|
||||
action: "",
|
||||
})
|
||||
const walletList = ref<any>([])
|
||||
const curWalletId = ref("")
|
||||
const disabled = ref(false)
|
||||
const amount = ref("")
|
||||
const walletList = ref<any>([]) // 钱包列表
|
||||
const selectWallet = ref<any>({}) // 当前选中的钱包
|
||||
const orderInfo = ref<any>({}) // 订单信息
|
||||
const amount = ref("") // 键盘输入的金额
|
||||
|
||||
onLoad((options: any) => {
|
||||
if (!isEmpty(options.id)) {
|
||||
scanCodeData.id = options.id
|
||||
} else {
|
||||
uni.showToast({ title: "参数不存在", icon: "none" })
|
||||
onLoad(async (options: any) => {
|
||||
uni.showLoading({ title: "加载中..." })
|
||||
const { mchId, orderId, action } = options
|
||||
if (action === "harQrCodeScanPay") {
|
||||
if (!options.mchId || !options.orderId) return uni.showToast({ title: "扫码参数错误", icon: "none" })
|
||||
scanPayState.mchId = mchId
|
||||
scanPayState.orderId = orderId
|
||||
scanPayState.action = action
|
||||
await getMchDetail(mchId)
|
||||
await getOrderInfo()
|
||||
const order = orderInfo.value
|
||||
amount.value = displayPrice(order.totalPrice || 0 + order.extraPrice || 0, "")
|
||||
return
|
||||
}
|
||||
|
||||
const { id } = options
|
||||
if (!isEmpty(id)) {
|
||||
scanPayState.mchId = id
|
||||
await getMchDetail(id)
|
||||
return
|
||||
}
|
||||
|
||||
return uni.showToast({ title: "扫码参数错误", icon: "none" })
|
||||
})
|
||||
|
||||
onShow(async () => {
|
||||
uni.showLoading({ title: "加载中...", mask: true })
|
||||
if (scanCodeData.id) {
|
||||
const { data } = await merchantApi.detail({ id: scanCodeData.id })
|
||||
if (data) {
|
||||
scanCodeData.name = data.name
|
||||
disabled.value = false
|
||||
} else {
|
||||
disabled.value = true
|
||||
return uni.showToast({ title: "商户id错误", icon: "none" })
|
||||
}
|
||||
} else {
|
||||
uni.showToast({ title: "参数不存在", icon: "none" })
|
||||
disabled.value = true
|
||||
try {
|
||||
await getWalletList()
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
|
||||
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 getMchDetail = async (mchId: string) => {
|
||||
if (!mchId) return uni.showToast({ title: "商户id错误", icon: "none" })
|
||||
const { data } = await merchantApi.detail({ id: mchId })
|
||||
scanPayState.mchName = data.name
|
||||
}
|
||||
|
||||
// 获取钱包列表
|
||||
const getWalletList = async () => {
|
||||
const { code, data } = await walletApi.all()
|
||||
if (code !== 0) return uni.showToast({ title: "获取钱包列表失败", icon: "none" })
|
||||
walletList.value = data.records
|
||||
if (walletList.value.length > 0) {
|
||||
selectWallet.value = walletList.value.find((v: any) => v.walletTypeUniqueCode == "1")
|
||||
}
|
||||
}
|
||||
|
||||
// 获取订单信息
|
||||
const getOrderInfo = async () => {
|
||||
const { code, data }: any = await orderApi.detail({ id: scanPayState.orderId })
|
||||
if (code !== 0) return uni.showToast({ title: "获取订单信息失败", icon: "none" })
|
||||
orderInfo.value = data
|
||||
}
|
||||
|
||||
// 格式化金额显示
|
||||
const displayAmount = computed(() => {
|
||||
if (!amount.value) return "0"
|
||||
return (
|
||||
amount.value
|
||||
// .toString()
|
||||
// .toFixed(2)
|
||||
.replace(/\B(?=(\d{3})+(?!\d))/g, ",")
|
||||
)
|
||||
return amount.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
|
||||
})
|
||||
|
||||
// 点击支付
|
||||
const handlePay = () => {
|
||||
if (!scanCodeData.id || !scanCodeData.name) return uni.showToast({ title: "扫码参数不存在", icon: "none" })
|
||||
if (!amount.value) {
|
||||
uni.showToast({ title: "请输入金额", icon: "none" })
|
||||
return
|
||||
}
|
||||
if (Number(amount.value) === 0) {
|
||||
uni.showToast({ title: "金额不能为0", icon: "none" })
|
||||
return
|
||||
}
|
||||
if (!scanPayState.mchId) return uni.showToast({ title: "扫码参数不存在", icon: "none" })
|
||||
if (!amount.value) return uni.showToast({ title: "请输入金额", icon: "none" })
|
||||
if (Number(amount.value) === 0) return uni.showToast({ title: "金额不能为0", icon: "none" })
|
||||
|
||||
uni.showModal({
|
||||
title: "确定支付吗?",
|
||||
success: async (res) => {
|
||||
@@ -126,18 +143,28 @@ const handlePay = () => {
|
||||
const pay = async () => {
|
||||
try {
|
||||
uni.showLoading({ title: "支付中...", mask: true })
|
||||
const res = await payApi.createQrCodeOrder({
|
||||
merchantId: scanCodeData.id,
|
||||
customPrice: storePrice(Number(amount.value)),
|
||||
walletId: curWalletId.value,
|
||||
})
|
||||
if (res.code != 0) {
|
||||
uni.showToast({ title: res.msg || "支付失败", icon: "error" })
|
||||
if (scanPayState.action === "harQrCodeScanPay") {
|
||||
const { code, msg }: any = await orderApi.doneHardQrCodeScanOrder({
|
||||
orderId: scanPayState.orderId,
|
||||
walletTypeId: selectWallet.value.walletTypeId,
|
||||
})
|
||||
if (code != 0) return uni.showToast({ title: msg || "支付失败", icon: "error" })
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
usePayStore().setPayData({ id: scanCodeData.id, name: scanCodeData.name, customPrice: Number(amount.value).toFixed(2) })
|
||||
router.jump("/pages/pay/payComplete", {}, 2)
|
||||
const { code, msg } = await payApi.createQrCodeOrder({
|
||||
merchantId: scanPayState.mchId,
|
||||
customPrice: storePrice(Number(amount.value)),
|
||||
walletId: selectWallet.value.id,
|
||||
})
|
||||
if (code != 0) return uni.showToast({ title: msg || "支付失败", icon: "error" })
|
||||
}
|
||||
|
||||
uni.hideLoading()
|
||||
usePayStore().setScanPayData({
|
||||
mchId: scanPayState.mchId,
|
||||
mchName: scanPayState.mchName,
|
||||
payPrice: Number(amount.value).toFixed(2),
|
||||
})
|
||||
router.jump("/pages/pay/payComplete", {}, 2)
|
||||
} catch (error: any) {
|
||||
uni.showToast({ title: "请求错误", icon: "error" })
|
||||
uni.hideLoading()
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, reactive } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import NumberKeyboard from "@/sheep/components/numberKeyboard.vue"
|
||||
import NumberKeyboard from "@/sheep/components/number-keyboard.vue"
|
||||
import { payApi, walletApi } from "@/sheep/api"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
|
||||
@@ -96,13 +96,15 @@ const toDetail = async (v: any) => {
|
||||
<view class="sub-text-34">{{ v.name }}</view>
|
||||
<view class="m-t-10rpx">
|
||||
<view class="flex justify-between items-center">
|
||||
<view>
|
||||
<view class="flex-1">
|
||||
<view v-if="v.phone" class="flex items-center">
|
||||
<image class="w-24rpx h-24rpx" src="@/static/page/phone.svg" />
|
||||
<view class="second-text-28 ml-1">{{ v.phone }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<tm-tag size="xs">{{ v.deptName.length > 5 ? v.deptName.substring(0, 5) + "..." : v.deptName }}</tm-tag>
|
||||
<tm-tag class="max-w-160rpx" size="xs">
|
||||
{{ v.deptName.length > 5 ? v.deptName.substring(0, 5) + "..." : v.deptName }}
|
||||
</tm-tag>
|
||||
</view>
|
||||
<view class="second-text-24">
|
||||
<view v-if="v.jobTime != ',,'" class="second-text-28">营业时间:</view>
|
||||
|
||||
+24
-13
@@ -24,19 +24,24 @@
|
||||
<view class="sub-text-34">{{ state.detail.name }}</view>
|
||||
<view class="m-t-10rpx">
|
||||
<view class="flex justify-between items-center">
|
||||
<view>
|
||||
<view v-if="state.detail.phone" class="flex items-center">
|
||||
<view class="flex-1">
|
||||
<view
|
||||
v-if="state.detail.phone"
|
||||
v-for="(item, index) in state.detail.phone.split('/')"
|
||||
:key="index"
|
||||
class="flex items-center"
|
||||
>
|
||||
<image class="w-24rpx h-24rpx" src="@/static/page/phone.svg" />
|
||||
<view class="second-text-28 ml-1">{{ state.detail.phone?.slice(0, 11) }}</view>
|
||||
<view class="second-text-28 ml-1">{{ item.trim() }}</view>
|
||||
<view
|
||||
class="second-text-20 bg-#f8f8f8 ml-1 p-0.3 flex items-center rounded-1 border border-solid border-b-coolGray"
|
||||
@tap="doPhone"
|
||||
@tap="doPhone(item)"
|
||||
>
|
||||
联系商家
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<tm-tag size="xs">
|
||||
<tm-tag class="max-w-160rpx" size="xs">
|
||||
{{ state.detail.deptName?.length > 5 ? state.detail.deptName.substring(0, 5) + "..." : state.detail.deptName }}
|
||||
</tm-tag>
|
||||
</view>
|
||||
@@ -132,13 +137,15 @@
|
||||
import { reactive, nextTick } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
import { router } from "@@/index"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { foodApi, merchantApi, payApi, shopApi } from "@@/api"
|
||||
import { filePath } from "@@/utils/file"
|
||||
import ProductRow from "./components/product-row.vue"
|
||||
import ProductCart from "./components/product-cart.vue"
|
||||
import ProductTotal from "./components/product-total.vue"
|
||||
import ProductSku from "./components/product-sku.vue"
|
||||
import { getAppInfo } from "@/sheep/utils/app"
|
||||
import { APPENV } from "@/sheep/constant"
|
||||
|
||||
// 商品详情相关数据
|
||||
const state = reactive<any>({
|
||||
@@ -331,15 +338,19 @@ const submitPay = async () => {
|
||||
}
|
||||
|
||||
// 联系商家
|
||||
const doPhone = () => {
|
||||
if (isEmpty(state.detail.phone)) {
|
||||
uni.showToast({ title: "该商户没有预留电话", icon: "none" })
|
||||
const doPhone = async (item: string) => {
|
||||
if (isEmpty(item)) return uni.showToast({ title: "该商户没有预留电话", icon: "none" })
|
||||
if ((await getAppInfo()) == APPENV.ZZD) {
|
||||
;(window as any).dd
|
||||
.callPhone({ phoneNum: item.trim() })
|
||||
.then((res) => {})
|
||||
.catch((err) => {})
|
||||
return
|
||||
}
|
||||
if ((await getAppInfo()) == APPENV.SH) {
|
||||
hooks.useMakePhoneCall(item.trim())
|
||||
return
|
||||
}
|
||||
;(window as any).dd
|
||||
.callPhone({ phoneNum: state.detail.phone.slice(0, 11) })
|
||||
.then((res) => {})
|
||||
.catch((err) => {})
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,83 +1,97 @@
|
||||
<template>
|
||||
<crud-layout title="详情" mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<tm-sheet :margin="[0, 20]">
|
||||
<view class="prefix_title mb-15rpx">菜品分类购买数量占比图</view>
|
||||
<view class="w-full h-600rpx">
|
||||
<qiun-data-charts type="pie" :opts="pieChartOpts" :chartData="pieChartData" tooltipFormat="canteenPieTooltip" />
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
<tm-sheet :margin="[0, 20]">
|
||||
<view class="prefix_title mb-15rpx">近一周各食堂购买数量趋势图</view>
|
||||
<view class="w-full h-600rpx">
|
||||
<!-- tooltipFormat="canteenAreaTooltip" -->
|
||||
<qiun-data-charts type="area" :opts="areaChartOpts" :chartData="areaChartData" />
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
<tm-sheet :margin="[0, 20]">
|
||||
<view class="prefix_title mb-15rpx">个人菜品喜好排行</view>
|
||||
<view v-if="productLikeTopList.length > 0" class="rounded-16rpx bg-white overflow-hidden card">
|
||||
<view class="bg-gradient-to-r from-blue-100 to-blue-100 px-20rpx py-16rpx flex items-center border-b border-gray-100">
|
||||
<view class="w-80rpx text-center text-24rpx font-bold text-gray-600">排名</view>
|
||||
<view class="flex-1 px-16rpx text-24rpx font-bold text-gray-600">菜品名称</view>
|
||||
<view class="w-120rpx text-center text-24rpx font-bold text-gray-600">分类</view>
|
||||
<view class="w-160rpx text-center text-24rpx font-bold text-gray-600">购买数量</view>
|
||||
<crud-layout title="喜好分析" bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
hide-empty-view
|
||||
>
|
||||
<tm-sheet :margin="[0, 20]">
|
||||
<view class="prefix_title mb-15rpx">菜品分类购买数量占比图</view>
|
||||
<view class="w-full h-600rpx">
|
||||
<qiun-data-charts type="pie" :opts="pieChartOpts" :chartData="pieChartData" tooltipFormat="canteenPieTooltip" />
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
<view
|
||||
v-for="(item, index) in productLikeTopList"
|
||||
:key="item.productId"
|
||||
class="flex items-center px-20rpx py-16rpx border-b border-gray-50 hover:bg-gray-50 transition-colors"
|
||||
:class="{
|
||||
'bg-gradient-to-r from-yellow-50 to-orange-50': index === 0,
|
||||
'bg-gradient-to-r from-gray-50 to-gray-100': index === 1,
|
||||
'bg-gradient-to-r from-orange-50 to-red-50': index === 2,
|
||||
}"
|
||||
>
|
||||
<view class="w-80rpx flex justify-center items-center">
|
||||
<view
|
||||
v-if="index < 3"
|
||||
class="w-40rpx h-40rpx rounded-1 flex items-center justify-center text-20rpx font-bold text-white"
|
||||
:class="{
|
||||
'bg-gradient-to-r from-yellow-400 to-yellow-500': index === 0,
|
||||
'bg-gradient-to-r from-gray-400 to-gray-500': index === 1,
|
||||
'bg-gradient-to-r from-orange-400 to-orange-500': index === 2,
|
||||
}"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
<tm-sheet :margin="[0, 20]">
|
||||
<view class="prefix_title mb-15rpx">近一周各食堂购买数量趋势图</view>
|
||||
<view class="w-full h-600rpx">
|
||||
<!-- tooltipFormat="canteenAreaTooltip" -->
|
||||
<qiun-data-charts type="area" :opts="areaChartOpts" :chartData="areaChartData" />
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
<tm-sheet :margin="[0, 20]">
|
||||
<view class="prefix_title mb-15rpx">个人菜品喜好排行</view>
|
||||
<view v-if="productLikeTopList.length > 0" class="rounded-16rpx bg-white overflow-hidden card">
|
||||
<view class="bg-gradient-to-r from-blue-100 to-blue-100 px-20rpx py-16rpx flex items-center border-b border-gray-100">
|
||||
<view class="w-80rpx text-center text-24rpx font-bold text-gray-600">排名</view>
|
||||
<view class="flex-1 px-16rpx text-24rpx font-bold text-gray-600">菜品名称</view>
|
||||
<view class="w-120rpx text-center text-24rpx font-bold text-gray-600">分类</view>
|
||||
<view class="w-160rpx text-center text-24rpx font-bold text-gray-600">购买数量</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
v-for="(item, index) in productLikeTopList"
|
||||
:key="item.productId"
|
||||
class="flex items-center px-20rpx py-16rpx border-b border-gray-50 hover:bg-gray-50 transition-colors"
|
||||
:class="{
|
||||
'bg-gradient-to-r from-yellow-50 to-orange-50': index === 0,
|
||||
'bg-gradient-to-r from-gray-50 to-gray-100': index === 1,
|
||||
'bg-gradient-to-r from-orange-50 to-red-50': index === 2,
|
||||
}"
|
||||
>
|
||||
<view class="w-80rpx flex justify-center items-center">
|
||||
<view
|
||||
v-if="index < 3"
|
||||
class="w-40rpx h-40rpx rounded-1 flex items-center justify-center text-20rpx font-bold text-white"
|
||||
:class="{
|
||||
'bg-gradient-to-r from-yellow-400 to-yellow-500': index === 0,
|
||||
'bg-gradient-to-r from-gray-400 to-gray-500': index === 1,
|
||||
'bg-gradient-to-r from-orange-400 to-orange-500': index === 2,
|
||||
}"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</view>
|
||||
<view v-else class="text-24rpx font-medium text-gray-500">{{ index + 1 }}</view>
|
||||
</view>
|
||||
<view v-else class="text-24rpx font-medium text-gray-500">{{ index + 1 }}</view>
|
||||
</view>
|
||||
|
||||
<view class="flex-1 px-16rpx">
|
||||
<view class="text-26rpx font-medium text-gray-800 truncate">{{ item.productName || "未知菜品" }}</view>
|
||||
</view>
|
||||
<view class="flex-1 px-16rpx">
|
||||
<view class="text-26rpx font-medium text-gray-800 truncate">{{ item.productName || "未知菜品" }}</view>
|
||||
</view>
|
||||
|
||||
<view class="w-120rpx text-center">
|
||||
<view class="text-22rpx text-gray-600 truncate">{{ item.classifyName || "未分类" }}</view>
|
||||
</view>
|
||||
<view class="w-120rpx text-center">
|
||||
<view class="text-22rpx text-gray-600 truncate">{{ item.classifyName || "未分类" }}</view>
|
||||
</view>
|
||||
|
||||
<view class="w-160rpx text-center">
|
||||
<view class="px-12rpx py-6rpx bg-blue-100 text-blue-600 text-22rpx rounded-1 whitespace-nowrap">{{ item.payCount }}次</view>
|
||||
<view class="w-160rpx text-center">
|
||||
<view class="px-12rpx py-6rpx bg-blue-100 text-blue-600 text-22rpx rounded-1 whitespace-nowrap">{{ item.payCount }}次</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else class="bg-white rounded-16rpx p-60rpx flex flex-col items-center justify-center">
|
||||
<view class="text-28rpx text-gray-500">暂无菜品喜好数据</view>
|
||||
</view>
|
||||
</tm-sheet>
|
||||
<view v-else class="bg-white rounded-16rpx p-60rpx flex flex-col items-center justify-center">
|
||||
<view class="text-28rpx text-gray-500">暂无菜品喜好数据</view>
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
<view class="h-80rpx" />
|
||||
<view class="h-80rpx" />
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import { ref } from "vue"
|
||||
import qiunDataCharts from "@/components/qiun-data-charts/qiun-data-charts.vue"
|
||||
import { totalApi } from "@/sheep/api"
|
||||
import { hooks } from "@/sheep"
|
||||
|
||||
const pieChartData = ref({})
|
||||
const areaChartData = ref({})
|
||||
@@ -152,16 +166,16 @@ const areaChartOpts = {
|
||||
onLoad(() => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, () => [], null, "")
|
||||
const query = () => {
|
||||
getPieChartData()
|
||||
getAreaChartData()
|
||||
getProductLikeTop()
|
||||
})
|
||||
onShow(() => {
|
||||
getPieChartData()
|
||||
getAreaChartData()
|
||||
getProductLikeTop()
|
||||
})
|
||||
pageHook.startPage()
|
||||
}
|
||||
|
||||
const getPieChartData = async () => {
|
||||
const { code, data, msg } = await totalApi.productByClassify({})
|
||||
|
||||
@@ -11,6 +11,7 @@ const state = reactive<any>({
|
||||
pa: {
|
||||
pagesize: 10,
|
||||
type: "2",
|
||||
name: "",
|
||||
catgoryId: null,
|
||||
},
|
||||
tabs: [{ id: null, name: "全部", disabled: false }],
|
||||
@@ -40,6 +41,10 @@ onShow(() => {
|
||||
pageRef.value && pageRef.value.reload(false)
|
||||
})
|
||||
|
||||
const search = () => {
|
||||
pageRef.value && pageRef.value.reload(true)
|
||||
}
|
||||
|
||||
const doTab = (e: any) => {
|
||||
const target = state.tabs[e]
|
||||
state.pa.catgoryId = target.id
|
||||
@@ -74,12 +79,31 @@ const toDetail = async (v: any) => {
|
||||
>
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
<view class="bg-white rounded-16rpx px-20rpx">
|
||||
<view class="flex w-full">
|
||||
<tm-input
|
||||
class="flex-1"
|
||||
v-model="state.pa.name"
|
||||
type="text"
|
||||
height="66"
|
||||
minHeight="66"
|
||||
fontSize="28"
|
||||
:showClear="true"
|
||||
:focus="false"
|
||||
placeholder="请输入商家名称"
|
||||
style="border: 2rpx solid #0779fd; border-radius: 14rpx"
|
||||
:focus-highlight="false"
|
||||
color="#ECF4F9"
|
||||
>
|
||||
<template v-slot:rightIcon>
|
||||
<tm-button class="mr-1 py-3" size="xs" @click="search">搜索</tm-button>
|
||||
</template>
|
||||
</tm-input>
|
||||
</view>
|
||||
<view class="bg-white rounded-16rpx px-20rpx my-20rpx">
|
||||
<z-tabs :list="state.tabs" @change="doTab" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx my-auto" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
@@ -89,13 +113,13 @@ const toDetail = async (v: any) => {
|
||||
</view>
|
||||
<view class="m-t-10rpx">
|
||||
<view class="flex justify-between items-center">
|
||||
<view>
|
||||
<view class="flex-1">
|
||||
<view v-if="v.phone" class="flex items-center">
|
||||
<image class="w-24rpx h-24rpx" src="@/static/page/phone.svg" />
|
||||
<view class="second-text-28 ml-1">{{ v.phone }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<tm-tag size="xs">{{ v.deptName.length > 5 ? v.deptName.substring(0, 5) + "..." : v.deptName }}</tm-tag>
|
||||
<tm-tag class="max-w-160rpx" size="xs">{{ v.deptName.length > 5 ? v.deptName.substring(0, 5) + "..." : v.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="second-text-24">
|
||||
<view v-if="v.jobTime != ',,'" class="second-text-28">营业时间:</view>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { APPENV } from "@/sheep/constant"
|
||||
import { getAppInfo, getLaunchParam, isDevEnv } from "@/sheep/utils/app"
|
||||
import { onShow } from "@dcloudio/uni-app"
|
||||
|
||||
@@ -57,7 +58,7 @@ const jumpByParam = async () => {
|
||||
const launchParam = getLaunchParam() // 获取启动参数
|
||||
|
||||
// 浙政钉环境
|
||||
if (appInfo == "zzd") {
|
||||
if (appInfo == APPENV.ZZD) {
|
||||
switch (launchParam) {
|
||||
case "canteen": // 食堂
|
||||
uni.setStorageSync("launchParam", launchParam)
|
||||
@@ -87,7 +88,7 @@ const jumpByParam = async () => {
|
||||
}
|
||||
|
||||
// 诗画环境
|
||||
if (appInfo == "sh") {
|
||||
if (appInfo == APPENV.SH) {
|
||||
const userRole = uni.getStorageSync("userRole") // 获取用户角色
|
||||
|
||||
if (!launchParam) return uni.hideTabBar()
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
:quickDate="[]"
|
||||
drawerSize="900"
|
||||
>
|
||||
<view class="w-100rpx text-center second-text-28 text-30 mb-4rpx">筛选</view>
|
||||
<view class="mb-6rpx flex items-center gap-1">
|
||||
<image class="w-[30rpx] h-[30rpx]" src="@/static/page/filter.svg" />
|
||||
<view class="text-center second-text-28 text-30 whitespace-nowrap">筛选</view>
|
||||
</view>
|
||||
</tm-between-time>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
+15
-13
@@ -3,13 +3,10 @@
|
||||
<tm-sticky>
|
||||
<tm-sticky-header>
|
||||
<view class="flex-row items-center bg-#ECF4F9 py-3">
|
||||
<image
|
||||
v-if="state.userInfo?.sysUser?.avatar"
|
||||
class="w-100rpx h-100rpx rounded-full"
|
||||
:src="filePath(state.userInfo.sysUser.avatar)"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<image v-else class="w-100rpx h-100rpx rounded-full" src="/static/icon/default-avatar.png" mode="aspectFill" />
|
||||
<image v-if="state.userInfo?.sysUser?.avatar" class="w-100rpx h-100rpx rounded-full"
|
||||
:src="filePath(state.userInfo.sysUser.avatar)" mode="aspectFill" />
|
||||
<image v-else class="w-100rpx h-100rpx rounded-full" src="/static/icon/default-avatar.png"
|
||||
mode="aspectFill" />
|
||||
<view class="m-l-30rpx" v-if="state.userInfo?.sysUser?.userId">
|
||||
<view class="flex-row items-center">
|
||||
<text class="sub-text-30">{{ state.userInfo?.sysUser?.name }}</text>
|
||||
@@ -25,7 +22,8 @@
|
||||
</tm-sticky-header>
|
||||
|
||||
<view class="m-t-10rpx rounded-20rpx shadow-main p-30rpx p-b-40rpx bg-white!">
|
||||
<view class="service_item flex-row items-center justify-between" v-for="(v, i) in state.menuList" :key="i" @tap="onTabMenu(v)">
|
||||
<view class="service_item flex-row items-center justify-between" v-for="(v, i) in state.menuList"
|
||||
:key="i" @tap="onTabMenu(v)">
|
||||
<view class="flex-row-center">
|
||||
<image class="w-40rpx h-40rpx" :src="v.icon" mode="aspectFill" />
|
||||
<text class="sub-text-28 m-l-20rpx">{{ v.text }}</text>
|
||||
@@ -35,13 +33,15 @@
|
||||
</view>
|
||||
|
||||
<view v-if="isDevEnv()" 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="doLogout">
|
||||
<view class="w-full text-center sub-text-28 p-y-20rpx rounded-40rpx border-solid border border-#0094ff"
|
||||
@tap="doLogout">
|
||||
退出登录
|
||||
</view>
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
<view v-if="state.appInfo == '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 v-if="state.appInfo == APPENV.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>
|
||||
@@ -68,6 +68,7 @@ import { getAppInfo } from "@@/utils/app"
|
||||
import { hooks, router, constant } from "@@/index"
|
||||
import { userApi } from "@@/api"
|
||||
import { isDevEnv } from "@/sheep/utils/app"
|
||||
import { APPENV } from "@/sheep/constant"
|
||||
|
||||
const state = reactive<{
|
||||
wallet: any[]
|
||||
@@ -85,6 +86,7 @@ const state = reactive<{
|
||||
{ text: "扫一扫", icon: "/static/icon/scan.png", router: "" },
|
||||
{ text: "钱包管理", icon: "/static/icon/service_3.png", router: "/pages/wallet/list" },
|
||||
{ text: "人脸管理", icon: "/static/icon/service_5.png", router: "/pages/human-face/list" },
|
||||
// { text: "车辆管理", icon: "/static/icon/service_6.png", router: "/pages/car/userCar/list" },
|
||||
{ text: "清除缓存", icon: "/static/icon/clear-storage.png", router: "" },
|
||||
],
|
||||
appInfo: "",
|
||||
@@ -300,11 +302,11 @@ const scanCode = {
|
||||
uni.showModal({ content: "开发环境不是浙政钉和诗画环境,扫码仅供测试,收款商家为测试商户超市" })
|
||||
|
||||
return testQrCode
|
||||
} else if (state.appInfo == "zzd") {
|
||||
} else if (state.appInfo == APPENV.ZZD) {
|
||||
// 浙政钉扫码
|
||||
const res: any = await (window as any).dd.scan({ type: "all" })
|
||||
return res.text
|
||||
} else if (state.appInfo == "sh") {
|
||||
} else if (state.appInfo == APPENV.SH) {
|
||||
// 诗画扫码
|
||||
const res = await (window as any).CP2.showScanQr({ needResult: 1 })
|
||||
if (res.code == 1) return res.data.qrCode
|
||||
|
||||
@@ -29,39 +29,39 @@
|
||||
class="flex-1"
|
||||
v-model="state.params.keyword"
|
||||
type="text"
|
||||
:height="66"
|
||||
:minHeight="66"
|
||||
:fontSize="28"
|
||||
height="72"
|
||||
minHeight="72"
|
||||
fontSize="28"
|
||||
:showClear="true"
|
||||
:focus="false"
|
||||
placeholder="请输入商品名称"
|
||||
style="border: 2rpx solid #0779fd; border-radius: 14rpx"
|
||||
style="border: 4rpx solid #0779fd; border-radius: 14rpx"
|
||||
:focus-highlight="false"
|
||||
color="#ECF4F9"
|
||||
>
|
||||
<template v-slot:rightIcon>
|
||||
<tm-button class="mr-1 py-3" size="xs" @click="searchProduct">搜索</tm-button>
|
||||
<tm-button class="mr-1 px-3 py-26rpx text-30rpx!" size="xs" @click="searchProduct">搜 索</tm-button>
|
||||
</template>
|
||||
</tm-input>
|
||||
<tm-badge bg-color="red" :offset="[8, 4]" :label="cartStore.totCount">
|
||||
<view class="flex-col-center size-80rpx" @tap="doCart">
|
||||
<view class="color-#0094ff! iconfont icon-biaoqianlanicon_gouwuche-xuanzhong" />
|
||||
<view class="c-#0094ff text-20rpx">购物车</view>
|
||||
<view class="c-#0094ff text-22rpx">购物车</view>
|
||||
</view>
|
||||
</tm-badge>
|
||||
</view>
|
||||
|
||||
<scroll-view scroll-x class="whitespace-nowrap my-2">
|
||||
<tm-tag
|
||||
class="mr-2"
|
||||
size="s"
|
||||
:skin="state.params.categoryId == v.id ? 'normal' : 'outlined'"
|
||||
v-for="(v, i) in state.classifyList"
|
||||
:key="i"
|
||||
@tap="doClassify(v.id)"
|
||||
>
|
||||
{{ v.name }}
|
||||
</tm-tag>
|
||||
<scroll-view scroll-x>
|
||||
<view class="w-full flex my-2">
|
||||
<view
|
||||
class="mr-2 sub-text-28 py-1 px-2 rounded-1 bg-#fff border border-solid border-transparent"
|
||||
:class="{ 'bg-#0779FD22! c-#0779FD! border-#0779FD33!': state.params.categoryId === v.id }"
|
||||
v-for="(v, i) in state.classifyList"
|
||||
:key="i"
|
||||
@tap="doClassify(v.id)"
|
||||
>
|
||||
{{ v.name }}
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
:hasAroundGutter="false"
|
||||
backgroundColor="#ffffff00"
|
||||
:crossOrigin="false"
|
||||
:animationCancel="true"
|
||||
:animationCancel="false"
|
||||
>
|
||||
<template #default="{ item, url, index }">
|
||||
<view class="card" @click="toDetail(item)">
|
||||
|
||||
+30
-28
@@ -93,61 +93,63 @@ const doRefund = (v: any) => {
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
<view class="bg-white rounded-16rpx px-20rpx">
|
||||
<view class="bg-white rounded-16rpx px-20rpx my-20rpx">
|
||||
<z-tabs :list="data.tabs" @change="doTab" />
|
||||
</view>
|
||||
</template>
|
||||
<view class="h-20rpx" />
|
||||
|
||||
<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-110rpx h-110rpx rounded-8rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 m-l-20rpx">
|
||||
<view class="flex-row">
|
||||
<image class="w-80rpx h-80rpx rounded-8rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<view class="flex-1 ml-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row items-center">
|
||||
<view class="main-text-28">{{ v.merchantName }}</view>
|
||||
<!-- <view class="m-l-15rpx color-#999 font-size-26rpx! iconfont icon-youjiantou" /> -->
|
||||
</view>
|
||||
<view class="main-text-28">{{ v.merchantName }}</view>
|
||||
<!-- <view class="m-l-15rpx color-#999 font-size-26rpx! iconfont icon-youjiantou" /> -->
|
||||
<tm-tag v-if="v.orderStatus == 1" color="info" size="xs">未支付</tm-tag>
|
||||
<tm-tag v-if="v.orderStatus == 5" color="success" size="xs">已支付</tm-tag>
|
||||
<tm-tag v-if="v.orderStatus == 10" color="error" size="xs">售后</tm-tag>
|
||||
<tm-tag v-if="v.orderStatus == 20" size="xs">已核销</tm-tag>
|
||||
<tm-tag v-if="v.orderStatus == 30" color="info" size="xs">已取消(智能柜)</tm-tag>
|
||||
</view>
|
||||
<view class="flex-row items-center justify-between m-t-5rpx">
|
||||
<view class="flex-row items-center justify-between mt-5rpx">
|
||||
<view class="second-text-20">
|
||||
<text>下单时间</text>
|
||||
<text class="m-l-10rpx">{{ hooks.useTime(v.createTime, "{y}-{m}-{d} {h}:{i}:{s}") }}</text>
|
||||
</view>
|
||||
<view class="second-text-22">{{ hooks.useEnum("hardwareRefundStatusEnum", v.refundStatus) }}</view>
|
||||
</view>
|
||||
<view class="flex-row items-center justify-between m-t-5rpx">
|
||||
<view class="sub-text-24">
|
||||
<view class="flex-row items-center justify-end mt-5rpx">
|
||||
<!-- <view class="sub-text-24">
|
||||
<text v-if="v.payType == '9'">{{ v.productDesc?.replaceAll(";", "\;\n") }}</text>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="main-text-30 whitespace-nowrap color-red! text-right">¥ {{ hooks.useMoney(v.totalPrice) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex items-center ml-[120rpx]">
|
||||
<scroll-view v-if="['5', '20'].includes(v.orderStatus) && v.orderType == 2" scroll-x class="flex-row-center whitespace-nowrap">
|
||||
<view class="flex-row items-center">
|
||||
<view class="inline-flex! flex-col items-center m-r-20rpx" v-for="(pV, pI) in v.carList" :key="pI">
|
||||
<image class="w-60rpx h-60rpx rounded-8rpx" :src="filePath(pV.productPic)" mode="aspectFill" />
|
||||
<view class="w-80rpx m-t-10rpx sub-text-24 show-line text-center">{{ pV.productName }}</view>
|
||||
|
||||
<view class="flex items-center ml-[20rpx] overflow-hidden gap-2">
|
||||
<view class="w-4/5">
|
||||
<scroll-view v-if="['5', '20'].includes(v.orderStatus) && ['1', '2'].includes(v.orderType)" scroll-x>
|
||||
<view class="flex-row">
|
||||
<view class="flex-col justify-start items-center mr-20rpx" v-for="(pV, pI) in v.carList" :key="pI">
|
||||
<image v-if="v.payType == '9'" class="w-80rpx h-80rpx rounded-8rpx" :src="pV.productPic" mode="aspectFill" />
|
||||
<image v-else class="w-80rpx h-80rpx rounded-8rpx" :src="filePath(pV.productPic)" mode="aspectFill" />
|
||||
<view class="mt-10rpx sub-text-24 text-center min-w-120rpx max-w-200rpx">{{ pV.productName }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view
|
||||
v-if="v.carList?.length && ['5', '20'].includes(v.orderStatus) && v.orderType == 2"
|
||||
class="w-200rpx m-x-10rpx second-text-26"
|
||||
v-if="v.carList?.length && ['5', '20'].includes(v.orderStatus) && ['1', '2'].includes(v.orderType)"
|
||||
class="w-1/5 second-text-26 truncate text-center"
|
||||
>
|
||||
共 {{ v.carList.length }} 件
|
||||
</view>
|
||||
<view v-if="['5', '10'].includes(v.orderStatus)" class="w-500rpx flex-row items-center justify-end">
|
||||
<!-- <view v-if="v.orderStatus == 5 && v.orderType == 2" class="botder_btn" @tap.stop="doRefund(v)">退款</view> -->
|
||||
<view v-if="v.orderStatus == 5 && v.orderType == 2" class="m-l-20rpx botder_btn" @tap.stop="doToDetail(v)">核销码</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="['5', '10'].includes(v.orderStatus)" class="w-full flex-row items-center justify-end my-1">
|
||||
<!-- <view v-if="v.orderStatus == 5 && v.orderType == 2" class="botder_btn" @tap.stop="doRefund(v)">退款</view> -->
|
||||
<view v-if="v.orderStatus == 5 && v.orderType == 2" class="m-l-20rpx botder_btn" @tap.stop="doToDetail(v)">核销码</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
<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"
|
||||
>
|
||||
<template #top>
|
||||
<view class="flex justify-between items-center my-1">
|
||||
<tm-text font-size="40" color="#0779FD" class="font-bold">共富商城</tm-text>
|
||||
<tm-text font-size="30" color="#0779FD">优质商户,品质商品,欢迎联系购买</tm-text>
|
||||
</view>
|
||||
<view class="w-full flex items-center">
|
||||
<tm-input
|
||||
class="flex-1"
|
||||
v-model="state.params.keyword"
|
||||
type="text"
|
||||
height="72"
|
||||
minHeight="72"
|
||||
fontSize="28"
|
||||
:showClear="true"
|
||||
:focus="false"
|
||||
placeholder="请输入超市名称"
|
||||
style="border: 4rpx solid #0779fd; border-radius: 14rpx"
|
||||
:focus-highlight="false"
|
||||
color="#ECF4F9"
|
||||
>
|
||||
<template v-slot:rightIcon>
|
||||
<tm-button class="mr-1 px-3 py-26rpx text-30rpx!" size="xs" @click="search">搜 索</tm-button>
|
||||
</template>
|
||||
</tm-input>
|
||||
</view>
|
||||
|
||||
<scroll-view scroll-x>
|
||||
<view class="w-full flex my-2">
|
||||
<view
|
||||
class="mr-2 sub-text-28 py-1 px-2 rounded-1 bg-#fff border border-solid border-transparent"
|
||||
:class="{ 'bg-#0779FD22! c-#0779FD! border-#0779FD33!': state.params.categoryId === v.id }"
|
||||
v-for="(v, i) in state.classifyList"
|
||||
:key="i"
|
||||
@tap="doClassify(v.id)"
|
||||
>
|
||||
{{ v.name }}
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<view class="card p-20rpx mb-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<view class="flex">
|
||||
<image class="w-150rpx h-150rpx rounded-12rpx" :src="filePath(v.images)" mode="aspectFill" />
|
||||
<view class="ml-20rpx flex-1 overflow-hidden">
|
||||
<view class="sub-text-30 truncate">{{ v.name }}</view>
|
||||
<view class="second-text-26 truncate">
|
||||
<text class="mr-20rpx">{{ v.contactName }}</text>
|
||||
<text class="mr-20rpx">
|
||||
<image class="w-24rpx h-24rpx mr-1" src="@/static/page/phone.svg" />
|
||||
<text @tap="doPhone(v.contactPhone)">{{ v.contactPhone }}</text>
|
||||
</text>
|
||||
<text>{{ v.email }}</text>
|
||||
</view>
|
||||
<view class="sub-text-26 truncate">
|
||||
<text class="bg-#0779FD11 py-1 rounded-2 c-#0094ff">营业:{{ v.businessHours }}</text>
|
||||
</view>
|
||||
<view class="second-text-26">
|
||||
<image class="w-24rpx h-24rpx mr-1" src="@/static/page/address.svg" />
|
||||
<text>{{ v.address }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-x>
|
||||
<view class="flex mt-2">
|
||||
<view class="w-160rpx flex-col items-center mr-20rpx" v-for="(pV, pI) in v.featuredProducts" :key="pI">
|
||||
<image class="w-160rpx h-160rpx rounded-12rpx" :src="filePath(pV.coverImage)" mode="aspectFill" />
|
||||
<view class="w-full mt-4rpx sub-text-24 truncate">{{ pV.title }}</view>
|
||||
<view class="w-full flex justify-between pr-1">
|
||||
<text class="main-text-26 color-red!">
|
||||
<text class="text-22rpx">¥</text>
|
||||
<text>{{ pV.spuPrice.toFixed(2) }}</text>
|
||||
</text>
|
||||
<text class="sub-text-24">{{ pV.unit || "" }}</text>
|
||||
</view>
|
||||
<view class="w-full flex justify-between pr-1">
|
||||
<text class="second-text-24 line-through">
|
||||
<text class="text-22rpx">¥</text>
|
||||
<text>{{ pV.originalPrice.toFixed(2) }}</text>
|
||||
</text>
|
||||
<text class="second-text-24">库存{{ pV.totalStock }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { hooks, router } from "@/sheep"
|
||||
import { onlineShopApi, prosperityShopApi } from "@/sheep/api"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
import { reactive, ref } from "vue"
|
||||
import { filePath } from "@@/utils/file"
|
||||
import { getAppInfo } from "@/sheep/utils/app"
|
||||
import { APPENV } from "@/sheep/constant"
|
||||
|
||||
const state = reactive<any>({
|
||||
params: {
|
||||
categoryId: "",
|
||||
keyword: "",
|
||||
},
|
||||
classifyList: [],
|
||||
shopList: [],
|
||||
})
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, prosperityShopApi.getShopList, null, "data")
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.params)
|
||||
}
|
||||
|
||||
onLoad(async () => {
|
||||
const app = getApp()
|
||||
app._initTabbar()
|
||||
|
||||
await getClassify()
|
||||
})
|
||||
|
||||
// 获取分类
|
||||
const getClassify = async () => {
|
||||
const { data } = await onlineShopApi.getSpuCategory()
|
||||
state.classifyList = treeToList(data) ?? []
|
||||
state.classifyList.unshift({ id: "", name: "全部分类" })
|
||||
if (!isEmpty(state.classifyList)) {
|
||||
state.params.categoryId = state.classifyList[0].id
|
||||
}
|
||||
}
|
||||
const treeToList = <T extends { children?: T[] }>(tree: T[], result: T[] = []): T[] => {
|
||||
for (const node of tree) {
|
||||
result.push(node)
|
||||
if (node?.children?.length) {
|
||||
treeToList(node.children, result)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 切换分类
|
||||
const doClassify = async (categoryId: string) => {
|
||||
if (state.params.categoryId == categoryId) return
|
||||
state.params.categoryId = categoryId
|
||||
pageRef.value && pageRef.value.reload(true)
|
||||
}
|
||||
|
||||
// 点击搜索
|
||||
const search = () => {
|
||||
state.params.categoryId = ""
|
||||
pageRef.value && pageRef.value.reload(true)
|
||||
}
|
||||
|
||||
// 联系商家
|
||||
const doPhone = async (item: string) => {
|
||||
if (isEmpty(item)) return uni.showToast({ title: "该商户没有预留电话", icon: "none" })
|
||||
if ((await getAppInfo()) == APPENV.ZZD) {
|
||||
;(window as any).dd
|
||||
.callPhone({ phoneNum: item.trim() })
|
||||
.then((res) => {})
|
||||
.catch((err) => {})
|
||||
return
|
||||
}
|
||||
if ((await getAppInfo()) == APPENV.SH) {
|
||||
hooks.useMakePhoneCall(item.trim())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 超市详情
|
||||
const toDetail = async (v: any) => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
// router.jump("/pages/shop/detail", { id: v.id })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
+20
-56
@@ -29,7 +29,7 @@ const freezeForm = reactive<any>({
|
||||
remark: "",
|
||||
})
|
||||
|
||||
onLoad(() => {})
|
||||
onLoad(() => { })
|
||||
onShow(async () => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (!isLogin) return
|
||||
@@ -140,35 +140,22 @@ const doTransferMoney = (v: any) => {
|
||||
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="5"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="5"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
<view class="h-30rpx" />
|
||||
<view
|
||||
class="card flex-col rounded-20rpx p-x-30rpx p-y-20rpx m-b-30rpx"
|
||||
v-for="(v, i) in pageHook.list"
|
||||
:key="i"
|
||||
@tap="router.jump('/pages/wallet/detail', { id: v.id })"
|
||||
>
|
||||
<view class="card flex-col rounded-20rpx p-x-30rpx p-y-20rpx m-b-30rpx" v-for="(v, i) in pageHook.list"
|
||||
:key="i" @tap="router.jump('/pages/wallet/detail', { id: v.id })">
|
||||
<view class="flex-col">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center">
|
||||
<text v-if="v.cardNumber" class="second-text-28">卡号: {{ v.cardNumber }}</text>
|
||||
</view>
|
||||
<view class="second-text-50">
|
||||
<text v-if="v.cardNumber" class="iconfont icon-fuzhi" @tap.stop="hooks.useCopy(v.cardNumber)" />
|
||||
<text v-if="v.walletTypeUniqueCode != '2'" class="m-l-20rpx iconfont icon-erweima" @tap.stop="doPreviewQrCode(v)" />
|
||||
<text v-if="v.cardNumber" class="iconfont icon-fuzhi"
|
||||
@tap.stop="hooks.useCopy(v.cardNumber)" />
|
||||
<text v-if="v.walletTypeUniqueCode != '2'" class="m-l-20rpx iconfont icon-erweima"
|
||||
@tap.stop="doPreviewQrCode(v)" />
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="v.cardNumber" class="h-1px m-t-10rpx bg-#999 bg-opacity-5" />
|
||||
@@ -191,14 +178,12 @@ const doTransferMoney = (v: any) => {
|
||||
<view class="flex-row items-center justify-end space-x-20rpx m-t-10rpx">
|
||||
<!-- <view v-if="v.walletTypeUniqueCode == 1 && !v.cardNumber" class="botder_btn" @tap.stop="openBindDialog(v)">绑定</view> -->
|
||||
<view v-if="v.isRule == '1'" class="botder_btn" @tap.stop="doTransferMoney(v)">转账</view>
|
||||
<view v-if="v.walletTypeUniqueCode == 1 && v.cardNumber && v.isFreeze != 1" class="botder_btn" @tap.stop="openFreezeDialog(v)">
|
||||
<view v-if="v.walletTypeUniqueCode == 1 && v.cardNumber && v.isFreeze != 1" class="botder_btn"
|
||||
@tap.stop="openFreezeDialog(v)">
|
||||
申请冻结
|
||||
</view>
|
||||
<view
|
||||
v-if="false && v.walletTypeUniqueCode == 2"
|
||||
class="botder_btn"
|
||||
@tap.stop="router.jump('/pages/wallet/recharge', { id: v.id })"
|
||||
>
|
||||
<view v-if="false && v.walletTypeUniqueCode == 2" class="botder_btn"
|
||||
@tap.stop="router.jump('/pages/wallet/recharge', { id: v.id })">
|
||||
去充值
|
||||
</view>
|
||||
</view>
|
||||
@@ -206,15 +191,8 @@ const doTransferMoney = (v: any) => {
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
|
||||
<tm-drawer
|
||||
z-index="100"
|
||||
v-model:show="state.showBindDialog"
|
||||
:overlayClick="false"
|
||||
title="绑定饭卡"
|
||||
:show-close="true"
|
||||
position="bottom"
|
||||
size="40%"
|
||||
>
|
||||
<tm-drawer z-index="100" v-model:show="state.showBindDialog" :overlayClick="false" title="绑定饭卡" :show-close="true"
|
||||
position="bottom" size="40%">
|
||||
<view class="h-50rpx" />
|
||||
<tm-form ref="bindFormRef" v-model="bindForm" :rules="bindFormRules">
|
||||
<tm-form-item name="cardNumber" :showLabel="false" :showBottom="false">
|
||||
@@ -224,15 +202,8 @@ const doTransferMoney = (v: any) => {
|
||||
<view class="h-50rpx" />
|
||||
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx sub-text-30 color-white!" @tap="doBind">绑定</view>
|
||||
</tm-drawer>
|
||||
<tm-drawer
|
||||
z-index="100"
|
||||
v-model:show="state.showFreezeDialog"
|
||||
:overlayClick="false"
|
||||
title="申请冻结"
|
||||
:show-close="true"
|
||||
position="bottom"
|
||||
size="40%"
|
||||
>
|
||||
<tm-drawer z-index="100" v-model:show="state.showFreezeDialog" :overlayClick="false" title="申请冻结" :show-close="true"
|
||||
position="bottom" size="40%">
|
||||
<view class="h-50rpx" />
|
||||
<tm-form ref="bindFormRef" v-model="freezeForm">
|
||||
<tm-form-item name="remark" :showLabel="false" :showBottom="false">
|
||||
@@ -242,15 +213,8 @@ const doTransferMoney = (v: any) => {
|
||||
<view class="h-50rpx" />
|
||||
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx sub-text-30 color-white!" @tap="doFreeze">冻结</view>
|
||||
</tm-drawer>
|
||||
<tm-drawer
|
||||
z-index="100"
|
||||
v-model:show="state.showQrCodeDialog"
|
||||
:overlayClick="false"
|
||||
title="钱包二维码"
|
||||
:show-close="true"
|
||||
position="bottom"
|
||||
size="50%"
|
||||
>
|
||||
<tm-drawer z-index="100" v-model:show="state.showQrCodeDialog" :overlayClick="false" title="钱包二维码"
|
||||
:show-close="true" position="bottom" size="50%">
|
||||
<view class="flex-col-center">
|
||||
<view class="h-80rpx" />
|
||||
<canvas canvas-id="qrcodeId" class="size-200px" />
|
||||
|
||||
@@ -38,4 +38,8 @@ export { default as noticeApi } from "./notice"
|
||||
|
||||
export { default as invitationApi } from "./invitation"
|
||||
|
||||
export { default as totalApi } from "./total"
|
||||
export { default as totalApi } from "./total"
|
||||
|
||||
export { default as userCarApi } from "./userCar"
|
||||
|
||||
export { default as prosperityShopApi } from "./prosperityShop"
|
||||
@@ -16,7 +16,7 @@ export default {
|
||||
data,
|
||||
}),
|
||||
|
||||
// 获取访客邀约列表
|
||||
// 获取访客邀约记录列表
|
||||
// type为1:主动申请 type为2:邀约 type为3:后台创建
|
||||
getInvitationRecord: (params: { current: number; size: number; checkStatus?: string; type?: number }): Promise<any> =>
|
||||
request({
|
||||
|
||||
@@ -33,4 +33,15 @@ export default {
|
||||
url: "/hard/hard-appt/app/list",
|
||||
method: "GET",
|
||||
}),
|
||||
/**
|
||||
* 用户确认设备二维码扫一扫订单
|
||||
* @param orderId 订单id
|
||||
* @param walletTypeId 钱包类型ID
|
||||
*/
|
||||
doneHardQrCodeScanOrder: (data: any) =>
|
||||
request({
|
||||
url: "/hard/hard-api/ad/done-hard-qr-code-order",
|
||||
method: "POST",
|
||||
data,
|
||||
}),
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
// 获取超市列表
|
||||
getShopList: (params: { productLimit: number }): Promise<any> => {
|
||||
return request({
|
||||
url: "/supermarket/app/mall/merchant/list",
|
||||
method: "GET",
|
||||
params: { productLimit: 5 },
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
/**
|
||||
* 申请车
|
||||
*/
|
||||
apply: (data: any) =>
|
||||
request({
|
||||
url: `/admin/sysUserCar/app/create`,
|
||||
method: "POST",
|
||||
data,
|
||||
}),
|
||||
/**
|
||||
* 车列表
|
||||
*/
|
||||
page: (data: any) =>
|
||||
request({
|
||||
url: `/admin/sysUserCar/app/page`,
|
||||
method: "POST",
|
||||
data,
|
||||
}),
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
+1
-1
@@ -36,7 +36,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch, computed, onUnmounted } from "vue"
|
||||
import { ref, reactive, watch, onUnmounted } from "vue"
|
||||
import { userApi } from "@@/api"
|
||||
|
||||
const props = withDefaults(
|
||||
@@ -1,5 +1,5 @@
|
||||
import { h, render } from "vue"
|
||||
import VerifyDeviceImpModel from "./verifyDeviceImpModel.vue"
|
||||
import VerifyDeviceImpModel from "./verify-device-imp-model.vue"
|
||||
|
||||
let VerifyDeviceImpModelInstance: boolean | null = null
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* ZZD:浙政钉 | SH:诗画
|
||||
*/
|
||||
export default {
|
||||
ZZD: "zzd",
|
||||
SH: "sh",
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
export { default as serviceEnum } from "./service-enum"
|
||||
|
||||
export { default as storageConstant } from "./storage-constant"
|
||||
|
||||
export { default as APPENV } from "./app-env"
|
||||
@@ -36,6 +36,13 @@ const hardwareRefundStatusEnum = {
|
||||
30: "售后失败",
|
||||
}
|
||||
|
||||
const carTypeEnum = {
|
||||
1: "私家车",
|
||||
2: "公车",
|
||||
3: "军车",
|
||||
4: "警车",
|
||||
}
|
||||
|
||||
const boxesBxStatusEnum = {
|
||||
"0": "今日空闲",
|
||||
"1": "今日部分空闲",
|
||||
@@ -49,4 +56,5 @@ export default {
|
||||
boxesBxStatusEnum,
|
||||
hardwareSaleStatusEnum,
|
||||
hardwareRefundStatusEnum,
|
||||
carTypeEnum,
|
||||
}
|
||||
+17
-4
@@ -1,16 +1,29 @@
|
||||
import { defineStore } from "pinia"
|
||||
|
||||
type State = {
|
||||
scanPayData: {
|
||||
mchId: string
|
||||
mchName: string
|
||||
payPrice: number | string
|
||||
}
|
||||
sourceWalletData: any
|
||||
}
|
||||
|
||||
export const usePayStore = defineStore("pay", {
|
||||
state: (): { payData: { id?: string; name?: string; customPrice?: number }; sourceWalletData: any } => {
|
||||
state: (): State => {
|
||||
return {
|
||||
payData: {},
|
||||
scanPayData: {
|
||||
mchId: "",
|
||||
mchName: "",
|
||||
payPrice: 0,
|
||||
},
|
||||
sourceWalletData: {},
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
// 支付
|
||||
setPayData(data: any) {
|
||||
this.payData = data
|
||||
setScanPayData(data: any) {
|
||||
this.scanPayData = data
|
||||
},
|
||||
// 转账
|
||||
setSourceWalletData(data: any) {
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// app运行环境
|
||||
|
||||
import { APPENV } from "../constant"
|
||||
|
||||
// export default () => import.meta.env.VITE_DEV_ENV === "dev"
|
||||
export const isDevEnv = (): boolean => process.env.NODE_ENV === "development"
|
||||
|
||||
@@ -14,11 +17,11 @@ export const getAppInfo = async (): Promise<string> => {
|
||||
// 浙政钉环境
|
||||
if (res.code === 0) {
|
||||
console.log("环境:浙政钉-zzd")
|
||||
return "zzd"
|
||||
return APPENV.ZZD
|
||||
} else {
|
||||
// 诗画环境
|
||||
console.log("环境:诗画浦江-sh")
|
||||
return "sh"
|
||||
return APPENV.SH
|
||||
}
|
||||
} catch (error) {
|
||||
return "unknown"
|
||||
|
||||
@@ -4,6 +4,7 @@ import { isEmpty } from "radash"
|
||||
import { getAppInfo, isDevEnv } from "@@/utils/app"
|
||||
import { userApi } from "../api"
|
||||
import showVerifyDeviceImpModel from "../components/verifyDeviceImpModel/verifyDeviceImpModel"
|
||||
import { APPENV } from "../constant"
|
||||
|
||||
const TOKEN_KEY = constant.storageConstant.TOKEN
|
||||
const USER_INFO_KEY = constant.storageConstant.USERINFO
|
||||
@@ -27,8 +28,8 @@ const processQueue = (error: any, token: any = null) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 创建http请求实例
|
||||
const http = new Request({
|
||||
// 创建https请求实例
|
||||
const https = new Request({
|
||||
baseURL: import.meta.env.VITE_API_URL,
|
||||
timeout: 15000,
|
||||
method: "GET",
|
||||
@@ -47,7 +48,21 @@ const http = new Request({
|
||||
},
|
||||
})
|
||||
|
||||
http.interceptors.request.use(async (config) => {
|
||||
// 生产环境协议安全检查
|
||||
const validateProductionSecurity = () => {
|
||||
if (isDevEnv()) return
|
||||
|
||||
const apiUrl = import.meta.env.VITE_API_URL
|
||||
if (apiUrl && !apiUrl.startsWith("https://")) {
|
||||
uni.showToast({ title: "生产环境安全错误: 必须使用 HTTPS 协议", icon: "error" })
|
||||
throw new Error("生产环境禁止使用 HTTP 协议")
|
||||
}
|
||||
}
|
||||
|
||||
https.interceptors.request.use(async (config) => {
|
||||
// 生产环境协议检查
|
||||
// validateProductionSecurity()
|
||||
|
||||
const tokenStorage = uni.getStorageSync(TOKEN_KEY)
|
||||
const config_header: any = config.header || {}
|
||||
|
||||
@@ -84,7 +99,7 @@ http.interceptors.request.use(async (config) => {
|
||||
}, Promise.reject)
|
||||
|
||||
// 响应拦截器
|
||||
http.interceptors.response.use(
|
||||
https.interceptors.response.use(
|
||||
async (response) => {
|
||||
// 账号密码登录响应结果特殊处理
|
||||
if (response.config.url === "/auth/oauth2/token") {
|
||||
@@ -113,7 +128,7 @@ http.interceptors.response.use(
|
||||
const config = error.config
|
||||
const tokenValue = getTokenValue(newTokenStorage)
|
||||
if (tokenValue && config.header) config.header.Authorization = tokenValue
|
||||
return http.request(config)
|
||||
return https.request(config)
|
||||
}
|
||||
} catch (err) {
|
||||
return Promise.reject(err)
|
||||
@@ -196,9 +211,9 @@ async function refreshToken(): Promise<any> {
|
||||
const autoLogin = async (): Promise<boolean> => {
|
||||
const appInfo = await getAppInfo()
|
||||
// 浙政钉环境
|
||||
if (appInfo == "zzd") return await loginByZzd()
|
||||
if (appInfo == APPENV.ZZD) return await loginByZzd()
|
||||
// 诗画环境
|
||||
if (appInfo == "sh") return await loginBySh()
|
||||
if (appInfo == APPENV.SH) return await loginBySh()
|
||||
|
||||
uni.showToast({ title: "app环境错误", icon: "none" })
|
||||
return false
|
||||
@@ -284,7 +299,7 @@ async function loginBySh(): Promise<boolean> {
|
||||
|
||||
// 请求函数
|
||||
const request = (config: any) => {
|
||||
return http.middleware(config)
|
||||
return https.middleware(config)
|
||||
}
|
||||
|
||||
export default request
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
@@ -9,6 +9,12 @@ import { useRouter } from "./src/sheep"
|
||||
export default defineConfig(({ mode }) => {
|
||||
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
|
||||
|
||||
// 生产环境强制 HTTPS 检查
|
||||
if (NODE_ENV === "production" && baseUrl && !baseUrl.startsWith("https://")) {
|
||||
throw new Error("生产环境必须使用 HTTPS 协议!请检查 VITE_APP_PROD_SERVICE 配置")
|
||||
}
|
||||
|
||||
return {
|
||||
build: {
|
||||
target: "es6",
|
||||
@@ -40,6 +46,8 @@ export default defineConfig(({ mode }) => {
|
||||
ws: true,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, ""),
|
||||
// 生产环境强制 HTTPS 验证
|
||||
...(NODE_ENV === "production" && { secure: true }),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user