From 7e1d38f401555ac635c9ce10f63902d9a4c402e0 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期一, 14 十月 2024 17:15:47 +0800
Subject: [PATCH] Merge remote-tracking branch 'supervisionVue/hc-procheck-1014'

---
 src/api/fytz/userApi.js                                 |    6 
 src/views/fysp/check/components/CompDevicePhono.vue     |  264 ++++
 src/components.d.ts                                     |    6 
 src/components/ToolBar.vue                              |   41 
 src/utils/fileUtils.js                                  |    1 
 src/api/fysp/problemApi.js                              |   31 
 src/api/fysp/mediafileApi.js                            |   15 
 src/views/fysp/check/components/CompProRecent.vue       |  198 +++
 src/api/fysp/userApi.js                                 |   18 
 src/views/fysp/check/components/CompDeviceShowTest.vue  |  593 ++++++++++
 /dev/null                                               |   65 -
 src/views/fysp/check/components/ArbitraryPhoto.vue      |  358 ++++++
 src/main.js                                             |    2 
 src/views/fysp/check/components/CompDeviceShow.vue      |  233 +++
 src/api/fysp/sceneApi.js                                |    6 
 src/api/fysp/taskApi.js                                 |   18 
 src/views/fysp/check/ProCheck.vue                       |  188 ++
 src/components/SearchBar.vue                            |   38 
 src/views/fysp/check/components/CompLedgerPic.vue       |  191 +++
 src/views/fysp/check/components/CompProblemAddOrUpd.vue |  720 ++++++++++++
 src/api/fysp/deviceApi.js                               |   10 
 src/api/fytz/problemApi.js                              |   12 
 src/views/fysp/check/components/ComChangeEdit.vue       |  296 +++++
 src/views/fysp/check/components/CompProblemCard.vue     |  181 ++
 24 files changed, 3,313 insertions(+), 178 deletions(-)

diff --git a/src/api/fysp/deviceApi.js b/src/api/fysp/deviceApi.js
index f46d505..8dc9dd1 100644
--- a/src/api/fysp/deviceApi.js
+++ b/src/api/fysp/deviceApi.js
@@ -9,5 +9,15 @@
         }
       })
       .then((res) => res.data);
+  },
+  // 鑾峰彇璁惧
+  async fetchDevices(sceneId, deviceTypeId) {
+    const params = `?sceneId=${sceneId}&deviceTypeId=${deviceTypeId}`;
+    return await $fysp.get(`device${params}`).then((res) => res).then((res) => res.data);
+  },
+  // 鑾峰彇璁惧鐘舵�佷互鍙婅澶囪鎯�
+  async fetchDeviceStatus({deviceId, sceneId, deviceTypeId}) {
+    const params = `?deviceId=${deviceId}&sceneId=${sceneId}&deviceTypeId=${deviceTypeId}`;
+    return await $fysp.get(`device/status${params}`).then((res) => res).then((res) => res.data);
   }
 };
diff --git a/src/api/fysp/mediafileApi.js b/src/api/fysp/mediafileApi.js
new file mode 100644
index 0000000..ac05464
--- /dev/null
+++ b/src/api/fysp/mediafileApi.js
@@ -0,0 +1,15 @@
+import { $fysp } from '../index';
+
+export default {
+    /**
+    * 鑾峰彇宸℃煡涓殑浠绘剰鍥剧墖
+    */
+    getRoutineByStGuid(stGuid) {
+        const params = `?stGuid=${stGuid}`;
+        return $fysp.get(`mediafile/routine${params}`).then((res) => res.data);
+    },
+    getRoutineByiGuid(iGuid) {
+        const params = `?iGuid=${iGuid}`;
+        return $fysp.get(`mediafile/routine${params}`).then((res) => res.data);
+    }
+}
\ No newline at end of file
diff --git a/src/api/fysp/problemApi.js b/src/api/fysp/problemApi.js
index b543b7e..9fbc690 100644
--- a/src/api/fysp/problemApi.js
+++ b/src/api/fysp/problemApi.js
@@ -15,6 +15,35 @@
 
   fetchProblemType({ cityCode, districtCode, sceneTypeId }) {
     const params = `?taskTypeId=1&cityCode=${cityCode}&districtCode=${districtCode}&sceneTypeId=${sceneTypeId}`;
-    return $fysp.get(`problemtype/search${params}`).then((res) => res.data);
+    return $fysp.get(`problemtype/search${params}`).then((res) => res);
+  },
+
+  /**
+   * 鑾峰彇宸℃煡涓殑浠绘剰鍥剧墖
+   */
+  getAnyPic(inspectionGuid) {
+    const params = `${inspectionGuid}`;
+    return $fysp.get(`mediafile/${params}/5`).then((res) => res);
+  },
+  // 鑾峰彇闂浣嶇疆
+  getLocation({ sceneTypeId }) { 
+    const params = `?sceneType=${sceneTypeId}`;
+    return $fysp.get(`domainitem/location${params}`).then((res) => res);
+  },
+  // 鑾峰彇闂寤鸿
+  getSuggestion() {
+    return $fysp.get(`changeadvice`).then((res) => res);
+  },
+  // 淇敼闂
+  updateProblem(data) {    
+    return $fysp.post(`problemlist/updateProblem`, data).then((res) => res);
+  },
+  // 鏂板闂
+  newProblem(data) {
+    return $fysp.post(`problemlist/newProblem`, data).then((res) => res) 
+  },
+  // 淇敼鏁存敼
+  updateChange(data) {
+    return $fysp.post(`problemlist/updateChange`, data).then((res) => res) 
   }
 };
diff --git a/src/api/fysp/sceneApi.js b/src/api/fysp/sceneApi.js
index 9f38b93..88fec3b 100644
--- a/src/api/fysp/sceneApi.js
+++ b/src/api/fysp/sceneApi.js
@@ -66,5 +66,11 @@
    */
   updateScene(scene) {
     return $fysp.post('scense', scene).then((res) => res.data);
+  },
+  /**
+   * 鑾峰彇鎵�鏈夊満鏅被鍨�
+   */
+  getAllScene() {
+    return $fysp.get('scense/alltype').then((res) => res.data);
   }
 };
diff --git a/src/api/fysp/taskApi.js b/src/api/fysp/taskApi.js
index 6e4e66a..3da40bd 100644
--- a/src/api/fysp/taskApi.js
+++ b/src/api/fysp/taskApi.js
@@ -89,13 +89,27 @@
   /**
    * 鑾峰彇瀛愪换鍔¢棶棰樿鎯�
    */
-  getProBySubtask(id) {
-    return $fysp
+  async getProBySubtask(id) {
+    return await $fysp
       .get('problemlist/subtask', {
         params: {
           stGuid: id
         }
       })
       .then((res) => res.data);
+  },
+  /** 
+   * 閫氳繃鎬讳换鍔d鍜屾椂闂村尯闂磋幏鍙栧瓙浠诲姟鍒楄〃
+   */
+  async getByTopTaskAndDate({startTime, endTime, sceneTypeId, topTaskId}) {
+    const params = `?startTime=${startTime}&endTime=${endTime}&sceneTypeId=${sceneTypeId}&topTaskId=${topTaskId}`;
+    return await $fysp.get(`subtask/getSubTask${params}`).then((res) => res.data);
+  },
+  /** 
+   * 鑾峰彇鏌愪釜鍦烘櫙鐨勫贰鏌ヤ换鍔�
+   */
+  async getSubtaskByScene({startTime, endTime, sceneId}) {
+    const params = `?startTime=${startTime}&endTime=${endTime}&sceneId=${sceneId}`;
+    return await $fysp.get(`subtask/byScene${params}`).then((res) => res.data);
   }
 };
diff --git a/src/api/fysp/userApi.js b/src/api/fysp/userApi.js
index fc38ad2..a69250e 100644
--- a/src/api/fysp/userApi.js
+++ b/src/api/fysp/userApi.js
@@ -28,18 +28,10 @@
   autoCreateAccount(sId) {
     return $fysp.post(`userinfo/create?sceneId=${sId}`).then((res) => res.data);
   },
-
-  /**
-   * 鐢ㄦ埛妯$硦鎼滅储
-   * @param {object} area 鍖哄煙鑼冨洿鏉′欢
-   * @param {String} keyword 鎼滅储鍏抽敭瀛�
-   * @param {Number} userType 鐢ㄦ埛绫诲瀷锛岄粯璁�3锛氫紒涓�
-   * @returns
-   */
-  searchUser(area, keyword, page = 1, perPage = 20, userType = 3) {
-    const param = `?keyword=${keyword}&userType=${userType}&page=${page}&per_page=${perPage}`
-    return $fysp
-      .post(`userinfo/search${param}`, area)
-      .then((res) => res.data);
+   /**
+ * 鑾峰彇鍦烘櫙瀵瑰簲鐨勯缇界幆澧冪郴缁熺敤鎴穒d
+ */
+   getTzId(sceneId) {
+    return $fysp.get(`usermap?sceneId=${sceneId}`).then((res) => res.data);
   }
 };
diff --git a/src/api/fytz/problemApi.js b/src/api/fytz/problemApi.js
new file mode 100644
index 0000000..449d350
--- /dev/null
+++ b/src/api/fytz/problemApi.js
@@ -0,0 +1,12 @@
+import { $fytz } from '../index';
+
+export default {
+
+    /**
+     * 鑾峰彇鍦烘櫙瀵瑰簲鐨勫綋鏈堝彴璐﹀浘鐗�
+     */
+    getLedgerPic({tzUserId,sceneType,time}) {
+        return $fytz.get(`ledger/${tzUserId}/detail2?sceneType=${sceneType}&time=${time}`).then((res) => res.data);
+    }
+
+}
\ No newline at end of file
diff --git a/src/api/fytz/userApi.js b/src/api/fytz/userApi.js
index dd9b9fa..8c49db9 100644
--- a/src/api/fytz/userApi.js
+++ b/src/api/fytz/userApi.js
@@ -45,6 +45,8 @@
    * 閲嶇疆鐢ㄦ埛瀵嗙爜
    */
   resetPassword(id) {
-    return $fytz.post(`userInfo/resetPw?userId=${id}`).then((res) => res.data);
-  }
+    return $fytz.post(`userInfo/resetPw?userId=${id}`).then((res) => res);
+  },
+
+
 };
diff --git a/src/components.d.ts b/src/components.d.ts
index cb3ff11..1b14541 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -24,6 +24,8 @@
     ElCascader: typeof import('element-plus/es')['ElCascader']
     ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
     ElCol: typeof import('element-plus/es')['ElCol']
+    ElCollapse: typeof import('element-plus/es')['ElCollapse']
+    ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
     ElContainer: typeof import('element-plus/es')['ElContainer']
     ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
@@ -42,15 +44,12 @@
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
-    ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
     ElMain: typeof import('element-plus/es')['ElMain']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     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,7 +61,6 @@
     ElStep: typeof import('element-plus/es')['ElStep']
     ElSteps: typeof import('element-plus/es')['ElSteps']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
-    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']
diff --git a/src/components/SearchBar.vue b/src/components/SearchBar.vue
index ca5c7e2..539278a 100644
--- a/src/components/SearchBar.vue
+++ b/src/components/SearchBar.vue
@@ -4,18 +4,23 @@
       <el-form :inline="true" :model="formSearch">
         <el-form-item label="鎬讳换鍔�">
           <!-- <el-input v-model="formSearch.topTaskId" placeholder="鎬讳换鍔�" /> -->
-          <el-select v-model="formSearch.topTaskId" placeholder="鎬讳换鍔�" style="width: 260px">
-            <el-option v-for="s in topTasks" :key="s.value" :label="s.label" :value="s.value" />
+          <el-select v-model="formSearch.topTaskId" placeholder="鎬讳换鍔�">
+            <el-option
+              v-for="s in topTasks"
+              :key="s.value"
+              :label="s.label"
+              :value="s.value"
+            />
           </el-select>
         </el-form-item>
-        <!-- <FYOptionScene
-          :allOption="false"
-          :type="2"
-          v-model:value="formSearch.scenetype"
-        ></FYOptionScene> -->
         <el-form-item label="鍦烘櫙绫诲瀷">
-          <el-select v-model="formSearch.sceneTypeId" placeholder="鍦烘櫙绫诲瀷" style="width: 150px">
-            <el-option v-for="s in sceneTypes" :key="s.value" :label="s.label" :value="s.value" />
+          <el-select v-model="formSearch.sceneTypeId" placeholder="鍦烘櫙绫诲瀷">
+            <el-option
+              v-for="s in sceneTypes"
+              :key="s.value"
+              :label="s.label"
+              :value="s.value"
+            />
           </el-select>
         </el-form-item>
         <el-form-item>
@@ -33,7 +38,7 @@
 
 <script>
 import taskApi from '@/api/fysp/taskApi';
-import { enumScene } from '@/enum/scene';
+import { enumScene } from "@/enum/scene";
 
 export default {
   emits: ['onSubmit'],
@@ -43,8 +48,9 @@
       sceneTypes: enumScene(2, false),
       formSearch: {
         topTaskId: '',
-        sceneTypeId: ''
-      }
+        sceneTypeId: '',
+        obj: '',
+      },
     };
   },
   methods: {
@@ -56,13 +62,15 @@
           list.push({
             value: r.tguid,
             label: r.name,
+            obj: r,
             towncode: r.towncode,
             districtCode: r.districtcode,
-            month: r.starttime.slice(0, 7)
+            month: r.starttime.slice(0, 7),
           });
         });
         this.topTasks = list;
         this.formSearch.topTaskId = list[0].value;
+        this.formSearch.obj = list[0].obj;
         this.$emit('onSubmit', this.formSearch);
       });
     },
@@ -70,12 +78,12 @@
     onSubmit() {
       // console.log(this.formSearch.sceneTypeId)
       this.$emit('onSubmit', this.formSearch);
-    }
+    },
   },
   mounted() {
     this.formSearch.sceneTypeId = this.sceneTypes[0].value;
     this.getOptions();
-  }
+  },
 };
 </script>
 
diff --git a/src/components/ToolBar.vue b/src/components/ToolBar.vue
index bf2912b..09c3f3b 100644
--- a/src/components/ToolBar.vue
+++ b/src/components/ToolBar.vue
@@ -1,17 +1,25 @@
 <template>
-  <div class="layout" >
+  <div class="layout">
     <el-row v-if="title">
-      <el-col :span=" 16 " class="title">{{ title }}</el-col>
-      <el-col :span=" 8 ">
+      <el-col :span="16" class="title">{{ title }}</el-col>
+      <el-col :span="8">
         <el-row justify="end" class="btn-group">
-          <el-button v-for="(b, i) in buttons" :key=" i " :type=" b.color ? b.color : 'primary' " size="small">{{ b.name
-          }}</el-button>
+          <el-button
+            v-for="(b, i) in buttons"
+            :key="i"
+            :type="b.color ? b.color : 'primary'"
+            size="small"
+            @click="b.click"
+            >{{ b.name }}</el-button
+          >
         </el-row>
       </el-col>
     </el-row>
     <el-row class="tag-group" v-if="title">
       <el-space>
-        <el-tag v-for="(d, i) in descriptions" :key=" i " type="info" size="small">{{ d.name + ": " + d.value }}</el-tag>
+        <el-tag v-for="(d, i) in descriptions" :key="i" type="info" size="small">{{
+          d.name + ': ' + d.value
+        }}</el-tag>
       </el-space>
     </el-row>
   </div>
@@ -27,21 +35,22 @@
       type: Array,
       default: () => [
         {
-          name: "",
-          value: "",
-        },
-      ],
+          name: '',
+          value: ''
+        }
+      ]
     },
     buttons: {
       type: Array,
       default: () => [
         {
-          name: "",
-          color: "primary",
-        },
-      ],
-    },
-  },
+          name: '',
+          color: 'primary',
+          click: () => {}
+        }
+      ]
+    }
+  }
 };
 </script>
 <style scoped>
diff --git a/src/main.js b/src/main.js
index e7e95b7..511d8bd 100644
--- a/src/main.js
+++ b/src/main.js
@@ -5,7 +5,6 @@
 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';
@@ -26,7 +25,6 @@
 const app = createApp(App);
 
 app.config.globalProperties.$fm = timeUtil;
-app.config.globalProperties.$deepCopy = DeepCopy.deepCopy;
 
 for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
   app.component(key, component);
diff --git a/src/utils/DeepCopy.js b/src/utils/DeepCopy.js
deleted file mode 100644
index 5124708..0000000
--- a/src/utils/DeepCopy.js
+++ /dev/null
@@ -1,65 +0,0 @@
-export default {
-    deepCopy(target) {
-        const map = new WeakMap()
-        
-        function isObject(target) {
-            return (typeof target === 'object' && target ) || typeof target === 'function'
-        }
-    
-        function clone(data) {
-            if (!isObject(data)) {
-                return data
-            }
-            if ([Date, RegExp].includes(data.constructor)) {
-                return new data.constructor(data)
-            }
-            if (typeof data === 'function') {
-                return new Function('return ' + data.toString())()
-            }
-            const exist = map.get(data)
-            if (exist) {
-                return exist
-            }
-            if (data instanceof Map) {
-                const result = new Map()
-                map.set(data, result)
-                data.forEach((val, key) => {
-                    if (isObject(val)) {
-                        result.set(key, clone(val))
-                    } else {
-                        result.set(key, val)
-                    }
-                })
-                return result
-            }
-            if (data instanceof Set) {
-                const result = new Set()
-                map.set(data, result)
-                data.forEach(val => {
-                    if (isObject(val)) {
-                        result.add(clone(val))
-                    } else {
-                        result.add(val)
-                    }
-                })
-                return result
-            }
-            const keys = Reflect.ownKeys(data)
-            const allDesc = Object.getOwnPropertyDescriptors(data)
-            const result = Object.create(Object.getPrototypeOf(data), allDesc)
-            map.set(data, result)
-            keys.forEach(key => {
-                const val = data[key]
-                if (isObject(val)) {
-                    result[key] = clone(val)
-                } else {
-                    result[key] = val
-                }
-            })
-            return result
-        }
-        // clone(target)
-        return JSON.parse(JSON.stringify(target));
-    }
-    
-}
\ No newline at end of file
diff --git a/src/utils/fileUtils.js b/src/utils/fileUtils.js
index 5cf0c35..3733ddd 100644
--- a/src/utils/fileUtils.js
+++ b/src/utils/fileUtils.js
@@ -9,6 +9,7 @@
             Img.src = url;
         }else {
             Img.src = url + '?v=' + Math.random(); // 澶勭悊缂撳瓨,fix缂撳瓨bug,鏈夌紦瀛橈紝娴忚鍣ㄤ細鎶ラ敊;
+            // Img.src = url;
         }
         // Img.src = /^data:image/.test(url) ? url : url + '?' + new Date().getTime() + '&v=' + Math.random(); // 澶勭悊缂撳瓨,fix缂撳瓨bug,鏈夌紦瀛橈紝娴忚鍣ㄤ細鎶ラ敊;
 
diff --git a/src/views/fysp/check/ProCheck.vue b/src/views/fysp/check/ProCheck.vue
index f0c4e53..4be5761 100644
--- a/src/views/fysp/check/ProCheck.vue
+++ b/src/views/fysp/check/ProCheck.vue
@@ -3,16 +3,12 @@
     <template #header>
       <SearchBar @on-submit="search">
         <template #summary>
-          <CompSubTaskStatistic :subtasks="subtasks"/>
+          <CompSubTaskStatistic :subtasks="subtasks" />
         </template>
       </SearchBar>
     </template>
     <template #aside>
-      <SideList
-        :items="subtasks"
-        :loading="sideLoading"
-        @item-click="chooseSubtask"
-      ></SideList>
+      <SideList :items="subtasks" :loading="sideLoading" @item-click="chooseSubtask"></SideList>
     </template>
     <template #main>
       <ToolBar
@@ -21,41 +17,99 @@
         :buttons="buttons"
         :loading="mainLoading"
       ></ToolBar>
-      <el-scrollbar
-        v-if="curProList.length > 0"
-        class="el-scrollbar"
-        v-loading="mainLoading"
-      >
+      <el-scrollbar v-if="curProList.length > 0" class="el-scrollbar" v-loading="mainLoading">
         <CompProblemCard
-          v-for="(p, i) in curProList"
+          v-if="compProblemCardVisible"
           :key="i"
-          :index="i+1"
+          v-for="(p, i) in curProList"
+          :index="i + 1"
           :problem="p"
+          :subtask="curSubtask.data"
+          :topTask="topTask"
+          @updated="onProSubmited"
           @submit="updateSubtask"
         ></CompProblemCard>
       </el-scrollbar>
       <el-empty v-else description="鏆傛棤璁板綍" v-loading="mainLoading" />
     </template>
   </BaseContentLayout>
+  <el-dialog
+    v-model="proAddOrUpdDialogVisible"
+    :before-close="proAddOrUpdDialogClose"
+    width="80%"
+    title="鏂板闂"
+  >
+    <CompProblemAddOrUpd
+      v-if="proAddOrUpdDialogVisible"
+      :subtask="curSubtask.data"
+      :topTask="topTask"
+      ref="compProblemAddOrUpdRef"
+      @submited="newProSubmit"
+    />
+  </el-dialog>
+  <el-dialog
+    v-model="anyPhotoDialog"
+    :before-close="beforeAnyPhotoDialogclose"
+    width="80%"
+    title="浠绘剰鍥剧墖"
+  >
+    <ArbitraryPhoto
+      v-if="anyPhotoDialog"
+      :readonly="true"
+      :subtask="curSubtask.data"
+      ref="arbitraryPhotoRef"
+      @selectByAnyPhonoEvent="handleCloseCheckAnyPhono"
+    >
+    </ArbitraryPhoto>
+  </el-dialog>
+  <el-drawer
+    :direction="rtl"
+    v-model="deviceShowDialog"
+    :before-close="beforeDeviceShowDialogclose"
+    title="璁炬柦璁惧"
+    size="65%"
+  >
+    <CompDeviceShowTest v-if="deviceShowDialog" ref="deviceShowRef"> </CompDeviceShowTest>
+  </el-drawer>
 </template>
 
 <script>
+import ArbitraryPhoto from './components/ArbitraryPhoto.vue';
 import taskApi from '@/api/fysp/taskApi';
 import ProCheckProxy from './ProCheckProxy';
 
 import { ElMessageBox, ElNotification, ElMessage } from 'element-plus';
+import CompProblemAddOrUpd from './components/CompProblemAddOrUpd.vue';
+import CompDeviceShow from './components/CompDeviceShow.vue';
 
 import CompProblemCard from './components/CompProblemCard.vue';
 import CompSubTaskStatistic from './components/CompSubTaskStatistic.vue';
-
+import CompProRecent from './components/CompProRecent.vue';
+import CompDeviceShowTest from './components/CompDeviceShowTest.vue';
 export default {
-  components: { CompProblemCard, CompSubTaskStatistic },
+  components: {
+    CompProblemCard,
+    CompSubTaskStatistic,
+    CompProblemAddOrUpd,
+    ArbitraryPhoto,
+    CompDeviceShowTest,
+    CompProRecent
+  },
   data() {
     return {
+      compProblemCardVisible: true,
+      // 璁惧鍥�
+      deviceShowDialog: false,
+      // 浠绘剰鍥�
+      anyPhotoDialog: false,
+      // 鏂板闂
+      proAddOrUpdDialogVisible: false,
       //宸︿晶鑿滃崟鏍忓姞杞界姸鎬�
       sideLoading: false,
       //鍙充晶鍐呭鏍忓姞杞界姸鎬�
       mainLoading: false,
+      // 鎬讳换鍔�
+      topTask: {},
       //瀛愪换鍔″垪琛�
       subtasks: [],
       //褰撳墠閫変腑鐨勪换鍔�
@@ -67,16 +121,30 @@
         {
           name: '鏂板闂',
           color: 'success',
+          click: () => {
+            this.proAddOrUpdDialogVisible = true;
+          }
         },
         {
           name: '浠绘剰鍥剧墖',
           color: 'warning',
+          click: () => {
+            this.anyPhotoDialog = true;
+          }
+        },
+        {
+          name: '璁炬柦璁惧',
+          color: 'info',
+          click: () => {
+            this.openDeviceShowDialog();
+          }
         },
         {
           name: '鎵归噺瀹℃牳',
           color: 'primary',
-        },
-      ],
+          click: () => {}
+        }
+      ]
     };
   },
   computed: {
@@ -90,50 +158,50 @@
         {
           name: '浠诲姟鎬昏',
           value: 0,
-          type: 'info',
+          type: 'info'
         },
         {
           name: '闂鏈鏍�',
           value: 0,
           type: 'success',
-          icon: 'SuccessFilled',
+          icon: 'SuccessFilled'
         },
         {
           name: '闂閮ㄥ垎瀹℃牳',
           value: 0,
           type: 'success',
-          icon: 'SuccessFilled',
+          icon: 'SuccessFilled'
         },
         {
           name: '闂鍏ㄩ儴瀹℃牳',
           value: 0,
           type: 'success',
-          icon: 'SuccessFilled',
+          icon: 'SuccessFilled'
         },
         {
           name: '鏈暣鏀�',
           value: 0,
           type: 'info',
-          icon: 'WarningFilled',
+          icon: 'WarningFilled'
         },
         {
           name: '鏁存敼鏈鏍�',
           value: 0,
           type: 'info',
-          icon: 'WarningFilled',
+          icon: 'WarningFilled'
         },
         {
           name: '鏁存敼閮ㄥ垎瀹℃牳',
           value: 0,
           type: 'warning',
-          icon: 'WarningFilled',
+          icon: 'WarningFilled'
         },
         {
           name: '鏁存敼鍏ㄩ儴瀹℃牳',
           value: 0,
           type: 'warning',
-          icon: 'WarningFilled',
-        },    
+          icon: 'WarningFilled'
+        }
       ];
 
       this.subtasks.forEach((s) => {
@@ -158,11 +226,33 @@
       });
 
       return _summary;
-    },
+    }
   },
   methods: {
+    // 鎵撳紑璁惧鍥�
+    openDeviceShowDialog() {
+      this.deviceShowDialog = true;
+      this.$nextTick(() => {
+        this.$refs.deviceShowRef.init(this.curSubtask.data.scene);
+      });
+    },
+    // 鍏抽棴璁惧鍥惧脊绐�
+    beforeDeviceShowDialogclose() {
+      this.deviceShowDialog = false;
+    },
+    // 鍏抽棴浠绘剰鍥剧墖寮圭獥
+    beforeAnyPhotoDialogclose() {
+      this.anyPhotoDialog = false;
+    },
+    handleCloseCheckAnyPhono() {
+      this.beforeAnyPhotoDialogclose();
+    },
+    proAddOrUpdDialogClose() {
+      this.proAddOrUpdDialogVisible = false;
+    },
     //鏌ヨ瀛愪换鍔$粺璁′俊鎭�
     search(formSearch) {
+      this.topTask = formSearch.obj;
       this.sideLoading = true;
       this.mainLoading = true;
       this.curProList = [];
@@ -175,7 +265,7 @@
             type: t,
             title: s.stName,
             categoly: s.stPlanTime.split('T')[0],
-            data: s,
+            data: s
           });
         });
         this.subtasks = list;
@@ -201,6 +291,7 @@
     },
     //鐐瑰嚮宸︿晶鑿滃崟浠诲姟浜嬩欢
     chooseSubtask(s) {
+      // this.currInsGuid = s.data.insGuid
       this.sideLoading = false;
       this.mainLoading = true;
       // const controller = new AbortController();
@@ -214,12 +305,49 @@
           this.mainLoading = false;
         });
     },
-    updateSubtask() {
+    // 闂鍗$墖缁勪欢涓诲姩鍙戣捣鍒锋柊鐖剁粍浠舵暟鎹�
+    updateSubtask(isOk) {
       this.curSubtask.data.proCheckedNum++;
       this.curSubtask.type = this.getSubtaskType(this.curSubtask.data);
+      if (!isOk) {
+        return;
+      }
+      this.refreshCurrSubtask();
+    },
+    onProSubmited(isOk) {
+      this.proAddOrUpdDialogClose();
+      if (!isOk) {
+        return;
+      }
+      this.updateSubtask(isOk);
+    },
+    newProSubmit(isOk) {
+      this.proAddOrUpdDialogVisible = false;
+      if (!isOk) {
+        return;
+      }
+      this.refreshCurrSubtask();
+    },
+    // 鍒锋柊褰撳墠閫変腑瀛愪换鍔�
+    refreshCurrSubtask() {
+      this.compProblemCardVisible = false;
+      this.sideLoading = false;
+      this.mainLoading = true;
+      setTimeout(() => {
+        taskApi
+          .getProBySubtask(this.curSubtask.data.stGuid)
+          .then((res) => {
+            this.curProList = res;
+            // this.curSubtask = s;
+          })
+          .finally(() => {
+            this.mainLoading = false;
+            this.compProblemCardVisible = true;
+          });
+      }, 150);
     }
   },
-  mounted() {},
+  mounted() {}
 };
 </script>
 
diff --git a/src/views/fysp/check/components/ArbitraryPhoto.vue b/src/views/fysp/check/components/ArbitraryPhoto.vue
new file mode 100644
index 0000000..4759c38
--- /dev/null
+++ b/src/views/fysp/check/components/ArbitraryPhoto.vue
@@ -0,0 +1,358 @@
+<template>
+  <div class="main">
+    <div class="filters" v-if="false">
+      <el-select
+        v-for="(key_select, index_select) of filters.keys()"
+        :placeholder="key_select.text"
+      >
+        <el-option
+          v-for="(key_option, index_option) in filters.get(key_select.key)"
+          :key="key_option.key"
+          :value="key_option.value"
+          :label="key_option.label"
+        >
+        </el-option>
+      </el-select>
+    </div>
+    <div class="btns" v-if="!readonly">
+      <el-button size="small" type="primary" @click="sendSelectedImg(true)">纭畾</el-button>
+      <el-button size="small" type="primary" @click="sendSelectedImg(false)">鍙栨秷</el-button>
+    </div>
+
+    <div class="center">
+      <el-descriptions>
+        <el-descriptions-item label="鎬绘暟">
+          <span>{{ this.imgUrlList.length }}</span>
+        </el-descriptions-item>
+      </el-descriptions>
+      <el-tabs v-model="activeId" type="card">
+        <el-tab-pane
+          v-for="item in typeList"
+          :label="item.businesstype"
+          :name="item.businesstypeid"
+        >
+        </el-tab-pane>
+      </el-tabs>
+      <el-empty v-if="isEmpty" description="鏆傛棤璁板綍" />
+      <div class="imgs">
+        <el-image
+          v-for="(img, i) in typeImgMap.get(activeId)"
+          :class="[Boolean(img.isSelect) ? 'selected' : 'noActive', 'image']"
+          fit="cover"
+          :src="img.url"
+          lazy
+          @click="onSelect(img, i)"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import problemApi from '@/api/fysp/problemApi.js';
+import mediafileApi from '@/api/fysp/mediafileApi.js';
+import { $fysp } from '@/api/index.js';
+export default {
+  props: {
+    filters: Map,
+    // 鏄惁浠ュ彧璇荤殑褰㈠紡鏌ョ湅褰撳墠椤甸潰
+    readonly: {
+      type: Boolean,
+      default: false
+    },
+    subtask: {
+      type: Object,
+      efault: {}
+    },
+    inspectionGuid: {
+      type: String,
+      default: ''
+    },
+    defaultFile: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      // 鏃犳暟鎹�
+      isEmpty: false,
+      isClose: false,
+      isAll: false,
+      activeId: '',
+      typeList: [
+        // { businesstypeid: 5, businesstype: '甯歌璁板綍' },
+        // { businesstypeid: 3, businesstype: '鐩戞祴璁惧' },
+        // { businesstypeid: 7, businesstype: '閾墝' },
+        // { businesstypeid: 51, businesstype: '鎵╁睍绫讳竴' },
+        // { businesstypeid: 52, businesstype: '鎵╁睍绫讳簩' },
+        // { businesstypeid: 53, businesstype: '鎵╁睍绫讳笁' },
+        // { businesstypeid: 54, businesstype: '鎵╁睍绫诲洓' },
+        // { businesstypeid: 55, businesstype: '鎵╁睍绫讳簲' },
+        // { businesstypeid: 56, businesstype: '鎵╁睍绫诲叚' },
+        // { businesstypeid: 57, businesstype: '鎵╁睍绫讳竷' },
+        // { businesstypeid: 58, businesstype: '鎵╁睍绫诲叓' },
+        // { businesstypeid: 59, businesstype: '鎵╁睍绫讳節' },
+        // { businesstypeid: 60, businesstype: '鎵╁睍绫诲崄' }
+      ],
+      typeImgMap: new Map(),
+      imgUrlList: []
+    };
+  },
+  watch: {
+    defaultFile: {
+      handler(newFileList, oldFileList) {
+        if (this.isClose) {
+          return;
+        }
+      },
+      deep: true
+    },
+    typeImgMap: {
+      handler(newMap, oldMap) {
+        if (this.isClose || newMap.get(this.activeId) == undefined) {
+          return;
+        }
+        newMap.get(this.activeId).forEach((i) => {
+          if (i.isSelect == true) {
+            return;
+          }
+          this.defaultFile.forEach((imgItem) => {
+            if (imgItem.url == i.url) {
+              i.isSelect = true;
+            }
+          });
+        });
+      },
+
+      deep: true
+    }
+  },
+  mounted() {
+    if (this.defaultFile == undefined || this.defaultFile == null) {
+      this.defaultFile = [];
+    }
+    if (this.subtask) {
+      this.getAllImgList();
+    }
+  },
+  methods: {
+    // 鍒濆鍖栧垰寮�濮嬮�変腑鐨勬爣绛�
+    initSelectedTab() {
+      if (this.typeList.length > 0) {
+        this.activeId = this.typeList[0].businesstypeid;
+      }
+    },
+    async getAllImgList() {
+      // for(var k of this.typeImgMap.keys()) {
+      //     this.typeImgMap.set(k, [])
+      // }
+      await mediafileApi.getRoutineByStGuid(this.subtask.stGuid).then((res) => {
+        this.isEmpty = false;
+        let data = res.data;
+        if (data.length == 0) {
+          this.isEmpty = true;
+        }
+        for (const e of data) {
+          let list;
+          let businesstypeid = e.businesstypeid;
+          let businesstype = e.businesstype;
+          let hasThisType = false;
+          this.typeImgMap.forEach((v, k, m) => {
+            if (k == businesstypeid) {
+              hasThisType = true;
+              var isAlreadyHas = false;
+              if (v != undefined && v != null) {
+                for (let index = 0; index < v.length; index++) {
+                  const element = v[index];
+                  if (element.guid == e.guid) {
+                    isAlreadyHas = true;
+                    break;
+                  }
+                }
+              }
+              if (!isAlreadyHas) {
+                v.push(e);
+              }
+            }
+          });
+          if (!hasThisType) {
+            this.typeImgMap.set(businesstypeid, Array.of(e));
+            this.typeList.push(e);
+          }
+          this.imgUrlList.push(e);
+          // TODO imgUrl鍏ㄥ眬閰嶇疆
+          e.url = $fysp.imgUrl + e.extension1 + e.guid + '.jpg';
+          // e.url = "http://47.100.191.150:9005/images/" + e.extension1 + e.guid + '.jpg'
+          e.isSelect = false;
+        }
+        this.initSelectedTab();
+      });
+    },
+    getInitImgList() {
+      mediafileApi.getRoutineByStGuid(this.subtask.stGuid).then((res) => {
+        let data = res.data;
+        for (const e of data) {
+          let list;
+          let businesstypeid = e.businesstypeid;
+          let businesstype = e.businesstype;
+          let hasThisType = false;
+          this.typeImgMap.forEach((v, k, m) => {
+            if (k == businesstypeid) {
+              hasThisType = true;
+              if (v.length < 3) {
+                v.push(e);
+              }
+            }
+          });
+          if (!hasThisType) {
+            this.typeImgMap.set(businesstypeid, Array.of(e));
+            this.typeList.push(e);
+          }
+          this.imgUrlList.push(e);
+          // TODO imgUrl鍏ㄥ眬閰嶇疆
+          e.url = $fysp.imgUrl + e.extension1 + e.guid + '.jpg';
+          // e.url = "http://47.100.191.150:9005/images/" + e.extension1 + e.guid + '.jpg'
+          e.isSelect = false;
+        }
+        if (this.typeList.length > 0) {
+          this.activeId = this.typeList[0].businesstypeid;
+        }
+      });
+    },
+    onSelect(img, i) {
+      // if (i == 2 && !this.isAll) {
+      //   this.getAllImgList();
+      //   this.isAll = true;
+      // } else {
+      //   if (this.readonly) {
+      //     return;
+      //   }
+      //   img.isSelect = !Boolean(img.isSelect);
+      // }
+
+      if (this.readonly) {
+        return;
+      }
+      img.isSelect = !Boolean(img.isSelect);
+    },
+    sendSelectedImg(isOk) {
+      let result = [];
+      if (!Boolean(isOk)) {
+        this.$emit('selectByAnyPhonoEvent', result);
+      }
+      for (const item of this.imgUrlList) {
+        if (item.isSelect == true) {
+          result.push(item);
+        }
+      }
+      this.isClose = true;
+      this.$emit('selectByAnyPhonoEvent', result);
+    }
+  }
+};
+</script>
+<style scoped>
+.center {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+.text {
+  padding: 20px;
+}
+
+.main {
+  margin: 0 auto; /* 浣跨埗鍏冪礌灞呬腑 */
+  height: 100%;
+  width: 100%;
+}
+
+.btns {
+  height: 10%;
+}
+/* 
+.img_types {
+  margin: 0 auto;
+  height: 440px;
+  width: 900px;
+  flex-grow: 1;
+  overflow-y: hidden ;
+  padding: 3%;
+  flex-wrap: wrap;
+  overflow: hidden;
+} */
+
+.imgs {
+  height: 370px;
+  width: 90%;
+  min-height: 100px !important;
+  /* border-style:solid;
+    border-radius: 1px; */
+  /* height: 100%; */
+  flex-grow: 1 !important;
+  overflow-y: auto !important;
+  /* 鍐呭鐨勫唴杈硅窛 */
+  display: flex !important;
+  flex-wrap: wrap !important;
+  /* overflow: hidden; */
+}
+
+.image {
+  height: 210px;
+  width: 200px;
+  border-radius: 4px;
+}
+
+.active {
+  padding: 5px;
+  width: 20%;
+  height: 200px;
+  border: 0.5rem outset rgb(52, 155, 4);
+}
+
+.selected {
+  padding: 5px;
+  color: #4abe84;
+  box-shadow: 0 2px 7px 0 rgba(85, 110, 97, 0.35);
+  border: 1px solid rgba(74, 190, 132, 1);
+}
+
+.selected:before {
+  content: '';
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  border: 17px solid #4abe84;
+  border-top-color: transparent;
+  border-left-color: transparent;
+}
+
+.selected:after {
+  content: '';
+  width: 5px;
+  height: 12px;
+  position: absolute;
+  right: 6px;
+  bottom: 6px;
+  border: 2px solid #fff;
+  border-top-color: transparent;
+  border-left-color: transparent;
+  transform: rotate(45deg);
+}
+
+.noActive {
+  padding: 5px;
+}
+
+.blurry {
+  filter: blur(3px);
+}
+.filters {
+  display: flex;
+  padding: 5px;
+}
+
+.el-dialog__body {
+  height: 60vh;
+}
+</style>
diff --git a/src/views/fysp/check/components/ComChangeEdit.vue b/src/views/fysp/check/components/ComChangeEdit.vue
new file mode 100644
index 0000000..6c52b21
--- /dev/null
+++ b/src/views/fysp/check/components/ComChangeEdit.vue
@@ -0,0 +1,296 @@
+<template>
+  <div>
+    <div class="t-card_item">
+      鏁存敼鍥剧墖&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+      <div>
+        <el-button @click="chosePicFromAnyPic">浠庝换鎰忓浘鐗囬�夊彇</el-button>
+        <!-- <el-button type="primary" @click="chosePicFromLedgerPic">浠庡彴璐﹂�夊彇</el-button> -->
+        <el-button @click="choseChangePic">浠庢枃浠跺す閫夊彇</el-button>
+      </div>
+    </div>
+    <el-upload
+      class="img-upload"
+      ref="uploadRef"
+      v-model:file-list="fileList"
+      list-type="picture-card"
+      multiple
+      :auto-upload="false"
+      crossorigin="Anonymous"
+      :before-remove="beforeRemoveFile"
+      :on-preview="handlePictureCardPreview"
+      :disabled="readonly"
+      accept="image/*"
+    >
+      <el-button type="primary" id="uploadBtnId" style="display: none"></el-button>
+      <el-icon>
+        <Plus />
+      </el-icon>
+    </el-upload>
+    <div class="flex-div">
+      <el-button type="primary" @click="onSubmit">淇濆瓨</el-button>
+      <el-button @click="this.$emit('submited', false)">鍙栨秷</el-button>
+    </div>
+    <el-dialog
+      title="浠绘剰鍥剧墖"
+      width="80%"
+      v-model="anyPhotoDialog"
+      :before-close="beforeAnyPhotoDialogclose"
+    >
+      <ArbitraryPhoto
+        v-if="anyPhotoDialog"
+        @selectByAnyPhonoEvent="handleSelectedAnyPhono"
+        :subtask="subtask"
+        :defaultFile="fileList"
+        ref="arbitraryPhotoRef"
+      >
+      </ArbitraryPhoto>
+    </el-dialog>
+    <el-dialog
+      title="鍙拌处鍥剧墖"
+      width="80%"
+      v-model="ledgerPicDialog"
+      :before-close="beforeLedgerPicDialogclose"
+    >
+      <LedgerPic
+        v-if="ledgerPicDialog"
+        @selectByLedgerPicEvent="handleLedgerPicPhono"
+        :month="month"
+        :subtask="subtask"
+        ref="ledgerPicRef"
+      >
+      </LedgerPic>
+    </el-dialog>
+  </div>
+  <el-dialog v-model="previewDialogVisible">
+    <img w-full :src="previewDialogImageUrl" alt="棰勮" class="preview-pic" />
+  </el-dialog>
+</template>
+<script>
+import ArbitraryPhoto from './ArbitraryPhoto.vue';
+import LedgerPic from './CompLedgerPic.vue';
+import problemApi from '@/api/fysp/problemApi.js';
+
+import { $fysp } from '@/api/index.js';
+import fileUtil from '@/utils/fileUtils.js';
+import { useCloned } from '@vueuse/core';
+import { ElMessage } from 'element-plus';
+export default {
+  components: {
+    ArbitraryPhoto,
+    LedgerPic
+  },
+  watch: {
+    fileList: {
+      handler(newFileList, oldFileList) {
+        this.pictureValidate();
+      },
+      deep: true
+    }
+  },
+  props: {
+    problemId: {
+      type: String
+    },
+    oldChangeFileList: {
+      type: Array,
+      default: () => []
+    },
+    subtask: {
+      type: Object,
+      default: () => {}
+    },
+    month: {
+      type: Number,
+      default: -1
+    }
+  },
+  data() {
+    return {
+      previewDialogImageUrl: '',
+      previewDialogVisible: false,
+      fileList: [],
+      oldFileList: [],
+      deleteImg: [],
+
+      ledgerPicDialog: false,
+      anyPhotoDialog: false
+    };
+  },
+  mounted() {
+    this.initParams();
+  },
+  methods: {
+    pictureValidate() {
+      if (this.fileList.length < 1) {
+        ElMessage({
+          message: '鑷冲皯涓婁紶涓�寮犲浘鐗�',
+          type: 'error'
+        });
+        return false;
+      } else if (this.fileList.length > 3) {
+        ElMessage({
+          message: '瓒呰繃涓夊紶, 宸插垹闄ゅ鍑虹殑鍥剧墖',
+          type: 'error'
+        });
+        return false;
+      }
+      return true;
+    },
+    initParams() {
+      let beforeEditImgList = [];
+      useCloned(this.oldChangeFileList).cloned.value.forEach((oldChangeFileitem) => {
+        if (oldChangeFileitem.ischanged == 1) {
+          oldChangeFileitem.url =
+            $fysp.imgUrl + oldChangeFileitem.extension1 + oldChangeFileitem.guid + '.jpg';
+          oldChangeFileitem.name = '1';
+          beforeEditImgList.push(oldChangeFileitem);
+        }
+      });
+      this.fileList = useCloned(beforeEditImgList).cloned.value;
+      this.oldFileList = useCloned(beforeEditImgList).cloned.value;
+    },
+    onSubmit() {
+      if (!this.pictureValidate()) {
+        return;
+      }
+      // 鏁版嵁鍑嗗
+      let data = new FormData();
+      var picUrls = [];
+      this.fileList.forEach((item) => {
+        if (!('guid' in item)) {
+          // 鏂扮殑
+          let exclude = false;
+          for (let index = 0; index < this.oldFileList.length; index++) {
+            const element = this.oldFileList[index];
+            if (item.url == element.url) {
+              exclude = true;
+              break;
+            }
+          }
+          if (!exclude) {
+            picUrls.push(item.url);
+          }
+          exclude = false;
+          // picUrls.push(item)
+        } else {
+        }
+      });
+
+      const that = this;
+      let deleteImgCopy = this.deleteImg;
+      fileUtil.getImageFiles(picUrls, function (files) {
+        data.append('deleteImg', deleteImgCopy);
+        data.append('problemId', that.problemId);
+        files.forEach((image) => {
+          data.append('images', image);
+        });
+        problemApi.updateChange(data).then((res) => {});
+      });
+      this.$emit('submited', true);
+    },
+    beforeRemoveFile(file, fileList) {
+      if (file.remark == '宸蹭笂浼�') {
+        this.deleteImg.push(file.guid);
+        this.oldFileList.filter((item) => item.url != file.url);
+      }
+    },
+    handlePictureCardPreview(uploadFile) {
+      this.previewDialogVisible = true;
+      this.previewDialogImageUrl = uploadFile.url;
+    },
+    handleSelectedAnyPhono(data) {
+      this.beforeAnyPhotoDialogclose();
+      let isExist = false;
+      for (const item of data) {
+        for (const already of this.fileList) {
+          if (item.url == already.url) {
+            isExist = true;
+          }
+        }
+        if (!isExist) {
+          this.fileList.push({
+            url: item.url,
+            name: '1'
+          });
+        }
+        isExist = false;
+      }
+    },
+    handleLedgerPicPhono(data) {
+      let isExist = false;
+      for (const item of data) {
+        for (const already of this.fileList) {
+          if (item.url == already.url) {
+            isExist = true;
+          }
+        }
+        if (!isExist) {
+          this.fileList.push({
+            url: item.url,
+            name: '1'
+          });
+        }
+        isExist = false;
+      }
+
+      this.beforeAnyPhotoDialogclose();
+    },
+    chosePicFromAnyPic() {
+      this.anyPhotoDialog = true;
+    },
+    // 浠庢枃浠跺す涓�
+    choseChangePic() {
+      // 鑾峰彇鎸囧畾ID鐨勫厓绱�
+      var btnElement = document.getElementById('uploadBtnId');
+      // 妫�鏌ュ厓绱犳槸鍚﹀瓨鍦�
+      if (btnElement) {
+        // 瑙﹀彂鐐瑰嚮浜嬩欢
+        btnElement.click();
+      }
+    },
+    chosePicFromLedgerPic() {
+      // 浣跨敤Date瀵硅薄瑙f瀽鏃ユ湡瀛楃涓�
+      var date = new Date(this.subtask.subtask.planstarttime.splice(0, 7));
+      // 鑾峰彇鏈堜唤淇℃伅锛屾湀浠芥槸浠�0寮�濮嬬殑锛屾墍浠ラ渶瑕佸姞1
+      this.month = date.getMonth() + 1;
+      if (String(this.month).length == 1) {
+        this.month = `0${this.month}`;
+      }
+      var year = date.getFullYear();
+      this.month = `${year}-${this.month}`;
+      this.ledgerPicDialog = true;
+    },
+    beforeAnyPhotoDialogclose() {
+      this.anyPhotoDialog = false;
+    },
+    beforeLedgerPicDialogclose() {
+      this.ledgerPicDialog = false;
+    }
+  }
+};
+</script>
+<style scoped>
+.flex-div {
+  display: flex;
+}
+.t-card_item {
+  display: flex;
+  padding: 5px;
+}
+.img-upload {
+  margin-top: 30px;
+  margin-bottom: 30px;
+  margin-left: 63px;
+}
+::v-deep .el-dialog__body {
+  width: 95%;
+}
+::v-deep .el-upload-list--picture-card .el-upload-list__item-thumbnail {
+  object-fit: cover !important;
+}
+.preview-pic {
+  object-fit: cover;
+  width: 100%;
+  height: 100%;
+}
+</style>
diff --git a/src/views/fysp/check/components/CompDevicePhono.vue b/src/views/fysp/check/components/CompDevicePhono.vue
new file mode 100644
index 0000000..ee4f320
--- /dev/null
+++ b/src/views/fysp/check/components/CompDevicePhono.vue
@@ -0,0 +1,264 @@
+<template>
+  <div class="main">
+    <div class="filters" v-if="false">
+      <el-select
+        v-for="(key_select, index_select) of filters.keys()"
+        :placeholder="key_select.text"
+      >
+        <el-option
+          v-for="(key_option, index_option) in filters.get(key_select.key)"
+          :key="key_option.key"
+          :value="key_option.value"
+          :label="key_option.label"
+        >
+        </el-option>
+      </el-select>
+    </div>
+    <div class="btns" v-if="!readonly">
+      <el-button size="small" type="primary" @click="sendSelectedImg(true)">纭畾</el-button>
+      <el-button size="small" type="primary" @click="sendSelectedImg(false)">鍙栨秷</el-button>
+    </div>
+
+    <div class="center">
+      <el-descriptions>
+        <el-descriptions-item label="鎬绘暟">
+          <span>{{ this.imgPathsDataSourceCopy.length }}</span>
+        </el-descriptions-item>
+      </el-descriptions>
+      <el-tabs v-model="activeId" type="card">
+        <el-tab-pane v-for="item in typeList" :label="item.label" :name="item.id"> </el-tab-pane>
+      </el-tabs>
+      <el-empty v-if="imgObjList.length == 0" description="鏆傛棤璁板綍" />
+      <div class="imgs">
+        <el-image
+          v-for="(img, i) in imgObjList"
+          :class="[Boolean(img.isSelect) ? 'selected' : 'noActive', 'image']"
+          fit="cover"
+          :src="img._picUrl"
+          lazy
+          @click="onSelect(img, i)"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import problemApi from '@/api/fysp/problemApi.js';
+import mediafileApi from '@/api/fysp/mediafileApi.js';
+import { $fysp } from '@/api/index.js';
+import { useCloned } from '@vueuse/core';
+export default {
+  props: {
+    filters: Map,
+    // 鏄惁浠ュ彧璇荤殑褰㈠紡鏌ョ湅褰撳墠椤甸潰
+    readonly: {
+      type: Boolean,
+      default: false
+    },
+    imgPathsDataSource: {
+      type: Array,
+      default: () => []
+    },
+    defaultFile: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      // 鏃犳暟鎹�
+      isEmpty: false,
+      isClose: false,
+      isAll: false,
+      activeId: 0,
+      typeList: [
+        { id: 0, label: '鐩戞帶璁惧' },
+        { id: 1, label: '娌荤悊璁惧' },
+        { id: 2, label: '鐢熶骇璁惧' }
+      ],
+      typeImgMap: new Map(),
+      imgPathsDataSourceCopy: [],
+      imgObjList: []
+    };
+  },
+  watch: {
+    activeId: {
+      handler(newId, oldId) {
+        this.filterImgList()
+      },
+      immediate: true
+    }
+  },
+  mounted() {
+    if (this.defaultFile == undefined || this.defaultFile == null) {
+      this.defaultFile = [];
+    }
+    this.initImgUrlList();
+  },
+  methods: {
+    filterImgList() {
+      this.imgObjList = this.imgPathsDataSourceCopy.filter((item) => {
+        return item.topTypeId == this.activeId;
+      });
+    },
+    initDefaultFile() {
+      for (let item of this.imgPathsDataSourceCopy) {
+        for (let defaultItem of this.defaultFile) {
+          if (item._picUrl == defaultItem.url) {
+            item.isSelect = true;
+          }
+        }
+      }
+    },
+    // 鑾峰彇鍥剧墖璧勬簮
+    initImgUrlList() {
+      this.imgPathsDataSourceCopy = useCloned(this.imgPathsDataSource).cloned.value;
+      this.imgObjList = this.imgPathsDataSourceCopy;
+      this.initDefaultFile();
+
+      this.initSelectedTab();
+    },
+    // 鍒濆鍖栧垰寮�濮嬮�変腑鐨勬爣绛�
+    initSelectedTab() {
+      if (this.typeList.length > 0) {
+        this.activeId = this.typeList[0].id;
+      }
+      this.filterImgList()
+    },
+    onSelect(img, i) {
+      // if (i == 2 && !this.isAll) {
+      //   this.getAllImgList();
+      //   this.isAll = true;
+      // } else {
+      //   if (this.readonly) {
+      //     return;
+      //   }
+      //   img.isSelect = !Boolean(img.isSelect);
+      // }
+
+      if (this.readonly) {
+        return;
+      }
+      img.isSelect = !Boolean(img.isSelect);
+    },
+    sendSelectedImg(isOk) {
+      let result = [];
+      if (!Boolean(isOk)) {
+        this.$emit('selectPhonoEvent', result);
+      }
+      for (const item of this.imgPathsDataSourceCopy) {
+        if (item.isSelect == true) {
+          result.push(item);
+        }
+      }
+      this.isClose = true;
+      this.$emit('selectPhonoEvent', result);
+    }
+  }
+};
+</script>
+<style scoped>
+.center {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+.text {
+  padding: 20px;
+}
+
+.main {
+  margin: 0 auto; /* 浣跨埗鍏冪礌灞呬腑 */
+  height: 100%;
+  width: 100%;
+}
+
+.btns {
+  height: 10%;
+}
+/* 
+  .img_types {
+    margin: 0 auto;
+    height: 440px;
+    width: 900px;
+    flex-grow: 1;
+    overflow-y: hidden ;
+    padding: 3%;
+    flex-wrap: wrap;
+    overflow: hidden;
+  } */
+
+.imgs {
+  height: 370px;
+  width: 90%;
+  min-height: 100px !important;
+  /* border-style:solid;
+      border-radius: 1px; */
+  /* height: 100%; */
+  flex-grow: 1 !important;
+  overflow-y: auto !important;
+  /* 鍐呭鐨勫唴杈硅窛 */
+  display: flex !important;
+  flex-wrap: wrap !important;
+  /* overflow: hidden; */
+}
+
+.image {
+  height: 210px;
+  width: 200px;
+  border-radius: 4px;
+}
+
+.active {
+  padding: 5px;
+  width: 20%;
+  height: 200px;
+  border: 0.5rem outset rgb(52, 155, 4);
+}
+
+.selected {
+  padding: 5px;
+  color: #4abe84;
+  box-shadow: 0 2px 7px 0 rgba(85, 110, 97, 0.35);
+  border: 1px solid rgba(74, 190, 132, 1);
+}
+
+.selected:before {
+  content: '';
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  border: 17px solid #4abe84;
+  border-top-color: transparent;
+  border-left-color: transparent;
+}
+
+.selected:after {
+  content: '';
+  width: 5px;
+  height: 12px;
+  position: absolute;
+  right: 6px;
+  bottom: 6px;
+  border: 2px solid #fff;
+  border-top-color: transparent;
+  border-left-color: transparent;
+  transform: rotate(45deg);
+}
+
+.noActive {
+  padding: 5px;
+}
+
+.blurry {
+  filter: blur(3px);
+}
+.filters {
+  display: flex;
+  padding: 5px;
+}
+
+.el-dialog__body {
+  height: 60vh;
+}
+</style>
diff --git a/src/views/fysp/check/components/CompDeviceShow.vue b/src/views/fysp/check/components/CompDeviceShow.vue
new file mode 100644
index 0000000..b7e36d7
--- /dev/null
+++ b/src/views/fysp/check/components/CompDeviceShow.vue
@@ -0,0 +1,233 @@
+<template>
+  <div class="main">
+    <!-- 閫夐」 -->
+    <!-- 璁惧绫诲瀷  -->
+    <el-row>
+      <el-col>
+        <span>璁惧绫诲瀷锛�</span>
+      </el-col>
+      <el-col>
+        <el-tabs class="child_select" placeholder="璁惧绫诲瀷" v-model="currSelect.deviceTypeId">
+          <el-tab-pane v-for="item in deviceTypes" :name="item.id" :label="item.label" />
+        </el-tabs>
+      </el-col>
+    </el-row>
+    <!-- 璁惧灞曠ず -->
+    <div class="devices">
+      <el-card class="layout" shadow="hover" v-for="item of cardData">
+        <div class="table-row">
+          <span class="table-cell">绔欑偣: {{ item.diName || item.piName || item.wiName }}</span>
+          <span class="table-cell"
+            >渚涘簲鍟�: {{ item.diSupplier || item.piSupplier || item.wiSupplier }}</span
+          >
+        </div>
+        <div class="table-row">
+          <span class="table-cell"
+            >杩愮淮鍟�: {{ item.diMaintainer || item.piMaintainer || item.wiMaintainer }}</span
+          >
+          <span class="table-cell"
+            >杩愮淮棰戞:
+            {{
+              maintainFrequencysMap.get(
+                item.diMaintainFrequency || item.piMaintainFrequency || item.wiMaintainFrequency
+              )
+            }}</span
+          >
+        </div>
+        <div class="table-row">
+          <span class="table-cell"
+            >杩愮淮浜哄憳:
+            {{ item.diMaintainStaff || item.piMaintainStaff || item.wiMaintainStaff }}</span
+          >
+          <span class="table-cell"
+            >杩愮淮鑱旂郴鏂瑰紡:
+            {{ item.diMaintainTel || item.piMaintainTel || item.wiMaintainTel }}</span
+          >
+        </div>
+        <div class="table-row">
+          <span class="table-cell"
+            >鍝佺墝鍨嬪彿: {{ item.diBrandModel || item.piBrandModel || item.wiBrandModel }}</span
+          >
+          <span class="table-cell"
+            >杩愯鐘舵��:
+            {{
+              runStatusMap.get(item.diRunningStatus || item.piRunningStatus || item.wiRunningStatus)
+            }}
+          </span>
+        </div>
+        <div class="table-row">
+          <span class="table-cell"
+            >浣嶇疆: {{ item.dlLocation || item.piLocation || item.wiLocation }}</span
+          >
+          <!-- The second cell is empty to maintain the two-field per row layout -->
+          <span class="table-cell"></span>
+        </div>
+        <el-image
+          class="pic-style"
+          :src="item.picUrl"
+          fit="cover"
+          :preview-src-list="Array.of(item.picUrl)"
+        />
+      </el-card>
+      <!-- 鏁版嵁涓虹┖鏃� -->
+      <div class="empty" v-if="isEmpty">
+        <h3>鏆傛棤鏁版嵁</h3>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import deviceApi from '@/api/fysp/deviceApi';
+import { $fysp } from '@/api/index';
+export default {
+  props: {},
+  mounted() {},
+  watch: {
+    // 閫夋嫨鏀瑰彉鐩戝惉
+    currSelect: {
+      handler(newObj, oldObj) {
+        this.getList();
+      },
+      deep: true
+    }
+  },
+  data() {
+    return {
+      // 鏃犳暟鎹�
+      isEmpty: false,
+      // 鍙屽悜缁戝畾
+      currSelect: {
+        deviceTypeId: 0
+      },
+      // 鍦烘櫙绫诲瀷
+      sceneType: '',
+      // 鍦烘櫙id
+      sceneId: null,
+      // 閫夐」
+      scenes: [],
+      // 鏍规嵁鍦烘櫙绫诲瀷鍐冲畾鐨勮澶囩被鍨�
+      iDevTypes: [
+
+      ],
+      deviceTypes: [
+        { id: 0, label: '鐩戞帶' },
+        { id: 1, label: '娌荤悊' },
+        { id: 2, label: '鐢熶骇' }
+      ],
+      // 鏁版嵁
+      cardData: [],
+      // 杩愯鐘舵��
+      runStatusMap: new Map(
+        [
+          { key: 0, value: '鏈仈缃�' },
+          { key: 1, value: '涓婄嚎涓�' },
+          { key: 2, value: '涓嬬嚎' },
+          { key: 3, value: '鎷嗛櫎' }
+        ].map((item) => [item.key, item.value])
+      ),
+
+      // 缁存姢棰戠巼鐘舵��
+      maintainFrequencysMap: new Map(
+        [
+          { key: '1', value: '姣忔湀涓�娆�' },
+          { key: '2', value: '姣忓搴︿竴娆�' },
+          { key: '3', value: '姣忓崐骞翠竴娆�' },
+          { key: '4', value: '姣忓勾涓�娆�' }
+        ].map((item) => [item.key, item.value])
+      )
+    };
+  },
+  methods: {
+    // 鐖剁粍浠朵富鍔ㄤ紶鍊�
+    init(scene) {
+      this.sceneId = scene.guid;
+      this.sceneType = scene.type;
+      this.iDevTypes = dataMonitorDeviceTypeJs.monitorDevices(this.sceneType)
+      this.getList();
+    },
+    isShowEmpty(data) {
+      if (data.length == 0) {
+        this.isEmpty = true;
+        return true;
+      } else {
+        this.isEmpty = false;
+        return false;
+      }
+    },
+    // 閲嶇疆灞曠ず鐨勬暟鎹�
+    initList() {
+      this.tableData = [];
+    },
+    // 瀛楁鍚嶆嫤鎴櫒
+    propNameConvert(obj, name) {
+      name = String(name).substring(1)
+      return obj['d'+name] || obj['p'+name] || obj['w'+name]
+    },
+    getList() {
+      this.initList();
+      var devicesInfoList = [];
+      deviceApi.fetchDevices(this.sceneId, this.currSelect.deviceTypeId).then((result) => {
+        devicesInfoList = result.data;
+        this.cardData = [];
+        if (this.isShowEmpty(devicesInfoList)) {
+          return;
+        }
+        if (devicesInfoList) {
+          devicesInfoList.forEach((e) => {
+            let data = {
+              deviceId: this.propNameConvert(e, 'diId'),
+              sceneId: this.propNameConvert(e, 'diSceneGuid'),
+              deviceTypeId: this.currSelect.deviceTypeId
+            };
+            deviceApi
+              .fetchDeviceStatus(data)
+              .then((status) => {
+                var statusData = status.data;
+                if (statusData && statusData instanceof Array) {
+                  if (statusData.length == 0) {
+                    this.cardData.push(e);
+                    return;
+                  }
+                  statusData.forEach((imgItem) => {
+                    e.picUrl = $fysp.imgUrl + imgItem.dlPicUrl;
+                    e.dlLocation = imgItem.dlLocation;
+                    this.cardData.push(e);
+                  });
+                }
+              })
+              .catch((err) => {});
+          });
+        }
+      });
+    }
+  }
+};
+</script>
+<style scoped>
+.selects {
+  display: flex;
+}
+.child_select {
+  margin-right: 10px;
+}
+.table-row {
+  display: flex;
+  justify-content: space-between;
+}
+.table-cell {
+  flex-basis: calc(50% - 10px); /* Adjust the width and margin as needed */
+  border: 1px solid #ddd; /* Add border to mimic table cell */
+  padding: 8px;
+  text-align: center;
+}
+.pic-style {
+  margin-top: 10px;
+  width: 100%;
+  height: 400px;
+}
+.empty {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+</style>
diff --git a/src/views/fysp/check/components/CompDeviceShowTest.vue b/src/views/fysp/check/components/CompDeviceShowTest.vue
new file mode 100644
index 0000000..4c0ee18
--- /dev/null
+++ b/src/views/fysp/check/components/CompDeviceShowTest.vue
@@ -0,0 +1,593 @@
+<template>
+  <div>
+    <!-- 閫夐」 -->
+    <!-- 璁惧绫诲瀷  -->
+    <el-row>
+      <!-- <el-col>
+        <span>璁惧绫诲瀷锛�</span>
+      </el-col> -->
+      <el-col>
+        <el-tabs class="child_select" placeholder="璁惧绫诲瀷" v-model="currSelect.topDeviceTypeId">
+          <el-tab-pane v-for="item in deviceTopTypes" :name="item.id">
+            <template #label>
+              <el-badge :value="item.count" :type="item.count == 0 ? 'danger' : 'primary'">
+                <span class="custom-tabs-label">
+                  <span>{{ item.label }}</span>
+                </span>
+              </el-badge>
+            </template>
+          </el-tab-pane>
+        </el-tabs>
+      </el-col>
+    </el-row>
+    <el-collapse style="height: 100%" v-model="activeNames">
+      <el-collapse-item v-for="item in formInfo" :name="item" style="height: 100%">
+        <template #title>
+          <!-- 鎽樿鍐呭寮�濮� -->
+          <div class="abstract_main" v-if="activeNames.indexOf(item) === -1">
+            <span class="abstract_main_title">{{ item.name }}</span>
+            <div class="abstract_other_item_inner">
+              <!-- 渚涘簲鍟� -->
+              <div class="abstract_other_item">
+                <span class="abstract_other_title">{{ `渚涘簲鍟哷 }}</span>
+                <span class="abstract_main_text">{{ item.supplier || '鏃�' }}</span>
+              </div>
+              <!-- 杩愮淮鍟� -->
+              <div class="abstract_other_item">
+                <span class="abstract_other_title">{{ `杩愮淮鍟哷 }}</span>
+                <span class="abstract_main_text">{{ item.maintainer || '鏃�' }}</span>
+              </div>
+              <!-- 杩愯鐘舵�� -->
+              <div class="abstract_other_item">
+                <span class="abstract_other_title">{{ `杩愯鐘舵�乣 }}</span>
+                <span class="abstract_main_text">{{
+                  getRunStatusValueByRunStatusKey(item.runningStatus) || '鏃�'
+                }}</span>
+              </div>
+              <!-- 鍥剧墖 -->
+              <div class="image-container">
+                <el-image
+                  v-for="status in item._statusList"
+                  fit="cover"
+                  class="pic-style"
+                  :src="status._picUrl"
+                  :preview-src-list="Array.of(status._picUrl)"
+                />
+              </div>
+            </div>
+          </div>
+          <div v-else class="centerDiv">
+            <el-button link type="primary" size="large">[鐐瑰嚮缂╂斁]</el-button>
+          </div>
+          <!-- 鎽樿鍐呭缁撴潫 -->
+        </template>
+        <!-- 璇︾粏鍐呭寮�濮� -->
+        <div class="sub-title">{{ item.name }}</div>
+        <el-form :model="item" class="form_class">
+          <!-- <el-form-item label="绔欑偣">
+            <el-input v-model="item.name" :disabled="isDisabled"></el-input>
+          </el-form-item> -->
+          <el-form-item label="渚涘簲鍟�">
+            <el-input v-model="item.supplier" :disabled="isDisabled"></el-input>
+          </el-form-item>
+          <el-form-item label="杩愮淮鍟�">
+            <el-input v-model="item.maintainer" :disabled="isDisabled"></el-input>
+          </el-form-item>
+          <el-form-item label="杩愮淮棰戞">
+            <el-select v-model="item.maintainFrequency" :disabled="isDisabled">
+              <el-option
+                v-for="frequency of maintainFrequencysArray"
+                :key="frequency.key"
+                :label="frequency.value"
+                :value="frequency.key"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="杩愮淮浜哄憳">
+            <el-input v-model="item.maintainStaff" :disabled="isDisabled"></el-input>
+          </el-form-item>
+          <el-form-item label="杩愮淮鑱旂郴鏂瑰紡">
+            <el-input v-model="item.maintainTel" :disabled="isDisabled"></el-input>
+          </el-form-item>
+          <el-form-item label="鍝佺墝鍨嬪彿">
+            <el-input v-model="item.brandModel" :disabled="isDisabled"></el-input>
+          </el-form-item>
+          <el-form-item label="杩愯鐘舵��">
+            <el-select v-model="item.runningStatus" :disabled="isDisabled">
+              <el-option
+                v-for="status of runStatusArray"
+                :key="status.key"
+                :label="status.value"
+                :value="status.key"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="鎵�鏈夋潈">
+            <el-select v-model="item.ownership" :disabled="isDisabled">
+              <el-option
+                v-for="ownership of ownershipArray"
+                :key="ownership.key"
+                :label="ownership.value"
+                :value="ownership.key"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="鐘舵��">
+            <el-tabs tab-position="top">
+              <el-tab-pane v-for="(status, i) in item._statusList" :label="status.dlCreateTime.slice(0, 10)">
+                <el-form :model="status" class="form-class">
+                  <el-form-item label="浣嶇疆">
+                    <el-input
+                      v-model="status.dlLocation"
+                      :disabled="isDisabled"
+                      class="form-item-class"
+                    ></el-input>
+                  </el-form-item>
+                  <el-form-item label="缁忓害">
+                    <el-input
+                      v-model="status.dlLongitude"
+                      :disabled="isDisabled"
+                      class="form-item-class"
+                    ></el-input>
+                  </el-form-item>
+                  <el-form-item label="绾害">
+                    <el-input
+                      v-model="status.dlLatitude"
+                      :disabled="isDisabled"
+                      class="form-item-class"
+                    ></el-input>
+                  </el-form-item>
+                  <el-form-item>
+                    <!-- 鍥剧墖 -->
+                    <el-image
+                      fit="cover"
+                      class="pic-style"
+                      :src="status._picUrl"
+                      :preview-src-list="Array.of(status._picUrl)"
+                    />
+                  </el-form-item>
+                </el-form>
+              </el-tab-pane>
+            </el-tabs>
+          </el-form-item>
+        </el-form>
+        <el-divider />
+        <!-- 璇︾粏鍐呭缁撴潫 -->
+      </el-collapse-item>
+    </el-collapse>
+    <!-- 绌虹姸鎬� -->
+    <el-empty v-if="isEmpty" />
+  </div>
+</template>
+
+<script>
+import deviceApi from '@/api/fysp/deviceApi';
+import { $fysp } from '@/api/index';
+export default {
+  components: {},
+  watch: {
+    // 閫夋嫨鏀瑰彉鐩戝惉
+    currSelect: {
+      handler(newObj, oldObj) {
+        this.getList();
+      },
+      deep: true
+    }
+  },
+  data() {
+    return {
+      activeNames: [],
+      // 鎺у埗鏄惁灞曠ず绌虹姸鎬�
+      isEmpty: false,
+      // 璇︽儏鎸夐挳澶у皬
+      detailSize: '22px',
+      // 琛ㄥ崟璇︽儏鐐瑰嚮鎸夐挳鐨勫浘鏍�
+      isDetail: false,
+      currSelect: {
+        topDeviceTypeId: 0
+      },
+      // 鎺у埗琛ㄥ崟鏄惁鍙互缂栬緫
+      isDisabled: true,
+      formInfo: {},
+      rules: [],
+      // 璁惧绫诲瀷
+      deviceTopTypes: [
+        { id: 0, label: '鐩戞帶璁惧' },
+        { id: 1, label: '娌荤悊璁惧' },
+        { id: 2, label: '鐢熶骇璁惧' }
+      ],
+      // 杩愯鐘舵��
+      runStatusArray: [
+        { key: 0, value: '鏈仈缃�' },
+        { key: 1, value: '涓婄嚎涓�' },
+        { key: 2, value: '涓嬬嚎' },
+        { key: 3, value: '鎷嗛櫎' }
+      ],
+      // 缁存姢棰戠巼鐘舵��
+      maintainFrequencysArray: [
+        { key: 1, value: '姣忔湀涓�娆�' },
+        { key: 2, value: '姣忓搴︿竴娆�' },
+        { key: 3, value: '姣忓崐骞翠竴娆�' },
+        { key: 4, value: '姣忓勾涓�娆�' }
+      ],
+      // 绉熻祦鏂瑰紡
+      ownershipArray: [
+        { key: 0, value: '璐拱' },
+        { key: 1, value: '绉熻祦' }
+      ],
+      // i-璁惧绫诲瀷
+      // 涓ゅ眰map锛� { key: topType, value: { key: sceneTypeId, value: [label, value, children] } }
+      iDeviceTypesMap: new Map(
+        [
+          {
+            topTypeId: 0,
+            value: new Map(
+              [
+                {
+                  sceneTypeId: 1,
+                  value: [
+                    {
+                      label: '鎵皹鐩戞祴',
+                      value: 1,
+                      children: [
+                        {
+                          label: '鎵皹鐩戞祴',
+                          value: 1
+                        }
+                      ]
+                    }
+                  ]
+                },
+                {
+                  sceneTypeId: 2,
+                  value: [
+                    {
+                      label: '鎵皹鐩戞祴',
+                      value: 1,
+                      children: [
+                        {
+                          label: '鎵皹鐩戞祴',
+                          value: 1
+                        }
+                      ]
+                    }
+                  ]
+                },
+                {
+                  sceneTypeId: 3,
+                  value: [
+                    {
+                      label: '鎵皹鐩戞祴',
+                      value: 1,
+                      children: [
+                        {
+                          label: '鎵皹鐩戞祴',
+                          value: 1
+                        }
+                      ]
+                    }
+                  ]
+                },
+                {
+                  sceneTypeId: 14,
+                  value: [
+                    {
+                      label: '鎵皹鐩戞祴',
+                      value: 1,
+                      children: [
+                        {
+                          label: '鎵皹鐩戞祴',
+                          value: 1
+                        }
+                      ]
+                    }
+                  ]
+                }
+              ].map((item) => [item.sceneTypeId, item.value])
+            )
+          }
+        ].map((item) => [item.topTypeId, item.value])
+      ),
+      scene: {}
+    };
+  },
+  props: {},
+
+  mounted() {},
+  methods: {
+    // 鑾峰彇褰撳墠绫诲瀷璁惧鏁伴噺
+    getTabsCount() {
+      this.deviceTopTypes.forEach((item) => {
+        deviceApi.fetchDevices(this.scene.guid, item.id).then((result) => {
+          item.count = result.data.length;
+        });
+      });
+    },
+    // 鑾峰彇杩愯鐘舵�佸搴旂殑value
+    getRunStatusValueByRunStatusKey(status) {
+      var runningStatusValueArray = this.runStatusArray.filter((runStatus) => {
+        return runStatus.key == status;
+      });
+      if (runningStatusValueArray.length > 0) {
+        return runningStatusValueArray[0].value;
+      }
+    },
+    // 灞曠ず琛ㄥ崟鐨勮鎯呯殑鐐瑰嚮浜嬩欢
+    showDetail(item) {
+      item._isDetail = !item._isDetail;
+      if (item._isDetail) {
+      } else {
+      }
+    },
+    init(scene) {
+      // 鐖剁粍浠朵富鍔ㄨ皟鐢ㄥ垵濮嬪寲瀛愮粍浠剁殑鏂规硶
+      this.scene = scene;
+
+      this.getList();
+      this.getTabsCount();
+    },
+    // 閲嶇疆灞曠ず鐨勬暟鎹�
+    initList() {
+      this.formInfo = [];
+      this.isEmpty = false;
+    },
+    // 鏍囧噯鍖栧睘鎬у悕
+    convertKeys(obj) {
+      // 灏嗕竴涓猨s瀵硅薄涓墍鏈塪i锛寃i锛宲i寮�澶寸殑灞炴�у叏閮ㄦ敼鎴愬幓鎺夎繖浜涘墠缂�骞朵笖閲嶆柊鍙樹负椹煎嘲寮忓懡鍚�
+      const newObj = {};
+      for (const key in obj) {
+        if (obj.hasOwnProperty(key)) {
+          let newKey = key;
+          if (key.startsWith('di')) {
+            newKey = key.substring(2);
+          } else if (key.startsWith('wi')) {
+            newKey = key.substring(2);
+          } else if (key.startsWith('pi')) {
+            newKey = key.substring(2);
+          }
+          newKey = newKey.charAt(0).toLowerCase() + newKey.slice(1);
+          newObj[newKey] = obj[key];
+        }
+      }
+      return newObj;
+    },
+    // 鏂板瀛楁
+    initFormData(data) {
+      data._isDetail = false;
+    },
+    getList() {
+      deviceApi.fetchDevices(this.scene.guid, this.currSelect.topDeviceTypeId).then((result) => {
+        this.initList();
+        if (result.data == null || result.data.length <= 0) {
+          this.isEmpty = true;
+          return;
+        }
+        // 鏍囧噯鍖栧睘鎬у悕
+        for (let index = 0; index < result.data.length; index++) {
+          var element = this.convertKeys(result.data[index]);
+          this.initFormData(element);
+          // 鑾峰彇璁惧鐘舵�佷俊鎭�
+          let data = {
+            deviceId: element.id,
+            sceneId: element.sceneGuid,
+            deviceTypeId: this.currSelect.topDeviceTypeId
+          };
+          deviceApi
+            .fetchDeviceStatus(data)
+            .then((status) => {
+              var statusData = status.data;
+              var imgPaths = [];
+              if (statusData) {
+                if (statusData.length == 0) {
+                  this.formInfo.push(element);
+                  return;
+                }
+                element = this.convertKeys(result.data[index]);
+                element._picUrls = imgPaths;
+                for (let index = 0; index < statusData.length; index++) {
+                  const statusItem = statusData[index];
+                  // 璁惧瀵硅薄娣诲姞涓�涓睘鎬у垪琛ㄥ睘鎬х敤鏉ヤ繚瀛樿澶囩姸鎬�
+                  this.saveStatus(element, statusItem);
+                  element.dlLocation = statusItem.dlLocation;
+                  this.formInfo.push(element);
+                }
+              }
+            })
+            .catch((err) => {});
+        }
+      });
+    },
+    // 淇濆瓨鐘舵�佷俊鎭�
+    saveStatus(device, status) {
+      var _picUrl = $fysp.imgUrl + status.dlPicUrl;
+      status._picUrl = _picUrl;
+      if ('_statusList' in device) {
+        device._statusList.push(status);
+      } else {
+        device._statusList = Array.of(status);
+      }
+      // 鎺掑簭
+      device._statusList.sort(function (x, y) {
+        return new Date(x.dlCreateTime) - new Date(y.dlCreateTime); //	闄嶅簭锛屽崌搴忓垯鍙嶄箣
+      });
+    },
+    submit() {},
+    cancel() {},
+    modifyObjectKeys(obj) {
+      const newObj = {};
+      for (const key in obj) {
+        if (obj.hasOwnProperty(key)) {
+          // 璺宠繃浠� 'dl' 鎴� '_' 寮�澶寸殑灞炴��
+          if (key.startsWith('dl') || key.startsWith('_')) {
+            newObj[key] = obj[key];
+            continue;
+          }
+          // 鏍规嵁 topDeviceTypeId 娣诲姞鍓嶇紑
+          let prefix = '';
+          switch (this.currSelect.topDeviceTypeId) {
+            case 0:
+              prefix = 'di';
+              break;
+            case 1:
+              prefix = 'pi';
+              break;
+            case 2:
+              prefix = 'wi';
+              break;
+            default:
+              // 濡傛灉 topDeviceTypeId 涓嶆槸 0, 1, 鎴� 2锛屼笉娣诲姞鍓嶇紑
+              newObj[key] = obj[key];
+              continue;
+          }
+
+          // 娣诲姞鍓嶇紑骞惰浆鎹负椹煎嘲寮忓懡鍚�
+          const newKey = `${prefix}${key.charAt(0).toUpperCase() + key.slice(1)}`;
+          newObj[newKey] = obj[key];
+        }
+      }
+      return newObj;
+    },
+    // 鐢熸垚鎺ュ彛鍙傛暟
+    generateQuery(obj) {
+      // 闇�瑕佹牴鎹満鏅被鍨嬬‘瀹氭帴鍙e弬鏁扮殑灞炴�у悕
+      var query = this.modifyObjectKeys(obj);
+      return query;
+    },
+    // 鏍规嵁鎺ュ彛杩斿洖鐢熸垚 iDeviceTypesMap
+    generateIDeviceTypesMap() {},
+    // 鑾峰彇褰撳墠topType锛屽綋鍓峴ceneTypeId涓嬫墍鏈夌埗绫诲瀷
+    getAlliDeviceParentTypeArray() {
+      console.log('topDeviceTypeId', this.currSelect.topDeviceTypeId);
+
+      var sceneTypeAndIDeviceTypesMap = this.iDeviceTypesMap.get(this.currSelect.topDeviceTypeId);
+      if (!sceneTypeAndIDeviceTypesMap) {
+        return '';
+      }
+      console.log('sceneTypeId', this.scene.typeid);
+      console.log('scene', this.scene);
+
+      var iDeviceTypesArray = sceneTypeAndIDeviceTypesMap.get(this.scene.typeid);
+      if (!iDeviceTypesArray) {
+        return '';
+      }
+      return iDeviceTypesArray;
+    },
+    // 鑾峰彇璁惧绫诲瀷 topDeviceTypeId, sceneTypeId 鍜� 鑷韩鐨勪竴浜涘弬鏁�
+    getIDeviceParentTypeObj(device) {
+      var iDeviceTypesArray = this.getAlliDeviceParentTypeArray();
+      console.log('iDeviceTypesArray', this.getAlliDeviceParentTypeArray());
+      var result;
+      iDeviceTypesArray.forEach((e) => {
+        if (e.value == device.typeId) {
+          result = e;
+        }
+      });
+      return result;
+    },
+    // 鑾峰彇璁惧瀛愮被鍨� topDeviceTypeId, sceneTypeId 鍜� 鑷韩鐨勪竴浜涘弬鏁�
+    getIDeviceChildrenTypeObj(device) {
+      console.log('device', device);
+
+      var parentType = this.getIDeviceParentTypeObj(device);
+      console.log('parentType', this.getIDeviceParentTypeObj(device));
+
+      if (parentType == null || parentType == '' || !('children' in parentType)) {
+        return '';
+      }
+      var children = parentType.children;
+      if (children == null || children.length <= 0) {
+        return '';
+      }
+      let result;
+      iDeviceTypesArray.forEach((e) => {
+        if (e.value == device.typeId) {
+          result = e;
+        }
+      });
+      return result;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.image-container {
+  display: flex;
+  flex-direction: row-reverse;
+  width: 100%;
+  height: 200px;
+  overflow: hidden; /* 纭繚鍥剧墖涓嶄細瓒呭嚭瀹瑰櫒 */
+}
+.pic-style {
+  width: 180px;
+  height: 180px;
+  margin-right: 5%;
+}
+.card-style {
+  height: 400px;
+  margin-bottom: 10px;
+  border-color: rgba(0, 0, 0, 0.308);
+}
+.centerDiv {
+  text-align: center; /* 姘村钩灞呬腑 */
+}
+.dot {
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 10px;
+  height: 10px;
+  background-color: #f56c6c;
+  border-radius: 50%;
+}
+.abstract_main {
+  width: 100%;
+}
+.abstract_other_item {
+  display: flex;
+  flex-direction: column;
+  margin-right: 50px;
+  margin-top: 10px;
+  width: 20%;
+}
+.abstract_other_item_inner {
+  margin-left: 10px;
+  display: flex;
+}
+.abstract_main_title {
+  margin-left: -400px;
+  color: #303133;
+  font-size: 16px;
+}
+.abstract_other_title {
+  color: #606266;
+  font-size: 13px;
+}
+.abstract_main_text {
+  color: #303133;
+  font-size: 17px;
+  margin-top: 5px;
+}
+.form_class {
+  margin-left: 10px;
+}
+
+.el-collapse {
+  /* 鎶樺彔闈㈡澘鎶樺彔鏃剁殑楂樺害 */
+  --el-collapse-header-height: auto;
+}
+.el-collapse-item__header {
+  width: 100%;
+}
+.form-class {
+  width: 50vw;
+}
+.form-item-class {
+  margin-bottom: 10px;
+}
+.sub-title {
+  font-size: var(--el-font-size-large);
+  margin-bottom: 30px;
+  margin-left: 20px;
+}
+</style>
diff --git a/src/views/fysp/check/components/CompLedgerPic.vue b/src/views/fysp/check/components/CompLedgerPic.vue
new file mode 100644
index 0000000..d209ac7
--- /dev/null
+++ b/src/views/fysp/check/components/CompLedgerPic.vue
@@ -0,0 +1,191 @@
+<template>
+  <div>
+    <div class="btns" v-if="!readonly">
+      <el-button size="small" type="primary" @click="sendSelectedImg(true)">纭畾</el-button>
+      <el-button size="small" type="primary" @click="sendSelectedImg(false)">鍙栨秷</el-button>
+    </div>
+    <div class="center">
+      <el-descriptions>
+        <el-descriptions-item label="鎬绘暟">
+          <span>{{ this.imgListAll.length }}</span>
+        </el-descriptions-item>
+      </el-descriptions>
+      <el-tabs v-model="activeName" type="card">
+        <el-tab-pane v-for="item in typeList" :label="item" :name="item"> </el-tab-pane>
+      </el-tabs>
+      <el-empty v-if="imgList.length == 0" description="鏆傛棤璁板綍" />
+      <div class="imgs">
+        <el-image
+          v-for="(img, i) in imgList"
+          :class="[Boolean(img.isSelect) ? 'selected' : 'noActive', 'image']"
+          fit="cover"
+          :src="img._picPath"
+          lazy
+          @click="onSelect(img)"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import problemApiFytz from '@/api/fytz/problemApi.js';
+import userApi from '@/api/fysp/userApi.js';
+import mediafileApi from '@/api/fysp/mediafileApi.js';
+import { svToTz } from '@/enum/scene';
+import { $fytz } from '@/api/index';
+import { useCloned } from '@vueuse/core';
+export default {
+  watch: {
+    activeName: {
+      handler(newObj, oldObj) {
+        this.imgList = this.imgListAll.filter(item=>{
+          return item.ledgerType == newObj
+        })
+      },
+      immediate: true
+    }
+  },
+  props: {
+    month: Number,
+    subtask: Object
+  },
+  computed: {
+    currImgList() {
+      return this.imgList.filter((item) => item.ledgerType == this.activeName);
+    }
+  },
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    getList() {
+      userApi.getTzId(this.subtask.sceneId).then((res) => {
+        this.isEmpty = false;
+        this.tzUserId = res.tzUserId;
+
+        problemApiFytz
+          .getLedgerPic({
+            tzUserId: this.tzUserId,
+            sceneType: svToTz(this.subtask.sceneTypeId).value,
+            time: this.month
+          })
+          .then((res) => {
+            let data = res;
+            this.imgListAll = data;
+            if (this.imgListAll.length === 0) {
+              this.isEmpty = true;
+            }
+            if (this.imgListAll && this.imgListAll.length > 0) {
+              this.imgListAll.forEach((item) => {
+                item._picPath = $fytz.imgUrl + item.path1;
+                if (this.typeList.indexOf(item.ledgerType) == -1) {
+                  this.typeList.push(item.ledgerType);
+                }
+              });
+              this.activeName = this.typeList[0];
+            }
+          });
+      });
+    },
+    handleClick(tab, event) {
+      this.activeName = tab.label;
+    },
+    onSelect(img) {
+      img.isSelect = !Boolean(img.isSelect);
+    },
+    sendSelectedImg(isOk) {
+      let result = [];
+      if (!Boolean(isOk)) {
+        this.$emit('selectByLedgerPicEvent', result);
+      }
+      for (const item in this.imgList) {
+        if (item.isSelect == true) {
+          result.push(item);
+        }
+      }
+      this.$emit('selectByLedgerPicEvent', result);
+    }
+  },
+  data() {
+    return {
+      tzUserId: null,
+      imgList: [],
+      imgListAll: [],
+      typeList: [],
+      isEmpty: false,
+      activeName: ''
+    };
+  }
+};
+</script>
+<style scoped>
+.imgs {
+  height: 370px;
+  width: 90%;
+  min-height: 100px !important;
+  /* border-style:solid;
+    border-radius: 1px; */
+  /* height: 100%; */
+  flex-grow: 1 !important;
+  overflow-y: auto !important;
+  /* 鍐呭鐨勫唴杈硅窛 */
+  display: flex !important;
+  flex-wrap: wrap !important;
+  /* overflow: hidden; */
+}
+
+.image {
+  height: 210px;
+  width: 200px;
+  border-radius: 4px;
+}
+
+.active {
+  padding: 5px;
+  width: 20%;
+  height: 200px;
+  border: 0.5rem outset rgb(52, 155, 4);
+}
+
+.selected {
+  padding: 5px;
+  color: #4abe84;
+  box-shadow: 0 2px 7px 0 rgba(85, 110, 97, 0.35);
+  border: 1px solid rgba(74, 190, 132, 1);
+}
+
+.selected:before {
+  content: '';
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  border: 17px solid #4abe84;
+  border-top-color: transparent;
+  border-left-color: transparent;
+}
+
+.selected:after {
+  content: '';
+  width: 5px;
+  height: 12px;
+  position: absolute;
+  right: 6px;
+  bottom: 6px;
+  border: 2px solid #fff;
+  border-top-color: transparent;
+  border-left-color: transparent;
+  transform: rotate(45deg);
+}
+
+.noActive {
+  padding: 5px;
+}
+.btns {
+  height: 10%;
+}
+.center {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
+</style>
diff --git a/src/views/fysp/check/components/CompProRecent.vue b/src/views/fysp/check/components/CompProRecent.vue
new file mode 100644
index 0000000..3dff972
--- /dev/null
+++ b/src/views/fysp/check/components/CompProRecent.vue
@@ -0,0 +1,198 @@
+<template>
+  <div>
+    <el-tabs v-model="activeName" type="card">
+      <el-tab-pane v-for="item in ranges" :label="item" :name="item"> </el-tab-pane>
+    </el-tabs>
+    <div class="proList">
+      <el-card class="card-style" shadow="hover">
+        <el-descriptions v-loading="loading">
+          <el-descriptions-item label="鎬诲嚭鐜版鏁�">{{ curProList.length }}</el-descriptions-item>
+          <!-- <el-descriptions-item label="澶嶇幇鐜�">{{ repeteRate }}%</el-descriptions-item> -->
+        </el-descriptions>
+        <!-- <el-descriptions v-loading="loading" column="3">
+          <div v-for="pro in curProList">
+            <el-descriptions-item>{{ pro.problemname }}</el-descriptions-item>
+            <el-descriptions-item label="浠诲姟鍚嶇О">{{ pro._stName }}</el-descriptions-item>
+            <el-descriptions-item>
+              <el-button link type="primary" @click="info(pro)">璇︽儏</el-button>
+            </el-descriptions-item>
+          </div>
+        </el-descriptions> -->
+        <el-table :data="curProList" style="width: 100%">
+          <el-table-column type="index" width="50" />
+          <el-table-column prop="problemname" label="闂"/>
+          <el-table-column prop="_time" label="鏃堕棿" width="250" />
+          <el-table-column prop="鎿嶄綔" label="鎿嶄綔" width="180">
+            <template v-slot="scope">
+              <el-button link type="primary" @click="info(scope.row)">璇︽儏</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-card>
+      <el-dialog
+        title="棰勮"
+        v-model="proAddOrUpdDialogVisible"
+        :before-close="proAddOrUpdDialogClose"
+        width="80%"
+      >
+        <CompProblemAddOrUpd
+          v-if="proAddOrUpdDialogVisible"
+          :subtask="subtask"
+          :topTask="topTask"
+          :problem="previewPro"
+          :readonly="true"
+          ref="compProblemAddOrUpdRef"
+        />
+      </el-dialog>
+    </div>
+  </div>
+</template>
+<script>
+import CompProblemAddOrUpd from './CompProblemAddOrUpd.vue';
+import taskApi from '@/api/fysp/taskApi';
+import { useCloned } from '@vueuse/core';
+export default {
+  computed: {
+    // repeteRate() {
+    //   return this.curProList.length !== 0 ? (this.curProList.length - 1) / this.subtaskCount * 1.0 : 0 
+    // },
+  },
+  props: {
+    problem: {
+      type: Object,
+      default: () => {}
+    },
+    topTask: {
+      type: Object,
+      default: () => {
+        return {};
+      }
+    },
+    subtask: {
+      type: Object,
+      default: () => {
+        return {};
+      }
+    }
+  },
+  watch: {
+    activeName: {
+      handler(newObj, oldObj) {
+        this.handleClick();
+      }
+    }
+  },
+  components: {
+    CompProblemAddOrUpd
+  },
+  mounted() {
+    console.log('subtask', this.subtask);
+
+    this.deepCopyPro = useCloned(this.problem).cloned.value;
+    this.getRecentPros();
+  },
+  data() {
+    return {
+      proAddOrUpdDialogVisible: false,
+      previewPro: {},
+      // 鍔犺浇缁熻淇℃伅
+      loading: false,
+      // 鏃堕棿鍜岄棶棰樺璞″垪琛�
+      timeProMap: new Map(),
+      curProList: [],
+      activeName: '杩戜笁涓湀',
+      ranges: ['杩戜笁涓湀', '杩戝崐骞�', '杩戜竴骞�'],
+      deepCopyPro: {}
+    };
+  },
+  methods: {
+    // 杞崲涓哄寳浜椂闂�
+    convertTime(time) {
+      time.setHours(time.getHours);
+      return time;
+    },
+    // 鎵撳紑璇︽儏椤甸潰
+    info(pro) {
+      this.previewPro = pro;
+      this.proAddOrUpdDialogVisible = true;
+    },
+    // 鍏抽棴璇︽儏寮圭獥
+    proAddOrUpdDialogClose() {
+      this.proAddOrUpdDialogVisible = false;
+    },
+    // 鍒囨崲鏃堕棿鑼冨洿
+    handleClick() {
+      this.getRecentPros();
+    },
+    updateSubtask() {},
+    generateQueryParam() {
+      // 浠婂ぉ鐨勬棩鏈�
+      const today = new Date();
+      // 涓変釜鏈堝墠
+      const threeMonthsAgo = new Date(today);
+      threeMonthsAgo.setMonth(today.getMonth() - 3);
+      // 璁$畻鍗婂勾鍓嶇殑鏃ユ湡
+      const sixMonthsAgo = new Date(today);
+      sixMonthsAgo.setMonth(today.getMonth() - 6);
+      // 璁$畻涓�骞村墠鐨勬棩鏈�
+      const oneYearAgo = new Date(today);
+      oneYearAgo.setFullYear(today.getFullYear() - 1);
+      console.log('today', this.$fm.formatYMDH(today));
+      console.log('threeMonthsAgo', this.$fm.formatYMDH(threeMonthsAgo));
+      console.log('sixMonthsAgo', this.$fm.formatYMDH(sixMonthsAgo));
+      console.log('oneYearAgo', this.$fm.formatYMDH(oneYearAgo));
+      return {
+        startTime:
+          this.activeName === '杩戜笁涓湀'
+            ? this.$fm.formatYMDH(threeMonthsAgo)
+            : this.activeName === '杩戝崐骞�'
+              ? this.$fm.formatYMDH(sixMonthsAgo)
+              : this.$fm.formatYMDH(oneYearAgo),
+        endTime: this.$fm.formatYMDH(today),
+        sceneId: this.deepCopyPro.sguid
+      };
+    },
+    /**
+     * 鑾峰彇杩戞湡鎯呭喌
+     * */
+    async getRecentPros() {
+      this.loading = true;
+      this.subtaskCount = 0
+      // 鑾峰彇瀛愪换鍔″垪琛�
+      await taskApi.getSubtaskByScene(this.generateQueryParam()).then((subtasks) => {
+        this.curProList = [];
+        if (subtasks) {
+          subtasks.forEach((subtask) => {
+            // 鑾峰彇闂鍒楄〃
+            this.getProBySubtask(subtask);
+          });
+        }
+        
+      });
+      // 棰濆澶勭悊
+      console.log('curr', this.curProList);
+      this.curProList.sort((o1, o2) => o2.getTime() - o1.getTime());
+      this.loading = false;
+    },
+    // 鏍规嵁瀛愪换鍔¤幏鍙栭噷闈㈢殑闂鍒楄〃
+    async getProBySubtask(subtask) {
+      taskApi.getProBySubtask(subtask.stGuid).then((pros) => {
+        if (pros) {
+          pros.forEach((pro) => {
+            if (pro.ptguid == this.deepCopyPro.ptguid) {
+              pro._stName = subtask.stName;
+              pro._time = this.$fm.formatYM(subtask.stPlanTime)
+              this.curProList.push(pro);
+            }
+          });
+        }
+      });
+    }
+  }
+};
+</script>
+<style scoped>
+.problem-style {
+  margin-bottom: 10px;
+}
+</style>
diff --git a/src/views/fysp/check/components/CompProblemAddOrUpd.vue b/src/views/fysp/check/components/CompProblemAddOrUpd.vue
new file mode 100644
index 0000000..00f7751
--- /dev/null
+++ b/src/views/fysp/check/components/CompProblemAddOrUpd.vue
@@ -0,0 +1,720 @@
+<template>
+  <div class="main-container">
+    <el-form :model="problem" label-width="auto" style="max-width: 95%">
+      <el-form-item label="闂绫诲瀷" prop="proType">
+        <el-select v-model="proType" @change="onProTypeChange" class="row" :disabled="readonly">
+          <el-option
+            v-for="item in problemTypeOptions"
+            :key="item.typeid"
+            :label="item.typename"
+            :value="item.typename"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="闂鎻忚堪" prop="description">
+        <el-select
+          v-model="deepCopyProblem.description"
+          @change="onProDesChange"
+          class="row"
+          :disabled="readonly"
+        >
+          <el-option
+            v-for="item in descriptionOptions"
+            :key="item.guid"
+            :label="item.description"
+            :value="item.guid"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="闂浣嶇疆" prop="locationid">
+        <el-select
+          v-model="deepCopyProblem.locationid"
+          @change="onProLocationChange"
+          class="row"
+          :disabled="readonly"
+        >
+          <el-option
+            v-for="item in posList"
+            :key="item.index"
+            :label="item.text"
+            :value="item.index"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="闂寤鸿" prop="advise">
+        <el-select v-model="deepCopyProblem.advise" class="row" :disabled="readonly">
+          <el-option
+            v-for="item in adviseOptions"
+            :key="item.adGuid"
+            :label="item.adName"
+            :value="item.adName"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="琛ュ厖璇存槑" :disabled="readonly" prop="proRemark">
+        <el-input
+          v-model="proRemark"
+          type="textarea"
+          @change="onProRemarkChange"
+          class="row"
+          placeholder="璇疯緭鍏�"
+        />
+      </el-form-item>
+      <div class="t-card_item">
+        闂鍥剧墖&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+        <div>
+          <el-button @click="chosePicFromAnyPic" v-show="!readonly">浠庝换鎰忓浘鐗囬�夊彇</el-button>
+          <el-button @click="chosePicFromDevicePic" v-show="!readonly">浠庤澶囧浘鐗囬�夊彇</el-button>
+          <el-button @click="chosePicFromLedgerPic" v-show="!readonly">浠庡彴璐﹂�夊彇</el-button>
+          <el-button @click="choseChangePic" v-show="!readonly">浠庢枃浠跺す閫夊彇</el-button>
+        </div>
+      </div>
+      <el-upload
+        class="img-upload"
+        ref="uploadRef"
+        v-model:file-list="fileList"
+        list-type="picture-card"
+        multiple
+        :auto-upload="false"
+        crossorigin="Anonymous"
+        :before-remove="beforeRemoveFile"
+        :on-preview="handlePictureCardPreview"
+        :disabled="readonly"
+        accept="image/*"
+      >
+        <el-button type="primary" id="uploadBtnId" style="display: none"></el-button>
+        <el-icon>
+          <Plus />
+        </el-icon>
+      </el-upload>
+      <el-form-item>
+        <el-button type="primary" @click="onSubmit" v-show="!readonly">淇濆瓨</el-button>
+        <el-button @click="this.$emit('submited', false)" v-show="!readonly">鍙栨秷</el-button>
+      </el-form-item>
+    </el-form>
+    <el-dialog
+      title="浠绘剰鍥剧墖"
+      width="80%"
+      v-model="anyPhotoDialog"
+      :before-close="beforeAnyPhotoDialogclose"
+      class="dialog_style"
+    >
+      <ArbitraryPhoto
+        v-if="anyPhotoDialog"
+        @selectByAnyPhonoEvent="handleSelectedAnyPhono"
+        :subtask="subtask"
+        :defaultFile="fileList"
+        ref="arbitraryPhotoRef"
+      >
+      </ArbitraryPhoto>
+    </el-dialog>
+    <el-dialog
+      width="80%"
+      v-model="ledgerPicDialog"
+      :before-close="beforeLedgerPicDialogclose"
+      class="dialog_style"
+    >
+      <LedgerPic
+        v-if="ledgerPicDialog"
+        @selectByLedgerPicEvent="handleLedgerPicPhono"
+        :month="month"
+        :subtask="subtask"
+        :defaultFile="fileList"
+        ref="ledgerPicRef"
+      >
+      </LedgerPic>
+    </el-dialog>
+    <el-dialog
+      title="璁惧鍥剧墖"
+      width="80%"
+      v-model="deiveceImgDialog"
+      :before-close="beforeDeiveceImgDialogclose"
+      class="dialog_style"
+    >
+      <CompDevicePhono
+        v-if="deiveceImgDialog"
+        @selectPhonoEvent="handleSelectedDevicePhono"
+        :imgPathsDataSource="deviceImgObjList"
+        :defaultFile="fileList"
+        ref="deiveceImgDialogRef"
+      >
+      </CompDevicePhono>
+    </el-dialog>
+    <el-dialog v-model="previewDialogVisible">
+      <img w-full :src="previewDialogImageUrl" alt="棰勮" class="preview-pic"/>
+    </el-dialog>
+  </div>
+</template>
+<script>
+import ArbitraryPhoto from './ArbitraryPhoto.vue';
+import LedgerPic from './CompLedgerPic.vue';
+import CompDevicePhono from './CompDevicePhono.vue';
+import problemApi from '@/api/fysp/problemApi.js';
+
+import { $fysp } from '@/api/index.js';
+import fileUtil from '@/utils/fileUtils.js';
+import { useCloned } from '@vueuse/core';
+import { ElMessage } from 'element-plus';
+import deviceApi from '@/api/fysp/deviceApi';
+export default {
+  components: {
+    ArbitraryPhoto,
+    LedgerPic,
+    CompDevicePhono
+  },
+  props: {
+    readonly: {
+      type: Boolean,
+      default: false
+    },
+    topTask: {
+      type: Object,
+      default: () => {
+        return {};
+      }
+    },
+    subtask: {
+      type: Object,
+      default: () => {
+        return {};
+      }
+    },
+    insGuid: {
+      type: String
+    },
+    problem: {
+      type: Object,
+      default: () => {
+        return {};
+      }
+    }
+  },
+  data() {
+    return {
+      previewDialogVisible: false,
+      previewDialogImageUrl: '',
+      // 璁惧鍥剧墖鍒楄〃
+      deviceImgObjList: [],
+      // 0浠h〃鏂板 1淇敼
+      type: -1,
+      deepCopyProblem: {},
+      currProTypeGuid: '',
+      proType: '',
+      proRemark: null,
+
+      suggestions: [],
+      problemTypeList: [],
+      posList: [],
+
+      fileList: [],
+      oldFileList: [],
+      deleteImg: [],
+      deiveceImgDialog: false,
+      anyPhotoDialog: false,
+      // 鍙拌处
+      month: -1,
+      ledgerPicDialog: false,
+      rules: {
+        proType: { required: true, message: '闂绫诲瀷涓嶈兘涓虹┖', trigger: 'change' },
+        description: { required: true, message: '闂鎻忚堪涓嶈兘涓虹┖', trigger: 'change' },
+        locationid: { required: true, message: '闂浣嶇疆涓嶈兘涓虹┖', trigger: 'change' },
+        advise: { required: true, message: '闂寤鸿涓嶈兘涓虹┖', trigger: 'change' },
+        proRemark: { required: true, message: '琛ュ厖璇存槑涓嶈兘涓虹┖', trigger: 'change' }
+      },
+      deviceTopTypes: [
+        { id: 0, label: '鐩戞帶璁惧' },
+        { id: 1, label: '娌荤悊璁惧' },
+        { id: 2, label: '鐢熶骇璁惧' }
+      ]
+    };
+  },
+  watch: {
+    fileList: {
+      handler(newFileList, oldFileList) {
+        console.log('newFileList', newFileList);
+        // 鍥剧墖鏍¢獙
+        this.pictureValidate();
+      },
+      deep: true
+    }
+  },
+  computed: {
+    descriptionOptions() {
+      const descriptions = [];
+      this.problemTypeList.forEach((item) => {
+        if (item.typename == this.proType) {
+          descriptions.push(item);
+        }
+      });
+      return descriptions;
+    },
+    problemTypeOptions() {
+      return this.problemTypeList.reduce((acc, current) => {
+        const x = acc.find((item) => item.typeid === current.typeid);
+        if (!x) {
+          acc.push(current);
+        }
+        return acc;
+      }, []);
+    },
+    adviseOptions() {
+      var array = this.suggestions.filter((item) => item.adProblemtypeguid == this.currProTypeGuid);
+      console.log('adName', array);
+
+      return array;
+    }
+  },
+  mounted() {
+    this.initOptions();
+    this.getDeviceImgList();
+  },
+  methods: {
+    handlePictureCardPreview(uploadFile) {
+      this.previewDialogVisible = true;
+      this.previewDialogImageUrl = uploadFile.url;
+    },
+    beforeDeiveceImgDialogclose() {
+      this.deiveceImgDialog = false;
+    },
+    // 鏍囧噯鍖栧睘鎬у悕
+    convertKeys(obj) {
+      // 灏嗕竴涓猨s瀵硅薄涓墍鏈塪i锛寃i锛宲i寮�澶寸殑灞炴�у叏閮ㄦ敼鎴愬幓鎺夎繖浜涘墠缂�骞朵笖閲嶆柊鍙樹负椹煎嘲寮忓懡鍚�
+      const newObj = {};
+      for (const key in obj) {
+        if (obj.hasOwnProperty(key)) {
+          let newKey = key;
+          if (key.startsWith('di')) {
+            newKey = key.substring(2);
+          } else if (key.startsWith('wi')) {
+            newKey = key.substring(2);
+          } else if (key.startsWith('pi')) {
+            newKey = key.substring(2);
+          }
+          newKey = newKey.charAt(0).toLowerCase() + newKey.slice(1);
+          newObj[newKey] = obj[key];
+        }
+      }
+      return newObj;
+    },
+    // 淇濆瓨鐘舵�佷俊鎭�
+    saveStatus(device, status) {
+      var _picUrl = $fysp.imgUrl + status.dlPicUrl;
+      device._picUrl = _picUrl;
+      status._picUrl = _picUrl;
+      if ('_statusList' in device) {
+        device._statusList.push(status);
+      } else {
+        device._statusList = Array.of(status);
+      }
+      // 鎺掑簭
+      device._statusList.sort(function (x, y) {
+        return new Date(x.dlCreateTime) - new Date(y.dlCreateTime); //	闄嶅簭锛屽崌搴忓垯鍙嶄箣
+      });
+    },
+    async getDeviceImgList() {
+      this.deviceImgObjList = [];
+      for (const deviceTopTypeElement of this.deviceTopTypes) {
+        const topTypeId = deviceTopTypeElement.id;
+        await deviceApi.fetchDevices(this.subtask.sceneId, topTypeId).then((result) => {
+          // 鏍囧噯鍖栧睘鎬у悕
+          for (let i = 0; i < result.data.length; i++) {
+            var element = this.convertKeys(result.data[i]);
+            // 鑾峰彇璁惧鐘舵�佷俊鎭�
+            let data = {
+              deviceId: element.id,
+              sceneId: element.sceneGuid,
+              deviceTypeId: topTypeId
+            };
+            deviceApi
+              .fetchDeviceStatus(data)
+              .then((status) => {
+                var statusData = status.data;
+                var imgPaths = [];
+
+                if (statusData) {
+                  if (statusData.length == 0) {
+                    this.deviceImgObjList.push(element);
+                    return;
+                  }
+                  element = this.convertKeys(result.data[i]);
+                  for (let j = 0; j < statusData.length; j++) {
+                    // 澶嶅埗鍑轰竴涓澶囧璞�
+                    var newDevice = useCloned(element).cloned.value;
+                    const statusItem = statusData[j];
+                    // 璁惧瀵硅薄娣诲姞涓�涓睘鎬у垪琛ㄥ睘鎬х敤鏉ヤ繚瀛樿澶囩姸鎬�
+                    this.saveStatus(newDevice, statusItem);
+                    newDevice.dlLocation = statusItem.dlLocation;
+                    newDevice.topTypeId = topTypeId;
+                    console.log('newDevice.topTypeId', newDevice.topTypeId);
+                    console.log('newDevice', newDevice);
+
+                    this.deviceImgObjList.push(newDevice);
+                  }
+                }
+              })
+              .catch((err) => {});
+          }
+        });
+      }
+    },
+    initOptions() {
+      if (this.problem == undefined || this.problem == null) {
+        this.problem = {};
+        this.deepCopyProblem = {};
+      } else {
+        this.deepCopyProblem = useCloned(this.problem).cloned.value;
+      }
+
+      this.type = 'guid' in this.deepCopyProblem ? 1 : 0;
+      // 鑾峰彇闂绫诲瀷
+      let data = {
+        sceneTypeId: this.subtask.sceneTypeId,
+        cityCode: this.topTask.citycode,
+        districtCode: this.topTask.districtcode
+      };
+      problemApi.fetchProblemType(data).then((res) => {
+        this.problemTypeList = res.data;
+
+        if (this.type == 1) {
+          let currProName = String(this.problem.problemname);
+
+          let currDescription;
+          if (currProName.lastIndexOf('(') == -1) {
+            currDescription = currProName;
+            this.problemTypeList.forEach((item) => {
+              if (item.description == currDescription) {
+                this.proType = item.typename;
+              }
+            });
+            this.deepCopyProblem.description = currDescription;
+            this.proRemark = '';
+          } else {
+            currDescription = currProName.substring(0, currProName.lastIndexOf('('));
+
+            this.problemTypeList.forEach((item) => {
+              if (item.description === currDescription) {
+                this.proType = item.typename;
+              }
+            });
+            this.deepCopyProblem.description = currDescription;
+            this.proRemark = currProName.substring(
+              currProName.lastIndexOf('(') + 1,
+              currProName.length - 1
+            );
+          }
+
+          let beforeEditImgList = [];
+          let oldFiles = this.problem.mediafileList;
+          if (oldFiles && oldFiles.length > 0) {
+            this.problem.mediafileList.forEach((item) => {
+              if (item.ischanged == 0) {
+                item.url = $fysp.imgUrl + item.extension1 + item.guid + '.jpg';
+                item.name = '1';
+                beforeEditImgList.push(item);
+              }
+            });
+            this.fileList = useCloned(beforeEditImgList).cloned.value;
+            this.oldFileList = useCloned(beforeEditImgList).cloned.value;
+          }
+        }
+      });
+
+      // 闂寤鸿
+      problemApi.getSuggestion().then((res) => {
+        this.suggestions = res.data;
+        // 濉厖褰撳墠闂寤鸿
+        this.deepCopyProblem.advise = this.suggestions.filter(
+          (item) => item.adProblemtypeguid == this.deepCopyProblem.guid
+        )[0].adName;
+      });
+
+      // 闂浣嶇疆
+      problemApi
+        .getLocation({
+          sceneTypeId: this.subtask.sceneTypeId
+        })
+        .then((res) => {
+          this.posList = res.data;
+        });
+    },
+    beforeRemoveFile(file, fileList) {
+      if (file.remark == '宸蹭笂浼�') {
+        this.deleteImg.push(file.guid);
+        this.oldFileList.filter((item) => item.url != file.url);
+      }
+    },
+    handleLedgerPicPhono() {
+      this.beforeLedgerPicDialogclose();
+      let isExist = false;
+      for (const item of data) {
+        for (const already of this.fileList) {
+          if (item.url == already.url) {
+            isExist = true;
+          }
+        }
+        if (!isExist) {
+          this.fileList.push({
+            url: item.url,
+            name: '1'
+          });
+        }
+        isExist = false;
+      }
+    },
+    beforeLedgerPicDialogclose() {
+      this.ledgerPicDialog = false;
+    },
+    findProTypeByGuid(guid) {
+      let result;
+      this.problemTypeList.forEach((item) => {
+        if (item.guid == guid) {
+          result = item;
+        }
+      });
+      return result;
+    },
+    changeProblemname() {
+      if (this.proRemark == null || this.proRemark == '') {
+        this.deepCopyProblem.problemname = this.deepCopyProblem.description;
+      } else {
+        this.deepCopyProblem.problemname =
+          this.deepCopyProblem.description + '(' + this.proRemark + ')';
+      }
+    },
+    onProRemarkChange(value) {
+      this.changeProblemname();
+    },
+    onProTypeChange(value) {
+      this.deepCopyProblem.description = '';
+      this.deepCopyProblem.advise = '';
+    },
+    onProDesChange(value) {
+      let currPro = this.findProTypeByGuid(value);
+      this.deepCopyProblem.advise = '';
+      this.currProTypeGuid = value;
+      this.deepCopyProblem.description = currPro.description;
+      this.changeProblemname();
+      this.deepCopyProblem.advise = '';
+
+      this.deepCopyProblem.advise = this.adviseOptions[0].adName;
+    },
+    onProLocationChange(value) {
+      this.posList.forEach((item) => {
+        if (item.index == value) {
+          this.deepCopyProblem.location = item.text;
+        }
+      });
+    },
+    pictureValidate() {
+      if (this.fileList.length < 1) {
+        ElMessage({
+          message: '鑷冲皯涓婁紶涓�寮犲浘鐗�',
+          type: 'error'
+        });
+        return false;
+      } else if (this.fileList.length > 3) {
+        ElMessage({
+          message: '瓒呰繃涓夊紶, 宸插垹闄ゅ鍑虹殑鍥剧墖',
+          type: 'error'
+        });
+        this.fileList = this.fileList.slice(0, 3);
+        return false;
+      }
+      return true;
+    },
+    // TODO
+    validateForm() {},
+    onSubmit() {
+      this.validateForm();
+      // 鍥剧墖鏍¢獙
+      if (!this.pictureValidate()) {
+        return;
+      }
+      // 鏁版嵁鍑嗗
+      let deepCopyPro = useCloned(this.deepCopyProblem).cloned.value;
+      let data = new FormData();
+      var picUrls = [];
+      this.fileList.forEach((item) => {
+        if (!('guid' in item)) {
+          // 鏂扮殑
+          let exclude = false;
+          for (let index = 0; index < this.oldFileList.length; index++) {
+            const element = this.oldFileList[index];
+            if (item.url == element.url) {
+              exclude = true;
+              break;
+            }
+          }
+          if (!exclude) {
+            picUrls.push(item.url);
+          }
+          exclude = false;
+          // picUrls.push(item)
+        } else {
+        }
+      });
+      if (this.type == 1) {
+        let deleteImgCopy = this.deleteImg;
+        fileUtil.getImageFiles(picUrls, function (files) {
+          data.append('deleteImg', deleteImgCopy);
+          delete deepCopyPro['mediafileList'];
+          delete deepCopyPro['description'];
+          data.append('problem', JSON.stringify(deepCopyPro));
+          files.forEach((image) => {
+            data.append('images', image);
+          });
+          problemApi.updateProblem(data).then((res) => {});
+        });
+      } else {
+        const deepCopySubTask = useCloned(this.subtask).cloned.value;
+        const that = this;
+        fileUtil.getImageFiles(picUrls, function (files) {
+          console.log('deepCopySubTask', deepCopySubTask);
+          deepCopyPro.insGuid = deepCopySubTask.insGuid;
+          delete deepCopyPro['advise'];
+          delete deepCopyPro['description'];
+          deepCopyPro.proName = deepCopyPro.problemname;
+          delete deepCopyPro['problemname'];
+          deepCopyPro.ptGuid = that.findProTypeByGuid(that.currProTypeGuid).guid;
+          deepCopyPro.locationId = deepCopyPro.locationid;
+          delete deepCopyPro['locationid'];
+          data.append('problemVo', JSON.stringify(deepCopyPro));
+          files.forEach((image) => {
+            data.append('images', image);
+          });
+          problemApi.newProblem(data).then((res) => {});
+        });
+      }
+      this.$emit('submited', true);
+    },
+    handleSelectedAnyPhono(data) {
+      this.beforeAnyPhotoDialogclose();
+      let isExist = false;
+      for (const item of data) {
+        for (const already of this.fileList) {
+          if (item.url == already.url) {
+            isExist = true;
+          }
+        }
+        if (!isExist) {
+          this.fileList.push({
+            url: item.url,
+            name: '1'
+          });
+        }
+        isExist = false;
+      }
+    },
+    handleSelectedDevicePhono(data) {
+      this.beforeDeiveceImgDialogclose();
+      let isExist = false;
+      for (const item of data) {
+        for (const already of this.fileList) {
+          if (item._picUrl == already.url) {
+            isExist = true;
+          }
+        }
+        if (!isExist) {
+          this.fileList.push({
+            url: item._picUrl,
+            name: '1'
+          });
+        }
+        isExist = false;
+      }
+    },
+    handleLedgerPicPhono(data) {
+      let isExist = false;
+      for (const item of data) {
+        for (const already of this.fileList) {
+          if (item.url == already.url) {
+            isExist = true;
+          }
+        }
+        if (!isExist) {
+          this.fileList.push({
+            url: item.url,
+            name: '1'
+          });
+        }
+        isExist = false;
+      }
+
+      this.beforeAnyPhotoDialogclose();
+    },
+    chosePicFromAnyPic() {
+      this.anyPhotoDialog = true;
+    },
+    chosePicFromDevicePic() {
+      this.deiveceImgDialog = true;
+    },
+    chosePicFromLedgerPic() {
+      // 浣跨敤Date瀵硅薄瑙f瀽鏃ユ湡瀛楃涓�
+      var date = new Date(this.subtask.subtask.planstarttime);
+      // 鑾峰彇鏈堜唤淇℃伅锛屾湀浠芥槸浠�0寮�濮嬬殑锛屾墍浠ラ渶瑕佸姞1
+      this.month = date.getMonth() + 1;
+      if (String(this.month).length == 1) {
+        this.month = `0${this.month}`;
+      }
+      var year = date.getFullYear();
+      this.month = `${year}-${this.month}`;
+      this.ledgerPicDialog = true;
+    },
+    // 浠庢枃浠跺す涓�
+    choseChangePic() {
+      // 鑾峰彇鎸囧畾ID鐨勫厓绱�
+      var btnElement = document.getElementById('uploadBtnId');
+      // 妫�鏌ュ厓绱犳槸鍚﹀瓨鍦�
+      if (btnElement) {
+        // 瑙﹀彂鐐瑰嚮浜嬩欢
+        btnElement.click();
+      }
+    },
+    beforeAnyPhotoDialogclose() {
+      this.anyPhotoDialog = false;
+    },
+    beforeLedgerPicDialogclose() {
+      this.ledgerPicDialog = false;
+    },
+
+    destoryMyself() {
+      this.$destroy();
+    }
+  }
+};
+</script>
+<style scoped>
+.main-container {
+  padding: 3px;
+}
+.t-card_item {
+  display: flex;
+}
+
+.w-msg-img {
+  position: absolute;
+  width: 25rem;
+  height: 27rem;
+}
+
+.img-upload {
+  margin-top: 30px;
+  margin-bottom: 30px;
+  margin-left: 63px;
+}
+.row {
+  width: 100%;
+}
+
+::v-deep .el-dialog__body {
+  width: 95%;
+}
+::v-deep .el-upload-list--picture-card .el-upload-list__item-thumbnail {
+  object-fit: cover !important;
+}
+.preview-pic {
+  object-fit: cover;
+  width: 100%;
+  height: 100%;
+}
+</style>
diff --git a/src/views/fysp/check/components/CompProblemCard.vue b/src/views/fysp/check/components/CompProblemCard.vue
index 7423ba5..04947c6 100644
--- a/src/views/fysp/check/components/CompProblemCard.vue
+++ b/src/views/fysp/check/components/CompProblemCard.vue
@@ -59,15 +59,16 @@
     <el-row v-if="true" style="margin-top: 16px">
       <el-col :span="12">
         <el-row justify="start" class="btn-group">
-          <el-button type="success" size="small" @click="updatePro" plain>淇敼闂</el-button>
+          <el-button type="success" size="small" @click="updatePro" plain>闂鏇存</el-button>
           <el-button
             type="primary"
             size="small"
             @click="updateChange"
             plain
             :disabled="!proStatus.changeable"
-            >淇敼鏁存敼</el-button
+            >鏁存敼妫�楠�</el-button
           >
+          <el-button type="info" size="small" @click="currProRecent" plain>闂澶嶇幇</el-button>
         </el-row>
       </el-col>
       <el-col :span="12">
@@ -85,19 +86,84 @@
       </el-col>
     </el-row>
   </el-card>
+  <el-dialog v-model="proAddOrUpdDialogVisible" :before-close="proAddOrUpdDialogClose" width="80%">
+    <CompProblemAddOrUpd
+      v-if="proAddOrUpdDialogVisible"
+      :problem="deepCopyPro"
+      :subtask="deepCopySubtask"
+      :topTask="deepCopyTopTask"
+      ref="compProblemAddOrUpdRef"
+      @submited="onProSubmited"
+    />
+  </el-dialog>
+  <el-dialog
+    width="80%"
+    title="鏁存敼妫�楠�"
+    v-model="changeEditDialogVisible"
+    :before-close="changeEditDialogClose"
+  >
+    <ComChangeEdit
+      v-if="changeEditDialogVisible"
+      :problemId="problem.guid"
+      :oldChangeFileList="problem.mediafileList"
+      :subtask="subtask"
+      :month="month"
+      @submited="onChangeSubmited"
+    />
+  </el-dialog>
+  <!-- 闂澶嶇幇 -->
+  <el-dialog
+    width="80%"
+    title="闂澶嶇幇"
+    v-model="proRecentDialogVisible"
+    :before-close="proRecentDialogClose"
+  >
+    <CompProRecent 
+      v-if="proRecentDialogVisible" 
+      :subtask="subtask"
+      :topTask="topTask"
+      :problem="problem"/>
+  </el-dialog>
 </template>
 
 <script>
-import ProCheckProxy from '../ProCheckProxy'
-import problemApi from '@/api/fysp/problemApi'
-import { useMessageBoxTip } from '@/composables/messageBox'
-
+import ProCheckProxy from '../ProCheckProxy';
+import problemApi from '@/api/fysp/problemApi';
+import { useMessageBoxTip } from '@/composables/messageBox';
+import CompProblemAddOrUpd from './CompProblemAddOrUpd.vue';
+import ComChangeEdit from './ComChangeEdit.vue';
+import CompProRecent from './CompProRecent.vue';
+import { useCloned } from '@vueuse/core';
 export default {
+  components: {
+    CompProblemAddOrUpd,
+    ComChangeEdit,
+    CompProRecent
+  },
   props: {
+    // 鍙閫夐」
+    readonly: {
+      type: Boolean,
+      default: () => {
+        return false;
+      }
+    },
+    topTask: {
+      type: Object,
+      default: () => {}
+    },
+    subtask: {
+      type: Object,
+      default: () => {}
+    },
+    insGuid: {
+      type: String,
+      default: () => ''
+    },
     problem: {
       type: Object,
       default: () => {
-        return {}
+        return {};
       }
     },
     index: {
@@ -105,9 +171,17 @@
       default: 1
     }
   },
-  emits:['submit'],
+  emits: ['submit'],
   data() {
     return {
+      // 杩戞湡鎯呭喌
+      proRecentDialogVisible: false,
+      month: -1,
+      deepCopyPro: {},
+      deepCopySubtask: {},
+      deepCopyTopTask: {},
+      proAddOrUpdDialogVisible: false,
+      changeEditDialogVisible: false,
       // 瀹℃牳姝ラ
       steps: [
         {
@@ -123,12 +197,16 @@
           aft: '鏁存敼宸插鏍�'
         }
       ]
-    }
+    };
+  },
+  mounted() {
+    console.log(this.topTask);
+    
   },
   computed: {
     // 闂鍚嶇О
     title() {
-      return this.problem.problemname
+      return this.problem.problemname;
     },
     // 闂鎻忚堪
     descriptions() {
@@ -141,11 +219,11 @@
           name: '鎻愪氦鏃堕棿',
           value: this.problem.time.replace('T', ' ').split('.')[0]
         }
-      ]
+      ];
     },
     // 闂鍥剧墖
     pics() {
-      return ProCheckProxy.proPics(this.problem)
+      return ProCheckProxy.proPics(this.problem);
     },
     /**
      * 鑾峰彇褰撳墠闂瀹℃牳姝ラ
@@ -153,46 +231,93 @@
     getSteps() {
       return this.steps.map((v, i) => {
         if (i >= this.proStatus.index) {
-          return v.bef
+          return v.bef;
         } else {
-          return v.aft
+          return v.aft;
         }
-      })
+      });
     },
     // 闂鐘舵��
     proStatus() {
-      return ProCheckProxy.proStatusMap(this.problem.extension3)
+      return ProCheckProxy.proStatusMap(this.problem.extension3);
     }
   },
   methods: {
+    // 杩戞湡鎯呭喌寮圭獥鍏抽棴
+    proRecentDialogClose() {
+      this.proRecentDialogVisible = false;
+    },
+    newProblem() {
+      this.proAddOrUpdDialogVisible = true;
+    },
+    onProSubmited(isOk) {
+      this.$emit('updated', isOk);
+      this.proAddOrUpdDialogVisible = false;
+    },
+    onChangeSubmited(isOk) {
+      console.log("zhenggaisubmit");
+      
+      this.$emit('updated', isOk);
+      this.changeEditDialogVisible = false;
+    },
+    proAddOrUpdDialogClose() {
+      this.proAddOrUpdDialogVisible = false;
+    },
+    changeEditDialogClose() {
+      this.changeEditDialogVisible = false;
+    },
     deletePro() {},
     rejectPro() {
-      this.checkPro(false)
+      this.checkPro(false);
     },
     passPro() {
-      this.checkPro(true)
+      this.checkPro(true);
     },
     checkPro(pass) {
-      const pro = this.problem
-      let doneMsg = pass ? '閫氳繃' : '椹冲洖'
+      const pro = this.problem;
+      let doneMsg = pass ? '閫氳繃' : '椹冲洖';
       useMessageBoxTip({
         confirmMsg: `纭鏄惁${doneMsg}璇ラ棶棰橈紵`,
         confirmTitle: '闂瀹℃牳',
         onConfirm: () => {
-          const { status, action } = ProCheckProxy.proNextStatus(pro.extension3, pass)
+          const { status, action } = ProCheckProxy.proNextStatus(pro.extension3, pass);
           return problemApi.checkProblem({ pId: pro.guid, action: action }).then((res) => {
             if (res.success) {
-              pro.extension3 = status
-              this.$emit('submit')
+              pro.extension3 = status;
+              this.$emit('submit');
             }
-          })
+          });
         }
-      })
+      });
     },
-    updatePro() {},
-    updateChange() {}
+    updatePro() {
+      console.log("clone", this.topTask);
+      
+      this.deepCopyPro = useCloned(this.problem).cloned.value;
+      this.deepCopySubtask = useCloned(this.subtask).cloned.value;
+      this.deepCopyTopTask = useCloned(this.topTask).cloned.value;
+      this.$nextTick(() => {
+        this.proAddOrUpdDialogVisible = true;
+      });
+    },
+    updateChange() {
+      // 浣跨敤Date瀵硅薄瑙f瀽鏃ユ湡瀛楃涓�
+      var date = new Date(this.subtask.subtask.planstarttime);
+      // 鑾峰彇鏈堜唤淇℃伅锛屾湀浠芥槸浠�0寮�濮嬬殑锛屾墍浠ラ渶瑕佸姞1
+      this.month = date.getMonth() + 1;
+      if (String(this.month).length == 1) {
+        this.month = `0${this.month}`;
+      }
+      // 鑾峰彇骞翠唤
+      var year = date.getFullYear();
+      this.month = `${year}-${this.month}`;
+      this.changeEditDialogVisible = true;
+    },
+    currProRecent() {
+      this.proRecentDialogVisible = true;
+    }
   }
-}
+};
 </script>
 <style scoped>
 .layout {

--
Gitblit v1.9.3