|
|
@@ -13,6 +13,101 @@ export const initDate = () => {
|
|
|
weekNow: `${weekdays[weekdayNumber]}`,
|
|
|
};
|
|
|
};
|
|
|
+/** 诊室名称中代表 VIP(优先展示)的关键字 */
|
|
|
+const VIP_ROOM_KEYWORDS = ['VIP'];
|
|
|
+/** 中文数字 */
|
|
|
+const CN_NUM_MAP = {
|
|
|
+ 零: 0, 〇: 0, 一: 1, 壹: 1, 二: 2, 贰: 2, 两: 2, 三: 3, 叁: 3, 四: 4, 肆: 4,
|
|
|
+ 五: 5, 伍: 5, 六: 6, 陆: 6, 七: 7, 柒: 7, 八: 8, 捌: 8, 九: 9, 玖: 9,
|
|
|
+};
|
|
|
+/** 中文数字字符集 */
|
|
|
+const CN_NUM_CHARS = '零〇一壹二贰两三叁四肆五伍六陆七柒八捌九玖十';
|
|
|
+/**
|
|
|
+ * 解析中文数字(支持 1~99,如 十、十一、二十、二十一)
|
|
|
+ * @param {*} str 只包含中文数字的字符串
|
|
|
+ */
|
|
|
+const parseCnNumber = (str) => {
|
|
|
+ if (!str) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ let total = 0;
|
|
|
+ let num = 0;
|
|
|
+ let hasNum = false;
|
|
|
+ for (const ch of str) {
|
|
|
+ if (ch === '十') {
|
|
|
+ hasNum = true;
|
|
|
+ total += (num || 1) * 10;
|
|
|
+ num = 0;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ const n = CN_NUM_MAP[ch];
|
|
|
+ if (n == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ hasNum = true;
|
|
|
+ num = n;
|
|
|
+ }
|
|
|
+ return hasNum ? total + num : null;
|
|
|
+};
|
|
|
+/**
|
|
|
+ * 从诊室名称中提取编号,支持 诊室10、诊室A1、诊室十、3楼诊室2
|
|
|
+ * @param {*} name 诊室名称
|
|
|
+ */
|
|
|
+const getRoomNumber = (name) => {
|
|
|
+ if (!name) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // 结尾的阿拉伯数字,如 诊室10、诊室A1
|
|
|
+ const arabic = name.match(/(\d+)\s*$/);
|
|
|
+ if (arabic) {
|
|
|
+ return parseInt(arabic[1], 10);
|
|
|
+ }
|
|
|
+ // 结尾的中文数字,如 诊室十、诊室二十一
|
|
|
+ const cn = name.match(new RegExp(`([${CN_NUM_CHARS}]+)\\s*$`));
|
|
|
+ if (cn) {
|
|
|
+ return parseCnNumber(cn[1]);
|
|
|
+ }
|
|
|
+ // 名称中间的阿拉伯数字,取最后一个,如 3楼诊室
|
|
|
+ const mid = name.match(/(\d+)(?!.*\d)/);
|
|
|
+ if (mid) {
|
|
|
+ return parseInt(mid[1], 10);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+};
|
|
|
+/**
|
|
|
+ * 按诊室排序:VIP 诊室排在最前,其余诊室按编号升序(诊室1、诊室2…诊室10),无编号的排最后
|
|
|
+ * @param {*} list 诊室数据列表,元素需包含 roomDesc
|
|
|
+ */
|
|
|
+export const sortRoomList = (list = []) => {
|
|
|
+ if (!Array.isArray(list)) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ const getKey = (roomDesc) => {
|
|
|
+ const name = String(roomDesc || '').trim();
|
|
|
+ const isVip = VIP_ROOM_KEYWORDS.some((key) => name.toUpperCase().includes(key.toUpperCase()));
|
|
|
+ const num = getRoomNumber(name);
|
|
|
+ return {
|
|
|
+ vip: isVip ? 0 : 1,
|
|
|
+ hasNum: num == null ? 1 : 0,
|
|
|
+ num: num == null ? Number.MAX_SAFE_INTEGER : num,
|
|
|
+ name,
|
|
|
+ };
|
|
|
+ };
|
|
|
+ return [...list].sort((a, b) => {
|
|
|
+ const keyA = getKey(a?.roomDesc);
|
|
|
+ const keyB = getKey(b?.roomDesc);
|
|
|
+ if (keyA.vip !== keyB.vip) {
|
|
|
+ return keyA.vip - keyB.vip;
|
|
|
+ }
|
|
|
+ if (keyA.hasNum !== keyB.hasNum) {
|
|
|
+ return keyA.hasNum - keyB.hasNum;
|
|
|
+ }
|
|
|
+ if (keyA.num !== keyB.num) {
|
|
|
+ return keyA.num - keyB.num;
|
|
|
+ }
|
|
|
+ return keyA.name.localeCompare(keyB.name, 'zh-Hans-CN');
|
|
|
+ });
|
|
|
+};
|
|
|
/**
|
|
|
* 数组data拆分为num个为一组的二维数组
|
|
|
* @param {*} data
|