From 84f19ab0d37599400959e85e63cfda5df4869bc8 Mon Sep 17 00:00:00 2001 From: sd <shidong@jhsoft.cc> Date: 星期一, 28 七月 2025 16:44:25 +0800 Subject: [PATCH] 整合督查任务 --- src/pages/inspection/index/App.vue | 33 src/pages/testingtask/index/TestingTaskView.vue | 727 ++++++++++++++++++++ src/api/TestingTaskView.ts | 35 + src/pages/testingtask/index/main.ts | 28 src/api/InspectionView.ts | 83 ++ src/pages/inspection/index/main.ts | 28 src/pages/inspection/index/mixins.ts | 25 src/pages/cameraAccess/components/SceneRule.vue | 37 src/pages/inspection/index/InspectionView.vue | 1039 +++++++++++++++++++++++++++++ src/pages/testingtask/index/App.vue | 33 src/pages/testingtask/index/mixins.ts | 9 src/pages/cameraAccess/components/SeparateRules.vue | 1 12 files changed, 2,061 insertions(+), 17 deletions(-) diff --git a/src/api/InspectionView.ts b/src/api/InspectionView.ts new file mode 100644 index 0000000..b0101d3 --- /dev/null +++ b/src/api/InspectionView.ts @@ -0,0 +1,83 @@ +import request from "@/scripts/httpRequest"; +export default { + getFiles(params) { + // return service.get('/task/all', { params }) + return request({ + url: '/api-v1/v1/task/all', + method: 'get', + params + }) + }, + createFile(data) { + // return service.post('/task/add', data) + return request({ + url: '/api-v1/v1/task/add', + method: 'post', + data + }) + }, + updateFile( data) { + // return service.put(`/task/update`, data) + return request({ + url: '/api-v1/v1/task/update', + method: 'put', + data + }) + }, + deleteFile(params) { + // return service.delete(`/task/delete`, { params }) + return request({ + url: '/api-v1/v1/task/delete', + method: 'delete', + params + }) + }, + getTasks(params) { + // return service.get('/checkContent/all', { params }) + return request({ + url: '/api-v1/v1/checkContent/all', + method: 'get', + params + }) + }, + getWarnings(params) { + // return service.get('/warningRule/all', { params }) + return request({ + url: '/api-v1/v1/warningRule/all', + method: 'get', + params + }) + }, + getCameras(params) { + // return service.get('/task/getVideoOption') + return request({ + url: '/api-v1/v1/task/getVideoOption', + method: 'get', + params + }) + }, + getTimes(params) { + // return service.get('/workTime/all') + return request({ + url: '/api-v1/v1/workTime/all', + method: 'get', + params + }) + }, + getEvelens(params) { + // return service.get('/task/getDictType') + return request({ + url: '/api-v1/v1/task/getDictType', + method: 'get', + params + }) + }, + getKnowledges(params) { + // return service.get('/checkContent/all', { params }) + return request({ + url: '/api-v1/v1/task/getKnowOption', + method: 'get', + params + }) + }, +} \ No newline at end of file diff --git a/src/api/TestingTaskView.ts b/src/api/TestingTaskView.ts new file mode 100644 index 0000000..a91dad9 --- /dev/null +++ b/src/api/TestingTaskView.ts @@ -0,0 +1,35 @@ +import request from "@/scripts/httpRequest"; +export default { + getFiles(params) { + // return service.get('/checkContent/all', { params }) + return request({ + url: '/api-v1/v1/checkContent/all', + method: 'get', + params + }) + }, + createFile(data) { + // return service.post('/checkContent/add', data) + return request({ + url: '/api-v1/v1/checkContent/add', + method: 'post', + data + }) + }, + updateFile(data) { + // return service.put(`/checkContent/update`, data) + return request({ + url: '/api-v1/v1/checkContent/update', + method: 'put', + data + }) + }, + deleteFile(params) { + // return service.delete(`/checkContent/delete`,{ params }) + return request({ + url: '/api-v1/v1/checkContent/delete', + method: 'delete', + params + }) + } +} \ No newline at end of file diff --git a/src/pages/cameraAccess/components/SceneRule.vue b/src/pages/cameraAccess/components/SceneRule.vue index d061e72..3e67bce 100644 --- a/src/pages/cameraAccess/components/SceneRule.vue +++ b/src/pages/cameraAccess/components/SceneRule.vue @@ -22,7 +22,7 @@ </el-select> </el-form-item> <el-form-item label="鏃堕棿娈�"> - <el-select v-model="sceneForm.workingTimes" placeholder="璇烽�夋嫨" size="mini"> + <el-select v-model="sceneForm.workTimeId" placeholder="璇烽�夋嫨" size="mini"> <el-option v-for="item in VideoManageData.TimeRules" :key="item.id" :label="item.name" :value="item.id"></el-option> </el-select> @@ -442,7 +442,7 @@ message: "浜嬩欢绛夌骇涓嶈兘涓虹┖", }); return false; - } else if (!this.sceneForm.workingTimes) { + } else if (!this.sceneForm.workTimeId) { this.$notify({ type: "warning", message: "鏃堕棿娈典笉鑳戒负绌�", @@ -454,19 +454,20 @@ message: "妫�娴嬪唴瀹逛笉鑳戒负绌�", }); return false; - } else if (!this.sceneForm.workingTimes) { + } else if (!this.sceneForm.warningRules) { this.$notify({ type: "warning", message: "棰勮瑙勫垯涓嶈兘涓虹┖", }); return false; - } else if (!this.sceneForm.knowsList) { - this.$notify({ - type: "warning", - message: "鐭ヨ瘑搴撲笉鑳戒负绌�", - }); - return false; } + // else if (!this.sceneForm.knowsList) { + // this.$notify({ + // type: "warning", + // message: "鐭ヨ瘑搴撲笉鑳戒负绌�", + // }); + // return false; + // } return true; }, saveSceneRule() { @@ -487,19 +488,21 @@ // labelName: timeOption ? timeOption.name : '' // } // }) - const fileIds = this.sceneForm.knowsList.map( - path => { - // 鎻愬彇鏈�鍚庝竴绾х殑鏂囦欢ID骞惰浆鎹负鏁板瓧 - const id = path[path.length - 1]; - return Number(id); // 鎴栬�呬娇鐢� parseInt(id) 鎴� +id - } - ) + let fileIds = [] + if (this.sceneForm.knowsList) { + fileIds = this.sceneForm.knowsList.map( + path => { + // 鎻愬彇鏈�鍚庝竴绾х殑鏂囦欢ID骞惰浆鎹负鏁板瓧 + const id = path[path.length - 1]; + return Number(id); // 鎴栬�呬娇鐢� parseInt(id) 鎴� +id + } + ) + } this.sceneForm.taskName = this.sceneForm.scene_name this.sceneForm.eventLevel = this.sceneForm.alarm_level this.sceneForm.checks = this.sceneForm.checkContents this.sceneForm.rules = this.sceneForm.warningRules // this.sceneForm.workTimes = workTimes - this.sceneForm.workTimeId = this.sceneForm.workingTimes this.sceneForm.taskDescription = this.sceneForm.desc this.sceneForm.knows = fileIds, this.onSaveScene(this.sceneForm); diff --git a/src/pages/cameraAccess/components/SeparateRules.vue b/src/pages/cameraAccess/components/SeparateRules.vue index db18819..5487d38 100644 --- a/src/pages/cameraAccess/components/SeparateRules.vue +++ b/src/pages/cameraAccess/components/SeparateRules.vue @@ -375,6 +375,7 @@ }, refresh(url) { this.Camera.baseImg = url + // console.info("url="+url) }, // 鍒濆鍖栨憚鍍忔満淇℃伅锛岀埗缁勪欢璋冪敤 async initCameraData(id, type) { diff --git a/src/pages/inspection/index/App.vue b/src/pages/inspection/index/App.vue new file mode 100644 index 0000000..a85b803 --- /dev/null +++ b/src/pages/inspection/index/App.vue @@ -0,0 +1,33 @@ +<template> + <div class="column"> + <inspec-tion + :appName="app" + ></inspec-tion> + </div> +</template> + +<script> +import InspecTion from "../index/InspectionView.vue"; + +export default { + name: "inspection", + components: { + InspecTion, + }, + computed: { + app() { + }, + }, + data() { + return { + }; + }, + mounted() { + }, + methods: {}, +}; +</script> + +<style lang="scss" scoped> + +</style> diff --git a/src/pages/inspection/index/InspectionView.vue b/src/pages/inspection/index/InspectionView.vue new file mode 100644 index 0000000..e0f4dc7 --- /dev/null +++ b/src/pages/inspection/index/InspectionView.vue @@ -0,0 +1,1039 @@ +<template> + <div class="task-container"> + + <!-- 鏃堕棿娈佃缃脊绐� --> + <el-dialog title="鏃堕棿娈�" :visible.sync="timeDialogVisible" custom-class="time-dialog" width="900px"> + <time-span v-model="taskForm.workTime" @confirm="confirmTimePeriods" :visible="this.timeDialogVisible" /> + <span slot="footer"> + <el-button @click="timeDialogVisible = false">鍙栨秷</el-button> + <el-button type="primary" @click="timeDialogVisible = false">纭畾</el-button> + </span> + </el-dialog> + + <!-- 鏂板鏌ョ湅璇︽儏寮圭獥 --> + <el-dialog title="浠诲姟璇︽儏" :visible.sync="viewDialogVisible" width="800px" custom-class="view-dialog" + @open="handleDialogOpen" @closed="handleDialogClose"> + <el-form :model="currentTask" label-width="100px"> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="浠诲姟鍚嶇О" prop="taskName"> + <el-input v-model="currentTask.taskName" :readonly="true"></el-input> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="浜嬩欢绛夌骇" prop="eventLevel"> + <el-select v-model="currentTask.eventLevel" placeholder="璇烽�夋嫨" disabled> + <el-option v-for="item in levelOptions" :key="item.dictId" :label="item.dictValue" + :value="item.dictId"></el-option> + </el-select> + </el-form-item> + </el-col> + </el-row> + <!-- 宸ヤ綔鏃堕棿 --> + <el-row :gutter="20"> + + <el-form-item label="宸ヤ綔鏃堕棿" prop="workingTimes"> + <el-col :span="20"> + <el-select v-model="currentTask.workingTimes" placeholder="璇烽�夋嫨鎴栬缃椂闂存" multiple disabled> + <el-option v-for="item in timeOptions" :key="item.labelId" :label="item.labelName" + :value="item.labelId"></el-option> + </el-select> + </el-col> + </el-form-item> + </el-row> + + <!-- 浠诲姟鎻忚堪 --> + <el-form-item label="浠诲姟鎻忚堪" prop="taskDescription"> + <el-input type="textarea" :rows="3" v-model="currentTask.taskDescription" placeholder="璇疯緭鍏ュ唴瀹�" + :readonly="true"></el-input> + </el-form-item> + + <!-- 澶氬垪閫夋嫨 --> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="瑙嗛鐐逛綅" prop="videoIds"> + <el-select v-model="currentTask.videoIds" placeholder="璇烽�夋嫨" multiple disabled> + <el-option v-for="item in positionOptions" :key="item.videoId" :label="item.deviceName" + :value="item.videoId"></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="澶氭ā鎬佸ぇ妯″瀷" prop="modelName"> + <el-select v-model="currentTask.modelName" placeholder="璇烽�夋嫨" disabled> + <el-option v-for="item in modelOptions" :key="item.value" :label="item.label" + :value="item.value"></el-option> + </el-select> + </el-form-item> + </el-col> + </el-row> + + <!-- 妫�娴嬪唴瀹� --> + <el-form-item label="妫�娴嬪唴瀹�" prop="checkContents"> + <el-select v-model="currentTask.checkContents" multiple placeholder="璇烽�夋嫨" disabled> + <el-option v-for="item in checkOptions" :key="item.checkId" :label="item.fileName" + :value="item.checkId"></el-option> + </el-select> + </el-form-item> + + <!-- 棰勮瑙勫垯 --> + <el-form-item label="棰勮瑙勫垯" prop="warningRules"> + <el-select v-model="currentTask.warningRules" placeholder="璇烽�夋嫨" multiple disabled> + <el-option v-for="item in ruleOptions" :key="item.ruleId" :label="item.fileName" + :value="item.ruleId"></el-option> + </el-select> + </el-form-item> + <!-- 鐭ヨ瘑搴� --> + <!-- <el-form-item label="鐭ヨ瘑搴�" prop="knows"> + <el-select v-model="currentTask.knowsList" placeholder="璇烽�夋嫨" multiple disabled> + <el-option v-for="item in flattenKnowledgeOptions" :key="item.value" :label="getKnowledgeLabel(item)" + :value="item.value"></el-option> + </el-select> + </el-form-item> --> + </el-form> + <span slot="footer"> + <el-button @click="viewDialogVisible = false">鍏抽棴</el-button> + </span> + </el-dialog> + <!-- 鏂板缓浠诲姟寮圭獥 --> + <el-dialog title="娣诲姞鏅烘煡浠诲姟" :visible.sync="dialogVisible" width="800px" custom-class="task-dialog" + @open="handleDialogOpen" @closed="handleDialogClose"> + <el-form ref="taskForm" :model="taskForm" label-width="100px" :rules="formRules"> + <!-- 绗竴琛� --> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="浠诲姟鍚嶇О" prop="taskName" required> + <el-input v-model="taskForm.taskName" placeholder="璇疯緭鍏�" clearable></el-input> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="浜嬩欢绛夌骇" prop="eventLevel"> + <el-select v-model="taskForm.eventLevel" placeholder="璇烽�夋嫨" clearvnle=""> + <el-option v-for="item in levelOptions" :key="item.dictId" :label="item.dictValue" + :value="item.dictId"></el-option> + </el-select> + </el-form-item> + </el-col> + </el-row> + + <el-row :gutter="20"> + <el-col :span="18"> + <el-form-item label="宸ヤ綔鏃堕棿" prop="workingTimes" required> + <el-select v-model="taskForm.workingTimes" placeholder="璇烽�夋嫨鎴栬缃椂闂存" multiple> + <el-option v-for="item in timeOptions" :key="item.labelId" :label="item.labelName" + :value="item.labelId"></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="6"> + <el-button type="primary" @click="handleTimeSetting" class="time-setting-btn">鏃堕棿娈佃缃�</el-button> + </el-col> + </el-row> + + + <!-- 浠诲姟鎻忚堪 --> + <el-form-item label="浠诲姟鎻忚堪" prop="taskDescription"> + <el-input type="textarea" :rows="3" v-model="taskForm.taskDescription" placeholder="璇疯緭鍏ュ唴瀹�"></el-input> + </el-form-item> + + <!-- 澶氬垪閫夋嫨 --> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="瑙嗛鐐逛綅" prop="videoIds" required> + <el-select v-model="taskForm.videoIds" placeholder="璇烽�夋嫨" multiple> + <el-option-group v-for="group in positionOptions" :key="group.label" :label="group.label" + class="custom-group-header"> + <el-option v-for="item in group.options" :key="item.videoId" :label="item.deviceName" + :value="item.videoId"></el-option> + </el-option-group> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="澶氭ā鎬佸ぇ妯″瀷" prop="modelName"> + <el-select v-model="taskForm.modelId" placeholder="璇烽�夋嫨"> + <el-option v-for="item in modelOptions" :key="item.value" :label="item.label" + :value="item.value"></el-option> + </el-select> + </el-form-item> + </el-col> + </el-row> + + <!-- 妫�娴嬪唴瀹� --> + <el-form-item label="妫�娴嬪唴瀹�" prop="checkContents" required> + <el-select v-model="taskForm.checkContents" multiple placeholder="璇烽�夋嫨"> + <el-option v-for="item in checkOptions" :key="item.checkId" :label="item.fileName" + :value="item.checkId"></el-option> + </el-select> + </el-form-item> + + <!-- 棰勮瑙勫垯 --> + <el-form-item label="棰勮瑙勫垯" prop="warningRules" required> + <el-select v-model="taskForm.warningRules" placeholder="璇烽�夋嫨" multiple> + <el-option v-for="item in ruleOptions" :key="item.ruleId" :label="item.fileName" + :value="item.ruleId"></el-option> + </el-select> + </el-form-item> + <!-- 鐭ヨ瘑搴� --> + <!-- <el-form-item label="鐭ヨ瘑搴�" prop="knows"> + <el-cascader v-model="taskForm.knowsList" :options="knowledgeOptions" :props="knowledgeProps" clearable + filterable placeholder="璇烽�夋嫨鐭ヨ瘑搴撴枃浠�" class="knowledge-cascader" :show-all-levels="false"></el-cascader> + </el-form-item> --> + </el-form> + + <span slot="footer"> + <el-button @click="dialogVisible = false">鍙栨秷</el-button> + <el-button type="primary" @click="submitTask">淇濆瓨</el-button> + </span> + </el-dialog> + + <!-- 鎼滅储鍜屾搷浣滄爮 --> + <div class="search-bar"> + <el-input v-model="searchKey" placeholder="璇疯緭鍏ヤ换鍔″悕绉�/鎽勫儚鏈哄悕绉�" clearable class="search-input"></el-input> + <el-button type="primary" @click="handleSearch">鏌ヨ</el-button> + <el-button @click="handleReset">閲嶇疆</el-button> + <!-- <el-button type="primary" class="new-btn" @click="handleCreate()"><i class="el-icon-plus"></i> 鏂板缓浠诲姟</el-button> --> + </div> + + <!-- 浠诲姟琛ㄦ牸锛堢簿纭垪瀹介厤缃級 --> + <el-table :data="tableData" style="width: 100%" class="data-table" :header-cell-style="{ + background: '#f5f7fa', + color: '#606266' + }"> + <!-- 閫夋嫨鍒� --> + <!-- <el-table-column type="selection" width="auto" min-width="5%"></el-table-column> --> + + + <!-- 浠诲姟ID --> + <el-table-column prop="id" label="浠诲姟ID" v-if="false"> + <template #default="{ row }"> + <span class="text-ellipsis">{{ row.taskId }}</span> + </template> + </el-table-column> + <!-- 浠诲姟鍚嶇О --> + <el-table-column prop="taskName" label="浠诲姟鍚嶇О" width="auto" min-width="180px"> + <template #default="{ row }"> + <span class="text-ellipsis">{{ row.taskName }}</span> + </template> + </el-table-column> + <!-- 澶氭ā鎬佸ぇ妯″瀷 --> + <!-- <el-table-column prop="modelName" label="澶氭ā鎬佸ぇ妯″瀷" width="auto" min-width="80px"> + <template #default="{ row }"> + {{ row.modelName }} + </template> + </el-table-column> --> + + <!-- 浜嬩欢绛夌骇 --> + <el-table-column prop="eventLevel" label="浜嬩欢绛夌骇" width="auto" min-width="80px"> + <template #default="{ row }"> + <!-- <span class="level level-1 text-ellipsis">{{ row.eventLevel }}</span> --> + <!-- {{ row.eventLevel }} --> + {{levelOptions.find(item => item.dictId === row.eventLevel).dictValue || ''}} + </template> + </el-table-column> + <!-- 瑙嗛鐐逛綅 --> + <el-table-column prop="deviceName" label="鎽勫儚鏈哄悕绉�" width="auto" min-width="180px"> + <template #default="{ row }"> + <div class="multi-tags"> + <!-- <span v-for="(item, index) in row.videoCamera" :key="index" class="text-ellipsis tag-item">{{ item.deviceName + }}/</span> --> + {{row.deviceName}} + </div> + </template> + </el-table-column> + <el-table-column prop="deviceName" label="RTSP" width="auto" min-width="180px"> + <template #default="{ row }"> + <div class="multi-tags"> + <!-- <span v-for="(item, index) in row.videoCamera" :key="index" class="text-ellipsis tag-item">{{ item.deviceName + }}/</span> --> + {{row.rtspAddress}} + </div> + </template> + </el-table-column> + <!-- 宸ヤ綔鏃堕棿 --> + <el-table-column prop="labelName" label="宸ヤ綔鏃堕棿" width="auto" min-width="180px"> + <template #default="{ row }"> + <div class="multi-tags"> + {{row.WorkTimeName}} + </div> + </template> + <!-- <template #default="{ row }"> + <div class="multi-tags"> + {{(row.workingTime || []).map(r => r.labelName).join('/') || ''}} + </div> + </template> --> + </el-table-column> + + <!-- 妫�鏌ラ」绫诲瀷 --> + <!-- <el-table-column prop="checkType" label="妫�鏌ラ」绫诲瀷" width="100"> + <template #default="{row}"> + <span class="text-ellipsis">{{ row.checkType }}</span> + </template> + </el-table-column> --> + <!-- 妫�娴嬪唴瀹� --> + <el-table-column label="妫�娴嬪唴瀹�" width="auto" min-width="180px"> + <template #default="{ row }"> + <div class="check-items"> + <!-- <span v-for="(item, index) in row.checkContent" :key="index" >{{ item.fileName + }}/</span> --> + {{(row.checkContent || []).map(r => r.fileName).join('/') || ''}} + </div> + </template> + </el-table-column> + <!-- 棰勮瑙勫垯 --> + <el-table-column label="棰勮瑙勫垯" width="auto" min-width="180px"> + <template #default="{ row }"> + <div class="check-items"> + <!-- <el-tag v-for="(item, index) in row.warningRule" :key="index" class="text-ellipsis check-tag">{{ item.fileName }}</el-tag> --> + {{(row.warningRule || []).map(r => r.fileName).join('/') || ''}} + </div> + </template> + </el-table-column> + + <!-- 鐭ヨ瘑搴� --> + <!-- <el-table-column label="鐭ヨ瘑搴�" width="auto" min-width="185px"> + <template #default="{ row }"> + <div class="check-items"> + {{(row.knowledge || []).map(r => r.fileName).join('/') || ''}} + </div> + </template> + </el-table-column> --> + + <!-- 鎿嶄綔 --> + <el-table-column label="鎿嶄綔" width="auto" min-width="80px"> + <template #default="{ row }"> + <div style="display: flex; gap: 8px"> + <!-- <el-button type="text" icon="el-icon-edit" @click="handleEdit(row)"></el-button> --> + <el-button type="text" icon="el-icon-view" @click="handleView(row)"></el-button> + <!-- <el-button type="text" icon="el-icon-delete" @click="handleDelete(row)"></el-button> --> + </div> + </template> + </el-table-column> + </el-table> + + <!-- 鍒嗛〉 --> + <div class="pagination"> + <el-pagination @current-change="handleCurrentChange" :page-size="10" layout="prev, pager, next" + :total="this.pagination.total"></el-pagination> + </div> + </div> +</template> + +<script> +import Inspection from "@/api/InspectionView" +export default { + data() { + return { + // 鏂板鎼滅储鍙傛暟 + searchParams: { + searchKey: '', + }, + // 鏂板鍒嗛〉鍙傛暟 + pagination: { + page: 1, + pageSize: 10, + total: 100, + totalPage: 1 + }, + // 鏂板鏃堕棿璁剧疆鐩稿叧鐘舵�� + timeDialogVisible: false, + // 鏂板鐘舵�佺鐞� + dialogType: 'create', // create/edit + viewDialogVisible: false, + currentTask: { + taskId: null, + taskName: '', + taskDescription: "", + modelId: '', + modelName: '', + eventLevel: '', + eventLevelName: '', + videoIds: [], + videoCamera: [], + workingTimes: [], + checkContents: [], + warningRules: [], + knowsList: [] + }, + //鏍¢獙瑙勫垯閰嶇疆 + formRules: { + taskName: [{ required: true, message: '浠诲姟鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' }], + workingTimes: [{ + type: 'array', + required: true, + message: '鑷冲皯閫夋嫨涓�涓椂闂存', + trigger: 'change' + }], + videoIds: [{ + type: 'array', + required: true, + message: '鑷冲皯閫夋嫨涓�涓棰戠偣', + trigger: 'change' + }], + checkContents: [{ + type: 'array', + required: true, + message: '鑷冲皯閫夋嫨涓�涓娴嬮」', + trigger: 'change' + }], + warningRules: [{ + type: 'array', + required: true, + message: '鑷冲皯閫夋嫨涓�涓璀﹁鍒�', + trigger: 'change' + }], + knowsList: [{ + type: 'array', + required: true, + message: '鑷冲皯閫夋嫨涓�涓璀﹁鍒�', + trigger: 'change' + }] + }, + dialogVisible: false, + taskForm: { + taskId: null, + taskName: '', + taskDescription: "", + modelId: '', + modelName: '', + eventLevel: '', + eventLevelName: '', + videoIds: [], + videoCamera: [], + workingTimes: [], + checkContents: [], + warningRules: [], + knowsList: [] + }, + // 涓嬫媺閫夐」鏁版嵁 + levelOptions: [//浜嬩欢绛夌骇 + { dictId: 1, dictValue: '涓�绾�' }, + { dictId: 2, dictValue: '浜岀骇' }, + { dictId: 3, dictValue: '涓夌骇' } + ], + timeOptions: [//宸ヤ綔鏃堕棿 + { labelId: '1', labelName: '宸ヤ綔鏃堕棿1' }, + { labelId: '2', labelName: '宸ヤ綔鏃堕棿2' } + ], + positionOptions: [//瑙嗛鐐逛綅 + { + label: '鏈湴鎽勫儚鏈�', + options: [ + { videoId: 1, deviceName: '鐐逛綅A' }, + { videoId: 2, deviceName: '鐐逛綅B' } + ] + }, + { + label: '鍥芥爣鎽勫儚鏈�', + options: [ + { videoId: 3, deviceName: 'GB鐐逛綅A' }, + { videoId: 4, deviceName: 'GB鐐逛綅B' } + ] + } + ], + modelOptions: [//澶фā鍨� + { value: 1, label: 'DINO' } + ], + checkOptions: [//妫�娴嬪唴瀹� + { checkId: 1, fileName: '瀹夊叏甯芥娴�' }, + { checkId: 2, fileName: '鐏劙妫�娴�' } + ], + ruleOptions: [//棰勮瑙勫垯 + { ruleId: 1, fileName: '瑙勫垯1' }, + { ruleId: 2, fileName: '瑙勫垯2' } + ], + knowledgFiles: [//棰勮瑙勫垯 + { id: 1, title: '鐭ヨ瘑搴�1' }, + { id: 2, title: '鐭ヨ瘑搴�2' } + ], + searchKey: '', + currentPage: 1, + tableData: [], + knowledgeOptions: [{ + id: 1, + title: "鐭ヨ瘑搴�1", + files: [ + { id: 11, title: "鏂囦欢1-1" }, + { id: 12, title: "鏂囦欢2-2" } + ] + }, { + id: 2, + title: "鐭ヨ瘑搴�2", + files: [ + { id: 13, title: "鏂囦欢2-1" }, + { id: 14, title: "鏂囦欢2-2" } + ] + }, { + id: 3, + title: "鐭ヨ瘑搴�3", + files: [ + { id: 15, title: "鏂囦欢3-1" }, + { id: 16, title: "鏂囦欢3-2" } + ] + },], // 绾ц仈閫夋嫨鍣ㄩ�夐」 + knowledgeProps: { + multiple: true, // 鏀寔澶氶�� + value: 'id', // 鎸囧畾閫夐」鍊煎瓧娈� + label: 'title', // 鎸囧畾閫夐」鏍囩瀛楁 + children: 'files' // 鎸囧畾瀛愰�夐」瀛楁锛堟枃浠跺垪琛級 + }, + } + }, + computed: { + // 灞曞钩鐨勭煡璇嗗簱閫夐」锛岀敤浜庤鎯呭脊绐� + flattenKnowledgeOptions() { + const flatten = [] + this.knowledgeOptions.forEach(lib => { + if (lib.files) { + lib.files.forEach(file => { + flatten.push({ + value: file.id, + label: file.title + // label: `${lib.title}/${file.title}` + }) + }) + } + }) + return flatten + } + }, + mounted() { + this.fetchTableData() // 鍒濆鍖栧姞杞芥暟鎹� + this.selectData() + }, + methods: { + + // 鑾峰彇鐭ヨ瘑搴撴爣绛撅紙鐢ㄤ簬璇︽儏寮圭獥锛� + getKnowledgeLabel(item) { + // console.info(item) + return item.label + }, + + // 鏂板鎼滅储澶勭悊鏂规硶 + handleSearch() { + this.pagination.page = 1; // 鎼滅储鏃堕噸缃埌绗竴椤� + this.fetchTableData(); + }, + // 鏂板閲嶇疆澶勭悊鏂规硶 + handleReset() { + this.searchKey = ''; + }, + // 鍒嗛〉澶勭悊 + handleCurrentChange(page) { + this.pagination.page = page + this.fetchTableData() + // console.info(this.pagination) + }, + // 鎵撳紑鏃堕棿璁剧疆寮圭獥 + handleTimeSetting() { + this.timeDialogVisible = true + }, + // 纭鏃堕棿璁剧疆 + confirmTimePeriods(periods) { + this.taskForm.workTime = periods + this.timeDialogVisible = false + }, + // 缂栬緫鎿嶄綔 + handleEdit(row) { + this.dialogType = 'edit' + this.dialogVisible = true + // 灏嗙煡璇嗗簱鏂囦欢杞崲涓虹骇鑱旈�夋嫨鍣ㄩ渶瑕佺殑鏍煎紡 [鐭ヨ瘑搴揑D, 鏂囦欢ID] 鐨勬暟缁� + // 淇鐭ヨ瘑搴撴枃浠惰浆鎹㈤�昏緫 + const convertKnowledge = row.knowledge.map(file => { + const library = this.knowledgeOptions.find(lib => + lib.files.some(f => f.id === file.id) + ) + return library ? [library.id, file.id] : null + }).filter(item => item !== null) || [] + this.taskForm = { + ...row, + videoIds: row.videoCamera ? row.videoCamera.map(camera => camera.videoId) : [], + checkContents: row.checkContent ? row.checkContent.map(check => check.checkId) : [], + warningRules: row.warningRule ? row.warningRule.map(rule => rule.ruleId) : [], + knowsList: convertKnowledge, + workingTimes: row.workingTime ? row.workingTime.map(time => time.labelId) : [], + } + // console.info(this.taskForm) + }, + // 鏂板鎿嶄綔 + handleCreate() { + this.dialogType = 'create' + this.dialogVisible = true + this.taskForm = { + taskId: 0, + taskName: '', + taskDescription: "", + modelId: 1, + modelName: '', + eventLevel: 1, + eventLevelName: '', + videoIds: [], + videoCamera: [], + workingTimes: [], + checkContents: [], + warningRules: [], + knowsList: [] + } + }, + // 鏌ョ湅璇︽儏寮圭獥 + // handleView(row) { + // this.currentTask = { + // ...row, + // videoIds: row.videoCamera?.map(camera => camera.videoId), + // checkContents: row.checkContent?.map(check => check.checkId), + // warningRules: row.warningRule?.map(rule => rule.ruleId), + // knowsList: row.knowledge ? row.knowledge.map(file => file.id) : [], + // workingTimes: row.workingTime?.map(rule => rule.labelId), + // } + // this.viewDialogVisible = true + // }, + + // 鏌ョ湅璇︽儏璺宠浆鎽勫儚鏈洪厤缃� + handleView(row) { + this.$router.push({ + name: 'camera', + params: { + tempData: { id:row.videoId ,videoType:row.videoType} // 涓存椂鏁版嵁 + } + }) + }, + + // 鍒犻櫎鎿嶄綔 + async handleDelete(row) { + this.$confirm('纭鍒犻櫎璇ヤ换鍔″悧锛�', '鎻愮ず', { + type: 'warning' + }).then(async () => { + // this.tableData = this.tableData.filter(item => item.taskName !== row.taskName) + try { + await Inspection.deleteFile({ + taskId: row.taskId + }) + // 鍒犻櫎鎴愬姛鍚庤嚜鍔ㄤ慨姝i〉鐮� + if (this.tableData.length === 1 && this.pagination.page > 1) { + this.pagination.page -= 1 + } + this.$message.success('鍒犻櫎鎴愬姛') + await this.handleReset() + await this.fetchTableData() + } catch (error) { + this.$message.error('鍒犻櫎澶辫触') + console.error('API Error:', error) + } + }).catch(() => { + + }) + }, + // 寮圭獥鎵撳紑鏃剁殑澶勭悊 + handleDialogOpen() { + this.$nextTick(() => { + this.$refs.taskForm.clearValidate() + }) + }, + // 寮圭獥鍏抽棴鏃剁殑澶勭悊 + handleDialogClose() { + this.$refs.taskForm.resetFields() + }, + //鍔犺浇涓嬫媺妗嗘暟鎹� + async selectData() { + // const knowRes = await Inspection.getKnowledges({ //鐭ヨ瘑搴� + // page: 1, + // pageSize: 999 + // }) + // this.knowledgeOptions = knowRes.data?.map(k => ({ + // id: Number(k.knowledgeId), + // title: k.title, + // files: k.files?.map(f => ({ + // id: Number(f.id), + // title: f.title + // })) + // })) + //levelOptions + const events = await Inspection.getEvelens() //浜嬩欢绛夌骇 + this.levelOptions = events.data + + const cameras = await Inspection.getCameras({})//瑙嗛鐐逛綅 + this.positionOptions = cameras.data + + const checkContent = await Inspection.getTasks({//妫�娴嬪唴瀹� + page: 1, + pageSize: 999 + }) + this.checkOptions = checkContent.data.list + // console.info(this.checkOptions) + + const warnings = await Inspection.getWarnings({//棰勮瑙勫垯 + page: 1, + pageSize: 999 + }) + this.ruleOptions = warnings.data.list + // console.info(this.ruleOptions) + + const workT = await Inspection.getTimes()//宸ヤ綔鏃堕棿 + let workArr = workT.msg + this.timeOptions = workArr.filter((item, index, self) => { + // 杩斿洖绗竴涓尮閰嶉」鐨勭储寮曪紝鐢ㄤ簬鍒ゆ柇褰撳墠椤规槸鍚︿负绗竴涓尮閰嶉」 + const firstIndex = self.findIndex((obj) => obj.labelId === item.labelId); + + // 濡傛灉褰撳墠椤规槸绗竴涓尮閰嶉」锛屽垯淇濈暀锛屽惁鍒欒繃婊ゆ帀 + return index === firstIndex; + }); + // console.info(this.timeOptions) + }, + // 鏂板鏁版嵁鑾峰彇鏂规硶 + async fetchTableData() { + try { + // 妯℃嫙鎺ュ彛璇锋眰 + const res = await Inspection.getFiles({ + page: this.pagination.page, + pageSize: this.pagination.pageSize, + searchName: this.searchKey // 娣诲姞鎼滅储鍙傛暟 + }) + // 鏇存柊鍒嗛〉鏁版嵁鍓嶅厛鏍¢獙褰撳墠椤电爜 + const totalPage = res.data.pagination.totalPage + const currentPage = this.pagination.page > totalPage + ? totalPage + : res.data.pagination.page + this.pagination = { + ...this.pagination, + page: currentPage, + total: res.data.pagination.total, + totalPage: totalPage + } + this.pagination.total = res.data.pagination.total + this.pagination.totalPage = res.data.pagination.totalPage + this.tableData = res.data.list + // this.tableData = [ + // { + // taskId: 76, + // taskName: "鍥芥爣娴嬭瘯", + // eventLevel: 1, + // taskDescription: "", + // modelId: 1, + // modelName: "DINO", + // checkContent: [ + // { + // taskId: 76, + // checkId: 95, + // fileName: "鍥芥爣娴嬭瘯0703" + // } + // ], + // warningRule: [ + // { + // taskId: 76, + // ruleId: 62, + // fileName: "鍥芥爣娴嬭瘯0703" + // } + // ], + // workingTime: [ + // { + // taskId: 76, + // labelId: "994d7c94-cd4d-4b6f-b2f6-44b533973cd4", + // labelName: "鏃堕棿娈�1" + // } + // ], + // deviceName: "鍔炲叕瀹�", + // rtspAddress: "rtsp://192.168.1.173:554/rtp/34020000002000000001_44122500041325000002?originTypeStr=rtp_push", + // knowledge: null, + // createTime: "", + // createUser: 0 + // } + // ] + } catch (error) { + this.$message.error('鏁版嵁鍔犺浇澶辫触' + error.message) + } + }, + + // 鎻愪氦鏂规硶 + async submitTask() { + try { + // 琛ㄥ崟楠岃瘉 + await this.$refs.taskForm.validate() + const formData = JSON.parse(JSON.stringify(this.taskForm)) + // console.info("knowsList:" + fileIds) + // console.info(formData) + // console.info(this.taskForm) + // 杞崲鐭ヨ瘑搴撻�夋嫨缁撴灉鍒版枃浠禝D鍒楄〃 + // const fileIds = this.taskForm.knowsList.map( + // path => { + // // 鎻愬彇鏈�鍚庝竴绾х殑鏂囦欢ID骞惰浆鎹负鏁板瓧 + // const id = path[path.length - 1]; + // return Number(id); // 鎴栬�呬娇鐢� parseInt(id) 鎴� +id + // } + // ) + // console.info(fileIds) + // 杞崲宸ヤ綔鏃堕棿鏍煎紡 + const workTimes = formData.workingTimes.map(id => { + const timeOption = this.timeOptions.find(opt => opt.labelId === id) + return { + labelId: id, + labelName: timeOption ? timeOption.labelName : '' + } + }) + if (this.dialogType === 'create') { + // 鏂板閫昏緫 + await Inspection.createFile({ + + taskName: formData.taskName, + eventLevel: formData.eventLevel, + taskDescription: formData.taskDescription, + modelId: formData.modelId, + modelName: this.modelOptions.find(item => item.value === formData.modelId).label || '', + checks: formData.checkContents, + rules: formData.warningRules, + // knows: fileIds, + videos: formData.videoIds, + workTimes: workTimes + }) + } else { + // 鏇存柊閫昏緫 + await Inspection.updateFile({ + taskId: formData.taskId, + taskName: formData.taskName, + eventLevel: formData.eventLevel, + taskDescription: formData.taskDescription, + modelId: formData.modelId, + modelName: this.modelOptions.find(item => item.value === formData.modelId).label || '', + checks: formData.checkContents, + rules: formData.warningRules, + // knows: fileIds, + videos: formData.videoIds, + workTimes: workTimes + }) + } + this.$message.success('鎿嶄綔鎴愬姛') + this.dialogVisible = false + // 鍒锋柊鍒楄〃 + await this.handleReset() + await this.fetchTableData() + + // 閲嶇疆琛ㄥ崟 + this.$refs.taskForm.resetFields() + this.currentTask = { + taskId: null, + taskName: '', + eventLevel: '', + workTime: [], + taskDescription: '', + deviceName: [], + modelName: '', + checkContents: [], + warningRules: [], + knowsList: [] + } + } catch (error) { + // 7. 閿欒绫诲瀷鍒ゆ柇 + if (error instanceof Error) { + this.$message.error('淇濆瓨澶辫触锛�' + error.message) + } else { + console.log('琛ㄥ崟楠岃瘉鏈�氳繃') + } + } + } + } +} +</script> + +<style lang="scss" scoped> +.task-container { + padding: 20px; + background: #fff; + + .search-bar { + display: flex; + gap: 10px; + margin-bottom: 20px; + + .search-input { + width: 300px; + } + + .new-btn { + margin-left: auto; + } + } + + .data-table { + ::v-deep { + + .el-table__header, + .el-table__body { + + th, + td { + border-right: 1px solid #ebeef5; + + &:last-child { + border-right: none; + } + } + } + + .el-table__row td { + padding: 12px 0; + } + + .cell { + overflow: visible !important; + } + } + + .text-ellipsis { + display: inline-block; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + vertical-align: middle; + } + + .level { + display: inline-block; + padding: 4px 12px; + border-radius: 4px; + font-size: 12px; + + &-1 { + background: #fef0f0; + color: #f56c6c; + } + } + + .check-tag { + margin: 2px; + } + + .kb-btn { + padding: 5px 10px; + } + + .multi-tags { + display: flex; + flex-wrap: nowrap; + overflow: hidden; + gap: 4px; + + .tag-item { + flex-shrink: 1; + max-width: 100px; + margin: 2px; + } + } + + .check-items { + display: flex; + flex-wrap: wrap; + max-height: 36px; + overflow: hidden; + gap: 4px; + + .check-tag { + max-width: 120px; + flex-shrink: 1; + } + } + + .kb-buttons { + display: flex; + flex-wrap: nowrap; + overflow: hidden; + gap: 4px; + + .kb-btn { + max-width: 100px; + overflow: hidden; + text-overflow: ellipsis; + padding: 5px 8px; + + span { + display: block; + overflow: hidden; + text-overflow: ellipsis; + } + } + } + } + + .pagination { + display: flex; + justify-content: flex-end; + margin-top: 20px; + } +} + +.task-dialog { + .knowledge-cascader { + width: 100%; + } + + .el-dialog__header { + border-bottom: 1px solid #ebeef5; + padding: 15px 20px; + } + + .el-dialog__title { + font-size: 16px; + color: #303133; + } + + .el-form-item { + margin-bottom: 18px; + + .el-input__inner, + .el-textarea__inner { + border-radius: 4px; + } + } + + .el-select { + width: 100%; + } + + .el-button--primary { + padding: 10px 20px; + } +} + +/* 鏌ョ湅璇︽儏寮圭獥鏍峰紡 */ +.view-dialog { + .el-dialog__header { + border-bottom: 1px solid #ebeef5; + padding: 15px 20px; + } + + .el-dialog__title { + font-size: 16px; + color: #303133; + } + + .el-form-item { + margin-bottom: 18px; + + .el-input__inner, + .el-textarea__inner { + border-radius: 4px; + } + } + + .el-select { + width: 100%; + } + + .el-button--primary { + padding: 10px 20px; + } +} + +.time-dialog { + .el-dialog__body { + padding: 20px; + } + + .time-period-component { + margin: 15px 0; + } +} + +.time-setting-btn { + margin-left: 10px; +} +</style> \ No newline at end of file diff --git a/src/pages/inspection/index/main.ts b/src/pages/inspection/index/main.ts new file mode 100644 index 0000000..bffb4d6 --- /dev/null +++ b/src/pages/inspection/index/main.ts @@ -0,0 +1,28 @@ +import Vue from 'vue'; +import App from './App.vue'; + +import ElementUI from 'element-ui'; +import 'element-ui/lib/theme-chalk/index.css'; +import "@/assets/css/element-variables.scss"; + +import VueAwesomeSwiper from "vue-awesome-swiper"; +import "swiper/dist/css/swiper.css"; +import * as VueWindow from "@hscmap/vue-window"; + +import Mixin from "./mixins"; + + +import preview from 'vue-photo-preview' +import 'vue-photo-preview/dist/skin.css' +Vue.use(preview) + +Vue.use(ElementUI) +Vue.use(VueAwesomeSwiper as any); +Vue.use(VueWindow); + +Vue.mixin(Mixin); + +new Vue({ + el: '#app', + render: h => h(App) +}) diff --git a/src/pages/inspection/index/mixins.ts b/src/pages/inspection/index/mixins.ts new file mode 100644 index 0000000..52fb92b --- /dev/null +++ b/src/pages/inspection/index/mixins.ts @@ -0,0 +1,25 @@ +import TreeDataPool from "@/Pool/TreeData"; +import DataStackPool from "@/Pool/dataStack" +import DataPool from "@/Pool/PollData" +import VideoManageData from "@/Pool/VideoManageData"; +import TaskMange from '@/Pool/TaskMange' + +/* eslint-disable */ +const onlyTreeDataPool = new TreeDataPool +const onlyDataStack = new DataStackPool +const onlyDataPool = new DataPool +const onlyVideoManageData = new VideoManageData +const onlyTaskMange = new TaskMange + +const mixin = { + data() { + return { + TreeDataPool: onlyTreeDataPool, + DataStackPool: onlyDataStack, + VideoManageData: onlyVideoManageData, + TaskMange: onlyTaskMange, + PollData: onlyDataPool + }; + }, +}; +export default mixin; \ No newline at end of file diff --git a/src/pages/testingtask/index/App.vue b/src/pages/testingtask/index/App.vue new file mode 100644 index 0000000..2be6db3 --- /dev/null +++ b/src/pages/testingtask/index/App.vue @@ -0,0 +1,33 @@ +<template> + <div class="column"> + <testing-task + :appName="app" + ></testing-task> + </div> +</template> + +<script> +import TestingTask from "../index/TestingTaskView.vue"; + +export default { + name: "inspection", + components: { + TestingTask, + }, + computed: { + app() { + }, + }, + data() { + return { + }; + }, + mounted() { + }, + methods: {}, +}; +</script> + +<style lang="scss" scoped> + +</style> diff --git a/src/pages/testingtask/index/TestingTaskView.vue b/src/pages/testingtask/index/TestingTaskView.vue new file mode 100644 index 0000000..4072d10 --- /dev/null +++ b/src/pages/testingtask/index/TestingTaskView.vue @@ -0,0 +1,727 @@ +<template> + <div> + <!-- 鏂板缓浠诲姟鎸夐挳 --> + <div class="header-container"> + <!-- <el-button type="primary" @click="openDialog('create')"> + <i class="el-icon-plus"></i> 鏂板缓妫�娴嬪唴瀹� + </el-button> --> + </div> + + <!-- 閫氱敤寮圭獥缁勪欢 --> + <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="800px" custom-class="custom-dialog" + @open="handleDialogOpen" @closed="handleDialogClose" :close-on-click-modal="false"> + <el-form label-width="100px" :disabled="isViewMode" ref="form" :rules="formRules" :model="currentFile"> + <!-- 鏂囦欢鍚嶇О杈撳叆妗� --> + <el-form-item label="鏂囦欢鍚嶇О" prop="fileName"> + <el-input v-model="currentFile.fileName" placeholder="璇疯緭鍏ユ枃浠跺悕绉�" /> + </el-form-item> + + <!-- 妫�娴嬪唴瀹规枃鏈 --> + <el-form-item label="妫�娴嬪唴瀹�" prop="checkContent" class="full-width-item full-width-item2"> + <el-input type="textarea" :rows="5" v-model="currentFile.checkContent" resize="none" + placeholder="璇疯緭鍏ユ娴嬪唴瀹癸紝浠ヨ嫳鏂囬�楀彿鍒嗛殧" @blur="dialogType === 'create' ? splitThresholds() : syncThresholds()"> + </el-input> + </el-form-item> + <!-- 鏂板鐨勬娴嬪唴瀹归槇鍊煎尯鍩� thresholdItems.length > 0--> + <el-form-item class="full-width-item" v-show="true"> + + <div class="thresholds-container" > + <div class="slider-container" style="text-align: left" @click="openThreshold=!openThreshold"> + <i class="close-btn el-icon-arrow-right" v-show="!openThreshold"></i> + <i class="close-btn el-icon-arrow-down" v-show="openThreshold"></i> + <span class="slider-label">妫�娴嬪唴瀹归槇鍊�</span> + </div> + <div style="height:300px; overflow-y:auto;" v-if="openThreshold"> + <div v-for="(item, index) in thresholdItems" :key="index" class="threshold-item"> + <div class="slider-container"> + <span class="slider-label">妫�娴嬬洰鏍囷細</span> + <span class="slider-label">{{ item.name }}</span> + <span class="slider-label">鍒嗘暟闃堝�硷細</span> + <el-slider v-model="item.threshold" :min="0" :max="100" :step="1" :show-input="true" + :show-input-controls="false" + :input-width="60" class="slider" ></el-slider> + </div> + </div> + </div> + + </div> + </el-form-item> + </el-form> + + <span slot="footer" class="dialog-footer"> + <el-button @click="dialogVisible = false">鍙� 娑�</el-button> + <el-button type="primary" @click="handleConfirm" v-if="!isViewMode"> + 纭� 瀹� + </el-button> + </span> + </el-dialog> + + <div class="file-manager-container"> + + <el-row v-if="files.length > 0" :gutter="30"> + <el-col v-for="(file, index) in files" :key="file.checkId" :span="5" class="file-col"> + <el-card :class="['file-card', { 'selected': file.selected }]" @click.native="toggleSelect(file)"> + <!-- 鏂囦欢鏍囬閮ㄥ垎 --> + <div class="file-header"> + <span class="file-index" hidden>{{ index + 1 }}</span> + <i class="el-icon-document file-icon"></i> + <div class="file-title">{{ file.fileName }}</div> + </div> + + <!-- 鏂囦欢鎻忚堪 --> + <div class="file-desc"> + {{ file.checkContent }} + </div> + + <!-- 鎿嶄綔鎸夐挳缁� --> + <div class="file-actions"> + <!-- <el-button type="text" @click.stop="handleEdit(file)"> --> + <el-button type="text" @click.stop="openDialog('edit', file)"> + <i class="el-icon-edit"></i> 缂栬緫 + </el-button>| + <el-button type="text" @click.stop="openDialog('view', file)"> + <i class="el-icon-view"></i> 鏌ョ湅 + </el-button>| + <!-- <el-button type="text" @click.stop="handleDelete(file)"> + <i class="el-icon-delete"></i> 鍒犻櫎 + </el-button> --> + </div> + </el-card> + </el-col> + </el-row> + + <!-- 鏂板绌虹姸鎬佹樉绀� --> + <el-empty v-else description="鏆傛棤妫�娴嬩换鍔�"></el-empty> + + </div> + <div class="footer-container"> + <el-pagination @current-change="handleCurrentChange" :page-size="16" layout="prev, pager, next" + :total="this.pagination.total"> + </el-pagination> + </div> + </div> + +</template> + +<script> +import FileAPI from '@/api/TestingTaskView' +export default { + data() { + return { + openThreshold:false,//闃堝�煎紑鍏� + thresholdItems: [], // 瀛樺偍鍒嗗壊鍚庣殑妫�娴嬪唴瀹瑰強鍏堕槇鍊� + // 鏂板琛ㄥ崟楠岃瘉瑙勫垯 + formRules: { + // fileName: [ + // { required: true, message: '鏂囦欢鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' } + // ], + // checkContent: [ + // { required: true, message: '妫�娴嬪唴瀹逛笉鑳戒负绌�', trigger: 'blur' } + // ] + }, + // 鏂板鍒嗛〉鍙傛暟 + pagination: { + page: 1, + pageSize: 16, + total: 0, + totalPage: 1 + }, + dialogVisible: false, + dialogType: 'create', // create/edit/view + currentFile: this.initFile(), + form: { + fileName: '', + checkContent: '', + rangeValue: 0 + }, + files: [ + + ] + } + }, + mounted() { + this.fetchFiles() + }, + computed: { + dialogTitle() { + return { + create: '娣诲姞妫�娴嬪唴瀹�', + edit: '缂栬緫妫�娴嬪唴瀹�', + view: '妫�娴嬪唴瀹硅鎯�' + }[this.dialogType] + }, + isViewMode() { + return this.dialogType === 'view' + } + }, + methods: { + // 鍒嗗壊妫�娴嬪唴瀹瑰苟鍒濆鍖栭槇鍊� + splitThresholds() { + // 鍙湪鍒涘缓妯″紡鏃舵墠瑙﹀彂鑷姩鍒嗗壊 + if (this.dialogType !== 'create') return; + + if (this.currentFile.checkContent) { + // 鍒涘缓妯″紡涓嬫墠閲嶇疆闃堝�奸」 + this.thresholdItems = []; + const items = this.currentFile.checkContent.split(',') + .map(item => item.trim()) + .filter(item => item !== ''); + + this.thresholdItems = items.map(name => ({ + name, + threshold: this.currentFile.rangeValue + })); + }else { + this.thresholdItems = []; + } + }, + // 娣诲姞鍚屾闃堝�兼柟娉� + syncThresholds() { + // 褰撳墠妫�娴嬪唴瀹归」 + const currentItems = this.currentFile.checkContent + ? this.currentFile.checkContent.split(',') + .map(item => item.trim()) + .filter(item => item !== '') + : []; + + // 淇濈暀鐜版湁闃堝�� + const newItems = []; + console.log("currentItems"+currentItems) + + // 鍚屾鐜版湁鏁版嵁 + currentItems.forEach(item => { + const exist = this.thresholdItems.find(t => t.name === item); + newItems.push({ + name: item, + // 淇濈暀鐜版湁鍊兼垨浣跨敤榛樿鍊� + threshold: exist ? exist.threshold : this.currentFile.rangeValue + }); + }); + + this.thresholdItems = newItems; + }, + // 寮圭獥鎵撳紑鏃剁殑澶勭悊 + handleDialogOpen() { + this.$nextTick(() => { + this.$refs.form.clearValidate() + }) + // console.info("thresholds:"+JSON.stringify(this.currentFile.thresholds)) + if (!this.currentFile.thresholds) { + this.splitThresholds(); + } + }, + // 寮圭獥鍏抽棴鏃剁殑澶勭悊 + handleDialogClose() { + this.$refs.form.resetFields() + this.formRules = {} + this.thresholdItems = []; + }, + // 鑾峰彇鏂囦欢鍒楄〃 + async fetchFiles() { + try { + const res = await FileAPI.getFiles({ + page: this.pagination.page, + pageSize: this.pagination.pageSize + }) + // 鏇存柊鍒嗛〉鏁版嵁鍓嶅厛鏍¢獙褰撳墠椤电爜 + const totalPage = res.data.pagination.totalPage + const currentPage = this.pagination.page > totalPage + ? totalPage + : res.data.pagination.page + this.pagination = { + ...this.pagination, + page: currentPage, + total: res.data.pagination.total, + totalPage: totalPage + } + this.files = res.data.list + this.pagination.total = res.data.pagination.total + this.pagination.totalPage = res.data.pagination.totalPage + } catch (error) { + this.$message.error('鑾峰彇鏂囦欢鍒楄〃澶辫触') + console.error('API Error:', error) + } + }, + //鍒濆鍖栨粦鍧� + formatTooltip(val) { + return val / 10; + }, + // 鍒濆鍖栨枃浠舵暟鎹� + initFile() { + return { + checkId: null, + fileName: '', + checkContent: '', + rangeValue: 80, + thresholds: {} // 瀛樺偍闃堝�煎璞� {itemName: value} + } + }, + + // 鎵撳紑寮圭獥锛堢粺涓�鍏ュ彛锛� + openDialog(type, file = null) { + if (type != 'view') { + this.formRules = { + fileName: [ + { required: true, message: '鏂囦欢鍚嶇О涓嶈兘涓虹┖', trigger: 'blur' } + ], + checkContent: [ + { required: true, message: '妫�娴嬪唴瀹逛笉鑳戒负绌�', trigger: 'blur' } + ] + } + } + // 濡傛灉鏄紪杈戞垨鏌ョ湅妯″紡锛屽垵濮嬪寲闃堝�奸」 + if (file && file.thresholds) { + this.thresholdItems = file.thresholds + this.currentFile = { ...file }; + // if (file.checkContent) { + // const items = file.checkContent.split(',') + // .map(item => item.trim()) + // .filter(item => item !== ''); + + // this.thresholdItems = items.map(name => ({ + // name, + // threshold: file.thresholds.forEach(item => { + // if(name == item.name){ + // return item.threshold + // } + // }) || file.rangeValue// * 100 + // })); + // } + } + // console.info("thresholdItems:"+JSON.stringify(this.thresholdItems)) + this.dialogType = type + this.currentFile = file ? { ...file } : this.initFile() + this.dialogVisible = true + }, + + // 寮圭獥纭 + handleConfirm() { + // 鍑嗗闃堝�兼暟鎹紙瀛樺偍涓哄璞★級 + // const thresholds = {}; + // this.thresholdItems.forEach(item => { + // thresholds[item.name] = item.threshold/100; + // }); + + // // 鏇存柊褰撳墠鏂囦欢鐨勯槇鍊兼暟鎹� + // this.currentFile.thresholds = thresholds; + + // this.thresholdItems.forEach(item => { + // item.threshold /= 100; + // }); + this.currentFile.thresholds = this.thresholdItems; + // 鎻愪氦鍓嶆墜鍔ㄨЕ鍙戞牎楠� + this.$refs.form.validate(valid => { + if (valid) { + // 鏍规嵁绫诲瀷鎵ц涓嶅悓鎿嶄綔 + const operation = { + create: this.createFile, + edit: this.updateFile + }[this.dialogType] + + operation && operation(this.currentFile) + + } + }) + + }, + + // 鍒涘缓鏂囦欢 + async createFile(file) { + try { + // 瀹為檯璋冪敤API鎺ュ彛 + await FileAPI.createFile({ + fileName: file.fileName, + checkContent: file.checkContent, + // rangeValue: file.rangeValue + thresholds: file.thresholds + }).then((rsp) => { + if (rsp && rsp.status === 200) { + + this.dialogVisible = false; + this.fetchFiles() + this.$message({ + type: "success", + message: "娣诲姞鎴愬姛" + }) + } else { + this.$message({ + type: "error", + message: rsp.msg + }) + } + }) + } catch (error) { + this.$message.error('娣诲姞澶辫触') + console.error('API Error:', error) + } + }, + + // 鏇存柊鏂囦欢 + async updateFile(file) { + try { + console.info("file:" + JSON.stringify(file)) + // 瀹為檯璋冪敤API鎺ュ彛 + await FileAPI.updateFile({ + checkId: file.checkId, + fileName: file.fileName, + checkContent: file.checkContent, + // rangeValue: file.rangeValue + thresholds: file.thresholds + }).then((rsp) => { + if (rsp && rsp.status === 200) { + + this.dialogVisible = false; + this.fetchFiles() + this.$message({ + type: "success", + message: "缂栬緫鎴愬姛" + }) + } else { + this.$message({ + type: "error", + message: rsp.msg + }) + } + }) + + } catch (error) { + this.$message.error('缂栬緫澶辫触') + console.error('API Error:', error) + } + }, + // 鍒嗛〉澶勭悊 + handleCurrentChange(page) { + this.pagination.page = page + this.fetchFiles() + // console.info(this.pagination) + }, + toggleSelect(file) { + file.selected = !file.selected + }, + async handleDelete(file) { + this.$confirm('鍗冲皢鍒犻櫎璇ユ枃浠讹紝鎵�鏈夊唴瀹瑰皢鏃犳硶鎵惧洖, 鏄惁缁х画?', '鎻愮ず', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + }).then(async () => { + try { + + await FileAPI.deleteFile({ + checkId: file.checkId + }).then((rsp) => { + if (rsp && rsp.status === 200) { + // 鍒犻櫎鎴愬姛鍚庤嚜鍔ㄤ慨姝i〉鐮� + if (this.files.length === 1 && this.pagination.page > 1) { + this.pagination.page -= 1 + } + this.fetchFiles() + this.$message({ + type: "success", + message: "鍒犻櫎鎴愬姛" + }) + } else { + this.$message({ + type: "error", + message: rsp.msg + }) + } + }) + } catch (error) { + this.$message.error('鍒犻櫎澶辫触') + console.error('API Error:', error) + } + }).catch(() => { + this.$message({ + type: 'info', + message: '宸插彇娑堝垹闄�' + }); + }); + } + } +} +</script> +<style> +.el-slider__input { + margin-right: 30px !important; /* 鍚戝彸绉诲姩杈撳叆妗� */ + width: 100px !important; /* 璋冩暣杈撳叆妗嗗搴� */ +} +</style> +<style lang="scss" scoped> + +.close-btn { + font-size: 18px; + color: #606266; +} +.custom-input { + margin-left: 10px; + width: 60px; /* 璋冩暣杈撳叆妗嗗搴� */ + +} +.slider-container { + margin-left: 10px !important; + display: flex; + align-items: center; + gap: 10px; /* 鍙�夛紝璁剧疆闂磋窛 */ +} +.slider-label { + text-align: left; + width: 100px; + white-space: nowrap; /* 绂佹鎹㈣ */ + overflow: hidden; /* 闅愯棌婧㈠嚭鍐呭 */ + text-overflow: ellipsis; /* 鏄剧ず鐪佺暐鍙� */ +} +.slider { + flex: 1; /* 璁╂粦鍧楀崰鎹墿浣欑┖闂� */ +} +/* 鏂板鎸夐挳瀹瑰櫒鏍峰紡 */ +.header-container { + text-align: right; + margin-top: 10px; + margin-right: 20px; + + +} + +.footer-container {} + +.file-manager-container { + min-height: 750px; + padding: 20px; + background: #fff; + position: relative; + /* 鏂板瀹氫綅鍩哄噯 */ + + .new-task-btn { + /* 绉婚櫎缁濆瀹氫綅 */ + position: absolute; + right: 30px; + top: 20px; + } + + .file-col { + margin-bottom: 60px; + margin-right: 60px; + width: 302px; + height: 210px; + } + + .file-card { + cursor: pointer; + transition: all 0.3s; + border: 2px solid transparent; + + // &.selected { + // border-color: #409EFF; + // } + + .file-header { + display: flex; + align-items: center; + margin-bottom: 12px; + + .file-index { + width: 24px; + height: 24px; + background: #409EFF; + color: white; + border-radius: 50%; + text-align: center; + line-height: 24px; + margin-right: 8px; + } + + .file-icon { + color: #409EFF; + font-size: 24px; + margin-right: 8px; + } + + .file-title { + font-weight: bold; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + + .file-desc { + color: #666; + font-size: 12px; + line-height: 1.5; // 鏍规嵁瀹為檯瀛椾綋澶у皬璋冩暣 + height: 3em; // 2琛� x 1.5琛岄珮 = 3em锛堟帹鑽愪娇鐢ㄧ浉瀵瑰崟浣嶏級 + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + margin-bottom: 12px; + text-align: left; + // 鏂板浠ヤ笅涓よ + word-wrap: break-word; + white-space: normal; // 鎴栦娇鐢� pre-line + + } + + .file-actions { + border-top: 1px solid #eee; + padding-top: 12px; + // text-align: right; + + .el-button { + // padding: 0 8px; + color: #666; + + i { + margin-right: 4px; + } + } + } + } +} + +/* 寮圭獥鏍峰紡 */ +:deep(.custom-dialog) { + border-radius: 8px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + width: 800px; + + .el-dialog__header { + border-bottom: 1px solid #ebeef5; + padding: 16px 20px; + + .el-dialog__title { + font-size: 16px; + color: #303133; + } + } + + .el-dialog__body { + padding: 20px 30px; + } + + .dialog-input { + width: 80%; + + .el-input__inner { + border-color: #dcdfe6; + } + } + + .dialog-textarea { + .el-textarea__inner { + font-family: 'Microsoft YaHei', sans-serif; + line-height: 1.6; + color: #606266; + border-color: #dcdfe6; + } + } + + .dialog-slider { + width: 70%; + margin-right: 20px; + flex: 1; // 婊戝潡鑷�傚簲瀹藉害 + } + + .score-value { + color: rgb(4, 8, 12); + font-weight: bold; + margin-right: 15px; + } + + .dialog-footer { + .el-button { + padding: 10px 20px; + + &--primary { + background: #409EFF; + border-color: #409EFF; + } + } + } +} + +.content-pre { + white-space: pre-wrap; + word-break: break-word; + margin: 0; + font-size: 13px; + line-height: 1.6; +} + +/* 闃堝�煎尯鍩熸牱寮� */ +.thresholds-container { + user-select: none; /* 绂佹鏂囨湰閫夋嫨 */ + border: 1px solid #DCDFE6; + border-radius: 10px; + padding: 15px; + background: #f5f7fa; +} + +.threshold-item { + padding: 10px 0; + border-bottom: 1px dashed #EBEEF5; + + &:last-child { + border-bottom: none; + } + + .param-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15px; + } + + .param-info, + .slider-info { + flex: 1; + align-items: center; + } + + .param-label { + font-size: 14px; + color: #606266; + min-width: 80px; + display: inline-block; + } + + .param-name { + font-weight: 600; + color: #303133; + } + + .slider-container { + padding-right: 20px; + + :deep(.el-slider__button) { + width: 16px; + height: 16px; + } + + :deep(.el-slider__input) { + width: 60px; + } + } +} + +/* 鍦� style 鏍囩涓坊鍔� */ + +:deep(.full-width-item .el-form-item__content) { + margin-left: 0 !important; + width: 100%; + line-height: 40px; + position: relative; + font-size: 14px; +} + +:deep .el-form-item__label { + text-align: right; + vertical-align: middle; + float: left; + font-size: 14px; + color: #606266; + line-height: 40px; + padding: 0 30px 0 0; + box-sizing: border-box; +} +</style> \ No newline at end of file diff --git a/src/pages/testingtask/index/main.ts b/src/pages/testingtask/index/main.ts new file mode 100644 index 0000000..bffb4d6 --- /dev/null +++ b/src/pages/testingtask/index/main.ts @@ -0,0 +1,28 @@ +import Vue from 'vue'; +import App from './App.vue'; + +import ElementUI from 'element-ui'; +import 'element-ui/lib/theme-chalk/index.css'; +import "@/assets/css/element-variables.scss"; + +import VueAwesomeSwiper from "vue-awesome-swiper"; +import "swiper/dist/css/swiper.css"; +import * as VueWindow from "@hscmap/vue-window"; + +import Mixin from "./mixins"; + + +import preview from 'vue-photo-preview' +import 'vue-photo-preview/dist/skin.css' +Vue.use(preview) + +Vue.use(ElementUI) +Vue.use(VueAwesomeSwiper as any); +Vue.use(VueWindow); + +Vue.mixin(Mixin); + +new Vue({ + el: '#app', + render: h => h(App) +}) diff --git a/src/pages/testingtask/index/mixins.ts b/src/pages/testingtask/index/mixins.ts new file mode 100644 index 0000000..3dd80f8 --- /dev/null +++ b/src/pages/testingtask/index/mixins.ts @@ -0,0 +1,9 @@ + + +const mixin = { + data() { + return { + }; + }, +}; +export default mixin; \ No newline at end of file -- Gitblit v1.8.0