# Conflicts:
#	.env
This commit is contained in:
zjf committed 2025-04-10 10:00:21 +08:00
commit 6ca457aa74
58 files changed
+3434 -2302

No files matched your search

+56 -43
View File
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { ref, reactive } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app";
import { isEmpty } from 'radash'
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import { hooks, router } from "@@/index"
import { applyApi } from "@@/api"
@@ -9,56 +9,69 @@ import { applyApi } from "@@/api"
import { filePath } from "@@/utils/file"
const state = reactive<any>({
pa: {
id: null,
pagesize: 15,
},
pa: {
id: null,
pagesize: 15,
},
})
const pageRef = ref<any>(null)
const pageHook = hooks.usePage(pageRef, applyApi.codeList, null, 'data.records')
const pageHook = hooks.usePage(pageRef, applyApi.codeList, null, "data.records")
const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, state.pa);
pageHook.startPage(page, pagesize, false, state.pa)
}
onLoad((options: any) => {
if (!isEmpty(options.id)) {
state.pa.id = options.id
}
});
onShow(() => {
if (pageRef.value) {
pageRef.value.reload(false)
}
if (!isEmpty(options.id)) {
state.pa.id = options.id
}
})
onShow(() => {
if (pageRef.value) {
pageRef.value.reload(false)
}
})
</script>
<template>
<crud-layout title="外来人员就餐" bg="/static/page/blue-bg.png">
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="5"
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
<template #top>
<view class="h-30rpx" />
</template>
<view class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx"
v-for="(v, i) in pageHook.list" :key="i" @tap="hooks.usePreviewImage(v.code)">
<view class="flex-row items-center">
<view class="flex-row items-center">
<tm-tag v-if="v.status == 0" size="m" color="info">未使用</tm-tag>
<tm-tag v-if="v.status == 1" size="m" color="success">已使用</tm-tag>
</view>
<view class="flex-row items-center sub-text-28">
<text class="m-l-30rpx">{{ v.username }}</text>
<text class="m-l-10rpx second-text-26">{{ v.userMobile }}</text>
</view>
</view>
<view class="iconfont icon-erweima font-size-40rpx! color-blue" />
</view>
</z-paging>
</crud-layout>
<crud-layout title="外来人员就餐" bg="/static/page/blue-bg.png">
<z-paging
ref="pageRef"
height="100%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="pageHook.scroll"
>
<template #top>
<view class="h-30rpx" />
</template>
<view
class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx"
v-for="(v, i) in pageHook.list"
:key="i"
@tap="hooks.usePreviewImage(v.code)"
>
<view class="flex-row items-center">
<view class="flex-row items-center">
<tm-tag v-if="v.status == 0" size="m" color="info">未使用</tm-tag>
<tm-tag v-if="v.status == 1" size="m" color="success">已使用</tm-tag>
</view>
<view class="flex-row items-center sub-text-28">
<text class="m-l-30rpx">{{ v.username }}</text>
<text class="m-l-10rpx second-text-26">{{ v.userMobile }}</text>
</view>
</view>
<view class="iconfont icon-erweima font-size-40rpx! color-blue" />
</view>
</z-paging>
</crud-layout>
</template>
<style lang="scss" scoped></style>
<style lang="scss" scoped></style>
+107 -103
View File
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { ref, reactive } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app";
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { hooks, router } from "@@/index"
import { applyApi } from "@@/api"
@@ -8,128 +8,132 @@ import { applyApi } from "@@/api"
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
const data = {
tabs: [
{ id: null, name: '全部', disabled: false },
{ id: 1, name: '待审核', disabled: false },
{ id: 2, name: '已通过', disabled: false },
{ id: 3, name: '已拒绝', disabled: false },
]
tabs: [
{ id: null, name: "全部", disabled: false },
{ id: 1, name: "待审核", disabled: false },
{ id: 2, name: "已通过", disabled: false },
{ id: 3, name: "已拒绝", disabled: false },
],
}
const state = reactive<any>({
pa: {
processStatus: data.tabs[0].id,
},
pa: {
processStatus: data.tabs[0].id,
},
})
const pageRef = ref<any>(null)
const pageHook = hooks.usePage(pageRef, applyApi.foreignList, null, 'data.records')
const pageHook = hooks.usePage(pageRef, applyApi.foreignList, null, "data.records")
const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, state.pa);
pageHook.startPage(page, pagesize, false, state.pa)
}
onLoad(() => {
});
onLoad(() => {})
onShow(() => {
if (pageRef.value) {
pageRef.value.reload(false)
}
if (pageRef.value) {
pageRef.value.reload(false)
}
})
const doTab = (e: any) => {
const target = data.tabs[e];
state.pa.processStatus = target.id
pageRef.value.reload(true)
const target = data.tabs[e]
state.pa.processStatus = target.id
pageRef.value.reload(true)
}
const doApply = async () => {
router.jump("/pages/apply/foreign-apply", { type: 'add' })
router.jump("/pages/apply/foreign-apply", { type: "add" })
}
const doCard = (v: any) => {
if (v.processStatus == 2) {
router.jump("/pages/apply/foreign-items", { id: v.id })
} else {
router.jump("/pages/apply/foreign-apply", { type: 'view', id: v.id })
}
if (v.processStatus == 2) {
router.jump("/pages/apply/foreign-items", { id: v.id })
} else {
router.jump("/pages/apply/foreign-apply", { type: "view", id: v.id })
}
}
</script>
<template>
<crud-layout title="外来人员就餐" bg="/static/page/blue-bg.png">
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="5"
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
<template #top>
<view class="h-30rpx" />
<view class="bg-white rounded-16rpx px-20rpx">
<z-tabs :list="data.tabs" @change="doTab" />
</view>
</template>
<view class="h-20rpx" />
<view class="flex-col card p-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i"
@tap="doCard(v)">
<view class="flex-row items-center justify-between">
<view class="sub-text-30">电子餐券</view>
<view class="flex-row items-center">
<view class="second-text-26">{{ hooks.useTime(v.createTime, "") }}</view>
<view class="flex-row-center m-l-20rpx">
<tm-tag v-if="v.processStatus == 1" size="xs" color="info">待审核</tm-tag>
<tm-tag v-if="v.processStatus == 2" size="xs" color="success">已通过</tm-tag>
<tm-tag v-if="v.processStatus == 3" size="xs" color="error">已拒绝</tm-tag>
</view>
</view>
</view>
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
<view class="flex items-center justify-between second-text-26">
<view class="flex items-center">
<text>数量</text>
<text class="m-l-10rpx">{{ v.count }}</text>
</view>
<view class="color-red">
<text>已使用</text>
<text class="m-l-10rpx">{{ v.useCount }}</text>
</view>
</view>
<view class="flex items-center m-t-20rpx second-text-26">
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
<text>有效期</text>
<text class="m-l-10rpx">
{{ hooks.useTime(v.applyStartTime, " {y}-{m}-{d}") }}
~
{{ hooks.useTime(v.applyEndTime, "{y}-{m}-{d}") }}
</text>
</view>
<view v-if="v.processStatus != 1 && false">
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
<view class="flex items-center justify-between second-text-26">
<view class="flex items-center">
<text>审核人</text>
<text class="m-l-10rpx">{{ v.checkUserName }}</text>
</view>
<view class="flex items-center">
<text>审核时间</text>
<text class="m-l-10rpx"> {{ hooks.useTime(v.checkTime, "") }}</text>
</view>
</view>
</view>
<view class="flex items-center justify-end m-t-25rpx">
<text v-if="v.processStatus == 2" class="botder_btn">使用</text>
<text v-else class="botder_btn">查看</text>
</view>
</view>
<template #bottom>
<view
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!"
@tap="doApply">
申请
</view>
<view class="h-30rpx" />
</template>
</z-paging>
</crud-layout>
<crud-layout title="外来人员就餐" bg="/static/page/blue-bg.png">
<z-paging
ref="pageRef"
height="100%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="pageHook.scroll"
>
<template #top>
<view class="h-30rpx" />
<view class="bg-white rounded-16rpx px-20rpx">
<z-tabs :list="data.tabs" @change="doTab" />
</view>
</template>
<view class="h-20rpx" />
<view class="flex-col card p-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="doCard(v)">
<view class="flex-row items-center justify-between">
<view class="sub-text-30">电子餐券</view>
<view class="flex-row items-center">
<view class="second-text-26">{{ hooks.useTime(v.createTime, "") }}</view>
<view class="flex-row-center m-l-20rpx">
<tm-tag v-if="v.processStatus == 1" size="xs" color="info">待审核</tm-tag>
<tm-tag v-if="v.processStatus == 2" size="xs" color="success">已通过</tm-tag>
<tm-tag v-if="v.processStatus == 3" size="xs" color="error">已拒绝</tm-tag>
</view>
</view>
</view>
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
<view class="flex items-center justify-between second-text-26">
<view class="flex items-center">
<text>数量</text>
<text class="m-l-10rpx">{{ v.count }}</text>
</view>
<view class="color-red">
<text>已使用</text>
<text class="m-l-10rpx">{{ v.useCount }}</text>
</view>
</view>
<view class="flex items-center m-t-20rpx second-text-26">
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
<text>有效期</text>
<text class="m-l-10rpx">
{{ hooks.useTime(v.applyStartTime, " {y}-{m}-{d}") }}
~
{{ hooks.useTime(v.applyEndTime, "{y}-{m}-{d}") }}
</text>
</view>
<view v-if="v.processStatus != 1 && false">
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
<view class="flex items-center justify-between second-text-26">
<view class="flex items-center">
<text>审核人</text>
<text class="m-l-10rpx">{{ v.checkUserName }}</text>
</view>
<view class="flex items-center">
<text>审核时间</text>
<text class="m-l-10rpx"> {{ hooks.useTime(v.checkTime, "") }}</text>
</view>
</view>
</view>
<view class="flex items-center justify-end m-t-25rpx">
<text v-if="v.processStatus == 2" class="botder_btn">使用</text>
<text v-else class="botder_btn">查看</text>
</view>
</view>
<template #bottom>
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!" @tap="doApply">
申请
</view>
<view class="h-30rpx" />
</template>
</z-paging>
</crud-layout>
</template>
<style lang="scss" scoped></style>
<style lang="scss" scoped></style>
+52 -41
View File
@@ -1,60 +1,71 @@
<script setup lang="ts">
import { ref, reactive } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app";
import { isEmpty } from 'radash'
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import { hooks, router } from "@@/index"
import { applyApi } from "@@/api"
const state = reactive<any>({
pa: {
bizId: null,
pagesize: 99,
},
pa: {
bizId: null,
pagesize: 99,
},
})
const pageRef = ref<any>(null)
const pageHook = hooks.usePage(pageRef, applyApi.codeList, null, 'data.records')
const pageHook = hooks.usePage(pageRef, applyApi.codeList, null, "data.records")
const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, state.pa);
pageHook.startPage(page, pagesize, false, state.pa)
}
onLoad((options: any) => {
if (!isEmpty(options.id)) {
state.pa.bizId = options.id
}
});
onShow(() => {
if (!isEmpty(options.id)) {
state.pa.bizId = options.id
}
})
onShow(() => {})
</script>
<template>
<crud-layout title="跨单位就餐" bg="/static/page/blue-bg.png">
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="5"
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
<template #top>
<view class="h-30rpx" />
</template>
<view class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx"
v-for="(v, i) in pageHook.list" :key="i" @tap="hooks.usePreviewImage(v.code)">
<view class="flex-row items-center">
<view class="flex-row items-center">
<tm-tag v-if="v.status == 0" size="m" color="info">未使用</tm-tag>
<tm-tag v-if="v.status == 1" size="m" color="success">已使用</tm-tag>
</view>
<view class="flex-row items-center sub-text-26">
<text class="m-l-30rpx">{{ v.username }}</text>
<text class="m-l-10rpx second-text-26">{{ v.userMobile }}</text>
</view>
</view>
<view class="iconfont icon-erweima font-size-40rpx! color-blue" />
</view>
</z-paging>
</crud-layout>
<crud-layout title="跨单位就餐" bg="/static/page/blue-bg.png">
<z-paging
ref="pageRef"
height="100%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="pageHook.scroll"
>
<template #top>
<view class="h-30rpx" />
</template>
<view
class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx"
v-for="(v, i) in pageHook.list"
:key="i"
@tap="hooks.usePreviewImage(v.code)"
>
<view class="flex-row items-center">
<view class="flex-row items-center">
<tm-tag v-if="v.status == 0" size="m" color="info">未使用</tm-tag>
<tm-tag v-if="v.status == 1" size="m" color="success">已使用</tm-tag>
</view>
<view class="flex-row items-center sub-text-26">
<text class="m-l-30rpx">{{ v.username }}</text>
<text class="m-l-10rpx second-text-26">{{ v.userMobile }}</text>
</view>
</view>
<view class="iconfont icon-erweima font-size-40rpx! color-blue" />
</view>
</z-paging>
</crud-layout>
</template>
<style lang="scss" scoped></style>
<style lang="scss" scoped></style>
+98 -94
View File
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { ref, reactive } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app";
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { hooks, router } from "@@/index"
import { applyApi } from "@@/api"
@@ -8,119 +8,123 @@ import { applyApi } from "@@/api"
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
const data = {
tabs: [
{ id: null, name: '全部', disabled: false },
{ id: 1, name: '待审核', disabled: false },
{ id: 2, name: '已通过', disabled: false },
{ id: 3, name: '已拒绝', disabled: false },
]
tabs: [
{ id: null, name: "全部", disabled: false },
{ id: 1, name: "待审核", disabled: false },
{ id: 2, name: "已通过", disabled: false },
{ id: 3, name: "已拒绝", disabled: false },
],
}
const state = reactive<any>({
pa: {
processStatus: data.tabs[0].id,
},
pa: {
processStatus: data.tabs[0].id,
},
})
const pageRef = ref<any>(null)
const pageHook = hooks.usePage(pageRef, applyApi.strideList, null, 'data.records')
const pageHook = hooks.usePage(pageRef, applyApi.strideList, null, "data.records")
const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, state.pa);
pageHook.startPage(page, pagesize, false, state.pa)
}
onLoad(() => {
});
onLoad(() => {})
onShow(() => {
if (pageRef.value) {
pageRef.value.reload(false)
}
if (pageRef.value) {
pageRef.value.reload(false)
}
})
const doTab = (e: any) => {
const target = data.tabs[e];
state.pa.processStatus = target.id
pageRef.value.reload(true)
const target = data.tabs[e]
state.pa.processStatus = target.id
pageRef.value.reload(true)
}
const doApply = async () => {
router.jump("/pages/apply/stride-apply")
router.jump("/pages/apply/stride-apply")
}
const doCard = (v: any) => {
if (v.processStatus == 2) {
router.jump("/pages/apply/stride-items", { id: v.id })
} else {
router.jump("/pages/apply/stride-apply", { type: 'view', id: v.id })
}
if (v.processStatus == 2) {
router.jump("/pages/apply/stride-items", { id: v.id })
} else {
router.jump("/pages/apply/stride-apply", { type: "view", id: v.id })
}
}
</script>
<template>
<crud-layout title="跨单位就餐" bg="/static/page/blue-bg.png">
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="5"
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
<template #top>
<view class="h-30rpx" />
<view class="bg-white rounded-16rpx px-20rpx">
<z-tabs :list="data.tabs" @change="doTab" />
</view>
</template>
<view class="h-20rpx" />
<view class="flex-col card p-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i"
@tap="doCard(v)">
<view class="flex-row items-center justify-between">
<view class="sub-text-30">跨单位就餐</view>
<view class="flex-row items-center">
<view class="second-text-26">{{ hooks.useTime(v.createTime, "") }}</view>
<view class="flex-row-center m-l-20rpx">
<tm-tag v-if="v.processStatus == 1" size="xs" color="info">待审核</tm-tag>
<tm-tag v-if="v.processStatus == 2" size="xs" color="success">已通过</tm-tag>
<tm-tag v-if="v.processStatus == 3" size="xs" color="error">已拒绝</tm-tag>
</view>
</view>
</view>
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
<view class="flex items-center justify-between second-text-26">
<view class="flex items-center">
<text>数量</text>
<text class="m-l-10rpx">{{ v.count }}</text>
</view>
<view class="color-red">
<text>已使用</text>
<text class="m-l-10rpx">{{ v.useCount }}</text>
</view>
</view>
<view v-if="v.processStatus != 1 && false">
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
<view class="flex items-center justify-between second-text-26">
<view class="flex items-center">
<text>审核人</text>
<text class="m-l-10rpx">{{ v.checkUserName }}</text>
</view>
<view class="flex items-center">
<text>审核时间</text>
<text class="m-l-10rpx"> {{ hooks.useTime(v.checkTime, "") }}</text>
</view>
</view>
</view>
<view class="flex items-center justify-end m-t-25rpx">
<text v-if="v.processStatus == 2" class="botder_btn">使用</text>
<text v-else class="botder_btn">查看</text>
</view>
</view>
<template #bottom>
<view
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!"
@tap="doApply">
申请
</view>
<view class="h-30rpx" />
</template>
</z-paging>
</crud-layout>
<crud-layout title="跨单位就餐" bg="/static/page/blue-bg.png">
<z-paging
ref="pageRef"
height="100%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="pageHook.scroll"
>
<template #top>
<view class="h-30rpx" />
<view class="bg-white rounded-16rpx px-20rpx">
<z-tabs :list="data.tabs" @change="doTab" />
</view>
</template>
<view class="h-20rpx" />
<view class="flex-col card p-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="doCard(v)">
<view class="flex-row items-center justify-between">
<view class="sub-text-30">跨单位就餐</view>
<view class="flex-row items-center">
<view class="second-text-26">{{ hooks.useTime(v.createTime, "") }}</view>
<view class="flex-row-center m-l-20rpx">
<tm-tag v-if="v.processStatus == 1" size="xs" color="info">待审核</tm-tag>
<tm-tag v-if="v.processStatus == 2" size="xs" color="success">已通过</tm-tag>
<tm-tag v-if="v.processStatus == 3" size="xs" color="error">已拒绝</tm-tag>
</view>
</view>
</view>
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
<view class="flex items-center justify-between second-text-26">
<view class="flex items-center">
<text>数量</text>
<text class="m-l-10rpx">{{ v.count }}</text>
</view>
<view class="color-red">
<text>已使用</text>
<text class="m-l-10rpx">{{ v.useCount }}</text>
</view>
</view>
<view v-if="v.processStatus != 1 && false">
<view class="h-1px m-y-20rpx bg-#999 bg-opacity-5" />
<view class="flex items-center justify-between second-text-26">
<view class="flex items-center">
<text>审核人</text>
<text class="m-l-10rpx">{{ v.checkUserName }}</text>
</view>
<view class="flex items-center">
<text>审核时间</text>
<text class="m-l-10rpx"> {{ hooks.useTime(v.checkTime, "") }}</text>
</view>
</view>
</view>
<view class="flex items-center justify-end m-t-25rpx">
<text v-if="v.processStatus == 2" class="botder_btn">使用</text>
<text v-else class="botder_btn">查看</text>
</view>
</view>
<template #bottom>
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!" @tap="doApply">
申请
</view>
<view class="h-30rpx" />
</template>
</z-paging>
</crud-layout>
</template>
<style lang="scss" scoped></style>
<style lang="scss" scoped></style>
+98 -93
View File
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { ref, reactive } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app";
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { hooks, router } from "@@/index"
import { boxesApi } from "@@/api"
@@ -8,119 +8,124 @@ import { boxesApi } from "@@/api"
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
const data = {
tabs: [
{ id: null, name: '全部', disabled: false },
{ id: "0", name: '预约成功', disabled: false },
{ id: "1", name: '预约失败', disabled: false },
{ id: "2", name: '取消预约', disabled: false },
],
tabs: [
{ id: null, name: "全部", disabled: false },
{ id: "0", name: "预约成功", disabled: false },
{ id: "1", name: "预约失败", disabled: false },
{ id: "2", name: "取消预约", disabled: false },
],
}
const state = reactive<any>({
pa: {
status: data.tabs[0].id,
},
pa: {
status: data.tabs[0].id,
},
})
onLoad(() => {
});
onLoad(() => {})
onShow(() => {
if (pageRef.value) {
pageRef.value.reload(false)
}
if (pageRef.value) {
pageRef.value.reload(false)
}
})
const pageRef = ref<any>(null)
const pageHook = hooks.usePage(pageRef, boxesApi.MyBookingPage, null, 'data.list')
const pageHook = hooks.usePage(pageRef, boxesApi.MyBookingPage, null, "data.list")
const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, state.pa);
pageHook.startPage(page, pagesize, false, state.pa)
}
const doTab = (e: any) => {
const target = data.tabs[e];
state.pa.status = target.id
pageRef.value.reload(true)
const target = data.tabs[e]
state.pa.status = target.id
pageRef.value.reload(true)
}
const doCard = (v: any) => {
router.jump('/pages/boxes/detail', { id: v.id })
router.jump("/pages/boxes/detail", { id: v.id })
}
const doCancelApply = async (v: any) => {
uni.showModal({
title: '提示',
content: '是否确定取消预约',
confirmColor: '#0094ff',
success: async (res) => {
if (!res.confirm) return
try {
uni.showLoading({ title: '取消预约中...', mask: true });
const _pa = { id: v.id }
const { data, code }: any = await boxesApi.cancel(_pa)
if (code != 0) throw new Error()
pageRef.value.reload(true)
uni.hideLoading()
uni.showToast({ title: '取消预约成功', icon: "none" });
} catch (error) {
console.error(error);
uni.hideLoading()
}
}
})
uni.showModal({
title: "提示",
content: "是否确定取消预约",
confirmColor: "#0094ff",
success: async (res) => {
if (!res.confirm) return
try {
uni.showLoading({ title: "取消预约中...", mask: true })
const _pa = { id: v.id }
const { data, code }: any = await boxesApi.cancel(_pa)
if (code != 0) throw new Error()
pageRef.value.reload(true)
uni.hideLoading()
uni.showToast({ title: "取消预约成功", icon: "none" })
} catch (error) {
console.error(error)
uni.hideLoading()
}
},
})
}
</script>
<template>
<crud-layout title="包厢预约" bg="/static/page/blue-bg.png">
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="5"
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
<template #top>
<view class="bg-white rounded-16rpx px-20rpx m-x-10rpx m-t-15rpx">
<z-tabs :list="data.tabs" @change="doTab" />
</view>
</template>
<view class="h-20rpx" />
<view class="flex-col card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="doCard(v)">
<view>
<view class="flex-row items-center justify-between">
<view class="main-text-28">{{ v.boxesName }}</view>
<view>
<tm-tag v-if="v.status == 0" color="success" size="xs">预约成功</tm-tag>
<tm-tag v-if="v.status == 1" color="error" size="xs">预约失败</tm-tag>
<tm-tag v-if="v.status == 2" color="info" size="xs">取消预约</tm-tag>
</view>
</view>
<view class="m-t-10rpx second-text-26">
<text>预约时间</text>
<text class="m-l-5rpx">
{{ v.bookingDate }} {{ hooks.useTime(v.startTime, "{h}:{i}") }} ~ {{
hooks.useTime(v.endTime, "{h}:{i}")
}}
</text>
</view>
<view class="m-t-10rpx second-text-26">
<text>提交时间</text>
<text class="m-l-5rpx">
{{ hooks.useTime(v.createTime, "") }}
</text>
</view>
<view>
<text class="main-text-28">审批状态:</text>
<tm-tag v-if="v.checkStatus == '1'" color="info" size="xs">审批中</tm-tag>
<tm-tag v-if="v.checkStatus == '2'" color="success" size="xs">审批通过</tm-tag>
<tm-tag v-if="v.checkStatus == '3'" color="error" size="xs">审批不通过</tm-tag>
<tm-tag v-if="v.checkStatus == '4'" color="info" size="xs">已取消</tm-tag>
</view>
</view>
<view class="flex-row items-center justify-end p-t-10rpx">
<view class="botder_btn" @tap.stop="doCancelApply(v)">取消预约</view>
</view>
</view>
</z-paging>
</crud-layout>
<crud-layout title="包厢预约" bg="/static/page/blue-bg.png">
<z-paging
ref="pageRef"
height="100%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="pageHook.scroll"
>
<template #top>
<view class="bg-white rounded-16rpx px-20rpx m-x-10rpx m-t-15rpx">
<z-tabs :list="data.tabs" @change="doTab" />
</view>
</template>
<view class="h-20rpx" />
<view class="flex-col card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="doCard(v)">
<view>
<view class="flex-row items-center justify-between">
<view class="main-text-28">{{ v.boxesName }}</view>
<view>
<tm-tag v-if="v.status == 0" color="success" size="xs">预约成功</tm-tag>
<tm-tag v-if="v.status == 1" color="error" size="xs">预约失败</tm-tag>
<tm-tag v-if="v.status == 2" color="info" size="xs">取消预约</tm-tag>
</view>
</view>
<view class="m-t-10rpx second-text-26">
<text>预约时间</text>
<text class="m-l-5rpx">
{{ v.bookingDate }} {{ hooks.useTime(v.startTime, "{h}:{i}") }} ~ {{ hooks.useTime(v.endTime, "{h}:{i}") }}
</text>
</view>
<view class="m-t-10rpx second-text-26">
<text>提交时间</text>
<text class="m-l-5rpx">
{{ hooks.useTime(v.createTime, "") }}
</text>
</view>
<view>
<text class="main-text-28">审批状态:</text>
<tm-tag v-if="v.checkStatus == '1'" color="info" size="xs">审批中</tm-tag>
<tm-tag v-if="v.checkStatus == '2'" color="success" size="xs">审批通过</tm-tag>
<tm-tag v-if="v.checkStatus == '3'" color="error" size="xs">审批不通过</tm-tag>
<tm-tag v-if="v.checkStatus == '4'" color="info" size="xs">已取消</tm-tag>
</view>
</view>
<view class="flex-row items-center justify-end p-t-10rpx">
<view class="botder_btn" @tap.stop="doCancelApply(v)">取消预约</view>
</view>
</view>
</z-paging>
</crud-layout>
</template>
<style lang="scss" scoped></style>
+14 -8
View File
@@ -6,8 +6,6 @@ import { isEmpty } from "radash"
import { router } from "@@/index"
import { boxesApi } from "@@/api"
import zSwiper from "@zebra-ui/swiper/components/z-swiper/z-swiper.vue"
import zSwiperItem from "@zebra-ui/swiper/components/z-swiper-item/z-swiper-item.vue"
import { filePath } from "@/sheep/utils/file"
const state = reactive<any>({
@@ -38,12 +36,20 @@ const doSubmit = () => {
<template>
<crud-layout mainIsScroll tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
<z-swiper>
<z-swiper-item v-for="(v, i) in state.detail.imagesArray" :key="i">
<image class="w-100vw" :src="filePath(v)" mode="widthFix" />
</z-swiper-item>
</z-swiper>
<view class="p-x-15rpx">
<swiper
class="w-100vw h-30vh"
circular
:indicator-dots="true"
indicator-active-color="#0779FD"
indicator-color="#ffffff"
:autoplay="true"
>
<swiper-item v-for="(v, i) in state.detail?.imagesArray" :key="i">
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
</swiper-item>
</swiper>
<view class="p-15rpx">
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
<view class="flex-row items-center justify-between">
<view class="flex-row items-center">
+32 -33
View File
@@ -2,27 +2,23 @@
import { reactive, nextTick } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import { hooks, router } from "@@/index"
import { merchantApi, foodApi, payApi } from "@@/api"
import { filePath } from "@@/utils/file"
import zSwiper from "@zebra-ui/swiper/components/z-swiper/z-swiper.vue"
import zSwiperItem from "@zebra-ui/swiper/components/z-swiper-item/z-swiper-item.vue"
import ProductRow from "./components/product-row.vue"
import ProductCar from "./components/product-car.vue"
import ProductTotal from "./components/product-total.vue"
const state = reactive<any>({
detailId: null,
canteenDetail: {},
totPrice: 0,
totCount: 0,
currentClassifyIndex: 0,
showCarDialog: false,
detail: {},
carList: [],
classifyList: [],
shopList: [],
@@ -39,20 +35,16 @@ onShow(() => {
getClassify()
})
// 获取食堂详情信息
const getDetail = async () => {
uni.showLoading({
title: "加载中...",
mask: true,
})
const _pa = { id: state.detailId }
const { data } = await merchantApi.detail(_pa)
state.detail = data
uni.showLoading({ title: "加载中...", mask: true })
const { code, data } = await merchantApi.detail({ id: state.detailId })
if (code == 0) state.canteenDetail = data
uni.hideLoading()
}
const getShopCar = async () => {
const _pa = { merchantId: state.detailId, hardType: "CANTEEN" }
const { data } = await foodApi.getShopCar(_pa)
const { data } = await foodApi.getShopCar({ merchantId: state.detailId, hardType: "CANTEEN" })
state.carList = data ?? []
if (isEmpty(state.carList)) {
state.shopList.forEach((v: any) => {
@@ -204,11 +196,11 @@ const getHeight = () => {
}
const doPhone = () => {
if (isEmpty(state.detail.phone)) {
if (isEmpty(state.canteenDetail.phone)) {
uni.showToast({ title: "该商户没有预留电话", icon: "none" })
return
}
hooks.useMakePhoneCall(state.detail.phone)
hooks.useMakePhoneCall(state.canteenDetail.phone)
}
const doFood = () => {
router.jump("/pages/merchant/food", { merchantId: state.detailId })
@@ -218,43 +210,49 @@ const doFood = () => {
<template>
<crud-layout mainIsScroll tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
<tm-sticky>
<!-- start 轮播 start -->
<z-swiper>
<z-swiper-item v-for="(v, i) in state.detail.swiperPic?.split(',')" :key="i">
<image class="w-100vw h-400rpx" :src="filePath(v)" mode="aspectFill" />
</z-swiper-item>
</z-swiper>
<!-- end 轮播 end -->
<swiper
class="w-100vw h-30vh"
circular
:indicator-dots="true"
indicator-active-color="#0779FD"
indicator-color="#ffffff"
:autoplay="true"
>
<swiper-item v-for="(v, i) in state.canteenDetail?.swiperPic?.split(',')" :key="i">
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
</swiper-item>
</swiper>
<tm-sticky-header>
<view class="m-x-30rpx">
<!-- start 简介 start -->
<view class="h-15rpx" />
<view flex-row card p-20rpx>
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(state.detail.logoPic)" mode="aspectFill" />
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(state.canteenDetail.logoPic)" mode="aspectFill" />
<view class="flex-1 flex-col m-l-20rpx">
<view class="flex-row items-center justify-between">
<view class="flex-row-center sub-text-34">
<text>{{ state.detail.name }}</text>
<text>{{ state.canteenDetail.name }}</text>
</view>
<view>
<tm-tag size="s">{{ state.detail.deptName }}</tm-tag>
<tm-tag size="s">{{ state.canteenDetail.deptName }}</tm-tag>
</view>
</view>
<view class="second-text-24">
<view class="second-text-28">营业时间:</view>
<view>
{{ state.detail.jobTime?.split(",")[0] ? "早:" + state.detail.jobTime?.split(",")[0] : "" }}
{{ state.canteenDetail.jobTime?.split(",")[0] ? "早:" + state.canteenDetail.jobTime?.split(",")[0] : "" }}
</view>
<view>
{{ state.detail.jobTime?.split(",")[1] ? "中:" + state.detail.jobTime?.split(",")[1] : "" }}
{{ state.canteenDetail.jobTime?.split(",")[1] ? "中:" + state.canteenDetail.jobTime?.split(",")[1] : "" }}
</view>
<view>
{{ state.detail.jobTime?.split(",")[2] ? "晚:" + state.detail.jobTime?.split(",")[2] : "" }}
{{ state.canteenDetail.jobTime?.split(",")[2] ? "晚:" + state.canteenDetail.jobTime?.split(",")[2] : "" }}
</view>
</view>
<view v-if="state.detail.addressDes" class="m-t-10rpx second-text-28">
<view v-if="state.canteenDetail.addressDes" class="m-t-10rpx second-text-28">
<text>食堂地址:</text>
<text class="m-l-10rpx">{{ state.detail.addressDes }}</text>
<text class="m-l-10rpx">{{ state.canteenDetail.addressDes }}</text>
</view>
</view>
</view>
@@ -287,8 +285,9 @@ const doFood = () => {
</view>
</tm-sticky-header>
<!-- start 商品 start -->
<view class="h-15rpx" />
<!-- start 商品 start -->
<view class="flex-row">
<scroll-view
v-if="state.classifyList.length > 0"
+3 -3
View File
@@ -138,9 +138,9 @@ const doProduct = (v: any) => {
:list="foodList"
:gutter="10"
:breakpoints="{
1200: { rowPerView: 4 },
800: { rowPerView: 3 },
375: { rowPerView: 2 },
1800: { rowPerView: 4 },
1400: { rowPerView: 3 },
975: { rowPerView: 2 },
}"
:hasAroundGutter="false"
backgroundColor="#ffffff00"
-23
View File
@@ -1,23 +0,0 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { hooks } from "@@/index"
import { foodApi } from "@@/api"
const data = {}
const state = reactive<any>({
pa: {
status: 1,
},
})
onLoad(() => {})
onShow(() => {})
</script>
<template>
<crud-layout title="订单详情" bg="/static/page/blue-bg.png"> </crud-layout>
</template>
<style lang="scss" scoped></style>
-3
View File
@@ -2,11 +2,8 @@
import { reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import { hooks } from "@@/index"
import { productApi } from "@@/api"
import { filePath } from "@@/utils/file"
import zSwiper from "@zebra-ui/swiper/components/z-swiper/z-swiper.vue"
import zSwiperItem from "@zebra-ui/swiper/components/z-swiper-item/z-swiper-item.vue"
const state = reactive<any>({
detailId: null,
+5 -13
View File
@@ -1,14 +1,13 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import { hooks, constant, router } from "@@/index"
import { hooks, router } from "@@/index"
import { orderApi, refundApi } from "@@/api"
import { filePath } from "@@/utils/file"
const data = {}
const state = reactive<any>({
detailId: null,
detail: {},
@@ -77,11 +76,7 @@ const doCancelRefund = async () => {
</view>
<view class="h-30rpx" />
<view class="relative flex-col justify-center overflow-hidden card p-x-20rpx p-y-30rpx m-b-20rpx">
<image
class="absolute top--20rpx right--60rpx w-160rpx h-160rpx"
src="/static/icon/guarantee.png"
mode="widthFix"
/>
<image class="absolute top--20rpx right--60rpx w-160rpx h-160rpx" src="/static/icon/guarantee.png" mode="widthFix" />
<view class="sub-text-32">订单信息</view>
<view class="m-t-15rpx">
<view class="info_cell">
@@ -94,7 +89,7 @@ const doCancelRefund = async () => {
</view>
<view class="info_cell">
<view>商户</view>
<view>{{ state.detail.merchantStr }}</view>
<view>{{ state.detail.merchantName }}</view>
</view>
<view class="m-t-15rpx h-1px bg-#999 bg-opacity-5" />
<view class="info_cell">
@@ -184,10 +179,7 @@ const doCancelRefund = async () => {
<view>{{ state.refundDetail.applyDescription }}</view>
</view>
</view>
<view
v-if="state.refundDetail.status == 62"
class="card p-x-20rpx p-y-30rpx space-y-10rpx m-b-20rpx second-text-24"
>
<view v-if="state.refundDetail.status == 62" class="card p-x-20rpx p-y-30rpx space-y-10rpx m-b-20rpx second-text-24">
<view class="flex-row items-center">
<view>审核人:</view>
<view>{{ state.refundDetail.auditUsername }}</view>
+64
View File
@@ -0,0 +1,64 @@
<template>
<view class="w-full h-full">
<view class="flex-col-center p-30rpx">
<view class="flex-col-center m-y-50rpx">
<svg
t="1742978804614"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="1708"
width="64"
height="64"
>
<path
d="M512 0C230.4 0 0 230.4 0 512s230.4 512 512 512 512-230.4 512-512S793.6 0 512 0z m288 371.2L460.8 710.4c-6.4 6.4-19.2 12.8-25.6 12.8-12.8 0-19.2-6.4-25.6-12.8L224 531.2c-12.8-12.8-12.8-38.4 0-57.6 12.8-12.8 38.4-12.8 57.6 0l147.2 147.2L736 313.6c12.8-12.8 38.4-12.8 57.6 0 19.2 19.2 19.2 44.8 6.4 57.6z"
fill="#2BCDA3"
p-id="1709"
data-spm-anchor-id="a313x.search_index.0.i2.beb13a81SVstw0"
class="selected"
></path>
</svg>
<text class="text-36 mt-3 font-bold c-#333333!">支付成功</text>
</view>
<view class="flex-col-center m-b-60rpx">
<text class="text-90 c-#333333!">¥{{ payData.customPrice }}</text>
</view>
<view class="w-full p-10rpx flex-col justify-center">
<view class="flex-row justify-between m-15rpx">
<text class="sub-text-30 c-#333333!">商家</text>
<text class="sub-text-30">{{ payData.name }}</text>
</view>
<hr />
<view class="flex-row justify-between m-15rpx">
<text class="sub-text-30 c-#333333!">支付方式</text>
<text class="sub-text-30">扫一扫</text>
</view>
</view>
</view>
<view class="p-40rpx fixed bottom-30rpx left-0 right-0 font-bold">
<tm-button :block="true" @click="goBack">完成</tm-button>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from "vue"
import { onShow } from "@dcloudio/uni-app"
import { router } from "@@/index"
import { usePayStore } from "@/sheep/stores/pay"
const payData = ref<{ id?: string; name?: string; customPrice?: number }>({})
onShow(() => {
if (!usePayStore().payData.id) return uni.showToast({ title: "支付信息不存在", icon: "none" })
payData.value = usePayStore().payData
})
const goBack = () => {
router.jump("/pages/tabbar/my", {}, 2)
}
</script>
+51 -95
View File
@@ -1,71 +1,36 @@
<template>
<crud-layout bg="/static/page/blue-bg.png">
<view class="h-screen flex flex-col position-relative">
<view class="mx-auto text-34 py-2">{{ scanData.name }}</view>
<view class="mx-auto text-34 py-2 h-80rpx">{{ scanData.name }}</view>
<tm-sheet class="flex flex-row">
<span class="text-2xl text-[#333] mr-1 line-height-normal">¥</span>
<span class="text-3xl font-medium text-[#333]">{{ displayAmount }}</span>
</tm-sheet>
<tm-button class="mt-40" :block="true" @click="disabled ? '' : handlePay()" :disabled="disabled">支付</tm-button>
<view class="bg-[#f5f5f5] px-1 py-2 rounded-4 absolute bottom-0 w-full">
<view class="flex mb-2.5" v-for="(row, rowIndex) in keyboardLayout" :key="rowIndex">
<view
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
v-for="(key, keyIndex) in row"
:key="keyIndex"
@click="handleKeyPress(key)"
>
{{ key }}
<tm-sheet v-if="walletList.length > 0" class="flex flex-col">
<view class="text-gray-700 font-bold text-sm mb-1">选择支付钱包:</view>
<view
v-for="(v, index) in walletList"
:key="index"
class="card relative border-4 border-solid my-1 duration-200 border-#efefef flex justify-between items-center p-3"
:class="{ 'border-4 border-solid border-blue!': curWalletId == v.id }"
@click="curWalletId = v.id"
>
<view class="flex items-center">
<image class="w-70 h-70 mr-2" :src="filePath(v.walletTypeIcon)" />
<view class="main-text-32">{{ v.walletTypeName }}</view>
</view>
<view class="main-text-28 flex items-center">
<view>余额:{{ hooks.useMoney(v.balance) }}</view>
<text>元</text>
</view>
</view>
<view class="flex mb-0">
<view
class="flex-1 h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
@click="handleKeyPress('.')"
>
.
</view>
<view
class="flex-auto h-[60px] flex items-center justify-center bg-white text-2xl text-[#333] mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
@click="handleKeyPress('0')"
>
0
</view>
<view
class="flex-1 h-[60px] flex items-center justify-center bg-white mx-[5px] rounded-lg cursor-pointer select-none active:bg-[#f0f0f0]"
@click="handleDelete"
>
<svg
t="1742457305987"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="4499"
width="24"
height="24"
>
<path
d="M897.706667 831.146667H286.72c-8.533333 0-15.36-3.413333-20.48-10.24L39.253333 527.36c-6.826667-8.533333-6.826667-22.186667 0-30.72l226.986667-293.546667c5.12-6.826667 11.946667-10.24 20.48-10.24h610.986667c51.2 0 92.16 40.96 92.16 92.16v453.973334c0 51.2-40.96 92.16-92.16 92.16z m-599.04-51.2h599.04c22.186667 0 40.96-18.773333 40.96-40.96V285.013333c0-22.186667-18.773333-40.96-40.96-40.96H298.666667L92.16 512l206.506667 267.946667z"
fill="#333333"
p-id="4500"
></path>
<path
d="M670.72 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667L426.666667 416.426667c-10.24-10.24-10.24-25.6 0-35.84 10.24-10.24 25.6-10.24 35.84 0l226.986666 226.986666c10.24 10.24 10.24 25.6 0 35.84-6.826667 5.12-11.946667 6.826667-18.773333 6.826667z"
fill="#333333"
p-id="4501"
></path>
<path
d="M443.733333 650.24c-6.826667 0-13.653333-1.706667-18.773333-6.826667-10.24-10.24-10.24-25.6 0-35.84l226.986667-226.986666c10.24-10.24 25.6-10.24 35.84 0 10.24 10.24 10.24 25.6 0 35.84L462.506667 643.413333c-5.12 5.12-11.946667 6.826667-18.773334 6.826667z"
fill="#333333"
p-id="4502"
></path>
</svg>
</view>
</view>
</view>
</tm-sheet>
<tm-button class="mt-1" :block="true" @click="disabled ? '' : handlePay()" :disabled="disabled">支付</tm-button>
<numberKeyboard v-model="amount" />
</view>
</crud-layout>
</template>
@@ -77,24 +42,38 @@ import { usePayStore } from "@/sheep/stores/pay"
import payApi from "@@/api/pay"
import { storePrice } from "@/sheep/utils/formatMoney"
import { router } from "@/sheep"
import { merchantApi, walletApi } from "@/sheep/api"
import numberKeyboard from "@/sheep/components/numberKeyboard.vue"
import { filePath } from "@/sheep/utils/file"
import { hooks } from "@@/index"
const amount = ref("")
const keyboardLayout = ref([
["1", "2", "3"],
["4", "5", "6"],
["7", "8", "9"],
])
const scanData = ref<{ id?: string; name?: string }>({})
const disabled = ref(false)
const walletList = ref<any>([])
const curWalletId = ref("")
onShow(() => {
scanData.value = usePayStore().payData
if (scanData.value.id && scanData.value.name) {
onShow(async () => {
uni.showLoading({ title: "加载中...", mask: true })
scanData.value.id = usePayStore().payData.id
if (scanData.value.id) {
const { data } = await merchantApi.detail({ id: scanData.value.id })
scanData.value.name = data.name
usePayStore().setPayData(scanData.value)
disabled.value = false
} else {
uni.showToast({ title: "扫码信息不存在", icon: "none" })
disabled.value = true
}
const res = await walletApi.all()
if (res.code == 0) {
walletList.value = res.data.records
if (walletList.value.length > 0) {
curWalletId.value = walletList.value.find((v: any) => v.walletTypeUniqueCode == "1").id
}
}
uni.hideLoading()
})
const displayAmount = computed(() => {
@@ -107,27 +86,6 @@ const displayAmount = computed(() => {
)
})
// 按下键盘
const handleKeyPress = (key) => {
if (key === "." && amount.value.includes(".")) return
if (key === "." && !amount.value) {
amount.value = "0."
return
}
if (amount.value.includes(".")) {
const decimalPlaces = amount.value.split(".")[1]
if (decimalPlaces && decimalPlaces.length >= 2) return
}
amount.value += key
}
// 点击删除
const handleDelete = () => {
amount.value = amount.value.slice(0, -1)
}
// 点击支付
const handlePay = () => {
if (!scanData.value.id || !scanData.value.name) return uni.showToast({ title: "扫码信息不存在", icon: "none" })
@@ -156,19 +114,17 @@ const pay = async () => {
const res = await payApi.createQrCodeOrder({
merchantId: scanData.value.id,
customPrice: storePrice(Number(amount.value)),
walletId: curWalletId.value,
})
if (res.code != 0) {
throw new Error()
}
uni.showToast({ title: "支付成功", icon: "success" })
usePayStore().payData = {}
setTimeout(() => {
router.back()
uni.showToast({ title: res.msg || "支付失败", icon: "error" })
} else {
uni.hideLoading()
}, 1000)
usePayStore().setPayData({ ...scanData.value, customPrice: Number(amount.value).toFixed(2) })
router.jump("/pages/pay/payComplete", {}, 2)
}
} catch (error: any) {
// uni.showToast({ title: "错误", icon: "error" })
uni.showToast({ title: "错误", icon: "error" })
uni.hideLoading()
}
}
+199
View File
@@ -0,0 +1,199 @@
<template>
<view class="bg-gray-100 flex-col min-h-screen">
<view class="bg-white p-4 card mx-3 my-1 mt-2 flex items-center justify-between">
<view class="flex items-center">
<image class="w-64 h-64 mr-2" :src="filePath(transferMoney.sourceWalletType.walletTypeIcon)" />
<view>{{ transferMoney.sourceWalletType.walletTypeName }}</view>
</view>
<view class="flex items-center">
<view class="main-text-28">余额:</view>
<view class="main-text-28 mr-1">{{ hooks.useMoney(transferMoney.sourceWalletType.balance) + "元" }}</view>
</view>
</view>
<view class="bg-white p-4 card mx-3 my-1 flex items-center justify-between active:bg-[#f0f0f0]" @click="targetWalletSelect">
<view class="flex items-center">
<image class="w-64 h-64 rounded-full mr-2" src="@/static/page/money-cny-circle-fill.svg" />
<view>转入到</view>
</view>
<view class="flex items-center">
<view class="second-text-28 mr-1">{{ state.targetWalletTypeName }}</view>
<image class="w-38 h-38 rounded-full c-blueGray" src="@/static/page/arrow-right.svg" />
</view>
</view>
<view class="bg-white p-4 card mx-3 my-1">
<text class="text-gray-700 font-bold text-lg">转账金额</text>
<view class="flex-row items-center">
<text class="text-3xl text-[#333] mr-2">¥</text>
<text v-if="!amount" class="text-xl text-gray-300">转账金额</text>
<text v-else class="text-3xl">{{ formattedAmount }}</text>
</view>
</view>
<!-- 金额限制提示 -->
<view class="h-30rpx">
<view v-if="storePrice(amount) > transferMoney.sourceWalletType?.balance" class="text-xs c-red px-8">
注:转账金额不能超过钱包余额
</view>
</view>
<view class="p-4 font-bold mt-1">
<tm-button block @click="confirmTransfer" v-if="transferMoney.sourceWalletType.walletTypeId">确定转账</tm-button>
</view>
<number-keyboard v-model="amount" />
<!-- 选择转入方式 -->
<tm-drawer v-model:show="show" title="选择钱包" size="50%" bg-color="#efefef" position="bottom" :show-footer="true" :showClose="true">
<view class="m-4">
<view
v-for="(v, index) in state.walletList"
:key="index"
class="card mb-2 overflow-hidden relative border-4 border-solid border-white duration-200 flex justify-between items-center p-4"
:class="{ 'border-4 border-solid border-blue!': state.targetWalletTypeId == v.walletTypeId }"
@click="state.targetWalletTypeId = v.walletTypeId"
>
<view class="flex items-center">
<image class="w-70 h-70 mr-2" :src="filePath(v.walletTypeIcon)" />
<view class="flex flex-col">
<view class="main-text-32">{{ v.walletTypeName }}</view>
<view class="text-gray-500 text-sm">{{ v.cardNumber }}</view>
</view>
</view>
<view class="main-text-32">余额:{{ hooks.useMoney(v.balance) + "元" }}</view>
</view>
</view>
<template #footer>
<view class="font-bold px-5">
<tm-button block @click="confirmTargetWallet">确 定</tm-button>
</view>
</template>
</tm-drawer>
</view>
</template>
<script setup lang="ts">
import { ref, computed, reactive } from "vue"
import { onLoad } from "@dcloudio/uni-app"
import NumberKeyboard from "@/sheep/components/numberKeyboard.vue"
import { payApi, walletApi } from "@/sheep/api"
import { hooks, router } from "@@/index"
import { filePath } from "@/sheep/utils/file"
import { storePrice } from "@/sheep/utils/formatMoney"
import { useTransferMoney } from "@/sheep/stores/transferMoney"
const transferMoney = useTransferMoney()
const amount = ref("")
const show = ref(false)
const state = reactive<any>({
sourceWalletTypeId: "",
sourceWalletTypeName: "",
walletList: [],
targetWalletTypeId: "",
targetWalletTypeName: "",
})
const curTargetWallet = ref()
onLoad(async () => {
if (!transferMoney.sourceWalletType.walletTypeId) return uni.showToast({ title: "钱包类型id不存在", icon: "none" })
state.sourceWalletTypeId = transferMoney.sourceWalletType.walletTypeId
state.sourceWalletTypeName = transferMoney.sourceWalletType.walletTypeName
uni.setNavigationBarTitle({ title: state.sourceWalletTypeName || "源钱包" })
const res = await walletApi.all()
if (res.code == 0) {
state.walletList = res.data.records.filter((item: any) => item.walletTypeId != state.sourceWalletTypeId)
}
if (!curTargetWallet.value) {
curTargetWallet.value = state.walletList[0]
state.targetWalletTypeId = state.walletList[0]?.walletTypeId
state.targetWalletTypeName = state.walletList[0]?.walletTypeName
}
})
// 目标钱包选择
const targetWalletSelect = () => {
// state.sourceWalletTypeId = ""
show.value = true
}
// 确认目标钱包
const confirmTargetWallet = () => {
// state.sourceWalletTypeName = state.walletList.find((item: any) => item.walletTypeId != state.sourceWalletTypeId).walletTypeName
show.value = false
}
// 格式化金额显示
const formattedAmount = computed(() => {
if (!amount.value) return ""
// 处理小数点情况
if (amount.value.endsWith(".")) {
return amount.value
}
const parts = amount.value.split(".")
// 添加千位分隔符
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",")
// 处理小数部分
if (parts.length > 1) {
// 如果小数部分不足两位,不自动补零
return `${parts[0]}.${parts[1]}`
}
return parts[0]
})
const numAmount = computed(() => storePrice(parseFloat(amount.value.endsWith(".") ? amount.value.slice(0, -1) : amount.value)))
// 确认转账
const confirmTransfer = async () => {
if (!amount.value || amount.value === "0" || amount.value === "0." || parseFloat(amount.value) === 0) {
return uni.showToast({ title: "金额不能为零", icon: "none" })
}
if (numAmount.value > transferMoney.sourceWalletType.balance) {
return uni.showToast({ title: "转账金额不能超过钱包余额", icon: "none" })
}
// console.log("state.sourceWalletTypeId", state.sourceWalletTypeId)
// console.log("state.targetWalletTypeId", state.targetWalletTypeId)
// console.log("金额", numAmount.value)
uni.showModal({
title: "确定转入吗?",
success: async (res) => {
if (res.confirm) {
await confirmTransferAgain()
}
},
})
}
// 二次确认转账
const confirmTransferAgain = async () => {
try {
uni.showLoading({ title: "正在转入...", mask: true })
const res = await payApi.transferMoney({
sourceWalletTypeId: state.sourceWalletTypeId,
targetWalletTypeId: state.targetWalletTypeId,
balance: numAmount.value,
})
if (res.code == 0) {
uni.showToast({ title: "转账成功", icon: "success" })
transferMoney.setSourceWalletType({})
// router.jump("/pages/wallet/list", {}, 2)
router.back()
} else {
uni.showToast({ title: res.msg, icon: "none" })
}
} catch (error: any) {
uni.showToast({
title: error.message,
icon: "none",
})
} finally {
uni.hideLoading()
}
}
</script>
+24 -26
View File
@@ -119,34 +119,34 @@ const doSubmit = async () => {
<crud-layout title="申请售后" mainIsScroll bg="/static/page/blue-bg.png">
<view class="h-30rpx" />
<view class="flex-col justify-center card p-x-20rpx p-y-30rpx m-b-20rpx">
<view class="m-t-15rpx">
<view
class="flex-row items-start justify-between"
v-for="(v, i) in state.shopCarList"
:key="i"
@tap.stop="router.jump('/pages/merchant/product-detail', { id: v.productId })"
>
<view class="flex-row items-center">
<image class="w-160rpx h-160rpx rounded-8rpx" :src="filePath(v.productPic)" mode="aspectFill" />
<view class="flex-col m-l-15rpx second-text-26">
<view class="sub-text-28">{{ v.productName }}</view>
<view class="m-t-5rpx">¥ {{ hooks.useMoney(v.productPrice) }}</view>
<view class="m-t-5rpx">x {{ v.productCount }}</view>
</view>
</view>
<view class="flex-row-center">
<view class="sub-text-32">¥ {{ hooks.useMoney(v.totalPrice) }}</view>
<!-- <view class="m-t-15rpx"> -->
<view
class="flex-row items-start justify-between"
v-for="(v, i) in state.shopCarList"
:key="i"
@tap.stop="router.jump('/pages/merchant/product-detail', { id: v.productId })"
>
<view class="flex-row items-center">
<image class="w-160rpx h-160rpx rounded-8rpx" :src="filePath(v.productPic)" mode="aspectFill" />
<view class="flex-col m-l-15rpx second-text-26">
<view class="sub-text-28">{{ v.productName }}</view>
<view class="m-t-5rpx">¥ {{ hooks.useMoney(v.productPrice) }}</view>
<view class="m-t-5rpx">x {{ v.productCount }}</view>
</view>
</view>
<view class="m-y-15rpx h-1px bg-#999 bg-opacity-5" />
<view class="flex-row items-center justify-between">
<view class="sub-text-28">实付款</view>
<view class="flex-row items-end">
<view class="sub-text-28">¥</view>
<view class="m-l-5rpx sub-text-28">{{ hooks.useMoney(state.detail.payPrice) }}</view>
</view>
<view class="flex-row-center">
<view class="sub-text-32">¥ {{ hooks.useMoney(v.totalPrice) }}</view>
</view>
</view>
<!-- <view class="m-y-15rpx h-1px bg-#999 bg-opacity-5" /> -->
<view class="flex-row items-center justify-between">
<view class="sub-text-28">实付款</view>
<view class="flex-row items-end">
<view class="sub-text-28">¥</view>
<view class="m-l-5rpx sub-text-28">{{ hooks.useMoney(state.detail.payPrice) }}</view>
</view>
</view>
<!-- </view> -->
</view>
<view class="card p-x-20rpx p-y-30rpx m-b-20rpx">
<view class="sub-text-28">售后类型</view>
@@ -208,5 +208,3 @@ const doSubmit = async () => {
</template>
</crud-layout>
</template>
<style lang="scss" scoped></style>
+152
View File
@@ -0,0 +1,152 @@
<script setup lang="ts">
import { ref, reactive, computed } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { merchantApi } from "@@/api"
import { hooks, router } from "@@/index"
import { filePath } from "@@/utils/file"
const pageRef = ref<any>(null)
const state = reactive<any>({
pa: {
pagesize: 10,
type: "2",
parentId: "",
},
})
const pageHook = hooks.usePage(pageRef, merchantApi.childrenPage, null, "data.records")
const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, state.pa)
}
onLoad((options: any) => {
const app = getApp()
app._initTabbar()
if (options.parentId) {
state.pa.parentId = options.parentId
}
})
onShow(async () => {
pageRef.value && pageRef.value.reload(false)
uni.showLoading({
title: "加载中...",
mask: true,
})
try {
await getDetail()
} catch (error) {
uni.showToast({
title: "加载失败",
icon: "error",
})
} finally {
uni.hideLoading()
}
uni.setNavigationBarTitle({ title: state.detail.name })
})
const getDetail = async () => {
const { data } = await merchantApi.detail({ id: state.pa.parentId })
state.detail = data
}
const toDetail = async (v: any) => {
const isLogin = await hooks.useCheckLogin()
if (isLogin) {
router.jump("/pages/shop/detail", { id: v.id })
}
}
</script>
<template>
<view class="h-full overflow-hidden">
<swiper
class="w-100vw h-30vh"
circular
:indicator-dots="true"
indicator-active-color="#0779FD"
indicator-color="#ffffff"
:autoplay="true"
>
<swiper-item v-for="(v, i) in state.detail?.swiperPic?.split(',')" :key="i">
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
</swiper-item>
</swiper>
<crud-layout>
<z-paging
ref="pageRef"
height="70%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="pageHook.scroll"
>
<view class="h-20rpx" />
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
<view class="flex-1 flex-col m-l-20rpx">
<view class="flex-row items-center justify-between">
<view class="flex-row-center sub-text-34">{{ v.name.length > 7 ? v.name.substring(0, 7) + "..." : v.name }}</view>
<tm-tag size="s">{{ v.deptName.length > 5 ? v.deptName.substring(0, 5) + "..." : v.deptName }}</tm-tag>
</view>
<view class="m-t-10rpx">
<view v-if="v.phone" class="flex items-center">
<svg
t="1743075703202"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2684"
width="12"
height="12"
>
<path
d="M575.7 647.1l69.4-69.2 13.3 2.3c1.7 0.3 4.9 0.9 9.4 1.7 7.4 1.3 15.7 2.9 24.6 4.5 25.5 4.8 50.9 9.8 74.8 14.9 17.3 3.7 33.1 7.3 47 10.7 27.6 6.8 47.3 12.9 59.1 18.6 43 20.8 60 65.5 53.4 122-9.7 81.3-97 174.3-204.4 175.4-121 1.2-291.4-87.7-411.9-214.7C165.3 560.4 81.8 406.9 98 278.3c8.5-67.1 40.2-115.9 87.8-147.2 32.4-21.3 69.4-32.5 97.9-34.6 38.2-2.8 69.6 9.6 92.5 38 9.7 12 19.7 36.1 32.2 73.3 3.6 10.9 7.4 22.8 11.3 35.4 7 23 14.1 47.6 20.9 72.2 2.4 8.6 4.5 16.6 6.4 23.7 1.1 4.3 2 7.4 2.4 9.1l3.7 14.2-80.4 81.8c44.5 89 122.6 169.8 203 202.9z m13.5 60l-15.3-5.1c-105.4-35.6-205.4-139.4-256.3-252.3l-7.3-16.2 85-86.4c-1.5-5.6-3.1-11.6-4.9-17.9-6.6-24.1-13.5-48.2-20.4-70.7-3.8-12.3-7.4-23.7-10.9-34.2-10.2-30.5-19.1-52-23.3-57.2-11.8-14.6-26.4-20.4-48.2-18.8-20.2 1.5-48.7 10.1-73.1 26.2-35.2 23.2-58.3 58.6-64.8 110.3-13.8 108.7 63.1 250.2 198.4 392.7C459.5 794.9 617 877 721.8 876c79.2-0.8 146.4-72.5 153.2-129.4 4.3-36.6-4.3-59.4-24.4-69.1-7.5-3.6-24.7-8.9-48.9-14.9-13.4-3.3-28.6-6.8-45.4-10.4-23.3-5-48.4-10-73.5-14.7-7.2-1.3-13.9-2.6-20.1-3.7l-73.5 73.3z"
fill="#666666"
p-id="2685"
></path>
</svg>
<view class="second-text-28 ml-1">{{ v.phone }}</view>
</view>
<view class="second-text-24">
<view v-if="v.jobTime != ',,'" class="second-text-28">营业时间:</view>
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
</view>
<view v-if="v.addressDes" class="second-text-28">
<svg
t="1743075857752"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="3808"
width="12"
height="11"
>
<path
d="M512 1012.8c-253.6 0-511.2-54.4-511.2-158.4 0-92.8 198.4-131.2 283.2-143.2h3.2c12 0 22.4 8.8 24 20.8 0.8 6.4-0.8 12.8-4.8 17.6-4 4.8-9.6 8.8-16 9.6-176.8 25.6-242.4 72-242.4 96 0 44.8 180.8 110.4 463.2 110.4s463.2-65.6 463.2-110.4c0-24-66.4-70.4-244.8-96-6.4-0.8-12-4-16-9.6-4-4.8-5.6-11.2-4.8-17.6 1.6-12 12-20.8 24-20.8h3.2c85.6 12 285.6 50.4 285.6 143.2 0.8 103.2-256 158.4-509.6 158.4z m-16.8-169.6c-12-11.2-288.8-272.8-288.8-529.6 0-168 136.8-304.8 304.8-304.8S816 145.6 816 313.6c0 249.6-276.8 517.6-288.8 528.8l-16 16-16-15.2zM512 56.8c-141.6 0-256.8 115.2-256.8 256.8 0 200.8 196 416 256.8 477.6 61.6-63.2 257.6-282.4 257.6-477.6C768.8 172.8 653.6 56.8 512 56.8z m0 392.8c-80 0-144.8-64.8-144.8-144.8S432 160 512 160c80 0 144.8 64.8 144.8 144.8 0 80-64.8 144.8-144.8 144.8zM512 208c-53.6 0-96.8 43.2-96.8 96.8S458.4 401.6 512 401.6c53.6 0 96.8-43.2 96.8-96.8S564.8 208 512 208z"
fill="#707070"
p-id="3809"
></path>
</svg>
<text class="ml-1">地址:</text>
<text class="m-l-10rpx">{{ v.addressDes }}</text>
</view>
</view>
</view>
</view>
</z-paging>
</crud-layout>
</view>
</template>
+123 -31
View File
@@ -1,47 +1,114 @@
<template>
<crud-layout mainIsScroll tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
<tm-sticky>
<!-- start 轮播 start -->
<z-swiper>
<z-swiper-item v-for="(v, i) in state.detail.swiperPic?.split(',')" :key="i">
<image class="w-100vw h-400rpx" :src="filePath(v)" mode="aspectFill" />
</z-swiper-item>
</z-swiper>
<!-- end 轮播 end -->
<swiper
class="w-100vw h-30vh"
circular
:indicator-dots="true"
indicator-active-color="#0779FD"
indicator-color="#ffffff"
:autoplay="true"
>
<swiper-item v-for="(v, i) in state.detail?.swiperPic?.split(',')" :key="i">
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
</swiper-item>
</swiper>
<tm-sticky-header>
<view class="m-x-30rpx">
<view class="h-15rpx" />
<!-- start 简介 start -->
<view flex-row card p-20rpx>
<view class="flex-row card p-20rpx m-b-20rpx">
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(state.detail.logoPic)" mode="aspectFill" />
<view class="flex-1 flex-col m-l-20rpx">
<view class="flex-row items-center justify-between">
<view class="flex-row-center sub-text-32">{{ state.detail.name }}</view>
<tm-tag size="s">{{ state.detail.deptName }}</tm-tag>
<view class="flex-row-center sub-text-34">
{{ state.detail.name?.length > 7 ? state.detail.name.substring(0, 7) + "..." : state.detail.name }}
</view>
<tm-tag size="s">
{{ state.detail.deptName?.length > 5 ? state.detail.deptName.substring(0, 5) + "..." : state.detail.deptName }}
</tm-tag>
</view>
<view class="second-text-24">{{ state.detail.phone }}</view>
<view class="second-text-24">
<view class="second-text-28">营业时间:</view>
<view>{{ state.detail.jobTime?.split(",")[0] ? "早:" + state.detail.jobTime?.split(",")[0] : "" }}</view>
<view>{{ state.detail.jobTime?.split(",")[1] ? "中:" + state.detail.jobTime?.split(",")[1] : "" }}</view>
<view>{{ state.detail.jobTime?.split(",")[2] ? "晚:" + state.detail.jobTime?.split(",")[2] : "" }}</view>
</view>
<view v-if="state.detail.addressDes" class="m-t-10rpx second-text-28">
<text>地址</text>
<text class="m-l-10rpx">{{ state.detail.addressDes }}</text>
<view class="m-t-10rpx">
<view v-if="state.detail.phone" class="flex items-center">
<svg
t="1743075703202"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2684"
width="12"
height="12"
>
<path
d="M575.7 647.1l69.4-69.2 13.3 2.3c1.7 0.3 4.9 0.9 9.4 1.7 7.4 1.3 15.7 2.9 24.6 4.5 25.5 4.8 50.9 9.8 74.8 14.9 17.3 3.7 33.1 7.3 47 10.7 27.6 6.8 47.3 12.9 59.1 18.6 43 20.8 60 65.5 53.4 122-9.7 81.3-97 174.3-204.4 175.4-121 1.2-291.4-87.7-411.9-214.7C165.3 560.4 81.8 406.9 98 278.3c8.5-67.1 40.2-115.9 87.8-147.2 32.4-21.3 69.4-32.5 97.9-34.6 38.2-2.8 69.6 9.6 92.5 38 9.7 12 19.7 36.1 32.2 73.3 3.6 10.9 7.4 22.8 11.3 35.4 7 23 14.1 47.6 20.9 72.2 2.4 8.6 4.5 16.6 6.4 23.7 1.1 4.3 2 7.4 2.4 9.1l3.7 14.2-80.4 81.8c44.5 89 122.6 169.8 203 202.9z m13.5 60l-15.3-5.1c-105.4-35.6-205.4-139.4-256.3-252.3l-7.3-16.2 85-86.4c-1.5-5.6-3.1-11.6-4.9-17.9-6.6-24.1-13.5-48.2-20.4-70.7-3.8-12.3-7.4-23.7-10.9-34.2-10.2-30.5-19.1-52-23.3-57.2-11.8-14.6-26.4-20.4-48.2-18.8-20.2 1.5-48.7 10.1-73.1 26.2-35.2 23.2-58.3 58.6-64.8 110.3-13.8 108.7 63.1 250.2 198.4 392.7C459.5 794.9 617 877 721.8 876c79.2-0.8 146.4-72.5 153.2-129.4 4.3-36.6-4.3-59.4-24.4-69.1-7.5-3.6-24.7-8.9-48.9-14.9-13.4-3.3-28.6-6.8-45.4-10.4-23.3-5-48.4-10-73.5-14.7-7.2-1.3-13.9-2.6-20.1-3.7l-73.5 73.3z"
fill="#666666"
p-id="2685"
></path>
</svg>
<view class="second-text-28 ml-1">{{ state.detail.phone }}</view>
<view
class="second-text-20 bg-#f8f8f8 ml-1 p-0.3 flex items-center rounded-1 border border-solid border-b-coolGray"
@tap="doPhone"
>
联系商家
</view>
</view>
<view class="second-text-24">
<view class="second-text-28">{{ state.detail.jobTime == ",," ? "" : "营业时间:" }}</view>
<view>{{ state.detail.jobTime?.split(",")[0] ? "早:" + state.detail.jobTime?.split(",")[0] : "" }}</view>
<view>{{ state.detail.jobTime?.split(",")[1] ? "中:" + state.detail.jobTime?.split(",")[1] : "" }}</view>
<view>{{ state.detail.jobTime?.split(",")[2] ? "晚:" + state.detail.jobTime?.split(",")[2] : "" }}</view>
</view>
<view v-if="state.detail.addressDes" class="second-text-28">
<svg
t="1743075857752"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="3808"
width="12"
height="11"
>
<path
d="M512 1012.8c-253.6 0-511.2-54.4-511.2-158.4 0-92.8 198.4-131.2 283.2-143.2h3.2c12 0 22.4 8.8 24 20.8 0.8 6.4-0.8 12.8-4.8 17.6-4 4.8-9.6 8.8-16 9.6-176.8 25.6-242.4 72-242.4 96 0 44.8 180.8 110.4 463.2 110.4s463.2-65.6 463.2-110.4c0-24-66.4-70.4-244.8-96-6.4-0.8-12-4-16-9.6-4-4.8-5.6-11.2-4.8-17.6 1.6-12 12-20.8 24-20.8h3.2c85.6 12 285.6 50.4 285.6 143.2 0.8 103.2-256 158.4-509.6 158.4z m-16.8-169.6c-12-11.2-288.8-272.8-288.8-529.6 0-168 136.8-304.8 304.8-304.8S816 145.6 816 313.6c0 249.6-276.8 517.6-288.8 528.8l-16 16-16-15.2zM512 56.8c-141.6 0-256.8 115.2-256.8 256.8 0 200.8 196 416 256.8 477.6 61.6-63.2 257.6-282.4 257.6-477.6C768.8 172.8 653.6 56.8 512 56.8z m0 392.8c-80 0-144.8-64.8-144.8-144.8S432 160 512 160c80 0 144.8 64.8 144.8 144.8 0 80-64.8 144.8-144.8 144.8zM512 208c-53.6 0-96.8 43.2-96.8 96.8S458.4 401.6 512 401.6c53.6 0 96.8-43.2 96.8-96.8S564.8 208 512 208z"
fill="#707070"
p-id="3809"
></path>
</svg>
<text class="ml-1">地址:</text>
<text class="m-l-10rpx">{{ state.detail.addressDes }}</text>
</view>
</view>
</view>
</view>
<!-- end 简介 end -->
</view>
</tm-sticky-header>
<view class="h-30rpx" />
<tm-alert
v-if="state.detail?.discountsPrice"
color="#0779FD"
icon="notification-line"
closeIcon="close-line"
:border="['2']"
:borderColor="['#89c0ff']"
>
<marquee class="flex items-center">{{ state.detail.discountsPrice }}</marquee>
<!-- <view class="w-full overflow-hidden flex">
<view class="scroll-text">{{ state.detail.discountsPrice }}</view>
</view> -->
</tm-alert>
<!-- start 商品 start -->
<view class="flex-row">
<scroll-view scroll-y :style="{ height: getHeight() }" class="menu w-200rpx h-full p-l-12rpx p-b-20rpx bg-#f6f6f6">
<scroll-view
v-if="state.classifyList?.length > 0"
scroll-y
:style="{ height: getHeight() }"
class="menu w-200rpx h-full p-l-12rpx p-b-20rpx bg-#f6f6f6"
>
<view
class="menu_item flex-row-center"
v-for="(v, i) in state.classifyList"
@@ -55,7 +122,7 @@
</view>
</scroll-view>
<scroll-view scroll-y :style="{ height: getHeight() }" class="flex-1 p-b-20rpx">
<scroll-view v-if="state.shopList?.length > 0" scroll-y :style="{ height: getHeight() }" class="flex-1 p-b-20rpx">
<view class="m-x-15rpx">
<product-row
v-for="goodsItem in state.goodsList"
@@ -75,7 +142,7 @@
<!-- end 商品 end -->
<template #main-bottom>
<view class="car z-200 p-x-30rpx p-y-30rpx bg-white">
<view v-if="false" class="car z-200 p-x-30rpx p-y-30rpx bg-white">
<product-total :totPrice="state.totPrice" :totCount="state.totCount" @doContainer="doVisibleCar" @doPay="doPay" />
</view>
</template>
@@ -99,15 +166,13 @@
import { reactive, nextTick, ref } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import { hooks, router } from "@@/index"
import { router } from "@@/index"
import { foodApi, merchantApi, payApi, shopApi } from "@@/api"
import zSwiper from "@zebra-ui/swiper/components/z-swiper/z-swiper.vue"
import zSwiperItem from "@zebra-ui/swiper/components/z-swiper-item/z-swiper-item.vue"
import { filePath } from "@@/utils/file"
import ProductRow from "./components/product-row.vue"
import ProductCar from "./components/product-car.vue"
import ProductTotal from "./components/product-total.vue"
import ProductSku from "./components/product-sku.vue"
import { filePath } from "@@/utils/file"
// 商品详情相关数据
const state = reactive<any>({
@@ -140,8 +205,8 @@ onShow(async () => {
})
try {
await getDetail()
await getShopCar()
await getClassify()
// await getShopCar()
// await getClassify()
} catch (error) {
uni.showToast({
title: "加载失败",
@@ -217,6 +282,20 @@ const doClassify = async (i: any) => {
await getPorduct()
}
// 联系商家
const doPhone = () => {
if (isEmpty(state.detail.phone)) {
uni.showToast({ title: "该商户没有预留电话", icon: "none" })
return
}
;(window as any).dd
.callPhone({
phoneNum: state.detail.phone,
})
.then((res) => {})
.catch((err) => {})
}
const getHeight = () => {
const rpx = 480
return `calc(100vh - ${uni.upx2px(rpx)}px)`
@@ -414,4 +493,17 @@ const submitPay = async () => {
.car {
box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.1);
}
.scroll-text {
display: inline-block;
white-space: nowrap;
animation: scroll-left 10s linear infinite;
}
@keyframes scroll-left {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(-100%);
}
}
</style>
+58 -53
View File
@@ -1,71 +1,76 @@
<script setup lang="ts">
import { reactive } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app";
import { isEmpty } from "radash";
import { shopApi } from "@@/api";
import zSwiper from "@zebra-ui/swiper/components/z-swiper/z-swiper.vue";
import zSwiperItem from "@zebra-ui/swiper/components/z-swiper-item/z-swiper-item.vue";
import { filePath } from "@/sheep/utils/file";
import { reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import { shopApi } from "@@/api"
import { filePath } from "@/sheep/utils/file"
const state = reactive<any>({
detailId: null,
detail: null,
});
detailId: null,
detail: null,
})
onLoad((options: any) => {
if (!isEmpty(options.id)) {
state.detailId = options.id;
}
});
if (!isEmpty(options.id)) {
state.detailId = options.id
}
})
onShow(() => {
getDetail();
});
getDetail()
})
const getDetail = async () => {
const { data } = await shopApi.getSupermarketSpuDetail({ id: state.detailId });
state.detail = data;
};
const { data } = await shopApi.getSupermarketSpuDetail({ id: state.detailId })
state.detail = data
}
</script>
<template>
<crud-layout title="订单详情" tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
<!-- <z-swiper> -->
<!-- <z-swiper-item v-for="(v, i) in state.detail.sliderPicUrls" :key="i"> -->
<image class="w-100vw" :src="filePath(state.detail.picUrl)" mode="widthFix" />
<!-- </z-swiper-item> -->
<!-- </z-swiper> -->
<crud-layout title="订单详情" tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
<swiper
class="w-100vw h-30vh"
circular
:indicator-dots="true"
indicator-active-color="#0779FD"
indicator-color="#ffffff"
:autoplay="true"
>
<swiper-item v-for="(v, i) in state.detail?.sliderPicUrls?.split(',')" :key="i">
<image class="w-full h-full" :src="filePath(state.detail.picUrl)" mode="aspectFill" />
</swiper-item>
</swiper>
<view class="p-x-15rpx">
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
<view class="flex-row items-center justify-between">
<!-- <view class="flex-row items-center"> -->
<!-- <view class="second-text-46 color-#f63a36!">¥{{ state.detail.price }}</view> -->
<!-- <view class="m-l-20rpx second-text-28 line-through">¥{{ state.detail.marketPrice }}</view> -->
<!-- </view> -->
<view class="second-text-26">已售{{ state.detail.salesCount }}</view>
</view>
<view class="flex-col m-t-15rpx">
<view class="sub-text-32">{{ state.detail.productName }}</view>
<view class="m-t-15rpx second-text-26">{{ state.detail.introduction }}</view>
</view>
</view>
<view class="h-15rpx" />
<view class="flex-row items-center justify-between card p-y-20rpx p-x-30rpx">
<view class="prefix_title">评价</view>
</view>
<view class="h-15rpx" />
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
<view class="prefix_title">详情</view>
<view class="m-t-15rpx" v-html="state.detail.description"></view>
</view>
</view>
</crud-layout>
<view class="p-x-15rpx">
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
<view class="flex-row items-center justify-between">
<!-- <view class="flex-row items-center"> -->
<!-- <view class="second-text-46 color-#f63a36!">¥{{ state.detail.price }}</view> -->
<!-- <view class="m-l-20rpx second-text-28 line-through">¥{{ state.detail.marketPrice }}</view> -->
<!-- </view> -->
<view class="second-text-26">已售{{ state.detail.salesCount }}</view>
</view>
<view class="flex-col m-t-15rpx">
<view class="sub-text-32">{{ state.detail.productName }}</view>
<view class="m-t-15rpx second-text-26">{{ state.detail.introduction }}</view>
</view>
</view>
<view class="h-15rpx" />
<view class="flex-row items-center justify-between card p-y-20rpx p-x-30rpx">
<view class="prefix_title">评价</view>
</view>
<view class="h-15rpx" />
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
<view class="prefix_title">详情</view>
<view class="m-t-15rpx" v-html="state.detail.description"></view>
</view>
</view>
</crud-layout>
</template>
<style lang="scss" scoped>
:deep() {
.layout_main > scroll-view {
padding: 0 !important;
}
.layout_main > scroll-view {
padding: 0 !important;
}
}
</style>
+119
View File
@@ -0,0 +1,119 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { merchantApi } from "@@/api"
import { hooks, router } from "@@/index"
import { filePath } from "@@/utils/file"
const pageRef = ref<any>(null)
const state = reactive<any>({
pa: {
pagesize: 10,
type: "2",
},
})
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, state.pa)
}
onLoad(() => {
const app = getApp()
app._initTabbar()
})
onShow(() => {
// pageRef.value && pageRef.value.reload(false)
})
const toDetail = async (v: any) => {
const isLogin = await hooks.useCheckLogin()
if (isLogin) {
if (v.supType && v.supType == "10") return router.jump("/pages/shop/brandDetail", { parentId: v.id })
if (v.supType && v.supType == "20") return router.jump("/pages/shop/detail", { id: v.id })
uni.showToast({ title: "合作商家类型未知", icon: "none" })
}
}
</script>
<template>
<crud-layout bg="/static/page/blue-bg.png">
<z-paging
ref="pageRef"
height="100%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="pageHook.scroll"
>
<view class="h-20rpx" />
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
<view class="flex-1 flex-col m-l-20rpx">
<view class="flex-row items-center justify-between">
<view class="flex-row-center sub-text-34">{{ v.name.length > 7 ? v.name.substring(0, 6) + "..." : v.name }}</view>
<tm-tag size="s">{{ v.deptName.length > 5 ? v.deptName.substring(0, 5) + "..." : v.deptName }}</tm-tag>
</view>
<view class="m-t-10rpx">
<view class="flex items-center justify-between">
<view>
<view v-if="v.phone" class="flex items-center">
<svg
t="1743075703202"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2684"
width="12"
height="12"
>
<path
d="M575.7 647.1l69.4-69.2 13.3 2.3c1.7 0.3 4.9 0.9 9.4 1.7 7.4 1.3 15.7 2.9 24.6 4.5 25.5 4.8 50.9 9.8 74.8 14.9 17.3 3.7 33.1 7.3 47 10.7 27.6 6.8 47.3 12.9 59.1 18.6 43 20.8 60 65.5 53.4 122-9.7 81.3-97 174.3-204.4 175.4-121 1.2-291.4-87.7-411.9-214.7C165.3 560.4 81.8 406.9 98 278.3c8.5-67.1 40.2-115.9 87.8-147.2 32.4-21.3 69.4-32.5 97.9-34.6 38.2-2.8 69.6 9.6 92.5 38 9.7 12 19.7 36.1 32.2 73.3 3.6 10.9 7.4 22.8 11.3 35.4 7 23 14.1 47.6 20.9 72.2 2.4 8.6 4.5 16.6 6.4 23.7 1.1 4.3 2 7.4 2.4 9.1l3.7 14.2-80.4 81.8c44.5 89 122.6 169.8 203 202.9z m13.5 60l-15.3-5.1c-105.4-35.6-205.4-139.4-256.3-252.3l-7.3-16.2 85-86.4c-1.5-5.6-3.1-11.6-4.9-17.9-6.6-24.1-13.5-48.2-20.4-70.7-3.8-12.3-7.4-23.7-10.9-34.2-10.2-30.5-19.1-52-23.3-57.2-11.8-14.6-26.4-20.4-48.2-18.8-20.2 1.5-48.7 10.1-73.1 26.2-35.2 23.2-58.3 58.6-64.8 110.3-13.8 108.7 63.1 250.2 198.4 392.7C459.5 794.9 617 877 721.8 876c79.2-0.8 146.4-72.5 153.2-129.4 4.3-36.6-4.3-59.4-24.4-69.1-7.5-3.6-24.7-8.9-48.9-14.9-13.4-3.3-28.6-6.8-45.4-10.4-23.3-5-48.4-10-73.5-14.7-7.2-1.3-13.9-2.6-20.1-3.7l-73.5 73.3z"
fill="#666666"
p-id="2685"
></path>
</svg>
<view class="second-text-28 ml-1">{{ v.phone }}</view>
</view>
</view>
<tm-tag v-if="v.supType == '10' && Number(v.mchCount) > 0" size="xs" skin="thin">共{{ v.mchCount }}家</tm-tag>
</view>
<view class="second-text-24">
<view v-if="v.jobTime != ',,'" class="second-text-28">营业时间:</view>
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
</view>
<view v-if="v.addressDes" class="second-text-28">
<svg
t="1743075857752"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="3808"
width="12"
height="11"
>
<path
d="M512 1012.8c-253.6 0-511.2-54.4-511.2-158.4 0-92.8 198.4-131.2 283.2-143.2h3.2c12 0 22.4 8.8 24 20.8 0.8 6.4-0.8 12.8-4.8 17.6-4 4.8-9.6 8.8-16 9.6-176.8 25.6-242.4 72-242.4 96 0 44.8 180.8 110.4 463.2 110.4s463.2-65.6 463.2-110.4c0-24-66.4-70.4-244.8-96-6.4-0.8-12-4-16-9.6-4-4.8-5.6-11.2-4.8-17.6 1.6-12 12-20.8 24-20.8h3.2c85.6 12 285.6 50.4 285.6 143.2 0.8 103.2-256 158.4-509.6 158.4z m-16.8-169.6c-12-11.2-288.8-272.8-288.8-529.6 0-168 136.8-304.8 304.8-304.8S816 145.6 816 313.6c0 249.6-276.8 517.6-288.8 528.8l-16 16-16-15.2zM512 56.8c-141.6 0-256.8 115.2-256.8 256.8 0 200.8 196 416 256.8 477.6 61.6-63.2 257.6-282.4 257.6-477.6C768.8 172.8 653.6 56.8 512 56.8z m0 392.8c-80 0-144.8-64.8-144.8-144.8S432 160 512 160c80 0 144.8 64.8 144.8 144.8 0 80-64.8 144.8-144.8 144.8zM512 208c-53.6 0-96.8 43.2-96.8 96.8S458.4 401.6 512 401.6c53.6 0 96.8-43.2 96.8-96.8S564.8 208 512 208z"
fill="#707070"
p-id="3809"
></path>
</svg>
<text class="ml-1">地址:</text>
<text class="m-l-10rpx">{{ v.addressDes }}</text>
</view>
</view>
</view>
</view>
</z-paging>
</crud-layout>
</template>
-79
View File
@@ -1,79 +0,0 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { merchantApi } from "@@/api"
import { hooks, router } from "@@/index"
import { filePath } from "@@/utils/file"
const pageRef = ref<any>(null)
const state = reactive<any>({
pa: {
pagesize: 10,
type: "2",
},
})
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, state.pa)
}
onLoad(() => {
const app = getApp()
app._initTabbar()
})
onShow(() => {
pageRef.value && pageRef.value.reload(false)
})
const toDetail = async (v: any) => {
return
const isLogin = await hooks.useCheckLogin()
if (isLogin) {
router.jump("/pages/shop/detail", { id: v.id })
}
}
</script>
<template>
<crud-layout bg="/static/page/blue-bg.png">
<z-paging
ref="pageRef"
height="100%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="pageHook.scroll"
>
<view class="h-20rpx" />
<view class="flex-col card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
<view class="flex-row-center">
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
<view class="flex-1 flex-col m-l-20rpx">
<view class="flex-row items-center justify-between">
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
<tm-tag size="s">{{ v.deptName }}</tm-tag>
</view>
<view class="second-text-24">{{ v.phone }}</view>
<view class="second-text-24">
<view v-if="v.jobTime != ',,'" class="second-text-28">营业时间:</view>
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
</view>
<view v-if="v.addressDes" class="m-t-10rpx second-text-28">
<text>地址</text>
<text class="m-l-10rpx">{{ v.addressDes }}</text>
</view>
</view>
</view>
</view>
</z-paging>
</crud-layout>
</template>
+16 -16
View File
@@ -3,7 +3,7 @@
<z-paging
ref="pageRef"
:fixed="false"
v-model="list"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
@@ -11,7 +11,7 @@
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="scroll"
@scroll="pageHook.scroll"
>
<template #top>
<view class="h-30rpx" />
@@ -21,7 +21,7 @@
<view class="flex items-center cursor-pointer">
<tm-between-time
start="2020-1-1"
end="2040-1-1"
end="2050-1-1"
v-model="state.date"
v-model:model-str="state.formatVal"
@confirm="datePickerConfirm"
@@ -50,7 +50,7 @@
<view class="h-20rpx" />
<view class="bg-white rounded-16rpx p-2 mb-1 shadow-md" v-for="(v, i) in list" :key="i">
<view class="bg-white rounded-16rpx p-3 mb-2 shadow-md" v-for="(v, i) in pageHook.list" :key="i">
<view class="flex justify-between items-center text-sm text-gray-800 mb-1">
<view class="flex items-center">
<image class="w-50rpx h-50rpx rounded-8rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
@@ -58,33 +58,33 @@
</view>
<view>{{ v.day }}</view>
</view>
<view class="bg-gray-100 rounded-12rpx p-1">
<view class="flex justify-between mb-1">
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx">
<view class="bg-gray-100 rounded-12rpx p-2">
<view class="flex justify-between mb-2">
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx">
<text class="flex-1 text-sm text-center text-gray-600">流水金额</text>
<text class="flex-1 text-sm text-center text-gray-800">¥ {{ hooks.useMoney(v.totalPayPrice) }}</text>
</view>
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx ml-1">
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx ml-2">
<text class="flex-1 text-sm text-center text-gray-600">流水次数</text>
<text class="flex-1 text-sm text-center text-gray-800">{{ v.totalPayCount }}</text>
</view>
</view>
<view class="flex justify-between mb-1">
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx">
<view class="flex justify-between mb-2">
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx">
<text class="flex-1 text-sm text-center text-gray-600">盈利金额</text>
<text class="flex-1 text-sm text-center text-green-500">¥ {{ hooks.useMoney(v.totalProfitPrice) }}</text>
</view>
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx ml-1">
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx ml-2">
<text class="flex-1 text-sm text-center text-gray-600">盈利次数</text>
<text class="flex-1 text-sm text-center text-green-500">{{ v.totalProfitCount }}</text>
</view>
</view>
<view class="flex justify-between mb-0">
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx">
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx">
<text class="flex-1 text-sm text-center text-gray-600">退款金额</text>
<text class="flex-1 text-sm text-center text-red-500">¥ {{ hooks.useMoney(v.totalRefundPrice) }}</text>
</view>
<view class="flex-1 flex items-center p-1 bg-white rounded-8rpx ml-1">
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx ml-2">
<text class="flex-1 text-sm text-center text-gray-600">退款次数</text>
<text class="flex-1 text-sm text-center text-red-500">{{ v.totalRefundCount || 0 }}</text>
</view>
@@ -111,7 +111,7 @@ const state = reactive<any>({
date: "",
})
const formatVal = computed(() => (state.date.length === 2 ? state.formatVal : ""))
const { list, startPage, scroll } = hooks.usePage(pageRef, flowStatisticsApi.page, null, "data")
const pageHook = hooks.usePage(pageRef, flowStatisticsApi.page, null, "data")
onLoad(() => {
const app = getApp()
@@ -128,12 +128,12 @@ onShow(() => {
const query = (page: number, pagesize: number) => {
const isLogin = hooks.useStaticCheckLogin()
if (!isLogin) return
startPage(page, pagesize, false, state.pa)
pageHook.startPage(page, pagesize, false, state.pa)
}
// 时间范围选择器确认
const datePickerConfirm = (date: any) => {
state.pa.createTimeList = date.map((v: any) => hooks.useTime(v, "{y}-{m}-{d}"))
state.pa.createTimeList = formatVal.value.split("~")
pageRef.value.reload(false)
}
</script>
+17 -14
View File
@@ -3,7 +3,7 @@
<z-paging
ref="pageRef"
:fixed="false"
v-model="list"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
@@ -11,7 +11,7 @@
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="scroll"
@scroll="pageHook.scroll"
>
<template #top>
<view class="h-30rpx" />
@@ -22,7 +22,7 @@
<view class="h-20rpx" />
<view class="flex-col justify-center card p-x-15rpx p-y-25rpx m-b-10rpx" v-for="(v, i) in list" :key="i">
<view class="flex-col justify-center card p-3 m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i">
<view class="flex-row items-center">
<image class="w-100rpx h-100rpx rounded-8rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
<view class="flex-1 flex-col m-l-20rpx">
@@ -38,11 +38,11 @@
</view>
<view class="flex justify-between items-center">
<view class="flex flex-col">
<view class="second-text-20">
<view class="second-text-22">
<text>{{ v.username }}</text>
<text class="m-l-10rpx">{{ v.userMobile }}</text>
</view>
<view class="second-text-20">
<view class="second-text-22">
<text>下单时间</text>
<text class="m-l-10rpx">
{{ hooks.useTime(v.createTime, "{y}-{m}-{d} {h}:{i}:{s}") }}
@@ -50,7 +50,7 @@
</view>
</view>
<view class="flex flex-col items-end justify-center m-t-5rpx">
<view class="second-text-22">{{ hooks.useEnum("hardwareRefundStatusEnum", v.refundStatus) }}</view>
<view class="second-text-22 h-30rpx">{{ hooks.useEnum("hardwareRefundStatusEnum", v.refundStatus) }}</view>
<view class="flex">
<view v-if="v.carList?.length" class="m-t-4rpx m-r-10rpx second-text-26">共 {{ v.carList.length }} 件</view>
<view class="main-text-30 color-red!">¥ {{ hooks.useMoney(v.totalPrice) }}</view>
@@ -59,8 +59,8 @@
</view>
</view>
</view>
<view v-if="v.orderStatus == 10 && v.refundStatus == 0" class="h-50rpx mt-1 flex justify-end items-center">
<view class="botder_btn" @tap.stop="doIndividualRefund(v)">退款</view>
<view v-if="v.orderStatus == '5' && v.orderType == '1'" class="h-50rpx mt-1 flex justify-end items-center">
<view class="botder_btn" @tap.stop="doIndividualRefund(v)">申请退款</view>
</view>
</view>
</z-paging>
@@ -220,7 +220,7 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { hooks } from "@@/index"
import { hooks, router } from "@@/index"
import { filePath } from "@@/utils/file"
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
import { individualOrderApi, refundApi } from "@@/api"
@@ -242,7 +242,8 @@ const state = reactive<any>({
refundDetail: {},
remark: "",
})
const { list, startPage, scroll } = hooks.usePage(pageRef, individualOrderApi.page, null, "data.records")
const pageHook = hooks.usePage(pageRef, individualOrderApi.page, null, "data.records")
onLoad(() => {
const app = getApp()
@@ -251,9 +252,9 @@ onLoad(() => {
onShow(() => {
const isLogin = hooks.useCheckLogin()
if (!isLogin) return
// if (pageRef.value) {
// pageRef.value.reload(false)
// }
if (pageRef.value) {
pageRef.value.reload(false)
}
})
// 切换选项卡
@@ -265,7 +266,7 @@ const tabChange = (e: number) => {
const query = (page: number, pagesize: number) => {
// const isLogin = hooks.useStaticCheckLogin()
// if (!isLogin) return
startPage(page, pagesize, false, state.pa)
pageHook.startPage(page, pagesize, false, state.pa)
}
// 重置状态
@@ -278,6 +279,8 @@ const resetState = () => {
// 点击退款
const doIndividualRefund = async (v: any) => {
return router.jump("/pages/refund/apply", { id: v.id })
if (!v.id) return uni.showToast({ title: "订单id不存在", icon: "none" })
resetState()
+276 -165
View File
@@ -37,31 +37,39 @@
退出登录
</view>
</view>
<view v-if="state.appInfo == 'sh'" class="flex-col-center m-t-40rpx m-x-30rpx">
<view class="w-full text-center sub-text-28 p-y-20rpx rounded-40rpx border-solid border border-#0094ff" @tap="doChangeRole">
切换角色
</view>
</view>
</crud-layout>
</template>
<script setup lang="ts">
import { reactive } from "vue"
import { reactive, ref } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import { filePath } from "@@/utils/file"
import { getAppInfo } from "@@/utils/getAppInfo"
import { hooks, router, constant } from "@@/index"
import { userApi } from "@@/api"
import isDevEnv from "@/sheep/utils/isDevEnv"
import { usePayStore } from "@/sheep/stores/pay"
// import dd from "gdt-jsapi"
interface MenuItem {
text: string
icon: string
router: string
}
const state = reactive<{ wallet: any; userInfo: any; menuList: MenuItem[] }>({
const state = reactive<{
wallet: any[]
userInfo: any
menuList: {
text: string
icon: string
router: string
}[]
appInfo: string
}>({
wallet: [],
userInfo: {},
menuList: [
{ text: "扫一扫", icon: "/static/icon/scan.png", router: "" },
{ text: "钱包管理", icon: "/static/icon/service_3.png", router: "/pages/wallet/list" },
// { text: "包厢预定", icon: "/static/icon/service_4.png", router: "/pages/boxes/apply-list" },
// { text: "外来人员就餐", icon: "/static/icon/service_1.png", router: "/pages/apply/foreign-list" },
@@ -69,213 +77,316 @@ const state = reactive<{ wallet: any; userInfo: any; menuList: MenuItem[] }>({
{ text: "人脸管理", icon: "/static/icon/service_5.png", router: "/pages/human-face/list" },
// { text: "意见反馈", icon: "/static/icon/service_5.png", router: "/pages/integrated/feedback/index" }
],
appInfo: "",
})
const onTabLogin = () => (isDevEnv() ? router.jump("/pages/test/login") : checkAppInfo())
// 常量
const STORAGE_KEYS = {
TOKEN: constant.storageConstant.TOKEN,
USER_INFO: constant.storageConstant.USERINFO,
}
const storage = {
// 获取存储的用户信息
getUserInfo: () => {
const tokenStorage = uni.getStorageSync(STORAGE_KEYS.TOKEN)
const userStorage = uni.getStorageSync(STORAGE_KEYS.USER_INFO)
if (!isEmpty(userStorage) && !isEmpty(tokenStorage)) {
state.userInfo = userStorage
} else {
state.userInfo = {}
}
},
// 保存用户信息到存储
saveUserInfo: (userData: any) => {
uni.setStorageSync(STORAGE_KEYS.USER_INFO, userData)
storage.getUserInfo()
},
// 保存token到存储
saveToken: (tokenData: any) => {
uni.setStorageSync(STORAGE_KEYS.TOKEN, tokenData)
},
// 清除用户登录相关的存储
clearUserStorage: () => {
uni.removeStorageSync(STORAGE_KEYS.TOKEN)
uni.removeStorageSync(STORAGE_KEYS.USER_INFO)
state.userInfo = {}
},
}
const login = {
// 检查应用环境并登录
checkAppInfo: async () => {
try {
// 先尝试诗画登录
const shihuaResult = await login.shihuaLogin()
if (shihuaResult) return
// 尝试浙政钉登录
const zhengdingResult = login.zhengdingLogin()
if (zhengdingResult) return
uni.showToast({ title: "当前登录环境未知", icon: "none" })
} catch (error) {
console.error("登录失败:", error)
uni.showToast({ title: "登录失败", icon: "none" })
}
},
// 登录相关方法
const loginMethods = {
// 诗画环境登录
async shihuaLogin() {
// const appInfo = await (window as any).CP2.getAppInfo()
// if (appInfo.code !== 0) return false
shihuaLogin: async () => {
const appInfo = await (window as any).CP2.getAppInfo()
if (appInfo.code == 0) return false
// const userInfo = await (window as any).CP2.getUserInfo()
// const { accountId, sessionId } = userInfo.data
// return doLogin(1, null, accountId, sessionId)
return false
const userInfo = await (window as any).CP2.getUserInfo()
if (userInfo.code == 0) {
uni.showToast({ title: "获取诗画用户信息失败", icon: "none" })
return false
} else {
const { accountId, sessionId } = userInfo.data
return login.doLogin(1, "", accountId, sessionId)
// return login.doLogin(1, "", "67186e49d63fea141aad6772", "67186e49d63fea141aad6776")
}
},
// 浙政钉登录
zhengdingLogin() {
zhengdingLogin: () => {
const params = new URL(window.location.href).searchParams
const token = params.get("uabaseToken")
if (token) {
return doLogin(2, token, null, null)
return login.doLogin(2, token, "", "")
}
return false
},
}
// 检查应用环境并登录
const checkAppInfo = async () => {
try {
// 先尝试诗画登录
const shihuaResult = await loginMethods.shihuaLogin()
if (shihuaResult) return
// 尝试浙政钉登录
const zhengdingResult = loginMethods.zhengdingLogin()
if (zhengdingResult) return
// 执行登录操作 - loginType 1:诗画登录 2:浙政钉登录
doLogin: async (loginType: number, token: string, accountId: string, sessionId: string) => {
const tokenStorage = uni.getStorageSync(STORAGE_KEYS.TOKEN)
const userStorage = uni.getStorageSync(STORAGE_KEYS.USER_INFO)
uni.showToast({ title: "当前登录环境未知", icon: "none" })
} catch (error) {
console.error("登录失败:", error)
uni.showToast({ title: "登录失败", icon: "none" })
}
}
switch (loginType) {
case 1: // 诗画登录
uni.showLoading({ title: "登录中...", mask: true })
const response = await userApi.authsh({ accountId, sessionId })
// loginType 1:诗画登录 2:浙政钉登录
const doLogin = async (loginType: number, token: string, accountId: string | null, sessionId: string | null) => {
const tokenKey = constant.storageConstant.TOKEN
const userInfoKey = constant.storageConstant.USERINFO
const tokenStorage = uni.getStorageSync(tokenKey)
const userStorage = uni.getStorageSync(userInfoKey)
switch (loginType) {
case 1:
// 诗画
// const params = {
// accountId: accountId,
// sessionId: sessionId,
// }
// const response = await userApi.authsh(params)
// authData = response.data
break
case 2:
if (isEmpty(tokenStorage) || isEmpty(userStorage)) {
try {
uni.showLoading({ title: "登录中...", mask: true })
const res = await userApi.auth(token)
if (res.code == 0) {
uni.setStorageSync(tokenKey, res.data)
uni.hideLoading()
uni.showToast({ title: "登录成功", icon: "none" })
const { data: userData } = await userApi.userInfo()
uni.setStorageSync(userInfoKey, userData)
getStorageUserInfo()
} else {
uni.hideLoading()
uni.showToast({ title: "获取浙政钉用户信息失败", icon: "none" })
}
} catch (error) {
if (response.code == 0) {
storage.saveToken({ accessToken: response.data.accessToken })
uni.hideLoading()
uni.showToast({ title: "错误", icon: "none" })
uni.showToast({ title: "登录成功", icon: "none" })
const { data: userData } = await userApi.userInfo()
storage.saveUserInfo(userData)
} else {
uni.hideLoading()
storage.clearUserStorage()
if (response.msg == "token已失效") {
uni.showToast({ title: "用户凭证已失效,请退出并重新进入智慧后勤应用", icon: "none", duration: 6000 })
} else {
uni.showToast({ title: response.msg || "登录失败", icon: "none" })
}
}
}
break
default:
uni.showToast({ title: "当前登录环境未知", icon: "none" })
}
}
break
const doLogout = async () => {
const isLogin = await hooks.useCheckLogin()
if (!isLogin) return
uni.showLoading({
title: "退出登录中...",
mask: true,
})
const tokenKey = constant.storageConstant.TOKEN
const userInfoKey = constant.storageConstant.USERINFO
uni.removeStorageSync(tokenKey)
uni.removeStorageSync(userInfoKey)
state.userInfo = {}
uni.hideLoading()
uni.showToast({ title: "退出登录成功", icon: "none" })
}
case 2: // 浙政钉登录
if (isEmpty(tokenStorage) || isEmpty(userStorage)) {
try {
uni.showLoading({ title: "登录中...", mask: true })
const res = await userApi.auth(token)
// 扫一扫
const doScanCode = async () => {
usePayStore().setPayData({})
try {
let decodedString: string | undefined = ""
if (isDevEnv()) {
decodedString = decodeBase64("eyJpZCI6IjE4ODk0ODM5Mzg0ODQ1MzEyMDEiLCJuYW1lIjoi5rWL6K+V6LaF5biCIn0=")
uni.showToast({ title: "开发环境不是浙政钉环境,扫码仅供测试", icon: "none" })
} else {
const res: any = await (window as any).dd.scan({ type: "all" })
decodedString = decodeBase64(res.text)
if (res.code == 0) {
storage.saveToken(res.data)
uni.hideLoading()
uni.showToast({ title: "登录成功", icon: "none" })
const { data: userData } = await userApi.userInfo()
storage.saveUserInfo(userData)
} else {
storage.clearUserStorage()
if (res.msg == "token已失效") {
uni.showToast({ title: "用户凭证已失效,请退出并重新进入智慧后勤应用", icon: "none", duration: 6000 })
} else {
uni.showToast({ title: res.msg || "登录失败", icon: "none" })
}
}
} catch (error) {
uni.showToast({ title: "登录错误", icon: "none" })
} finally {
uni.hideLoading()
}
}
break
default:
uni.showToast({ title: "当前登录环境未知", icon: "none" })
}
},
if (decodedString) {
// 退出登录
logout: async () => {
const isLogin = await hooks.useCheckLogin()
if (!isLogin) return
uni.showLoading({ title: "退出登录中...", mask: true })
storage.clearUserStorage()
uni.hideLoading()
uni.showToast({ title: "退出登录成功", icon: "none" })
},
// 切换角色
changeRole: () => {
router.jump("/pages/user/userRole")
},
}
const scanCode = {
// 扫一扫
scan: async () => {
usePayStore().setPayData({})
try {
const decodedString = await scanCode.getScanResult()
if (decodedString) {
scanCode.processScanResult(decodedString)
}
// else {
// uni.showToast({ title: "无效的二维码", icon: "none" })
// }
} catch (error: any) {
// if (error) {
// uni.showToast({ title: error, icon: "none" })
// }
}
},
// 获取扫码结果
getScanResult: async (): Promise<string | undefined> => {
if (isDevEnv()) {
// 开发环境模拟扫码
// const testQrCode = "eyJpZCI6IjE4OTYxNTcyMDc2NDQwNTM1MDYiLCJuYW1lIjoi5rWL6K+V5ZWG5oi3In0=" // 线上-测试超市-收款码
// const testQrCode = "eyJpZCI6IjE5MDU4MTY3NTEwNDM0NTI5MzAiLCJuYW1lIjoi5paw5Y6/5bqc6LaF5biCIn0=" // 测试环境-邓本地-新县府超市-收款码
const testQrCode = "eyJpZCI6IjE5MDc2ODQwNTY4NDA4NDMyNjYiLCJuYW1lIjoi5pm66IO95p+c6Ieq6JCl5ZWG5oi3MSJ9" // 测试环境-邓本地-智能柜自营商户1-收款码
uni.showToast({ title: "开发环境不是浙政钉环境,扫码仅供测试,收款商家为测试商户超市", icon: "none" })
return scanCode.decodeBase64(testQrCode)
} else if (state.appInfo == "dd") {
// 浙政钉扫码
const res: any = await (window as any).dd.scan({ type: "all" })
return scanCode.decodeBase64(res.text)
} else if (state.appInfo == "sh") {
// 诗画扫码
const res = await (window as any).CP2.showScanQr({ needResult: 1 })
if (res.code == 1) return scanCode.decodeBase64(res.data.qrCode)
} else {
uni.showToast({ title: "当前环境未知", icon: "none" })
}
},
// 处理扫码结果
processScanResult: (decodedString: string) => {
try {
const decodedJson = JSON.parse(decodedString)
if (decodedJson?.id && decodedJson?.name) {
usePayStore().setPayData(decodedJson)
router.jump("/pages/pay/scanPay")
} else {
uni.showToast({
title: "无效的二维码",
icon: "none",
})
uni.showToast({ title: "无效的二维码", icon: "none" })
}
} else {
uni.showToast({
title: "无效的二维码",
icon: "none",
})
} catch (error) {
uni.showToast({ title: "无效的二维码内容", icon: "none" })
}
} catch (error: any) {
if (error) {
uni.showToast({
title: error,
icon: "none",
})
},
// 解码base64
decodeBase64: (base64String: string): string | undefined => {
try {
const decodedBinaryString = atob(base64String)
const uint8Array = new Uint8Array(decodedBinaryString.length)
for (let i = 0; i < decodedBinaryString.length; i++) {
uint8Array[i] = decodedBinaryString.charCodeAt(i)
}
const decoder = new TextDecoder("utf-8")
const decodedString = decoder.decode(uint8Array)
console.log("解码结果", decodedString)
return decodedString
} catch (error) {
console.error("Base64 解码失败:", error)
uni.showToast({ title: "无效的二维码", icon: "none" })
return undefined
}
}
},
}
const onTabMenu = async (v: MenuItem, i: number) => {
if (i == state.menuList.length - 1) {
router.jump(v.router)
const onTabLogin = () => (isDevEnv() ? router.jump("/pages/test/login") : login.checkAppInfo())
const onTabMenu = async (item: any, index: number) => {
if (index == state.menuList.length - 1) {
router.jump(item.router)
return
}
const isLogin = await hooks.useCheckLogin()
if (isLogin) {
if (v.text === "扫一扫") {
await doScanCode()
if (item.text === "扫一扫") {
await scanCode.scan()
} else {
router.jump(v.router)
router.jump(item.router)
}
}
}
// 解码base64
const decodeBase64 = (base64String: string) => {
try {
const decodedBinaryString = atob(base64String)
const uint8Array = new Uint8Array(decodedBinaryString.length)
for (let i = 0; i < decodedBinaryString.length; i++) {
uint8Array[i] = decodedBinaryString.charCodeAt(i)
}
const decoder = new TextDecoder("utf-8")
const decodedString = decoder.decode(uint8Array)
console.log("解码结果", decodedString)
return decodedString
} catch (error) {
console.error("Base64 解码失败:", error)
uni.showToast({
title: "解码失败,无效的二维码",
icon: "none",
// 退出登录
const doLogout = async () => {
await login.logout()
}
// 切换角色
const doChangeRole = () => {
login.changeRole()
}
// 初始化配置菜单
const initMenuConfig = () => {
if (isDevEnv()) {
state.menuList.push({
text: "测试-登录",
icon: "/static/icon/login.png",
router: "/pages/test/login",
})
state.menuList.push({
text: "测试-角色选择",
icon: "/static/icon/login.png",
router: "/pages/user/userRole",
})
}
// 根据启动参数添加扫一扫菜单项
const launchParam = new URL(window.location.href).searchParams.get("launchParam")
if (launchParam === "selfMerchant") {
state.menuList.unshift({
text: "扫一扫",
icon: "/static/icon/scan.png",
router: "",
})
}
}
const getStorageUserInfo = () => {
const tokenKey = constant.storageConstant.TOKEN
const userInfoKey = constant.storageConstant.USERINFO
const tokenStorage = uni.getStorageSync(tokenKey)
const userStorage = uni.getStorageSync(userInfoKey)
if (!isEmpty(userStorage) && !isEmpty(tokenStorage)) {
state.userInfo = userStorage
} else {
state.userInfo = {}
}
}
onLoad(() => {
onLoad(async () => {
const app = getApp()
app._initTabbar()
isDevEnv()
? state.menuList.push({
text: "测试登录",
icon: "/static/icon/login.png",
router: "/pages/test/login",
})
: ""
// checkAppInfo()
// 初始化配置菜单
initMenuConfig()
// 获取应用信息
state.appInfo = await getAppInfo()
})
onShow(() => {
getStorageUserInfo()
// 获取存储中的用户信息
storage.getUserInfo()
})
</script>
+16 -12
View File
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, reactive, computed } from "vue"
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { hooks, router } from "@@/index"
@@ -31,9 +31,9 @@ onLoad(() => {
onShow(async () => {
const isLogin = await hooks.useCheckLogin()
if (!isLogin) return
// if (pageRef.value) {
// pageRef.value.reload(false)
// }
if (pageRef.value) {
pageRef.value.reload(false)
}
})
const doTab = (e: any) => {
const target = data.tabs[e]
@@ -42,7 +42,16 @@ const doTab = (e: any) => {
}
const pageRef = ref<any>(null)
const pageHook = hooks.usePage(pageRef, orderApi.page, null, "data.records")
const pageHook = hooks.usePage(
pageRef,
new URL(window.location.href).searchParams.get("launchParam") == "canteen"
? orderApi.caneenPage
: new URL(window.location.href).searchParams.get("launchParam") == "selfMerchant"
? orderApi.supPage
: null,
null,
"data.records",
)
const query = (page: number, pagesize: number) => {
const isLogin = hooks.useStaticCheckLogin()
console.log(isLogin, "isLogin")
@@ -69,7 +78,7 @@ const doRefund = (v: any) => {
height="100%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="5"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@@ -85,12 +94,7 @@ const doRefund = (v: any) => {
</view>
</template>
<view class="h-20rpx" />
<view
class="flex-col justify-center card p-x-15rpx p-y-25rpx m-b-20rpx"
v-for="(v, i) in pageHook.list"
:key="i"
@tap="doToDetail(v)"
>
<view class="flex-col justify-center card p-3 m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="doToDetail(v)">
<view class="flex-row items-center">
<image class="w-80rpx h-80rpx rounded-8rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
<view class="flex-1 flex-col m-l-20rpx">
+112
View File
@@ -0,0 +1,112 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { merchantApi } from "@@/api"
import { hooks, router } from "@@/index"
import { filePath } from "@@/utils/file"
const pageRef = ref<any>(null)
const state = reactive<any>({
pa: {
pagesize: 10,
type: "3",
},
})
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, state.pa)
}
onLoad(() => {
const app = getApp()
app._initTabbar()
})
onShow(() => {
// pageRef.value && pageRef.value.reload(false)
})
const toDetail = async (v: any) => {
const isLogin = await hooks.useCheckLogin()
if (isLogin) {
router.jump("/pages/shop/detail", { id: v.id })
}
}
</script>
<template>
<crud-layout bg="/static/page/blue-bg.png">
<z-paging
ref="pageRef"
height="100%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="pageHook.scroll"
>
<view class="h-20rpx" />
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
<view class="flex-1 flex-col m-l-20rpx">
<view class="flex-row items-center justify-between">
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
<tm-tag size="s">{{ v.deptName }}</tm-tag>
</view>
<view class="m-t-10rpx">
<view v-if="v.phone" class="flex items-center">
<svg
t="1743075703202"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2684"
width="12"
height="12"
>
<path
d="M575.7 647.1l69.4-69.2 13.3 2.3c1.7 0.3 4.9 0.9 9.4 1.7 7.4 1.3 15.7 2.9 24.6 4.5 25.5 4.8 50.9 9.8 74.8 14.9 17.3 3.7 33.1 7.3 47 10.7 27.6 6.8 47.3 12.9 59.1 18.6 43 20.8 60 65.5 53.4 122-9.7 81.3-97 174.3-204.4 175.4-121 1.2-291.4-87.7-411.9-214.7C165.3 560.4 81.8 406.9 98 278.3c8.5-67.1 40.2-115.9 87.8-147.2 32.4-21.3 69.4-32.5 97.9-34.6 38.2-2.8 69.6 9.6 92.5 38 9.7 12 19.7 36.1 32.2 73.3 3.6 10.9 7.4 22.8 11.3 35.4 7 23 14.1 47.6 20.9 72.2 2.4 8.6 4.5 16.6 6.4 23.7 1.1 4.3 2 7.4 2.4 9.1l3.7 14.2-80.4 81.8c44.5 89 122.6 169.8 203 202.9z m13.5 60l-15.3-5.1c-105.4-35.6-205.4-139.4-256.3-252.3l-7.3-16.2 85-86.4c-1.5-5.6-3.1-11.6-4.9-17.9-6.6-24.1-13.5-48.2-20.4-70.7-3.8-12.3-7.4-23.7-10.9-34.2-10.2-30.5-19.1-52-23.3-57.2-11.8-14.6-26.4-20.4-48.2-18.8-20.2 1.5-48.7 10.1-73.1 26.2-35.2 23.2-58.3 58.6-64.8 110.3-13.8 108.7 63.1 250.2 198.4 392.7C459.5 794.9 617 877 721.8 876c79.2-0.8 146.4-72.5 153.2-129.4 4.3-36.6-4.3-59.4-24.4-69.1-7.5-3.6-24.7-8.9-48.9-14.9-13.4-3.3-28.6-6.8-45.4-10.4-23.3-5-48.4-10-73.5-14.7-7.2-1.3-13.9-2.6-20.1-3.7l-73.5 73.3z"
fill="#666666"
p-id="2685"
></path>
</svg>
<view class="second-text-28 ml-1">{{ v.phone }}</view>
</view>
<view class="second-text-24">
<view class="second-text-28">{{ v.jobTime == ",," ? "" : "营业时间:" }}</view>
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
</view>
<view v-if="v.addressDes" class="second-text-28">
<svg
t="1743075857752"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="3808"
width="12"
height="11"
>
<path
d="M512 1012.8c-253.6 0-511.2-54.4-511.2-158.4 0-92.8 198.4-131.2 283.2-143.2h3.2c12 0 22.4 8.8 24 20.8 0.8 6.4-0.8 12.8-4.8 17.6-4 4.8-9.6 8.8-16 9.6-176.8 25.6-242.4 72-242.4 96 0 44.8 180.8 110.4 463.2 110.4s463.2-65.6 463.2-110.4c0-24-66.4-70.4-244.8-96-6.4-0.8-12-4-16-9.6-4-4.8-5.6-11.2-4.8-17.6 1.6-12 12-20.8 24-20.8h3.2c85.6 12 285.6 50.4 285.6 143.2 0.8 103.2-256 158.4-509.6 158.4z m-16.8-169.6c-12-11.2-288.8-272.8-288.8-529.6 0-168 136.8-304.8 304.8-304.8S816 145.6 816 313.6c0 249.6-276.8 517.6-288.8 528.8l-16 16-16-15.2zM512 56.8c-141.6 0-256.8 115.2-256.8 256.8 0 200.8 196 416 256.8 477.6 61.6-63.2 257.6-282.4 257.6-477.6C768.8 172.8 653.6 56.8 512 56.8z m0 392.8c-80 0-144.8-64.8-144.8-144.8S432 160 512 160c80 0 144.8 64.8 144.8 144.8 0 80-64.8 144.8-144.8 144.8zM512 208c-53.6 0-96.8 43.2-96.8 96.8S458.4 401.6 512 401.6c53.6 0 96.8-43.2 96.8-96.8S564.8 208 512 208z"
fill="#707070"
p-id="3809"
></path>
</svg>
<text class="ml-1">地址:</text>
<text class="m-l-10rpx">{{ v.addressDes }}</text>
</view>
</view>
</view>
</view>
</z-paging>
</crud-layout>
</template>
-79
View File
@@ -1,79 +0,0 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { merchantApi } from "@@/api"
import { hooks, router } from "@@/index"
import { filePath } from "@@/utils/file"
const pageRef = ref<any>(null)
const state = reactive<any>({
pa: {
pagesize: 10,
type: "3",
},
})
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, state.pa)
}
onLoad(() => {
const app = getApp()
app._initTabbar()
})
onShow(() => {
pageRef.value && pageRef.value.reload(false)
})
const toDetail = async (v: any) => {
return
const isLogin = await hooks.useCheckLogin()
if (isLogin) {
router.jump("/pages/shop/detail", { id: v.id })
}
}
</script>
<template>
<crud-layout bg="/static/page/blue-bg.png">
<z-paging
ref="pageRef"
height="100%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@query="query"
:auto-clean-list-when-reload="false"
:auto-scroll-to-top-when-reload="false"
@scroll="pageHook.scroll"
>
<view class="h-20rpx" />
<view class="flex-col card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
<view class="flex-row-center">
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
<view class="flex-1 flex-col m-l-20rpx">
<view class="flex-row items-center justify-between">
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
<tm-tag size="s">{{ v.deptName }}</tm-tag>
</view>
<view class="second-text-24">{{ v.phone }}</view>
<view class="second-text-24">
<view v-if="v.jobTime != ',,'" class="second-text-28">营业时间:</view>
<view>{{ v.jobTime?.split(",")[0] ? "早:" + v.jobTime?.split(",")[0] : "" }}</view>
<view>{{ v.jobTime?.split(",")[1] ? "中:" + v.jobTime?.split(",")[1] : "" }}</view>
<view>{{ v.jobTime?.split(",")[2] ? "晚:" + v.jobTime?.split(",")[2] : "" }}</view>
</view>
<view v-if="v.addressDes" class="m-t-10rpx second-text-28">
<text>地址</text>
<text class="m-l-10rpx">{{ v.addressDes }}</text>
</view>
</view>
</view>
</view>
</z-paging>
</crud-layout>
</template>
+2 -6
View File
@@ -1,11 +1,9 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { hooks, constant, router } from "@@/index"
import { onShow } from "@dcloudio/uni-app"
import { constant, router } from "@@/index"
import { userApi } from "@@/api"
const data = {}
const state = reactive<any>({
userInfo: null,
})
@@ -18,8 +16,6 @@ const applyFormRules = reactive<any>({
password: [{ required: true, message: "请输入密码" }],
})
onLoad(() => {})
onShow(() => {
const userInfoKey = constant.storageConstant.USERINFO
state.userInfo = uni.getStorageSync(userInfoKey)
+70
View File
@@ -0,0 +1,70 @@
<template>
<view class="flex-col min-h-screen bg-gray-100">
<view class="text-center py-12">
<view class="main-text-40 mb-2">请选择您的身份</view>
</view>
<view class="px-6 my-20">
<view
class="card mb-6 overflow-hidden relative border-8 border-solid border-white duration-200"
:class="{ 'border-8 border-solid border-blue!': userRole === 'user' }"
@click="selectRole('user')"
>
<view class="flex-row items-center p-6">
<view class="w-64 h-64 rounded-full flex-col-center mr-8">
<image src="@/static/page/userRole.svg" />
</view>
<view class="main-text-32 mb-1">我是用户</view>
</view>
</view>
<view
class="card overflow-hidden relative border-8 border-solid border-white duration-200"
:class="{ 'border-8 border-solid border-blue!': userRole === 'merchant' }"
@click="selectRole('merchant')"
>
<view class="flex-row items-center p-6">
<view class="w-64 h-64 rounded-full flex-col-center mr-8">
<image src="@/static/page/merchantRole.svg" />
</view>
<view class="main-text-32 mb-1">我是商户</view>
</view>
</view>
</view>
<view class="flex-row-center px-10 mt-auto pb-10 font-bold">
<tm-button block @click="confirmRole">确 定</tm-button>
</view>
</view>
</template>
<script setup lang="ts">
import user from "@/sheep/api/user"
import { ref } from "vue"
const userRole = ref("user")
const selectRole = (role: "user" | "merchant") => (userRole.value = role)
// 确认选择
const confirmRole = async () => {
if (userRole.value === "user") {
uni.setStorageSync("userRole", userRole.value)
uni.reLaunch({ url: "/pages/tabbar/coopMerchant" })
return
}
if (userRole.value === "merchant") {
uni.showLoading({ title: "正在验证身份", mask: true })
const res = await user.isMerchant().finally(() => uni.hideLoading())
if (res.code == 0) {
if (res.data) {
uni.setStorageSync("userRole", userRole.value)
uni.reLaunch({ url: "/pages/tabbar/individualOrder" })
return
} else {
uni.showToast({ title: "您不是商户", icon: "none" })
}
}
}
}
</script>
+4 -6
View File
@@ -49,7 +49,7 @@ const doTab = (e: any) => {
height="100%"
:fixed="false"
v-model="pageHook.list"
:default-page-size="5"
:default-page-size="10"
safe-area-inset-bottom
:loading-more-enabled="true"
:show-scrollbar="false"
@@ -63,11 +63,7 @@ const doTab = (e: any) => {
<z-tabs :list="data.tabs" @change="doTab" />
</view>
<view class="h-20rpx" />
<view
class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx"
v-for="(v, i) in pageHook.list"
:key="i"
>
<view class="flex-row items-center justify-between card p-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i">
<view class="flex">
<view class="w-200rpx flex justify-left p-r-25rpx">
<tm-tag v-if="v.title == '更新余额'" size="m">{{ v.title }}</tm-tag>
@@ -75,6 +71,8 @@ const doTab = (e: any) => {
<tm-tag v-if="v.title == '充值'" size="m">{{ v.title }}</tm-tag>
<tm-tag v-if="v.title == '支付'" color="error" size="m">{{ v.title }}</tm-tag>
<tm-tag v-if="v.title == '退款'" color="info" size="m">{{ v.title }}</tm-tag>
<tm-tag v-if="v.title == '转账'" color="success" size="m">{{ v.title }}</tm-tag>
<tm-tag v-if="v.title == '转账退款'" color="info" size="m">{{ v.title }}</tm-tag>
</view>
<view class="flex-row-center">
<text class="sub-text-30">{{ hooks.useMoney(v.price) }}元</text>
+25 -4
View File
@@ -1,13 +1,13 @@
<script setup lang="ts">
import { ref, reactive } from "vue"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { isEmpty } from "radash"
import uqrcode from "@@/utils/uqrcode"
import { hooks, router } from "@@/index"
import { merchantApi, walletApi } from "@@/api"
import { walletApi } from "@@/api"
import { filePath } from "@@/utils/file"
import { useTransferMoney } from "@/sheep/stores/transferMoney"
const state = reactive<any>({
showBindDialog: false,
@@ -30,7 +30,13 @@ const freezeForm = reactive<any>({
})
onLoad(() => {})
onShow(() => {})
onShow(async () => {
const isLogin = await hooks.useCheckLogin()
if (!isLogin) return
if (pageRef.value) {
pageRef.value.reload(false)
}
})
const pageRef = ref<any>(null)
const pageHook = hooks.usePage(pageRef, walletApi.all, null, "data.records")
@@ -119,6 +125,16 @@ const doFreeze = async () => {
uni.hideLoading()
}
}
// 转账
const doTransferMoney = (v: any) => {
if (v.walletTypeId) {
useTransferMoney().setSourceWalletType(v)
router.jump("/pages/pay/transferMoney")
return
}
uni.showToast({ title: "钱包类型id不存在", icon: "none" })
}
</script>
<template>
@@ -173,10 +189,15 @@ const doFreeze = async () => {
</view>
<view class="flex-row items-center justify-end space-x-20rpx m-t-10rpx">
<!-- <view v-if="v.walletTypeUniqueCode == 1 && !v.cardNumber" class="botder_btn" @tap.stop="openBindDialog(v)">绑定</view> -->
<view v-if="v.isRule == '1'" class="botder_btn" @tap.stop="doTransferMoney(v)">转账</view>
<view v-if="v.walletTypeUniqueCode == 1 && v.cardNumber && v.isFreeze != 1" class="botder_btn" @tap.stop="openFreezeDialog(v)">
申请冻结
</view>
<view v-if="v.walletTypeUniqueCode == 2" class="botder_btn" @tap.stop="router.jump('/pages/wallet/recharge', { id: v.id })">
<view
v-if="false && v.walletTypeUniqueCode == 2"
class="botder_btn"
@tap.stop="router.jump('/pages/wallet/recharge', { id: v.id })"
>
去充值
</view>
</view>