WXL
7 天以前 4c9fdc87987140e8b2c3f0dfc2f6608cdb6be774
青岛维护
已修改99个文件
已添加4个文件
8016 ■■■■■ 文件已修改
package.json 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/businessApi/statistics.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/businessApi/statisticsMock.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/common/echart/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/common/map/qingdao.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/charts/G2PlotChart.vue 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/g2Dark.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/GetWitness/GetWitnessInfo.vue 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/GetWitness/index.vue 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/OrganUtilization/OrganUtilizationInfo.vue 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/OrganUtilization/index.vue 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/affirm/affirmInfo.vue 1468 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/affirm/index.vue 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/allocation/allocationInfo.vue 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/allocation/index.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/appear/caseDetail.vue 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/appear/index.vue 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/assessInfo.vue 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/index.vue 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/decide/DecideInfo.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/decide/index.vue 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/ethicalReview/ethicalReviewInfo.vue 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/ethicalReview/index.vue 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/followupVisit/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/followupVisit/info.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/maintain/index.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/maintain/maintainInfo.vue 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/transfer/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/transfer/transportDetail.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/cockpitMock.js 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/components/MapChart/index.vue 274 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/index.vue 2904 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/monitor/job/index.vue 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/monitor/job/log.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/monitor/logininfor/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/monitor/online/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/monitor/operlog/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/components/annexupload/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/distributedetail/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/documentfiles/index.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donateannex/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donateannexrequirement/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donatebaseinfo/EditCaseModal.vue 748 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donatebaseinfo/index.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donateconsolationfund/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donatefinish/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donatefollowup/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donateorgan/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donateorganstatics/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donatereview/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donationwitness/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donorcharge/donorcharge/index.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donorcharge/organcharge/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/ethicalReview/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/externalperson/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/financesubject/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/ethicalExpertFeeApply/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/expertFeeApply/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/medicalCostApply/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/officeExpenseApply/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fund/performanceApply/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fundcheck/ethicalExpertFeeCheck/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fundcheck/expertFeeCheck/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fundcheck/medicalCostCheck/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fundcheck/officeExpenseCheck/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fundcheck/performanceCheck/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/funddetail/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fundflow/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fundflowrule/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/fundstatistics/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/itemexpense/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/organallocation/index0.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/organization/index.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/reimbursement/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/reimbursementdetail/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/reimbursementpayee/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/relativesconfirmation/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/tallage/computingBill/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/tallage/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/travelexpenseapply/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/travelexpensecheck/index.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/travelexpensedeal/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/unitCost/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/unitCost/particulars/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/statistics/components/OrganDetail.vue 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/statistics/organ.vue 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/class/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/config/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/costmaintenance/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/dept/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/dict/data.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/dict/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/grade/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/medicalevalustion/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/menu/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/notice/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/post/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/role/authUser.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/role/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/student/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/user/index.vue 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tool/gen/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -36,6 +36,7 @@
    "url": "https://gitee.com/y_project/RuoYi-Vue.git"
  },
  "dependencies": {
    "@antv/g2plot": "^2.4.33",
    "@jiaminghi/data-view": "^2.10.0",
    "@riophae/vue-treeselect": "0.4.0",
    "axios": "0.21.0",
src/api/businessApi/statistics.js
@@ -58,3 +58,11 @@
export function trendList(data) {
  return post('/opo/totals/trendList', data)
}
// å™¨å®˜ç§»æ¤æ€»ç»Ÿè®¡ï¼ˆæ•°æ®æ¦‚览:总获取/总移植/总回纳/总弃用)
export function organTotals(data) {
  return post('/opo/totals/organTotals', data)
}
// æçŒ®å™¨å®˜ç»Ÿè®¡æ˜Žç»†åˆ—表(器官明细详情)
export function organList(data) {
  return post('/opo/totals/organList', data)
}
src/api/businessApi/statisticsMock.js
@@ -137,6 +137,41 @@
  });
}
// å™¨å®˜ç§»æ¤æ€»ç»Ÿè®¡ï¼ˆæ•°æ®æ¦‚览)
function mockOrganTotals() {
  return [{ totalGet: 486, totalTransplant: 398, totalRecycle: 12, totalDiscard: 76 }];
}
// æçŒ®å™¨å®˜ç»Ÿè®¡æ˜Žç»†åˆ—表(器官明细详情)
function mockOrganList() {
  const r = createRand(111);
  const NAMES = ['张三', '李四', '王五', '赵六', '陈七', '刘八'];
  const HOSPITALS = ['青岛大学附属医院', '青岛市立医院', '青岛市中心医院'];
  const DOCTORS = ['李医生', '张医生', '王医生'];
  const RECIPIENTS = ['王明', '陈强', '刘伟', '赵刚'];
  const STATUS = [1, 1, 2, 3];
  return NAMES.map((name, i) => {
    const year = YEARS[i % YEARS.length];
    const month = String(1 + Math.floor(r() * 12)).padStart(2, '0');
    const st = STATUS[i % STATUS.length];
    return {
      id: 2000 + i,
      caseNo: `O${year}00${i + 1}`,
      name,
      organName: ORGANS[i % ORGANS.length],
      registerCountyName: REGIONS[i % REGIONS.length],
      donateYear: year,
      transplantstate: st,
      organGetTime: `${year}-${month}-15 10:30`,
      transplantTime: st === 1 ? `${year}-${month}-15 13:20` : '',
      notgetreason: st === 3 ? '器官质量不合格' : '',
      transplantName: st === 1 ? RECIPIENTS[i % RECIPIENTS.length] : '',
      hospitalName: HOSPITALS[i % HOSPITALS.length],
      transplantDoct: DOCTORS[i % DOCTORS.length]
    };
  });
}
const MOCK_MAP = {
  '/opo/totals/caseTrend': mockCaseTrend,
  '/opo/totals/caseTrendArea': mockCaseTrendArea,
@@ -148,7 +183,9 @@
  '/opo/totals/organMoon': mockOrganMoon,
  '/opo/totals/organType': mockOrganType,
  '/opo/totals/totals': mockTotalsAll,
  '/opo/totals/trendList': mockTrendList
  '/opo/totals/trendList': mockTrendList,
  '/opo/totals/organTotals': mockOrganTotals,
  '/opo/totals/organList': mockOrganList
};
export function mockTotals(url) {
src/common/echart/index.vue
@@ -6,6 +6,7 @@
import tdTheme from "./theme.json"; // å¼•入默认主题
import resize from "@/views/dashboard/mixins/resize";
import "../map/zhejiang.js";
import "../map/qingdao.js";
export default {
  name: "echart",
src/common/map/qingdao.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
/*
 * é’å²› + æ—¥ç…§ åœ°å›¾æ•°æ®ï¼ˆGeoJSON,源自阿里 DataV è¡Œæ”¿åŒºåˆ’)
 * é’岛:市南/市北/黄岛/崂山/李沧/城阳/即墨/胶州/平度/莱西(10 åŒºåŽ¿ï¼‰
 * æ—¥ç…§ï¼šä¸œæ¸¯/岚山/五莲/莒县(4 åŒºåŽ¿ï¼‰
 */
(function (root, factory) {
  if (typeof define === "function" && define.amd) {
    define(["exports", "echarts"], factory);
  } else if (typeof exports === "object" && typeof exports.nodeName !== "string") {
    factory(exports, require("echarts"));
  } else {
    factory({}, root.echarts);
  }
}(this, function (exports, echarts) {
  if (!echarts) { return; }
  if (!echarts.registerMap) { return; }
  echarts.registerMap("青岛日照", {"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"市南区","adcode":370202},"geometry":{"type":"MultiPolygon","coordinates":[[[[120.41966,36.090991],[120.410955,36.092223],[120.405539,36.088717],[120.396493,36.091023],[120.390022,36.091054],[120.387477,36.087028],[120.373992,36.087075],[120.371572,36.085875],[120.373356,36.080742],[120.370113,36.079305],[120.370361,36.074251],[120.364185,36.068391],[120.35967,36.068201],[120.358149,36.070887],[120.349723,36.07155],[120.343252,36.069591],[120.336239,36.070918],[120.333011,36.073888],[120.324585,36.07065],[120.318626,36.070176],[120.318782,36.074061],[120.314018,36.072798],[120.305018,36.078294],[120.300874,36.075609],[120.301356,36.071266],[120.290633,36.061393],[120.289438,36.051978],[120.286117,36.04719],[120.2886,36.042924],[120.291347,36.045879],[120.296778,36.043051],[120.294978,36.050714],[120.299292,36.052199],[120.307981,36.050192],[120.312606,36.051662],[120.311613,36.055248],[120.315104,36.059308],[120.324383,36.059861],[120.324585,36.051093],[120.33014,36.051282],[120.337558,36.054979],[120.342896,36.051693],[120.337946,36.044631],[120.34004,36.042182],[120.345627,36.043541],[120.350344,36.048107],[120.357963,36.048913],[120.362292,36.046021],[120.36223,36.042671],[120.367941,36.042213],[120.371975,36.046369],[120.368375,36.049971],[120.370222,36.053415],[120.385258,36.059545],[120.389184,36.059387],[120.387849,36.051693],[120.397315,36.05084],[120.404391,36.051614],[120.415284,36.057412],[120.422267,36.054995],[120.426658,36.056417],[120.426565,36.059924],[120.42115,36.065058],[120.423245,36.065769],[120.413546,36.074677],[120.422267,36.077789],[120.41966,36.090991]]]]}},{"type":"Feature","properties":{"name":"市北区","adcode":370203},"geometry":{"type":"MultiPolygon","coordinates":[[[[120.41966,36.090991],[120.420219,36.094797],[120.434309,36.097592],[120.416339,36.124666],[120.411017,36.128076],[120.419986,36.134357],[120.409962,36.135367],[120.404391,36.139739],[120.400636,36.152047],[120.39415,36.154998],[120.383179,36.154556],[120.379206,36.1514],[120.371044,36.152442],[120.35174,36.160899],[120.346977,36.155818],[120.333694,36.134657],[120.33087,36.12787],[120.329287,36.117437],[120.326199,36.111675],[120.321063,36.112006],[120.317556,36.108091],[120.319837,36.103497],[120.311923,36.099423],[120.312249,36.093297],[120.306771,36.089917],[120.310914,36.088117],[120.306662,36.082085],[120.311007,36.08],[120.305018,36.078294],[120.314018,36.072798],[120.318782,36.074061],[120.318626,36.070176],[120.324585,36.07065],[120.333011,36.073888],[120.336239,36.070918],[120.343252,36.069591],[120.349723,36.07155],[120.358149,36.070887],[120.35967,36.068201],[120.364185,36.068391],[120.370361,36.074251],[120.370113,36.079305],[120.373356,36.080742],[120.371572,36.085875],[120.373992,36.087075],[120.387477,36.087028],[120.390022,36.091054],[120.396493,36.091023],[120.405539,36.088717],[120.410955,36.092223],[120.41966,36.090991]]]]}},{"type":"Feature","properties":{"name":"黄岛区","adcode":370211},"geometry":{"type":"MultiPolygon","coordinates":[[[[119.717048,36.04185],[119.713138,36.040507],[119.708576,36.034802],[119.706465,36.028276],[119.69655,36.025826],[119.696131,36.021148],[119.686665,36.01786],[119.681063,36.012059],[119.682848,36.005136],[119.685362,36.006021],[119.689148,36.000219],[119.686106,35.997864],[119.687394,35.990622],[119.684819,35.982637],[119.690156,35.963691],[119.697465,35.95273],[119.701779,35.944488],[119.698163,35.94107],[119.703269,35.935818],[119.701345,35.923729],[119.708731,35.923064],[119.710624,35.92759],[119.716117,35.923554],[119.719779,35.91686],[119.718646,35.912429],[119.7213,35.906699],[119.727755,35.902552],[119.734303,35.892643],[119.732488,35.890648],[119.734893,35.885487],[119.734909,35.880183],[119.738043,35.873121],[119.735328,35.866993],[119.73691,35.86305],[119.731371,35.864665],[119.72926,35.861973],[119.722231,35.865156],[119.720586,35.862258],[119.72549,35.859407],[119.72521,35.856731],[119.718336,35.853151],[119.714379,35.853674],[119.712036,35.857934],[119.704014,35.863968],[119.693896,35.864237],[119.687006,35.861799],[119.686634,35.857966],[119.681389,35.851694],[119.675648,35.848162],[119.675989,35.842507],[119.664305,35.841002],[119.65577,35.84493],[119.649827,35.845215],[119.635209,35.835521],[119.629359,35.833889],[119.632882,35.828122],[119.629065,35.826965],[119.622594,35.816127],[119.616526,35.811849],[119.61229,35.812403],[119.608985,35.799265],[119.618016,35.789612],[119.611607,35.776613],[119.600047,35.776264],[119.59623,35.773775],[119.591947,35.753241],[119.600807,35.750941],[119.605525,35.747437],[119.615533,35.733875],[119.626023,35.726182],[119.627808,35.722089],[119.62472,35.712823],[119.62174,35.71176],[119.614183,35.716663],[119.601226,35.709443],[119.598728,35.713315],[119.588797,35.715711],[119.587028,35.713156],[119.576973,35.712379],[119.572333,35.715298],[119.566514,35.714537],[119.566079,35.717488],[119.56054,35.721771],[119.546915,35.724262],[119.545069,35.726737],[119.536239,35.722469],[119.527317,35.723215],[119.525455,35.730592],[119.522476,35.731623],[119.517836,35.724214],[119.521079,35.716853],[119.519465,35.702572],[119.514841,35.698002],[119.519108,35.685543],[119.523934,35.681512],[119.528264,35.674321],[119.526774,35.663256],[119.527426,35.653841],[119.524493,35.648537],[119.52637,35.644948],[119.523686,35.642645],[119.523143,35.636801],[119.519884,35.635134],[119.524462,35.632291],[119.517774,35.625794],[119.518146,35.615421],[119.522569,35.610878],[119.536876,35.606032],[119.538753,35.598183],[119.536441,35.593416],[119.538195,35.589269],[119.556521,35.592526],[119.563116,35.589634],[119.567631,35.590365],[119.570735,35.586806],[119.577578,35.586249],[119.575328,35.592129],[119.582745,35.592987],[119.59235,35.600694],[119.597735,35.599152],[119.60059,35.590254],[119.60928,35.592034],[119.614137,35.600185],[119.615006,35.606334],[119.618994,35.606827],[119.623494,35.601981],[119.632308,35.602092],[119.639709,35.594417],[119.651441,35.58876],[119.662148,35.589285],[119.677587,35.588601],[119.68215,35.590016],[119.717964,35.61566],[119.729943,35.618948],[119.751357,35.617868],[119.752878,35.588681],[119.762499,35.578335],[119.769637,35.577222],[119.780142,35.584851],[119.786209,35.576062],[119.795426,35.577286],[119.800827,35.581895],[119.792618,35.593861],[119.800485,35.598692],[119.80303,35.609178],[119.794216,35.612768],[119.792664,35.615469],[119.79794,35.620203],[119.802208,35.620267],[119.800609,35.626477],[119.809423,35.634324],[119.818439,35.638564],[119.824335,35.646314],[119.829642,35.643709],[119.831768,35.631703],[119.830092,35.623491],[119.831458,35.618329],[119.835554,35.617868],[119.844787,35.623618],[119.851755,35.622093],[119.865239,35.610369],[119.868343,35.608844],[119.877591,35.610957],[119.894567,35.628733],[119.90245,35.632974],[119.915205,35.633736],[119.923259,35.635229],[119.927898,35.645758],[119.927898,35.650458],[119.923647,35.655333],[119.912241,35.660636],[119.909976,35.664447],[119.910891,35.674321],[119.917331,35.682528],[119.919317,35.691352],[119.923879,35.69651],[119.944843,35.705508],[119.952912,35.713124],[119.953362,35.725595],[119.949312,35.729862],[119.938869,35.728371],[119.930397,35.72891],[119.926471,35.731448],[119.924438,35.736239],[119.92076,35.737539],[119.921241,35.751528],[119.924826,35.758236],[119.932569,35.762962],[119.937085,35.763422],[119.9551,35.761138],[119.959957,35.759124],[119.969935,35.74907],[119.967794,35.740347],[119.972108,35.73765],[119.978454,35.739506],[119.986073,35.729687],[119.981682,35.719629],[119.981216,35.71533],[119.990046,35.715362],[120.001497,35.720216],[120.006603,35.718614],[120.011072,35.713235],[120.020615,35.72331],[120.021313,35.729418],[120.024665,35.734954],[120.031353,35.752258],[120.037544,35.753891],[120.037436,35.763057],[120.042882,35.76932],[120.0431,35.776772],[120.049446,35.782289],[120.04926,35.786458],[120.042122,35.798362],[120.033293,35.806001],[120.033184,35.816603],[120.036458,35.824747],[120.051572,35.852185],[120.056631,35.859565],[120.062807,35.871348],[120.071217,35.881545],[120.078712,35.885756],[120.084019,35.880373],[120.0908,35.881893],[120.102221,35.881909],[120.112493,35.885123],[120.118405,35.888527],[120.123992,35.895287],[120.12545,35.906715],[120.12798,35.90776],[120.135816,35.905402],[120.142706,35.909406],[120.137678,35.917873],[120.141899,35.919424],[120.143699,35.911464],[120.147733,35.907839],[120.156795,35.909137],[120.162289,35.916496],[120.168015,35.918443],[120.164151,35.921165],[120.169846,35.922241],[120.179296,35.936656],[120.192361,35.942621],[120.202215,35.944614],[120.207848,35.947351],[120.212456,35.945548],[120.210796,35.938428],[120.20327,35.935169],[120.194456,35.934014],[120.194999,35.926878],[120.188699,35.925343],[120.186139,35.9227],[120.184199,35.915673],[120.172142,35.904404],[120.171444,35.896743],[120.167906,35.892405],[120.16938,35.888558],[120.185223,35.88745],[120.202091,35.892057],[120.205179,35.898896],[120.203099,35.905259],[120.204372,35.910419],[120.209291,35.91762],[120.222046,35.924963],[120.233157,35.941577],[120.238324,35.946782],[120.246486,35.947462],[120.248752,35.95545],[120.251514,35.959373],[120.261724,35.965479],[120.269079,35.966507],[120.284659,35.965558],[120.299711,35.968072],[120.305095,35.971836],[120.3165,36.002148],[120.310619,36.008914],[120.309518,36.01413],[120.291161,36.017608],[120.285295,36.016311],[120.285652,36.012692],[120.277754,36.008772],[120.274604,36.004677],[120.278793,35.996362],[120.271283,35.993959],[120.268785,35.994844],[120.265588,36.001057],[120.259381,35.99886],[120.260886,35.99214],[120.256386,35.989342],[120.254896,35.980835],[120.249946,35.979791],[120.247696,35.982558],[120.248798,35.992077],[120.256417,36.005436],[120.265526,36.01402],[120.265526,36.01579],[120.257007,36.024815],[120.24495,36.020437],[120.234413,36.013182],[120.227229,36.006843],[120.213248,35.998354],[120.206203,35.995824],[120.198848,35.995729],[120.196427,35.999492],[120.202525,35.999097],[120.223598,36.01639],[120.223644,36.022397],[120.234801,36.03063],[120.232722,36.032385],[120.235267,36.036477],[120.229789,36.040017],[120.230581,36.044931],[120.237393,36.045326],[120.240977,36.047822],[120.242886,36.055137],[120.241381,36.060445],[120.231884,36.063842],[120.194984,36.064205],[120.181623,36.066527],[120.17419,36.071629],[120.173911,36.077236],[120.168061,36.081184],[120.16187,36.0827],[120.152125,36.095255],[120.14193,36.098397],[120.120702,36.100813],[120.116854,36.102865],[120.116016,36.114043],[120.108614,36.127428],[120.091467,36.130333],[120.084112,36.133189],[120.078557,36.13764],[120.071357,36.140086],[120.058058,36.136772],[120.051758,36.14067],[120.042401,36.141569],[120.036737,36.138934],[120.028498,36.138729],[120.019373,36.145483],[120.012235,36.144426],[120.008387,36.133552],[120.008853,36.130633],[120.014439,36.129701],[120.014284,36.123956],[120.010311,36.124003],[120.010218,36.114169],[119.999837,36.110538],[120.007223,36.109275],[120.012018,36.092554],[120.007115,36.087722],[120.001016,36.087106],[120.000334,36.083932],[119.98823,36.084438],[119.984615,36.090486],[119.978982,36.089712],[119.985918,36.080489],[119.983311,36.07583],[119.984242,36.070413],[119.975289,36.064252],[119.969904,36.073287],[119.962952,36.070934],[119.94939,36.06858],[119.941864,36.063368],[119.9317,36.06073],[119.922979,36.062025],[119.9137,36.059103],[119.911155,36.054063],[119.905538,36.056986],[119.893388,36.052388],[119.893295,36.049766],[119.885474,36.051598],[119.878584,36.0452],[119.875232,36.044552],[119.87441,36.050287],[119.866201,36.054853],[119.865348,36.058234],[119.858039,36.060366],[119.851506,36.059039],[119.840241,36.051788],[119.836408,36.054458],[119.826725,36.050003],[119.821356,36.049971],[119.818361,36.044125],[119.823885,36.040238],[119.820751,36.036999],[119.820022,36.032179],[119.813225,36.028781],[119.813892,36.026853],[119.797661,36.02758],[119.793735,36.031752],[119.788304,36.031452],[119.78264,36.02355],[119.782919,36.016801],[119.781026,36.011206],[119.77288,36.010321],[119.769683,36.012818],[119.76329,36.010969],[119.762328,36.016912],[119.755997,36.021432],[119.743335,36.019394],[119.743226,36.024467],[119.736972,36.024909],[119.73404,36.032416],[119.729338,36.037267],[119.721315,36.036462],[119.720353,36.040649],[119.717048,36.04185]]],[[[119.926657,35.62913],[119.924221,35.625334],[119.930024,35.623539],[119.929574,35.62886],[119.932988,35.629686],[119.935967,35.634895],[119.93468,35.6375],[119.9272,35.632132],[119.926657,35.62913]]],[[[119.73525,35.595752],[119.738741,35.587505],[119.741845,35.583897],[119.743645,35.591335],[119.738866,35.599677],[119.73525,35.595752]]],[[[120.158859,35.764976],[120.156392,35.761233],[120.15543,35.751814],[120.158673,35.744883],[120.166525,35.74087],[120.173042,35.741425],[120.187939,35.748705],[120.191989,35.752702],[120.192873,35.757158],[120.184711,35.766958],[120.182166,35.776883],[120.182741,35.785015],[120.180522,35.788645],[120.172096,35.785745],[120.169954,35.779388],[120.158859,35.764976]]],[[[119.841963,35.615151],[119.838968,35.613594],[119.841327,35.610179],[119.841963,35.615151]]],[[[120.159511,35.910007],[120.161808,35.906874],[120.163033,35.910546],[120.159511,35.910007]]],[[[120.181127,35.934884],[120.180956,35.929346],[120.183827,35.933555],[120.181127,35.934884]]],[[[120.311706,35.944472],[120.314856,35.938681],[120.320038,35.942827],[120.314778,35.947557],[120.311706,35.944472]]]]}},{"type":"Feature","properties":{"name":"崂山区","adcode":370212},"geometry":{"type":"MultiPolygon","coordinates":[[[[120.484492,36.215752],[120.497775,36.211479],[120.511275,36.208688],[120.509863,36.201577],[120.507178,36.197351],[120.508218,36.191122],[120.501747,36.185144],[120.503376,36.179308],[120.493802,36.175018],[120.491056,36.165647],[120.483375,36.15828],[120.476919,36.157633],[120.462938,36.151889],[120.453271,36.143684],[120.433471,36.143037],[120.430041,36.14411],[120.425526,36.138113],[120.419986,36.134357],[120.411017,36.128076],[120.416339,36.124666],[120.434309,36.097592],[120.420219,36.094797],[120.41966,36.090991],[120.422267,36.077789],[120.413546,36.074677],[120.423245,36.065769],[120.42115,36.065058],[120.426565,36.059924],[120.426658,36.056417],[120.431779,36.051899],[120.433641,36.054869],[120.430802,36.058186],[120.432896,36.062831],[120.437179,36.0655],[120.440934,36.063573],[120.449671,36.073003],[120.460347,36.081784],[120.463295,36.081674],[120.467593,36.087154],[120.479837,36.091654],[120.487331,36.090612],[120.497837,36.086238],[120.510577,36.090344],[120.517668,36.09036],[120.52628,36.093455],[120.538896,36.090849],[120.541161,36.093312],[120.548051,36.092412],[120.552163,36.100481],[120.547368,36.106733],[120.547213,36.109543],[120.551806,36.111548],[120.555344,36.108154],[120.56706,36.105975],[120.572336,36.108612],[120.573298,36.114248],[120.577286,36.115148],[120.580808,36.111422],[120.579241,36.103939],[120.585743,36.101034],[120.599817,36.101807],[120.607855,36.107223],[120.612122,36.117516],[120.615567,36.120104],[120.621293,36.119252],[120.632233,36.113317],[120.643173,36.114737],[120.650978,36.117879],[120.672687,36.129828],[120.675821,36.130033],[120.686156,36.12574],[120.695683,36.123767],[120.712209,36.126576],[120.719797,36.134405],[120.718153,36.140986],[120.712334,36.141917],[120.705413,36.139707],[120.703613,36.142453],[120.704327,36.152347],[120.697856,36.154367],[120.698321,36.158863],[120.707027,36.159352],[120.708842,36.163738],[120.697142,36.168582],[120.69469,36.177131],[120.694814,36.185097],[120.692999,36.190617],[120.696739,36.204021],[120.689213,36.230176],[120.681982,36.237648],[120.681345,36.242928],[120.690221,36.253171],[120.685861,36.260215],[120.68628,36.279121],[120.675852,36.281295],[120.669102,36.276522],[120.65973,36.27482],[120.654826,36.27983],[120.653678,36.284178],[120.656005,36.288604],[120.665735,36.297471],[120.66783,36.304007],[120.666371,36.30933],[120.660723,36.314621],[120.660319,36.320793],[120.656037,36.322163],[120.653787,36.320462],[120.636671,36.321092],[120.633288,36.325217],[120.632435,36.332427],[120.634281,36.340046],[120.62944,36.338504],[120.62539,36.341494],[120.619586,36.333844],[120.619012,36.321722],[120.609174,36.326225],[120.595007,36.326051],[120.584889,36.32824],[120.581274,36.325988],[120.57066,36.327374],[120.570318,36.320069],[120.567184,36.32021],[120.567541,36.315676],[120.57156,36.311692],[120.572848,36.306322],[120.578372,36.301424],[120.576789,36.298338],[120.580281,36.288746],[120.577006,36.281689],[120.570846,36.272221],[120.572708,36.268251],[120.562777,36.257158],[120.554258,36.256354],[120.537018,36.257158],[120.528732,36.258419],[120.508963,36.253108],[120.506759,36.244393],[120.495432,36.233266],[120.492763,36.225889],[120.486307,36.220797],[120.484492,36.215752]]],[[[120.584424,36.09617],[120.57952,36.091544],[120.589405,36.088575],[120.595007,36.090281],[120.594464,36.09317],[120.589157,36.095049],[120.590026,36.098839],[120.584424,36.09617]]],[[[120.87733,35.893577],[120.875375,35.888432],[120.882435,35.892121],[120.888782,35.897281],[120.884561,35.897946],[120.87733,35.893577]]],[[[120.734058,36.229341],[120.738124,36.227575],[120.739598,36.230413],[120.734058,36.229341]]],[[[120.818643,36.234085],[120.818954,36.227087],[120.82215,36.228584],[120.823904,36.235583],[120.821871,36.237663],[120.818643,36.234085]]],[[[120.949579,36.181327],[120.955088,36.177116],[120.954529,36.181753],[120.949579,36.181327]]],[[[120.494687,35.962616],[120.494345,35.959468],[120.500149,35.958883],[120.500816,35.961366],[120.494687,35.962616]]],[[[120.775055,36.237963],[120.772215,36.239397],[120.768041,36.230712],[120.771501,36.224612],[120.777429,36.222294],[120.778593,36.227402],[120.775055,36.237963]]],[[[120.721598,36.286934],[120.720868,36.279326],[120.726858,36.280539],[120.725446,36.288352],[120.721598,36.286934]]]]}},{"type":"Feature","properties":{"name":"李沧区","adcode":370213},"geometry":{"type":"MultiPolygon","coordinates":[[[[120.343439,36.208341],[120.351539,36.20287],[120.358739,36.200331],[120.362339,36.196137],[120.368763,36.183046],[120.369492,36.177762],[120.358258,36.174781],[120.356054,36.171169],[120.356939,36.166058],[120.35174,36.160899],[120.371044,36.152442],[120.379206,36.1514],[120.383179,36.154556],[120.39415,36.154998],[120.400636,36.152047],[120.404391,36.139739],[120.409962,36.135367],[120.419986,36.134357],[120.425526,36.138113],[120.430041,36.14411],[120.433471,36.143037],[120.453271,36.143684],[120.462938,36.151889],[120.476919,36.157633],[120.483375,36.15828],[120.491056,36.165647],[120.493802,36.175018],[120.503376,36.179308],[120.501747,36.185144],[120.508218,36.191122],[120.507178,36.197351],[120.509863,36.201577],[120.511275,36.208688],[120.497775,36.211479],[120.484492,36.215752],[120.47228,36.204699],[120.465064,36.201009],[120.461324,36.202082],[120.453985,36.199764],[120.452185,36.202854],[120.443309,36.208042],[120.437505,36.205346],[120.425743,36.203974],[120.423648,36.209067],[120.428024,36.214964],[120.425945,36.2187],[120.421491,36.218716],[120.419164,36.222689],[120.410629,36.228773],[120.409977,36.231705],[120.400108,36.230318],[120.391294,36.231138],[120.390643,36.234164],[120.38532,36.238436],[120.37421,36.237553],[120.368779,36.233944],[120.370796,36.229672],[120.364837,36.226645],[120.365427,36.223839],[120.354332,36.223161],[120.349196,36.224233],[120.343439,36.208341]]]]}},{"type":"Feature","properties":{"name":"城阳区","adcode":370214},"geometry":{"type":"MultiPolygon","coordinates":[[[[120.57066,36.327374],[120.566191,36.327846],[120.559705,36.331624],[120.559658,36.334505],[120.546934,36.340251],[120.54501,36.335607],[120.547446,36.33397],[120.546825,36.328791],[120.549991,36.3292],[120.544498,36.323942],[120.538089,36.324162],[120.531789,36.327043],[120.531665,36.331939],[120.525334,36.337496],[120.518583,36.338818],[120.519515,36.335025],[120.51309,36.333986],[120.507814,36.335717],[120.507147,36.332742],[120.511244,36.332002],[120.508978,36.328586],[120.489892,36.328444],[120.486416,36.324587],[120.47813,36.324697],[120.4765,36.327169],[120.471193,36.327106],[120.469207,36.329452],[120.472357,36.336504],[120.470061,36.34247],[120.465731,36.340818],[120.463295,36.345949],[120.462023,36.342612],[120.454652,36.340518],[120.447017,36.3363],[120.436434,36.33896],[120.424253,36.345429],[120.419319,36.342943],[120.416308,36.345728],[120.416526,36.352984],[120.410086,36.352481],[120.406362,36.357312],[120.406796,36.361105],[120.400946,36.364409],[120.395856,36.364755],[120.393187,36.358005],[120.394863,36.352166],[120.406486,36.348074],[120.404593,36.341463],[120.39941,36.333451],[120.392877,36.327327],[120.385708,36.327626],[120.380168,36.325831],[120.375017,36.317518],[120.370594,36.316605],[120.366404,36.319502],[120.367413,36.310715],[120.359732,36.310432],[120.35728,36.315266],[120.358894,36.321123],[120.350266,36.321706],[120.34122,36.329216],[120.341142,36.341919],[120.32952,36.341982],[120.323514,36.344658],[120.312187,36.344595],[120.311737,36.342675],[120.302612,36.343257],[120.303776,36.33386],[120.296235,36.335119],[120.291347,36.338047],[120.288755,36.344485],[120.28154,36.346752],[120.281059,36.35237],[120.278359,36.35662],[120.268738,36.35673],[120.268598,36.358445],[120.259955,36.358587],[120.25814,36.365338],[120.249527,36.367934],[120.255859,36.367824],[120.252119,36.389787],[120.243972,36.387491],[120.224467,36.39232],[120.224374,36.39943],[120.2148,36.394837],[120.217996,36.389709],[120.218105,36.371915],[120.220975,36.365637],[120.216025,36.358571],[120.211836,36.350167],[120.211789,36.339606],[120.204496,36.340109],[120.204201,36.333073],[120.19908,36.331483],[120.199437,36.327862],[120.19427,36.327232],[120.190251,36.322194],[120.191198,36.317801],[120.183842,36.315959],[120.184246,36.314022],[120.177511,36.312022],[120.179032,36.305834],[120.174051,36.300542],[120.163623,36.297125],[120.164508,36.292368],[120.150837,36.292069],[120.151225,36.287281],[120.146647,36.287864],[120.142721,36.280681],[120.120299,36.274537],[120.116078,36.270756],[120.119802,36.267069],[120.125854,36.265021],[120.122859,36.260908],[120.12078,36.253865],[120.114386,36.258135],[120.107667,36.253534],[120.111842,36.239208],[120.113719,36.239303],[120.114728,36.224706],[120.108335,36.227244],[120.107202,36.223981],[120.112416,36.218542],[120.120888,36.21993],[120.124814,36.21859],[120.12365,36.213434],[120.114511,36.209177],[120.117055,36.203942],[120.127747,36.205141],[120.132371,36.203863],[120.13473,36.200095],[120.133271,36.195064],[120.124426,36.196073],[120.118328,36.190428],[120.122176,36.186721],[120.131456,36.183267],[120.140378,36.173314],[120.144925,36.178283],[120.164321,36.188772],[120.174423,36.199085],[120.181546,36.203958],[120.207196,36.211621],[120.217313,36.211416],[120.221627,36.205771],[120.224436,36.191311],[120.228657,36.18792],[120.235034,36.189229],[120.240279,36.196357],[120.244795,36.199369],[120.260933,36.198423],[120.263555,36.193724],[120.259241,36.189213],[120.262997,36.182274],[120.271888,36.181611],[120.277691,36.185523],[120.280733,36.179308],[120.284814,36.179687],[120.291502,36.185964],[120.310247,36.185286],[120.313537,36.188645],[120.313211,36.196342],[120.310697,36.199464],[120.303016,36.203469],[120.298314,36.2038],[120.294295,36.211905],[120.293286,36.219236],[120.297368,36.225479],[120.305142,36.229073],[120.320007,36.232257],[120.343439,36.208341],[120.349196,36.224233],[120.354332,36.223161],[120.365427,36.223839],[120.364837,36.226645],[120.370796,36.229672],[120.368779,36.233944],[120.37421,36.237553],[120.38532,36.238436],[120.390643,36.234164],[120.391294,36.231138],[120.400108,36.230318],[120.409977,36.231705],[120.410629,36.228773],[120.419164,36.222689],[120.421491,36.218716],[120.425945,36.2187],[120.428024,36.214964],[120.423648,36.209067],[120.425743,36.203974],[120.437505,36.205346],[120.443309,36.208042],[120.452185,36.202854],[120.453985,36.199764],[120.461324,36.202082],[120.465064,36.201009],[120.47228,36.204699],[120.484492,36.215752],[120.486307,36.220797],[120.492763,36.225889],[120.495432,36.233266],[120.506759,36.244393],[120.508963,36.253108],[120.528732,36.258419],[120.537018,36.257158],[120.554258,36.256354],[120.562777,36.257158],[120.572708,36.268251],[120.570846,36.272221],[120.577006,36.281689],[120.580281,36.288746],[120.576789,36.298338],[120.578372,36.301424],[120.572848,36.306322],[120.57156,36.311692],[120.567541,36.315676],[120.567184,36.32021],[120.570318,36.320069],[120.57066,36.327374]]]]}},{"type":"Feature","properties":{"name":"即墨区","adcode":370215},"geometry":{"type":"MultiPolygon","coordinates":[[[[120.656037,36.322163],[120.663004,36.331782],[120.666899,36.332726],[120.670095,36.328712],[120.684418,36.328271],[120.692114,36.325532],[120.707973,36.328932],[120.715856,36.328318],[120.738201,36.323721],[120.738605,36.327641],[120.744439,36.328145],[120.74492,36.330774],[120.740761,36.33408],[120.739629,36.338614],[120.729573,36.349805],[120.726718,36.359814],[120.722715,36.362191],[120.716508,36.360507],[120.709727,36.368107],[120.700401,36.371223],[120.696366,36.376163],[120.69438,36.390149],[120.697033,36.393987],[120.705025,36.398911],[120.709928,36.407121],[120.716958,36.412012],[120.725989,36.413899],[120.727029,36.422941],[120.732056,36.430472],[120.736867,36.432831],[120.751034,36.43129],[120.760112,36.43456],[120.761632,36.443191],[120.758172,36.449809],[120.75676,36.458108],[120.75946,36.462602],[120.828481,36.466641],[120.830173,36.462414],[120.837016,36.459962],[120.841283,36.462508],[120.842975,36.45773],[120.842369,36.441587],[120.838335,36.436997],[120.839825,36.434167],[120.845954,36.432941],[120.858926,36.424592],[120.861983,36.419261],[120.859532,36.412405],[120.849213,36.403142],[120.852471,36.395623],[120.852875,36.386421],[120.854938,36.38189],[120.862092,36.377013],[120.874397,36.373252],[120.875747,36.370751],[120.872023,36.36699],[120.884142,36.372497],[120.891125,36.373363],[120.895889,36.376084],[120.89741,36.382079],[120.891653,36.389677],[120.903337,36.406146],[120.915844,36.414811],[120.91842,36.418758],[120.924115,36.415817],[120.922625,36.411587],[120.927777,36.410062],[120.933627,36.413537],[120.936203,36.418349],[120.935086,36.421054],[120.925558,36.41989],[120.918777,36.425378],[120.91738,36.435362],[120.907853,36.445973],[120.908908,36.450233],[120.915332,36.451632],[120.920127,36.4552],[120.931656,36.455719],[120.934527,36.454681],[120.938313,36.448111],[120.947236,36.449274],[120.952403,36.459176],[120.963591,36.464331],[120.968727,36.474373],[120.967688,36.477956],[120.954964,36.489331],[120.954777,36.493148],[120.95861,36.498725],[120.954343,36.507585],[120.962738,36.519207],[120.973678,36.531141],[120.983919,36.540813],[120.983298,36.5459],[120.969348,36.559494],[120.957664,36.563811],[120.952558,36.563277],[120.936358,36.565333],[120.930353,36.567075],[120.923758,36.572019],[120.919956,36.572019],[120.912663,36.568425],[120.893406,36.579191],[120.891327,36.582565],[120.891994,36.588982],[120.88484,36.601408],[120.881008,36.603667],[120.86594,36.605612],[120.858538,36.610208],[120.850082,36.612263],[120.786227,36.589657],[120.779726,36.591555],[120.7803,36.594678],[120.777057,36.600545],[120.765527,36.607008],[120.757551,36.606083],[120.751531,36.61504],[120.741755,36.61642],[120.738372,36.618427],[120.733484,36.615698],[120.731436,36.620059],[120.734787,36.619635],[120.727106,36.624293],[120.708299,36.621407],[120.708377,36.612922],[120.699097,36.606648],[120.702977,36.598349],[120.692363,36.59827],[120.692285,36.595776],[120.686559,36.593893],[120.680507,36.589139],[120.671616,36.58928],[120.669785,36.586377],[120.665362,36.587476],[120.664447,36.584008],[120.653833,36.578877],[120.648805,36.579018],[120.637742,36.574216],[120.635755,36.577057],[120.635678,36.587743],[120.634452,36.588998],[120.62719,36.588951],[120.62736,36.591289],[120.6212,36.590583],[120.61701,36.58404],[120.6131,36.584636],[120.607188,36.59008],[120.595953,36.588088],[120.595767,36.591132],[120.591345,36.596921],[120.591205,36.603055],[120.588753,36.598741],[120.583679,36.601659],[120.580281,36.60078],[120.584532,36.595666],[120.583617,36.592104],[120.575719,36.590363],[120.576851,36.58043],[120.563243,36.578641],[120.557936,36.572113],[120.54352,36.57249],[120.541922,36.575613],[120.542387,36.584353],[120.537577,36.588511],[120.538244,36.595023],[120.541611,36.595964],[120.544265,36.600686],[120.54113,36.6066],[120.535761,36.61264],[120.531075,36.613769],[120.535823,36.615887],[120.535854,36.620811],[120.528406,36.62078],[120.52299,36.618224],[120.523766,36.621925],[120.520911,36.624591],[120.51098,36.628935],[120.503982,36.629704],[120.495013,36.622521],[120.492344,36.61802],[120.486199,36.617455],[120.484523,36.610946],[120.477137,36.610632],[120.476904,36.608044],[120.465498,36.609346],[120.462069,36.607087],[120.458733,36.611118],[120.459385,36.61689],[120.429188,36.616012],[120.420948,36.613832],[120.420389,36.615996],[120.406238,36.620121],[120.407184,36.62216],[120.401598,36.623807],[120.401319,36.627336],[120.385413,36.62398],[120.379936,36.615839],[120.368872,36.618396],[120.372937,36.625046],[120.37286,36.630331],[120.366932,36.631382],[120.36431,36.620529],[120.343035,36.62205],[120.34212,36.627445],[120.337946,36.628088],[120.335696,36.624419],[120.325082,36.621831],[120.325997,36.624732],[120.320985,36.624058],[120.314933,36.626128],[120.314126,36.622129],[120.30584,36.622035],[120.305654,36.618396],[120.300099,36.61711],[120.280469,36.618443],[120.27271,36.621831],[120.27029,36.617251],[120.265681,36.617455],[120.259459,36.621078],[120.253484,36.628261],[120.243786,36.63168],[120.235391,36.631711],[120.226515,36.62514],[120.218291,36.624654],[120.213294,36.622286],[120.209182,36.617126],[120.204667,36.614553],[120.203968,36.610522],[120.206529,36.597502],[120.203317,36.594144],[120.193525,36.590269],[120.188203,36.585342],[120.177744,36.584071],[120.16727,36.579049],[120.162273,36.58087],[120.155678,36.573023],[120.155477,36.56469],[120.152776,36.554769],[120.143218,36.54243],[120.14674,36.533858],[120.159232,36.525567],[120.161202,36.519772],[120.157773,36.514652],[120.157292,36.507914],[120.166882,36.498317],[120.167192,36.488294],[120.175665,36.484445],[120.177977,36.480454],[120.174982,36.472723],[120.170559,36.471843],[120.161761,36.47497],[120.157882,36.474656],[120.155787,36.471026],[120.156221,36.463734],[120.15363,36.460088],[120.140285,36.456536],[120.137057,36.453801],[120.135785,36.443175],[120.142768,36.441257],[120.160008,36.44044],[120.162133,36.434356],[120.165268,36.43368],[120.165315,36.427186],[120.158999,36.426353],[120.156858,36.422076],[120.151147,36.41989],[120.153692,36.410518],[120.148339,36.404148],[120.153661,36.387884],[120.159356,36.383856],[120.168325,36.383778],[120.168309,36.381921],[120.17492,36.381119],[120.175261,36.378271],[120.183889,36.376714],[120.185627,36.373772],[120.18212,36.372686],[120.184913,36.370027],[120.196846,36.367792],[120.201641,36.362678],[120.20853,36.362757],[120.216025,36.358571],[120.220975,36.365637],[120.218105,36.371915],[120.217996,36.389709],[120.2148,36.394837],[120.224374,36.39943],[120.224467,36.39232],[120.243972,36.387491],[120.252119,36.389787],[120.255859,36.367824],[120.249527,36.367934],[120.25814,36.365338],[120.259955,36.358587],[120.268598,36.358445],[120.268738,36.35673],[120.278359,36.35662],[120.281059,36.35237],[120.28154,36.346752],[120.288755,36.344485],[120.291347,36.338047],[120.296235,36.335119],[120.303776,36.33386],[120.302612,36.343257],[120.311737,36.342675],[120.312187,36.344595],[120.323514,36.344658],[120.32952,36.341982],[120.341142,36.341919],[120.34122,36.329216],[120.350266,36.321706],[120.358894,36.321123],[120.35728,36.315266],[120.359732,36.310432],[120.367413,36.310715],[120.366404,36.319502],[120.370594,36.316605],[120.375017,36.317518],[120.380168,36.325831],[120.385708,36.327626],[120.392877,36.327327],[120.39941,36.333451],[120.404593,36.341463],[120.406486,36.348074],[120.394863,36.352166],[120.393187,36.358005],[120.395856,36.364755],[120.400946,36.364409],[120.406796,36.361105],[120.406362,36.357312],[120.410086,36.352481],[120.416526,36.352984],[120.416308,36.345728],[120.419319,36.342943],[120.424253,36.345429],[120.436434,36.33896],[120.447017,36.3363],[120.454652,36.340518],[120.462023,36.342612],[120.463295,36.345949],[120.465731,36.340818],[120.470061,36.34247],[120.472357,36.336504],[120.469207,36.329452],[120.471193,36.327106],[120.4765,36.327169],[120.47813,36.324697],[120.486416,36.324587],[120.489892,36.328444],[120.508978,36.328586],[120.511244,36.332002],[120.507147,36.332742],[120.507814,36.335717],[120.51309,36.333986],[120.519515,36.335025],[120.518583,36.338818],[120.525334,36.337496],[120.531665,36.331939],[120.531789,36.327043],[120.538089,36.324162],[120.544498,36.323942],[120.549991,36.3292],[120.546825,36.328791],[120.547446,36.33397],[120.54501,36.335607],[120.546934,36.340251],[120.559658,36.334505],[120.559705,36.331624],[120.566191,36.327846],[120.57066,36.327374],[120.581274,36.325988],[120.584889,36.32824],[120.595007,36.326051],[120.609174,36.326225],[120.619012,36.321722],[120.619586,36.333844],[120.62539,36.341494],[120.62944,36.338504],[120.634281,36.340046],[120.632435,36.332427],[120.633288,36.325217],[120.636671,36.321092],[120.653787,36.320462],[120.656037,36.322163]]],[[[120.990033,36.413348],[120.99295,36.414559],[120.993385,36.419591],[120.986759,36.420047],[120.978116,36.428633],[120.969783,36.431573],[120.9664,36.429875],[120.967191,36.426447],[120.963902,36.424639],[120.955801,36.425724],[120.948539,36.421117],[120.947577,36.417673],[120.950339,36.414779],[120.963638,36.413647],[120.968727,36.41577],[120.981452,36.4175],[120.990033,36.413348]]],[[[121.004262,36.48831],[121.003145,36.490368],[120.989862,36.492379],[120.98755,36.491075],[120.989459,36.485262],[121.004262,36.48831]]],[[[121.014023,36.440204],[121.01213,36.43195],[121.017902,36.432862],[121.016211,36.439213],[121.014023,36.440204]]],[[[120.932556,36.40635],[120.930151,36.402355],[120.933022,36.40105],[120.935877,36.40451],[120.932556,36.40635]]],[[[120.858321,36.375015],[120.854659,36.372922],[120.856894,36.368768],[120.86307,36.367556],[120.864016,36.371884],[120.858321,36.375015]]],[[[120.939338,36.411634],[120.93417,36.411052],[120.93895,36.406963],[120.942907,36.409244],[120.939338,36.411634]]],[[[121.062654,36.5459],[121.059504,36.539604],[121.065044,36.538427],[121.066549,36.54174],[121.062654,36.5459]]]]}},{"type":"Feature","properties":{"name":"胶州市","adcode":370281},"geometry":{"type":"MultiPolygon","coordinates":[[[[119.717048,36.04185],[119.720353,36.040649],[119.721315,36.036462],[119.729338,36.037267],[119.73404,36.032416],[119.736972,36.024909],[119.743226,36.024467],[119.743335,36.019394],[119.755997,36.021432],[119.762328,36.016912],[119.76329,36.010969],[119.769683,36.012818],[119.77288,36.010321],[119.781026,36.011206],[119.782919,36.016801],[119.78264,36.02355],[119.788304,36.031452],[119.793735,36.031752],[119.797661,36.02758],[119.813892,36.026853],[119.813225,36.028781],[119.820022,36.032179],[119.820751,36.036999],[119.823885,36.040238],[119.818361,36.044125],[119.821356,36.049971],[119.826725,36.050003],[119.836408,36.054458],[119.840241,36.051788],[119.851506,36.059039],[119.858039,36.060366],[119.865348,36.058234],[119.866201,36.054853],[119.87441,36.050287],[119.875232,36.044552],[119.878584,36.0452],[119.885474,36.051598],[119.893295,36.049766],[119.893388,36.052388],[119.905538,36.056986],[119.911155,36.054063],[119.9137,36.059103],[119.922979,36.062025],[119.9317,36.06073],[119.941864,36.063368],[119.94939,36.06858],[119.962952,36.070934],[119.969904,36.073287],[119.975289,36.064252],[119.984242,36.070413],[119.983311,36.07583],[119.985918,36.080489],[119.978982,36.089712],[119.984615,36.090486],[119.98823,36.084438],[120.000334,36.083932],[120.001016,36.087106],[120.007115,36.087722],[120.012018,36.092554],[120.007223,36.109275],[119.999837,36.110538],[120.010218,36.114169],[120.010311,36.124003],[120.014284,36.123956],[120.014439,36.129701],[120.008853,36.130633],[120.008387,36.133552],[120.012235,36.144426],[120.019373,36.145483],[120.028498,36.138729],[120.036737,36.138934],[120.042401,36.141569],[120.051758,36.14067],[120.058058,36.136772],[120.071357,36.140086],[120.078557,36.13764],[120.084112,36.133189],[120.091467,36.130333],[120.108614,36.127428],[120.128104,36.129733],[120.13594,36.134641],[120.142535,36.143526],[120.140378,36.173314],[120.131456,36.183267],[120.122176,36.186721],[120.118328,36.190428],[120.124426,36.196073],[120.133271,36.195064],[120.13473,36.200095],[120.132371,36.203863],[120.127747,36.205141],[120.117055,36.203942],[120.114511,36.209177],[120.12365,36.213434],[120.124814,36.21859],[120.120888,36.21993],[120.112416,36.218542],[120.107202,36.223981],[120.108335,36.227244],[120.114728,36.224706],[120.113719,36.239303],[120.111842,36.239208],[120.107667,36.253534],[120.114386,36.258135],[120.12078,36.253865],[120.122859,36.260908],[120.125854,36.265021],[120.119802,36.267069],[120.116078,36.270756],[120.120299,36.274537],[120.142721,36.280681],[120.146647,36.287864],[120.151225,36.287281],[120.150837,36.292069],[120.164508,36.292368],[120.163623,36.297125],[120.174051,36.300542],[120.179032,36.305834],[120.177511,36.312022],[120.184246,36.314022],[120.183842,36.315959],[120.191198,36.317801],[120.190251,36.322194],[120.19427,36.327232],[120.199437,36.327862],[120.19908,36.331483],[120.204201,36.333073],[120.204496,36.340109],[120.211789,36.339606],[120.211836,36.350167],[120.216025,36.358571],[120.20853,36.362757],[120.201641,36.362678],[120.196846,36.367792],[120.184913,36.370027],[120.18212,36.372686],[120.185627,36.373772],[120.183889,36.376714],[120.175261,36.378271],[120.17492,36.381119],[120.168309,36.381921],[120.168325,36.383778],[120.159356,36.383856],[120.153661,36.387884],[120.148339,36.404148],[120.153692,36.410518],[120.151147,36.41989],[120.156858,36.422076],[120.158999,36.426353],[120.165315,36.427186],[120.165268,36.43368],[120.162133,36.434356],[120.160008,36.44044],[120.142768,36.441257],[120.135785,36.443175],[120.137057,36.453801],[120.140285,36.456536],[120.15363,36.460088],[120.156221,36.463734],[120.155787,36.471026],[120.157882,36.474656],[120.161761,36.47497],[120.170559,36.471843],[120.16879,36.478364],[120.162801,36.48014],[120.160877,36.482858],[120.138625,36.484586],[120.13909,36.487618],[120.129252,36.48787],[120.13023,36.492457],[120.125792,36.492379],[120.117118,36.487917],[120.116031,36.483691],[120.077983,36.488325],[120.077952,36.486267],[120.064607,36.483172],[120.061922,36.476259],[120.054039,36.476997],[120.053776,36.480407],[120.041672,36.48754],[120.040043,36.490415],[120.036008,36.487917],[120.038025,36.485246],[120.031974,36.481695],[120.008077,36.498223],[120.007006,36.498977],[120.004182,36.489519],[120.004927,36.485639],[120.010715,36.484429],[120.004089,36.477453],[120.006882,36.468826],[120.012779,36.467836],[120.014827,36.463451],[120.011103,36.462162],[120.011848,36.454241],[120.005253,36.453204],[120.005904,36.448567],[120.001637,36.446067],[119.99664,36.446319],[119.994142,36.450327],[119.968399,36.45006],[119.958871,36.448048],[119.953952,36.444244],[119.949219,36.446523],[119.945014,36.439198],[119.941042,36.435739],[119.940157,36.428868],[119.935952,36.427422],[119.933935,36.420047],[119.92526,36.41934],[119.924423,36.412483],[119.92644,36.403346],[119.930335,36.402874],[119.935176,36.398234],[119.941445,36.395041],[119.94548,36.384675],[119.936355,36.380663],[119.930319,36.385178],[119.921412,36.384281],[119.920341,36.385603],[119.909836,36.384376],[119.904281,36.381528],[119.906578,36.376006],[119.903365,36.37503],[119.904809,36.369917],[119.898322,36.366628],[119.900231,36.360428],[119.896258,36.349962],[119.898307,36.344879],[119.896972,36.334064],[119.891355,36.324729],[119.891991,36.318777],[119.87036,36.311597],[119.86541,36.308905],[119.864262,36.303834],[119.854408,36.302338],[119.852701,36.297613],[119.833863,36.278806],[119.833522,36.269448],[119.830449,36.265635],[119.830418,36.260562],[119.826523,36.257552],[119.819292,36.256575],[119.820891,36.244504],[119.817228,36.240406],[119.813721,36.240296],[119.808073,36.23284],[119.811409,36.229877],[119.814684,36.219031],[119.819509,36.211858],[119.828789,36.210707],[119.823156,36.198959],[119.827377,36.191311],[119.826166,36.187636],[119.831349,36.184923],[119.831722,36.180633],[119.822396,36.177999],[119.821309,36.171279],[119.81324,36.175239],[119.812992,36.167698],[119.802114,36.169181],[119.79839,36.167493],[119.797801,36.170585],[119.792307,36.171642],[119.790989,36.168203],[119.782811,36.165316],[119.774866,36.165821],[119.772352,36.167698],[119.762561,36.164764],[119.760714,36.161435],[119.754212,36.159037],[119.748098,36.158658],[119.74321,36.161845],[119.739114,36.160504],[119.733838,36.163549],[119.732783,36.172557],[119.729028,36.17475],[119.715838,36.176926],[119.713479,36.175302],[119.704184,36.176327],[119.698629,36.179198],[119.691693,36.176295],[119.685269,36.178882],[119.681917,36.183693],[119.681281,36.180428],[119.671055,36.177889],[119.668587,36.174986],[119.669161,36.168597],[119.665313,36.162729],[119.659634,36.161498],[119.660844,36.15413],[119.657492,36.154446],[119.657492,36.147597],[119.652465,36.143463],[119.649935,36.137151],[119.651192,36.130522],[119.645994,36.131074],[119.643713,36.127176],[119.652946,36.116316],[119.654001,36.110364],[119.657632,36.108644],[119.657042,36.100876],[119.643108,36.094876],[119.635566,36.093802],[119.632152,36.091528],[119.63434,36.082037],[119.631671,36.080758],[119.633596,36.067696],[119.646444,36.068328],[119.648027,36.065974],[119.659448,36.065484],[119.659541,36.063352],[119.66671,36.062989],[119.665748,36.05787],[119.672684,36.058534],[119.672048,36.061756],[119.675679,36.064079],[119.683965,36.057254],[119.695696,36.053036],[119.704138,36.055264],[119.711276,36.053305],[119.709693,36.049481],[119.717281,36.04422],[119.717048,36.04185]]]]}},{"type":"Feature","properties":{"name":"平度市","adcode":370283},"geometry":{"type":"MultiPolygon","coordinates":[[[[120.008077,36.498223],[120.031974,36.481695],[120.038025,36.485246],[120.036008,36.487917],[120.040043,36.490415],[120.041672,36.48754],[120.053776,36.480407],[120.054039,36.476997],[120.061922,36.476259],[120.064607,36.483172],[120.077952,36.486267],[120.077983,36.488325],[120.116031,36.483691],[120.117118,36.487917],[120.125792,36.492379],[120.13023,36.492457],[120.129252,36.48787],[120.13909,36.487618],[120.138625,36.484586],[120.160877,36.482858],[120.162801,36.48014],[120.16879,36.478364],[120.170559,36.471843],[120.174982,36.472723],[120.177977,36.480454],[120.175665,36.484445],[120.167192,36.488294],[120.166882,36.498317],[120.157292,36.507914],[120.157773,36.514652],[120.161202,36.519772],[120.159232,36.525567],[120.14674,36.533858],[120.143218,36.54243],[120.152776,36.554769],[120.155477,36.56469],[120.155678,36.573023],[120.162273,36.58087],[120.16727,36.579049],[120.177744,36.584071],[120.188203,36.585342],[120.193525,36.590269],[120.203317,36.594144],[120.206529,36.597502],[120.203968,36.610522],[120.204667,36.614553],[120.209182,36.617126],[120.213294,36.622286],[120.218291,36.624654],[120.226515,36.62514],[120.235391,36.631711],[120.243786,36.63168],[120.253484,36.628261],[120.260871,36.626536],[120.264533,36.628669],[120.267047,36.635976],[120.270476,36.638893],[120.279507,36.637764],[120.285016,36.638987],[120.292619,36.644318],[120.293768,36.656484],[120.298376,36.663021],[120.297988,36.667191],[120.293038,36.673507],[120.281679,36.678616],[120.277195,36.690229],[120.2742,36.69272],[120.27496,36.699818],[120.271857,36.703609],[120.272912,36.717646],[120.272881,36.73287],[120.275954,36.735611],[120.273626,36.74153],[120.274526,36.748999],[120.272167,36.756937],[120.269809,36.758284],[120.266566,36.766988],[120.26835,36.769226],[120.263928,36.776943],[120.261941,36.797022],[120.262624,36.801091],[120.272385,36.816924],[120.275364,36.833786],[120.282161,36.849003],[120.282036,36.852177],[120.286117,36.868704],[120.287545,36.880944],[120.291486,36.889181],[120.29518,36.893307],[120.294807,36.898917],[120.287126,36.907308],[120.281198,36.910402],[120.279973,36.914964],[120.281819,36.920464],[120.285636,36.922682],[120.298237,36.926135],[120.302768,36.929727],[120.309456,36.945737],[120.320256,36.957965],[120.320907,36.967146],[120.314809,36.975655],[120.304847,36.984381],[120.30525,36.988096],[120.310076,36.993496],[120.324213,36.998787],[120.32443,37.004343],[120.316113,37.006184],[120.307857,37.004827],[120.304785,37.009134],[120.298485,37.008182],[120.299804,37.005545],[120.293659,37.002658],[120.282843,37.003453],[120.272866,37.011037],[120.276807,37.020774],[120.282579,37.020665],[120.293705,37.023379],[120.298174,37.030166],[120.293985,37.030899],[120.290959,37.035579],[120.277754,37.039853],[120.269343,37.038917],[120.264316,37.036281],[120.253515,37.035064],[120.252057,37.030618],[120.242033,37.031008],[120.238138,37.032833],[120.240077,37.037295],[120.23522,37.044641],[120.230472,37.046887],[120.222775,37.042161],[120.213946,37.04238],[120.209105,37.044298],[120.205334,37.038387],[120.193401,37.034253],[120.190391,37.038168],[120.183547,37.035641],[120.180677,37.032537],[120.173011,37.034409],[120.171553,37.027233],[120.16637,37.025782],[120.167751,37.018371],[120.156904,37.012582],[120.155383,37.01525],[120.144382,37.014033],[120.142302,37.015282],[120.141697,37.021632],[120.138097,37.022194],[120.123045,37.016468],[120.117412,37.017575],[120.112136,37.015344],[120.101538,37.014283],[120.087045,37.018792],[120.076617,37.018964],[120.074398,37.016889],[120.067633,37.018886],[120.049338,37.020041],[120.044093,37.010054],[120.045117,37.006933],[120.040462,37.005747],[120.036474,36.999427],[120.031974,36.99771],[120.031989,37.001784],[120.025751,36.999365],[120.019436,37.005669],[120.011599,37.00645],[120.004927,37.009945],[120.002289,37.013487],[119.993506,37.012192],[119.984816,37.017903],[119.980192,37.018106],[119.975583,37.011115],[119.967188,37.014252],[119.959088,37.013066],[119.953006,37.009399],[119.94953,37.010866],[119.949685,37.006169],[119.939568,37.004093],[119.93665,37.000629],[119.923367,36.993949],[119.902279,36.994807],[119.90006,36.99757],[119.887538,36.998943],[119.88566,37.000613],[119.878165,36.999505],[119.851491,37.002049],[119.844725,37.000566],[119.829611,37.002033],[119.820192,36.999614],[119.820208,37.002455],[119.811518,37.006855],[119.811363,37.010944],[119.804954,37.013799],[119.796839,37.013924],[119.783369,37.007963],[119.771887,37.007011],[119.769931,36.996618],[119.762887,36.993091],[119.750566,36.990827],[119.750023,36.992575],[119.739657,36.991936],[119.731122,36.988486],[119.722309,36.993418],[119.721191,36.999926],[119.716971,37.007152],[119.70617,37.003547],[119.692779,37.000894],[119.688822,36.997882],[119.681731,36.998491],[119.682196,37.002439],[119.676113,37.002642],[119.662536,37.00826],[119.658594,37.007324],[119.655848,37.010335],[119.649827,37.012145],[119.640904,37.011053],[119.63988,37.014314],[119.629375,37.016218],[119.625961,37.01316],[119.619739,37.012879],[119.619102,37.017872],[119.61423,37.01756],[119.609776,37.013893],[119.604578,36.99604],[119.598061,36.989423],[119.587556,36.960697],[119.583754,36.952374],[119.586097,36.945643],[119.595035,36.932492],[119.599938,36.920604],[119.599054,36.866656],[119.597797,36.857259],[119.573714,36.81536],[119.567678,36.805722],[119.563721,36.802734],[119.556583,36.80447],[119.550593,36.808664],[119.539979,36.807036],[119.541919,36.803641],[119.546807,36.805534],[119.549041,36.802593],[119.545395,36.799902],[119.539126,36.799933],[119.537853,36.795207],[119.539188,36.787743],[119.53281,36.780089],[119.53056,36.765266],[119.534983,36.743331],[119.547086,36.725478],[119.551493,36.722658],[119.561021,36.720873],[119.567445,36.713087],[119.572535,36.714262],[119.579828,36.711584],[119.583397,36.702215],[119.587633,36.699426],[119.587416,36.696089],[119.596835,36.689398],[119.600218,36.679541],[119.603694,36.678005],[119.604407,36.672551],[119.607961,36.666736],[119.611561,36.666955],[119.617023,36.652549],[119.621694,36.644804],[119.620577,36.642468],[119.625123,36.638799],[119.63538,36.634549],[119.636684,36.631444],[119.641153,36.631005],[119.651254,36.623634],[119.653085,36.620827],[119.657306,36.623289],[119.669053,36.614538],[119.67048,36.616294],[119.681839,36.606883],[119.691786,36.606287],[119.70091,36.602757],[119.707722,36.596623],[119.715419,36.593705],[119.716381,36.590567],[119.730114,36.581011],[119.729415,36.574812],[119.726684,36.570261],[119.727553,36.562743],[119.733497,36.563873],[119.739719,36.567122],[119.739517,36.570167],[119.747509,36.571784],[119.75595,36.565537],[119.766657,36.564234],[119.76613,36.561707],[119.772119,36.560075],[119.784487,36.55466],[119.798033,36.551614],[119.813551,36.54535],[119.826741,36.541033],[119.837804,36.538835],[119.885645,36.53166],[119.893186,36.529508],[119.917564,36.525865],[119.920233,36.522081],[119.92301,36.495458],[119.936697,36.496369],[119.935471,36.50815],[119.936324,36.511527],[119.94503,36.517228],[119.953906,36.519615],[119.9533,36.523243],[119.959352,36.521484],[119.971983,36.522442],[119.974745,36.515705],[119.999046,36.50383],[120.000101,36.508747],[120.010342,36.509265],[120.008077,36.498223]]]]}},{"type":"Feature","properties":{"name":"莱西市","adcode":370285},"geometry":{"type":"MultiPolygon","coordinates":[[[[120.634452,36.588998],[120.635631,36.596796],[120.638921,36.599337],[120.640348,36.610083],[120.643436,36.613424],[120.64474,36.626536],[120.648712,36.628277],[120.657449,36.626646],[120.659435,36.629908],[120.65838,36.640257],[120.660568,36.647987],[120.654438,36.652894],[120.652685,36.650762],[120.648961,36.655857],[120.652173,36.663319],[120.646509,36.66324],[120.64204,36.666093],[120.6374,36.663021],[120.631767,36.662739],[120.62736,36.659855],[120.62511,36.671234],[120.630774,36.672379],[120.626585,36.67846],[120.619214,36.681516],[120.616514,36.689743],[120.609934,36.691764],[120.599181,36.691764],[120.589746,36.694506],[120.586146,36.698831],[120.593688,36.703296],[120.596512,36.708043],[120.594588,36.71716],[120.591546,36.716957],[120.589467,36.724319],[120.585277,36.7285],[120.584067,36.735235],[120.579784,36.737662],[120.57412,36.735094],[120.56256,36.736488],[120.560372,36.742485],[120.554056,36.742141],[120.550627,36.746055],[120.546437,36.744599],[120.544203,36.749391],[120.544544,36.762119],[120.540835,36.767896],[120.546934,36.770025],[120.548454,36.775785],[120.555391,36.778712],[120.559161,36.784049],[120.559068,36.78793],[120.563739,36.795332],[120.563475,36.802968],[120.582794,36.803547],[120.590724,36.801435],[120.601555,36.805002],[120.605481,36.810166],[120.605,36.817143],[120.607219,36.818316],[120.608972,36.824996],[120.612324,36.829219],[120.609826,36.832895],[120.602874,36.834271],[120.595953,36.838056],[120.589715,36.838791],[120.587527,36.843639],[120.595953,36.852678],[120.588381,36.859042],[120.579846,36.858901],[120.577177,36.862685],[120.579039,36.867687],[120.57651,36.874738],[120.576634,36.879896],[120.586131,36.882585],[120.592912,36.882147],[120.60067,36.885258],[120.609158,36.88371],[120.608646,36.886305],[120.61864,36.88854],[120.622814,36.890837],[120.621898,36.900792],[120.622814,36.907371],[120.619834,36.913168],[120.617398,36.911121],[120.600376,36.910511],[120.599786,36.912543],[120.592896,36.91223],[120.589296,36.919089],[120.586053,36.918198],[120.578806,36.926135],[120.575005,36.927041],[120.571777,36.938272],[120.574353,36.943519],[120.571094,36.948673],[120.566268,36.948673],[120.563196,36.951718],[120.560294,36.960666],[120.566563,36.965585],[120.568534,36.983288],[120.574027,36.987565],[120.57592,36.999053],[120.58236,37.001784],[120.585789,36.99821],[120.589576,36.998319],[120.590413,36.994089],[120.593843,36.991249],[120.600655,36.992154],[120.602905,37.000005],[120.606443,37.001191],[120.605714,37.011022],[120.601741,37.012707],[120.606102,37.018496],[120.611486,37.019635],[120.613876,37.023847],[120.609143,37.036094],[120.60396,37.036546],[120.605031,37.039993],[120.609546,37.039775],[120.606195,37.047153],[120.602129,37.045686],[120.586503,37.048525],[120.584424,37.058147],[120.580591,37.058849],[120.577875,37.050771],[120.570846,37.046388],[120.558975,37.047418],[120.549773,37.041272],[120.541704,37.044158],[120.542263,37.046997],[120.537297,37.047932],[120.533278,37.053937],[120.533884,37.05768],[120.539858,37.060362],[120.54082,37.065009],[120.538725,37.071713],[120.541875,37.074286],[120.540882,37.078994],[120.536382,37.081972],[120.537592,37.090281],[120.540866,37.097576],[120.53888,37.104137],[120.545661,37.104387],[120.547648,37.11302],[120.542558,37.12868],[120.543116,37.132419],[120.538337,37.131624],[120.528003,37.136734],[120.527134,37.143339],[120.520011,37.144071],[120.519732,37.148277],[120.506821,37.148838],[120.505704,37.143557],[120.493818,37.134506],[120.493057,37.126732],[120.485485,37.123632],[120.478673,37.124208],[120.470666,37.120858],[120.462954,37.115155],[120.454124,37.119051],[120.447203,37.11902],[120.443852,37.123569],[120.440267,37.12265],[120.439491,37.116932],[120.431934,37.116636],[120.432571,37.11489],[120.424377,37.112553],[120.418155,37.114454],[120.415145,37.110574],[120.407107,37.112802],[120.412926,37.103155],[120.408907,37.09516],[120.398122,37.096438],[120.388206,37.104215],[120.384637,37.102953],[120.377918,37.105291],[120.369663,37.104652],[120.362603,37.100896],[120.358428,37.090951],[120.357854,37.084373],[120.351989,37.083406],[120.352609,37.079447],[120.348606,37.077092],[120.344959,37.082939],[120.34617,37.086929],[120.33568,37.092884],[120.336921,37.104246],[120.33222,37.102781],[120.33523,37.106646],[120.331692,37.111976],[120.320628,37.106553],[120.315368,37.11302],[120.312031,37.112335],[120.304785,37.11461],[120.304521,37.108189],[120.301976,37.110278],[120.30179,37.118178],[120.300176,37.12103],[120.302768,37.125501],[120.301821,37.132575],[120.298485,37.129786],[120.288988,37.131064],[120.284333,37.125875],[120.281664,37.131157],[120.271547,37.123195],[120.271485,37.120282],[120.264098,37.114703],[120.260234,37.115124],[120.251219,37.12011],[120.245679,37.118911],[120.242964,37.122463],[120.236648,37.125969],[120.232381,37.117882],[120.233901,37.116371],[120.231232,37.106304],[120.232846,37.098121],[120.228129,37.094552],[120.229867,37.089533],[120.220494,37.087101],[120.217189,37.080787],[120.218012,37.076703],[120.21407,37.07017],[120.217437,37.062904],[120.216475,37.056697],[120.211618,37.05545],[120.209105,37.044298],[120.213946,37.04238],[120.222775,37.042161],[120.230472,37.046887],[120.23522,37.044641],[120.240077,37.037295],[120.238138,37.032833],[120.242033,37.031008],[120.252057,37.030618],[120.253515,37.035064],[120.264316,37.036281],[120.269343,37.038917],[120.277754,37.039853],[120.290959,37.035579],[120.293985,37.030899],[120.298174,37.030166],[120.293705,37.023379],[120.282579,37.020665],[120.276807,37.020774],[120.272866,37.011037],[120.282843,37.003453],[120.293659,37.002658],[120.299804,37.005545],[120.298485,37.008182],[120.304785,37.009134],[120.307857,37.004827],[120.316113,37.006184],[120.32443,37.004343],[120.324213,36.998787],[120.310076,36.993496],[120.30525,36.988096],[120.304847,36.984381],[120.314809,36.975655],[120.320907,36.967146],[120.320256,36.957965],[120.309456,36.945737],[120.302768,36.929727],[120.298237,36.926135],[120.285636,36.922682],[120.281819,36.920464],[120.279973,36.914964],[120.281198,36.910402],[120.287126,36.907308],[120.294807,36.898917],[120.29518,36.893307],[120.291486,36.889181],[120.287545,36.880944],[120.286117,36.868704],[120.282036,36.852177],[120.282161,36.849003],[120.275364,36.833786],[120.272385,36.816924],[120.262624,36.801091],[120.261941,36.797022],[120.263928,36.776943],[120.26835,36.769226],[120.266566,36.766988],[120.269809,36.758284],[120.272167,36.756937],[120.274526,36.748999],[120.273626,36.74153],[120.275954,36.735611],[120.272881,36.73287],[120.272912,36.717646],[120.271857,36.703609],[120.27496,36.699818],[120.2742,36.69272],[120.277195,36.690229],[120.281679,36.678616],[120.293038,36.673507],[120.297988,36.667191],[120.298376,36.663021],[120.293768,36.656484],[120.292619,36.644318],[120.285016,36.638987],[120.279507,36.637764],[120.270476,36.638893],[120.267047,36.635976],[120.264533,36.628669],[120.260871,36.626536],[120.253484,36.628261],[120.259459,36.621078],[120.265681,36.617455],[120.27029,36.617251],[120.27271,36.621831],[120.280469,36.618443],[120.300099,36.61711],[120.305654,36.618396],[120.30584,36.622035],[120.314126,36.622129],[120.314933,36.626128],[120.320985,36.624058],[120.325997,36.624732],[120.325082,36.621831],[120.335696,36.624419],[120.337946,36.628088],[120.34212,36.627445],[120.343035,36.62205],[120.36431,36.620529],[120.366932,36.631382],[120.37286,36.630331],[120.372937,36.625046],[120.368872,36.618396],[120.379936,36.615839],[120.385413,36.62398],[120.401319,36.627336],[120.401598,36.623807],[120.407184,36.62216],[120.406238,36.620121],[120.420389,36.615996],[120.420948,36.613832],[120.429188,36.616012],[120.459385,36.61689],[120.458733,36.611118],[120.462069,36.607087],[120.465498,36.609346],[120.476904,36.608044],[120.477137,36.610632],[120.484523,36.610946],[120.486199,36.617455],[120.492344,36.61802],[120.495013,36.622521],[120.503982,36.629704],[120.51098,36.628935],[120.520911,36.624591],[120.523766,36.621925],[120.52299,36.618224],[120.528406,36.62078],[120.535854,36.620811],[120.535823,36.615887],[120.531075,36.613769],[120.535761,36.61264],[120.54113,36.6066],[120.544265,36.600686],[120.541611,36.595964],[120.538244,36.595023],[120.537577,36.588511],[120.542387,36.584353],[120.541922,36.575613],[120.54352,36.57249],[120.557936,36.572113],[120.563243,36.578641],[120.576851,36.58043],[120.575719,36.590363],[120.583617,36.592104],[120.584532,36.595666],[120.580281,36.60078],[120.583679,36.601659],[120.588753,36.598741],[120.591205,36.603055],[120.591345,36.596921],[120.595767,36.591132],[120.595953,36.588088],[120.607188,36.59008],[120.6131,36.584636],[120.61701,36.58404],[120.6212,36.590583],[120.62736,36.591289],[120.62719,36.588951],[120.634452,36.588998]]]]}},{"type":"Feature","properties":{"name":"东港区","adcode":371102},"geometry":{"type":"MultiPolygon","coordinates":[[[[119.033266,35.481089],[119.035493,35.47855],[119.036654,35.474248],[119.035716,35.470991],[119.039073,35.464585],[119.043207,35.462957],[119.045881,35.458847],[119.053031,35.455144],[119.057495,35.453777],[119.0644,35.465128],[119.067873,35.466107],[119.074586,35.461978],[119.080223,35.459962],[119.082204,35.46381],[119.087276,35.463587],[119.095033,35.46001],[119.100329,35.453448],[119.102108,35.447748],[119.100968,35.442658],[119.105379,35.440884],[119.107542,35.441175],[119.112699,35.443724],[119.116482,35.446255],[119.125943,35.449502],[119.12914,35.448407],[119.131367,35.444548],[119.134393,35.443259],[119.139678,35.444122],[119.143002,35.443666],[119.149321,35.438751],[119.153721,35.437529],[119.16574,35.435464],[119.175404,35.437742],[119.178697,35.437403],[119.182511,35.434019],[119.182628,35.431818],[119.178942,35.428395],[119.177983,35.42311],[119.176896,35.420424],[119.181275,35.416681],[119.181073,35.403965],[119.189032,35.400512],[119.189522,35.397806],[119.193049,35.393373],[119.190566,35.389492],[119.193379,35.387348],[119.199826,35.385495],[119.202457,35.385544],[119.203278,35.382604],[119.204993,35.382604],[119.203193,35.37946],[119.199026,35.374279],[119.198558,35.371028],[119.197183,35.369204],[119.199197,35.359898],[119.200998,35.359024],[119.201264,35.35486],[119.19958,35.35489],[119.195766,35.351745],[119.199357,35.346892],[119.203565,35.345009],[119.203001,35.343252],[119.207039,35.342728],[119.207124,35.341087],[119.210385,35.342068],[119.212452,35.340243],[119.215574,35.339476],[119.218845,35.340243],[119.219186,35.338388],[119.220901,35.338495],[119.223821,35.334243],[119.225366,35.337389],[119.226634,35.334272],[119.229958,35.334661],[119.229297,35.340213],[119.225408,35.339961],[119.228711,35.341679],[119.231396,35.342],[119.232313,35.33932],[119.232686,35.334573],[119.239121,35.335292],[119.240112,35.330874],[119.242893,35.331506],[119.242936,35.333379],[119.245237,35.33636],[119.247986,35.337583],[119.247922,35.339495],[119.250544,35.340806],[119.250128,35.343242],[119.255541,35.345446],[119.26318,35.344883],[119.263585,35.34399],[119.26887,35.343922],[119.267379,35.341825],[119.265365,35.341543],[119.264459,35.339476],[119.266601,35.339476],[119.269957,35.337515],[119.270895,35.338466],[119.273175,35.337408],[119.27781,35.338427],[119.281795,35.338563],[119.283691,35.339476],[119.283244,35.342786],[119.285066,35.343922],[119.284853,35.348853],[119.287112,35.350143],[119.289914,35.357364],[119.295977,35.357597],[119.29635,35.355938],[119.299813,35.357219],[119.302572,35.357219],[119.303627,35.355938],[119.304724,35.357597],[119.309274,35.360257],[119.32857,35.363847],[119.332801,35.363411],[119.333248,35.362392],[119.336519,35.363236],[119.340547,35.362392],[119.343019,35.364565],[119.345576,35.365264],[119.349028,35.364847],[119.347824,35.366312],[119.350626,35.369485],[119.353631,35.370631],[119.35752,35.370698],[119.361399,35.371727],[119.363327,35.374706],[119.368356,35.375783],[119.367088,35.374696],[119.369145,35.373532],[119.368847,35.375715],[119.373311,35.376996],[119.376486,35.376802],[119.378585,35.373687],[119.381228,35.373124],[119.384573,35.373842],[119.384446,35.375492],[119.393119,35.376113],[119.392362,35.372843],[119.395058,35.345281],[119.395005,35.326671],[119.392906,35.319107],[119.374845,35.31229],[119.37329,35.309911],[119.374153,35.305551],[119.372714,35.296451],[119.366321,35.295402],[119.34825,35.295819],[119.335454,35.299539],[119.325182,35.300977],[119.319119,35.29749],[119.312151,35.290992],[119.311299,35.287311],[119.31295,35.282201],[119.310574,35.27268],[119.311576,35.267832],[119.310745,35.264645],[119.304011,35.260001],[119.301006,35.258466],[119.300473,35.25693],[119.304415,35.254666],[119.305673,35.249933],[119.303094,35.245055],[119.302966,35.240633],[119.310073,35.232342],[119.314037,35.231739],[119.321773,35.233479],[119.325427,35.232954],[119.342688,35.226237],[119.345629,35.223301],[119.348272,35.213297],[119.348932,35.2062],[119.35508,35.205694],[119.38907,35.205577],[119.405202,35.203448],[119.411296,35.231622],[119.417125,35.244112],[119.424583,35.255317],[119.451114,35.285397],[119.476526,35.308338],[119.486127,35.314815],[119.493489,35.318602],[119.502408,35.321709],[119.509323,35.32169],[119.516014,35.318087],[119.518241,35.308212],[119.520436,35.303793],[119.523537,35.30322],[119.52847,35.303735],[119.531229,35.302414],[119.532945,35.300209],[119.533105,35.297014],[119.534735,35.294799],[119.536365,35.294712],[119.538475,35.296752],[119.538645,35.320466],[119.539136,35.322593],[119.542716,35.324137],[119.552081,35.324447],[119.554681,35.326243],[119.554926,35.328205],[119.552731,35.330001],[119.539785,35.329787],[119.538901,35.338039],[119.54376,35.34794],[119.548608,35.349619],[119.563077,35.352628],[119.579135,35.357627],[119.584025,35.360538],[119.586934,35.363867],[119.588799,35.368059],[119.589726,35.37261],[119.589022,35.376113],[119.5867,35.378801],[119.578783,35.385573],[119.577494,35.390783],[119.577377,35.395924],[119.57971,35.406546],[119.586923,35.421937],[119.592517,35.433379],[119.597408,35.440612],[119.6002,35.44353],[119.613028,35.449832],[119.617109,35.454795],[119.618974,35.459458],[119.625527,35.486177],[119.628681,35.500855],[119.635212,35.504479],[119.63925,35.509448],[119.649873,35.537642],[119.663022,35.563028],[119.665749,35.57025],[119.666538,35.575902],[119.66576,35.581555],[119.662148,35.589277],[119.659026,35.588639],[119.65145,35.588765],[119.642447,35.593884],[119.639719,35.594406],[119.634701,35.598741],[119.632303,35.602099],[119.626038,35.601654],[119.623502,35.601973],[119.619006,35.60682],[119.61501,35.606337],[119.614254,35.605243],[119.614126,35.600183],[119.611174,35.594048],[119.609278,35.592035],[119.602778,35.590071],[119.600594,35.590255],[119.597728,35.599148],[119.592347,35.600696],[119.586742,35.597116],[119.582736,35.592984],[119.578453,35.593158],[119.575331,35.592122],[119.577579,35.586258],[119.576471,35.585513],[119.570738,35.58681],[119.567627,35.590361],[119.563109,35.589626],[119.559966,35.592074],[119.556514,35.592519],[119.550483,35.591126],[119.547148,35.591097],[119.540169,35.58889],[119.538198,35.589277],[119.536248,35.592219],[119.530984,35.592945],[119.528651,35.594213],[119.526062,35.59847],[119.521416,35.601354],[119.504251,35.602602],[119.497005,35.605389],[119.494491,35.604102],[119.491348,35.59909],[119.487949,35.597435],[119.479691,35.598567],[119.474811,35.598103],[119.47024,35.596458],[119.465903,35.593971],[119.463463,35.591087],[119.463389,35.586103],[119.459862,35.581109],[119.458946,35.578835],[119.447662,35.566455],[119.443922,35.563328],[119.440853,35.563386],[119.434503,35.566503],[119.429889,35.571653],[119.425254,35.575873],[119.412692,35.578196],[119.409932,35.579396],[119.402357,35.579541],[119.397541,35.578254],[119.382964,35.569572],[119.379555,35.568023],[119.374963,35.564897],[119.371841,35.564035],[119.366993,35.561131],[119.359907,35.559417],[119.354867,35.559969],[119.34874,35.56237],[119.345214,35.566562],[119.344841,35.572989],[119.346098,35.57779],[119.345682,35.582851],[119.342369,35.584961],[119.338416,35.584342],[119.33555,35.582784],[119.331511,35.579183],[119.325917,35.57055],[119.32384,35.566455],[119.320302,35.561005],[119.319407,35.55873],[119.315049,35.553744],[119.312162,35.55173],[119.310702,35.549465],[119.305002,35.54657],[119.302753,35.547073],[119.298214,35.545311],[119.291065,35.540198],[119.28789,35.540411],[119.284235,35.534601],[119.279568,35.531628],[119.2726,35.532897],[119.268497,35.5371],[119.264757,35.543829],[119.260144,35.549649],[119.258546,35.55266],[119.253325,35.556891],[119.246409,35.560453],[119.243991,35.56417],[119.240901,35.574092],[119.239558,35.576648],[119.234849,35.578796],[119.227891,35.580538],[119.222297,35.580877],[119.210928,35.585455],[119.197758,35.588832],[119.194615,35.587332],[119.195723,35.584835],[119.195649,35.582155],[119.193113,35.572118],[119.191206,35.571247],[119.185612,35.577277],[119.186613,35.579367],[119.190801,35.580867],[119.191802,35.584787],[119.191579,35.587797],[119.188691,35.591329],[119.185846,35.590942],[119.184621,35.587303],[119.178771,35.585252],[119.174999,35.581642],[119.172186,35.5817],[119.171121,35.583326],[119.168052,35.582513],[119.165676,35.579048],[119.166028,35.575834],[119.170332,35.573308],[119.170727,35.571353],[119.168468,35.567626],[119.158473,35.564645],[119.156182,35.559427],[119.148809,35.555893],[119.140093,35.554683],[119.137025,35.555196],[119.134819,35.556619],[119.126785,35.559979],[119.113722,35.5648],[119.110195,35.569214],[119.105763,35.571363],[119.104484,35.57022],[119.10133,35.570666],[119.097345,35.567336],[119.094575,35.56418],[119.086871,35.561131],[119.081043,35.5563],[119.078219,35.555632],[119.073009,35.552747],[119.067128,35.551905],[119.065124,35.550627],[119.063622,35.548129],[119.063398,35.544469],[119.061342,35.540925],[119.050079,35.537855],[119.042909,35.534011],[119.038796,35.529507],[119.037794,35.52513],[119.043132,35.518883],[119.043516,35.508354],[119.044294,35.505641],[119.04325,35.497765],[119.044741,35.491399],[119.041374,35.480944],[119.03642,35.482688],[119.034054,35.482882],[119.033266,35.481089]]]]}},{"type":"Feature","properties":{"name":"岚山区","adcode":371103},"geometry":{"type":"MultiPolygon","coordinates":[[[[118.871853,35.392975],[118.874154,35.388483],[118.874101,35.377413],[118.871597,35.372193],[118.871043,35.367215],[118.872748,35.364925],[118.877212,35.362518],[118.889551,35.357267],[118.904841,35.355511],[118.910775,35.353599],[118.921974,35.348396],[118.923359,35.345678],[118.923252,35.339194],[118.925575,35.335156],[118.930455,35.331272],[118.935335,35.331175],[118.9416,35.335729],[118.947205,35.336952],[118.954589,35.335913],[118.958361,35.334369],[118.961813,35.334156],[118.968036,35.336777],[118.973033,35.340175],[118.980641,35.348833],[118.986874,35.353123],[118.988376,35.355511],[118.989655,35.360664],[118.988483,35.366982],[118.982867,35.378558],[118.984423,35.382216],[118.990987,35.384894],[118.99966,35.388968],[119.013831,35.389337],[119.019329,35.388639],[119.024337,35.386873],[119.031561,35.382633],[119.038007,35.380266],[119.04456,35.377015],[119.04862,35.373338],[119.048897,35.371475],[119.065774,35.364565],[119.069983,35.36409],[119.075534,35.366099],[119.077761,35.364992],[119.078528,35.36311],[119.077857,35.358888],[119.078422,35.35751],[119.085571,35.354249],[119.086903,35.349978],[119.087234,35.340553],[119.088065,35.338951],[119.09222,35.335127],[119.092742,35.33003],[119.093776,35.32769],[119.096163,35.326865],[119.105678,35.330641],[119.118762,35.332816],[119.133732,35.335583],[119.146486,35.334874],[119.148532,35.332039],[119.148191,35.326748],[119.141287,35.320835],[119.141393,35.316728],[119.143215,35.314038],[119.148244,35.310649],[119.152613,35.305842],[119.157642,35.301705],[119.15924,35.298626],[119.155959,35.293896],[119.16054,35.290613],[119.164078,35.289554],[119.172591,35.289933],[119.177397,35.289758],[119.179549,35.287592],[119.182309,35.277829],[119.18347,35.269737],[119.185186,35.264684],[119.188052,35.26141],[119.187498,35.258193],[119.183747,35.256541],[119.181978,35.252334],[119.182149,35.241857],[119.17794,35.232828],[119.174573,35.230339],[119.174349,35.226344],[119.172975,35.219481],[119.170205,35.212325],[119.164515,35.205908],[119.161308,35.204138],[119.156992,35.203428],[119.148873,35.203273],[119.139038,35.202349],[119.136321,35.200968],[119.135384,35.195863],[119.135384,35.191652],[119.139912,35.18749],[119.144728,35.189065],[119.149193,35.189279],[119.152347,35.187733],[119.154808,35.184202],[119.157312,35.182442],[119.160285,35.175935],[119.161904,35.170468],[119.164877,35.166509],[119.166614,35.166061],[119.171238,35.162257],[119.173135,35.161703],[119.165442,35.158123],[119.163396,35.154133],[119.162959,35.147595],[119.164238,35.143158],[119.169256,35.139985],[119.174221,35.139032],[119.178483,35.138915],[119.184951,35.139518],[119.18998,35.138117],[119.193454,35.134789],[119.196661,35.129903],[119.197716,35.120861],[119.203235,35.110874],[119.21031,35.10809],[119.213741,35.107204],[119.220709,35.107194],[119.223799,35.108625],[119.226229,35.111068],[119.227007,35.114057],[119.229553,35.115167],[119.235307,35.116374],[119.237299,35.118593],[119.238844,35.121922],[119.24073,35.122915],[119.248924,35.123139],[119.249766,35.124511],[119.25293,35.122623],[119.263692,35.119557],[119.267293,35.117172],[119.272301,35.116383],[119.274592,35.1154],[119.286664,35.115157],[119.291555,35.110241],[119.293537,35.106717],[119.29391,35.103455],[119.295348,35.09998],[119.299589,35.0974],[119.301805,35.093154],[119.305843,35.076678],[119.343743,35.083641],[119.35052,35.083884],[119.354068,35.080057],[119.35686,35.078032],[119.357467,35.072821],[119.380375,35.070279],[119.377264,35.075168],[119.374046,35.078694],[119.383572,35.085189],[119.386555,35.088929],[119.396507,35.091684],[119.398585,35.094508],[119.403252,35.106824],[119.407876,35.109861],[119.412873,35.110747],[119.426608,35.108216],[119.43136,35.108975],[119.432436,35.11138],[119.428259,35.121192],[119.418947,35.128287],[119.413992,35.130205],[119.397711,35.137689],[119.395303,35.13982],[119.393545,35.143586],[119.39606,35.157831],[119.416975,35.158161],[119.416634,35.167462],[119.397668,35.166888],[119.399395,35.176635],[119.405202,35.203448],[119.38907,35.205577],[119.35508,35.205694],[119.348932,35.2062],[119.348272,35.213297],[119.345629,35.223301],[119.342688,35.226237],[119.325427,35.232954],[119.321773,35.233479],[119.314037,35.231739],[119.310073,35.232342],[119.302966,35.240633],[119.303094,35.245055],[119.305673,35.249933],[119.304415,35.254666],[119.300473,35.25693],[119.301006,35.258466],[119.304011,35.260001],[119.310745,35.264645],[119.311576,35.267832],[119.310574,35.27268],[119.31295,35.282201],[119.311299,35.287311],[119.312151,35.290992],[119.319119,35.29749],[119.325182,35.300977],[119.335454,35.299539],[119.34825,35.295819],[119.366321,35.295402],[119.372714,35.296451],[119.374153,35.305551],[119.37329,35.309911],[119.374845,35.31229],[119.392906,35.319107],[119.395005,35.326671],[119.395058,35.345281],[119.392362,35.372843],[119.393119,35.376113],[119.384446,35.375492],[119.384573,35.373842],[119.381228,35.373124],[119.378585,35.373687],[119.376486,35.376802],[119.373311,35.376996],[119.368847,35.375715],[119.369145,35.373532],[119.367088,35.374696],[119.368356,35.375783],[119.363327,35.374706],[119.361399,35.371727],[119.35752,35.370698],[119.353631,35.370631],[119.350626,35.369485],[119.347824,35.366312],[119.349028,35.364847],[119.345576,35.365264],[119.343019,35.364565],[119.340547,35.362392],[119.336519,35.363236],[119.333248,35.362392],[119.332801,35.363411],[119.32857,35.363847],[119.309274,35.360257],[119.304724,35.357597],[119.303627,35.355938],[119.302572,35.357219],[119.299813,35.357219],[119.29635,35.355938],[119.295977,35.357597],[119.289914,35.357364],[119.287112,35.350143],[119.284853,35.348853],[119.285066,35.343922],[119.283244,35.342786],[119.283691,35.339476],[119.281795,35.338563],[119.27781,35.338427],[119.273175,35.337408],[119.270895,35.338466],[119.269957,35.337515],[119.266601,35.339476],[119.264459,35.339476],[119.265365,35.341543],[119.267379,35.341825],[119.26887,35.343922],[119.263585,35.34399],[119.26318,35.344883],[119.255541,35.345446],[119.250128,35.343242],[119.250544,35.340806],[119.247922,35.339495],[119.247986,35.337583],[119.245237,35.33636],[119.242936,35.333379],[119.242893,35.331506],[119.240112,35.330874],[119.239121,35.335292],[119.232686,35.334573],[119.232313,35.33932],[119.231396,35.342],[119.228711,35.341679],[119.225408,35.339961],[119.229297,35.340213],[119.229958,35.334661],[119.226634,35.334272],[119.225366,35.337389],[119.223821,35.334243],[119.220901,35.338495],[119.219186,35.338388],[119.218845,35.340243],[119.215574,35.339476],[119.212452,35.340243],[119.210385,35.342068],[119.207124,35.341087],[119.207039,35.342728],[119.203001,35.343252],[119.203565,35.345009],[119.199357,35.346892],[119.195766,35.351745],[119.19958,35.35489],[119.201264,35.35486],[119.200998,35.359024],[119.199197,35.359898],[119.197183,35.369204],[119.198558,35.371028],[119.199026,35.374279],[119.203193,35.37946],[119.204993,35.382604],[119.203278,35.382604],[119.202457,35.385544],[119.199826,35.385495],[119.193379,35.387348],[119.190566,35.389492],[119.193049,35.393373],[119.189522,35.397806],[119.189032,35.400512],[119.181073,35.403965],[119.181275,35.416681],[119.176896,35.420424],[119.177983,35.42311],[119.178942,35.428395],[119.182628,35.431818],[119.182511,35.434019],[119.178697,35.437403],[119.175404,35.437742],[119.16574,35.435464],[119.153721,35.437529],[119.149321,35.438751],[119.143002,35.443666],[119.139678,35.444122],[119.134393,35.443259],[119.131367,35.444548],[119.12914,35.448407],[119.125943,35.449502],[119.116482,35.446255],[119.112699,35.443724],[119.107542,35.441175],[119.105379,35.440884],[119.100968,35.442658],[119.102108,35.447748],[119.100329,35.453448],[119.095033,35.46001],[119.087276,35.463587],[119.082204,35.46381],[119.080223,35.459962],[119.074586,35.461978],[119.067873,35.466107],[119.0644,35.465128],[119.057495,35.453777],[119.053031,35.455144],[119.045881,35.458847],[119.043207,35.462957],[119.039073,35.464585],[119.035716,35.470991],[119.036654,35.474248],[119.035493,35.47855],[119.033266,35.481089],[119.027075,35.479209],[119.025477,35.47982],[119.023857,35.477921],[119.0226,35.478454],[119.021098,35.471108],[119.018945,35.469538],[119.016804,35.469605],[119.015216,35.467929],[119.008908,35.46821],[119.004753,35.467279],[119.004646,35.469053],[119.002558,35.467425],[118.999553,35.467493],[118.997731,35.469247],[118.997571,35.471738],[118.993927,35.470798],[118.992979,35.473414],[118.985691,35.475081],[118.984412,35.473889],[118.987481,35.473191],[118.98681,35.470497],[118.983485,35.46853],[118.981301,35.469169],[118.981269,35.466649],[118.979543,35.463936],[118.980843,35.462298],[118.984423,35.462298],[118.983422,35.459021],[118.985435,35.458469],[118.982526,35.457364],[118.978456,35.454533],[118.979532,35.452255],[118.97851,35.450685],[118.976656,35.450889],[118.970401,35.443724],[118.971339,35.440632],[118.967769,35.438014],[118.968217,35.434194],[118.967588,35.432245],[118.964349,35.431964],[118.962889,35.429607],[118.959693,35.428929],[118.960939,35.422247],[118.958595,35.41703],[118.956411,35.417524],[118.954291,35.416351],[118.952852,35.417961],[118.952735,35.415595],[118.950497,35.414993],[118.950817,35.41251],[118.945628,35.415148],[118.940173,35.411832],[118.931755,35.40899],[118.933321,35.406992],[118.930828,35.4022],[118.92711,35.403413],[118.925437,35.405576],[118.925096,35.409533],[118.921654,35.41093],[118.91899,35.416526],[118.917062,35.416002],[118.917105,35.419183],[118.911095,35.415197],[118.911532,35.413374],[118.907664,35.410474],[118.904958,35.407108],[118.905267,35.405537],[118.897734,35.403752],[118.893951,35.40445],[118.894303,35.402704],[118.888027,35.402423],[118.884596,35.399067],[118.883967,35.396865],[118.882529,35.397961],[118.879268,35.394711],[118.877596,35.395012],[118.876626,35.392946],[118.871853,35.392975]]]]}},{"type":"Feature","properties":{"name":"五莲县","adcode":371121},"geometry":{"type":"MultiPolygon","coordinates":[[[[119.078816,35.959281],[119.073712,35.956391],[119.063835,35.955939],[119.060798,35.954503],[119.057975,35.957258],[119.055737,35.957133],[119.053521,35.954022],[119.05351,35.951845],[119.056323,35.944841],[119.056238,35.934358],[119.053915,35.9277],[119.046531,35.922525],[119.046148,35.921147],[119.053212,35.913688],[119.063089,35.906844],[119.063856,35.90403],[119.060468,35.897899],[119.058561,35.897292],[119.056813,35.899624],[119.054405,35.899297],[119.054033,35.895662],[119.05139,35.894101],[119.046904,35.894592],[119.044677,35.892481],[119.041513,35.895904],[119.03903,35.897041],[119.034843,35.900675],[119.029313,35.900694],[119.028908,35.897591],[119.029973,35.890553],[119.030016,35.882667],[119.032808,35.876081],[119.035876,35.872291],[119.038636,35.862812],[119.036334,35.857112],[119.031007,35.85255],[119.028333,35.85199],[119.018157,35.851518],[119.015877,35.850457],[119.011221,35.846174],[119.008322,35.844563],[119.001429,35.843598],[118.990869,35.847669],[118.983869,35.847592],[118.977092,35.845402],[118.971488,35.847081],[118.966832,35.852878],[118.964051,35.854749],[118.960396,35.85526],[118.956976,35.853929],[118.947216,35.847408],[118.937946,35.837212],[118.934664,35.829687],[118.933716,35.825577],[118.928463,35.818301],[118.925756,35.811006],[118.925043,35.80482],[118.926044,35.799067],[118.925927,35.794492],[118.927323,35.787194],[118.929763,35.783661],[118.933737,35.779693],[118.9385,35.778245],[118.942954,35.775426],[118.951627,35.77279],[118.95444,35.77252],[118.957285,35.77363],[118.964754,35.779037],[118.974993,35.782339],[118.982644,35.781779],[118.985968,35.780736],[118.994471,35.77533],[118.999084,35.770801],[119.003528,35.765163],[119.009153,35.762575],[119.015323,35.761049],[119.023708,35.760074],[119.033383,35.759436],[119.042994,35.758239],[119.044656,35.757688],[119.046883,35.754376],[119.045594,35.748388],[119.048545,35.745568],[119.056984,35.738826],[119.061203,35.73446],[119.072306,35.720848],[119.072636,35.715641],[119.074746,35.711544],[119.076962,35.709331],[119.082833,35.706017],[119.087106,35.701968],[119.087937,35.699755],[119.089823,35.698537],[119.095246,35.698382],[119.097526,35.695995],[119.096418,35.69356],[119.098411,35.691733],[119.108427,35.689462],[119.110867,35.687684],[119.111591,35.685354],[119.111197,35.678936],[119.110142,35.676935],[119.101234,35.670729],[119.100627,35.669453],[119.104889,35.665189],[119.111634,35.662085],[119.108821,35.657212],[119.099157,35.652561],[119.097015,35.649844],[119.095577,35.643974],[119.094138,35.640754],[119.087372,35.632997],[119.086807,35.631643],[119.08848,35.626788],[119.09026,35.624514],[119.090036,35.622744],[119.082908,35.622077],[119.078124,35.622145],[119.071571,35.623557],[119.067298,35.622938],[119.061353,35.619833],[119.055673,35.613303],[119.051582,35.607391],[119.050048,35.60237],[119.049685,35.599157],[119.050825,35.588813],[119.054544,35.580045],[119.067128,35.551905],[119.073009,35.552747],[119.078219,35.555632],[119.081043,35.5563],[119.086871,35.561131],[119.094575,35.56418],[119.097345,35.567336],[119.10133,35.570666],[119.104484,35.57022],[119.105763,35.571363],[119.110195,35.569214],[119.113722,35.5648],[119.126785,35.559979],[119.134819,35.556619],[119.137025,35.555196],[119.140093,35.554683],[119.148809,35.555893],[119.156182,35.559427],[119.158473,35.564645],[119.168468,35.567626],[119.170727,35.571353],[119.170332,35.573308],[119.166028,35.575834],[119.165676,35.579048],[119.168052,35.582513],[119.171121,35.583326],[119.172186,35.5817],[119.174999,35.581642],[119.178771,35.585252],[119.184621,35.587303],[119.185846,35.590942],[119.188691,35.591329],[119.191579,35.587797],[119.191802,35.584787],[119.190801,35.580867],[119.186613,35.579367],[119.185612,35.577277],[119.191206,35.571247],[119.193113,35.572118],[119.195649,35.582155],[119.195723,35.584835],[119.194615,35.587332],[119.197758,35.588832],[119.210928,35.585455],[119.222297,35.580877],[119.227891,35.580538],[119.234849,35.578796],[119.239558,35.576648],[119.240901,35.574092],[119.243991,35.56417],[119.246409,35.560453],[119.253325,35.556891],[119.258546,35.55266],[119.260144,35.549649],[119.264757,35.543829],[119.268497,35.5371],[119.2726,35.532897],[119.279568,35.531628],[119.284235,35.534601],[119.28789,35.540411],[119.291065,35.540198],[119.298214,35.545311],[119.302753,35.547073],[119.305002,35.54657],[119.310702,35.549465],[119.312162,35.55173],[119.315049,35.553744],[119.319407,35.55873],[119.320302,35.561005],[119.32384,35.566455],[119.325917,35.57055],[119.331511,35.579183],[119.33555,35.582784],[119.338416,35.584342],[119.342369,35.584961],[119.345682,35.582851],[119.346098,35.57779],[119.344841,35.572989],[119.345214,35.566562],[119.34874,35.56237],[119.354867,35.559969],[119.359907,35.559417],[119.366993,35.561131],[119.371841,35.564035],[119.374963,35.564897],[119.379555,35.568023],[119.382964,35.569572],[119.397541,35.578254],[119.402357,35.579541],[119.409932,35.579396],[119.412692,35.578196],[119.425254,35.575873],[119.429889,35.571653],[119.434503,35.566503],[119.440853,35.563386],[119.443922,35.563328],[119.447662,35.566455],[119.458946,35.578835],[119.459862,35.581109],[119.463389,35.586103],[119.463463,35.591087],[119.465903,35.593971],[119.47024,35.596458],[119.474811,35.598103],[119.479691,35.598567],[119.487949,35.597435],[119.491348,35.59909],[119.494491,35.604102],[119.497005,35.605389],[119.504251,35.602602],[119.521416,35.601354],[119.526062,35.59847],[119.528651,35.594213],[119.530984,35.592945],[119.536248,35.592219],[119.538422,35.595451],[119.538752,35.59818],[119.537527,35.605127],[119.536877,35.606027],[119.530526,35.607372],[119.522567,35.610874],[119.518145,35.615431],[119.517772,35.625791],[119.518582,35.627842],[119.524464,35.632291],[119.524208,35.63351],[119.519882,35.635144],[119.52018,35.637543],[119.523142,35.636808],[119.523686,35.64264],[119.526371,35.644951],[119.524485,35.648529],[119.527426,35.653847],[119.526776,35.663265],[119.528267,35.674315],[119.527383,35.677225],[119.523931,35.681507],[119.519115,35.685538],[119.517431,35.693086],[119.515439,35.693831],[119.515939,35.696276],[119.514842,35.698006],[119.518486,35.700644],[119.519456,35.702577],[119.519935,35.70765],[119.520862,35.709998],[119.51937,35.711602],[119.521171,35.714501],[119.521075,35.716858],[119.51838,35.722027],[119.517836,35.72421],[119.520521,35.726384],[119.520479,35.728896],[119.523675,35.731862],[119.527255,35.729437],[119.53075,35.731156],[119.524357,35.733784],[119.513926,35.741434],[119.511347,35.744361],[119.509994,35.74835],[119.506243,35.75172],[119.50407,35.752329],[119.4961,35.75145],[119.492062,35.752],[119.488087,35.754598],[119.485253,35.765249],[119.486564,35.771641],[119.490612,35.775455],[119.496601,35.77922],[119.49724,35.781721],[119.495951,35.785428],[119.493287,35.789849],[119.48895,35.794762],[119.482376,35.799733],[119.479595,35.800718],[119.469952,35.806441],[119.464689,35.808622],[119.461609,35.809143],[119.455717,35.809047],[119.451466,35.807531],[119.444338,35.804009],[119.438967,35.802754],[119.436453,35.803266],[119.427716,35.802069],[119.421461,35.800129],[119.416048,35.797716],[119.411179,35.794598],[119.405191,35.791963],[119.402303,35.789492],[119.397722,35.786828],[119.396528,35.785051],[119.392511,35.781875],[119.390444,35.778709],[119.381558,35.77336],[119.375847,35.770715],[119.368804,35.77083],[119.367472,35.773379],[119.367291,35.777048],[119.370392,35.786866],[119.371713,35.792813],[119.371489,35.794878],[119.37248,35.800361],[119.372203,35.80977],[119.374078,35.816169],[119.373695,35.822363],[119.372064,35.82356],[119.372352,35.830015],[119.369379,35.833806],[119.364212,35.838003],[119.362304,35.842219],[119.358287,35.845113],[119.359481,35.847621],[119.366076,35.850949],[119.368857,35.855202],[119.371425,35.860487],[119.370434,35.865097],[119.366161,35.873429],[119.364265,35.876216],[119.361367,35.882917],[119.356977,35.886562],[119.345523,35.893773],[119.341783,35.894448],[119.334985,35.893648],[119.331618,35.890495],[119.329252,35.890678],[119.323179,35.888345],[119.316008,35.887545],[119.307015,35.888615],[119.301805,35.890225],[119.298118,35.893031],[119.297106,35.896617],[119.298182,35.904627],[119.296893,35.909013],[119.29441,35.911345],[119.288795,35.912357],[119.281976,35.910179],[119.276339,35.907297],[119.272227,35.904386],[119.268796,35.902844],[119.260442,35.896337],[119.250991,35.890775],[119.244438,35.888143],[119.240443,35.884267],[119.236287,35.883129],[119.224236,35.881211],[119.217087,35.879514],[119.196043,35.877826],[119.190598,35.879456],[119.181659,35.886137],[119.17598,35.889791],[119.171451,35.894043],[119.169128,35.894824],[119.161872,35.894467],[119.160413,35.893031],[119.160508,35.886301],[119.159944,35.883939],[119.158239,35.882474],[119.156236,35.882917],[119.148767,35.887834],[119.139752,35.891623],[119.135608,35.892963],[119.13451,35.895055],[119.135959,35.896896],[119.144686,35.904435],[119.151782,35.905485],[119.169661,35.917196],[119.173593,35.917967],[119.18185,35.917359],[119.183449,35.918767],[119.180849,35.924404],[119.179368,35.926235],[119.180305,35.929974],[119.180146,35.934561],[119.182042,35.942095],[119.18152,35.943935],[119.182362,35.954243],[119.182586,35.962267],[119.181893,35.968017],[119.17859,35.971061],[119.170418,35.970531],[119.165324,35.969481],[119.155096,35.965783],[119.153252,35.971215],[119.140829,35.96924],[119.134414,35.968586],[119.12523,35.963722],[119.121809,35.96272],[119.105198,35.962614],[119.099103,35.962171],[119.091794,35.963279],[119.088906,35.963163],[119.082918,35.95984],[119.078816,35.959281]]]]}},{"type":"Feature","properties":{"name":"莒县","adcode":371122},"geometry":{"type":"MultiPolygon","coordinates":[[[[119.078816,35.959281],[119.074213,35.961487],[119.066616,35.963972],[119.06473,35.965792],[119.064229,35.971109],[119.062951,35.974653],[119.060511,35.978197],[119.05806,35.979468],[119.052019,35.980287],[119.040085,35.978698],[119.027874,35.976569],[119.025296,35.976444],[119.021066,35.977436],[119.020288,35.978765],[119.018509,35.988058],[119.015951,35.993594],[119.015621,35.995914],[119.024955,36.003587],[119.02374,36.011231],[119.021961,36.012328],[119.015962,36.01253],[119.014065,36.013416],[119.013511,36.016515],[119.017624,36.024032],[119.023261,36.026564],[119.022835,36.030115],[119.012552,36.035312],[119.009548,36.034494],[119.004487,36.034224],[118.998989,36.038401],[118.997582,36.03713],[118.988046,36.02229],[118.981877,36.017401],[118.97494,36.014138],[118.966874,36.011144],[118.956858,36.00842],[118.941259,36.007457],[118.923444,36.007255],[118.904798,36.006841],[118.896039,36.006408],[118.889646,36.001614],[118.886024,35.999881],[118.879822,35.992313],[118.881804,35.989598],[118.886237,35.985852],[118.890701,35.983724],[118.894548,35.979988],[118.897275,35.976049],[118.897425,35.970541],[118.895358,35.965995],[118.893035,35.963269],[118.883552,35.957297],[118.872204,35.954417],[118.846366,35.950477],[118.837213,35.948878],[118.823447,35.948588],[118.819803,35.94934],[118.813878,35.948743],[118.806484,35.944957],[118.804108,35.939725],[118.803969,35.932614],[118.805844,35.928683],[118.805749,35.923874],[118.802893,35.922313],[118.792995,35.920405],[118.779484,35.920154],[118.777204,35.919499],[118.77519,35.917234],[118.77454,35.913119],[118.774966,35.90669],[118.776266,35.902304],[118.778173,35.899065],[118.777278,35.89679],[118.768562,35.89761],[118.765206,35.898342],[118.765153,35.896279],[118.761935,35.891054],[118.760411,35.88687],[118.758121,35.883987],[118.756341,35.87989],[118.756011,35.877373],[118.757236,35.86909],[118.756842,35.864287],[118.75437,35.853543],[118.7529,35.850804],[118.749767,35.849473],[118.736512,35.848961],[118.732836,35.848093],[118.727956,35.844254],[118.7259,35.840608],[118.723342,35.839035],[118.722117,35.834926],[118.722341,35.831481],[118.723662,35.827333],[118.724632,35.820434],[118.722266,35.815194],[118.716736,35.807232],[118.708383,35.798614],[118.704654,35.795679],[118.700615,35.791374],[118.699113,35.787484],[118.70036,35.779211],[118.702182,35.772308],[118.706539,35.765143],[118.706401,35.75849],[118.7033,35.74522],[118.704089,35.742226],[118.707094,35.738063],[118.709864,35.735967],[118.712112,35.735474],[118.714318,35.733388],[118.722149,35.730992],[118.735628,35.729215],[118.743512,35.72934],[118.749383,35.727428],[118.757226,35.72594],[118.776927,35.727485],[118.790459,35.72934],[118.793282,35.730219],[118.798887,35.730123],[118.804193,35.728664],[118.806377,35.726104],[118.806825,35.720819],[118.805855,35.715786],[118.804427,35.713969],[118.80235,35.708964],[118.798024,35.703524],[118.796255,35.699426],[118.794092,35.697513],[118.792313,35.693154],[118.791215,35.687964],[118.791407,35.682957],[118.789404,35.681633],[118.785579,35.674122],[118.77812,35.666426],[118.770086,35.65875],[118.766602,35.653519],[118.758589,35.646982],[118.75714,35.644941],[118.751429,35.640425],[118.742724,35.630483],[118.739687,35.624979],[118.737333,35.603231],[118.735574,35.599477],[118.73582,35.593439],[118.738771,35.587139],[118.740582,35.581477],[118.739687,35.57719],[118.734839,35.569756],[118.728745,35.565942],[118.726837,35.563677],[118.724024,35.56297],[118.723183,35.55935],[118.725111,35.553192],[118.723673,35.550723],[118.720274,35.547567],[118.713252,35.543026],[118.709267,35.538969],[118.702906,35.534059],[118.699518,35.531938],[118.696556,35.528616],[118.698729,35.523725],[118.699646,35.516955],[118.698847,35.513575],[118.705804,35.507666],[118.714403,35.502841],[118.71972,35.498676],[118.725037,35.496573],[118.729086,35.490595],[118.73436,35.48607],[118.727519,35.473976],[118.723886,35.468772],[118.710833,35.460844],[118.709129,35.457693],[118.700786,35.455386],[118.697035,35.456046],[118.693583,35.459118],[118.688437,35.459535],[118.681841,35.458798],[118.678272,35.45685],[118.675064,35.456239],[118.669076,35.456356],[118.665677,35.459671],[118.662055,35.461532],[118.655757,35.460921],[118.650973,35.458614],[118.648011,35.453293],[118.64571,35.452265],[118.64051,35.451412],[118.632892,35.452061],[118.628896,35.449337],[118.62847,35.446012],[118.631443,35.443598],[118.632103,35.440399],[118.631922,35.43273],[118.632583,35.430916],[118.639317,35.429219],[118.642108,35.426999],[118.642247,35.425147],[118.639008,35.421656],[118.635673,35.421054],[118.627564,35.422383],[118.623824,35.423469],[118.61904,35.42311],[118.614821,35.420444],[118.60733,35.41766],[118.601406,35.414518],[118.601715,35.409504],[118.60358,35.406361],[118.605029,35.398931],[118.606116,35.390753],[118.617325,35.388813],[118.622887,35.388532],[118.62505,35.38664],[118.625455,35.382633],[118.625188,35.371319],[118.626605,35.369563],[118.632071,35.368428],[118.635843,35.370097],[118.645752,35.372988],[118.652305,35.373561],[118.664196,35.371446],[118.672539,35.370951],[118.677845,35.367981],[118.682928,35.368661],[118.686337,35.373658],[118.69386,35.380295],[118.696907,35.37981],[118.698857,35.376627],[118.703077,35.372649],[118.709587,35.369825],[118.712325,35.366031],[118.712506,35.363547],[118.714584,35.363731],[118.721552,35.366487],[118.723897,35.368467],[118.727264,35.366817],[118.735095,35.361547],[118.739464,35.359519],[118.740977,35.359694],[118.748254,35.363343],[118.75323,35.363857],[118.760806,35.366817],[118.768957,35.36802],[118.772238,35.369505],[118.773102,35.37098],[118.773613,35.375967],[118.776426,35.376249],[118.782158,35.371814],[118.784119,35.371057],[118.797544,35.369427],[118.800986,35.369903],[118.808775,35.372445],[118.816777,35.373309],[118.823596,35.372193],[118.827645,35.372076],[118.833697,35.372697],[118.841283,35.370757],[118.845332,35.371659],[118.849104,35.375414],[118.857671,35.380217],[118.860622,35.382788],[118.865747,35.391704],[118.868049,35.39378],[118.871853,35.392975],[118.876626,35.392946],[118.877596,35.395012],[118.879268,35.394711],[118.882529,35.397961],[118.883967,35.396865],[118.884596,35.399067],[118.888027,35.402423],[118.894303,35.402704],[118.893951,35.40445],[118.897734,35.403752],[118.905267,35.405537],[118.904958,35.407108],[118.907664,35.410474],[118.911532,35.413374],[118.911095,35.415197],[118.917105,35.419183],[118.917062,35.416002],[118.91899,35.416526],[118.921654,35.41093],[118.925096,35.409533],[118.925437,35.405576],[118.92711,35.403413],[118.930828,35.4022],[118.933321,35.406992],[118.931755,35.40899],[118.940173,35.411832],[118.945628,35.415148],[118.950817,35.41251],[118.950497,35.414993],[118.952735,35.415595],[118.952852,35.417961],[118.954291,35.416351],[118.956411,35.417524],[118.958595,35.41703],[118.960939,35.422247],[118.959693,35.428929],[118.962889,35.429607],[118.964349,35.431964],[118.967588,35.432245],[118.968217,35.434194],[118.967769,35.438014],[118.971339,35.440632],[118.970401,35.443724],[118.976656,35.450889],[118.97851,35.450685],[118.979532,35.452255],[118.978456,35.454533],[118.982526,35.457364],[118.985435,35.458469],[118.983422,35.459021],[118.984423,35.462298],[118.980843,35.462298],[118.979543,35.463936],[118.981269,35.466649],[118.981301,35.469169],[118.983485,35.46853],[118.98681,35.470497],[118.987481,35.473191],[118.984412,35.473889],[118.985691,35.475081],[118.992979,35.473414],[118.993927,35.470798],[118.997571,35.471738],[118.997731,35.469247],[118.999553,35.467493],[119.002558,35.467425],[119.004646,35.469053],[119.004753,35.467279],[119.008908,35.46821],[119.015216,35.467929],[119.016804,35.469605],[119.018945,35.469538],[119.021098,35.471108],[119.0226,35.478454],[119.023857,35.477921],[119.025477,35.47982],[119.027075,35.479209],[119.033266,35.481089],[119.034054,35.482882],[119.03642,35.482688],[119.041374,35.480944],[119.044741,35.491399],[119.04325,35.497765],[119.044294,35.505641],[119.043516,35.508354],[119.043132,35.518883],[119.037794,35.52513],[119.038796,35.529507],[119.042909,35.534011],[119.050079,35.537855],[119.061342,35.540925],[119.063398,35.544469],[119.063622,35.548129],[119.065124,35.550627],[119.067128,35.551905],[119.054544,35.580045],[119.050825,35.588813],[119.049685,35.599157],[119.050048,35.60237],[119.051582,35.607391],[119.055673,35.613303],[119.061353,35.619833],[119.067298,35.622938],[119.071571,35.623557],[119.078124,35.622145],[119.082908,35.622077],[119.090036,35.622744],[119.09026,35.624514],[119.08848,35.626788],[119.086807,35.631643],[119.087372,35.632997],[119.094138,35.640754],[119.095577,35.643974],[119.097015,35.649844],[119.099157,35.652561],[119.108821,35.657212],[119.111634,35.662085],[119.104889,35.665189],[119.100627,35.669453],[119.101234,35.670729],[119.110142,35.676935],[119.111197,35.678936],[119.111591,35.685354],[119.110867,35.687684],[119.108427,35.689462],[119.098411,35.691733],[119.096418,35.69356],[119.097526,35.695995],[119.095246,35.698382],[119.089823,35.698537],[119.087937,35.699755],[119.087106,35.701968],[119.082833,35.706017],[119.076962,35.709331],[119.074746,35.711544],[119.072636,35.715641],[119.072306,35.720848],[119.061203,35.73446],[119.056984,35.738826],[119.048545,35.745568],[119.045594,35.748388],[119.046883,35.754376],[119.044656,35.757688],[119.042994,35.758239],[119.033383,35.759436],[119.023708,35.760074],[119.015323,35.761049],[119.009153,35.762575],[119.003528,35.765163],[118.999084,35.770801],[118.994471,35.77533],[118.985968,35.780736],[118.982644,35.781779],[118.974993,35.782339],[118.964754,35.779037],[118.957285,35.77363],[118.95444,35.77252],[118.951627,35.77279],[118.942954,35.775426],[118.9385,35.778245],[118.933737,35.779693],[118.929763,35.783661],[118.927323,35.787194],[118.925927,35.794492],[118.926044,35.799067],[118.925043,35.80482],[118.925756,35.811006],[118.928463,35.818301],[118.933716,35.825577],[118.934664,35.829687],[118.937946,35.837212],[118.947216,35.847408],[118.956976,35.853929],[118.960396,35.85526],[118.964051,35.854749],[118.966832,35.852878],[118.971488,35.847081],[118.977092,35.845402],[118.983869,35.847592],[118.990869,35.847669],[119.001429,35.843598],[119.008322,35.844563],[119.011221,35.846174],[119.015877,35.850457],[119.018157,35.851518],[119.028333,35.85199],[119.031007,35.85255],[119.036334,35.857112],[119.038636,35.862812],[119.035876,35.872291],[119.032808,35.876081],[119.030016,35.882667],[119.029973,35.890553],[119.028908,35.897591],[119.029313,35.900694],[119.034843,35.900675],[119.03903,35.897041],[119.041513,35.895904],[119.044677,35.892481],[119.046904,35.894592],[119.05139,35.894101],[119.054033,35.895662],[119.054405,35.899297],[119.056813,35.899624],[119.058561,35.897292],[119.060468,35.897899],[119.063856,35.90403],[119.063089,35.906844],[119.053212,35.913688],[119.046148,35.921147],[119.046531,35.922525],[119.053915,35.9277],[119.056238,35.934358],[119.056323,35.944841],[119.05351,35.951845],[119.053521,35.954022],[119.055737,35.957133],[119.057975,35.957258],[119.060798,35.954503],[119.063835,35.955939],[119.073712,35.956391],[119.078816,35.959281]]]]}}]});
}));
src/components/charts/G2PlotChart.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,112 @@
<!-- G2Plot é€šç”¨å›¾è¡¨åŒ…装组件(Vue 2 å…¼å®¹ï¼‰ -->
<template>
  <div ref="container" class="g2plot-chart" :style="{ height: height + 'px', width: '100%' }"></div>
</template>
<script>
import { Line, Area, Column, Bar, Pie, Ring, Gauge } from '@antv/g2plot';
const PLOTS = {
  line: Line,
  area: Area,
  column: Column,
  bar: Bar,
  pie: Pie,
  ring: Ring,
  gauge: Gauge
};
export default {
  name: 'G2PlotChart',
  props: {
    // å›¾è¡¨ç±»åž‹ï¼šline / area / column / bar / pie / ring / gauge
    type: {
      type: String,
      required: true
    },
    // G2Plot é…ç½®å¯¹è±¡ï¼ˆå« data)
    options: {
      type: Object,
      required: true
    },
    height: {
      type: [String, Number],
      default: 280
    }
  },
  data() {
    return {
      plot: null,
      key: ''
    };
  },
  watch: {
    options: {
      deep: true,
      handler(val) {
        const key = JSON.stringify(val || {});
        if (key !== this.key) {
          this.key = key;
          this.$nextTick(() => this.render());
        }
      }
    },
    type() {
      this.render();
    }
  },
  mounted() {
    this.render();
    window.addEventListener('resize', this.handleResize);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleResize);
    this.destroy();
  },
  methods: {
    render() {
      if (!this.$refs.container) return;
      const data = (this.options && this.options.data) || [];
      // ä»ªè¡¨ç›˜ç­‰ç™¾åˆ†æ¯”类图表没有 data,只有 percent;两者皆无时不渲染,避免 G2Plot æŠ›å¼‚常
      const hasPercent =
        this.options && typeof this.options.percent === 'number';
      if (!data.length && !hasPercent) {
        this.destroy();
        return;
      }
      const Ctor = PLOTS[this.type];
      if (!Ctor) {
        console.warn('[G2PlotChart] æœªçŸ¥å›¾è¡¨ç±»åž‹:', this.type);
        return;
      }
      this.destroy();
      this.plot = new Ctor(this.$refs.container, this.options);
      this.plot.render();
    },
    destroy() {
      if (this.plot) {
        try {
          this.plot.destroy();
        } catch (e) {
          // ignore
        }
        this.plot = null;
      }
    },
    handleResize() {
      if (this.plot && this.$refs.container) {
        this.plot.changeSize(
          this.$refs.container.clientWidth,
          this.$refs.container.clientHeight
        );
      }
    }
  }
};
</script>
<style scoped>
.g2plot-chart {
  position: relative;
}
</style>
src/utils/g2Dark.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
// G2Plot æ·±è‰²ä¸»é¢˜é€šç”¨é…ç½®ç‰‡æ®µ
// ä¾›é©¾é©¶èˆ±ï¼ˆviews/home)复用,保证深色大屏下图表配色/坐标轴/图例一致
export const PALETTE = [
  '#38a5f8',
  '#22d3ee',
  '#9078e5',
  '#34d399',
  '#fbbf24',
  '#fb7185',
  '#60a5fa',
  '#f472b6',
  '#a78bfa',
  '#2dd4bf'
];
const AXIS_LABEL_COLOR = '#9aa7c7';
const AXIS_LINE_COLOR = '#253455';
const GRID_LINE_COLOR = 'rgba(120, 140, 190, 0.14)';
const LEGEND_TEXT_COLOR = '#c3cde4';
// ç±»ç›®è½´
export function xAxis(extra = {}) {
  const { label, ...rest } = extra;
  return {
    label: { style: { fill: AXIS_LABEL_COLOR, fontSize: 12 }, ...(label || {}) },
    line: { style: { stroke: AXIS_LINE_COLOR } },
    tickLine: { style: { stroke: AXIS_LINE_COLOR } },
    ...rest
  };
}
// æ•°å€¼è½´
export function yAxis(extra = {}) {
  const { label, ...rest } = extra;
  return {
    label: { style: { fill: AXIS_LABEL_COLOR, fontSize: 12 }, ...(label || {}) },
    grid: { line: { style: { stroke: GRID_LINE_COLOR, lineDash: [3, 3] } } },
    ...rest
  };
}
export function legend(extra = {}) {
  return {
    position: 'top',
    text: { style: { fill: LEGEND_TEXT_COLOR, fontSize: 12 } },
    marker: { symbol: 'circle', style: { r: 4 } },
    itemHeight: 14,
    ...extra
  };
}
export function tooltip(extra = {}) {
  return {
    domStyles: {
      'g2-tooltip': {
        backgroundColor: 'rgba(13, 20, 43, 0.94)',
        color: '#e6edff',
        boxShadow: '0 8px 24px rgba(0, 0, 0, 0.45)',
        borderRadius: '8px',
        padding: '10px 14px'
      },
      'g2-tooltip-title': { color: '#aeb9d8', marginBottom: '6px' },
      'g2-tooltip-list-item': { color: '#e6edff' },
      'g2-tooltip-marker': { borderRadius: '50%' }
    },
    ...extra
  };
}
src/views/business/GetWitness/GetWitnessInfo.vue
@@ -14,11 +14,12 @@
        <div class="form-row">
          <el-form-item label="手术医生" prop="operationdoctor" class="col-1-3">
            <el-input v-model="form.operationdoctor" />
            <el-input v-model="form.operationdoctor" :disabled="isReadOnly" />
          </el-form-item>
          <el-form-item label="手术开始时间" prop="operationbegtime" class="col-1-3">
            <el-date-picker
              v-model="form.operationbegtime"
              :disabled="isReadOnly"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
@@ -27,6 +28,7 @@
          <el-form-item label="手术结束时间" prop="operationendtime" class="col-1-3">
            <el-date-picker
              v-model="form.operationendtime"
              :disabled="isReadOnly"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
@@ -42,6 +44,7 @@
          >
            <el-date-picker
              v-model="form.abdominalaortacannulatime"
              :disabled="isReadOnly"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
@@ -54,6 +57,7 @@
          >
            <el-date-picker
              v-model="form.abdominalaortaperfusiontime"
              :disabled="isReadOnly"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
@@ -65,6 +69,7 @@
          <el-form-item label="门静脉插管时间" prop="portalveincannulatime" class="col-1-3">
            <el-date-picker
              v-model="form.portalveincannulatime"
              :disabled="isReadOnly"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
@@ -73,6 +78,7 @@
          <el-form-item label="门静脉灌注时间" prop="portalveinperfusiontime" class="col-1-3">
            <el-date-picker
              v-model="form.portalveinperfusiontime"
              :disabled="isReadOnly"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
@@ -92,6 +98,7 @@
          <el-form-item label="进手术室时间" prop="coordinatorInOperating" class="col-1-3">
            <el-date-picker
              v-model="form.coordinatorInOperating"
              :disabled="isReadOnly"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
@@ -100,6 +107,7 @@
          <el-form-item label="出手术室时间" prop="coordinatorOutOperating" class="col-1-3">
            <el-date-picker
              v-model="form.coordinatorOutOperating"
              :disabled="isReadOnly"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
@@ -124,13 +132,13 @@
            </el-form-item>
          </el-col> -->
          <el-form-item label="是否默哀缅怀" prop="isspendremember" class="col-1-3">
            <el-select v-model="form.isspendremember" style="width: 100%">
            <el-select v-model="form.isspendremember" :disabled="isReadOnly" style="width: 100%">
              <el-option label="是" :value="1" />
              <el-option label="否" :value="0" />
            </el-select>
          </el-form-item>
          <el-form-item label="恢复遗体仪容" prop="isrestoreremains" class="col-1-3">
            <el-select v-model="form.isrestoreremains" style="width: 100%">
            <el-select v-model="form.isrestoreremains" :disabled="isReadOnly" style="width: 100%">
              <el-option label="是" :value="1" />
              <el-option label="否" :value="0" />
            </el-select>
@@ -142,13 +150,13 @@
        <div class="form-row">
          <el-form-item label="负责人姓名" prop="responsibleusername" class="col-1-3">
            <el-input v-model="form.responsibleusername" />
            <el-input v-model="form.responsibleusername" :disabled="isReadOnly" />
          </el-form-item>
          <el-form-item label="协调员一" prop="coordinatedusernameo" class="col-1-3">
            <el-input v-model="form.coordinatedusernameo" />
            <el-input v-model="form.coordinatedusernameo" :disabled="isReadOnly" />
          </el-form-item>
          <el-form-item label="协调员二" prop="coordinatedusernamet" class="col-1-3">
            <el-input v-model="form.coordinatedusernamet" />
            <el-input v-model="form.coordinatedusernamet" :disabled="isReadOnly" />
          </el-form-item>
        </div>
@@ -159,6 +167,7 @@
          <el-form-item label="获取机构名称" prop="gainhospitalname" class="col-1-3">
            <el-input
              v-model="form.gainhospitalname"
              :disabled="isReadOnly"
              placeholder="请输入获取机构名称"
            />
          </el-form-item>
@@ -197,6 +206,7 @@
            <el-form-item label-width="100px" label="捐献器官">
              <el-checkbox-group
                v-model="selectedOrgans"
                :disabled="isReadOnly"
                @change="handleOrganSelectionChange"
              >
                <el-checkbox
@@ -248,6 +258,7 @@
                      size="small"
                      style="width: 100%"
                      v-model="scope.row.organStartTime"
                      :disabled="isReadOnly"
                      type="datetime"
                      value-format="yyyy-MM-dd HH:mm:ss"
                      placeholder="选择获取开始时间"
@@ -267,6 +278,7 @@
                      size="small"
                      style="width: 100%"
                      v-model="scope.row.organgettime"
                      :disabled="isReadOnly"
                      type="datetime"
                      value-format="yyyy-MM-dd HH:mm:ss"
                      placeholder="选择器官离体时间"
@@ -298,6 +310,7 @@
                  <template slot-scope="scope">
                    <el-autocomplete
                      v-model="scope.row.gainhospitalname"
                      :disabled="isReadOnly"
                      :fetch-suggestions="queryHospitalSearch"
                      placeholder="请选择或输入获取医院"
                      style="width: 100%"
@@ -315,12 +328,13 @@
                  <template slot-scope="scope">
                    <el-input
                      v-model="scope.row.organgetdoct"
                      :disabled="isReadOnly"
                      placeholder="获取医师"
                    />
                  </template>
                </el-table-column>
                <!-- <el-table-column
                <el-table-column
                  label="获取状态"
                  align="center"
                  width="120"
@@ -329,6 +343,7 @@
                  <template slot-scope="scope">
                    <el-select
                      v-model="scope.row.organstate"
                      :disabled="isReadOnly"
                      placeholder="请选择获取状态"
                      style="width: 100%"
                    >
@@ -340,9 +355,9 @@
                      />
                    </el-select>
                  </template>
                </el-table-column> -->
                </el-table-column>
                <el-table-column
                <!-- <el-table-column
                  label="说明"
                  align="center"
                  prop="notgetreason"
@@ -352,13 +367,15 @@
                    <el-input
                      type="textarea"
                      clearable
                      :disabled="isReadOnly"
                      v-model="scope.row.notgetreason"
                      placeholder="请输入未获取说明"
                    />
                  </template>
                </el-table-column>
                </el-table-column> -->
                <el-table-column
                  v-if="!isReadOnly"
                  label="操作"
                  align="center"
                  width="120"
@@ -407,6 +424,7 @@
        >
          <div style="margin-bottom: 10px; text-align: right;">
            <el-button
              v-if="!isReadOnly"
              size="mini"
              type="primary"
              icon="el-icon-plus"
@@ -436,6 +454,7 @@
                  <el-select
                    v-model="scope.row.fileType"
                    size="small"
                    :disabled="isReadOnly"
                    @change="updateAttachmentCategory(scope.row, $event)"
                    placeholder="选择分类"
                  >
@@ -474,6 +493,7 @@
                    >预览</el-button
                  >
                  <el-button
                    v-if="!isReadOnly"
                    size="mini"
                    type="danger"
                    @click="handleRemoveAttachmentByFile(scope.row)"
@@ -491,7 +511,7 @@
        </el-tab-pane>
      </el-tabs>
    </el-card>
    <div style="text-align: center; margin: 30px 0;">
    <div v-if="!isReadOnly" style="text-align: center; margin: 30px 0;">
      <el-button type="primary" @click="handleSave" :loading="saveLoading">
        ä¿å­˜
      </el-button>
@@ -516,7 +536,7 @@
              <el-input v-model="currentRecord.organname" readonly />
            </el-form-item>
          </el-col>
          <!-- <el-col :span="12">
          <el-col :span="12">
            <el-form-item label="获取状态">
              <el-select v-model="currentRecord.organstate" style="width: 100%">
                <el-option
@@ -527,7 +547,7 @@
                />
              </el-select>
            </el-form-item>
          </el-col> -->
          </el-col>
        </el-row>
        <el-row :gutter="20">
@@ -644,6 +664,7 @@
<script>
import { witnessList, witnessadd, witnessedit } from "@/api/businessApi";
import { getDonatebaseinfo } from "@/api/project/donatebaseinfo";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import { getToken } from "@/utils/auth";
@@ -781,6 +802,10 @@
    };
  },
  computed: {
    // æŸ¥çœ‹æ¨¡å¼ï¼šåªè¯»ï¼Œç¦ç”¨è¡¨å•并隐藏保存按钮
    isReadOnly() {
      return this.$route.query.mode === "view";
    },
    // å½“前用户信息
    currentUser() {
      return JSON.parse(sessionStorage.getItem("user") || "{}");
@@ -818,7 +843,7 @@
        record =>
          !record.organStartTime ||
          !record.organgettime ||
          !record.gainhospitalno ||
          !record.gainhospitalname ||
          !record.organgetdoct
      ).length;
    },
@@ -1209,10 +1234,19 @@
    },
    // ä¿å­˜åŸºæœ¬ä¿¡æ¯
    async handleSave() {
      if (this.saveLoading) return;
      this.$refs.form.validate(async valid => {
        if (valid) {
          this.saveLoading = true;
          try {
            // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…
            if (!this.form.id) {
              const exists = await this.checkPatientExists();
              if (exists) {
                this.$message.warning("该患者已存在,请勿重复添加");
                return;
              }
            }
            console.log(this.procurementData.serviceDonationwitnessorgans);
            const saveData = {
@@ -1250,6 +1284,26 @@
        }
      });
    },
    // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…(按住院号)
    async checkPatientExists() {
      let inpatientno = this.form.inpatientno;
      if (!inpatientno && this.caseId) {
        try {
          const caseRes = await getDonatebaseinfo(this.caseId);
          inpatientno = (caseRes.data && caseRes.data.inpatientno) || "";
        } catch (e) {
          inpatientno = "";
        }
      }
      if (!inpatientno) return false;
      try {
        const res = await witnessList({ inpatientno, pageNum: 1, pageSize: 1 });
        const list = res.data || [];
        return list.some(item => item && item.id != null && item.id !== "");
      } catch (e) {
        return false;
      }
    },
    // ä¿å­˜èŽ·å–è®°å½•
    async handleSaveProcurement() {
      if (!this.form.id) {
src/views/business/GetWitness/index.vue
@@ -88,7 +88,7 @@
          width="120"
        />
        <el-table-column
          label="捐献者姓名"
          label="姓名"
          align="center"
          prop="name"
          width="120"
@@ -103,12 +103,38 @@
        </el-table-column>
        <el-table-column label="年龄" align="center" prop="age" width="80" />
        <el-table-column
          label="血型"
          align="center"
          prop="bloodtype"
          width="80"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_BloodType"
              :value="scope.row.bloodtype"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="疾病诊断"
          align="center"
          prop="diagnosisname"
          min-width="180"
          width="200"
          show-overflow-tooltip
        />
        <el-table-column
          label="捐献类型"
          align="center"
          prop="donationcategory"
          width="180"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_DonationCategory"
              :value="scope.row.donationcategory"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="获取状态"
          align="center"
@@ -148,10 +174,10 @@
          prop="responsibleusername"
          width="100"
        />
        <el-table-column
         <el-table-column
          label="操作"
          align="center"
          width="210"
          min-width="180"
          fixed="right"
          class-name="small-padding fixed-width"
        >
@@ -160,15 +186,15 @@
              size="mini"
              type="text"
              icon="el-icon-view"
              @click="handleView(scope.row)"
              >详情</el-button
              @click.stop="handleView(scope.row)"
              >查看</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click="handleUpdate(scope.row)"
              >修改</el-button
              @click.stop="handleUpdate(scope.row)"
              >编辑</el-button
            >
          </template>
        </el-table-column>
@@ -194,7 +220,7 @@
export default {
  name: "OrganProcurementList",
  components: { Pagination },
  dicts: ["sys_user_sex",'Obtain_status'],
  dicts: ["sys_user_sex", "Obtain_status", "sys_BloodType", "sys_DonationCategory"],
  data() {
    return {
      // é®ç½©å±‚
@@ -262,18 +288,19 @@
    handleView(row) {
      this.$router.push({
        path: "/case/GetWitnessInfo",
        query: { id: row.id, infoid: row.infoid }
        query: { id: row.id, infoid: row.infoid, mode: "view" }
      });
    },
    // æ–°å¢žæŒ‰é’®æ“ä½œ
    handleCreate() {
      this.$router.push("/case/GetWitnessInfo");
    },
    // ä¿®æ”¹æŒ‰é’®æ“ä½œ
    // ç¼–辑
    handleUpdate(row) {
      const id = row.id || this.ids[0];
      this.$router.push({
        path: "/case/GetWitnessInfo",
        query: { id: row.id, infoid: row.infoid }
        query: { id: id, infoid: row.infoid, mode: "edit" }
      });
    },
    // æ—¶é—´æ ¼å¼åŒ–
src/views/business/OrganUtilization/OrganUtilizationInfo.vue
@@ -13,18 +13,21 @@
            <el-input
              v-model="form.responsibleusername"
              placeholder="请输入负责人姓名"
              :disabled="isReadOnly"
            />
          </el-form-item>
          <el-form-item label="协调员一" prop="coordinatedusernameo" class="col-1-3">
            <el-input
              v-model="form.coordinatedusernameo"
              placeholder="请输入协调员一姓名"
              :disabled="isReadOnly"
            />
          </el-form-item>
          <el-form-item label="协调员二" prop="coordinatedusernamet" class="col-1-3">
            <el-input
              v-model="form.coordinatedusernamet"
              placeholder="请输入协调员二姓名"
              :disabled="isReadOnly"
            />
          </el-form-item>
          <el-form-item label="完成时间" prop="completetime" class="col-1-3">
@@ -33,6 +36,7 @@
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
              :disabled="isReadOnly"
            />
          </el-form-item>
        </div>
@@ -61,7 +65,7 @@
        </div>
        <div class="form-row">
          <el-form-item align="left" label="遗体接收" prop="isbodydonation" class="col-1-3">
            <el-radio-group v-model="form.isbodydonation">
            <el-radio-group v-model="form.isbodydonation" :disabled="isReadOnly">
              <el-radio
                v-for="dict in dict.type.sys_0_1 || []"
                :key="dict.value"
@@ -75,12 +79,14 @@
            <el-input
              v-model="form.relationname"
              placeholder="请输入接收家属"
              :disabled="isReadOnly"
            />
          </el-form-item>
          <el-form-item label="与捐献者关系" prop="signfamilyrelations" class="col-1-3">
            <el-select
              v-model="form.signfamilyrelations"
              placeholder="请选择与捐献者关系"
              :disabled="isReadOnly"
            >
              <el-option
                v-for="dict in dict.type.sys_FamilyRelation || []"
@@ -116,6 +122,7 @@
            <el-form-item label-width="100px" label="移植器官">
              <el-checkbox-group
                v-model="selectedOrgans"
                :disabled="isReadOnly"
                @change="handleOrganSelectionChange"
              >
                <el-checkbox
@@ -181,7 +188,9 @@
                              <el-form-item label="受者姓名">
                                <el-input
                                  v-model="scope.row.name"
                                  :class="{ 'field-error': isFieldError(scope.row, 'name') }"
                                  placeholder="请输入受者姓名"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -193,6 +202,7 @@
                                  value-format="yyyy-MM-dd"
                                  placeholder="选择出生日期"
                                  style="width: 100%"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -202,6 +212,7 @@
                                  v-model="scope.row.sex"
                                  placeholder="请选择性别"
                                  style="width: 100%"
                                  :disabled="isReadOnly"
                                >
                                  <el-option label="男" :value="0" />
                                  <el-option label="女" :value="1" />
@@ -216,6 +227,7 @@
                                <el-input
                                  v-model="scope.row.age"
                                  placeholder="年龄"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -225,6 +237,7 @@
                                  v-model="scope.row.idcardtype"
                                  placeholder="请选择证件类型"
                                  style="width: 100%"
                                  :disabled="isReadOnly"
                                >
                                  <el-option label="身份证" :value="1" />
                                  <el-option label="护照" :value="2" />
@@ -238,6 +251,7 @@
                                <el-input
                                  v-model="scope.row.idcardno"
                                  placeholder="证件号码"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -253,6 +267,7 @@
                                <el-input
                                  v-model="scope.row.hospitalname"
                                  placeholder="请输入移植中心名称"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -261,6 +276,7 @@
                                <el-input
                                  v-model="scope.row.phone"
                                  placeholder="联系电话"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -274,6 +290,7 @@
                                  :rows="2"
                                  v-model="scope.row.residenceaddress"
                                  placeholder="请输入详细地址"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -295,6 +312,7 @@
                                  value-format="yyyy-MM-dd HH:mm:ss"
                                  placeholder="选择移植日期"
                                  style="width: 100%"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -303,6 +321,7 @@
                                <el-input
                                  v-model="scope.row.transplantdoct"
                                  placeholder="请输入移植医生"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -321,8 +340,10 @@
                                <el-input
                                  type="textarea"
                                  :rows="3"
                                  :class="{ 'field-error': isFieldError(scope.row, 'abandonreason') }"
                                  v-model="scope.row.abandonreason"
                                  placeholder="请输入未移植原因"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -365,10 +386,12 @@
                  <template slot-scope="scope">
                    <el-autocomplete
                      v-model="scope.row.hospitalname"
                      :class="{ 'field-error': isFieldError(scope.row, 'hospitalname') }"
                      :fetch-suggestions="queryHospitalSearch"
                      placeholder="请选择或输入移植医院"
                      style="width: 100%"
                      clearable
                      :disabled="isReadOnly"
                    ></el-autocomplete>
                  </template>
                </el-table-column>
@@ -382,6 +405,7 @@
                      v-model="scope.row.transplantstate"
                      placeholder="请选择移植状态"
                      style="width: 100%"
                      :disabled="isReadOnly"
                      @change="handleTransplantStatusChange(scope.row, $event)"
                    >
                      <el-option
@@ -406,9 +430,11 @@
                      size="small"
                      style="width: 100%"
                      v-model="scope.row.transplanttime"
                      :class="{ 'field-error': isFieldError(scope.row, 'transplanttime') }"
                      type="datetime"
                      value-format="yyyy-MM-dd HH:mm:ss"
                      placeholder="选择移植时间"
                      :disabled="isReadOnly"
                    />
                  </template>
                </el-table-column>
@@ -422,13 +448,18 @@
                    <el-input
                      v-model="scope.row.transplantdoct"
                      placeholder="医师姓名"
                      :disabled="isReadOnly"
                    />
                  </template>
                </el-table-column>
                <el-table-column label="受者姓名" align="center" prop="name">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.name" placeholder="受者姓名" />
                    <el-input
                      v-model="scope.row.name"
                      placeholder="受者姓名"
                      :disabled="isReadOnly"
                    />
                  </template>
                </el-table-column>
              </el-table>
@@ -469,6 +500,7 @@
        >
          <div style="margin-bottom: 10px; text-align: right;">
            <el-button
              v-if="!isReadOnly"
              size="mini"
              type="primary"
              icon="el-icon-plus"
@@ -498,6 +530,7 @@
                <el-select
                  v-model="scope.row.fileType"
                  size="small"
                  :disabled="isReadOnly"
                  @change="updateAttachmentCategory(scope.row, $event)"
                  placeholder="选择分类"
                >
@@ -526,7 +559,12 @@
                <span>{{ formatFileSize(scope.row.fileSize) }}</span>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="180" fixed="right">
            <el-table-column
              v-if="!isReadOnly"
              label="操作"
              width="180"
              fixed="right"
            >
              <template #default="scope">
                <el-button
                  size="mini"
@@ -553,10 +591,16 @@
      </el-tabs>
    </el-card>
    <div style="text-align: center; margin: 30px 0;">
      <el-button type="primary" @click="handleSave" :loading="saveLoading">
      <el-button
        v-if="!isReadOnly"
        type="primary"
        @click="handleSave"
        :loading="saveLoading"
      >
        ä¿å­˜
      </el-button>
      <el-button
        v-if="!isReadOnly"
        type="success"
        @click="handleComplete"
        :loading="confirmLoading"
@@ -621,6 +665,7 @@
  completionadd,
  completionedit
} from "@/api/businessApi";
import { getDonatebaseinfo } from "@/api/project/donatebaseinfo";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import { getToken } from "@/utils/auth";
@@ -706,7 +751,8 @@
        { value: "1", label: "已移植" },
        { value: "0", label: "未移植" },
        { value: "2", label: "移植中" },
        { value: "3", label: "库存" }
        { value: "3", label: "库存" },
        { value: "4", label: "弃用" }
      ],
      organExpansionMap: {
        C64: { subItems: ["C64L", "C64R"], subNames: ["左肾", "右肾"] },
@@ -724,6 +770,8 @@
      attachments: [],
      // å±•开的行keys
      expandedRows: [],
      // æ ¡éªŒå¤±è´¥æ—¶é«˜äº®çš„字段(organno -> ç¼ºå¤±å­—段名数组)
      errorFields: {},
      // ç¼–辑对话框
      editDialogVisible: false,
      currentRecord: {},
@@ -795,6 +843,21 @@
    // èŽ·å–å™¨å®˜å­—å…¸
    organDict() {
      return this.dict.type.sys_Organ || [];
    },
    // æŸ¥çœ‹æ¨¡å¼ï¼šåªè¯»ï¼Œç¦ç”¨è¡¨å•并隐藏保存按钮
    isReadOnly() {
      return this.$route.query.mode === "view";
    }
  },
  watch: {
    // ç”¨æˆ·ä¿®æ”¹åˆ©ç”¨è®°å½•时,清除字段高亮
    "utilizationData.serviceDonatecomporganList": {
      deep: true,
      handler() {
        if (Object.keys(this.errorFields).length > 0) {
          this.errorFields = {};
        }
      }
    }
  },
  created() {
@@ -1154,7 +1217,7 @@
    getOrganRowClassName({ row }) {
      if (
        row.transplantstate == "1" &&
        (!row.hospitalno || !row.name || !row.transplanttime)
        (!row.hospitalname || !row.name || !row.transplanttime)
      ) {
        return "warning-row";
      }
@@ -1162,6 +1225,11 @@
        return "warning-row";
      }
      return "";
    },
    // æ ¡éªŒå¤±è´¥æ—¶å­—段是否高亮
    isFieldError(row, field) {
      const fields = this.errorFields[row.organno];
      return fields && fields.includes(field);
    },
    // èŽ·å–çŠ¶æ€æ ‡ç­¾ç±»åž‹
@@ -1206,10 +1274,19 @@
    // ä¿å­˜åŸºæœ¬ä¿¡æ¯
    async handleSave() {
      if (this.saveLoading) return;
      this.$refs.form.validate(async valid => {
        if (valid) {
          this.saveLoading = true;
          try {
            // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…
            if (!this.form.id) {
              const exists = await this.checkPatientExists();
              if (exists) {
                this.$message.warning("该患者已存在,请勿重复添加");
                return;
              }
            }
            const saveData = {
              ...this.form,
              assessannex: JSON.stringify(this.attachments),
@@ -1240,6 +1317,33 @@
          }
        }
      });
    },
    // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…(按住院号)
    async checkPatientExists() {
      let inpatientno = this.form.inpatientno;
      if (!inpatientno && this.caseId) {
        try {
          const caseRes = await getDonatebaseinfo(this.caseId);
          inpatientno = (caseRes.data && caseRes.data.inpatientno) || "";
        } catch (e) {
          inpatientno = "";
        }
      }
      if (!inpatientno) return false;
      try {
        const res = await completionList({
          inpatientno,
          pageNum: 1,
          pageSize: 1
        });
        let list = res.data || [];
        if (!Array.isArray(list)) {
          list = list.rows || list.list || [];
        }
        return list.some(item => item && item.id != null && item.id !== "");
      } catch (e) {
        return false;
      }
    },
    // ä¿å­˜åˆ©ç”¨è®°å½•
@@ -1281,20 +1385,57 @@
    // ç¡®è®¤å®Œæˆåˆ©ç”¨
    async handleConfirmUtilization() {
      // æ£€æŸ¥åˆ©ç”¨è®°å½•是否完整
      const incompleteRecords = this.utilizationData.serviceDonatecomporganList.filter(
        record => {
          if (record.transplantstate == "1") {
            return !record.hospitalno || !record.name || !record.transplanttime;
          } else if (record.transplantstate == "0") {
            return !record.abandonreason;
          }
          return false;
      if (
        !this.utilizationData.serviceDonatecomporganList ||
        this.utilizationData.serviceDonatecomporganList.length == 0
      ) {
        this.$message.warning("请先添加利用记录");
        return;
      }
      // æ£€æŸ¥åˆ©ç”¨è®°å½•是否完整,记录缺失字段
      const errorFields = {};
      const incompleteRecords = [];
      this.utilizationData.serviceDonatecomporganList.forEach(record => {
        const missing = [];
        if (record.transplantstate == "1") {
          if (!record.hospitalname) missing.push("hospitalname");
          if (!record.name) missing.push("name");
          if (!record.transplanttime) missing.push("transplanttime");
        } else if (record.transplantstate == "0") {
          if (!record.abandonreason) missing.push("abandonreason");
        }
      );
        if (missing.length > 0) {
          errorFields[record.organno] = missing;
          incompleteRecords.push(record);
        }
      });
      this.errorFields = errorFields;
      if (incompleteRecords.length > 0) {
        this.$message.warning("请先完善所有利用记录的信息");
        // ä»…当缺少「未移植原因」时该字段位于折叠面板内,才自动展开对应面板
        this.expandedRows = incompleteRecords
          .filter(record =>
            (errorFields[record.organno] || []).includes("abandonreason")
          )
          .map(record => record.organno);
        // ç¼ºå¤±å­—段中文名,用于提示具体是哪个项没填
        const fieldLabels = {
          hospitalname: "移植医院",
          name: "受者姓名",
          transplanttime: "移植时间",
          abandonreason: "未移植原因"
        };
        const details = incompleteRecords
          .map(record => {
            const missingLabels = (errorFields[record.organno] || [])
              .map(field => fieldLabels[field] || field)
              .join("、");
            return `${record.organname || record.organno} ${missingLabels}`;
          })
          .join(";");
        this.$message.warning(`请完善以下器官的利用信息:${details}`);
        return;
      }
@@ -1760,6 +1901,13 @@
  background-color: #fdf6ec;
}
/* æ ¡éªŒå¤±è´¥å­—段高亮 */
.field-error >>> .el-input__inner,
.field-error >>> .el-textarea__inner {
  border-color: #f56c6c !important;
  box-shadow: 0 0 0 2px rgba(245, 108, 108, 0.15);
}
:deep(.el-table__row.default-row) {
  background-color: #f0f9ff;
}
src/views/business/OrganUtilization/index.vue
@@ -92,18 +92,7 @@
          prop="inpatientno"
          width="120"
        />
        <el-table-column
          label="案例编号"
          align="center"
          prop="caseNo"
          width="120"
        />
        <el-table-column
          label="捐献者姓名"
          align="center"
          prop="name"
          width="120"
        />
        <el-table-column label="姓名" align="center" prop="name" width="120" />
        <el-table-column label="性别" align="center" prop="sex" width="80">
          <template slot-scope="scope">
            <dict-tag
@@ -128,7 +117,27 @@
            <span v-else>-</span>
          </template>
        </el-table-column>
           <el-table-column
        <el-table-column
          label="疾病诊断"
          align="center"
          prop="diagnosisname"
          width="200"
          show-overflow-tooltip
        />
        <el-table-column
          label="捐献类型"
          align="center"
          prop="donationcategory"
          width="180"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_DonationCategory"
              :value="scope.row.donationcategory"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="利用状态"
          align="center"
          prop="recordstate"
@@ -174,10 +183,16 @@
        </el-table-column>
        <el-table-column
          label="捐献编号"
          align="center"
          prop="caseNo"
          width="220"
        />
        <el-table-column
          label="操作"
          fixed="right"
          align="center"
          width="210"
          width="120"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
@@ -185,24 +200,17 @@
              size="mini"
              type="text"
              icon="el-icon-view"
              @click="handleView(scope.row)"
              >详情</el-button
              @click.stop="handleView(scope.row)"
              >查看</el-button
            >
            <!-- <el-button
            <el-button
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click="handleUpdate(scope.row)"
              >修改</el-button
            > -->
            <!-- <el-button
              size="mini"
              type="text"
              icon="el-icon-delete"
              style="color: #F56C6C"
              @click="handleDelete(scope.row)"
              >删除</el-button
            > -->
              @click.stop="handleUpdate(scope.row)"
              >编辑</el-button
            >
          </template>
        </el-table-column>
      </el-table>
@@ -230,7 +238,7 @@
export default {
  name: "OrganUtilizationList",
  components: { Pagination },
  dicts: ["sys_user_sex", "sys_BloodType", "utilize_statue"],
  dicts: ["sys_user_sex", "sys_BloodType", "sys_DonationCategory", "utilize_statue"],
  data() {
    return {
      // é®ç½©å±‚
@@ -315,7 +323,8 @@
        path: "/case/organUtilizationInfo",
        query: {
          id: row.id,
          infoid: row.infoid
          infoid: row.infoid,
          mode: "view"
        }
      });
    },
@@ -331,7 +340,8 @@
        path: "/case/organUtilizationInfo",
        query: {
          id: id,
          infoid: infoid
          infoid: infoid,
          mode: "edit"
        }
      });
    },
src/views/business/affirm/affirmInfo.vue
@@ -9,28 +9,6 @@
      </div>
      <el-form :model="form" ref="form" label-width="120px" class="paper-form">
        <div class="form-row">
          <el-form-item
            label="协调员1"
            prop="coordinatedusernameo"
            class="col-1-3"
          >
            <el-input v-model="form.coordinatedusernameo" />
          </el-form-item>
          <el-form-item
            label="协调员2"
            prop="coordinatedusernamet"
            class="col-1-3"
          >
            <el-input v-model="form.coordinatedusernamet" />
          </el-form-item>
          <!-- <el-col :span="8">
            <el-form-item label="业务人员" prop="responsibleusername">
              <el-input v-model="form.responsibleusername" />
            </el-form-item>
          </el-col> -->
        </div>
        <!-- <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="确认时间" prop="signdate">
@@ -46,86 +24,155 @@
        <!-- äº²å±žä¿¡æ¯ -->
        <el-divider content-position="left">亲属确认信息</el-divider>
        <el-alert
          title="第一条数据为主要亲属,需填写完整的姓名、关系、身份证和电话信息"
          type="info"
          show-icon
          :closable="false"
          style="margin-bottom: 15px;"
        >
        </el-alert>
        <div style="margin-top: 15px;">
          <el-button
            style="float: right; margin-bottom: 5px;"
            type="primary"
            size="mini"
            icon="el-icon-plus"
            @click="openFamilyDialog(false)"
          >
            æ·»åŠ å…¶ä»–å®¶å±ž
          </el-button>
        <!-- ä¸»è¦äº²å±žè¡¨å• -->
        <div class="form-row">
          <el-form-item label="亲属姓名" class="col-1-3">
            <el-input
              v-model="familyMemberList[0].name"
              :disabled="isReadOnly"
              placeholder="请输入亲属姓名"
            />
          </el-form-item>
          <el-form-item label="关系" class="col-1-3">
            <el-select
              v-model="familyMemberList[0].relation"
              :disabled="isReadOnly"
              placeholder="请选择关系"
            >
              <el-option
                v-for="dict in dict.type.sys_FamilyRelation"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="身份证号" class="col-1-3">
            <el-input
              v-model="familyMemberList[0].idcard"
              :disabled="isReadOnly"
              placeholder="请输入身份证号"
              maxlength="18"
            />
          </el-form-item>
        </div>
        <el-table :data="familyMemberList" size="small" border>
        <div class="form-row">
          <el-form-item label="住址" class="col-full">
            <template v-if="!isReadOnly">
              <div class="area-select-box">
                <li_area_select v-model="familyMemberList[0].address" />
              </div>
              <el-input
                v-model="familyMemberList[0].address.detail"
                placeholder="请输入详细地址"
                class="address-detail"
              />
            </template>
            <span v-else>{{ formatAddress(familyMemberList[0].address) }}</span>
          </el-form-item>
        </div>
        <div class="form-row">
          <el-form-item label="现居住地" class="col-full">
            <template v-if="!isReadOnly">
              <div class="area-select-box">
                <li_area_select
                  v-model="familyMemberList[0].currentResidence"
                />
              </div>
              <el-input
                v-model="familyMemberList[0].currentResidence.detail"
                placeholder="请输入详细地址"
                class="address-detail"
              />
            </template>
            <span v-else>{{
              formatAddress(familyMemberList[0].currentResidence)
            }}</span>
          </el-form-item>
        </div>
        <div class="form-row">
          <el-form-item label="手机" class="col-1-3">
            <el-input
              v-model="familyMemberList[0].phone"
              :disabled="isReadOnly"
              placeholder="请输入手机号"
              maxlength="11"
            />
          </el-form-item>
        </div>
        <!-- äº²å±žå…³ç³»ç¡®è®¤ -->
        <div class="form-row">
          <el-form-item label="亲属关系确认" class="col-full">
            <el-checkbox-group
              v-model="form.kinship"
              :disabled="isReadOnly"
              @change="syncKinshipRelatives"
            >
              <el-checkbox
                v-for="dict in kinshipCheckboxOptions"
                :key="dict.value"
                :label="String(dict.value)"
              >
                {{
                  isChildLabel(dict.label) ? dict.label + "(人)" : dict.label
                }}
              </el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </div>
        <div class="form-row" v-if="adultChildSelected">
          <el-form-item label="子女数量" class="col-1-3">
            <el-input
              v-model="form.kinshipChildrennum"
              :disabled="isReadOnly"
              placeholder="请输入子女数量"
              @input="syncKinshipRelatives"
            />
          </el-form-item>
        </div>
        <!-- äº²å±žè¡¨ï¼ˆç”±äº²å±žå…³ç³»å‹¾é€‰è‡ªåŠ¨ç”Ÿæˆï¼Œå§“åå¯ç¼–è¾‘ï¼‰ -->
        <el-table
          :data="otherFamilyMemberList"
          size="small"
          border
          style="margin-top: 15px;"
        >
          <el-table-column label="序号" width="60" align="center">
            <template slot-scope="scope">
              {{ scope.$index + 1 }}
            </template>
          </el-table-column>
          <el-table-column label="姓名" prop="name" min-width="120">
          <el-table-column label="与捐赠者关系" width="160" align="center">
            <template slot-scope="scope">
              <span :class="{ 'main-family': scope.$index === 0 }">{{
                scope.row.name
              }}</span>
              {{ getKinshipLabel(scope.row.relation) }}
            </template>
          </el-table-column>
          <el-table-column label="与捐赠者关系" prop="relation" min-width="140">
          <el-table-column label="姓名" min-width="200">
            <template slot-scope="scope">
              <dict-tag
                :options="dict.type.sys_FamilyRelation"
                :value="scope.row.relation"
              <el-input
                style="width: 160px"
                v-model="scope.row.name"
                :disabled="isReadOnly"
                placeholder="请输入姓名"
                size="small"
              />
            </template>
          </el-table-column>
          <el-table-column label="身份证号" prop="idcard" min-width="180">
            <template slot-scope="scope">
              <span v-if="scope.$index === 0">{{ scope.row.idcard }}</span>
              <span v-else style="color: #909399;">-</span>
            </template>
          </el-table-column>
          <el-table-column label="联系电话" prop="phone" min-width="130">
            <template slot-scope="scope">
              <span v-if="scope.$index === 0">{{ scope.row.phone }}</span>
              <span v-else style="color: #909399;">-</span>
            </template>
          </el-table-column>
          <el-table-column label="类型" width="70" align="center">
            <template slot-scope="scope">
              <el-tag v-if="scope.$index === 0" type="warning" size="small"
                >主要</el-tag
              >
              <el-tag v-else type="info" size="small">其他</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="150" align="center">
          <el-table-column
            v-if="!isReadOnly"
            label="操作"
            width="80"
            align="center"
          >
            <template slot-scope="scope">
              <el-button
                size="mini"
                type="text"
                @click="editFamilyMember(scope.$index)"
              >
                ç¼–辑
              </el-button>
              <el-button
                v-if="scope.$index > 0"
                size="mini"
                type="text"
                style="color:red"
                @click="deleteFamilyMember(scope.$index)"
              >
                åˆ é™¤
              </el-button>
              <span v-else style="color: #909399; font-size: 12px;"
                >不可删除</span
                size="small"
                style="color: #f56c6c"
                @click="handleDeleteFamilyRow(scope.$index)"
                >删除</el-button
              >
            </template>
          </el-table-column>
@@ -133,24 +180,35 @@
        <div class="form-row">
          <el-form-item label-width="100px" label="捐献决定" class="col-full">
            <el-checkbox-group v-model="organdecision">
              <el-checkbox
                v-for="item in organselection"
                :key="item"
                :label="item"
                >{{ item }}
              </el-checkbox>
            </el-checkbox-group>
            <el-input
              v-if="organdecision.includes('其他')"
              v-model="organdecisionOther"
              placeholder="请输入其他捐献决定的具体内容"
              style="margin-top: 10px; width: 300px;"
            ></el-input>
            <div class="decision-statement">
              æˆ‘(们)已知悉捐献的相关法律法规及规定,同意并代表捐献者做出逝世后自愿、无偿捐献决定:
            </div>
            <template v-if="!isReadOnly">
              <el-checkbox-group v-model="organdecision">
                <el-checkbox
                  v-for="item in organselection"
                  :key="item"
                  :label="item"
                  >{{ item }}
                </el-checkbox>
              </el-checkbox-group>
              <el-input
                v-if="organdecision.includes('其他')"
                v-model="organdecisionOther"
                placeholder="请输入其他捐献决定的具体内容"
                class="decision-other"
              ></el-input>
            </template>
            <span v-else class="decision-selected">{{
              displayOrganDecision
            }}</span>
            <div class="decision-statement">
              åŒæ„ä¸Šè¿°æ‰€æç”¨äºŽä¸´åºŠåŒ»ç–—、医学教学和科学研究。
            </div>
          </el-form-item>
        </div>
        <div class="form-row">
        <!-- <div class="form-row">
          <el-form-item
            label="家属意见备注"
            prop="relativeRemark"
@@ -161,6 +219,65 @@
              :rows="3"
              v-model="form.relativeRemark"
              placeholder="记录家属的意见和沟通情况"
              :disabled="isReadOnly"
            />
          </el-form-item>
        </div> -->
        <!-- äººä½“器官获取组织与负责人签字 -->
        <div class="form-row">
          <el-form-item label="人体器官获取组织" class="col-half">
            <el-input
              v-model="form.acquisitiontissuename"
              :disabled="isReadOnly"
              placeholder="请输入人体器官获取组织"
            />
          </el-form-item>
          <el-form-item
            label="负责人签字"
            prop="responsibleusername"
            class="col-half"
          >
            <el-input
              v-model="form.responsibleusername"
              :disabled="isReadOnly"
              placeholder="请输入负责人签字"
            />
          </el-form-item>
        </div>
        <!-- åè°ƒå‘˜ä¸Žç­¾ç½²æ—¥æœŸ -->
        <div class="form-row">
          <el-form-item
            label="协调员1"
            prop="coordinatedusernameo"
            class="col-1-3"
          >
            <el-input
              v-model="form.coordinatedusernameo"
              :disabled="isReadOnly"
              placeholder="请输入协调员1"
            />
          </el-form-item>
          <el-form-item
            label="协调员2"
            prop="coordinatedusernamet"
            class="col-1-3"
          >
            <el-input
              v-model="form.coordinatedusernamet"
              :disabled="isReadOnly"
              placeholder="请输入协调员2"
            />
          </el-form-item>
          <el-form-item label="签署日期" prop="signdate" class="col-1-3">
            <el-date-picker
              clearable
              v-model="form.signdate"
              type="date"
              value-format="yyyy-MM-dd"
              placeholder="选择签署日期"
              :disabled="isReadOnly"
            />
          </el-form-item>
        </div>
@@ -169,15 +286,15 @@
    <!-- æ·»åŠ è¿™é‡Œï¼šåº•éƒ¨å±…ä¸­æŒ‰é’® -->
    <!-- é™„件信息 - æŒ‰ç±»åž‹åˆ†ç±» -->
    <!-- æçŒ®ç¡®è®¤é˜¶æ®µé™„件(可编辑) -->
    <el-card class="attachment-card">
      <div slot="header" class="clearfix">
        <span class="detail-title">相关附件上传</span>
        <span class="detail-title">捐献确认阶段附件</span>
      </div>
      <el-tabs v-model="activeAttachmentType" type="card">
        <el-tab-pane
          v-for="type in attachmentTypes"
          v-for="type in confirmAttachmentTypes"
          :key="type.value"
          :label="type.label"
          :name="type.value"
@@ -187,6 +304,7 @@
              <span class="upload-title">{{ type.label }}</span>
              <el-tooltip content="点击上传该类型附件" placement="top">
                <el-button
                  v-if="!isReadOnly"
                  size="mini"
                  type="primary"
                  icon="el-icon-plus"
@@ -199,7 +317,7 @@
            <div class="attachment-list">
              <el-table
                :data="getAttachmentsByType(type.value)"
                :data="getConfirmAttachments(type.value)"
                size="small"
                v-loading="attachmentLoading"
                style="width: 100%;"
@@ -244,6 +362,7 @@
                      é¢„览
                    </el-button>
                    <el-button
                      v-if="!isReadOnly"
                      size="mini"
                      type="danger"
                      @click="handleRemoveAttachment(type.value, scope.$index)"
@@ -255,7 +374,94 @@
              </el-table>
              <div
                v-if="getAttachmentsByType(type.value).length === 0"
                v-if="getConfirmAttachments(type.value).length === 0"
                class="empty-attachment"
              >
                <el-empty
                  :description="`暂无${type.label}附件`"
                  :image-size="80"
                ></el-empty>
              </div>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-card>
    <!-- æçŒ®è€…登记阶段附件(仅查看) -->
    <el-card class="attachment-card">
      <div slot="header" class="clearfix">
        <span class="detail-title">捐献者登记阶段附件(仅查看)</span>
      </div>
      <el-tabs v-model="activeRegisterType" type="card">
        <el-tab-pane
          v-for="type in registerAttachmentTypes"
          :key="type.value"
          :label="type.label"
          :name="type.value"
        >
          <div class="attachment-section">
            <div class="attachment-header">
              <span class="upload-title">{{ type.label }}</span>
            </div>
            <div class="attachment-list">
              <el-table
                :data="getRegisterAttachments(type.value)"
                size="small"
                v-loading="attachmentLoading"
                style="width: 100%;"
              >
                <el-table-column label="文件名" min-width="200">
                  <template slot-scope="scope">
                    <i
                      class="el-icon-document"
                      style="color: #409EFF; margin-right: 8px;"
                    ></i>
                    <span class="file-name">{{ scope.row.fileName }}</span>
                  </template>
                </el-table-column>
                <el-table-column label="文件类型" width="90" align="center">
                  <template slot-scope="scope">
                    <el-tag size="small">{{
                      getFileType(scope.row.fileName)
                    }}</el-tag>
                  </template>
                </el-table-column>
                <el-table-column label="文件大小" width="90" align="center">
                  <template slot-scope="scope">
                    <span>{{ formatFileSize(scope.row.fileSize) }}</span>
                  </template>
                </el-table-column>
                <el-table-column label="上传时间" width="155" align="center">
                  <template slot-scope="scope">
                    <span>{{
                      formatDateTime(
                        scope.row.uploadTime || scope.row.createTime
                      )
                    }}</span>
                  </template>
                </el-table-column>
                <el-table-column label="操作" width="90" align="center">
                  <template slot-scope="scope">
                    <el-button
                      size="mini"
                      type="primary"
                      @click="handlePreview(scope.row)"
                    >
                      é¢„览
                    </el-button>
                  </template>
                </el-table-column>
              </el-table>
              <div
                v-if="getRegisterAttachments(type.value).length === 0"
                class="empty-attachment"
              >
                <el-empty
@@ -271,6 +477,7 @@
    <!-- åº•部操作按钮 -->
    <div style="text-align: center; margin: 30px 0;">
      <el-button
        v-if="!isReadOnly"
        type="primary"
        @click="handleSave"
        :loading="saveLoading"
@@ -279,6 +486,7 @@
        ä¿å­˜ç¡®è®¤ä¿¡æ¯
      </el-button>
      <el-button
        v-if="!isReadOnly"
        type="success"
        @click="accomplish"
        :loading="saveLoading"
@@ -287,60 +495,6 @@
        ç¡®è®¤å®Œæˆ
      </el-button>
    </div>
    <!-- å®¶å±žå¼¹çª— -->
    <el-dialog
      :title="familyDialogTitle"
      :visible.sync="familyDialogVisible"
      width="420px"
      :close-on-click-modal="false"
    >
      <el-form :model="currentFamilyMember" label-width="110px">
        <el-form-item label="姓名" prop="name">
          <el-input
            v-model="currentFamilyMember.name"
            placeholder="请输入姓名"
          />
        </el-form-item>
        <el-form-item label="与捐赠者关系" prop="relation">
          <el-select
            v-model="currentFamilyMember.relation"
            style="width:100%"
            placeholder="请选择关系"
          >
            <el-option
              v-for="dict in dict.type.sys_FamilyRelation"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
        <template v-if="currentFamilyMember.isMain">
          <el-form-item label="身份证号" prop="idcard">
            <el-input
              v-model="currentFamilyMember.idcard"
              placeholder="请输入身份证号"
              maxlength="18"
            />
          </el-form-item>
          <el-form-item label="联系电话" prop="phone">
            <el-input
              v-model="currentFamilyMember.phone"
              placeholder="请输入联系电话"
              maxlength="11"
            />
          </el-form-item>
        </template>
      </el-form>
      <span slot="footer">
        <el-button @click="familyDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="saveFamilyMember">确定</el-button>
      </span>
    </el-dialog>
    <!-- ä¸Šä¼ å¯¹è¯æ¡† -->
    <el-dialog
@@ -394,18 +548,32 @@
</template>
<script>
import { relativesList, relativesEdit, relativesAdd } from "@/api/businessApi";
import {
  relativesList,
  relativesEdit,
  relativesAdd
} from "@/api/businessApi";
import {
  listRelativesconfirmation,
  getRelativesconfirmation
} from "@/api/project/relativesconfirmation";
import {
  getDonatebaseinfo,
  updateDonatebaseinfo
} from "@/api/project/donatebaseinfo";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import Li_area_select from "@/components/Address";
import { getToken } from "@/utils/auth";
export default {
  name: "ConfirmationDetail",
  components: {
    FilePreviewDialog,
    CaseBasicInfo
    CaseBasicInfo,
    Li_area_select
  },
  dicts: ["sys_FamilyRelation"],
  dicts: ["sys_FamilyRelation", "sys_KinshipConfirm", "sys_Kinship"],
  data() {
    return {
      caseId: null,
@@ -422,30 +590,34 @@
        coordinatedusernameo: "",
        coordinatedusernamet: "",
        responsibleusername: "",
        acquisitiontissuename: "",
        relativeconfirmationsign: "0",
        signdate: "",
        relativeconfirmationsignname: "",
        signfamilyrelations: "",
        relativeidcardno: "",
        relativephone: "",
        phone: "",
        kinship: [],
        kinshipChildrennum: null,
        relativeRemark: "",
        assessannex: "",
        otherFamilyMembers: ""
      },
      // ç»Ÿä¸€äº²å±žåˆ—表(第一条为主要亲属,其余为其他亲属)
      familyMemberList: [],
      // å½“前编辑的家属(弹窗用)
      currentFamilyMember: {
        name: "",
        relation: "",
        phone: "",
        idcard: "",
        isMain: false
      },
      isEditFamilyMember: false,
      editFamilyMemberIndex: -1,
      familyDialogVisible: false,
      familyDialogTitle: "添加家属",
      familyMemberList: [
        {
          name: "",
          relation: "",
          phone: "",
          idcard: "",
          address: { sheng: "", shi: "", qu: "", detail: "" },
          currentResidence: { sheng: "", shi: "", qu: "", detail: "" },
          isMain: true
        }
      ],
      // æ ‡è®°æœ¬æ¬¡ syncKinshipRelatives å±žäºŽ"回显填充"(此时允许用已有子女行数兜底数量)
      kinshipHydrated: false,
      uploadAction: process.env.VUE_APP_BASE_API + "/common/upload",
      headers: {
@@ -466,7 +638,9 @@
      loading: false,
      saveLoading: false,
      infoid: null,
      activeAttachmentType: "1",
      archiveData: null,
      activeAttachmentType: "2",
      activeRegisterType: "1",
      attachmentLoading: false,
      uploadDialogVisible: false,
      uploadLoading: false,
@@ -474,30 +648,117 @@
      currentUploadType: "",
      previewVisible: false,
      currentPreviewFile: null,
      attachmentTypes: [
        { value: "1", label: "人体器官潜在捐献者登记表" },
      // æçŒ®ç¡®è®¤é˜¶æ®µé™„件(可编辑,存储于亲属确认表 assessannex)
      confirmAttachmentTypes: [
        { value: "2", label: "人体器官捐献亲属确认登记表" },
        { value: "3", label: "捐献者及直系亲属身份证、户口簿相关证明" },
        { value: "4", label: "公民身故后人体器官(角膜)遗体捐献告知书" },
        { value: "5", label: "脑死亡判定知情同意书" },
        { value: "6", label: "心死亡判定知情同意书" }
        { value: "7", label: "授权委托资料" }
      ],
      attachmentData: {
        "1": [],
      confirmAttachmentData: {
        "2": [],
        "3": [],
        "4": [],
        "7": []
      },
      // æçŒ®è€…登记阶段附件(仅查看,存储于亲属确认表 assessannex)
      registerAttachmentTypes: [
        { value: "1", label: "人体器官潜在捐献者登记表附件" },
        { value: "5", label: "证件照" },
        { value: "6", label: "疾病诊断治疗" }
      ],
      registerAttachmentData: {
        "1": [],
        "5": [],
        "6": []
      }
    };
  },
  computed: {
    getCurrentTypeLabel() {
      const type = this.attachmentTypes.find(
        t => t.value === this.currentUploadType
    // æŸ¥çœ‹æ¨¡å¼ï¼šåªè¯»ï¼Œç¦ç”¨è¡¨å•并隐藏保存按钮
    isReadOnly() {
      return this.$route.query.mode === "view";
    },
    // æ˜¯å¦é€‰ä¸­"成年子女"
    adultChildSelected() {
      const value = this.findAdultChildValue();
      return value != null && (this.form.kinship || []).includes(value);
    },
    // äº²å±žå…³ç³»ç¡®è®¤å­—典(优先 sys_KinshipConfirm,其次 sys_Kinship)
    kinshipDictOptions() {
      const a = this.dict.type.sys_KinshipConfirm || [];
      const b = this.dict.type.sys_Kinship || [];
      return a.length ? a : b;
    },
    // é‡æŽ’亲属关系选项:子女/成年子女排倒数第二,受托人排最后
    orderedKinshipOptions() {
      const list = this.kinshipDictOptions;
      const children = list.filter(d => this.isChildLabel(d.label));
      const trustee = list.filter(d => d.label === "受托人");
      const others = list.filter(
        d => !this.isChildLabel(d.label) && d.label !== "受托人"
      );
      return [...others, ...children, ...trustee];
    },
    // æ¸²æŸ“勾选框实际使用的选项 = å½“前字典 + åŽ†å²è„æ•°æ®ä¸­æ˜ å°„ä¸åˆ°çš„å€¼
    // è„å€¼å¦‚果不在选项里,el-checkbox-group æ ¹æœ¬æ²¡æœ‰å¯¹åº”复选框,视觉上就是"勾不上";
    // è¡¥æˆå¸¦"(历史数据)"标记的项后既能显示勾选,也允许用户手动取消。
    // ç‹¬ç«‹æˆè®¡ç®—属性(不并入 orderedKinshipOptions),避免与 watch äº’相触发形成循环。
    kinshipCheckboxOptions() {
      const options = (this.orderedKinshipOptions || []).map(d => ({
        value: String(d.value),
        label: d.label
      }));
      const extra = [];
      (this.form.kinship || []).forEach(v => {
        const raw = String(v);
        if (!raw) return;
        if (options.some(o => o.value === raw)) return;
        if (extra.some(o => o.value === raw)) return;
        const label = this.getKinshipLabel(raw);
        extra.push({
          value: raw,
          label: label === raw ? `历史数据(${raw})` : `${label}(历史数据)`
        });
      });
      return [...options, ...extra];
    },
    // å…¶ä»–亲属列表(排除第一条主要亲属)
    otherFamilyMemberList() {
      return this.familyMemberList.slice(1);
    },
    // æçŒ®å†³å®šï¼ˆæŸ¥çœ‹æ¨¡å¼åªå±•示已勾选项)
    displayOrganDecision() {
      return (this.organdecision || [])
        .map(item => {
          if (item === "其他" && this.organdecisionOther) {
            return `其他(${this.organdecisionOther})`;
          }
          return item;
        })
        .join("、");
    },
    getCurrentTypeLabel() {
      const type =
        this.confirmAttachmentTypes.find(
          t => t.value === this.currentUploadType
        ) ||
        this.registerAttachmentTypes.find(
          t => t.value === this.currentUploadType
        );
      return type ? type.label : "";
    }
  },
  watch: {
    // å­—典是异步加载的,加载完成后重新校准已保存的勾选值并重算亲属表
    orderedKinshipOptions(val) {
      if (!val || !val.length) return;
      const normalized = this.normalizeKinshipValues(this.form.kinship || []);
      if (normalized.join(",") !== (this.form.kinship || []).join(",")) {
        this.form.kinship = normalized;
      }
      this.kinshipHydrated = true;
      this.syncKinshipRelatives();
    }
  },
  created() {
@@ -512,9 +773,39 @@
    async getDetail(infoid) {
      this.loading = true;
      try {
        const response = await relativesList({ infoid });
        const response = await relativesList({
          infoid,
          pageNum: 1,
          pageSize: 10
        });
        // äº²å±žç¡®è®¤å®Œæ•´è®°å½•(含 kinship å¤šé€‰å­—段),用于保证勾选回显
        let fullRecord = null;
        try {
          const fullRes = await listRelativesconfirmation({
            infoid,
            pageNum: 1,
            pageSize: 10
          });
          if (
            fullRes.code === 200 &&
            Array.isArray(fullRes.rows) &&
            fullRes.rows.length
          ) {
            // å¿…须校验 infoid ä¸€è‡´ï¼Œå¦åˆ™å¯èƒ½æ‹¿åˆ°å…¨è¡¨ç¬¬ä¸€æ¡è®°å½•
            const matched = fullRes.rows.find(
              r => String(r.infoid) === String(infoid)
            );
            fullRecord = matched || fullRes.rows[0];
          }
        } catch (e) {
          console.warn("获取亲属确认完整记录失败:", e);
        }
        if (response.code === 200) {
          this.handleDetailData(response);
          this.handleDetailData(response, fullRecord);
          await this.loadArchiveInfo();
          // å†ç”¨ä¸»é”®ç²¾ç¡®æ‹‰ä¸€æ¬¡å®Œæ•´è®°å½•,确保 kinship ä¸€å®šèƒ½æ‹¿åˆ°
          await this.loadFullKinship();
        } else {
          this.$message.error("获取详情失败:" + (response.msg || "未知错误"));
        }
@@ -526,7 +817,7 @@
      }
    },
    handleDetailData(response) {
    handleDetailData(response, fullRecord) {
      let detailData = null;
      if (response.data) {
        if (Array.isArray(response.data)) {
@@ -538,8 +829,60 @@
        } else {
          detailData = response.data;
        }
      } else if (response.rows && Array.isArray(response.rows)) {
        detailData = response.rows[0] || {};
      } else {
        detailData = response;
      }
      // å…ˆè§£æžäº²å±žå¤§å­—段:勾选值可能需要从它反推
      this.familyMemberList = [];
      let parsedMembers = [];
      const rawMembers =
        detailData.otherFamilyMembers ||
        (fullRecord && fullRecord.otherFamilyMembers) ||
        "";
      if (rawMembers) {
        try {
          parsedMembers =
            typeof rawMembers === "string"
              ? JSON.parse(rawMembers)
              : rawMembers || [];
          if (!Array.isArray(parsedMembers)) parsedMembers = [];
        } catch (e) {
          console.warn("解析其他家属数据失败:", e);
          parsedMembers = [];
        }
      }
      // äº²å±žå…³ç³»ç¡®è®¤å‹¾é€‰å€¼ï¼šå®Œæ•´è®°å½• â†’ è¯¦æƒ… â†’ ä»Žäº²å±žè¡¨åæŽ¨ï¼ˆä¸‰é‡å…œåº•)
      let kinshipRaw = null;
      if (
        fullRecord &&
        fullRecord.kinship != null &&
        fullRecord.kinship !== ""
      ) {
        kinshipRaw = fullRecord.kinship;
      } else if (detailData.kinship != null && detailData.kinship !== "") {
        kinshipRaw = detailData.kinship;
      }
      let kinshipValues = this.parseKinship(kinshipRaw);
      if (!kinshipValues.length) {
        // å…œåº•:亲属表能复现,说明它存的 relation å°±æ˜¯å½“时勾选的值
        kinshipValues = Array.from(
          new Set(
            parsedMembers
              .filter(
                m =>
                  m &&
                  m.isMain !== true &&
                  m.relation != null &&
                  m.relation !== ""
              )
              .map(m => String(m.relation).trim())
              .filter(v => v !== "")
          )
        );
      }
      this.form = {
@@ -555,81 +898,252 @@
        coordinatedusernameo: detailData.coordinatedusernameo || "",
        coordinatedusernamet: detailData.coordinatedusernamet || "",
        responsibleusername: detailData.responsibleusername || "",
        acquisitiontissuename: "",
        relativeconfirmationsign: detailData.relativeconfirmationsign || "0",
        signdate: detailData.signdate,
        signdate: this.normalizeSigndate(detailData.signdate),
        relativeconfirmationsignname:
          detailData.relativeconfirmationsignname || "",
        signfamilyrelations: detailData.signfamilyrelations || "",
        relativeidcardno: detailData.relativeidcardno || "",
        relativephone: detailData.relativephone || "",
        phone: detailData.phone || detailData.relativephone || "",
        kinship: kinshipValues,
        kinshipChildrennum:
          detailData.kinshipChildrennum != null &&
          detailData.kinshipChildrennum !== ""
            ? detailData.kinshipChildrennum
            : fullRecord && fullRecord.kinshipChildrennum != null
            ? fullRecord.kinshipChildrennum
            : null,
        relativeRemark: detailData.relativeRemark || "",
        assessannex: detailData.assessannex || ""
      };
      // åˆå§‹åŒ–家属列表
      this.familyMemberList = [];
      if (detailData.relativeconfirmationsignname) {
        this.familyMemberList.push({
          name: detailData.relativeconfirmationsignname,
          relation: detailData.signfamilyrelations || "",
          phone: detailData.relativephone || "",
          idcard: detailData.relativeidcardno || ""
        });
      }
      if (detailData.otherFamilyMembers) {
        try {
          const otherMembers =
            typeof detailData.otherFamilyMembers === "string"
              ? JSON.parse(detailData.otherFamilyMembers)
              : detailData.otherFamilyMembers || [];
          otherMembers.forEach(member => {
            this.familyMemberList.push({
              name: member.name,
              relation: member.relation,
              phone: member.phone || "",
              idcard: member.idcard || ""
            });
          });
        } catch (e) {
          console.warn("解析其他家属数据失败:", e);
      // ä¸»è¦äº²å±žï¼šä¼˜å…ˆå– JSON ä¸­æ ‡è®° isMain çš„项(新格式,含住址/现居住地)
      let mainMember = (parsedMembers || []).find(m => m && m.isMain === true);
      // å‘½ä¸­é¡¹åœ¨è§£æžæ•°ç»„中的位置;-1 è¡¨ç¤ºä¸»äº²å±žä¸æ¥è‡ª otherFamilyMembers
      let mainIndex = mainMember ? parsedMembers.indexOf(mainMember) : -1;
      if (!mainMember) {
        const hasMain =
          detailData.relativeconfirmationsignname ||
          detailData.signfamilyrelations ||
          detailData.relativeidcardno;
        if (hasMain) {
          // è€æ ¼å¼ï¼šä¸»äº²å±žå­˜åœ¨ä¸“用字段里,otherFamilyMembers åªå­˜"其他亲属"
          mainMember = {
            name: detailData.relativeconfirmationsignname || "",
            relation: detailData.signfamilyrelations || "",
            idcard: detailData.relativeidcardno || "",
            phone: detailData.phone || detailData.relativephone || "",
            address: "",
            currentResidence: "",
            isMain: true
          };
        } else if (parsedMembers.length) {
          // è„æ•°æ®å…œåº•:主亲属专用字段全空、JSON é‡Œä¹Ÿæ²¡æœ‰ isMain æ ‡è®°æ—¶ï¼Œ
          // æŠŠç¬¬ä¸€æ¡å½“作主亲属,其余作为其他亲属,避免主亲属整块空白
          mainMember = parsedMembers[0];
          mainIndex = 0;
        }
      }
      this.familyMemberList.push({
        name: (mainMember && mainMember.name) || "",
        relation: (mainMember && mainMember.relation) || "",
        idcard: (mainMember && mainMember.idcard) || "",
        phone: (mainMember && mainMember.phone) || "",
        address: this.normalizeAddress(mainMember && mainMember.address),
        currentResidence: this.normalizeAddress(
          mainMember && mainMember.currentResidence
        ),
        isMain: true
      });
      // å…¶ä»–亲属(姓名来自 JSON,关系按 kinship å‹¾é€‰ç”Ÿæˆï¼‰
      // åŽ†å²è„æ•°æ®çš„è¡Œæ²¡æœ‰ isMain / seq / ä½å€å­—段,这里统一补齐默认值
      (parsedMembers || []).forEach((member, idx) => {
        if (!member) return;
        if (idx === mainIndex) return;
        if (member.isMain === true) return;
        this.familyMemberList.push({
          relation: member.relation != null ? String(member.relation) : "",
          seq: member.seq != null ? member.seq : 0,
          name: member.name || "",
          phone: member.phone || "",
          idcard: member.idcard || "",
          address: this.normalizeAddress(member.address),
          currentResidence: this.normalizeAddress(member.currentResidence),
          isMain: false
        });
      });
      // å­—典若已缓存,watch ä¸ä¼šè§¦å‘,这里主动把勾选值归一化一次
      this.form.kinship = this.normalizeKinshipValues(this.form.kinship || []);
      // æ ¹æ® kinship å‹¾é€‰è‡ªåŠ¨ç”Ÿæˆäº²å±žè¡¨è¡Œï¼ˆä¿ç•™å·²æœ‰å§“åï¼‰
      this.kinshipHydrated = true;
      this.syncKinshipRelatives();
      if (detailData.organdecision) {
        this.organdecision = Array.isArray(detailData.organdecision)
          ? detailData.organdecision
          : detailData.organdecision.split(",");
      }
      this.organdecisionOther = detailData.organdecisionOther || "";
      this.processAssessannexData();
      // è°ƒè¯•用:确认 kinship / å­å¥³æ•°é‡ / äº²å±žå¤§å­—段 æ˜¯å¦éƒ½å›žæ¥äº†
      console.log("[affirmInfo] äº²å±žå…³ç³»å›žæ˜¾", {
        kinship: this.form.kinship,
        kinshipChildrennum: this.form.kinshipChildrennum,
        otherFamilyMembers: this.form.otherFamilyMembers
      });
    },
    processAssessannexData() {
      if (this.form.assessannex) {
        try {
          const annexData =
            typeof this.form.assessannex === "string"
              ? JSON.parse(this.form.assessannex)
              : this.form.assessannex;
          Object.keys(this.attachmentData).forEach(key => {
            this.attachmentData[key] = [];
          });
          if (Array.isArray(annexData)) {
            annexData.forEach(attachment => {
              const type = attachment.type || "1";
              if (this.attachmentData[type]) {
                this.attachmentData[type].push(attachment);
              }
            });
          }
        } catch (error) {
          console.warn("assessannex数据解析失败:", error);
    // åŠ è½½æ¡£æ¡ˆè¡¨ä¿¡æ¯ï¼ˆäººä½“å™¨å®˜èŽ·å–ç»„ç»‡ç­‰å­—æ®µå±žäºŽæ¡£æ¡ˆè¡¨ï¼Œä¸åœ¨äº²å±žç¡®è®¤è¡¨ï¼‰
    async loadArchiveInfo() {
      if (!this.caseId) return;
      try {
        const caseRes = await getDonatebaseinfo(this.caseId);
        if (caseRes.code === 200 && caseRes.data) {
          this.archiveData = caseRes.data;
          this.form.acquisitiontissuename =
            caseRes.data.acquisitiontissuename || "";
        }
      } catch (e) {
        console.warn("获取档案表信息失败:", e);
      }
    },
    getAttachmentsByType(type) {
      return this.attachmentData[type] || [];
    // ç”¨ä¸»é”®ç²¾ç¡®æ‹‰å–完整记录,补齐列表接口可能缺失的 kinship å­—段
    async loadFullKinship() {
      const rid = this.form.id || this.$route.query.id;
      if (!rid) return;
      try {
        const res = await getRelativesconfirmation(rid);
        const data = res && res.data;
        if (!data) return;
        let changed = false;
        if (data.kinship != null && data.kinship !== "") {
          const values = this.parseKinship(data.kinship);
          // æŽ¥å£è¿”回的真实值优先于从 otherFamilyMembers åæŽ¨çš„兜底值
          // ï¼ˆåæŽ¨å€¼åªç”¨äºŽå­—段缺失的情况,属于降级真相源)
          if (
            values.length &&
            values.join(",") !== (this.form.kinship || []).join(",")
          ) {
            this.form.kinship = values;
            changed = true;
          }
        }
        if (
          (this.form.kinshipChildrennum == null ||
            this.form.kinshipChildrennum === "") &&
          data.kinshipChildrennum != null
        ) {
          this.form.kinshipChildrennum = data.kinshipChildrennum;
          changed = true;
        }
        if (changed) {
          this.kinshipHydrated = true;
          this.syncKinshipRelatives();
        }
      } catch (e) {
        console.warn("获取亲属确认完整记录失败(getInfo):", e);
      }
    },
    // æŠŠå·²ä¿å­˜çš„勾选值映射到当前字典的 value(兼容两套字典编码不一致)
    // æ³¨æ„ï¼šæ˜ å°„不到的历史脏值(如 relation="4"/"6")必须原样保留,不能丢弃;
    // å­—典是异步加载的,若在此处过滤,字典一到位就会把反推出来的勾选清空。
    normalizeKinshipValues(values) {
      const options = this.orderedKinshipOptions || [];
      if (!options.length) return values;
      const result = [];
      (values || []).forEach(v => {
        const mapped = this.toCurrentKinshipValue(v);
        if (mapped !== "" && !result.includes(mapped)) result.push(mapped);
      });
      return result;
    },
    // å•个关系值 â†’ å½“前字典体系下的值
    // å‘½ä¸­é¡ºåºï¼šå½“前字典 value â†’ å½“前字典同名 label â†’ å­å¥³ç±»å½’一化(子女 â‡„ æˆå¹´å­å¥³ï¼‰
    // å…¨éƒ½å‘½ä¸­ä¸äº†è¯´æ˜Žæ˜¯åŽ†å²è„æ•°æ®ï¼ŒåŽŸæ ·è¿”å›žï¼Œä¿è¯è¡¨æ ¼è¡Œä¸ä¸¢ã€å‹¾é€‰ä¸è¢«æŠ¹æŽ‰
    toCurrentKinshipValue(v) {
      if (v == null || v === "") return "";
      const options = this.orderedKinshipOptions || [];
      if (!options.length) return String(v);
      const raw = String(v);
      if (options.some(o => String(o.value) === raw)) return raw;
      const label = this.getKinshipLabel(raw);
      if (!label || label === raw) return raw; // ä¸‰ä¸ªå­—典都查不到 â†’ è„å€¼åŽŸæ ·ä¿ç•™
      const sameLabel = options.find(o => o.label === label);
      if (sameLabel) return String(sameLabel.value);
      // å­å¥³ç±»å…³ç³»åœ¨ä¸åŒå­—典里叫法不同("子女"/"成年子女"),视为同一关系
      if (this.isChildLabel(label)) {
        const exact = options.find(o => o.label === "成年子女");
        if (exact) return String(exact.value);
        const any = options.find(o => this.isChildLabel(o.label));
        if (any) return String(any.value);
      }
      return raw;
    },
    // è§£æžäº²å±žå…³ç³»ç¡®è®¤ï¼ˆå¤šé€‰ï¼Œ; æˆ– , åˆ†éš”,统一转为字符串数组)
    parseKinship(val) {
      if (!val) return [];
      const arr = Array.isArray(val) ? val : String(val).split(/[;,]/);
      return arr
        .map(v => (v == null ? "" : String(v).trim()))
        .filter(v => v !== "");
    },
    // ç­¾ç½²æ—¥æœŸç»Ÿä¸€è½¬æˆ yyyy-MM-dd,兼容后端返回的多种日期格式
    normalizeSigndate(val) {
      if (!val) return null;
      const m = String(val).match(/^(\d{4}-\d{2}-\d{2})/);
      return m ? m[1] : null;
    },
    processAssessannexData() {
      Object.keys(this.confirmAttachmentData).forEach(key => {
        this.confirmAttachmentData[key] = [];
      });
      Object.keys(this.registerAttachmentData).forEach(key => {
        this.registerAttachmentData[key] = [];
      });
      if (!this.form.assessannex) return;
      try {
        const annexData =
          typeof this.form.assessannex === "string"
            ? JSON.parse(this.form.assessannex)
            : this.form.assessannex;
        if (Array.isArray(annexData)) {
          annexData.forEach(attachment => {
            const type = String(attachment.type || "");
            // ç¡®è®¤é˜¶æ®µï¼ˆ2/3/4)与登记阶段(1/5/6)均维护在 assessannex
            if (this.confirmAttachmentData[type]) {
              this.confirmAttachmentData[type].push(attachment);
            } else if (this.registerAttachmentData[type]) {
              this.registerAttachmentData[type].push(attachment);
            }
          });
        }
      } catch (error) {
        console.warn("assessannex数据解析失败:", error);
      }
    },
    getConfirmAttachments(type) {
      return this.confirmAttachmentData[type] || [];
    },
    getRegisterAttachments(type) {
      return this.registerAttachmentData[type] || [];
    },
    openUploadDialog(type) {
@@ -696,7 +1210,11 @@
        uploadTime: this.getCurrentTime(),
        uploader: "当前用户"
      };
      this.attachmentData[this.currentUploadType].push(newAttachment);
      if (this.confirmAttachmentData[this.currentUploadType]) {
        this.confirmAttachmentData[this.currentUploadType].push(newAttachment);
      } else if (this.registerAttachmentData[this.currentUploadType]) {
        this.registerAttachmentData[this.currentUploadType].push(newAttachment);
      }
      this.updateAssessannexField();
      this.$message.success("上传成功");
@@ -721,8 +1239,10 @@
        type: "warning"
      })
        .then(() => {
          if (this.attachmentData[type] && this.attachmentData[type][index]) {
            this.attachmentData[type].splice(index, 1);
          const container =
            this.confirmAttachmentData[type] || this.registerAttachmentData[type];
          if (container && container[index]) {
            container.splice(index, 1);
            this.$message.success("附件删除成功");
            this.updateAssessannexField();
          }
@@ -730,146 +1250,276 @@
        .catch(() => {});
    },
    // å®¶å±žæ“ä½œæ–¹æ³•
    openFamilyDialog(isMain) {
      this.isEditFamilyMember = false;
      this.editFamilyMemberIndex = -1;
      this.familyDialogTitle = "添加其他家属";
    // æ ¹æ® kinship å‹¾é€‰è‡ªåŠ¨ç”Ÿæˆäº²å±žè¡¨è¡Œï¼ŒåŒæ—¶ä¿ç•™å·²æœ‰äº²å±žæ•°æ®ï¼ˆåˆå¹¶ï¼Œé¿å…ä¸¢å¤±ï¼‰
    syncKinshipRelatives() {
      // å‹¾é€‰å€¼ç»Ÿä¸€æ˜ å°„到当前字典体系,保证与表格行的 relation å¤„在同一值域。
      // å¿…须去重:历史脏数据里多个不同编码(如 "4"、"6")可能映射成同一个 value,
      // ä¸åŽ»é‡çš„è¯æ¯ä¸ªé‡å¤å€¼éƒ½ä¼šå†ç”Ÿæˆä¸€éè¡Œï¼Œè¡¨çŽ°å°±æ˜¯"行数成倍变多"。
      const kinship = Array.from(
        new Set(
          (this.form.kinship || [])
            .map(v => this.toCurrentKinshipValue(v))
            .filter(v => v !== "")
        )
      );
      const adultChildValue = this.findAdultChildValue();
      // å¦‚果还没有任何家属,则添加主要亲属
      if (this.familyMemberList.length === 0) {
        this.currentFamilyMember = {
          name: "",
          relation: "",
          phone: "",
          idcard: "",
          isMain: true
        };
        this.familyDialogTitle = "添加主要亲属";
      // å·²æœ‰äº²å±žï¼ˆéžä¸»è¦äº²å±žï¼‰ï¼Œä¿ç•™å§“名与关系;关系值统一映射到当前字典体系
      const existing = this.familyMemberList
        .slice(1)
        .filter(m => m && !m.isMain)
        .map(m => ({ ...m, relation: this.toCurrentKinshipValue(m.relation) }));
      // å­å¥³æ•°é‡ï¼šæŽ¥å£å¯èƒ½ä¸è¿”回该字段
      // å›žæ˜¾æ—¶ç”¨å·²æœ‰å­å¥³è¡Œæ•°å…œåº•;用户主动清空("")则不兜底,行照常清掉
      const existingChildCount = adultChildValue
        ? existing.filter(e => e.relation === adultChildValue).length
        : 0;
      const rawCountStr = this.form.kinshipChildrennum;
      // null / "" / æ•°å­— 0 éƒ½è§†ä¸º"没填数量"(真要 0 ä¸ªï¼Œå–消勾选即可)
      const rawMissing =
        rawCountStr == null || rawCountStr === "" || rawCountStr === 0;
      let childCount;
      if (rawMissing) {
        childCount = this.kinshipHydrated ? existingChildCount : 0;
        // å›žæ˜¾å…œåº•:把推算出的数量写回表单,否则数量框空白、保存时又丢
        // ï¼ˆç¨‹åºèµ‹å€¼ä¸ä¼šè§¦å‘ el-input çš„ @input,不会形成循环)
        if (this.kinshipHydrated && existingChildCount > 0) {
          this.form.kinshipChildrennum = String(existingChildCount);
        }
      } else {
        this.currentFamilyMember = {
          name: "",
          relation: "",
          phone: "",
          idcard: "",
          isMain: false
        };
        const n = parseInt(rawCountStr, 10);
        childCount = isNaN(n) || n < 0 ? 0 : n;
      }
      this.familyDialogVisible = true;
    },
    editFamilyMember(index) {
      this.isEditFamilyMember = true;
      this.editFamilyMemberIndex = index;
      const member = this.familyMemberList[index];
      this.currentFamilyMember = {
        name: member.name,
        relation: member.relation,
        phone: member.phone || "",
        idcard: member.idcard || "",
        isMain: index === 0
      };
      this.familyDialogTitle = index === 0 ? "编辑主要亲属" : "编辑其他家属";
      this.familyDialogVisible = true;
    },
    deleteFamilyMember(index) {
      if (index === 0) {
        this.$message.warning("主要亲属不可删除");
        return;
      }
      this.$confirm("确认删除该家属?", "提示", { type: "warning" })
        .then(() => {
          this.familyMemberList.splice(index, 1);
          this.updateFamilyMemberField();
        })
        .catch(() => {});
    },
    saveFamilyMember() {
      if (!this.currentFamilyMember.name) {
        this.$message.warning("请输入姓名");
        return;
      }
      if (!this.currentFamilyMember.relation) {
        this.$message.warning("请选择与捐赠者关系");
        return;
      }
      // å¦‚果是主要亲属,验证身份证和电话
      if (this.currentFamilyMember.isMain) {
        if (!this.currentFamilyMember.idcard) {
          this.$message.warning("请输入主要亲属的身份证号");
          return;
      // å–一行已有数据复用姓名:先按 å…³ç³»+序号 ç²¾ç¡®åŒ¹é…ï¼Œå†é€€åŒ–为同关系顺序取
      const used = new Set();
      const takeExisting = (relation, seq) => {
        let idx = existing.findIndex(
          (e, i) =>
            !used.has(i) && e.relation === relation && (e.seq || 0) === seq
        );
        if (idx === -1) {
          idx = existing.findIndex(
            (e, i) => !used.has(i) && e.relation === relation
          );
        }
        if (
          !/^(\d{15}|\d{18}|\d{17}(\d|X|x))$/.test(
            this.currentFamilyMember.idcard
          )
        ) {
          this.$message.warning("请输入正确的身份证号");
          return;
        }
        if (!this.currentFamilyMember.phone) {
          this.$message.warning("请输入主要亲属的联系电话");
          return;
        }
        if (!/^1[3-9]\d{9}$/.test(this.currentFamilyMember.phone)) {
          this.$message.warning("请输入正确的手机号");
          return;
        }
      }
      const memberData = {
        name: this.currentFamilyMember.name,
        relation: this.currentFamilyMember.relation,
        phone: this.currentFamilyMember.isMain
          ? this.currentFamilyMember.phone
          : "",
        idcard: this.currentFamilyMember.isMain
          ? this.currentFamilyMember.idcard
          : ""
        if (idx === -1) return null;
        used.add(idx);
        return existing[idx];
      };
      if (this.isEditFamilyMember) {
        this.familyMemberList.splice(this.editFamilyMemberIndex, 1, memberData);
      } else {
        this.familyMemberList.push(memberData);
      }
      // ç”Ÿæˆä¸€è¡Œï¼šå‘½ä¸­å·²æœ‰è¡Œæ—¶æ•´è¡Œå¤ç”¨ï¼ˆå« phone/idcard/住址等),
      // åŽ†å²è„æ•°æ®é‡Œè¿™äº›å­—æ®µå¯èƒ½æœ‰å€¼ï¼Œé‡å»ºæ—¶ä¸èƒ½åªä¿ç•™ relation/name æŠŠå…¶ä½™æŠ¹æŽ‰
      const buildRow = (relation, seq, hit) => ({
        relation: relation,
        seq: seq,
        name: (hit && hit.name) || "",
        phone: (hit && hit.phone) || "",
        idcard: (hit && hit.idcard) || "",
        address: this.normalizeAddress(hit && hit.address),
        currentResidence: this.normalizeAddress(hit && hit.currentResidence),
        isMain: false
      });
      const merged = [];
      kinship.forEach(rel => {
        if (adultChildValue && rel === adultChildValue) {
          // æˆå¹´å­å¥³ï¼šå­å¥³æ•°é‡å†³å®šè¡Œæ•°
          for (let i = 0; i < childCount; i++) {
            const hit = takeExisting(rel, i);
            merged.push(buildRow(rel, i, hit));
          }
        } else {
          const hit = takeExisting(rel, 0);
          merged.push(buildRow(rel, 0, hit));
        }
      });
      // æœªè¢«å‹¾é€‰å‘½ä¸­çš„已有亲属一律保留。
      // ä¸èƒ½æŒ‰å…³ç³»åŽ»é‡ï¼šåŽ†å²æ•°æ®é‡Œ"两个兄弟姐妹"这类同关系多行是合法的,
      // åŽ»é‡ä¼šé™é»˜ä¸¢äººã€‚ä¹‹å‰å‡ºçŽ°"同关系重复行"的根因是 takeExisting æ²¡å‘½ä¸­ï¼Œ
      // çŽ°åœ¨ used ä¿è¯æ¯ä¸ªå·²æœ‰è¡Œæœ€å¤šè¢«æ¶ˆè€—一次,不会重复生成。
      existing.forEach((e, idx) => {
        if (used.has(idx)) return;
        // å­å¥³è¡Œæ•°ç”±å­å¥³æ•°é‡å†³å®šï¼Œå¤šä½™çš„子女行不保留
        if (adultChildValue && e.relation === adultChildValue) return;
        merged.push(buildRow(e.relation || "", e.seq != null ? e.seq : 0, e));
      });
      this.familyMemberList = [this.familyMemberList[0], ...merged];
      this.updateFamilyMemberField();
      this.familyDialogVisible = false;
      this.$message.success(this.isEditFamilyMember ? "编辑成功" : "添加成功");
      // å…œåº•只在回显那一次生效
      this.kinshipHydrated = false;
    },
    // åˆ é™¤äº²å±žè¡¨æŸä¸€è¡Œï¼Œå¹¶åŒæ­¥å–消上方对应的关系勾选
    handleDeleteFamilyRow(index) {
      const rowIndex = index + 1; // otherFamilyMemberList = familyMemberList.slice(1)
      const row = this.familyMemberList[rowIndex];
      if (!row) return;
      if (row.isMain) return;
      const relation = row.relation
        ? this.toCurrentKinshipValue(row.relation)
        : "";
      const adultChildValue = this.findAdultChildValue();
      const isChild = !!adultChildValue && relation === adultChildValue;
      // å‹¾é€‰é‡Œå­˜çš„可能是历史编码(如 "4")而不是映射后的值(如 "2"),
      // å–消勾选时两种都要比对,否则会出现"行删了但勾选还在"
      const removeKinship = target => {
        const mapped = this.toCurrentKinshipValue(target);
        this.form.kinship = (this.form.kinship || []).filter(
          v =>
            String(v) !== String(target) &&
            this.toCurrentKinshipValue(v) !== mapped
        );
      };
      console.log("[affirmInfo] åˆ é™¤äº²å±žè¡Œ", {
        index,
        relation,
        adultChildValue,
        isChild,
        before: this.familyMemberList.slice(1).map(m => m.relation),
        kinship: this.form.kinship
      });
      if (isChild) {
        // æˆå¹´å­å¥³ï¼šç›´æŽ¥åˆ è¿™ä¸€è¡Œï¼Œæ•°é‡æŒ‰å‰©ä½™å­å¥³è¡Œæ•°é‡ç®—,归零才取消勾选
        this.familyMemberList.splice(rowIndex, 1);
        const rest = this.familyMemberList.filter(
          (m, i) =>
            i > 0 &&
            !m.isMain &&
            this.toCurrentKinshipValue(m.relation) === adultChildValue
        ).length;
        if (rest > 0) {
          this.form.kinshipChildrennum = String(rest);
        } else {
          this.form.kinshipChildrennum = "";
          removeKinship(adultChildValue);
        }
      } else if (relation) {
        // å…¶ä½™å…³ç³»ï¼šä¸€è¡Œå¯¹åº”一个勾选,取消勾选并整组清掉
        removeKinship(relation);
        this.familyMemberList = this.familyMemberList.filter(
          (m, i) =>
            i === 0 ||
            m.isMain ||
            this.toCurrentKinshipValue(m.relation) !== relation
        );
      } else {
        // å…³ç³»ä¸ºç©ºçš„历史遗留行,只删这一行
        this.familyMemberList.splice(rowIndex, 1);
      }
      // ç›´æŽ¥å›žå†™å¤§å­—段。不调用 syncKinshipRelatives,避免行被按勾选重新生成回来
      this.updateFamilyMemberField();
      if (relation) {
        this.$message.success(
          `已移除「${this.getKinshipLabel(relation)}」并同步取消勾选`
        );
      }
    },
    getKinshipLabel(value) {
      if (value == null || value === "") return "";
      const dictLists = [
        this.dict.type.sys_KinshipConfirm,
        this.dict.type.sys_Kinship,
        this.dict.type.sys_FamilyRelation
      ];
      for (const list of dictLists) {
        const dict = (list || []).find(d => String(d.value) === String(value));
        if (dict) return dict.label;
      }
      // ä¸‰ä¸ªå­—典都查不到 â†’ è€ç¼–码/脏数据,按原值展示,并记录一次便于排查
      if (!this._warnedKinshipValues) this._warnedKinshipValues = new Set();
      const key = String(value);
      if (!this._warnedKinshipValues.has(key)) {
        this._warnedKinshipValues.add(key);
        console.warn(
          `[affirmInfo] äº²å±žå…³ç³»ç¼–码「${key}」在 sys_KinshipConfirm / sys_Kinship / sys_FamilyRelation ä¸­å‡ä¸å­˜åœ¨ï¼ŒæŒ‰åŽŸå€¼å±•ç¤º`
        );
      }
      return value;
    },
    isChildLabel(label) {
      return label === "子女" || label === "成年子女";
    },
    findAdultChildValue() {
      const list = this.kinshipDictOptions || [];
      // ä¼˜å…ˆç²¾ç¡®åŒ¹é…"成年子女",避免把"子女"当成成年子女处理
      const exact = list.find(d => d.label === "成年子女");
      if (exact) return String(exact.value);
      const any = list.find(d => this.isChildLabel(d.label));
      return any ? String(any.value) : null;
    },
    formatAddress(addr) {
      if (!addr) return "";
      if (typeof addr === "string") return addr;
      return [addr.sheng, addr.shi, addr.qu, addr.detail]
        .filter(p => p)
        .join("");
    },
    normalizeAddress(addr) {
      if (!addr) {
        return { sheng: "", shi: "", qu: "", detail: "" };
      }
      if (typeof addr === "string") {
        return { sheng: "", shi: "", qu: "", detail: addr };
      }
      return {
        sheng: (addr && addr.sheng) || "",
        shi: (addr && addr.shi) || "",
        qu: (addr && addr.qu) || "",
        detail: (addr && addr.detail) || ""
      };
    },
    updateFamilyMemberField() {
      if (this.familyMemberList.length > 0) {
        const mainMember = this.familyMemberList[0];
        this.form.relativeconfirmationsignname = mainMember.name;
        this.form.signfamilyrelations = mainMember.relation;
      const mainMember = this.familyMemberList[0];
      if (mainMember) {
        this.form.relativeconfirmationsignname = mainMember.name || "";
        this.form.signfamilyrelations = mainMember.relation || "";
        this.form.relativeidcardno = mainMember.idcard || "";
        this.form.phone = mainMember.phone || "";
        this.form.relativephone = mainMember.phone || "";
        const otherMembers = this.familyMemberList.slice(1).map(member => ({
          name: member.name,
          relation: member.relation,
          phone: member.phone || "",
          idcard: member.idcard || ""
        }));
        this.form.otherFamilyMembers = JSON.stringify(otherMembers);
      } else {
        this.form.relativeconfirmationsignname = "";
        this.form.signfamilyrelations = "";
        this.form.relativeidcardno = "";
        this.form.phone = "";
        this.form.relativephone = "";
        this.form.otherFamilyMembers = "[]";
      }
      // æ‰€æœ‰äº²å±žï¼ˆå«ä¸»è¦äº²å±žï¼‰ç»Ÿä¸€å­˜å…¥ä¸€ä¸ª JSON å¤§å­—段,住址/现居住地也存这里
      const allMembers = this.familyMemberList.map((member, index) => ({
        name: member.name || "",
        relation: member.relation || "",
        idcard: member.idcard || "",
        phone: member.phone || "",
        address: member.address || "",
        currentResidence: member.currentResidence || "",
        seq: member.seq != null ? member.seq : 0,
        isMain: index === 0
      }));
      this.form.otherFamilyMembers = JSON.stringify(allMembers);
    },
    updateAssessannexField() {
      const allAttachments = [];
      Object.values(this.attachmentData).forEach(attachments => {
      [
        ...Object.values(this.confirmAttachmentData),
        ...Object.values(this.registerAttachmentData)
      ].forEach(attachments => {
        allAttachments.push(...attachments);
      });
      this.form.assessannex = JSON.stringify(allAttachments);
@@ -977,6 +1627,7 @@
    },
    async handleSave() {
      if (this.saveLoading) return;
      try {
        await this.$refs.form.validate();
        this.saveLoading = true;
@@ -988,10 +1639,26 @@
          ...this.form,
          infoid: this.infoid,
          organdecision: this.organdecision.join(","),
          organdecisionOther: this.organdecisionOther
          organdecisionOther: this.organdecisionOther,
          kinship: (this.form.kinship || []).join(",")
        };
        // äººä½“器官获取组织属于档案表字段,不随亲属确认表保存
        delete saveData.acquisitiontissuename;
        // ç­¾ç½²æ—¥æœŸä¸ºç©ºæ—¶ä¸æäº¤ï¼Œé¿å…åŽç«¯ Date ååºåˆ—化报错
        if (!saveData.signdate) {
          delete saveData.signdate;
        }
        if (saveData.state == 1 || !saveData.state) {
          saveData.state = 2;
        }
        // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…
        if (!saveData.id) {
          const exists = await this.checkPatientExists();
          if (exists) {
            this.$message.warning("该患者已存在,请勿重复添加");
            return;
          }
        }
        let response = null;
@@ -1002,6 +1669,8 @@
        }
        if (response.code === 200) {
          // äººä½“器官获取组织单独保存到档案表
          await this.saveArchiveAcquisitionTissue();
          this.$message.success("保存成功");
          this.$router.push("/case/affirm");
        } else {
@@ -1014,6 +1683,45 @@
        }
      } finally {
        this.saveLoading = false;
      }
    },
    // ä¿å­˜æ¡£æ¡ˆè¡¨çš„人体器官获取组织字段
    async saveArchiveAcquisitionTissue() {
      if (!this.caseId) return;
      try {
        const payload = {
          ...(this.archiveData || {}),
          id: this.caseId,
          acquisitiontissuename: this.form.acquisitiontissuename
        };
        await updateDonatebaseinfo(payload);
      } catch (e) {
        console.warn("保存档案表人体器官获取组织失败:", e);
      }
    },
    // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…(按住院号)
    async checkPatientExists() {
      let inpatientno = this.form.inpatientno;
      if (!inpatientno && this.caseId) {
        try {
          const caseRes = await getDonatebaseinfo(this.caseId);
          inpatientno = (caseRes.data && caseRes.data.inpatientno) || "";
        } catch (e) {
          inpatientno = "";
        }
      }
      if (!inpatientno) return false;
      try {
        const res = await relativesList({
          inpatientno,
          pageNum: 1,
          pageSize: 1
        });
        const list = res.data || [];
        return list.some(item => item && item.id != null && item.id !== "");
      } catch (e) {
        return false;
      }
    }
  }
@@ -1171,19 +1879,53 @@
  line-height: 1.4;
}
/* æŽ§ä»¶å®½åº¦é€‚中,不铺满整格(内容短时输入框不再拉得很长) */
/* æŽ§ä»¶å®½åº¦é€‚中,不铺满整格(内容短时输入框不再拉得很长);窄屏时自动收缩避免溢出 */
.paper-form >>> .el-form-item__content .el-input,
.paper-form >>> .el-form-item__content .el-select,
.paper-form >>> .el-form-item__content .el-cascader {
  width: 220px;
  max-width: 100%;
  width: 100%;
  max-width: 220px;
}
.paper-form >>> .el-form-item__content .el-date-editor {
  width: 240px;
  max-width: 100%;
  width: 100%;
  max-width: 240px;
}
.paper-form >>> .el-form-item__content .el-range-editor {
  width: 360px;
  max-width: 100%;
}
/* åœ°å€é€‰æ‹©å™¨ï¼ˆçœå¸‚区三级联动 + è¯¦ç»†åœ°å€ï¼Œè¯¦ç»†åœ°å€åˆ†è¡Œæ˜¾ç¤ºï¼‰ */
.paper-form >>> .area-select-box {
  flex: 0 0 auto;
  width: 480px;
  max-width: 100%;
}
.paper-form >>> .address-detail {
  flex: 0 0 100%;
  width: 100% !important;
  margin: 6px 0 0 0;
}
/* æçŒ®å†³å®šè¯­å¥æŽ’版 */
.paper-form >>> .decision-statement {
  flex: 0 0 100%;
  width: 100%;
  line-height: 1.8;
  font-size: 13px;
  color: #303133;
  padding: 2px 0;
}
.paper-form >>> .decision-other {
  width: 320px !important;
  margin-left: 8px;
}
.paper-form >>> .decision-selected {
  flex: 0 0 100%;
  width: 100%;
  line-height: 1.8;
  font-size: 13px;
  color: #303133;
  padding: 2px 0;
}
</style>
src/views/business/affirm/index.vue
@@ -112,9 +112,9 @@
      >
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column
          label="捐献编号"
          label="住院号"
          align="center"
          prop="caseNo"
          prop="inpatientno"
          width="120"
        />
        <el-table-column label="姓名" align="center" prop="name" width="120" />
@@ -128,12 +128,38 @@
        </el-table-column>
        <el-table-column label="年龄" align="center" prop="age" width="80" />
        <el-table-column
          label="血型"
          align="center"
          prop="bloodtype"
          width="80"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_BloodType"
              :value="scope.row.bloodtype"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="疾病诊断"
          align="center"
          prop="diagnosisname"
          min-width="180"
          width="200"
          show-overflow-tooltip
        />
        <el-table-column
          label="捐献类型"
          align="center"
          prop="donationcategory"
          width="180"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_DonationCategory"
              :value="scope.row.donationcategory"
            />
          </template>
        </el-table-column>
        <!-- <el-table-column
          label="确认状态"
          align="center"
@@ -173,13 +199,13 @@
            />
          </template>
        </el-table-column>
        <el-table-column
        <!-- <el-table-column
          label="家属意见"
          align="center"
          prop="relativeRemark"
          width="150"
          show-overflow-tooltip
        />
        /> -->
        <el-table-column
          label="协调员1"
          align="center"
@@ -196,19 +222,25 @@
          label="上报医院"
          align="center"
          prop="treatmenthospitalname"
          width="150"
          width="220"
          show-overflow-tooltip
        />
        <el-table-column
        <!-- <el-table-column
          label="上报人员"
          align="center"
          prop="responsibleusername"
          width="100"
        />
        /> -->
        <el-table-column
          label="捐献编号"
          align="center"
          prop="caseNo"
          width="220"
        />
         <el-table-column
          label="操作"
          align="center"
          width="120"
          min-width="180"
          fixed="right"
          class-name="small-padding fixed-width"
        >
@@ -218,16 +250,15 @@
              type="text"
              icon="el-icon-view"
              @click.stop="handleView(scope.row)"
              >详情</el-button
              >查看</el-button
            >
            <!-- <el-button
              v-if="scope.row.relativeconfirmationsign === '0'"
            <el-button
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click.stop="handleConfirm(scope.row)"
              >确认</el-button
            > -->
              @click.stop="handleUpdate(scope.row)"
              >编辑</el-button
            >
          </template>
        </el-table-column>
      </el-table>
@@ -251,7 +282,7 @@
export default {
  name: "ConfirmationList",
  components: { Pagination },
  dicts: ["sys_user_sex", "affirm_type"],
  dicts: ["sys_user_sex", "affirm_type", "sys_BloodType", "sys_DonationCategory"],
  data() {
    return {
      // é®ç½©å±‚
@@ -425,29 +456,19 @@
    handleView(row) {
      this.$router.push({
        path: "/case/affirmInfo",
        query: { id: row.id, infoid: row.infoid }
        query: { id: row.id, infoid: row.infoid, mode: "view" }
      });
    },
    // ç¡®è®¤æ“ä½œ
    handleConfirm(row) {
    // ç¼–辑
    handleUpdate(row) {
      this.$router.push({
        path: "/case/affirmInfo",
        query: { id: row.id, confirm: true }
        query: { id: row.id, infoid: row.infoid, confirm: true, mode: "edit" }
      });
    },
    // æ–°å¢žæŒ‰é’®æ“ä½œ
    handleCreate() {
      this.$router.push("/case/confirmation/add");
    },
    // ä¿®æ”¹æŒ‰é’®æ“ä½œ
    handleUpdate() {
      if (this.ids.length === 0) return;
      const id = this.ids[0];
      this.$router.push({
        path: "/case/confirmation/edit",
        query: { id: id }
      });
    },
    // åˆ é™¤æŒ‰é’®æ“ä½œ
    async handleDelete() {
src/views/business/allocation/allocationInfo.vue
@@ -10,20 +10,20 @@
      <el-form :model="form" ref="form" :rules="rules" label-width="120px" class="paper-form">
        <div class="form-row">
          <el-form-item label="分配状态" prop="allocationStatus" class="col-half">
            <el-select v-model="form.allocationStatus" placeholder="请选择分配状态">
            <el-select v-model="form.allocationStatus" placeholder="请选择分配状态" :disabled="isReadOnly">
              <el-option v-for="dict in dict.type.organ_allocation_status || []" :key="dict.value" :label="dict.label"
                :value="dict.value"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="分配时间" prop="allocationTime" class="col-half">
            <el-date-picker v-model="form.allocationTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%" :disabled="form.allocationStatus == '1'" />
              style="width: 100%" :disabled="form.allocationStatus == '1' || isReadOnly" />
          </el-form-item>
        </div>
        <div class="form-row">
          <el-form-item label="负责人" prop="registrationName" class="col-half">
              <el-input v-model="form.registrationName" />
              <el-input v-model="form.registrationName" :disabled="isReadOnly" />
          </el-form-item>
        </div>
      </el-form>
@@ -43,12 +43,12 @@
          <el-form-item label-width="100px" label="分配器官" class="col-full">
              <el-checkbox-group v-model="selectedOrgans" @change="handleOrganSelectionChange">
                <el-checkbox v-for="dict in dict.type.sys_Organ || []" :key="dict.value" :label="dict.value"
                  :disabled="form.allocationStatus == '1'">
                  :disabled="form.allocationStatus == '1' || isReadOnly">
                  {{ dict.label }}
                </el-checkbox>
              </el-checkbox-group>
              <el-input v-if="showOtherInput" v-model="otherOrganInput" placeholder="请输入其他器官名称"
                style="margin-top: 10px; width: 300px;" :disabled="form.allocationStatus == '1'" />
                style="margin-top: 10px; width: 300px;" :disabled="form.allocationStatus == '1' || isReadOnly" />
          </el-form-item>
        </div>
@@ -95,7 +95,7 @@
                  <template slot-scope="scope">
                    <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.applicanttime"
                      type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择开始接收时间" :disabled="form.allocationStatus == '1' ||
                        scope.row.allocationstatus == '3'
                        scope.row.allocationstatus == '3' || isReadOnly
                        " />
                  </template>
                </el-table-column>
@@ -103,7 +103,7 @@
                  <template slot-scope="scope">
                    <el-date-picker clearable size="small" style="width: 100%" v-model="scope.row.organgettime"
                      type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择分配接收时间" :disabled="form.allocationStatus == '1' ||
                        scope.row.allocationstatus == '3'
                        scope.row.allocationstatus == '3' || isReadOnly
                        " />
                  </template>
                </el-table-column>
@@ -111,7 +111,7 @@
                <el-table-column label="受体姓氏" align="center" width="120" prop="name">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.name" placeholder="受体姓氏" :disabled="form.allocationStatus == '1' ||
                      scope.row.allocationstatus == '3'
                      scope.row.allocationstatus == '3' || isReadOnly
                      " />
                  </template>
                </el-table-column>
@@ -119,7 +119,7 @@
                <el-table-column label="移植医院" align="center" width="200" prop="transplanthospitalname">
                  <template slot-scope="scope">
                    <el-autocomplete v-model="scope.row.transplanthospitalname" :fetch-suggestions="queryHospitalSearch"
                      placeholder="请选择或输入移植医院" style="width: 100%" clearable></el-autocomplete>
                      placeholder="请选择或输入移植医院" style="width: 100%" :disabled="isReadOnly" clearable></el-autocomplete>
                  </template>
                  <!-- <template slot-scope="scope">
                    <el-select
@@ -143,7 +143,7 @@
                    <div v-if="scope.row.allocationstatus != '3'">
                      <el-input type="textarea" clearable v-model="scope.row.reallocationreason" placeholder="请输入说明"
                        :disabled="form.allocationStatus == '1' ||
                          scope.row.allocationstatus == '3'
                          scope.row.allocationstatus == '3' || isReadOnly
                          " />
                    </div>
                    <div v-else>
@@ -169,7 +169,7 @@
                </el-table-column>
                <el-table-column label="操作" align="center" width="120" class-name="small-padding fixed-width"
                  v-if="form.allocationStatus !== '1'" fixed="right">
                  v-if="!isReadOnly && form.allocationStatus !== '1'" fixed="right">
                  <template slot-scope="scope">
                    <el-button size="mini" type="text" icon="el-icon-copy-document"
                      @click="handleRedistribution(scope.row)" :disabled="scope.row.allocationstatus == '3'"
@@ -252,7 +252,7 @@
      </div>
      <!-- ä½¿ç”¨ UploadAttachment ç»„ä»¶ -->
      <UploadAttachment ref="uploadAttachment" :file-list="attachmentFileList" :limit="attachmentLimit"
      <UploadAttachment v-if="!isReadOnly" ref="uploadAttachment" :file-list="attachmentFileList" :limit="attachmentLimit"
        :accept="attachmentAccept" :multiple="true" @change="handleAttachmentChange"
        @upload-success="handleUploadSuccess" @upload-error="handleUploadError" @remove="handleAttachmentRemove" />
@@ -292,7 +292,7 @@
              <el-button size="mini" type="success" @click="handleDownloadAttachment(scope.row)">
                ä¸‹è½½
              </el-button>
              <el-button size="mini" type="danger" @click="handleRemoveAttachment(scope.$index)">
              <el-button v-if="!isReadOnly" size="mini" type="danger" @click="handleRemoveAttachment(scope.$index)">
                åˆ é™¤
              </el-button>
            </template>
@@ -300,7 +300,7 @@
        </el-table>
      </div>
    </el-card>
    <div style="text-align: center; margin: 30px 0;">
    <div v-if="!isReadOnly" style="text-align: center; margin: 30px 0;">
      <el-button type="primary" @click="handleSave" :loading="saveLoading">
        ä¿å­˜
      </el-button>
@@ -447,6 +447,7 @@
  allocationedit,
  donateorganBaseinfoInfo
} from "@/api/businessApi";
import { getDonatebaseinfo } from "@/api/project/donatebaseinfo";
import UploadAttachment from "@/components/UploadAttachment";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import OrgSelecter from "@/views/project/components/orgselect";
@@ -564,6 +565,10 @@
    };
  },
  computed: {
    // æŸ¥çœ‹æ¨¡å¼ï¼šåªè¯»ï¼Œç¦ç”¨è¡¨å•并隐藏保存按钮
    isReadOnly() {
      return this.$route.query.mode === "view";
    },
    // å½“前用户信息
    currentUser() {
      return JSON.parse(sessionStorage.getItem("user") || "{}");
@@ -572,15 +577,16 @@
    return (this.allocationData.serviceDonateorganList || [])
      .filter(item => item.delFlag !== 1);
  },
    // ä¸å®Œæ•´çš„记录数量
    // ä¸å®Œæ•´çš„记录数量(重分配记录不参与校验)
    incompleteRecords() {
      if (!this.allocationData.serviceDonateorganList) return 0;
      return this.allocationData.serviceDonateorganList.filter(
        record =>
          !record.applicanttime ||
          !record.organgettime ||
          !record.name ||
          !record.transplanthospitalname
          record.allocationstatus != "3" &&
          (!record.applicanttime ||
            !record.organgettime ||
            !record.name ||
            !record.transplanthospitalname)
      ).length;
    },
    // å¾…审核记录数量
@@ -1293,6 +1299,7 @@
    // ä¿å­˜åŸºæœ¬ä¿¡æ¯
    async handleSave() {
      if (this.saveLoading) return;
      this.$refs.form.validate(async valid => {
        if (!valid) {
          this.$message.warning("请完善表单信息");
@@ -1301,6 +1308,14 @@
        this.saveLoading = true;
        try {
          // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…
          if (!this.form.id) {
            const exists = await this.checkPatientExists();
            if (exists) {
              this.$message.warning("该患者已存在,请勿重复添加");
              return;
            }
          }
          const saveData = {
            ...this.form,
            serviceDonateorganList:
@@ -1346,6 +1361,27 @@
      });
    },
    // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…(按住院号)
    async checkPatientExists() {
      let inpatientno = this.form.inpatientno;
      if (!inpatientno && this.caseId) {
        try {
          const caseRes = await getDonatebaseinfo(this.caseId);
          inpatientno = (caseRes.data && caseRes.data.inpatientno) || "";
        } catch (e) {
          inpatientno = "";
        }
      }
      if (!inpatientno) return false;
      try {
        const res = await allocationList({ inpatientno, pageNum: 1, pageSize: 1 });
        const list = res.data || [];
        return list.some(item => item && item.id != null && item.id !== "");
      } catch (e) {
        return false;
      }
    },
    // ç¡®è®¤å®Œæˆåˆ†é…
    async handleConfirmAllocation() {
      if (this.incompleteRecords > 0) {
src/views/business/allocation/index.vue
@@ -129,12 +129,38 @@
        </el-table-column>
        <el-table-column label="年龄" align="center" prop="age" width="80" />
        <el-table-column
          label="血型"
          align="center"
          prop="bloodtype"
          width="80"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_BloodType"
              :value="scope.row.bloodtype"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="疾病诊断"
          align="center"
          prop="diagnosisname"
          min-width="180"
          width="200"
          show-overflow-tooltip
        />
        <el-table-column
          label="捐献类型"
          align="center"
          prop="donationcategory"
          width="180"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_DonationCategory"
              :value="scope.row.donationcategory"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="分配状态"
          align="center"
@@ -175,10 +201,10 @@
            }}</span>
          </template>
        </el-table-column>
        <el-table-column
         <el-table-column
          label="操作"
          align="center"
          width="210"
          min-width="180"
          fixed="right"
          class-name="small-padding fixed-width"
        >
@@ -187,24 +213,15 @@
              size="mini"
              type="text"
              icon="el-icon-view"
              @click="handleView(scope.row)"
              >详情</el-button
              @click.stop="handleView(scope.row)"
              >查看</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click="handleUpdate(scope.row)"
              >修改</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-delete"
              style="color: #F56C6C"
              @click="handleDelete(scope.row)"
              :disabled="scope.row.allocationStatus === '2'"
              >删除</el-button
              @click.stop="handleUpdate(scope.row)"
              >编辑</el-button
            >
          </template>
        </el-table-column>
@@ -229,7 +246,7 @@
export default {
  name: "OrganAllocationList",
  components: { Pagination },
  dicts: ["sys_user_sex", "organ_allocation_status"],
  dicts: ["sys_user_sex", "organ_allocation_status", "sys_BloodType", "sys_DonationCategory"],
  data() {
    return {
      // é®ç½©å±‚
@@ -322,7 +339,7 @@
    handleView(row) {
      this.$router.push({
        path: "/case/allocationInfo",
        query: { id: row.id, infoid: row.infoid }
        query: { id: row.id, infoid: row.infoid, mode: "view" }
      });
    },
    // æ–°å¢žæŒ‰é’®æ“ä½œ
@@ -331,9 +348,19 @@
    },
    // ä¿®æ”¹æŒ‰é’®æ“ä½œ
    handleUpdate(row) {
      const selectedRow =
        row || (this.selectedRows.length === 1 ? this.selectedRows[0] : null);
      if (!selectedRow) {
        this.$message.warning("请选择一条记录");
        return;
      }
      this.$router.push({
        path: "/case/allocationInfo",
        query: { id: row.id, infoid: row.infoid }
        query: {
          id: selectedRow.id,
          infoid: selectedRow.infoid,
          mode: "edit"
        }
      });
    },
    // åˆ é™¤æŒ‰é’®æ“ä½œ
src/views/business/appear/caseDetail.vue
@@ -200,91 +200,98 @@
        <span class="section-title">附件信息</span>
      </div>
      <div class="detail-attachments">
        <div class="attachment-grid">
          <div
            v-for="file in caseData.annexfilesList"
            :key="file.id || file.fileName"
            class="attachment-card"
          >
            <template v-if="isImageFile(file.fileName || file.path)">
              <!-- å›¾ç‰‡ä½¿ç”¨ el-image é¢„览 -->
              <el-image
                class="image-attachment"
                :src="getFileUrl(file)"
                :preview-src-list="getImagePreviewList(file)"
                fit="cover"
                :style="{ width: '120px', height: '120px' }"
                lazy
              >
                <div slot="error" class="image-error">
                  <i class="el-icon-picture-outline"></i>
                  <span>加载失败</span>
                </div>
                <div slot="placeholder" class="image-loading">
                  <i class="el-icon-loading"></i>
                </div>
              </el-image>
              <div class="image-info">
                <div class="file-name" :title="file.fileName">
                  {{ file.fileName }}
                </div>
                <div class="file-actions">
                  <el-button
                    type="text"
                    size="mini"
                    @click="handleDownload(file)"
                    icon="el-icon-download"
                    title="下载"
                  />
                  <el-button
                    type="text"
                    size="mini"
                    @click="handlePreview(file)"
                    icon="el-icon-view"
                    title="预览"
                  />
                </div>
              </div>
            </template>
            <template v-else>
              <!-- éžå›¾ç‰‡æ–‡ä»¶ä½¿ç”¨å¡ç‰‡æ ·å¼ -->
              <el-card shadow="hover" class="file-card">
                <div class="file-content">
                  <i :class="getFileIcon(file.fileName)" class="file-icon"></i>
                  <div class="file-info">
                    <div class="file-name" :title="file.fileName">
                      {{ file.fileName }}
                    </div>
                    <div class="file-meta">
                      <span class="file-type">{{
                        getFileTypeText(file.fileName)
                      }}</span>
                      <span v-if="file.createTime" class="file-time">
                        {{ formatDateTime(file.createTime) }}
                      </span>
                    </div>
        <div
          v-for="group in attachmentGroups"
          :key="group.label"
          class="attachment-group"
        >
          <div class="attachment-group-title">{{ group.label }}</div>
          <div class="attachment-grid">
            <div
              v-for="file in group.files"
              :key="file.id || file.fileName"
              class="attachment-card"
            >
              <template v-if="isImageFile(file.fileName || file.path)">
                <!-- å›¾ç‰‡ä½¿ç”¨ el-image é¢„览 -->
                <el-image
                  class="image-attachment"
                  :src="getFileUrl(file)"
                  :preview-src-list="getImagePreviewList(file)"
                  fit="cover"
                  :style="{ width: '120px', height: '120px' }"
                  lazy
                >
                  <div slot="error" class="image-error">
                    <i class="el-icon-picture-outline"></i>
                    <span>加载失败</span>
                  </div>
                  <div slot="placeholder" class="image-loading">
                    <i class="el-icon-loading"></i>
                  </div>
                </el-image>
                <div class="image-info">
                  <div class="file-name" :title="file.fileName">
                    {{ file.fileName }}
                  </div>
                  <div class="file-actions">
                    <el-button
                      type="text"
                      size="mini"
                      @click="handleDownload(file)"
                      icon="el-icon-download"
                      title="下载"
                    />
                    <el-button
                      type="text"
                      size="mini"
                      @click="handlePreview(file)"
                      icon="el-icon-view"
                      title="预览"
                    />
                  </div>
                </div>
                <div class="file-actions">
                  <el-button
                    type="text"
                    size="mini"
                    @click="handleDownload(file)"
                  >
                    ä¸‹è½½
                  </el-button>
                  <el-button
                    v-if="canPreview(file.fileName)"
                    type="text"
                    size="mini"
                    @click="handlePreview(file)"
                  >
                    é¢„览
                  </el-button>
                </div>
              </el-card>
            </template>
              </template>
              <template v-else>
                <!-- éžå›¾ç‰‡æ–‡ä»¶ä½¿ç”¨å¡ç‰‡æ ·å¼ -->
                <el-card shadow="hover" class="file-card">
                  <div class="file-content">
                    <i :class="getFileIcon(file.fileName)" class="file-icon"></i>
                    <div class="file-info">
                      <div class="file-name" :title="file.fileName">
                        {{ file.fileName }}
                      </div>
                      <div class="file-meta">
                        <span class="file-type">{{
                          getFileTypeText(file.fileName)
                        }}</span>
                        <span v-if="file.createTime" class="file-time">
                          {{ formatDateTime(file.createTime) }}
                        </span>
                      </div>
                    </div>
                  </div>
                  <div class="file-actions">
                    <el-button
                      type="text"
                      size="mini"
                      @click="handleDownload(file)"
                    >
                      ä¸‹è½½
                    </el-button>
                    <el-button
                      v-if="canPreview(file.fileName)"
                      type="text"
                      size="mini"
                      @click="handlePreview(file)"
                    >
                      é¢„览
                    </el-button>
                  </div>
                </el-card>
              </template>
            </div>
          </div>
        </div>
      </div>
@@ -492,6 +499,32 @@
        .filter(file => this.isImageFile(file.fileName || file.path))
        .map(file => this.getFileUrl(file))
        .filter(url => url);
    },
    // æŒ‰åˆ†ç±»åˆ†ç»„附件(捐献者登记阶段:登记表附件/证件照/疾病诊断治疗)
    attachmentGroups() {
      const list = this.caseData.annexfilesList;
      if (!Array.isArray(list) || list.length === 0) return [];
      const categories = [
        { value: "登记表附件", label: "人体器官潜在捐献者登记表附件" },
        { value: "证件照", label: "证件照" },
        { value: "疾病诊断治疗", label: "疾病诊断治疗" }
      ];
      const groups = categories
        .map(cat => ({
          label: cat.label,
          files: list.filter(f => (f.fileType || "").trim() === cat.value)
        }))
        .filter(group => group.files.length > 0);
      // æœªåˆ†ç±»é™„件兜底,避免丢失旧数据
      const classifiedValues = categories.map(c => c.value);
      const unclassified = list.filter(f => {
        const t = (f.fileType || "").trim();
        return !t || !classifiedValues.includes(t);
      });
      if (unclassified.length > 0) {
        groups.push({ label: "未分类", files: unclassified });
      }
      return groups;
    }
  },
  created() {
@@ -855,6 +888,19 @@
  padding: 10px 0;
}
.attachment-group {
  margin-bottom: 20px;
}
.attachment-group-title {
  font-size: 14px;
  font-weight: bold;
  color: #409eff;
  margin-bottom: 12px;
  padding-left: 10px;
  border-left: 3px solid #409eff;
}
.attachment-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
src/views/business/appear/index.vue
@@ -75,14 +75,16 @@
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
          <el-button size="mini" type="text" icon="el-icon-check" @click="handleApprove(scope.row)"
            v-if="scope.row.reportStatus == '2' && scope.row.delFlag == 0">确认</el-button>
          <!-- ç§»é™¤è½¬è¿æŒ‰é’® -->
          <el-button v-if="scope.row.serviceTransport.length" size="mini" type="primary"
            @click="goToTransportDetail(scope.row.name)">查看转运单</el-button>
          <el-button v-if="
            scope.row.reportStatus == 3 &&
            !scope.row.serviceTransport.length &&
            scope.row.isTransport == 2
          " size="mini" type="success" @click="Createatransferorder(scope.row)">创建转运单</el-button>
          <el-button
            size="mini"
            icon="el-icon-truck"
            :type="getTransportStatustype(scope.row)"
            @click="handleTransport(scope.row)"
            v-if="shouldShowTransportButton(scope.row)"
            :disabled="!canGoToTransport(scope.row)"
          >
            {{ getTransportButtonText(scope.row) }}
          </el-button>
        </template>
      </el-table-column>
    </el-table>
@@ -880,6 +882,73 @@
      return "未知";
    },
    /** åˆ¤æ–­æ˜¯å¦éœ€è¦æ˜¾ç¤ºè½¬è¿æŒ‰é’® */
    shouldShowTransportButton(row) {
      // é™¤å·²å½’档案例外均显示转运按钮
      return row.reportStatus != "4";
    },
    /** åˆ¤æ–­æ˜¯å¦å¯ä»¥è·³è½¬åˆ°è½¬è¿å• */
    canGoToTransport(row) {
      return row.isTransport == "2" && row.serviceTransport;
    },
    /** èŽ·å–è½¬è¿æŒ‰é’®æ–‡æœ¬ */
    getTransportButtonText(row) {
      if (row.isTransport == "2") {
        if (
          row.serviceTransport &&
          Array.isArray(row.serviceTransport) &&
          row.serviceTransport.length > 0
        ) {
          return "查看转运单";
        } else {
          return "创建转运单";
        }
      }
      return "无需转运";
    },
    /** èŽ·å–è½¬è¿æŒ‰é’®æ ·å¼ */
    getTransportStatustype(row) {
      if (row.isTransport == "1") {
        return "info";
      }
      if (
        row.serviceTransport &&
        Array.isArray(row.serviceTransport) &&
        row.serviceTransport.length > 0
      ) {
        return "primary";
      }
      return "success";
    },
    /** å¤„理转运操作 */
    async handleTransport(row) {
      try {
        const caseData = row;
        if (caseData.isTransport == "2") {
          if (
            caseData.serviceTransport &&
            Array.isArray(caseData.serviceTransport) &&
            caseData.serviceTransport.length > 0
          ) {
            // å·²æœ‰è½¬è¿å•,跳转到转运单详情页
            this.goToTransportDetail(caseData.name);
          } else {
            // æ²¡æœ‰è½¬è¿å•,跳转到创建转运单页面
            this.Createatransferorder(caseData);
          }
        } else {
          this.$message.warning("该案例不需要转运");
        }
      } catch (error) {
        console.error("获取案例信息失败:", error);
        this.$message.error("获取案例信息失败");
      }
    },
    /** è·³è½¬åˆ°åˆ›å»ºè½¬è¿å•页面 */
    Createatransferorder(res) {
      console.log(res);
src/views/business/assess/assessInfo.vue
@@ -12,12 +12,12 @@
      <el-form class="paper-form">
        <div class="form-row">
          <el-form-item label-width="100px" label="捐献决定" class="col-full">
            <el-checkbox-group v-model="organdecisionValues" @change="handleOrganDecisionChange" :disabled="!isEdit">
            <el-checkbox-group v-model="organdecisionValues" @change="handleOrganDecisionChange" :disabled="!isEdit || isReadOnly">
              <el-checkbox v-for="dict in dict.type.sys_Organ" :key="dict.value" :label="dict.value">{{ dict.label }}
              </el-checkbox>
            </el-checkbox-group>
            <el-input v-if="showOtherInput" v-model="organdecisionOther" placeholder="请输入其他捐献决定的具体内容"
              style="margin-top: 10px; width: 300px;" :readonly="!isEdit" @input="handleOtherDecisionInput"></el-input>
              style="margin-top: 10px; width: 300px;" :readonly="!isEdit || isReadOnly" @input="handleOtherDecisionInput"></el-input>
          </el-form-item>
        </div>
      </el-form>
@@ -35,13 +35,13 @@
                <el-tab-pane v-for="(assessment, index) in getOrganAssessments(scope.row)"
                  :key="`${scope.row.organno}_${index}`" :label="`第${index + 1}次评估`" :name="String(index)">
                  <organ-assessment-form :organ-data="scope.row" :assessment-index="index"
                    :readonly="!canAssessOrgan(scope.row)" :current-user="currentUser"
                    :readonly="!canAssessOrgan(scope.row) || isReadOnly" :current-user="currentUser"
                    @update-assessment="handleUpdateAssessment" @delete-assessment="handleDeleteAssessment"
                    @save-assessment="handleSaveAssessment" />
                </el-tab-pane>
                <!-- æ·»åŠ è¯„ä¼°æŒ‰é’® -->
                <el-tab-pane name="add" v-if="canAssessOrgan(scope.row) && isEdit">
                <el-tab-pane name="add" v-if="canAssessOrgan(scope.row) && isEdit && !isReadOnly">
                  <template slot="label">
                    <el-button type="text" icon="el-icon-plus" @click.stop="handleAddNewAssessment(scope.row)"
                      size="mini">
@@ -255,7 +255,7 @@
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width">
        <el-table-column v-if="!isReadOnly" label="操作" align="center" width="150" class-name="small-padding fixed-width">
          <template slot-scope="scope">
            <el-button v-if="canAssessOrgan(scope.row) && isEdit" size="mini" type="text"
              @click="handleToggleExpand(scope.row)">
@@ -275,7 +275,7 @@
    </el-card>
    <!-- æ•´ä½“保存按钮 -->
    <div class="footer-actions" v-if="isEdit">
    <div class="footer-actions" v-if="isEdit && !isReadOnly">
      <el-button type="primary" @click="handleSaveAll" :loading="saveLoading">保存评估表</el-button>
      <el-button type="success" @click="accomplish" :loading="saveLoading">评估完成</el-button>
    </div>
@@ -291,6 +291,7 @@
  assessedit,
  assessAdd
} from "@/api/businessApi/index";
import { getDonatebaseinfo } from "@/api/project/donatebaseinfo";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import OrganAssessmentForm from "@/components/assessInfoComponents/OrganAssessmentForm.vue";
@@ -360,6 +361,10 @@
    };
  },
  computed: {
    // æŸ¥çœ‹æ¨¡å¼ï¼šåªè¯»ï¼Œç¦ç”¨è¡¨å•并隐藏保存按钮
    isReadOnly() {
      return this.$route.query.mode === "view";
    },
    isCoordinator() {
      return this.currentUser.role == "coordinator";
    },
@@ -550,7 +555,7 @@
        type: "warning"
      })
        .then(() => {
          this.form.assessState = 3;
          this.assessmentData.assessState = 3;
          this.handleSaveAll();
        })
@@ -558,8 +563,17 @@
    },
    // æ•´ä½“保存方法
    async handleSaveAll() {
      if (this.saveLoading) return;
      this.saveLoading = true;
      try {
        // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…
        if (!this.assessmentData.id) {
          const exists = await this.checkPatientExists();
          if (exists) {
            this.$message.warning("该患者已存在,请勿重复添加");
            return;
          }
        }
        const saveData = {
          id: this.assessmentData.id || undefined,
          infoid: this.infoid,
@@ -623,6 +637,29 @@
        this.saveLoading = false;
      }
    },
    // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…(按住院号)
    async checkPatientExists() {
      let inpatientno = this.assessmentData.inpatientno;
      if (!inpatientno && this.caseId) {
        try {
          const caseRes = await getDonatebaseinfo(this.caseId);
          inpatientno = (caseRes.data && caseRes.data.inpatientno) || "";
        } catch (e) {
          inpatientno = "";
        }
      }
      if (!inpatientno) return false;
      try {
        const res = await evaluateBaseInfolist({ inpatientno, pageNum: 1, pageSize: 1 });
        let list = res.data || [];
        if (!Array.isArray(list)) {
          list = list.rows || list.list || [];
        }
        return list.some(item => item && item.id != null && item.id !== "");
      } catch (e) {
        return false;
      }
    },
    // å–消按钮事件
    handleCancel() {
src/views/business/assess/index.vue
@@ -123,12 +123,6 @@
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" align="center" />
         <el-table-column
          label="捐献编号"
          align="center"
          prop="caseNo"
          width="120"
        />
        <el-table-column
          label="住院号"
          align="center"
@@ -146,12 +140,38 @@
        </el-table-column>
        <el-table-column label="年龄" align="center" prop="age" width="80" />
        <el-table-column
          label="血型"
          align="center"
          prop="bloodtype"
          width="80"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_BloodType"
              :value="scope.row.bloodtype"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="疾病诊断"
          align="center"
          prop="diagnosisname"
          min-width="180"
          width="200"
          show-overflow-tooltip
        />
        <el-table-column
          label="捐献类型"
          align="center"
          prop="donationcategory"
          width="180"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_DonationCategory"
              :value="scope.row.donationcategory"
            />
          </template>
        </el-table-column>
        <!--
        <el-table-column
          label="所在医疗机构"
@@ -206,38 +226,33 @@
          width="100"
        />
        <el-table-column
          label="捐献编号"
          align="center"
          prop="caseNo"
          width="220"
        />
         <el-table-column
          label="操作"
          align="center"
          width="200"
          min-width="180"
          fixed="right"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
            <!-- <el-button
            <el-button
              size="mini"
              type="text"
              icon="el-icon-view"
              @click.stop="handleView(scope.row)"
              >详情</el-button
            > -->
              >查看</el-button
            >
            <el-button
              v-if="
                scope.row.assessState != '3' || scope.row.assessState != '4'
              "
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click.stop="handleAssess(scope.row)"
              >评估</el-button
              @click.stop="handleUpdate(scope.row)"
              >编辑</el-button
            >
            <!-- <el-button
              v-if="scope.row.assessState === '3'"
              size="mini"
              type="text"
              icon="el-icon-check"
              @click.stop="handleConfirm(scope.row)"
              >确认</el-button
            > -->
          </template>
        </el-table-column>
      </el-table>
@@ -261,7 +276,7 @@
export default {
  name: "AssessmentList",
  components: { Pagination },
  dicts: ["sys_user_sex", "state_Evaluation"],
  dicts: ["sys_user_sex", "state_Evaluation", "sys_BloodType", "sys_DonationCategory"],
  data() {
    return {
      // é®ç½©å±‚
@@ -446,14 +461,7 @@
    handleView(row) {
      this.$router.push({
        path: "/case/assessInfo",
        query: { id: row.id, infoid: row.infoid }
      });
    },
    // è¿›è¡Œè¯„ä¼°
    handleAssess(row) {
      this.$router.push({
        path: "/case/assessInfo",
        query: { id: row.id, infoid: row.infoid, assess: true }
        query: { id: row.id, infoid: row.infoid, mode: "view" }
      });
    },
    // ç¡®è®¤è¯„ä¼°
@@ -479,14 +487,11 @@
    handleCreate() {
      this.$router.push("/case/assessment/add");
    },
    // ä¿®æ”¹æŒ‰é’®æ“ä½œ
    handleUpdate() {
      if (this.ids.length === 0) return;
      const id = this.ids[0];
    // ç¼–辑
    handleUpdate(row) {
      this.$router.push({
        path: "/case/assessment/edit",
        query: { id: id }
        path: "/case/assessInfo",
        query: { id: row.id, infoid: row.infoid, mode: "edit" }
      });
    },
    // åˆ é™¤æŒ‰é’®æ“ä½œ
src/views/business/decide/DecideInfo.vue
@@ -35,7 +35,7 @@
            <el-form-item label="负责人" prop="responsibleusername">
              <el-input
                v-model="form.responsibleusername"
                :readonly="!isEdit"
                :disabled="isReadOnly || !isEdit"
              />
            </el-form-item>
          </el-col>
@@ -43,7 +43,7 @@
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="器官获取机构" prop="gainhospitalname">
              <el-input v-model="form.gainhospitalname" :readonly="!isEdit" />
              <el-input v-model="form.gainhospitalname" :disabled="isReadOnly || !isEdit" />
            </el-form-item>
          </el-col>
@@ -56,7 +56,7 @@
        <span class="detail-title">脑死亡判定信息</span>
        <el-button
          v-if="!isEdit"
          v-if="!isReadOnly && !isEdit"
          style="float: right; margin-left: 10px;"
          type="primary"
          @click="handleEdit"
@@ -68,25 +68,25 @@
      <el-form :model="form" ref="brainForm" :rules="rules" label-width="120px" class="paper-form">
        <div class="form-row">
          <el-form-item label="死亡原因" prop="deathreason" class="col-1-3">
            <el-input v-model="form.deathreason" :readonly="!isEdit" />
            <el-input v-model="form.deathreason" :disabled="isReadOnly || !isEdit" />
          </el-form-item>
        </div>
        <div class="form-row">
          <el-form-item label="死亡时间" prop="deathtime" class="col-1-3">
            <el-date-picker
              v-model="form.deathtime"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
              :disabled="!isEdit"
              :disabled="isReadOnly || !isEdit"
            />
          </el-form-item>
        </div>
        <div class="form-row">
          <el-form-item label="判定医生一" prop="deathjudgedocto" class="col-1-3">
            <el-input v-model="form.deathjudgedocto" :readonly="!isEdit" />
            <el-input v-model="form.deathjudgedocto" :disabled="isReadOnly || !isEdit" />
          </el-form-item>
          <el-form-item label="判定医生二" prop="deathjudgedoctt" class="col-1-3">
            <el-input v-model="form.deathjudgedoctt" :readonly="!isEdit" />
            <el-input v-model="form.deathjudgedoctt" :disabled="isReadOnly || !isEdit" />
          </el-form-item>
        </div>
        <div class="form-row">
@@ -94,16 +94,16 @@
            <div
              v-for="(doctor, index) in brainExtraDoctors"
              :key="index"
              style="display: flex; align-items: center; margin-bottom: 8px;"
              style="display: flex; align-items: center; margin-bottom: 8px; width: 100%;"
            >
              <el-input
                v-model="brainExtraDoctors[index]"
                placeholder="请输入医生姓名"
                style="flex: 1; margin-right: 10px;"
                :readonly="!isEdit"
                :disabled="isReadOnly || !isEdit"
              />
              <el-button
                v-if="isEdit"
                v-if="!isReadOnly && isEdit"
                type="danger"
                icon="el-icon-minus"
                circle
@@ -112,7 +112,7 @@
              />
            </div>
            <el-button
              v-if="isEdit"
              v-if="!isReadOnly && isEdit"
              type="primary"
              icon="el-icon-plus"
              size="small"
@@ -143,6 +143,7 @@
                <span class="upload-title">{{ type.label }}</span>
                <el-tooltip content="点击上传该类型评估表" placement="top">
                  <el-button
                    v-if="!isReadOnly"
                    size="mini"
                    type="primary"
                    icon="el-icon-plus"
@@ -215,7 +216,7 @@
                      >下载</el-button
                    >
                    <el-button
                      v-if="isEdit"
                      v-if="!isReadOnly && isEdit"
                      size="mini"
                      type="text"
                      icon="el-icon-delete"
@@ -247,7 +248,7 @@
      <div slot="header" class="clearfix">
        <span class="detail-title">心死亡判定信息</span>
        <el-button
          v-if="isEdit"
          v-if="!isReadOnly && isEdit"
          style="float: right; margin-left: 10px;"
          type="success"
          @click="handleSave"
@@ -256,7 +257,7 @@
          ä¿å­˜ä¿¡æ¯
        </el-button>
        <el-button
          v-else
          v-else-if="!isReadOnly"
          style="float: right; margin-left: 10px;"
          type="primary"
          @click="handleEdit"
@@ -268,30 +269,30 @@
      <el-form :model="form" ref="heartForm" :rules="rules" label-width="120px" class="paper-form">
        <div class="form-row">
          <el-form-item label="心死亡原因" prop="heartdeathreason" class="col-1-3">
            <el-input v-model="form.heartdeathreason" :readonly="!isEdit" />
            <el-input v-model="form.heartdeathreason" :disabled="isReadOnly || !isEdit" />
          </el-form-item>
        </div>
        <div class="form-row">
          <el-form-item label="心死亡判定完成时间" prop="heartdeathtime" class="col-1-3">
            <el-date-picker
              v-model="form.heartdeathtime"
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
              :disabled="!isEdit"
              :disabled="isReadOnly || !isEdit"
            />
          </el-form-item>
        </div>
        <div class="form-row">
          <el-form-item label="判定医生一" prop="heartdeathjudgedocto" class="col-1-3">
            <el-input
              v-model="form.heartdeathjudgedocto"
              :readonly="!isEdit"
              :disabled="isReadOnly || !isEdit"
            />
          </el-form-item>
          <el-form-item label="判定医生二" prop="heartdeathjudgedoctt" class="col-1-3">
            <el-input
              v-model="form.heartdeathjudgedoctt"
              :readonly="!isEdit"
              :disabled="isReadOnly || !isEdit"
            />
          </el-form-item>
        </div>
@@ -300,16 +301,16 @@
            <div
              v-for="(doctor, index) in heartExtraDoctors"
              :key="index"
              style="display: flex; align-items: center; margin-bottom: 8px;"
              style="display: flex; align-items: center; margin-bottom: 8px; width: 100%;"
            >
              <el-input
                v-model="heartExtraDoctors[index]"
                placeholder="请输入医生姓名"
                style="flex: 1; margin-right: 10px;"
                :readonly="!isEdit"
                :disabled="isReadOnly || !isEdit"
              />
              <el-button
                v-if="isEdit"
                v-if="!isReadOnly && isEdit"
                type="danger"
                icon="el-icon-minus"
                circle
@@ -318,7 +319,7 @@
              />
            </div>
            <el-button
              v-if="isEdit"
              v-if="!isReadOnly && isEdit"
              type="primary"
              icon="el-icon-plus"
              size="small"
@@ -349,6 +350,7 @@
                <span class="upload-title">{{ type.label }}</span>
                <el-tooltip content="点击上传该类型评估表" placement="top">
                  <el-button
                    v-if="!isReadOnly"
                    size="mini"
                    type="primary"
                    icon="el-icon-plus"
@@ -421,7 +423,7 @@
                      >下载</el-button
                    >
                    <el-button
                      v-if="isEdit"
                      v-if="!isReadOnly && isEdit"
                      size="mini"
                      type="text"
                      icon="el-icon-delete"
@@ -450,7 +452,7 @@
    <!-- åº•部操作按钮 -->
    <div style="text-align: center; margin: 30px 0;">
      <el-button
        v-if="isEdit"
        v-if="!isReadOnly && isEdit"
        type="primary"
        @click="handleSave"
        :loading="saveLoading"
@@ -458,7 +460,7 @@
        ä¿å­˜ä¿¡æ¯
      </el-button>
      <el-button
        v-if="isEdit"
        v-if="!isReadOnly && isEdit"
        type="success"
        @click="accomplish"
        :loading="saveLoading"
@@ -569,6 +571,7 @@
  deathinfoadd,
  queryDathInfoBaseInfo
} from "@/api/businessApi";
import { getDonatebaseinfo } from "@/api/project/donatebaseinfo";
import { getToken } from "@/utils/auth";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import FilePreviewDialog from "@/components/FilePreviewDialog";
@@ -693,6 +696,10 @@
    };
  },
  computed: {
    // æŸ¥çœ‹æ¨¡å¼ï¼šåªè¯»ï¼Œç¦ç”¨è¡¨å•并隐藏保存按钮
    isReadOnly() {
      return this.$route.query.mode === "view";
    },
    getCurrentBrainDeathTypeLabel() {
      const type = this.brainDeathAttachmentTypes.find(
        t => t.value === this.currentUploadType
@@ -715,6 +722,9 @@
    if (this.$route.query.judgmentType) {
      this.activeJudgmentType = this.$route.query.judgmentType;
    }
    // æŸ¥çœ‹æ¨¡å¼ä¸‹é»˜è®¤åªè¯»
    this.isEdit = !this.isReadOnly;
    this.getDetail(this.infoid);
    this.getAttachmentList();
@@ -1177,6 +1187,7 @@
    },
    // ä¿å­˜ä¿¡æ¯
    async handleSave() {
      if (this.saveLoading) return;
      // æ ¹æ®å½“前标签选择验证规则
      let formRef =
        this.activeJudgmentType === "brain" ? "brainForm" : "heartForm";
@@ -1221,6 +1232,12 @@
            if (submitData.id) {
              response = await deathinfoedit(submitData);
            } else {
              // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…
              const exists = await this.checkPatientExists();
              if (exists) {
                this.$message.warning("该患者已存在,请勿重复添加");
                return;
              }
              response = await deathinfoadd(submitData);
            }
@@ -1246,6 +1263,31 @@
      });
    },
    // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…(按住院号)
    async checkPatientExists() {
      let inpatientno = this.form.inpatientno;
      if (!inpatientno && this.caseId) {
        try {
          const caseRes = await getDonatebaseinfo(this.caseId);
          inpatientno = (caseRes.data && caseRes.data.inpatientno) || "";
        } catch (e) {
          inpatientno = "";
        }
      }
      if (!inpatientno) return false;
      try {
        const res = await queryDathInfoBaseInfo({
          inpatientno,
          pageNum: 1,
          pageSize: 1
        });
        const list = res.rows || res.data || [];
        return list.some(item => item && item.id != null && item.id !== "");
      } catch (e) {
        return false;
      }
    },
    // æ–‡ä»¶å¤§å°æ ¼å¼åŒ–
    formatFileSize(size) {
      if (size === 0) return "0 B";
src/views/business/decide/index.vue
@@ -142,14 +142,39 @@
          width="80"
          fixed="left"
        />
        <el-table-column
          label="血型"
          align="center"
          prop="bloodtype"
          width="80"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_BloodType"
              :value="scope.row.bloodtype"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="疾病诊断"
          align="center"
          prop="diagnosisname"
          min-width="200"
          width="200"
          show-overflow-tooltip
        />
        <el-table-column
          label="捐献类型"
          align="center"
          prop="donationcategory"
          width="180"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_DonationCategory"
              :value="scope.row.donationcategory"
            />
          </template>
        </el-table-column>
        <!-- çŠ¶æ€ä¿¡æ¯ -->
        <el-table-column
          label="判定状态"
@@ -281,10 +306,10 @@
          </template>
        </el-table-column>
        <el-table-column
         <el-table-column
          label="操作"
          align="center"
          width="200"
          min-width="180"
          fixed="right"
          class-name="small-padding fixed-width"
        >
@@ -293,26 +318,16 @@
              size="mini"
              type="text"
              icon="el-icon-view"
              @click="handleView(scope.row)"
              >详情</el-button
              @click.stop="handleView(scope.row)"
              >查看</el-button
            >
            <el-dropdown
            <el-button
              size="mini"
              @command="command => handleUpdateDropdown(scope.row, command)"
              type="text"
              icon="el-icon-edit"
              @click.stop="handleUpdate(scope.row)"
              >编辑</el-button
            >
              <el-button
                size="mini"
                type="text"
                icon="el-icon-edit"
                class="el-button--text"
              >
                ä¿®æ”¹<i class="el-icon-arrow-down el-icon--right"></i>
              </el-button>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item command="brainDeath">脑死亡</el-dropdown-item>
                <el-dropdown-item command="heartDeath">心死亡</el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </template>
        </el-table-column>
      </el-table>
@@ -340,7 +355,7 @@
export default {
  name: "DeathJudgmentList",
  components: { Pagination },
  dicts: ["sys_user_sex", "decide_type"],
  dicts: ["sys_user_sex", "decide_type", "sys_BloodType", "sys_DonationCategory"],
  data() {
    return {
      // é®ç½©å±‚
@@ -565,7 +580,8 @@
        query: {
          id: row.id,
          infoid: row.infoid,
          type: this.getDeathType(row) // ä¼ é€’死亡类型
          type: this.getDeathType(row), // ä¼ é€’死亡类型
          mode: "view"
        }
      });
    },
@@ -596,34 +612,18 @@
      });
    },
    // ä¿®æ”¹æŒ‰é’®æ“ä½œï¼ˆä¸‹æ‹‰èœå•)
    handleUpdateDropdown(row, command) {
      const id = row.id;
      const infoid = row.infoid;
      if (command === "brainDeath") {
        // ä¿®æ”¹è„‘死亡判定
        this.$router.push({
          path: "/case/DecideInfo",
          query: {
            id: id,
            infoid: infoid,
            type: "brain",
            isEdit: true
          }
        });
      } else if (command === "heartDeath") {
        // ä¿®æ”¹å¿ƒæ­»äº¡åˆ¤å®š
        this.$router.push({
          path: "/case/DecideInfo",
          query: {
            id: id,
            infoid: infoid,
            type: "heart",
            isEdit: true
          }
        });
      }
    // ç¼–辑
    handleUpdate(row) {
      this.$router.push({
        path: "/case/DecideInfo",
        query: {
          id: row.id,
          infoid: row.infoid,
          type: this.getDeathType(row),
          isEdit: true,
          mode: "edit"
        }
      });
    },
    // å¯¼å‡ºæŒ‰é’®æ“ä½œ
src/views/business/ethicalReview/ethicalReviewInfo.vue
@@ -14,10 +14,11 @@
            <el-input
              v-model="form.initiateTheme"
              placeholder="请输入发起主题"
              :disabled="isReadOnly"
            />
          </el-form-item>
          <el-form-item label="发起人" prop="initiatePerson" class="col-1-3">
            <el-input v-model="form.initiatePerson" />
            <el-input v-model="form.initiatePerson" :disabled="isReadOnly" />
          </el-form-item>
          <!-- <el-col :span="8">
            <el-form-item label="审查状态" prop="status">
@@ -37,7 +38,11 @@
        <div class="form-row">
          <el-form-item label="伦理审查结论" prop="expertConclusion" class="col-1-3">
            <el-select v-model="form.expertConclusion" style="width: 100%">
            <el-select
              v-model="form.expertConclusion"
              style="width: 100%"
              :disabled="isReadOnly"
            >
              <el-option label="同意" value="1" />
              <el-option label="审查中" value="2" />
              <el-option label="不同意" value="0" />
@@ -51,6 +56,7 @@
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
              :disabled="isReadOnly"
            />
          </el-form-item>
        </div>
@@ -62,6 +68,7 @@
              :rows="2"
              v-model="form.expertOpinion"
              placeholder="请输入意见"
              :disabled="isReadOnly"
            />
          </el-form-item>
        </div>
@@ -73,6 +80,7 @@
              :rows="3"
              v-model="form.remark"
              placeholder="请输入备注信息"
              :disabled="isReadOnly"
            />
          </el-form-item>
        </div>
@@ -87,6 +95,7 @@
      <!-- ä½¿ç”¨ UploadAttachment ç»„ä»¶ -->
      <UploadAttachment
        v-if="!isReadOnly"
        ref="uploadAttachment"
        :file-list="attachmentFileList"
        :limit="10"
@@ -144,6 +153,7 @@
                ä¸‹è½½
              </el-button>
              <el-button
                v-if="!isReadOnly"
                size="mini"
                type="danger"
                @click="handleRemoveAttachment(scope.$index)"
@@ -181,10 +191,16 @@
          >
            åˆ·æ–°
          </el-button>
          <el-button size="mini" type="primary" @click="handleAddExpert">
          <el-button
            v-if="!isReadOnly"
            size="mini"
            type="primary"
            @click="handleAddExpert"
          >
            æ·»åР䏓家
          </el-button>
          <el-button
            v-if="!isReadOnly"
            size="mini"
            type="primary"
            @click="handleSendToNormalExperts"
@@ -193,6 +209,7 @@
            å‘送专家
          </el-button>
          <el-button
            v-if="!isReadOnly"
            size="mini"
            type="success"
            @click="handleSendToChiefExpert"
@@ -378,7 +395,13 @@
          </template>
        </el-table-column>
        <el-table-column label="操作" width="180" align="center" fixed="right">
        <el-table-column
          v-if="!isReadOnly"
          label="操作"
          width="180"
          align="center"
          fixed="right"
        >
          <template slot-scope="scope">
            <el-button
              size="mini"
@@ -417,12 +440,17 @@
      </el-table>
    </el-card>
    <div style="text-align: center; margin: 30px 0;">
      <el-button type="primary" @click="handleSave" :loading="saveLoading">
      <el-button
        v-if="!isReadOnly"
        type="primary"
        @click="handleSave"
        :loading="saveLoading"
      >
        ä¿å­˜
      </el-button>
      <el-button
        v-if="form.status != '3'"
        v-if="!isReadOnly && form.status != '3'"
        type="success"
        @click="handleCompleteReview"
        :loading="completeLoading"
@@ -431,6 +459,7 @@
      </el-button>
      <el-button
        v-if="!isReadOnly"
        type="warning"
        @click="handleSuspendReview"
        :disabled="form.status == '2' || form.status == '3'"
@@ -440,6 +469,7 @@
      </el-button>
      <el-button
        v-if="!isReadOnly"
        type="danger"
        @click="handleEndReview"
        :disabled="form.status == '2'"
@@ -808,6 +838,7 @@
  sendcall
} from "@/api/businessApi";
import { listExternalperson } from "@/api/project/externalperson";
import { getDonatebaseinfo } from "@/api/project/donatebaseinfo";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import UploadAttachment from "@/components/UploadAttachment";
import FilePreviewDialog from "@/components/FilePreviewDialog";
@@ -966,6 +997,11 @@
    };
  },
  computed: {
    // æŸ¥çœ‹æ¨¡å¼ï¼šåªè¯»ï¼Œç¦ç”¨è¡¨å•并隐藏保存按钮
    isReadOnly() {
      return this.$route.query.mode === "view";
    },
    // è®¡ç®—属性:获取专家列表(确保响应式)
    ethicalreviewopinionsList() {
      return this.form.ethicalreviewopinionsList || [];
@@ -1505,6 +1541,7 @@
    // ä¿å­˜ä¿¡æ¯
    async handleSave() {
      if (this.saveLoading) return;
      this.$refs.form.validate(async valid => {
        if (valid) {
          this.saveLoading = true;
@@ -1527,6 +1564,12 @@
            if (submitData.id) {
              response = await ethicalreviewedit(submitData);
            } else {
              // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…
              const exists = await this.checkPatientExists();
              if (exists) {
                this.$message.warning("该患者已存在,请勿重复添加");
                return;
              }
              response = await ethicalreviewadd(submitData);
            }
@@ -1556,6 +1599,31 @@
      });
    },
    // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…(按住院号)
    async checkPatientExists() {
      let inpatientno = this.form.inpatientno;
      if (!inpatientno && this.caseId) {
        try {
          const caseRes = await getDonatebaseinfo(this.caseId);
          inpatientno = (caseRes.data && caseRes.data.inpatientno) || "";
        } catch (e) {
          inpatientno = "";
        }
      }
      if (!inpatientno) return false;
      try {
        const res = await reviewinitiateBaseInfoList({
          inpatientno,
          pageNum: 1,
          pageSize: 1
        });
        const list = res.data || [];
        return list.some(item => item && item.id != null && item.id !== "");
      } catch (e) {
        return false;
      }
    },
    // å®¡æŸ¥å®Œæˆ
    async handleCompleteReview() {
      this.$confirm("确定要将本次伦理审查状态设为完成吗?", "提示", {
src/views/business/ethicalReview/index.vue
@@ -127,13 +127,34 @@
        </el-table-column>
        <el-table-column label="年龄" align="center" prop="age" width="80" />
        <el-table-column label="血型" align="center" prop="bloodtype" width="80">
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_BloodType"
              :value="scope.row.bloodtype"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="疾病诊断"
          align="center"
          prop="diagnosisname"
          min-width="180"
          width="200"
          show-overflow-tooltip
        />
        <el-table-column
          label="捐献类型"
          align="center"
          prop="donationcategory"
          width="180"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_DonationCategory"
              :value="scope.row.donationcategory"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="审查状态"
          align="center"
@@ -184,7 +205,7 @@
        <el-table-column
          label="操作"
          align="center"
          width="240"
          width="220"
          fixed="right"
          class-name="small-padding fixed-width"
        >
@@ -193,30 +214,22 @@
              size="mini"
              type="text"
              icon="el-icon-view"
              @click="handleView(scope.row)"
              >详情</el-button
              @click.stop="handleView(scope.row)"
              >查看</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click="handleUpdate(scope.row)"
              >修改</el-button
              @click.stop="handleUpdate(scope.row)"
              >编辑</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-check"
              @click="handleEndReview(scope.row)"
              :disabled="scope.row.status === '2'"
              >结束</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-download"
              @click="handleDownload(scope.row)"
              >下载</el-button
              icon="el-icon-printer"
              @click.stop="handleDownload(scope.row)"
              >打印</el-button
            >
          </template>
        </el-table-column>
@@ -250,7 +263,9 @@
    "sys_user_sex",
    "ReviewForm_status",
    "sys_ethical",
    "expert_Conclusion"
    "expert_Conclusion",
    "sys_BloodType",
    "sys_DonationCategory"
  ],
  data() {
    return {
@@ -344,7 +359,7 @@
    handleView(row) {
      this.$router.push({
        path: "/case/ethicalReviewInfo",
        query: { infoid: row.infoid, id: row.id }
        query: { infoid: row.infoid, id: row.id, mode: "view" }
      });
    },
    // æ–°å¢žæŒ‰é’®æ“ä½œ
@@ -356,7 +371,7 @@
      const infoid = row.infoid;
      this.$router.push({
        path: "/case/ethicalReviewInfo",
        query: { infoid: infoid, id: row.id }
        query: { infoid: infoid, id: row.id, mode: "edit" }
      });
    },
    // ç»“束审查操作
src/views/business/followupVisit/index.vue
@@ -86,7 +86,6 @@
            type="primary"
            icon="el-icon-plus"
            @click="handleCreate"
            v-hasPermi="['system:followup:add']"
            >新增随访</el-button
          >
          <el-button
@@ -94,7 +93,6 @@
            icon="el-icon-edit"
            :disabled="single"
            @click="handleUpdate"
            v-hasPermi="['system:followup:edit']"
            >修改</el-button
          >
          <el-button
@@ -102,14 +100,12 @@
            icon="el-icon-delete"
            :disabled="multiple"
            @click="handleDelete"
            v-hasPermi="['system:followup:remove']"
            >删除</el-button
          >
          <el-button
            type="warning"
            icon="el-icon-download"
            @click="handleExport"
            v-hasPermi="['system:followup:export']"
            >导出</el-button
          >
        </el-col>
@@ -230,7 +226,6 @@
              type="text"
              icon="el-icon-view"
              @click="handleView(scope.row)"
              v-hasPermi="['system:followup:query']"
              >详情</el-button
            >
            <!-- <el-button
@@ -238,7 +233,6 @@
              type="text"
              icon="el-icon-edit"
              @click="handleUpdate(scope.row)"
              v-hasPermi="['system:followup:edit']"
              >修改</el-button
            > -->
            <el-button
@@ -246,7 +240,6 @@
              type="text"
              icon="el-icon-delete"
              @click="handleDelete(scope.row)"
              v-hasPermi="['system:followup:remove']"
              >删除</el-button
            >
          </template>
src/views/business/followupVisit/info.vue
@@ -19,7 +19,6 @@
          type="primary"
          icon="el-icon-plus"
          @click="handleAddFollowup"
          v-hasPermi="['system:followup:add']"
        >
          æ–°å¢žéšè®¿
        </el-button>
@@ -28,7 +27,6 @@
          icon="el-icon-delete"
          :disabled="!selectedFollowup"
          @click="handleDeleteFollowup"
          v-hasPermi="['system:followup:remove']"
        >
          åˆ é™¤é€‰ä¸­
        </el-button>
@@ -127,7 +125,6 @@
              type="text"
              icon="el-icon-delete"
              @click="handleDeleteSingle(scope.row)"
              v-hasPermi="['system:followup:remove']"
            >
              åˆ é™¤
            </el-button>
src/views/business/maintain/index.vue
@@ -114,12 +114,6 @@
        />
        -->
        <el-table-column
          label="捐献编号"
          align="center"
          prop="caseNo"
          width="120"
        />
        <el-table-column
          label="住院号"
          align="center"
          prop="inpatientno"
@@ -165,9 +159,22 @@
          label="疾病诊断"
          align="center"
          prop="diagnosisname"
          min-width="180"
          width="200"
          show-overflow-tooltip
        />
        <el-table-column
          label="捐献类型"
          align="center"
          prop="donationcategory"
          width="180"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_DonationCategory"
              :value="scope.row.donationcategory"
            />
          </template>
        </el-table-column>
        <!-- <el-table-column
          label="维护项目"
          align="center"
@@ -227,7 +234,7 @@
          label="上报医院"
          align="center"
          prop="treatmenthospitalname"
          width="150"
          width="200"
          show-overflow-tooltip
        />
        <!-- <el-table-column
@@ -249,9 +256,15 @@
          width="100"
        />
        <el-table-column
          label="捐献编号"
          align="center"
          prop="caseNo"
          width="220"
        />
        <el-table-column
          label="操作"
          align="center"
          width="120"
          min-width="180"
          fixed="right"
          class-name="small-padding fixed-width"
        >
@@ -261,7 +274,14 @@
              type="text"
              icon="el-icon-view"
              @click.stop="handleView(scope.row)"
              >详情</el-button
              >查看</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click.stop="handleUpdate(scope.row)"
              >编辑</el-button
            >
          </template>
        </el-table-column>
@@ -286,7 +306,12 @@
export default {
  name: "MaintenanceList",
  components: { Pagination },
  dicts: ["sys_user_sex", "sys_BloodType", "maintain_type"],
  dicts: [
    "sys_user_sex",
    "sys_BloodType",
    "maintain_type",
    "sys_DonationCategory"
  ],
  data() {
    return {
      // é®ç½©å±‚
@@ -373,7 +398,6 @@
          if (response.code === 200) {
            this.maintenanceList = response.data;
            this.total = response.total || 0;
          } else {
            this.$message.error(response.msg || "获取数据失败");
          }
@@ -433,14 +457,21 @@
    handleRowClick(row) {
      this.$router.push({
        path: "/case/maintainInfo",
        query: { id: row.id, infoid: row.infoid }
        query: { id: row.id, infoid: row.infoid, mode: "view" }
      });
    },
    // æŸ¥çœ‹è¯¦æƒ…
    handleView(row) {
      this.$router.push({
        path: "/case/maintainInfo",
        query: { id: row.id, infoid: row.infoid }
        query: { id: row.id, infoid: row.infoid, mode: "view" }
      });
    },
    // ç¼–辑
    handleUpdate(row) {
      this.$router.push({
        path: "/case/maintainInfo",
        query: { id: row.id, infoid: row.infoid, mode: "edit" }
      });
    },
    // å¯¼å‡ºæŒ‰é’®æ“ä½œ
src/views/business/maintain/maintainInfo.vue
@@ -6,16 +6,20 @@
      <div slot="header" class="clearfix">
        <span class="detail-title">评估各项记录</span>
        <el-button
          v-if="!isReadOnly"
          type="primary"
          size="mini"
          :loading="saveLoading"
          @click="toggleEditMode"
          style="float: right;margin-left: 20px;"
        >
          ä¿å­˜ç¼–辑
        </el-button>
        <el-button
          v-if="!isReadOnly"
          type="success"
          size="mini"
          :loading="saveLoading"
          @click="accomplish"
          style="float: right;margin-left: 20px;"
        >
@@ -30,6 +34,7 @@
            <div slot="header" class="clearfix">
              <span class="detail-title">培养结果记录</span>
              <el-button
                v-if="!isReadOnly"
                type="primary"
                size="mini"
                icon="el-icon-plus"
@@ -120,6 +125,7 @@
                </template>
              </el-table-column>
              <el-table-column
                v-if="!isReadOnly"
                label="操作"
                align="center"
                width="200"
@@ -151,6 +157,7 @@
            <div slot="header" class="clearfix">
              <span class="detail-title">护理核查记录</span>
              <el-button
                v-if="!isReadOnly"
                type="primary"
                size="mini"
                icon="el-icon-plus"
@@ -196,6 +203,7 @@
                </template>
              </el-table-column>
              <el-table-column
                v-if="!isReadOnly"
                label="操作"
                align="center"
                width="180"
@@ -228,7 +236,7 @@
          <liver-kidney-panel
            ref="liverKidney"
            :initial-data="assessmentData.liverKidney"
            :is-editing="isEdit && activeTab === 'liverKidney'"
            :is-editing="!isReadOnly && isEdit && activeTab === 'liverKidney'"
            @data-change="handleLiverKidneyDataChange"
          />
        </el-tab-pane>
@@ -238,7 +246,7 @@
          <blood-routine-panel
            ref="bloodRoutine"
            :initial-data="assessmentData.bloodRoutine"
            :is-editing="isEdit && activeTab === 'bloodRoutine'"
            :is-editing="!isReadOnly && isEdit && activeTab === 'bloodRoutine'"
            @data-change="handleBloodRoutineDataChange"
          />
        </el-tab-pane>
@@ -248,7 +256,7 @@
          <urine-routine-panel
            ref="urineRoutine"
            :initial-data="assessmentData.urineRoutine"
            :is-editing="isEdit && activeTab === 'urineRoutine'"
            :is-editing="!isReadOnly && isEdit && activeTab === 'urineRoutine'"
            @data-change="handleUrineRoutineDataChange"
          />
        </el-tab-pane>
@@ -256,7 +264,7 @@
          <heart-lab-panel
            ref="heartLab"
            :initial-data="assessmentData.heartLab"
            :is-editing="isEdit && activeTab === 'heartLab'"
            :is-editing="!isReadOnly && isEdit && activeTab === 'heartLab'"
            @data-change="handleHeartLabDataChange"
          />
        </el-tab-pane>
@@ -264,7 +272,7 @@
          <lung-lab-panel
            ref="lungLab"
            :initial-data="assessmentData.lungLab"
            :is-editing="isEdit && activeTab === 'lungLab'"
            :is-editing="!isReadOnly && isEdit && activeTab === 'lungLab'"
            @data-change="handleLungLabDataChange"
          />
        </el-tab-pane>
@@ -272,7 +280,7 @@
          <pancreas-lab-panel
            ref="pancreasLab"
            :initial-data="assessmentData.pancreasLab"
            :is-editing="isEdit && activeTab === 'pancreasLab'"
            :is-editing="!isReadOnly && isEdit && activeTab === 'pancreasLab'"
            @data-change="handlePancreasLabDataChange"
          />
        </el-tab-pane>
@@ -516,6 +524,7 @@
<script>
import { maintainList, maintainedit, maintainAdd } from "@/api/businessApi";
import { getDonatebaseinfo } from "@/api/project/donatebaseinfo";
import Pagination from "@/components/Pagination";
import UploadAttachment from "@/components/UploadAttachment";
import FilePreviewDialog from "@/components/FilePreviewDialog";
@@ -558,6 +567,7 @@
      isEdit: true,
      currentMaintenanceId: null,
      isEditMode: false,
      saveLoading: false,
      form: {
        id: undefined,
        caseNo: "",
@@ -676,6 +686,12 @@
  watch: {
    $route(to, from) {
      this.loadMaintenanceData();
    }
  },
  computed: {
    // æŸ¥çœ‹æ¨¡å¼ï¼šåªè¯»ï¼Œç¦ç”¨è¡¨å•并隐藏保存按钮
    isReadOnly() {
      return this.$route.query.mode === "view";
    }
  },
  methods: {
@@ -805,7 +821,17 @@
    },
    // ä¿å­˜æ‰€æœ‰æ•°æ®
    async handleSave() {
      if (this.saveLoading) return;
      this.saveLoading = true;
      try {
        // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…
        if (!this.currentMaintenanceId) {
          const exists = await this.checkPatientExists();
          if (exists) {
            this.$message.warning("该患者已存在,请勿重复添加");
            return;
          }
        }
        const saveData = {
          ...this.form,
          itemDesc: {
@@ -851,6 +877,28 @@
      } catch (error) {
        console.error("保存数据失败:", error);
        this.$message.error("保存失败");
      } finally {
        this.saveLoading = false;
      }
    },
    // æ–°å¢žæ—¶æ ¡éªŒæ˜¯å¦å·²æœ‰ç›¸åŒæ‚£è€…(按住院号)
    async checkPatientExists() {
      let inpatientno = this.form.inpatientno;
      if (!inpatientno && this.caseId) {
        try {
          const caseRes = await getDonatebaseinfo(this.caseId);
          inpatientno = (caseRes.data && caseRes.data.inpatientno) || "";
        } catch (e) {
          inpatientno = "";
        }
      }
      if (!inpatientno) return false;
      try {
        const res = await maintainList({ inpatientno, pageNum: 1, pageSize: 1 });
        const list = res.data || [];
        return list.some(item => item && item.id != null && item.id !== "");
      } catch (e) {
        return false;
      }
    },
    // 5. åœ¨ methods ä¸­æ·»åŠ æ•°æ®å¤„ç†æ–¹æ³•
src/views/business/transfer/index.vue
@@ -184,7 +184,7 @@
        </template>
      </el-table-column>
      <el-table-column
        label="计划转运时间"
        label="转运时间"
        align="center"
        prop="transportStartTime"
        width="160"
src/views/business/transfer/transportDetail.vue
@@ -40,7 +40,7 @@
        <el-descriptions-item label="出发地点">{{
          transportData.transportStartPlace
        }}</el-descriptions-item>
        <el-descriptions-item label="计划转运时间">{{
        <el-descriptions-item label="转运时间">{{
          transportData.transportStartTime
        }}</el-descriptions-item>
        <el-descriptions-item label="负责协调员">{{
@@ -79,7 +79,7 @@
        <el-descriptions-item label="治疗科室">{{
          transportData.treatmentDeptName
        }}</el-descriptions-item>
        <el-descriptions-item label="出发时间">{{
        <el-descriptions-item label="转运时间">{{
          transportData.transportStartTime
        }}</el-descriptions-item>
        <el-descriptions-item label="转运状态">
src/views/home/cockpitMock.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,184 @@
// é©¾é©¶èˆ±æ¨¡æ‹Ÿæ•°æ®ï¼ˆæŽ¥å£æœªå°±ç»ªæ—¶çš„兜底展示)
// å­—段形状与真实接口保持一致,后端就绪后可在 home/index.vue é‡Œåˆ‡æ¢çœŸå®žæŽ¥å£
// è¯´æ˜Žï¼šé©¾é©¶èˆ±åœ°å›¾ä¸ºã€ŒåŒºåŽ¿çº§ã€ï¼Œè€Œ /opo/totals/* ç»Ÿè®¡æŽ¥å£ä¸ºã€Œåœ°åŒºçº§ã€ï¼Œæ•…区县地图、仪表盘、动态表暂用此模拟数据
// ç¡®å®šæ€§ä¼ªéšæœºï¼Œä¿è¯æ¯æ¬¡æ¸²æŸ“数据一致
function createRand(seed) {
  let s = seed % 2147483647;
  if (s <= 0) s += 2147483646;
  return function () {
    s = (s * 16807) % 2147483647;
    return (s - 1) / 2147483646;
  };
}
// é’å²› 10 åŒºåŽ¿ + æ—¥ç…§ 4 åŒºåŽ¿ï¼ˆä¸Ž common/map/qingdao.js åç§°ä¸€ä¸€å¯¹åº”)
const DISTRICTS = [
  { name: '市南区', district: '370202' },
  { name: '市北区', district: '370203' },
  { name: '黄岛区', district: '370211' },
  { name: '崂山区', district: '370212' },
  { name: '李沧区', district: '370213' },
  { name: '城阳区', district: '370214' },
  { name: '即墨区', district: '370215' },
  { name: '胶州市', district: '370281' },
  { name: '平度市', district: '370283' },
  { name: '莱西市', district: '370285' },
  { name: '东港区', district: '371102' },
  { name: '岚山区', district: '371103' },
  { name: '五莲县', district: '371121' },
  { name: '莒县', district: '371122' }
];
const REGIONS = ['青岛地区', '日照地区', '济南地区', '烟台地区', '威海地区', '潍坊地区', '临沂地区'];
const MONTHS = ['2024-01', '2024-02', '2024-03', '2024-04', '2024-05', '2024-06', '2024-07', '2024-08', '2024-09', '2024-10', '2024-11', '2024-12'];
const ORGANS = ['全肝', '肾脏', '心脏', '肺', '胰腺', '眼角膜'];
const BLOOD_TYPES = ['A', 'B', 'O', 'AB'];
const AGE_GROUPS = ['1', '2', '3', '4'];
// åŒºåŽ¿åœ°å›¾æ•°æ®ï¼š{ name, district, value(潜在), elseData:{ value2(完成), value3(器官) } }
export function mockMapData() {
  const r = createRand(101);
  return DISTRICTS.map(d => {
    const potential = 8 + Math.round(r() * 60);
    return {
      name: d.name,
      district: d.district,
      value: potential,
      elseData: {
        value2: Math.round(potential * (0.45 + r() * 0.35)),
        value3: Math.round(potential * (1.5 + r() * 2.5))
      }
    };
  });
}
// ä»ªè¡¨ç›˜æŒ‡æ ‡ï¼š{ name, value, max, color }
export function mockGauges() {
  return [
    { name: '捐献完成率', value: 68.5, max: 100, color: '#34d399' },
    { name: '潜献转化率', value: 45.2, max: 100, color: '#38a5f8' },
    { name: '器官利用率', value: 86.0, max: 100, color: '#22d3ee' },
    { name: '器官弃用率', value: 14.0, max: 100, color: '#fb7185' }
  ];
}
export function mockCaseTrend() {
  const r = createRand(111);
  return MONTHS.map(m => {
    const potential = 40 + Math.round(r() * 50);
    return {
      donateTime: m,
      potentialCount: potential,
      completeCount: Math.round(potential * (0.5 + r() * 0.3)),
      totalCount: potential
    };
  });
}
export function mockOrganMoon() {
  const r = createRand(122);
  return MONTHS.map(m => {
    const get = 60 + Math.round(r() * 80);
    return { donateTime: m, getCount: get, useCount: Math.round(get * (0.7 + r() * 0.2)) };
  });
}
export function mockCaseBloodType() {
  const r = createRand(133);
  return BLOOD_TYPES.map(boodType => {
    const man = 25 + Math.round(r() * 35);
    const woman = 20 + Math.round(r() * 30);
    return { boodType, manCount: man, womanCount: woman, boodTypeCount: man + woman };
  });
}
export function mockCaseSex() {
  const r = createRand(144);
  return AGE_GROUPS.map(ageGroup => ({
    ageGroup,
    manCount: 20 + Math.round(r() * 45),
    womanCount: 15 + Math.round(r() * 40)
  }));
}
export function mockOrganType() {
  const r = createRand(155);
  return ORGANS.map(organName => {
    const get = 50 + Math.round(r() * 90);
    return { organName, getCount: get, useCount: Math.round(get * (0.7 + r() * 0.2)) };
  });
}
export function mockCaseTrendArea() {
  const r = createRand(166);
  return REGIONS.map(area => {
    const potential = 30 + Math.round(r() * 80);
    return { area, potentialCount: potential, completeCount: Math.round(potential * (0.5 + r() * 0.3)) };
  });
}
export function mockTotals() {
  return [{ totalPotential: 486, totalCompletion: 327 }];
}
export function mockCaseAvgAge() {
  return [{ avgAge: 45.6 }];
}
// å™¨å®˜å¼ƒç”¨æƒ…况:{ organName, getCount, discardCount }
export function mockOrganDiscard() {
  const r = createRand(199);
  return ORGANS.map(organName => {
    const get = 50 + Math.round(r() * 90);
    const discard = Math.round(get * (0.05 + r() * 0.2));
    return { organName, getCount: get, discardCount: discard };
  });
}
// æœºæž„捐献动态表(dv-scroll-board é…ç½®ï¼‰
export function mockHospitalDonate() {
  const r = createRand(177);
  const HOSPITALS = [
    '青岛大学附属医院', '青岛市立医院', '青岛市中心医院', '山东大学齐鲁医院(青岛)',
    '青岛妇女儿童医院', '青岛市海慈医院', '日照市人民医院', '日照市中医医院', '莒县人民医院'
  ];
  const header = ['区域', '机构', '捐献登记', '捐献完成'];
  const data = HOSPITALS.map((h, i) => {
    const region = i < 6 ? '青岛地区' : '日照地区';
    const potential = 15 + Math.round(r() * 40);
    return [region, h, potential, Math.round(potential * (0.5 + r() * 0.3))];
  });
  return { header, data };
}
// æœºæž„接受器官动态表(dv-scroll-board é…ç½®ï¼‰
export function mockHospitalAccept() {
  const r = createRand(188);
  const HOSPITALS = [
    '青岛大学附属医院', '青岛市立医院', '青岛市中心医院', '山东大学齐鲁医院(青岛)',
    '青岛妇女儿童医院', '青岛市海慈医院', '日照市人民医院', '日照市中医医院'
  ];
  const header = ['移植医院', '接受器官数'];
  const data = HOSPITALS.map(h => [h, 8 + Math.round(r() * 50)]);
  return { header, data };
}
// æ±‡æ€»ï¼šä¸€æ¬¡æ€§è¿”回驾驶舱所需全部模拟数据
export function mockCockpitData() {
  return {
    mapData: mockMapData(),
    gauges: mockGauges(),
    caseTrend: mockCaseTrend(),
    organMoon: mockOrganMoon(),
    caseBloodType: mockCaseBloodType(),
    caseSex: mockCaseSex(),
    organType: mockOrganType(),
    organDiscard: mockOrganDiscard(),
    caseTrendArea: mockCaseTrendArea(),
    totals: mockTotals(),
    caseAvgAge: mockCaseAvgAge(),
    hospitalDonate: mockHospitalDonate(),
    hospitalAccept: mockHospitalAccept()
  };
}
src/views/home/components/MapChart/index.vue
@@ -37,6 +37,33 @@
      type: String,
      default: "map",
    },
    zoom: {
      type: Number,
      default: 1.2,
    },
    left: {
      type: String,
      default: "8%",
    },
    top: {
      type: String,
      default: "10%",
    },
    // åŒºåŽ¿æ ‡ç­¾ï¼šfull=名称+数值(默认,浅色页用)/ name=仅名称(深色大屏用,置于区县内部避免重叠)/ none=不显示
    labelMode: {
      type: String,
      default: "full",
    },
    // æ˜¯å¦å…è®¸æ‹–拽缩放地图
    roam: {
      type: Boolean,
      default: false,
    },
    // æ·±è‰²å¤§å±é…è‰²ï¼ˆè¿žç»­æ¸å˜ + æ·±è‰²æè¾¹ï¼‰ï¼Œæµ…色页默认关闭
    dark: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
@@ -64,40 +91,24 @@
    },
    resetOption(newData) {
      const nameMode = this.labelMode === "name";
      const showLabel = this.labelMode !== "none";
      const dark = this.dark;
      let seriesData = [
        {
          name: "杭州市",
        },
        {
          name: "宁波市",
        },
        {
          name: "温州市",
        },
        {
          name: "嘉兴市",
        },
        {
          name: "湖州市",
        },
        {
          name: "绍兴市",
        },
        {
          name: "金华市",
        },
        {
          name: "衢州市",
        },
        {
          name: "舟山市",
        },
        {
          name: "台州市",
        },
        {
          name: "丽水市",
        },
        { name: "市南区" },
        { name: "市北区" },
        { name: "黄岛区" },
        { name: "崂山区" },
        { name: "李沧区" },
        { name: "城阳区" },
        { name: "即墨区" },
        { name: "胶州市" },
        { name: "平度市" },
        { name: "莱西市" },
        { name: "东港区" },
        { name: "岚山区" },
        { name: "五莲县" },
        { name: "莒县" },
      ];
      if (this.chartType == "map") {
        let maxValue = 2;
@@ -127,17 +138,20 @@
        }
        // è®¾ç½®ç‚¹çš„位置(经纬度)
        const geoCoordMap = {
          æ­å·žå¸‚: [120.19, 30.26, 20],
          å®æ³¢å¸‚: [121.56, 29.86, 20],
          æ¸©å·žå¸‚: [120.65, 28.01, 20],
          å˜‰å…´å¸‚: [120.76, 30.77, 20],
          æ¹–州市: [120.1, 30.86, 20],
          ç»å…´å¸‚: [120.58, 30.01, 20],
          é‡‘华市: [119.64, 29.12, 20],
          è¡¢å·žå¸‚: [118.88, 28.97, 20],
          èˆŸå±±å¸‚: [122.11, 30.07, 20],
          å°å·žå¸‚: [121.03, 29.15, 20],
          ä¸½æ°´å¸‚: [119.92, 28.45, 20],
          å¸‚南区: [120.364533, 36.065674, 20],
          å¸‚北区: [120.366891, 36.111867, 20],
          é»„岛区: [119.883281, 35.859051, 20],
          å´‚山区: [120.580013, 36.189115, 20],
          æŽæ²§åŒº: [120.421969, 36.185575, 20],
          åŸŽé˜³åŒº: [120.32982, 36.274819, 20],
          å³å¢¨åŒº: [120.524774, 36.482445, 20],
          èƒ¶å·žå¸‚: [119.953343, 36.24043, 20],
          å¹³åº¦å¸‚: [119.944487, 36.782164, 20],
          èŽ±è¥¿å¸‚: [120.435764, 36.858461, 20],
          ä¸œæ¸¯åŒº: [119.374789, 35.451344, 20],
          å²šå±±åŒº: [119.19844, 35.284019, 20],
          äº”莲县: [119.243496, 35.737456, 20],
          èŽ’åŽ¿: [118.880292, 35.667313, 20],
        };
        let convertData = function (data) {
@@ -177,43 +191,62 @@
              }`;
            },
          },
          visualMap: {
            min: 0,
            max: 1,
            show: false,
            right:'20%',
            seriesIndex: 0,
            text: ["最高", "低"],
            textStyle: {
              color: "#fff",
              fontSize: "10",
            },
            inRange: {
              color: [
                "rgba(41,166,206)",
                "rgba(69,117,245)",
                "rgba(255, 69, 0)",
              ], // å–值范围的颜色
            },
            // é¢œè‰²
            pieces: [
              { value: 0, color: "rgba(41,166,206, .5)" },
              { value: minValue, color: "rgba(41,166,206, .6)" },
              { min: 0, max: maxValue - 1, color: "rgba(69,117,245, .9)" },
              { value: maxValue, color: "rgba(255, 69, 0,.9)" },
            ],
            show: true,
            backgroundColor:"rgba(255, 255, 255, 0.19)"
          },
          visualMap: dark
            ? {
                type: "continuous",
                min: 0,
                max: maxValue,
                seriesIndex: 0,
                calculable: true,
                show: true,
                left: "3%",
                bottom: "5%",
                orient: "vertical",
                text: ["高", "低"],
                textStyle: { color: "#c3cde4", fontSize: 12 },
                inRange: {
                  color: ["#16325c", "#2f6fb5", "#38a5f8", "#22d3ee"],
                },
                itemWidth: 12,
                itemHeight: 90,
              }
            : {
                min: 0,
                max: 1,
                show: false,
                right: "20%",
                seriesIndex: 0,
                text: ["最高", "低"],
                textStyle: {
                  color: "#fff",
                  fontSize: "10",
                },
                inRange: {
                  color: [
                    "rgba(41,166,206)",
                    "rgba(69,117,245)",
                    "rgba(255, 69, 0)",
                  ], // å–值范围的颜色
                },
                // é¢œè‰²
                pieces: [
                  { value: 0, color: "rgba(41,166,206, .5)" },
                  { value: minValue, color: "rgba(41,166,206, .6)" },
                  { min: 0, max: maxValue - 1, color: "rgba(69,117,245, .9)" },
                  { value: maxValue, color: "rgba(255, 69, 0,.9)" },
                ],
                show: true,
                backgroundColor: "rgba(255, 255, 255, 0.19)",
              },
          // åº•部背景
          geo: {
            show: true,
            aspectScale: 0.85, //长宽比
            zoom: 1.2,
            top: "10%",
            left: "8%",
            map: "浙江",
            roam: false,
            zoom: this.zoom,
            top: this.top,
            left: this.left,
            map: "青岛日照",
            roam: this.roam,
            itemStyle: {
              normal: {
                areaColor: "rgba(0,0,0,0)",
@@ -231,40 +264,57 @@
            {
              name: "相关指数",
              type: "map",
              aspectScale: 0.85, //长宽比
              zoom: 1.2,
              mapType: "浙江", // è‡ªå®šä¹‰æ‰©å±•图表类型
              top: "10%",
              left: "8%",
              itemStyle: {
                normal: {
                  color: "red",
                  areaColor: "rgba(19,54,162, .5)",
                  borderColor: "rgba(0,242,252,.3)",
                  borderWidth: 1,
                  shadowBlur: 7,
                  shadowColor: "#00f2fc",
                },
                emphasis: {
                  areaColor: "rgba(255, 249, 133, 0.6)",
                  borderColor: "rgba(252, 239, 0, 0.6)",
                  borderWidth: 2,
                  shadowBlur: 10,
                  shadowColor: "#00f2fc",
                },
              },
              geoIndex: 0,
              itemStyle: dark
                ? {
                    normal: {
                      areaColor: "#16325c",
                      borderColor: "rgba(56,165,248,.55)",
                      borderWidth: 1,
                      shadowBlur: 8,
                      shadowColor: "rgba(56,165,248,.5)",
                    },
                    emphasis: {
                      areaColor: "rgba(56,165,248,.6)",
                      borderColor: "#22d3ee",
                      borderWidth: 2,
                      shadowBlur: 12,
                      shadowColor: "#22d3ee",
                    },
                  }
                : {
                    normal: {
                      color: "red",
                      areaColor: "rgba(19,54,162, .5)",
                      borderColor: "rgba(0,242,252,.3)",
                      borderWidth: 1,
                      shadowBlur: 7,
                      shadowColor: "#00f2fc",
                    },
                    emphasis: {
                      areaColor: "rgba(255, 249, 133, 0.6)",
                      borderColor: "rgba(252, 239, 0, 0.6)",
                      borderWidth: 2,
                      shadowBlur: 10,
                      shadowColor: "#00f2fc",
                    },
                  },
              label: {
                show: true,
                formatter: (params) =>
                  `${params.name},${params.value},${
                show: showLabel,
                formatter: (params) => {
                  if (nameMode) return params.name;
                  return `${params.name},${params.value},${
                    params.data.elseData ? params.data.elseData.value2 : ""
                  },${params.data.elseData ? params.data.elseData.value3 : ""}`,
                position: "right",
                distance: 20,
                  },${params.data.elseData ? params.data.elseData.value3 : ""}`;
                },
                position: nameMode ? "inside" : "right",
                distance: nameMode ? 0 : 20,
                textStyle: {
                  fontSize: 14,
                  color: "#606266",
                  fontSize: nameMode ? 14 : 14,
                  color: nameMode ? "#ffffff" : "#606266",
                  fontWeight: nameMode ? 600 : 400,
                  textBorderColor: nameMode ? "rgba(6,16,34,0.85)" : "transparent",
                  textBorderWidth: nameMode ? 2 : 0,
                },
                emphasis: {
                  textStyle: {
@@ -272,9 +322,11 @@
                  },
                },
                padding: [4, 4, 4, 4],
                backgroundColor: "rgba(255,255,255,0.6)",
                backgroundColor: nameMode
                  ? "rgba(0,0,0,0)"
                  : "rgba(255,255,255,0.6)",
                borderRadius: 3,
                borderColor: "#DCDFE6",
                borderColor: nameMode ? "rgba(0,0,0,0)" : "#DCDFE6",
              },
              data: newData,
              universalTransition: true,
@@ -411,7 +463,7 @@
    },
    // é‡æ–°éšæœºé€‰ä¸­åœ°å›¾åŒºåŸŸ
    reSelectMapRandomArea() {
      const length = 9;
      const length = 14;
      this.$nextTick(() => {
        const map = this.$refs.mapChart.chart;
        let index = Math.floor(Math.random() * length);
src/views/home/index.vue
@@ -1,2162 +1,860 @@
<template>
  <div>
    <div v-loading="isloading" style="padding: 10px">
      <div>
        <el-image
          style="width: 100%; height: 72px"
          :src="img.head"
          fit="contain"
        ></el-image>
  <div v-loading="loading" class="cockpit">
    <!-- é¡¶éƒ¨æ ‡é¢˜æ  -->
    <header class="cockpit-header">
      <div class="header-left">
        <span class="header-logo"></span>
        <h1 class="header-title">青岛大学附属医院 Â· OPO å™¨å®˜æçŒ®ç®¡ç†é©¾é©¶èˆ±</h1>
      </div>
      <div class="header-right">
        <span class="header-clock">{{ now }}</span>
        <el-button type="text" class="header-logout" @click="handleLogout"
          >退出</el-button
        >
      </div>
    </header>
      <el-row :gutter="20">
        <el-col :span="6">
          <div class="iwc-dv-box" style="margin-bottom: 0.5rem">
            <dv-border-box-7
              :color="['#0a336e', '#1a7ade']"
              :backgroundColor="'#030e40'"
            >
              <div class="iwc-box-head">占比统计</div>
              <div style="padding: 0 2rem">
                <div class="iwc-box-a" :style="'height:' + heightA + 'px'">
                  <div class="iwc-box-a-1">
                    <span
                      class="iwc-before-o"
                      style="border-color: #38a5f8"
                    ></span
                    >性别占比:{{
                      currentZb.sex == -1 ? "" : arrZb.sex[currentZb.sex].label
                    }}
                  </div>
                  <el-progress
                    :text-inside="true"
                    :stroke-width="15"
                    :percentage="
                      currentZb.sex == -1
                        ? 0
                        : Number(
                            (arrZb.sex[currentZb.sex].value * 100).toFixed(0)
                          )
                    "
                    :color="'#38a5f8'"
                  ></el-progress>
                </div>
                <div class="iwc-box-a" :style="'height:' + heightA + 'px'">
                  <div class="iwc-box-a-1">
                    <span
                      class="iwc-before-o"
                      style="border-color: #9078e5"
                    ></span
                    >年龄占比:{{
                      currentZb.age == -1 ? "" : arrZb.age[currentZb.age].label
                    }}
                  </div>
                  <el-progress
                    :text-inside="true"
                    :stroke-width="15"
                    :percentage="
                      currentZb.age == -1
                        ? 0
                        : Number(
                            (arrZb.age[currentZb.age].value * 100).toFixed(0)
                          )
                    "
                    :color="'#9078e5'"
                  ></el-progress>
                </div>
                <div class="iwc-box-a" :style="'height:' + heightA + 'px'">
                  <div class="iwc-box-a-1">
                    <span
                      class="iwc-before-o"
                      style="border-color: #3fc529"
                    ></span
                    >捐献分类占比:{{
                      currentZb.type == -1
                        ? ""
                        : arrZb.type[currentZb.type].label
                    }}
                  </div>
                  <el-progress
                    :text-inside="true"
                    :stroke-width="15"
                    :percentage="
                      currentZb.type == -1
                        ? 0
                        : Number(
                            (arrZb.type[currentZb.type].value * 100).toFixed(0)
                          )
                    "
                    :color="'#3fc529'"
                  ></el-progress>
                </div>
                <div class="iwc-box-a" :style="'height:' + heightA + 'px'">
                  <div class="iwc-box-a-1">
                    <span
                      class="iwc-before-o"
                      style="border-color: #2a65b5"
                    ></span
                    >疾病占比:{{
                      currentZb.d == -1 ? "" : arrZb.d[currentZb.d].label
                    }}
                  </div>
                  <el-progress
                    :text-inside="true"
                    :stroke-width="15"
                    :percentage="
                      currentZb.d == -1
                        ? 0
                        : Number((arrZb.d[currentZb.d].value * 100).toFixed(0))
                    "
                    :color="'#2a65b5'"
                  ></el-progress>
                </div>
                <div class="iwc-box-a" :style="'height:' + heightA + 'px'">
                  <div class="iwc-box-a-1">
                    <span
                      class="iwc-before-o"
                      style="border-color: #fbc329"
                    ></span
                    >血型占比:{{
                      currentZb.x == -1 ? "" : arrZb.x[currentZb.x].label
                    }}
                  </div>
                  <el-progress
                    :text-inside="true"
                    :stroke-width="15"
                    :percentage="
                      currentZb.x == -1
                        ? 0
                        : Number((arrZb.x[currentZb.x].value * 100).toFixed(0))
                    "
                    :color="'#fbc329'"
                  ></el-progress>
                </div>
              </div>
            </dv-border-box-7>
    <!-- KPI æŒ‡æ ‡å¡ -->
    <section class="kpi-row">
      <div v-for="kpi in kpiCards" :key="kpi.label" class="kpi-card">
        <div class="kpi-icon" :style="{ background: kpi.gradient }">
          <i :class="kpi.icon"></i>
        </div>
        <div class="kpi-body">
          <div class="kpi-label">{{ kpi.label }}</div>
          <div class="kpi-value">
            <count-to
              :start-val="0"
              :end-val="kpi.value"
              :duration="1400"
              :decimals="kpi.decimals || 0"
              separator=","
            />
            <span class="kpi-unit">{{ kpi.unit }}</span>
          </div>
        </div>
      </div>
    </section>
          <div class="iwc-dv-box" style="margin-bottom: 0.5rem">
            <dv-border-box-7
              :color="['#0a336e', '#1a7ade']"
              :backgroundColor="'#030e40'"
            >
              <div class="iwc-box-head">机构捐献统计</div>
    <!-- ä»ªè¡¨ç›˜æŒ‡æ ‡ -->
    <section class="gauge-row">
      <div v-for="g in gaugeCharts" :key="g.name" class="panel">
        <div class="panel-title">{{ g.name }}</div>
        <G2PlotChart type="gauge" :options="g.options" :height="150" />
      </div>
    </section>
              <div
                style="padding: 0 2rem"
                :style="'height:' + (height * 0.35 - 54) + 'px'"
              >
                <dv-scroll-board
                  :config="tableConfig"
                  style="width: 100%"
                  class="iwc-h-rb-table"
                  :style="'height:' + (height * 0.35 - 54) + 'px'"
    <!-- ä¸»åŒºï¼šåœ°å›¾å±…中,其他图环绕 -->
    <el-row :gutter="16">
      <el-col :span="6">
        <div class="col-stack">
          <div class="panel">
            <div class="panel-title">案例月度趋势</div>
            <G2PlotChart type="area" :options="trendOptions" :height="205" />
          </div>
          <div class="panel">
            <div class="panel-title">器官获取 / ç§»æ¤è¶‹åŠ¿</div>
            <G2PlotChart type="line" :options="organMoonOptions" :height="205" />
          </div>
        </div>
      </el-col>
      <el-col :span="12">
        <div class="panel panel--map">
          <div class="panel-title">地区分布</div>
          <MapChart
            :cdata="raw.mapData"
            :height="'480px'"
            :zoom="1.4"
            left="center"
            top="middle"
            label-mode="name"
            dark
            :roam="true"
            @click="mapClick"
          />
        </div>
      </el-col>
      <el-col :span="6">
        <div class="col-stack">
          <div class="panel">
            <div class="panel-title">地区捐献对比</div>
            <G2PlotChart type="column" :options="areaOptions" :height="205" />
          </div>
          <div class="panel panel--carousel">
            <div class="panel-title">{{ currentCarousel.title }}</div>
            <transition name="fade" mode="out-in">
              <div :key="carouselIndex" class="carousel-body">
                <G2PlotChart
                  :type="currentCarousel.type"
                  :options="currentCarousel.options"
                  :height="205"
                />
              </div>
            </dv-border-box-7>
          </div>
        </el-col>
        <el-col :span="12">
          <div class="iwc-box-d" style="height: 125px">
            <div class="iwc-box-d-1">
              <div class="iwc-box-d-img">
                <el-image
                  style="width: 100%; height: 100%"
                  :src="img.btn1"
                  fit="cover"
                ></el-image>
              </div>
              <div class="iwc-box-d-f">
                <div class="iwc-box-d-f1">{{ leijishuju.processOrgans }}</div>
                <div class="iwc-box-d-f2">捐献案例累计</div>
              </div>
            </div>
            <div class="iwc-box-d-1">
              <div class="iwc-box-d-img">
                <el-image
                  style="width: 100%; height: 100%"
                  :src="img.btn2"
                  fit="cover"
                ></el-image>
              </div>
              <div class="iwc-box-d-f">
                <div class="iwc-box-d-f1">{{ leijishuju.finishedOrgans }}</div>
                <div class="iwc-box-d-f2">捐献完成累计</div>
              </div>
            </div>
            <div class="iwc-box-d-1">
              <div class="iwc-box-d-img">
                <el-image
                  style="width: 100%; height: 100%"
                  :src="img.btn3"
                  fit="cover"
                ></el-image>
              </div>
              <div class="iwc-box-d-f">
                <div class="iwc-box-d-f1">{{ leijishuju.Organsnum }}</div>
                <div class="iwc-box-d-f2">捐献器官累计</div>
              </div>
            </div>
            <div class="iwc-box-d-1" style="flex: 1.4">
              <div class="iwc-box-d-img">
                <el-image
                  style="width: 100%; height: 100%"
                  :src="img.btn4"
                  fit="cover"
                ></el-image>
              </div>
              <div class="iwc-box-d-f">
                <div class="iwc-box-d-f1">{{ leijishuju.PMP }}</div>
                <div class="iwc-box-d-f2">每百万人口器官捐献率(PMP)</div>
              </div>
            </transition>
            <div class="carousel-dots">
              <span
                v-for="(item, i) in carouselItems"
                :key="i"
                class="dot"
                :class="{ active: i === carouselIndex }"
                @click="carouselIndex = i"
              ></span>
            </div>
          </div>
        </div>
      </el-col>
    </el-row>
          <div class="iwc-box-e" style="margin-bottom: 10px; padding-left: 12%">
            <el-col :span="17">
              <MapChart
                :cdata="cdata"
                :height="height * 0.72 - 128 + 'px'"
                @click="mapClick"
                :chartType="chartType"
              />
            </el-col>
            <el-col :span="7">
              <div
                style="backgroun-color:black; margin-bottom:5px;height:100%;padding-top:50px;"
              >
                <el-row>
                  <div style="color:white;font-size:15px;text-align:center">
                    å½“前各地市潜在捐献案例
                  </div>
                </el-row>
                <el-row>
                  <el-col
                    :span="12"
                    style="color:white;font-size:14px;text-align:center;margin-top:10px"
                    v-for="(item, index) in cityDonoateCaseArr"
                    :key="index"
                  >
                    {{ item.cityName }}<br />
                    <span style="color:#ffd200">{{ item.donoateNum }}</span
                    >例
                  </el-col>
                </el-row>
              </div>
            </el-col>
          </div>
        </el-col>
        <el-col :span="6">
          <div class="iwc-dv-box" style="margin-bottom: 0.5rem">
            <dv-border-box-7
              :color="['#0a336e', '#1a7ade']"
              :backgroundColor="'#030e40'"
            >
              <div class="iwc-box-head">器官获取统计</div>
              <el-row
                style="padding: 0 2rem"
                :style="'height:' + (height * 0.35 - 54) + 'px'"
              >
                <el-col
                  :span="8"
                  v-for="(item, index) in organSumData"
                  :key="index"
                >
                  <div
                    style="
                      color: #fff;
                      padding-bottom: 10px;
                    "
                  >
                    {{ item.name }}:<span style="font-size: 18px">{{
                      item.value
                    }}</span>
                  </div>
                </el-col>
              </el-row>
            </dv-border-box-7>
          </div>
          <div class="iwc-dv-box" style="margin-bottom: 0.5rem">
            <dv-border-box-7
              :color="['#0a336e', '#1a7ade']"
              :backgroundColor="'#030e40'"
            >
              <div class="iwc-box-head">机构接受器官统计</div>
              <el-row
                style="padding: 0 1rem"
                :style="'height:' + (height * 0.35 - 54) + 'px'"
              >
                <dv-scroll-board
                  v-if="configHosOrgan.data.length > 0"
                  :config="configHosOrgan"
                  class="iwc-box-b-table"
                  style="width: 100%"
                  :style="'height:' + (height * 0.35 - 54) + 'px'"
                />
              </el-row>
            </dv-border-box-7>
          </div>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="6">
          <div class="iwc-dv-box" style="margin-bottom: 0.5rem">
            <dv-border-box-7
              :color="['#0a336e', '#1a7ade']"
              :backgroundColor="'#030e40'"
            >
              <div class="iwc-box-head">历年捐献数据</div>
              <el-row
                style="padding: 0 1rem"
                :style="'height:' + (height * 0.28 - 80) + 'px'"
              >
                <BarChartH
                  :cdata="cdataYear"
                  :organData="organYearData"
                  :height="height * 0.28 - 80 + 'px'"
                />
              </el-row>
            </dv-border-box-7>
          </div>
        </el-col>
        <el-col :span="12">
          <div class="iwc-dv-box" style="margin-bottom: 0.5rem">
            <dv-border-box-7
              :color="['#0a336e', '#1a7ade']"
              :backgroundColor="'#030e40'"
            >
              <div class="iwc-box-head">捐献案例月度统计</div>
              <div style="padding: 0 2rem">
                <LineChart
                  :cdata="anlidata"
                  :height="height * 0.28 - 80 + 'px'"
                />
              </div>
            </dv-border-box-7>
          </div>
        </el-col>
        <el-col :span="6">
          <div class="iwc-dv-box">
            <dv-border-box-7
              :color="['#0a336e', '#1a7ade']"
              :backgroundColor="'#030e40'"
            >
              <div class="iwc-box-head">质控指标</div>
              <div
                style="padding: 0 2rem"
                :style="'height:' + (height * 0.28 - 80) + 'px'"
              >
                <div class="iwc-box-c">
                  <div class="iwc-box-c1" style="color: #fac738">
                    <div class="iwc-box-c1-o">
                      {{
                        leijishuju.donateTransferRate
                          ? leijishuju.donateTransferRate.toFixed(2)
                          : ""
                      }}
                    </div>
                    <div class="iwc-box-c1-l" style="font-size:0.8rem">
                      å™¨å®˜æçŒ®è½¬åŒ–率
                    </div>
                  </div>
                  <div class="iwc-box-c1" style="color: #34bc1d">
                    <div class="iwc-box-c1-o">
                      {{
                        leijishuju.organProductionRate
                          ? leijishuju.organProductionRate.toFixed(2)
                          : ""
                      }}
                    </div>
                    <div class="iwc-box-c1-l" style="font-size:0.8rem">
                      å¹³å‡å™¨å®˜äº§å‡ºçއ
                    </div>
                  </div>
                  <div class="iwc-box-c1" style="color: #2f9ef4">
                    <div class="iwc-box-c1-o">
                      {{
                        leijishuju.organUsedRate
                          ? leijishuju.organUsedRate.toFixed(2)
                          : ""
                      }}
                    </div>
                    <div class="iwc-box-c1-l" style="font-size:0.8rem">
                      èŽ·å–å™¨å®˜åˆ©ç”¨çŽ‡
                    </div>
                  </div>
                </div>
              </div>
            </dv-border-box-7>
          </div>
        </el-col>
      </el-row>
      <!-- <el-row v-if="0" class="c-home" :gutter="10">
        <el-col :span="8">
          <div style="padding-top: 25px; padding-bottom: 10px">
            <dv-border-box-2 :color="['#1b88a3']">
              <div class="box-title" style="position: absolute; top: -8px">
                <span><b>对比分析</b></span>
              </div>
              <div style="padding: 40px 10px">
                <div
                  class="c-table-title light"
                  v-if="0"
                  style="height: 50px; line-height: 50px"
                >
                  å™¨å®˜ç»Ÿè®¡
                </div>
                <LineChart :cdata="anlidata" :height="height / 7 + 'px'" />
                <Line2Chart :cdata="yiyuan" :height="height / 7 + 'px'" />
                <Line1Chart :cdata="organsum" :height="height / 7 + 'px'" />
                <BarChart :cdata="organData" :height="height / 7 + 'px'" />
                <BarChart2
                  :cdata="hosGetData"
                  :height="(height / 7) * 2 + 'px'"
                />
                <BarChart3
                  :cdata="organSumData"
                  :height="(height - 10) / 7 + 'px'"
                />
              </div>
            </dv-border-box-2>
          </div>
        </el-col>
        <el-col :span="8" style="margin-top: 28px">
          <dv-border-box-12 :color="['#1b88a3']" style="padding: -20px">
            <div class="box-title" style="position: absolute; top: -8px">
              <span><b>全省概况</b></span>
            </div>
            <div style="padding: 30px 20px 30px; margin: 0 auto">
              <el-row>
                <el-col :span="8" class="box-num">
                  <div class="box-num-main" style="text-align: center">
                    <p>潜在捐献累计</p>
                    <span class="box-num-main-n">{{
                      leijishuju.processOrgans
                    }}</span>
                  </div>
                  <div class="box-num-ex">
                    <span></span>
                  </div>
                </el-col>
                <el-col :span="8" class="box-num">
                  <div class="box-num-main" style="text-align: center">
                    <p>捐献完成累计</p>
                    <span class="box-num-main-n">{{
                      leijishuju.finishedOrgans
                    }}</span>
                  </div>
                  <div style="height: 20px"></div>
                  <div class="box-num-ex">
                    <span></span>
                  </div>
                </el-col>
                <el-col :span="8" class="box-num">
                  <div class="box-num-main" style="text-align: center">
                    <p>捐献器官累计</p>
                    <span class="box-num-main-n">{{
                      leijishuju.Organsnum
                    }}</span>
                  </div>
                  <div class="box-num-ex">
                    <span></span>
                  </div>
                </el-col>
              </el-row>
              <el-row style="margin-bottom: 10px">
                <el-col :span="12" class="box-num">
                  <div class="box-num-main" style="text-align: center">
                    <p>每百万人口器官捐献率(PMP)</p>
                    <span class="box-num-main-n">{{ leijishuju.PMP }}</span>
                  </div>
                  <div class="box-num-ex">
                    <span></span>
                  </div>
                </el-col>
                <el-col :span="12" class="box-num">
                  <div class="box-num-main" style="text-align: center">
                    <p>潜献转化率/器官产出率/器官利用率</p>
                    <span class="box-num-main-n">
                      {{ leijishuju.donateTransferRate.toFixed(2) }}/{{
                        leijishuju.organProductionRate.toFixed(2)
                      }}/{{ leijishuju.organUsedRate.toFixed(2) }}</span
                    >
                  </div>
                  <div class="box-num-ex">
                    <span></span>
                  </div>
                </el-col>
              </el-row>
            </div>
          </dv-border-box-12>
          <dv-border-box-7 :color="['#fff']">
            <dv-border-box-8>
              <div style="padding: 40px 20px">
                <div style="padding-top: 12px"></div>
                <MapChart
                  :cdata="cdata"
                  :height="height - 220 + 'px'"
                  @click="mapClick"
                  :chartType="chartType"
                /></div></dv-border-box-8
          ></dv-border-box-7>
        </el-col>
        <el-col :span="8" v-loading="tableLoading" style="padding-top: 28px">
          <dv-border-box-6 :color="['#1b88a3']">
            <div class="box-title" style="position: absolute; top: -8px">
              <span><b>占比统计</b></span>
            </div>
            <div
              class="iwc-ring"
              v-if="1"
              style="
                padding: 30px 10px 20px;
                min-height: 280px;
                text-align: center;
              "
            >
              <el-row
                ><el-col :span="8">
                  <dv-active-ring-chart
                    v-if="configSex.data.length > 0"
                    :config="configSex"
                    style="width: 100%; height: 100px"
                  />
                  <div>性别占比</div></el-col
                ><el-col :span="8">
                  <dv-active-ring-chart
                    v-if="configAge.data.length > 0"
                    :config="configAge"
                    style="width: 100%; height: 100px"
                  />
                  <div>年龄占比</div></el-col
                ><el-col :span="8">
                  <dv-active-ring-chart
                    v-if="configDd.data.length > 0"
                    :config="configDd"
                    style="width: 100%; height: 100px"
                  />
                  <div>捐献分类占比</div></el-col
                ></el-row
              >
              <el-row
                ><el-col :span="12">
                  <dv-active-ring-chart
                    v-if="configD.data.length > 0"
                    :config="configD"
                    style="width: 100%; height: 100px"
                  />
                  <div>疾病占比</div></el-col
                ><el-col :span="12">
                  <dv-active-ring-chart
                    v-if="configX.data.length > 0"
                    :config="configX"
                    style="width: 100%; height: 100px"
                  />
                  è¡€åž‹å æ¯”</el-col
                ></el-row
              >
            </div>
            <div v-if="0" style="padding: 30px 10px 20px; min-height: 280px">
              <el-row style="margin-bottom: 10px">
                <el-col :span="7" style="text-align: right">男女占比</el-col>
                <el-col :span="17">
                  <div style="display: flex; text-align: center">
                    <div style="flex: 1">
                      <span class="fc-white">男</span>&nbsp;<span
                        class="fc-sp"
                        >{{ (objZb.manRate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">女</span>&nbsp;<span
                        class="fc-sp"
                        >{{ (objZb.womanRate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                  </div>
                </el-col>
              </el-row>
              <el-row style="margin-bottom: 10px">
                <el-col :span="7" style="text-align: right"
                  >捐献分类占比</el-col
                >
                <el-col :span="17">
                  <div style="display: flex; text-align: center">
                    <div style="flex: 1">
                      <span class="fc-white">DBD</span>&nbsp;<span
                        class="fc-sp"
                        >{{ (objZb.dbdrate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">DCD</span>&nbsp;<span
                        class="fc-sp"
                        >{{ (objZb.dcdrate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">DBCD</span>&nbsp;<span
                        class="fc-sp"
                        >{{ (objZb.dbcdrate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                  </div>
                </el-col>
              </el-row>
              <el-row style="margin-bottom: 10px">
                <el-col :span="7" style="text-align: right">年龄占比</el-col>
                <el-col :span="17">
                  <div style="display: flex; text-align: center">
                    <div style="flex: 1">
                      <span class="fc-white">1-17岁</span>&nbsp;<span
                        class="fc-sp"
                        >{{ (objZb.a1Rate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">18-49岁</span>&nbsp;<span
                        class="fc-sp"
                        >{{ (objZb.a2Rate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">49-69岁</span>&nbsp;<span
                        class="fc-sp"
                        >{{ (objZb.a3Rate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                  </div>
                </el-col>
              </el-row>
              <el-row style="margin-bottom: 10px">
                <el-col
                  :span="24"
                  style="margin-bottom: 10px; text-align: center"
                  >血型占比</el-col
                >
                <el-col :span="24">
                  <div style="display: flex; text-align: center">
                    <div style="flex: 1">
                      <span class="fc-white">A型</span><br /><span
                        class="fc-sp"
                        >{{ (objZb.xarate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">B型</span><br /><span
                        class="fc-sp"
                        >{{ (objZb.xbrate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">AB型</span><br /><span
                        class="fc-sp"
                        >{{ (objZb.xabrate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">O型</span><br /><span
                        class="fc-sp"
                        >{{ (objZb.xorate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                  </div>
                </el-col>
              </el-row>
              <el-row>
                <el-col
                  :span="24"
                  style="margin-bottom: 10px; text-align: center"
                  >病因占比</el-col
                >
                <el-col :span="24">
                  <div style="display: flex; text-align: center">
                    <div style="flex: 1">
                      <span class="fc-white">脑血管意外</span><br /><span
                        class="fc-sp"
                        >{{ (objZb.d0Rate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">脑外伤</span><br /><span
                        class="fc-sp"
                        >{{ (objZb.d1Rate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">缺血缺氧性脑病</span><br /><span
                        class="fc-sp"
                        >{{ (objZb.d2Rate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">脑肿瘤</span><br /><span
                        class="fc-sp"
                        >{{ (objZb.d3Rate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                    <div style="flex: 1">
                      <span class="fc-white">心血管疾病</span><br /><span
                        class="fc-sp"
                        >{{ (objZb.d4Rate * 100).toFixed(2) + "%" }}</span
                      >
                    </div>
                  </div>
                </el-col>
              </el-row>
            </div>
          </dv-border-box-6>
          <dv-border-box-6 :color="['#1b88a3']" style="margin-top: 30px">
            <div class="box-title" style="position: absolute; top: -8px">
              <span><b>机构统计</b></span>
            </div>
            <div style="padding: 20px">
              <el-row class="c-table-title">
                <el-col :span="18" :class="isAll ? 'active' : ''">
                  <el-divider content-position="left"
                    ><span>浙江省</span></el-divider
                  ></el-col
                >
                <el-col :span="6"><el-divider></el-divider></el-col>
              </el-row>
              <dv-scroll-board
                :config="tableConfig"
                style="width: 100%; border: 1px solid #142984"
                class="iwc-h-rb-table"
                :style="{ height: height - 310 + 'px' }"
              />
            </div>
          </dv-border-box-6>
        </el-col>
      </el-row> -->
      <el-dialog title="登陆" :visible.sync="dialogVisible" width="30%">
        <el-form :model="form">
          <el-form-item label="账号" label-width="80px">
            <el-input
              v-model="defaultAccount"
              autocomplete="off"
              @keyup.enter.native="loginFn"
            ></el-input>
          </el-form-item>
          <el-form-item
            label="密码"
            label-width="80px"
    <!-- ç™»å½•弹窗 -->
    <el-dialog
      title="登录"
      :visible.sync="dialogVisible"
      width="380px"
      :close-on-click-modal="false"
      :show-close="false"
      append-to-body
      custom-class="login-dialog"
    >
      <el-form :model="form" @submit.native.prevent>
        <el-form-item label="账号" label-width="60px">
          <el-input
            v-model="defaultAccount"
            autocomplete="off"
            placeholder="请输入账号"
            @keyup.enter.native="loginFn"
          >
            <el-input
              v-model="defaultPassword"
              show-password
              autocomplete="off"
            ></el-input>
          </el-form-item>
          <el-form-item prop="code" label-width="80px">
            <el-input
              v-model="code"
              auto-complete="off"
              placeholder="验证码"
              style="width: 63%"
              @keyup.enter.native="loginFn"
            >
              <svg-icon
                slot="prefix"
                icon-class="validCode"
                class="el-input__icon input-icon"
              />
            </el-input>
            <div class="login-code">
              <img :src="codeUrl" @click="getCode" class="login-code-img" />
            </div>
          </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
          <el-button type="primary" @click="loginFn">ç¡® å®š</el-button>
        </span>
      </el-dialog>
    </div>
          ></el-input>
        </el-form-item>
        <el-form-item label="密码" label-width="60px">
          <el-input
            v-model="defaultPassword"
            show-password
            autocomplete="off"
            placeholder="请输入密码"
            @keyup.enter.native="loginFn"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" :loading="loginLoading" @click="loginFn"
          >登 å½•</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  getNumberOfOrgan,
  getOrgansOfHospital,
  getAllOrganInfo,
  countDonateorgan,
  countDonateHostipal,
  countorganHostipal,
  getDonateNumber,
  getdonateBaseInfoByMonth,
  getdonatePeopleByMonth,
  getdonateNumberByMonth,
  getdonateHospitalByMonth,
  getacceptHospitalByMonths,
  getOrgansOfHospitalByMonth,
  getDonateorganPMP,
  getDonateorganQuality,
  getDonationwitnessStats,
  getTransplantHospitalNum,
  getDonateorganSum,
  getDonateorganDistrictDonateCalculate
} from "@/api/project/donateorgan";
import { listData } from "@/api/system/dict/data";
import { login, logout, getInfo, getCodeImg } from "@/api/login";
import { listDonatebaseinfo } from "@/api/project/donatebaseinfo";
import { getToken, setToken, removeToken } from "@/utils/auth";
import MapChart from "./components/MapChart";
import BarChart from "./components/BarChart";
import BarChart2 from "./components/BarChart2";
import BarChart3 from "./components/BarChart3";
import BarChartH from "./components/BarChartH";
import LineChart from "./components/lineChart";
import Line1Chart from "./components/line1Chart";
import Line2Chart from "./components/line2Chart";
const DEF_TABLE_CONFIG = {
  header: ["区域", "机构", "捐献登记", "捐献完成"],
  data: [],
  headerBGC: "#0a3073",
  oddRowBGC: "",
  evenRowBGC: "",
  rowNum: 6
<script>
import CountTo from 'vue-count-to';
import G2PlotChart from '@/components/charts/G2PlotChart.vue';
import MapChart from './components/MapChart';
import { login } from '@/api/login';
import { encrypts } from '@/utils/crypto';
import { setToken, removeToken } from '@/utils/auth';
import { xAxis, yAxis, legend, tooltip } from '@/utils/g2Dark';
import { toMonth, toNum } from '@/utils/totals';
import { mockCockpitData } from './cockpitMock';
const AGE_LABELS = {
  '1': '≤17岁',
  '2': '18-49岁',
  '3': '50-69岁',
  '4': '≥70岁',
  '0-17': '≤17岁',
  '18-49': '18-49岁',
  '50-69': '50-69岁',
  '70-100': '≥70岁'
};
export default {
  name: "home",
  props: {},
  components: {
    MapChart,
    BarChart,
    BarChart2,
    BarChart3,
    BarChartH,
    LineChart,
    Line1Chart,
    Line2Chart
  },
  name: 'home',
  components: { CountTo, G2PlotChart, MapChart },
  data() {
    return {
      img: {
        head: require("../../assets/images/dv-head.png"),
        btn1: require("../../assets/images/dv-btn-1.png"),
        btn2: require("../../assets/images/dv-btn-2.png"),
        btn3: require("../../assets/images/dv-btn-3.png"),
        btn4: require("../../assets/images/dv-btn-4.png")
      },
      leijishuju: {},
      arrrrr: [],
      captchaOnOff: true,
      uuid: "",
      form: {},
      hospitallist: [],
      year: "",
      code: "",
      codeUrl: "",
      now: '',
      clockTimer: null,
      carouselTimer: null,
      loading: false,
      loginLoading: false,
      dialogVisible: true,
      isloading: false,
      tableLoading: false,
      showTable: false,
      currentArea: null,
      tableList: [],
      defaultAccount: "",
      defaultPassword: "",
      pageData: {
        pageNum: 1,
        pageSize: 10
      },
      total: 0,
      height: 1080,
      width: 1920,
      isAll: true,
      chartType: "map",
      tableConfig: { ...DEF_TABLE_CONFIG },
      totalCount: 0,
      allInfo: {
        finishedOrgans: 0,
        processOrgans: 4,
        Organsnum: 0
      },
      anlidata: [
        {
          name: "1月",
          value: 0
        },
        {
          name: "2月",
          value: 0
        },
        {
          name: "3月",
          value: 0
        },
        {
          name: "4月",
          value: 0
        },
        {
          name: "5月",
          value: 0
        },
        {
          name: "6月",
          value: 0
        },
        {
          name: "7月",
          value: 0
        },
        {
          name: "8月",
          value: 0
        },
        {
          name: "9月",
          value: 0
        },
        {
          name: "10月",
          value: 0
        },
        {
          name: "11月",
          value: 0
        },
        {
          name: "12月",
          value: 0
        }
      ],
      organsum: [
        {
          name: "一月",
          value: 0
        },
        {
          name: "二月",
          value: 0
        },
        {
          name: "三月",
          value: 0
        },
        {
          name: "四月",
          value: 0
        },
        {
          name: "五月",
          value: 0
        },
        {
          name: "六月",
          value: 0
        },
        {
          name: "七月",
          value: 0
        },
        {
          name: "八月",
          value: 0
        },
        {
          name: "九月",
          value: 0
        },
        {
          name: "十月",
          value: 0
        },
        {
          name: "十一月",
          value: 0
        },
        {
          name: "十二月",
          value: 0
        }
      ],
      yiyuan: [
        {
          name: "一月",
          value: 0
        },
        {
          name: "二月",
          value: 0
        },
        {
          name: "三月",
          value: 0
        },
        {
          name: "四月",
          value: 0
        },
        {
          name: "五月",
          value: 0
        },
        {
          name: "六月",
          value: 0
        },
        {
          name: "七月",
          value: 0
        },
        {
          name: "八月",
          value: 0
        },
        {
          name: "九月",
          value: 0
        },
        {
          name: "十月",
          value: 0
        },
        {
          name: "十一月",
          value: 0
        },
        {
          name: "十二月",
          value: 0
        }
      ],
      organData: [
        {
          key: "heart",
          name: "心脏",
          value: 0
        },
        {
          key: "fullLiver",
          name: "肝脏",
          value: 0
        },
        {
          key: "leftRenal",
          name: "左肾",
          value: 0
        },
        {
          key: "rightRenal",
          name: "右肾",
          value: 0
        },
        {
          key: "fullLung",
          name: "全肺",
          value: 0
        },
        {
          key: "leftLung",
          name: "左肺",
          value: 0
        },
        {
          key: "rightLung",
          name: "右肺",
          value: 0
        },
        {
          key: "leftEye",
          name: "左眼膜",
          value: 0
        },
        {
          key: "rightEye",
          name: "右眼膜",
          value: 0
        }
        //  é—体换成全肝了
      ],
      hosGetData: [],
      configHosOrgan: {
        data: [],
        oddRowBGC: "",
        evenRowBGC: "",
        rowNum: 6
      },
      organSumData: [],
      cdata: [
        {
          // åå­—需要与 â€œcommon/map/zhejiang.js” åœ°å›¾æ•°æ®æ–‡ä»¶é‡Œé¢å®šä¹‰çš„一一对应,不能是 â€œç¦å·žâ€ æˆ–者 â€œé—½â€ ä¹‹ç±»çš„缩写
          name: "杭州市",
          district: "1",
          value: 0,
          elseData: {
            value2: 0,
            value3: 0
          }
        },
        {
          district: "2",
          name: "宁波市",
          value: 0,
          elseData: {
            value2: 0,
            value3: 0
          }
        },
        {
          district: "3",
          name: "温州市",
          value: 0,
          elseData: {
            value2: 0,
            value3: 0
          }
        },
        {
          name: "嘉兴市",
          district: "4",
          value: 0,
          elseData: {
            value2: 0,
            value3: 0
          }
        },
        {
          name: "湖州市",
          district: "5",
          value: 0,
          elseData: {
            value2: 0,
            value3: 0
          }
        },
        {
          name: "绍兴市",
          district: "6",
          value: 0,
          elseData: {
            value2: 0,
            value3: 0
          }
        },
        {
          name: "金华市",
          district: "7",
          value: 0,
          elseData: {
            value2: 0,
            value3: 0
          }
        },
        {
          name: "衢州市",
          district: "8",
          value: 0,
          elseData: {
            value2: 0,
            value3: 0
          }
        },
        {
          name: "舟山市",
          district: "9",
          value: 0,
          elseData: {
            value2: 0,
            value3: 0
          }
        },
        {
          name: "台州市",
          district: "A",
          value: 0,
          elseData: {
            value2: 0,
            value3: 0
          }
        },
        {
          name: "丽水市",
          district: "B",
          value: 0,
          elseData: {
            value2: 0,
            value3: 0
          }
        }
      ],
      hospitalarr: [],
      objZb: {}, //占比
      arrZb: {},
      currentZb: {
        sex: -1,
        age: -1,
        type: -1,
        d: -1,
        x: -1
      },
      loopShowZb: null,
      cdataYear: [],
      organYearData: [],
      configSex: {
        data: [],
        lineWidth: 6,
        digitalFlopStyle: {
          fontSize: 14
        }
      },
      configAge: {
        data: [],
        lineWidth: 6,
        digitalFlopStyle: {
          fontSize: 14
        }
      },
      configDd: {
        data: [],
        lineWidth: 6,
        digitalFlopStyle: {
          fontSize: 14
        }
      },
      configD: {
        data: [],
        lineWidth: 6,
        digitalFlopStyle: {
          fontSize: 14
        }
      },
      configX: {
        data: [],
        lineWidth: 6,
        digitalFlopStyle: {
          fontSize: 14
        }
      },
      cityDonoateCaseArr: []
      defaultAccount: '',
      defaultPassword: '',
      form: {},
      carouselIndex: 0,
      raw: {
        mapData: [],
        gauges: [],
        caseTrend: [],
        organMoon: [],
        caseBloodType: [],
        caseSex: [],
        organType: [],
        organDiscard: [],
        caseTrendArea: [],
        totals: [],
        caseAvgAge: []
      }
    };
  },
  computed: {
    kpiCards() {
      const t = this.raw.totals[0] || {};
      const potential = toNum(t.totalPotential);
      const completed = toNum(t.totalCompletion);
      const age = toNum((this.raw.caseAvgAge[0] || {}).avgAge);
      const getTotal = this.raw.organMoon.reduce(
        (s, i) => s + toNum(i.getCount),
        0
      );
      const useTotal = this.raw.organMoon.reduce(
        (s, i) => s + toNum(i.useCount),
        0
      );
      return [
        {
          label: '总潜在捐献案例',
          value: potential,
          unit: '例',
          icon: 'el-icon-s-flag',
          gradient: 'linear-gradient(135deg,#1d4ed8,#38bdf8)'
        },
        {
          label: '总完成捐献',
          value: completed,
          unit: '例',
          icon: 'el-icon-circle-check',
          gradient: 'linear-gradient(135deg,#059669,#34d399)'
        },
        {
          label: '平均年龄',
          value: age,
          unit: '岁',
          icon: 'el-icon-user',
          decimals: 1,
          gradient: 'linear-gradient(135deg,#7c3aed,#a78bfa)'
        },
        {
          label: '器官获取总数',
          value: getTotal,
          unit: '个',
          icon: 'el-icon-box',
          gradient: 'linear-gradient(135deg,#0e7490,#22d3ee)'
        },
        {
          label: '器官移植总数',
          value: useTotal,
          unit: '个',
          icon: 'el-icon-s-help',
          gradient: 'linear-gradient(135deg,#d97706,#fbbf24)'
        }
      ];
    },
    gaugeCharts() {
      return this.raw.gauges.map(g => ({ name: g.name, options: this.buildGauge(g) }));
    },
    trendOptions() {
      const data = [];
      this.raw.caseTrend.forEach(d => {
        data.push({
          time: this.fmtMonth(d.donateTime),
          type: '潜在捐献',
          value: toNum(d.potentialCount)
        });
        data.push({
          time: this.fmtMonth(d.donateTime),
          type: '完成捐献',
          value: toNum(d.completeCount)
        });
      });
      return {
        data,
        xField: 'time',
        yField: 'value',
        seriesField: 'type',
        smooth: true,
        color: ['#38a5f8', '#34d399'],
        legend: legend(),
        xAxis: xAxis(),
        yAxis: yAxis(),
        tooltip: tooltip(),
        line: { size: 3 },
        areaStyle: { fillOpacity: 0.16 }
      };
    },
    organMoonOptions() {
      const data = [];
      this.raw.organMoon.forEach(d => {
        data.push({
          time: this.fmtMonth(d.donateTime),
          type: '获取',
          value: toNum(d.getCount)
        });
        data.push({
          time: this.fmtMonth(d.donateTime),
          type: '移植',
          value: toNum(d.useCount)
        });
      });
      return {
        data,
        xField: 'time',
        yField: 'value',
        seriesField: 'type',
        smooth: true,
        color: ['#22d3ee', '#fbbf24'],
        lineStyle: { lineWidth: 3 },
        point: { size: 4, shape: 'circle' },
        legend: legend(),
        xAxis: xAxis(),
        yAxis: yAxis(),
        tooltip: tooltip()
      };
    },
    // ç”·å¥³æ¯”例(按年龄段汇总为总体男女)
    sexRatioOptions() {
      let man = 0;
      let woman = 0;
      this.raw.caseSex.forEach(d => {
        man += toNum(d.manCount);
        woman += toNum(d.womanCount);
      });
      const data = [
        { type: '男', value: man },
        { type: '女', value: woman }
      ];
      return {
        data,
        angleField: 'value',
        colorField: 'type',
        radius: 0.85,
        innerRadius: 0.62,
        color: ['#38a5f8', '#fb7185'],
        label: {
          type: 'spider',
          content: '{percentage}',
          style: { fill: '#c3cde4' }
        },
        legend: legend({ position: 'bottom' }),
        tooltip: tooltip({ showTitle: false })
      };
    },
    // å¹´é¾„与性别分布
    ageSexOptions() {
      const data = [];
      this.raw.caseSex.forEach(d => {
        const g = AGE_LABELS[d.ageGroup] || d.ageGroup;
        data.push({ age: g, type: '男', value: toNum(d.manCount) });
        data.push({ age: g, type: '女', value: toNum(d.womanCount) });
      });
      return {
        data,
        xField: 'age',
        yField: 'value',
        seriesField: 'type',
        isGroup: true,
        columnWidthRatio: 0.4,
        color: ['#38a5f8', '#fb7185'],
        legend: legend(),
        xAxis: xAxis(),
        yAxis: yAxis(),
        tooltip: tooltip()
      };
    },
    organTypeOptions() {
      const data = [];
      this.raw.organType.forEach(d => {
        data.push({ organ: d.organName, type: '获取', value: toNum(d.getCount) });
        data.push({ organ: d.organName, type: '移植', value: toNum(d.useCount) });
      });
      return {
        data,
        xField: 'value',
        yField: 'organ',
        seriesField: 'type',
        isGroup: true,
        barWidthRatio: 0.6,
        color: ['#22d3ee', '#fbbf24'],
        legend: legend(),
        xAxis: yAxis(),
        yAxis: xAxis(),
        tooltip: tooltip()
      };
    },
    // å™¨å®˜å¼ƒç”¨æƒ…况
    discardOptions() {
      const data = this.raw.organDiscard.map(d => ({
        organ: d.organName,
        value: toNum(d.discardCount)
      }));
      return {
        data,
        xField: 'organ',
        yField: 'value',
        columnWidthRatio: 0.5,
        color: '#fb7185',
        legend: false,
        xAxis: xAxis({ label: { autoRotate: true } }),
        yAxis: yAxis(),
        tooltip: tooltip()
      };
    },
    areaOptions() {
      const data = [];
      this.raw.caseTrendArea.forEach(d => {
        const name = String(d.area || '').replace('地区', '');
        data.push({
          area: name,
          type: '潜在捐献',
          value: toNum(d.potentialCount)
        });
        data.push({
          area: name,
          type: '完成捐献',
          value: toNum(d.completeCount)
        });
      });
      return {
        data,
        xField: 'area',
        yField: 'value',
        seriesField: 'type',
        isGroup: true,
        columnWidthRatio: 0.45,
        color: ['#38a5f8', '#34d399'],
        legend: legend(),
        xAxis: xAxis({ label: { autoRotate: true } }),
        yAxis: yAxis(),
        tooltip: tooltip()
      };
    },
    carouselItems() {
      return [
        { title: '男女比例', type: 'ring', options: this.sexRatioOptions },
        { title: '器官类型分布', type: 'bar', options: this.organTypeOptions },
        { title: '器官弃用情况', type: 'column', options: this.discardOptions },
        { title: '年龄与性别分布', type: 'column', options: this.ageSexOptions }
      ];
    },
    currentCarousel() {
      return this.carouselItems[this.carouselIndex] || this.carouselItems[0];
    }
  },
  created() {
    this.height = window.innerHeight - 72;
    this.getCode();
    //this.getinfos();
    //this.getOrgansOfHospitalByMonthss();
    this.startClock();
  },
  mounted() {
    removeToken();
    // let defaultAccount = "cockpit";
    // let defaultPassword = "Admin@123";
  },
  beforeDestroy() {
    if (this.clockTimer) clearInterval(this.clockTimer);
    if (this.carouselTimer) clearInterval(this.carouselTimer);
  },
  methods: {
    getCode() {
      getCodeImg().then(res => {
        this.captchaOnOff =
          res.captchaOnOff === undefined ? true : res.captchaOnOff;
        if (this.captchaOnOff) {
          this.codeUrl = "data:image/gif;base64," + res.img;
          this.uuid = res.uuid;
    fmtMonth(value) {
      const m = toMonth(value);
      if (!m) return '';
      const mm = Number(m.split('-')[1]);
      return mm ? `${mm}月` : m;
    },
    buildGauge(g) {
      const pct = g.max ? Math.min(Math.max(g.value / g.max, 0), 1) : 0;
      const suffix = g.max === 100 ? '%' : '';
      return {
        percent: pct,
        startAngle: Math.PI,
        endAngle: Math.PI * 2,
        radius: 0.85,
        innerRadius: 0.72,
        range: { color: [g.color, '#1c2a4d'], width: 10 },
        axis: {
          label: null,
          tickLine: { style: { stroke: '#2a3a63' } }
        },
        indicator: {
          pointer: { style: { stroke: '#e6edff', lineWidth: 2 } },
          pin: { style: { stroke: '#e6edff', lineWidth: 2, r: 4 } }
        },
        statistic: {
          content: {
            content: `${g.value}${suffix}`,
            style: {
              color: '#ffffff',
              fontSize: 30,
              fontWeight: 700,
              lineHeight: 1,
              opacity: 1
            }
          }
        }
      });
      };
    },
    startClock() {
      const tick = () => {
        this.now = this.$moment().format('YYYY-MM-DD HH:mm:ss');
      };
      tick();
      this.clockTimer = setInterval(tick, 1000);
    },
    startCarousel() {
      if (this.carouselTimer) clearInterval(this.carouselTimer);
      this.carouselTimer = setInterval(() => {
        this.carouselIndex =
          (this.carouselIndex + 1) % this.carouselItems.length;
      }, 5000);
    },
    loginFn() {
      login(this.defaultAccount, this.defaultPassword, this.code, this.uuid)
        .then(async res => {
          if (res.code == 200) {
      if (!this.defaultAccount || !this.defaultPassword) {
        this.$message.warning('请输入账号和密码');
        return;
      }
      this.loginLoading = true;
      login(encrypts(this.defaultAccount), encrypts(this.defaultPassword))
        .then(res => {
          if (res.code === 200) {
            setToken(res.token);
            this.dialogVisible = false;
            this.$message.success("登陆成功");
            const loading = this.$loading({
              lock: true,
              text: "Loading",
              spinner: "el-icon-loading",
              background: "rgba(0, 0, 0, 0.7)"
            });
            setTimeout(() => {
              loading.close();
            }, 2000);
            await this.getDictData();
            this.getinfos();
            this.getData();
            // this.getList();
            this.getAllInfo();
            this.getdonatecount();
            this.getorgancount();
            this.getDonateNumbers();
            this.get();
            this.getcountDonateHostipal();
            //按月度统计的器官数  æŠ˜çº¿å›¾
            //this.getcurrentmonthorgan();
            // this.getcurrentPeopleBymonth();
            this.getOrgansOfHospitalByMonths();
            //this.getOrgansOfHospitalByMonthss();
            //resolve()
            this.$message.success('登录成功');
            this.loadData();
          } else {
            this.$message.error(res.msg);
            this.$message.error(res.msg || '登录失败');
          }
        })
        .catch(error => {
          // this.$message.error(error);
          console.log(error);
        });
    },
    getOrgansOfHospitalByMonthss() {
      var date = new Date();
      var year = date.getFullYear();
      var month = date.getMonth();
      month = Number(month) + 1;
      if (month < 10) {
        month = "0" + month;
      }
      var data = date.getDate();
      if (data < 10) {
        data = "0" + data;
      }
      var hours = date.getHours();
      var minute = date.getMinutes();
      var second = date.getSeconds();
      var time =
        year +
        "-" +
        month +
        "-" +
        data +
        " " +
        hours +
        ":" +
        minute +
        ":" +
        second;
      let params = {
        starttime: "1998-01-01 00:00:00",
        endtime: time
      };
      getOrgansOfHospitalByMonth(params).then(res => {
        let hospitalarr = res.data;
        // this.hospitalarr = hospitalarr
        let shi = [
          { name: "省本级", value: "0" },
          { name: "杭州市", value: "1" },
          { name: "宁波市", value: "2" },
          { name: "温州市", value: "3" },
          { name: "嘉兴市", value: "4" },
          { name: "湖州市", value: "5" },
          { name: "绍兴市", value: "6" },
          { name: "金华市", value: "7" },
          { name: "衢州市", value: "8" },
          { name: "舟山市", value: "9" },
          { name: "台州市", value: "A" },
          { name: "丽水市", value: "B" }
        ];
        for (let i = 0; i < hospitalarr.length; i++) {
          for (let j = 0; j < shi.length; j++) {
            if (hospitalarr[i].regionLevel == shi[j].value) {
              hospitalarr[i].regionLevel = shi[j].name;
            }
          }
        }
      });
    },
    getOrgansOfHospitalByMonths() {
      let curYear = this.$moment().year();
      let params = {
        starttime: this.$moment().format(curYear + "-01-01 00:00:00"),
        endtime: this.$moment().format("YYYY-MM-DD 00:00:00")
      };
      getOrgansOfHospitalByMonth(params).then(res => {
        let arr = [];
        arr = res.data;
        let shi = [
          { name: "省本级", value: "0" },
          { name: "杭州市", value: "1" },
          { name: "宁波市", value: "2" },
          { name: "温州市", value: "3" },
          { name: "嘉兴市", value: "4" },
          { name: "湖州市", value: "5" },
          { name: "绍兴市", value: "6" },
          { name: "金华市", value: "7" },
          { name: "衢州市", value: "8" },
          { name: "舟山市", value: "9" },
          { name: "台州市", value: "A" },
          { name: "丽水市", value: "B" }
        ];
        let newConfig = {
          ...DEF_TABLE_CONFIG
        };
        let arrr = [];
        for (let i = 0; i < arr.length; i++) {
          for (let j = 0; j < shi.length; j++) {
            if (arr[i].regionLevel == shi[j].value) {
              arr[i].regionLevel = shi[j].name;
            }
          }
          arrr.push({
            regionLevel: arr[i].regionLevel,
            hospitalName: arr[i].hospitalName,
            donateNumber: arr[i].baseInfoCount,
            acceptNumber: arr[i].completionCount
          });
        }
        this.arrrrr = arrr;
        newConfig.data = arrr;
        this.tableConfig = newConfig;
      });
    },
    refresh() {
      if (this.showTable) {
        this.getList();
      } else {
        this.getData();
      }
    },
    //柱状图数据
    getinfos() {},
    //当前年份按月度统计的捐献器官数
    getcurrentmonthorgan() {
      let nowYear = this.$moment().year();
      let params = {
        starttime: this.$moment(nowYear + "-01-01").format(
          "YYYY-01-01 00:00:00"
        ),
        endtime: this.$moment().format("YYYY-MM-DD 00:00:00")
      };
      getdonateNumberByMonth(params).then(res => {
        let donateorgans = res.data;
        let arr1 = [];
        let num = 0;
        for (let i = 0; i < donateorgans.length; i++) {
          num = donateorgans[i].donatemonth.substring(0, 4);
          // if (this.year == num) {
          arr1.push(donateorgans[i]);
          for (let i = 0; i < arr1.length; i++) {
            let month = arr1[i].donatemonth;
            month = month.substring(month.length - 2, month.length);
            let donatecount = arr1[i].donatecount;
            this.organsum[month - 1].value = donatecount;
          }
          // }
        }
      });
    },
    getcountDonateHostipal() {
      let nowYear = this.$moment().year();
      let a = {
        // starttime: "2020-01-01 00:00:00",
        // endtime: "2022-02-01 00:00:00", //????
        starttime: this.$moment(nowYear + "-01-01").format(
          "YYYY-01-01 00:00:00"
        ),
        endtime: this.$moment().format("YYYY-MM-DD 00:00:00")
      };
      countDonateHostipal(a).then(res => {
        let donateorgans = res.data;
        let arr3 = [];
        let num = 0;
        for (let i = 0; i < donateorgans.length; i++) {
          num = donateorgans[i].donatemonth.substring(0, 4);
          arr3.push(donateorgans[i]);
          for (let i = 0; i < arr3.length; i++) {
            let month = arr3[i].donatemonth;
            month = month.substring(month.length - 2, month.length);
            let donatecount = arr3[i].donatecount;
            this.yiyuan[month - 1].value = donatecount;
          }
        }
      });
    },
    get() {},
    //捐献累计信息
    getDonateNumbers() {
      let paramStartTime = null;
      let nowDateYear = this.$moment().year();
      paramStartTime = this.$moment(nowDateYear + "-01-01").format(
        "YYYY-MM-DD HH:mm:ss"
      );
      let a = {
        starttime: paramStartTime,
        endtime: this.$moment().format("YYYY-MM-DD HH:mm:ss")
      };
      getDonateorganDistrictDonateCalculate(a).then(res => {
        let cityCaseArr = [];
        let data = res.data;
        for (let i = 0; i < data.length; i++) {
          let ii = this.cdata.findIndex(
            item => item.district == data[i].district
          );
          if (ii > -1) {
            this.cdata[ii].value = data[i].donateCount;
            this.cdata[ii].elseData.value2 = data[i].completeCount;
            this.cdata[ii].elseData.value3 = data[i].totalOrganCount;
            cityCaseArr.push({
              cityName: this.cdata[ii].name,
              donoateNum: data[i].donateCount
            });
          }
        }
        this.cityDonoateCaseArr = cityCaseArr;
      });
      getDonateNumber(a).then(res => {
        console.log("捐献累计信息", res);
        this.leijishuju.processOrgans = res.data.numberOfDonate;
        this.leijishuju.finishedOrgans = res.data.numberOfCompletion;
        this.leijishuju.Organsnum = res.data.numberOfOrgans;
      });
      getDonateorganPMP(a).then(res => {
        console.log("PMP", res);
        let data = res.data;
        this.leijishuju.PMP = ((data.pmprate * 100) / 64).toFixed(2);
      });
      getDonateorganQuality(a).then(res => {
        let data = res.data;
        this.leijishuju.donateTransferRate = data.donateTransferRate;
        this.leijishuju.organProductionRate = data.organProductionRate;
        this.leijishuju.organUsedRate = data.organUsedRate;
        this.$forceUpdate();
      });
      getDonationwitnessStats(a).then(res => {
        console.log("各种占比", res);
        let data = res.data;
        this.objZb = { ...data };
        this.arrZb = {
          sex: [
            { label: "男", value: data.manRate },
            { label: "女", value: data.womanRate }
          ],
          age: [
            { label: "1-17岁", value: data.a1Rate },
            { label: "18-48岁", value: data.a2Rate },
            { label: "49-69岁", value: data.a2Rate }
          ],
          type: [
            { label: "DBD", value: data.dbdrate },
            { label: "DCD", value: data.dcdrate },
            { label: "DBCD", value: data.dbcdrate }
          ],
          d: [
            { label: "脑血管意外", value: data.d0Rate },
            { label: "脑外伤", value: data.d1Rate },
            { label: "缺血缺氧性脑病", value: data.d2Rate },
            { label: "脑肿瘤", value: data.d3Rate },
            { label: "心血管疾病", value: data.d4Rate }
          ],
          x: [
            { label: "A型", value: data.xarate },
            { label: "B型", value: data.xbrate },
            { label: "AB型", value: data.xabrate },
            { label: "O型", value: data.xorate }
          ]
        };
        window.clearInterval(this.loopShowZb);
        this.loopShowZb = setInterval(() => {
          if (this.currentZb.sex < this.arrZb.sex.length - 1) {
            this.currentZb.sex += 1;
          } else {
            this.currentZb.sex = 0;
          }
          if (this.currentZb.age < this.arrZb.age.length - 1) {
            this.currentZb.age += 1;
          } else {
            this.currentZb.age = 0;
          }
          if (this.currentZb.type < this.arrZb.type.length - 1) {
            this.currentZb.type += 1;
          } else {
            this.currentZb.type = 0;
          }
          if (this.currentZb.d < this.arrZb.d.length - 1) {
            this.currentZb.d += 1;
          } else {
            this.currentZb.d = 0;
          }
          if (this.currentZb.x < this.arrZb.x.length - 1) {
            this.currentZb.x += 1;
          } else {
            this.currentZb.x = 0;
          }
        }, 3000);
      });
      getTransplantHospitalNum(a).then(res => {
        console.log("每家移植医院获取的器官总数", res);
        let data = res.data;
        let list = data.map(item => {
          return [item.orgName, item.organCount];
        });
        list = list.filter(item => !item[0].includes("眼"));
        this.configHosOrgan.data = list;
        this.hosGetData = data.map(item => {
          return {
            name: item.orgName,
            value: item.organCount
          };
        });
      });
      getDonateorganSum(a).then(res => {
        console.log("各种器官的获取总数", res);
        let data = res.data;
        let list = this.organSumData.map(item => item);
        for (let i = 0; i < data.length; i++) {
          let k = data[i].organNo;
          let ii = this.organSumData.findIndex(item => item.key == k);
          if (ii > -1) {
            this.organSumData[ii].value = data[i].count;
          }
        }
      });
      //历年数据
      let startTime = "2019-01-01 00:00:00";
      let endTime = this.$moment().format("YYYY-01-01 00:00:00");
      endTime = this.$moment(endTime)
        .add(1, "years")
        .format("YYYY-01-01 00:00:00");
      let dYear = this.$moment(endTime).diff(this.$moment(startTime), "years");
      if (dYear > 5) {
        startTime ==
          this.$moment(endtime)
            .add(-5, "year")
            .format("YYYY-01-01 00:00:00");
      }
      let arrYear = [];
      for (let i = 0; i < 6; i++) {
        let year = this.$moment(startTime)
          .add(i, "year")
          .format("YYYY");
        if (i >= dYear) {
          year = "";
          continue;
        }
        arrYear.push({
          year: year,
          num: year ? 0 : ""
        });
      }
      let params = {
        starttime: startTime,
        endtime: endTime
      };
      // getdonateNumberByMonth ???//带注释
      getdonatePeopleByMonth(params).then(res => {
        let data = res.data;
        for (let i = 0; i < data.length; i++) {
          let year = this.$moment(data[i].donatemonth).format("YYYY");
          let ii = arrYear.findIndex(item => item.year == year);
          if (ii > -1) {
            arrYear[ii].num += data[i].donatecount;
          }
        }
        this.cdataYear = arrYear;
        console.log("cdataYear:" + JSON.stringify(this.cdataYear));
      });
    },
    async getDictData() {
      try {
        let res = await listData({
          pageNum: 1,
          pageSize: 20,
          dictType: "sys_Organ"
        });
        let list = res.rows.map(item => {
          return {
            key: item.dictValue,
            name: item.dictLabel,
            value: 0
          };
        });
        this.organSumData = list.filter(it => it.key != "C00");
      } catch (e) {}
    },
    async getdonatecount() {
      let nowDateYear = this.$moment().year();
      let nowDateMonth = this.$moment().month() + 1;
      let startTime;
      let endTime = this.$moment()
        .add(1, "month")
        .format("YYYY-MM-01");
      if (nowDateMonth <= 5) {
        startTime = this.$moment()
          .add(-6, "month")
          .format("YYYY-MM-01");
      } else {
        startTime = this.$moment().format(nowDateYear + "-01-01");
      }
      let donateorgans = [];
      let organList = [];
      let params = {
        starttime: startTime,
        endtime: endTime
      };
      try {
        let res = await countDonateorgan(params);
        donateorgans = res.data;
        console.log("donateorgans:" + JSON.stringify(donateorgans));
      } catch (e) {}
      //debugger
      try {
        let res = await getdonateNumberByMonth(params);
        organList = res.data;
        console.log("organList:" + JSON.stringify(organList));
      } catch (e) {}
      //debugger
      console.log(donateorgans);
      let arr = [];
      for (let i = 0; i < 12; i++) {
        //统计捐献案例月度统计数据
        let mm = this.$moment(startTime)
          .add(i, "month")
          .format("YYYY-MM");
        let num = "";
        let num2 = "";
        let ii = donateorgans.findIndex(item => item.donatemonth == mm);
        if (ii > -1) {
          num = donateorgans[ii].donatecount;
        }
        let oi = organList.findIndex(item => item.donatemonth == mm);
        if (oi > -1) {
          num2 = organList[oi].donatecount;
        }
        arr.push({
          name: this.$moment(mm).format("M月"),
          value: num,
          value2: num2
        });
      }
      let organYearArr = [];
      this.anlidata = arr;
      for (let k = 0; k < organList.length; k++) {
        let yearNo = this.$moment(organList[k].donatemonth + "-01").format(
          "YYYY"
        );
        let organNum = organList[k].donatecount;
        //判断当前年份是否在数组中
        let yearIndex = organYearArr.findIndex(item => item.year == yearNo);
        if (yearIndex > -1) {
          organYearArr[yearIndex].num += organNum;
        } else {
          organYearArr.push({ year: yearNo, num: organNum });
        }
      }
      this.organYearData = organYearArr;
    },
    getorgancount() {},
    getData() {},
    getAllInfo() {
      let params = {
        starttime: "2022-01-01 00:00:00",
        endtime: this.$moment().format("YYYY-MM-DD HH:mm:ss")
      };
      getAllOrganInfo(params)
        .then(response => {
          if (response.data) {
            this.allInfo = response.data;
            let list = this.organData.map(item => item);
            for (let i = 0; i < list.length; i++) {
              let k = list[i].key;
              if (this.allInfo[k]) {
                list.value = this.allInfo[k];
                this.organData[i].value = list.value;
              }
            }
            this.organData = list;
            let organsums = 0;
          }
        .catch(() => {
          // è¯·æ±‚失败由 request æ‹¦æˆªå™¨ç»Ÿä¸€æç¤º
        })
        .catch(erroe => {})
        .finally(() => {});
        .finally(() => {
          this.loginLoading = false;
        });
    },
    async getTempList() {
      let total = 0;
      let pageIndex = 1;
      let list = [];
    handleLogout() {
      removeToken();
      this.dialogVisible = true;
      this.$message.info('已退出登录');
    },
    mapClick() {
      // åŒºåŽ¿ç‚¹å‡»å¯åœ¨æ­¤æ‰©å±•ä¸‹é’»
    },
    async loadData() {
      this.loading = true;
      try {
        let searchInfo = {
          pageNum: 1,
          pageSize: 1
        };
        let response = await listDonatebaseinfo(searchInfo);
        this.totalCount = response.total;
      } catch (error) {}
    },
    mapClick(data) {
      let newConfig = {
        ...DEF_TABLE_CONFIG
      };
      let arr = [];
      for (let i = 0; i < this.arrrrr.length; i++) {
        if (data.name == this.arrrrr[i].regionLevel) {
          arr.push(this.arrrrr[i]);
        }
        // åŽç«¯æŽ¥å£å°±ç»ªåŽï¼Œå°†ä¸‹é¢æ¨¡æ‹Ÿæ•°æ®æ›¿æ¢ä¸ºçœŸå®žæŽ¥å£ï¼š
        // è¶‹åŠ¿/性别/器官/地区/KPI â†’ /opo/totals/*(@/api/businessApi/statistics.js)
        // åŒºåŽ¿åœ°å›¾ â†’ getDonateorganDistrictDonateCalculate;
        // ä»ªè¡¨ç›˜ â†’ getDonateorganQuality / getDonateorganPMP;
        // å™¨å®˜å¼ƒç”¨ â†’ ç»Ÿè®¡æ¨¡å—器官弃用相关接口(@/api/businessApi/statistics.js)
        const m = mockCockpitData();
        this.raw.mapData = m.mapData;
        this.raw.gauges = m.gauges;
        this.raw.caseTrend = m.caseTrend;
        this.raw.organMoon = m.organMoon;
        this.raw.caseBloodType = m.caseBloodType;
        this.raw.caseSex = m.caseSex;
        this.raw.organType = m.organType;
        this.raw.organDiscard = m.organDiscard;
        this.raw.caseTrendArea = m.caseTrendArea;
        this.raw.totals = m.totals;
        this.raw.caseAvgAge = m.caseAvgAge;
        this.startCarousel();
      } catch (e) {
        console.error('驾驶舱数据加载失败', e);
      } finally {
        this.loading = false;
      }
      newConfig.data = arr;
      this.tableConfig = newConfig;
      // let name = data.name;
      // let arr = [];
      // for(let i=0;i<this.arrrrr.length;i++){
      //   if(this.arrrr[i].regionLevel == name){
      //     arr.push({
      //      regionLevel   : this.arrrrr[i].regionLevel,
      //       hospitalName  : this.arrrrr[i].hospitalName,
      //      donateNumber  : this.arrrrr[i].baseInfoCount,
      //      acceptNumber  : this.arrrrr[i].completionCount
      //     })
      //   }
      // }
      //   this.arrrr = arr;
      // this.currentArea = { ...data };
      // this.tableList = [];
      // this.total = 0;
      // this.pageData.pageNum = 1;
      // this.showTable = true;
      // this.getList(data.name);
    },
    getRanNum() {
      return Math.round(Math.random() * 40);
    }
  },
  computed: {
    heightA() {
      let h = (this.height * 0.36 - 54) / 5;
      return h;
    },
    totalValue() {
      let sum = 0;
      for (let i = 0; i < this.cdata.length; i++) {
        sum += this.cdata[i].value;
      }
      return sum;
    },
    totalValue2() {
      let sum = 0;
      for (let i = 0; i < this.cdata.length; i++) {
        sum += this.cdata[i].elseData.value2;
      }
      return sum;
    },
    totalValue3() {
      let sum = 0;
      for (let i = 0; i < this.cdata.length; i++) {
        sum += this.cdata[i].elseData.value3;
      }
      return sum;
    }
  }
};
</script>
<style lang="scss" scoped>
#app {
  overflow: hidden;
.cockpit {
  min-height: 100vh;
  padding: 14px 16px 20px;
  box-sizing: border-box;
  color: #e6edff;
  background: radial-gradient(
      1200px 640px at 18% -10%,
      #12275a 0%,
      rgba(18, 39, 90, 0) 60%
    ),
    radial-gradient(1000px 600px at 110% 10%, #0c2a52 0%, rgba(12, 42, 82, 0) 55%),
    linear-gradient(180deg, #0a1226 0%, #070c1c 60%, #050812 100%);
}
.iwc-dv-box {
  .iwc-box-head {
    text-align: center;
    font-size: 18px;
    padding: 7px 0 25px;
    color: #fff;
    background-image: url("../../assets/images/dv-box-title.png");
    background-size: 100% 150%;
    height: 54px;
  }
  .iwc-box-a {
    font-size: 13px;
    .iwc-box-a-1 {
      color: #5ba2ff;
      margin-bottom: 5px;
    }
  }
  .iwc-before-o {
    display: inline-block;
    width: 11px;
    height: 10px;
    border-radius: 50%;
    border: 0.15rem solid;
    margin-right: 0.5rem;
  }
  .iwc-box-c {
    display: flex;
    padding: 1rem 0;
    .iwc-box-c1 {
      flex: 1;
      font-size: 1rem;
      text-align: center;
      .iwc-box-c1-o {
        display: inline-block;
        width: 3.6rem;
        height: 3.6rem;
        line-height: 3.6rem;
        margin: 0 auto;
        border: 0.2rem solid;
        border-radius: 50%;
      }
      .iwc-box-c1-l {
        padding: 1rem 0;
      }
    }
  }
::v-deep .el-loading-mask {
  background-color: rgba(5, 8, 18, 0.75);
}
.iwc-box-d {
  display: flex;
  padding-top: 2rem;
  .iwc-box-d-1 {
    flex: 1;
    position: relative;
    .iwc-box-d-img {
      width: 3.6rem;
      height: 3.6rem;
      position: absolute;
    }
  }
  .iwc-box-d-f {
    padding-left: 4rem;
    padding-top: 0.5rem;
    .iwc-box-d-f1 {
      font-size: 1.4rem;
      color: #07dbff;
      height: 2rem;
    }
    .iwc-box-d-f2 {
      color: #fff;
      font-size: 0.75rem;
    }
  }
}
.c-home {
  .fc-white {
    color: #fff;
  }
  .fc-sp {
    color: #409eff;
  }
  .box-title {
    width: 100%;
    span {
      display: block;
      width: 130px;
      height: 25px;
      -webkit-transform: skew(20deg);
      -moz-transform: skew(20deg);
      -o-transform: skew(20deg);
      background: #1356a1;
      line-height: 25px;
      align-self: center;
      border: 1px transparent solid;
      border-image: linear-gradient(#070a17, #7be6fc) 10 10;
      border-image: linear-gradient(#070a17, #7be6fc) 10 10;
      border-image: linear-gradient(#070a17, #7be6fc) 10 10;
      margin: 0 auto;
    }
    b {
      display: block;
      color: #fff;
      text-align: center;
      transform: skewY(-20deg);
      transform: skewX(-20deg);
    }
  }
  .box-num {
    position: relative;
    .box-num-main {
      p {
        margin: 0 0 10px;
      }
      text-align: right;
      .box-num-main-n {
        color: #409eff;
        font-size: 25px;
      }
    }
    .box-num-ex {
      position: absolute;
      bottom: 5px;
      right: 10px;
      width: 45px;
      span {
        color: #409eff;
        font-size: 12px;
      }
    }
/* é¡¶éƒ¨æ ‡é¢˜æ  */
.cockpit-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 4px 14px;
  .header-left {
    display: flex;
    align-items: center;
  }
}
::v-deep .c-table-title {
  .el-divider.el-divider--horizontal {
    background-color: #95a1ec;
    .el-divider__text.is-left {
      color: #303133;
      background: #fafafa;
    }
  .header-logo {
    width: 10px;
    height: 26px;
    border-radius: 3px;
    margin-right: 12px;
    background: linear-gradient(180deg, #38a5f8, #22d3ee);
    box-shadow: 0 0 12px rgba(56, 165, 248, 0.7);
  }
  .active {
    .el-divider.el-divider--horizontal {
      .el-divider__text.is-left {
        color: #409eff;
      }
    }
  .header-title {
    margin: 0;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: 2px;
    background: linear-gradient(90deg, #eaf2ff, #6db8ff);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
  }
}
::v-deep .iwc-ring {
  .dv-active-ring-chart .active-ring-info .active-ring-name {
    position: absolute;
    top: 82px;
  .header-right {
    display: flex;
    align-items: center;
  }
}
::v-deep .iwc-box-b-table.dv-scroll-board {
  .rows {
    .row-item:nth-child(2) {
      border: 1px solid #02406e;
      background-color: rgba(19, 187, 206, 0.13);
      background-blend-mode: multiply;
      //filter: drop-shadow(3px 3px 4px #07dbff);
      box-shadow: 0 0 10px rgb(0, 153, 184) inset;
    }
    .ceil:nth-child(1) {
      flex: 1;
    }
    .ceil:nth-child(2) {
      width: 70px !important;
    }
  }
}
::v-deep .iwc-h-rb-table.dv-scroll-board {
  .header {
    color: #07dbff;
    .header-item:nth-child(1) {
      width: 70px !important;
    }
    .header-item:nth-child(2) {
      flex: 1;
    }
    .header-item:nth-child(3) {
      width: 80px !important;
    }
    .header-item:nth-child(4) {
      width: 80px !important;
    }
  }
  .rows {
    .row-item {
      border-bottom: 1px solid #036492;
    }
    .row-item:nth-child(2) {
      border: 1px solid #07dbff;
      background-color: rgba(19, 187, 206, 0.13);
      background-blend-mode: multiply;
      box-shadow: 0 0 10px rgb(0, 153, 184) inset;
      //filter: drop-shadow(3px 3px 4px #07dbff);
    }
    .ceil:nth-child(1) {
      width: 70px;
    }
    .ceil:nth-child(2) {
      flex: 1;
      padding-left: 0;
      padding-right: 0;
    }
    .ceil:nth-child(3) {
      width: 80px;
      text-align: center;
      padding-left: 0;
      padding-right: 0;
    }
    .ceil:nth-child(4) {
      width: 80px;
      text-align: center;
      padding-left: 0;
      padding-right: 0;
    }
  }
}
::v-deep .el-dialog {
  -webkit-transform: none;
  transform: none;
  background-color: rgb(3, 14, 64);
  box-shadow: rgb(10, 51, 110) 0px 0px 40px inset;
  border: 1px solid rgb(10, 51, 110);
  color: #fff !important;
  left: 0;
  position: relative;
  margin: 0 auto;
  .el-dialog__title {
    color: #fff;
  }
  .el-form-item__label {
    text-align: right;
    vertical-align: middle;
    float: left;
  .header-clock {
    color: #9aa7c7;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
    letter-spacing: 1px;
    margin-right: 16px;
  }
  .header-logout {
    color: #9aa7c7;
    &:hover {
      color: #38a5f8;
    }
  }
}
/* KPI æŒ‡æ ‡å¡ */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 16px;
  margin-bottom: 16px;
}
.kpi-card {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  border-radius: 12px;
  border: 1px solid rgba(90, 120, 190, 0.28);
  background: linear-gradient(
    135deg,
    rgba(40, 52, 96, 0.72),
    rgba(16, 24, 52, 0.9)
  );
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
.kpi-icon {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  color: #fff;
  margin-right: 12px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
}
.kpi-body {
  min-width: 0;
}
.kpi-label {
  font-size: 13px;
  color: #8aa0c8;
  margin-bottom: 2px;
}
.kpi-value {
  font-size: 24px;
  font-weight: 700;
  color: #fff;
  line-height: 1.2;
}
.kpi-unit {
  font-size: 13px;
  font-weight: 400;
  color: #8aa0c8;
  margin-left: 4px;
}
/* ä»ªè¡¨ç›˜è¡Œ */
.gauge-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 16px;
}
/* é¢æ¿ */
.panel {
  height: 100%;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid rgba(80, 110, 180, 0.25);
  background: linear-gradient(
    180deg,
    rgba(25, 35, 70, 0.82),
    rgba(13, 20, 43, 0.82)
  );
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
  box-sizing: border-box;
}
.panel-title {
  position: relative;
  font-size: 15px;
  font-weight: 600;
  color: #dbe4ff;
  margin-bottom: 10px;
  padding-left: 12px;
  &::before {
    content: '';
    position: absolute;
    left: 0;
    top: 2px;
    bottom: 2px;
    width: 4px;
    border-radius: 2px;
    background: linear-gradient(180deg, #38a5f8, #22d3ee);
  }
}
/* å·¦å³ä¸¤åˆ—堆叠 */
.col-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
  height: 100%;
  .panel {
    flex: 1;
  }
}
/* è½®æ’­ */
.panel--carousel {
  position: relative;
}
.carousel-body {
  height: 205px;
}
.carousel-dots {
  position: absolute;
  right: 16px;
  top: 16px;
  display: flex;
  gap: 6px;
}
.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(120, 140, 190, 0.35);
  cursor: pointer;
  transition: all 0.3s;
  &.active {
    width: 20px;
    border-radius: 4px;
    background: #38a5f8;
  }
}
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.4s;
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
}
</style>
<!-- ç™»å½•弹窗通过 append-to-body æŒ‚到 body ä¸‹ï¼Œscoped æ ·å¼æ— æ³•命中,故用全局样式 -->
<style lang="scss">
.el-dialog.login-dialog {
  background: linear-gradient(180deg, rgba(28, 40, 78, 0.97), rgba(13, 20, 43, 0.99));
  border: 1px solid rgba(74, 120, 200, 0.45);
  border-radius: 14px;
  box-shadow: 0 0 0 1px rgba(56, 165, 248, 0.12), 0 0 44px rgba(56, 165, 248, 0.28),
    0 24px 60px rgba(0, 0, 0, 0.55);
  overflow: hidden;
  .el-dialog__header {
    padding: 22px 26px 14px;
    border-bottom: 1px solid rgba(74, 120, 200, 0.22);
  }
  .el-dialog__title {
    color: #eaf2ff;
    font-size: 18px;
    font-weight: 600;
    letter-spacing: 2px;
    &::before {
      content: '';
      display: inline-block;
      width: 4px;
      height: 16px;
      margin-right: 10px;
      border-radius: 2px;
      background: linear-gradient(180deg, #38a5f8, #22d3ee);
      box-shadow: 0 0 8px rgba(56, 165, 248, 0.8);
      vertical-align: -2px;
    }
  }
  .el-dialog__body {
    padding: 26px 26px 8px;
    color: #c3cde4;
  }
  .el-dialog__footer {
    padding: 8px 26px 24px;
    text-align: right;
  }
  .el-form-item__label {
    color: #aab6d4;
    font-weight: 500;
    letter-spacing: 1px;
  }
  .el-input__inner {
    background: rgba(8, 15, 34, 0.9);
    border: 1px solid rgba(90, 124, 200, 0.35);
    border-radius: 6px;
    color: #e6edff;
    transition: border-color 0.25s, box-shadow 0.25s;
    &::placeholder {
      color: rgba(154, 167, 199, 0.6);
    }
    &:hover {
      border-color: rgba(90, 124, 200, 0.55);
    }
    &:focus {
      border-color: #38a5f8;
      box-shadow: 0 0 0 3px rgba(56, 165, 248, 0.18);
    }
  }
  .el-button {
    background: rgba(24, 36, 68, 0.9);
    border: 1px solid rgba(90, 124, 200, 0.4);
    color: #c3cde4;
    &:hover {
      border-color: #38a5f8;
      color: #eaf2ff;
    }
  }
  .el-button--primary {
    background: linear-gradient(135deg, #2563eb, #22d3ee);
    border: none;
    color: #fff;
    line-height: 40px;
    padding: 0 12px 0 0;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    box-shadow: 0 4px 14px rgba(56, 165, 248, 0.4);
    &:hover,
    &:focus {
      background: linear-gradient(135deg, #2f6ff0, #2fd8f2);
      color: #fff;
    }
  }
}
::v-deep .iwc-box-a {
  .el-progress-bar__outer {
    background-color: #29345c;
  }
  .el-progress-bar__innerText {
    margin-right: -27px;
  }
}
.login-code {
  width: 33%;
  height: 38px;
  float: right;
  img {
    cursor: pointer;
    vertical-align: middle;
  }
}
.login-code-img {
  height: 38px;
}
</style>
src/views/monitor/job/index.vue
@@ -44,7 +44,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['monitor:job:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -55,7 +54,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['monitor:job:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -66,7 +64,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['monitor:job:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -77,7 +74,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['monitor:job:export']"
        >导出</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -87,7 +83,6 @@
          icon="el-icon-s-operation"
          size="mini"
          @click="handleJobLog"
          v-hasPermi="['monitor:job:query']"
        >日志</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -121,26 +116,24 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['monitor:job:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['monitor:job:remove']"
          >删除</el-button>
          <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['monitor:job:changeStatus', 'monitor:job:query']">
          <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)">
            <span class="el-dropdown-link">
              <i class="el-icon-d-arrow-right el-icon--right"></i>更多
            </span>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item command="handleRun" icon="el-icon-caret-right"
                v-hasPermi="['monitor:job:changeStatus']">执行一次</el-dropdown-item>
>执行一次</el-dropdown-item>
              <el-dropdown-item command="handleView" icon="el-icon-view"
                v-hasPermi="['monitor:job:query']">任务详细</el-dropdown-item>
>任务详细</el-dropdown-item>
              <el-dropdown-item command="handleJobLog" icon="el-icon-s-operation"
                v-hasPermi="['monitor:job:query']">调度日志</el-dropdown-item>
>调度日志</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </template>
src/views/monitor/job/log.vue
@@ -70,7 +70,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['monitor:job:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -80,7 +79,6 @@
          icon="el-icon-delete"
          size="mini"
          @click="handleClean"
          v-hasPermi="['monitor:job:remove']"
        >清空</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -91,7 +89,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['monitor:job:export']"
        >导出</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -134,7 +131,6 @@
            type="text"
            icon="el-icon-view"
            @click="handleView(scope.row)"
            v-hasPermi="['monitor:job:query']"
          >详细</el-button>
        </template>
      </el-table-column>
src/views/monitor/logininfor/index.vue
@@ -64,7 +64,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['monitor:logininfor:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -74,7 +73,6 @@
          icon="el-icon-delete"
          size="mini"
          @click="handleClean"
          v-hasPermi="['monitor:logininfor:remove']"
        >清空</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -85,7 +83,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['monitor:logininfor:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
src/views/monitor/online/index.vue
@@ -54,7 +54,6 @@
            type="text"
            icon="el-icon-delete"
            @click="handleForceLogout(scope.row)"
            v-hasPermi="['monitor:online:forceLogout']"
          >强退</el-button>
        </template>
      </el-table-column>
src/views/monitor/operlog/index.vue
@@ -80,7 +80,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['monitor:operlog:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -90,7 +89,6 @@
          icon="el-icon-delete"
          size="mini"
          @click="handleClean"
          v-hasPermi="['monitor:operlog:remove']"
        >清空</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -101,7 +99,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['monitor:operlog:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -137,7 +134,6 @@
            type="text"
            icon="el-icon-view"
            @click="handleView(scope.row,scope.index)"
            v-hasPermi="['monitor:operlog:query']"
          >详细</el-button>
        </template>
      </el-table-column>
src/views/project/components/annexupload/index.vue
@@ -76,7 +76,6 @@
                type="text"
                icon="el-icon-delete"
                @click="handleDelete(scope.row)"
                v-hasPermi="['project:donateannex:remove']"
                >删除</el-button
              >
            </template>
src/views/project/distributedetail/index.vue
@@ -124,7 +124,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:distributedetail:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -135,7 +134,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:distributedetail:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -146,7 +144,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:distributedetail:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -157,7 +154,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:distributedetail:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -228,14 +224,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:distributedetail:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:distributedetail:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/project/documentfiles/index.vue
@@ -90,7 +90,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
           v-hasPermi="['product:documentfiles:add']"
          >新增</el-button
        >
      </el-col>
@@ -101,7 +100,6 @@
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
        v-hasPermi="['product:documentfiles:update']"
          @click="handleUpdate"
          >修改</el-button
        >
@@ -114,7 +112,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
        v-hasPermi="['product:documentfiles:delete']"
          >删除</el-button
        >
      </el-col>
@@ -126,7 +123,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:documentfiles:export']"
        >导出</el-button>
      </el-col> -->
      <right-toolbar
@@ -210,7 +206,7 @@
            @click="handleUpdate(scope.row)"
            >修改</el-button
          >
          <!-- v-hasPermi="['project:documentfiles:edit']" -->
          <!-- -->
          <el-button
            size="mini"
            type="text"
@@ -218,7 +214,7 @@
            @click="handleDelete(scope.row)"
            >删除</el-button
          >
          <!-- v-hasPermi="['project:documentfiles:remove']" -->
          <!-- -->
          <el-button
            size="mini"
            type="text"
@@ -226,7 +222,7 @@
            @click="handleDownload(scope.row)"
            >下载</el-button
          >
          <!-- v-hasPermi="['project:documentfiles:remove']" -->
          <!-- -->
        </template>
      </el-table-column>
    </el-table>
src/views/project/donateannex/index.vue
@@ -83,7 +83,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:donateannex:add']"
          >新增</el-button
        >
      </el-col>
@@ -95,7 +94,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:donateannex:edit']"
          >修改</el-button
        >
      </el-col>
@@ -107,7 +105,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:donateannex:remove']"
          >删除</el-button
        >
      </el-col>
@@ -119,7 +116,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:donateannex:export']"
          >导出</el-button
        >
      </el-col>
@@ -217,7 +213,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:donateannex:edit']"
            >修改</el-button
          >
          <el-button
@@ -225,7 +220,6 @@
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:donateannex:remove']"
            >删除</el-button
          >
        </template>
src/views/project/donateannexrequirement/index.vue
@@ -94,7 +94,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:donateannexrequirement:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -105,7 +104,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:donateannexrequirement:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -116,7 +114,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:donateannexrequirement:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -127,7 +124,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:donateannexrequirement:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -155,14 +151,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:donateannexrequirement:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:donateannexrequirement:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/project/donatebaseinfo/EditCaseModal.vue
@@ -534,46 +534,66 @@
                </el-form-item>
              </el-col>
            </el-row>
             <el-row :gutter="20">
            <!-- ä¿¡æ¯å‘˜ -->
            <el-row>
              <el-col :span="8">
                <el-form-item label="信息员" prop="infoName">
                  <el-input
                    v-model="formData.infoName"
                    placeholder="请输入信息员"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="联系电话" prop="infophone">
                  <el-input
                    v-model="formData.infophone"
                    placeholder="请输入信息员联系电话"
                  />
                </el-form-item>
              </el-col>
            </el-row>
            <el-col :span="20">
              <el-form-item label="获取组织名称" prop="acquisitiontissuename">
                <el-input
                  v-model="formData.acquisitiontissuename"
                  placeholder="请输入获取组织名称"
                />
              </el-form-item>
            </el-col>
          </el-row>
            <!-- ä¸ŠæŠ¥é˜¶æ®µæŠ¥å‘Šäºº -->
            <el-col :span="8">
              <el-form-item label="报告人签字" prop="reportername">
              <el-form-item label="上报阶段报告人" prop="reportername">
                <el-input
                  v-model="formData.reportername"
                  placeholder="报告人姓名"
                  :disabled="true"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="联系电话" prop="reporterphone">
              <el-form-item label="报告人联系电话" prop="reporterphone">
                <el-input
                  v-model="formData.reporterphone"
                  placeholder="报告人联系电话"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="报告时间" prop="reporttime">
                <el-date-picker
                  v-model="formData.reporttime"
                  type="date"
                  placeholder="选择报告时间"
                  value-format="yyyy-MM-dd "
                  style="width: 100%"
                />
              </el-form-item>
            </el-col>
            <!-- æŠ¥å‘Šä¿¡æ¯å‘˜ -->
            <el-col :span="8">
              <el-form-item label="报告信息员" prop="infoName">
                <el-input
                  v-model="formData.infoName"
                  placeholder="请输入报告信息员"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="信息员联系电话" prop="infophone">
                <el-input
                  v-model="formData.infophone"
                  placeholder="请输入信息员联系电话"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
          <!-- <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="报告时间" prop="reporttime">
                <el-date-picker
@@ -585,21 +605,21 @@
                />
              </el-form-item>
            </el-col>
            <!-- <el-col :span="12">
            <el-col :span="12">
              <el-form-item label="部门ID" prop="deptid">
                <el-input
                  v-model="formData.deptid"
                  placeholder="请输入部门ID"
                />
              </el-form-item>
            </el-col> -->
          </el-row>
            </el-col>
          </el-row> -->
        </el-card>
        <!-- æçŒ®ä¿¡æ¯éƒ¨åˆ† -->
        <el-card header="捐献信息" class="form-section">
        <!-- <el-card header="捐献信息" class="form-section">
          <el-row :gutter="20">
            <!-- <el-col :span="8">
            <el-col :span="8">
              <el-form-item label="捐献类别" prop="donationcategory">
                <el-select
                  v-model="formData.donationcategory"
@@ -613,7 +633,7 @@
                  />
                </el-select>
              </el-form-item>
            </el-col> -->
            </el-col>
            <el-col :span="8">
              <el-form-item label="案例上报时间" prop="donatetime">
                <el-date-picker
@@ -638,15 +658,10 @@
            </el-col>
          </el-row>
          <!-- çº¢åå­—会和联系人 -->
          <el-row>
            <el-col :span="8">
              <el-form-item align="left" label="红十字会" prop="redorganno">
                <!-- <org-selecter
                  ref="addCrossOrgSelect"
                  :org-type="'2'"
                  v-model="formData.redorganno"
                /> -->
                <el-select
                  v-model="formData.redorganname"
                  placeholder="请选择红十字会机构名称"
@@ -681,14 +696,7 @@
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <!-- <el-col :span="12">
              <el-form-item label="获取组织编号" prop="acquisitiontissueno">
                <el-input
                  v-model="formData.acquisitiontissueno"
                  placeholder="请输入获取组织编号"
                />
              </el-form-item>
            </el-col> -->
            <el-col :span="12">
              <el-form-item label="获取组织名称" prop="acquisitiontissuename">
                <el-input
@@ -698,67 +706,95 @@
              </el-form-item>
            </el-col>
          </el-row>
        </el-card>
        <!-- ä¸ŠæŠ¥é˜¶æ®µé™„ä»¶ -->
<el-card v-if="reportAttachments && reportAttachments.length > 0" class="form-section" shadow="never">
  <div slot="header" class="section-header">
    <i class="el-icon-paperclip" style="color: #409EFF; margin-right: 8px;"></i>
    <span>上报阶段附件</span>
  </div>
  <div class="attachment-list">
    <el-tabs v-model="reportActiveTab" type="border-card">
      <el-tab-pane
        v-for="category in reportCategories"
        :key="category"
        :label="category + '(' + getReportCategoryCount(category) + ')'"
        :name="category"
      >
        <el-table :data="getReportCategoryFiles(category)" style="width: 100%" size="small" border>
          <el-table-column label="文件名" min-width="200">
            <template #default="scope">
              <i class="el-icon-document" style="margin-right: 8px; color: #409EFF;"></i>
              <span class="file-name">{{ scope.row.fileName }}</span>
            </template>
          </el-table-column>
          <el-table-column label="文件类型" width="100">
            <template #default="scope">
              <el-tag size="small">{{ getFileType(scope.row.fileName) }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="创建时间" width="160">
            <template #default="scope">
              <span>{{ formatDateTime(scope.row.createTime) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="120">
            <template #default="scope">
              <el-button size="mini" type="primary" @click="handleReportPreview(scope.row)">预览</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
    </el-tabs>
  </div>
</el-card>
<!-- åŠ è½½ä¸­å ä½ -->
<el-card v-else-if="reportAttachmentLoading" class="form-section" shadow="never">
  <div slot="header" class="section-header">
    <i class="el-icon-paperclip" style="color: #409EFF; margin-right: 8px;"></i>
    <span>上报阶段附件</span>
  </div>
  <div style="text-align:center; padding:20px;">加载附件中...</div>
</el-card>
<!-- æœ‰ reportId ä½†æ— é™„ä»¶ -->
<el-card v-else-if="editData.reportId" class="form-section" shadow="never">
  <div slot="header" class="section-header">
    <i class="el-icon-paperclip" style="color: #409EFF; margin-right: 8px;"></i>
    <span>上报阶段附件</span>
  </div>
  <div style="text-align:center; padding:20px; color:#909399;">暂无上报附件</div>
</el-card>
        </el-card> -->
      </el-form>
      <!-- æçŒ®è€…登记阶段附件(可编辑,存储于亲属确认表 assessannex) -->
      <el-card header="登记阶段附件" class="form-section">
        <el-tabs v-model="activeRegisterType" type="card">
          <el-tab-pane
            v-for="type in registerAttachmentTypes"
            :key="type.value"
            :label="type.label"
            :name="type.value"
          >
            <div class="attachment-header">
              <span class="upload-title">{{ type.label }}</span>
              <el-button
                size="mini"
                type="primary"
                icon="el-icon-plus"
                @click="openUploadDialog(type.value)"
              >
                æ·»åР附件
              </el-button>
            </div>
            <el-table
              :data="getRegisterAttachments(type.value)"
              size="small"
              style="width: 100%"
            >
              <el-table-column label="文件名" min-width="200">
                <template slot-scope="scope">
                  <i
                    class="el-icon-document"
                    style="color: #409eff; margin-right: 8px"
                  ></i>
                  <span>{{ scope.row.fileName }}</span>
                </template>
              </el-table-column>
              <el-table-column label="文件类型" width="90" align="center">
                <template slot-scope="scope">
                  <el-tag size="small">{{
                    getFileType(scope.row.fileName)
                  }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="文件大小" width="90" align="center">
                <template slot-scope="scope">
                  <span>{{ formatFileSize(scope.row.fileSize) }}</span>
                </template>
              </el-table-column>
              <el-table-column label="上传时间" width="155" align="center">
                <template slot-scope="scope">
                  <span>{{
                    formatDateTime(scope.row.uploadTime || scope.row.createTime)
                  }}</span>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="145" align="center">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="primary"
                    @click="handlePreview(scope.row)"
                  >
                    é¢„览
                  </el-button>
                  <el-button
                    size="mini"
                    type="danger"
                    @click="handleRemoveAttachment(type.value, scope.$index)"
                  >
                    åˆ é™¤
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
            <div
              v-if="getRegisterAttachments(type.value).length === 0"
              class="empty-attachment"
            >
              <el-empty
                :description="`暂无${type.label}`"
                :image-size="80"
              ></el-empty>
            </div>
          </el-tab-pane>
        </el-tabs>
      </el-card>
      <div slot="footer" class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
@@ -771,6 +807,55 @@
        </el-button>
      </div>
    </el-dialog>
    <!-- ä¸Šä¼ é™„件对话框 -->
    <el-dialog
      :title="`上传${getCurrentTypeLabel()}附件`"
      :visible.sync="uploadDialogVisible"
      width="480px"
      :close-on-click-modal="false"
    >
      <el-upload
        ref="uploadRef"
        class="upload-demo"
        drag
        :action="uploadAction"
        :headers="headers"
        multiple
        :file-list="tempFileList"
        :before-upload="beforeUpload"
        :on-change="handleFileChange"
        :on-remove="handleTempRemove"
        :on-success="handleUploadSuccess"
        :auto-upload="false"
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <div class="el-upload__tip" slot="tip">
          æ”¯æŒä¸Šä¼ pdf、jpg、png、doc、docx格式文件,单个文件不超过10MB
        </div>
      </el-upload>
      <span slot="footer" class="dialog-footer">
        <el-button @click="uploadDialogVisible = false">取消</el-button>
        <el-button
          type="primary"
          @click="submitUpload"
          :loading="uploadLoading"
          :disabled="tempFileList.length === 0"
        >
          ç¡®è®¤ä¸Šä¼ 
        </el-button>
      </span>
    </el-dialog>
    <!-- æ–‡ä»¶é¢„览弹窗 -->
    <FilePreviewDialog
      :visible="previewVisible"
      :file="currentPreviewFile"
      @close="previewVisible = false"
      @download="handleDownload"
    />
  </div>
</template>
@@ -779,15 +864,18 @@
  getDonatebaseinfo,
  updateDonatebaseinfo
} from "@/api/project/donatebaseinfo";
import { relativesEdit, relativesAdd, relativesList } from "@/api/businessApi";
import OrgSelecter from "@/views/project/components/orgselect";
import { donateInfo } from "@/api/businessApi/index";
import LiAreaSelect from "@/components/Address";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import { getToken } from "@/utils/auth";
export default {
  name: "EditCaseModal",
  components: {
    OrgSelecter,
    LiAreaSelect
    LiAreaSelect,
    FilePreviewDialog
  },
  // æ·»åŠ æ‰€æœ‰éœ€è¦çš„å­—å…¸ç±»åž‹
@@ -836,10 +924,24 @@
      residenceAddress: {},
      registerAddress: {},
      formData: this.getDefaultFormData(),
      reportAttachments: [], // ä¸ŠæŠ¥é˜¶æ®µçš„附件列表
      reportAttachmentLoading: false, // åŠ è½½çŠ¶æ€
      reportActiveTab: "登记表附件", // å½“前激活的附件分类 Tab
      presetCategories: ["登记表附件", "证件照", "疾病诊断治疗"], // é¢„设分类
      // ç™»è®°é˜¶æ®µé™„件(可编辑,存储于亲属确认表 assessannex)
      registerAttachmentTypes: [
        { value: "1", label: "人体器官潜在捐献者登记表附件" },
        { value: "5", label: "证件照" },
        { value: "6", label: "疾病诊断治疗" }
      ],
      registerAttachmentData: { "1": [], "5": [], "6": [] },
      otherAttachments: [],
      confirmationRecord: null,
      activeRegisterType: "1",
      uploadAction: process.env.VUE_APP_BASE_API + "/common/upload",
      headers: { Authorization: "Bearer " + getToken() },
      uploadDialogVisible: false,
      uploadLoading: false,
      tempFileList: [],
      currentUploadType: "",
      previewVisible: false,
      currentPreviewFile: null,
      rules: {
        name: [
          { required: true, message: "请输入捐献者姓名", trigger: "blur" }
@@ -866,9 +968,9 @@
        bloodtype: [
          { required: true, message: "请选择血型", trigger: "change" }
        ],
        donatetime: [
          { required: true, message: "请选择案例时间", trigger: "change" }
        ],
        // donatetime: [
        //   { required: true, message: "请选择案例时间", trigger: "change" }
        // ],
        reporttime: [
          { required: true, message: "请选择报告时间", trigger: "change" }
        ],
@@ -896,21 +998,6 @@
        }
      }
    },
    reportCategories() {
      if (!this.reportAttachments || this.reportAttachments.length === 0)
        return [];
      const cats = new Set();
      this.reportAttachments.forEach(item => {
        const type = item.fileType || item.filetype || "";
        if (this.presetCategories.includes(type)) {
          cats.add(type);
        } else {
          cats.add("未分类");
        }
      });
      const order = ["登记表附件", "证件照", "疾病诊断治疗", "未分类"];
      return order.filter(c => cats.has(c));
    }
  },
  watch: {
    visible(newVal) {
@@ -921,16 +1008,6 @@
        });
      } else {
        this.handleClose();
      }
    },
    "editData.reportId": {
      immediate: true,
      handler(newVal) {
        if (newVal) {
          this.loadReportAttachments(newVal);
        } else {
          this.reportAttachments = [];
        }
      }
    },
    editData: {
@@ -1125,6 +1202,7 @@
        console.log(this.registerAddress, "registerAddress12");
        this.calculateAge(data.birthday);
        await this.loadRegisterAttachments();
      } catch (error) {
        console.error("获取案例数据失败:", error);
        this.$message.error("获取案例数据失败");
@@ -1262,6 +1340,310 @@
      this.formData.registercommunityname = address.qu;
    },
    // åŠ è½½ç™»è®°é˜¶æ®µé™„ä»¶ï¼ˆè¯»å–äº²å±žç¡®è®¤è¡¨ assessannex,与确认详情页共用同一份数据)
    // æçŒ®ç¡®è®¤ä¿¡æ¯ç»Ÿä¸€é€šè¿‡ confirmationBaseInfoList æŽ¥å£èŽ·å–
    async loadRegisterAttachments() {
      const infoid = this.editData && this.editData.id;
      if (!infoid) {
        this.resetAttachments();
        return;
      }
      try {
        const res = await relativesList({ infoid });
        const record = this.parseConfirmationBaseInfo(res);
        if (record && record.id) {
          this.confirmationRecord = record;
          this.parseAssessannex(record.assessannex);
        } else {
          this.confirmationRecord = null;
          this.resetAttachments();
        }
      } catch (e) {
        console.warn("获取亲属确认附件失败:", e);
        this.resetAttachments();
      }
    },
    // è§£æž confirmationBaseInfoList è¿”回的确认基础信息(兼容数组 / rows / å•对象结构)
    parseConfirmationBaseInfo(res) {
      if (!res || res.code !== 200) return null;
      const data = res.data;
      if (!data) return null;
      if (Array.isArray(data)) return data[0] || null;
      if (Array.isArray(data.rows)) return data.rows[0] || null;
      if (Array.isArray(data.list)) return data.list[0] || null;
      return data;
    },
    resetAttachments() {
      Object.keys(this.registerAttachmentData).forEach(key => {
        this.registerAttachmentData[key] = [];
      });
      this.otherAttachments = [];
    },
    parseAssessannex(assessannex) {
      this.resetAttachments();
      if (!assessannex) return;
      try {
        const list =
          typeof assessannex === "string" ? JSON.parse(assessannex) : assessannex;
        if (!Array.isArray(list)) return;
        list.forEach(item => {
          const type = String(item.type || "");
          if (this.registerAttachmentData[type]) {
            this.registerAttachmentData[type].push(item);
          } else {
            this.otherAttachments.push(item);
          }
        });
      } catch (e) {
        console.warn("解析assessannex失败:", e);
      }
    },
    getRegisterAttachments(type) {
      return this.registerAttachmentData[type] || [];
    },
    // åºåˆ—化登记阶段附件,并保留确认阶段等其他附件
    serializeAssessannex() {
      const all = [...this.otherAttachments];
      this.registerAttachmentTypes.forEach(t => {
        all.push(...(this.registerAttachmentData[t.value] || []));
      });
      return JSON.stringify(all);
    },
    getCurrentTypeLabel() {
      const type = this.registerAttachmentTypes.find(
        t => t.value === this.currentUploadType
      );
      return type ? type.label : "";
    },
    openUploadDialog(type) {
      this.currentUploadType = type;
      this.tempFileList = [];
      this.uploadDialogVisible = true;
      this.$nextTick(() => {
        if (this.$refs.uploadRef) {
          this.$refs.uploadRef.clearFiles();
        }
      });
    },
    beforeUpload(file) {
      const allowedTypes = [
        "application/pdf",
        "image/jpeg",
        "image/png",
        "application/msword",
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
      ];
      const maxSize = 10 * 1024 * 1024;
      const isTypeOk =
        allowedTypes.includes(file.type) ||
        file.name.endsWith(".pdf") ||
        file.name.endsWith(".jpg") ||
        file.name.endsWith(".jpeg") ||
        file.name.endsWith(".png") ||
        file.name.endsWith(".doc") ||
        file.name.endsWith(".docx");
      if (!isTypeOk) {
        this.$message.error(
          "文件格式不支持,请上传pdf、jpg、png、doc或docx格式文件"
        );
        return false;
      }
      if (file.size > maxSize) {
        this.$message.error("文件大小不能超过10MB");
        return false;
      }
      return true;
    },
    handleFileChange(file, fileList) {
      this.tempFileList = fileList;
    },
    handleTempRemove(file, fileList) {
      this.tempFileList = fileList;
    },
    handleUploadSuccess(response, file) {
      if (response.code !== 200) {
        this.$message.error(response.msg || "上传失败");
        return;
      }
      const newAttachment = {
        id: Date.now(),
        fileName: file.name,
        fileUrl: response.url,
        fileSize: file.size,
        fileType: this.getFileExtension(file.name),
        type: this.currentUploadType,
        uploadTime: this.getCurrentTime(),
        uploader: "当前用户"
      };
      if (this.registerAttachmentData[this.currentUploadType]) {
        this.registerAttachmentData[this.currentUploadType].push(newAttachment);
      }
      this.$message.success("上传成功");
      this.uploadLoading = false;
      this.uploadDialogVisible = false;
      this.tempFileList = [];
    },
    submitUpload() {
      if (this.tempFileList.length === 0) {
        this.$message.warning("请先选择要上传的文件");
        return;
      }
      this.uploadLoading = true;
      this.$refs.uploadRef.submit();
    },
    handleRemoveAttachment(type, index) {
      this.$confirm("确定要删除这个附件吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          const container = this.registerAttachmentData[type];
          if (container && container[index]) {
            container.splice(index, 1);
            this.$message.success("附件删除成功");
          }
        })
        .catch(() => {});
    },
    handlePreview(file) {
      this.currentPreviewFile = {
        fileName: file.fileName,
        fileUrl: file.fileUrl,
        fileType: this.getFileType(file.fileName)
      };
      this.previewVisible = true;
    },
    handleDownload(file) {
      const fileUrl = file.fileUrl;
      const fileName = file.fileName;
      if (fileUrl) {
        const link = document.createElement("a");
        link.href = fileUrl;
        link.download = fileName;
        link.style.display = "none";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        this.$message.success("开始下载文件");
      } else {
        this.$message.warning("文件路径不存在,无法下载");
      }
    },
    getFileType(fileName) {
      if (!fileName) return "other";
      const extension = this.getFileExtension(fileName);
      const imageTypes = ["jpg", "jpeg", "png"];
      const pdfTypes = ["pdf"];
      const officeTypes = ["doc", "docx"];
      if (imageTypes.includes(extension)) return "image";
      if (pdfTypes.includes(extension)) return "pdf";
      if (officeTypes.includes(extension)) return "office";
      return "other";
    },
    getFileExtension(filename) {
      return filename
        .split(".")
        .pop()
        .toLowerCase();
    },
    formatFileSize(size) {
      if (!size) return "0 B";
      const k = 1024;
      const sizes = ["B", "KB", "MB", "GB"];
      const i = Math.floor(Math.log(size) / Math.log(k));
      return parseFloat((size / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
    },
    formatDateTime(dateTime) {
      if (!dateTime) return "";
      try {
        const date = new Date(dateTime);
        if (isNaN(date.getTime())) return dateTime;
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, "0");
        const day = String(date.getDate()).padStart(2, "0");
        const hours = String(date.getHours()).padStart(2, "0");
        const minutes = String(date.getMinutes()).padStart(2, "0");
        return `${year}-${month}-${day} ${hours}:${minutes}`;
      } catch (error) {
        return dateTime;
      }
    },
    getCurrentTime() {
      const now = new Date();
      return `${now.getFullYear()}-${(now.getMonth() + 1)
        .toString()
        .padStart(2, "0")}-${now
        .getDate()
        .toString()
        .padStart(2, "0")} ${now
        .getHours()
        .toString()
        .padStart(2, "0")}:${now
        .getMinutes()
        .toString()
        .padStart(2, "0")}:${now
        .getSeconds()
        .toString()
        .padStart(2, "0")}`;
    },
    // ä¿å­˜ç™»è®°é˜¶æ®µé™„件到亲属确认表 assessannex
    async saveAssessannex() {
      const infoid = this.formData.id;
      if (!infoid) return;
      const assessannex = this.serializeAssessannex();
      try {
        if (this.confirmationRecord && this.confirmationRecord.id) {
          // å·²å­˜åœ¨ç¡®è®¤è¡¨è®°å½•:仅更新附件字段,保留其余信息
          await relativesEdit({ ...this.confirmationRecord, assessannex });
        } else {
          // ç¡®è®¤è¡¨è®°å½•不存在:新增完整记录(携带登记表基础信息)
          await relativesAdd(this.buildConfirmationRecord(infoid, assessannex));
        }
      } catch (e) {
        console.warn("保存登记阶段附件失败:", e);
        this.$message.warning("登记阶段附件保存失败,请重试");
      }
    },
    // æž„建新增亲属确认表记录:携带捐献者基础信息,而非仅 infoid + assessannex
    buildConfirmationRecord(infoid, assessannex) {
      const f = this.formData;
      return {
        infoid,
        caseNo: f.caseNo || "",
        name: f.name || "",
        sex: f.sex || "",
        age: f.age != null ? f.age : "",
        diagnosisname: f.diagnosisname || "",
        treatmenthospitalname: f.treatmenthospitalname || "",
        relativeconfirmationsign: "0",
        state: 2,
        assessannex
      };
    },
    handleClose() {
      console.log("关闭弹框");
      this.isEdit = false;
@@ -1269,6 +1651,7 @@
      this.formData = this.getDefaultFormData();
      this.residenceAddress = {};
      this.registerAddress = {};
      this.resetAttachments();
      this.$emit("closed");
    },
@@ -1297,6 +1680,7 @@
        const result = await updateDonatebaseinfo(submitData);
        if (result.code === 200) {
          await this.saveAssessannex();
          this.$message.success(this.isEdit ? "更新成功" : "新增成功");
          this.$emit("success", result.data);
          console.log(1122);
@@ -1366,79 +1750,6 @@
      return data;
    },
    /** åŠ è½½ä¸ŠæŠ¥æ¡ˆä¾‹é™„ä»¶ */
    async loadReportAttachments(reportId) {
      this.reportAttachmentLoading = true;
      try {
        const res = await donateInfo(reportId);
        const data = res.data || res;
        this.reportAttachments = (data.annexfilesList || []).map(item => ({
          ...item,
          fileType: item.fileType || item.filetype || "" // å…¼å®¹å­—段大小写
        }));
      } catch (error) {
        console.error("加载上报附件失败:", error);
        this.$message.error("加载上报附件失败");
      } finally {
        this.reportAttachmentLoading = false;
      }
    },
    /** èŽ·å–æŸåˆ†ç±»æ–‡ä»¶æ•°é‡ */
    getReportCategoryCount(category) {
      return this.reportAttachments.filter(item => {
        const type = item.fileType || "";
        if (category === "未分类") {
          return !this.presetCategories.includes(type);
        }
        return type === category;
      }).length;
    },
    /** èŽ·å–æŸåˆ†ç±»æ–‡ä»¶åˆ—è¡¨ */
    getReportCategoryFiles(category) {
      return this.reportAttachments.filter(item => {
        const type = item.fileType || "";
        if (category === "未分类") {
          return !this.presetCategories.includes(type);
        }
        return type === category;
      });
    },
    /** é¢„览上报附件(直接在新窗口打开) */
    handleReportPreview(file) {
      const url = file.fileUrl || file.path;
      if (url) {
        window.open(url, "_blank");
      } else {
        this.$message.warning("文件地址不存在");
      }
    },
    /** èŽ·å–æ–‡ä»¶ç±»åž‹ï¼ˆç”¨äºŽæ ‡ç­¾æ˜¾ç¤ºï¼‰ */
    getFileType(fileName) {
      if (!fileName) return "other";
      const extension = fileName
        .split(".")
        .pop()
        .toLowerCase();
      const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
      const pdfTypes = ["pdf"];
      const officeTypes = ["doc", "docx", "xls", "xlsx"];
      if (imageTypes.includes(extension)) return "image";
      if (pdfTypes.includes(extension)) return "pdf";
      if (officeTypes.includes(extension)) return "office";
      return "other";
    },
    /** æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–(复用) */
    formatDateTime(dateTime) {
      if (!dateTime) return "";
      return this.$moment
        ? this.$moment(dateTime).format("YYYY-MM-DD HH:mm:ss")
        : dateTime;
    }
  }
};
</script>
@@ -1451,4 +1762,21 @@
.form-section:last-child {
  margin-bottom: 0;
}
.attachment-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}
.upload-title {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
}
.empty-attachment {
  padding: 12px 0;
}
</style>
src/views/project/donatebaseinfo/index.vue
@@ -73,7 +73,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:donatebaseinfo:export']"
        >
          å¯¼å‡º
        </el-button>
@@ -157,7 +156,7 @@
          />
        </template>
      </el-table-column>
      <el-table-column
      <!-- <el-table-column
        label="捐献类别"
        align="center"
        prop="donationcategory"
@@ -169,7 +168,7 @@
            :value="scope.row.donationcategory"
          />
        </template>
      </el-table-column>
      </el-table-column> -->
      <el-table-column label="传染病" align="center" prop="infectious">
        <template slot-scope="scope">
          <span v-for="item in scope.row.infectious.split(',')"
@@ -178,12 +177,12 @@
        </template>
      </el-table-column>
      <el-table-column label="疾病诊断" align="center" prop="diagnosisname" />
      <el-table-column
      <!-- <el-table-column
        label="协调员"
        align="center"
        prop="coordinatorName"
        width="100"
      />
      /> -->
      <el-table-column
        label="上报时间"
        align="center"
@@ -207,7 +206,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:donatebaseinfo:edit']"
          >
            è¯¦æƒ…
          </el-button>
@@ -217,7 +215,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleOpenEdit(scope.row)"
            v-hasPermi="['project:donatebaseinfo:edit']"
            v-if="scope.row.recordstate !== '4'"
          >
            ç¼–辑
src/views/project/donateconsolationfund/index.vue
@@ -130,7 +130,6 @@
                  icon="el-icon-plus"
                  size="mini"
                  @click="handleAdd"
                  v-hasPermi="['project:donateconsolationfund:add']"
                  >新增</el-button
                >
              </el-col>
@@ -142,7 +141,6 @@
                  size="mini"
                  :loading="exportLoading"
                  @click="handleExport"
                  v-hasPermi="['project:donateconsolationfund:export']"
                  >导出</el-button
                >
              </el-col>
@@ -261,7 +259,6 @@
                      type="text"
                      icon="el-icon-edit"
                      @click="handleUpdate(scope.row)"
                      v-hasPermi="['project:donateconsolationfund:edit']"
                      >修改</el-button
                    >
                    <el-button
@@ -269,7 +266,6 @@
                      type="text"
                      icon="el-icon-delete"
                      @click="handleDelete(scope.row)"
                      v-hasPermi="['project:donateconsolationfund:remove']"
                      >删除</el-button
                    >
                    <el-button
@@ -277,7 +273,6 @@
                      type="text"
                      icon="el-icon-download"
                      @click="totaldayin(scope.row.id)"
                      v-hasPermi="['project:donateconsolationfund:download']"
                      >下载</el-button
                    >
                    <el-button
@@ -285,7 +280,6 @@
                      type="text"
                      icon="el-icon-download"
                      @click="dayin(scope.row.id)"
                      v-hasPermi="['project:donateconsolationfund:download']"
                      >专家费打印</el-button
                    >
                    <el-button
@@ -293,7 +287,6 @@
                      type="text"
                      icon="el-icon-download"
                      @click="dayin2(scope.row.id)"
                      v-hasPermi="['project:donateconsolationfund:download']"
                      >医学成本打印</el-button
                    >
                    <!-- æ–°å¢žå®¡æ ¸é¡µé¢ -->
@@ -302,7 +295,6 @@
                      type="text"
                      icon="el-icon-edit"
                      @click="tojust(scope.row.id)"
                      v-hasPermi="['project:donateconsolationfund:edit']"
                      >审核</el-button
                    >
                  </template>
src/views/project/donatefinish/index.vue
@@ -240,7 +240,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleAdd(scope.row)"
            v-hasPermi="['project:donatebaseinfo:edit']"
            >修改</el-button
          >
src/views/project/donatefollowup/index.vue
@@ -75,7 +75,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:donatefollowup:add']"
          >新增</el-button
        >
      </el-col>
@@ -87,7 +86,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:donatefollowup:edit']"
          >修改</el-button
        >
      </el-col>
@@ -99,7 +97,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:donatefollowup:remove']"
          >删除</el-button
        >
      </el-col>
@@ -111,7 +108,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:donatefollowup:export']"
          >导出</el-button
        >
      </el-col>
@@ -219,7 +215,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleAdd(scope.row)"
            v-hasPermi="['project:donatefollowup:edit']"
            >添加</el-button
          >
          <el-button
@@ -228,7 +223,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:donatefollowup:edit']"
            >修改</el-button
          >
          <el-button
@@ -236,7 +230,6 @@
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:donatefollowup:remove']"
            >删除</el-button
          >
        </template>
src/views/project/donateorgan/index.vue
@@ -295,13 +295,12 @@
      <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width" width="100">
        <template slot-scope="scope">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
            v-hasPermi="['project:donateorgan:edit']">修改</el-button>
>修改</el-button>
          <!-- <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:donateorgan:remove']"
            >删除</el-button
          > -->
        </template>
src/views/project/donateorganstatics/index.vue
@@ -379,7 +379,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:donateorganstatics:add']"
          >新增</el-button
        >
      </el-col>
@@ -391,7 +390,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:donateorganstatics:edit']"
          >修改</el-button
        >
      </el-col>
@@ -403,7 +401,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:donateorganstatics:remove']"
          >删除</el-button
        >
      </el-col>
@@ -415,7 +412,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['system:donateorganstatics:export']"
          >导出</el-button
        >
      </el-col>
@@ -557,7 +553,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:donateorganstatics:edit']"
            >修改</el-button
          >
          <el-button
@@ -565,7 +560,6 @@
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:donateorganstatics:remove']"
            >删除</el-button
          >
        </template>
src/views/project/donatereview/index.vue
@@ -197,7 +197,6 @@
            type="text"
            icon="el-icon-view"
            @click="handleShow(scope.row)"
            v-hasPermi="['project:donatebaseinfo:edit']"
            >查看</el-button
          >
          <el-button
@@ -209,7 +208,6 @@
            size="mini"
            type="text"
            icon="el-icon-refrigerator"
            v-hasPermi="['project:donatebaseinfo:edit']"
            @click="getReview(scope.row)"
            >审核</el-button
          >
@@ -219,7 +217,6 @@
            type="text"
            icon="el-icon-thumb"
            @click="reject(scope.row)"
            v-hasPermi="['project:donatebaseinfo:edit']"
            >审核拒绝</el-button
          > -->
          <!-- æ’¤é”€ç”³è¯· -->
src/views/project/donationwitness/index.vue
@@ -249,7 +249,6 @@
              type="text"
              icon="el-icon-edit"
              @click="submitRecord(scope.row)"
              v-hasPermi="['project:donatebaseinfo:edit']"
              >上报伦理审查</el-button> -->
          <el-button
            size="mini"
src/views/project/donorcharge/donorcharge/index.vue
@@ -22,19 +22,19 @@
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
          v-hasPermi="['system:donorcharge:add']">新增</el-button>
>新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
          v-hasPermi="['system:donorcharge:edit']">修改</el-button>
>修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
          v-hasPermi="['system:donorcharge:remove']">删除</el-button>
>删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="warning" plain icon="el-icon-download" size="mini" :loading="exportLoading" @click="handleExport"
          v-hasPermi="['system:donorcharge:export']">导出</el-button>
>导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>
@@ -56,11 +56,11 @@
      <el-table-column label="操作" align="center">
        <template slot-scope="scope">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
            v-hasPermi="['system:donorcharge:edit']">修改</el-button>
>修改</el-button>
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleDetail(scope.row)"
            v-hasPermi="['system:donorcharge:edit']">详情</el-button>
>详情</el-button>
          <el-button size="mini" type="text" @click="handleDelete(scope.row)"
            v-hasPermi="['system:donorcharge:remove']"><span class="button-delete"
><span class="button-delete"
              ><i class="el-icon-delete"></i>删除</span
            ></el-button>
        </template>
src/views/project/donorcharge/organcharge/index.vue
@@ -42,7 +42,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:organcharge:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -53,7 +52,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:organcharge:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -64,7 +62,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:organcharge:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -75,7 +72,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['system:organcharge:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -94,14 +90,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:organcharge:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:organcharge:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/project/ethicalReview/index.vue
@@ -349,7 +349,6 @@
                    type="text"
                    icon="el-icon-edit"
                    @click="handleUpdateExpert(scope.row)"
                    v-hasPermi="['project:ethicalreviewopinions:edit']"
                    >修改</el-button
                  >
                  <el-button
@@ -357,7 +356,6 @@
                    type="text"
                    icon="el-icon-delete"
                    @click="handleDeleteExpert(scope.row)"
                    v-hasPermi="['project:ethicalreviewopinions:remove']"
                    >删除</el-button
                  >
                </template>
src/views/project/externalperson/index.vue
@@ -64,7 +64,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:externalperson:add']"
          >新增</el-button
        >
      </el-col>
@@ -76,7 +75,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:externalperson:edit']"
          >修改</el-button
        >
      </el-col>
@@ -88,7 +86,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:externalperson:remove']"
          >删除</el-button
        >
      </el-col>
@@ -100,7 +97,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:externalperson:export']"
          >导出</el-button
        >
      </el-col>
@@ -164,7 +160,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:externalperson:edit']"
            >修改</el-button
          >
          <el-button
src/views/project/financesubject/index.vue
@@ -25,19 +25,19 @@
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
          v-hasPermi="['project:financesubject:add']">新增</el-button>
>新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
          v-hasPermi="['project:financesubject:edit']">修改</el-button>
>修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
          v-hasPermi="['project:financesubject:remove']">删除</el-button>
>删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="warning" plain icon="el-icon-download" size="mini" :loading="exportLoading" @click="handleExport"
          v-hasPermi="['project:financesubject:export']">导出</el-button>
>导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>
src/views/project/fund/ethicalExpertFeeApply/index.vue
@@ -125,7 +125,6 @@
                  icon="el-icon-plus"
                  size="mini"
                  @click="handleAdd"
                  v-hasPermi="['project:ethicalfund:add']"
                  >新增申请单</el-button
                >
              </el-col>
@@ -230,7 +229,6 @@
                      type="text"
                      icon="el-icon-edit"
                      @click="handleUpdate(scope.row)"
                      v-hasPermi="['project:ethicalfund:edit']"
                      >修改</el-button
                    >
                    <el-button
@@ -248,7 +246,6 @@
                      size="mini"
                      type="text"
                      @click="handleDelete(scope.row)"
                      v-hasPermi="['project:ethicalfund:delete']"
                      ><span class="button-delete"
                        ><i class="el-icon-delete"></i>删除</span
                      ></el-button
@@ -258,7 +255,6 @@
                      type="text"
                      icon="el-icon-download"
                      @click="mixExport(scope.row.id)"
                      v-hasPermi="['project:ethicalfund:download']"
                      >下载</el-button
                    >
                  </template>
src/views/project/fund/expertFeeApply/index.vue
@@ -123,7 +123,6 @@
                  icon="el-icon-plus"
                  size="mini"
                  @click="handleAdd"
                  v-hasPermi="['project:expretfund:add']"
                  >新增申请单</el-button
                >
              </el-col>
@@ -244,7 +243,7 @@
                      @click="handleDetail(scope.row)"
                      >查看</el-button
                    >
                    <!-- v-hasPermi="['project:expretfund:edit']" -->
                    <!-- -->
                    <el-button
                      v-if="
                        scope.row.recordstatus == -1 ||
@@ -257,7 +256,7 @@
                        ><i class="el-icon-delete"></i>删除</span
                      ></el-button
                    >
                    <!-- v-hasPermi="['project:expretfund:delete']" -->
                    <!-- -->
                    <!-- <el-button
                      size="mini"
                      type="text"
@@ -265,7 +264,7 @@
                      @click="mixExport(scope)"
                      >下载</el-button
                                          > -->
                    <!-- v-hasPermi="['project:expretfund:download']" -->
                    <!-- -->
                  </template>
                </el-table-column>
                <el-table-column
src/views/project/fund/index.vue
@@ -45,19 +45,19 @@
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
          v-hasPermi="['project:fund:add']">新增</el-button>
>新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
          v-hasPermi="['project:fund:edit']">修改</el-button>
>修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
          v-hasPermi="['project:fund:remove']">删除</el-button>
>删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="warning" plain icon="el-icon-download" size="mini" :loading="exportLoading" @click="handleExport"
          v-hasPermi="['project:fund:export']">导出</el-button>
>导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>
@@ -101,9 +101,9 @@
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
            v-hasPermi="['project:fund:edit']">修改</el-button>
>修改</el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
            v-hasPermi="['project:fund:remove']">删除</el-button>
>删除</el-button>
        </template>
      </el-table-column>
    </el-table>
src/views/project/fund/medicalCostApply/index.vue
@@ -114,7 +114,6 @@
                  icon="el-icon-plus"
                  size="mini"
                  @click="handleAdd"
                  v-hasPermi="['project:medicalfund:add']"
                  >新增申请单</el-button
                >
              </el-col>
@@ -219,7 +218,6 @@
                      type="text"
                      icon="el-icon-edit"
                      @click="handleUpdate(scope.row)"
                      v-hasPermi="['project:medicalfund:edit']"
                      >修改</el-button
                    >
                    <el-button
@@ -237,7 +235,6 @@
                      size="mini"
                      type="text"
                      @click="handleDelete(scope.row)"
                      v-hasPermi="['project:medicalfund:delete']"
                      ><span class="button-delete"
                        ><i class="el-icon-delete"></i>删除</span
                      ></el-button
@@ -247,7 +244,6 @@
                      type="text"
                      icon="el-icon-download"
                      @click="mixExport(scope.row.id)"
                      v-hasPermi="['project:medicalfund:download']"
                      >下载</el-button
                    >
                  </template>
src/views/project/fund/officeExpenseApply/index.vue
@@ -71,7 +71,7 @@
          @click="handleAdd"
          >新增</el-button
        >
        <!-- v-hasPermi="['project:medicalfund:add']" -->
        <!-- -->
      </el-col>
      <el-col :span="1.5">
        <el-button
@@ -84,7 +84,7 @@
          >导出</el-button
        >
      </el-col>
      <!-- v-hasPermi="['project:medicalfund:export']" -->
      <!-- -->
      <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> -->
    </el-row>
    <el-table
@@ -180,7 +180,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:medicalfund:edit']"
            >修改</el-button
          >
          <el-button
@@ -195,7 +194,6 @@
            size="mini"
            type="text"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:medicalfund:delete']"
            ><span class="button-delete"
              ><i class="el-icon-delete"></i>删除</span
            ></el-button
@@ -205,7 +203,6 @@
            type="text"
            icon="el-icon-download"
            @click="mixExport(scope.row.id)"
            v-hasPermi="['project:medicalfund:download']"
            >下载</el-button
          >
        </template>
src/views/project/fund/performanceApply/index.vue
@@ -88,7 +88,7 @@
          @click="handleAdd"
          >新增</el-button
        >
        <!-- v-hasPermi="['project:medicalfund:add']" -->
        <!-- -->
      </el-col>
      <el-col :span="1.5">
        <el-button
@@ -101,7 +101,7 @@
          >导出</el-button
        >
      </el-col>
      <!-- v-hasPermi="['project:medicalfund:export']" -->
      <!-- -->
      <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> -->
    </el-row>
    <el-table
@@ -195,7 +195,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:medicalfund:edit']"
            >修改</el-button
          >
@@ -211,7 +210,6 @@
            size="mini"
            type="text"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:medicalfund:delete']"
            ><span class="button-delete"
              ><i class="el-icon-delete"></i>删除</span
            ></el-button
@@ -221,7 +219,6 @@
            type="text"
            icon="el-icon-download"
            @click="mixExport(scope.row.id)"
            v-hasPermi="['project:medicalfund:download']"
            >下载</el-button
          >
          <el-button
src/views/project/fundcheck/ethicalExpertFeeCheck/index.vue
@@ -252,7 +252,7 @@
                @click="handleCheck(scope.row)"
                >审核</el-button
              >
              <!-- v-hasPermi="['project:donateconsolationfund:edit']" -->
              <!-- -->
              <el-button
                size="mini"
                type="text"
@@ -615,7 +615,6 @@
                  "
                  type="text"
                  size="small"
                  v-hasPermi="['project:ethicFeeCheck:delete']"
                >
                  åˆ é™¤
                </el-button>
src/views/project/fundcheck/expertFeeCheck/index.vue
@@ -144,7 +144,7 @@
              <el-button v-if="scope.row.checkFlag == 1" size="mini" type="text" icon="el-icon-edit"
                @click="handleCheck(scope.row)">审核</el-button>
              <!-- v-hasPermi="['project:donateconsolationfund:edit']" -->
              <!-- -->
              <el-button size="mini" type="text" icon="el-icon-download"
                @click="totaldayin(scope.row.id)">下载</el-button>
            </template>
@@ -355,7 +355,7 @@
                </el-button>
                <el-button @click.native.prevent="
                  deleteRows(scope.row, scope.$index, fundDetailArr)
                  " type="text" size="small" v-hasPermi="['project:expertFeeCheck:delete']">
                  " type="text" size="small">
                  åˆ é™¤
                </el-button>
              </template>
src/views/project/fundcheck/medicalCostCheck/index.vue
@@ -113,11 +113,11 @@
            <template slot-scope="scope">
              <el-button v-if="scope.row.checkFlag == 1" size="mini" type="text" icon="el-icon-edit"
                @click="handleCheck(scope.row)">审核</el-button>
              <!-- v-hasPermi="['project:donateconsolationfund:edit']" -->
              <!-- -->
              <el-button size="mini" type="text" icon="el-icon-edit" @click="handleDetail(scope.row)">详情</el-button>
              <el-button size="mini" type="text" icon="el-icon-download"
                @click="totaldayin(scope.row.id)">下载</el-button>
              <!-- v-hasPermi="['project:donateconsolationfund:download']" -->
              <!-- -->
              <!-- æ–°å¢žå®¡æ ¸é¡µé¢ -->
              <!-- <el-button
@@ -125,7 +125,6 @@
                type="text"
                icon="el-icon-edit"
                @click="tojust(scope.row.id)"
                v-hasPermi="['project:donateconsolationfund:edit']"
                >测试审核</el-button
              > -->
            </template>
@@ -370,7 +369,7 @@
                </el-button>
                <el-button @click.native.prevent="
                  deleteRows(scope.row, scope.$index, fundDetailArr)
                  " type="text" size="small" v-hasPermi="['project:costFeeCheck:delete']">
                  " type="text" size="small">
                  åˆ é™¤
                </el-button>
              </template>
src/views/project/fundcheck/officeExpenseCheck/index.vue
@@ -257,7 +257,7 @@
                @click="handleCheck(scope.row)"
                >审核</el-button
              >
              <!-- v-hasPermi="['project:donateconsolationfund:edit']" -->
              <!-- -->
              <el-button
                size="mini"
                type="text"
@@ -265,7 +265,7 @@
                @click="totaldayin(scope.row.id)"
                >下载</el-button
              >
              <!-- v-hasPermi="['project:donateconsolationfund:download']" -->
              <!-- -->
              <!-- æ–°å¢žå®¡æ ¸é¡µé¢ -->
              <!-- <el-button
@@ -273,7 +273,6 @@
                type="text"
                icon="el-icon-edit"
                @click="tojust(scope.row.id)"
                v-hasPermi="['project:donateconsolationfund:edit']"
                >测试审核</el-button
              > -->
            </template>
@@ -762,7 +761,6 @@
                  "
                  type="text"
                  size="small"
                  v-hasPermi="['project:costFeeCheck:delete']"
                >
                  åˆ é™¤
                </el-button>
src/views/project/fundcheck/performanceCheck/index.vue
@@ -87,9 +87,9 @@
              <el-button v-if="scope.row.checkFlag == 1" size="mini" type="text" icon="el-icon-edit"
                @click="handleCheck(scope.row)">审核</el-button>
              <!-- v-hasPermi="['project:donateconsolationfund:edit']" -->
              <!-- -->
              <el-button size="mini" type="text" icon="el-icon-download" @click="totaldayin(scope.row.id)"
                v-hasPermi="['project:donateconsolationfund:download']">下载</el-button>
>下载</el-button>
            </template>
          </el-table-column>
        </el-table>
src/views/project/funddetail/index.vue
@@ -46,19 +46,19 @@
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
          v-hasPermi="['project:funddetail:add']">新增</el-button>
>新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
          v-hasPermi="['project:funddetail:edit']">修改</el-button>
>修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
          v-hasPermi="['project:funddetail:remove']">删除</el-button>
>删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="warning" plain icon="el-icon-download" size="mini" :loading="exportLoading" @click="handleExport"
          v-hasPermi="['project:funddetail:export']">导出</el-button>
>导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>
@@ -84,9 +84,9 @@
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
            v-hasPermi="['project:funddetail:edit']">修改</el-button>
>修改</el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
            v-hasPermi="['project:funddetail:remove']">删除</el-button>
>删除</el-button>
        </template>
      </el-table-column>
    </el-table>
src/views/project/fundflow/index.vue
@@ -73,7 +73,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:fundflow:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -84,7 +83,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:fundflow:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -95,7 +93,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:fundflow:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -106,7 +103,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:fundflow:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -140,7 +136,7 @@
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
          >修改</el-button>
            <!-- v-hasPermi="['project:fundflow:edit']" -->
            <!-- -->
          <el-button
            size="mini"
            type="text"
@@ -148,7 +144,7 @@
            @click="handleDelete(scope.row)"
          >删除</el-button>
        </template>
            <!-- v-hasPermi="['project:fundflow:remove']" -->
            <!-- -->
      </el-table-column>
    </el-table>
    
src/views/project/fundflowrule/index.vue
@@ -126,7 +126,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:fundflowrule:add']"
          >新增</el-button
        >
      </el-col>
@@ -138,7 +137,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:fundflowrule:edit']"
          >修改</el-button
        >
      </el-col>
@@ -150,7 +148,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:fundflowrule:remove']"
          >删除</el-button
        >
      </el-col>
@@ -162,7 +159,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:fundflowrule:export']"
        >导出</el-button>
      </el-col> -->
      <right-toolbar
@@ -274,7 +270,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:fundflowrule:edit']"
            >修改</el-button
          >
          <el-button
@@ -282,7 +277,6 @@
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:fundflowrule:remove']"
            >删除</el-button
          >
        </template>
src/views/project/fundstatistics/index.vue
@@ -123,7 +123,6 @@
                type="text"
                icon="el-icon-download"
                @click="exportSummary(scope.row.id)"
                v-hasPermi="['project:fundstatistics:summaryexoprt']"
                >导出</el-button
              >
              <el-button
@@ -131,7 +130,6 @@
                type="text"
                icon="el-icon-edit"
                @click="jumptocost(scope.row)"
                v-hasPermi="['project:fundstatistics:list']"
                >查看成本汇总</el-button
              >
            </template>
src/views/project/itemexpense/index.vue
@@ -51,7 +51,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:itemexpense:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -62,7 +61,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:itemexpense:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -73,7 +71,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:itemexpense:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -84,7 +81,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:itemexpense:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -105,14 +101,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:itemexpense:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:itemexpense:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/project/organallocation/index0.vue
@@ -134,15 +134,15 @@
      <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width" >
        <template slot-scope="scope">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleAdd(scope.row)"
            v-hasPermi="['project:donateorgan:edit']">新增</el-button>
>新增</el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleEdit(scope.row)"
            v-hasPermi="['project:donateorgan:remove']">修改</el-button>
>修改</el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
            v-hasPermi="['project:donateorgan:remove']">删除</el-button>
>删除</el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleRedo(scope.row)"
            v-hasPermi="['project:donateorgan:remove']">重新分配</el-button>
>重新分配</el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleSave(scope.row)"
            v-hasPermi="['project:donateorgan:remove']">保存</el-button>
>保存</el-button>
        </template>
      </el-table-column>
    </el-table>
src/views/project/organization/index.vue
@@ -283,10 +283,38 @@
            </el-form-item>
          </el-col>
          <el-col :span="10">
            <el-form-item label="协调员" prop="coordinator">
            <el-form-item label="协调员姓名" prop="coordinatorName">
              <el-input
                v-model="form.coordinator"
                placeholder="请输入机构协调员"
                v-model="form.coordinatorName"
                placeholder="请输入协调员姓名"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="10">
            <el-form-item label="协调员编号" prop="coordinatorNo">
              <el-input
                v-model="form.coordinatorNo"
                placeholder="请输入协调员编号"
              />
            </el-form-item>
          </el-col>
          <el-col :span="10">
            <el-form-item label="上报人员姓名" prop="reporterName">
              <el-input
                v-model="form.reporterName"
                placeholder="请输入上报人员姓名"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="10">
            <el-form-item label="上报人员编号" prop="reporterNo">
              <el-input
                v-model="form.reporterNo"
                placeholder="请输入上报人员编号"
              />
            </el-form-item>
          </el-col>
@@ -399,7 +427,7 @@
        pageSize: 10,
        organizationname: null,
        organizationtype: null,
        province: null
        regionallevel: null
      },
      initregionallevel: "",
      inithospitalnature: "",
@@ -451,6 +479,10 @@
        legalperson: null,
        contactperson: null,
        contactnumber: null,
        coordinatorName: null,
        coordinatorNo: null,
        reporterName: null,
        reporterNo: null,
        introduction: null,
        organizationtype: null,
        hospitalnature: null,
src/views/project/reimbursement/index.vue
@@ -73,7 +73,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:reimbursement:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -84,7 +83,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:reimbursement:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -95,7 +93,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:reimbursement:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -106,7 +103,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:reimbursement:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -156,14 +152,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:reimbursement:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:reimbursement:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/project/reimbursementdetail/index.vue
@@ -49,7 +49,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:reimbursementdetail:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -60,7 +59,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:reimbursementdetail:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -71,7 +69,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:reimbursementdetail:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -82,7 +79,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:reimbursementdetail:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -129,14 +125,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:reimbursementdetail:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:reimbursementdetail:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/project/reimbursementpayee/index.vue
@@ -117,7 +117,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:reimbursementpayee:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -128,7 +127,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:reimbursementpayee:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -139,7 +137,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:reimbursementpayee:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -150,7 +147,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:reimbursementpayee:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -187,14 +183,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:reimbursementpayee:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:reimbursementpayee:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/project/relativesconfirmation/index.vue
@@ -224,7 +224,6 @@
              type="text"
              icon="el-icon-edit"
              @click="submitRecord(scope.row)"
              v-hasPermi="['project:donatebaseinfo:edit']"
              >上报伦理审查</el-button> -->
        </template>
      </el-table-column>
src/views/project/tallage/computingBill/index.vue
@@ -236,7 +236,6 @@
                <el-button
                  type="text"
                  @click="handleDelete(scope.row)"
                  v-hasPermi="['system:donorcharge:remove']"
                  ><span class="button-delete"
                    ><i class="el-icon-delete"></i>删除</span
                  ></el-button
@@ -245,7 +244,6 @@
                  type="text"
                  icon="el-icon-folder-opened"
                  @click="Filepopup(scope.$index, scope.row)"
                  v-hasPermi="['system:donorcharge:edit']"
                  >附件</el-button
                > -->
              </template>
src/views/project/tallage/index.vue
@@ -50,7 +50,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:donorcharge:add']"
          >新增</el-button
        >
      </el-col>
@@ -62,7 +61,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:donorcharge:remove']"
          >删除</el-button
        >
      </el-col>
@@ -124,7 +122,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:donorcharge:edit']"
            >修改</el-button
          >
          <el-button
@@ -132,14 +129,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleDetail(scope.row)"
            v-hasPermi="['system:donorcharge:edit']"
            >详情</el-button
          >
          <el-button
            size="mini"
            type="text"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:donorcharge:remove']"
            ><span class="button-delete"
              ><i class="el-icon-delete"></i>删除</span
            ></el-button
src/views/project/travelexpenseapply/index.vue
@@ -103,7 +103,7 @@
        <el-button type="primary" plain icon="el-icon-plus" @click="handleAdd"
          >新增</el-button
        >
        <!-- v-hasPermi="['project:funddetail:add']" -->
        <!-- -->
      </el-col>
      <el-col :span="1.5">
        <el-button
@@ -115,7 +115,7 @@
          >导出</el-button
        >
      </el-col>
      <!-- v-hasPermi="['project:funddetail:export']" -->
      <!-- -->
      <right-toolbar
        :showSearch.sync="showSearch"
        @queryTable="getList"
@@ -244,7 +244,7 @@
            @click="handleDetail(scope.row)"
            >查看</el-button
          >
          <!-- v-hasPermi="['project:funddetail:edit']" -->
          <!-- -->
          <el-button
            size="mini"
            type="text"
@@ -253,7 +253,7 @@
          >
            ä¸‹è½½
          </el-button>
          <!-- v-hasPermi="['project:funddetail:edit']" -->
          <!-- -->
          <el-button
            v-if="scope.row.recordstatus == -1 || scope.row.recordstatus == 1"
            size="mini"
@@ -263,7 +263,7 @@
              ><i class="el-icon-delete"></i>删除</span
            ></el-button
          >
          <!-- v-hasPermi="['project:funddetail:remove']" -->
          <!-- -->
        </template>
      </el-table-column>
      <el-table-column fixed="right" align="center" width="120" label="功能">
@@ -281,7 +281,7 @@
        </template>
      </el-table-column>
    </el-table>
    <!-- v-hasPermi="['project:donateconsolationfund:edit']" -->
    <!-- -->
    <pagination
      v-show="total > 0"
src/views/project/travelexpensecheck/index.vue
@@ -137,7 +137,7 @@
          >导出</el-button
        >
      </el-col>
      <!-- v-hasPermi="['project:funddetail:export']" -->
      <!-- -->
      <right-toolbar
        :showSearch.sync="showSearch"
        @queryTable="getList"
@@ -265,7 +265,7 @@
            @click="handleShow(scope.row)"
            >详情</el-button
          >
          <!-- v-hasPermi="['project:funddetail:edit']" -->
          <!-- -->
          <el-button
            size="mini"
            type="text"
@@ -274,7 +274,7 @@
          >
            ä¸‹è½½
          </el-button>
          <!-- v-hasPermi="['project:funddetail:edit']" -->
          <!-- -->
          <el-button
            size="mini"
            type="text"
@@ -283,11 +283,11 @@
            @click="handleDelete(scope.row)"
            >删除</el-button
          >
          <!-- v-hasPermi="['project:funddetail:remove']" -->
          <!-- -->
        </template>
      </el-table-column>
    </el-table>
    <!-- v-hasPermi="['project:donateconsolationfund:edit']" -->
    <!-- -->
    <pagination
      v-show="total > 0"
      :total="total"
src/views/project/travelexpensedeal/index.vue
@@ -83,7 +83,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:funddetail:add']"
          >新增</el-button
        >
      </el-col>
@@ -95,7 +94,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:funddetail:edit']"
          >修改</el-button
        >
      </el-col>
@@ -107,7 +105,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['project:funddetail:remove']"
          >删除</el-button
        >
      </el-col>
@@ -119,7 +116,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:funddetail:export']"
          >导出</el-button
        >
      </el-col>
@@ -193,7 +189,6 @@
            type="text"
            icon="el-icon-view"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:funddetail:edit']"
            >查看</el-button
          >
          <el-button
@@ -201,7 +196,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:funddetail:edit']"
            >修改</el-button
          >
          <el-button
@@ -209,7 +203,6 @@
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:funddetail:remove']"
            >删除</el-button
          >
        </template>
src/views/project/unitCost/index.vue
@@ -21,15 +21,15 @@
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
          v-hasPermi="['system:donorcharge:add']">新增</el-button>
>新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
          v-hasPermi="['system:donorcharge:edit']">修改</el-button>
>修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
          v-hasPermi="['system:donorcharge:remove']">删除</el-button>
>删除</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -59,11 +59,11 @@
      <el-table-column label="操作" width="280" align="center">
        <template slot-scope="scope">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
            v-hasPermi="['system:donorcharge:edit']">修改</el-button>
>修改</el-button>
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleDetail(scope.row)"
            v-hasPermi="['system:donorcharge:edit']">详情</el-button>
>详情</el-button>
          <el-button size="mini" type="text" @click="handleDelete(scope.row)"
            v-hasPermi="['system:donorcharge:remove']"><span class="button-delete"><i
><span class="button-delete"><i
                class="el-icon-delete"></i>删除</span></el-button>
          <el-button size="mini" type="primary" @click="download(scope.row.id)" icon="el-icon-download"
            circle></el-button>
src/views/project/unitCost/particulars/index.vue
@@ -273,7 +273,6 @@
                <el-button
                  type="text"
                  @click="handleDelete(scope.row)"
                  v-hasPermi="['system:donorcharge:remove']"
                  ><span class="button-delete"
                    ><i class="el-icon-delete"></i>删除</span
                  ></el-button
@@ -282,7 +281,6 @@
                  type="text"
                  icon="el-icon-folder-opened"
                  @click="Filepopup(scope.$index, scope.row)"
                  v-hasPermi="['system:donorcharge:edit']"
                  >附件</el-button
                >
              </template>
src/views/statistics/components/OrganDetail.vue
@@ -8,36 +8,40 @@
      border
      stripe
    >
      <el-table-column label="器官编号" prop="organNo" align="center"  />
      <el-table-column label="器官名称" prop="organName" align="center"  />
      <el-table-column label="捐献者" prop="donorName" align="center"  />
      <el-table-column label="地区" prop="region" align="center"  />
      <el-table-column label="年份" prop="year" align="center"  />
      <el-table-column label="器官状态" prop="status" align="center" >
      <el-table-column label="案例编号" prop="caseNo" align="center" />
      <el-table-column label="器官名称" prop="organName" align="center" />
      <el-table-column label="捐献者" prop="name" align="center" />
      <el-table-column label="地区" prop="registerCountyName" align="center" />
      <el-table-column label="年份" prop="donateYear" align="center" />
      <el-table-column label="器官状态" align="center">
        <template slot-scope="{ row }">
          <el-tag :type="getStatusTag(row.status)" size="small">
            {{ getStatusText(row.status) }}
          <el-tag :type="getStatusTag(row.transplantstate)" size="small">
            {{ getStatusText(row.transplantstate) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="获取时间" prop="acquisitionTime" align="center"  />
      <el-table-column label="移植时间" prop="transplantTime" align="center" >
      <el-table-column label="获取时间" align="center">
        <template slot-scope="{ row }">
          {{ row.transplantTime || '-' }}
          {{ fmtTime(row.organGetTime || row.OrganGetTime) || '-' }}
        </template>
      </el-table-column>
      <el-table-column label="弃用原因" prop="abandonReason" align="center" >
      <el-table-column label="移植时间" align="center">
        <template slot-scope="{ row }">
          {{ row.abandonReason || '-' }}
          {{ fmtTime(row.transplantTime || row.TransplantTime) || '-' }}
        </template>
      </el-table-column>
      <el-table-column label="受体姓名" prop="recipientName" align="center" >
      <el-table-column label="弃用原因" align="center">
        <template slot-scope="{ row }">
          {{ row.recipientName || '-' }}
          {{ row.notgetreason || '-' }}
        </template>
      </el-table-column>
      <el-table-column label="移植医院" prop="hospital" align="center" />
      <el-table-column label="操作医生" prop="doctor" align="center"  />
      <el-table-column label="受体姓名" align="center">
        <template slot-scope="{ row }">
          {{ row.transplantName || '-' }}
        </template>
      </el-table-column>
      <el-table-column label="移植医院" prop="hospitalName" align="center" />
      <el-table-column label="操作医生" prop="transplantDoct" align="center" />
    </el-table>
    <div style="text-align: center; margin-top: 20px;">
@@ -47,9 +51,14 @@
</template>
<script>
import { organList as getOrganList } from '@/api/businessApi';
import { toTotalsList } from '@/utils/totals';
import statisticsMode from '@/utils/statisticsMode';
export default {
  name: 'OrganDetail',
  props: {
    // ä¼ å…¥ opo统计 æŸ¥è¯¢å¯¹è±¡ï¼š{ area, startTime, endTime, organName },时间范围精确到天(yyyy-MM-dd)
    query: {
      type: Object,
      default: () => ({})
@@ -58,23 +67,52 @@
  data() {
    return {
      loading: false,
      organList: [
        { organNo: 'O202401001', organName: '全肝', donorName: '张三', region: '青岛地区', year: '2024', status: 'transplanted', acquisitionTime: '2024-01-15 10:30', transplantTime: '2024-01-15 12:45', abandonReason: '', recipientName: '王明', hospital: '青岛大学附属医院', doctor: '李医生' },
        { organNo: 'O202401002', organName: '左肾', donorName: '张三', region: '青岛地区', year: '2024', status: 'transplanted', acquisitionTime: '2024-01-15 10:30', transplantTime: '2024-01-15 13:20', abandonReason: '', recipientName: '陈强', hospital: '青岛市立医院', doctor: '张医生' },
        { organNo: 'O202401003', organName: '右肾', donorName: '张三', region: '青岛地区', year: '2024', status: 'transplanted', acquisitionTime: '2024-01-15 10:30', transplantTime: '2024-01-15 13:50', abandonReason: '', recipientName: '刘伟', hospital: '青岛市中心医院', doctor: '王医生' },
        { organNo: 'O202401004', organName: '全肝', donorName: '李四', region: '青岛地区', year: '2024', status: 'abandoned', acquisitionTime: '2024-01-20 14:20', transplantTime: null, abandonReason: '器官质量不合格', recipientName: '', hospital: '青岛市立医院', doctor: '张医生' },
        { organNo: 'O202401005', organName: '心脏', donorName: '李四', region: '青岛地区', year: '2024', status: 'transplanted', acquisitionTime: '2024-01-20 14:20', transplantTime: '2024-01-20 15:30', abandonReason: '', recipientName: '赵刚', hospital: '青岛市立医院', doctor: '张医生' }
      ]
      organList: []
    };
  },
  watch: {
    query: {
      immediate: true,
      deep: true,
      handler() {
        this.load();
      }
    }
  },
  created() {
    // æ•°æ®æº(mock/真实接口)切换时重新加载
    this.$watch(() => statisticsMode.useMock, () => this.load());
  },
  methods: {
    load() {
      this.loading = true;
      getOrganList(this.query || {})
        .then((res) => {
          this.organList = toTotalsList(res);
        })
        .catch(() => {
          this.organList = [];
        })
        .finally(() => {
          this.loading = false;
        });
    },
    // å™¨å®˜çŠ¶æ€ï¼š1已移植 2库存 3弃用
    getStatusTag(status) {
      const map = { transplanted: 'success', abandoned: 'danger', pending: 'warning' };
      const map = { 1: 'success', 2: 'warning', 3: 'danger' };
      return map[status] || 'info';
    },
    getStatusText(status) {
      const map = { transplanted: '已移植', abandoned: '已弃用', pending: '待移植' };
      const map = { 1: '已移植', 2: '库存', 3: '弃用' };
      return map[status] || '未知';
    },
    // æ—¶é—´å­—符串统一成 yyyy-MM-dd HH:mm
    fmtTime(value) {
      if (!value) return '';
      const s = String(value).replace('T', ' ');
      return s.length > 16 ? s.substring(0, 16) : s.substring(0, 10);
    }
  }
};
src/views/statistics/organ.vue
@@ -68,7 +68,7 @@
          style="float: right; margin-left: 10px;"
          type="primary"
          icon="el-icon-zoom-in"
          @click="showOrganDetail = true"
          @click="viewAllOrganDetail"
        >
          æŸ¥çœ‹å™¨å®˜æ˜Žç»†
        </el-button>
@@ -139,7 +139,7 @@
import FilterPanel from '@/components/charts/FilterPanel.vue';
import EChartsWrapper from '@/components/charts/EChartsWrapper.vue';
import OrganDetail from './components/OrganDetail.vue';
import { organ, organMoon, organType } from '@/api/businessApi';
import { organ, organMoon, organType, organTotals } from '@/api/businessApi';
import { toTotalsList, toMonth, toNum } from '@/utils/totals';
import statisticsMode from '@/utils/statisticsMode';
import { COLORS, PALETTE, axisTooltip, grid, xAxis, yAxis, legend, barSeries } from '@/utils/chartStyle';
@@ -263,10 +263,11 @@
      this.loading = true;
      try {
        const q = this.buildQuery();
        const [moonRes, typeRes, organRes] = await Promise.all([
        const [moonRes, typeRes, organRes, totalsRes] = await Promise.all([
          organMoon(q),
          organType(q),
          organ(q)
          organ(q),
          organTotals(q)
        ]);
        // èŽ·å–/移植趋势
@@ -301,8 +302,8 @@
        const start = (this.query.page - 1) * this.query.limit;
        this.tableData = all.slice(start, start + this.query.limit);
        // æ›´æ–°æ¦‚览
        this.updateOverviewData(all);
        // æ›´æ–°æ¦‚览(总获取/移植/移植率/弃用,来自 /organTotals)
        this.updateOverviewData(toTotalsList(totalsRes)[0] || {});
        // æ›´æ–°å›¾è¡¨
        this.updateCharts();
@@ -314,17 +315,17 @@
      }
    },
    // æ›´æ–°æ¦‚览数据
    updateOverviewData(data) {
      const totalAcquisition = data.reduce((sum, item) => sum + toNum(item.acquisitionCount), 0);
      const totalTransplant = data.reduce((sum, item) => sum + toNum(item.transplantCount), 0);
      const totalAbandon = data.reduce((sum, item) => sum + toNum(item.abandonCount), 0);
      const transplantRate = totalAcquisition > 0 ? ((totalTransplant / totalAcquisition) * 100).toFixed(1) : 0;
    // æ›´æ–°æ¦‚览数据(来自 /organTotals çš„æ€»èŽ·å–/总移植/总弃用,移植率=移植/获取)
    updateOverviewData(totals) {
      const totalGet = toNum(totals.totalGet);
      const totalTransplant = toNum(totals.totalTransplant);
      const totalDiscard = toNum(totals.totalDiscard);
      const transplantRate = totalGet > 0 ? ((totalTransplant / totalGet) * 100).toFixed(1) : 0;
      this.overviewData[0].value = totalAcquisition;
      this.overviewData[0].value = totalGet;
      this.overviewData[1].value = totalTransplant;
      this.overviewData[2].value = `${transplantRate}%`;
      this.overviewData[3].value = totalAbandon;
      this.overviewData[3].value = totalDiscard;
    },
    // æ›´æ–°å›¾è¡¨
@@ -424,13 +425,33 @@
      this.$message.info('导出功能开发中...');
    },
    // æŸ¥çœ‹å™¨å®˜è¯¦æƒ…
    // æŸ¥çœ‹å™¨å®˜è¯¦æƒ…(某一行:年份 + å™¨å®˜ + åœ°åŒºï¼Œæ—¶é—´èŒƒå›´ç²¾ç¡®åˆ°å¤©ï¼‰
    viewOrganDetail(row) {
      this.detailQuery = {
        year: row.year,
        organType: row.organName,
        region: row.region
      };
      const q = {};
      if (row.year) {
        q.startTime = `${row.year}-01-01`;
        q.endTime = `${row.year}-12-31`;
      }
      if (row.organName) q.organName = row.organName;
      if (row.region) q.area = row.region;
      this.detailQuery = q;
      this.showOrganDetail = true;
    },
    // æŸ¥çœ‹å…¨éƒ¨å™¨å®˜æ˜Žç»†ï¼ˆæŒ‰å½“前筛选条件,时间范围精确到天)
    viewAllOrganDetail() {
      const q = {};
      if (this.query.region && this.query.region.length) {
        q.area = this.query.region.join(',');
      }
      if (this.query.yearRange && this.query.yearRange.length === 2) {
        q.startTime = `${this.query.yearRange[0]}-01-01`;
        q.endTime = `${this.query.yearRange[1]}-12-31`;
      }
      if (this.query.organType) {
        q.organName = this.query.organType;
      }
      this.detailQuery = q;
      this.showOrganDetail = true;
    }
  }
src/views/system/class/index.vue
@@ -34,7 +34,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:class:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -45,7 +44,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:class:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -56,7 +54,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:class:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -67,7 +64,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['system:class:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -89,14 +85,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:class:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:class:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/system/config/index.vue
@@ -57,7 +57,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:config:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -68,7 +67,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:config:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -79,7 +77,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:config:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -90,7 +87,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['system:config:export']"
        >导出</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -100,7 +96,6 @@
          icon="el-icon-refresh"
          size="mini"
          @click="handleRefreshCache"
          v-hasPermi="['system:config:remove']"
        >刷新缓存</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -130,14 +125,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:config:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:config:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/system/costmaintenance/index.vue
@@ -39,7 +39,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:travelexpensestandard:add']"
          >新增</el-button
        >
      </el-col>
@@ -98,7 +97,6 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:travelexpensestandard:edit']"
            >修改</el-button
          >
          <el-button
@@ -106,7 +104,6 @@
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:travelexpensestandard:remove']"
            >删除</el-button
          >
        </template>
src/views/system/dept/index.vue
@@ -34,7 +34,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:dept:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -76,14 +75,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:dept:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-plus"
            @click="handleAdd(scope.row)"
            v-hasPermi="['system:dept:add']"
          >新增</el-button>
          <el-button
            v-if="scope.row.parentId != 0"
@@ -91,7 +88,6 @@
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:dept:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/system/dict/data.vue
@@ -44,7 +44,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:dict:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -55,7 +54,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:dict:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -66,7 +64,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:dict:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -77,7 +74,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['system:dict:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -112,14 +108,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:dict:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:dict:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/system/dict/index.vue
@@ -63,7 +63,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:dict:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -74,7 +73,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:dict:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -85,7 +83,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:dict:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -96,7 +93,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['system:dict:export']"
        >导出</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -106,7 +102,6 @@
          icon="el-icon-refresh"
          size="mini"
          @click="handleRefreshCache"
          v-hasPermi="['system:dict:remove']"
        >刷新缓存</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -141,14 +136,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:dict:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:dict:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/system/grade/index.vue
@@ -34,7 +34,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:grade:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -45,7 +44,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:grade:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -56,7 +54,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:grade:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -67,7 +64,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['system:grade:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -89,14 +85,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:grade:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:grade:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/system/medicalevalustion/index.vue
@@ -60,7 +60,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:medicalevaluation:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -71,7 +70,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:medicalevaluation:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -82,7 +80,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:medicalevaluation:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -93,7 +90,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['system:medicalevaluation:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -147,7 +143,7 @@
            icon="el-icon-edit"
            @click="handleAdd(scope.row)"
          >修改</el-button>
            <!-- v-hasPermi="['system:medicalevaluation:edit']" -->
            <!-- -->
        </template>
      </el-table-column>
src/views/system/menu/index.vue
@@ -34,7 +34,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:menu:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -82,21 +81,18 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:menu:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-plus"
            @click="handleAdd(scope.row)"
            v-hasPermi="['system:menu:add']"
          >新增</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:menu:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/system/notice/index.vue
@@ -43,7 +43,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:notice:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -54,7 +53,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:notice:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -65,7 +63,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:notice:remove']"
        >删除</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -103,14 +100,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:notice:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:notice:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/system/post/index.vue
@@ -43,7 +43,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:post:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -54,7 +53,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:post:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -65,7 +63,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:post:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -76,7 +73,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['system:post:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -105,14 +101,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:post:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:post:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/system/role/authUser.vue
@@ -35,7 +35,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="openSelectUser"
          v-hasPermi="['system:role:add']"
        >添加用户</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -46,7 +45,6 @@
          size="mini"
          :disabled="multiple"
          @click="cancelAuthUserAll"
          v-hasPermi="['system:role:remove']"
        >批量取消授权</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -84,7 +82,6 @@
            type="text"
            icon="el-icon-circle-close"
            @click="cancelAuthUser(scope.row)"
            v-hasPermi="['system:role:remove']"
          >取消授权</el-button>
        </template>
      </el-table-column>
src/views/system/role/index.vue
@@ -63,7 +63,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:role:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -74,7 +73,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:role:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -85,7 +83,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:role:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -96,7 +93,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['system:role:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -130,24 +126,22 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:role:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:role:remove']"
          >删除</el-button>
          <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:role:edit']">
          <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)">
            <span class="el-dropdown-link">
              <i class="el-icon-d-arrow-right el-icon--right"></i>更多
            </span>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item command="handleDataScope" icon="el-icon-circle-check"
                v-hasPermi="['system:role:edit']">数据权限</el-dropdown-item>
>数据权限</el-dropdown-item>
              <el-dropdown-item command="handleAuthUser" icon="el-icon-user"
                v-hasPermi="['system:role:edit']">分配用户</el-dropdown-item>
>分配用户</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </template>
src/views/system/student/index.vue
@@ -74,7 +74,6 @@
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:student:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -85,7 +84,6 @@
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:student:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -96,7 +94,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:student:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -107,7 +104,6 @@
          size="mini"
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['system:student:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -155,14 +151,12 @@
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:student:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['system:student:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
src/views/system/user/index.vue
@@ -90,7 +90,6 @@
              icon="el-icon-plus"
              size="mini"
              @click="handleAdd"
              v-hasPermi="['system:user:add']"
            >新增</el-button>
          </el-col>
          <el-col :span="1.5">
@@ -101,7 +100,6 @@
              size="mini"
              :disabled="single"
              @click="handleUpdate"
              v-hasPermi="['system:user:edit']"
            >修改</el-button>
          </el-col>
          <el-col :span="1.5">
@@ -112,7 +110,6 @@
              size="mini"
              :disabled="multiple"
              @click="handleDelete"
              v-hasPermi="['system:user:remove']"
            >删除</el-button>
          </el-col>
          <el-col :span="1.5">
@@ -122,7 +119,6 @@
              icon="el-icon-upload2"
              size="mini"
              @click="handleImport"
              v-hasPermi="['system:user:import']"
            >导入</el-button>
          </el-col>
          <el-col :span="1.5">
@@ -133,7 +129,6 @@
              size="mini"
              :loading="exportLoading"
              @click="handleExport"
              v-hasPermi="['system:user:export']"
            >导出</el-button>
          </el-col>
@@ -175,31 +170,28 @@
                class="el-xg"
                icon="el-icon-help"
                @click="handleunlock(scope.row)"
                v-hasPermi="['system:user:edit']"
              >解锁</el-button>
              <el-button
                size="mini"
                type="text"
                icon="el-icon-edit"
                @click="handleUpdate(scope.row)"
                v-hasPermi="['system:user:edit']"
              >修改</el-button>
              <el-button
                size="mini"
                type="text"
                icon="el-icon-delete"
                @click="handleDelete(scope.row)"
                v-hasPermi="['system:user:remove']"
              >删除</el-button>
              <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']">
              <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)">
                <span class="el-dropdown-link">
                  <i class="el-icon-d-arrow-right el-icon--right"></i>更多
                </span>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item command="handleResetPwd" icon="el-icon-key"
                    v-hasPermi="['system:user:resetPwd']">重置密码</el-dropdown-item>
>重置密码</el-dropdown-item>
                  <el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check"
                    v-hasPermi="['system:user:edit']">分配角色</el-dropdown-item>
>分配角色</el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </template>
@@ -217,8 +209,8 @@
    </el-row>
    <!-- æ·»åŠ æˆ–ä¿®æ”¹å‚æ•°é…ç½®å¯¹è¯æ¡† -->
    <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
    <el-dialog :title="title" :visible.sync="open" width="660px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="用户昵称" prop="nickName">
@@ -240,6 +232,37 @@
          <el-col :span="12">
            <el-form-item label="邮箱" prop="email">
              <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="机构" prop="orgId">
              <el-select v-model="form.orgId" filterable clearable placeholder="请选择机构" @change="handleOrgChange">
                <el-option
                  v-for="org in orgOptions"
                  :key="org.id"
                  :label="org.organizationname"
                  :value="org.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="协调员姓名" prop="coordinatorName">
              <el-input v-model="form.coordinatorName" placeholder="请输入协调员姓名" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="协调员编号" prop="coordinatorNo">
              <el-input v-model="form.coordinatorNo" placeholder="请输入协调员编号" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="身份证" prop="idcardno">
              <el-input v-model="form.idcardno" placeholder="请输入身份证号" maxlength="18" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -356,6 +379,7 @@
<script>
import { listUser, getUser, delUser, addUser, updateUser, exportUser,handleunlock, resetUserPwd, changeUserStatus, importTemplate } from "@/api/system/user";
import { listOrganization } from "@/api/project/organization";
import { getToken } from "@/utils/auth";
import { treeselect } from "@/api/system/dept";
import Treeselect from "@riophae/vue-treeselect";
@@ -399,6 +423,8 @@
      postOptions: [],
      // è§’色选项
      roleOptions: [],
      // æœºæž„选项
      orgOptions: [],
      // è¡¨å•参数
      form: {},
      defaultProps: {
@@ -465,6 +491,13 @@
            message: "请输入正确的手机号码",
            trigger: "blur"
          }
        ],
        idcardno: [
          {
            pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
            message: "请输入正确的身份证号码",
            trigger: "blur"
          }
        ]
      }
    };
@@ -478,6 +511,7 @@
  created() {
    this.getList();
    this.getTreeselect();
    this.getOrgList();
    this.getConfigKey("sys.user.initPassword").then(response => {
      this.initPassword = response.msg;
    });
@@ -498,6 +532,25 @@
      treeselect().then(response => {
        this.deptOptions = response.data;
      });
    },
    /** æŸ¥è¯¢æœºæž„下拉列表 */
    getOrgList() {
      listOrganization({ pageNum: 1, pageSize: 100000 }).then(response => {
        this.orgOptions = response.rows || [];
      });
    },
    /** æœºæž„选择变更,同步机构名称及协调员信息 */
    handleOrgChange(orgId) {
      const org = this.orgOptions.find(o => o.id === orgId);
      if (org) {
        this.form.orgName = org.organizationname;
        this.form.coordinatorName = org.coordinatorName;
        this.form.coordinatorNo = org.coordinatorNo;
      } else {
        this.form.orgName = undefined;
        this.form.coordinatorName = undefined;
        this.form.coordinatorNo = undefined;
      }
    },
    // ç­›é€‰èŠ‚ç‚¹
    filterNode(value, data) {
@@ -538,6 +591,11 @@
        sex: undefined,
        status: "0",
        remark: undefined,
        orgId: undefined,
        orgName: undefined,
        coordinatorName: undefined,
        coordinatorNo: undefined,
        idcardno: undefined,
        postIds: [],
        roleIds: []
      };
src/views/tool/gen/index.vue
@@ -45,7 +45,6 @@
          icon="el-icon-download"
          size="mini"
          @click="handleGenTable"
          v-hasPermi="['tool:gen:code']"
        >生成</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -55,7 +54,6 @@
          icon="el-icon-upload"
          size="mini"
          @click="openImportTable"
          v-hasPermi="['tool:gen:import']"
        >导入</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -66,7 +64,6 @@
          size="mini"
          :disabled="single"
          @click="handleEditTable"
          v-hasPermi="['tool:gen:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
@@ -77,7 +74,6 @@
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['tool:gen:remove']"
        >删除</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
@@ -120,35 +116,30 @@
            size="small"
            icon="el-icon-view"
            @click="handlePreview(scope.row)"
            v-hasPermi="['tool:gen:preview']"
          >预览</el-button>
          <el-button
            type="text"
            size="small"
            icon="el-icon-edit"
            @click="handleEditTable(scope.row)"
            v-hasPermi="['tool:gen:edit']"
          >编辑</el-button>
          <el-button
            type="text"
            size="small"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['tool:gen:remove']"
          >删除</el-button>
          <el-button
            type="text"
            size="small"
            icon="el-icon-refresh"
            @click="handleSynchDb(scope.row)"
            v-hasPermi="['tool:gen:edit']"
          >同步</el-button>
          <el-button
            type="text"
            size="small"
            icon="el-icon-download"
            @click="handleGenTable(scope.row)"
            v-hasPermi="['tool:gen:code']"
          >生成代码</el-button>
        </template>
      </el-table-column>