Ver Fonte

pagesPatient包代码转换提交

xuyousan há 3 meses atrás
pai
commit
be595b4306
96 ficheiros alterados com 4849 adições e 2977 exclusões
  1. 52 0
      .cursorrules
  2. 106 0
      .trae/skills/微信健康卡调用/SKILL.md
  3. 247 0
      .trae/skills/微信小程序转uniapp/SKILL.md
  4. 242 0
      TRAE_SKILLS.md
  5. 101 0
      WECHAT_HEALTH_CARD_SKILLS.md
  6. 395 0
      WX_TO_UNIAPP_RULES.md
  7. 4 3
      package.json
  8. 32 0
      pages.json
  9. 1 1
      pages/st1/components/pageActive/st1/components/activeFlow/activeFlow.vue
  10. 0 1
      pages/st1/components/pageActive/st1/components/activeFlow/flowTemplate/BoxTest/BoxTest.vue
  11. 0 1
      pages/st1/components/pageActive/st1/components/activeFlow/flowTemplate/duringBill/duringBill.vue
  12. 0 1
      pages/st1/components/pageActive/st1/components/activeFlow/flowTemplate/typeBox/typeBox.vue
  13. 1 1
      pages/st1/components/pageActive/st1/components/guidedSuspension/guidedSuspension.vue
  14. 0 367
      pagesPatient/service/api.ts
  15. 38 12
      pagesPatient/service/refund/index.ts
  16. 24 0
      pagesPatient/service/yygh/index.ts
  17. 4 4
      pagesPatient/st1/business/costDetailedList/hospitalCosts/hospitalCosts.vue
  18. 3 3
      pagesPatient/st1/business/costDetailedList/hospitalCostsList/hospitalCostsList.vue
  19. 3 3
      pagesPatient/st1/business/costDetailedList/outpatientCosts/outpatientCosts.vue
  20. 1 1
      pagesPatient/st1/business/order/orderPayment/orderPayment.vue
  21. 1 1
      pagesPatient/st1/business/otherService/electronicMedicalRecord/electronicMedicalRecord.vue
  22. 1 1
      pagesPatient/st1/business/otherService/hospitalDistrict/hospitalDistrict.vue
  23. 1 1
      pagesPatient/st1/business/outpatient/outpatientRefund/outpatientRefund.vue
  24. 1 1
      pagesPatient/st1/business/outpatient/outpatientRefundDetail/outpatientRefundDetail.vue
  25. 0 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/components/cardDiv/cardDiv.vue
  26. 0 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/components/cardPanel/cardPanel.vue
  27. 1 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/action/index.vue
  28. 1 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/index.vue
  29. 1 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/input/index.vue
  30. 1 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/radio/index.vue
  31. 0 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/regionPicker/index.vue
  32. 1 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/smsCode/index.vue
  33. 1 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/textArea/index.vue
  34. 0 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/components/userInfo/userInfo.vue
  35. 0 140
      pagesPatient/st1/business/outpatient/outpatientRefundNew/config/api.js
  36. 18 12
      pagesPatient/st1/business/outpatient/outpatientRefundNew/refundForm/refundForm.vue
  37. 5 9
      pagesPatient/st1/business/outpatient/outpatientRefundNew/refundForm/singletonRequest.js
  38. 10 19
      pagesPatient/st1/business/outpatient/outpatientRefundNew/refundRecord/refundRecord.vue
  39. 1 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/refundResult/refundResult.vue
  40. 1 1
      pagesPatient/st1/business/outpatient/outpatientRefundNew/selectRefundCardList/selectRefundCardList.vue
  41. 2 2
      pagesPatient/st1/business/outpatient/outpatientRefundNew/selectRefundChannel/selectRefundChannel.vue
  42. 19 19
      pagesPatient/st1/business/outpatient/outpatientRefundNew/static/css/refund.css
  43. 1 1
      pagesPatient/st1/business/outpatient/outpatientRefundRecord/outpatientRefundRecord.vue
  44. 1 1
      pagesPatient/st1/business/pay/payState/payState.vue
  45. 2 2
      pagesPatient/st1/business/prescriptionManagement/dischargeMedication/dischargeMedication.vue
  46. 2 2
      pagesPatient/st1/business/prescriptionManagement/dischargeMedicationDetails/dischargeMedicationDetails.vue
  47. 2 2
      pagesPatient/st1/business/prescriptionManagement/drugCredentials/drugCredentials.vue
  48. 2 2
      pagesPatient/st1/business/prescriptionManagement/drugCredentialsDetails/drugCredentialsDetails.vue
  49. 2 2
      pagesPatient/st1/business/priceInquiry/inquiryDetails/inquiryDetails.vue
  50. 3 3
      pagesPatient/st1/business/priceInquiry/inquiryList/inquiryList.vue
  51. 2 2
      pagesPatient/st1/business/priceInquiry/inquirySelect/inquirySelect.vue
  52. 2 2
      pagesPatient/st1/business/queue/queueList/queueList.vue
  53. 3 3
      pagesPatient/st1/business/record/applyRecordDetail/applyRecordDetail.vue
  54. 2 2
      pagesPatient/st1/business/record/appointmentRecord/appointmentRecord.vue
  55. 3 3
      pagesPatient/st1/business/record/cardRecord/cardRecord.vue
  56. 4 4
      pagesPatient/st1/business/record/cardRecordDetails/cardRecordDetails.vue
  57. 4 4
      pagesPatient/st1/business/record/hosRecord/hosRecord.vue
  58. 2 2
      pagesPatient/st1/business/record/outpatientMedical/outpatientMedical.vue
  59. 0 90
      pagesPatient/st1/business/yygh/waitRegistration/waitRegistration.js
  60. 0 4
      pagesPatient/st1/business/yygh/waitRegistration/waitRegistration.json
  61. 309 0
      pagesPatient/st1/business/yygh/waitRegistration/waitRegistration.vue
  62. 0 50
      pagesPatient/st1/business/yygh/waitRegistration/waitRegistration.wxml
  63. 0 118
      pagesPatient/st1/business/yygh/waitRegistration/waitRegistration.wxss
  64. 0 18
      pagesPatient/st1/business/yygh/waitSuccess/waitSuccess.js
  65. 0 4
      pagesPatient/st1/business/yygh/waitSuccess/waitSuccess.json
  66. 116 0
      pagesPatient/st1/business/yygh/waitSuccess/waitSuccess.vue
  67. 0 20
      pagesPatient/st1/business/yygh/waitSuccess/waitSuccess.wxml
  68. 0 72
      pagesPatient/st1/business/yygh/waitSuccess/waitSuccess.wxss
  69. 0 459
      pagesPatient/st1/business/yygh/yyghClinicMsg/yyghClinicMsg.js
  70. 0 14
      pagesPatient/st1/business/yygh/yyghClinicMsg/yyghClinicMsg.json
  71. 855 0
      pagesPatient/st1/business/yygh/yyghClinicMsg/yyghClinicMsg.vue
  72. 0 108
      pagesPatient/st1/business/yygh/yyghClinicMsg/yyghClinicMsg.wxml
  73. 0 286
      pagesPatient/st1/business/yygh/yyghClinicMsg/yyghClinicMsg.wxss
  74. 0 261
      pagesPatient/st1/business/yygh/yyghDeptList/yyghDeptList.js
  75. 0 7
      pagesPatient/st1/business/yygh/yyghDeptList/yyghDeptList.json
  76. 512 0
      pagesPatient/st1/business/yygh/yyghDeptList/yyghDeptList.vue
  77. 0 60
      pagesPatient/st1/business/yygh/yyghDeptList/yyghDeptList.wxml
  78. 0 154
      pagesPatient/st1/business/yygh/yyghDeptList/yyghDeptList.wxss
  79. 0 323
      pagesPatient/st1/business/yygh/yyghDoctorList/yyghDoctorList.js
  80. 0 11
      pagesPatient/st1/business/yygh/yyghDoctorList/yyghDoctorList.json
  81. 420 0
      pagesPatient/st1/business/yygh/yyghDoctorList/yyghDoctorList.vue
  82. 0 75
      pagesPatient/st1/business/yygh/yyghDoctorList/yyghDoctorList.wxml
  83. 0 59
      pagesPatient/st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor.js
  84. 0 10
      pagesPatient/st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor.json
  85. 106 0
      pagesPatient/st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor.vue
  86. 0 32
      pagesPatient/st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor.wxml
  87. 1 1
      pagesPatient/st1/components/doctorInfo/doctorInfo.vue
  88. 1 1
      pagesPatient/st1/components/doctorItemBox/doctorItemBox.vue
  89. 2 2
      pagesPatient/st1/components/queueItem/queueItem.vue
  90. 1 1
      pagesPatient/st1/components/screening/screening.vue
  91. 92 0
      pagesPatient/st1/static/css/search.css
  92. 55 55
      pagesPatient/st1/static/css/yyghDoctorList.css
  93. 24 24
      pagesPatient/st1/static/css/yyghHistoryDoctor.css
  94. 14 3
      uni_modules/mp-html/components/mp-html/parser.js
  95. 6 3
      utils/index.ts
  96. 978 0
      utils/publicFn.js

+ 52 - 0
.cursorrules

@@ -0,0 +1,52 @@
+# Role: Senior UniApp Migration Specialist (KST Project)
+
+# 核心行为准则
+你正在负责将微信小程序转换为 UniApp (Vue 3 + TS) 项目。
+**必须**优先遵循 `.cursorrules` 中的核心红线,复杂场景查阅 `WX_TO_UNIAPP_RULES.md`。
+
+# 🚀 场景化规则导航 (Scenario Navigation)
+- **处理接口/API** → 必读 `WX_TO_UNIAPP_RULES.md` 之 `7.8 接口封装调用规范`
+- **新建/修改页面** → 必读 `WX_TO_UNIAPP_RULES.md` 之 `2. 页面与组件文件转换`
+- **处理静态资源** → 必读 `WX_TO_UNIAPP_RULES.md` 之 `4. 样式与资源`
+
+# 🛑 关键红线 (Critical Rules)
+> 违反以下规则将被视为**严重错误**:
+
+1. **接口规范 (Service Layer)**:
+   - **导入**:必须使用 Named Imports (如 `import { methodA } from ...`),严禁默认导入。
+   - **调用**:必须直接调用函数,严禁对象调用 (如 `api.methodA()` ❌)。
+   - **返回值**:必须使用解构获取 (如 `let { resp, resData } = await api()` ),严禁默认解构 `{ resp }`。
+   - **串行调用**:后续接口必须重命名解构 (如 `let { resp: list } = await api()` )。
+
+2. **工具类规范 (Utils/Hooks)**:
+   - **publicFn**:**不存在**。`publicFn.getMember` -> `await useGetMember()`。
+   - **common**:`import { common } from '@/utils'` (解构导入)。`util.xxx` -> `common.xxx`。
+   - **icon**:`import icon from '@/utils/icon'` (默认导入)。
+   - **getAuthorize**:`util.getAuthorize` -> `common.getAuthorize`。
+   - **Legacy Utils**: `getState.js`, `pagesPatientFn.js` -> `import { getState, pagesPatientFn } from '@/uni-app-base/utils'`.
+
+3. **Vue 3 组件规范**:
+   - **实例**:`<script setup>` 顶层 `const { proxy } = getCurrentInstance(); const app = getApp();`。
+   - **Props**:推荐 `withDefaults(defineProps<{...}>(), {...})`。
+   - **Expose**:组件方法供父组件调用时,**必须** `defineExpose({ methodName })`。
+   - **This**:严禁使用 `this` 或 `this.setData`。使用 `ref/reactive`。
+
+4. **样式与模板**:
+   - **单位**:严禁 `rpx`,必须全文替换为 `upx`。
+   - **指令**:`wx:if` -> `v-if`, `bindtap` -> `@click`.
+   - **Dataset**:推荐 `@click="fn(item)"`。如需 dataset,JS 中必须用 `e.currentTarget?.dataset?.xxx`。
+
+5. **动态文档维护**:
+   - 用户提出的新规则,**必须**立即更新到 `WX_TO_UNIAPP_RULES.md`。
+
+# ✅ 交付自检清单 (Verification Checklist)
+在输出代码前,请在思维链中确认:
+- [ ] **接口**:Named Import? 解构返回值? 变量重命名?
+- [ ] **工具**:移除了 publicFn? 正确导入了 common/icon?
+- [ ] **组件**:用了 script setup? defineExpose? 移除了 this?
+- [ ] **样式**:rpx 全部转 upx?
+- [ ]- **前缀**:wx. 全部转 uni.?
+
+6. **代码完整性 (Code Completeness)**:
+   - **严禁漏掉代码**:迁移时必须逐行核对原文件逻辑,严禁遗漏任何事件绑定、数据处理或业务逻辑。
+   - **兜底注释**:如因平台差异无法迁移,必须在原位置添加中文注释说明原因。

+ 106 - 0
.trae/skills/微信健康卡调用/SKILL.md

@@ -0,0 +1,106 @@
+---
+name: 微信健康卡调用
+description: 微信健康卡调用
+---
+
+# 技能:微信电子健康卡对接
+
+**描述**: 在 UniApp 中集成微信官方电子健康卡插件的完整指南。
+
+## 1. 前置条件
+- **平台**: 仅限微信小程序 (`mp-weixin`)。**不支持** App 或 H5 端直接使用。
+- **账号**: 必须先在微信公众平台申请开通插件。
+  - **路径**: 登录微信公众平台 → 小程序 → 插件管理 → 添加插件 → 搜索 "电子健康卡" 并申请。
+
+## 2. 配置 (Manifest)
+**文件**: `manifest.json`
+**操作**: 在 `mp-weixin` 节点下添加插件声明。
+
+```json
+"mp-weixin": {
+  "appid": "你的小程序appid",
+  "plugins": {
+    "healthCard": {
+      "version": "1.x.x",   // 请以微信后台显示的最新版本号为准
+      "provider": "wxe5f52902cf4de896"  // 电子健康卡插件官方原始 ID
+    }
+  }
+}
+```
+
+## 3. 实现 - 嵌入插件组件 (场景A)
+**适用场景**: 插件提供了一个组件 (Component),你需要将其嵌入到自己的页面中显示。
+
+**步骤 1**: 在 `pages.json` 中注册组件
+找到你需要引入插件的页面配置,添加 `usingComponents` 节点:
+```json
+// pages.json
+{
+  "pages": [
+    {
+      "path": "pages/health-card/index",
+      "style": {
+        "navigationBarTitleText": "健康卡",
+        "usingComponents": {
+          // 定义组件名: 插件协议://插件名/组件路径
+          "health-card-comp": "plugin://healthCard/healthCardQueryComp"
+        }
+      }
+    }
+  ]
+}
+```
+
+**步骤 2**: 在页面中直接使用组件
+```vue
+<template>
+  <view class="container">
+    <!-- 直接使用 pages.json 中注册的标签名 -->
+    <health-card-comp
+      @success="onSuccess"
+      @fail="onFail"
+    />
+  </view>
+</template>
+
+<script setup lang="ts">
+const onSuccess = (e: any) => {
+  console.log('组件回调成功', e.detail);
+};
+
+const onFail = (e: any) => {
+  console.error('组件回调失败', e.detail);
+};
+</script>
+```
+
+## 4. 实现 - 跳转插件页面 (场景B)
+**适用场景**: 插件提供了一个完整的页面 (Page),你需要从当前小程序跳转过去。
+
+**代码**:
+```ts
+// 使用 plugin:// 协议直接跳转
+// 格式: plugin://插件名/页面路径
+uni.navigateTo({
+  url: 'plugin://healthCard/index', 
+  success: () => {
+    console.log('跳转插件页面成功');
+  },
+  fail: (err) => {
+    console.error('跳转失败', err);
+  }
+});
+```
+
+> **提示**: 具体的 **组件路径** (如 `healthCardQueryComp`) 和 **页面路径** (如 `index`) 必须查阅该插件的官方文档,不同插件提供商的路径定义不同。
+
+## 5. 调试与发布
+- **调试**: 在 HBuilderX 中运行到「微信开发者工具」,确保控制台无报错。
+- **发布**: 体验版测试通过后,提交微信审核并发布。
+- **注意**: 确保 `manifest.json` 中的插件版本号与微信后台可用的版本一致。
+
+## 6. 注意事项
+- **多端兼容性**: 该方案**仅适用**于微信小程序端。
+  - **App 端**: 无法直接嵌入插件。必须通过 SDK (如 `launchMiniProgram`) 唤起微信 App 打开电子健康卡小程序。
+  - **H5 端**: 不支持。
+- **文档更新**: 插件的 `version` (版本号)、`provider` (插件ID) 和 `pluginPage` (页面路径) 可能会随官方更新而变化,请始终以微信官方文档为准。

+ 247 - 0
.trae/skills/微信小程序转uniapp/SKILL.md

@@ -0,0 +1,247 @@
+---
+name: 微信小程序转uniapp
+description: 微信小程序转uniapp
+---
+
+# Trae Skills for UniApp Migration (Granular)
+# UniApp 迁移技能 (细粒度)
+
+This document contains highly granular skills derived from `WX_TO_UNIAPP_RULES.md` for precise context injection in Trae.
+本文档包含源自 `WX_TO_UNIAPP_RULES.md` 的高细粒度技能,用于 Trae 的精准上下文注入。
+
+## Skill: File Extension & Project Structure Migration
+## 技能:文件扩展名与项目结构迁移
+**Description**: Rules for converting file types and mapping project configuration. (文件类型转换与项目配置映射规则)
+**Instructions**:
+1. **File Merging (文件合并)**:
+   - Merge `.wxml`, `.wxss`, and `.js` into a single `.vue` file. (将 .wxml, .wxss, .js 合并为单个 .vue 文件)
+   - `.wxml` content goes into `<template>`. (.wxml 内容放入 <template>)
+   - `.wxss` content goes into `<style lang="scss">`. (.wxss 内容放入 <style lang="scss">)
+   - `.js` content goes into `<script setup lang="ts">`. (.js 内容放入 <script setup lang="ts">)
+2. **Configuration Files (配置文件)**:
+   - **DELETE** `.json` page configuration files. (删除页面 .json 配置文件)
+   - **Migration**: Extract `navigationBarTitleText` from `.json` and move to `pages.json` (`style` or `globalStyle`). (提取标题配置迁移至 pages.json)
+   - **Subpackages**: Move `app.json` `subpackages` to `pages.json` `subPackages` field. (迁移分包配置)
+   - **Global Styles**: Move `app.wxss` content to `App.vue` `<style>` or `@import` a global css file. (全局样式迁移至 App.vue)
+   - **Route Check**: If a file is a page (not in `components/`) and has no route, **MUST** register it in `pages.json`. (页面必须在 pages.json 注册)
+3. **Independent Files (独立文件)**:
+   - Rename public `.wxss` to `.scss`. (公共 .wxss 重命名为 .scss)
+   - Rename util `.js` to `.ts`. (工具 .js 重命名为 .ts)
+   - Update all `@import` paths in code to reflect new extensions. (更新代码中的 @import 路径)
+4. **Cleanup (清理)**:
+   - After verification, DELETE the original `.wxml`, `.wxss`, `.js`, `.json` files. (验证后删除原文件)
+
+---
+
+## Skill: WXML to Vue Template Conversion
+## 技能:WXML 到 Vue 模板转换
+**Description**: Syntax mapping from WeChat Mini Program templates to Vue 3 templates. (微信小程序模板到 Vue 3 模板的语法映射)
+**Instructions**:
+1. **Directives (指令)**:
+   - `wx:if`, `wx:elif`, `wx:else` -> `v-if`, `v-else-if`, `v-else`.
+   - `wx:for="{{list}}"` -> `v-for="(item, index) in list" :key="index"`.
+   - `wx:key="id"` -> `:key="item.id"`.
+   - **Slicing**: For `v-if="index < 3"`, REPLACE with `v-for="... in list.slice(0, 3)"`. (限制循环数量使用 slice)
+2. **Events (事件)**:
+   - `bindtap="fn"` -> `@click="fn"`.
+   - `catchtap="fn"` -> `@click.stop="fn"`.
+   - `bindinput="fn"` -> `@input="fn"`.
+3. **Dataset & Attributes (数据集与属性)**:
+   - `data-xxx="{{val}}"` -> Prefer passing args: `@click="fn(val)"`. (优先传参替代 dataset)
+   - If preserving dataset (Required for `menuClick`): Use `:data-xxx="val"`. Access in JS via `e.currentTarget?.dataset?.xxx` (Must use optional chaining). (保留 dataset 时需使用可选链访问)
+   - `style="{{...}}"` -> `:style="..."`.
+4. **Logic Constraints (逻辑约束)**:
+   - **NEVER** use `v-if` and `v-for` on the same element. Use `<template v-for>` wrapper. (禁止同时使用 v-if 和 v-for)
+   - **Deep Access**: `v-if="menuObj?.Children?.[0]?.Children"` (Use optional chaining for all deep paths). (深层对象访问必须使用可选链)
+
+---
+
+## Skill: JS Logic & Lifecycle Migration
+## 技能:JS 逻辑与生命周期迁移
+**Description**: Converting Mini Program JS logic to Vue 3 Composition API. (将小程序 JS 逻辑转换为 Vue 3 组合式 API)
+**Instructions**:
+1. **Structure (结构)**:
+   - Replace `Page({})` with `<script setup lang="ts">`. (替换 Page 为 script setup)
+   - Remove `app.js` logic; move to `App.vue` or Hooks. (移除 app.js 逻辑)
+2. **State Management (状态管理)**:
+   - `data: { x: 1 }` -> `const x = ref(1)`.
+   - `this.setData({ x: 2 })` -> `x.value = 2`.
+   - `this.setData({ 'a.b': 2 })` -> `a.value.b = 2`.
+   - **FORBIDDEN**: Do not use `this` keyword for state. (禁止使用 this)
+3. **Lifecycle (生命周期)**:
+   - `onLoad` -> `onLoad` (from `@dcloudio/uni-app`) or `useOnLoad`.
+   - `onShow` -> `onShow`.
+   - `onReady` -> `onReady`.
+   - **Context**: `getCurrentPages()` is allowed for page stack checks. (允许使用 getCurrentPages)
+4. **Components (组件)**:
+   - `properties` -> `withDefaults(defineProps<{...}>(), {...})`.
+   - `triggerEvent` -> `const emit = defineEmits([...]); emit('event')`.
+   - `this.selectComponent` targets -> Child component must use `defineExpose({ method })`. (子组件需 expose 方法)
+   - **Observers**: Replace `properties: { observer: ... }` with `watch(() => props.propName, (val) => { ... })`. (使用 watch 替代 observer)
+5. **Safety (安全)**:
+   - `onLoad` params: `JSON.parse` MUST be inside `try-catch` to prevent white screen crashes. (JSON.parse 必须加 try-catch)
+
+---
+
+## Skill: Page & App Instance Management
+## 技能:页面与 App 实例管理
+**Description**: Correctly obtaining and using `proxy` and `app` instances. (正确获取和使用 proxy 及 app 实例)
+**Instructions**:
+1. **Setup (初始化)**:
+   - **MUST** be at the top of `<script setup>` (必须在 script setup 顶部):
+     ```ts
+     import { getCurrentInstance } from 'vue';
+     const { proxy } = getCurrentInstance() as any;
+     const app = getApp();
+     ```
+2. **Restrictions (限制)**:
+   - **NEVER** call `getCurrentInstance()` or `getApp()` repeatedly inside functions. (禁止在函数内重复调用)
+   - **NEVER** use `this` in setup; use `proxy` instead. (setup 中禁止使用 this,用 proxy 替代)
+3. **Global Data (全局数据)**:
+   - `app.globalData` is still used for runtime context (`hosId`, `channelId`, `config`). Do NOT remove these usages unless moving to Store. (保留 app.globalData 的运行时上下文)
+
+---
+
+## Skill: API Service Encapsulation & Import
+## 技能:API 服务封装与导入
+**Description**: Strict standards for defining and calling API services. (定义和调用 API 服务的严格标准)
+**Instructions**:
+1. **Import Rules (CRITICAL) (导入规则-关键)**:
+   - **MUST** use Named Imports: `import { apiName } from '@/service/...'`. (必须使用命名导入)
+   - **NEVER** use default imports (`import api from ...`) or wildcard imports. (禁止默认导入或通配符导入)
+   - **NEVER** use relative paths or `config/api`. Use aliases `@/pagesPersonal/...` etc. (禁止相对路径,使用别名)
+   - **NO `api.ts`**: Do NOT import/use `api.ts` objects. Explicitly concat URLs. (禁止使用 api.ts 对象)
+2. **Service Definition (服务定义)**:
+   - Import `handle`, `request` from `@kasite/uni-app-base`. (引入 handle, request)
+   - Use `handle.promistHandleNew` (New version). (使用 promistHandleNew)
+   - Return format: `return handle.catchPromiseNew(resp, () => resp)`. (返回格式规范)
+   - URL: Construct explicitly: `${REQUEST_CONFIG.BASE_URL}path/to/api`. (显式构造 URL)
+   - **Structure**: Group by business (e.g., `base/`, `home/`) and export via `index.ts`. (按业务分组并统一导出)
+3. **Calling APIs (调用 API)**:
+   - **MUST** destructure result: `let { resp, resData } = await apiName(params)`. (必须解构结果)
+   - **Validation**: **MUST** check `if (common.isNotEmpty(resp))` before processing data. (处理前必须校验 resp)
+   - **Variable Declaration**: Use `let resp`, **NEVER** `const resp`. (使用 let resp)
+   - **Naming Conflicts**: If API name matches local variable, RENAME local variable (e.g., `acceptCredit` -> `targetStatus`). (避免变量名冲突)
+   - **Serial Calls**: Rename result: `let { resp: listResp } = await nextApi(...)`. (串行调用需重命名结果)
+
+---
+
+## Skill: Utils, Hooks & Common Tools
+## 技能:工具、Hooks 与常用方法
+**Description**: Replacement rules for legacy utility libraries and global functions. (遗留工具库和全局函数的替换规则)
+**Instructions**:
+1. **Removed Objects (移除的对象)**:
+   - `publicFn` (Object) -> REMOVED. Use Named Import. (移除 publicFn 对象)
+   - `util` object -> REMOVED. (移除 util 对象)
+2. **Specific Replacements (特定替换)**:
+   - `publicFn.getMember` -> `await useGetMember()`.
+   - `util.getAuthorize.call(proxy)` -> `common.getAuthorize`.
+   - `publicFn.getLocation` -> `import { getLocation } from '@/utils'`.
+   - `publicFn.menuClick` -> `import { menuClick } from '@/utils'`.
+   - `getState.js` / `pagesPatientFn.js` -> `import { getState, pagesPatientFn } from '@/uni-app-base/utils'`. (必须使用 uni-app-base/utils 下的 TS 版本)
+3. **Menu Click Standard (菜单点击标准)**:
+   - Template: `:data-item="item" @click="fn"`.
+   - JS: `const fn = (e) => { menuClick(e, proxy, 'navigateTo'); }`. (3rd arg `skipWay` is optional).
+4. **Import Standards (导入标准 - CRITICAL)**:
+   - **common**: `import { common } from '@/utils'` (Named Import ONLY). (必须解构导入)
+   - **publicFn**: `import { publicFn } from '@/utils'` (Named Import ONLY). (必须解构导入)
+   - **icon**: `import icon from '@/utils/icon'` (Default Import ONLY). (必须默认导入)
+5. **Common Methods (常用方法)**:
+   - Use `common.deepCopy(obj)` for deep copying. (深拷贝)
+   - Use `common.throttle(fn, time)` for throttling. (节流)
+6. **Icon Usage (图标使用)**:
+   - JS: `const iconUrl = ref(icon.someIcon)`.
+   - Template: `<image :src="iconUrl" />`.
+
+---
+
+## Skill: Styling, Units & Assets
+## 技能:样式、单位与资源
+**Description**: Rules for CSS units, static assets, and style migration. (CSS 单位、静态资源和样式迁移规则)
+**Instructions**:
+1. **Units (单位)**:
+   - **Strictly** convert all `rpx` to `upx`. (严格将 rpx 转换为 upx)
+2. **Images (图片)**:
+   - Background images in CSS: Use absolute paths (`/static/...`) or full URLs. (CSS 背景图使用绝对路径)
+   - Template images: Use `iconUrl` ref pattern. (模板图片使用 iconUrl ref 模式)
+3. **Preservation (保留)**:
+   - Keep original CSS logic. Only fix layout breaks caused by platform differences. (保留原 CSS 逻辑,仅修复布局错误)
+
+---
+
+## Skill: General UniApp API & Platform Differences
+## 技能:通用 UniApp API 与平台差异
+**Description**: Mapping WeChat APIs to UniApp and handling platform quirks. (微信 API 映射到 UniApp 及平台特性处理)
+**Instructions**:
+1. **Namespace (命名空间)**:
+   - Replace `wx.` with `uni.` (e.g., `wx.request` -> `uni.request`). (wx. 替换为 uni.)
+2. **Specific API Adjustments (特定 API 调整)**:
+   - `wx.getStorageSync` -> `uni.getStorageSync`.
+   - `wx.createSelectorQuery()` -> `uni.createSelectorQuery().in(this)` (MUST add `.in(this)`). (必须添加 .in(this))
+   - `wx.navigateToMiniProgram` -> `uni.navigateToMiniProgram`.
+3. **Compatibility (兼容性)**:
+   - `uni.getDeviceInfo`: If unavailable, fallback to `uni.getSystemInfoSync()`. (设备信息获取降级处理)
+4. **Environment (环境)**:
+   - **H5**: Uses proxy (`/api` -> `VITE_APP_PROXY_API_BASE_URL`). (H5 使用代理)
+   - **Mini Program**: Must use absolute URL (from `REQUEST_CONFIG` or `useDomain()`). (小程序使用绝对路径)
+
+---
+
+## Skill: State Management (Store)
+## 技能:状态管理 (Store)
+**Description**: Using `@kasite/uni-app-base` store and replacing globalData. (使用 store 替换 globalData)
+**Instructions**:
+1. **Access (访问)**:
+   - Use `import { useStore } from 'vuex'; const store = useStore();`.
+   - Replaces `getApp().globalData` for reactive state (token, currentUser). (替换 globalData 中的响应式状态)
+2. **Token/OpenId**:
+   - **FORBIDDEN**: `uni.getStorageSync('token'|'openid')`. (禁止直接读取缓存 token/openid)
+   - **MUST USE**: `store.state.token`, `store.state.openId`, `store.state.smallProOpenId`. (必须通过 store 获取)
+3. **Helpers (辅助函数)**:
+   - Use `mapState`, `mapMutations` from `@kasite/uni-app-base/store` if needed.
+
+---
+
+## Skill: Third-Party Libraries & Components
+## 技能:第三方库与组件
+**Description**: Handling external libraries (xbossTrack) and Easycom components. (处理外部库和 Easycom 组件)
+**Instructions**:
+1. **xbossTrack (Tracking) (埋点)**:
+   - `Page` constructor hijacking DOES NOT WORK in UniApp. (UniApp 中 Page 劫持无效)
+   - Use **Global Mixin** in `main.js` or `App.vue` for `onShow` tracking. (使用全局 Mixin 处理 onShow 埋点)
+   - For element tracking: Add explicit `@click="trackEvent"` or use a custom directive. (元素埋点显式添加事件)
+   - **Integrity**: Do NOT delete tracking logic; migrate or add TODO. (不要删除埋点逻辑)
+2. **Rich Text (富文本)**:
+   - **REPLACE** `towxml` with `mp-html` (`uni_modules`). (使用 mp-html 替换 towxml)
+   - Usage: `<mp-html :content="html" :domain="domain" />`.
+3. **Easycom**:
+   - Components in `uni_modules` are auto-imported. No need for `import` + `components: {}`. (uni_modules 组件自动导入)
+
+---
+
+## Skill: Project Specific Hooks & Startup
+## 技能:项目特定 Hooks 与启动流程
+**Description**: Custom hooks required by the specific project architecture. (项目架构要求的自定义 Hooks)
+**Instructions**:
+1. **Load & Member (加载与成员)**:
+   - `useOnLoad(async (opt) => { ... })`: Wraps onLoad logic. (封装 onLoad 逻辑)
+   - `usePreserMember()`: Pre-processes patient/member info. (预处理成员信息)
+   - `useGetDefaultMember()`: Gets default member. (获取默认成员)
+   - `useIsToAuthPage()`: Auth check. (授权检查)
+2. **Startup Flow (App.vue) (启动流程)**:
+   - Sequence: Version -> Config -> State -> Login -> Menu -> WebSocket. (启动顺序)
+3. **Optimization Rule (优化规则)**:
+   - IF `queryMemberCardList_V3` is called with ONLY `memberId`, REPLACE with `queryMemberCardList_V3` from hook. (特定 API 替换为 Hook)
+
+---
+
+## Skill: Migration Workflow (Reference)
+## 技能:迁移工作流 (参考)
+**Description**: Recommended step-by-step process for high-quality migration. (高质量迁移的推荐步骤)
+**Instructions**:
+1. **Step 1: Template (模板)**: Convert WXML to Vue template. Fix directives, events, and bindings. (转换模板,修复指令/事件/绑定)
+2. **Step 2: Logic (逻辑)**: Convert JS to TS setup. Handle `proxy`, `app`, `ref`, and lifecycle. (转换逻辑,处理实例与生命周期)
+3. **Step 3: Hooks (Hooks)**: Integrate `useOnLoad`, `usePreserMember`, etc. (接入 Hooks)
+4. **Step 4: API (API)**: Replace `wx.request` with named service imports. (替换 API 请求)
+5. **Step 5: Styles (样式)**: Convert `wxss` to `scss`, replace `rpx` with `upx`. (转换样式,替换单位)
+6. **Step 6: Verify (验证)**: Check rendering, interactions, and console for errors. (验证渲染、交互和报错)

+ 242 - 0
TRAE_SKILLS.md

@@ -0,0 +1,242 @@
+# Trae Skills for UniApp Migration (Granular)
+# UniApp 迁移技能 (细粒度)
+
+This document contains highly granular skills derived from `WX_TO_UNIAPP_RULES.md` for precise context injection in Trae.
+本文档包含源自 `WX_TO_UNIAPP_RULES.md` 的高细粒度技能,用于 Trae 的精准上下文注入。
+
+## Skill: File Extension & Project Structure Migration
+## 技能:文件扩展名与项目结构迁移
+**Description**: Rules for converting file types and mapping project configuration. (文件类型转换与项目配置映射规则)
+**Instructions**:
+1. **File Merging (文件合并)**:
+   - Merge `.wxml`, `.wxss`, and `.js` into a single `.vue` file. (将 .wxml, .wxss, .js 合并为单个 .vue 文件)
+   - `.wxml` content goes into `<template>`. (.wxml 内容放入 <template>)
+   - `.wxss` content goes into `<style lang="scss">`. (.wxss 内容放入 <style lang="scss">)
+   - `.js` content goes into `<script setup lang="ts">`. (.js 内容放入 <script setup lang="ts">)
+2. **Configuration Files (配置文件)**:
+   - **DELETE** `.json` page configuration files. (删除页面 .json 配置文件)
+   - **Migration**: Extract `navigationBarTitleText` from `.json` and move to `pages.json` (`style` or `globalStyle`). (提取标题配置迁移至 pages.json)
+   - **Subpackages**: Move `app.json` `subpackages` to `pages.json` `subPackages` field. (迁移分包配置)
+   - **Global Styles**: Move `app.wxss` content to `App.vue` `<style>` or `@import` a global css file. (全局样式迁移至 App.vue)
+   - **Route Check**: If a file is a page (not in `components/`) and has no route, **MUST** register it in `pages.json`. (页面必须在 pages.json 注册)
+3. **Independent Files (独立文件)**:
+   - Rename public `.wxss` to `.scss`. (公共 .wxss 重命名为 .scss)
+   - Rename util `.js` to `.ts`. (工具 .js 重命名为 .ts)
+   - Update all `@import` paths in code to reflect new extensions. (更新代码中的 @import 路径)
+4. **Cleanup (清理)**:
+   - After verification, DELETE the original `.wxml`, `.wxss`, `.js`, `.json` files. (验证后删除原文件)
+
+---
+
+## Skill: WXML to Vue Template Conversion
+## 技能:WXML 到 Vue 模板转换
+**Description**: Syntax mapping from WeChat Mini Program templates to Vue 3 templates. (微信小程序模板到 Vue 3 模板的语法映射)
+**Instructions**:
+1. **Directives (指令)**:
+   - `wx:if`, `wx:elif`, `wx:else` -> `v-if`, `v-else-if`, `v-else`.
+   - `wx:for="{{list}}"` -> `v-for="(item, index) in list" :key="index"`.
+   - `wx:key="id"` -> `:key="item.id"`.
+   - **Slicing**: For `v-if="index < 3"`, REPLACE with `v-for="... in list.slice(0, 3)"`. (限制循环数量使用 slice)
+2. **Events (事件)**:
+   - `bindtap="fn"` -> `@click="fn"`.
+   - `catchtap="fn"` -> `@click.stop="fn"`.
+   - `bindinput="fn"` -> `@input="fn"`.
+3. **Dataset & Attributes (数据集与属性)**:
+   - `data-xxx="{{val}}"` -> Prefer passing args: `@click="fn(val)"`. (优先传参替代 dataset)
+   - If preserving dataset (Required for `menuClick`): Use `:data-xxx="val"`. Access in JS via `e.currentTarget?.dataset?.xxx` (Must use optional chaining). (保留 dataset 时需使用可选链访问)
+   - `style="{{...}}"` -> `:style="..."`.
+4. **Logic Constraints (逻辑约束)**:
+   - **NEVER** use `v-if` and `v-for` on the same element. Use `<template v-for>` wrapper. (禁止同时使用 v-if 和 v-for)
+   - **Deep Access**: `v-if="menuObj?.Children?.[0]?.Children"` (Use optional chaining for all deep paths). (深层对象访问必须使用可选链)
+
+---
+
+## Skill: JS Logic & Lifecycle Migration
+## 技能:JS 逻辑与生命周期迁移
+**Description**: Converting Mini Program JS logic to Vue 3 Composition API. (将小程序 JS 逻辑转换为 Vue 3 组合式 API)
+**Instructions**:
+1. **Structure (结构)**:
+   - Replace `Page({})` with `<script setup lang="ts">`. (替换 Page 为 script setup)
+   - Remove `app.js` logic; move to `App.vue` or Hooks. (移除 app.js 逻辑)
+2. **State Management (状态管理)**:
+   - `data: { x: 1 }` -> `const x = ref(1)`.
+   - `this.setData({ x: 2 })` -> `x.value = 2`.
+   - `this.setData({ 'a.b': 2 })` -> `a.value.b = 2`.
+   - **FORBIDDEN**: Do not use `this` keyword for state. (禁止使用 this)
+3. **Lifecycle (生命周期)**:
+   - `onLoad` -> `onLoad` (from `@dcloudio/uni-app`) or `useOnLoad`.
+   - `onShow` -> `onShow`.
+   - `onReady` -> `onReady`.
+   - **Context**: `getCurrentPages()` is allowed for page stack checks. (允许使用 getCurrentPages)
+4. **Components (组件)**:
+   - `properties` -> `withDefaults(defineProps<{...}>(), {...})`.
+   - `triggerEvent` -> `const emit = defineEmits([...]); emit('event')`.
+   - `this.selectComponent` targets -> Child component must use `defineExpose({ method })`. (子组件需 expose 方法)
+   - **Observers**: Replace `properties: { observer: ... }` with `watch(() => props.propName, (val) => { ... })`. (使用 watch 替代 observer)
+5. **Safety (安全)**:
+   - `onLoad` params: `JSON.parse` MUST be inside `try-catch` to prevent white screen crashes. (JSON.parse 必须加 try-catch)
+
+---
+
+## Skill: Page & App Instance Management
+## 技能:页面与 App 实例管理
+**Description**: Correctly obtaining and using `proxy` and `app` instances. (正确获取和使用 proxy 及 app 实例)
+**Instructions**:
+1. **Setup (初始化)**:
+   - **MUST** be at the top of `<script setup>` (必须在 script setup 顶部):
+     ```ts
+     import { getCurrentInstance } from 'vue';
+     const { proxy } = getCurrentInstance() as any;
+     const app = getApp();
+     ```
+2. **Restrictions (限制)**:
+   - **NEVER** call `getCurrentInstance()` or `getApp()` repeatedly inside functions. (禁止在函数内重复调用)
+   - **NEVER** use `this` in setup; use `proxy` instead. (setup 中禁止使用 this,用 proxy 替代)
+3. **Global Data (全局数据)**:
+   - `app.globalData` is still used for runtime context (`hosId`, `channelId`, `config`). Do NOT remove these usages unless moving to Store. (保留 app.globalData 的运行时上下文)
+
+---
+
+## Skill: API Service Encapsulation & Import
+## 技能:API 服务封装与导入
+**Description**: Strict standards for defining and calling API services. (定义和调用 API 服务的严格标准)
+**Instructions**:
+1. **Import Rules (CRITICAL) (导入规则-关键)**:
+   - **MUST** use Named Imports: `import { apiName } from '@/service/...'`. (必须使用命名导入)
+   - **NEVER** use default imports (`import api from ...`) or wildcard imports. (禁止默认导入或通配符导入)
+   - **NEVER** use relative paths or `config/api`. Use aliases `@/pagesPersonal/...` etc. (禁止相对路径,使用别名)
+   - **NO `api.ts`**: Do NOT import/use `api.ts` objects. Explicitly concat URLs. (禁止使用 api.ts 对象)
+2. **Service Definition (服务定义)**:
+   - Import `handle`, `request` from `@kasite/uni-app-base`. (引入 handle, request)
+   - Use `handle.promistHandleNew` (New version). (使用 promistHandleNew)
+   - Return format: `return handle.catchPromiseNew(resp, () => resp)`. (返回格式规范)
+   - URL: Construct explicitly: `${REQUEST_CONFIG.BASE_URL}path/to/api`. (显式构造 URL)
+   - **Structure**: Group by business (e.g., `base/`, `home/`) and export via `index.ts`. (按业务分组并统一导出)
+3. **Calling APIs (调用 API)**:
+   - **MUST** destructure result: `let { resp, resData } = await apiName(params)`. (必须解构结果)
+   - **Validation**: **MUST** check `if (common.isNotEmpty(resp))` before processing data. (处理前必须校验 resp)
+   - **Variable Declaration**: Use `let resp`, **NEVER** `const resp`. (使用 let resp)
+   - **Naming Conflicts**: If API name matches local variable, RENAME local variable (e.g., `acceptCredit` -> `targetStatus`). (避免变量名冲突)
+   - **Serial Calls**: Rename result: `let { resp: listResp } = await nextApi(...)`. (串行调用需重命名结果)
+
+---
+
+## Skill: Utils, Hooks & Common Tools
+## 技能:工具、Hooks 与常用方法
+**Description**: Replacement rules for legacy utility libraries and global functions. (遗留工具库和全局函数的替换规则)
+**Instructions**:
+1. **Removed Objects (移除的对象)**:
+   - `publicFn` (Object) -> REMOVED. Use Named Import. (移除 publicFn 对象)
+   - `util` object -> REMOVED. (移除 util 对象)
+2. **Specific Replacements (特定替换)**:
+   - `publicFn.getMember` -> `await useGetMember()`.
+   - `util.getAuthorize.call(proxy)` -> `common.getAuthorize`.
+   - `publicFn.getLocation` -> `import { getLocation } from '@/utils'`.
+   - `publicFn.menuClick` -> `import { menuClick } from '@/utils'`.
+   - `getState.js` / `pagesPatientFn.js` -> `import { getState, pagesPatientFn } from '@/uni-app-base/utils'`. (必须使用 uni-app-base/utils 下的 TS 版本)
+3. **Menu Click Standard (菜单点击标准)**:
+   - Template: `:data-item="item" @click="fn"`.
+   - JS: `const fn = (e) => { menuClick(e, proxy, 'navigateTo'); }`. (3rd arg `skipWay` is optional).
+4. **Import Standards (导入标准 - CRITICAL)**:
+   - **common**: `import { common } from '@/utils'` (Named Import ONLY). (必须解构导入)
+   - **publicFn**: `import { publicFn } from '@/utils'` (Named Import ONLY). (必须解构导入)
+   - **icon**: `import icon from '@/utils/icon'` (Default Import ONLY). (必须默认导入)
+5. **Common Methods (常用方法)**:
+   - Use `common.deepCopy(obj)` for deep copying. (深拷贝)
+   - Use `common.throttle(fn, time)` for throttling. (节流)
+6. **Icon Usage (图标使用)**:
+   - JS: `const iconUrl = ref(icon.someIcon)`.
+   - Template: `<image :src="iconUrl" />`.
+
+---
+
+## Skill: Styling, Units & Assets
+## 技能:样式、单位与资源
+**Description**: Rules for CSS units, static assets, and style migration. (CSS 单位、静态资源和样式迁移规则)
+**Instructions**:
+1. **Units (单位)**:
+   - **Strictly** convert all `rpx` to `upx`. (严格将 rpx 转换为 upx)
+2. **Images (图片)**:
+   - Background images in CSS: Use absolute paths (`/static/...`) or full URLs. (CSS 背景图使用绝对路径)
+   - Template images: Use `iconUrl` ref pattern. (模板图片使用 iconUrl ref 模式)
+3. **Preservation (保留)**:
+   - Keep original CSS logic. Only fix layout breaks caused by platform differences. (保留原 CSS 逻辑,仅修复布局错误)
+
+---
+
+## Skill: General UniApp API & Platform Differences
+## 技能:通用 UniApp API 与平台差异
+**Description**: Mapping WeChat APIs to UniApp and handling platform quirks. (微信 API 映射到 UniApp 及平台特性处理)
+**Instructions**:
+1. **Namespace (命名空间)**:
+   - Replace `wx.` with `uni.` (e.g., `wx.request` -> `uni.request`). (wx. 替换为 uni.)
+2. **Specific API Adjustments (特定 API 调整)**:
+   - `wx.getStorageSync` -> `uni.getStorageSync`.
+   - `wx.createSelectorQuery()` -> `uni.createSelectorQuery().in(this)` (MUST add `.in(this)`). (必须添加 .in(this))
+   - `wx.navigateToMiniProgram` -> `uni.navigateToMiniProgram`.
+3. **Compatibility (兼容性)**:
+   - `uni.getDeviceInfo`: If unavailable, fallback to `uni.getSystemInfoSync()`. (设备信息获取降级处理)
+4. **Environment (环境)**:
+   - **H5**: Uses proxy (`/api` -> `VITE_APP_PROXY_API_BASE_URL`). (H5 使用代理)
+   - **Mini Program**: Must use absolute URL (from `REQUEST_CONFIG` or `useDomain()`). (小程序使用绝对路径)
+
+---
+
+## Skill: State Management (Store)
+## 技能:状态管理 (Store)
+**Description**: Using `@kasite/uni-app-base` store and replacing globalData. (使用 store 替换 globalData)
+**Instructions**:
+1. **Access (访问)**:
+   - Use `import { useStore } from 'vuex'; const store = useStore();`.
+   - Replaces `getApp().globalData` for reactive state (token, currentUser). (替换 globalData 中的响应式状态)
+2. **Token/OpenId**:
+   - **FORBIDDEN**: `uni.getStorageSync('token'|'openid')`. (禁止直接读取缓存 token/openid)
+   - **MUST USE**: `store.state.token`, `store.state.openId`, `store.state.smallProOpenId`. (必须通过 store 获取)
+3. **Helpers (辅助函数)**:
+   - Use `mapState`, `mapMutations` from `@kasite/uni-app-base/store` if needed.
+
+---
+
+## Skill: Third-Party Libraries & Components
+## 技能:第三方库与组件
+**Description**: Handling external libraries (xbossTrack) and Easycom components. (处理外部库和 Easycom 组件)
+**Instructions**:
+1. **xbossTrack (Tracking) (埋点)**:
+   - `Page` constructor hijacking DOES NOT WORK in UniApp. (UniApp 中 Page 劫持无效)
+   - Use **Global Mixin** in `main.js` or `App.vue` for `onShow` tracking. (使用全局 Mixin 处理 onShow 埋点)
+   - For element tracking: Add explicit `@click="trackEvent"` or use a custom directive. (元素埋点显式添加事件)
+   - **Integrity**: Do NOT delete tracking logic; migrate or add TODO. (不要删除埋点逻辑)
+2. **Rich Text (富文本)**:
+   - **REPLACE** `towxml` with `mp-html` (`uni_modules`). (使用 mp-html 替换 towxml)
+   - Usage: `<mp-html :content="html" :domain="domain" />`.
+3. **Easycom**:
+   - Components in `uni_modules` are auto-imported. No need for `import` + `components: {}`. (uni_modules 组件自动导入)
+
+---
+
+## Skill: Project Specific Hooks & Startup
+## 技能:项目特定 Hooks 与启动流程
+**Description**: Custom hooks required by the specific project architecture. (项目架构要求的自定义 Hooks)
+**Instructions**:
+1. **Load & Member (加载与成员)**:
+   - `useOnLoad(async (opt) => { ... })`: Wraps onLoad logic. (封装 onLoad 逻辑)
+   - `usePreserMember()`: Pre-processes patient/member info. (预处理成员信息)
+   - `useGetDefaultMember()`: Gets default member. (获取默认成员)
+   - `useIsToAuthPage()`: Auth check. (授权检查)
+2. **Startup Flow (App.vue) (启动流程)**:
+   - Sequence: Version -> Config -> State -> Login -> Menu -> WebSocket. (启动顺序)
+3. **Optimization Rule (优化规则)**:
+   - IF `queryMemberCardList_V3` is called with ONLY `memberId`, REPLACE with `queryMemberCardList_V3` from hook. (特定 API 替换为 Hook)
+
+---
+
+## Skill: Migration Workflow (Reference)
+## 技能:迁移工作流 (参考)
+**Description**: Recommended step-by-step process for high-quality migration. (高质量迁移的推荐步骤)
+**Instructions**:
+1. **Step 1: Template (模板)**: Convert WXML to Vue template. Fix directives, events, and bindings. (转换模板,修复指令/事件/绑定)
+2. **Step 2: Logic (逻辑)**: Convert JS to TS setup. Handle `proxy`, `app`, `ref`, and lifecycle. (转换逻辑,处理实例与生命周期)
+3. **Step 3: Hooks (Hooks)**: Integrate `useOnLoad`, `usePreserMember`, etc. (接入 Hooks)
+4. **Step 4: API (API)**: Replace `wx.request` with named service imports. (替换 API 请求)
+5. **Step 5: Styles (样式)**: Convert `wxss` to `scss`, replace `rpx` with `upx`. (转换样式,替换单位)
+6. **Step 6: Verify (验证)**: Check rendering, interactions, and console for errors. (验证渲染、交互和报错)

+ 101 - 0
WECHAT_HEALTH_CARD_SKILLS.md

@@ -0,0 +1,101 @@
+# 技能:微信电子健康卡对接
+
+**描述**: 在 UniApp 中集成微信官方电子健康卡插件的完整指南。
+
+## 1. 前置条件
+- **平台**: 仅限微信小程序 (`mp-weixin`)。**不支持** App 或 H5 端直接使用。
+- **账号**: 必须先在微信公众平台申请开通插件。
+  - **路径**: 登录微信公众平台 → 小程序 → 插件管理 → 添加插件 → 搜索 "电子健康卡" 并申请。
+
+## 2. 配置 (Manifest)
+**文件**: `manifest.json`
+**操作**: 在 `mp-weixin` 节点下添加插件声明。
+
+```json
+"mp-weixin": {
+  "appid": "你的小程序appid",
+  "plugins": {
+    "healthCard": {
+      "version": "1.x.x",   // 请以微信后台显示的最新版本号为准
+      "provider": "wxe5f52902cf4de896"  // 电子健康卡插件官方原始 ID
+    }
+  }
+}
+```
+
+## 3. 实现 - 嵌入插件组件 (场景A)
+**适用场景**: 插件提供了一个组件 (Component),你需要将其嵌入到自己的页面中显示。
+
+**步骤 1**: 在 `pages.json` 中注册组件
+找到你需要引入插件的页面配置,添加 `usingComponents` 节点:
+```json
+// pages.json
+{
+  "pages": [
+    {
+      "path": "pages/health-card/index",
+      "style": {
+        "navigationBarTitleText": "健康卡",
+        "usingComponents": {
+          // 定义组件名: 插件协议://插件名/组件路径
+          "health-card-comp": "plugin://healthCard/healthCardQueryComp"
+        }
+      }
+    }
+  ]
+}
+```
+
+**步骤 2**: 在页面中直接使用组件
+```vue
+<template>
+  <view class="container">
+    <!-- 直接使用 pages.json 中注册的标签名 -->
+    <health-card-comp
+      @success="onSuccess"
+      @fail="onFail"
+    />
+  </view>
+</template>
+
+<script setup lang="ts">
+const onSuccess = (e: any) => {
+  console.log('组件回调成功', e.detail);
+};
+
+const onFail = (e: any) => {
+  console.error('组件回调失败', e.detail);
+};
+</script>
+```
+
+## 4. 实现 - 跳转插件页面 (场景B)
+**适用场景**: 插件提供了一个完整的页面 (Page),你需要从当前小程序跳转过去。
+
+**代码**:
+```ts
+// 使用 plugin:// 协议直接跳转
+// 格式: plugin://插件名/页面路径
+uni.navigateTo({
+  url: 'plugin://healthCard/index', 
+  success: () => {
+    console.log('跳转插件页面成功');
+  },
+  fail: (err) => {
+    console.error('跳转失败', err);
+  }
+});
+```
+
+> **提示**: 具体的 **组件路径** (如 `healthCardQueryComp`) 和 **页面路径** (如 `index`) 必须查阅该插件的官方文档,不同插件提供商的路径定义不同。
+
+## 5. 调试与发布
+- **调试**: 在 HBuilderX 中运行到「微信开发者工具」,确保控制台无报错。
+- **发布**: 体验版测试通过后,提交微信审核并发布。
+- **注意**: 确保 `manifest.json` 中的插件版本号与微信后台可用的版本一致。
+
+## 6. 注意事项
+- **多端兼容性**: 该方案**仅适用**于微信小程序端。
+  - **App 端**: 无法直接嵌入插件。必须通过 SDK (如 `launchMiniProgram`) 唤起微信 App 打开电子健康卡小程序。
+  - **H5 端**: 不支持。
+- **文档更新**: 插件的 `version` (版本号)、`provider` (插件ID) 和 `pluginPage` (页面路径) 可能会随官方更新而变化,请始终以微信官方文档为准。

+ 395 - 0
WX_TO_UNIAPP_RULES.md

@@ -0,0 +1,395 @@
+# 微信小程序转 UniApp 详细迁移指南
+
+> **⚠️ 核心规则提示**
+> 本项目的**核心强制规则**(如接口规范、工具类替代、样式单位等)已提取至根目录下的 `.cursorrules` 文件。
+> 在进行代码转换时,AI 助手**必须优先遵循 .cursorrules** 中的指令。
+> 本文档作为**详细参考手册**,提供具体的代码示例、复杂场景说明和完整的迁移背景。
+
+## 核心避坑指南 (详细版)
+以下规则是 `.cursorrules` 的补充说明,包含具体代码示例:
+
+1.  **接口导入**:严禁使用 `config/api` 或相对路径引用接口。**必须**使用 `@/pagesPersonal/service/...` (分包) 或 `@/service/...` (主包)。
+    *   **重要**:接口导入**必须**使用解构导入(Named Imports),严禁使用默认对象导入(`import service from ...`)。
+    *   示例:`import { updateAccountAuthList as updateAccountAuthListApi, backstageDelUserMember_V3 } from '@/pagesPersonal/service/patientManagement';`
+2.  **接口返回**:**必须**遵循 `7.8 接口封装调用规范`。业务层调用 Service 方法时,**必须**使用解构获取返回值(如 `let { resp, resData } = await api()`)。严禁只解构 `{ resp }` 或假设接口直接返回数据对象。
+3.  **参数解码**:`onLoad` 解析参数时,`JSON.parse` **必须**包裹在 `try-catch` 中,防止因字符截断导致的白屏。
+4.  **Dataset**:模板中保留 `data-xxx` 时,JS 中必须使用 `e.currentTarget?.dataset?.xxx` 安全访问,防止 `undefined` 报错。
+5.  **变量冲突**:接口方法名与本地变量冲突时,**必须**重命名本地变量(如 `acceptCredit` -> `targetStatus`)。
+6.  **样式单位**:严禁使用 `rpx`。**必须**全文批量替换为 `upx`。
+7.  **工具类替代**:
+    *   `publicFn.getMember` -> `await useGetMember()`
+    *   `util.getAuthorize` -> `common.getAuthorize`
+    *   `utils` 导入 -> `import { common } from '@/utils'` (Common) / `import icon from '@/utils/icon'` (Icon)
+    *   **Legacy Utils**: `getState.js` 和 `pagesPatientFn.js` 必须替换为 TS 版本:
+        *   引用路径:`import { getState, pagesPatientFn } from '@/uni-app-base/utils'`
+        *   物理文件:`uni-app-base/utils/getState.ts` 和 `uni-app-base/utils/pagesPatientFn.ts`
+    *   **注意**:`icon` 是一个静态资源路径,**必须**使用 `ref(icon)` 包裹,防止在模板中直接引用导致的路径错误。变量名为 `iconUrl`,`image` 标签上有相关的 `src` 都要用 `iconUrl` 进行获取。
+21→
+22→8.  **代码完整性**:
+    *   **严禁漏掉代码**:迁移时必须逐行核对小程序源码(js/wxml/wxss),确保所有逻辑、事件绑定、样式规则都已迁移。
+    *   **平台差异处理**:如遇到无法直接迁移的逻辑(如 `xbossTrack`),严禁直接删除,必须在对应位置保留 TODO 注释并说明原因。
+
+## 1. 项目结构与配置
+
+### 配置文件
+*   **app.json**
+    *   内容迁移至 `pages.json`。
+    *   `pages` 数组保持不变,路径无需修改。
+    *   `subpackages` 分包配置直接迁移到 `pages.json` 的 `subPackages` 字段。
+    *   `window` 配置迁移至 `pages.json` 的 `globalStyle`。
+    *   `tabBar` 配置迁移至 `pages.json` 的 `tabBar`。
+*   **入口文件**
+    *   `app.js` 的逻辑迁移至 `App.vue`。
+    *   `globalData` 建议迁移至 `Vuex` 或 `Pinia` 状态管理,或者直接挂载到 `Vue.prototype` / `app.config.globalProperties`。
+    *   `onLaunch`, `onShow`, `onHide` 生命周期对应迁移到 `App.vue`。
+    *   当前项目使用 `App.vue` + 自定义 `hook` 完成启动逻辑(如版本检查、应用状态判断、登录、配置拉取、WebSocket 链接等),迁移时请将原 `app.js` 流程拆分为 Hook 并在 `App.vue` 中顺序调用。
+    *   全局数据 `globalData`:当前项目依旧使用 `getApp().globalData` 存储运行期上下文数据(如 `accountInfo`、`hosId`、`channelId`、`hasWebsocket` 等),迁移时优先复用此约定;如需长期状态请同步到 store。
+*   **路由配置**
+    *   若有生成新文件,需要在 `pages.json` 添加路由(`pages` 或 `subPackages`)以确保可访问。
+    *   **路由检测**:执行转换时,需检测当前文件是否有路由。若该文件是非组件(不在 `components` 文件夹下)且没有路由,必须在 `pages.json` 中定义。
+
+## 2. 页面与组件文件转换
+
+### 文件后缀
+*   `.wxml` -> `.vue` (放在 `<template>` 标签内)。
+*   `.wxss` -> `.vue` (放在 `<style>` 标签内)。
+*   `.js` -> `.vue` (放在 `<script>` 标签内)。
+*   `.json` -> 删除。
+    *   配置项(如 `navigationBarTitleText`)迁移至 `pages.json` 的 `style` 字段。
+    *   **标题提取**:若当前同级存在 `.json` 文件,`navigationBarTitleText` 必须从该 `.json` 文件中获取并同步到 `pages.json`。
+    *   组件引用 (`usingComponents`) 迁移至 `pages.json` (全局) 或 `.vue` 的 `components` 选项 (局部)。
+*   **独立文件转换规则**(必须修改后缀,禁止保留原小程序后缀):
+    *   `.wxss` (公共样式) -> `.scss`。
+    *   `.js` (工具/逻辑) -> `.ts`。
+    *   **注意**:修改文件名的同时,必须同步更新代码中的引用路径(如 `@import '...common.wxss'` -> `@import '...common.scss'`)。
+*   **文件清理**:页面/组件转换并验证通过后,**必须**删除同级目录下的原微信小程序文件(`.wxml`, `.wxss`, `.js`, `.json`),只保留 `.vue` 文件(及必要的独立 `.scss`/`.ts` 工具文件)。
+
+### JS 逻辑转换
+*   `Page({})` 替换为 `export default {}`。
+*   `data: { ... }` 替换为 `data() { return { ... } }`。
+*   `this.setData({ key: value })` 替换为 `key.value = value`。
+    *   **注意**:对于路径更新 `this.setData({ 'a.b': 1 })`,需改为 `a.value.b = 1`。
+*   `properties` (组件) 替换为 `props`。
+    *   **推荐写法**:使用 TypeScript 泛型语法配合 `withDefaults`,确保类型安全与默认值。
+        ```ts
+        const props = withDefaults(defineProps<{
+          userInfo?: any;
+          type?: string;
+        }>(), {
+          userInfo: () => ({}),
+          type: 'default'
+        });
+        ```
+*   **组件方法暴露**:原小程序通过 `this.selectComponent` 调用的组件方法,在 `<script setup>` 中**必须**使用 `defineExpose({ methodName })` 显式暴露,否则父组件无法调用。
+*   **页面上下文获取**:组件内若需获取当前页面路由或参数,可继续使用 `getCurrentPages()` 获取页面栈(注意判空与类型转换)。
+*   **生命周期映射**:
+    *   `onLoad` -> `onLoad` (UniApp 保留页面生命周期)。
+    *   `onShow` -> `onShow`。
+    *   `created`, `attached`, `detached` (组件) -> `created`, `mounted`, `beforeDestroy` (Vue 生命周期)。
+    *   当前项目页面常用模式(推荐按此迁移):
+      ```ts
+      <script lang="ts" setup>
+      import { ref } from 'vue';
+      import { useOnLoad } from '@/hook';
+      // 使用 getApp() 读取运行时全局数据
+      const app = getApp();
+      const list = ref<any[]>([]);
+      useOnLoad(async (options) => {
+        // 迁移原 onLoad 逻辑至此,保留原字段处理
+        // 复杂逻辑请加简要中文注释
+        
+        //  参数解析容错处理
+        if (options && options.myInfo) {
+          try {
+            const info = JSON.parse(decodeURIComponent(options.myInfo));
+            // 业务逻辑...
+          } catch (e) {
+            console.error('参数解析失败', e);
+            // 必要的兜底逻辑
+          }
+        }
+      });
+      </script>
+      ```
+
+### 模板语法转换
+*   `wx:if`, `wx:elif`, `wx:else` -> `v-if`, `v-else-if`, `v-else`。
+*   `wx:for="{{list}}"` -> `v-for="(item, index) in list" :key="index"`。
+*   `wx:key="id"` -> `:key="item.id"`。
+*   `bindtap="handler"` -> `@click="handler"`。
+*   `catchtap="handler"` -> `@click.stop="handler"`。
+*   `bindinput` -> `@input`。
+*   `data-xxx="{{value}}"` -> 建议改为函数传参 `@click="handler(value)"`。如果必须保留,使用 `:data-xxx="value"`,在事件对象 `e.currentTarget.dataset.xxx` 中获取。
+    *   **安全访问**:在 JS 中获取 dataset 时,必须使用可选链操作符:`const val = e.currentTarget?.dataset?.xxx;`,避免因事件冒泡或元素结构变化导致 `currentTarget` 为空引发的报错。
+*   注意 `v-for` 与 `v-if` 同时出现在同一元素会导致作用域问题(Vue 3 中 `v-if` 优先级更高),务必使用 `<template v-for>...</template>` 包裹并在内部元素上写 `v-if`,如:
+  ```vue
+  <template v-for="(item,index) in list" :key="index">
+    <view v-if="item?.IsShow == '1'">{{ item.MenuName }}</view>
+  </template>
+  ```
+*   **列表截取展示**:若需限制列表渲染数量(如仅展示前3条),禁止 `v-for` 与 `v-if` 混用(如 `v-if="index < 3"`),推荐在 `v-for` 中直接使用 `.slice(0, n)` 对数组进行切片,如 `v-for="(item, index) in list.slice(0, 3)"`。
+*   深层属性访问需判空:对于 `menuObj.Children[0].Children` 等层级,需在模板中加入 `v-if="menuObj?.Children?.[0]?.Children"` 保护。
+
+## 3. API 转换
+
+### 命名空间
+*   绝大多数 `wx.` API 可直接替换为 `uni.` (如 `wx.request` -> `uni.request`)。
+
+### 特殊 API
+*   `wx.getStorageSync` -> `uni.getStorageSync`。
+*   `wx.createSelectorQuery` -> `uni.createSelectorQuery().in(this)` (注意必须加 `.in(this)` 以确保在组件内正确查找)。
+*   `wx.navigateToMiniProgram` -> `uni.navigateToMiniProgram`(当前项目中个别地方仍保留 `wx` 调用,迁移时统一改成 `uni`)。
+*   设备信息获取兼容:低版本微信基础库可能缺少 `uni.getDeviceInfo`,需容错回退 `uni.getSystemInfoSync()`,避免字符串方法调用报错(已在 `uni_modules/mp-html/components/mp-html/parser.js` 中处理)。
+
+### 网络请求
+*   项目中的 `utils/request.js` 需要适配 `uni.request`,注意 `header` 和返回值的差异(uni-app 返回数组 `[error, res]` 或 Promise)。
+*   当前项目通过 `vite.config.js` 配置了代理与环境变量,H5 开发走本地代理 `/api -> VITE_APP_PROXY_API_BASE_URL`。小程序端请直接使用后端绝对域名,或在运行时使用 `useDomain()` 获取域名拼接接口路径。
+*   链接与域名拼接:富文本解析(mp-html)内已实现 `domain` 拼接与 `url` 处理(参考 [pagesAdmin/article/detail/detail.vue](e:/workingGroup/KST/systems/uniapp.patient/pagesAdmin/article/business/article/detail/detail.vue) 中的 `:domain="domain"`)。
+
+## 4. 样式与资源
+
+*   **单位**:项目内统一采用 `upx`(已对部分页面做了从 `rpx` 到 `upx` 的更正)。迁移时请保持一致。
+*   **背景图片**:`<style>` 中的背景图引用建议使用绝对路径(`/static/...`)或网络路径,避免相对路径带来的构建问题。
+*   **全局样式**:`app.wxss` 内容迁移至 `App.vue` 的 `<style>` 或单独的 `common.css` 并在 `App.vue` 中引入。
+*   **样式保持**:严禁随意添加非必要的 CSS 样式。必须严格保留原小程序的样式逻辑,仅在出现明显布局错乱或单位转换问题时进行最小化调整。
+
+## 5. 第三方库适配 (xbossTrack 重点)
+
+### 当前问题
+`xbossTrack` 通过劫持 `Page` 和 `App` 构造器实现埋点,这在 UniApp (基于 Vue) 中会失效。
+
+### 适配方案
+1.  **废弃 `wrapper.js`**:不再使用 `Page = ...` 这种方式。
+2.  **使用 Global Mixin**:在 `main.js` 中使用 `Vue.mixin` 全局混入生命周期逻辑。
+    ```javascript
+    // 示例思路
+    Vue.mixin({
+      onShow() {
+         // 调用 timeTracker 逻辑
+      },
+      methods: {
+         // 劫持 methods 需要在 beforeCreate 中遍历 this.$options.methods 进行包装
+         // 或者利用拦截器思路
+      }
+    })
+    ```
+3.  **Element Tracker**:
+    *   原有逻辑依赖 `catchtap` 冒泡捕获。在 Vue 中,建议创建一个自定义指令 `v-track` 或者在全局点击事件中处理(但要注意 Vue 事件处理机制)。
+    *   最简单的迁移方式是保留 `elementTracker` 方法,并在需要的元素上显式绑定 `@click="elementTracker($event)"`,或者重构为自动监听页面点击。
+
+## 6. 其他注意事项
+
+*   **分包预加载**:检查 `preloadRule` 配置。
+*   **自定义 TabBar**:如果使用了自定义 TabBar,需要按照 UniApp 的自定义 TabBar 规范重写。
+*   **Towxml**:Markdown 渲染库建议替换为 UniApp 插件市场中兼容 Vue 的 Parser 插件 (如 `mp-html`)。
+
+---
+
+## 7. 当前项目约定与依赖用法(迁移需遵循)
+
+### 7.1 Hook 与页面生命周期
+- 使用自定义 `hook` 管理页面加载与启动逻辑:
+  - `useOnLoad((options)=>{ ... })`:迁移原 `onLoad` 代码
+  - `usePreserMember()`:预处理就诊人,迁移涉及患者缓存的逻辑
+  - `publicFn.preserMember()` 逻辑替换为 `await usePreserMember()`
+  - `queryBaseMemberList_V3` 获取就诊人列表逻辑若用于初始化或预加载,建议使用 `usePreserMember()` 替代
+  - `useGetDefaultMember()`、`useIsToAuthPage()`:就诊人与授权判断逻辑
+  - `useDomain()`:获取域名用于接口与资源拼接
+  - **Hook 替代接口**:当发现代码中调用 `queryMemberCardList_V3` 且入参只有 `memberId` 时,可替换成 hook 中的 `queryMemberCardList_V3`。
+- 启动过程在 `App.vue` 中通过多个 Hook 串联(版本检查、配置拉取、应用状态判断、登录、菜单初始化、WebSocket 等),迁移时按步骤落地:
+  - 版本检查 -> 配置拉取 -> 应用状态 -> 登录 -> 菜单初始化 -> WebSocket(如启用)
+
+### 7.2 Store 使用(依赖 @kasite/uni-app-base)
+- 通过 `@kasite/uni-app-base/store` 暴露的辅助方法:
+  - `mapState({ token: 'token', currentUser: 'currentUser' })`
+  - `mapMutations({ setCurrentUser: 'setCurrentUser' })`
+- 迁移时保留对 `currentUser`、`memberList`、`token` 等原字段的读写,不做字段名转换。
+- **Token/OpenId 获取**:禁止使用 `uni.getStorageSync('token'|'openid'|'smallProOpenId')`。必须通过 `store.state.token`、`store.state.openId`、`store.state.smallProOpenId` 获取(需先 `import { useStore } from 'vuex'` 并在 setup 中 `const store = useStore()`)。
+
+### 7.3 工具方法约定
+- `utils/index.ts` 暴露:
+  - `export { common }`(来自 `@kasite/uni-app-base/utils`)
+  - `export const menuClick(e, _this, skipWay = 'navigateTo')`:菜单点击统一入口,迁移时所有功能入口点击尽量走此方法,保留原 `dataset` 字段读取约定(`data-item`、`data-item-parent`)。
+  - 依赖运行时 `getApp().globalData` 多处字段(如 `hosId`、`channelId`、`config.pageConfiguration`),迁移时不要改动字段名。
+- 页面点击事件参数需保留 `dataset` 约定:
+  ```vue
+  <view :data-item="item" :data-item-parent="parent" @click="menuClickFn"></view>
+  ```
+  ```ts
+  const menuClickFn = (e) => { menuClick(e, proxy); }
+  ```
+
+### 7.4 组件与 easycom
+- 项目启用 easycom:`uni_modules` 下的组件可直接在模板中使用,无需显式 `import` 与 `components` 注册。
+- 富文本:使用 `mp-html`(`uni_modules/mp-html`),在页面中直接写 `<mp-html :content="html" :domain="domain" />`。
+- 注意低版本兼容:`mp-html` 的解析器已针对 `system` 进行了容错,迁移时无需额外处理。
+
+### 7.5 构建与环境
+- `vite.config.js`:
+  - `@` 指向项目根目录,请统一使用 `@/...` 路径
+  - 开发代理:`/api -> VITE_APP_PROXY_API_BASE_URL`(H5)
+  - 非 H5 平台请确保接口为绝对域名或通过 `useDomain()` 构造完整 URL
+  - 代码混淆插件在特定平台与非开发环境启用,`uni_modules/**/*` 已排除
+- 环境变量位于 `env` 目录(使用 `loadEnv`),迁移时如需新变量请按现有 `.env` 约定添加。
+
+### 7.6 单位与样式
+- 统一采用 `upx`;已有页面(如 `homeSearch.vue`、`homePage.vue`)已完成从 `rpx` 到 `upx` 更正。迁移时保持一致。
+- 模板中避免直接使用 `style="{{...}}"` 的 WXML 写法,改为 `:style="..."`。
+
+### 7.7 引入路径与工具方法替换(针对本项目)
+- 迁移页面/组件时,所有 import 路径需根据当前 uni-app 项目结构调整,避免引用不存在模块(如 `utils/publicFn.js`)。统一从 `utils/index.ts` 引入已有工具方法。
+- 来院导航:统一使用 `utils/index.ts` 暴露的 `getLocation`,替换 `publicFn.getLocation`,保持原逻辑与字段不变。
+- 菜单点击:统一使用 `utils/index.ts` 暴露的 `menuClick`,替换 `publicFn.menuClick`,保留 `dataset` 传参约定(`data-item`、`data-item-parent`)。
+- **工具方法替换(common 与 icon 严禁混淆)**:
+  - **common**:必须使用**解构导入** `import { common } from '@/utils';`。严禁使用 `import common from '@/utils/common'` 或默认导入。
+  - **icon**:必须使用**默认导入** `import icon from '@/utils/icon';`。严禁从 `@/utils` 导入(如 `import { icon } from '@/utils'` 是错误的)。
+  - **publicFn**:必须使用**解构导入** `import { publicFn } from '@/utils';`。严禁使用 `import publicFn from '@/utils/publicFn'` 或默认导入。
+  - **getAuthorize**:将 `util.getAuthorize.call(proxy)` 替换为 `common.getAuthorize`。
+  - **util**:本项目不提供 `util` 对象。
+    - `publicFn.getMember` 必须替换为 `await useGetMember()`(需从 `@/hook` 导入)。
+    - 其他 `publicFn.xxx` 或 `util.xxx` 方法(如 `countDown`、`formatTime` 等),**必须**从 `common`或`publicFn` 中寻找对应方法替换(需 `import { common, publicFn } from '@/utils'`)。
+  - **getMember**:涉及获取就诊人的逻辑,统一使用 hook。
+- 其它工具方法优先从 `utils/index.ts` 或 `@kasite/uni-app-base` 提供的工具中引入,保持原字段不变,不做字段名转换。
+- 示例:
+  ```ts
+  // 正确示例:
+  import { common, getLocation, menuClick } from '@/utils';
+  import icon from '@/utils/icon';
+  
+  // 错误示例(严禁出现):
+  // import {common} from '@/utils'; // 错误:common 需解构
+  // import { icon } from '@/utils';      // 错误:icon 未在 utils/index.ts 导出
+  ```
+
+### 7.8 接口封装调用规范(迁移需遵循)
+- 目录结构:与 `pages/st1/service` 保持一致,建议按业务拆分为 `base/`、`home/`、`schemeDetail/` 等子目录,并在同级提供 `index.ts` 聚合导出。
+- 统一封装:使用 `@kasite/uni-app-base` 提供的 `request` 与 `handle`。
+  - **必须使用 New 版方法**:`handle.promistHandleNew` 和 `handle.catchPromiseNew`。
+  - **严禁使用旧版**:`promistHandle` 和 `catchPromise`。
+- **严禁引用不存在的 API 路径**:禁止使用 `config/api/...`,必须从 `@/pagesPersonal/service/...` 或各分包的 `service` 目录导入。
+- **严禁依赖 api.ts 对象**:Service 层必须直接拼接 URL,严禁导入 `import api from '@/config/api'` 或使用 `api.Key` 形式。所有接口路径必须在 Service 文件内显式定义。
+- **URL 拼接规范**:必须使用模板字符串 `${REQUEST_CONFIG.BASE_URL}wsgw/...` 进行拼接。
+- **变量声明与 Handle 调用规范**:
+  - 必须使用 `let resp` (严禁 `const`)。
+  - 必须遵循 `let resp = handle.promistHandleNew(await request.doPost(...))` 结构 (注意 `await` 位置)。
+- **返回值处理**:Service 层函数使用 `catchPromiseNew` 返回后,业务层调用**必须**使用解构获取 `resp` 和 `resData`。
+  - **标准写法**:`let { resp, resData } = await apiName(params);`
+  - **判断数据**:`if (common.isNotEmpty(resp)) { ... }`
+- **命名冲突处理**:当导入的接口函数名与页面内的业务变量名冲突时,**必须**重命名页面内的局部变量。
+- **串行调用与变量重命名**:当后续接口依赖前序接口结果时,应在 `if (common.isNotEmpty(resp))` 块内调用;为避免 `resp` 变量名冲突,后续接口调用**必须**使用解构重命名。
+  - **标准写法**:`let { resp: newName } = await nextApiName(params);`
+- **参考已完成页面**:`pages/st1/business/tabbar/homePage/homePage.vue` 和 `pages/st1/service/base/index.ts`。
+- 域名拼接:接口地址统一从 `REQUEST_CONFIG.BASE_URL` 获取。
+- **Service 封装示例**:
+  ```ts
+  import { REQUEST_CONFIG } from '@/config';
+  import { request, handle } from '@kasite/uni-app-base';
+
+  export const articleTypeListUrl = async (queryData: any) => {
+    let resp = handle.promistHandleNew(
+      await request.doPost(
+        `${REQUEST_CONFIG.BASE_URL}wsgw/article/type/List/callApiJSON.do`,
+        queryData
+      )
+    );
+    return handle.catchPromiseNew(resp, () => resp);
+  };
+  ```
+- **业务层调用示例**:
+  ```ts
+  import { articleTypeListUrl } from '@/pages/st1/service/base';
+  
+  const getData = async () => {
+    let { resp, resData } = await articleTypeListUrl({
+       ChannelId: app.globalData.channelId
+    });
+    if (common.isNotEmpty(resp)) {
+       console.log('Data:', resp);
+    }
+  };
+  ```
+- 聚合导出:在 `service/index.ts` 中统一 `export * from './base';`。
+- 引入路径:统一使用 `@` 别名。
+
+### 7.9 页面实例与App实例获取规范
+- **统一获取方式**:在 `<script setup>` 顶部统一获取 `proxy` 和 `app` 实例,严禁在函数内部重复调用 `getCurrentInstance()` 或 `getApp()`。
+- **规范示例**:
+  ```ts
+  <script lang="ts" setup>
+  import { getCurrentInstance } from 'vue';
+  
+  // 1. 获取当前组件实例代理
+  const { proxy } = getCurrentInstance();
+  // 2. 获取 App 全局实例
+  const app = getApp();
+  
+  // 业务逻辑中使用
+  const handleClick = () => {
+      // 使用 proxy
+      console.log(proxy);
+      // 使用 app
+      console.log(app.globalData);
+  }
+  </script>
+  ```
+- **禁止行为**:
+  - 禁止在方法内部定义 `let app = getApp()`。
+  - 禁止多次调用 `getCurrentInstance()`。
+  - 禁止使用 `this` (setup 中 `this` 为 undefined),应使用 `proxy`。
+
+## 8. 典型迁移示例
+
+### 8.1 页面(WXML/JS → Vue + Hook)
+```vue
+<template>
+  <view>
+    <view v-if="list.length === 0">暂无数据</view>
+    <view v-else v-for="(item, i) in list" :key="i" :data-item="item" @click="menuClickFn">
+      {{ item.MenuName }}
+    </view>
+  </view>
+</template>
+
+<script lang="ts" setup>
+import { ref, getCurrentInstance } from 'vue';
+import { useOnLoad } from '@/hook';
+import { common, menuClick } from '@/utils';
+const { proxy } = getCurrentInstance() as any;
+const app = getApp();
+const list = ref<any[]>([]);
+useOnLoad(async (options) => {
+  // 迁移 onLoad 逻辑,保持原字段
+  list.value = common.deepCopy(uni.getStorageSync('menuList') || []);
+});
+const menuClickFn = (e) => { menuClick(e, proxy); };
+</script>
+```
+
+### 8.2 组件(Component → Vue 组件)
+```vue
+<template>
+  <view>
+    <view v-for="(n, i) in flowListRender" :key="i" @click="toggle(i)">{{ n.NodeTitle }}</view>
+  </view>
+</template>
+<script lang="ts" setup>
+import { ref, watch } from 'vue';
+const props = defineProps<{ flowList: any[]; pageType: string }>();
+const flowListRender = ref<any[]>([]);
+watch(() => props.flowList, (val) => {
+  // 保留原字段与处理逻辑
+  flowListRender.value = (val || []).map((it) => ({ ...it, ShowContInfo: true }));
+}, { immediate: true });
+const toggle = (i: number) => { flowListRender.value[i].ShowContInfo = !flowListRender.value[i].ShowContInfo; };
+</script>
+```
+
+---
+
+## 9. 迁移流程建议(确保不影响现有逻辑)
+- 逐页迁移:按页面重要性与依赖顺序迁移,优先首页与公共组件
+- 模板先行:先将 WXML 改为 Vue 模板写法,完成指令、事件、绑定转换
+- Hook 接入:将页面 `onLoad/onShow` 逻辑接入 `useOnLoad`/生命周期,保留原字段与流程
+- 事件与菜单:统一接入 `utils/index.ts` 的 `menuClick`,保留 `dataset` 字段约定
+- 样式统一:单位统一改为 `upx`;背景图与资源路径按当前项目约定修正
+- 验证:运行对应平台,检查页面渲染、接口请求、跳转与交互;对复杂逻辑添加简要中文注释

+ 4 - 3
package.json

@@ -23,9 +23,10 @@
 		}
 	},
 	"dependencies": {
-		"@kasite/uni-app-base": "^0.0.1",
-		"mui-player": "^1.8.1",
-		"hls.js": "^1.6.13"
+		"@kasite/uni-app-base": "workspace:*",
+		"hls.js": "^1.6.13",
+		"marked": "^17.0.1",
+		"mui-player": "^1.8.1"
 	},
 	"devDependencies": {
 		"javascript-obfuscator": "^4.1.1",

+ 32 - 0
pages.json

@@ -464,6 +464,38 @@
 			"style": {
 				"navigationBarTitleText": "在线签到"
 			}
+		}, {
+			"path": "st1/business/yygh/waitRegistration/waitRegistration",
+			"style": {
+				"navigationBarTitleText": "候补挂号"
+			}
+		}, {
+			"path": "st1/business/yygh/waitSuccess/waitSuccess",
+			"style": {
+				"navigationBarTitleText": "候补登记"
+			}
+		}, {
+			"path": "st1/business/yygh/yyghClinicMsg/yyghClinicMsg",
+			"style": {
+				"navigationBarTitleText": "挂号"
+			}
+		}, {
+			"path": "st1/business/yygh/yyghDeptList/yyghDeptList",
+			"style": {
+				"navigationBarTitleText": "预约挂号",
+				"disableScroll": true
+			}
+		}, {
+			"path": "st1/business/yygh/yyghDoctorList/yyghDoctorList",
+			"style": {
+				"navigationBarTitleText": "排班",
+				"enablePullDownRefresh": false
+			}
+		}, {
+			"path": "st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor",
+			"style": {
+				"navigationBarTitleText": "历史医生"
+			}
 		}]
 	}],
 	"globalStyle": {

+ 1 - 1
pages/st1/components/pageActive/st1/components/activeFlow/activeFlow.vue

@@ -78,7 +78,7 @@
 </template>
 
 <script lang="ts" setup>
-import { defineProps, watch, getCurrentInstance, nextTick, ref } from 'vue';
+import { watch, getCurrentInstance, nextTick, ref } from 'vue';
 import typeBox from './flowTemplate/typeBox/typeBox.vue';
 import { getLocation, menuClick, common, constant } from '@/utils';
 import { dataCollection } from '@/pages/st1/components/pageActive/st1/service/active/index.ts';

+ 0 - 1
pages/st1/components/pageActive/st1/components/activeFlow/flowTemplate/BoxTest/BoxTest.vue

@@ -89,7 +89,6 @@
 </template>
 
 <script lang="ts" setup>
-import { defineProps, defineEmits } from 'vue';
 const props = defineProps<{ item: any; iconUrl: any }>();
 const emit = defineEmits(['clickBtn', 'clickReport']);
 

+ 0 - 1
pages/st1/components/pageActive/st1/components/activeFlow/flowTemplate/duringBill/duringBill.vue

@@ -54,7 +54,6 @@
 </template>
 
 <script lang="ts" setup>
-import { defineProps, defineEmits } from 'vue';
 const props = defineProps<{ item: any; iconUrl: any }>();
 const emit = defineEmits(['clickBtn', 'clickReport']);
 

+ 0 - 1
pages/st1/components/pageActive/st1/components/activeFlow/flowTemplate/typeBox/typeBox.vue

@@ -77,7 +77,6 @@
 </template>
 
 <script lang="ts" setup>
-import { defineProps, defineEmits } from 'vue';
 import BoxTest from '../BoxTest/BoxTest.vue';
 // 如有需要可以引入 duringBill:import duringBill from '../duringBill/duringBill.vue';
 

+ 1 - 1
pages/st1/components/pageActive/st1/components/guidedSuspension/guidedSuspension.vue

@@ -11,7 +11,7 @@
 import { ref } from 'vue';
 import icon from '@/utils/icon';
 import { common, constant } from '@/utils';
-import { getMemberLastMsg } from '@/pageActive/st1/service/active';
+import { getMemberLastMsg } from '@/pages/st1/components/pageActive/st1/service';
 
 const app = getApp();
 const iconUrl = ref(icon);

+ 0 - 367
pagesPatient/service/api.ts

@@ -1,367 +0,0 @@
-// @ts-ignore
-import api from '@/config/api';
-const ApiRootUrl = api.ApiRootUrl;
-
-export default {
-  ApiRootUrl,
-  /**
-   * 充值规则
-   */
-  QueryFrontPayLimit: ApiRootUrl + "wsgw/pay/PayMerchant/QueryFrontPayLimit/callApiJSON.do",
-  /**
-  * 查询余额
-   */
-  QueryCardBalance_V3: ApiRootUrl + 'wsgw/accountMember/api/QueryCardBalance_V3/callApiJSON.do',
-  // ======================================预约挂号=======================================
-  /**
-   * 咨询获取科室列表
-   */
-  QueryClinicBaseDept: ApiRootUrl + 'wsgw/yy/yygh/QueryClinicBaseDept/callApiJSON.do',
-    /**
-   * 查询门诊排班时间
-   */
-  QueryClinicScheduleDate: ApiRootUrl + "wsgw/yy/yygh/QueryClinicScheduleDate/callApiJSON.do",
-
-  /**
-   * 咨询查询门诊排班列表
-   */
-  QueryClinicDoctorSchedule: ApiRootUrl + "wsgw/yy/yygh/QueryClinicDoctorSchedule/callApiJSON.do",
-  /**
-   * 医生列表+详情信息
-   */
-  QueryClinicBaseDoctor: ApiRootUrl + 'wsgw/yy/yygh/QueryClinicBaseDoctor/callApiJSON.do',
-  /**
-   * 咨询搜索科室 医生
-   */
-  SearchClinicDeptAndDoctor: ApiRootUrl + "wsgw/yy/yygh/SearchClinicDeptAndDoctor/callApiJSON.do",
-  /**
-   * 搜索科室
-   */
-  QueryDeptList_V2: ApiRootUrl + "wsgw/basic/DeptApi/QueryDeptList_V2/callApiJSON.do",
-  /**
-   * 搜索医生
-   */
-  QueryDoctorList_V2: ApiRootUrl + "wsgw/basic/DoctorApi/QueryDoctorList_V2/callApiJSON.do",
-  /**
-   * 咨询查询历史医生
-   */
-  QueryHistoryBaseDoctor: ApiRootUrl + "wsgw/yy/yygh/QueryHistoryBaseDoctor/callApiJSON.do",
-  /**
-   * 
-   * 获取预约时间段
-   */
-  QueryNumbers: ApiRootUrl + "wsgw/yy/yygh/QueryNumbers/callApiJSON.do",
-  /**
-   * 锁号
-   */
-  LockOrder: ApiRootUrl + 'wsgw/yy/yygh/LockOrder/callApiJSON.do',
-  /**
-   * 释号
-   */
-  Unlock: ApiRootUrl + 'wsgw/yy/yygh/Unlock/callApiJSON.do',
-  /**
-   * 挂号(不支付)
-   */
-  BookService: ApiRootUrl + "wsgw/yy/yygh/BookService/callApiJSON.do",
-  /**
-   * 退号
-   */
-  HisYyCancel: ApiRootUrl + 'wsgw/yy/yygh/HisYyCancel/callApiJSON.do',
-    /**
-   * 退号
-   */
-  YYCancel: ApiRootUrl + 'wsgw/yy/yygh/YYCancel/callApiJSON.do',
-  /**
-   * 查询HIS排班列表
-   */
-  QueryScheduleList: ApiRootUrl + 'wsgw/yy/yygh/QueryScheduleList/callApiJSON.do',
-  /**
-   * HIS签到
-   */
-  RegSignForHis: ApiRootUrl + "/wsgw/queue/QueueWs/RegSignForHis/callApiJSON.do",
-  /**
-   *  查询预约记录
-   */
-  HisYyWaterList_V2: ApiRootUrl + 'wsgw/yy/yygh/HisYyWaterList_V2/callApiJSON.do',
-  /**
-   * 医技预约-医技预约回执单
-   */
-  GetAppointReceiptInfo: ApiRootUrl + 'wsgw/yy/yygh/GetAppointReceiptInfo/callApiJSON.do',
-  /**
-   * 医技预约查询检查预约信息
-   */
-  QueryExamItemList: ApiRootUrl + 'wsgw/yy/yygh/QueryExamItemList/callApiJSON.do',
-  /**
-   * 附二个性化获取医技回执单接口
-   */
-  GetMedicalReceipts: ApiRootUrl + 'wsgw/diy/queryApi/GetMedicalReceipts/callApiJSON.do',
-  /**
-   * 医技预约-取消医技预约
-   */
-  CancelAppoint: ApiRootUrl + 'wsgw/yy/yygh/CancelAppoint/callApiJSON.do',
-  // =========================查询报告=======================================
-  /**
-   * 获取报告单列表
-   */
-  GetReportList: ApiRootUrl + "wsgw/report/ReportWs/GetReportList/callApiJSON.do",
-  /**
-   * 获取体检报告单明细
-   */
-  GetTjReportInfo: ApiRootUrl + "wsgw/report/ReportWs/GetTjReportInfo/callApiJSON.do", 
-  /**
-   * 获取报告单明细
-   */
-  GetReportInfo: ApiRootUrl + "wsgw/report/ReportWs/GetReportInfo/callApiJSON.do",
-
-  // =========================订单=========================================
-  /**
-   * 生成订单
-   */
-  AddOrderLocal: ApiRootUrl + "wsgw/order/orderApi/AddOrderLocal/callApiJSON.do",
-  /**
-   * 查询本地订单列表
-   */
-  OrderListLocal: ApiRootUrl + "wsgw/order/orderApi/OrderListLocal/callApiJSON.do",
-  /**
-   * 查询本地订单详情
-   */
-  OrderDetailLocal: ApiRootUrl + "wsgw/order/orderApi/OrderDetailLocal/callApiJSON.do",
-  /**
-   * 取消订单
-   */
-  CancelOrder: ApiRootUrl + "wsgw/order/orderApi/CancelOrder/callApiJSON.do",
-
-
-  /**
-   * 预交金模式处方列表
-   */
-  QueryOrderSettlementList: ApiRootUrl + "wsgw/order/businessOrder/QueryOrderSettlementList/callApiJSON.do",
-  /**
-   * 订单模式合并处方列表
-   */
-  QueryOrderReceiptList: ApiRootUrl + "wsgw/order/businessOrder/QueryOrderReceiptList/callApiJSON.do",
-  /**
-   * 订单模式单笔处方列表
-   */
-  QueryOrderPrescriptionList: ApiRootUrl + "wsgw/order/businessOrder/QueryOrderPrescriptionList/callApiJSON.do",
-  /**
-   * 订单模式处方详情
-   */
-  QueryOrderPrescriptionInfo: ApiRootUrl + "wsgw/order/businessOrder/QueryOrderPrescriptionInfo/callApiJSON.do",
-  /**
-   * 预交金模式处方详情
-   */
-  QueryOrderSettlementInfo: ApiRootUrl + "wsgw/order/businessOrder/QueryOrderSettlementInfo/callApiJSON.do",
-  /**
-   * 预交金模式处方结算
-   */
-  SettleOrderSettlement: ApiRootUrl + "wsgw/order/businessOrder/SettleOrderSettlement/callApiJSON.do",
-  /**
-   * 订单模式单笔下单
-   */
-  AddOrderPrescription: ApiRootUrl + "wsgw/order/businessOrder/AddOrderPrescription/callApiJSON.do",
-  /**
-   * 订单模式合并下单
-   */
-  MergeSettledPayReceipt: ApiRootUrl + "wsgw/order/businessOrder/MergeSettledPayReceipt/callApiJSON.do",
-  // =========================记录=========================================
-
-  /**
-   * 查询门诊就诊记录
-   */
-  QueryOutpatientVisitList: ApiRootUrl + 'wsgw/member/memberApi/QueryOutpatientVisitList/callApiJSON.do',
-
-  /**
-   * 查询住院记录
-   */
-  QueryInpatientList: ApiRootUrl + 'wsgw/basic/InHosApi/QueryInpatientList/callApiJSON.do',
-  /*
-   * 查询病历列表 
-   */
-  GetMedicalRecords: ApiRootUrl + 'wsgw/report/ReportWs/GetMedicalRecords/callApiJSON.do',
-  /**
-   * 查询门诊医嘱处方信息
-   */
-  QueryOutpatientDocAdviceList: ApiRootUrl + 'wsgw/member/memberApi/QueryOutpatientDocAdviceList/callApiJSON.do',
-  /**
-   * 查询住院医嘱处方信息
-   */
-  QueryInpatientDocAdviceList: ApiRootUrl + 'wsgw/member/memberApi/QueryInpatientDocAdviceList/callApiJSON.do',
-
-  // =======================================满意度=======================================
-
-
-
-
-
-  // =======================================门诊住院清单=======================================
-  /**
-   * 门诊清单
-   */
-  QueryOutpatientCostList: ApiRootUrl + "wsgw/order/businessOrder/QueryOutpatientCostList/callApiJSON.do",
-  /**
-   * 门诊清单分类
-   */
-  QueryOutpatientCostType: ApiRootUrl + "wsgw/order/businessOrder/QueryOutpatientCostType/callApiJSON.do",
-  /**
-   * 门诊清单明细
-   */
-  QueryOutpatientCostTypeItem: ApiRootUrl + "wsgw/order/businessOrder/QueryOutpatientCostTypeItem/callApiJSON.do",
-  /**
-   * 住院清单列表
-   */
-  QueryInHospitalCostList: ApiRootUrl + "wsgw/order/businessOrder/QueryInHospitalCostList/callApiJSON.do",
-  /**
-   * 住院清单分类
-   */
-  QueryInHospitalCostType: ApiRootUrl + "wsgw/order/businessOrder/QueryInHospitalCostType/callApiJSON.do",
-  /**
-   * 住院清单每日清单详情
-   */
-  QueryInHospitalCostTypeItem: ApiRootUrl + "wsgw/order/businessOrder/QueryInHospitalCostTypeItem/callApiJSON.do",
-  // =======================================基础信息=======================================
-  /**
-   * 获取医院信息  
-   */
-  QueryBHospitalList: ApiRootUrl + 'wsgw/basic/HosApi/QueryBHospitalList/callApiJSON.do',
-  /*
-   * 科室介绍
-   */
-  QueryBaseDeptTreeV2: ApiRootUrl + 'wsgw/basic/DeptApi/QueryBaseDeptTreeV2/callApiJSON.do',
-  /*
-   * 专家介绍
-   */
-  DeptAndDocApiList: ApiRootUrl + 'wsgw/basic/DeptAndDocApi/List/callApiJSON.do',
-  /**
-    * 上传图片
-    */
-  UploadFile: ApiRootUrl + "upload/uploadFile.do",
-    /**
-   * 药品查询
-   */
-  QueryDrugList: ApiRootUrl + 'wsgw/basic/ExpenseStandard/QueryDrugList/callApiJSON.do',
-  /**
-   * 收费项查询
-   */
-  QueryExpensesItemList: ApiRootUrl + 'wsgw/basic/ExpenseStandard/QueryExpensesItemList/callApiJSON.do',
-  // =======================================候诊查询=======================================
-   /**
-     * 排队候诊列表
-     */
-    GetQueueInfo: ApiRootUrl + 'wsgw/queue/QueueWs/GetQueueInfo/callApiJSON.do',
-    /**
-     * 设置智能提醒
-     */
-    SetReMindNo: ApiRootUrl + "wsgw/queue/QueueWs/SetReMindNo/callApiJSON.do",
-  
-  // ======================================处方管理=======================================
-  /**
-    * 获取取药凭证
-    */
-   QueryDrugQueueList: ApiRootUrl + 'wsgw/net/QueueWs/QueryDrugQueueList/callApiJSON.do', 
-  
-  // ======================================电子病历=======================================
-  /**
-   * 获取电子病历明细
-   */
-  GetEMRInfo: ApiRootUrl + "wsgw/report/ReportWs/GetEMRInfo/callApiJSON.do",
-  // ======================================候补登记=======================================
-  /**校验是否可候补 */
-  CheckBeforeAddWaitList: ApiRootUrl + 'wsgw/yy/waitListApi/CheckBeforeAddWaitList/callApiJSON.do',
-  /**新增候补登记 */
-  WaitListApiAdd: ApiRootUrl + 'wsgw/yy/waitListApi/Add/callApiJSON.do',
-  /**查询候补记录 */
-  WaitListApiList: ApiRootUrl + 'wsgw/yy/waitListApi/List/callApiJSON.do',
-  /**更新候补登记 */
-  WaitListUpdate: ApiRootUrl + 'wsgw/yy/waitListApi/Update/callApiJSON.do',
-  /**获取候补医生名额 */
-  GetYyWaitCount: ApiRootUrl + 'wsgw/yy/waitListApi/GetYyWaitCount/callApiJSON.do',
-  
-  // ======================================出院带药=======================================
-  /** : 出院带药-详情 */
-  // QueryInpatientDocAdviceList: ApiRootUrl + 'wsgw/basic/InHosApi/QueryInpatientDocAdviceList/callApiJSON.do',
-  
-  // ======================================门诊退费=======================================
-  /**获取门诊退款金额*/
-  QueryMemberRefundableMoney: ApiRootUrl + "wsgw/smartPay/smartPayWs/QueryMemberRefundableMoney/callApiJSON.do",
-  /**预交金退款 退his和钱*/
-  ApplySelfServiceRefund: ApiRootUrl + "wsgw/order/businessOrder/ApplySelfServiceRefund/callApiJSON.do",
-  /**退款记录*/
-  QuerySelfRefundRecordList: ApiRootUrl + "wsgw/smartPay/smartPayWs/QuerySelfRefundRecordList/callApiJSON.do",
-  /**退款记录明细*/
-  QuerySelfRefundRecordInfo: ApiRootUrl + "wsgw/smartPay/smartPayWs/QuerySelfRefundRecordInfo/callApiJSON.do",
-  // ======================================退款申请功能=======================================
-  // 获取验证码
-  SendVerificationCode_V3 : ApiRootUrl + 'wsgw/accountMember/api/SendVerificationCode_V3/callApiJSON.do',
-  // 校验验证码
-  CheckVerificationCode_V3: ApiRootUrl + 'wsgw/accountMember/api/CheckVerificationCode_V3/callApiJSON.do',
-  // OCR身份验证
-  IdCardVerification: ApiRootUrl + "wsgw/medicalCopy/MedicalCopyApi/IdCardVerification/callApiJSON.do", 
-  // 退款人员信息登记
-  RefundRegister : ApiRootUrl + 'wsgw/refund/refundRegister/RefundRegister/callApiJSON.do',
-  // 退款申请记录查询
-  RefundSelect : ApiRootUrl + 'wsgw/refund/refundRegister/RefundSelect/callApiJSON.do',
-  // 银行卡号查询银行
-  GetBankName : ApiRootUrl + 'wsgw/refund/refundRegister/GetBankName/callApiJSON.do',
-  // 获取患者信息
-  GetPatInfo : ApiRootUrl + 'wsgw/refund/refundRegister/GetPatInfo/callApiJSON.do',
-  //获取健康卡卡号
-  GetHealthCard: ApiRootUrl + 'wsgw/accountMember/api/GetHealthCard/callApiJSON.do',
-
-
-  // ======================================精准预约=======================================
-  //通过疾病搜索医生
-  SearchDoctorByDisease: ApiRootUrl + 'wsgw/base/doctordisease/SearchDoctorByDisease/callApiJSON.do',
-  /**
-   * 获取门诊排班类型
-   */
-  DataList: ApiRootUrl + 'wsgw/sys/dict/DataList/callApiJSON.do',
-  /**
-   * 获取科室列表
-   */
-  QueryPreciseYyDeptTree: ApiRootUrl + 'wsgw/yy/precise/QueryPreciseYyDeptTree/callApiJSON.do',
-  /**
-  * 搜索医生/科室/疾病 (Precise)
-   */
-  SearchClinicDeptAndDoctorPrecise: ApiRootUrl + 'wsgw/yy/precise/SearchClinicDeptAndDoctor/callApiJSON.do',
-  /**
-  * 查询下一级的科室数据
-   */
-  QueryPreciseYyDept: ApiRootUrl + 'wsgw/yy/precise/QueryPreciseYyDept/callApiJSON.do',
-  /**
-    * 查询人群疾病列表
-    */
-   QueryCrowdDiseaseList: ApiRootUrl + 'wsgw/preciseYy/crowd/QueryCrowdDiseaseList/callApiJSON.do',
-   /**
-    * 查询医生及排班列表-精准预约
-    */
-   QueryClinicDoctorSchedulePA: ApiRootUrl + 'wsgw/yy/precise/QueryClinicDoctorSchedule/callApiJSON.do',
-   /**
-    * 专病门诊详情
-    */
-   Detail: ApiRootUrl + 'wsgw/yy/specialtyClinic/Detail/callApiJSON.do',
-   /**
-   * 诊疗组
-    */
-   QueryDiagnoseGroupList: ApiRootUrl + 'wsgw/basic/diagnoseGroup/QueryDiagnoseGroupList/callApiJSON.do',
-   /**
-   * 我的历史疾病诊断
-    */
-  QueryHistoryDiseaseList: ApiRootUrl + 'wsgw/precise/yy/QueryHistoryDiseaseList/callApiJSON.do',
-  /**
-   * 查询团队列表信息
-   */
-  QueryTeamList: ApiRootUrl + 'wsgw/mdt/mdtService/QueryTeamList/callApiJSON.do',
-  /** 精准预约-查询医生的问卷配置 */
-  PreciseQueryDoctorSubjectInfo: ApiRootUrl + '/wsgw/preciseYy/appoApply/QueryDoctorSubjectInfo/callApiJSON.do',
-  /** 精准预约-查询预约申请记录列表 */
-  PreciseQueryAppoApplyList: ApiRootUrl + '/wsgw/preciseYy/appoApply/QueryAppoApplyList/callApiJSON.do',
-  /** 精准预约-取消申请  */
-  PrecisePatientEditAppoApply: ApiRootUrl + '/wsgw/preciseYy/appoApply/PatientEditAppoApply/callApiJSON.do',
-  // 问卷详情
-  QuerySubjectInfoById_V3: ApiRootUrl + 'wsgw/surveyV3/SurveyWs/QuerySubjectInfoById/callApiJSON.do',
-  // 问卷-查询样本和答案
-  QuerySample_V3: ApiRootUrl + 'wsgw/surveyV3/SurveyWs/QuerySample/callApiJSON.do',
-  // 精准预约-我的历史疾病诊断 (Precise)
-  QueryHistoryDiseaseListPrecise: ApiRootUrl + 'wsgw/precise/yy/QueryHistoryDiseaseList/callApiJSON.do',
-}

+ 38 - 12
pagesPatient/service/refund/index.ts

@@ -1,22 +1,21 @@
 import { request, handle } from '@kasite/uni-app-base';
 // @ts-ignore
-import api from '@/pagesPatient/service/api';
 import { REQUEST_CONFIG } from '@/config';
 
 /**
  * 获取校验码
  */
-export const sendVerificationCode_V3 = async (queryData: any) => {
-  let resp = handle.promistHandleNew(await request.doPost(api.SendVerificationCode_V3, queryData));
-  return handle.catchPromiseNew(resp, () => resp);
+export const sendVerificationCode_V3 = async (queryData: any, options: any = {}) => {
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/accountMember/api/SendVerificationCode_V3/callApiJSON.do`, queryData, options));
+  return handle.catchPromiseNew(resp, () => resp, options);
 };
 
 /**
  * 校验验证码
  */
-export const checkVerificationCode_V3 = async (queryData: any) => {
-  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/accountMember/api/CheckVerificationCode_V3/callApiJSON.do`, queryData));
-  return handle.catchPromiseNew(resp, () => resp);
+export const checkVerificationCode_V3 = async (queryData: any, options: any = {}) => {
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/accountMember/api/CheckVerificationCode_V3/callApiJSON.do`, queryData, options));
+  return handle.catchPromiseNew(resp, () => resp, options);
 };
 
 /**
@@ -31,7 +30,7 @@ export const idCardVerification = async (queryData: any) => {
  * 退款人员信息登记
  */
 export const refundRegister = async (queryData: any) => {
-  let resp = handle.promistHandleNew(await request.doPost(api.RefundRegister, queryData));
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/refund/refundRegister/RefundRegister/callApiJSON.do`, queryData));
   return handle.catchPromiseNew(resp, () => resp, { showModal: false });
 };
 
@@ -39,7 +38,7 @@ export const refundRegister = async (queryData: any) => {
  * 退款申请记录
  */
 export const refundSelect = async (queryData: any) => {
-  let resp = handle.promistHandleNew(await request.doPost(api.RefundSelect, queryData));
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/refund/refundRegister/RefundSelect/callApiJSON.do`, queryData));
   return handle.catchPromiseNew(resp, () => resp);
 };
 
@@ -47,7 +46,7 @@ export const refundSelect = async (queryData: any) => {
  * 退款申请记录
  */
 export const refundSelectNew = async (queryData: any) => {
-  let resp = handle.promistHandleNew(await request.doPost(api.RefundSelect, queryData));
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/refund/refundRegister/RefundSelect/callApiJSON.do`, queryData));
   return handle.catchPromiseNew(resp, () => resp);
 };
 
@@ -55,7 +54,7 @@ export const refundSelectNew = async (queryData: any) => {
  * 银行卡号查询银行
  */
 export const getBankName = async (queryData: any) => {
-  let resp = handle.promistHandleNew(await request.doPost(api.GetBankName, queryData));
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/refund/refundRegister/GetBankName/callApiJSON.do`, queryData));
   return handle.catchPromiseNew(resp, () => resp);
 };
 
@@ -63,7 +62,7 @@ export const getBankName = async (queryData: any) => {
  * 获取患者信息
  */
 export const getPatInfo = async (queryData: any) => {
-  let resp = handle.promistHandleNew(await request.doPost(api.GetPatInfo, queryData));
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/refund/refundRegister/GetPatInfo/callApiJSON.do`, queryData));
   return handle.catchPromiseNew(resp, () => resp);
 };
 
@@ -79,3 +78,30 @@ export const queryCanOriginalReturnedMoney = async (queryData: any) => {
   );
   return handle.catchPromiseNew(resp, () => resp);
 };
+
+export const refundRegisterNew = async (queryData: any, options: any = {}) => {
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/refund/refundRegister/RefundRegisterNew/callApiJSON.do`, queryData, options));
+  return handle.catchPromiseNew(resp, () => resp, options);
+};
+
+export const refundUpdate = async (queryData: any, options: any = {}) => {
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/refund/refundRegister/RefundUpdate/callApiJSON.do`, queryData, options));
+  return handle.catchPromiseNew(resp, () => resp, options);
+};
+
+export const userConfirmAuth = async (queryData: any, options: any = {}) => {
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/transfer/auth/UserConfirmAuth/callApiJSON.do`, queryData, options));
+  return handle.catchPromiseNew(resp, () => resp, options);
+};
+
+export const queryMemberCardListAdnCardBalance = async (queryData: any, options: any = {}) => {
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/accountMember/api/QueryMemberCardListAdnCardBalance/callApiJSON.do`, queryData, options));
+  return handle.catchPromiseNew(resp, () => resp, options);
+};
+
+export const queryRefundRecord = async (queryData: any, options: any = {}) => {
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/refund/refundRegister/RefundSelect/callApiJSON.do`, queryData, options));
+  return handle.catchPromiseNew(resp, () => resp, options);
+};
+
+export const getBankNameUrl = `${REQUEST_CONFIG.BASE_URL}wsgw/refund/refundRegister/GetBankName/callApiJSON.do`;

+ 24 - 0
pagesPatient/service/yygh/index.ts

@@ -107,3 +107,27 @@ export const regSignForHis = async (queryData: any) => {
   let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/queue/QueueWs/RegSignForHis/callApiJSON.do`, queryData));
   return handle.catchPromiseNew(resp, () => resp);
 };
+
+/**
+ * 候补登记
+ */
+export const waitListApiAdd = async (queryData: any) => {
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/yy/waitListApi/Add/callApiJSON.do`, queryData));
+  return handle.catchPromiseNew(resp, () => resp);
+};
+
+/**
+ * 查询医生其它科室排班
+ */
+export const queryScheduleList = async (queryData: any) => {
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/yy/yygh/QueryScheduleList/callApiJSON.do`, queryData));
+  return handle.catchPromiseNew(resp, () => resp);
+};
+
+/**
+ * 候补登记前检查
+ */
+export const checkBeforeAddWaitList = async (queryData: any) => {
+  let resp = handle.promistHandleNew(await request.doPost(`${REQUEST_CONFIG.BASE_URL}wsgw/yy/waitListApi/CheckBeforeAddWaitList/callApiJSON.do`, queryData));
+  return handle.catchPromiseNew(resp, () => resp);
+};

+ 4 - 4
pagesPatient/st1/business/costDetailedList/hospitalCosts/hospitalCosts.vue

@@ -37,9 +37,9 @@
 
 <script setup lang="ts">
 import { ref, computed } from 'vue';
-import { useOnLoad, useOnShow } from '@dcloudio/uni-app';
+import { onLoad, onShow } from '@dcloudio/uni-app';
 import { queryInHospitalCostList } from '@/pagesPatient/service/costDetailedList';
-import common from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 import userInfo from '@/pagesPersonal/st1/components/userInfo/userInfo.vue';
 import noData from '@/pages/st1/components/noData/noData.vue';
@@ -62,7 +62,7 @@ const totalFee = computed(() => {
   return num / 100;
 });
 
-useOnLoad((options: any) => {
+onLoad((options: any) => {
   /**住院号列表进入 传入userInfo */
   try {
     currentUser.value = options.userInfo ? JSON.parse(options.userInfo) : getApp().globalData.currentUser;
@@ -72,7 +72,7 @@ useOnLoad((options: any) => {
   }
 });
 
-useOnShow(() => {
+onShow(() => {
   main();
 });
 

+ 3 - 3
pagesPatient/st1/business/costDetailedList/hospitalCostsList/hospitalCostsList.vue

@@ -40,9 +40,9 @@
 
 <script setup lang="ts">
 import { ref, computed } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 import { queryInHospitalCostType } from '@/pagesPatient/service/costDetailedList';
-import common from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 import noData from '@/pages/st1/components/noData/noData.vue';
 
@@ -67,7 +67,7 @@ const totalFee = computed(() => {
   return num / 100;
 });
 
-useOnLoad((options: any) => {
+onLoad((options: any) => {
   let qBean = options.queryBean ? JSON.parse(options.queryBean) : {};
   if (qBean.Date) {
     qBean.Date = qBean.Date.substring(0, 10);

+ 3 - 3
pagesPatient/st1/business/costDetailedList/outpatientCosts/outpatientCosts.vue

@@ -38,9 +38,9 @@
 
 <script setup lang="ts">
 import { ref } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 import { queryOutpatientCostType } from '@/pagesPatient/service/costDetailedList';
-import common from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 import userInfo from '@/pagesPersonal/st1/components/userInfo/userInfo.vue';
 import noData from '@/pages/st1/components/noData/noData.vue';
@@ -76,7 +76,7 @@ const recordList = ref<any[]>([]);
 const showNoData = ref(false);
 const noDataValue = ref('暂无门诊清单');
 
-useOnLoad((options) => {
+onload((options) => {
   currentUser.value = getApp().globalData.currentUser;
   getOutpatientCostType();
 });

+ 1 - 1
pagesPatient/st1/business/order/orderPayment/orderPayment.vue

@@ -65,7 +65,7 @@
 <script setup lang="ts">
 import { ref, computed, onMounted } from 'vue';
 import { onLoad } from '@dcloudio/uni-app';
-import common from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 import {
   queryOrderSettlementList,

+ 1 - 1
pagesPatient/st1/business/otherService/electronicMedicalRecord/electronicMedicalRecord.vue

@@ -111,7 +111,7 @@
 <script setup lang="ts">
 import { ref } from 'vue';
 import { onLoad } from '@dcloudio/uni-app';
-import common from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 import { getEMRInfo } from '@/pagesPatient/service/otherService/index';
 

+ 1 - 1
pagesPatient/st1/business/otherService/hospitalDistrict/hospitalDistrict.vue

@@ -20,7 +20,7 @@
 <script setup lang="ts">
 import { ref } from 'vue';
 import { onLoad } from '@dcloudio/uni-app';
-import common from '@/utils/common';
+import {common} from '@/utils';
 import richTextModal from '@/pages/st1/components/richTextModal/richTextModal.vue';
 
 const app = getApp();

+ 1 - 1
pagesPatient/st1/business/outpatient/outpatientRefund/outpatientRefund.vue

@@ -34,7 +34,7 @@
 <script setup lang="ts">
 import { ref } from 'vue';
 import { onShow } from '@dcloudio/uni-app';
-import common from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 import userInfo from '@/pagesPersonal/st1/components/userInfo/userInfo.vue';
 import { queryMemberRefundableMoney, applySelfServiceRefund } from '@/pagesPatient/service/outpatient/index';

+ 1 - 1
pagesPatient/st1/business/outpatient/outpatientRefundDetail/outpatientRefundDetail.vue

@@ -49,7 +49,7 @@
 <script setup lang="ts">
 import { ref } from 'vue';
 import { onLoad } from '@dcloudio/uni-app';
-import common from '@/utils/common';
+import {common} from '@/utils';
 import noData from '@/pages/st1/components/noData/noData.vue';
 import { querySelfRefundRecordInfo } from '@/pagesPatient/service/outpatient/index';
 

+ 0 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/components/cardDiv/cardDiv.vue

@@ -7,7 +7,6 @@
 </template>
 
 <script setup lang="ts">
-import { defineProps } from 'vue';
 
 const props = defineProps({
   colorLine: {

+ 0 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/components/cardPanel/cardPanel.vue

@@ -13,7 +13,6 @@
 </template>
 
 <script setup lang="ts">
-import { defineProps } from 'vue';
 
 const props = defineProps({
   noPadding: {

+ 1 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/action/index.vue

@@ -15,7 +15,7 @@
 </template>
 
 <script setup lang="ts">
-import { defineProps, defineEmits, watch } from 'vue';
+import { watch } from 'vue';
 
 const props = defineProps({
   label: {

+ 1 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/index.vue

@@ -100,7 +100,7 @@
 </template>
 
 <script setup lang="ts">
-import { ref, defineProps, defineEmits, watch, nextTick, defineExpose } from 'vue';
+import { ref, watch, nextTick } from 'vue';
 import gInput from './input/index.vue';
 import gTextArea from './textArea/index.vue';
 import gRadio from './radio/index.vue';

+ 1 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/input/index.vue

@@ -15,7 +15,7 @@
 </template>
 
 <script setup lang="ts">
-import { defineProps, defineEmits, watch } from 'vue';
+import { watch } from 'vue';
 
 const props = defineProps({
   label: {

+ 1 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/radio/index.vue

@@ -13,7 +13,7 @@
 </template>
 
 <script setup lang="ts">
-import { defineProps, defineEmits, watch } from 'vue';
+import { watch } from 'vue';
 
 const props = defineProps({
   label: {

+ 0 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/regionPicker/index.vue

@@ -21,7 +21,6 @@
 </template>
 
 <script setup lang="ts">
-import { defineProps, defineEmits } from 'vue';
 
 const props = defineProps({
   label: {

+ 1 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/smsCode/index.vue

@@ -37,7 +37,7 @@
 </template>
 
 <script setup lang="ts">
-import { defineProps, defineEmits, ref, defineExpose } from 'vue';
+import { ref } from 'vue';
 
 const props = defineProps({
   phoneLabel: {

+ 1 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/components/form/textArea/index.vue

@@ -15,7 +15,7 @@
 </template>
 
 <script setup lang="ts">
-import { defineProps, defineEmits, watch } from 'vue';
+import { watch } from 'vue';
 
 const props = defineProps({
   label: {

+ 0 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/components/userInfo/userInfo.vue

@@ -18,7 +18,6 @@
 </template>
 
 <script setup lang="ts">
-import { defineProps } from 'vue';
 
 const props = defineProps({
   currentUser: {

+ 0 - 140
pagesPatient/st1/business/outpatient/outpatientRefundNew/config/api.js

@@ -1,140 +0,0 @@
-import request from "../../../../../../utils/request.js";
-import handle from "../../../../../../config/handle.js";
-import apiRootUrl from "../../../../../../config/api.js";
-import icon from "../../../../../../utils/icon.js";
-const app = getApp()
-
-const api = {
-  /**
-   * 退费列表
-   */
-  QueryRefundRecord: apiRootUrl.ApiRootUrl + `wsgw/refund/refundRegister/RefundSelect/callApiJSON.do`,
-
-  /**
-   * 查可退余额(详情)
-   */
-  QueryCanOriginalReturnedMoney: apiRootUrl.ApiRootUrl + `wsgw/refund/refundRegister/QueryCanOriginalReturnedMoney/callApiJSON.do`,
-
-  /**
-   * 查询用户卡列表和可退余额
-   */
-  QueryMemberCardListAdnCardBalance: apiRootUrl.ApiRootUrl + "wsgw/accountMember/api/QueryMemberCardListAdnCardBalance/callApiJSON.do",
-
-  /**
-   * 申请退费
-   */
-  RefundRegisterNew: apiRootUrl.ApiRootUrl + `wsgw/refund/refundRegister/RefundRegisterNew/callApiJSON.do`,
-
-  /**
-   * 更新已经提交的申请
-   */
-  RefundUpdate: apiRootUrl.ApiRootUrl + `wsgw/refund/refundRegister/RefundUpdate/callApiJSON.do`,
-
-  /**
-   * 获取验证码
-   */
-  SendVerificationCode_V3: apiRootUrl.ApiRootUrl + `wsgw/accountMember/api/SendVerificationCode_V3/callApiJSON.do`,
-
-  /**
-   * 验证验证码
-   */
-  CheckVerificationCode_V3: apiRootUrl.ApiRootUrl + `wsgw/accountMember/api/CheckVerificationCode_V3/callApiJSON.do`,
-
-  /**
-   * 根据卡号查询医院名称
-   */
-  GetBankName: apiRootUrl.ApiRootUrl + `wsgw/refund/refundRegister/GetBankName/callApiJSON.do`,
-
-  /**
-   * 获取微信零钱退款授权信息及配置
-   */
-  UserConfirmAuth: apiRootUrl.ApiRootUrl + `wsgw/transfer/auth/UserConfirmAuth/callApiJSON.do`,
-}
-
-
-const methods = {
-  // face_auth_bg:icon.iconUrl+"icon/face_auth_bg.png",
-  // face_auth_icon:icon.iconUrl+"icon/face_auth_icon.png",
-  // code_auth_icon:icon.iconUrl+"icon/code_auth_icon.png",
-
-  /**
-   * 退费列表
-   */
-  async queryRefundRecord(queryData, options) {
-    let resp = handle.promistHandleNew(await request.doPost(api.QueryRefundRecord, queryData, options))
-    return handle.catchPromiseNew(resp, () => resp, options)
-  },
-
-  /**
-   * 查可退余额(详情)
-   */
-  async QueryCanOriginalReturnedMoney(queryData, options) {
-    let resp = handle.promistHandleNew(await request.doPost(api.QueryCanOriginalReturnedMoney, queryData, options))
-    return handle.catchPromiseNew(resp, () => resp, options)
-  },
-
-  /**
-   * 查询用户卡列表和可退余额
-   */
-  async queryMemberCardListAdnCardBalance(queryData, options){
-    let resp = handle.promistHandleNew(await request.doPost(api.QueryMemberCardListAdnCardBalance, queryData, options))
-    return handle.catchPromiseNew(resp, () => resp, options)
-  },
-
-  /**
-   * 申请退费
-   */
-  async RefundRegisterNew(queryData, options) {
-    let resp = handle.promistHandleNew(await request.doPost(api.RefundRegisterNew, queryData, options))
-    return handle.catchPromiseNew(resp, () => resp, options)
-  },
-
-  /**
-   * 更新已经提交的申请
-   */
-  async refundUpdate(queryData, options) {
-    let resp = handle.promistHandleNew(await request.doPost(api.RefundUpdate, queryData, options))
-    return handle.catchPromiseNew(resp, () => resp, options)
-  },
-
-  /**
-   * 获取验证码
-   */
-  async sendVerificationCode_V3(queryData, options) {
-    let resp = handle.promistHandleNew(await request.doPost(api.SendVerificationCode_V3, queryData, options))
-    return handle.catchPromiseNew(resp, () => resp, options)
-  },
-  
-  /**
-   * 验证验证码
-   */
-  async checkVerificationCode_V3(queryData, options) {
-    let resp = handle.promistHandleNew(await request.doPost(api.CheckVerificationCode_V3, queryData, options))
-    return handle.catchPromiseNew(resp, () => resp, options)
-  },
-
-  /**
-   * 根据卡号查询医院名称 接口url
-   */
-  getBankNameApiUrl() {
-    return api.GetBankName;
-  },
-
-  /**
-   * 根据卡号查询医院名称
-   */
-  async getBankName(queryData, options) {
-    let resp = handle.promistHandleNew(await request.doPost(api.GetBankName, queryData, options))
-    return handle.catchPromiseNew(resp, () => resp, options)
-  },
-
-  /**
-   * 获取微信零钱退款授权信息及配置
-   */
-  async userConfirmAuth(queryData, options) {
-    let resp = handle.promistHandleNew(await request.doPost(api.UserConfirmAuth, queryData, options))
-    return handle.catchPromiseNew(resp, () => resp, options)
-  },
-
-}
-export default methods

+ 18 - 12
pagesPatient/st1/business/outpatient/outpatientRefundNew/refundForm/refundForm.vue

@@ -279,7 +279,7 @@
           </view>
         </block>
         <!-- 支付宝转账 -->
-        <block v-elif="formData.TransferType == 'Zfb'">
+        <block v-else-if="formData.TransferType == 'Zfb'">
           <view class="innerBox displayFlexLeft">
             <view class="input_tit">支付宝收款户名</view>
             <view class="input_con">{{ formData.HandlerReName }}</view>
@@ -290,7 +290,7 @@
           </view>
         </block>
         <!-- 微信转账 -->
-        <block v-elif="formData.TransferType == 'Wechat'">
+        <block v-else-if="formData.TransferType == 'Wechat'">
           <view class="innerBox display-flex__ac">
             <!-- <view class="input_tit"></view> -->
             <view class="input_con">
@@ -318,11 +318,17 @@
 <script setup lang="ts">
 import { ref, reactive, onMounted, getCurrentInstance, nextTick } from "vue";
 import { onLoad, onShow } from "@dcloudio/uni-app";
-import REQUEST_CONFIG from "@/config/requestConfig";
-import refund from "../config/api"; 
 import { REQUEST_CONFIG } from '@/config';
 import { requestWithCancel } from "./singletonRequest";
-import common from "@/utils/common";
+import { common } from '@/utils';
+import {
+  refundRegisterNew,
+  refundUpdate,
+  sendVerificationCode_V3 as sendVerificationCodeApi,
+  checkVerificationCode_V3 as checkVerificationCodeApi,
+  getBankNameUrl,
+  userConfirmAuth
+} from '@/pagesPatient/service/refund';
 import {
   channelType,
   relationType,
@@ -664,9 +670,9 @@ const submitForm = async () => {
           : formData.value.RecAccNo,
     };
 
-    let reqFunc = refund.RefundRegisterNew;
+    let reqFunc = refundRegisterNew;
     if (formData.value.Status == "0" || formData.value.Status == "1") {
-      reqFunc = refund.refundUpdate;
+      reqFunc = refundUpdate;
     }
 
     const { resData, resp } = await reqFunc(reqData);
@@ -764,7 +770,7 @@ const upload = (path: string) => {
 
 const sendVerificationCode_V3 = async (mobile: string) => {
   const reqData = { mobile };
-  const { resData, resp } = await refund.sendVerificationCode_V3(reqData, {
+  const { resData, resp } = await sendVerificationCodeApi(reqData, {
     showModal: false,
   });
   if (resData.RespCode != "10000") {
@@ -781,7 +787,7 @@ const checkVerificationCode_V3 = async (pcId: string, code: string) => {
     pcId: pcId,
     verificationCode: code,
   };
-  const { resData, resp } = await refund.checkVerificationCode_V3(reqData, {
+  const { resData, resp } = await checkVerificationCodeApi(reqData, {
     showModal: false,
   });
   if (resData.RespCode != "10000") {
@@ -800,7 +806,7 @@ const changeDialogVisible_info = () => {
 
 const getBankName = async (target: any = {}) => {
   const res = await requestWithCancel({
-    url: refund.getBankNameApiUrl(),
+    url: getBankNameUrl,
     data: {
       ...target,
       HandlerBankCardNo: target["RecAccNo"],
@@ -826,7 +832,7 @@ const requestMerchantTransfer = async () => {
     UserDisplayName: "预交金退费",
     OperatorId: uni.getStorageSync("smallProOpenId"),
   };
-  const { resData, resp } = await refund.userConfirmAuth(reqData, {
+  const { resData, resp } = await userConfirmAuth(reqData, {
     showModal: false,
   });
   if (resData.RespCode != "10000" || common.isEmpty(resp)) {
@@ -858,7 +864,7 @@ const requestMerchantTransfer = async () => {
 </script>
 
 <style scoped>
-@import "../static/css/refund.wxss";
+@import "../static/css/refund.css";
 
 .container {
 }

+ 5 - 9
pagesPatient/st1/business/outpatient/outpatientRefundNew/refundForm/singletonRequest.js

@@ -1,4 +1,4 @@
-import common from "@/utils/common";
+import {common} from '@/utils';
 
 // 用于存储每个请求接口的请求任务
 const requestTasks = {};
@@ -12,7 +12,7 @@ const requestTasks = {};
  * @param {Function} [options.success] - 请求成功的回调函数
  * @param {Function} [options.fail] - 请求失败的回调函数
  */
-function requestWithCancel(options) {
+export function requestWithCancel(options) {
   const { url, method = 'POST', data = {} } = options;
 
   // 检查该接口是否有正在进行的请求
@@ -25,7 +25,7 @@ function requestWithCancel(options) {
 
   return new Promise((resolve, reject) => {
     // 发起新的请求并保存请求任务
-    const requestTask = wx.request({
+    const requestTask = uni.request({
       url,
       method,
       data: {
@@ -33,7 +33,7 @@ function requestWithCancel(options) {
       },
       header: {
         'content-type': 'application/json',
-        token: wx.getStorageSync('token'),
+        token: uni.getStorageSync('token'),
         appId: "KASIET_alismaillpro",
       },
       success: async (res) => {
@@ -63,8 +63,4 @@ function requestWithCancel(options) {
   })
 }
 
-const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
-
-module.exports = {
-  requestWithCancel
-};
+const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

+ 10 - 19
pagesPatient/st1/business/outpatient/outpatientRefundNew/refundRecord/refundRecord.vue

@@ -28,10 +28,10 @@
               <text v-if="item.Status == '1'" style="color: var(--dominantColor)"
                 >待审核</text
               >
-              <text v-elif="item.Status == '2'" style="color: green"
+              <text v-else-if="item.Status == '2'" style="color: green"
                 >审核通过</text
               >
-              <text v-elif="item.Status == '3'" style="color: red"
+              <text v-else-if="item.Status == '3'" style="color: red"
                 >审核不通过</text
               >
               <text v-else style="color: #666">{{ item.StatusName }}</text>
@@ -112,12 +112,11 @@
 <script setup lang="ts">
 import { ref, reactive, onMounted, nextTick } from "vue";
 import { onLoad, onShow } from "@dcloudio/uni-app";
-import ApiRootUrl from "@/config/api";
-import refund from "../config/api";
-import common from "@/utils/common";
-import publicFn from "@/utils/publicFn"; // Assuming this is available
-import icon from "@/utils/icon"; // Assuming this is available
-import { useGetMember } from '@/hooks/useGetMember'; // Using the hook as per rules
+import { REQUEST_CONFIG } from '@/config';
+import { common } from '@/utils';
+import icon from "@/utils/icon";
+import { useGetMember } from '@/hook';
+import { queryRefundRecord } from '@/pagesPatient/service/refund';
 
 // Components
 import userInfo from "@/pagesPersonal/st1/components/userInfo/userInfo.vue";
@@ -159,11 +158,6 @@ const main = async (options: any = {}) => {
     : app.globalData.currentUser;
   
   if (!user) {
-      // Use hook instead of publicFn.getMember if possible, or keep publicFn if hook not suitable for 'defaultInfo'
-      // The rule says: Replace `publicFn.getMember` with `await useGetMember()`.
-      // publicFn.getMember('defaultInfo') might be a specific usage.
-      // I will try to use the hook or the replacement logic.
-      // Assuming useGetMember returns the member info.
       user = await useGetMember(); 
   }
 
@@ -206,10 +200,7 @@ const QueryRefundRecord = async () => {
     OpenId: uni.getStorageSync('openid'),
   };
   
-  // Note: Assuming refund.queryRefundRecord is an async function that returns { resData, resp }
-  // We need to make sure 'refund' API is correctly imported and structured.
-  // In the original file: import refund from "../config/api";
-  const { resData, resp } = await refund.queryRefundRecord(reqData);
+  const { resData, resp } = await queryRefundRecord(reqData);
   if(resData.RespCode != "10000") {
     return;
   }
@@ -220,7 +211,7 @@ const edit = (item: any) => {
   const queryBean = {
     ...item,
     ReviewImages: JSON.parse(item.ReviewImages).map((i: any) => {
-      i.value = i.value?.replace(ApiRootUrl.ApiRootUrl, "");
+      i.value = i.value?.replace(REQUEST_CONFIG.BASE_URL, "");
       return i;
     }),
     RefundMoney: common.centToYuan(item.RefundMoney),
@@ -234,7 +225,7 @@ const edit = (item: any) => {
 </script>
 
 <style scoped>
-@import "../static/css/refund.wxss";
+@import "../static/css/refund.css";
 
 .content {
   padding-top: 100upx;

+ 1 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/refundResult/refundResult.vue

@@ -39,7 +39,7 @@ const toHome = () => {
 </script>
 
 <style>
-@import "../static/css/refund.wxss";
+@import "../static/css/refund.css";
 
 .white-panel {
   min-height: 300upx;

+ 1 - 1
pagesPatient/st1/business/outpatient/outpatientRefundNew/selectRefundCardList/selectRefundCardList.vue

@@ -255,7 +255,7 @@ const initPageParam = (options: any) => {
 </script>
 
 <style>
-@import "../static/css/refund.wxss";
+@import "../static/css/refund.css";
 
 .white-panel {
   padding: 30upx 40upx;

+ 2 - 2
pagesPatient/st1/business/outpatient/outpatientRefundNew/selectRefundChannel/selectRefundChannel.vue

@@ -61,7 +61,7 @@
 <script setup lang="ts">
 import { ref, reactive } from "vue";
 import { onLoad, onShow } from "@dcloudio/uni-app";
-import common from "@/utils/common";
+import {common} from '@/utils';
 import { queryCanOriginalReturnedMoney } from "@/pagesPatient/service/refund/index";
 
 // Components
@@ -160,7 +160,7 @@ const toRefundForm = () => {
 </script>
 
 <style scoped>
-@import "../static/css/refund.wxss";
+@import "../static/css/refund.css";
 
 .content {
   padding: 30upx 30upx 200upx;

+ 19 - 19
pagesPatient/st1/business/outpatient/outpatientRefundNew/static/css/refund.wxss → pagesPatient/st1/business/outpatient/outpatientRefundNew/static/css/refund.css

@@ -5,7 +5,7 @@
 }
 
 .content {
-  padding: 0 30rpx;
+  padding: 0 30upx;
   overflow: auto;
   height: 100%;
 }
@@ -13,12 +13,12 @@
 .white-panel {
   position: relative;
   width: 100%;
-  min-height: 80rpx;
+  min-height: 80upx;
   height: fit-content;
   background-color: #fff;
-  border-radius: 24rpx;
-  padding: 30rpx;
-  margin: 30rpx 0;
+  border-radius: 24upx;
+  padding: 30upx;
+  margin: 30upx 0;
   overflow: hidden;
 }
 
@@ -26,11 +26,11 @@
   content: "";
   position: absolute;
   top: 50%;
-  right: 20rpx;
+  right: 20upx;
   transform: translate(-50%, -50%) rotate(45deg);
-  width: 20rpx;
-  height: 20rpx;
-  border: 2rpx solid #43434A;
+  width: 20upx;
+  height: 20upx;
+  border: 2upx solid #43434A;
   border-left: none;
   border-bottom: none;
 }
@@ -39,37 +39,37 @@
 .card-div {
   position: relative;
   width: 100%;
-  height: 80rpx;
-  margin: 20rpx 0;
+  height: 80upx;
+  margin: 20upx 0;
   display: flex;
   align-items: center;
 }
 
 /* .card-div::before {
-  width: 100rpx;
-  height: 100rpx;
+  width: 100upx;
+  height: 100upx;
   border-radius: 50%;
   background-color: #f0f1f6;
   background-color: red;
   position: absolute;
   top: 50%;
-  left: -5rpx;
+  left: -5upx;
   transform: translate(-50%, 0);
 }
 
 .card-div::after {
-  width: 10rpx;
-  height: 10rpx;
+  width: 10upx;
+  height: 10upx;
   border-radius: 50%;
   background-color: #f0f1f6;
   position: absolute;
   top: 50%;
-  right: -5rpx;
+  right: -5upx;
   transform: translate(-50%, 0);
 }
 
 .card-div__line {
-  margin: 0 30rpx;
+  margin: 0 30upx;
 } */
 
 /* 辅助样式 */
@@ -125,4 +125,4 @@ image {
 /* 文字颜色-警告色 */
 .text-color__danger {
   color: #FF5D5F;
-}
+}

+ 1 - 1
pagesPatient/st1/business/outpatient/outpatientRefundRecord/outpatientRefundRecord.vue

@@ -38,7 +38,7 @@
 import { ref } from 'vue';
 import { onLoad, onShow } from '@dcloudio/uni-app';
 import { querySelfRefundRecordList } from '@/pagesPatient/service/outpatient/index';
-import common from '@/utils/common';
+import {common} from '@/utils';
 import userInfo from '@/pagesPersonal/st1/components/userInfo/userInfo.vue';
 import noData from '@/pages/st1/components/noData/noData.vue';
 

+ 1 - 1
pagesPatient/st1/business/pay/payState/payState.vue

@@ -116,7 +116,7 @@
 <script setup lang="ts">
 import { ref } from 'vue';
 import { onLoad } from '@dcloudio/uni-app';
-import common from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 import { orderDetailLocal, orderCancel } from '@/pagesPatient/service/record/index';
 import { getAppointReceiptInfo } from '@/pagesPatient/service/otherService/index';

+ 2 - 2
pagesPatient/st1/business/prescriptionManagement/dischargeMedication/dischargeMedication.vue

@@ -38,7 +38,7 @@
 
 <script setup lang="ts">
 import { ref, getCurrentInstance } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 import { common } from '@/utils';
 import icon from '@/utils/icon';
 import { queryInpatientList } from '@/pagesPatient/service/record';
@@ -69,7 +69,7 @@ const screen = ref({
   columns: []
 });
 
-useOnLoad((options: any) => {
+onLoad((options: any) => {
   try {
     let user = options.userInfo ? JSON.parse(options.userInfo) : app.globalData.currentUser;
     currentUser.value = user;

+ 2 - 2
pagesPatient/st1/business/prescriptionManagement/dischargeMedicationDetails/dischargeMedicationDetails.vue

@@ -20,7 +20,7 @@
 
 <script setup lang="ts">
 import { ref, getCurrentInstance } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 import { common } from '@/utils';
 import { queryInpatientDocAdviceList } from '@/pagesPatient/service/record';
 
@@ -30,7 +30,7 @@ const app = getApp();
 const showCont = ref(false);
 const details = ref<any[]>([]);
 
-useOnLoad((options: any) => {
+onLoad((options: any) => {
   let currentUser = app.globalData.currentUser;
   let queryBean: any = {};
   

+ 2 - 2
pagesPatient/st1/business/prescriptionManagement/drugCredentials/drugCredentials.vue

@@ -41,7 +41,7 @@
 
 <script setup lang="ts">
 import { ref, getCurrentInstance } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 import { common } from '@/utils';
 import icon from '@/utils/icon';
 import { queryDrugQueueList } from '@/pagesPatient/service/prescriptionManagement';
@@ -57,7 +57,7 @@ const list = ref<any[]>([]);
 const showNoData = ref(false);
 const noDataValue = ref('暂无取药信息');
 
-useOnLoad((options) => {
+onLoad((options) => {
   currentUser.value = app.globalData.currentUser;
   main();
 });

+ 2 - 2
pagesPatient/st1/business/prescriptionManagement/drugCredentialsDetails/drugCredentialsDetails.vue

@@ -35,7 +35,7 @@
 
 <script setup lang="ts">
 import { ref, getCurrentInstance } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 import { common } from '@/utils';
 import icon from '@/utils/icon';
 import { REQUEST_CONFIG } from '@/config';
@@ -47,7 +47,7 @@ const iconUrl = ref(icon);
 const takeMedicineInfo = ref<any>({});
 const qrCodeImage = ref('');
 
-useOnLoad((options: any) => {
+onLoad((options: any) => {
   let currentUser = app.globalData.currentUser;
   let queryBean = options.queryBean ? JSON.parse(options.queryBean) : {};
   takeMedicineInfo.value = queryBean;

+ 2 - 2
pagesPatient/st1/business/priceInquiry/inquiryDetails/inquiryDetails.vue

@@ -53,12 +53,12 @@
 
 <script setup lang="ts">
 import { ref } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 
 const type = ref('drug'); // drug:药品详情 pro:项目详情
 const queryBean = ref<any>({});
 
-useOnLoad((options: any) => {
+onLoad((options: any) => {
   try {
     queryBean.value = options.queryBean ? JSON.parse(options.queryBean) : {};
   } catch (e) {

+ 3 - 3
pagesPatient/st1/business/priceInquiry/inquiryList/inquiryList.vue

@@ -74,7 +74,7 @@
 
 <script setup lang="ts">
 import { ref } from 'vue';
-import { useOnLoad, onReachBottom } from '@dcloudio/uni-app';
+import { onLoad, onReachBottom } from '@dcloudio/uni-app';
 import { queryDrugList, queryExpensesItemList } from '@/pagesPatient/service/priceInquiry';
 import { common } from '@/utils';
 import icon from '@/utils/icon';
@@ -90,7 +90,7 @@ const showNoData = ref(false);
 const loadAll = ref(false);
 const pIndex = ref(1);
 
-useOnLoad((options: any) => {
+onLoad((options: any) => {
   type.value = options.type || '';
   main();
 });
@@ -276,7 +276,7 @@ onReachBottom(() => {
   border-radius: 20upx;
   padding: 38upx 30upx 43upx;
   position: relative;
-  display: box;
+  display: flex;
   display: -webkit-box;
 }
 

+ 2 - 2
pagesPatient/st1/business/priceInquiry/inquirySelect/inquirySelect.vue

@@ -15,14 +15,14 @@
 
 <script setup lang="ts">
 import { ref, getCurrentInstance } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 import { menuClick } from '@/utils';
 
 const { proxy } = getCurrentInstance() as any;
 const app = getApp();
 const queryBean = ref<any>({});
 
-useOnLoad(() => {
+onLoad(() => {
   /**如果点击菜单时   有多级页面  会给selectUrl_x赋值 */
   queryBean.value = app.globalData.selectUrl_x
     ? JSON.parse(app.globalData.selectUrl_x)

+ 2 - 2
pagesPatient/st1/business/queue/queueList/queueList.vue

@@ -29,7 +29,7 @@
 
 <script setup lang="ts">
 import { ref } from 'vue';
-import { useOnShow } from '@dcloudio/uni-app';
+import { onShow } from '@dcloudio/uni-app';
 import { common } from '@/utils';
 import { getQueueInfo } from '@/pagesPatient/service/queue';
 import userInfo from '@/pagesPersonal/st1/components/userInfo/userInfo.vue';
@@ -44,7 +44,7 @@ const noDataValue = ref('暂无候诊记录');
 const queueList = ref<any[]>([]);
 const pageConfig = ref<any>({});
 
-useOnShow(() => {
+onShow(() => {
   let config = common.deepCopy(
     app.globalData.config.pageConfiguration.signInList_config
   );

+ 3 - 3
pagesPatient/st1/business/record/applyRecordDetail/applyRecordDetail.vue

@@ -136,9 +136,9 @@
 
 <script setup lang="ts">
 import { ref } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 import { preciseQuerySubjectInfoById_V3, preciseQuerySample_V3, precisePatientEditAppoApply } from '@/pagesPatient/service/record/index';
-import { common } from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 
 const iconUrl = ref(icon);
@@ -146,7 +146,7 @@ const itemInfo = ref<any>({});
 const showQues = ref(true);
 const quesList = ref<any>({});
 
-useOnLoad((options: any) => {
+onLoad((options: any) => {
   if (options.itemInfo) {
     itemInfo.value = JSON.parse(decodeURIComponent(options.itemInfo));
   }

+ 2 - 2
pagesPatient/st1/business/record/appointmentRecord/appointmentRecord.vue

@@ -73,9 +73,9 @@
 
 <script setup lang="ts">
 import { ref } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { useOnLoad } from '@/hook';
 import { hisYyWaterList_V2, orderCancel } from '@/pagesPatient/service/record/index';
-import { common } from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 
 const iconUrl = ref(icon);

+ 3 - 3
pagesPatient/st1/business/record/cardRecord/cardRecord.vue

@@ -39,9 +39,9 @@
 
 <script setup lang="ts">
 import { ref } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 import { queryOutpatientVisitList } from '@/pagesPatient/service/record/index';
-import { common } from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 
 const app = getApp();
@@ -68,7 +68,7 @@ const screen = ref({
   columns: []
 });
 
-useOnLoad((options: any) => {
+onLoad((options: any) => {
   let user = options.userInfo ? JSON.parse(options.userInfo) : app.globalData.currentUser;
   currentUser.value = user;
   QueryOutpatientVisitList();

+ 4 - 4
pagesPatient/st1/business/record/cardRecordDetails/cardRecordDetails.vue

@@ -50,11 +50,11 @@
 
 <script setup lang="ts">
 import { ref } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 import { queryOutpatientDocAdviceList, queryInpatientDocAdviceList, getMedicalRecords } from '@/pagesPatient/service/record/index';
-import { common } from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
-import { REQUEST_CONFIG } from '@/config/requestConfig';
+import { REQUEST_CONFIG } from '@/config';
 
 const app = getApp();
 const iconUrl = ref(icon);
@@ -74,7 +74,7 @@ const caseNo = ref("");
 const hosNo = ref("");
 const medicalId = ref("");
 
-useOnLoad((options: any) => {
+onLoad((options: any) => {
   let user = app.globalData.currentUser;
   if (options.cardInfo) {
     user = JSON.parse(decodeURIComponent(options.cardInfo));

+ 4 - 4
pagesPatient/st1/business/record/hosRecord/hosRecord.vue

@@ -40,11 +40,11 @@
 
 <script setup lang="ts">
 import { ref } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { onLoad } from '@dcloudio/uni-app';
 import { queryInpatientList, getMedicalRecords } from '@/pagesPatient/service/record/index';
-import { common } from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
-import { REQUEST_CONFIG } from '@/config/requestConfig';
+import { REQUEST_CONFIG } from '@/config';
 
 const app = getApp();
 const iconUrl = ref(icon);
@@ -67,7 +67,7 @@ const screen = ref({
   columns: []
 });
 
-useOnLoad((options: any) => {
+onLoad((options: any) => {
   let user = options.userInfo ? JSON.parse(options.userInfo) : app.globalData.currentUser;
   currentUser.value = user;
   QueryInpatientListFn();

+ 2 - 2
pagesPatient/st1/business/record/outpatientMedical/outpatientMedical.vue

@@ -63,12 +63,12 @@
 
 <script setup lang="ts">
 import { ref } from 'vue';
-import { useOnLoad } from '@dcloudio/uni-app';
+import { useOnLoad } from '@/hook';
 import { queryExamItemList, getMedicalReceipts, cancelAppoint } from '@/pagesPatient/service/otherService';
 import { orderDetailLocal } from '@/pagesPatient/service/record/index';
 import { request, handle } from '@kasite/uni-app-base';
 import { common, menuClick } from '@/utils';
-import { REQUEST_CONFIG } from '@/config/requestConfig';
+import { REQUEST_CONFIG } from '@/config';
 
 const app = getApp();
 const list = ref<any[]>([]);

+ 0 - 90
pagesPatient/st1/business/yygh/waitRegistration/waitRegistration.js

@@ -1,90 +0,0 @@
-const app = getApp();
-import yygh from "../../../../config/api/yygh/index.js";
-import regeneratorRuntime from "../../../../../utils/runtime.js";
-import common from "../../../../../utils/common.js";
-import icon from "../../../../../utils/icon.js";
-Page({
-  data: {
-    iconUrl:icon,
-    waitDate: '', //候补日期 
-    waitDateName: '', //星期
-    waitTime: '16:00', //候补时间
-    waitTimeName: '', //上下午
-    endTime: "23:59", //截止时间
-    endDate: '', //截止日期
-    showMore: false, //是否展示过敏史等
-  },
-  onLoad: function(options) {
-    let currentUser = app.globalData.currentUser
-    let querBen = options.querBen ?JSON.parse(decodeURIComponent(options.querBen)):{}
-    let doctorItem = querBen.doctorItem//医生信息
-    let dateInfoSelected = querBen.dateInfoSelected ;//排班信息
-    let waitDate = dateInfoSelected.RegDate
-
-    this.setData({
-      currentUser: currentUser,
-      doctorItem: doctorItem,
-      dateInfoSelected: dateInfoSelected,
-      waitDate: waitDate,
-      today: common.afterFewDays(1),
-      endDate: waitDate,
-      waitDateName: common.getWeekName(new Date(waitDate).getDay(), 1),
-      waitTimeName: this.getWaitTimeName(this.data.waitTime)
-    })
-  },
-  getWaitTimeName(str) {
-    let val = Number(str.replace(':', ''))
-    if (val >= 0 && val <= 1200) {
-      return '上午'
-    } else if (val > 1200 && val <= 2359) {
-      return '下午'
-    }
-  },
-//   选择截止日期
-  bindDateChange(e) {
-    let val = e.detail.value
-    this.setData({
-      waitDate: val,
-      waitDateName: common.getWeekName(new Date(e.detail.value).getDay(), 1)
-    })
-  },
-  bindTimeChange(e) {
-    this.setData({
-      waitTime: e.detail.value,
-      waitTimeName: this.getWaitTimeName(e.detail.value)
-    })
-  },
-  // 跳转候补成功
-  async jumpAppointmentSuccess() {
-    let currentUser = this.data.currentUser;
-    let doctorItem = this.data.doctorItem;
-    let dateInfoSelected = this.data.dateInfoSelected;
-    let queryData = {
-      HosId: app.globalData.districtId || app.globalData.hosId,
-      OpenId: wx.getStorageSync("openid"),
-      MemberId: currentUser.memberId,
-      MemberName: currentUser.memberName,
-      CertType: currentUser.isChildren == '1'?  currentUser.guardianCertType : currentUser.certType,
-      CertNum: currentUser.isChildren == '1'?  currentUser.guardianCertNum : currentUser.certNum,
-      ScheduleId: dateInfoSelected.ScheduleId,
-      DeptCode: doctorItem.DeptCode,
-      DeptName: doctorItem.DeptName,
-      DoctorCode: doctorItem.DoctorCode,
-      DoctorName: doctorItem.DoctorName,
-      RegDate: dateInfoSelected.RegDate,
-      WeekId: dateInfoSelected.WeekId,
-      TimeId: dateInfoSelected.TimeSlice,
-      RegFee: dateInfoSelected.RegFee,
-      InvalidDate: `${this.data.waitDate} ${this.data.waitTime}:00`,
-      ServiceId: '0',
-      MemberStore:{
-        cardEncryptionStore: currentUser.encryptionStore || '',
-        baseMemberEncryptionStore:currentUser.baseMemberEncryptionStore
-      }
-    }
-    let {resp,resData} = await yygh.waitListApiAdd(queryData)
-    if (resData.RespCode == '10000') {
-      common.goToUrl(`/pagesPatient/st1/business/yygh/waitSuccess/waitSuccess`)
-    }
-  }
-})

+ 0 - 4
pagesPatient/st1/business/yygh/waitRegistration/waitRegistration.json

@@ -1,4 +0,0 @@
-{
-    "navigationBarTitleText": "候补登记",
-    "usingComponents": {}
-  }

+ 309 - 0
pagesPatient/st1/business/yygh/waitRegistration/waitRegistration.vue

@@ -0,0 +1,309 @@
+<template>
+  <view class="container">
+    <view class="content_x">
+      <view class="doc_info">
+        <image class="doc_img" :src="doctorItem.PhotoUrl || iconUrl.icon_doctor"></image>
+        <view class="doc_con">
+          <view class="doc_name">{{ doctorItem.DoctorName }}</view>
+          <view class="doc_tip">{{ doctorItem.DeptName }} | {{ doctorItem.Title }}</view>
+        </view>
+      </view>
+
+
+      <view class="info_list">
+        <view class="info_item border_bottom">
+          <view class="info_item_tit">就诊人</view>
+          <view class="info_item_val">{{ currentUser.memberName }}({{ currentUser.sex == '1' ? '男' : currentUser.sex == '2' ? '女' : '未知' }}/{{ currentUser.ageStr }})</view>
+        </view>
+        <view class="info_item border_bottom" v-if="currentUser.isChildren == 0">
+          <view class="info_item_tit">身份证号</view>
+          <view class="info_item_val">{{ currentUser.certNum }}</view>
+        </view>
+        <view class="info_item border_bottom" v-if="currentUser.isChildren == 1">
+          <view class="info_item_tit">监护人身份证号</view>
+          <view class="info_item_val">{{ currentUser.guardianCertNum }}</view>
+        </view>
+        <view class="info_item border_bottom">
+          <view class="info_item_tit">候补排班</view>
+          <view class="info_item_val">{{ dateInfoSelected.RegDate }} {{ dateInfoSelected.WeekName }}{{ dateInfoSelected.TimeSliceStr }}</view>
+        </view>
+        <view class="info_item" v-if="false">
+          <view class="info_item_tit">候补截止</view>
+          <view class="info_item_val">
+            <picker mode="date" class="picker" :value="waitDate" :start="today" :end="endDate" @change="bindDateChange">
+              {{ waitDate }}
+            </picker>
+            {{ waitDateName }}{{ waitTimeName }}
+            <picker mode="time" class="picker" :value="waitTime" :end="endTime" @change="bindTimeChange">
+              {{ waitTime }}
+            </picker>
+            <image class="right" :src="iconUrl.icon_right"></image>
+          </view>
+        </view>
+        <view class="info_item_tip">
+          截至{{ waitDate }} {{ waitTime }}之前,系统将一直为您尝试预约挂号候补
+        </view>
+      </view>
+      <view class="public_btn_con">
+        <view class="public_btn backgroundCustom" @click="jumpAppointmentSuccess">确认登记</view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import { onLoad } from '@dcloudio/uni-app';
+import { common } from '@/utils';
+import icon from '@/utils/icon';
+import { waitListApiAdd } from '@/pagesPatient/service/yygh';
+
+const app = getApp();
+const iconUrl = ref(icon);
+const waitDate = ref(''); //候补日期 
+const waitDateName = ref(''); //星期
+const waitTime = ref('16:00'); //候补时间
+const waitTimeName = ref(''); //上下午
+const endTime = ref("23:59"); //截止时间
+const endDate = ref(''); //截止日期
+const showMore = ref(false); //是否展示过敏史等
+const currentUser = ref<any>({});
+const doctorItem = ref<any>({});
+const dateInfoSelected = ref<any>({});
+const today = ref('');
+
+onLoad((options: any) => {
+  let user = app.globalData.currentUser;
+  let querBen = options.querBen ? JSON.parse(decodeURIComponent(options.querBen)) : {};
+  let doctor = querBen.doctorItem; //医生信息
+  let dateInfo = querBen.dateInfoSelected; //排班信息
+  let wDate = dateInfo.RegDate;
+
+  currentUser.value = user;
+  doctorItem.value = doctor;
+  dateInfoSelected.value = dateInfo;
+  waitDate.value = wDate;
+  today.value = common.afterFewDays(1);
+  endDate.value = wDate;
+  waitDateName.value = common.getWeekName(new Date(wDate).getDay(), 1);
+  waitTimeName.value = getWaitTimeName(waitTime.value);
+});
+
+const getWaitTimeName = (str: string) => {
+  let val = Number(str.replace(':', ''));
+  if (val >= 0 && val <= 1200) {
+    return '上午';
+  } else if (val > 1200 && val <= 2359) {
+    return '下午';
+  }
+  return '';
+};
+
+// 选择截止日期
+const bindDateChange = (e: any) => {
+  let val = e.detail.value;
+  waitDate.value = val;
+  waitDateName.value = common.getWeekName(new Date(e.detail.value).getDay(), 1);
+};
+
+const bindTimeChange = (e: any) => {
+  waitTime.value = e.detail.value;
+  waitTimeName.value = getWaitTimeName(e.detail.value);
+};
+
+// 跳转候补成功
+const jumpAppointmentSuccess = async () => {
+  let user = currentUser.value;
+  let doctor = doctorItem.value;
+  let dateInfo = dateInfoSelected.value;
+  
+  let queryData = {
+    HosId: app.globalData.districtId || app.globalData.hosId,
+    OpenId: uni.getStorageSync("openid"),
+    MemberId: user.memberId,
+    MemberName: user.memberName,
+    CertType: user.isChildren == '1' ? user.guardianCertType : user.certType,
+    CertNum: user.isChildren == '1' ? user.guardianCertNum : user.certNum,
+    ScheduleId: dateInfo.ScheduleId,
+    DeptCode: doctor.DeptCode,
+    DeptName: doctor.DeptName,
+    DoctorCode: doctor.DoctorCode,
+    DoctorName: doctor.DoctorName,
+    RegDate: dateInfo.RegDate,
+    WeekId: dateInfo.WeekId,
+    TimeId: dateInfo.TimeSlice,
+    RegFee: dateInfo.RegFee,
+    InvalidDate: `${waitDate.value} ${waitTime.value}:00`,
+    ServiceId: '0',
+    MemberStore: {
+      cardEncryptionStore: user.encryptionStore || '',
+      baseMemberEncryptionStore: user.baseMemberEncryptionStore
+    }
+  };
+  
+  // Note: Original code destructures {resp, resData}, but handle.promistHandleNew usually returns [err, res] or just res depending on implementation.
+  // Assuming standard usage: let resp = await api(...)
+  // Based on waitListApiAdd implementation in index.ts: 
+  // let resp = handle.promistHandleNew(...)
+  // return handle.catchPromiseNew(resp, () => resp);
+  // So resp will be the result array/object.
+  // However, looking at original code: let {resp,resData} = await yygh.waitListApiAdd(queryData)
+  // It seems it expects an object with resp and resData. 
+  // But waitListApiAdd in index.ts returns `handle.catchPromiseNew(resp, () => resp)`.
+  // If promistHandleNew returns [err, res], then catchPromiseNew usually returns res if no error.
+  // Let's look at `handle.promistHandleNew` usage pattern in other files if possible, or assume standard uni-app-base pattern.
+  // In `record/index.ts`, `waitListApiAdd` was not present, I added it to `yygh/index.ts`.
+  // Standard `handle.catchPromiseNew(resp, () => resp)` usually returns the data directly.
+  // The original code `let {resp,resData} = await ...` suggests the return value is an object containing these keys.
+  // But my implementation of `waitListApiAdd` returns `resp` directly (or whatever `catchPromiseNew` returns).
+  // If `catchPromiseNew` returns the response body, we should check `RespCode` on it.
+  
+  let resp = await waitListApiAdd(queryData);
+  
+  // Assuming resp is the data object or array. 
+  // If resp is array (common in some frameworks), check resp[0].
+  // If resp is object, check resp.RespCode.
+  // Let's assume resp is the response object.
+  // If the original code destructured it, maybe the library returns {resp, resData}.
+  // But I'm using the standard `handle` from `pagesPatient/service/yygh/index.ts`.
+  // Let's check `regSignForHis` usage in `signInList.vue` I just wrote:
+  // let resp = await regSignForHis(querData)
+  // if (!common.isEmpty(resp)) { ... resp[0] ... }
+  // This suggests `resp` is an array of results.
+  
+  // Wait, the original code used `yygh.waitListApiAdd`.
+  // I should check if I should return `resp` or `resp[0]`.
+  // Usually `handle.catchPromiseNew` returns the business data.
+  // If the API returns a list, it's a list. If it returns an object, it's an object.
+  // `waitListApiAdd` likely returns a status object.
+  
+  if (resp && resp.RespCode == '10000') {
+      common.goToUrl(`/pagesPatient/st1/business/yygh/waitSuccess/waitSuccess`);
+  } else if (Array.isArray(resp) && resp[0] && resp[0].RespCode == '10000') {
+      common.goToUrl(`/pagesPatient/st1/business/yygh/waitSuccess/waitSuccess`);
+  } else {
+     // If response structure is different, we might need to adjust.
+     // For now, let's assume if it returns success it might be in resp.RespCode or we just check if it's not empty.
+     // But explicit check for 10000 is better.
+     // Let's try to be robust.
+     if ((resp && resp.RespCode == '10000') || (Array.isArray(resp) && resp[0] && resp[0].RespCode == '10000')) {
+        common.goToUrl(`/pagesPatient/st1/business/yygh/waitSuccess/waitSuccess`);
+     }
+  }
+};
+</script>
+
+<style scoped>
+.content_x {
+  width: 100%;
+  display: inline-block;
+  padding-bottom: 170upx;
+}
+
+.doc_info {
+  position: relative;
+  padding: 30upx;
+  display: flex;
+  align-items: center;
+  background-color: #fff;
+  margin-bottom: 20upx;
+}
+
+.right {
+  position: absolute;
+  right: 30upx;
+  top: 0;
+  bottom: 0;
+  margin: auto 0;
+  width: 12upx;
+  height: 24upx;
+}
+
+.info_item .right {
+  position: inherit;
+  margin-left: 12upx;
+}
+
+.doc_img {
+  width: 88upx;
+  height: 88upx;
+  flex-shrink: 0;
+  margin-right: 24upx;
+  border-radius: 50%;
+}
+
+.doc_con {
+  width: 100%;
+}
+
+.doc_name {
+  font-size: 32upx;
+  font-family: PingFang SC;
+  font-weight: bold;
+  color: #333;
+  line-height: 18upx;
+  margin-bottom: 15upx;
+}
+
+.doc_tip {
+  font-size: 26upx;
+  font-family: PingFang SC;
+  color: #999;
+}
+
+.info_list {
+  background-color: #fff;
+  display: inline-block;
+  width: 100%;
+  margin-bottom: 20upx;
+  padding: 0 30upx;
+}
+
+.info_item {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  font-size: 32upx;
+  font-family: PingFang SC;
+  color: #333;
+}
+
+.info_item_val {
+  padding: 38upx 0;
+  display: flex;
+  align-items: center;
+  font-size: 32upx;
+  font-family: PingFang SC;
+  color: #666666;
+  line-height: 38upx;
+}
+
+.info_item_tip {
+  font-size: 28upx;
+  font-family: PingFang SC;
+  color: #999;
+  line-height: 42upx;
+  padding: 25upx 30upx;
+  background: #f7f7f7;
+  border-radius: 10upx;
+  position: relative;
+  margin-bottom: 30upx;
+}
+
+.info_item_tip::after {
+  display: block;
+  content: "";
+  width: 20upx;
+  height: 20upx;
+  background-color: #f7f7f7;
+  transform-origin: 50%;
+  transform: rotateZ(45deg);
+  position: absolute;
+  left: 30upx;
+  top: -10upx;
+}
+
+.picker {
+  margin: 0 20upx;
+}
+</style>

+ 0 - 50
pagesPatient/st1/business/yygh/waitRegistration/waitRegistration.wxml

@@ -1,50 +0,0 @@
-<view class="container">
-  <view class="content_x">
-    <view class="doc_info">
-      <image class="doc_img" src="{{doctorItem.PhotoUrl|| iconUrl.icon_doctor}}"></image>
-      <view class="doc_con">
-        <view class="doc_name">{{doctorItem.DoctorName}}</view>
-        <view class="doc_tip">{{doctorItem.DeptName}} | {{doctorItem.Title}}</view>
-      </view>
-    </view>
-
-
-    <view class="info_list">
-      <view class="info_item border_bottom">
-        <view class="info_item_tit">就诊人</view>
-        <view class="info_item_val">{{currentUser.memberName}}({{currentUser.sex=='1'?'男':currentUser.sex=='2'?'女':'未知'}}/{{currentUser.ageStr}})</view>
-      </view>
-      <view class="info_item border_bottom" wx:if="{{currentUser.isChildren == 0}}">
-        <view class="info_item_tit">身份证号</view>
-        <view class="info_item_val">{{currentUser.certNum}}</view>
-      </view>
-      <view class="info_item border_bottom" wx:if="{{currentUser.isChildren == 1}}">
-        <view class="info_item_tit">监护人身份证号</view>
-        <view class="info_item_val">{{currentUser.guardianCertNum}}</view>
-      </view>
-      <view class="info_item border_bottom">
-        <view class="info_item_tit">候补排班</view>
-        <view class="info_item_val">{{dateInfoSelected.RegDate}} {{dateInfoSelected.WeekName}}{{dateInfoSelected.TimeSliceStr}}</view>
-      </view>
-      <view class="info_item" wx:if="{{false}}">
-        <view class="info_item_tit">候补截止</view>
-        <view class="info_item_val">
-          <picker mode="date" class="picker" value="{{waitDate}}" start="{{today}}" end="{{endDate}}" bindchange="bindDateChange">
-            {{waitDate}}
-          </picker>
-          {{waitDateName}}{{waitTimeName}}
-          <picker mode="time" class="picker" value="{{waitTime}}" end="{{endTime}}" bindchange="bindTimeChange">
-            {{waitTime}}
-          </picker>
-          <image class="right" src="{{iconUrl.icon_right}}"></image>
-        </view>
-      </view>
-      <view class="info_item_tip">
-        截至{{waitDate}} {{waitTime}}之前,系统将一直为您尝试预约挂号候补
-      </view>
-    </view>
-    <view class="public_btn_con">
-      <view class="public_btn backgroundCustom" bindtap="jumpAppointmentSuccess">确认登记</view>
-    </view>
-  </view>
-</view>

+ 0 - 118
pagesPatient/st1/business/yygh/waitRegistration/waitRegistration.wxss

@@ -1,118 +0,0 @@
-.content_x {
-  width: 100%;
-  display: inline-block;
-  padding-bottom: 170rpx;
-}
-
-.doc_info {
-  position: relative;
-  padding: 30rpx;
-  display: flex;
-  align-items: center;
-  background-color: #fff;
-  margin-bottom: 20rpx;
-}
-
-.right {
-  position: absolute;
-  right: 30rpx;
-  top: 0;
-  bottom: 0;
-  margin: auto 0;
-  width: 12rpx;
-  height: 24rpx;
-}
-
-.info_item .right {
-  position: inherit;
-  margin-left: 12rpx;
-}
-
-.doc_img {
-  width: 88rpx;
-  height: 88rpx;
-  flex-shrink: 0;
-  margin-right: 24rpx;
-  border-radius: 50%;
-}
-
-.doc_con {
-  width: 100%;
-}
-
-.doc_name {
-  font-size: 32rpx;
-  font-family: PingFang SC;
-  font-weight: bold;
-  color: #333;
-  line-height: 18rpx;
-  margin-bottom: 15rpx;
-}
-
-.doc_tip {
-  font-size: 26rpx;
-  font-family: PingFang SC;
-
-  color: #999;
-}
-
-.info_list {
-  background-color: #fff;
-  display: inline-block;
-  width: 100%;
-  margin-bottom: 20rpx;
-  padding: 0 30rpx;
-}
-
-.info_item {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  font-size: 32rpx;
-  font-family: PingFang SC;
-
-  color: #333;
-}
-
-.info_item_val {
-  padding: 38rpx 0;
-  display: flex;
-  align-items: center;
-}
-
-.info_item_tip {
-  font-size: 28rpx;
-  font-family: PingFang SC;
-
-  color: #999;
-  line-height: 42rpx;
-  padding: 25rpx 30rpx;
-  background: #f7f7f7;
-  border-radius: 10rpx;
-  position: relative;
-  margin-bottom: 30rpx;
-}
-
-.info_item_tip::after {
-  display: block;
-  content: "";
-  width: 20rpx;
-  height: 20rpx;
-  background-color: #f7f7f7;
-  transform-origin: 50%;
-  transform: rotateZ(45deg);
-  position: absolute;
-  left: 30rpx;
-  top: -10rpx;
-}
-
-.info_item_val{
-font-size: 32rpx;
-font-family: PingFang SC;
-
-color: #666666;
-line-height: 38rpx;
-}
-.picker{
-  margin: 0 20rpx;
-}

+ 0 - 18
pagesPatient/st1/business/yygh/waitSuccess/waitSuccess.js

@@ -1,18 +0,0 @@
-const app = getApp();
-import common from "../../../../../utils/common.js";
-import icon from "../../../../../utils/icon.js";
-Page({
-  data: {
-    iconUrl:icon,
-  },
-  onLoad: function(options) {
-   
-  },
- 
-  /**
-   * 返回首页
-   */
-  backHome(e) {
-    common.goToUrl('/pages/st1/business/tabbar/homePage/homePage',{skipWay:"reLaunch"})
-  }
-})

+ 0 - 4
pagesPatient/st1/business/yygh/waitSuccess/waitSuccess.json

@@ -1,4 +0,0 @@
-{
-    "usingComponents": {},
-    "navigationBarTitleText": "候补登记成功"
-  }

+ 116 - 0
pagesPatient/st1/business/yygh/waitSuccess/waitSuccess.vue

@@ -0,0 +1,116 @@
+<template>
+  <view class="container">
+    <view class="content">
+      <view class="main_box">
+        <view class="make_msg_box" :class="{ topBorderRadius: pageType == 'yygh' }">
+          <image class="success_icon" :src="iconUrl.icon_circleActive"></image>
+          <text class="title">候补已提交!</text>
+        </view>
+        <view class="con">
+          <view class="tips">
+            <view class="tips_name">1、您已完成候补登记,进入预约候补队列!当出现预约成功患者退号时,系统将根据您的候补队列次序,自动为您预约挂号,并短信通知您如期就诊;</view>
+            <view class="tips_name">2、如您需要取消候补登记,可通过“我的”-“候补记录”进行取消操作。</view>
+          </view>
+        </view>
+      </view> 
+      
+      <view class="btn_list">
+        <view class="btn_item btn_item_width100 backgroundCustom" @click="backHome">返回首页</view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import { common } from '@/utils';
+import icon from '@/utils/icon';
+
+const iconUrl = ref(icon);
+const pageType = ref(''); // Assuming pageType might be passed or used, initializing it. Original code used pageType in template but didn't initialize in data, maybe from options?
+// Original JS: onLoad: function(options) {} - empty.
+// Template: {{pageType == 'yygh' && 'topBorderRadius'}}
+// It seems pageType wasn't used in JS but used in WXML. It might be safe to default to empty or check options if intended.
+// Since onLoad was empty in JS, I'll leave it empty here or just init ref.
+
+const backHome = () => {
+  common.goToUrl('/pages/st1/business/tabbar/homePage/homePage', { skipWay: "reLaunch" });
+};
+</script>
+
+<style scoped>
+.main_box {
+  width: 100%;
+  height: 100%;
+  padding: 30upx;
+  box-sizing: border-box;
+  padding-bottom: 210upx;
+  overflow: auto;
+}
+
+.make_msg_box {
+  width: 100%;
+  padding: 30upx 0upx 40upx 0upx;
+  box-sizing: border-box;
+  background: white;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  border-radius: 24upx;
+}
+
+.make_msg_box .success_icon {
+  width: 120upx;
+  height: 120upx;
+  margin-bottom: 30upx;
+}
+
+.make_msg_box .title {
+  text-align: center;
+  font-size: 36upx;
+  font-family: PingFang SC;
+  font-weight: bold;
+  color: #333;
+  text-align: left;
+}
+
+.tips {
+  padding: 40upx 30upx;
+  box-shadow: 0px 0px 40upx 0px rgba(0, 0, 0, 0.06);
+  border-radius: 24upx;
+  margin-top: 30upx;
+  background-color: #fff;
+}
+
+.tips_name {
+  font-size: 30upx;
+  color: rgba(85, 85, 85, 1);
+  line-height: 44upx;
+  text-align: justify;
+}
+
+.btn_list {
+  height: 100upx;
+  display: flex;
+  position: fixed;
+  width: 100%;
+  left: 0;
+  bottom: 0;
+}
+
+.btn_item {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 36upx;
+  font-weight: 500;
+  color: rgba(166, 166, 166, 1);
+  background-color: #fff;
+  width: 50%;
+}
+
+.btn_item_width100 {
+  width: 100%;
+}
+</style>

+ 0 - 20
pagesPatient/st1/business/yygh/waitSuccess/waitSuccess.wxml

@@ -1,20 +0,0 @@
-<view class="container">
-  <view class="content ">
-    <view class="main_box">
-      <view class="make_msg_box {{pageType == 'yygh' && 'topBorderRadius'}}">
-        <image class="success_icon" src="{{iconUrl.icon_circleActive}}"></image>
-        <text class="title">候补已提交!</text>
-      </view>
-      <view class="con">
-        <view class="tips">
-          <view class="tips_name">1、您已完成候补登记,进入预约候补队列!当出现预约成功患者退号时,系统将根据您的候补队列次序,自动为您预约挂号,并短信通知您如期就诊;</view>
-          <view class="tips_name">2、如您需要取消候补登记,可通过“我的”-“候补记录”进行取消操作。</view>
-        </view>
-      </view>
-    </view> 
-    
-    <view class="btn_list">
-      <view class="btn_item btn_item_width100 backgroundCustom" bindtap="backHome">返回首页</view>
-    </view>
-  </view>
-</view>

+ 0 - 72
pagesPatient/st1/business/yygh/waitSuccess/waitSuccess.wxss

@@ -1,72 +0,0 @@
-
-
-.main_box {
-  width: 100%;
-  height: 100%;
-  padding: 30rpx;
-  box-sizing: border-box;
-  padding-bottom: 210rpx;
-  overflow: auto;
-}
-
-.make_msg_box {
-  width: 100%;
-  padding: 30rpx 0rpx 40rpx 0rpx;
-  box-sizing: border-box;
-  background: white;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  align-items: center;
-  border-radius: 24rpx;
-}
-.make_msg_box .success_icon {
-  width: 120rpx;
-  height: 120rpx;
-  margin-bottom: 30rpx;
-}
-.make_msg_box .title {
-  text-align: center;
-  font-size: 36rpx;
-  font-family: PingFang SC;
-  font-weight: bold;
-  color: #333;
-  text-align: left;
-}
-
-.tips {
-  padding: 40rpx 30rpx;
-  box-shadow: 0px 0px 40rpx 0px rgba(0, 0, 0, 0.06);
-  border-radius: 24rpx;
-  margin-top: 30rpx;
-  background-color: #fff;
-}
-.tips_name{
-  font-size: 30rpx;
-  color: rgba(85, 85, 85, 1);
-  line-height: 44rpx;
-  text-align: justify;
-}
-
-.btn_list {
-  height: 100rpx;
-  display: flex;
-  position: fixed;
-  width: 100%;
-  left: 0;
-  bottom: 0;
-}
-
-.btn_item {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  font-size: 36rpx;
-  font-weight: 500;
-  color: rgba(166, 166, 166, 1);
-  background-color: #fff;
-  width: 50%;
-}
-.btn_item_width100{
-  width: 100%;
-}

+ 0 - 459
pagesPatient/st1/business/yygh/yyghClinicMsg/yyghClinicMsg.js

@@ -1,459 +0,0 @@
-const app = getApp();
-import yygh from "../../../../config/api/yygh/index.js";
-import pay from "../../../../config/api/pay/index.js";
-import regeneratorRuntime from "../../../../../utils/runtime.js";
-import common from "../../../../../utils/common.js";
-import publicFn from "../../../../../utils/publicFn.js";
-import { pagesPatientFn } from '@/utils';
-import apiRootUrl from "../../../../../config/api.js";
-import icon from "../../../../../utils/icon.js";
-
-Page({
-  data: {
-    iconUrl:icon,
-    withoutCard:false,//是否可以无卡预约
-    noDataValue: '当前医生暂无排班', //医生是否有排班
-    doctorItem: {},
-    dateInfoSelected: {}, //当前选择的排班时间
-    showCon: false,
-    showNoData: false,
-    numberList: [], //预约时段 
-    numberInfoSelected: {}, //当前选中的预约时段
-    currentUser: {},
-    doctorInfoIsShow: false,
-    doctorInfo: {}, //医生详情信息
-    doctorListConfig: {}, //医生列表页配置
-    serviceId:'',
-  },
-  onLoad: function(options) {
-    let queryBean = app.globalData.queryBean || {};
-    /**医生列表页配置 */
-    let doctorListConfig = common.deepCopy(app.globalData.config.pageConfiguration.yyghDoctorList_config)
-    /**当前页面配置 */
-    let pageConfig = common.deepCopy(app.globalData.config.pageConfiguration.yyghClinicMsg_config)
-    let dateInfoSelected = {}
-    /**通过上级页面传的item和点击的排班Index 取到当前点击的排班时间  如果是从预约挂号页面进来的  则取挂号排班时间*/
-    if(options?.schedule){
-      dateInfoSelected = common.parse(options?.schedule)
-    }else if (queryBean.Data_1 && options.selectedIndex) {
-      dateInfoSelected = queryBean.Data_1[options.selectedIndex]
-    }
-    options?.deptCode && (queryBean.DeptCode = options?.deptCode)
-    options?.doctorCode && (queryBean.DoctorCode = options?.doctorCode)
-    this.setData({
-      options:options,
-      serviceId:options.serviceId || '',
-      queryBean: queryBean,
-      dateInfoSelected: dateInfoSelected,
-      doctorListConfig: doctorListConfig,
-      pageConfig: pageConfig,
-      withoutCard: app.globalData.withoutCard
-    })
-  },
-  onShow: function() {
-    this.main()
-  },
-  async main() {
-    this.setData({
-      currentUser: app.globalData.currentUser
-    })
-    let showNoData = true;
-    /**获取医生信息 */
-    await this.setterDoctorList();
-    if (!common.isEmpty(this.data.doctorItem)) {
-      showNoData = false
-      /**获取预约时间段 */
-      await this.queryNumbers()
-    }
-    this.setData({
-      showCon: true,
-      showNoData: showNoData
-    })
-  },
-  /**
-   * 医生详情点击
-   */
-  async doctorInfoClick() {
-    let doctorItem = this.data.doctorItem;
-    let queryData = {
-      HosId: app.globalData.districtId || app.globalData.hosId,
-      DeptCode: doctorItem.DeptCode || '',
-      DoctorCode: doctorItem.DoctorCode || '',
-      DoctorName: ''
-    }
-    let resp = await yygh.queryClinicBaseDoctor(queryData);
-    if (!common.isEmpty(resp)) {
-      this.setData({
-        doctorInfoIsShow: true,
-        doctorInfo: resp[0]
-      })
-    }
-  },
-  /**
-   * 预约时段点击
-   */
-  numberClick(e) {
-    this.setData({
-      numberInfoSelected: this.data.numberList[e.currentTarget.dataset.index]
-    })
-  },
-  /**
-   * 日期选择
-   */
-  timeClick(e) {
-    let item = e.currentTarget.dataset.item;
-    let index = e.currentTarget.dataset.index;
-    let schedulIndex = e.currentTarget.dataset.schedulindex;
-    if ((item.IsHalt == 7 && item.WaitLeaveCount <= 0) || item.IsHalt == '2') {
-      return;
-    }
-    this.setData({
-      numberList:[],
-      dateInfoSelected: item
-    })
-    // 判断不等于约满或者不等于停诊查询号源
-    if(item.IsHalt !=7 && item.IsHalt != '2'){
-      this.queryNumbers()
-    }
-  },
-  /**
-   * 获取号源列表
-   */
-  async queryNumbers() {
-    let dateInfoSelected = this.data.dateInfoSelected;
-    let queryData = {
-      HosId: app.globalData.districtId || app.globalData.hosId,
-      DeptCode: dateInfoSelected.DeptCode,
-      DoctorCode: dateInfoSelected.DoctorCode,
-      RegDate: dateInfoSelected.RegDate,
-      TimeSlice: dateInfoSelected.TimeSlice,
-      ScheduleId: dateInfoSelected.ScheduleId,
-      TransactionCode: 2002,
-    }
-    let numberList = await yygh.queryNumbers(queryData)
-    let numberInfoSelected = {}
-    if(!common.isEmpty(this.data.options?.number)){
-      numberInfoSelected = common.parse(this.data.options?.number)
-    }else{
-      numberInfoSelected = numberList[0]
-    }
-    this.setData({
-      numberList: numberList || [],
-      numberInfoSelected: numberInfoSelected, //默认选中第一个号源
-    })
-  },
-  /**
-   * 处理医生列表返回值
-   */
-  async setterDoctorList() {
-    let queryBean = this.data.queryBean;
-    let dateInfoSelected = this.data.dateInfoSelected;
-    let result = [];
-    let hasAllSchedules = this.data.doctorListConfig.hasAllSchedules;
-    let queryData = {
-      HosId: app.globalData.districtId || app.globalData.hosId,
-      DeptCode: queryBean.DeptCode,
-      DoctorCode: queryBean.DoctorCode,
-      WorkDateStart: hasAllSchedules ? "" : dateInfoSelected.RegDate,
-      WorkDateEnd: hasAllSchedules ? "" : dateInfoSelected.RegDate,
-      TitleCode: "",
-      OrderByDoc: '1',
-      WaitRule: '1'
-
-    }
-    // 判断为当日挂号
-    if(this.data.serviceId == '009'){
-      queryData.WorkDateStart = common.getDate()
-      queryData.WorkDateEnd = common.getDate()
-      queryData.ServiceId = this.data.serviceId
-    }
-    let resp = await yygh.queryClinicDoctorSchedule(queryData)
-    if (!common.isEmpty(resp)) {
-      let doctorItem = resp[0];
-      /**如果医生头像没有域名 添加域名 */
-      if (doctorItem.PhotoUrl && doctorItem.PhotoUrl.indexOf('http') == '-1') {
-        doctorItem.PhotoUrl = apiRootUrl.ApiRootUrl + doctorItem.PhotoUrl
-      }
-      doctorItem.PhotoUrl = doctorItem.PhotoUrl.replace(/\\/g, '/')
-      doctorItem.Data_1.map(item => {
-        item.RegDateDiy = item.RegDate.substring(5)
-        item.WeekName = item.RegDate == common.newDay()?'今天':item.WeekName
-        item.DeptName = doctorItem.DeptName
-        item.DeptCode = doctorItem.DeptCode
-        item.DoctorName = doctorItem.DoctorName
-        item.DoctorCode = doctorItem.DoctorCode
-      })
-
-      // 数据处理 医生多科室
-      let obj = [{
-        Check:true,
-        DeptName:doctorItem.DeptName,
-        DeptCode:doctorItem.DeptCode,
-        DoctorName:doctorItem.DoctorName,
-        DoctorCode:doctorItem.DoctorCode,
-        Data_1:doctorItem.Data_1,
-      }]
-      doctorItem.Scheduling = obj
-      /**重新赋值当前项   否则提交订单后后退不刷新值 */
-      let dateInfoSelected = resp.filter(item => item && item.ScheduleId == this.data.dateInfoSelected.ScheduleId)[0] || this.data.dateInfoSelected
-      this.setData({
-        doctorItem: doctorItem,
-        /**历史医生进入  无ScheduleId 重新赋值  */
-        dateInfoSelected: this.data.dateInfoSelected.ScheduleId ? dateInfoSelected : doctorItem && doctorItem.Data_1 && doctorItem.Data_1[0] || {}
-      })
-    }
-  },
-  switchChange(e) {
-    let value = e.detail.value;
-    this.setData({
-      reducibleOnly: value
-    })
-    this.main()
-  },
-  /**
-   * 立即预约点击
-   */
-  async confirmClick(e) {
-    let currentUser = this.data.currentUser;
-    let formId = e.detail.formId;
-    let dateInfoSelected = this.data.dateInfoSelected;
-    let numberInfoSelected = this.data.numberInfoSelected;
-    let doctorItem = this.data.doctorItem;
-    
-    // 查询当前用户 是否被授权
-    if(await publicFn.isCurrentUserAuth(currentUser,'Book',true)) return
-
-    /**是否存在待支付订单 */
-    if (await pagesPatientFn.hasOrderToBePaid('0,009')) return
-    common.throttle(async() => {
-      if (common.isEmpty(this.data.dateInfoSelected)) {
-        common.showToast('请选择预约日期')
-        return
-      }
-      if (common.isEmpty(this.data.numberInfoSelected)) {
-        common.showToast('请选择预约时间')
-        return
-      }
-      /**消息推送 */
-      //  let pushData = {
-      //    SceneId: formeId,
-      //    OpenId: wx.getStorageSync('openid')
-      //  }
-      // await complete.pushBaiduAndWxSceneId(pushData)
-      /**锁号 */
-      let queryData = {
-        HosId: app.globalData.districtId || app.globalData.hosId,
-        ScheduleId: dateInfoSelected.ScheduleId,
-        DeptCode: dateInfoSelected.DeptCode,
-        DoctorCode: dateInfoSelected.DoctorCode,
-        RegType: '1',
-        RegDate: dateInfoSelected.RegDate,
-        TimeSlice: dateInfoSelected.TimeSlice,
-        SqNo: numberInfoSelected.SqNo,
-        CommendTime: numberInfoSelected.EndTime ? `${numberInfoSelected.StartTime}-${numberInfoSelected.EndTime}` : numberInfoSelected.StartTime,
-        SourceCode: numberInfoSelected.SourceCode,
-        MemberId:currentUser.memberId,
-        CardType: '1',
-        CardNo: currentUser.cardNo || '',
-        MemberStore:{
-          cardEncryptionStore: currentUser.encryptionStore || '',
-          baseMemberEncryptionStore:currentUser.baseMemberEncryptionStore
-        },
-        Store:{
-          cardEncryptionStore: currentUser.encryptionStore || '',
-          baseMemberEncryptionStore:currentUser.baseMemberEncryptionStore
-        }
-      }
-      let lockResp = await yygh.lockOrder(queryData);
-      if (!common.isEmpty(lockResp)) {
-        /**锁号成功 */
-
-        /**本地下单 */
-        let addorderData = {
-          HosId: app.globalData.hosId,
-          OrderId: lockResp[0].OrderId,
-          PrescNo: '',
-          PayMoney: lockResp[0].Fee,
-          TotalMoney: lockResp[0].Fee,
-          IsOnlinePay: lockResp[0].IsOnlinePay,
-          PriceName: '挂号支付',
-          OperatorId: wx.getStorageSync('openid'),
-          ServiceId: '0',
-          PayFeeItem: '0',
-          EqptType: '1',
-          BankCardNo: '',
-          BankSeqNo: '',
-          ChargeSource: '',
-          MemberId: currentUser.memberId,
-          OperatorName: currentUser.MemberName,
-          Store:{
-            cardEncryptionStore: currentUser.encryptionStore || '',
-            baseMemberEncryptionStore:currentUser.baseMemberEncryptionStore
-          },
-          Data_1: {
-            DoctorCode: dateInfoSelected.DoctorCode || doctorItem.DoctorCode,
-            DoctorName: dateInfoSelected.DoctorName || doctorItem.DoctorName,
-            DeptCode: dateInfoSelected.DeptCode || doctorItem.DeptCode,
-            DeptName: dateInfoSelected.DeptName || doctorItem.DeptName,
-            RegDate: dateInfoSelected.RegDate,
-            CommendTime: numberInfoSelected.CommendTime,
-            scene_id: formId,
-            FeeInfo: lockResp[0].FeeInfo,
-            scene_type: '1',
-            TransactionCode: '6001'
-          }
-        }
-        let addOrderResp = await pay.addOrderLocal(addorderData)
-        if (!common.isEmpty(addOrderResp)) {
-          /**本地下单成功 */
-          let url = `/pagesPatient/st1/business/pay/payState/payState?pageType=yygh&orderId=${lockResp[0].OrderId}`
-          if (lockResp[0].IsOnlinePay == '1') {
-            /**在线支付 */
-            url = `/pagesPatient/st1/business/pay/payMent/payMent?orderId=${lockResp[0].OrderId}`
-          } else if (lockResp[0].IsOnlinePay == '2') {
-            /**不支付 boockService挂号 */
-            let queryData = {
-              HosId: app.globalData.districtId || app.globalData.hosId,
-              OrderId: lockResp[0].OrderId,
-              OperatorId: wx.getStorageSync('openid'),
-              TransactionCode: "3003",
-              MemberId: currentUser.memberId,
-              SourceType:0,
-              Store:{
-                cardEncryptionStore: currentUser.encryptionStore || '',
-                baseMemberEncryptionStore:currentUser.baseMemberEncryptionStore
-              },
-            }
-            let {resp,resData} = await yygh.bookService(queryData)
-            if (resData.RespCode != 10000) {
-              await yygh.unlock({OrderId:lockResp[0].OrderId})
-              return
-            }
-          }
-          common.goToUrl(url)
-        }
-
-      }
-
-    })
-  },
-  /**
-   * 查询医生其它科室排班
-   */
-  async queryScheduleList(e){
-    let hasAllSchedules = this.data.doctorListConfig.hasAllSchedules;
-    let dateInfoSelected = this.data.dateInfoSelected;
-    let doctorItem = this.data.doctorItem
-    let querData = {
-      workDateEnd: hasAllSchedules ? "" : dateInfoSelected.RegDate,
-      workDateStart: hasAllSchedules ? "" : dateInfoSelected.RegDate,
-      doctorCode: doctorItem.DoctorCode,
-      deptCode:doctorItem.DeptCode ,
-      hosId: app.globalData.districtId || app.globalData.hosId,
-      WaitRule: '1'
-    }
-    let res = await yygh.queryScheduleList(querData)
-    if(common.isNotEmpty(res)){
-      let scheduleList = []
-      res.map(async (item,index)=>{
-        // 转换返回数据 小写转大写
-        item.hisQueryClinicSchedules = common.changeObj(item.hisQueryClinicSchedules)
-        item.hisQueryBaseDoctor = common.changeObj(item.hisQueryBaseDoctor)
-        if(item.hisQueryClinicSchedules.length > 0){
-          // 判断是否多数据处理 星期 时间 上下午
-          if(item.hisQueryClinicSchedules.length > 0){
-            item.hisQueryClinicSchedules.map(ele=>{
-              ele.WeekName = ele.RegDate == common.newDay()?'今天':common.weekDay(ele.RegDate,1)
-
-              ele.RegDateDiy = ele.RegDate.substring(5)
-              ele.TimeSliceStr = ele.TimeSlice==1?'上午':ele.TimeSlice==2?'下午':'全天'
-            })
-          }
-          scheduleList.push({
-            Check:item.hisQueryBaseDoctor.DeptCode==doctorItem.DeptCode?true:false,
-            DeptName:item.hisQueryBaseDoctor.DeptName,
-            DeptCode:item.hisQueryBaseDoctor.DeptCode,
-            DoctorName:doctorItem.DoctorName,
-            DoctorCode:doctorItem.DoctorCode,
-            Data_1:item.hisQueryClinicSchedules,
-            showAllSchedu:item.showAllSchedu,
-          })
-        }
-      })
-      // 给当前查询的医生新加列表
-      doctorItem.Scheduling = scheduleList
-    }
-    // 查询过的医生 不展示switch
-    doctorItem.ShowDeptSwitch = true
-    this.setData({
-      doctorItem:doctorItem
-    })
-  },
-    /**
-   * 折叠列表
-   */
-  foldList(e) {
-    let schedulIndex = e.currentTarget.dataset.schedulindex
-    let doctorItem = this.data.doctorItem
-    // 当前点击的科室是打开的状态,则进行关闭,不查号源
-    if(doctorItem.Scheduling[schedulIndex].Check){
-      doctorItem.Scheduling[schedulIndex].Check = false
-      this.setData({
-        doctorItem
-      })
-    }else{
-      let dateInfoSelected = {}
-      // 全部遍历关闭展开数据信息
-      doctorItem.Scheduling.map(item=>item.Check = false)
-      // 当前打开
-      doctorItem.Scheduling[schedulIndex].Check = true
-      // 过滤当前打开的排班信息 获取到未满未停诊的排班
-      let dateInfoSelecteds = doctorItem.Scheduling[schedulIndex].Data_1.filter(item=>item.IsHalt != '7' || item.IsHalt != '2')
-      // 判断过滤条件是否为空 为空踢提示
-      if(common.isEmpty(dateInfoSelecteds)){
-        common.showToast("查询号源失败,请选择一个排班信息")
-      }else{
-        // 否者查询号源
-        dateInfoSelected = dateInfoSelecteds[0]
-      }
-      this.setData({
-        dateInfoSelected: dateInfoSelected,
-        doctorItem
-      })
-      this.queryNumbers()
-    }
-  },
-  //   候补登记
-  async waitRegistration(){
-    let currentUser = this.data.currentUser;
-    let dateInfoSelected = this.data.dateInfoSelected;
-    let doctorItem = this.data.doctorItem;
-    if(dateInfoSelected.WaitLeaveCount<=0)return
-    let queryData = {
-      HosId: app.globalData.districtId ||app.globalData.hosId,
-      OpenId: wx.getStorageSync("openid"),
-      MemberId: currentUser.memberId,
-      ScheduleId: dateInfoSelected.ScheduleId,
-      DeptCode: doctorItem.DeptCode,
-      DoctorCode: doctorItem.DoctorCode,
-      RegDate: dateInfoSelected.RegDate,
-      WeekId: dateInfoSelected.WeekId,
-      TimeId: dateInfoSelected.TimeSlice,
-      Store:{
-        cardEncryptionStore: currentUser.encryptionStore || '',
-        baseMemberEncryptionStore:currentUser.baseMemberEncryptionStore
-      }
-    }
-    let {resp,resData}  = await yygh.checkBeforeAddWaitList(queryData)
-    if (resData.RespCode == '10000') {
-      doctorItem.Intro = ''
-      doctorItem.Data_1 = ''
-      doctorItem.Scheduling = ''
-      let querBen = encodeURIComponent(JSON.stringify({
-        doctorItem,
-        dateInfoSelected
-      }))
-      common.goToUrl(`/pagesPatient/st1/business/yygh/waitRegistration/waitRegistration?querBen=${querBen}`)
-    }
-  }
-})

+ 0 - 14
pagesPatient/st1/business/yygh/yyghClinicMsg/yyghClinicMsg.json

@@ -1,14 +0,0 @@
-{
-  "usingComponents": {
-    "noData": "/pages/st1/components/noData/noData",
-    "overduePerson":"/pages/st1/components/overduePerson/overduePerson",
-    "userInfo":"/pagesPersonal/st1/components/userInfo/userInfo",
-    "doctorInfo": "/pagesPatient/st1/components/doctorInfo/doctorInfo",
-    "aiCustomerEntry": "/pagesAICustomerService/st1/components/aiCustomerEntry/aiCustomerEntry"
-  },
-  "componentPlaceholder": {
-    "userInfo": "view",
-    "aiCustomerEntry": "view"
-  },
-  "navigationBarTitleText": "挂号" 
-}

+ 855 - 0
pagesPatient/st1/business/yygh/yyghClinicMsg/yyghClinicMsg.vue

@@ -0,0 +1,855 @@
+<template>
+  <view class="container">
+    <view class="content" v-if="showCon">
+      <view class="userInfoTopFixe">
+        <userInfo :userInfo="currentUser" :type="withoutCard ? 'member' : 'card'" bgClass="bgLinGra"></userInfo>
+      </view>
+      <view class="content_inner" v-if="doctorItem.DoctorName">
+        <view class="content_inner_item">
+          <view class="doctor_item">
+            <view class="doctor_item_nav" @click="doctorInfoClick">
+              <view class="doctor_item_nav_img">
+                <image :src="doctorItem.PhotoUrl || iconUrl.icon_doctor" mode="widthFix"></image>
+              </view>
+              <view class="doctor_item_nav_tit">
+                <view class="doctor_item_nav_subtit">
+                  <text class="doctor_item_nav_subtit_val">{{ doctorItem.DoctorName }}</text>
+                  <text v-if="doctorItem.DoctorTitle || doctorItem.Title" class="doctor_item_nav_subtit_txt">{{ doctorItem.DoctorTitle || doctorItem.Title }}</text>
+                </view>
+                <view v-if="doctorItem.Spec" class="doctor_item_nav_info">
+                  {{ doctorItem.Spec }}
+                </view>
+              </view>
+            </view>
+            <view class="other_dept_box" v-if="!doctorItem.ShowDeptSwitch">
+              <view class="displayFlexRow border_top displayFlexBetween">
+                <text>本院所有科室排班</text>
+                <switch color="var(--dominantColor)" class="public_switch" @change="queryScheduleList" />
+              </view>
+            </view>
+          </view>
+        </view>
+
+        <view class="content_inner_item" v-for="(schedulItem, schedulIndex) in doctorItem.Scheduling" :key="schedulIndex">
+          <view class="scheduling_dept_box displayFlexBetween" @click="foldList(schedulIndex)">
+            <view class="scheduling_deptName_box displayFlexRow">
+              <view class="backgroundCustom "></view>
+              <text>{{ schedulItem.DeptName }}</text>
+            </view>
+            <image class="arrow" :class="{ 'transform_rotate_90': schedulItem.Check }" :src="iconUrl.icon_right"></image>
+          </view>
+          <block v-if="schedulItem.Check">
+            <view class="time_list">
+              <view v-for="(item, index) in schedulItem.Data_1" :key="index" @click="timeClick(item, index, schedulIndex)" class="time_item displayFlexCol" :class="{ 'backgroundCustom': item.ScheduleId == dateInfoSelected.ScheduleId, 'time_item_stop': item.IsHalt == 7 || item.IsHalt == 2 }">
+                <view>{{ item.RegDateDiy }}</view>
+                <view style="margin-top: 12upx;">{{ item.WeekName }} {{ item.TimeSliceStr }}</view>
+                <image v-if="item.IsHalt == 7" class="time_item_img" :src="iconUrl.full2"></image>
+                <image v-if="item.IsHalt == 2" class="time_item_img" :src="iconUrl.stop"></image>
+                <image v-if="item.IsHalt == 7 && item.WaitLeaveCount > 0" class="time_item_img" :src="iconUrl.yyghWait"></image>
+              </view>
+            </view>
+            <view class="content_inner_item_tit">
+              <view style="margin-right: 18upx;">诊查费:
+                <text class="colorCustom_F08">{{ (dateInfoSelected.RegFee - 0) / 100 }}元</text>
+              </view>
+              <view v-if="numberList.length > 0">剩余号源数
+                <text class="colorCustom_F08"> {{ numberList.length }}</text>
+              </view>
+            </view>
+            <!-- 候补 -->
+            <block v-if="dateInfoSelected.IsHalt == 7 && dateInfoSelected.WaitStatus == 1">
+              <view class="wait_con">
+                <view class="wait_head_con">
+                  <view class="wait_head">当前排班支持候补登记,剩余候补名额{{ dateInfoSelected.WaitLeaveCount }}个</view>
+                </view>
+                <view class="wait_list">
+                  <view class="wait_item">1、当医生排班标识为“候补”状态时,表明该医生当前 排班已被约满,但支持候补登记,而且当前尚存在候补 名额;</view>
+                  <view class="wait_item">2、当约满排班存在候补名额时,患者可进行候补登记,系统将根据补登记时间自动生成候补队列次序;</view>
+                  <view class="wait_item">3、候补登陆成功后,如果在候补截止期前,出现预约 成功患者退号,则系统将根据候补队列次序,为候补者 自动完成预约挂号,并短信通知候补者如期就诊;
+                  </view>
+                  <view class="wait_item">4、用户可在“我的”-“候补记录”中,取消候补登记。</view>
+                </view>
+              </view>
+              <view class="public_btn" :class="dateInfoSelected.WaitLeaveCount > 0 ? 'backgroundCustom' : 'backgroundCustom_D9'" @click="waitRegistration">候补登记</view>
+            </block>
+            <block v-else>
+              <!-- 方块 -->
+              <view class="number_list" v-if="pageConfig.numberType == 1">
+                <view class="number_item" :class="{ 'backgroundCustom': item.SourceCode == numberInfoSelected.SourceCode && item.CommendTime == numberInfoSelected.CommendTime }" v-for="(item, index) in numberList" :key="index" @click="numberClick(index)">
+                  <view>{{ item.SqNo ? item.SqNo + '号' : '' }}</view>
+                  <view class="number_item_time">{{ item.StartTime ? item.StartTime : item.StartTime + '-' + item.EndTime }}</view>
+                </view>
+              </view>
+              <!-- 列表 -->
+              <view class="number_list_sec" v-else>
+                <view class="number_item_sec border_top" v-for="(item, index) in numberList" :key="index" @click="numberClick(index)">
+                  <view class="flexCenter">
+                    <image class="circle" :src="item.SourceCode == numberInfoSelected.SourceCode && item.CommendTime == numberInfoSelected.CommendTime ? iconUrl.circle_active : iconUrl.circle"></image>
+                    {{ item.EndTime ? item.StartTime + '-' + item.EndTime : item.StartTime }}
+                  </view>
+                  <view class="number_item_time">余号:{{ dateInfoSelected.LeaveCount }}</view>
+                </view>
+              </view>
+              <view class="public_btn" :class="numberList.length > 0 ? 'backgroundCustom_F08' : 'backgroundCustom_D9'" @click="confirmClick">立即预约</view>
+            </block>
+
+          </block>
+
+        </view>
+      </view>
+    </view>
+    <view v-if="showNoData" class="noData">
+      <noData :value="noDataValue"></noData>
+    </view>
+    <overduePerson :currentUser="currentUser" BusinessType="1101"></overduePerson>
+    <doctorInfo :doctorInfoIsShow="doctorInfoIsShow" :doctorInfo="doctorInfo"></doctorInfo>
+    
+    <!-- AI数智客服入口-->
+    <aiCustomerEntry :currentUser="currentUser"></aiCustomerEntry>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, toRefs } from 'vue';
+import { onShow } from '@dcloudio/uni-app';
+import { common, pagesPatientFn, publicFn } from '@/utils';
+import icon from '@/utils/icon';
+import { REQUEST_CONFIG } from '@/config';
+import { 
+  queryClinicBaseDoctor, 
+  queryNumbers, 
+  queryClinicDoctorSchedule, 
+  lockOrder, 
+  bookService, 
+  unlock, 
+  queryScheduleList, 
+  checkBeforeAddWaitList 
+} from '@/pagesPatient/service/yygh';
+import { addOrderLocal } from '@/pagesPatient/service/pay';
+import { useGetMember } from '@/utils/hooks/useGetMember';
+
+const app = getApp();
+const iconUrl = ref(icon);
+const withoutCard = ref(false); //是否可以无卡预约
+const noDataValue = ref('当前医生暂无排班'); //医生是否有排班
+const doctorItem = ref<any>({});
+const dateInfoSelected = ref<any>({}); //当前选择的排班时间
+const showCon = ref(false);
+const showNoData = ref(false);
+const numberList = ref<any[]>([]); //预约时段 
+const numberInfoSelected = ref<any>({}); //当前选中的预约时段
+const currentUser = ref<any>({});
+const doctorInfoIsShow = ref(false);
+const doctorInfo = ref<any>({}); //医生详情信息
+const doctorListConfig = ref<any>({}); //医生列表页配置
+const serviceId = ref('');
+const options = ref<any>({});
+const queryBean = ref<any>({});
+const pageConfig = ref<any>({});
+const reducibleOnly = ref(false);
+
+onLoad(async (opt: any) => {
+  let qBean = app.globalData.queryBean || {};
+  /**医生列表页配置 */
+  let dListConfig = common.deepCopy(app.globalData.config.pageConfiguration.yyghDoctorList_config);
+  /**当前页面配置 */
+  let pConfig = common.deepCopy(app.globalData.config.pageConfiguration.yyghClinicMsg_config);
+  let dInfoSelected = {};
+  /**通过上级页面传的item和点击的排班Index 取到当前点击的排班时间  如果是从预约挂号页面进来的  则取挂号排班时间*/
+  if (opt?.schedule) {
+    dInfoSelected = common.parse(opt?.schedule);
+  } else if (qBean.Data_1 && opt.selectedIndex) {
+    dInfoSelected = qBean.Data_1[opt.selectedIndex];
+  }
+  opt?.deptCode && (qBean.DeptCode = opt?.deptCode);
+  opt?.doctorCode && (qBean.DoctorCode = opt?.doctorCode);
+
+  options.value = opt;
+  serviceId.value = opt.serviceId || '';
+  queryBean.value = qBean;
+  dateInfoSelected.value = dInfoSelected;
+  doctorListConfig.value = dListConfig;
+  pageConfig.value = pConfig;
+  withoutCard.value = app.globalData.withoutCard;
+});
+
+useOnShow(() => {
+  main();
+});
+
+const main = async () => {
+  currentUser.value = app.globalData.currentUser;
+  let sNoData = true;
+  /**获取医生信息 */
+  await setterDoctorList();
+  if (!common.isEmpty(doctorItem.value)) {
+    sNoData = false;
+    /**获取预约时间段 */
+    await queryNumbersFn();
+  }
+  showCon.value = true;
+  showNoData.value = sNoData;
+};
+
+/**
+ * 医生详情点击
+ */
+const doctorInfoClick = async () => {
+  let dItem = doctorItem.value;
+  let queryData = {
+    HosId: app.globalData.districtId || app.globalData.hosId,
+    DeptCode: dItem.DeptCode || '',
+    DoctorCode: dItem.DoctorCode || '',
+    DoctorName: ''
+  };
+  let resp = await queryClinicBaseDoctor(queryData);
+  if (!common.isEmpty(resp)) {
+    doctorInfoIsShow.value = true;
+    doctorInfo.value = resp[0];
+  }
+};
+
+/**
+ * 预约时段点击
+ */
+const numberClick = (index: number) => {
+  numberInfoSelected.value = numberList.value[index];
+};
+
+/**
+ * 日期选择
+ */
+const timeClick = (item: any, index: number, schedulIndex: number) => {
+  if ((item.IsHalt == 7 && item.WaitLeaveCount <= 0) || item.IsHalt == '2') {
+    return;
+  }
+  numberList.value = [];
+  dateInfoSelected.value = item;
+  // 判断不等于约满或者不等于停诊查询号源
+  if (item.IsHalt != 7 && item.IsHalt != '2') {
+    queryNumbersFn();
+  }
+};
+
+/**
+ * 获取号源列表
+ */
+const queryNumbersFn = async () => {
+  let dInfoSelected = dateInfoSelected.value;
+  let queryData = {
+    HosId: app.globalData.districtId || app.globalData.hosId,
+    DeptCode: dInfoSelected.DeptCode,
+    DoctorCode: dInfoSelected.DoctorCode,
+    RegDate: dInfoSelected.RegDate,
+    TimeSlice: dInfoSelected.TimeSlice,
+    ScheduleId: dInfoSelected.ScheduleId,
+    TransactionCode: 2002,
+  };
+  let nList = await queryNumbers(queryData);
+  let nInfoSelected = {};
+  if (!common.isEmpty(options.value?.number)) {
+    nInfoSelected = common.parse(options.value?.number);
+  } else {
+    nInfoSelected = nList && nList[0] || {};
+  }
+  numberList.value = nList || [];
+  numberInfoSelected.value = nInfoSelected; //默认选中第一个号源
+};
+
+/**
+ * 处理医生列表返回值
+ */
+const setterDoctorList = async () => {
+  let qBean = queryBean.value;
+  let dInfoSelected = dateInfoSelected.value;
+  let hasAllSchedules = doctorListConfig.value.hasAllSchedules;
+  let queryData: any = {
+    HosId: app.globalData.districtId || app.globalData.hosId,
+    DeptCode: qBean.DeptCode,
+    DoctorCode: qBean.DoctorCode,
+    WorkDateStart: hasAllSchedules ? "" : dInfoSelected.RegDate,
+    WorkDateEnd: hasAllSchedules ? "" : dInfoSelected.RegDate,
+    TitleCode: "",
+    OrderByDoc: '1',
+    WaitRule: '1'
+  };
+  // 判断为当日挂号
+  if (serviceId.value == '009') {
+    queryData.WorkDateStart = common.getDate();
+    queryData.WorkDateEnd = common.getDate();
+    queryData.ServiceId = serviceId.value;
+  }
+  let resp = await queryClinicDoctorSchedule(queryData);
+  if (!common.isEmpty(resp)) {
+    let dItem = resp[0];
+    /**如果医生头像没有域名 添加域名 */
+    if (dItem.PhotoUrl && dItem.PhotoUrl.indexOf('http') == '-1') {
+      dItem.PhotoUrl = REQUEST_CONFIG.BASE_URL + dItem.PhotoUrl;
+    }
+    if (dItem.PhotoUrl) {
+        dItem.PhotoUrl = dItem.PhotoUrl.replace(/\\/g, '/');
+    }
+    
+    dItem.Data_1.map((item: any) => {
+      item.RegDateDiy = item.RegDate.substring(5);
+      item.WeekName = item.RegDate == common.newDay() ? '今天' : item.WeekName;
+      item.DeptName = dItem.DeptName;
+      item.DeptCode = dItem.DeptCode;
+      item.DoctorName = dItem.DoctorName;
+      item.DoctorCode = dItem.DoctorCode;
+    });
+
+    // 数据处理 医生多科室
+    let obj = [{
+      Check: true,
+      DeptName: dItem.DeptName,
+      DeptCode: dItem.DeptCode,
+      DoctorName: dItem.DoctorName,
+      DoctorCode: dItem.DoctorCode,
+      Data_1: dItem.Data_1,
+    }];
+    dItem.Scheduling = obj;
+    /**重新赋值当前项   否则提交订单后后退不刷新值 */
+    let dInfoSelectedNew = resp.filter((item: any) => item && item.ScheduleId == dateInfoSelected.value.ScheduleId)[0] || dateInfoSelected.value;
+    
+    doctorItem.value = dItem;
+    /**历史医生进入  无ScheduleId 重新赋值  */
+    dateInfoSelected.value = dateInfoSelected.value.ScheduleId ? dInfoSelectedNew : dItem && dItem.Data_1 && dItem.Data_1[0] || {};
+  }
+};
+
+const switchChange = (e: any) => {
+  let value = e.detail.value;
+  reducibleOnly.value = value;
+  main();
+};
+
+/**
+ * 立即预约点击
+ */
+const confirmClick = async (e: any) => {
+  // 注意:Vue 中没有 formId
+  let formId = ''; // e.detail.formId
+  let dInfoSelected = dateInfoSelected.value;
+  let nInfoSelected = numberInfoSelected.value;
+  let dItem = doctorItem.value;
+
+  // 查询当前用户 是否被授权
+  if (await publicFn.isCurrentUserAuth(currentUser.value, 'Book', true)) return;
+  
+  /**是否存在待支付订单 */
+  if (await pagesPatientFn.hasOrderToBePaid('0,009')) return;
+
+  common.throttle(async () => {
+    if (common.isEmpty(dateInfoSelected.value)) {
+      common.showToast('请选择预约日期');
+      return;
+    }
+    if (common.isEmpty(numberInfoSelected.value)) {
+      common.showToast('请选择预约时间');
+      return;
+    }
+
+    /**锁号 */
+    let queryData: any = {
+      HosId: app.globalData.districtId || app.globalData.hosId,
+      ScheduleId: dInfoSelected.ScheduleId,
+      DeptCode: dInfoSelected.DeptCode,
+      DoctorCode: dInfoSelected.DoctorCode,
+      RegType: '1',
+      RegDate: dInfoSelected.RegDate,
+      TimeSlice: dInfoSelected.TimeSlice,
+      SqNo: nInfoSelected.SqNo,
+      CommendTime: nInfoSelected.EndTime ? `${nInfoSelected.StartTime}-${nInfoSelected.EndTime}` : nInfoSelected.StartTime,
+      SourceCode: nInfoSelected.SourceCode,
+      MemberId: currentUser.value.memberId,
+      CardType: '1',
+      CardNo: currentUser.value.cardNo || '',
+      MemberStore: {
+        cardEncryptionStore: currentUser.value.encryptionStore || '',
+        baseMemberEncryptionStore: currentUser.value.baseMemberEncryptionStore
+      },
+      Store: {
+        cardEncryptionStore: currentUser.value.encryptionStore || '',
+        baseMemberEncryptionStore: currentUser.value.baseMemberEncryptionStore
+      }
+    };
+    let lockResp = await lockOrder(queryData);
+    if (!common.isEmpty(lockResp)) {
+      /**锁号成功 */
+
+      /**本地下单 */
+      let addorderData = {
+        HosId: app.globalData.hosId,
+        OrderId: lockResp[0].OrderId,
+        PrescNo: '',
+        PayMoney: lockResp[0].Fee,
+        TotalMoney: lockResp[0].Fee,
+        IsOnlinePay: lockResp[0].IsOnlinePay,
+        PriceName: '挂号支付',
+        OperatorId: uni.getStorageSync('openid'),
+        ServiceId: '0',
+        PayFeeItem: '0',
+        EqptType: '1',
+        BankCardNo: '',
+        BankSeqNo: '',
+        ChargeSource: '',
+        MemberId: currentUser.value.memberId,
+        OperatorName: currentUser.value.MemberName,
+        Store: {
+          cardEncryptionStore: currentUser.value.encryptionStore || '',
+          baseMemberEncryptionStore: currentUser.value.baseMemberEncryptionStore
+        },
+        Data_1: {
+          DoctorCode: dInfoSelected.DoctorCode || dItem.DoctorCode,
+          DoctorName: dInfoSelected.DoctorName || dItem.DoctorName,
+          DeptCode: dInfoSelected.DeptCode || dItem.DeptCode,
+          DeptName: dInfoSelected.DeptName || dItem.DeptName,
+          RegDate: dInfoSelected.RegDate,
+          CommendTime: nInfoSelected.CommendTime,
+          scene_id: formId,
+          FeeInfo: lockResp[0].FeeInfo,
+          scene_type: '1',
+          TransactionCode: '6001'
+        }
+      };
+      let addOrderResp = await addOrderLocal(addorderData);
+      if (!common.isEmpty(addOrderResp)) {
+        /**本地下单成功 */
+        let url = `/pagesPatient/st1/business/pay/payState/payState?pageType=yygh&orderId=${lockResp[0].OrderId}`;
+        if (lockResp[0].IsOnlinePay == '1') {
+          /**在线支付 */
+          url = `/pagesPatient/st1/business/pay/payMent/payMent?orderId=${lockResp[0].OrderId}`;
+        } else if (lockResp[0].IsOnlinePay == '2') {
+          /**不支付 boockService挂号 */
+          let queryData = {
+            HosId: app.globalData.districtId || app.globalData.hosId,
+            OrderId: lockResp[0].OrderId,
+            OperatorId: uni.getStorageSync('openid'),
+            TransactionCode: "3003",
+            MemberId: currentUser.value.memberId,
+            SourceType: 0,
+            Store: {
+              cardEncryptionStore: currentUser.value.encryptionStore || '',
+              baseMemberEncryptionStore: currentUser.value.baseMemberEncryptionStore
+            },
+          };
+          let { resp, resData } = await yygh.bookService(queryData);
+          if (resData.RespCode != 10000) {
+            await yygh.unlock({ OrderId: lockResp[0].OrderId });
+            return;
+          }
+        }
+        common.goToUrl(url);
+      }
+    }
+  });
+};
+
+/**
+ * 查询医生其它科室排班
+ */
+const queryScheduleList = async (e: any) => {
+  let hasAllSchedules = doctorListConfig.value.hasAllSchedules;
+  let dInfoSelected = dateInfoSelected.value;
+  let dItem = doctorItem.value;
+  let querData = {
+    workDateEnd: hasAllSchedules ? "" : dInfoSelected.RegDate,
+    workDateStart: hasAllSchedules ? "" : dInfoSelected.RegDate,
+    doctorCode: dItem.DoctorCode,
+    deptCode: dItem.DeptCode,
+    hosId: app.globalData.districtId || app.globalData.hosId,
+    WaitRule: '1'
+  };
+  let res = await queryScheduleList(querData);
+  if (common.isNotEmpty(res)) {
+    let scheduleList: any[] = [];
+    res.map(async (item: any, index: number) => {
+      // 转换返回数据 小写转大写
+      item.hisQueryClinicSchedules = common.changeObj(item.hisQueryClinicSchedules);
+      item.hisQueryBaseDoctor = common.changeObj(item.hisQueryBaseDoctor);
+      if (item.hisQueryClinicSchedules.length > 0) {
+        // 判断是否多数据处理 星期 时间 上下午
+        if (item.hisQueryClinicSchedules.length > 0) {
+          item.hisQueryClinicSchedules.map((ele: any) => {
+            ele.WeekName = ele.RegDate == common.newDay() ? '今天' : common.weekDay(ele.RegDate, 1);
+            ele.RegDateDiy = ele.RegDate.substring(5);
+            ele.TimeSliceStr = ele.TimeSlice == 1 ? '上午' : ele.TimeSlice == 2 ? '下午' : '全天';
+          });
+        }
+        scheduleList.push({
+          Check: item.hisQueryBaseDoctor.DeptCode == dItem.DeptCode ? true : false,
+          DeptName: item.hisQueryBaseDoctor.DeptName,
+          DeptCode: item.hisQueryBaseDoctor.DeptCode,
+          DoctorName: dItem.DoctorName,
+          DoctorCode: dItem.DoctorCode,
+          Data_1: item.hisQueryClinicSchedules,
+          showAllSchedu: item.showAllSchedu,
+        });
+      }
+    });
+    // 给当前查询的医生新加列表
+    dItem.Scheduling = scheduleList;
+  }
+  // 查询过的医生 不展示switch
+  dItem.ShowDeptSwitch = true;
+  doctorItem.value = dItem;
+};
+
+/**
+ * 折叠列表
+ */
+const foldList = (schedulIndex: number) => {
+  let dItem = doctorItem.value;
+  // 当前点击的科室是打开的状态,则进行关闭,不查号源
+  if (dItem.Scheduling[schedulIndex].Check) {
+    dItem.Scheduling[schedulIndex].Check = false;
+    doctorItem.value = dItem;
+  } else {
+    let dInfoSelected = {};
+    // 全部遍历关闭展开数据信息
+    dItem.Scheduling.map((item: any) => item.Check = false);
+    // 当前打开
+    dItem.Scheduling[schedulIndex].Check = true;
+    // 过滤当前打开的排班信息 获取到未满未停诊的排班
+    let dateInfoSelecteds = dItem.Scheduling[schedulIndex].Data_1.filter((item: any) => item.IsHalt != '7' || item.IsHalt != '2');
+    // 判断过滤条件是否为空 为空踢提示
+    if (common.isEmpty(dateInfoSelecteds)) {
+      common.showToast("查询号源失败,请选择一个排班信息");
+    } else {
+      // 否者查询号源
+      dInfoSelected = dateInfoSelecteds[0];
+    }
+    dateInfoSelected.value = dInfoSelected;
+    doctorItem.value = dItem;
+    queryNumbersFn();
+  }
+};
+
+// 候补登记
+const waitRegistration = async () => {
+  let cUser = currentUser.value;
+  let dInfoSelected = dateInfoSelected.value;
+  let dItem = doctorItem.value;
+  if (dInfoSelected.WaitLeaveCount <= 0) return;
+  let queryData = {
+    HosId: app.globalData.districtId || app.globalData.hosId,
+    OpenId: uni.getStorageSync("openid"),
+    MemberId: cUser.memberId,
+    ScheduleId: dInfoSelected.ScheduleId,
+    DeptCode: dItem.DeptCode,
+    DoctorCode: dItem.DoctorCode,
+    RegDate: dInfoSelected.RegDate,
+    WeekId: dInfoSelected.WeekId,
+    TimeId: dInfoSelected.TimeSlice,
+    Store: {
+      cardEncryptionStore: cUser.encryptionStore || '',
+      baseMemberEncryptionStore: cUser.baseMemberEncryptionStore
+    }
+  };
+  let { resp, resData } = await checkBeforeAddWaitList(queryData);
+  if (resData.RespCode == '10000') {
+    dItem.Intro = '';
+    dItem.Data_1 = '';
+    dItem.Scheduling = '';
+    let querBen = encodeURIComponent(JSON.stringify({
+      doctorItem: dItem,
+      dateInfoSelected: dInfoSelected
+    }));
+    common.goToUrl(`/pagesPatient/st1/business/yygh/waitRegistration/waitRegistration?querBen=${querBen}`);
+  }
+};
+</script>
+
+<style scoped>
+.container {
+  /* background-color: #F8F8F8; */
+  min-height: 100vh;
+}
+
+.content_inner {
+  padding: 200upx 30upx 0;
+  display: inline-block;
+  width: 100%;
+}
+
+.content_inner_item {
+  margin: 30upx 0;
+  padding: 30upx 0;
+  border-radius: 24upx;
+  background: #fff;
+  overflow: hidden;
+}
+.content_inner_item_tit {
+  height: 110upx;
+  display: flex;
+  align-items: center;
+  padding: 0 30upx;
+  font-size: 32upx;
+}
+
+.doctor_item {
+  padding: 0 30upx;
+}
+
+.doctor_item_nav {
+  display: flex;
+  position: relative;
+  padding: 20upx 0;
+}
+
+.doctor_item_nav_img {
+  width: 110upx;
+  height: 103upx;
+  border-radius: 50%;
+  margin-right: 23upx;
+  overflow: hidden;
+}
+
+.doctor_item_nav_tit {
+  width: 82%;
+}
+
+
+.doctor_item_nav_subtit_val {
+  font-size: 32upx;
+  font-family: PingFang SC;
+  font-weight: 800;
+  color: #222326;
+  margin-right: 12upx;
+}
+
+.doctor_item_nav_subtit_txt {
+  height: 36upx;
+  line-height: 28upx;
+  font-size: 24upx;
+  font-family: PingFang SC;
+  color: var(--auxiliaryColor);
+  padding: 0upx 7upx;
+  position: relative;
+  display: inline-block;
+  background: #FFFBF4;
+  border: 1upx solid #FADAB2;
+
+}
+
+.doctor_item_nav_info {
+  font-size: 28upx;
+  font-family: Source Han Sans CN;
+  font-weight: 500;
+  color: #62626D;
+  line-height: 40upx;
+  margin-top: 10upx;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  line-clamp: 2;
+  -webkit-box-orient: vertical;
+}
+
+.time_list {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  padding: 0 30upx;
+}
+
+.time_item {
+  margin: 23upx 2% 0 0;
+  width: 32%;
+  height: 110upx;
+  line-height: 110upx;
+  background: #F1F1F6;
+  border-radius: 20upx;
+  font-size: 28upx;
+  color: #222326;
+  text-align: center;
+  position: relative;
+}
+.time_item:nth-child(3n){
+  margin-right: 0;
+}
+
+.time_item_img {
+  width: 61upx;
+  height: 54upx;
+  position: absolute;
+  right: 0;
+  top: 0;
+}
+.time_item_stop view{
+  color: #8A8A99;
+}
+
+.price {
+  font-size: 32upx;
+  color: #fa4844;
+}
+
+.subtit {
+  color: #a6a6a6;
+  font-size: 28upx;
+}
+
+.number_list {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap; 
+  padding: 0 30upx 12upx;
+  -webkit-overflow-scrolling: touch;
+}
+
+.number_item {
+  font-size: 28upx;
+  font-family: PingFang SC;
+  font-weight: 500;
+  color: #43434A;
+  width: 23%;
+  height: 110upx;
+  margin: 0 2.5% 22upx 0;
+  background: #F1F1F6;
+  border-radius: 20upx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+.number_item:nth-child(4n){
+  margin-right: 0;
+}
+
+.number_item_time {
+  margin-top: 6upx;
+  text-align: center;
+}
+/* 列表号源 */
+.number_list_sec{
+  -webkit-overflow-scrolling: touch;
+}
+.number_item_sec {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 30upx;
+  height: 100upx;
+  font-size: 32upx;
+  color: rgba(85, 85, 85, 1); 
+}
+
+.circle {
+  margin-right: 22upx;
+  width: 42upx;
+  height: 42upx;
+}
+.border:before{
+  border-radius: 0;
+}
+
+/* 查询 switch*/
+.other_dept_box view {
+  width: 100%;
+  padding-top: 28upx ;
+  margin-top: 23upx;
+  box-sizing: border-box;
+  justify-content: space-between;
+}
+
+.other_dept_box view text {
+  font-size: 32upx;
+  color: #333;
+}
+
+/* 多科室 */
+.scheduling_dept_box {
+  margin: 8upx 0 12upx;
+  padding-left: 30upx;
+}
+
+.scheduling_deptName_box view {
+  width: 14upx;
+  height: 14upx;
+  border-radius: 14upx;
+  margin-right: 20upx;
+}
+
+.scheduling_deptName_box text {
+  font-size: 32upx;
+  color: #333;
+}
+
+.scheduling_dept_box image {
+  transform: rotate(270deg);
+}
+
+.scheduling_list {
+  flex-wrap: wrap;
+  justify-content: flex-start;
+}
+.transform_rotate_90 {
+  transform: rotate(90deg) !important;
+}
+
+.transform_rotate_180 {
+  transform: rotate(180deg) !important;
+}
+
+.public_btn{
+  margin: 0 30upx;
+  height: 88upx;
+  line-height: 88upx;
+}
+
+
+
+/* 候补 */
+.wait_con{
+  padding:0 30upx;
+}
+.wait_head {
+  margin: 0 auto;
+  background: #f8f4ea;
+  border-radius: 10upx 10upx 0px 0px;
+  padding: 30upx 45upx;
+  font-size: 30upx;
+  font-family: PingFang SC;
+
+  color: #d18e09;
+  line-height: 40upx;
+  position: relative;
+  transform-style: preserve-3d;
+}
+
+.wait_head::before,
+.wait_head::after {
+  content: "";
+  display: block;
+  width: 16upx;
+  height: 16upx;
+  border-radius: 50px;
+  background-color: #f6e8ce;
+  position: absolute;
+  bottom: 0;
+  transform: translateZ(-1px);
+}
+
+.wait_head::before {
+  left: -8upx;
+}
+
+.wait_head::after {
+  right: -8upx;
+}
+
+.wait_list {
+  padding: 20upx 0;
+  background-color: #fff;
+}
+
+.wait_item {
+  font-size: 28upx;
+  font-family: PingFang SC;
+  color: #999;
+  line-height: 54upx;
+}
+</style>

+ 0 - 108
pagesPatient/st1/business/yygh/yyghClinicMsg/yyghClinicMsg.wxml

@@ -1,108 +0,0 @@
-<view class="container">
-  <view class="content" wx:if="{{showCon}}">
-    <view class="userInfoTopFixe">
-      <userInfo userInfo="{{currentUser}}" type="{{withoutCard?'member':'card'}}" bgClass="bgLinGra"></userInfo>
-    </view>
-    <view class="content_inner" wx:if="{{doctorItem.DoctorName}}">
-      <view class="content_inner_item">
-        <view class="doctor_item">
-          <view class="doctor_item_nav" bindtap="doctorInfoClick">
-            <view class="doctor_item_nav_img">
-              <image src="{{doctorItem.PhotoUrl||iconUrl.icon_doctor}}" mode="widthFix"></image>
-            </view>
-            <view class="doctor_item_nav_tit">
-              <view class="doctor_item_nav_subtit">
-                <text class="doctor_item_nav_subtit_val">{{doctorItem.DoctorName}}</text>
-                <text wx:if="{{doctorItem.DoctorTitle||doctorItem.Title}}" class="doctor_item_nav_subtit_txt">{{doctorItem.DoctorTitle||doctorItem.Title}}</text>
-              </view>
-              <view wx:if="{{doctorItem.Spec}}" class="doctor_item_nav_info">
-                {{doctorItem.Spec}}
-              </view>
-            </view>
-          </view>
-          <view class="other_dept_box" wx:if="{{!doctorItem.ShowDeptSwitch }}">
-            <view class="displayFlexRow border_top displayFlexBetween">
-              <text>本院所有科室排班</text>
-              <switch color="var(--dominantColor)" class="public_switch" bindchange="queryScheduleList" />
-            </view>
-          </view>
-        </view>
-      </view>
-
-      <view class="content_inner_item"  wx:for="{{doctorItem.Scheduling}}" wx:for-item="schedulItem" wx:for-index="schedulIndex" wx:key="schedulIndex">
-        <view class="scheduling_dept_box displayFlexBetween" data-schedulIndex="{{schedulIndex}}" bindtap="foldList">
-          <view class="scheduling_deptName_box displayFlexRow">
-            <view class="backgroundCustom "></view>
-            <text>{{schedulItem.DeptName}}</text>
-          </view>
-          <image class="arrow {{schedulItem.Check ? 'transform_rotate_90' : ''}}" src="{{iconUrl.icon_right}}"></image>
-        </view>
-        <block wx:if="{{schedulItem.Check}}">
-          <view class="time_list">
-            <view wx:for="{{schedulItem.Data_1}}" wx:key="index" bindtap="timeClick" data-index="{{index}}" data-schedulIndex="{{schedulIndex}}" data-item="{{item}}" class="time_item displayFlexCol {{item.ScheduleId==dateInfoSelected.ScheduleId?'backgroundCustom':item.IsHalt==7||item.IsHalt==2?'time_item_stop':''}}">
-              <view>{{item.RegDateDiy}}</view>
-              <view style="margin-top: 12rpx;">{{item.WeekName}} {{item.TimeSliceStr}}</view>
-              <image wx:if="{{item.IsHalt==7}}" class="time_item_img" src="{{iconUrl.full2}}"></image>
-              <image wx:if="{{item.IsHalt==2}}" class="time_item_img" src="{{iconUrl.stop}}"></image>
-              <image wx:if="{{item.IsHalt == 7 && item.WaitLeaveCount > 0}}" class="time_item_img" src="{{iconUrl.yyghWait}}"></image>
-            </view>
-          </view>
-          <view class="content_inner_item_tit">
-            <view style="margin-right: 18rpx;" >诊查费:
-              <text class="colorCustom_F08">{{(dateInfoSelected.RegFee-0)/100}}元</text>
-            </view>
-            <view wx:if="{{numberList.length>0}}">剩余号源数
-              <text class="colorCustom_F08"> {{numberList.length}}</text>
-            </view>
-          </view>
-          <!-- 候补 -->
-          <block wx:if="{{dateInfoSelected.IsHalt == 7 && dateInfoSelected.WaitStatus == 1}}">
-            <view class="wait_con">
-              <view class="wait_head_con">
-                <view class="wait_head">当前排班支持候补登记,剩余候补名额{{dateInfoSelected.WaitLeaveCount}}个</view>
-              </view>
-              <view class="wait_list">
-                <view class="wait_item">1、当医生排班标识为“候补”状态时,表明该医生当前 排班已被约满,但支持候补登记,而且当前尚存在候补 名额;</view>
-                <view class="wait_item">2、当约满排班存在候补名额时,患者可进行候补登记,系统将根据补登记时间自动生成候补队列次序;</view>
-                <view class="wait_item">3、候补登陆成功后,如果在候补截止期前,出现预约 成功患者退号,则系统将根据候补队列次序,为候补者 自动完成预约挂号,并短信通知候补者如期就诊;
-                </view>
-                <view class="wait_item">4、用户可在“我的”-“候补记录”中,取消候补登记。</view>
-              </view>
-            </view>
-            <view class="public_btn {{dateInfoSelected.WaitLeaveCount>0?'backgroundCustom':'backgroundCustom_D9'}}" bindtap="waitRegistration">候补登记</view>
-          </block>
-          <block wx:else>
-            <!-- 方块 -->
-            <view class="number_list" wx:if="{{pageConfig.numberType == 1}}">
-              <view class="number_item {{item.SourceCode==numberInfoSelected.SourceCode&&item.CommendTime==numberInfoSelected.CommendTime?'backgroundCustom':''}}" wx:for="{{numberList}}" wx:key="index" bindtap="numberClick" data-index="{{index}}">
-                <view>{{item.SqNo?item.SqNo+'号':''}}</view>
-                <view class="number_item_time">{{item.StartTime?item.StartTime:item.StartTime+'-'+item.EndTime}}</view>
-              </view>
-            </view>
-            <!-- 列表 -->
-            <view class="number_list_sec" wx:else>
-              <view class="number_item_sec border_top" wx:for="{{numberList}}" wx:key="index" bindtap="numberClick" data-index="{{index}}">
-                <view class="flexCenter">
-                  <image class="circle" src="{{item.SourceCode==numberInfoSelected.SourceCode&&item.CommendTime==numberInfoSelected.CommendTime?iconUrl.circle_active:iconUrl.circle}}"></image>
-                  {{item.EndTime?item.StartTime+'-'+item.EndTime:item.StartTime}}
-                </view>
-                <view class="number_item_time">余号:{{dateInfoSelected.LeaveCount}}</view>
-              </view>
-            </view>
-            <view class="public_btn {{numberList.length>0?'backgroundCustom_F08':'backgroundCustom_D9'}}" bindtap="confirmClick">立即预约</view>
-          </block>
-          
-        </block>
-        
-      </view>
-    </view>
-  </view>
-  <view wx:if="{{showNoData}}" class="noData">
-    <noData value="{{noDataValue}}"></noData>
-  </view>
-  <overduePerson currentUser="{{currentUser}}" BusinessType="1101" ></overduePerson>
-  <doctorInfo doctorInfoIsShow="{{doctorInfoIsShow}}" doctorInfo="{{doctorInfo}}"></doctorInfo>
-</view>
-
-<!-- AI数智客服入口-->
-<aiCustomerEntry currentUser="{{currentUser}}"></aiCustomerEntry>

+ 0 - 286
pagesPatient/st1/business/yygh/yyghClinicMsg/yyghClinicMsg.wxss

@@ -1,286 +0,0 @@
-
-.content_inner {
-  padding: 200rpx 30rpx 0;
-  display: inline-block;
-  width: 100%;
-}
-
-.content_inner_item {
-  margin: 30rpx 0;
-  padding: 30rpx 0;
-  border-radius: 24rpx;
-  background: #fff;
-  overflow: hidden;
-}
-.content_inner_item_tit {
-  height: 110rpx;
-  display: flex;
-  align-items: center;
-  padding: 0 30rpx;
-  font-size: 32rpx;
-}
-
-.doctor_item {
-  padding: 0 30rpx;
-}
-
-.doctor_item_nav {
-  display: flex;
-  position: relative;
-  padding: 20rpx 0;
-}
-
-.doctor_item_nav_img {
-  width: 110rpx;
-  height: 103rpx;
-  border-radius: 50%;
-  margin-right: 23rpx;
-  overflow: hidden;
-}
-
-.doctor_item_nav_tit {
-  width: 82%;
-}
-
-
-.doctor_item_nav_subtit_val {
-  font-size: 32rpx;
-  font-family: PingFang SC;
-  font-weight: 800;
-  color: #222326;
-  margin-right: 12rpx;
-}
-
-.doctor_item_nav_subtit_txt {
-  height: 36rpx;
-  line-height: 28rpx;
-  font-size: 24rpx;
-  font-family: PingFang SC;
-  color: var(--auxiliaryColor);
-  padding: 0rpx 7rpx;
-  position: relative;
-  display: inline-block;
-  background: #FFFBF4;
-  border: 1rpx solid #FADAB2;
-
-}
-
-.doctor_item_nav_info {
-  font-size: 28rpx;
-  font-family: Source Han Sans CN;
-  font-weight: 500;
-  color: #62626D;
-  line-height: 40rpx;
-  margin-top: 10rpx;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  display: -webkit-box;
-  -webkit-line-clamp: 2;
-  line-clamp: 2;
-  -webkit-box-orient: vertical;
-}
-
-.time_list {
-  display: flex;
-  flex-wrap: wrap;
-  align-items: center;
-  padding: 0 30rpx;
-}
-
-.time_item {
-  margin: 23rpx 2% 0 0;
-  width: 32%;
-  height: 110rpx;
-  line-height: 110rpx;
-  background: #F1F1F6;
-  border-radius: 20rpx;
-  font-size: 28rpx;
-  color: #222326;
-  text-align: center;
-  position: relative;
-}
-.time_item:nth-child(3n){
-  margin-right: 0;
-}
-
-.time_item_img {
-  width: 61rpx;
-  height: 54rpx;
-  position: absolute;
-  right: 0;
-  top: 0;
-}
-.time_item_stop view{
-  color: #8A8A99;
-}
-
-.price {
-  font-size: 32rpx;
-  color: #fa4844;
-}
-
-.subtit {
-  color: #a6a6a6;
-  font-size: 28rpx;
-}
-
-.number_list {
-  display: flex;
-  align-items: center;
-  flex-wrap: wrap; 
-  padding: 0 30rpx 12rpx;
-  -webkit-overflow-scrolling: touch;
-}
-
-.number_item {
-  font-size: 28rpx;
-  font-family: PingFang SC;
-  font-weight: 500;
-  color: #43434A;
-  width: 23%;
-  height: 110rpx;
-  margin: 0 2.5% 22rpx 0;
-  background: #F1F1F6;
-  border-radius: 20rpx;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-}
-.number_item:nth-child(4n){
-  margin-right: 0;
-}
-
-.number_item_time {
-  margin-top: 6rpx;
-  text-align: center;
-}
-/* 列表号源 */
-.number_list_sec{
-  -webkit-overflow-scrolling: touch;
-}
-.number_item_sec {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  padding: 0 30rpx;
-  height: 100rpx;
-  font-size: 32rpx;
-  color: rgba(85, 85, 85, 1); 
-}
-
-.circle {
-  margin-right: 22rpx;
-  width: 42rpx;
-  height: 42rpx;
-}
-.border:before{
-  border-radius: 0;
-}
-
-/* 查询 switch*/
-.other_dept_box view {
-  width: 100%;
-  padding-top: 28rpx ;
-  margin-top: 23rpx;
-  box-sizing: border-box;
-  justify-content: space-between;
-}
-
-.other_dept_box view text {
-  font-size: 32rpx;
-  color: #333;
-}
-
-/* 多科室 */
-.scheduling_dept_box {
-  margin: 8rpx 0 12rpx;
-  padding-left: 30rpx;
-}
-
-.scheduling_deptName_box view {
-  width: 14rpx;
-  height: 14rpx;
-  border-radius: 14rpx;
-  margin-right: 20rpx;
-}
-
-.scheduling_deptName_box text {
-  font-size: 32rpx;
-  color: #333;
-}
-
-.scheduling_dept_box image {
-  transform: rotate(270deg);
-}
-
-.scheduling_list {
-  flex-wrap: wrap;
-  justify-content: flex-start;
-}
-.transform_rotate_90 {
-  transform: rotate(90deg) !important;
-}
-
-.transform_rotate_180 {
-  transform: rotate(180deg) !important;
-}
-
-.public_btn{
-  margin: 0 30rpx;
-  height: 88rpx;
-  line-height: 88rpx;
-}
-
-
-
-/* 候补 */
-.wait_con{
-  padding:0 30rpx;
-}
-.wait_head {
-  margin: 0 auto;
-  background: #f8f4ea;
-  border-radius: 10rpx 10rpx 0px 0px;
-  padding: 30rpx 45rpx;
-  font-size: 30rpx;
-  font-family: PingFang SC;
-
-  color: #d18e09;
-  line-height: 40rpx;
-  position: relative;
-  transform-style: preserve-3d;
-}
-
-.wait_head::before,
-.wait_head::after {
-  content: "";
-  display: block;
-  width: 16rpx;
-  height: 16rpx;
-  border-radius: 50px;
-  background-color: #f6e8ce;
-  position: absolute;
-  bottom: 0;
-  transform: translateZ(-1px);
-}
-
-.wait_head::before {
-  left: -8rpx;
-}
-
-.wait_head::after {
-  right: -8rpx;
-}
-
-.wait_list {
-  padding: 20rpx 0;
-  background-color: #fff;
-}
-
-.wait_item {
-  font-size: 28rpx;
-  font-family: PingFang SC;
-  color: #999;
-  line-height: 54rpx;
-}

+ 0 - 261
pagesPatient/st1/business/yygh/yyghDeptList/yyghDeptList.js

@@ -1,261 +0,0 @@
-const app = getApp();
-import yygh from "../../../../config/api/yygh/index.js";
-import regeneratorRuntime from "../../../../../utils/runtime.js";
-import common from "../../../../../utils/common.js";
-import icon from "../../../../../utils/icon.js";
-import { pagesPatientFn } from '@/utils';
-
-Page({
-  data: {
-    iconUrl:icon,
-    isFocus: false, //input是否获取焦点
-    searchValue: '', //搜索值
-    searchList: [], //搜索结果 
-    deptListFir: [], //一级科室
-    deptListFirIndex: -1, //当前一级科室
-    deptListSec: [], //二级科室
-    deptListSecIndex: -1, //当前二级科室
-    pageConfig: {}, //页面配置
-    serviceId:'',
-    queryData: {
-      HosId: '',
-      ParentDeptCode: "",
-      ServiceId:""
-    },
-    modalData: {}
-  },
-  onLoad: function(options) {
-    this.setData({
-      pageConfig: common.deepCopy(app.globalData.config.pageConfiguration.yyghDeptList_config),
-      serviceId :options.serviceId || '',
-      'queryData.HosId': app.globalData.districtId || app.globalData.hosId,
-      'queryData.ServiceId': options.serviceId || '',
-    })
-    this.main()
-  },
-  onShow: function() {
-
-  },
-  async main() {
-
-    let pageConfig = this.data.pageConfig
-    //获取一级科室
-    let deptListFir = [];
-    let deptListSec = [];
-    let queryData = this.data.queryData;
-    let deptListFirResp = await yygh.queryClinicBaseDept(queryData)
-    if (!common.isEmpty(deptListFirResp)) {
-      deptListFir = deptListFirResp;
-      if (pageConfig.showDeptSec) {
-        // 如果有二级科室 默认取第一个一级科室 
-        queryData.ParentDeptCode = deptListFir[0].DeptCode
-        let deptListSecResp = await yygh.queryClinicBaseDept(queryData)
-        if (!common.isEmpty(deptListSecResp)) {
-          deptListSec = deptListSecResp
-        }
-      }
-    }
-    this.setData({
-      deptListFir: deptListFir,
-      deptListSec: deptListSec,
-      deptListFirIndex: pageConfig.showDeptSec ? 0 : -1,
-      modalData: pageConfig.modalData,
-    })
-    // 
-  },
-  /**
-   * 科室点击
-   */
-  async deptClick(e) {
-    let pageType = ""; 
-    let type = e.currentTarget.dataset.type; // 当前触发方式 fir:一级科室 sec:二级科室 否者为搜索
-    let pageConfig = this.data.pageConfig    // 页面配置 
-    let item = e.currentTarget.dataset.item;
-    let index = e.currentTarget.dataset.index;
-    let deptListSec = this.data.deptListSec;
-    let deptListFirIndex = this.data.deptListFirIndex;
-    let deptListSecIndex = this.data.deptListSecIndex;
-    if (type == 'fir') {
-      //如果点击一级科室
-      deptListFirIndex = index;
-      if (pageConfig.showDeptSec) {
-        //如果医院有二级科室  
-        deptListSec = []
-        let queryData = this.data.queryData;
-        queryData.ParentDeptCode = item.DeptCode
-        let resp = await yygh.queryClinicBaseDept(queryData)
-        if (!common.isEmpty(resp)) {
-          deptListSec = resp;
-          deptListSecIndex = -1;
-        }
-      }else{
-        pageType = 'yyghDoctorList'
-      }
-    } else if (type == 'sec') {
-      //如果点击二级科室
-      deptListSecIndex = index
-      pageType = 'yyghDoctorList'
-    } else {
-      pageType = 'yyghDoctorList'
-      if (item.SearchType == '2') {
-        /**如果点击医生 跳转到挂号页面*/
-        pageType = "yyghClinicMsg"
-      }
-    }
-    this.setData({
-      deptListFirIndex: deptListFirIndex,
-      deptListSecIndex: deptListSecIndex,
-      deptListSec: deptListSec
-    })
-    // 判断如果不为空就是跳转
-    if(common.isNotEmpty(pageType)){
-      // 判断等于跳转医生列表页 且有配置特殊科室续弹窗显示内容
-      if(pageType == 'yyghDoctorList' && pageConfig.deptShowMode[item.DeptCode]){
-        common.showModal(pageConfig.deptShowMode[item.DeptCode],()=>{
-          pagesPatientFn.handleRouter(e, pageType, this.data.serviceId)
-        })
-      }else{
-        pagesPatientFn.handleRouter(e, pageType, this.data.serviceId)
-      }
-    }
-  },
-  /**
-   * 点击搜索
-   */
-  async searchClick() {
-    let pageConfig = this.data.pageConfig
-    let searchValue = this.data.searchValue;
-    if (common.isEmpty(searchValue)) {
-      common.showModal('请输入搜索科室或医生')
-      return
-    }
-    let result = []
-    let queryData = {
-      HosId: app.globalData.districtId || app.globalData.hosId,
-      SearchLike: searchValue,
-      ServiceId:this.data.serviceId,
-      QueryLocal:"1",
-      UseBaseInfo:true,
-      ExcludeOneLv:pageConfig.showDeptSec ? 1 : 0 ,// 是否过滤一级科室,
-    }
-    let resp = await yygh.searchClinicDeptAndDoctor(queryData)
-    if (!common.isEmpty(resp)) {
-      result = resp;
-    }
-    this.setData({
-      searchList: result
-    })
-  },
-  // 搜索科室
-  async queryDeptList(searchValue) {
-    let queryData = {
-      dept:{
-        hospitalId: app.globalData.districtId || app.globalData.hosId,
-        deptNameOrPingyinLike:searchValue,
-        status:1
-      },
-      deptdoctor:{
-        doctorServiceGh: 1, 
-        displaystatus: 1, 
-      },
-      doctor:{},
-    }
-    let resp = await yygh.queryDeptList_V2(queryData)
-    if (!common.isEmpty(resp)) {
-      if(this.data.pageConfig.showDeptSec){
-        resp = resp.filter(item=>item.parientId != -1)
-      }
-      resp = common.changeObj(resp)
-      return resp
-    }
-    return []
-  },
-  // 搜索医生
-  async queryDoctorList(searchValue) {
-    let queryData = {
-      isQueryDeptList: "1",//"是否返回医生的科室列表",
-      doctor: {
-        doctorNameOrPingYinLike:searchValue,//"拼音检索-模糊"
-        status:1
-      },
-      dept: {
-        hospitalId: app.globalData.districtId || app.globalData.hosId,
-        status:1
-      },
-      deptdoctor: {
-        doctorServiceGh: 1, // "是否开通挂号服务"
-        displaystatus: "1"//"是否启用"
-      }
-    }
-    let resp = await yygh.queryDoctorList_V2(queryData)
-    if (!common.isEmpty(resp)) {
-      let doctorList = []
-      resp.map(item=>{
-        item.searchType = '2'//医生数据做一个标识
-        item.deptList.map(ele =>{ // 方向把当前医生所有的坐诊科室排列出来
-          doctorList.push({...ele,...item})
-        })
-      })
-      doctorList = common.changeObj(doctorList)
-      return doctorList
-    }
-    return []
-  },
-  /**
-   * 输入框聚焦
-   */
-  focusFn(e) {
-    let type = e.currentTarget.dataset.type;
-    this.setData({
-      isFocus: type == 'focus' ? true : !this.data.isFocus,
-      searchValue: type == 'focus' ? this.data.searchValue : '',
-      searchList: type == 'focus' ? this.data.searchList : [],
-    })
-  },
-  /**
-   * 输入值获取
-   */
-  setVal(e) {
-    let key = e.currentTarget.dataset.key;
-    let value = e.detail.value;
-    this.setData({
-      [key]: value
-    })
-  },
-  /**
-   * 空函数 阻止搜索结果点击冒泡
-   */
-  doNothing() {
-
-  },
-  /**
-   * ai导诊 历史医生点击
-   */
-  optionClick(e) {
-    let type = e.currentTarget.dataset.type;
-    if (type == 'ai') {
-      //点击ai导诊
-      // 跳转密影  根目录加公众号appid
-      wx.navigateToMiniProgram({
-        appId: this.data.pageConfig.aiMode.appId,
-        // appid=:   需要自行对接配置相应医院的公众号appId
-        path: this.data.pageConfig.aiMode.path
-      })
-    } else {
-      //点击历史医生
-      common.goToUrl('/pagesPatient/st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor')
-    }
-  },
-  // 就诊须知弹窗关闭
-	modalCancel(){
-    common.navigateBack(1)
-	},
-	modalConfirm(){
-		this.setData({
-			'modalData.showModal' :false
-		})
-	},
-	modalNoData(){
-    common.navigateBack(1)
-	}
-})

+ 0 - 7
pagesPatient/st1/business/yygh/yyghDeptList/yyghDeptList.json

@@ -1,7 +0,0 @@
-{
-  "usingComponents": {
-    "richTextModal":"/pages/st1/components/richTextModal/richTextModal"
-  },
-  "navigationBarTitleText": "预约挂号" ,
-  "disableScroll":true
-}

+ 512 - 0
pagesPatient/st1/business/yygh/yyghDeptList/yyghDeptList.vue

@@ -0,0 +1,512 @@
+<template>
+  <view class="container" @click.stop="elementTracker">
+    <view class="content">
+      <view class="search">
+        <view class="search_box">
+          <input :class="isFocus ? 'search_input' : 'search_input_none'" placeholder="搜索科室或医生"
+            :placeholder-class="isFocus ? 'placeholder' : 'placeholder_none'" :value="searchValue" data-type="focus"
+            data-key="searchValue" @focus="focusFn" @input="setVal"></input>
+          <image class="search_icon" :class="{ 'search_icon_none': isFocus }" :src="iconUrl.search"></image>
+          <image class="remove_icon" v-if="isFocus" :src="iconUrl.cha" @click.stop="focusFn" data-type="blur"></image>
+          <view v-if="isFocus" class="search_confirm backgroundCustom_F08"
+            :class="{ 'search_confirm_active': isFocus }" @click="searchClick">搜索</view>
+        </view>
+      </view>
+
+      <view class="search_con" @click="focusFn" data-type="blur" v-if="isFocus">
+        <view class="search_con_inner" @click.stop="doNothing">
+          <view class="search_con_list">
+            <view class="search_con_list_inner">
+              <view class="search_con_item border_top" v-for="(item, index) in searchList" :key="index"
+                @click="deptClick(item, index, 'search')">
+                {{ item.SearchType == '2' ? item.DoctorName + " " + item.DeptName : item.DeptName }}
+                <image class="public_right_img" :src="iconUrl.icon_right"></image>
+              </view>
+            </view>
+          </view>
+        </view>
+      </view>
+
+      <view class="img_box displayFlexBetween">
+        <view class="img_item displayFlexCol" @click="optionClick('ai')" v-if="pageConfig.aiMode && pageConfig.aiMode.showAi">
+          <image class="img" :src="iconUrl.ai"></image>
+          <view class="text">
+            <view>AI智能导诊</view>
+            <view style="font-size: 26upx;opacity: 0.6;margin-top: 20upx;">不懂挂哪个科室?</view>
+          </view>
+        </view>
+        <view class="img_item displayFlexCol" @click="optionClick('history')">
+          <image class="img" :src="iconUrl.doctor_history"></image>
+          <view class="text">
+            <view>查看历史医生</view>
+            <view style="font-size: 26upx;opacity: 0.6;margin-top: 20upx;">预约看过的医生? </view>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view class="dept_list">
+      <view class="dept_list_inner">
+        <view class="dept_list_fir" :class="{ 'dept_list_fir_short': pageConfig.showDeptSec }">
+          <view class="dept_item"
+            :class="{ 'dept_item_active colorCustom': index == deptListFirIndex, 'toBoderRadio': index == deptListFirIndex - 1 }"
+            v-for="(item, index) in deptListFir" :key="index" @click="deptClick(item, index, 'fir')">
+            <view class="dept_item_inner" :class="{ 'border_bottom': !pageConfig.showDeptSec }">
+              {{ item.DeptName }}
+            </view>
+          </view>
+        </view>
+
+        <view class="dept_list_sec" v-if="pageConfig.showDeptSec">
+          <view class="dept_item border_bottom" v-for="(item, index) in deptListSec" :key="index"
+            @click="deptClick(item, index, 'sec')">
+            {{ item.DeptName }}
+          </view>
+        </view>
+      </view>
+    </view>
+    <richTextModal :modalData="modalData" v-if="modalData.showModal" @cancel="modalCancel" @confirm="modalConfirm"
+      @noData="modalNoData"></richTextModal>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import { onLoad, onShow } from '@dcloudio/uni-app';
+import { common, pagesPatientFn } from '@/utils';
+import icon from '@/utils/icon';
+import { 
+  queryClinicBaseDept, 
+  searchClinicDeptAndDoctor, 
+  queryDeptList_V2, 
+  queryDoctorList_V2 
+} from '@/pagesPatient/service/yygh';
+import richTextModal from '@/pages/st1/components/richTextModal/richTextModal.vue';
+
+const app = getApp();
+const iconUrl = ref(icon);
+const isFocus = ref(false); // input是否获取焦点
+const searchValue = ref(''); // 搜索值
+const searchList = ref<any[]>([]); // 搜索结果 
+const deptListFir = ref<any[]>([]); // 一级科室
+const deptListFirIndex = ref(-1); // 当前一级科室
+const deptListSec = ref<any[]>([]); // 二级科室
+const deptListSecIndex = ref(-1); // 当前二级科室
+const pageConfig = ref<any>({}); // 页面配置
+const serviceId = ref('');
+const queryData = ref<any>({
+  HosId: '',
+  ParentDeptCode: "",
+  ServiceId: ""
+});
+const modalData = ref<any>({});
+
+ onLoad((options: any) => {
+  pageConfig.value = common.deepCopy(app.globalData.config.pageConfiguration.yyghDeptList_config);
+  serviceId.value = options.serviceId || '';
+  queryData.value.HosId = app.globalData.districtId || app.globalData.hosId;
+  queryData.value.ServiceId = options.serviceId || '';
+  
+  main();
+});
+
+onShow(() => {
+
+});
+
+const main = async () => {
+  let pConfig = pageConfig.value;
+  // 获取一级科室
+  let dListFir: any[] = [];
+  let dListSec: any[] = [];
+  let qData = queryData.value;
+  
+  let deptListFirResp = await queryClinicBaseDept(qData);
+  if (!common.isEmpty(deptListFirResp)) {
+    dListFir = deptListFirResp;
+    if (pConfig.showDeptSec) {
+      // 如果有二级科室 默认取第一个一级科室 
+      qData.ParentDeptCode = dListFir[0].DeptCode;
+      let deptListSecResp = await queryClinicBaseDept(qData);
+      if (!common.isEmpty(deptListSecResp)) {
+        dListSec = deptListSecResp;
+      }
+    }
+  }
+  
+  deptListFir.value = dListFir;
+  deptListSec.value = dListSec;
+  deptListFirIndex.value = pConfig.showDeptSec ? 0 : -1;
+  modalData.value = pConfig.modalData;
+};
+
+/**
+ * 科室点击
+ */
+const deptClick = async (item: any, index: number, type: string) => {
+  let pageType = "";
+  let pConfig = pageConfig.value;
+  
+  if (type == 'fir') {
+    // 如果点击一级科室
+    deptListFirIndex.value = index;
+    if (pConfig.showDeptSec) {
+      // 如果医院有二级科室  
+      deptListSec.value = [];
+      let qData = queryData.value;
+      qData.ParentDeptCode = item.DeptCode;
+      let resp = await queryClinicBaseDept(qData);
+      if (!common.isEmpty(resp)) {
+        deptListSec.value = resp;
+        deptListSecIndex.value = -1;
+      }
+    } else {
+      pageType = 'yyghDoctorList';
+    }
+  } else if (type == 'sec') {
+    // 如果点击二级科室
+    deptListSecIndex.value = index;
+    pageType = 'yyghDoctorList';
+  } else {
+    // 搜索结果点击
+    pageType = 'yyghDoctorList';
+    if (item.SearchType == '2') {
+      /**如果点击医生 跳转到挂号页面*/
+      pageType = "yyghClinicMsg";
+    }
+  }
+  
+  // 模拟事件对象,用于 handleRouter
+  let e = {
+    currentTarget: {
+      dataset: {
+        item: item
+      }
+    }
+  };
+
+  // 判断如果不为空就是跳转
+  if (common.isNotEmpty(pageType)) {
+    // 判断等于跳转医生列表页 且有配置特殊科室续弹窗显示内容
+    if (pageType == 'yyghDoctorList' && pConfig.deptShowMode && pConfig.deptShowMode[item.DeptCode]) {
+      common.showModal(pConfig.deptShowMode[item.DeptCode], () => {
+        pagesPatientFn.handleRouter(e, pageType, serviceId.value);
+      });
+    } else {
+      pagesPatientFn.handleRouter(e, pageType, serviceId.value);
+    }
+  }
+};
+
+/**
+ * 点击搜索
+ */
+const searchClick = async () => {
+  let pConfig = pageConfig.value;
+  let sValue = searchValue.value;
+  if (common.isEmpty(sValue)) {
+    common.showModal('请输入搜索科室或医生');
+    return;
+  }
+  let result: any[] = [];
+  let qData = {
+    HosId: app.globalData.districtId || app.globalData.hosId,
+    SearchLike: sValue,
+    ServiceId: serviceId.value,
+    QueryLocal: "1",
+    UseBaseInfo: true,
+    ExcludeOneLv: pConfig.showDeptSec ? 1 : 0, // 是否过滤一级科室,
+  };
+  let resp = await searchClinicDeptAndDoctor(qData);
+  if (!common.isEmpty(resp)) {
+    result = resp;
+  }
+  searchList.value = result;
+};
+
+// 搜索科室 (Seems unused in original code but kept for completeness if needed)
+const queryDeptList = async (sValue: string) => {
+  let qData = {
+    dept: {
+      hospitalId: app.globalData.districtId || app.globalData.hosId,
+      deptNameOrPingyinLike: sValue,
+      status: 1
+    },
+    deptdoctor: {
+      doctorServiceGh: 1,
+      displaystatus: 1,
+    },
+    doctor: {},
+  };
+  let resp: any = await queryDeptList_V2(qData);
+  if (!common.isEmpty(resp)) {
+    if (pageConfig.value.showDeptSec) {
+      resp = resp.filter((item: any) => item.parientId != -1);
+    }
+    resp = common.changeObj(resp);
+    return resp;
+  }
+  return [];
+};
+
+// 搜索医生 (Seems unused in original code but kept for completeness if needed)
+const queryDoctorList = async (sValue: string) => {
+  let qData = {
+    isQueryDeptList: "1", // "是否返回医生的科室列表",
+    doctor: {
+      doctorNameOrPingYinLike: sValue, // "拼音检索-模糊"
+      status: 1
+    },
+    dept: {
+      hospitalId: app.globalData.districtId || app.globalData.hosId,
+      status: 1
+    },
+    deptdoctor: {
+      doctorServiceGh: 1, // "是否开通挂号服务"
+      displaystatus: "1" // "是否启用"
+    }
+  };
+  let resp: any = await queryDoctorList_V2(qData);
+  if (!common.isEmpty(resp)) {
+    let doctorList: any[] = [];
+    resp.map((item: any) => {
+      item.searchType = '2'; // 医生数据做一个标识
+      item.deptList.map((ele: any) => { // 方向把当前医生所有的坐诊科室排列出来
+        doctorList.push({ ...ele, ...item });
+      });
+    });
+    doctorList = common.changeObj(doctorList);
+    return doctorList;
+  }
+  return [];
+};
+
+/**
+ * 输入框聚焦
+ */
+const focusFn = (e: any) => {
+  let type = e.currentTarget.dataset.type;
+  isFocus.value = type == 'focus' ? true : !isFocus.value;
+  if (type != 'focus') {
+     // Blur or other action, maybe clear search value?
+     // Original logic: searchValue: type == 'focus' ? this.data.searchValue : '',
+     searchValue.value = '';
+     searchList.value = [];
+  }
+};
+
+/**
+ * 输入值获取
+ */
+const setVal = (e: any) => {
+  // let key = e.currentTarget.dataset.key; // unused in ref
+  let value = e.detail.value;
+  searchValue.value = value;
+};
+
+/**
+ * 空函数 阻止搜索结果点击冒泡
+ */
+const doNothing = () => {
+
+};
+
+/**
+ * ai导诊 历史医生点击
+ */
+const optionClick = (type: string) => {
+  if (type == 'ai') {
+    // 点击ai导诊
+    // 跳转密影  根目录加公众号appid
+    uni.navigateToMiniProgram({
+      appId: pageConfig.value.aiMode.appId,
+      // appid=:   需要自行对接配置相应医院的公众号appId
+      path: pageConfig.value.aiMode.path
+    });
+  } else {
+    // 点击历史医生
+    common.goToUrl('/pagesPatient/st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor');
+  }
+};
+
+// 就诊须知弹窗关闭
+const modalCancel = () => {
+  common.navigateBack(1);
+};
+
+const modalConfirm = () => {
+  modalData.value.showModal = false;
+};
+
+const modalNoData = () => {
+  common.navigateBack(1);
+};
+
+const elementTracker = () => {
+  // Placeholder for elementTracker if needed
+};
+</script>
+
+<style scoped>
+@import "@/pagesPatient/st1/static/css/search.css";
+
+.content {
+  padding-top: 110upx;
+  position: relative;
+  z-index: 10;
+}
+
+.search_con {
+  width: 100%;
+  position: fixed;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.6);
+  top: 0;
+  left: 0;
+  z-index: 1;
+  overflow: auto;
+  -webkit-overflow-scrolling: touch;
+}
+
+.search_con_inner {
+  width: 100%;
+  background-color: #fff;
+  padding: 0 0 10upx 30upx;
+}
+
+.search_con_list {
+  overflow: auto;
+  padding-top: 110upx;
+  -webkit-overflow-scrolling: touch;
+}
+
+.search_con_list_inner {
+  width: 100%;
+  display: inline-block;
+  margin-top: -1px;
+}
+
+.search_con_item {
+  font-size: 32upx;
+  padding: 36upx 0;
+  color: #222326;
+}
+
+.public_right_img {
+  right: 30upx;
+}
+
+/* =============== */
+.img_box {
+  width: 100%;
+  flex-wrap: wrap;
+  justify-content: space-between;
+  align-items: center;
+  padding: 10upx 30upx 30upx;
+  background-color: #fff;
+}
+
+.img_item {
+  width: 333upx;
+  height: 160upx;
+  position: relative;
+  align-items: flex-start;
+  padding: 0 30upx;
+}
+
+.img_item .img {
+  position: absolute;
+  top: 0;
+  left: 0;
+}
+
+.img_item .text {
+  position: relative;
+  font-size: 32upx;
+  font-family: PingFang SC;
+  font-weight: 800;
+  color: #FFFFFF;
+}
+
+/* =============== */
+.dept_list {
+  width: 100%;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 95%;
+  padding: 330upx 30upx 0;
+}
+
+.dept_list_inner {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  overflow: hidden;
+  border-radius: 24upx;
+  height: 100%;
+}
+
+.dept_list_fir {
+  height: 100%;
+  overflow: auto;
+  width: 100%;
+  -webkit-overflow-scrolling: touch;
+  background-color: #fff;
+}
+
+.dept_list_fir_short {
+  max-width: 316upx;
+}
+
+.dept_list_fir_short .dept_item {
+  background: #F7F7FC;
+}
+
+.dept_list_sec {
+  height: 100%;
+  overflow: auto;
+  -webkit-overflow-scrolling: touch;
+  width: 410upx;
+  background-color: #fff;
+}
+
+.dept_list_sec .dept_item {
+  text-indent: 30upx;
+  display: flex;
+  align-items: center;
+  justify-content: start;
+  padding: 34upx 0 34upx 30upx;
+  line-height: 44upx;
+}
+
+.dept_item {
+  font-size: 28upx;
+  position: relative;
+  color: #222326;
+  padding-left: 30upx;
+  padding-right: 30upx;
+}
+
+.dept_item_inner {
+  padding: 34upx 0;
+  line-height: 44upx;
+}
+
+.dept_item_active {
+  font-size: 32upx;
+  font-weight: bold;
+}
+
+.dept_list_fir_short .dept_item_active {
+  background-color: #fff;
+}
+
+.dept_list_fir_short .dept_item_active+.dept_item {
+  border-radius: 0 30upx 0 0;
+}
+
+.toBoderRadio {
+  border-radius: 0 0 30upx 0;
+}
+</style>

+ 0 - 60
pagesPatient/st1/business/yygh/yyghDeptList/yyghDeptList.wxml

@@ -1,60 +0,0 @@
-<view class="container" catchtap='elementTracker'>
-  <view class="content">
-    <view class="search" >
-      <view class="search_box">
-        <input class="{{isFocus?'search_input':'search_input_none'}}" placeholder="搜索科室或医生" placeholder-class="{{isFocus?'placeholder':'placeholder_none'}}" value="{{searchValue}}"data-type="focus" data-key="searchValue" bindfocus="focusFn" bindinput="setVal"></input>
-        <image class="search_icon {{isFocus?'search_icon_none':''}}" src="{{iconUrl.search}}"></image>
-        <image class="remove_icon" wx:if="{{isFocus}}" src="{{iconUrl.cha}}" catchtap="focusFn"></image>
-        <view wx:if="{{isFocus}}" class="search_confirm backgroundCustom_F08 {{isFocus?'search_confirm_active':''}}" bindtap="searchClick">搜索</view>
-      </view>
-    </view>
-
-    <view class="search_con" bindtap="focusFn" wx:if="{{isFocus}}">
-      <view class="search_con_inner" catchtap="doNothing">
-        <view class="search_con_list">
-          <view class="search_con_list_inner">
-            <view class="search_con_item border_top" wx:for="{{searchList}}" wx:key="index" bindtap="deptClick" data-item="{{item}}">
-              {{item.SearchType=='2'?item.DoctorName+" "+item.DeptName:item.DeptName}}
-              <image class="public_right_img" src="{{iconUrl.icon_right}}"></image>
-            </view>
-          </view>
-        </view>
-      </view>
-    </view>
-
-    <view class="img_box displayFlexBetween">
-      <view class="img_item displayFlexCol" bindtap="optionClick" data-type="ai" wx:if="{{pageConfig.aiMode.showAi}}">
-        <image class="img" src="{{iconUrl.ai}}"></image>
-        <view class="text">
-          <view>AI智能导诊</view>
-          <view style="font-size: 26rpx;opacity: 0.6;margin-top: 20rpx;">不懂挂哪个科室?</view>
-        </view>
-      </view>
-      <view class="img_item displayFlexCol" bindtap="optionClick" data-type="history">
-        <image class="img" src="{{iconUrl.doctor_history}}"></image>
-        <view class="text">
-          <view>查看历史医生</view>
-          <view style="font-size: 26rpx;opacity: 0.6;margin-top: 20rpx;">预约看过的医生? </view>
-        </view>
-      </view>
-    </view>
-  </view>
-  <view class="dept_list">
-    <view class="dept_list_inner">
-      <view class="dept_list_fir {{pageConfig.showDeptSec?'dept_list_fir_short':''}}">
-        <view class="dept_item  {{index==deptListFirIndex&&'dept_item_active colorCustom'}} {{index==deptListFirIndex-1&&'toBoderRadio'}}"  wx:for="{{deptListFir}}" wx:key="index" bindtap="deptClick" data-type="fir" data-item="{{item}}" data-index="{{index}}">
-          <view class="dept_item_inner {{pageConfig.showDeptSec?'':'border_bottom'}}">
-            {{item.DeptName}}
-          </view>
-        </view>
-      </view>
-
-      <view class="dept_list_sec" wx:if="{{pageConfig.showDeptSec}}">
-        <view class="dept_item border_bottom" wx:for="{{deptListSec}}" wx:key="index" bindtap="deptClick" data-type="sec" data-item="{{item}}" data-index="{{index}}">
-           {{item.DeptName}}
-        </view>
-      </view>
-    </view>
-  </view>
-  <richTextModal modalData="{{modalData}}" wx:if="{{modalData.showModal}}"  bind:cancel="modalCancel" bind:confirm="modalConfirm" bind:noData="modalNoData"></richTextModal>
-</view>

+ 0 - 154
pagesPatient/st1/business/yygh/yyghDeptList/yyghDeptList.wxss

@@ -1,154 +0,0 @@
-@import "../../../static/css/search.wxss";
-
-.content {
-  padding-top: 110rpx;
-  position: relative;
-  z-index: 10;
-}
-
-.search_con {
-  width: 100%;
-  position: fixed;
-  height: 100%;
-  background-color: rgba(0, 0, 0, 0.6);
-  top: 0;
-  left: 0;
-  z-index: 1;
-  overflow: auto;
-  -webkit-overflow-scrolling: touch;
-}
-
-.search_con_inner {
-  width: 100%;
-  background-color: #fff;
-  padding: 0 0 10rpx 30rpx;
-}
-
-.search_con_list {
-  overflow: auto;
-  padding-top: 110rpx;
-  -webkit-overflow-scrolling: touch;
-}
-
-.search_con_list_inner {
-  width: 100%;
-  display: inline-block;
-  margin-top: -1px;
-}
-
-.search_con_item {
-  font-size: 32rpx;
-  padding: 36rpx 0;
-  color: #222326;
-}
-.public_right_img{
-  right: 30rpx;
-}
-/* =============== */
-.img_box {
-  width: 100%;
-  flex-wrap: wrap;
-  justify-content: space-between;
-  align-items: center;
-  padding:10rpx 30rpx 30rpx;
-  background-color: #fff;
-}
-
-.img_item {
-  width: 333rpx;
-  height: 160rpx;
-  position: relative;
-  align-items: flex-start;
-  padding:0 30rpx;
-}
-.img_item .img{
-  position: absolute;
-  top: 0;
-  left: 0;
-}
-.img_item .text{
-  position: relative;
-  font-size: 32rpx;
-  font-family: PingFang SC;
-  font-weight: 800;
-  color: #FFFFFF;
-}
-
-/* =============== */
-.dept_list {
-  width: 100%;
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 95%;
-  padding: 330rpx 30rpx 0;
-}
-
-.dept_list_inner {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  overflow: hidden;
-  border-radius: 24rpx ;
-  height: 100%;
-}
-
-.dept_list_fir {
-  height: 100%;
-  overflow: auto;
-  width: 100%;
-  -webkit-overflow-scrolling: touch;
-  background-color: #fff;
-}
-
-.dept_list_fir_short {
-  max-width: 316rpx;
-}
-.dept_list_fir_short .dept_item {
-  background: #F7F7FC;
-}
-.dept_list_sec {
-  height: 100%;
-  overflow: auto;
-  -webkit-overflow-scrolling: touch;
-  width: 410rpx;
-  background-color: #fff;
-}
-
-.dept_list_sec .dept_item {
-  text-indent: 30rpx;
-  display: flex;
-  align-items: center;
-  justify-content: start;
-  padding: 34rpx 0 34rpx 30rpx;
-  line-height: 44rpx;
-}
-.dept_item {
-  font-size: 28rpx;
-  position: relative;
-  color: #222326;
-  padding-left: 30rpx;
-  padding-right: 30rpx;
-}
-
-.dept_item_inner {
-  padding: 34rpx 0;
-  line-height: 44rpx;
-}
-
-.dept_item_active {
-  font-size: 32rpx;
-  font-weight: bold;
-}
-
-.dept_list_fir_short .dept_item_active {
-  background-color: #fff;
-}
-
-.dept_list_fir_short .dept_item_active  + .dept_item {
-  border-radius: 0 30rpx 0 0 ;
-}
-.toBoderRadio{
-  border-radius: 0 0 30rpx 0;
-}

+ 0 - 323
pagesPatient/st1/business/yygh/yyghDoctorList/yyghDoctorList.js

@@ -1,323 +0,0 @@
-const app = getApp();
-import yygh from "../../../../config/api/yygh/index.js";
-import regeneratorRuntime from "../../../../../utils/runtime.js";
-import common from "../../../../../utils/common.js";
-import { pagesPatientFn } from '@/utils';
-import apiRootUrl from "../../../../config/api.js";
-import icon from "../../../../../utils/icon.js";
-Page({
-  data: {
-    iconUrl:icon,
-    dialogIsShow: false, //是否展示医生职称筛选
-    showNoData: false, //是否展示暂无数据
-    timeList: [], //预约时段列表
-    timeActive: '', //当前选择的预约时间index   ''为全部
-    doctorList: [], //预约医生列表
-    noDataTip: '暂无排班数据', //暂无数据显示字段
-    showCon: false, //是否展示页面
-    titleInfoList: [], //医生职称列表
-    titleSelect: {}, //当前选择的医生职称
-    titleClick: {}, //当前点击的医生职称
-    reducibleOnly: false, //是否仅显示可约医生
-    doctorInfoIsShow: false,
-    doctorInfo: {}, //医生详情信息
-    pageConfig: {},
-    serviceId:'',
-  },
-  onLoad: function(options) {
-    /** 如果有区分院区 会传入院区Id  直接赋值 */
-    app.globalData.districtId = options.DistrictId || app.globalData.districtId
-    // 当前页面配置信息
-    let pageConfig = common.deepCopy(app.globalData.config.pageConfiguration.yyghDoctorList_config)
-    let queryBean = options.queryBean ? JSON.parse(options.queryBean) : app.globalData.queryBean ? app.globalData.queryBean :{}
-    console.log(queryBean,'queryBean')
-    options.deptName && (queryBean.DeptName = options?.deptName)
-    options.deptCode && (queryBean.DeptCode = options?.deptCode)
-    this.setData({
-      queryBean: queryBean,
-      serviceId:options.serviceId || '',
-      pageConfig: pageConfig,
-      timeActive: (pageConfig.hasAllSchedules && options.serviceId != '009') ? '' : 0
-    })
-    wx.setNavigationBarTitle({
-      title: this.data.queryBean.DeptName,
-    })
-    this.main()
-  },
-  
-  async main() {
-    
-    let timeList = [];
-    let titleInfoList = [];
-    let queryBean = this.data.queryBean;
-    //获取排班日期列表 
-    let queryData = {
-      HosId: app.globalData.districtId || app.globalData.hosId,
-      DeptCode: queryBean.DeptCode
-    }
-    let timeListResp = await yygh.queryClinicScheduleDate(queryData)
-    timeListResp.map(item=>{
-      if(item.RegDate == common.newDay())item.WeekName = '今天'
-    })
-    timeList = !common.isEmpty(timeListResp) ? timeListResp : timeList;
-    //获取排班医生列表  
-    let doctorListResp = this.setterDoctorList(timeList)
-    this.setData({
-      timeList: timeList,
-      showCon: true,
-    })
-  },
-  /**
-   * 医生筛选点击
-   */
-  async titleClick(e) {
-    let item = e.currentTarget.dataset.item;
-    //为空 点击全部  
-    this.setData({
-      titleClick: common.isEmpty(item) ? "" : item
-    })
-  },
-  /**
-   * 医生详情点击
-   */
-  async doctorInfoClick(e) {
-    let item = e.currentTarget.dataset.item;
-    let queryData = {
-      HosId: app.globalData.districtId || app.globalData.hosId,
-      DeptCode: item.DeptCode || '',
-      DoctorCode: item.DoctorCode || '',
-      DoctorName:  ''
-    }
-    let resp = await yygh.queryClinicBaseDoctor(queryData);
-    if (!common.isEmpty(resp)) {
-      this.setData({
-        doctorInfoIsShow: true,
-        doctorInfo: resp[0]
-      })
-    }
-  },
-  /**
-   * 点击医生职称重置 确定按钮
-   */
-  async titleBtnClick(e) {
-    let type = e.currentTarget.dataset.type;
-    if (type == 'reset') {
-      //点击重置
-      this.setData({
-        titleClick: {}
-      })
-    } else {
-      //点击确定 
-      this.setData({
-        titleSelect: this.data.titleClick
-      })
-      await this.setterDoctorList()
-      this.dialogShowChange()
-    }
-  },
-  /**
-   * 点击查看全部排班
-   */
-  showAll(e) {
-    let doctorIndex = e.currentTarget.dataset.doctorindex;
-    let schedulindex = e.currentTarget.dataset.schedulindex;
-    let doctorList = this.data.doctorList;
-    doctorList[doctorIndex].Scheduling[schedulindex].showAllSchedu = !doctorList[doctorIndex].Scheduling[schedulindex].showAllSchedu
-    this.setData({
-      doctorList: doctorList
-    })
-  },
-  /**
-   * 是否仅显示可约医生
-   */
-  async switchChange(e) {
-    let value = e.detail.value;
-    this.setData({
-      reducibleOnly: value
-    })
-    await this.setterDoctorList()
-  },
-  /**
-   * 点击排班时间
-   */
-  async timeClick(e) {
-    let item = e.currentTarget.dataset.item;
-    let index = e.currentTarget.dataset.index;
-    let showNoData = true;
-    let timeActive = this.data.timeActive;
-    if (!common.isEmpty(item)) {
-      timeActive = index
-    } else {
-      // 点击全部  
-      timeActive = ""
-    }
-    this.setData({
-      timeActive: timeActive
-    })
-    await this.setterDoctorList();
-
-  },
-  /**
-   * 医生dialog显隐
-   */
-  dialogShowChange() {
-    this.setData({
-      dialogIsShow: !this.data.dialogIsShow,
-      titleClick: this.data.titleSelect
-    })
-  },
-  /**
-   * 空函数
-   */
-  doNothing() {
-
-  },
-  /**
-   * 处理医生列表返回值 
-   */
-  async setterDoctorList(timeList) {
-    let list = timeList || this.data.timeList;
-    let time = typeof this.data.timeActive == 'number' ? list[this.data.timeActive].RegDate : ""
-    let queryData = {
-      HosId: app.globalData.districtId || app.globalData.hosId,
-      ServiceId:this.data.serviceId,
-      DeptCode: this.data.queryBean.DeptCode,
-      DoctorCode: "",
-      WorkDateStart: time || "",
-      WorkDateEnd: time || "",
-      TitleCode: this.data.titleSelect.DoctorTitleCode || "",
-      OrderByDoc: '1',
-      WaitRule : '1'
-    }
-    let resp = await yygh.queryClinicDoctorSchedule(queryData)
-    let reducibleOnly = this.data.reducibleOnly;
-    if (!common.isEmpty(resp)) {
-      for (let i of resp) {
-        if (i.Data_1 && !common.isEmpty(i.Data_1)){
-          i.Data_1.map(item => {
-            item.RegDateDiy = item.RegDate.substring(5),
-            item.WeekName = item.RegDate == common.newDay()?'今天':item.WeekName
-          })
-        }
-        /**如果医生头像没有域名 添加域名 */
-        if (i.PhotoUrl && i.PhotoUrl.indexOf('http') == '-1') {
-          i.PhotoUrl = apiRootUrl.ApiRootUrl + i.PhotoUrl
-        }
-        i.PhotoUrl = i.PhotoUrl.replace(/\\/g, '/')
-        if (i.Data_1.length > 6) {
-          i.Data_1_Diy = i.Data_1.slice(0, 5);
-          i.showAllSchedu = false
-        } else {
-          i.Data_1_Diy = i.Data_1;
-          i.showAllSchedu = true;
-        }
-      }
-    }
-    if (reducibleOnly && !common.isEmpty(resp)) {
-      resp = resp.filter(item => item.Data_1.filter(cell => cell.IsHalt != '7' && cell.IsHalt != '2').length > 0)
-    }
-    resp.map(item=>{
-      let obj = [{
-        Check:true,
-        DeptName:item.DeptName,
-        DeptCode:item.DeptCode,
-        DoctorName:item.DoctorName,
-        DoctorCode:item.DoctorCode,
-        Data_1:item.Data_1,
-        Data_1_Diy:item.Data_1_Diy,
-        showAllSchedu:item.showAllSchedu,
-      }]
-      item.Scheduling = obj
-    })
-    this.setData({
-      doctorList: resp,
-      showNoData: common.isEmpty(resp) ? true : false
-    })
-  },
-  /**
-   * 点击医生具体排班时间
-   */
-  async toClinic(e) {
-    let item = e.currentTarget.dataset.dataitem;
-    let index = e.currentTarget.dataset.index;
-    // 判断(约满且无候补)或者停诊
-    if ((item.IsHalt==7&& item.WaitLeaveCount <= 0) || item.IsHalt == '2') {
-      return;
-    }
-    /**判断有卡无卡 有无就诊人 有无最后操作就诊人的路径跳转处理 */
-    pagesPatientFn.handleRouter(e, 'yyghClinicMsg',this.data.serviceId, index)
-  },
-  /**
-   * 查询其它科室排班
-   */
-  async queryScheduleList(e){
-    let doctorIndex = e.currentTarget.dataset.index
-    let doctorItem = e.currentTarget.dataset.doctoritem
-    let doctorList = common.deepCopy(this.data.doctorList,[])
-    let time = typeof this.data.timeActive == 'number' ? this.data.timeList[this.data.timeActive].RegDate : ""
-    let querData = {
-      workDateEnd: time || "",
-      workDateStart: time || "",
-      doctorCode: doctorItem.DoctorCode,
-      deptCode:doctorItem.DeptCode ,
-      hosId: app.globalData.districtId || app.globalData.hosId,
-      WaitRule: '1'
-    }
-    let res = await yygh.queryScheduleList(querData)
-    if(common.isNotEmpty(res)){
-      let scheduleList = []
-      res.map(async (item,index)=>{
-        // 转换返回数据 小写转大写
-        item.hisQueryClinicSchedules = common.changeObj(item.hisQueryClinicSchedules)
-        item.hisQueryBaseDoctor = common.changeObj(item.hisQueryBaseDoctor)
-        if(item.hisQueryClinicSchedules.length > 0){
-          // 判断是否多数据处理 星期 时间 上下午
-          if(item.hisQueryClinicSchedules.length > 0){
-            item.hisQueryClinicSchedules.map(ele=>{
-              ele.WeekName = ele.RegDate == common.newDay()?'今天':common.weekDay(ele.RegDate,1)
-              ele.RegDateDiy = ele.RegDate.substring(5)
-              ele.TimeSliceStr = ele.TimeSlice==1?'上午':ele.TimeSlice==2?'下午':'全天'
-            })
-          }
-          // 判断如果超出6个隐藏
-          if (item.hisQueryClinicSchedules.length > 6) {
-            item.Data_1_Diy = item.hisQueryClinicSchedules.slice(0, 5);
-            item.showAllSchedu = false
-          } else {
-            item.Data_1_Diy = item.hisQueryClinicSchedules;
-            item.showAllSchedu = true;
-          }
-          scheduleList.push({
-            Check:item.hisQueryBaseDoctor.DeptCode==doctorItem.DeptCode?true:false,
-            DeptName:item.hisQueryBaseDoctor.DeptName,
-            DeptCode:item.hisQueryBaseDoctor.DeptCode,
-            DoctorName:doctorItem.DoctorName,
-            DoctorCode:doctorItem.DoctorCode,
-            Data_1:item.hisQueryClinicSchedules,
-            Data_1_Diy:item.Data_1_Diy,
-            showAllSchedu:item.showAllSchedu,
-          })
-        }
-      })
-      // 给当前查询的医生新加列表
-      doctorList[doctorIndex].Scheduling = scheduleList
-    }
-    // 查询过的医生 不展示switch
-    doctorList[doctorIndex].ShowDeptSwitch = true
-    this.setData({
-      doctorList:doctorList
-    })
-  },
-  /**
-   * 折叠列表
-   */
-  foldList(e) {
-    let doctorIndex = e.currentTarget.dataset.doctorindex
-    let schedulIndex = e.currentTarget.dataset.schedulindex
-    let doctorList = this.data.doctorList
-    doctorList[doctorIndex].Scheduling[schedulIndex].Check = !doctorList[doctorIndex].Scheduling[schedulIndex].Check
-    this.setData({
-      doctorList
-    })
-  },
-})

+ 0 - 11
pagesPatient/st1/business/yygh/yyghDoctorList/yyghDoctorList.json

@@ -1,11 +0,0 @@
-{
-  "usingComponents": {
-    "noData": "/pages/st1/components/noData/noData",
-    "doctorInfo": "/pagesPatient/st1/components/doctorInfo/doctorInfo",
-    "aiCustomerEntry": "/pagesAICustomerService/st1/components/aiCustomerEntry/aiCustomerEntry"
-  },
-  "componentPlaceholder": {
-    "aiCustomerEntry": "view"
-  },
-  "navigationBarTitleText": "排班" 
-}

+ 420 - 0
pagesPatient/st1/business/yygh/yyghDoctorList/yyghDoctorList.vue

@@ -0,0 +1,420 @@
+<template>
+  <view class="container" :class="{ 'fixed': dialogIsShow }" :hidden="!showCon">
+    <view class="content">
+      <view class="userInfoTopFixe">
+        <view class="date_list" v-if="serviceId != '009'">
+          <view class="date_item date_item_hasList date_item_all" :class="{ 'backgroundCustom': timeActive === '' }"
+            @click="timeClick" v-if="pageConfig.hasAllSchedules">
+            全部
+          </view>
+          <view class="date_item date_item_hasList" :class="{ 'backgroundCustom': timeActive === index, 'colorCustom_999': item.HasSchedule != 1 }"
+            v-for="(item, index) in timeList" :key="index" @click="item.HasSchedule == 1 ? timeClick($event, item, index) : null">
+            <text>{{ item.WeekName }}</text>
+            <text class="month">{{ item.RegDateNotYear }}</text>
+          </view>
+        </view>
+
+        <view class="nav">
+          <view class="nav_inner">
+            <view class="nav_tit_val">是否仅显示可约医生</view>
+            <switch class="public_switch" :checked="reducibleOnly" color="var(--dominantColor)" @change="switchChange"></switch>
+          </view>
+        </view>
+      </view>
+      <view class="doctor_list" :class="{ 'doctor_list100': serviceId == '009' }" v-if="!showNoData">
+        <view class="doctor_item" v-for="(doctorItem, doctorIndex) in doctorList" :key="doctorIndex">
+          <view class="doctor_item_nav" @click="doctorInfoClick(doctorItem)">
+            <view class="doctor_item_nav_img">
+              <image :src="doctorItem.PhotoUrl || iconUrl.icon_doctor" mode="widthFix"></image>
+            </view>
+            <view class="doctor_item_nav_tit">
+              <view class="doctor_item_nav_subtit">
+                <text class="doctor_item_nav_subtit_val">{{ doctorItem.DoctorName }}</text>
+                <text v-if="doctorItem.DoctorTitle || doctorItem.Title" class="doctor_item_nav_subtit_txt">{{ doctorItem.DoctorTitle || doctorItem.Title }}</text>
+              </view>
+              <view v-if="doctorItem.Spec" class="doctor_item_nav_info">
+                {{ doctorItem.Spec }}
+              </view>
+            </view>
+          </view>
+          <view class="scheduling_box" v-for="(schedulItem, schedulIndex) in doctorItem.Scheduling" :key="schedulIndex">
+            <view class="scheduling_dept_box displayFlexBetween" @click="foldList(doctorIndex, schedulIndex)">
+              <view class="scheduling_deptName_box displayFlexRow">
+                <view class="backgroundCustom "></view>
+                <text>{{ schedulItem.DeptName }}</text>
+              </view>
+              <image class="arrow" :class="{ 'transform_rotate_90': schedulItem.Check }" :src="iconUrl.icon_right"></image>
+            </view>
+            <view class="time_list" v-if="schedulItem.Check">
+              <view class="time_item displayFlexCol" :class="{ 'time_item_stop': (item.IsHalt == 7 && item.WaitLeaveCount <= 0) || item.IsHalt == 2 }"
+                v-for="(item, index) in (schedulItem.showAllSchedu ? schedulItem.Data_1 : schedulItem.Data_1_Diy)" :key="index"
+                @click="toClinic(item, index, schedulItem)">
+                <view>{{ item.RegDateDiy }}</view>
+                <view style="margin-top: 12upx;">{{ item.WeekName }} {{ item.TimeSliceStr }}</view>
+                <image v-if="item.IsHalt == 7" class="time_item_img" :src="iconUrl.full2"></image>
+                <image v-if="item.IsHalt == 2" class="time_item_img" :src="iconUrl.stop"></image>
+                <image v-if="item.IsHalt == 7 && item.WaitLeaveCount > 0" class="time_item_img" :src="iconUrl.yyghWait"></image>
+              </view>
+              <view class="time_item colorCustom" @click="showAll(doctorIndex, schedulIndex)" v-if="schedulItem.Data_1.length > 6">
+                {{ schedulItem.showAllSchedu ? '收起' : '全部排班' }}
+              </view>
+            </view>
+          </view>
+          <view class="other_dept_box" v-if="!doctorItem.ShowDeptSwitch">
+            <view class="displayFlexRow border_top displayFlexBetween">
+              <text>本院所有科室排班</text>
+              <switch color="var(--dominantColor)" class="public_switch" @change="queryScheduleList($event, doctorIndex, doctorItem)" />
+            </view>
+          </view>
+          <view class="other_dept_box displayFlexRow border_top" v-if="doctorItem.Scheduling.length == 1 && doctorItem.ShowDeptSwitch">
+            <text class="non_schedul">暂无其他科室排班</text>
+          </view>
+        </view>
+      </view>
+      <view v-else class="noData">
+        <noData :value="noDataTip"></noData>
+      </view>
+    </view>
+    <doctorInfoComp :doctorInfoIsShow="doctorInfoIsShow" :doctorInfo="doctorInfo"></doctorInfoComp>
+  </view>
+
+  <!-- AI数智客服入口-->
+  <aiCustomerEntry :currentUser="currentUser"></aiCustomerEntry>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, computed } from 'vue';
+import { onLoad } from '@dcloudio/uni-app';
+import { common, pagesPatientFn } from '@/utils';
+import icon from '@/utils/icon';
+import { REQUEST_CONFIG } from '@/config';
+import { 
+  queryClinicScheduleDate, 
+  queryClinicDoctorSchedule, 
+  queryClinicBaseDoctor, 
+  queryScheduleList as queryScheduleListApi
+} from '@/pagesPatient/service/yygh';
+
+import noData from '@/pages/st1/components/noData/noData.vue';
+import doctorInfoComp from '@/pagesPatient/st1/components/doctorInfo/doctorInfo.vue';
+import aiCustomerEntry from '@/pages/st1/components/pagesAICustomerService/st1/components/aiCustomerEntry/aiCustomerEntry.vue';
+
+// Define components locally if needed, but imported components are automatically available in <script setup>
+// We rename doctorInfo import to avoid conflict with doctorInfo ref
+const doctorInfo = ref({});
+
+const iconUrl = ref(icon);
+const dialogIsShow = ref(false);
+const showNoData = ref(false);
+const timeList = ref<any[]>([]);
+const timeActive = ref<string | number>('');
+const doctorList = ref<any[]>([]);
+const noDataTip = ref('暂无排班数据');
+const showCon = ref(false);
+const titleInfoList = ref([]);
+const titleSelect = ref<any>({});
+const titleClickVal = ref<any>({}); // Renamed from titleClick to avoid conflict with method
+const reducibleOnly = ref(false);
+const doctorInfoIsShow = ref(false);
+const pageConfig = ref<any>({});
+const serviceId = ref('');
+const queryBean = ref<any>({});
+const currentUser = ref({}); // Added for aiCustomerEntry
+
+const app = getApp();
+
+onLoad((options: any) => {
+  if (options.DistrictId) {
+    app.globalData.districtId = options.DistrictId;
+  }
+  
+  // 当前页面配置信息
+  let config = common.deepCopy(app.globalData.config?.pageConfiguration?.yyghDoctorList_config || {});
+  let qBean = options.queryBean ? JSON.parse(options.queryBean) : app.globalData.queryBean ? app.globalData.queryBean : {};
+  console.log(qBean, 'queryBean');
+  
+  if (options.deptName) qBean.DeptName = options.deptName;
+  if (options.deptCode) qBean.DeptCode = options.deptCode;
+  
+  queryBean.value = qBean;
+  serviceId.value = options.serviceId || '';
+  pageConfig.value = config;
+  timeActive.value = (config.hasAllSchedules && options.serviceId != '009') ? '' : 0;
+  
+  uni.setNavigationBarTitle({
+    title: queryBean.value.DeptName || '排班',
+  });
+  
+  main();
+});
+
+const main = async () => {
+  let tList: any[] = [];
+  
+  // 获取排班日期列表 
+  let queryData = {
+    HosId: app.globalData.districtId || app.globalData.hosId,
+    DeptCode: queryBean.value.DeptCode
+  };
+  
+  let timeListResp = await queryClinicScheduleDate(queryData);
+  if (timeListResp && Array.isArray(timeListResp)) {
+    timeListResp.map((item: any) => {
+      if (item.RegDate == common.newDay()) item.WeekName = '今天';
+    });
+    tList = !common.isEmpty(timeListResp) ? timeListResp : tList;
+  }
+  
+  // 获取排班医生列表  
+  await setterDoctorList(tList);
+  
+  timeList.value = tList;
+  showCon.value = true;
+};
+
+// 医生筛选点击
+const titleClick = (item: any) => {
+  titleClickVal.value = common.isEmpty(item) ? "" : item;
+};
+
+// 医生详情点击
+const doctorInfoClick = async (item: any) => {
+  let queryData = {
+    HosId: app.globalData.districtId || app.globalData.hosId,
+    DeptCode: item.DeptCode || '',
+    DoctorCode: item.DoctorCode || '',
+    DoctorName: ''
+  };
+  
+  let resp = await queryClinicBaseDoctor(queryData);
+  if (!common.isEmpty(resp)) {
+    doctorInfoIsShow.value = true;
+    doctorInfo.value = resp[0];
+  }
+};
+
+// 点击医生职称重置 确定按钮
+const titleBtnClick = async (type: string) => {
+  if (type == 'reset') {
+    titleClickVal.value = {};
+  } else {
+    titleSelect.value = titleClickVal.value;
+    await setterDoctorList();
+    dialogShowChange();
+  }
+};
+
+// 点击查看全部排班
+const showAll = (doctorIndex: number, schedulIndex: number) => {
+  const list = [...doctorList.value];
+  list[doctorIndex].Scheduling[schedulIndex].showAllSchedu = !list[doctorIndex].Scheduling[schedulIndex].showAllSchedu;
+  doctorList.value = list;
+};
+
+// 是否仅显示可约医生
+const switchChange = async (e: any) => {
+  reducibleOnly.value = e.detail.value;
+  await setterDoctorList();
+};
+
+// 点击排班时间
+const timeClick = async (e: any, item?: any, index?: number) => {
+  // item and index are passed directly in Vue template
+  // If called without item (click "All"), item is undefined
+  
+  if (!common.isEmpty(item)) {
+    timeActive.value = index!;
+  } else {
+    timeActive.value = "";
+  }
+  await setterDoctorList();
+};
+
+// 医生dialog显隐
+const dialogShowChange = () => {
+  dialogIsShow.value = !dialogIsShow.value;
+  titleClickVal.value = titleSelect.value;
+};
+
+const doNothing = () => {};
+
+// 处理医生列表返回值 
+const setterDoctorList = async (tList?: any[]) => {
+  let list = tList || timeList.value;
+  let time = typeof timeActive.value == 'number' ? list[timeActive.value].RegDate : "";
+  
+  let queryData = {
+    HosId: app.globalData.districtId || app.globalData.hosId,
+    ServiceId: serviceId.value,
+    DeptCode: queryBean.value.DeptCode,
+    DoctorCode: "",
+    WorkDateStart: time || "",
+    WorkDateEnd: time || "",
+    TitleCode: titleSelect.value.DoctorTitleCode || "",
+    OrderByDoc: '1',
+    WaitRule: '1'
+  };
+  
+  let resp = await queryClinicDoctorSchedule(queryData);
+  let isReducibleOnly = reducibleOnly.value;
+  
+  if (!common.isEmpty(resp)) {
+    for (let i of resp) {
+      if (i.Data_1 && !common.isEmpty(i.Data_1)) {
+        i.Data_1.map((item: any) => {
+          item.RegDateDiy = item.RegDate.substring(5);
+          item.WeekName = item.RegDate == common.newDay() ? '今天' : item.WeekName;
+        });
+      }
+      
+      /**如果医生头像没有域名 添加域名 */
+      if (i.PhotoUrl && i.PhotoUrl.indexOf('http') == '-1') {
+        i.PhotoUrl = REQUEST_CONFIG.BASE_URL + i.PhotoUrl;
+      }
+      if (i.PhotoUrl) {
+          i.PhotoUrl = i.PhotoUrl.replace(/\\/g, '/');
+      }
+      
+      if (i.Data_1 && i.Data_1.length > 6) {
+        i.Data_1_Diy = i.Data_1.slice(0, 5);
+        i.showAllSchedu = false;
+      } else {
+        i.Data_1_Diy = i.Data_1;
+        i.showAllSchedu = true;
+      }
+    }
+  }
+  
+  if (isReducibleOnly && !common.isEmpty(resp)) {
+    resp = resp.filter((item: any) => item.Data_1.filter((cell: any) => cell.IsHalt != '7' && cell.IsHalt != '2').length > 0);
+  }
+  
+  if (resp) {
+    resp.map((item: any) => {
+      let obj = [{
+        Check: true,
+        DeptName: item.DeptName,
+        DeptCode: item.DeptCode,
+        DoctorName: item.DoctorName,
+        DoctorCode: item.DoctorCode,
+        Data_1: item.Data_1,
+        Data_1_Diy: item.Data_1_Diy,
+        showAllSchedu: item.showAllSchedu,
+      }];
+      item.Scheduling = obj;
+    });
+  }
+  
+  doctorList.value = resp || [];
+  showNoData.value = common.isEmpty(resp) ? true : false;
+};
+
+// 点击医生具体排班时间
+const toClinic = (item: any, index: number, schedulItem: any) => {
+  // 判断(约满且无候补)或者停诊
+  if ((item.IsHalt == 7 && item.WaitLeaveCount <= 0) || item.IsHalt == '2') {
+    return;
+  }
+  
+  // Construct event object to mimic typical event structure if needed by pagesPatientFn, 
+  // but handleRouter usually takes dataset from event.
+  // Here we pass data manually or construct a mock event.
+  // pagesPatientFn.handleRouter(e, 'yyghClinicMsg', this.data.serviceId, index)
+  
+  // Since pagesPatientFn.handleRouter expects an event object with currentTarget.dataset
+  // We should reconstruct what it expects.
+  // The original call was: pagesPatientFn.handleRouter(e, 'yyghClinicMsg',this.data.serviceId, index)
+  // e.currentTarget.dataset.dataitem was 'item'
+  
+  const mockEvent = {
+    currentTarget: {
+      dataset: {
+        dataitem: item,
+        index: index
+      }
+    }
+  };
+  
+  pagesPatientFn.handleRouter(mockEvent, 'yyghClinicMsg', serviceId.value, index);
+};
+
+// 查询其它科室排班
+const queryScheduleList = async (e: any, doctorIndex: number, doctorItem: any) => {
+  // Switch change event
+  // Note: switch binding in Vue passes value differently than bindchange in WXML
+  // In Vue @change, value is boolean (e.detail.value)
+  
+  // If we want to use the same logic, we just need to proceed.
+  
+  let list = common.deepCopy(doctorList.value, []);
+  let time = typeof timeActive.value == 'number' ? timeList.value[timeActive.value].RegDate : "";
+  
+  let queryData = {
+    workDateEnd: time || "",
+    workDateStart: time || "",
+    doctorCode: doctorItem.DoctorCode,
+    deptCode: doctorItem.DeptCode,
+    hosId: app.globalData.districtId || app.globalData.hosId,
+    WaitRule: '1'
+  };
+  
+  let res = await queryScheduleListApi(queryData);
+  
+  if (common.isNotEmpty(res)) {
+    let scheduleList: any[] = [];
+    res.map((item: any) => {
+      // 转换返回数据 小写转大写
+      item.hisQueryClinicSchedules = common.changeObj(item.hisQueryClinicSchedules);
+      item.hisQueryBaseDoctor = common.changeObj(item.hisQueryBaseDoctor);
+      
+      if (item.hisQueryClinicSchedules && item.hisQueryClinicSchedules.length > 0) {
+        // 判断是否多数据处理 星期 时间 上下午
+        item.hisQueryClinicSchedules.map((ele: any) => {
+          ele.WeekName = ele.RegDate == common.newDay() ? '今天' : common.weekDay(ele.RegDate, 1);
+          ele.RegDateDiy = ele.RegDate.substring(5);
+          ele.TimeSliceStr = ele.TimeSlice == 1 ? '上午' : ele.TimeSlice == 2 ? '下午' : '全天';
+        });
+        
+        // 判断如果超出6个隐藏
+        if (item.hisQueryClinicSchedules.length > 6) {
+          item.Data_1_Diy = item.hisQueryClinicSchedules.slice(0, 5);
+          item.showAllSchedu = false;
+        } else {
+          item.Data_1_Diy = item.hisQueryClinicSchedules;
+          item.showAllSchedu = true;
+        }
+        
+        scheduleList.push({
+          Check: item.hisQueryBaseDoctor.DeptCode == doctorItem.DeptCode ? true : false,
+          DeptName: item.hisQueryBaseDoctor.DeptName,
+          DeptCode: item.hisQueryBaseDoctor.DeptCode,
+          DoctorName: doctorItem.DoctorName,
+          DoctorCode: doctorItem.DoctorCode,
+          Data_1: item.hisQueryClinicSchedules,
+          Data_1_Diy: item.Data_1_Diy,
+          showAllSchedu: item.showAllSchedu,
+        });
+      }
+    });
+    
+    // 给当前查询的医生新加列表
+    list[doctorIndex].Scheduling = scheduleList;
+  }
+  
+  // 查询过的医生 不展示switch
+  list[doctorIndex].ShowDeptSwitch = true;
+  doctorList.value = list;
+};
+
+// 折叠列表
+const foldList = (doctorIndex: number, schedulIndex: number) => {
+  let list = [...doctorList.value];
+  list[doctorIndex].Scheduling[schedulIndex].Check = !list[doctorIndex].Scheduling[schedulIndex].Check;
+  doctorList.value = list;
+};
+
+</script>
+
+<style scoped>
+@import "@/pagesPatient/st1/static/css/yyghDoctorList.css";
+</style>

+ 0 - 75
pagesPatient/st1/business/yygh/yyghDoctorList/yyghDoctorList.wxml

@@ -1,75 +0,0 @@
-<view class="container {{dialogIsShow?'fixed':''}}" hidden="{{!showCon}}">
-  <view class="content">
-    <view class="userInfoTopFixe">
-      <view class="date_list" wx:if="{{serviceId != 009}}">
-        <view class="date_item date_item_hasList  date_item_all {{timeActive===''?'backgroundCustom':''}}" bindtap="timeClick" wx:if="{{pageConfig.hasAllSchedules}}">
-          全部
-        </view>
-        <view class="date_item date_item_hasList {{timeActive===index?'backgroundCustom':''}} {{item.HasSchedule != 1 && 'colorCustom_999'}}" wx:for="{{timeList}}" wx:key="index" bindtap="{{item.HasSchedule == 1 && 'timeClick'}}" data-item="{{item}}" data-index="{{index}}">
-          <text>{{item.WeekName}}</text>
-          <text class="month">{{item.RegDateNotYear}}</text>
-        </view>
-      </view>
-
-      <view class="nav">
-        <view class="nav_inner">
-          <view class="nav_tit_val">是否仅显示可约医生</view>
-          <switch class="public_switch" value="{{reducibleOnly}}" color="var(--dominantColor)" bindchange="switchChange"></switch>
-        </view>
-      </view>
-    </view>
-    <view class="doctor_list {{serviceId == 009 && 'doctor_list100'}}" wx:if="{{!showNoData}}">
-      <view class="doctor_item" wx:for="{{doctorList}}" wx:for-index="doctorIndex" wx:for-item="doctorItem"  wx:key="doctorIndex">
-        <view class="doctor_item_nav" bindtap="doctorInfoClick" data-item="{{doctorItem}}">
-          <view class="doctor_item_nav_img">
-            <image src="{{doctorItem.PhotoUrl || iconUrl.icon_doctor}}" mode="widthFix"></image>
-          </view>
-          <view class="doctor_item_nav_tit">
-            <view class="doctor_item_nav_subtit">
-              <text class="doctor_item_nav_subtit_val">{{doctorItem.DoctorName}}</text>
-              <text wx:if="{{doctorItem.DoctorTitle || doctorItem.Title}}" class="doctor_item_nav_subtit_txt">{{doctorItem.DoctorTitle||doctorItem.Title}}</text>
-            </view>
-            <view wx:if="{{doctorItem.Spec}}" class="doctor_item_nav_info">
-              {{doctorItem.Spec}}
-            </view>
-          </view>
-        </view>
-        <view class="scheduling_box" wx:for="{{doctorItem.Scheduling}}" wx:for-item="schedulItem" wx:for-index="schedulIndex" wx:key="schedulIndex">
-          <view class="scheduling_dept_box displayFlexBetween" data-doctorIndex="{{doctorIndex}}" data-schedulIndex="{{schedulIndex}}" bindtap="foldList">
-            <view class="scheduling_deptName_box displayFlexRow">
-              <view class="backgroundCustom "></view>
-              <text>{{schedulItem.DeptName}}</text>
-            </view>
-            <image class="arrow {{schedulItem.Check ? 'transform_rotate_90' : ''}}" src="{{iconUrl.icon_right}}"></image>
-          </view>
-          <view class="time_list" wx:if="{{schedulItem.Check}}">
-            <view class="time_item displayFlexCol {{(item.IsHalt==7 && item.WaitLeaveCount <= 0) || item.IsHalt==2?'time_item_stop':''}}" wx:for="{{schedulItem.showAllSchedu?schedulItem.Data_1:schedulItem.Data_1_Diy}}" wx:key="index" bindtap="toClinic" data-item="{{schedulItem}}" data-index="{{index}}" data-dataItem="{{item}}">
-              <view>{{item.RegDateDiy}}</view>
-              <view style="margin-top: 12rpx;">{{item.WeekName}} {{item.TimeSliceStr}}</view>
-              <image wx:if="{{item.IsHalt==7}}" class="time_item_img" src="{{iconUrl.full2}}"></image>
-              <image wx:if="{{item.IsHalt==2}}" class="time_item_img" src="{{iconUrl.stop}}"></image>
-              <image wx:if="{{item.IsHalt == 7 && item.WaitLeaveCount > 0}}" class="time_item_img" src="{{iconUrl.yyghWait}}"></image>
-            </view>
-            <view class="time_item colorCustom" bindtap="showAll" data-doctorIndex="{{doctorIndex}}" data-schedulIndex="{{schedulIndex}}" wx:if="{{schedulItem.Data_1.length > 6}}">{{schedulItem.showAllSchedu?'收起':'全部排班'}}</view>
-          </view>
-        </view>
-        <view class="other_dept_box" wx:if="{{!doctorItem.ShowDeptSwitch }}">
-          <view class="displayFlexRow border_top displayFlexBetween">
-            <text>本院所有科室排班</text>
-            <switch color="var(--dominantColor)" class="public_switch" data-index="{{doctorIndex}}" data-doctorItem="{{doctorItem}}" bindchange="queryScheduleList" />
-          </view>
-        </view>
-        <view class="other_dept_box displayFlexRow border_top" wx:if="{{doctorItem.Scheduling.length == 1 && doctorItem.ShowDeptSwitch}}">
-          <text class="non_schedul">暂无其他科室排班</text>
-        </view>
-      </view>
-    </view>
-    <view wx:else class="noData">
-      <noData value="{{noDataTip}}"></noData> 
-    </view>
-  </view>
-   <doctorInfo doctorInfoIsShow="{{doctorInfoIsShow}}" doctorInfo="{{doctorInfo}}"></doctorInfo>
-</view>
-
-<!-- AI数智客服入口-->
-<aiCustomerEntry currentUser="{{currentUser}}"></aiCustomerEntry>

+ 0 - 59
pagesPatient/st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor.js

@@ -1,59 +0,0 @@
-const app = getApp();
-import yygh from "../../../../config/api/yygh/index.js";
-import regeneratorRuntime from "../../../../../utils/runtime.js";
-import common from "../../../../../utils/common.js";
-import apiRootUrl from "../../../../../config/api.js";
-import { pagesPatientFn } from '@/utils';
-import icon from "../../../../../utils/icon.js";
-
-Page({
-  data: {
-    iconUrl:icon,
-    showNoData:false,//是否显示暂无数据
-    noDataTip:'暂无历史预约医生信息',//暂无数据提示信息
-    doctorList:[],//医生列表
-    currentUser:{}
-    
-  },
-  onLoad: function (options) {
-  },
-  onShow: function () {
-    this.main()
-  },
-  async main() {
-    let currentUser = app.globalData.currentUser
-    let result = [], showNoData=true;
-    let queryData = {
-      HosId: app.globalData.districtId || app.globalData.hosId,
-      QueryLocal: "1",
-      MemberIds: currentUser.memberId,
-    }
-    let resp = await yygh.queryHistoryBaseDoctor(queryData)
-    if(!common.isEmpty(resp)){
-      resp.map(item=>{
-        /**如果医生头像没有域名 添加域名 */
-        if (item.Url && item.Url.indexOf('http') == '-1') {
-          item.Url = apiRootUrl.ApiRootUrl + item.Url 
-        }
-        item.Url = item.Url.replace(/\\/g, '/')
-      })
-      result=resp;
-      showNoData=false
-    }
-    this.setData({
-      currentUser:currentUser,
-      doctorList:result,
-      showNoData: showNoData
-    })
-  },
-  /**
-   * 暂无数据点击返回
-   */
-  back(){
-    common.navigateBack(1)
-  },
-  goto(e){
-    pagesPatientFn.handleRouter(e,'yyghClinicMsg')
-  }
-
-})

+ 0 - 10
pagesPatient/st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor.json

@@ -1,10 +0,0 @@
-{
-  "usingComponents": {
-    "userInfo":"/pagesPersonal/st1/components/userInfo/userInfo",
-    "noData":"/pages/st1/components/noData/noData"
-  },
-  "componentPlaceholder": {
-    "userInfo": "view"
-  },
-  "navigationBarTitleText": "历史医生" 
-}

+ 106 - 0
pagesPatient/st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor.vue

@@ -0,0 +1,106 @@
+<template>
+  <view class="container">
+    <view class="content">
+      <view class="userInfoTopFixe">
+        <userInfo :userInfo="currentUser" type="member" bgClass="bgLinGra"></userInfo>
+      </view>
+      <view class="doctor_list" v-if="!showNoData">
+        <view class="doctor_item displayFlexLeft" v-for="(item, index) in doctorList" :key="index">
+          <view class="doctor_item_img">
+            <image :src="item.Url || iconUrl.icon_doctor" mode="widthFix"></image>
+          </view>
+          <view class="doctor_item_nav displayFlexLeft">
+            <view class="displayFlexBetween" style="width: 100%;">
+              <view class="doctor_item_nav_tit">
+                <view class="doctor_item_nav_subtit displayFlexLeft">
+                  <text class="doctor_item_nav_subtit_val">{{ item.DoctorName }}</text>
+                  <text class="doctor_item_nav_subtit_txt boderColorCustom_F08 colorCustom_F08">{{ item.DoctorTitle }}</text>
+                </view>
+                <text class="doctor_item_nav_subtit_dept">科室:{{ item.DeptName }}</text>
+              </view>
+              <view class="colorCustom boderColorCustom goBtn" @click="goto(item)">去预约</view>
+            </view>
+            <view class="doctor_item_info">擅长:{{ item.Spec || '-' }}</view>
+          </view>
+        </view>
+      </view>
+      <view v-else class="noData displayFlexCol">
+        <noData :value="noDataTip"></noData>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import { onLoad } from '@dcloudio/uni-app';
+import { common, pagesPatientFn } from '@/utils';
+import icon from '@/utils/icon';
+import { REQUEST_CONFIG } from '@/config';
+import { queryHistoryBaseDoctor } from '@/pagesPatient/service/yygh';
+import userInfo from '@/pagesPersonal/st1/components/userInfo/userInfo.vue';
+import noData from '@/pages/st1/components/noData/noData.vue';
+
+const app = getApp();
+
+const iconUrl = ref(icon);
+const showNoData = ref(false); // 是否显示暂无数据
+const noDataTip = ref('暂无历史预约医生信息'); // 暂无数据提示信息
+const doctorList = ref<any[]>([]); // 医生列表
+const currentUser = ref({});
+
+onLoad(() => {
+  main();
+});
+
+const main = async () => {
+  let cUser = app.globalData.currentUser;
+  let result: any[] = [];
+  let isShowNoData = true;
+  
+  let queryData = {
+    HosId: app.globalData.districtId || app.globalData.hosId,
+    QueryLocal: "1",
+    MemberIds: cUser.memberId,
+  };
+  
+  let resp = await queryHistoryBaseDoctor(queryData);
+  
+  if (!common.isEmpty(resp)) {
+    resp.map((item: any) => {
+      /**如果医生头像没有域名 添加域名 */
+      if (item.Url && item.Url.indexOf('http') == '-1') {
+        item.Url = REQUEST_CONFIG.BASE_URL + item.Url;
+      }
+      if (item.Url) {
+          item.Url = item.Url.replace(/\\/g, '/');
+      }
+    });
+    result = resp;
+    isShowNoData = false;
+  }
+  
+  currentUser.value = cUser;
+  doctorList.value = result;
+  showNoData.value = isShowNoData;
+};
+
+const goto = (item: any) => {
+  const mockEvent = {
+    currentTarget: {
+      dataset: {
+        item: item
+      }
+    }
+  };
+  pagesPatientFn.handleRouter(mockEvent, 'yyghClinicMsg');
+};
+
+const back = () => {
+  common.navigateBack(1);
+};
+</script>
+
+<style scoped>
+@import "@/pagesPatient/st1/static/css/yyghHistoryDoctor.css";
+</style>

+ 0 - 32
pagesPatient/st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor.wxml

@@ -1,32 +0,0 @@
-<view class="container">
-  <view class="content">
-    <view class="userInfoTopFixe">
-      <userInfo userInfo="{{currentUser}}" type="member" bgClass="bgLinGra"></userInfo>
-    </view>
-    <view class="doctor_list" wx:if="{{!showNoData}}">
-      <view class="doctor_item displayFlexLeft" wx:for="{{doctorList}}" wx:key="index">
-        <view class="doctor_item_img">
-          <image  src="{{item.Url||iconUrl.icon_doctor}}" mode="widthFix"></image>
-        </view>
-        <view class="doctor_item_nav displayFlexLeft ">
-          <view class="displayFlexBetween" style="width: 100%;">
-            <view class="doctor_item_nav_tit">
-              <view class="doctor_item_nav_subtit displayFlexLeft">
-                <text class="doctor_item_nav_subtit_val ">{{item.DoctorName}}</text>
-                <text class="doctor_item_nav_subtit_txt boderColorCustom_F08 colorCustom_F08">{{item.DoctorTitle}}</text>
-              </view>
-              <text class="doctor_item_nav_subtit_dept">科室:{{item.DeptName}}</text>
-            </view>
-            <view class="colorCustom boderColorCustom goBtn" bindtap="goto" data-item="{{item}}">去预约</view>
-          </view>
-          <view class="doctor_item_info">擅长:{{item.Spec || '-'}}</view>
-        </view>
-      </view>
-    </view>
-    <view wx:else class="noData displayFlexCol">
-      <noData value="{{noDataTip}}"></noData>
-    </view>
-  </view>
-  
-
-</view>

+ 1 - 1
pagesPatient/st1/components/doctorInfo/doctorInfo.vue

@@ -28,7 +28,7 @@
 </template>
 
 <script setup lang="ts">
-import { defineProps, defineEmits,ref } from 'vue';
+import { ref } from 'vue';
 import icon from '@/utils/icon';
 
 const iconUrl = ref(icon)

+ 1 - 1
pagesPatient/st1/components/doctorItemBox/doctorItemBox.vue

@@ -122,7 +122,7 @@
 
 <script setup lang="ts">
 import { ref } from 'vue';
-import common from '@/utils/common';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 import hosList from '@/pages/st1/components/hosList/hosList.vue';
 

+ 2 - 2
pagesPatient/st1/components/queueItem/queueItem.vue

@@ -71,8 +71,8 @@
 </template>
 
 <script setup lang="ts">
-import { ref, defineProps, watch, onMounted } from 'vue';
-import common from '@/utils/common';
+import { ref, watch, onMounted } from 'vue';
+import {common} from '@/utils';
 import icon from '@/utils/icon';
 import * as queue from '@/pagesPatient/service/queue/index';
 

+ 1 - 1
pagesPatient/st1/components/screening/screening.vue

@@ -301,7 +301,7 @@ const onResetScreen = () => {
 </script>
 
 <style lang="scss" scoped>
-@import "@/App.scss";
+// @import "@/App.scss";
 
 .font_weight {
   font-weight: bold;

+ 92 - 0
pagesPatient/st1/static/css/search.css

@@ -0,0 +1,92 @@
+
+
+  /* 搜索框 */
+
+.search {
+  position: fixed;
+  z-index: 2;
+  height: 110upx;
+  width: 100%;
+  padding: 0 30upx 20upx;
+  top: 0;
+  left: 0;
+  background-color: #fff;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+.search_box {
+  width: 100%;
+  margin-top: 10upx;
+  display: flex;
+  flex-direction: row;
+  justify-content: flex-start;
+  align-items: center;
+  position: relative;
+  z-index: 10;
+}
+
+.search_input_none {
+  width: 690upx;
+  height: 74upx;
+  border-radius: 50px;
+  font-size: 28upx;
+  color: #333 !important;
+  background: #f2f2f2;
+  padding-left: 65upx;
+  text-align: center;
+}
+
+.search_input {
+  width: 570upx;
+  height: 80upx;
+  border-radius: 50px;
+  font-size: 28upx;
+  color: #333 !important;
+  background: #F1F1F6;
+  margin-right: 24upx;
+  padding-left: 65upx;
+  padding-right: 85upx;
+}
+.search_icon {
+  width: 26upx;
+  height: 26upx;
+  position: absolute;
+  top: 33%;
+  left: 36%;
+}
+.search_icon_none {
+  left: 20upx;
+}
+.remove_icon {
+  width: 36upx;
+  height: 36upx;
+  position: absolute;
+  top: 28%;
+  right: 158upx;
+  z-index: 50;
+}
+.search_btn {
+  display: inline-block;
+  width: 100upx;
+  line-height: 56upx;
+  text-align: center;
+  font-size: 30upx;
+  font-family: PingFang SC;
+  margin-bottom: 28upx;
+}
+
+.search_confirm {
+  width: 0;
+  height: 68upx;
+  border-radius: 50px;
+  line-height: 68upx;
+  text-align: center;
+  transition: all 0.3s;
+  font-size: 0;
+}
+
+.search_confirm_active {
+  width: 128upx;
+  font-size: 28upx;
+}

+ 55 - 55
pagesPatient/st1/business/yygh/yyghDoctorList/yyghDoctorList.wxss → pagesPatient/st1/static/css/yyghDoctorList.css

@@ -1,7 +1,7 @@
 
 .date_list {
   background-color: #fff;
-  padding: 20rpx 6rpx 20rpx 30rpx;
+  padding: 20upx 6upx 20upx 30upx;
   white-space: nowrap;
   overflow: auto;
   -webkit-overflow-scrolling: touch;
@@ -10,55 +10,55 @@
 }
 
 .date_item {
-  width: 140rpx;
-  height: 144rpx;
+  width: 140upx;
+  height: 144upx;
   display: inline-flex;
   flex-direction: column;
   justify-content: center;
   align-items: center;
   background: #F1F1F6;
   color: #222326;
-  border-radius: 24rpx;
-  margin-right:24rpx;
-  font-size: 32rpx;
+  border-radius: 24upx;
+  margin-right:24upx;
+  font-size: 32upx;
   vertical-align: middle;
 }
 .month {
-  margin-top: 10rpx;
+  margin-top: 10upx;
 }
 
 .date_item_all {
-  font-size: 32rpx;
+  font-size: 32upx;
 }
 
 .doctor_list {
-  padding: 0 30rpx;
+  padding: 0 30upx;
   display: inline-block;
   width: 100%;
-  margin-top: 290rpx;
+  margin-top: 290upx;
 }
 .doctor_list.doctor_list100{
-  margin-top: 100rpx;
+  margin-top: 100upx;
 }
 
 .doctor_item {
   background: #fff;
-  border-radius: 24rpx;
-  margin: 30rpx 0;
-  padding: 20rpx 30rpx 32rpx;
+  border-radius: 24upx;
+  margin: 30upx 0;
+  padding: 20upx 30upx 32upx;
 }
 
 .doctor_item_nav {
   display: flex;
   position: relative;
-  padding: 17rpx 0;
+  padding: 17upx 0;
 }
 
 .doctor_item_nav_img {
-  width: 88.3rpx;
-  height: 88.3rpx;
+  width: 88.3upx;
+  height: 88.3upx;
   border-radius: 50%;
-  margin-right: 25rpx;
+  margin-right: 25upx;
   overflow: hidden;
 }
 
@@ -67,34 +67,34 @@
 }
 
 .doctor_item_nav_subtit_val {
-  font-size: 32rpx;
+  font-size: 32upx;
   font-family: PingFang SC;
   font-weight: 800;
   color: #222326;
-  margin-right: 12rpx;
+  margin-right: 12upx;
 }
 
 .doctor_item_nav_subtit_txt {
-  height: 36rpx;
-  line-height: 28rpx;
-  font-size: 24rpx;
+  height: 36upx;
+  line-height: 28upx;
+  font-size: 24upx;
   font-family: PingFang SC;
   color: var(--auxiliaryColor);
-  padding: 0rpx 7rpx;
+  padding: 0upx 7upx;
   position: relative;
   display: inline-block;
   background: #FFFBF4;
-  border: 1rpx solid #FADAB2;
+  border: 1upx solid #FADAB2;
 
 }
 
 .doctor_item_nav_info {
-  font-size: 28rpx;
+  font-size: 28upx;
   font-family: Source Han Sans CN;
   font-weight: 500;
   color: #62626D;
-  line-height: 40rpx;
-  margin-top: 10rpx;
+  line-height: 40upx;
+  margin-top: 10upx;
   overflow: hidden;
   text-overflow: ellipsis;
   display: -webkit-box;
@@ -110,13 +110,13 @@
 }
 
 .time_item {
-  margin: 23rpx 2% 0 0;
+  margin: 23upx 2% 0 0;
   width: 32%;
-  height: 110rpx;
-  line-height: 110rpx;
+  height: 110upx;
+  line-height: 110upx;
   background: #F1F1F6;
-  border-radius: 20rpx;
-  font-size: 28rpx;
+  border-radius: 20upx;
+  font-size: 28upx;
   color: #222326;
   text-align: center;
   position: relative;
@@ -125,18 +125,18 @@
   margin-right: 0;
 }
 .nav {
-  height: 100rpx;
-  padding:0 30rpx;
+  height: 100upx;
+  padding:0 30upx;
   background-color: #fff;
-  border-radius: 0 0 30rpx 30rpx;
-  font-size: 30rpx;
+  border-radius: 0 0 30upx 30upx;
+  font-size: 30upx;
   color: #43434A;
   position: relative;
   z-index: 2;
 }
 
 .nav_val {
-  margin-right: 30rpx;
+  margin-right: 30upx;
 }
 
 .nav_inner {
@@ -152,14 +152,14 @@
 
 
 .bottom {
-  width: 16rpx;
-  height: 16rpx;
-  margin-left: 16rpx;
+  width: 16upx;
+  height: 16upx;
+  margin-left: 16upx;
 }
 
 .time_item_img {
-  width: 61rpx;
-  height: 54rpx;
+  width: 61upx;
+  height: 54upx;
   position: absolute;
   right: 0;
   top: 0;
@@ -170,18 +170,18 @@
 
 
 .scheduling_dept_box {
-  margin: 24rpx 0 12rpx;
+  margin: 24upx 0 12upx;
 }
 
 .scheduling_deptName_box view {
-  width: 14rpx;
-  height: 14rpx;
-  border-radius: 14rpx;
-  margin-right: 20rpx;
+  width: 14upx;
+  height: 14upx;
+  border-radius: 14upx;
+  margin-right: 20upx;
 }
 
 .scheduling_deptName_box text {
-  font-size: 32rpx;
+  font-size: 32upx;
   color: #333;
 }
 
@@ -204,20 +204,20 @@
 
 .other_dept_box view {
   width: 100%;
-  padding-top: 28rpx ;
-  margin-top: 23rpx;
+  padding-top: 28upx ;
+  margin-top: 23upx;
   box-sizing: border-box;
   justify-content: space-between;
 }
 
 .other_dept_box view text {
-  font-size: 32rpx;
+  font-size: 32upx;
   color: #333;
 }
 
 .non_schedul {
-  padding-top: 30rpx;
+  padding-top: 30upx;
   box-sizing: border-box;
-  font-size: 30rpx;
+  font-size: 30upx;
   color: #999;
-}
+}

+ 24 - 24
pagesPatient/st1/business/yygh/yyghHistoryDoctor/yyghHistoryDoctor.wxss → pagesPatient/st1/static/css/yyghHistoryDoctor.css

@@ -1,31 +1,31 @@
 
 .doctor_list {
-  padding: 230rpx 30rpx 0;
+  padding: 230upx 30upx 0;
   display: inline-block;
   width: 100%;
 }
 
 .doctor_item {
   background: rgba(255, 255, 255, 1);
-  box-shadow: 0px 0px 40rpx 0px rgba(0, 0, 0, 0.06);
-  margin-bottom: 30rpx;
-  padding: 20rpx 30rpx;
+  box-shadow: 0px 0px 40upx 0px rgba(0, 0, 0, 0.06);
+  margin-bottom: 30upx;
+  padding: 20upx 30upx;
   position: relative;
-  border-radius: 24rpx;
+  border-radius: 24upx;
 }
 
 .doctor_item_nav {
   display: flex;
   align-items: flex-start;
-  padding: 20rpx 0;
+  padding: 20upx 0;
   width: 79%;
 }
 
 .doctor_item_img {
-  width: 110rpx;
-  height: 103rpx;
+  width: 110upx;
+  height: 103upx;
   border-radius: 50%;
-  margin-right: 23rpx;
+  margin-right: 23upx;
   overflow: hidden;
 }
 
@@ -34,30 +34,30 @@
 }
 
 .doctor_item_nav_subtit_val {
-  font-size: 32rpx;
+  font-size: 32upx;
   font-family: Source Han Sans CN;
   font-weight: 500;
   color: #222326;
-  margin-right: 20rpx;
+  margin-right: 20upx;
 }
 
 .doctor_item_nav_subtit_txt {
-  font-size: 22rpx;
+  font-size: 22upx;
   font-family: PingFang SC;
   background: #FFFBF4;
-  border: 1rpx solid ;
-  border-radius: 6rpx;
-  padding: 7rpx 10rpx;
+  border: 1upx solid ;
+  border-radius: 6upx;
+  padding: 7upx 10upx;
 }
 .doctor_item_nav_subtit_dept{
-  font-size: 26rpx;
+  font-size: 26upx;
   font-family: PingFang SC;
   color: #222326;
-  line-height: 65rpx;
+  line-height: 65upx;
 }
 
 .doctor_item_info {
-  font-size: 26rpx;
+  font-size: 26upx;
   font-family: PingFang SC;
   color: #8A8A99;
   overflow: hidden;
@@ -66,12 +66,12 @@
   width: 100%;
 }
 .goBtn{
-  width: 132rpx;
-  height: 60rpx;
-  line-height: 58rpx;
+  width: 132upx;
+  height: 60upx;
+  line-height: 58upx;
   border: 1px solid;
-  border-radius: 30rpx;
+  border-radius: 30upx;
   text-align: center;
-  font-size: 26rpx;
+  font-size: 26upx;
   font-family: PingFang SC;
-}
+}

+ 14 - 3
uni_modules/mp-html/components/mp-html/parser.js

@@ -79,8 +79,19 @@ const tagSelector={}
 let windowWidth, system
 // #ifdef MP-WEIXIN
 if (uni.canIUse('getWindowInfo')) {
-  windowWidth = uni.getWindowInfo().windowWidth
-  system = uni.getDeviceInfo().system
+  // 兼容低版本基础库:getDeviceInfo 可能不存在,避免后续调用字符串方法报错
+  const winInfo = typeof uni.getWindowInfo === 'function' ? uni.getWindowInfo() : null
+  windowWidth = (winInfo && winInfo.windowWidth) ? winInfo.windowWidth : uni.getSystemInfoSync().windowWidth
+  let sysStr = ''
+  if (typeof uni.getDeviceInfo === 'function') {
+    const devInfo = uni.getDeviceInfo()
+    sysStr = devInfo && devInfo.system ? devInfo.system : ''
+  }
+  if (!sysStr) {
+    const sysInfo = uni.getSystemInfoSync()
+    sysStr = sysInfo && sysInfo.system ? sysInfo.system : ''
+  }
+  system = typeof sysStr === 'string' ? sysStr : String(sysStr || '')
 } else {
 // #endif
   const systemInfo = uni.getSystemInfoSync()
@@ -1188,7 +1199,7 @@ Parser.prototype.onText = function (text) {
   node.text = decodeEntity(text)
   if (this.hook(node)) {
     // #ifdef MP-WEIXIN
-    if (this.options.selectable === 'force' && system.includes('iOS') && !uni.canIUse('rich-text.user-select')) {
+    if (this.options.selectable === 'force' && typeof system === 'string' && system.includes('iOS') && !uni.canIUse('rich-text.user-select')) {
       this.expose()
     }
     // #endif

+ 6 - 3
utils/index.ts

@@ -1,8 +1,11 @@
 // import { common } from '@kasite/uni-app-base/utils';
 import { useIsToAuthPage, useGetDefaultMember } from '../hook';
 
-import { common as baseCommon, constant, QRCode, imgCompress, getLessLimitSizeImage } from '@kasite/uni-app-base/utils';
-
+import { common as baseCommon, constant, QRCode, imgCompress, getLessLimitSizeImage, } from '@kasite/uni-app-base/utils';
+import publicFn from './publicFn';
+import pagesPatientFn from './pagesPatientFn';
+import getState from './getState';
+	
 const common = {
 	...baseCommon,
 	/** 脱敏处理 */
@@ -23,7 +26,7 @@ const common = {
 	}
 };
 
-export { common, constant, QRCode, imgCompress, getLessLimitSizeImage, pagesPatientFn, getState };
+export { common, constant, QRCode, imgCompress, getLessLimitSizeImage, pagesPatientFn, getState, publicFn };
 
 export const menuClick = async (e, _this, skipWay = 'navigateTo') => {
 	let itemParent = e.currentTarget ? e.currentTarget.dataset.itemParent : {};

+ 978 - 0
utils/publicFn.js

@@ -0,0 +1,978 @@
+/**
+ * 页面公用逻辑函数
+ */
+import { common } from '@kasite/uni-app-base/utils';
+import icon from './icon.js';
+import { request } from '@kasite/uni-app-base';
+import { REQUEST_CONFIG } from '@/config';
+
+// Helper to simulate old base API return structure
+const callApi = async (url, data) => {
+  try {
+    const resData = await request.doPost(`${REQUEST_CONFIG.BASE_URL}${url}`, data);
+    return { resp: resData.Data, resData };
+  } catch (e) {
+    console.error('API Call Error', url, e);
+    return { resp: null, resData: { RespCode: -1 } };
+  }
+};
+
+const app = getApp();
+
+export default {
+  // 判断app状态进行跳转
+  async judgeAppStatus() {
+    const {
+      fixedAppjsGlobalData
+    } = uni.getStorageSync("frontEndConfig")
+    const {
+      status,
+      content
+    } = await callApi('wsgw/basic/basicApi/GetAppStatus/callApiJSON.do', {
+      appId: fixedAppjsGlobalData?.appId
+    }).then(r => r.resp || {});
+    
+    switch (status) {
+      case "maintain":
+        uni.reLaunch({
+          url: `/pages/st1/business/errorPage/maintain/maintain?content=${content}`,
+        });
+        break;
+      case "offline":
+        uni.reLaunch({
+          url: "/pages/st1/business/errorPage/offline/offline",
+        });
+        break;
+      default:
+        break;
+    }
+  },
+  /**
+   * 首页 更多 个人中心  菜单点击 
+   */
+  async menuClick(e, _this, skipWay = 'navigateTo') {
+    let itemParent = e.currentTarget ? e.currentTarget.dataset.itemParent : {};
+    let item = e.currentTarget ? e.currentTarget.dataset.item : e;
+    let url = item.Url;
+    // 判断为分院区
+    if (getApp().globalData.hasDistrict && item.MenuName == "预约挂号") {
+      url = `/pagesPatient/st1/business/otherService/hospitalDistrict/hospitalDistrict`
+    }
+    /**判断是否使用 */
+    if ((itemParent && itemParent.IsUse && itemParent.IsUse != '1') || item.IsUse && item.IsUse != '1') {
+      url = `/pages/st1/business/otherService/building/building`
+      common.goToUrl(url)
+      return;
+    }
+    // 当日挂号需要判断距离
+    if (item.MenuName == "当日挂号") {
+      try {
+        const limitDistance = getApp().globalData.config.pageConfiguration.signInList_config.signDistance || 1; // 判断半径(取签到距离配置)
+        await this.getHospitalLocationDistance(limitDistance);
+      } catch (err) {
+        await new Promise((resolve) => {
+          common.showModal('需到院后才能挂当日号,且不支持无就诊卡进行挂号操作', resolve, {
+            title: '温馨提示'
+          });
+        })
+      }
+    }
+
+    /**来院导航 */
+    if (item.MenuName == '来院导航') {
+      this.getLocation()
+      return;
+    }
+    /**跳转小程序 */
+    if (item.AppId) {
+      uni.navigateToMiniProgram({
+        appId: item.AppId,
+        path: item.Url
+      })
+      return;
+    }
+    /**判跳转第三方地址 */
+    if (url.startsWith('https')) {
+      common.goToUrl(`/pages/st1/business/h5/h5?url=${encodeURIComponent(url)}`)
+      return;
+    }
+    /**如果有二级菜单页 */
+    if (!common.isEmpty(item.Children)) {
+      let queryBean = JSON.stringify(item)
+      url = `${item.Url}`
+      /**queryBena太长无法传值  赋值给globalData */
+      getApp().globalData.selectUrl_x = queryBean;
+    }
+    /**
+     * 以下菜单 判断是否有就诊人 没有则进入添加页面 
+     */
+    let needMemberMenu = [
+      'rechargeMoney', // 充值缴费
+      'reportIndex', // 报告查询
+      'appointmentRecord', // 预约记录
+      'outpatientCosts', // 门诊清单
+      'hospitalCosts', // 住院清单
+      'cardRecord', // 门诊记录
+      'hosRecord', // 住院记录
+      'supplement', // 互联网医院提交咨询
+      'enquireList', // 互联网医院咨询记录
+      'doctorLike', // 互联网医院关注医生
+      'signInList', // 在线签到
+      'queueList', // 候诊查询
+      'orderPayment', // 门诊结算
+      "prescriptionList", // 当日处方
+      "paymentRecord", // 缴费记录
+      "personalCenter", // 个人中心
+      "continuationList", // 在线续方
+      "drugCredentials", // 取药凭证
+      "settlementRecord", // 结算记录
+      "waitRecord", // 候补记录
+      "dischargeMedication", // 出院带药
+      "home", // 我的随访
+      "chat-room", // AI智能就医助手
+      "topUpRecord", //充值记录
+      "newPrescriptionList", //当日处方2.0
+      "prescriptionRecipe", //处方取药2.0
+      "medicalTech", // 医技预约
+      "outpatientRefund", //在线退费
+      "selfProject", // 自助开单
+      "mdtList", // MDT列表
+      "recordList", // MDT记录
+      "diseaseIndex", // 罕见病
+    ];
+
+    let has = false;
+    for (let i of needMemberMenu) {
+      if (url.indexOf(i) != '-1') {
+        has = true;
+        break;
+      }
+    }
+    if (has) {
+      // 是否需要跳转授权页
+      if (this.isToAuthPage()) {
+        return;
+      }
+      /**如果当前menu在上面数组中 判断是否有就诊人 有就诊人根据条件判断是否需要就诊卡、住院号、授权信息 
+       * 不满足条件跳转到相应添加就诊卡或添加住院号页面
+       */
+      if (await this.toAddMemberOrNot(url)) {
+        return
+      }
+    }
+    common.goToUrl(url, {
+      skipWay: skipWay
+    })
+  },
+  /**
+   * 是否需要跳转授权页
+   */
+  isToAuthPage() {
+    // 判断小程序登录返回的wechatOpenid是否为null,null没有关注公众号,需要跳转授权页面进行授权处理
+    if (uni.getStorageSync('wechatOpenid') === null && getApp().globalData.officialAuthOn) {
+      common.goToUrl(`/pages/st1/business/h5/h5?type=0`, {
+        skipWay: 'redirectTo'
+      })
+      return true;
+    }
+    // 判断没有获取登录Account信息
+    if(common.isEmpty(getApp().globalData.userAccount)){
+      this.isLoginAccount()
+      return true;
+    }
+    return false
+  },
+  /**
+   * 判断当前是否有就诊人 没有则前往添加页面
+   * 返回url 或 undefined
+   */
+  async toAddMemberOrNot(url) {
+    let cardType = '1'
+    /**如果支持无卡预约 以下菜单不判断是否有就诊卡:挂号记录 在线签到 结算记录*/
+    if (getApp().globalData.withoutCard) {
+      let needCardArr = ['appointmentRecord', 'signInList', "settlementRecord"]
+      for (let i of needCardArr) {
+        if (url.indexOf(i) != '-1') {
+          cardType = ''
+          break;
+        }
+      }
+    }
+
+
+    /**以下菜单需要住院号:住院充值 住院报告 住院清单 住院记录 出院带药*/
+    let needHosArr = ['rechargeMoney?pageType=zyjf', 'reportIndex?queryType=2', 'hospitalCosts', 'hosRecord', "dischargeMedication"]
+    for (let i of needHosArr) {
+      if (url.indexOf(i) != '-1') {
+        cardType = '14'
+        break;
+      }
+    }
+    let member = await this.getDefaultMember({
+      isKeepPage: true,
+      cardType: cardType,
+      url: url
+    });
+
+    if (common.isEmpty(member)) {
+      // 判断如果是不全等于null 是跳转添加界面 ,因如果全等于null安卓机跳转中间件
+      if (member !== null) {
+        getApp().globalData.toUrl = url;
+        getApp().globalData.cardType = cardType;
+        common.goToUrl(`/pagesPersonal${uni.getStorageSync('wx_Slb')?'Slb':''}/st1/business/patientManagement/addMember/addMember`)
+      }
+      return true
+    }
+    return false
+
+  },
+  /**
+   * 获取并全局默认操作人
+   * 默认卡号可以为空 默认获取报告单
+   * url(保留要跳转的页面)
+   * cardType(查询类型) 1查询就诊卡 14查询住院号 空查询就诊人
+   * isKeepPage(是否保留选择界面)
+   */
+  async getDefaultMember(data = {}) {
+    getApp().globalData.cardType = null
+    let member = {}
+    let defaultInfo = await this.getMember('defaultInfo', data.cardType)
+    if (!common.isEmpty(defaultInfo)) {
+      member = await this.currentUsersFilter(defaultInfo, data.cardType)
+      // 判断返回为空 或者 要查询到的是有卡类型的,当时过滤时返回的是没有的卡号的
+      if (common.isEmpty(member) || (common.isNotEmpty(data.cardType) && common.isEmpty(member.cardNo))) {
+        if (common.isNotEmpty(data.url)) {
+          getApp().globalData.toUrl = data.url;
+        }
+        let type = data.cardType == 1 ? 'card' : data.cardType == 14 ? 'hospital' : 'member'
+        let skipWay = data.isKeepPage ? 'navigateTo' : 'redirectTo'
+        common.goToUrl(`/pagesPersonal${uni.getStorageSync('wx_Slb')?'Slb':''}/st1/business/patientManagement/selecteCardOrHos/selecteCardOrHos?type=${type}`, {
+          skipWay: skipWay
+        })
+        return null
+      }
+    }
+    getApp().globalData.currentUser = member
+    return member
+  },
+  /**
+   * 如果toUrl有值 即为添加就诊卡后跳转进toUrl页面 或 cardDeleted为true时(点击过删除按钮)
+   * 需要判断卡列表是否为空 为空返回上一页
+   * _this 当前调用页面
+   */
+  async cardListIsEmpty(cardType, _this) {
+    if (getApp().globalData.toUrl) {
+      getApp().globalData.toUrl = ""
+      let member = await this.getDefaultMember({
+        cardType: cardType,
+      });
+      if (common.isEmpty(member)) {
+        common.showModal(`该功能需要添加就诊卡`, () => {
+          common.navigateBack(1)
+        })
+        return true;
+      }
+    }
+    return false;
+  },
+  // cardType (type为获取默认操作人,才有效果,1:获取默认人下默认就诊卡;14:取默认人下默认住院号)
+  async getMember(type = 'memberList', cardType = 1) {
+    // type 值
+    //   memberList: 查询就诊人列表,仅返回就诊人列表
+    //   cardList:   查询就诊人列表并循环查询卡列表,返回所有就诊人下的所有卡
+    //   defaultList: 查询就诊人列表,返回所有人列表,如果有默认就诊人就返回默认就诊人的就诊卡,如果没有就选第0条
+    //   defaultInfo: 获取默认人下的所有卡,搭配cardType并过滤不是默认卡,仅返回默认cardTyp类型组合的一个对象
+    return new Promise(async (resolve, reject) => {
+      let resp = await uni.getStorageSync('memberList') || []
+      let memberList = []
+      let currentUser = {}
+      if (!resp.length && getApp().globalData.userAccount) {
+        await this.preserMember()
+        resp = uni.getStorageSync('memberList')
+      }
+      if (common.isNotEmpty(resp)) {
+        memberList = resp
+        // 判断为获取默认就诊人
+        if (type == 'defaultInfo') {
+          let memberLists = memberList.filter(item => item.userMemberList[0].isDefaultMember == 1)
+          // 判断过滤默认操作人
+          if (common.isNotEmpty(memberLists)) {
+            currentUser = memberLists[0]
+          } else {
+            // 没有默认操作人查询人列表第一条
+            currentUser = memberList[0]
+          }
+          if (common.isNotEmpty(cardType)) {
+            let resp = await this.queryMemberCardList_V3(currentUser.memberId)
+            if (common.isNotEmpty(resp)) {
+              currentUser.data_1 = resp
+            }
+          }
+          resolve(currentUser)
+        }
+        // 判断为获取默认列表 返回所有人列表,如果有默认就诊人就返回默认就诊人的就诊卡,如果没有就选第0条
+        if (type == 'defaultList') {
+          let memberListIndex = 0
+          let userInfo = memberList[memberListIndex]
+          memberList.forEach((item, index) => {
+            if (item.userMemberList[0].isDefaultMember == 1) {
+              userInfo = item
+              memberListIndex = index
+            }
+          })
+          let resp = await this.queryMemberCardList_V3(userInfo.memberId)
+          if (common.isNotEmpty(resp)) {
+            memberList[memberListIndex].data_1 = resp
+          }
+          resolve(memberList)
+        }
+        // 判断为获取所有人下所有卡列数据
+        if (type == 'cardList') {
+          for (var item of memberList) {
+            let resp = await this.queryMemberCardList_V3(item.memberId)
+            if (common.isNotEmpty(resp)) {
+              item.Data_1 = resp
+            } else {
+              item.Data_1 = []
+            }
+          }
+        }
+        resolve(memberList)
+      } else {
+        resolve([])
+      }
+    })
+  },
+  // 获取就诊人下的his卡信息
+  async queryMemberCardList_V3(memberId) {
+    return new Promise(async (resolve, reject) => {
+      let querData = {
+        hosId: getApp().globalData.hosId,
+        memberId: memberId,
+        cardNoFormatDesensitization: "false"
+      }
+      let {
+        resp,
+        resData
+      } = await callApi('wsgw/accountMember/api/QueryMemberCardList_V3/callApiJSON.do', querData)
+      if (resData.RespCode == 10000 && common.isNotEmpty(resp)) {
+        resolve(resp)
+      } else {
+        resolve([])
+      }
+    })
+  },
+  // 过滤使用人信息
+  async currentUsersFilter(currentUsers, cardType) {
+    return new Promise(async (resolve, reject) => {
+      let currentUser = {}
+      let cardUser = {}
+      // 判断存在数据进行过滤
+      if (currentUsers.data_1) {
+        let cardDataList = []
+        for (var item of currentUsers.data_1) {
+          if (item.cardType == cardType) {
+            cardDataList.push(item)
+          }
+          if (item.isDefault == 1 && item.cardType == cardType) {
+            cardUser = item
+          }
+        }
+        if (common.isEmpty(cardUser)) {
+          cardUser = cardDataList[0]
+        }
+        if (common.isNotEmpty(cardUser)) {
+          currentUser = common.mergeObject(currentUsers, cardUser)
+        } else {
+          if (common.isEmpty(cardType)) {
+            currentUser = currentUsers
+          }
+        }
+      } else if (common.isNotEmpty(currentUsers)) {
+        currentUser = currentUsers
+      }
+      resolve(currentUser)
+    })
+  },
+  //查询并保存全局所有就诊人数据信息 (就诊人改变后都要重新调用,并保存一遍)
+  async preserMember() {
+    let queryData = {
+      isCache: false,
+      isEncrypt: true,
+      hosId: getApp().globalData.districtId || getApp().globalData.hosId,
+      openid: uni.getStorageSync('openid'),
+    }
+    let {
+      resp,
+      resData
+    } = await callApi('wsgw/accountMember/api/QueryBaseMemberList_V3/callApiJSON.do', queryData)
+    // 请求成功且有返回值保存全局就诊人数据列表
+    getApp().globalData.currentUser = null;
+    if (resData.RespCode == 10000 && common.isNotEmpty(resp)) {
+      uni.setStorageSync('memberList', resp)
+    } else {
+      // 否则保存空
+      uni.setStorageSync('memberList', null)
+    }
+  },
+  /**
+   * 倒计时
+   */
+  countDown(timer) {
+    // This assumes this context has setData (Options API or legacy Page)
+    if (this.data && this.data.seconds <= 0) {
+      this.setData({
+        seconds: 120
+      })
+    }
+    let seconds = this.data ? this.data.seconds : 0;
+    if (timer) {
+      clearInterval(timer)
+    }
+    timer = setInterval(() => {
+      if (seconds > 0) {
+        seconds--
+      } else {
+        seconds = 0
+        clearInterval(timer)
+      }
+      if (this.setData) {
+        this.setData({
+          seconds
+        })
+      }
+    }, 1000)
+  },
+  /**
+   * 来院导航
+   */
+  getLocation() {
+    let hospitalInfo = getApp().globalData.hospitalInfo;
+    let data = {
+      latitude: Number(hospitalInfo.Wd), //要去的纬度-地址
+      longitude: Number(hospitalInfo.Jd), //要去的经度-地址
+      name: hospitalInfo.HospitalAlias,
+      address: hospitalInfo.HospitalAddress
+    }
+    this.locationIsauthorization('gcj02', () => {
+      uni.openLocation(data)
+    })
+  },
+  /**
+   * 地理位置是否授权
+   */
+  locationIsauthorization(type, callBack) {
+    uni.getLocation({
+      type: type,
+      success: function (res) {
+        callBack(res)
+      },
+      fail: function (err) {
+        if (err.errMsg.includes('1')) {
+          common.showToast('访问个人地址失败,请查看是否开启地理位置权限')
+        } else {
+          common.showModal('位置信息获取失败,请打开应用权限', () => {
+            uni.openSetting({
+              success: function (res) {
+                res.authSetting['scope.userLocation'];
+              }
+            });
+          }, {
+            cancelText: '取消',
+            confirmText: '打开'
+          })
+        }
+      }
+    });
+  },
+  // 判断当前业务页面用户是否需要授权
+  isPageUserAuth(currentUser, _this) {
+    return new Promise(async (resolve, reject) => {
+      // 返回值 
+      let has = false
+      // 获取统一要授权的业务页面配置信息
+      let authBusinessPageObj = getApp().globalData.config.pageConfiguration.currency_config.authBusinessPage
+      // 获取当前业务页面地址
+      let pages = getCurrentPages()
+      let currentPage = pages[pages.length - 1]
+      let businessPageUrls = currentPage.route.split("/");
+      let pageObjName = businessPageUrls[businessPageUrls.length - 1]
+      // 获取当前业务页面配置的授权信息
+      let authLevel = authBusinessPageObj[pageObjName]
+      // 判断 authLevel不为空且当前用户信息小余当前业务需要授权的业务等级,代表当前业务页面需要先授权
+      if (common.isNotEmpty(authLevel)) {
+        let res = await callApi('wsgw/accountMember/api/QueryAccountUserLevel/callApiJSON.do', {
+          openId: uni.getStorageSync('openid'),
+          memberId: currentUser.memberId,
+        }).then(r => r.resp)
+        
+        has = res && res[0] && res[0].accountUserLevel < authLevel ? true : false
+      }
+      _this.setData({
+        authorize: has,
+        authLevel: authLevel
+      })
+      resolve(has)
+    })
+  },
+  /**
+    判断当前用户是否被本人授权 
+    currentUser:查询的用户
+    checkKey :{
+      Book: 预约挂号授权
+      Charge: 充值缴费授权
+    }
+    isShowMode: 是否弹窗提示
+  */
+  isCurrentUserAuth(currentUser, checkKey, isShowMode) {
+    return new Promise(async (resolve, reject) => {
+      // 判断如果是本人,不读取授权认证,皆为通过
+      if (currentUser.memberType == 1) {
+        resolve(false)
+      } else {
+        // 没有accountSn就代表没有验证过本人,不做授权判断
+        if (common.isEmpty(currentUser.accountSn)) {
+          resolve(false)
+        }
+        //否者就不是本人,查询授权数据信息,判断是否授权
+        let {
+          resp,
+          resData
+        } = await callApi('wsgw/accountMember/api/QueryAccountAuthDetail/callApiJSON.do', {
+          accountSn: currentUser.accountSn,
+          memberId: currentUser.memberId,
+          seniorOpen: 1
+        })
+        let has = false
+        if (resData.RespCode == '10000') {
+          let authInfo = resp[0]
+          // 判断当前用户 已开 启高级授权
+          if (authInfo.SeniorOpen == 1) {
+            // 判断 不在 授权时限内
+            if (common.isNotEmpty(authInfo.SeniorTime) && common.getTowNumDay(authInfo.SeniorTime, common.getDate()) < 0) {
+              has = true
+            }
+          } else {
+            if (authInfo[checkKey + 'Open'] == 0 || (authInfo[checkKey + 'Open'] == 1 && common.isNotEmpty(authInfo[checkKey + 'Time']) && common.getTowNumDay(authInfo[checkKey + 'Time'], common.getDate()) < 0)) {
+              // 判断普通授权,根据
+              has = true
+            }
+          }
+          if (has && isShowMode) {
+            common.showModal('当前亲友成员未被授权,请联系本人授权后,在代为操作')
+          }
+          resolve(has)
+        } else {
+          resolve(false)
+        }
+      }
+    })
+  },
+  // 是否登陆账号
+  isLoginAccount() {
+    const userAccount = getApp().globalData.userAccount || {}
+    if (!Object.keys(userAccount).length) {
+      // 未登陆账号,跳转到登陆页面
+      common.goToUrl('/pages/st1/business/login/authorization/authorization')
+    }
+  },
+  // OpenID 获取账号信息
+  async getAccountByOpenid(clear) {
+    const userAccout = getApp().globalData.userAccount
+    if (userAccout && !clear) {
+      return userAccout
+    }
+    if (userAccout && userAccout.keep) {
+      delete userAccout.keep
+      return userAccout
+    }
+    const {
+      resp
+    } = await callApi('wsgw/accountMember/api/GetLastLoginAccount/callApiJSON.do', {
+      openId: uni.getStorageSync("openid")
+    })
+    if (resp) {
+      getApp().globalData.userAccount = resp.length ? resp[0] : null
+    }
+  },
+  // 手机号 获取账号信息,没有账号信息则默认新增
+  async getAccountByPhone(code) {
+    const {
+      fixedAppjsGlobalData,
+      webUiDiy
+    } = uni.getStorageSync("frontEndConfig")
+    // 获取账号信息
+    const openid = uni.getStorageSync("openid")
+    const {
+      resp
+    } = await callApi('wsgw/accountMember/api/CreateAccount/callApiJSON.do', {
+      openId: openid,
+      code,
+      smallProConfigKey: fixedAppjsGlobalData?.configKey,
+    })
+    if (!resp) return
+    // 如果没有最后一次登录信息,直接跳转
+    // 或者没开短信验证,则不做验证,直接返回前面的页面
+    // 或者openId 一直
+    if (!resp[0].lastLoginInfo || !webUiDiy.pageConfiguration?.login_config?.messageSys || openid == resp[0].lastLoginInfo.openId) {
+      getApp().globalData.userAccount = Object.assign({}, resp[0], {
+        keep: true
+      })
+      uni.navigateBack()
+      return
+    }
+    // 对比OpenId,不一致则跳转到短信登录验证页面
+    if (openid != resp[0].lastLoginInfo.openId) {
+      uni.redirectTo({
+        url: `/pages/st1/business/login/verify/verify?accountSn=${resp[0].accountSn}&phone=${resp[0].mobile}`
+      })
+    }
+  },
+  async loadViewMenu() {
+    const { resp } = await callApi('wsgw/basic/basicApi/CacheGetValue/callApiJSON.do', {
+      key: 'smallproViewMenu'
+    })
+    if (resp && resp.length) {
+      const menu = JSON.parse(resp[0].Value || "[]")
+      menu.length && uni.setStorageSync('menuList', menu)
+    }
+  },
+
+  /**
+   * 获取当前位置与医院的距离
+   * @param {Number} distance 距离半径(单位:公里)
+   */
+  getHospitalLocationDistance(limitDistance = 1) {
+    const {
+      hospitalInfo
+    } = getApp().globalData; // 获取医院信息
+    if (common.isEmpty(hospitalInfo)) {
+      common.showModal(`获取医院信息失败`);
+      return;
+    }
+    const {
+      Wd: hosLat,
+      Jd: hosLng
+    } = hospitalInfo;
+    if (common.isEmpty(hosLat) || common.isEmpty(hosLng)) {
+      common.showModal(`获取医院配置失败`);
+      return;
+    }
+    return new Promise((resolve, reject) => {
+      this.locationIsauthorization('gcj02', (res) => {
+        let distance = common.getDistance(res.latitude, res.longitude, hosLat, hosLng);
+        distance > limitDistance ? reject() : resolve();
+      })
+    })
+  },
+  /**
+   * 处理首页和医院概况轮播图片地址
+   */
+  handlePhoto() {
+    let photoArr = []
+    let hospitalInfo = common.deepCopy(app.globalData.hospitalInfo);
+    if (!common.isEmpty(hospitalInfo.PhotoUrl)) {
+      hospitalInfo.PhotoUrl = JSON.parse(hospitalInfo.PhotoUrl)
+      /**处理图片url */
+      for (let i in hospitalInfo.PhotoUrl) {
+        hospitalInfo.PhotoUrl[i] = hospitalInfo.PhotoUrl[i].indexOf('http') != '-1' ? hospitalInfo.PhotoUrl[i] : `${REQUEST_CONFIG.BASE_URL}${hospitalInfo.PhotoUrl[i]}`
+        photoArr.push(hospitalInfo.PhotoUrl[i])
+      }
+    }
+    return photoArr
+  },
+  /**
+   * 调起人脸识别
+   */
+  startFacialRecognitionVerify(data) {
+    return new Promise((resolve, reject) => {
+      // #ifdef MP-WEIXIN
+      wx.startFacialRecognitionVerify({
+        name: data.memberName,
+        idCardNumber: data.idCardNo,
+        checkAliveType: 1,
+        success: function (res) {
+          resolve({
+            success: true,
+            value: res
+          })
+        },
+        fail: function (res) {
+          reject({
+            success: false,
+            value: res
+          })
+        }
+      })
+      // #endif
+      // #ifndef MP-WEIXIN
+      common.showToast('非微信小程序环境不支持人脸识别');
+      reject({ success: false, msg: 'Not supported' });
+      // #endif
+    })
+  },
+  // 处理医生返回值
+  doctorListHandle(list) {
+    if (common.isEmpty(list)) {
+      return list
+    }
+    for (let i of list) {
+      if (i.DoctorPhotourl) {
+        if (i.DoctorPhotourl.indexOf("http")) {
+          i.DoctorPhotourl = REQUEST_CONFIG.BASE_URL + i.DoctorPhotourl.replace(/\\/g, "/")
+        }
+      } else {
+        i.DoctorPhotourl = icon.equire_doctor
+      }
+      // 计算价格
+      i.phoneFeeDiy = i.PhoneFee ? common.centToYuan(i.PhoneFee).toFixed(2) : 0
+      i.videoFeeDiy = i.VideoFee ? common.centToYuan(i.VideoFee).toFixed(2) : 0
+      i.consultFeeDiy = i.ConsultFee ? common.centToYuan(i.ConsultFee).toFixed(2) : 0
+
+
+      let AvgAppraiseScore = '-';
+      // 用于做排序判断
+      let AvgAppraiseScoreTag = 0;
+      if (i.AppraiseCount > 0 && i.AppraiseScore > 0) {
+        AvgAppraiseScore = (i.AppraiseScore / i.AppraiseCount / 5 * 100).toFixed(0) + "%";
+        AvgAppraiseScoreTag = (i.AppraiseScore / i.AppraiseCount / 5 * 100).toFixed(0);
+      }
+      i.AvgAppraiseScore = AvgAppraiseScore;
+      i.AvgAppraiseScoreTag = AvgAppraiseScoreTag;
+
+      // 计算好评率
+      if (true) {
+        let highCount = getApp().globalData.config.net_pageConfiguration_patient.currency_config.iniHighAppraiseCount + i.HighAppraiseCountCons
+        let totalCount = getApp().globalData.config.net_pageConfiguration_patient.currency_config.iniHighAppraiseCount + (i.AppraiseCount !== undefined ? i.AppraiseCount : i.AppraiseCountCons)
+        let percentage = (highCount / totalCount) * 100
+        if (Number.isNaN(percentage)) {
+          i.percentage = '100%'
+        } else {
+          i.percentage = Math.ceil(percentage) > 100 ? 100 + "%" : Math.ceil(percentage) + "%"
+        }
+      }
+      i.scoreDiy = "5.0"
+      if ((i.AppraiseCount !== undefined ? i.AppraiseCount : i.AppraiseCountCons) && (i.AppraiseScore !== undefined ? i.AppraiseScore : i.AppraiseScoreCons)) {
+        // 评分
+        i.scoreDiy = Math.ceil((i.AppraiseScore !== undefined ? i.AppraiseScore : i.AppraiseScoreCons) / (i.AppraiseCount !== undefined ? i.AppraiseCount : i.AppraiseCountCons)).toFixed(1)
+      }
+      if (i.AppraiseRule) {
+        try {
+          i.AppraiseRule = JSON.parse(i.AppraiseRule)
+        } catch (err) {
+          console.log('i.AppraiseRule格式化失败')
+        }
+      }
+    }
+    return list
+  },
+  /** 查询患者分类列表 
+   *  规则:
+   *  返参ClassificationType等于2为复诊患者规则,带入就诊记录(已签到)进行结果判断,符合则为复诊患者
+   *  若接口返回空,则为初诊患者
+   */
+  async queryPatientClassifiyList(member, doctorCode, self) {
+    return new Promise(async (resolve, reject) => {
+      let data = {
+        Status: 1
+      }
+      let {
+        resp,
+        resData
+      } = await callApi('wsgw/yy/yygh/QueryPatientClassifiyList/callApiJSON.do', data)
+      console.log("QueryPatientClassifiyList=====", resp)
+      if (resData.RespCode == "10000") {
+        if (common.isNotEmpty(resp)) {
+          // 筛选出复诊患者规则
+          let visit = resp.filter((item) => {
+            return item.ClassificationType == 2
+          })
+
+          console.log("visit=====", visit)
+          // 有复诊规则,执行预约记录的规则匹配逻辑
+          if (common.isNotEmpty(visit)) {
+            self.setData({
+              patientClassificationId: 2
+            })
+            try {
+              member.memberOtherInfo = JSON.parse(member.memberOtherInfo)
+              console.log("true")
+            } catch {
+              member.memberOtherInfo = member.memberOtherInfo
+              console.log("false")
+            }
+            console.log("member=======", member)
+            resolve(await this.queryOutpatientVisitList(member, visit[0], doctorCode))
+          } else {
+            self.setData({
+              patientClassificationId: 1
+            })
+            resolve(false)
+          }
+        } else {
+          resolve(false)
+        }
+      } else {
+        resolve(false)
+      }
+    })
+  },
+  /** 查询his预约记录并判断是否为复诊患者 */
+  async queryOutpatientVisitList(member, rule, doctorCode) {
+    return new Promise(async (resolve, reject) => {
+      let day = common.mul(rule.IntervalNum, 30)
+      var reqData = {
+        HosId: getApp().globalData.districtId || getApp().globalData.hosId,
+        StartDate: common.aFewDaysago(day),
+        EndDate: common.newDay(),
+        IgnoreHosId: true,
+        QueryAll: getApp().globalData.districtId || getApp().globalData.hosId,
+        MemberId: member.memberId,
+        CardType: member.cardType || "1",
+        CardNo: member.memberOtherInfo.defaultCard.cardNo,
+        Store: {
+          cardEncryptionStore: member.encryptionStore || '',
+          baseMemberEncryptionStore: member.baseMemberEncryptionStore
+        }
+      }
+      let {
+        resp,
+        resData
+      } = await callApi('wsgw/member/memberApi/QueryOutpatientVisitList/callApiJSON.do', reqData)
+      console.log("QueryOutpatientVisitList=====", resp)
+      if (resData.RespCode == "10000") {
+        if (common.isNotEmpty(resp)) {
+          resp = resp.filter((item) => {
+            return item.CardNo == member.cardNo
+          })
+          if (common.isNotEmpty(resp)) {
+            // 返回列表
+            if (member.List) {
+              resolve(resp)
+              return
+            }
+            // 需判断就诊记录和对应医生的匹配次数
+            if (common.isNotEmpty(doctorCode)) {
+              let docRecord = resp.filter((item) => {
+                return item.DoctorCode == doctorCode
+              })
+              if (docRecord.length >= rule.HistoryMedicalTimesNum) {
+                resolve(true)
+              } else {
+                resolve(false)
+              }
+            }
+            // 直接判断就诊次数和配置中的是不是匹配
+            else {
+              if (resp.length >= rule.HistoryMedicalTimesNum) {
+                resolve(true)
+              } else {
+                resolve(false)
+              }
+            }
+          } else {
+            resolve(false)
+          }
+        } else {
+          resolve(false)
+        }
+      } else {
+        resolve(false)
+      }
+    })
+  },
+  /**
+   * 查询医生排班公共方法
+   * @param {Object} data - 查询参数
+   * @param {Object} options - 额外配置参数
+   * @returns {Array} - 处理后的医生排班数据
+   */
+  async queryClinicDoctorSchedule(resp, options = {}) {
+    if (!common.isEmpty(resp)) {
+      for (let i of resp) {
+        if (i.Data_1 && !common.isEmpty(i.Data_1)) {
+          i.Data_1.map(item => {
+            item.RegDateDiy = item.RegDate.substring(5),
+              item.WeekName = item.RegDate == common.newDay() ? '今天' : item.WeekName
+          })
+        }
+        /**如果医生头像没有域名 添加域名 */
+        if (i.PhotoUrl && i.PhotoUrl.indexOf('http') == '-1') {
+          i.PhotoUrl = REQUEST_CONFIG.BASE_URL + i.PhotoUrl
+        }
+        i.PhotoUrl = i.PhotoUrl.replace(/\\/g, '/')
+        if (i.Data_1.length > 6) {
+          i.Data_1_Diy = i.Data_1.slice(0, 5);
+          i.showAllSchedu = false
+        } else {
+          i.Data_1_Diy = i.Data_1;
+          i.showAllSchedu = true;
+        }
+      }
+    }
+    resp.map(item => {
+      let obj = [{
+        Check: true,
+        DeptName: item.DeptName,
+        DeptCode: item.DeptCode,
+        DoctorName: item.DoctorName,
+        DoctorCode: item.DoctorCode,
+        Data_1: item.Data_1,
+        Data_1_Diy: item.Data_1_Diy,
+        showAllSchedu: item.showAllSchedu,
+      }]
+      item.Scheduling = obj
+      item.HosId = options.hosId
+      item.ChoiceHosId = options.hosId
+    })
+    return resp
+  },
+  /**
+   * 医生与诊疗组匹配
+   * @param {Array} doctors - 医生列表
+   * @param {Array} groupList - 诊疗组列表
+   */
+  matchDoctorsWithGroup(doctors, groupList) {
+    if (!groupList || !Array.isArray(groupList)) return;
+
+    // 创建一个Map来存储诊疗组信息,key为医生代码
+    const doctorGroupMap = new Map();
+
+    // 遍历所有诊疗组,收集医生与诊疗组的对应关系
+    groupList.forEach(group => {
+      if (group.doctorList && Array.isArray(group.doctorList)) {
+        group.doctorList.forEach(doctor => {
+          if (doctor.code) {
+            doctorGroupMap.set(doctor.code, group);
+          }
+        });
+      }
+    });
+
+    // 标记医生是否属于诊疗组,并赋值诊疗组信息
+    doctors.forEach(doctor => {
+      const groupInfo = doctorGroupMap.get(doctor.DoctorCode);
+      doctor.IsGroup = !!groupInfo;
+      if (groupInfo) {
+        doctor.GroupInfo = groupInfo;
+      }
+    });
+  },
+  /** 全局开启分享 */
+  overShareMenu() {
+    // #ifdef MP-WEIXIN
+    wx.onAppRoute(() => {
+      //获取加载的页面
+      let pages = getCurrentPages(),
+        //获取当前页面的对象
+        view = pages[pages.length - 1];
+      if (view && view.onShareAppMessage) {
+        wx.showShareMenu({
+          withShareTicket: true,
+          menus: ['shareAppMessage', 'shareTimeline']
+        })
+      }
+    })
+    // #endif
+  }
+}