From cfa5a3aacd38eab6e89818098a9675456bf52625 Mon Sep 17 00:00:00 2001
From: WXL (wul) <wl_5969728@163.com>
Date: 星期三, 04 二月 2026 10:16:13 +0800
Subject: [PATCH] 测试完成

---
 src/views/patient/SignAcontract/index.vue |  265 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 169 insertions(+), 96 deletions(-)

diff --git a/src/views/patient/SignAcontract/index.vue b/src/views/patient/SignAcontract/index.vue
index 32c6166..62dc6f7 100644
--- a/src/views/patient/SignAcontract/index.vue
+++ b/src/views/patient/SignAcontract/index.vue
@@ -27,11 +27,12 @@
           <el-col :span="6">
             <el-form-item label="鏈嶅姟濂楅" prop="servicePackage">
               <el-select v-model="queryParams.servicePackage" placeholder="璇烽�夋嫨濂楅" clearable>
-                <el-option label="鍩虹鍋ュ悍绠$悊鍖�" value="1" />
-                <el-option label="鎱㈡�х梾绠$悊鍖�" value="2" />
-                <el-option label="鑰佸勾浜哄仴搴峰寘" value="3" />
-                <el-option label="瀛曚骇濡囦繚鍋ュ寘" value="4" />
-                <el-option label="鍎跨淇濆仴鍖�" value="5" />
+                <el-option
+                  v-for="pkg in packageOptions"
+                  :key="pkg.id"
+                  :label="pkg.name"
+                  :value="pkg.id"
+                />
               </el-select>
             </el-form-item>
           </el-col>
@@ -51,7 +52,7 @@
         <el-card class="stats-card" shadow="hover">
           <div class="stats-content">
             <div class="stats-number">{{ stats.total }}</div>
-            <div class="stats-label">鎬荤绾︽偅鑰�</div>
+            <div class="stats-label">鎬荤绾﹀効绔�</div>
           </div>
         </el-card>
       </el-col>
@@ -91,12 +92,15 @@
         :default-sort="{prop: 'signDate', order: 'descending'}"
       >
         <el-table-column type="selection" width="55" />
-        <el-table-column label="鎮h�呬俊鎭�" min-width="180" fixed>
+        <el-table-column label="鍎跨淇℃伅" min-width="180" fixed>
           <template slot-scope="scope">
             <div class="patient-info">
               <div class="patient-name">{{ scope.row.patientName }}</div>
               <div class="patient-detail">
                 {{ scope.row.gender }} | {{ scope.row.age }}宀� | {{ scope.row.phone }}
+                <div style="color: #909399; font-size: 12px; margin-top: 2px;">
+                  {{ scope.row.applicableAge }}
+                </div>
               </div>
             </div>
           </template>
@@ -190,118 +194,161 @@
       },
       total: 0,
       patientList: [],
-      // 鏈嶅姟濂楅閰嶇疆
+      // 鍎跨鏈嶅姟濂楅閰嶇疆 [1,3,5](@ref)
       servicePackages: {
         '1': {
-          name: '鍩虹鍋ュ悍绠$悊鍖�',
-          services: ['骞村害鍋ュ悍璇勪及', '鍦ㄧ嚎鍋ュ悍鍜ㄨ', '鍋ュ悍妗f绠$悊', '瀹氭湡鍋ュ悍鎻愰啋'],
+          name: '濠村辜鍎垮仴搴峰熀纭�鍖�',
+          description: '涓�0-3宀佸┐骞煎効鎻愪緵鍏ㄩ潰鐨勫仴搴风洃娴嬩笌鍙戣偛鎸囧',
+          services: ['鏂扮敓鍎垮搴瑙�', '瀹氭湡浣撴牸妫�鏌ヤ笌鍙戣偛璇勪及', '琛�甯歌妫�娴�', '鍚姏绛涙煡', '鍠傚吇涓庢姢鐞嗘寚瀵�', '棰勯槻鎺ョ鏈嶅姟', '涓尰淇濆仴鎸囧'],
           price: 0,
-          color: 'info'
+          color: 'primary',
+          applicableAge: '0-3宀�'
         },
         '2': {
-          name: '鎱㈡�х梾绠$悊鍖�',
-          services: ['涓撳睘鍖荤敓鏈嶅姟', '鐢ㄨ嵂鎸囧绠$悊', '瀹氭湡闅忚鐩戞祴', '涓�у寲搴峰璁″垝', '绱ф�ュ尰鐤楀挩璇�'],
-          price: 299,
-          color: 'success'
+          name: '瀛﹂緞鍓嶅効绔ュ仴搴峰寘',
+          description: '鍏虫敞3-6宀佸効绔ョ敓闀垮彂鑲层�佸父瑙佺梾棰勯槻鍙婁範鎯吇鎴�',
+          services: ['鐢熼暱鍙戣偛璇勪及', '瑙嗗姏绛涙煡涓庡彛鑵斾繚鍋�', '琛�甯歌妫�鏌�', '鍚堢悊鑶抽涓庤涓烘寚瀵�', '鐤剧梾棰勯槻涓庡仴搴峰共棰�', '涓尰楗璋冨吇鎸囧'],
+          price: 0,
+          color: 'success',
+          applicableAge: '3-6宀�'
         },
         '3': {
-          name: '鑰佸勾浜哄仴搴峰寘',
-          services: ['璺屽�掗闄╄瘎浼�', '搴峰璁粌鎸囧', '鐢ㄨ嵂瀹夊叏绠$悊', '瀹氭湡涓婇棬璁胯', '绱ф�ヨ仈绯绘湇鍔�', '蹇冪悊鍋ュ悍鍏虫��'],
-          price: 499,
-          color: 'warning'
+          name: '瀛﹂緞鍎跨缁煎悎鍋ュ悍鍖�',
+          description: '涓�7-12宀佸効绔ユ彁渚涘涔犳湡鍋ュ悍淇濋殰涓庡彂灞曟敮鎸�',
+          services: ['骞村害鍋ュ悍妫�鏌�', '蹇冪悊琛屼负鍙戣偛璇勪及', '绉戝鐢ㄧ溂涓庡彛鑵斾繚鍋�', '鍚堢悊鑶抽鎸囧', '鍋ュ悍鐢熸椿鏂瑰紡骞查', '涓撳杞瘖缁胯壊閫氶亾'],
+          price: 0,
+          color: 'warning',
+          applicableAge: '7-12宀�'
         },
         '4': {
-          name: '瀛曚骇濡囦繚鍋ュ寘',
-          services: ['瀛曟湡鍋ュ悍绠$悊', '浜у悗搴峰鎸囧', '鏂扮敓鍎挎姢鐞嗗挩璇�', '钀ュ吇鑶抽寤鸿', '蹇冪悊鎯呯华鏀寔'],
-          price: 399,
-          color: 'danger'
+          name: '闈掑皯骞村仴搴锋敮鎸佸寘',
+          description: '閽堝13-18宀侀潚灏戝勾闈掓槬鏈熺壒鐐圭殑鍋ュ悍绠$悊',
+          services: ['闈掓槬鏈熷仴搴锋暀鑲�', '骞村害鍋ュ悍璇勪及', '蹇冪悊鍋ュ悍鏀寔', '鍋ュ悍椋庨櫓琛屼负骞查', '涓�у寲鍋ュ悍鏂规', '浼樺厛棰勭害妫�鏌ユ湇鍔�'],
+          price: 0,
+          color: 'danger',
+          applicableAge: '13-18宀�'
         },
         '5': {
-          name: '鍎跨淇濆仴鍖�',
-          services: ['鐢熼暱鍙戣偛鐩戞祴', '鐤嫍鎺ョ绠$悊', '甯歌鐥呴槻娌�', '钀ュ吇鎸囧', '鏃╂湡鏁欒偛鍜ㄨ'],
-          price: 199,
-          color: 'primary'
+          name: '鍎跨钀ュ吇涓庣敓闀垮彂鑲插鍊煎寘',
+          description: '閽堝鑲ヨ儢銆佽惀鍏讳笉鑹瓑闂鐨勪笓椤圭鐞�',
+          services: ['寰噺鍏冪礌娴嬪畾', '楠ㄥ瘑搴︽娴�', '涓�у寲鑶抽鏂规', '鐢熼暱鍙戣偛涓撻」璇勪及', '杩愬姩澶勬柟鎸囧', '瀹氭湡钀ュ吇鐩戞祴'],
+          price: 150,
+          color: 'info',
+          applicableAge: '3-18宀�'
+        },
+        '6': {
+          name: '鍎跨涓尰鐗硅壊淇濆仴鍖�',
+          description: '杩愮敤涓尰鑽柟娉曞寮哄効绔ヤ綋璐�',
+          services: ['涓尰浣撹川杈ㄨ瘑', '涓変紡璐存湇鍔�', '灏忓効鎺ㄦ嬁', '鑰崇┐娌荤枟', '闃叉劅棣欏泭', '椋熺枟鎸囧'],
+          price: 200,
+          color: 'primary',
+          applicableAge: '0-6宀�'
         }
-      }
+      },
+      packageOptions: []
     }
   },
   created() {
+    this.initPackageOptions()
     this.getList()
     this.calculateStats()
   },
   methods: {
-    // 鐢熸垚鏇寸湡瀹炵殑妯℃嫙鏁版嵁
-   // 绮剧畝鍚庣殑妯℃嫙鏁版嵁鐢熸垚鏂规硶
-// 浼樺寲鍚庣殑妯℃嫙鏁版嵁鐢熸垚鏂规硶
-generateMockData() {
-  const mockData = []
+    // 鍒濆鍖栧椁愰�夐」
+    initPackageOptions() {
+      this.packageOptions = Object.keys(this.servicePackages).map(key => ({
+        id: key,
+        name: this.servicePackages[key].name
+      }))
+    },
 
-  // 浣跨敤鎮ㄦ彁渚涚殑鐪熷疄濮撳悕鍒楄〃
-  const patientNames = [
-    '鏉庤倗鑺�', '鍗㈡湪浠�', '鏉庢垚鐧�', '鏂瑰厗鐜�', '鍒樼繆鎯�', '涓佹眽鑷�', '鍚翠匠鐟�', '鑸掔豢鐝�',
-    '鍛ㄧ櫧鑺�', '寮犲Э濡�', '寮犺櫣浼�', '鍛ㄧ惣鐜�', '鍊�¤姵', '閮吹濡�', '鏉ㄤ僵鑺�', '榛勬枃鏃�',
-    '榛勭洓鐜�', '閮戜附闈�', '璁告櫤浜�', '寮犲瓱娑�', '鏉庡皬鐖�', '鐜嬫仼榫�', '鏈辨斂寤�', '閭撹瘲娑�',
-    '闄堟斂鍊�', '鍚翠繆浼�', '闃Θ瀛�', '缈佹儬鐝�', '鍚存�濈堪', '鏋椾僵鐜�'
-  ]
+    // 鐢熸垚妯℃嫙鏁版嵁
+    generateMockData() {
+      const mockData = []
 
-  const doctors = ['鐜嬪尰鐢�', '鏉庡尰鐢�', '寮犲尰鐢�', '鍒樺尰鐢�', '闄堝尰鐢�']
-  const cities = ['鍖椾含甯�', '涓婃捣甯�', '骞垮窞甯�', '娣卞湷甯�', '鏉窞甯�', '鍗椾含甯�', '鎴愰兘甯�']
-  const areas = ['鏈濋槼鍖�', '娴锋穩鍖�', '娴︿笢鏂板尯', '榛勬郸鍖�', '澶╂渤鍖�', '绂忕敯鍖�', '瑗挎箹鍖�']
+      // 浣跨敤鍎跨濮撳悕鍒楄〃
+      const patientNames = [
+        '鏉庡皬瀹�', '寮犲皬鏄�', '鐜嬮洦娆�', '鍒樻旦鐒�', '闄堟�濈惇', '鏉ㄥ畤鑸�', '榛勮瘲娑�', '璧靛ぉ瀹�',
+        '鍛ㄥ皬钀�', '鍚翠繆鏉�', '閮戦泤闆�', '瀛欐矏杈�', '鏈遍洦钀�', '椹旦瀹�', '鑳″彲棣�', '鏋椾繆鐔�',
+        '閮瓙杞�', '浣曟鎬�', '楂樺ぉ浣�', '姊侀潤鎬�', '缃楁旦鐒�', '瀹嬮洦娉�', '鍞愯瀚�', '璁稿崥鏂�',
+        '璋㈡濡�', '鍐瓙榛�', '钁i洦妗�', '钀уぉ涔�', '鏇瑰績鎬�', '琚佸槈璞�'
+      ]
 
-  // 鐢熸垚绾�20鏉℃暟鎹�
-  for (let i = 0; i < patientNames.length; i++) {
-    const packageId = (i % 5) + 1 + ''
-    const packageInfo = this.servicePackages[packageId]
+      const doctors = ['鐜嬪尰鐢�', '鏉庡尰鐢�', '寮犲尰鐢�', '鍒樺尰鐢�', '闄堝尰鐢�']
+      const cities = ['鍖椾含甯�', '涓婃捣甯�', '骞垮窞甯�', '娣卞湷甯�', '鏉窞甯�', '鍗椾含甯�', '鎴愰兘甯�']
+      const areas = ['鏈濋槼鍖�', '娴锋穩鍖�', '娴︿笢鏂板尯', '榛勬郸鍖�', '澶╂渤鍖�', '绂忕敯鍖�', '瑗挎箹鍖�']
 
-    // 鐢熸垚鏇村悎鐞嗙殑绛剧害鏃堕棿锛堣繃鍘�1骞村唴锛�
-    const signDate = this.generateRandomDate('2023-12-01', '2024-11-30')
-    const contractPeriod = [1, 2][i % 2] // 1骞存垨2骞村悎鍚�
-    const expireDate = this.addYears(signDate, contractPeriod)
-    const remainingDays = this.calculateRemainingDays(expireDate)
-    const contractStatus = this.getContractStatus(expireDate, remainingDays)
+      for (let i = 0; i < patientNames.length; i++) {
+        const packageId = (i % 6) + 1 + ''
+        const packageInfo = this.servicePackages[packageId]
 
-    // 鐢熸垚鏇寸湡瀹炵殑鐢佃瘽鍙风爜鍜岃韩浠借瘉鍙�
-    const phonePrefix = ['138', '139', '150', '151', '152', '186', '187', '188']
-    const phone = `${phonePrefix[i % phonePrefix.length]}${this.padNumber(1000 + i * 37, 4)}${this.padNumber(i % 100, 2)}`
+        // 鏍规嵁濂楅閫傜敤骞撮緞鐢熸垚鍚堢悊鐨勫疄闄呭勾榫�
+        let age
+        switch(packageInfo.applicableAge) {
+          case '0-3宀�':
+            age = Math.floor(Math.random() * 3) + 1
+            break
+          case '3-6宀�':
+            age = Math.floor(Math.random() * 3) + 3
+            break
+          case '7-12宀�':
+            age = Math.floor(Math.random() * 6) + 7
+            break
+          case '13-18宀�':
+            age = Math.floor(Math.random() * 6) + 13
+            break
+          default:
+            age = Math.floor(Math.random() * 18) + 1
+        }
 
-    // 鐢熸垚鍚堢悊鐨勫勾榫勶紙20-80宀侊級
-    const age = 20 + (i % 60)
-    const birthYear = new Date().getFullYear() - age
-    const idCard = `11010${birthYear}${this.padNumber(1 + (i % 12), 2)}${this.padNumber(1 + (i % 28), 2)}${this.padNumber(i % 1000, 3)}X`
+        // 鐢熸垚绛剧害鏃堕棿锛堣繃鍘�1骞村唴锛�
+        const signDate = this.generateRandomDate('2023-12-01', '2024-11-30')
+        const contractPeriod = [1, 2][i % 2] // 1骞存垨2骞村悎鍚�
+        const expireDate = this.addYears(signDate, contractPeriod)
+        const remainingDays = this.calculateRemainingDays(expireDate)
+        const contractStatus = this.getContractStatus(expireDate, remainingDays)
 
-    mockData.push({
-      id: `P${2024000 + i}`,
-      patientName: patientNames[i],
-      gender: i % 2 === 0 ? '鐢�' : '濂�',
-      age: age,
-      phone: phone,
-      idCard: idCard,
-      doctorName: doctors[i % doctors.length],
-      servicePackageId: packageId,
-      servicePackage: packageInfo.name,
-      services: packageInfo.services,
-      contractPeriod: contractPeriod,
-      signDate: signDate,
-      expireDate: expireDate,
-      remainingDays: remainingDays,
-      contractStatus: contractStatus,
-      address: `${cities[i % cities.length]}${areas[i % areas.length]}${this.generateStreet(i)}` // 鏂板鍦板潃瀛楁
-    })
-  }
+        // 鐢熸垚鐢佃瘽鍙风爜锛堜娇鐢ㄥ闀跨數璇濓級
+        const phonePrefix = ['138', '139', '150', '151', '152', '186', '187', '188']
+        const phone = `${phonePrefix[i % phonePrefix.length]}${this.padNumber(1000 + i * 37, 4)}${this.padNumber(i % 100, 2)}`
 
-  return mockData
-},
+        // 鐢熸垚鍎跨韬唤璇佸彿
+        const birthYear = new Date().getFullYear() - age
+        const idCard = `11010${birthYear}${this.padNumber(1 + (i % 12), 2)}${this.padNumber(1 + (i % 28), 2)}${this.padNumber(i % 1000, 3)}X`
 
-// 鏂板杈呭姪鏂规硶锛氱敓鎴愯閬撳湴鍧�
-generateStreet(index) {
-  const streets = [
-    '涓北璺�123鍙�', '浜烘皯璺�456鍙�', '瑙f斁璺�789鍙�', '寤鸿璺�101鍙�', '鍜屽钩璺�202鍙�',
-    '鏂板崕璺�303鍙�', '鍏夋槑璺�404鍙�', '骞哥璺�505鍙�', '鍥㈢粨璺�606鍙�', '鏂囨槑璺�707鍙�'
-  ]
-  return streets[index % streets.length]
-},
+        mockData.push({
+          id: `C${2024000 + i}`,
+          patientName: patientNames[i],
+          gender: i % 2 === 0 ? '鐢�' : '濂�',
+          age: age,
+          phone: phone,
+          idCard: idCard,
+          doctorName: doctors[i % doctors.length],
+          servicePackageId: packageId,
+          servicePackage: packageInfo.name,
+          services: packageInfo.services,
+          contractPeriod: contractPeriod,
+          signDate: signDate,
+          expireDate: expireDate,
+          remainingDays: remainingDays,
+          contractStatus: contractStatus,
+          applicableAge: packageInfo.applicableAge,
+          address: `${cities[i % cities.length]}${areas[i % areas.length]}${this.generateStreet(i)}`
+        })
+      }
 
-    // 杈呭姪鏂规硶
+      return mockData
+    },
+
+    // 杈呭姪鏂规硶淇濇寔涓嶅彉
+    generateStreet(index) {
+      const streets = [
+        '涓北璺�123鍙�', '浜烘皯璺�456鍙�', '瑙f斁璺�789鍙�', '寤鸿璺�101鍙�', '鍜屽钩璺�202鍙�',
+        '鏂板崕璺�303鍙�', '鍏夋槑璺�404鍙�', '骞哥璺�505鍙�', '鍥㈢粨璺�606鍙�', '鏂囨槑璺�707鍙�'
+      ]
+      return streets[index % streets.length]
+    },
+
     generateRandomDate(start, end) {
       const startDate = new Date(start).getTime()
       const endDate = new Date(end).getTime()
@@ -336,11 +383,10 @@
     async getList() {
       this.loading = true
       try {
-        // 妯℃嫙API璋冪敤寤惰繜
         await new Promise(resolve => setTimeout(resolve, 500))
 
         const allData = this.generateMockData()
-        // 绠�鍗曠殑鏈湴绛涢��
+        // 绛涢�夐�昏緫
         let filteredData = allData.filter(item => {
           if (this.queryParams.patientName &&
               !item.patientName.includes(this.queryParams.patientName)) {
@@ -393,7 +439,10 @@
     },
 
     getPackageType(packageId) {
-      const typeMap = { '1': 'info', '2': 'success', '3': 'warning', '4': 'danger', '5': 'primary' }
+      const typeMap = {
+        '1': 'primary', '2': 'success', '3': 'warning',
+        '4': 'danger', '5': 'info', '6': 'primary'
+      }
       return typeMap[packageId] || 'info'
     },
 
@@ -425,13 +474,12 @@
     },
 
     handleView(row) {
-      this.$message.info(`鏌ョ湅鎮h�� ${row.patientName} 鐨勮鎯卄)
+      this.$message.info(`鏌ョ湅鍎跨 ${row.patientName} 鐨勮鎯卄)
       // 瀹為檯寮�鍙戜腑璺宠浆鍒拌鎯呴〉
-      // this.$router.push({ path: '/patient/contract/detail', query: { id: row.id } })
     },
 
     handleRenew(row) {
-      this.$confirm(`纭畾瑕佷负鎮h�� ${row.patientName} 鍔炵悊缁害鍚楋紵`, '鎻愮ず', {
+      this.$confirm(`纭畾瑕佷负鍎跨 ${row.patientName} 鍔炵悊缁害鍚楋紵`, '鎻愮ず', {
         type: 'warning'
       }).then(() => {
         this.$message.success('缁害鎿嶄綔鎴愬姛')
@@ -458,6 +506,10 @@
 
   .search-card {
     margin-bottom: 20px;
+
+    ::v-deep .el-form-item {
+      margin-bottom: 0;
+    }
   }
 
   .stats-row {
@@ -487,11 +539,13 @@
     .patient-name {
       font-weight: 600;
       margin-bottom: 4px;
+      color: #2c3e50;
     }
 
     .patient-detail {
       font-size: 12px;
       color: #666;
+      line-height: 1.4;
     }
   }
 
@@ -509,4 +563,23 @@
     color: #67C23A;
   }
 }
+
+// 鍝嶅簲寮忚璁�
+@media (max-width: 768px) {
+  .signed-patient-page {
+    padding: 10px;
+
+    .search-card {
+      ::v-deep .el-col {
+        margin-bottom: 10px;
+      }
+    }
+
+    .stats-row {
+      .el-col {
+        margin-bottom: 10px;
+      }
+    }
+  }
+}
 </style>

--
Gitblit v1.9.3