From 5aa63351c15fde21178f0c962570df65eba38560 Mon Sep 17 00:00:00 2001
From: hcong <1050828145@qq.com>
Date: 星期五, 27 九月 2024 15:47:15 +0800
Subject: [PATCH] 评估

---
 src/views/fysp/config/components/evalution/CompEvalutionSubRuleUpd.vue |  138 +++++++
 src/main.js                                                            |    1 
 src/views/fysp/evaluation/EvalutationEdit.vue                          |  256 +++++++++++++
 src/components.d.ts                                                    |   10 
 src/utils/fileUtils.js                                                 |   65 +++
 src/views/fysp/config/components/evalution/CompEvalutionRuleUpd.vue    |  172 +++++++++
 src/constants/menu.js                                                  |    6 
 src/router/index.js                                                    |    6 
 src/views/fysp/config/EvalutationRule.vue                              |  339 ++++++++++++++++++
 src/api/fysp/evaluateApi.js                                            |   46 ++
 10 files changed, 1,017 insertions(+), 22 deletions(-)

diff --git a/src/api/fysp/evaluateApi.js b/src/api/fysp/evaluateApi.js
index 3cf5a71..a09247d 100644
--- a/src/api/fysp/evaluateApi.js
+++ b/src/api/fysp/evaluateApi.js
@@ -62,5 +62,49 @@
           window.URL.revokeObjectURL(url);
         }
       });
-  }
+  },
+
+  /** 
+   * 淇敼鏈�灏忛」寰楀垎
+   */
+  updateScore({itemList, subTaskId}) {
+    const param = `?subTaskId=${subTaskId}`
+    return $fysp.post(`/itemevaluation/update${param}`, itemList).then((res) => res.data);
+  },
+  /** 
+   * 鑾峰緱鎵�鏈夎鍒欑埗鑺傜偣
+   */
+  getAllParentRules() {
+    return $fysp.get("evaluationrule").then((res) => res.data);
+  },
+  /** 鏍规嵁鐖惰妭鐐筰d鑾峰彇瀛愯鍒� */
+  getSubRules(id) {
+    const param = `?id=${id}`
+    return $fysp.get(`/evaluationsubrule/byRule${param}`).then((res) => res.data);
+  },
+  /** 
+   * 鏇存柊鐖惰妭鐐硅鍒�
+   */
+  updateParentRule(data) {
+    return $fysp.post("evaluationrule", data).then((res) => res.data);
+  },
+  /** 
+   * 鍒犻櫎鐖惰妭鐐硅鍒�
+   */
+  deleteParentRuleById(id) {
+    return $fysp.delete(`evaluationrule/${id}`).then((res) => res.data);
+  },
+
+  /** 
+   * 鏇存柊瀛愯妭鐐硅鍒�
+   */
+  updateSubRule(data) {
+    return $fysp.post("evaluationsubrule", data).then((res) => res.data);
+  },
+  /** 
+   * 鍒犻櫎瀛愯妭鐐硅鍒�
+   */
+  deleteSubRuleById(id) {
+    return $fysp.delete(`evaluationsubrule/${id}`).then((res) => res.data);
+  },
 };
diff --git a/src/components.d.ts b/src/components.d.ts
index 99aa4bb..c4f8efa 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -18,7 +18,6 @@
     ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
     ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
     ElButton: typeof import('element-plus/es')['ElButton']
-    ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
     ElCard: typeof import('element-plus/es')['ElCard']
     ElCascader: typeof import('element-plus/es')['ElCascader']
     ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
@@ -31,9 +30,6 @@
     ElDialog: typeof import('element-plus/es')['ElDialog']
     ElDivider: typeof import('element-plus/es')['ElDivider']
     ElDrawer: typeof import('element-plus/es')['ElDrawer']
-    ElDropdown: typeof import('element-plus/es')['ElDropdown']
-    ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
-    ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
     ElEmpty: typeof import('element-plus/es')['ElEmpty']
     ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
@@ -47,8 +43,8 @@
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
     ElOption: typeof import('element-plus/es')['ElOption']
-    ElPageHeader: typeof import('element-plus/es')['ElPageHeader']
     ElPagination: typeof import('element-plus/es')['ElPagination']
+    ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
     ElPopover: typeof import('element-plus/es')['ElPopover']
     ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
     ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
@@ -62,14 +58,10 @@
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
-    ElTabPane: typeof import('element-plus/es')['ElTabPane']
-    ElTabs: typeof import('element-plus/es')['ElTabs']
     ElTag: typeof import('element-plus/es')['ElTag']
     ElText: typeof import('element-plus/es')['ElText']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
-    ElTransfer: typeof import('element-plus/es')['ElTransfer']
     ElTree: typeof import('element-plus/es')['ElTree']
-    ElUpload: typeof import('element-plus/es')['ElUpload']
     Footer: typeof import('./components/core/Footer.vue')['default']
     FormCol: typeof import('./components/layout/FormCol.vue')['default']
     FYBgTaskCard: typeof import('./components/bg-task/FYBgTaskCard.vue')['default']
diff --git a/src/constants/menu.js b/src/constants/menu.js
index 49c2faf..e1a1c52 100644
--- a/src/constants/menu.js
+++ b/src/constants/menu.js
@@ -59,6 +59,12 @@
         icon: 'List',
         name: '璁惧鍖归厤',
       },
+      {
+        //璇勪及瑙勫垯绠$悊
+        path: '/fysp/config/evalutationRule',
+        icon: 'List',
+        name: '璇勪及瑙勫垯',
+      },
     ],
   },
   {
diff --git a/src/main.js b/src/main.js
index c56a19a..1f6b4b5 100644
--- a/src/main.js
+++ b/src/main.js
@@ -5,6 +5,7 @@
 import { router } from './router';
 import App from './App.vue';
 import timeUtil from './utils/time-util';
+import DeepCopy from './utils/DeepCopy';
 
 // import 'element-plus/dist/index.css';
 import './assets/main.css';
diff --git a/src/router/index.js b/src/router/index.js
index b33e0fd..f08c0ce 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -84,6 +84,12 @@
     component: () => import('@/views/fysp/config/DeviceMatch.vue')
   },
   {
+    //璇勪及瑙勫垯绠$悊
+    name: 'fyspEvalutationRule',
+    path: '/fysp/config/evalutationRule',
+    component: () => import('@/views/fysp/config/EvalutationRule.vue')
+  },
+  {
     //璇勪及鏁版嵁婧�
     name: 'fyspEvalutationTask',
     path: '/fysp/evaluation/evalutationTask',
diff --git a/src/utils/fileUtils.js b/src/utils/fileUtils.js
new file mode 100644
index 0000000..5cf0c35
--- /dev/null
+++ b/src/utils/fileUtils.js
@@ -0,0 +1,65 @@
+export default {
+    getBase64(url, callback) {
+        //閫氳繃鏋勯�犲嚱鏁版潵鍒涘缓鐨� img 瀹炰緥锛屽湪璧嬩簣 src 鍊煎悗灏变細绔嬪埢涓嬭浇鍥剧墖锛岀浉姣� createElement() 鍒涘缓 <img> 鐪佸幓浜� append()锛屼篃灏遍伩鍏嶄簡鏂囨。鍐椾綑鍜屾薄鏌�
+        var Img = new Image(),
+            dataURL = '';
+        Img.setAttribute('crossOrigin', 'Anonymous'); // 瑙e喅鎺у埗鍙拌法鍩熸姤閿欑殑闂
+        
+        if (url.startsWith("blob")) {
+            Img.src = url;
+        }else {
+            Img.src = url + '?v=' + Math.random(); // 澶勭悊缂撳瓨,fix缂撳瓨bug,鏈夌紦瀛橈紝娴忚鍣ㄤ細鎶ラ敊;
+        }
+        // Img.src = /^data:image/.test(url) ? url : url + '?' + new Date().getTime() + '&v=' + Math.random(); // 澶勭悊缂撳瓨,fix缂撳瓨bug,鏈夌紦瀛橈紝娴忚鍣ㄤ細鎶ラ敊;
+
+        // Img.crossOrigin = "*"; // 瑙e喅鎺у埗鍙拌法鍩熸姤閿欑殑闂
+        Img.onload = function () {
+            //瑕佸厛纭繚鍥剧墖瀹屾暣鑾峰彇鍒帮紝杩欐槸涓紓姝ヤ簨浠�
+            var canvas = document.createElement('canvas'), //鍒涘缓canvas鍏冪礌
+                width = Img.width, //纭繚canvas鐨勫昂瀵稿拰鍥剧墖涓�鏍�
+                height = Img.height;
+            canvas.width = width;
+            canvas.height = height;
+            canvas.setAttribute('crossOrigin', 'Anonymous'); // 瑙e喅鎺у埗鍙拌法鍩熸姤閿欑殑闂
+            canvas.getContext('2d').drawImage(Img, 0, 0, width, height); //灏嗗浘鐗囩粯鍒跺埌canvas涓�
+            dataURL = canvas.toDataURL('image/jpeg'); //杞崲鍥剧墖涓篸ataURL
+            callback ? callback(dataURL) : null; //璋冪敤鍥炶皟鍑芥暟
+        };
+    },
+    getImageFiles(urls, callback) {
+        if (urls.length == 0) {
+            callback([])
+        }
+        var files = [];
+        urls.forEach((url) => {
+            this.setInitImg(url, (file) => {
+                files.push(file);
+                if (files.length == urls.length) {
+                    callback(files);
+                }
+            });
+        });
+    },
+    setInitImg(url, callback) {
+        let img = url;
+        let _ = this;
+        let imgRes;
+        this.getBase64(img, (dataURL) => {
+            imgRes = this.dataURLtoFile(dataURL, img);
+            console.log(imgRes);
+            callback(imgRes);
+        });
+    },
+    dataURLtoFile(dataurl, filename) {
+        //灏哹ase64杞崲涓烘枃浠讹紝dataurl涓篵ase64瀛楃涓诧紝filename涓烘枃浠跺悕锛堝繀椤诲甫鍚庣紑鍚嶏紝濡�.jpg,.png锛�
+        var arr = dataurl.split(','),
+          mime = arr[0].match(/:(.*?);/)[1],
+          bstr = atob(arr[1]),
+          n = bstr.length,
+          u8arr = new Uint8Array(n);
+        while (n--) {
+          u8arr[n] = bstr.charCodeAt(n);
+        }
+        return new File([u8arr], filename, { type: mime });
+      }
+}
\ No newline at end of file
diff --git a/src/views/fysp/config/EvalutationRule.vue b/src/views/fysp/config/EvalutationRule.vue
new file mode 100644
index 0000000..271c802
--- /dev/null
+++ b/src/views/fysp/config/EvalutationRule.vue
@@ -0,0 +1,339 @@
+<template>
+  <div>
+    <FYTable @search="onSearch" :pagination="false" ref="tableRef" :expandChange="expandChange">
+      <template #options>
+        <!-- 鍖哄幙 -->
+        <!-- <FYOptionLocation
+          :allOption="false"
+          :level="3"
+          :checkStrictly="false"
+          v-model:value="formSearch.locations"
+        ></FYOptionLocation> -->
+      </template>
+      <template #table-column>
+        <el-table-column align="center" type="expand">
+          <template v-slot="scope">
+            <el-table :data="scope.row.children" table-layout="fixed">
+              <el-table-column
+                prop="itemname"
+                label="鍚嶇О"
+                width="200"
+                :show-overflow-tooltip="true"
+              ></el-table-column>
+              <el-table-column prop="itemdescription" label="鎻忚堪"></el-table-column>
+              <el-table-column prop="maxscore" label="鏈�楂樺垎"></el-table-column>
+              <el-table-column prop="minscore" label="鏈�浣庡垎"></el-table-column>
+              <el-table-column prop="defaultvalue" label="榛樿鍊�"></el-table-column>
+              <el-table-column
+                prop="ertype"
+                label="璇勫垎瑙勫垯绫诲瀷"
+                width="150"
+                :formatter="formatSubRuleType"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="extension1"
+                label="璇勫垎绫诲瀷"
+                width="150"
+                :formatter="formatScoreMode"
+              ></el-table-column>
+              <el-table-column
+                prop="extension2"
+                label="寰楀垎妯″紡"
+                width="150"
+                :formatter="formatScoreMode"
+              ></el-table-column>
+              <el-table-column
+                prop="extension3"
+                label="閫夋嫨妯″紡"
+                width="150"
+                :formatter="formatScoreMode"
+              ></el-table-column>
+              <!-- <el-table-column
+                prop="usedanalyse"
+                label="鏄惁鍒嗘瀽"
+                width="100"
+                :formatter="formatBoolean"
+              >
+              </el-table-column> -->
+              <el-table-column
+                prop="remark"
+                label="澶囨敞"
+                :show-overflow-tooltip="true"
+              ></el-table-column>
+              <el-table-column v-slot="scope" prop="鎿嶄綔" label="鎿嶄綔" width="150">
+                <el-button link type="primary" @click="editSubRule(scope.row, 1)">鏌ョ湅</el-button>
+                <el-button link type="primary" @click="editSubRule(scope.row, 2)">淇敼</el-button>
+                <el-popconfirm title="纭鍒犻櫎?" @confirm="deleteSubRule(scope.row)">
+                  <template #reference>
+                    <el-button link type="danger">鍒犻櫎</el-button>
+                  </template>
+                </el-popconfirm>
+              </el-table-column>
+            </el-table>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="rulename"
+          label="瑙勫垯鍚嶇О"
+          width="350"
+          :show-overflow-tooltip="true"
+        ></el-table-column>
+        <el-table-column
+          prop="ruletype"
+          label="瑙勫垯绫诲瀷"
+          :formatter="formatRuleType"
+        ></el-table-column>
+        <el-table-column prop="tasktype" label="浠诲姟绫诲瀷"></el-table-column>
+        <el-table-column prop="scensetype" label="鍦烘櫙绫诲瀷"></el-table-column>
+        <el-table-column prop="provincename" label="鐪佷唤鍚嶇О"></el-table-column>
+        <el-table-column prop="cityname" label="鍩庡競鍚嶇О"></el-table-column>
+        <el-table-column prop="districtname" label="鍖哄幙鍚嶇О"></el-table-column>
+        <el-table-column
+          prop="suitable"
+          label="鏄惁閫傜敤"
+          :formatter="formatBoolean"
+        ></el-table-column>
+        <el-table-column prop="isuse" label="鏄惁鍚敤" :formatter="formatBoolean"></el-table-column>
+        <el-table-column v-slot="scope" prop="鎿嶄綔" label="鎿嶄綔" width="160">
+          <el-button link type="primary" @click="editRule(scope.row, 1)">鏌ョ湅</el-button>
+          <el-button link type="primary" @click="editRule(scope.row, 2)">淇敼</el-button>
+          <el-popconfirm title="纭鍒犻櫎?" @confirm="deleteRule(scope.row)">
+            <template #reference>
+              <el-button link type="danger">鍒犻櫎</el-button>
+            </template>
+          </el-popconfirm>
+        </el-table-column>
+      </template>
+    </FYTable>
+    <!-- 鐖惰妭鐐圭殑淇敼椤甸潰 -->
+    <el-dialog title="淇敼" width="80%" v-model="evalutionRuleVisible">
+      <CompEvalutionRuleUpd
+        v-if="evalutionRuleVisible"
+        :before-close="beforeEvalutionRuleDialogClose"
+        :evalutionRule="currEvalutionRule"
+        :readonly="parentReadOnly"
+        @updated="onEvalutionRuleUpdated"
+      />
+    </el-dialog>
+    <!-- 瀛愯妭鐐圭殑淇敼椤甸潰 -->
+    <el-dialog title="淇敼" width="80%" v-model="evalutionSubRuleVisible">
+      <CompEvalutionSubRuleUpd
+        v-if="evalutionSubRuleVisible"
+        :before-close="beforeEvalutionSubRuleDialogClose"
+        :evalutionSubRule="currEvalutionSubRule"
+        :readonly="subReadOnly"
+        @updated="onEvalutionSubRuleUpdated"
+      />
+    </el-dialog>
+  </div>
+</template>
+<script>
+import evaluateApi from '@/api/fysp/evaluateApi';
+import CompEvalutionRuleUpd from './components/evalution/CompEvalutionRuleUpd.vue';
+import CompEvalutionSubRuleUpd from './components/evalution/CompEvalutionSubRuleUpd.vue';
+import { ElMessage } from 'element-plus';
+export default {
+  watch: {
+    expandKeyId: {
+      handler(newObj, oldObj) {
+        console.log('expandKeyId', this.expandKeyId);
+      },
+      deep: true
+    }
+  },
+  components: {
+    CompEvalutionRuleUpd,
+    CompEvalutionSubRuleUpd
+  },
+  mounted() {},
+  methods: {
+    // 璇勫垎瑙勫垯瀛愯妭鐐逛慨鏀归〉闈㈢浉鍏�
+    deleteSubRule(row) {
+      evaluateApi.deleteSubRuleById(row.guid).then((res) => {
+        if (res == 1) {
+          ElMessage({
+            message: '鍒犻櫎鎴愬姛',
+            type: 'success'
+          });
+          this.refreshTableData();
+        }
+      });
+    },
+    editSubRule(row, type) {
+      this.subReadOnly = (type == 1);
+      this.currEvalutionSubRule = row;
+      this.evalutionSubRuleVisible = true;
+    },
+    onEvalutionSubRuleUpdated(isOk) {
+      this.beforeEvalutionSubRuleDialogClose();
+      if (!isOk) {
+        return;
+      }
+      this.refreshTableData();
+    },
+    beforeEvalutionSubRuleDialogClose() {
+      this.evalutionSubRuleVisible = false;
+    },
+    // 璇勫垎瑙勫垯鐖惰妭鐐逛慨鏀归〉闈㈢浉鍏�
+    deleteRule(row) {
+      evaluateApi.deleteParentRuleById(row.guid).then((res) => {
+        if (res == 1) {
+          ElMessage({
+            message: '鍒犻櫎鎴愬姛',
+            type: 'success'
+          });
+          this.refreshTableData();
+        }
+      });
+    },
+    editRule(row, type) {
+      this.parentReadOnly = (type == 1);
+      this.currEvalutionRule = row;
+      this.evalutionRuleVisible = true;
+    },
+    onEvalutionRuleUpdated(isOk) {
+      this.beforeEvalutionRuleDialogClose();
+      if (!isOk) {
+        return;
+      }
+      this.refreshTableData();
+    },
+    beforeEvalutionRuleDialogClose() {
+      this.evalutionRuleVisible = false;
+    },
+    // 鍒锋柊鍒楄〃鏁版嵁
+    refreshTableData() {
+      setTimeout(() => {
+        this.$refs.tableRef.onSearch();
+      }, 1000);
+    },
+
+    onSearch(page, func) {
+      evaluateApi.getAllParentRules().then((res) => {
+        this.expandData = [];
+        this.expandKeyId = [];
+        res.forEach((element) => {
+          element.hasChildren = true;
+          // 鑾峰彇瀛愯妭鐐瑰垪琛�
+          evaluateApi.getSubRules(element.guid).then((res) => {
+            element.children = res.data;
+          });
+        });
+        func({ data: res });
+      });
+    },
+    // 鍔犺浇瀛愯妭鐐�
+    load(row) {
+      var topId = row.guid;
+      evaluateApi.getSubRules(topId).then((res) => {
+        return res.data;
+      });
+    },
+    // 鍒楄〃灞曠ず鍐呭閿�煎鐨勬槧灏勬柟娉�
+    formatBoolean(row, column, cellValue) {
+      if (cellValue == null || cellValue == undefined) {
+        return '';
+      }
+      return cellValue ? '鏄�' : '鍚�';
+    },
+    formatRuleType(row, column, cellValue) {
+      for (let index = 0; index < this.ruleTypes.length; index++) {
+        const item = this.ruleTypes[index];
+        if (item.value == cellValue) {
+          return item.label;
+        }
+      }
+      return '';
+    },
+    formatSubRuleType(row, column, cellValue) {
+      for (let index = 0; index < this.subRuleTypes.length; index++) {
+        const item = this.subRuleTypes[index];
+        if (item.value == cellValue) {
+          return item.label;
+        }
+      }
+      return '';
+    },
+    // 鍒嗘暟妯″紡
+    formatScoreMode(row, column, cellValue) {
+      for (let index = 0; index < this.scoreTypes.length; index++) {
+        const item = this.scoreTypes[index];
+        if (item.value == cellValue) {
+          return item.label;
+        }
+      }
+      return '';
+    },
+    // 鍒锋柊鏁版嵁鏃朵繚瀛樿鐨勫睍寮�鐘舵��
+    saveExpandedRowsStatus() {
+      this.tableData.forEach((item) => {
+        if (item.guid == this.expandKeyId) {
+          this.$refs.table.toggleRowExpansion(item, true);
+        }
+      });
+    },
+    // 鎵╁睍姣忔鍙兘鎵撳紑涓�涓�
+    expandChange(row, expandedRows) {
+      this.expandData = expandedRows;
+      if (expandedRows.length == 1) {
+        if (!this.expandKeyId) {
+          this.expandKeyId = row.guid;
+        }
+        this.load(row);
+      } else if (expandedRows.length >= 2) {
+        //宸茬粡灞曞紑涓�琛�
+        this.expandKeyId = expandedRows[expandedRows.length - 1].guid; //鑾峰彇鏈�鍚庝竴涓偣寮�鐨剅owID
+        //閬嶅巻琛ㄦ牸鏁版嵁锛屽叧闂叾浠栫殑灞曞紑琛�
+        this.tableData.map((item) => {
+          if (item.guid != this.expandKeyId) {
+            this.$refs.table.toggleRowExpansion(item, false);
+          }
+        });
+      } else {
+        //鍏抽棴
+        this.expandKeyId = undefined;
+        this.expandData = [];
+      }
+    }
+  },
+  data() {
+    return {
+      subReadOnly: false,
+      parentReadOnly: false,
+      // 褰撳墠灞曞紑鐨勮
+      expandKeyId: [],
+      expandData: [],
+      // 璇勫垎瑙勫垯瀛愯妭鐐逛慨鏀归〉闈㈢浉鍏�
+      currEvalutionSubRule: {},
+      evalutionSubRuleVisible: false,
+      // 璇勫垎瑙勫垯鐖惰妭鐐逛慨鏀归〉闈㈢浉鍏�
+      currEvalutionRule: {},
+      evalutionRuleVisible: false,
+
+      tableData: [],
+      ruleTypes: [
+        { label: '瑙勮寖鎬�', value: '1' },
+        { label: '璇勫垎', value: '2' }
+      ],
+      subRuleTypes: [
+        { label: '瑙勮寖鑰冩牳椤�', value: 1 },
+        { label: '璇勫垎澶ч」', value: 2 },
+        { label: '璇勫垎灏忛」', value: 3 },
+        { label: '鏈�灏忚瘎鍒嗛」', value: 4 }
+      ],
+      scoreTypes: [
+        { label: '鍩虹鍒�', value: 'basic_score' },
+        { label: '闄勫姞鍒�', value: 'addition_score' },
+        { label: '鍑忓垎妯″紡', value: 'minus_mode' },
+        { label: '鍔犲垎妯″紡', value: 'add_mode' },
+        { label: '鍗曢�夋ā寮�', value: 'single_mode' },
+        { label: '澶氶�夋ā寮�', value: 'multi_mode' },
+        { label: '绌�', value: 'null' }
+      ],
+      formSearch: {}
+    };
+  }
+};
+</script>
+<style scoped></style>
diff --git a/src/views/fysp/config/components/evalution/CompEvalutionRuleUpd.vue b/src/views/fysp/config/components/evalution/CompEvalutionRuleUpd.vue
new file mode 100644
index 0000000..1da7ece
--- /dev/null
+++ b/src/views/fysp/config/components/evalution/CompEvalutionRuleUpd.vue
@@ -0,0 +1,172 @@
+<template>
+  <FYForm
+    :form-info="formInfo"
+    :rules="rules"
+    :showButtons="!readonly"
+    @submit="submit"
+  >
+    <template #form-item="{ fyFormInfo }">
+      <el-form-item label="瑙勫垯鍚嶇О" prop="rulename">
+        <el-input v-model="formInfo.rulename" :disabled="readonly"></el-input>
+      </el-form-item>
+      <!-- <FYOptionScene
+        :allOption="false"
+        :type="2"
+        v-model:value="formInfo._scenetype"
+      ></FYOptionScene> -->
+      <el-form-item label="鍦烘櫙绫诲瀷" prop="_scenetype">
+        <el-select v-model="formInfo._scenetype" placeholder="鍦烘櫙绫诲瀷" :disabled="readonly">
+          <el-option v-for="s in sceneTypes" :key="s.value" :label="s.label" :value="s" />
+        </el-select>
+      </el-form-item>
+      <!-- 鍖哄幙 -->
+      <FYOptionLocation
+        :allOption="false"
+        :level="3"
+        :initValue="false"
+        :checkStrictly="true"
+        v-model:value="formInfo._locations"
+      ></FYOptionLocation>
+      <el-form-item label="瑙勫垯绫诲瀷" prop="ruletype">
+        <el-select v-model="formInfo.ruletype" placeholder="璇烽�夋嫨" :disabled="readonly">
+          <el-option
+            v-for="item in ruleTypeOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="浠诲姟绫诲瀷" prop="tasktype">
+        <el-select v-model="formInfo.tasktype" placeholder="璇烽�夋嫨" :disabled="readonly">
+          <el-option
+            v-for="item in tasktypeOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="鏄惁閫傜敤" prop="suitable">
+        <el-switch v-model="formInfo.suitable" :disabled="readonly"></el-switch>
+      </el-form-item>
+      <el-form-item label="鏄惁鍚敤" prop="isuse">
+        <el-switch v-model="formInfo.isuse" :disabled="readonly"></el-switch>
+      </el-form-item>
+    </template>
+  </FYForm>
+</template>
+<script>
+import { enumScene } from '@/enum/scene';
+import { ElMessage } from 'element-plus';
+import evaluateApi from '@/api/fysp/evaluateApi';
+import { useCloned } from '@vueuse/core';
+export default {
+  props: {
+    readonly: {
+      type: Boolean,
+      default: false,
+    },
+    evalutionRule: {
+      type: Object,
+      default: {}
+    }
+  },
+  created() {
+    this.initFormInfo();
+  },
+  mounted() {},
+  methods: {
+    // update鏂规硶
+    updateEvalutionRule() {
+      return evaluateApi.updateParentRule(this.formInfo);
+    },
+    initFormInfo() {
+      this.formInfo = useCloned(this.evalutionRule).cloned.value;
+      this.parseSceneBaseInfo(this.formInfo);
+    },
+    parseSceneBaseInfo(param) {
+      const s = param;
+      s._scenetype = {
+        label: s.scensetype,
+        value: s.scensetypeid + ''
+      };
+
+      s._locations = {
+        pCode: s.provincecode,
+        pName: s.provincename,
+        cCode: s.citycode,
+        cName: s.cityname,
+        dCode: s.districtcode,
+        dName: s.districtname
+      };
+      console.log('param', param);
+    },
+    // 鍒犻櫎鏃犲叧瀛楁
+    deleteExtraField(data) {
+      if (!(data instanceof Object)) {
+        return;
+      }
+      for (let i = data.length - 1; i >= 0; i--) {
+        if (key.startsWith('_')) {
+          delete data[key];
+        }
+      }
+    },
+    submit(formObj, success, fail) {
+      // 鏁版嵁鍑嗗
+      this.formInfo.scensetypeid = this.formInfo._scenetype.value;
+      this.formInfo.scensetype = this.formInfo._scenetype.label;
+      // 琛屾斂鍖哄垝淇℃伅濉厖
+      const a = this.formInfo._locations;
+      this.formInfo.provincecode = a.pCode;
+      this.formInfo.provincename = a.pName;
+      this.formInfo.citycode = a.cCode;
+      this.formInfo.cityname = a.cName;
+      this.formInfo.districtcode = a.dCode;
+      this.formInfo.districtname = a.dName;
+      this.deleteExtraField(this.formInfo);
+      console.log('鏁版嵁澶勭悊缁撴潫', this.formInfo);
+
+      return new Promise((reslove, reject) => {
+        setTimeout(() => {
+          this.$emit('updated', true);
+          this.updateEvalutionRule().then((res) => {
+            if (res != 1) {
+              fail();
+              reslove();
+            }
+            success();
+          });
+          reslove();
+        }, 1000);
+      });
+    }
+  },
+  data() {
+    return {
+      sceneTypes: enumScene(2, false),
+      formInfo: {},
+      ruleTypeOptions: [
+        { label: '瑙勮寖鎬�', value: '1' },
+        { label: '璇勫垎', value: '2' }
+      ],
+      tasktypeOptions: [
+        { label: '宸℃煡', value: 1 },
+        { label: '鏃犱汉鏈哄贰鏌�', value: 2 },
+        { label: '澶嶆牳', value: 3 },
+        { label: '鎵ф硶鏀寔', value: 4 },
+        { label: '鐩戞祴杩愮淮', value: 5 },
+        { label: '娌荤悊杩愮淮', value: 6 },
+        { label: '鏀归��', value: 7 },
+        { label: '娌荤悊', value: 8 },
+        { label: '鍜ㄨ', value: 9 },
+        { label: '鑷姩璇勫垎', value: 99 }
+      ]
+    };
+  }
+};
+</script>
+<style scoped></style>
diff --git a/src/views/fysp/config/components/evalution/CompEvalutionSubRuleUpd.vue b/src/views/fysp/config/components/evalution/CompEvalutionSubRuleUpd.vue
new file mode 100644
index 0000000..0cfd3f9
--- /dev/null
+++ b/src/views/fysp/config/components/evalution/CompEvalutionSubRuleUpd.vue
@@ -0,0 +1,138 @@
+<template>
+  <FYForm :form-info="formInfo" :rules="rules" :showButtons="!readonly" @submit="submit">
+    <template #form-item="{ fyFormInfo }">
+      <el-form-item label="鍚嶇О" prop="itemname">
+        <el-input v-model="formInfo.itemname" :disabled="readonly"></el-input>
+      </el-form-item>
+      <el-form-item label="鎻忚堪" prop="itemdescription">
+        <el-input
+          type="textarea"
+          v-model="formInfo.itemdescription"
+          :disabled="readonly"
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="鏈�楂樺垎" prop="maxscore">
+        <el-input-number v-model="formInfo.maxscore" :disabled="readonly"></el-input-number>
+      </el-form-item>
+      <el-form-item label="鏈�浣庡垎" prop="minscore">
+        <el-input-number v-model="formInfo.minscore" :disabled="readonly"></el-input-number>
+      </el-form-item>
+      <el-form-item label="榛樿鍊�" prop="defaultvalue">
+        <el-input-number v-model="formInfo.defaultvalue" :disabled="readonly"></el-input-number>
+      </el-form-item>
+      <el-form-item label="璇勫垎瑙勫垯绫诲瀷" prop="ertype">
+        <el-select v-model="formInfo.ertype" placeholder="璇烽�夋嫨" :disabled="readonly">
+          <el-option
+            v-for="item in subRuleTypeOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+            :disabled="item.disabled"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="璇勫垎绫诲瀷" prop="extension1">
+        <el-select v-model="formInfo.extension1" placeholder="璇烽�夋嫨" :disabled="readonly">
+          <el-option
+            v-for="item in score1Types"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="寰楀垎妯″紡" prop="extension2">
+        <el-select v-model="formInfo.extension2" placeholder="璇烽�夋嫨" :disabled="readonly">
+          <el-option
+            v-for="item in score2Types"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="閫夋嫨妯″紡" prop="extension3">
+        <el-select v-model="formInfo.extension3" placeholder="璇烽�夋嫨" :disabled="readonly">
+          <el-option
+            v-for="item in score3Types"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="澶囨敞" prop="remark">
+        <el-input type="textarea" v-model="formInfo.remark" :disabled="readonly"></el-input>
+      </el-form-item>
+    </template>
+  </FYForm>
+</template>
+<script>
+import { ElMessage } from 'element-plus';
+import evaluateApi from '@/api/fysp/evaluateApi';
+import { useCloned } from '@vueuse/core';
+export default {
+  props: {
+    readonly: {
+      type: Boolean,
+      default: false
+    },
+    evalutionSubRule: {
+      type: Object,
+      default: {}
+    }
+  },
+  mounted() {
+    this.formInfo = useCloned(this.evalutionSubRule).cloned.value;
+  },
+  methods: {
+    updateEvalutionSubRule() {
+      return evaluateApi.updateSubRule(this.formInfo);
+    },
+    submit(formObj, success, fail) {
+      return new Promise((reslove, reject) => {
+        setTimeout(() => {
+          this.$emit('updated', true);
+          this.updateEvalutionSubRule().then((res) => {
+            if (res != 1) {
+              fail();
+              reslove();
+            }
+            success();
+          });
+          reslove();
+        }, 1000);
+      });
+    }
+  },
+  data() {
+    return {
+      rules: {},
+      formInfo: {},
+      subRuleTypeOptions: [
+        { label: '瑙勮寖鑰冩牳椤�', value: 1, disabled: true },
+        { label: '璇勫垎澶ч」', value: 2 },
+        { label: '璇勫垎灏忛」', value: 3 },
+        { label: '鏈�灏忚瘎鍒嗛」', value: 4 }
+      ],
+      score1Types: [
+        { label: '鍩虹鍒�', value: 'basic_score' },
+        { label: '闄勫姞鍒�', value: 'addition_score' }
+      ],
+      score2Types: [
+        { label: '鍑忓垎妯″紡', value: 'minus_mode' },
+        { label: '鍔犲垎妯″紡', value: 'add_mode' }
+      ],
+      score3Types: [
+        { label: '鍗曢�夋ā寮�', value: 'single_mode' },
+        { label: '澶氶�夋ā寮�', value: 'multi_mode' }
+      ]
+    };
+  }
+};
+</script>
+<style scoped></style>
diff --git a/src/views/fysp/evaluation/EvalutationEdit.vue b/src/views/fysp/evaluation/EvalutationEdit.vue
index 24f1a0a..f45dabf 100644
--- a/src/views/fysp/evaluation/EvalutationEdit.vue
+++ b/src/views/fysp/evaluation/EvalutationEdit.vue
@@ -1,14 +1,44 @@
 <template>
   <FYPageHeader title="璇勪及缁撴灉璇︽儏"></FYPageHeader>
-  <el-row v-for="item in evaluation" :key="item.id">
-    
-  </el-row>
+  <el-row v-for="item in evaluation" :key="item.id"> </el-row>
+  <div class="btns">
+    <el-button type="primary" @click="submit" :disabled="!isUpdated">鎻愪氦</el-button>
+  </div>
+  <el-table
+    class="table-style"
+    :data="tableData"
+    ref="tableRef"
+    :span-method="objectSpanMethod"
+    table-layout="fixed"
+    :cell-style="cellClassName"
+    border
+    stripe
+  >
+    <el-table-column v-slot="scope" prop="one_title" label="涓�绾ф寚鏍�" width="200">
+      <!-- <el-checkbox v-model="scope.row.one_select" @change="checked => oneSelectChange(checked, scope.row)">{{ scope.row.one_title }}</el-checkbox> -->
+    </el-table-column>
+    <el-table-column prop="one_score" label="鍒嗗��" width="55" />
+    <el-table-column prop="one_maxScore" label="鏈�澶у垎鍊�" width="90" />
+    <el-table-column v-slot="scope" prop="two_title" label="浜岀骇鎸囨爣" width="200">
+      <!-- <el-checkbox v-model="scope.row.two_select" @change="checked => twoSelectChange(checked, scope.row)">{{ scope.row.two_title }}</el-checkbox> -->
+    </el-table-column>
+    <el-table-column prop="two_score" label="鍒嗗��" width="55" />
+    <el-table-column prop="two_maxScore" label="鏈�澶у垎鍊�" width="90" />
+    <el-table-column v-slot="scope" prop="three_title" label="鍏蜂綋闂">
+      <el-checkbox
+        v-model="scope.row.three_select"
+        @change="(checked) => threeSelectChange(checked, scope.row)"
+        >{{ scope.row.three_title }}</el-checkbox
+      >
+    </el-table-column>
+    <el-table-column prop="three_score" label="鍗曢」鎵e垎" width="90" />
+  </el-table>
 </template>
 
 <script>
 import evaluateApi from '@/api/fysp/evaluateApi';
 import { useFetchData } from '@/composables/fetchData';
-
+import { ElMessage } from 'element-plus';
 export default {
   setup() {
     const { loading, fetchData } = useFetchData();
@@ -16,7 +46,10 @@
   },
   data() {
     return {
-      evaluation: []
+      tableData: [],
+      evaluation: [],
+      subTaskId: '',
+      isUpdated: false
     };
   },
   created() {
@@ -30,18 +63,217 @@
     //   // 姝ゆ椂 data 宸茬粡琚� observed 浜�
     //   { immediate: true }
     // );
-    this.getScore();
+  },
+  computed: {
+    // 宸茶鍕鹃�夌殑item
+    checkedUpdatedList() {
+      var list = [];
+      for (let index = 0; index < this.tableData.length; index++) {
+        const element = this.tableData[index];
+        if (element.three_select) {
+          list.push(element.three_id);
+        }
+      }
+      return list;
+    }
+  },
+  mounted() {
+    this.getList();
   },
   methods: {
-    // 鑾峰彇璇勫垎
-    getScore() {
-      this.fetchData(() => {
-        return evaluateApi.fetchItemEvaluation(this.$route.params.subTaskId).then((res) => {
-          this.evaluation = res;
+    // 姣忎竴涓崟鍏冩牸鐨刢lass
+    cellClassName({ row, column, rowIndex, columnIndex }) {
+      if (column.property === 'one_score') {
+        if (row.one_score < 0) {
+          return { color: 'red' };
+        }
+      } else if (column.property === 'two_score') {
+        if (row.two_score < 0) {
+          return { color: 'red' };
+        }
+      } else if (column.property === 'three_score') {
+        if (row.three_score < 0) {
+          return { color: 'red' };
+        }
+      }
+      return { color: 'black' };
+    },
+    /** 鎻愪环 */
+    submit() {
+      evaluateApi
+        .updateScore({
+          subTaskId: this.subTaskId,
+          itemList: this.checkedUpdatedList
+        })
+        .then((res) => {
+          if (res.success) {
+            ElMessage({
+              message: res.message,
+              type: 'success'
+            });
+          }else {
+            ElMessage({
+              message: res.message,
+              type: 'error'
+            });
+          }
         });
+      setTimeout(() => {
+        this.getList();
+      }, 1000);
+    },
+    /** 閫氳繃绗笁绾х殑id鑾峰彇涓婄骇浠ュ強椤剁骇 */
+    getSuperObjByThreeId(threeId, list, path = []) {
+      for (let index = 0; index < list.length; index++) {
+        const item = list[index];
+        // 灏嗗綋鍓嶉」娣诲姞鍒拌矾寰勪腑
+        const currentPath = path.concat(item);
+        if (item.id === threeId) {
+          // 濡傛灉鎵惧埌鍖归厤鐨� id锛岃繑鍥炶矾寰勬暟缁�
+          return currentPath;
+        }
+        const subList = item.subList;
+        if (subList) {
+          // 閫掑綊鏌ユ壘瀛愬垪琛�
+          const result = this.getSuperObjByThreeId(threeId, subList, currentPath);
+          if (result) {
+            return result; // 濡傛灉鎵惧埌鍖归厤鐨� id锛岃繑鍥炵粨鏋�
+          }
+        }
+      }
+      return null; // 濡傛灉娌℃湁鎵惧埌鍖归厤鐨� id锛岃繑鍥� null
+    },
+    /** 闂閫夋嫨妗� */
+    threeSelectChange(isSelect, row) {
+      this.isUpdated = true;
+    },
+    /** 鍒楀悎骞� */
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (columnIndex === 0 || columnIndex === 1 || columnIndex === 2) {
+        // 瀵� 涓�绾ф寚鏍� 鍒楄繘琛屽悎骞�
+        let rowSpan = 1;
+        for (let i = rowIndex + 1; i < this.tableData.length; i++) {
+          if (this.tableData[i].one_id === row.one_id) {
+            rowSpan++;
+          } else {
+            break;
+          }
+        }
+        if (rowIndex > 0) {
+          if (this.tableData[rowIndex - 1].one_id === row.one_id) {
+            return { rowspan: 0, colspan: 0 };
+          }
+        }
+        return { rowspan: rowSpan, colspan: 1 };
+      } else if (columnIndex === 3 || columnIndex === 4 || columnIndex === 5) {
+        // 瀵� 浜岀骇鎸囨爣 鍒楄繘琛屽悎骞讹紝纭繚 涓�绾ф寚鏍� 涓�鏍�
+        let rowSpan = 1;
+        for (let i = rowIndex + 1; i < this.tableData.length; i++) {
+          if (this.tableData[i].one_id === row.one_id && this.tableData[i].two_id === row.two_id) {
+            rowSpan++;
+          } else {
+            break;
+          }
+        }
+        if (rowIndex > 0) {
+          if (
+            this.tableData[rowIndex - 1].one_id === row.one_id &&
+            this.tableData[rowIndex - 1].two_id === row.two_id
+          ) {
+            return { rowspan: 0, colspan: 0 };
+          }
+        }
+        return { rowspan: rowSpan, colspan: 1 };
+      }
+    },
+    /** 瀵硅薄灞炴�ф嫹璐� */
+    deepCopyWithPrefix(obj, target, prefix) {
+      // 纭繚 target 鏄竴涓璞�
+      if (typeof target !== 'object' || target === null) {
+        target = {};
+      }
+
+      // 閬嶅巻瀵硅薄鐨勬墍鏈夊睘鎬�
+      for (const key in obj) {
+        if (obj.hasOwnProperty(key)) {
+          // 涓哄睘鎬у悕鍔犱笂鍓嶇紑
+          const newKey = prefix + key;
+          // 濡傛灉灞炴�у�兼槸瀵硅薄锛屽垯閫掑綊澶嶅埗
+          if (typeof obj[key] === 'object' && obj[key] !== null) {
+            this.deepCopyWithPrefix(obj[key], (target[newKey] = {}), prefix);
+          } else {
+            // 鍚﹀垯鐩存帴澶嶅埗灞炴��
+            target[newKey] = obj[key];
+          }
+        }
+      }
+
+      return target;
+    },
+    /** @param data 鍒楄〃鏁版嵁 */
+    genTableData(data) {
+      var result = [];
+      if (data) {
+        for (let i = 0; i < data.length; i++) {
+          const firstLevelItem = data[i];
+          var secondLevel = firstLevelItem.subList;
+          if (secondLevel) {
+            for (let j = 0; j < secondLevel.length; j++) {
+              const secondLevelItem = secondLevel[j];
+              var thirdLevel = secondLevelItem.subList;
+              if (thirdLevel) {
+                for (let q = 0; q < thirdLevel.length; q++) {
+                  const thirdLevelItem = thirdLevel[q];
+                  var item = {};
+                  this.deepCopyWithPrefix(firstLevelItem, item, 'one_');
+                  this.deepCopyWithPrefix(secondLevelItem, item, 'two_');
+                  this.deepCopyWithPrefix(thirdLevelItem, item, 'three_');
+                  result.push(item);
+                }
+              }
+            }
+          }
+        }
+      }
+      return result;
+    },
+    getList() {
+      this.subTaskId = this.$route.params.subTaskId;
+      evaluateApi.fetchItemEvaluation(this.subTaskId).then((res) => {
+        this.isUpdated = false;
+        this.tableData = this.genTableData(res.data.details);
+      });
+    },
+    onSearch(page, func) {
+      evaluateApi.fetchItemEvaluation(this.$route.params.subTaskId).then((res) => {
+        if (typeof func === 'function') {
+          // 澶勭悊鏁版嵁
+          var data = this.genTableData(res.data);
+
+          func({ data: data });
+        }
+        this.tableData = this.genTableData(res.data);
       });
     }
   }
 };
 </script>
-<style scoped></style>
+<style scoped>
+.table-style {
+  width: 100%;
+  padding-bottom: 30px;
+}
+.btns {
+  padding-bottom: 10px;
+  padding-right: 30px;
+  display: flex;
+  flex-direction: row-reverse;
+}
+/* 鏀瑰彉琛ㄦ牸鍐呭崟鍏冩牸杈规棰滆壊 */
+.el-table {
+  --el-table-border-color: #000000;
+}
+.red-cell {
+  background-color: red;
+}
+</style>

--
Gitblit v1.9.3