liudan 14 hours ago
parent
commit
5e3234ac40
2 changed files with 103 additions and 5 deletions
  1. 8 5
      src/pages/bigScreen/Index.jsx
  2. 95 0
      src/utils/index.js

+ 8 - 5
src/pages/bigScreen/Index.jsx

@@ -1,7 +1,7 @@
 import React from 'react';
 import logo from '@assets/images/logo.png';
 import Scroll from '@components/Scroll.jsx';
-import { initDate, initArray } from '@utils/index.js';
+import { initDate, initArray, sortRoomList } from '@utils/index.js';
 import ScrollTop from '@components/ScrollTop.jsx';
 import { Swiper } from 'antd-mobile';
 /**
@@ -48,9 +48,10 @@ class BigScreen extends React.Component {
       if (!flag) {
         newArray.push(this.props.roomObj);
       }
+      const sortedList = sortRoomList(newArray);
       this.setState({
-        patList: newArray,
-        swapperArray: initArray(newArray, 4)
+        patList: sortedList,
+        swapperArray: initArray(sortedList, 4)
       });
     }
   }
@@ -76,13 +77,15 @@ class BigScreen extends React.Component {
      }],
     }, true).then((data) => {
       if (data && data.result) {
+        // 按诊室排序:VIP 诊室最前,其余按编号升序
+        const sortedList = sortRoomList(data.result);
         this.setState({
-          patList: data.result,
+          patList: sortedList,
           dateStr: {
             dateNow: data.curDate, //当前日期,
             weekNow: data.curWeekDate, // 当前日期,
           },
-          swapperArray: initArray(data.result, 4),
+          swapperArray: initArray(sortedList, 4),
         });
       }
     });

+ 95 - 0
src/utils/index.js

@@ -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