hookehuyr

refactor(qrCodeSearch): 重构预约码卡组件代码结构

将组件逻辑拆分为多个函数,提高可读性和可维护性
添加加载状态和销毁处理
优化数据处理和错误处理逻辑
1 /* 1 /*
2 * @Date: 2023-08-24 09:42:27 2 * @Date: 2023-08-24 09:42:27
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-01-14 20:43:23 4 + * @LastEditTime: 2026-01-14 20:50:41
5 * @FilePath: /xyxBooking-weapp/src/api/index.js 5 * @FilePath: /xyxBooking-weapp/src/api/index.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
...@@ -40,6 +40,7 @@ export const volunteerLoginAPI = (params) => fn(fetch.post(Api.REDEEM_LOGIN, par ...@@ -40,6 +40,7 @@ export const volunteerLoginAPI = (params) => fn(fetch.post(Api.REDEEM_LOGIN, par
40 40
41 /** 41 /**
42 * @description: 检查核销权限 42 * @description: 检查核销权限
43 + * @returns {Object} { data.can_redeem: Boolean, msg: String}
43 */ 44 */
44 export const checkRedeemPermissionAPI = (params) => fn(fetch.get(Api.REDEEM_CHECK_AUTH, params)); 45 export const checkRedeemPermissionAPI = (params) => fn(fetch.get(Api.REDEEM_CHECK_AUTH, params));
45 46
......
1 /* 1 /*
2 * @Date: 2025-06-28 10:33:00 2 * @Date: 2025-06-28 10:33:00
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-01-13 23:19:52 4 + * @LastEditTime: 2026-01-14 21:35:58
5 * @FilePath: /xyxBooking-weapp/src/app.config.js 5 * @FilePath: /xyxBooking-weapp/src/app.config.js
6 * @Description: 小程序配置文件 6 * @Description: 小程序配置文件
7 */ 7 */
...@@ -17,7 +17,6 @@ const pages = [ ...@@ -17,7 +17,6 @@ const pages = [
17 'pages/bookingList/index', 17 'pages/bookingList/index',
18 'pages/bookingDetail/index', 18 'pages/bookingDetail/index',
19 'pages/me/index', 19 'pages/me/index',
20 - 'pages/callback/index',
21 'pages/search/index', 20 'pages/search/index',
22 'pages/visitorList/index', 21 'pages/visitorList/index',
23 'pages/volunteerLogin/index', 22 'pages/volunteerLogin/index',
......
1 <!-- 1 <!--
2 * @Date: 2024-01-16 10:06:47 2 * @Date: 2024-01-16 10:06:47
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2026-01-06 23:06:49 4 + * @LastEditTime: 2026-01-14 21:57:40
5 * @FilePath: /xyxBooking-weapp/src/components/qrCodeSearch.vue 5 * @FilePath: /xyxBooking-weapp/src/components/qrCodeSearch.vue
6 * @Description: 预约码卡组件 6 * @Description: 预约码卡组件
7 --> 7 -->
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
36 </template> 36 </template>
37 37
38 <script setup> 38 <script setup>
39 -import { ref, onMounted } from 'vue' 39 +import { ref, onMounted, watch, onUnmounted } from 'vue'
40 import { formatDatetime } from '@/utils/tools'; 40 import { formatDatetime } from '@/utils/tools';
41 import { qrcodeStatusAPI, queryQrCodeAPI } from '@/api/index' 41 import { qrcodeStatusAPI, queryQrCodeAPI } from '@/api/index'
42 import BASE_URL from '@/utils/config'; 42 import BASE_URL from '@/utils/config';
...@@ -50,19 +50,21 @@ const props = defineProps({ ...@@ -50,19 +50,21 @@ const props = defineProps({
50 50
51 const userinfo = ref({}); 51 const userinfo = ref({});
52 52
53 -function replaceMiddleCharacters(inputString) { 53 +const replaceMiddleCharacters = (input_string) => {
54 - if (!inputString || inputString.length < 15) { 54 + if (!input_string || input_string.length < 15) {
55 - return inputString; 55 + return input_string;
56 } 56 }
57 - const start = Math.floor((inputString.length - 8) / 2); 57 + const start = Math.floor((input_string.length - 8) / 2);
58 const end = start + 8; 58 const end = start + 8;
59 const replacement = '*'.repeat(8); 59 const replacement = '*'.repeat(8);
60 - return inputString.substring(0, start) + replacement + inputString.substring(end); 60 + return input_string.substring(0, start) + replacement + input_string.substring(end);
61 } 61 }
62 62
63 const formatId = (id) => replaceMiddleCharacters(id); 63 const formatId = (id) => replaceMiddleCharacters(id);
64 64
65 const useStatus = ref('0'); 65 const useStatus = ref('0');
66 +const is_loading = ref(false)
67 +let is_destroyed = false
66 68
67 const qr_code_status = { 69 const qr_code_status = {
68 '1': '未激活', 70 '1': '未激活',
...@@ -78,24 +80,104 @@ const STATUS_CODE = { ...@@ -78,24 +80,104 @@ const STATUS_CODE = {
78 USED: '7', 80 USED: '7',
79 }; 81 };
80 82
81 -onMounted(async () => { 83 +const build_qr_code_url = (qr_code) => {
82 - if (props.id) { 84 + if (!qr_code) return ''
83 - const { code, data } = await queryQrCodeAPI({ id_number: props.id }); 85 + return `${BASE_URL}/admin?m=srv&a=get_qrcode&key=${encodeURIComponent(String(qr_code))}`
84 - if (code) { 86 +}
85 - // data 可能是一个对象 87 +
86 - const item = data; 88 +/**
87 - item.qr_code_url = BASE_URL + '/admin?m=srv&a=get_qrcode&key=' + item.qr_code; 89 + * @description: 格式化预约码卡数据
88 - item.datetime = formatDatetime({ begin_time: item.begin_time, end_time: item.end_time }); 90 + * @param {*} raw 原始数据
89 - item.id = formatId(item.id_number); 91 + * @return {*} 格式化后的数据
90 - userinfo.value = item; 92 + */
93 +
94 +const normalize_item = (raw) => {
95 + if (!raw || typeof raw !== 'object') return null
96 + const qr_code = raw.qr_code ? String(raw.qr_code) : ''
97 + const id_number = raw.id_number ? String(raw.id_number) : ''
98 + return {
99 + ...raw,
100 + qr_code,
101 + qr_code_url: build_qr_code_url(qr_code),
102 + datetime: formatDatetime({ begin_time: raw.begin_time, end_time: raw.end_time }),
103 + id: formatId(id_number),
104 + }
105 +}
106 +
107 +/**
108 + * @description: 重置状态
109 + */
110 +
111 +const reset_state = () => {
112 + userinfo.value = {}
113 + useStatus.value = '0'
114 +}
115 +
116 +/**
117 + * @description: 加载预约码卡状态
118 + * @param {*} qr_code 预约码
119 + * @return {*} 状态码
120 + */
121 +
122 +const load_qr_code_status = async (qr_code) => {
123 + if (!qr_code) return
124 + const res = await qrcodeStatusAPI({ qr_code })
125 + if (is_destroyed) return
126 + if (!res || res.code !== 1) return
127 + const status = res?.data?.status
128 + if (status === undefined || status === null) return
129 + useStatus.value = String(status)
130 +}
91 131
92 - const { code: status_code, data: status_data } = await qrcodeStatusAPI({ qr_code: item.qr_code }); 132 +/**
93 - if (status_code) { 133 + * @description: 加载预约码卡信息
94 - useStatus.value = status_data.status; 134 + * @param {*} id_number 身份证号
135 + * @return {*} 预约码卡信息
136 + */
137 +
138 +const load_qr_code_info = async (id_number) => {
139 + const id = String(id_number || '').trim()
140 + if (!id) {
141 + reset_state()
142 + return
95 } 143 }
144 +
145 + is_loading.value = true
146 + const res = await queryQrCodeAPI({ id_number: id })
147 + if (is_destroyed) return
148 + is_loading.value = false
149 +
150 + if (!res || res.code !== 1 || !res.data) {
151 + reset_state()
152 + return
96 } 153 }
154 +
155 + const raw = Array.isArray(res.data) ? res.data[0] : res.data
156 + const item = normalize_item(raw)
157 + if (!item || !item.qr_code) {
158 + reset_state()
159 + return
97 } 160 }
161 +
162 + userinfo.value = item
163 + await load_qr_code_status(item.qr_code)
164 +}
165 +
166 +onUnmounted(() => {
167 + is_destroyed = true
168 +})
169 +
170 +onMounted(() => {
171 + load_qr_code_info(props.id)
98 }) 172 })
173 +
174 +watch(
175 + () => props.id,
176 + (val) => {
177 + if (is_loading.value) return
178 + load_qr_code_info(val)
179 + }
180 +)
99 </script> 181 </script>
100 182
101 <style lang="less"> 183 <style lang="less">
......