hookehuyr

refactor(icon): 替换NutIcon为IconFont组件并优化数据默认值处理

- 将所有页面中的NutIcon组件替换为IconFont组件
- 为API返回数据添加默认空数组处理
- 更新README文档说明项目功能和技术栈
- 修复部分页面样式问题
## 项目介绍
基于Taro4的微信小程序模版,集成了常用的功能,如登录、注册、列表、详情、购物车等。
本项目是将原有H5预约系统迁移至微信小程序的实现。基于 Taro4 + Vue3 + NutUI 开发,保留了原有的功能和UI风格。
## 功能模块
1. **预约流程**
* 日期与时间段选择 (`pages/booking/index`)
* 预约信息确认与提交 (`pages/submit/index`)
* 预约记录查看 (`pages/bookingList/index`)
* 预约详情 (`pages/bookingDetail/index`)
2. **参观者管理**
* 参观者列表 (`pages/visitorList/index`)
* 添加/编辑参观者 (`pages/addVisitor/index`)
* 支持身份证号校验与脱敏显示
3. **个人中心**
* 预约码展示 (`pages/bookingCode/index`)
* 我的页面 (`pages/me/index`)
* 邀请码/证件号查询 (`pages/search/index`)
4. **公共功能**
* 全局路由封装 (`hooks/useGo`)
* API 请求封装 (`utils/request`, `api/index`)
* 登录授权流程 (`pages/auth/index`)
## 技术栈
- Taro4
- Vue3
- TypeScript
- Pinia
- Less
* **框架**: Taro 4.x
* **UI库**: NutUI 4.x (Vue3)
* **语言**: JavaScript (Vue3 Setup 语法糖)
* **样式**: Less + TailwindCSS (部分)
* **状态管理**: Pinia
* **路由**: Taro Router + 自定义 Hooks
## 项目结构
- src
- api:请求接口
- assets:静态资源
- components:全局组件
- config:项目配置
- pages:页面
- stores:状态管理
- utils:工具函数
- app.config.js:项目配置
- app.js:应用入口
- app.less:全局样式
- taro.config.js:Taro配置
- tsconfig.json:TypeScript配置
- package.json:依赖配置
* `src/api`: 接口定义
* `src/assets`: 图片等静态资源
* `src/components`: 公共组件 (qrCode, qrCodeSearch, reserveCard等)
* `src/pages`: 页面文件
* `src/hooks`: 组合式函数 (useGo等)
* `src/utils`: 工具函数 (request, tools等)
## 项目运行
1. 安装依赖
```bash
npm install
```
1. 安装依赖
```bash
pnpm install
```
2. 运行项目
2. 运行开发环境
```bash
pnpm dev:weapp
```
```bash
npm run dev:weapp
```
3. 打包构建
```bash
pnpm build:weapp
```
3. 打包项目
## 优化建议 (TODO)
```bash
npm run build:weapp
```
* [ ] 小程序授权流程有问题
* [ ] 完善支付流程(目前为模拟/H5跳转)
* [ ] 优化图片资源加载(考虑使用 CDN 或分包)
* [ ] 增强网络请求的错误处理与重试机制
* [ ] 补充单元测试
......
......@@ -14,7 +14,6 @@ declare module 'vue' {
NutDatePicker: typeof import('@nutui/nutui-taro')['DatePicker']
NutForm: typeof import('@nutui/nutui-taro')['Form']
NutFormItem: typeof import('@nutui/nutui-taro')['FormItem']
NutIcon: typeof import('@nutui/nutui-taro')['Icon']
NutInput: typeof import('@nutui/nutui-taro')['Input']
NutPopup: typeof import('@nutui/nutui-taro')['Popup']
Picker: typeof import('./src/components/time-picker-data/picker.vue')['default']
......
/*
* @Date: 2023-08-24 09:42:27
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-01-29 17:26:42
* @LastEditTime: 2026-01-06 21:08:32
* @FilePath: /xyxBooking-weapp/src/api/index.js
* @Description: 文件描述
*/
......@@ -100,55 +100,64 @@ export const payCallbackAPI = (params) => fn(fetch.post(Api.PAY_CALLBACK, params
export const billInfoAPI = (params) => fn(fetch.get(Api.BILL_INFO, params));
/**
* @description: 扫码核销二维码列表
* @returns
* @description: 预约单详情,参观者列表 - 免授权接口
* @param {String} pay_id 订单id
* @returns {String}
*/
export const onAuthBillInfoAPI = (params) => fn(fetch.get(Api.ON_AUTH_BILL_INFO, params));
/**
* @description: 预约码列表
* @returns {String}
*/
export const qrcodeListAPI = (params) => fn(fetch.get(Api.QRCODE_LIST, params));
/**
* @description: 扫码核销二维码状态
* @returns
* @description: 二维码使用状态
* @param {String} qr_code 二维码编号
* @returns {String} status 二维码状态 1=未激活(未支付),3=待使用(已支付),5=被取消,7=已使用
*/
export const qrcodeStatusAPI = (params) => fn(fetch.get(Api.QRCODE_STATUS, params));
/**
* @description: 预约单列表
* @returns
* @param {String}
* @returns {String}
*/
export const billListAPI = (params) => fn(fetch.get(Api.BILL_LIST, params));
/**
* @description: 退款
* @returns
* @description: 取消预约
* @param {String} pay_id
* @returns {String}
*/
export const icbcRefundAPI = (params) => fn(fetch.post(Api.ICBC_REFUND, params));
/**
* @description: 支付前准备(获取支付参数等)
* @returns
* @description: 预约单的参观者列表
* @param {String}
* @returns {String}
*/
export const billPrepareAPI = (params) => fn(fetch.post(Api.BILL_PREPARE, params));
export const billPersonAPI = (params) => fn(fetch.get(Api.BILL_PREPARE, params));
/**
* @description: 支付状态查询
* @returns
* 接口废弃
* @description: 刷新预约单支付状态
* @param {String}
* @returns {String}
*/
export const billPayStatusAPI = (params) => fn(fetch.get(Api.BILL_PAY_STATUS, params));
/**
* @description: 证件号查询二维码
* @returns
* @description: 身份证查询预约码
* @param {String}
* @returns {String}
*/
export const queryQrCodeAPI = (params) => fn(fetch.get(Api.QUERY_QR_CODE, params));
/**
* @description: 订单查询
* @returns
* @description: 查询订单号
* @param {String}
* @returns {String}
*/
export const icbcOrderQryAPI = (params) => fn(fetch.get(Api.ICBC_ORDER_QRY, params));
/**
* @description: 授权前订单详情查询
* @returns
*/
export const onAuthBillInfoAPI = (params) => fn(fetch.get(Api.ON_AUTH_BILL_INFO, params));
......
......@@ -15,7 +15,7 @@
<view class="booking-num">
<view class="num-body van-ellipsis">预约人数:<text>{{ reserve_info.total_qty }} 人</text>&nbsp;<text>({{ reserve_info.person_name }})</text></view>
<view v-if="(reserve_info.status === CodeStatus.SUCCESS || reserve_info.status === CodeStatus.USED || reserve_info.status === CodeStatus.CANCEL)">
<nut-icon name="rect-right" />
<IconFont name="rect-right" />
</view>
</view>
<view class="booking-price">支付金额:<text>¥ {{ reserve_info.total_amt }}</text></view>
......@@ -29,6 +29,7 @@
<script setup>
import { computed } from 'vue'
import { IconFont } from '@nutui/icons-vue-taro'
import { useGo } from '@/hooks/useGo'
const go = useGo();
......@@ -109,7 +110,7 @@ const goToDetail = (item) => {
padding: 1rem;
margin-bottom: 1rem;
box-shadow: 0rem 0rem 0.92rem 0rem rgba(106,106,106,0.1);
.booking-list-item-header {
display: flex;
justify-content: space-between;
......@@ -120,13 +121,13 @@ const goToDetail = (item) => {
font-size: 1rem;
font-weight: bold;
color: #333;
.status {
font-size: 0.85rem;
font-weight: normal;
padding: 2px 6px;
border-radius: 4px;
&.success {
color: #A67939;
background-color: #FBEEDC;
......@@ -141,7 +142,7 @@ const goToDetail = (item) => {
}
}
}
.booking-list-item-body {
.booking-num {
display: flex;
......@@ -149,7 +150,7 @@ const goToDetail = (item) => {
align-items: center;
margin-bottom: 0.5rem;
color: #666;
.num-body {
span, text {
color: #A67939;
......
......@@ -18,11 +18,11 @@
<nut-input v-model="id_number" placeholder="请输入参观者证件号" type="idcard" />
</nut-form-item>
</nut-form>
<view style="padding: 1rem;">
<nut-button type="primary" block color="#A67939" @click="save">保存</nut-button>
</view>
<view v-if="visitorList.length" class="history-list">
<view class="title">历史参观者</view>
<view v-for="(item, index) in visitorList" :key="index" class="item">
......@@ -66,7 +66,7 @@ const formatId = (id) => replaceMiddleCharacters(id);
const loadList = async () => {
const { code, data } = await personListAPI({});
if (code) {
visitorList.value = data;
visitorList.value = data || [];
}
}
......@@ -79,7 +79,7 @@ const save = async () => {
Taro.showToast({ title: '请输入正确的身份证号', icon: 'none' });
return;
}
Taro.showLoading({ title: '保存中' });
const { code, msg } = await addPersonAPI({
name: name.value,
......@@ -87,7 +87,7 @@ const save = async () => {
id_number: id_number.value
});
Taro.hideLoading();
if (code) {
Taro.showToast({ title: '添加成功' });
name.value = '';
......@@ -123,12 +123,12 @@ useDidShow(() => {
min-height: 100vh;
background-color: #F6F6F6;
padding-top: 1px;
.history-list {
margin-top: 1rem;
background-color: #FFF;
padding: 1rem;
.title {
font-size: 1rem;
color: #333;
......@@ -136,18 +136,18 @@ useDidShow(() => {
border-left: 3px solid #A67939;
padding-left: 0.5rem;
}
.item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 0;
border-bottom: 1px solid #EEE;
&:last-child {
border-bottom: none;
}
.info {
.name {
font-size: 1rem;
......@@ -159,7 +159,7 @@ useDidShow(() => {
color: #999;
}
}
.action {
color: #FF0000;
font-size: 0.9rem;
......
......@@ -109,7 +109,7 @@ useDidShow(async () => {
const { code, data } = await canReserveDateListAPI({ month: `${raw_date.getFullYear()}-${(raw_date.getMonth() + 1).toString().padStart(2, '0')}` });
if (code) {
// 日期列表
dates_list.value = data;
dates_list.value = data || [];
// 今日之前都不可约
dates_list.value.forEach((date) => {
if (dayjs(date.month_date).isBefore(dayjs())) {
......@@ -250,12 +250,12 @@ const onConfirm = async ({ selectedValue, selectedOptions }) => { // 选择日æœ
// selectedOptions 是选项对象数组
// year-month 模式下 selectedValue 可能是 [year, month]
// 实际上 NutUI DatePicker confirm 事件参数:{ selectedValue, selectedOptions }
showPicker.value = false;
// selectedValue: ['2024', '02']
const [year, month] = selectedValue;
currentDateText.value = month;
// 清空选择
checked_day.value = '';
checked_time.value = -1;
......@@ -264,7 +264,7 @@ const onConfirm = async ({ selectedValue, selectedOptions }) => { // 选择日æœ
const { code, data } = await canReserveDateListAPI({ month: `${year}-${month}` });
if (code) {
// 日期列表
dates_list.value = data;
dates_list.value = data || [];
// 今日之前都不可约
dates_list.value.forEach((date) => {
if (dayjs(date.month_date).isBefore(dayjs())) {
......
......@@ -10,7 +10,7 @@
<view style="padding: 1rem;">
<qrCode></qrCode>
<view class="warning">
<view><nut-icon name="tips" />&nbsp;温馨提示</view>
<view><IconFont name="tips" />&nbsp;温馨提示</view>
<view style="margin-top: 0.5rem;">一人一码,扫码或识别身份证成功后进入</view>
<view style="height: 8rem;"></view>
</view>
......@@ -36,6 +36,7 @@
import { ref } from 'vue'
import Taro from '@tarojs/taro'
import qrCode from '@/components/qrCode';
import { IconFont } from '@nutui/icons-vue-taro'
import icon_3 from '@/assets/images/首页01@2x.png'
import icon_4 from '@/assets/images/二维码icon.png'
import icon_5 from '@/assets/images/我的01@2x.png'
......
......@@ -10,10 +10,10 @@
<view v-for="(item, index) in bookingList" :key="index">
<reserveCard :data="item" />
</view>
<view v-if="loading" style="text-align: center; color: #999; padding: 10px;">加载中...</view>
<view v-if="finished && bookingList.length > 0" style="text-align: center; color: #999; padding: 10px;">没有更多了</view>
<view v-if="!bookingList.length && finished" class="no-qrcode">
<image src="https://cdn.ipadbiz.cn/xys/booking/%E6%9A%82%E6%97%A0@2x.png" style="width: 10rem; height: 10rem;" />
<view class="no-qrcode-title">您还没有预约过参观</view>
......@@ -36,29 +36,30 @@ const finished = ref(false);
const loadData = async (isRefresh = false) => {
if (loading.value || (finished.value && !isRefresh)) return;
loading.value = true;
if (isRefresh) {
page.value = 1;
finished.value = false;
}
const { code, data } = await billListAPI({ page: page.value, row_num: limit.value });
loading.value = false;
if (code) {
data.forEach(item => {
const list = data || [];
list.forEach(item => {
item.booking_time = item && formatDatetime(item);
item.order_time = item.created_time ? item.created_time.slice(0, -3) : '';
});
if (isRefresh) {
bookingList.value = data;
bookingList.value = list;
} else {
bookingList.value = bookingList.value.concat(data);
bookingList.value = bookingList.value.concat(list);
}
if (data.length < limit.value) {
if (list.length < limit.value) {
finished.value = true;
} else {
page.value++;
......@@ -80,14 +81,14 @@ useReachBottom(() => {
padding: 1rem;
min-height: 100vh;
background-color: #F6F6F6;
.no-qrcode {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding-top: 5rem;
.no-qrcode-title {
color: #A67939;
font-size: 1.05rem;
......
......@@ -6,7 +6,7 @@
{{ item.name }}
</view>
<view>
<nut-icon name="rect-right" size="1.2rem" />
<IconFont name="rect-right" size="1.2rem" />
</view>
</view>
<view class="index-nav">
......@@ -30,6 +30,7 @@
import { ref } from 'vue'
import Taro from '@tarojs/taro'
import { useGo } from '@/hooks/useGo'
import { IconFont } from '@nutui/icons-vue-taro'
import icon_3 from '@/assets/images/首页01@2x.png'
import icon_4 from '@/assets/images/二维码icon.png'
import icon_5 from '@/assets/images/我的02@2x.png'
......
......@@ -17,7 +17,7 @@
</view>
<view style="color:#A67939; font-size: 0.95rem; text-align: center;">
<view>
<nut-icon name="tips" />&nbsp;温馨提示
<IconFont name="tips" />&nbsp;温馨提示
</view>
<view style="margin-top: 0.5rem;">获取参观码,扫码或识别身份证成功进闸机</view>
</view>
......@@ -40,6 +40,7 @@
<script setup>
import { ref } from 'vue'
import Taro from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro'
import qrCodeSearch from '@/components/qrCodeSearch';
import { useGo } from '@/hooks/useGo'
......@@ -87,13 +88,13 @@ const goToHome = () => {
padding: 1rem;
min-height: 100vh;
background-color: #F6F6F6;
.input-item {
background-color: #FFF;
padding: 1rem;
border-radius: 8px;
margin-bottom: 1rem;
view:first-child {
margin-bottom: 0.5rem;
font-weight: bold;
......@@ -103,7 +104,7 @@ const goToHome = () => {
padding: 0.5rem 0;
}
}
.save-wrapper {
margin-top: 2rem;
.save-btn {
......@@ -115,7 +116,7 @@ const goToHome = () => {
font-size: 1.1rem;
}
}
.success-btn {
position: fixed;
bottom: 2rem;
......@@ -123,7 +124,7 @@ const goToHome = () => {
left: 0;
display: flex;
justify-content: space-around;
.btn-item {
width: 40%;
text-align: center;
......@@ -131,19 +132,19 @@ const goToHome = () => {
border-radius: 8px;
font-size: 1.1rem;
}
.btn-left {
border: 1px solid #A67939;
color: #A67939;
background-color: #FFF;
}
.btn-right {
background-color: #A67939;
color: #FFF;
}
}
.logo {
position: absolute;
right: 0;
......
<!--
* @Date: 2024-01-15 16:25:51
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-01-30 15:18:58
* @FilePath: /xyxBooking-weapp/src/pages/submit/index.vue
* @LastEditTime: 2026-01-06 21:22:54
* @FilePath: /git/xyxBooking-weapp/src/pages/submit/index.vue
* @Description: 预约人员信息
-->
<template>
<view class="submit-page">
<view @tap="goToBooking" class="visit-time">
<view>参访时间</view>
<view><text style="font-size: 0.95rem;">{{ date }} {{ time }}</text>&nbsp;<nut-icon name="rect-right" /></view>
</view>
<view @tap="goToVisitor" class="add-visitors">
<view><nut-icon name="plus" /> 添加参观者</view>
</view>
<view v-if="visitorList.length" class="visitors-list">
<view v-for="(item, index) in visitorList" :key="index" @tap="addVisitor(item)" class="visitor-item">
<view class="submit-page">
<view @tap="goToBooking" class="visit-time">
<view>参访时间</view>
<view><text style="font-size: 0.95rem;">{{ date }} {{ time }}</text>&nbsp;<IconFont name="rect-right" /></view>
</view>
<view @tap="goToVisitor" class="add-visitors">
<view><IconFont name="plus" /> 添加参观者</view>
</view>
<view v-if="visitorList.length" class="visitors-list">
<view v-for="(item, index) in visitorList" :key="index" @tap="addVisitor(item)" class="visitor-item">
<view style="margin-right: 1rem;">
<image v-if="!checked_visitors.includes(item.id)" :src="icon_check1" style="width: 1.2rem; height: 1.2rem;" />
<image v-else :src="icon_check2" style="width: 1.2rem; height: 1.2rem;" />
......@@ -49,6 +49,7 @@
<script setup>
import { ref, computed } from 'vue'
import Taro, { useDidShow, useRouter as useTaroRouter } from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro'
import { useGo } from '@/hooks/useGo'
import icon_check1 from '@/assets/images/多选01@2x.png'
import icon_check2 from '@/assets/images/多选02@2x.png'
......@@ -118,24 +119,24 @@ const submitBtn = async () => {
} else {
// TAG: 提交订单跳转到支付页面
Taro.showLoading({ title: '提交中...' });
const { code, data } = await addReserveAPI({
reserve_date: date.value,
begin_time: time.value.split('-')[0],
end_time: time.value.split('-')[1],
person_id_list: JSON.stringify(checked_visitors.value)
const { code, data } = await addReserveAPI({
reserve_date: date.value,
begin_time: time.value.split('-')[0],
end_time: time.value.split('-')[1],
person_id_list: JSON.stringify(checked_visitors.value)
});
Taro.hideLoading();
if (code) {
// H5 逻辑: const pay_url = `/srv/?f=reserve&a=icbc_pay&pay_id=${data.pay_id}`; location.href = pay_url;
// 小程序逻辑:
// 小程序逻辑:
// 1. 如果支持小程序支付,应该调用获取支付参数接口
// 2. 暂时提示不支持,或尝试模拟
// 假设 payPrepareAPI 可用
// const payParams = await payPrepareAPI({ bill_id: data.pay_id }); // 假设接口
Taro.showModal({
title: '提示',
content: '订单提交成功。由于小程序支付暂未配置,请联系管理员或前往H5完成支付。',
......@@ -144,7 +145,7 @@ const submitBtn = async () => {
go('/bookingList');
}
});
// 如果后端有返回支付参数,可以使用 requestPayment
/*
Taro.requestPayment({
......@@ -153,7 +154,7 @@ const submitBtn = async () => {
package: '',
signType: 'MD5',
paySign: '',
success (res) {
success (res) {
go('/success');
},
fail (res) { }
......@@ -168,11 +169,11 @@ useDidShow(async () => {
date.value = params.date || '';
time.value = params.time || '';
price.value = params.price || 0;
if (date.value && time.value) {
const { code, data } = await personListAPI({ reserve_date: date.value, begin_time: time.value.split('-')[0], end_time: time.value.split('-')[1] });
if (code) {
visitorList.value = data;
visitorList.value = data || [];
}
}
});
......@@ -235,7 +236,7 @@ useDidShow(async () => {
justify-content: space-between;
flex-direction: column;
box-shadow: 0rem -0.33rem 0.25rem 0rem rgba(0,0,0,0.12);
.control-wrapper {
display: flex;
justify-content: space-between;
......
......@@ -18,7 +18,7 @@
<view class="payment-amount">支付金额:<text>¥ {{ billInfo?.total_amt }}</text></view>
</view>
<view class="appointment-notice">
<view style="margin-bottom: 0.25rem;"><nut-icon name="tips" />&nbsp;温馨提示</view>
<view style="margin-bottom: 0.25rem;"><IconFont name="tips" />&nbsp;温馨提示</view>
<view style="font-size: 0.85rem;">1. 一人一码,或拿身份证,扫码或识别身份证成功后进入</view>
<view style="font-size: 0.85rem;">2. 若您无法按时参观,请提前在预约记录中取消您的预约</view>
</view>
......@@ -33,6 +33,7 @@
<script setup>
import { ref } from 'vue'
import Taro, { useDidShow, useRouter as useTaroRouter } from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro'
import { useGo } from '@/hooks/useGo'
import { billInfoAPI } from '@/api/index'
import { formatDatetime } from '@/utils/tools';
......@@ -64,7 +65,7 @@ useDidShow(async () => {
position: relative;
background-color: #FFF;
min-height: 100vh;
.text-prompts {
display: flex;
align-items: center;
......@@ -100,19 +101,19 @@ useDidShow(async () => {
}
}
}
.appointment-notice {
padding: 1rem;
color: #666;
}
.success-btn {
position: fixed;
bottom: 2rem;
width: 100vw;
display: flex;
justify-content: space-around;
.btn-item {
width: 40%;
text-align: center;
......@@ -120,12 +121,12 @@ useDidShow(async () => {
border-radius: 8px;
font-size: 1.1rem;
}
.btn-left {
border: 1px solid #A67939;
color: #A67939;
}
.btn-right {
background-color: #A67939;
color: #FFF;
......
<template>
<view class="me-page">
<view class="me-content">
<view class="visitor-list-page">
<view class="visitor-content">
<view class="title">
<view class="text">参观者信息</view>
</view>
<view @tap="() => { go('/pages/addVisitor/index') }" class="add-visitors">
<view><nut-icon name="plus" /> 添加参观者</view>
<view class="add-btn"><IconFont name="plus" /> 添加参观者</view>
</view>
<view v-if="visitorList.length" class="visitors-list">
<view v-for="(item, index) in visitorList" :key="index" class="visitor-item">
......@@ -44,6 +44,7 @@
<script setup>
import { ref } from 'vue'
import Taro, { useDidShow } from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro'
import { useGo } from '@/hooks/useGo'
import { personListAPI, delPersonAPI } from '@/api/index'
import icon_3 from '@/assets/images/首页01@2x.png'
......@@ -77,21 +78,31 @@ function replaceMiddleCharacters(inputString) {
const formatId = (id) => replaceMiddleCharacters(id);
const loadList = async () => {
try {
const { code, data } = await personListAPI({});
if (code) {
visitorList.value = data;
visitorList.value = data || [];
}
} catch (err) {
console.error(err);
Taro.showToast({ title: '加载失败', icon: 'none' });
}
}
const removeItem = async (item) => {
const { confirm } = await Taro.showModal({ title: '提示', content: '确定删除该参观者吗?' });
if (confirm) {
const { code, msg } = await delPersonAPI({ person_id: item.id });
if (code) {
Taro.showToast({ title: '删除成功' });
loadList();
} else {
Taro.showToast({ title: msg || '删除失败', icon: 'none' });
try {
const { code, msg } = await delPersonAPI({ person_id: item.id });
if (code) {
Taro.showToast({ title: '删除成功' });
loadList();
} else {
Taro.showToast({ title: msg || '删除失败', icon: 'none' });
}
} catch (error) {
console.error(error);
Taro.showToast({ title: '删除出错', icon: 'none' });
}
}
}
......@@ -102,12 +113,12 @@ useDidShow(() => {
</script>
<style lang="less">
.me-page {
.visitor-list-page {
min-height: 100vh;
background-color: #F6F6F6;
padding: 1rem;
.me-content {
.visitor-content {
.title {
.text {
font-size: 1.1rem;
......@@ -126,6 +137,11 @@ useDidShow(() => {
padding: .65rem 0;
margin: 1rem 0;
font-size: 1.15rem;
.add-btn {
display: flex;
align-items: center;
justify-content: center;
}
}
.visitors-list {
......@@ -171,6 +187,7 @@ useDidShow(() => {
display: flex;
flex-direction: column;
align-items: center;
font-size: 0.8rem;
}
}
}
......
......@@ -2,7 +2,7 @@
<view class="waiting-page">
<view class="waiting-content">
<view>
<nut-icon name="clock" size="40" color="#A67939" />
<IconFont name="clock" size="40" color="#A67939" />
</view>
<view style="margin: 1rem 0;">支付中</view>
<view>{{ current.seconds }} s</view>
......@@ -19,6 +19,7 @@
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import Taro, { useRouter } from '@tarojs/taro'
import { IconFont } from '@nutui/icons-vue-taro'
import { billPayStatusAPI } from '@/api/index'
import { useGo } from '@/hooks/useGo'
......@@ -70,7 +71,7 @@ const checkStatus = async () => {
case PAY_STATUS.SUCCESS:
// 预约成功页面
// Replace to avoid back button loop
go(`/pages/success/index?pay_id=${pay_id}`, 'replace')
go(`/pages/success/index?pay_id=${pay_id}`, 'replace')
break
case PAY_STATUS.FAIL:
pay_msg.value = '订单支付失败'
......@@ -112,7 +113,7 @@ const goBackBtn = () => {
background-color: #fff;
align-items: center;
padding-top: 3rem;
.waiting-content {
display: flex;
flex-direction: column;
......@@ -120,7 +121,7 @@ const goBackBtn = () => {
font-size: 1rem;
color: #333;
}
.go-back-wrapper {
width: 80%;
margin-top: 2rem;
......