Merge branch 'master' of http://gitea.zianxin.com/zianxin-tec/biz-mobile-react-cloud
# Conflicts: # .env
This commit is contained in:
commit
e4cd31b377
31 files changed
+1507
-934
No files matched your search
@@ -17,23 +17,22 @@ VITE_PWD_ENC_KEY='pigxpigxpigxpigx'
|
||||
VITE_OAUTH2_APP_CLIENT='mini:mini'
|
||||
|
||||
# 图片访问基础地址
|
||||
VITE_IMAGE_BASE_PATH = http://localhost:9999
|
||||
# VITE_IMAGE_BASE_PATH = http://192.168.101.29:9999 # 邓-本地
|
||||
# VITE_IMAGE_BASE_PATH = http://192.168.101.37:9999 # 邓-本地
|
||||
#VITE_IMAGE_BASE_PATH = http://localhost:9999
|
||||
# VITE_IMAGE_BASE_PATH = http://192.168.101.64:9999 # 邓-本地
|
||||
# VITE_IMAGE_BASE_PATH = https://123.156.230.15:8089/api # 线上
|
||||
# VITE_IMAGE_BASE_PATH = http://220.191.229.171:8090/api # 线上
|
||||
# VITE_IMAGE_BASE_PATH = https://stgl.pj.gov.cn/api # 线上
|
||||
# VITE_IMAGE_BASE_PATH = http://pjcloud.center.takin.cc # 张
|
||||
#VITE_IMAGE_BASE_PATH = http://59.202.170.152:81/api # 信创线上
|
||||
VITE_IMAGE_BASE_PATH = http://59.202.170.152:81/api # 信创线上
|
||||
|
||||
# ******************** start 开发环境 start ********************
|
||||
; VITE_APP_DEV_SERVICE = http://59.202.170.152:81/api # 信创线上
|
||||
VITE_APP_DEV_SERVICE = https://stgl.pj.gov.cn/api
|
||||
# VITE_APP_DEV_SERVICE = http://192.168.101.50:9999 # 邓-本地
|
||||
; VITE_APP_DEV_SERVICE = http://127.0.0.1:9999
|
||||
# VITE_APP_DEV_SERVICE = http://59.202.170.152:81/api # 信创线上
|
||||
# VITE_APP_DEV_SERVICE = https://stgl.pj.gov.cn/app-api
|
||||
VITE_APP_DEV_SERVICE = http://192.168.101.64:9999 # 邓-本地
|
||||
# VITE_APP_DEV_SERVICE = http://127.0.0.1:9999
|
||||
# VITE_APP_DEV_SERVICE = http://123.156.230.15:8089/api/ # 线上
|
||||
# VITE_APP_DEV_SERVICE = http://220.191.229.171:8090/api # 线上
|
||||
; VITE_APP_DEV_SERVICE = http://localhost:9999
|
||||
# VITE_APP_DEV_SERVICE = http://localhost:9999
|
||||
# ******************** end 开发环境 end ********************
|
||||
|
||||
# ******************** start 生产环境 start ****************
|
||||
@@ -41,8 +40,8 @@ VITE_APP_DEV_SERVICE = https://stgl.pj.gov.cn/api
|
||||
#VITE_APP_PROD_SERVICE = http://59.202.170.152:81/api
|
||||
# VITE_APP_PROD_SERVICE = https://stgl.pj.gov.cn/api
|
||||
# VITE_APP_PROD_SERVICE = http://220.191.229.171:8090/api
|
||||
#VITE_APP_PROD_SERVICE = http://59.202.170.152:81/api # 信创线上
|
||||
VITE_APP_PROD_SERVICE = http://59.202.170.152:81/api # 信创线上
|
||||
# ******************** end 生产环境 end ********************
|
||||
|
||||
VITE_DEV_ENV = dev
|
||||
#VITE_DEV_ENV = prod
|
||||
# VITE_DEV_ENV = dev
|
||||
# VITE_DEV_ENV = prod
|
||||
+21
-22
@@ -1,25 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<script src="https://dapp.tmuyun.com/oss-static/app/jcommind.js"></script>
|
||||
<script>
|
||||
var coverSupport =
|
||||
"CSS" in window &&
|
||||
typeof CSS.supports === "function" &&
|
||||
(CSS.supports("top: env(a)") || CSS.supports("top: constant(a)"));
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ", viewport-fit=cover" : "") +
|
||||
'" />'
|
||||
);
|
||||
</script>
|
||||
<title></title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<script src="https://dapp.tmuyun.com/oss-static/app/jcommind.js"></script>
|
||||
<script src="https://g.alicdn.com/gdt/jsapi/1.9.43/index.js"></script>
|
||||
<script>
|
||||
var coverSupport =
|
||||
"CSS" in window && typeof CSS.supports === "function" && (CSS.supports("top: env(a)") || CSS.supports("top: constant(a)"))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ", viewport-fit=cover" : "") +
|
||||
'" />',
|
||||
)
|
||||
</script>
|
||||
<title></title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -62,12 +62,14 @@
|
||||
"@zebra-ui/swiper": "^2.2.8",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.13",
|
||||
"gdt-jsapi": "^1.9.51",
|
||||
"luch-request": "^3.1.1",
|
||||
"pinia": "^2.2.6",
|
||||
"qs": "^6.13.1",
|
||||
"radash": "^12.1.0",
|
||||
"vue": "^3.3.11",
|
||||
"vue-i18n": "^9.1.9",
|
||||
"vue-waterfall-plugin-next": "^2.6.5",
|
||||
"z-paging": "^2.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
Generated
+24
@@ -65,6 +65,9 @@ importers:
|
||||
dayjs:
|
||||
specifier: ^1.11.13
|
||||
version: 1.11.13
|
||||
gdt-jsapi:
|
||||
specifier: ^1.9.51
|
||||
version: 1.9.51
|
||||
luch-request:
|
||||
specifier: ^3.1.1
|
||||
version: 3.1.1
|
||||
@@ -83,6 +86,9 @@ importers:
|
||||
vue-i18n:
|
||||
specifier: ^9.1.9
|
||||
version: 9.14.2(vue@3.5.13(typescript@4.9.5))
|
||||
vue-waterfall-plugin-next:
|
||||
specifier: ^2.6.5
|
||||
version: 2.6.5
|
||||
z-paging:
|
||||
specifier: ^2.8.0
|
||||
version: 2.8.4
|
||||
@@ -1295,6 +1301,9 @@ packages:
|
||||
'@polka/url@1.0.0-next.28':
|
||||
resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==}
|
||||
|
||||
'@remax/mini-types@0.1.0':
|
||||
resolution: {integrity: sha512-bVDcbUrp6p0PZwfS0xGVQS6k9f8B35BtZaYt/W/IGKh7VALYQ+tS2KcytLRmIJ/Vmohaw5ikIRN89I+frPdh4g==}
|
||||
|
||||
'@rollup/pluginutils@5.1.4':
|
||||
resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
@@ -2404,6 +2413,9 @@ packages:
|
||||
function-bind@1.1.2:
|
||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||
|
||||
gdt-jsapi@1.9.51:
|
||||
resolution: {integrity: sha512-VN1iIK7kJU2g2oxY/n8waCREhWxcVwR8qHAE1keVnUJHI6mTdgTelICzq++niRRCaLqUVWC1pYvftEVgk4sq8A==}
|
||||
|
||||
generic-names@4.0.0:
|
||||
resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==}
|
||||
|
||||
@@ -3846,6 +3858,9 @@ packages:
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
|
||||
vue-waterfall-plugin-next@2.6.5:
|
||||
resolution: {integrity: sha512-8ACGbdjoyKLiJfnKXB8h8f9eE14lhyzfI1N1nrfVAIRczSpNY1KRwGOnVXN5OHqheLl3V1C0uVVRPtjTJkHkhw==}
|
||||
|
||||
vue@3.5.13:
|
||||
resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==}
|
||||
peerDependencies:
|
||||
@@ -5960,6 +5975,8 @@ snapshots:
|
||||
|
||||
'@polka/url@1.0.0-next.28': {}
|
||||
|
||||
'@remax/mini-types@0.1.0': {}
|
||||
|
||||
'@rollup/pluginutils@5.1.4(rollup@4.34.2)':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.6
|
||||
@@ -7202,6 +7219,11 @@ snapshots:
|
||||
|
||||
function-bind@1.1.2: {}
|
||||
|
||||
gdt-jsapi@1.9.51:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.7
|
||||
'@remax/mini-types': 0.1.0
|
||||
|
||||
generic-names@4.0.0:
|
||||
dependencies:
|
||||
loader-utils: 3.3.1
|
||||
@@ -8834,6 +8856,8 @@ snapshots:
|
||||
semver: 7.7.1
|
||||
typescript: 4.9.5
|
||||
|
||||
vue-waterfall-plugin-next@2.6.5: {}
|
||||
|
||||
vue@3.5.13(typescript@4.9.5):
|
||||
dependencies:
|
||||
'@vue/compiler-dom': 3.5.13
|
||||
|
||||
+11
-12
@@ -1,18 +1,17 @@
|
||||
import { createSSRApp } from "vue";
|
||||
import "uno.css";
|
||||
import * as Pinia from "pinia";
|
||||
import { createSSRApp } from "vue"
|
||||
import "uno.css"
|
||||
import pinia from "../src/sheep/stores/index"
|
||||
|
||||
import App from "./App.vue";
|
||||
import tmUi from "./uni_modules/tm-ui";
|
||||
import App from "./App.vue"
|
||||
import tmUi from "./uni_modules/tm-ui"
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App);
|
||||
const app = createSSRApp(App)
|
||||
|
||||
app.use(Pinia.createPinia());
|
||||
app.use(tmUi);
|
||||
app.use(pinia)
|
||||
app.use(tmUi)
|
||||
|
||||
return {
|
||||
app,
|
||||
Pinia,
|
||||
};
|
||||
return {
|
||||
app,
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,20 @@
|
||||
"disableScroll": true
|
||||
}
|
||||
},
|
||||
// {
|
||||
// "path": "pages/tabbar/flowStatistics",
|
||||
// "style": {
|
||||
// "navigationBarTitleText": "流水统计",
|
||||
// "disableScroll": true
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// "path": "pages/tabbar/individualOrder",
|
||||
// "style": {
|
||||
// "navigationBarTitleText": "订单",
|
||||
// "disableScroll": true
|
||||
// }
|
||||
// },
|
||||
{
|
||||
"path": "pages/tabbar/my",
|
||||
"style": {
|
||||
@@ -256,6 +270,18 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"root": "pages/pay",
|
||||
"pages": [
|
||||
{
|
||||
"path": "scanPay",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"disableScroll": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
@@ -285,6 +311,18 @@
|
||||
"iconPath": "static/tabbar/order.png",
|
||||
"selectedIconPath": "static/tabbar/order-select.png"
|
||||
},
|
||||
// {
|
||||
// "pagePath": "pages/tabbar/flowStatistics",
|
||||
// "text": "流水统计",
|
||||
// "iconPath": "static/tabbar/order.png",
|
||||
// "selectedIconPath": "static/tabbar/order-select.png"
|
||||
// },
|
||||
// {
|
||||
// "pagePath": "pages/tabbar/individualOrder",
|
||||
// "text": "订单",
|
||||
// "iconPath": "static/tabbar/order.png",
|
||||
// "selectedIconPath": "static/tabbar/order-select.png"
|
||||
// },
|
||||
{
|
||||
"pagePath": "pages/tabbar/my",
|
||||
"text": "我的",
|
||||
|
||||
+164
-164
@@ -1,215 +1,215 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import { isEmpty, max, min } from "radash"
|
||||
import dayjs from "dayjs"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { router } from "@@/index"
|
||||
import { boxesApi } from "@@/api"
|
||||
|
||||
const data = {
|
||||
|
||||
}
|
||||
const state = reactive<any>({
|
||||
detailType: "add",
|
||||
detailId: null,
|
||||
detail: null,
|
||||
rechargeList: [],
|
||||
selectRechargeList: [],
|
||||
selectRechargeIdList: [],
|
||||
pickerDate: {
|
||||
start: "",
|
||||
end: "",
|
||||
}
|
||||
detailType: "add",
|
||||
detailId: null,
|
||||
detail: null,
|
||||
rechargeList: [],
|
||||
selectRechargeList: [],
|
||||
selectRechargeIdList: [],
|
||||
pickerDate: {
|
||||
start: "",
|
||||
end: "",
|
||||
},
|
||||
})
|
||||
const applyForm = reactive<any>({
|
||||
displayTimeRange: "",
|
||||
displayTimeRangeStr: "",
|
||||
bxDate: null,
|
||||
displayTimeRange: "",
|
||||
displayTimeRangeStr: "",
|
||||
bxDate: null,
|
||||
})
|
||||
const applyFormRules = reactive<any>({
|
||||
bxDate: [
|
||||
{ required: true, message: '预约时间不能为空' }
|
||||
],
|
||||
bxDate: [{ required: true, message: "预约时间不能为空" }],
|
||||
})
|
||||
|
||||
onLoad((options: any) => {
|
||||
const { type, id } = options
|
||||
if (!isEmpty(type)) state.detailType = type
|
||||
if (!isEmpty(id)) state.detailId = id
|
||||
if (type === 'view') {
|
||||
getDetail()
|
||||
}
|
||||
const today = dayjs()
|
||||
state.pickerDate.start = dayjs().format('YYYY-MM-DD')
|
||||
state.pickerDate.end = today.add(2, 'month').format('YYYY-MM-DD')
|
||||
applyForm.bxDate = state.pickerDate.start
|
||||
getDateRange()
|
||||
});
|
||||
onShow(() => {
|
||||
|
||||
const { type, id } = options
|
||||
if (!isEmpty(type)) state.detailType = type
|
||||
if (!isEmpty(id)) state.detailId = id
|
||||
if (type === "view") {
|
||||
getDetail()
|
||||
}
|
||||
const today = dayjs()
|
||||
state.pickerDate.start = dayjs().format("YYYY-MM-DD")
|
||||
state.pickerDate.end = today.add(2, "month").format("YYYY-MM-DD")
|
||||
applyForm.bxDate = state.pickerDate.start
|
||||
getDateRange()
|
||||
})
|
||||
|
||||
const getDetail = async () => {
|
||||
if (isEmpty(state.detailId)) return
|
||||
const _pa = { id: state.detailId }
|
||||
const { data } = await boxesApi.detail(_pa)
|
||||
if (!isEmpty(data)) {
|
||||
state.detail = data
|
||||
}
|
||||
if (isEmpty(state.detailId)) return
|
||||
const _pa = { id: state.detailId }
|
||||
const { data } = await boxesApi.detail(_pa)
|
||||
if (!isEmpty(data)) {
|
||||
state.detail = data
|
||||
}
|
||||
}
|
||||
|
||||
const getDateRange = async () => {
|
||||
const _pa = { id: state.detailId, currentDate: applyForm.bxDate }
|
||||
const { data } = await boxesApi.get(_pa)
|
||||
data.avaliabilityRespList.forEach(v => {
|
||||
v.dateTime = `${v.bxDate} ${v.hour}`
|
||||
v.timestamp = dayjs(v.dateTime).valueOf()
|
||||
});
|
||||
state.rechargeList = data.avaliabilityRespList
|
||||
const _pa = { id: state.detailId, currentDate: applyForm.bxDate }
|
||||
const { data } = await boxesApi.get(_pa)
|
||||
data.avaliabilityRespList.forEach((v) => {
|
||||
v.dateTime = `${v.bxDate} ${v.hour}`
|
||||
v.timestamp = dayjs(v.dateTime).valueOf()
|
||||
})
|
||||
state.rechargeList = data.avaliabilityRespList
|
||||
}
|
||||
|
||||
const bxDateConfirm = async (e: any) => {
|
||||
getDateRange()
|
||||
getDateRange()
|
||||
}
|
||||
|
||||
const doTimeItem = (v: any) => {
|
||||
if (v.status == 1) {
|
||||
uni.showToast({ title: '该时间段已被预约', icon: "none" })
|
||||
return
|
||||
}
|
||||
const flag = state.selectRechargeList.some(i => i.id == v.id)
|
||||
if (flag) {
|
||||
state.selectRechargeList = state.selectRechargeList.filter(i => i.id != v.id)
|
||||
if (state.selectRechargeList.length >= 2) {
|
||||
const { timestamp: targetMin } = min(state.selectRechargeList, (i: any) => i.timestamp)
|
||||
state.rechargeList.forEach(i => {
|
||||
if (i.timestamp <= v.timestamp) {
|
||||
state.selectRechargeList = state.selectRechargeList.filter(j => j.id != i.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
state.selectRechargeList.push({ ...v })
|
||||
if (state.selectRechargeList.length >= 2) {
|
||||
const { timestamp: targetMax } = max(state.selectRechargeList, (i: any) => i.timestamp)
|
||||
const { timestamp: targetMin } = min(state.selectRechargeList, (i: any) => i.timestamp)
|
||||
state.rechargeList.forEach(i => {
|
||||
if (i.timestamp >= targetMin && i.timestamp <= targetMax) {
|
||||
state.selectRechargeList.push({ ...i })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
state.selectRechargeIdList = state.selectRechargeList.map(v => v.id)
|
||||
if (v.status == 1) {
|
||||
uni.showToast({ title: "该时间段已被预约", icon: "none" })
|
||||
return
|
||||
}
|
||||
const flag = state.selectRechargeList.some((i) => i.id == v.id)
|
||||
if (flag) {
|
||||
state.selectRechargeList = state.selectRechargeList.filter((i) => i.id != v.id)
|
||||
if (state.selectRechargeList.length >= 2) {
|
||||
const { timestamp: targetMin } = min(state.selectRechargeList, (i: any) => i.timestamp)
|
||||
state.rechargeList.forEach((i) => {
|
||||
if (i.timestamp <= v.timestamp) {
|
||||
state.selectRechargeList = state.selectRechargeList.filter((j) => j.id != i.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
state.selectRechargeList.push({ ...v })
|
||||
if (state.selectRechargeList.length >= 2) {
|
||||
const { timestamp: targetMax } = max(state.selectRechargeList, (i: any) => i.timestamp)
|
||||
const { timestamp: targetMin } = min(state.selectRechargeList, (i: any) => i.timestamp)
|
||||
state.rechargeList.forEach((i) => {
|
||||
if (i.timestamp >= targetMin && i.timestamp <= targetMax) {
|
||||
state.selectRechargeList.push({ ...i })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
state.selectRechargeIdList = state.selectRechargeList.map((v) => v.id)
|
||||
}
|
||||
|
||||
const applyFormRef = ref<any>(null)
|
||||
const doSubmit = async () => {
|
||||
applyFormRef.value.submit()
|
||||
const { isPass } = applyFormRef.value.validate()
|
||||
if (!isPass) return
|
||||
try {
|
||||
const { hour: hourMax } = max(state.selectRechargeList, (i: any) => i.timestamp)
|
||||
const { hour: hourMin } = min(state.selectRechargeList, (i: any) => i.timestamp)
|
||||
const _pa = {
|
||||
boxesId: state.detailId,
|
||||
startTime: hourMin,
|
||||
endTime: hourMax,
|
||||
bxDate: applyForm.bxDate,
|
||||
}
|
||||
const { data, code }: any = await boxesApi.apply(_pa)
|
||||
if (code != 0) throw new Error()
|
||||
uni.showLoading({ title: '预定中...', mask: false })
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '申请成功', icon: "none" })
|
||||
router.jump("/pages/boxes/apply-list")
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
uni.hideLoading()
|
||||
}
|
||||
applyFormRef.value.submit()
|
||||
const { isPass } = applyFormRef.value.validate()
|
||||
if (!isPass) return
|
||||
try {
|
||||
const { hour: hourMax } = max(state.selectRechargeList, (i: any) => i.timestamp)
|
||||
const { hour: hourMin } = min(state.selectRechargeList, (i: any) => i.timestamp)
|
||||
const _pa = {
|
||||
boxesId: state.detailId,
|
||||
startTime: hourMin,
|
||||
endTime: hourMax,
|
||||
bxDate: applyForm.bxDate,
|
||||
}
|
||||
const { data, code }: any = await boxesApi.apply(_pa)
|
||||
if (code != 0) throw new Error()
|
||||
uni.showLoading({ title: "预定中...", mask: false })
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: "申请成功", icon: "none" })
|
||||
router.jump("/pages/boxes/apply-list")
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<crud-layout title="预定" mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<view class="h-30rpx" />
|
||||
<view class="card p-x-30rpx p-y-40rpx">
|
||||
<tm-form ref="applyFormRef" v-model="applyForm" :rules="applyFormRules" direction="vertical">
|
||||
<tm-form-item name="bxDate" label="预约时间" :showBottom="false">
|
||||
<tm-picker-date v-model="applyForm.bxDate" :start="state.pickerDate.start"
|
||||
:end="state.pickerDate.end" v-model:model-str="applyForm.bxDate" format="YYYY-MM-DD"
|
||||
@confirm="bxDateConfirm">
|
||||
<view :style="{ pointerEvents: state.detailType == 'view' ? 'auto' : 'none' }">
|
||||
<tm-input v-model="applyForm.bxDate" disabled placeholder="请选择使用时间..">
|
||||
<template v-slot:rightIcon>
|
||||
<text v-if="state.detailType != 'view'"
|
||||
class="p-0.5rem color-#b1b1b1 iconfont icon-xiangxiajiantouxiao"></text>
|
||||
</template>
|
||||
</tm-input>
|
||||
</view>
|
||||
</tm-picker-date>
|
||||
</tm-form-item>
|
||||
</tm-form>
|
||||
</view>
|
||||
<view class="prefix_title m-t-35rpx">时间段</view>
|
||||
<view class="recharge p-30rpx bg-white rounded-20rpx m-t-20rpx shadow-main">
|
||||
<view
|
||||
:class="[state.selectRechargeIdList.includes(v.id) ? 'recharge_item_active' : '', v.status == 1 ? 'recharge_item_disabled' : '']"
|
||||
class="recharge_item" v-for="(v, i) in state.rechargeList" :key="i" @tap="doTimeItem(v)">
|
||||
<text class="sub-text-24 text-center">{{ v.bxDate }}</text>
|
||||
<text class="sub-text-24 text-center">{{ v.hour }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<template #main-bottom>
|
||||
<view v-if="state.detailType != 'view'"
|
||||
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-y-30rpx sub-text-30 color-white!"
|
||||
@tap="doSubmit">
|
||||
提交
|
||||
</view>
|
||||
</template>
|
||||
</crud-layout>
|
||||
<crud-layout title="预定" mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<view class="h-30rpx" />
|
||||
<view class="card p-x-30rpx p-y-40rpx">
|
||||
<tm-form ref="applyFormRef" v-model="applyForm" :rules="applyFormRules" direction="vertical">
|
||||
<tm-form-item name="bxDate" label="预约时间" :showBottom="false">
|
||||
<tm-picker-date
|
||||
v-model="applyForm.bxDate"
|
||||
:start="state.pickerDate.start"
|
||||
:end="state.pickerDate.end"
|
||||
v-model:model-str="applyForm.bxDate"
|
||||
format="YYYY-MM-DD"
|
||||
@confirm="bxDateConfirm"
|
||||
>
|
||||
<view :style="{ pointerEvents: state.detailType == 'view' ? 'auto' : 'none' }">
|
||||
<tm-input v-model="applyForm.bxDate" disabled placeholder="请选择使用时间..">
|
||||
<template v-slot:rightIcon>
|
||||
<text v-if="state.detailType != 'view'" class="p-0.5rem color-#b1b1b1 iconfont icon-xiangxiajiantouxiao"></text>
|
||||
</template>
|
||||
</tm-input>
|
||||
</view>
|
||||
</tm-picker-date>
|
||||
</tm-form-item>
|
||||
</tm-form>
|
||||
</view>
|
||||
<view class="prefix_title m-t-35rpx ml-4">时间段</view>
|
||||
<view class="recharge p-30rpx bg-white rounded-20rpx m-t-20rpx shadow-main">
|
||||
<view
|
||||
:class="[state.selectRechargeIdList.includes(v.id) ? 'recharge_item_active' : '', v.status == 1 ? 'recharge_item_disabled' : '']"
|
||||
class="recharge_item"
|
||||
v-for="(v, i) in state.rechargeList"
|
||||
:key="i"
|
||||
@tap="doTimeItem(v)"
|
||||
>
|
||||
<text class="sub-text-24 text-center">{{ v.bxDate }}</text>
|
||||
<text class="sub-text-24 text-center">{{ v.hour }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<template #main-bottom>
|
||||
<view
|
||||
v-if="state.detailType != 'view'"
|
||||
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-y-30rpx sub-text-30 color-white!"
|
||||
@tap="doSubmit"
|
||||
>
|
||||
提交
|
||||
</view>
|
||||
</template>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep() {
|
||||
.tmFormItemLabel {
|
||||
padding-bottom: 10rpx !important;
|
||||
}
|
||||
.tmFormItemLabel {
|
||||
padding-bottom: 10rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
.recharge_item_active {
|
||||
background: #e9f5fe;
|
||||
border: 1px solid #e9f5fe !important;
|
||||
background: #e9f5fe;
|
||||
border: 1px solid #e9f5fe !important;
|
||||
|
||||
&>text {
|
||||
color: #0094ff !important;
|
||||
}
|
||||
& > text {
|
||||
color: #0094ff !important;
|
||||
}
|
||||
}
|
||||
|
||||
.recharge_item_disabled {
|
||||
background: #999;
|
||||
border: 1px solid #999 !important;
|
||||
background: #999;
|
||||
border: 1px solid #999 !important;
|
||||
|
||||
&>text {
|
||||
color: white !important;
|
||||
}
|
||||
& > text {
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
|
||||
.recharge {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-gap: 15rpx;
|
||||
border-bottom: 1px solid #f9f9f9;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-gap: 15rpx;
|
||||
border-bottom: 1px solid #f9f9f9;
|
||||
|
||||
&_item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 16rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
&_item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 16rpx;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
+50
-55
@@ -1,83 +1,78 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
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 data = {
|
||||
|
||||
}
|
||||
const state = reactive<any>({
|
||||
detailId: null,
|
||||
detail: {},
|
||||
detailId: null,
|
||||
detail: {},
|
||||
})
|
||||
|
||||
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 _pa = { id: state.detailId }
|
||||
const { data } = await boxesApi.detail(_pa)
|
||||
state.detail = data
|
||||
state.detail.imagesArray = data.images?.split(",")
|
||||
const _pa = { id: state.detailId }
|
||||
const { data } = await boxesApi.detail(_pa)
|
||||
state.detail = data
|
||||
state.detail.imagesArray = data.images?.split(",")
|
||||
}
|
||||
|
||||
const doSubmit = () => {
|
||||
router.jump('/pages/boxes/apply', { id: state.detail.id })
|
||||
router.jump("/pages/boxes/apply", { id: state.detail.id })
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<crud-layout title="" 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="v" mode="widthFix" />
|
||||
</z-swiper-item>
|
||||
</z-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>
|
||||
<view class="second-text-26">可容纳{{ state.detail.capacity }}</view>
|
||||
</view>
|
||||
<view class="flex-col m-t-15rpx">
|
||||
<view class="sub-text-32">{{ state.detail.name }}</view>
|
||||
</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>
|
||||
<template #main-bottom>
|
||||
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-60rpx m-y-30rpx sub-text-30 color-white!"
|
||||
@tap="doSubmit">
|
||||
预定
|
||||
</view>
|
||||
</template>
|
||||
</crud-layout>
|
||||
<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">
|
||||
<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>
|
||||
<view class="second-text-26">可容纳{{ state.detail.capacity }}</view>
|
||||
</view>
|
||||
<view class="flex-col m-t-15rpx">
|
||||
<view class="sub-text-32">{{ state.detail.name }}</view>
|
||||
</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>
|
||||
<template #main-bottom>
|
||||
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-60rpx m-y-30rpx sub-text-30 color-white!" @tap="doSubmit">
|
||||
预定
|
||||
</view>
|
||||
</template>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep() {
|
||||
.layout_main>scroll-view {
|
||||
padding: 0 !important;
|
||||
}
|
||||
.layout_main > scroll-view {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { ref, reactive, computed } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
|
||||
@@ -8,6 +8,7 @@ import { boxesApi } from "@@/api"
|
||||
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
import CustomWaterfallsFlow from "@@/components/other/custom-waterfalls-flow/custom-waterfalls-flow.vue"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
|
||||
const data = {
|
||||
tabs: [
|
||||
@@ -25,6 +26,13 @@ const state = reactive<any>({
|
||||
},
|
||||
})
|
||||
|
||||
// 重新设置图片路径
|
||||
const boxesList = computed(() => {
|
||||
return pageHook.list.map((item: any) => {
|
||||
return { ...item, images: filePath(item.images) }
|
||||
})
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, boxesApi.page, null, "data.records")
|
||||
const query = (page: number, pagesize: number) => {
|
||||
@@ -61,7 +69,7 @@ const doCard = (v: any) => {
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="5"
|
||||
:default-page-size="999"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@@ -76,16 +84,16 @@ const doCard = (v: any) => {
|
||||
</view>
|
||||
</template>
|
||||
<view class="h-20rpx" />
|
||||
<custom-waterfalls-flow v-model="pageHook.list" imageKey="images" :columnSpace="1" @wapperClick="doCard" @imageClick="doCard">
|
||||
<custom-waterfalls-flow v-model="boxesList" imageKey="images" :columnSpace="1" @wapperClick="doCard" @imageClick="doCard">
|
||||
<template v-slot:default="v">
|
||||
<view class="p-x-15rpx p-t-10rpx p-b-20rpx">
|
||||
<view class="sub-text-28 show-line">{{ v.name }}</view>
|
||||
<view class="m-t-10rpx flex-row items-center">
|
||||
<view class="second-text-32 color-#f63a36!"> ¥{{ v.price }} </view>
|
||||
</view>
|
||||
<view class="flex-row items-center m-t-10rpx">
|
||||
<view class="flex-row items-center justify-between m-t-10rpx">
|
||||
<view class="second-text-26">可容纳{{ v.capacity }}人</view>
|
||||
<view class="w-1px h-20rpx m-x-5rpx bg-#999" />
|
||||
<view class="w-2rpx h-20rpx m-x-5rpx bg-#999" />
|
||||
<view class="flex-row-center">
|
||||
<tm-tag v-if="v.status == 0" size="xs" color="success">
|
||||
{{ hooks.useEnum("boxesBxStatusEnum", v.status.toString()) }}
|
||||
|
||||
@@ -72,7 +72,7 @@ const doDel = (id: string) => {
|
||||
<text class="font-600">{{ v.username }}</text>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<text class="botder_btn" @click="doEdit(v.id)">修改</text>
|
||||
<!-- <text class="botder_btn" @click="doEdit(v.id)">修改</text> -->
|
||||
<view class="w-30rpx" />
|
||||
<tm-modal v-if="false" title="确定删除吗?" height="auto" @confirm="doDel(v.id)">
|
||||
<template v-slot:trigger><text class="botder_btn">删除</text></template>
|
||||
@@ -81,11 +81,7 @@ const doDel = (id: string) => {
|
||||
</view>
|
||||
</view>
|
||||
<template #bottom>
|
||||
<view
|
||||
v-if="false"
|
||||
class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!"
|
||||
@tap="doAdd"
|
||||
>
|
||||
<view v-if="false" class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!" @tap="doAdd">
|
||||
添加
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick } from "vue"
|
||||
import { reactive, nextTick } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
|
||||
@@ -15,7 +15,6 @@ import ProductRow from "./components/product-row.vue"
|
||||
import ProductCar from "./components/product-car.vue"
|
||||
import ProductTotal from "./components/product-total.vue"
|
||||
|
||||
const data = {}
|
||||
const state = reactive<any>({
|
||||
detailId: null,
|
||||
totPrice: 0,
|
||||
@@ -41,9 +40,14 @@ onShow(() => {
|
||||
})
|
||||
|
||||
const getDetail = async () => {
|
||||
uni.showLoading({
|
||||
title: "加载中...",
|
||||
mask: true,
|
||||
})
|
||||
const _pa = { id: state.detailId }
|
||||
const { data } = await merchantApi.detail(_pa)
|
||||
state.detail = data
|
||||
uni.hideLoading()
|
||||
}
|
||||
|
||||
const getShopCar = async () => {
|
||||
@@ -201,7 +205,7 @@ const getHeight = () => {
|
||||
|
||||
const doPhone = () => {
|
||||
if (isEmpty(state.detail.phone)) {
|
||||
uni.showToast({ title: "该店铺没有预留电话", icon: "none" })
|
||||
uni.showToast({ title: "该商户没有预留电话", icon: "none" })
|
||||
return
|
||||
}
|
||||
hooks.useMakePhoneCall(state.detail.phone)
|
||||
@@ -226,26 +230,30 @@ const doFood = () => {
|
||||
<!-- start 简介 start -->
|
||||
<view class="h-15rpx" />
|
||||
<view flex-row card p-20rpx>
|
||||
<image class="w-160rpx h-160rpx rounded-12rpx" :src="filePath(state.detail.logoPic)" mode="aspectFill" />
|
||||
<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-36">
|
||||
<view class="flex-row-center sub-text-34">
|
||||
<text>{{ state.detail.name }}</text>
|
||||
</view>
|
||||
<view>
|
||||
<tm-tag size="s">{{ state.detail.deptName }}</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
<view class="m-t-10rpx second-text-28">
|
||||
<text>营业时间</text>
|
||||
<text class="m-l-10rpx">
|
||||
{{ state.detail.jobStartTime }}
|
||||
~
|
||||
{{ state.detail.jobEndTime }}
|
||||
</text>
|
||||
<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 class="m-t-10rpx second-text-28">
|
||||
<text>食堂地址</text>
|
||||
<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>
|
||||
</view>
|
||||
@@ -283,6 +291,7 @@ const doFood = () => {
|
||||
<view class="h-15rpx" />
|
||||
<view class="flex-row">
|
||||
<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"
|
||||
@@ -299,7 +308,7 @@ const doFood = () => {
|
||||
</view>
|
||||
</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 v-for="(pV, pI) in state.shopList" :key="pI">
|
||||
<view class="m-x-15rpx">
|
||||
<product-row
|
||||
@@ -318,17 +327,13 @@ const doFood = () => {
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view v-else class="mx-auto mt-10 second-text-28">暂无信息</view>
|
||||
</view>
|
||||
</tm-sticky>
|
||||
<!-- end 商品 end -->
|
||||
<template #main-bottom>
|
||||
<view class="car z-200 p-x-30rpx p-y-30rpx bg-white">
|
||||
<product-total
|
||||
:totPrice="state.totPrice"
|
||||
:totCount="state.totCount"
|
||||
@doContainer="doVisibleCar"
|
||||
@submit="doPay"
|
||||
/>
|
||||
<view v-if="state.classifyList.length > 0" class="car z-200 p-x-30rpx p-y-30rpx bg-white">
|
||||
<product-total :totPrice="state.totPrice" :totCount="state.totCount" @doContainer="doVisibleCar" @submit="doPay" />
|
||||
</view>
|
||||
</template>
|
||||
</crud-layout>
|
||||
|
||||
+55
-18
@@ -1,19 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, watch } from "vue"
|
||||
import { ref, reactive, computed } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { isEmpty } from "radash"
|
||||
import dayjs from "dayjs"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { foodApi } from "@@/api"
|
||||
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
import CustomWaterfallsFlow from "@@/components/other/custom-waterfalls-flow/custom-waterfalls-flow.vue"
|
||||
import { LazyImg, Waterfall } from "vue-waterfall-plugin-next"
|
||||
import "vue-waterfall-plugin-next/dist/style.css"
|
||||
// import CustomWaterfallsFlow from "@@/components/other/custom-waterfalls-flow/custom-waterfalls-flow.vue"
|
||||
import { filePath } from "@@/utils/file"
|
||||
|
||||
const data = {
|
||||
const menus = {
|
||||
tabs: [
|
||||
{ id: null, name: "全部", disabled: false },
|
||||
// { id: null, name: "全部", disabled: false },
|
||||
{ id: 1, name: "早餐", disabled: false },
|
||||
{ id: 2, name: "午餐", disabled: false },
|
||||
{ id: 3, name: "晚餐", disabled: false },
|
||||
@@ -26,7 +26,7 @@ const state = reactive<any>({
|
||||
pa: {
|
||||
merchantId: null,
|
||||
startTime: null,
|
||||
hourType: data.tabs[0].id,
|
||||
hourType: menus.tabs[0].id,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -60,7 +60,7 @@ const initDate = () => {
|
||||
const now = new Date()
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const date = dayjs(now).add(i, "d")
|
||||
const weekDayStr = date.isSame(now, "day") ? "今天" : data.weekDays[date.day()]
|
||||
const weekDayStr = date.isSame(now, "day") ? "今天" : menus.weekDays[date.day()]
|
||||
list.push({
|
||||
weekDayStr,
|
||||
date: date.toDate(),
|
||||
@@ -76,17 +76,19 @@ const initDate = () => {
|
||||
const doDateItem = (v: any, i: any) => {
|
||||
state.currentDateIndex = i
|
||||
state.pa.startTime = state.dateList[i].dateTime
|
||||
pageHook.list = []
|
||||
pageRef.value.reload(true)
|
||||
}
|
||||
|
||||
const doTab = (e: any) => {
|
||||
const target = data.tabs[e]
|
||||
const target = menus.tabs[e]
|
||||
state.pa.hourType = target.id
|
||||
pageHook.list = []
|
||||
pageRef.value.reload(true)
|
||||
}
|
||||
|
||||
const doProduct = (v: any) => {
|
||||
router.jump("/pages/merchant/product-detail", { id: v.spuId })
|
||||
// router.jump("/pages/merchant/product-detail", { spuId: v.spuId })
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -97,7 +99,7 @@ const doProduct = (v: any) => {
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
:default-page-size="5"
|
||||
:default-page-size="8"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
:show-scrollbar="false"
|
||||
@@ -107,7 +109,7 @@ const doProduct = (v: any) => {
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<template #top>
|
||||
<view class="bg-#1777FF p-15rpx pt-10">
|
||||
<view class="bg-#1777FF p-15rpx">
|
||||
<scroll-view scroll-x class="whitespace-nowrap">
|
||||
<view class="flex-row items-center space-x-15rpx">
|
||||
<view
|
||||
@@ -117,19 +119,54 @@ const doProduct = (v: any) => {
|
||||
:key="i"
|
||||
@tap="doDateItem(v, i)"
|
||||
>
|
||||
<view class="">{{ v.dayTime }}</view>
|
||||
<view class="">{{ v.weekDayStr }}</view>
|
||||
<view>{{ v.dayTime }}</view>
|
||||
<view>{{ v.weekDayStr }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="bg-white rounded-16rpx px-20rpx m-x-10rpx m-t-15rpx">
|
||||
<z-tabs :list="data.tabs" @change="doTab" />
|
||||
<z-tabs :list="menus.tabs" @change="doTab" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view class="h-20rpx" />
|
||||
<view class="m-x-10rpx">
|
||||
<custom-waterfalls-flow v-model="foodList" imageKey="picUrl" :columnSpace="1" @wapperClick="doProduct" @imageClick="doProduct">
|
||||
|
||||
<view class="m-x-20rpx">
|
||||
<Waterfall
|
||||
v-if="foodList.length"
|
||||
:list="foodList"
|
||||
:gutter="10"
|
||||
:breakpoints="{
|
||||
1200: { rowPerView: 4 },
|
||||
800: { rowPerView: 3 },
|
||||
375: { rowPerView: 2 },
|
||||
}"
|
||||
:hasAroundGutter="false"
|
||||
backgroundColor="#ffffff00"
|
||||
:crossOrigin="false"
|
||||
:animationDuration="100"
|
||||
>
|
||||
<template #default="{ item, url, index }">
|
||||
<div class="card">
|
||||
<LazyImg class="rounded-2" :url="item.picUrl" />
|
||||
<view class="p-x-15rpx p-y-25rpx">
|
||||
<view class="sub-text-28 show-line">{{ item.name }}</view>
|
||||
<view class="m-t-10rpx flex-row items-center">
|
||||
<view class="second-text-32 color-#f63a36!"> ¥{{ hooks.useMoney(item.price) }} </view>
|
||||
<view class="m-l-20rpx second-text-24 line-through"> ¥{{ hooks.useMoney(item.marketPrice) }} </view>
|
||||
</view>
|
||||
<view class="flex-row items-center">
|
||||
<view class="second-text-24">{{ hooks.useFormatNum("库存", "", item.stock) }}</view>
|
||||
<view class="w-1px h-20rpx m-x-5rpx bg-#999" />
|
||||
<view class="second-text-24">{{ hooks.useFormatNum("销量", "", item.salesCount) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</div>
|
||||
</template>
|
||||
</Waterfall>
|
||||
|
||||
<!-- <custom-waterfalls-flow v-model="foodList" imageKey="picUrl" :columnSpace="1" @wapperClick="doProduct" @imageClick="doProduct">
|
||||
<template v-slot:default="v">
|
||||
<view class="p-x-15rpx p-y-25rpx">
|
||||
<view class="sub-text-28 show-line">{{ v.name }}</view>
|
||||
@@ -144,7 +181,7 @@ const doProduct = (v: any) => {
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</custom-waterfalls-flow>
|
||||
</custom-waterfalls-flow> -->
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
|
||||
@@ -1,87 +1,73 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { isEmpty } from "radash";
|
||||
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"
|
||||
|
||||
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 data = {};
|
||||
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 _pa = { id: state.detailId };
|
||||
const { data } = await productApi.get(_pa);
|
||||
state.detail = data;
|
||||
};
|
||||
uni.showLoading({
|
||||
title: "加载中...",
|
||||
})
|
||||
const _pa = { id: state.detailId }
|
||||
const { data } = await productApi.get(_pa)
|
||||
state.detail = data
|
||||
uni.hideLoading()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout
|
||||
title="订单详情"
|
||||
tabBarType="just-flot-back"
|
||||
bg="/static/page/blue-bg.png"
|
||||
>
|
||||
<image
|
||||
class="w-100vw"
|
||||
:src="filePath(state.detail.picUrl)"
|
||||
mode="widthFix"
|
||||
/>
|
||||
<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.name }}</view>
|
||||
<view class="m-t-15rpx second-text-26">{{
|
||||
state.detail.introduction
|
||||
}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="false"
|
||||
class="m-t-15rpx flex-row items-center justify-between card p-y-20rpx p-x-30rpx"
|
||||
>
|
||||
<view class="prefix_title">评价</view>
|
||||
</view>
|
||||
<view v-if="state.detail.description" class="m-t-15rpx 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>
|
||||
<crud-layout title="订单详情" tabBarType="just-flot-back" bg="/static/page/blue-bg.png">
|
||||
<view v-if="state.detail">
|
||||
<image class="w-100vw" :src="filePath(state.detail.picUrl)" mode="widthFix" />
|
||||
<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.name }}</view>
|
||||
<view class="m-t-15rpx second-text-26">{{ state.detail.introduction }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="false" class="m-t-15rpx flex-row items-center justify-between card p-y-20rpx p-x-30rpx">
|
||||
<view class="prefix_title">评价</view>
|
||||
</view>
|
||||
<view v-if="state.detail.description" class="m-t-15rpx 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>
|
||||
</view>
|
||||
<view v-else class="second-text-28 mt-24 text-center">暂无数据</view>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep() {
|
||||
.layout_main > scroll-view {
|
||||
padding: 0 !important;
|
||||
}
|
||||
.layout_main > scroll-view {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,175 @@
|
||||
<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">支付</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 }}
|
||||
</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>
|
||||
</view>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue"
|
||||
import { onShow } from "@dcloudio/uni-app"
|
||||
import { usePayStore } from "@/sheep/stores/pay"
|
||||
import payApi from "@@/api/pay"
|
||||
import { storePrice } from "@/sheep/utils/formatMoney"
|
||||
import { router } from "@/sheep"
|
||||
|
||||
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)
|
||||
|
||||
onShow(() => {
|
||||
scanData.value = usePayStore().payData
|
||||
if (scanData.value.id && scanData.value.name) {
|
||||
disabled.value = false
|
||||
} else {
|
||||
uni.showToast({ title: "扫码信息不存在", icon: "none" })
|
||||
disabled.value = true
|
||||
}
|
||||
})
|
||||
|
||||
const displayAmount = computed(() => {
|
||||
if (!amount.value) return "0"
|
||||
return (
|
||||
amount.value
|
||||
// .toString()
|
||||
// .toFixed(2)
|
||||
.replace(/\B(?=(\d{3})+(?!\d))/g, ",")
|
||||
)
|
||||
})
|
||||
|
||||
// 按下键盘
|
||||
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" })
|
||||
if (!amount.value) {
|
||||
uni.showToast({ title: "请输入金额", icon: "none" })
|
||||
return
|
||||
}
|
||||
if (Number(amount.value) === 0) {
|
||||
uni.showToast({ title: "金额不能为0", icon: "none" })
|
||||
return
|
||||
}
|
||||
uni.showModal({
|
||||
title: "确定支付吗?",
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
await pay()
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// handle pay
|
||||
const pay = async () => {
|
||||
try {
|
||||
uni.showLoading({ title: "支付中...", mask: true })
|
||||
const res = await payApi.createQrCodeOrder({
|
||||
merchantId: scanData.value.id,
|
||||
customPrice: storePrice(Number(amount.value)),
|
||||
})
|
||||
if (res.code != 0) {
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
uni.showToast({ title: "支付成功", icon: "success" })
|
||||
usePayStore().payData = {}
|
||||
setTimeout(() => {
|
||||
router.back()
|
||||
uni.hideLoading()
|
||||
}, 1000)
|
||||
} catch (error: any) {
|
||||
// uni.showToast({ title: "错误", icon: "error" })
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -22,9 +22,7 @@ const state = reactive<any>({
|
||||
selectList: [],
|
||||
})
|
||||
const uploadApplyPicUrls = ref<Array<Record<string, any> | string>>([]) // 补充凭证图片
|
||||
const applyPicUrls = computed(() =>
|
||||
uploadApplyPicUrls.value.map((item: any) => JSON.parse(item.response).data.url).join(","),
|
||||
)
|
||||
const applyPicUrls = computed(() => uploadApplyPicUrls.value.map((item: any) => JSON.parse(item.response).data.url).join(","))
|
||||
|
||||
const applyForm = reactive<any>({
|
||||
way: data.payType[0].type,
|
||||
@@ -154,14 +152,7 @@ const doSubmit = async () => {
|
||||
<view class="sub-text-28">售后类型</view>
|
||||
<view class="m-t-20rpx">
|
||||
<tm-radio-group @change="radioChange" direction="column" gap="20" v-model="applyForm.way">
|
||||
<tm-radio
|
||||
:disabled="v.disabled"
|
||||
v-for="(v, i) in data.payType"
|
||||
:key="i"
|
||||
v-show="v.visible"
|
||||
:value="v.type"
|
||||
:label="v.text"
|
||||
/>
|
||||
<tm-radio :disabled="v.disabled" v-for="(v, i) in data.payType" :key="i" v-show="v.visible" :value="v.type" :label="v.text" />
|
||||
</tm-radio-group>
|
||||
</view>
|
||||
</view>
|
||||
@@ -187,7 +178,6 @@ const doSubmit = async () => {
|
||||
</tm-picker>
|
||||
</view>
|
||||
<view class="flex-col justify-center card p-x-20rpx p-y-30rpx m-b-20rpx">
|
||||
<<<<<<< HEAD
|
||||
<view class="sub-text-28">补充凭证图片</view>
|
||||
<view class="m-t-20rpx">
|
||||
<tm-upload-photo
|
||||
@@ -201,15 +191,9 @@ const doSubmit = async () => {
|
||||
<view class="sub-text-20 c-red!">注:图片大小不超过5M,最多上传6张</view>
|
||||
</view>
|
||||
<view class="flex-col justify-center card p-x-20rpx p-y-30rpx m-b-20rpx">
|
||||
======= >>>>>>> c3eaafa5d0575ebd0fa74be0180c5cfe8a9901ea
|
||||
<view class="sub-text-28">相关描述</view>
|
||||
<view class="m-t-20rpx">
|
||||
<tm-input
|
||||
v-model="applyForm.remark"
|
||||
type="textarea"
|
||||
:showClear="false"
|
||||
placeholder="客官~请描述您遇到的问题"
|
||||
></tm-input>
|
||||
<tm-input v-model="applyForm.remark" type="textarea" :showClear="false" placeholder="客官~请描述您遇到的问题"></tm-input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
|
||||
+27
-29
@@ -14,24 +14,18 @@
|
||||
<view class="h-15rpx" />
|
||||
<!-- start 简介 start -->
|
||||
<view flex-row card p-20rpx>
|
||||
<image class="w-120rpx h-120rpx rounded-12rpx" :src="filePath(state.detail.logoPic)" mode="aspectFill" />
|
||||
<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-36">
|
||||
<text>{{ state.detail.name }}</text>
|
||||
</view>
|
||||
<view>
|
||||
<tm-tag size="s">{{ state.detail.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="flex-row-center sub-text-32">{{ state.detail.name }}</view>
|
||||
<tm-tag size="s">{{ state.detail.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="second-text-28">{{ state.detail.phone }}</view>
|
||||
<view class="m-t-10rpx second-text-28">
|
||||
<text>营业时间</text>
|
||||
<text class="m-l-10rpx">
|
||||
{{ state.detail.jobStartTime }}
|
||||
~
|
||||
{{ state.detail.jobEndTime }}
|
||||
</text>
|
||||
<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>
|
||||
@@ -47,11 +41,7 @@
|
||||
|
||||
<!-- 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 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"
|
||||
@@ -86,12 +76,7 @@
|
||||
|
||||
<template #main-bottom>
|
||||
<view class="car z-200 p-x-30rpx p-y-30rpx bg-white">
|
||||
<product-total
|
||||
:totPrice="state.totPrice"
|
||||
:totCount="state.totCount"
|
||||
@doContainer="doVisibleCar"
|
||||
@doPay="doPay"
|
||||
/>
|
||||
<product-total :totPrice="state.totPrice" :totCount="state.totCount" @doContainer="doVisibleCar" @doPay="doPay" />
|
||||
</view>
|
||||
</template>
|
||||
</crud-layout>
|
||||
@@ -149,9 +134,22 @@ onLoad((options: any) => {
|
||||
}
|
||||
})
|
||||
onShow(async () => {
|
||||
await getDetail()
|
||||
await getShopCar()
|
||||
await getClassify()
|
||||
uni.showLoading({
|
||||
title: "加载中...",
|
||||
mask: true,
|
||||
})
|
||||
try {
|
||||
await getDetail()
|
||||
await getShopCar()
|
||||
await getClassify()
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: "加载失败",
|
||||
icon: "error",
|
||||
})
|
||||
} finally {
|
||||
uni.hideLoading()
|
||||
}
|
||||
})
|
||||
|
||||
const getDetail = async () => {
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
:fixed="false"
|
||||
v-model="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="scroll"
|
||||
>
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
<view class="bg-white rounded-12rpx p-20rpx flex justify-between items-center">
|
||||
<text class="text-30 font-600">流水统计</text>
|
||||
<tm-text color="#999999">{{ state.nowVal }}</tm-text>
|
||||
<view class="flex items-center cursor-pointer">
|
||||
<tm-between-time
|
||||
start="2020-1-1"
|
||||
end="2040-1-1"
|
||||
v-model="state.newdata"
|
||||
v-model:model-str="state.nowVal"
|
||||
@confirm="datePickerConfirm"
|
||||
>
|
||||
<svg
|
||||
t="1742280333491"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="4288"
|
||||
width="16"
|
||||
height="14"
|
||||
>
|
||||
<path
|
||||
d="M568.552727 954.181818a86.341818 86.341818 0 0 1-41.425454-10.472727l-114.269091-62.836364a86.574545 86.574545 0 0 1-44.916364-76.101818V442.181818a16.989091 16.989091 0 0 0-6.981818-13.730909L97.047273 218.298182 93.090909 214.807273A85.876364 85.876364 0 0 1 155.927273 69.818182h711.214545A86.574545 86.574545 0 0 1 930.909091 214.807273l-3.490909 3.490909-266.24 213.410909a17.454545 17.454545 0 0 0-6.050909 13.730909v422.4A86.341818 86.341818 0 0 1 568.552727 954.181818zM141.963636 166.632727l262.283637 209.454546A85.178182 85.178182 0 0 1 437.061818 442.181818v362.589091a17.92 17.92 0 0 0 8.610909 15.592727l114.269091 62.138182a17.687273 17.687273 0 0 0 17.687273 0 17.221818 17.221818 0 0 0 8.378182-15.36V445.44a85.876364 85.876364 0 0 1 31.883636-67.258182l263.214546-211.549091a17.687273 17.687273 0 0 0 1.62909-18.152727 17.454545 17.454545 0 0 0-15.592727-8.843636H155.927273a17.221818 17.221818 0 0 0-13.963637 27.694545zM920.669091 512h-188.974546a34.443636 34.443636 0 0 1 0-69.818182h188.974546a34.443636 34.443636 0 0 1 0 69.818182z m0 128.930909h-188.974546a34.443636 34.443636 0 0 1 0-69.818182h188.974546a34.443636 34.443636 0 0 1 0 69.818182z m0 128h-188.974546a34.443636 34.443636 0 0 1 0-69.818182h188.974546a34.443636 34.443636 0 0 1 0 69.818182z"
|
||||
p-id="4289"
|
||||
/>
|
||||
</svg>
|
||||
<text class="ml-1 text-30">筛选</text>
|
||||
</tm-between-time>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view class="h-20rpx" />
|
||||
|
||||
<view class="bg-white rounded-16rpx p-2 mb-2 shadow-md" v-for="(v, i) in list" :key="i">
|
||||
<view class="text-28 text-gray-800 font-medium px-2 mb-2">
|
||||
{{ "2022-01-01" }}
|
||||
</view>
|
||||
<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 mr-1">
|
||||
<text class="flex-1 text-center text-gray-600">流水金额</text>
|
||||
<text class="flex-1 text-center text-26 text-gray-800 font-medium">¥{{ 1145 }}</text>
|
||||
</view>
|
||||
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx ml-1">
|
||||
<text class="flex-1 text-center text-gray-600">流水次数</text>
|
||||
<text class="flex-1 text-center text-26 text-gray-800 font-medium">{{ 1145 }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex justify-between mb-2">
|
||||
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx mr-1">
|
||||
<text class="flex-1 text-center text-gray-600">退款金额</text>
|
||||
<text class="flex-1 text-center text-26 text-red-500 font-medium">¥{{ 1145 }}</text>
|
||||
</view>
|
||||
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx ml-1">
|
||||
<text class="flex-1 text-center text-gray-600">退款次数</text>
|
||||
<text class="flex-1 text-center text-26 text-red-500 font-medium">{{ 1145 }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex justify-between mb-0">
|
||||
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx mr-1">
|
||||
<text class="flex-1 text-center text-gray-600">盈利金额</text>
|
||||
<text class="flex-1 text-center text-26 text-green-500 font-medium">¥{{ 1145 }}</text>
|
||||
</view>
|
||||
<view class="flex-1 flex items-center p-2 bg-white rounded-8rpx ml-1">
|
||||
<text class="flex-1 text-center text-gray-600">盈利次数</text>
|
||||
<text class="flex-1 text-center text-26 text-green-500 font-medium">{{ 1145 }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onShow } from "@dcloudio/uni-app"
|
||||
import { hooks } from "@@/index"
|
||||
import { orderApi } from "@@/api"
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
payTimeList: [],
|
||||
},
|
||||
nowVal: "",
|
||||
newdata: "",
|
||||
})
|
||||
const { list, startPage, scroll } = hooks.usePage(pageRef, orderApi.page, null, "data.records")
|
||||
|
||||
onShow(() => {
|
||||
// const isLogin = await hooks.useCheckLogin()
|
||||
// if (!isLogin) return
|
||||
})
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
// const isLogin = hooks.useStaticCheckLogin()
|
||||
// if (!isLogin) return
|
||||
startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
// 时间范围选择器确认
|
||||
const datePickerConfirm = (date: any) => {
|
||||
state.pa.payTimeList = state.newdata
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
</script>
|
||||
@@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { onShow } from "@dcloudio/uni-app"
|
||||
import { hooks, router } from "@@/index"
|
||||
import { merchantApi } from "@@/api"
|
||||
import { filePath } from "@@/utils/file"
|
||||
@@ -13,7 +12,6 @@ const state = reactive<any>({
|
||||
},
|
||||
})
|
||||
|
||||
onLoad(() => {})
|
||||
onShow(() => {
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
@@ -52,23 +50,19 @@ const toDetail = async (v: any) => {
|
||||
>
|
||||
<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-160rpx h-160rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<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">
|
||||
<text>{{ v.name }}</text>
|
||||
</view>
|
||||
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
|
||||
<view>
|
||||
<tm-tag size="s">{{ v.deptName }}</tm-tag>
|
||||
</view>
|
||||
</view>
|
||||
<view class="m-t-10rpx second-text-28">
|
||||
<text>营业时间</text>
|
||||
<text class="m-l-10rpx">
|
||||
{{ v.jobStartTime }}
|
||||
~
|
||||
{{ v.jobEndTime }}
|
||||
</text>
|
||||
<view class="second-text-24">
|
||||
<view 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>
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<crud-layout bg="/static/page/blue-bg.png">
|
||||
<z-paging
|
||||
ref="pageRef"
|
||||
:fixed="false"
|
||||
v-model="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="scroll"
|
||||
>
|
||||
<template #top>
|
||||
<view class="h-30rpx" />
|
||||
<view class="bg-white rounded-16rpx px-20rpx">
|
||||
<z-tabs :list="tabs" @change="tabChange" />
|
||||
</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 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">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row items-center">
|
||||
<view class="main-text-28">{{ v.merchantName }}</view>
|
||||
<view v-if="false" class="m-l-15rpx color-#999 font-size-26rpx! iconfont icon-youjiantou" />
|
||||
</view>
|
||||
<tm-tag v-if="v.orderStatus !== 1" color="success" size="xs">已支付</tm-tag>
|
||||
<tm-tag v-if="v.orderStatus == 2" color="info" size="xs">售后</tm-tag>
|
||||
</view>
|
||||
<view class="flex justify-between items-end m-t-5rpx">
|
||||
<view class="flex flex-col m-t-5rpx">
|
||||
<view class="second-text-20">
|
||||
<text>{{ "某个人" }}</text>
|
||||
<text class="m-l-10rpx">{{ "13155555555" }}</text>
|
||||
</view>
|
||||
<view class="second-text-20">
|
||||
<text>下单时间</text>
|
||||
<text class="m-l-10rpx">
|
||||
{{ hooks.useTime(v.createTime, "{y}-{m}-{d} {h}:{i}:{s}") }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex flex-row">
|
||||
<view class="m-t-14rpx m-r-20rpx second-text-26">共 {{ v.carList.length }} 件</view>
|
||||
<view class="m-t-10rpx main-text-30 color-red!">¥ {{ hooks.useMoney(v.totalPrice) }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="h-20rpx m-t-[-10rpx] flex justify-end items-center">
|
||||
<!-- <view class="absolute top-0 right-0 bottom-0 left-0 h-180rpx">
|
||||
<scroll-view scroll-x class="flex-row-center whitespace-nowrap">
|
||||
<view class="flex-row items-center">
|
||||
<view
|
||||
class="inline-flex! flex-col justify-center h-180rpx m-r-20rpx"
|
||||
v-for="(pV, pI) in v.carList"
|
||||
:key="pI"
|
||||
@tap.stop="
|
||||
router.jump('/pages/merchant/product-detail', {
|
||||
id: pV.productId,
|
||||
})
|
||||
"
|
||||
>
|
||||
<image class="w-160rpx h-120rpx rounded-8rpx" :src="filePath(pV.productPic)" mode="aspectFill" />
|
||||
<view class="w-160rpx m-t-10rpx sub-text-24 show-line text-center">
|
||||
{{ pV.productName }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="inline-flex! h-180rpx">
|
||||
<view class="w-160rpx h-full" />
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="flex-row items-center justify-end">
|
||||
<view class="botder_btn" @tap.stop="">退款</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
|
||||
<!-- <tm-drawer ref="calendarView" placement="bottom" v-model:show="state.showDrawer">
|
||||
<view style="height: 1800rpx"></view>
|
||||
</tm-drawer> -->
|
||||
</crud-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onShow } from "@dcloudio/uni-app"
|
||||
import { hooks } from "@@/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
import zTabs from "@@/components/other/z-tabs/z-tabs.vue"
|
||||
import { orderApi } from "@@/api"
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
// 选项卡
|
||||
const tabs = [
|
||||
{ id: null, name: "全部", disabled: false },
|
||||
{ id: 1, name: "已支付", disabled: false },
|
||||
{ id: 2, name: "售后", disabled: false },
|
||||
]
|
||||
const state = reactive<any>({
|
||||
pa: {
|
||||
orderStatus: tabs[0].id,
|
||||
},
|
||||
// showDrawer: false,
|
||||
})
|
||||
const { list, startPage, scroll } = hooks.usePage(pageRef, orderApi.page, null, "data.records")
|
||||
|
||||
onShow(() => {
|
||||
// const isLogin = await hooks.useCheckLogin()
|
||||
// if (!isLogin) return
|
||||
})
|
||||
|
||||
// 切换选项卡
|
||||
const tabChange = (e: number) => {
|
||||
state.pa.orderStatus = tabs[e].id
|
||||
pageRef.value.reload(true)
|
||||
}
|
||||
|
||||
const query = (page: number, pagesize: number) => {
|
||||
// const isLogin = hooks.useStaticCheckLogin()
|
||||
// if (!isLogin) return
|
||||
startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
// 点击退款
|
||||
// const tabRefund = (v: any) => {
|
||||
// state.showDrawer = true
|
||||
// }
|
||||
</script>
|
||||
+63
-18
@@ -48,6 +48,8 @@ import { filePath } from "@@/utils/file"
|
||||
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
|
||||
@@ -59,6 +61,7 @@ const state = reactive<{ wallet: any; userInfo: any; menuList: MenuItem[] }>({
|
||||
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" },
|
||||
@@ -172,6 +175,40 @@ const doLogout = async () => {
|
||||
uni.showToast({ title: "退出登录成功", icon: "none" })
|
||||
}
|
||||
|
||||
// 扫一扫
|
||||
const doScanCode = async () => {
|
||||
usePayStore().setPayData({})
|
||||
try {
|
||||
const res: any = await (window as any).dd.scan({ type: "all", sourceType: ["camera"], scanType: ["cameraScan"] })
|
||||
// const decodedString = decodeBase64("eyJpZCI6IjE4ODk0ODM5Mzg0ODQ1MzEyMDEiLCJuYW1lIjoi5rWL6K+V6LaF5biCIn0=")
|
||||
const decodedString = decodeBase64(res.text)
|
||||
if (decodedString) {
|
||||
const decodedJson = JSON.parse(decodedString)
|
||||
if (decodedJson?.id && decodedJson?.name) {
|
||||
usePayStore().setPayData(decodedJson)
|
||||
router.jump("/pages/pay/scanPay")
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "无效的二维码",
|
||||
icon: "none",
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "无效的二维码",
|
||||
icon: "none",
|
||||
})
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (error) {
|
||||
uni.showToast({
|
||||
title: error,
|
||||
icon: "none",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const onTabMenu = async (v: MenuItem, i: number) => {
|
||||
if (i == state.menuList.length - 1) {
|
||||
router.jump(v.router)
|
||||
@@ -179,7 +216,32 @@ const onTabMenu = async (v: MenuItem, i: number) => {
|
||||
}
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
router.jump(v.router)
|
||||
if (v.text === "扫一扫") {
|
||||
await doScanCode()
|
||||
} else {
|
||||
router.jump(v.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",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,23 +270,6 @@ onLoad(() => {
|
||||
onShow(() => {
|
||||
getStorageUserInfo()
|
||||
})
|
||||
|
||||
// {
|
||||
// "accessToken": {
|
||||
// "tokenValue": "06d43795-a3ef-4019-a70f-25830e7183a4",
|
||||
// "issuedAt": "2025-01-24T11:10:30.423604599Z",
|
||||
// "expiresAt": "2025-01-25T11:10:30.423604599Z",
|
||||
// "tokenType": {
|
||||
// "value": "Bearer"
|
||||
// },
|
||||
// "scopes": []
|
||||
// },
|
||||
// "refreshToken": {
|
||||
// "tokenValue": "FmRVP4l3d7t3263h9LeKnV8hdU0lPasMuI1wank_EbylRQPNLm7XP4_OtUV-zH9AbMZc9f14Qk2IXhw-33fWMGGKipVY8crbvVyWV5DeAcfeU8fYyQuNDh9rw3Dq0w75",
|
||||
// "issuedAt": "2025-01-24T11:10:30.423699280Z",
|
||||
// "expiresAt": "2025-01-31T11:10:30.423699280Z"
|
||||
// }
|
||||
// }
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
+12
-12
@@ -13,7 +13,7 @@ const data = {
|
||||
tabs: [
|
||||
{ id: null, name: "全部", disabled: false },
|
||||
{ id: 1, name: "未支付", disabled: false },
|
||||
{ id: 5, name: "待核销", disabled: false },
|
||||
{ id: 5, name: "已支付", disabled: false },
|
||||
{ id: 10, name: "售后", disabled: false },
|
||||
{ id: 20, name: "已核销", disabled: false },
|
||||
],
|
||||
@@ -49,7 +49,7 @@ const query = (page: number, pagesize: number) => {
|
||||
}
|
||||
|
||||
const doToDetail = (v: any) => {
|
||||
router.jump("/pages/order/detail", { id: v.id })
|
||||
// router.jump("/pages/order/detail", { id: v.id })
|
||||
}
|
||||
|
||||
const doAppraise = () => {}
|
||||
@@ -94,7 +94,7 @@ const doRefund = (v: any) => {
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row items-center">
|
||||
<view class="main-text-28">{{ v.merchantName }}</view>
|
||||
<view class="m-l-15rpx color-#999 font-size-26rpx! iconfont icon-youjiantou" />
|
||||
<!-- <view class="m-l-15rpx color-#999 font-size-26rpx! iconfont icon-youjiantou" /> -->
|
||||
</view>
|
||||
<tm-tag v-if="v.orderStatus == 1" color="info" size="xs">未支付</tm-tag>
|
||||
<tm-tag v-if="v.orderStatus == 5" color="success" size="xs">待核销</tm-tag>
|
||||
@@ -108,14 +108,14 @@ const doRefund = (v: any) => {
|
||||
{{ hooks.useTime(v.createTime, "{y}-{m}-{d} {h}:{i}:{s}") }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="second-text-22">
|
||||
<!-- <view class="second-text-22">
|
||||
{{ hooks.useEnum("hardwareRefundStatusEnum", v.refundStatus) }}
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="relative h-180rpx m-t-20rpx">
|
||||
<view class="absolute top-0 right-0 bottom-0 left-0 h-180rpx">
|
||||
<view class="relative h-0rpx m-t-[-10rpx] flex justify-end items-center">
|
||||
<!-- <view class="absolute top-0 right-0 bottom-0 left-0 h-180rpx">
|
||||
<scroll-view scroll-x class="flex-row-center whitespace-nowrap">
|
||||
<view class="flex-row items-center">
|
||||
<view
|
||||
@@ -138,11 +138,11 @@ const doRefund = (v: any) => {
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="absolute top-0 right-0 bottom-0 z-10 flex-col items-end w-160rpx p-x-20rpx bg-white bg-opacity-95">
|
||||
<view class="main-text-30 color-red!">¥ {{ hooks.useMoney(v.totalPrice) }}</view>
|
||||
<view class="m-t-10rpx second-text-26">共 {{ v.carList.length }} 件</view>
|
||||
</view>
|
||||
</view> -->
|
||||
<!-- <view class="absolute top-0 right-0 bottom-0 z-10 flex-col items-end w-160rpx p-x-20rpx bg-white bg-opacity-95"> -->
|
||||
<view class="m-t-2rpx m-r-20rpx second-text-26">共 {{ v.carList.length }} 件</view>
|
||||
<view class="main-text-30 color-red!">¥ {{ hooks.useMoney(v.totalPrice) }}</view>
|
||||
<!-- </view> -->
|
||||
</view>
|
||||
<view v-if="['5', '10'].includes(v.orderStatus)" class="flex-row items-center justify-end p-t-20rpx">
|
||||
<!-- <view v-if="v.orderStatus == 5 && v.orderType == 2" class="botder_btn" @tap.stop="doRefund(v)">退款</view> -->
|
||||
|
||||
+21
-31
@@ -1,31 +1,27 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { 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 { startPage, list, scroll } = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
|
||||
|
||||
onLoad(() => {})
|
||||
onShow(() => {
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
}
|
||||
})
|
||||
|
||||
const pageRef = ref<any>(null)
|
||||
const pageHook = hooks.usePage(pageRef, merchantApi.page, null, "data.records")
|
||||
const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
pageRef.value && pageRef.value.reload(false)
|
||||
})
|
||||
|
||||
const toDetail = async (v: any) => {
|
||||
const isLogin = await hooks.useCheckLogin()
|
||||
if (isLogin) {
|
||||
@@ -40,7 +36,7 @@ const toDetail = async (v: any) => {
|
||||
ref="pageRef"
|
||||
height="100%"
|
||||
:fixed="false"
|
||||
v-model="pageHook.list"
|
||||
v-model="list"
|
||||
:default-page-size="10"
|
||||
safe-area-inset-bottom
|
||||
:loading-more-enabled="true"
|
||||
@@ -48,29 +44,23 @@ const toDetail = async (v: any) => {
|
||||
@query="query"
|
||||
:auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false"
|
||||
@scroll="pageHook.scroll"
|
||||
@scroll="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-col card p-20rpx m-b-20rpx" v-for="(v, i) in list" :key="i" @tap="toDetail(v)">
|
||||
<view class="flex-row-center">
|
||||
<image class="w-120rpx h-120rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<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">
|
||||
<text> {{ v.name }}</text>
|
||||
</view>
|
||||
<view>
|
||||
<tm-tag size="s">{{ v.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
|
||||
<tm-tag size="s">{{ v.deptName }}</tm-tag>
|
||||
</view>
|
||||
<view class="second-text-28">{{ v.phone }}</view>
|
||||
<view class="m-t-10rpx second-text-28">
|
||||
<text>营业时间</text>
|
||||
<text class="m-l-10rpx">
|
||||
{{ v.jobStartTime }}
|
||||
~
|
||||
{{ v.jobEndTime }}
|
||||
</text>
|
||||
<view class="second-text-24">{{ v.phone }}</view>
|
||||
<view class="second-text-24">
|
||||
<view 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>
|
||||
|
||||
@@ -172,11 +172,13 @@ const doFreeze = async () => {
|
||||
<text class="sub-text-40 color-red!"> ¥{{ hooks.useMoney(v.balance) }} </text>
|
||||
</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.walletTypeUniqueCode == 1 && !v.cardNumber" class="botder_btn" @tap.stop="openBindDialog(v)">绑定</view> -->
|
||||
<view v-if="v.walletTypeUniqueCode == 1 && v.cardNumber && v.isFreeze != 1" class="botder_btn" @tap.stop="openFreezeDialog(v)">
|
||||
申请冻结
|
||||
</view>
|
||||
<view class="botder_btn" @tap.stop="router.jump('/pages/wallet/recharge', { id: v.id })"> 去充值 </view>
|
||||
<view v-if="v.walletTypeUniqueCode == 2" class="botder_btn" @tap.stop="router.jump('/pages/wallet/recharge', { id: v.id })">
|
||||
去充值
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
@@ -198,7 +200,7 @@ const doFreeze = async () => {
|
||||
</tm-form-item>
|
||||
</tm-form>
|
||||
<view class="h-50rpx" />
|
||||
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx sub-text-30 color-white!" @tap="doBind"> 绑定 </view>
|
||||
<!-- <view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx sub-text-30 color-white!" @tap="doBind">绑定</view> -->
|
||||
</tm-drawer>
|
||||
<tm-drawer
|
||||
z-index="100"
|
||||
@@ -216,7 +218,7 @@ const doFreeze = async () => {
|
||||
</tm-form-item>
|
||||
</tm-form>
|
||||
<view class="h-50rpx" />
|
||||
<view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx sub-text-30 color-white!" @tap="doFreeze"> 冻结 </view>
|
||||
<!-- <view class="bg-#0094ff p-y-20rpx text-center rounded-40rpx sub-text-30 color-white!" @tap="doFreeze">冻结</view> -->
|
||||
</tm-drawer>
|
||||
<tm-drawer
|
||||
z-index="100"
|
||||
@@ -233,5 +235,3 @@ const doFreeze = async () => {
|
||||
</view>
|
||||
</tm-drawer>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -7,8 +7,8 @@ export default {
|
||||
method: "POST",
|
||||
data,
|
||||
params: {
|
||||
pageNo: data.pageNo,
|
||||
pagesize: data.pagesize,
|
||||
current: data.current,
|
||||
size: data.size,
|
||||
},
|
||||
custom: {
|
||||
showLoading: false,
|
||||
|
||||
+62
-51
@@ -1,53 +1,64 @@
|
||||
import request from "@/sheep/utils/request";
|
||||
import request from "@/sheep/utils/request"
|
||||
|
||||
export default {
|
||||
// 获得支付订单
|
||||
getOrder: (params) => {
|
||||
return request({
|
||||
url: "/pay/order/get",
|
||||
method: "GET",
|
||||
params,
|
||||
});
|
||||
},
|
||||
// 提交支付订单
|
||||
submitOrder: (data) => {
|
||||
return request({
|
||||
url: "/pay/order/submit",
|
||||
method: "POST",
|
||||
data,
|
||||
});
|
||||
},
|
||||
// 创建硬件订单
|
||||
createHardwareOrder: (params) => {
|
||||
return request({
|
||||
url: "/hard/hard-order/app/create-order",
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
});
|
||||
},
|
||||
// 结算
|
||||
submitHardwareOrder: (data) => {
|
||||
return request({
|
||||
url: "/hardware/order/submit-order",
|
||||
method: "POST",
|
||||
data,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
});
|
||||
},
|
||||
// 退款
|
||||
refundHardwareOrder: (params) => {
|
||||
return request({
|
||||
url: "/hardware/order/refund",
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
// 获得支付订单
|
||||
getOrder: (params) => {
|
||||
return request({
|
||||
url: "/pay/order/get",
|
||||
method: "GET",
|
||||
params,
|
||||
})
|
||||
},
|
||||
// 提交支付订单
|
||||
submitOrder: (data) => {
|
||||
return request({
|
||||
url: "/pay/order/submit",
|
||||
method: "POST",
|
||||
data,
|
||||
})
|
||||
},
|
||||
// 创建硬件订单
|
||||
createHardwareOrder: (params) => {
|
||||
return request({
|
||||
url: "/hard/hard-order/app/create-order",
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
})
|
||||
},
|
||||
// 创建二维码订单
|
||||
createQrCodeOrder: (data): any => {
|
||||
return request({
|
||||
url: "/hard/hard-order/app/create-order-scan-qrcode",
|
||||
method: "POST",
|
||||
data,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
})
|
||||
},
|
||||
// 结算
|
||||
submitHardwareOrder: (data) => {
|
||||
return request({
|
||||
url: "/hardware/order/submit-order",
|
||||
method: "POST",
|
||||
data,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
})
|
||||
},
|
||||
// 退款
|
||||
refundHardwareOrder: (params) => {
|
||||
return request({
|
||||
url: "/hardware/order/refund",
|
||||
method: "GET",
|
||||
params,
|
||||
custom: {
|
||||
showLoading: false,
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -1,382 +1,363 @@
|
||||
<template>
|
||||
<view class="waterfalls-flow">
|
||||
<view
|
||||
v-for="(item, index) in data.column"
|
||||
:key="index"
|
||||
class="waterfalls-flow-column"
|
||||
:id="`waterfalls_flow_column_${index + 1}`"
|
||||
:msg="msg"
|
||||
:style="{ width: w, 'margin-left': index == 0 ? 0 : m }"
|
||||
>
|
||||
<view
|
||||
:class="['column-value', { 'column-value-show': item2.o }]"
|
||||
v-for="(item2, index2) in columnValue(index)"
|
||||
:key="index2"
|
||||
:style="[s1]"
|
||||
@click.stop="wapperClick(item2)"
|
||||
>
|
||||
<view class="inner" v-if="data.seat == 1">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- #ifdef VUE2 -->
|
||||
<slot name="slot{{item2.index}}"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef VUE3 -->
|
||||
<slot :name="`slot${item2.index}`"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<slot v-bind="item2"></slot>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<image
|
||||
:class="[
|
||||
'img',
|
||||
{
|
||||
'img-hide':
|
||||
item2[hideImageKey] == true || item2[hideImageKey] == 1,
|
||||
},
|
||||
{ 'img-error': !item2[data.imageKey] },
|
||||
]"
|
||||
:src="item2[data.imageKey]"
|
||||
mode="widthFix"
|
||||
@load="imgLoad(item2, index + 1)"
|
||||
@error="imgError(item2, index + 1)"
|
||||
@click.stop="imageClick(item2)"
|
||||
></image>
|
||||
<view class="inner" v-if="data.seat == 2">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- #ifdef VUE2 -->
|
||||
<slot name="slot{{item2.index}}"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef VUE3 -->
|
||||
<slot :name="`slot${item2.index}`"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<slot v-bind="item2"></slot>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="waterfalls-flow">
|
||||
<view
|
||||
v-for="(item, index) in data.column"
|
||||
:key="index"
|
||||
class="waterfalls-flow-column"
|
||||
:id="`waterfalls_flow_column_${index + 1}`"
|
||||
:msg="msg"
|
||||
:style="{ width: w, 'margin-left': index == 0 ? 0 : m }"
|
||||
>
|
||||
<view
|
||||
:class="['column-value', { 'column-value-show': item2.o }]"
|
||||
v-for="(item2, index2) in columnValue(index)"
|
||||
:key="index2"
|
||||
:style="[s1]"
|
||||
@click.stop="wapperClick(item2)"
|
||||
>
|
||||
<view class="inner" v-if="data.seat == 1">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- #ifdef VUE2 -->
|
||||
<slot name="slot{{item2.index}}"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef VUE3 -->
|
||||
<slot :name="`slot${item2.index}`"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<slot v-bind="item2"></slot>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<image
|
||||
:class="[
|
||||
'img',
|
||||
{
|
||||
'img-hide': item2[hideImageKey] == true || item2[hideImageKey] == 1,
|
||||
},
|
||||
{ 'img-error': !item2[data.imageKey] },
|
||||
]"
|
||||
:src="item2[data.imageKey]"
|
||||
mode="widthFix"
|
||||
@load="imgLoad(item2, index + 1)"
|
||||
@error="imgError(item2, index + 1)"
|
||||
@click.stop="imageClick(item2)"
|
||||
></image>
|
||||
<view class="inner" v-if="data.seat == 2">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- #ifdef VUE2 -->
|
||||
<slot name="slot{{item2.index}}"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef VUE3 -->
|
||||
<slot :name="`slot${item2.index}`"></slot>
|
||||
<!-- #endif -->
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<slot v-bind="item2"></slot>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
modelValue: Array,
|
||||
column: {
|
||||
// 列的数量
|
||||
type: [String, Number],
|
||||
default: 2,
|
||||
},
|
||||
maxColumn: {
|
||||
// 最大列数
|
||||
type: [String, Number],
|
||||
default: 5,
|
||||
},
|
||||
columnSpace: {
|
||||
// 列之间的间距 百分比
|
||||
type: [String, Number],
|
||||
default: 2,
|
||||
},
|
||||
imageKey: {
|
||||
// 图片key
|
||||
type: [String],
|
||||
default: "image",
|
||||
},
|
||||
hideImageKey: {
|
||||
// 隐藏图片key
|
||||
type: [String],
|
||||
default: "hide",
|
||||
},
|
||||
seat: {
|
||||
// 文本的位置,1图片之上 2图片之下
|
||||
type: [String, Number],
|
||||
default: 2,
|
||||
},
|
||||
listStyle: {
|
||||
// 单个展示项的样式:eg:{'background':'red'}
|
||||
type: Object,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: {
|
||||
list: this.modelValue ? this.modelValue : [],
|
||||
column: this.column < 2 ? 2 : this.column,
|
||||
columnSpace: this.columnSpace <= 5 ? this.columnSpace : 5,
|
||||
imageKey: this.imageKey,
|
||||
seat: this.seat,
|
||||
},
|
||||
msg: 0,
|
||||
listInitStyle: {
|
||||
"border-radius": "12rpx",
|
||||
"margin-bottom": "20rpx",
|
||||
"background-color": "#fff",
|
||||
},
|
||||
adds: [], //预置数据
|
||||
isLoaded: true,
|
||||
curIndex: 0,
|
||||
isRefresh: true,
|
||||
flag: false,
|
||||
refreshDatas: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 计算列宽
|
||||
w() {
|
||||
const column_rate = `${100 / this.data.column - +this.data.columnSpace}%`;
|
||||
return column_rate;
|
||||
},
|
||||
// 计算margin
|
||||
m() {
|
||||
const column_margin = `${
|
||||
(100 -
|
||||
(100 / this.data.column - +this.data.columnSpace).toFixed(5) *
|
||||
this.data.column) /
|
||||
(this.data.column - 1)
|
||||
}%`;
|
||||
return column_margin;
|
||||
},
|
||||
// list样式
|
||||
s1() {
|
||||
return { ...this.listInitStyle, ...this.listStyle };
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// 初始化
|
||||
this.refresh();
|
||||
},
|
||||
methods: {
|
||||
// 预加载图片
|
||||
loadImages(idx = 0) {
|
||||
let count = 0;
|
||||
const newList = this.data.list.filter((item, index) => index >= idx);
|
||||
for (let i = 0; i < newList.length; i++) {
|
||||
// #ifndef APP-PLUS
|
||||
uni.getImageInfo({
|
||||
src: `${newList[i][this.imageKey]}.jpg`,
|
||||
complete: (res) => {
|
||||
count++;
|
||||
if (count == newList.length) this.initValue(idx);
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
plus.io.getImageInfo({
|
||||
src: `${newList[i][this.imageKey]}.jpg`,
|
||||
complete: (res) => {
|
||||
count++;
|
||||
if (count == newList.length) this.initValue(idx);
|
||||
},
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
// 刷新
|
||||
refresh() {
|
||||
if (!this.isLoaded) {
|
||||
this.refreshDatas = this.modelValue;
|
||||
return false;
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.refreshDatas = [];
|
||||
this.isRefresh = true;
|
||||
this.adds = [];
|
||||
this.data.list = this.modelValue ? this.modelValue : [];
|
||||
this.data.column =
|
||||
this.column < 2
|
||||
? 2
|
||||
: this.column >= this.maxColumn
|
||||
? this.maxColumn
|
||||
: this.column;
|
||||
this.data.columnSpace = this.columnSpace <= 5 ? this.columnSpace : 5;
|
||||
this.data.imageKey = this.imageKey;
|
||||
this.data.seat = this.seat;
|
||||
this.curIndex = 0;
|
||||
// 每列的数据初始化
|
||||
for (let i = 1; i <= this.data.column; i++) {
|
||||
this.data[`column_${i}_values`] = [];
|
||||
this.msg++;
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.initValue(this.curIndex, "refresh==>");
|
||||
});
|
||||
}, 1);
|
||||
},
|
||||
columnValue(index) {
|
||||
return this.data[`column_${index + 1}_values`];
|
||||
},
|
||||
change(newValue) {
|
||||
for (let i = 0; i < this.data.list.length; i++) {
|
||||
const cv = this.data[`column_${this.data.list[i].column}_values`];
|
||||
for (let j = 0; j < cv.length; j++) {
|
||||
if (newValue[i] && i === cv[j].index) {
|
||||
this.data[`column_${this.data.list[i].column}_values`][j] =
|
||||
Object.assign(cv[j], newValue[i]);
|
||||
this.msg++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
getMin(a, s) {
|
||||
let m = a[0][s];
|
||||
let mo = a[0];
|
||||
for (var i = a.length - 1; i >= 0; i--) {
|
||||
if (a[i][s] < m) {
|
||||
m = a[i][s];
|
||||
}
|
||||
}
|
||||
mo = a.filter((i) => i[s] == m);
|
||||
return mo[0];
|
||||
},
|
||||
// 计算每列的高度
|
||||
getMinColumnHeight() {
|
||||
return new Promise((resolve) => {
|
||||
const heightArr = [];
|
||||
for (let i = 1; i <= this.data.column; i++) {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query
|
||||
.select(`#waterfalls_flow_column_${i}`)
|
||||
.boundingClientRect((data) => {
|
||||
heightArr.push({ column: i, height: data.height });
|
||||
})
|
||||
.exec(() => {
|
||||
if (this.data.column <= heightArr.length) {
|
||||
resolve(this.getMin(heightArr, "height"));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
async initValue(i, from) {
|
||||
this.isLoaded = false;
|
||||
if (i >= this.data.list.length || this.refreshDatas.length) {
|
||||
this.msg++;
|
||||
this.loaded();
|
||||
return false;
|
||||
}
|
||||
const minHeightRes = await this.getMinColumnHeight();
|
||||
const c = this.data[`column_${minHeightRes.column}_values`];
|
||||
this.data.list[i].column = minHeightRes.column;
|
||||
c.push({ ...this.data.list[i], cIndex: c.length, index: i, o: 0 });
|
||||
this.msg++;
|
||||
},
|
||||
// 图片加载完成
|
||||
imgLoad(item, c) {
|
||||
const i = item.index;
|
||||
item.o = 1;
|
||||
this.$set(
|
||||
this.data[`column_${c}_values`],
|
||||
item.cIndex,
|
||||
JSON.parse(JSON.stringify(item))
|
||||
);
|
||||
this.initValue(i + 1);
|
||||
},
|
||||
// 图片加载失败
|
||||
imgError(item, c) {
|
||||
const i = item.index;
|
||||
item.o = 1;
|
||||
item[this.data.imageKey] = null;
|
||||
this.$set(
|
||||
this.data[`column_${c}_values`],
|
||||
item.cIndex,
|
||||
JSON.parse(JSON.stringify(item))
|
||||
);
|
||||
this.initValue(i + 1);
|
||||
},
|
||||
// 渲染结束
|
||||
loaded() {
|
||||
if (this.refreshDatas.length) {
|
||||
this.isLoaded = true;
|
||||
this.refresh();
|
||||
return false;
|
||||
}
|
||||
this.curIndex = this.data.list.length;
|
||||
if (this.adds.length) {
|
||||
this.data.list = this.adds[0];
|
||||
this.adds.splice(0, 1);
|
||||
this.initValue(this.curIndex);
|
||||
} else {
|
||||
if (this.data.list.length) this.$emit("loaded");
|
||||
this.isLoaded = true;
|
||||
this.isRefresh = false;
|
||||
}
|
||||
},
|
||||
// 单项点击事件
|
||||
wapperClick(item) {
|
||||
this.$emit("wapperClick", item);
|
||||
},
|
||||
// 图片点击事件
|
||||
imageClick(item) {
|
||||
this.$emit("imageClick", item);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
modelValue: {
|
||||
deep: true,
|
||||
handler(newValue, oldValue) {
|
||||
setTimeout(() => {
|
||||
this.$nextTick(() => {
|
||||
if (this.isRefresh) return false;
|
||||
if (this.isLoaded) {
|
||||
this.refresh();
|
||||
if (newValue.length <= this.curIndex)
|
||||
return this.change(newValue);
|
||||
this.data.list = newValue;
|
||||
this.$nextTick(() => {
|
||||
this.initValue(this.curIndex, "watch==>");
|
||||
});
|
||||
} else {
|
||||
this.adds.push(newValue);
|
||||
}
|
||||
});
|
||||
}, 10);
|
||||
},
|
||||
},
|
||||
column(newValue) {
|
||||
this.refresh();
|
||||
},
|
||||
},
|
||||
};
|
||||
props: {
|
||||
modelValue: Array,
|
||||
column: {
|
||||
// 列的数量
|
||||
type: [String, Number],
|
||||
default: 2,
|
||||
},
|
||||
maxColumn: {
|
||||
// 最大列数
|
||||
type: [String, Number],
|
||||
default: 5,
|
||||
},
|
||||
columnSpace: {
|
||||
// 列之间的间距 百分比
|
||||
type: [String, Number],
|
||||
default: 2,
|
||||
},
|
||||
imageKey: {
|
||||
// 图片key
|
||||
type: [String],
|
||||
default: "image",
|
||||
},
|
||||
hideImageKey: {
|
||||
// 隐藏图片key
|
||||
type: [String],
|
||||
default: "hide",
|
||||
},
|
||||
seat: {
|
||||
// 文本的位置,1图片之上 2图片之下
|
||||
type: [String, Number],
|
||||
default: 2,
|
||||
},
|
||||
listStyle: {
|
||||
// 单个展示项的样式:eg:{'background':'red'}
|
||||
type: Object,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: {
|
||||
list: this.modelValue ? this.modelValue : [],
|
||||
column: this.column < 2 ? 2 : this.column,
|
||||
columnSpace: this.columnSpace <= 5 ? this.columnSpace : 5,
|
||||
imageKey: this.imageKey,
|
||||
seat: this.seat,
|
||||
},
|
||||
msg: 0,
|
||||
listInitStyle: {
|
||||
"border-radius": "12rpx",
|
||||
"margin-bottom": "20rpx",
|
||||
"background-color": "#fff",
|
||||
},
|
||||
adds: [], //预置数据
|
||||
isLoaded: true,
|
||||
curIndex: 0,
|
||||
isRefresh: true,
|
||||
flag: false,
|
||||
refreshDatas: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算列宽
|
||||
w() {
|
||||
const column_rate = `${100 / this.data.column - +this.data.columnSpace}%`
|
||||
return column_rate
|
||||
},
|
||||
// 计算margin
|
||||
m() {
|
||||
const column_margin = `${
|
||||
(100 - (100 / this.data.column - +this.data.columnSpace).toFixed(5) * this.data.column) / (this.data.column - 1)
|
||||
}%`
|
||||
return column_margin
|
||||
},
|
||||
// list样式
|
||||
s1() {
|
||||
return { ...this.listInitStyle, ...this.listStyle }
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// 初始化
|
||||
this.refresh()
|
||||
},
|
||||
methods: {
|
||||
// 预加载图片
|
||||
loadImages(idx = 0) {
|
||||
let count = 0
|
||||
const newList = this.data.list.filter((item, index) => index >= idx)
|
||||
for (let i = 0; i < newList.length; i++) {
|
||||
// #ifndef APP-PLUS
|
||||
uni.getImageInfo({
|
||||
src: `${newList[i][this.imageKey]}.jpg`,
|
||||
complete: (res) => {
|
||||
count++
|
||||
if (count == newList.length) this.initValue(idx)
|
||||
},
|
||||
})
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
plus.io.getImageInfo({
|
||||
src: `${newList[i][this.imageKey]}.jpg`,
|
||||
complete: (res) => {
|
||||
count++
|
||||
if (count == newList.length) this.initValue(idx)
|
||||
},
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
// 刷新
|
||||
refresh() {
|
||||
if (!this.isLoaded) {
|
||||
this.refreshDatas = this.modelValue
|
||||
return false
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.refreshDatas = []
|
||||
this.isRefresh = true
|
||||
this.adds = []
|
||||
this.data.list = this.modelValue ? this.modelValue : []
|
||||
this.data.column = this.column < 2 ? 2 : this.column >= this.maxColumn ? this.maxColumn : this.column
|
||||
this.data.columnSpace = this.columnSpace <= 5 ? this.columnSpace : 5
|
||||
this.data.imageKey = this.imageKey
|
||||
this.data.seat = this.seat
|
||||
this.curIndex = 0
|
||||
// 每列的数据初始化
|
||||
for (let i = 1; i <= this.data.column; i++) {
|
||||
this.data[`column_${i}_values`] = []
|
||||
this.msg++
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.initValue(this.curIndex, "refresh==>")
|
||||
})
|
||||
}, 1)
|
||||
},
|
||||
columnValue(index) {
|
||||
return this.data[`column_${index + 1}_values`]
|
||||
},
|
||||
change(newValue) {
|
||||
for (let i = 0; i < this.data.list.length; i++) {
|
||||
const cv = this.data[`column_${this.data.list[i].column}_values`]
|
||||
for (let j = 0; j < cv.length; j++) {
|
||||
if (newValue[i] && i === cv[j].index) {
|
||||
this.data[`column_${this.data.list[i].column}_values`][j] = Object.assign(cv[j], newValue[i])
|
||||
this.msg++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
getMin(a, s) {
|
||||
let m = a[0][s]
|
||||
let mo = a[0]
|
||||
for (var i = a.length - 1; i >= 0; i--) {
|
||||
if (a[i][s] < m) {
|
||||
m = a[i][s]
|
||||
}
|
||||
}
|
||||
mo = a.filter((i) => i[s] == m)
|
||||
return mo[0]
|
||||
},
|
||||
// 计算每列的高度
|
||||
getMinColumnHeight() {
|
||||
return new Promise((resolve) => {
|
||||
const heightArr = []
|
||||
for (let i = 1; i <= this.data.column; i++) {
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query
|
||||
.select(`#waterfalls_flow_column_${i}`)
|
||||
.boundingClientRect((data) => {
|
||||
heightArr.push({ column: i, height: data.height })
|
||||
})
|
||||
.exec(() => {
|
||||
if (this.data.column <= heightArr.length) {
|
||||
resolve(this.getMin(heightArr, "height"))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
async initValue(i, from) {
|
||||
this.isLoaded = false
|
||||
if (i >= this.data.list.length || this.refreshDatas.length) {
|
||||
this.msg++
|
||||
this.loaded()
|
||||
return false
|
||||
}
|
||||
const minHeightRes = await this.getMinColumnHeight()
|
||||
const c = this.data[`column_${minHeightRes.column}_values`]
|
||||
this.data.list[i].column = minHeightRes.column
|
||||
c.push({ ...this.data.list[i], cIndex: c.length, index: i, o: 0 })
|
||||
this.msg++
|
||||
},
|
||||
// 图片加载完成
|
||||
imgLoad(item, c) {
|
||||
const i = item.index
|
||||
item.o = 1
|
||||
this.$set(this.data[`column_${c}_values`], item.cIndex, JSON.parse(JSON.stringify(item)))
|
||||
this.initValue(i + 1)
|
||||
},
|
||||
// 图片加载失败
|
||||
imgError(item, c) {
|
||||
const i = item.index
|
||||
item.o = 1
|
||||
item[this.data.imageKey] = null
|
||||
this.$set(this.data[`column_${c}_values`], item.cIndex, JSON.parse(JSON.stringify(item)))
|
||||
this.initValue(i + 1)
|
||||
},
|
||||
// 渲染结束
|
||||
loaded() {
|
||||
if (this.refreshDatas.length) {
|
||||
this.isLoaded = true
|
||||
this.refresh()
|
||||
return false
|
||||
}
|
||||
this.curIndex = this.data.list.length
|
||||
if (this.adds.length) {
|
||||
this.data.list = this.adds[0]
|
||||
this.adds.splice(0, 1)
|
||||
this.initValue(this.curIndex)
|
||||
} else {
|
||||
if (this.data.list.length) this.$emit("loaded")
|
||||
this.isLoaded = true
|
||||
this.isRefresh = false
|
||||
}
|
||||
},
|
||||
// 单项点击事件
|
||||
wapperClick(item) {
|
||||
this.$emit("wapperClick", item)
|
||||
},
|
||||
// 图片点击事件
|
||||
imageClick(item) {
|
||||
this.$emit("imageClick", item)
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
modelValue: {
|
||||
deep: true,
|
||||
handler(newValue, oldValue) {
|
||||
setTimeout(() => {
|
||||
this.$nextTick(() => {
|
||||
if (this.isRefresh) return false
|
||||
if (this.isLoaded) {
|
||||
this.refresh()
|
||||
if (newValue.length <= this.curIndex) return this.change(newValue)
|
||||
this.data.list = newValue
|
||||
this.$nextTick(() => {
|
||||
this.initValue(this.curIndex, "watch==>")
|
||||
})
|
||||
} else {
|
||||
this.adds.push(newValue)
|
||||
}
|
||||
})
|
||||
}, 10)
|
||||
},
|
||||
},
|
||||
column(newValue) {
|
||||
this.refresh()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.waterfalls-flow {
|
||||
overflow: hidden;
|
||||
overflow: hidden;
|
||||
|
||||
&-column {
|
||||
float: left;
|
||||
}
|
||||
&-column {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
.column-value {
|
||||
width: 100%;
|
||||
font-size: 0;
|
||||
overflow: hidden;
|
||||
transition: opacity 0.4s;
|
||||
opacity: 0;
|
||||
width: 100%;
|
||||
font-size: 0;
|
||||
overflow: hidden;
|
||||
transition: opacity 0.4s;
|
||||
opacity: 0;
|
||||
|
||||
&-show {
|
||||
opacity: 1;
|
||||
}
|
||||
&-show {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.inner {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.inner {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
.img {
|
||||
width: 100%;
|
||||
|
||||
&-hide {
|
||||
display: none;
|
||||
}
|
||||
&-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-error {
|
||||
background: #f2f2f2
|
||||
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAiAQMAAAAatXkPAAAABlBMVEUAAADMzMzIT8AyAAAAAXRSTlMAQObYZgAAAIZJREFUCNdlzjEKwkAUBNAfEGyCuYBkLyLuxRYW2SKlV1JSeA2tUiZg4YrLjv9PGsHqNTPMSAQuyAJgRDHSyvBPwtZoSJXakeJI9iuRLGDygdl6V0yKDtyMAeMPZySj8yfD+UapvRPj2JOwkyAooSV5IwdDjPdCPspe8LyTl9IKJvDETKKRv6vnlUasgg0fAAAAAElFTkSuQmCC)
|
||||
no-repeat center center;
|
||||
}
|
||||
}
|
||||
&-error {
|
||||
background: #f2f2f2
|
||||
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAiAQMAAAAatXkPAAAABlBMVEUAAADMzMzIT8AyAAAAAXRSTlMAQObYZgAAAIZJREFUCNdlzjEKwkAUBNAfEGyCuYBkLyLuxRYW2SKlV1JSeA2tUiZg4YrLjv9PGsHqNTPMSAQuyAJgRDHSyvBPwtZoSJXakeJI9iuRLGDygdl6V0yKDtyMAeMPZySj8yfD+UapvRPj2JOwkyAooSV5IwdDjPdCPspe8LyTl9IKJvDETKKRv6vnlUasgg0fAAAAAElFTkSuQmCC)
|
||||
no-repeat center center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,8 @@
|
||||
// https://pinia.vuejs.org/
|
||||
import { createPinia } from "pinia"
|
||||
|
||||
// 创建
|
||||
const pinia = createPinia()
|
||||
|
||||
// 导出
|
||||
export default pinia
|
||||
@@ -0,0 +1,14 @@
|
||||
import { defineStore } from "pinia"
|
||||
|
||||
export const usePayStore = defineStore("pay", {
|
||||
state: (): { payData: { id?: string; name?: string } } => {
|
||||
return {
|
||||
payData: {},
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setPayData(data: any) {
|
||||
this.payData = data
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* 显示价格把分转换到元
|
||||
* @param price
|
||||
* @returns
|
||||
*/
|
||||
export function displayPrice(price: any, suffix: string = "元", fixed = 2) {
|
||||
if (typeof price === "undefined") return "0.00" + suffix
|
||||
const parsedNumber = typeof price === "string" ? parseFloat(price) : price
|
||||
return (parsedNumber / 100.0).toFixed(fixed) + suffix
|
||||
}
|
||||
|
||||
/**
|
||||
* 把显示价格改为分
|
||||
* @param price
|
||||
* @returns
|
||||
*/
|
||||
export const storePrice = (num: number | string | undefined) => {
|
||||
if (typeof num === "undefined") return 0
|
||||
const parsedNumber = typeof num === "string" ? parseFloat(num) : num
|
||||
return Math.round(parsedNumber * 100)
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
export default () => import.meta.env.VITE_DEV_ENV === "dev"
|
||||
// export default () => process.env.NODE_ENV === "development"
|
||||
// export default () => import.meta.env.VITE_DEV_ENV === "dev"
|
||||
export default () => process.env.NODE_ENV === "development"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Reference in new issue
Block a user