Commit 1d73dc486d30dbc5ff4a2bd6f51bd7fb0238bda9

Authored by wuxw
1 parent c7a5a78f

继续晚上巡检功能

Showing 33 changed files with 3746 additions and 13 deletions
src/api/inspection/addInspectionPlanApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取组织树
  4 +export function listOrgTree(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/org.listOrgTree',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + if (res.code == 0) {
  13 + resolve(res.data)
  14 + } else {
  15 + reject(new Error(res.msg || '获取组织树失败'))
  16 + }
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
  22 +
  23 +// 查询员工信息
  24 +export function listStaffInfos(params) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/query.staff.infos',
  28 + method: 'get',
  29 + params
  30 + }).then(response => {
  31 + const res = response.data
  32 + if (res.code == 0) {
  33 + resolve(res)
  34 + } else {
  35 + reject(new Error(res.msg || '获取员工信息失败'))
  36 + }
  37 + }).catch(error => {
  38 + reject(error)
  39 + })
  40 + })
  41 +}
  42 +
  43 +// 获取巡检路线列表
  44 +export function listInspectionRoutes(params) {
  45 + return new Promise((resolve, reject) => {
  46 + request({
  47 + url: '/inspectionRoute.listInspectionRoutes',
  48 + method: 'get',
  49 + params
  50 + }).then(response => {
  51 + const res = response.data
  52 + resolve(res.inspectionRoutes)
  53 +
  54 + }).catch(error => {
  55 + reject(error)
  56 + })
  57 + })
  58 +}
  59 +
  60 +// 保存巡检计划
  61 +export function saveInspectionPlan(data) {
  62 + return new Promise((resolve, reject) => {
  63 + request({
  64 + url: '/inspectionPlan.saveInspectionPlan',
  65 + method: 'post',
  66 + data
  67 + }).then(response => {
  68 + const res = response.data
  69 + if (res.code == 0) {
  70 + resolve(res)
  71 + } else {
  72 + reject(new Error(res.msg || '保存巡检计划失败'))
  73 + }
  74 + }).catch(error => {
  75 + reject(error)
  76 + })
  77 + })
  78 +}
0 \ No newline at end of file 79 \ No newline at end of file
src/api/inspection/inspectionPlanApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 获取字典数据
  5 +export function getDict(dictType, state) {
  6 + return request({
  7 + url: '/dict.listDict',
  8 + method: 'get',
  9 + params: { dictType, state }
  10 + }).then(res => res.data)
  11 +}
  12 +
  13 +// 查询巡检计划列表
  14 +export function listInspectionPlans(params) {
  15 + return request({
  16 + url: '/inspectionPlan.listInspectionPlans',
  17 + method: 'get',
  18 + params: {
  19 + communityId: getCommunityId(),
  20 + ...params
  21 + }
  22 + }).then(res => res.data)
  23 +}
  24 +
  25 +// 更新巡检计划状态
  26 +export function updateInspectionPlanState(data) {
  27 + return request({
  28 + url: '/inspectionPlan.updateInspectionPlanState',
  29 + method: 'post',
  30 + data: {
  31 + communityId: getCommunityId(),
  32 + ...data
  33 + }
  34 + }).then(res => res.data)
  35 +}
  36 +
  37 +// 删除巡检计划
  38 +export function deleteInspectionPlan(data) {
  39 + return request({
  40 + url: '/inspectionPlan.deleteInspectionPlan',
  41 + method: 'post',
  42 + data: {
  43 + communityId: getCommunityId(),
  44 + ...data
  45 + }
  46 + }).then(res => res.data)
  47 +}
  48 +
  49 +// 更新巡检计划
  50 +export function updateInspectionPlan(data) {
  51 + return request({
  52 + url: '/inspectionPlan.updateInspectionPlan',
  53 + method: 'post',
  54 + data: {
  55 + communityId: getCommunityId(),
  56 + ...data
  57 + }
  58 + }).then(res => res.data)
  59 +}
  60 +
  61 +// 查询巡检路线列表
  62 +export function listInspectionRoutes(params) {
  63 + return request({
  64 + url: '/inspectionRoute.listInspectionRoutes',
  65 + method: 'get',
  66 + params: {
  67 + communityId: getCommunityId(),
  68 + ...params
  69 + }
  70 + }).then(res => res.data)
  71 +}
  72 +
  73 +// 查询巡检计划员工
  74 +export function listInspectionPlanStaffs(params) {
  75 + return request({
  76 + url: '/inspection.listInspectionPlanStaffs',
  77 + method: 'get',
  78 + params: {
  79 + communityId: getCommunityId(),
  80 + ...params
  81 + }
  82 + }).then(res => res.data)
  83 +}
  84 +
  85 +// 查询组织树
  86 +export function listOrgTree() {
  87 + return request({
  88 + url: '/org.listOrgTree',
  89 + method: 'get',
  90 + params: { communityId: getCommunityId() }
  91 + }).then(res => res.data)
  92 +}
  93 +
  94 +// 根据组织ID查询员工
  95 +export function listStaffsByOrgId(params) {
  96 + return request({
  97 + url: '/query.staff.infos',
  98 + method: 'get',
  99 + params: {
  100 + communityId: getCommunityId(),
  101 + ...params
  102 + }
  103 + }).then(res => res.data)
  104 +}
0 \ No newline at end of file 105 \ No newline at end of file
src/api/inspection/inspectionTaskApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 获取巡检计划列表
  5 +export function listInspectionPlans() {
  6 + return new Promise((resolve, reject) => {
  7 + const communityId = getCommunityId()
  8 + request({
  9 + url: '/inspectionPlan.listInspectionPlans',
  10 + method: 'get',
  11 + params: {
  12 + page: 1,
  13 + row: 1000,
  14 + communityId
  15 + }
  16 + }).then(response => {
  17 + const res = response.data
  18 +
  19 + resolve(res)
  20 + }).catch(error => {
  21 + reject(error)
  22 + })
  23 + })
  24 +}
  25 +
  26 +// 获取巡检任务列表
  27 +export function listInspectionTasks(params) {
  28 + return new Promise((resolve, reject) => {
  29 + const communityId = getCommunityId()
  30 + request({
  31 + url: '/inspectionTask.listInspectionTasks',
  32 + method: 'get',
  33 + params: {
  34 + ...params,
  35 + communityId
  36 + }
  37 + }).then(response => {
  38 + const res = response.data
  39 +
  40 + resolve(res)
  41 + }).catch(error => {
  42 + reject(error)
  43 + })
  44 + })
  45 +}
  46 +
  47 +// 获取巡检任务详情
  48 +export function listInspectionTaskDetails(params) {
  49 + return new Promise((resolve, reject) => {
  50 + const communityId = getCommunityId()
  51 + request({
  52 + url: '/inspectionTaskDetail.listInspectionTaskDetails',
  53 + method: 'get',
  54 + params: {
  55 + ...params,
  56 + communityId
  57 + }
  58 + }).then(response => {
  59 + const res = response.data
  60 +
  61 + resolve(res)
  62 + }).catch(error => {
  63 + reject(error)
  64 + })
  65 + })
  66 +}
  67 +
  68 +// 更新巡检任务(流转)
  69 +export function updateInspectionTask(data) {
  70 + return new Promise((resolve, reject) => {
  71 + const communityId = getCommunityId()
  72 + request({
  73 + url: '/inspectionTask.updateInspectionTask',
  74 + method: 'post',
  75 + data: {
  76 + ...data,
  77 + communityId
  78 + }
  79 + }).then(response => {
  80 + const res = response.data
  81 + if (res.code === 0) {
  82 + resolve(res)
  83 + } else {
  84 + reject(new Error(res.msg || '更新巡检任务失败'))
  85 + }
  86 + }).catch(error => {
  87 + reject(error)
  88 + })
  89 + })
  90 +}
  91 +
  92 +// 删除巡检任务
  93 +export function deleteInspectionTask(data) {
  94 + return new Promise((resolve, reject) => {
  95 + const communityId = getCommunityId()
  96 + request({
  97 + url: '/inspectionTask.deleteInspectionTask',
  98 + method: 'post',
  99 + data: {
  100 + ...data,
  101 + communityId
  102 + }
  103 + }).then(response => {
  104 + const res = response.data
  105 + if (res.code === 0) {
  106 + resolve(res)
  107 + } else {
  108 + reject(new Error(res.msg || '删除巡检任务失败'))
  109 + }
  110 + }).catch(error => {
  111 + reject(error)
  112 + })
  113 + })
  114 +}
  115 +
  116 +// 获取字典数据
  117 +export function getDict(dictType, dictCd) {
  118 + return new Promise((resolve, reject) => {
  119 + request({
  120 + url: '/dict.getDict',
  121 + method: 'get',
  122 + params: {
  123 + dictType,
  124 + dictCd
  125 + }
  126 + }).then(response => {
  127 + const res = response.data
  128 + if (res.code === 0) {
  129 + resolve(res.data)
  130 + } else {
  131 + reject(new Error(res.msg || '获取字典数据失败'))
  132 + }
  133 + }).catch(error => {
  134 + reject(error)
  135 + })
  136 + })
  137 +}
0 \ No newline at end of file 138 \ No newline at end of file
src/api/inspection/inspectionTaskDetailsApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取巡检任务明细列表
  4 +export function listInspectionTaskDetails(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/inspectionTaskDetail.listInspectionTaskDetails',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + if (res.code === 0) {
  13 + resolve(res)
  14 + } else {
  15 + reject(new Error(res.msg || '获取巡检任务明细列表失败'))
  16 + }
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
  22 +
  23 +// 导出巡检任务明细
  24 +export function exportInspectionTaskDetails(params) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/export.exportData',
  28 + method: 'get',
  29 + params
  30 + }).then(response => {
  31 + const res = response.data
  32 + if (res.code === 0) {
  33 + resolve(res)
  34 + } else {
  35 + reject(new Error(res.msg || '导出失败'))
  36 + }
  37 + }).catch(error => {
  38 + reject(error)
  39 + })
  40 + })
  41 +}
  42 +
  43 +// 获取巡检计划列表
  44 +export function listInspectionPlans(params) {
  45 + return new Promise((resolve, reject) => {
  46 + request({
  47 + url: '/inspectionPlan.listInspectionPlans',
  48 + method: 'get',
  49 + params
  50 + }).then(response => {
  51 + const res = response.data
  52 + if (res.code === 0) {
  53 + resolve(res)
  54 + } else {
  55 + reject(new Error(res.msg || '获取巡检计划列表失败'))
  56 + }
  57 + }).catch(error => {
  58 + reject(error)
  59 + })
  60 + })
  61 +}
  62 +
  63 +// 获取巡检路线列表
  64 +export function listInspectionRoutes(params) {
  65 + return new Promise((resolve, reject) => {
  66 + request({
  67 + url: '/inspectionRoute.listInspectionRoutes',
  68 + method: 'get',
  69 + params
  70 + }).then(response => {
  71 + const res = response.data
  72 + if (res.code === 0) {
  73 + resolve(res)
  74 + } else {
  75 + reject(new Error(res.msg || '获取巡检路线列表失败'))
  76 + }
  77 + }).catch(error => {
  78 + reject(error)
  79 + })
  80 + })
  81 +}
  82 +
  83 +// 获取巡检点列表
  84 +export function listInspectionPoints(params) {
  85 + return new Promise((resolve, reject) => {
  86 + request({
  87 + url: '/inspectionPoint.listInspectionPoints',
  88 + method: 'get',
  89 + params
  90 + }).then(response => {
  91 + const res = response.data
  92 + if (res.code === 0) {
  93 + resolve(res)
  94 + } else {
  95 + reject(new Error(res.msg || '获取巡检点列表失败'))
  96 + }
  97 + }).catch(error => {
  98 + reject(error)
  99 + })
  100 + })
  101 +}
0 \ No newline at end of file 102 \ No newline at end of file
src/api/inspection/pointPlanApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +export function queryPointInspectionPlan(params) {
  4 + return new Promise((resolve, reject) => {
  5 + request({
  6 + url: '/inspection.queryPointInspectionPlan',
  7 + method: 'get',
  8 + params
  9 + }).then(response => {
  10 + const res = response.data
  11 + if (res.code === 0) {
  12 + resolve(res)
  13 + } else {
  14 + reject(new Error(res.msg || '获取巡检点计划失败'))
  15 + }
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
0 \ No newline at end of file 21 \ No newline at end of file
src/api/staff/staffApi.js
@@ -10,11 +10,7 @@ export function queryStaffInfos(params) { @@ -10,11 +10,7 @@ export function queryStaffInfos(params) {
10 params 10 params
11 }).then(response => { 11 }).then(response => {
12 const res = response.data 12 const res = response.data
13 - if (res.code === 0) {  
14 resolve(res) 13 resolve(res)
15 - } else {  
16 - reject(new Error(res.msg || '获取员工列表失败'))  
17 - }  
18 }).catch(error => { 14 }).catch(error => {
19 reject(error) 15 reject(error)
20 }) 16 })
src/components/inspection/DeleteInspectionTask.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('deleteInspectionTask.confirmOperation')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + >
  7 + <div style="text-align: center;">
  8 + <p>{{ $t('deleteInspectionTask.confirmDelete') }}</p>
  9 + </div>
  10 +
  11 + <div slot="footer" class="dialog-footer">
  12 + <el-button @click="visible = false">{{ $t('deleteInspectionTask.mistake') }}</el-button>
  13 + <el-button type="danger" @click="handleConfirm">{{ $t('deleteInspectionTask.confirmDeleteBtn') }}</el-button>
  14 + </div>
  15 + </el-dialog>
  16 +</template>
  17 +
  18 +<script>
  19 +import { deleteInspectionTask } from '@/api/inspection/inspectionTaskApi'
  20 +
  21 +export default {
  22 + name: 'DeleteInspectionTask',
  23 + data() {
  24 + return {
  25 + visible: false,
  26 + taskId: ''
  27 + }
  28 + },
  29 + methods: {
  30 + open(task) {
  31 + this.taskId = task.taskId
  32 + this.visible = true
  33 + },
  34 + close() {
  35 + this.taskId = ''
  36 + this.visible = false
  37 + },
  38 + async handleConfirm() {
  39 + try {
  40 + await deleteInspectionTask({ taskId: this.taskId })
  41 + this.$message.success(this.$t('common.deleteSuccess'))
  42 + this.visible = false
  43 + this.$emit('success')
  44 + } catch (error) {
  45 + console.error('删除任务失败:', error)
  46 + this.$message.error(error.message || this.$t('common.deleteFail'))
  47 + }
  48 + }
  49 + }
  50 +}
  51 +</script>
0 \ No newline at end of file 52 \ No newline at end of file
src/components/inspection/InspectionTaskDetail.vue 0 → 100644
  1 +<template>
  2 + <el-dialog :title="$t('inspectionTaskDetail.taskDetails')" :visible.sync="visible" width="90%" top="5vh" @close="close">
  3 + <el-card>
  4 + <el-table :data="taskDetails" border style="width: 100%">
  5 + <el-table-column prop="taskDetailId" :label="$t('inspectionTaskDetail.taskDetails') + 'ID'" align="center"
  6 + width="100" />
  7 + <el-table-column prop="inspectionName" :label="$t('inspectionTaskDetail.inspectionPoint')" align="center" />
  8 + <el-table-column prop="stateName" :label="$t('inspectionTaskDetail.inspectionStatus')" align="center" />
  9 + <el-table-column :label="$t('inspectionTaskDetail.signStatus')" align="center">
  10 + <template slot-scope="{row}">
  11 + <span v-if="row.inspectionState === '60000'" class="text-primary">
  12 + {{ row.inspectionStateName || '-' }}
  13 + </span>
  14 + <span v-else class="text-danger font-bold">
  15 + {{ row.inspectionStateName || '-' }}
  16 + </span>
  17 + </template>
  18 + </el-table-column>
  19 + <el-table-column :label="$t('inspectionTaskDetail.inspectorTime')" align="center">
  20 + <template slot-scope="{row}">
  21 + {{ row.planInsTime }}<br>{{ row.planEndTime }}
  22 + </template>
  23 + </el-table-column>
  24 + <el-table-column :label="$t('inspectionTaskDetail.pointTime')" align="center">
  25 + <template slot-scope="{row}">
  26 + {{ row.pointStartTime }}<br>{{ row.pointEndTime }}
  27 + </template>
  28 + </el-table-column>
  29 + <el-table-column :label="$t('inspectionTaskDetail.actualTime')" align="center">
  30 + <template slot-scope="{row}">
  31 + {{ row.inspectionTime || '-' }}
  32 + </template>
  33 + </el-table-column>
  34 + <el-table-column :label="$t('inspectionTaskDetail.inspectionSituation')" align="center">
  35 + <template slot-scope="{row}">
  36 + {{ row.description || '-' }}
  37 + </template>
  38 + </el-table-column>
  39 + <el-table-column :label="$t('inspectionTaskDetail.inspectionPhotos')" align="center">
  40 + <template slot-scope="{row}">
  41 + <span v-for="photo in row.photos" :key="photo.url" class="photo-item">
  42 + <el-image style="width: 60px; height: 60px; margin-right: 5px;" :src="photo.url"
  43 + :preview-src-list="[photo.url]" fit="cover" />
  44 + </span>
  45 + </template>
  46 + </el-table-column>
  47 + <el-table-column :label="$t('inspectionTaskDetail.locationInfo')" align="center" width="120">
  48 + <template slot-scope="{row}">
  49 + <el-button type="info" size="mini" @click="openMap(row.latitude, row.longitude)">
  50 + {{ $t('inspectionTaskDetail.view') }}
  51 + </el-button>
  52 + </template>
  53 + </el-table-column>
  54 + </el-table>
  55 +
  56 + <el-pagination :current-page="currentPage" :page-size="pageSize" :total="total"
  57 + layout="total, prev, pager, next, jumper" @current-change="handlePageChange" />
  58 + </el-card>
  59 +
  60 + <ViewMap ref="viewMap" />
  61 + <ViewImage ref="viewImage" />
  62 + </el-dialog>
  63 +</template>
  64 +
  65 +<script>
  66 +import ViewMap from '@/components/system/ViewMap'
  67 +import ViewImage from '@/components/system/viewImage'
  68 +import { listInspectionTaskDetails } from '@/api/inspection/inspectionTaskApi'
  69 +
  70 +export default {
  71 + name: 'InspectionTaskDetail',
  72 + components: { ViewMap, ViewImage },
  73 + data() {
  74 + return {
  75 + visible: false,
  76 + taskDetails: [],
  77 + taskId: '',
  78 + currentPage: 1,
  79 + pageSize: 10,
  80 + total: 0
  81 + }
  82 + },
  83 + methods: {
  84 + open(task) {
  85 + this.taskId = task.taskId
  86 + this.visible = true
  87 + this.loadTaskDetails()
  88 + },
  89 + close() {
  90 + this.taskDetails = []
  91 + this.taskId = ''
  92 + this.currentPage = 1
  93 + this.total = 0
  94 + },
  95 + async loadTaskDetails() {
  96 + try {
  97 + const res = await listInspectionTaskDetails({
  98 + page: this.currentPage,
  99 + row: this.pageSize,
  100 + taskId: this.taskId
  101 + })
  102 + this.taskDetails = res.inspectionTaskDetails || []
  103 + this.total = res.records || 0
  104 + } catch (error) {
  105 + console.error('加载任务详情失败:', error)
  106 + this.$message.error('加载任务详情失败')
  107 + }
  108 + },
  109 + handlePageChange(page) {
  110 + this.currentPage = page
  111 + this.loadTaskDetails()
  112 + },
  113 + openMap(lat, lng) {
  114 + if (!lat || !lng) {
  115 + this.$message.warning(this.$t('inspectionTaskDetail.noLocation'))
  116 + return
  117 + }
  118 + this.$refs.viewMap.open({ lat, lng })
  119 + }
  120 + }
  121 +}
  122 +</script>
  123 +
  124 +<style scoped>
  125 +.photo-item {
  126 + display: inline-block;
  127 + margin-right: 5px;
  128 +}
  129 +
  130 +.text-primary {
  131 + color: #409EFF;
  132 +}
  133 +
  134 +.text-danger {
  135 + color: #F56C6C;
  136 +}
  137 +
  138 +.font-bold {
  139 + font-weight: bold;
  140 +}
  141 +</style>
0 \ No newline at end of file 142 \ No newline at end of file
src/components/inspection/InspectionTaskTransfer.vue 0 → 100644
  1 +<template>
  2 + <el-dialog :title="$t('inspectionTaskTransfer.transfer')" :visible.sync="visible" width="50%" top="5vh">
  3 + <el-form ref="form" :model="form" label-width="120px">
  4 + <el-form-item :label="$t('inspectionTaskTransfer.transferObject')" required>
  5 + <el-select v-model="form.staffId" :placeholder="$t('inspectionTaskTransfer.required')">
  6 + <el-option v-for="item in staffs" :key="item.userId" :label="item.name" :value="item.userId"></el-option>
  7 + </el-select>
  8 + </el-form-item>
  9 +
  10 + <el-form-item :label="$t('inspectionTaskTransfer.transferDesc')" required>
  11 + <el-input v-model="form.transferDesc" type="textarea" :rows="4"
  12 + :placeholder="$t('inspectionTaskTransfer.required')"></el-input>
  13 + </el-form-item>
  14 + </el-form>
  15 +
  16 + <div slot="footer" class="dialog-footer">
  17 + <el-button @click="visible = false">{{ $t('inspectionTaskTransfer.cancel') }}</el-button>
  18 + <el-button type="primary" @click="handleSubmit">{{ $t('inspectionTaskTransfer.submit') }}</el-button>
  19 + </div>
  20 + </el-dialog>
  21 +</template>
  22 +
  23 +<script>
  24 +import { updateInspectionTask } from '@/api/inspection/inspectionTaskApi'
  25 +import { queryStaffInfos } from '@/api/staff/staffApi.js'
  26 +
  27 +export default {
  28 + name: 'InspectionTaskTransfer',
  29 + components: {},
  30 + data() {
  31 + return {
  32 + visible: false,
  33 + staffs: [],
  34 + form: {
  35 + taskId: '',
  36 + staffId: '',
  37 + staffName: '',
  38 + transferDesc: '',
  39 + currentUserId: '',
  40 + inspectionPlanId:''
  41 + }
  42 + }
  43 + },
  44 + methods: {
  45 + open(task) {
  46 + this.form = {
  47 + taskId: task.taskId,
  48 + staffId: '',
  49 + staffName: '',
  50 + transferDesc: '',
  51 + currentUserId: '',
  52 + inspectionPlanId:task.inspectionPlanId
  53 + }
  54 + this.loadStaffs()
  55 + this.visible = true
  56 + },
  57 + async loadStaffs() {
  58 + const { staffs } = await queryStaffInfos({
  59 + page: 1,
  60 + row: 1000
  61 + })
  62 + this.staffs = staffs
  63 + },
  64 + handleSwitchOrg(org) {
  65 + this.$refs.staffSelect.setOrg(org)
  66 + },
  67 + handleStaffChange(staff) {
  68 + this.form.staffId = staff.staffId
  69 + this.form.staffName = staff.staffName
  70 + },
  71 + async handleSubmit() {
  72 + if (!this.form.staffId) {
  73 + this.$message.warning(this.$t('inspectionTaskTransfer.chooseStaff'))
  74 + return
  75 + }
  76 +
  77 + if (!this.form.transferDesc) {
  78 + this.$message.warning(this.$t('inspectionTaskTransfer.inputDesc'))
  79 + return
  80 + }
  81 +
  82 + if (this.form.staffId === this.form.currentUserId) {
  83 + this.$message.warning(this.$t('inspectionTaskTransfer.cantTransferSelf'))
  84 + return
  85 + }
  86 +
  87 + try {
  88 + await updateInspectionTask(this.form)
  89 + this.$message.success(this.$t('common.operateSuccess'))
  90 + this.visible = false
  91 + this.$emit('success')
  92 + } catch (error) {
  93 + console.error('任务流转失败:', error)
  94 + this.$message.error(error.message || this.$t('common.operateFail'))
  95 + }
  96 + }
  97 + }
  98 +}
  99 +</script>
0 \ No newline at end of file 100 \ No newline at end of file
src/components/inspection/deleteInspectionPlan.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('inspectionPlan.confirmDeleteTitle')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + >
  7 + <div class="text-center">
  8 + <p>{{ $t('inspectionPlan.confirmDeleteContent') }}</p>
  9 + </div>
  10 + <div slot="footer">
  11 + <el-button @click="visible = false">{{ $t('inspectionPlan.cancel') }}</el-button>
  12 + <el-button type="danger" @click="confirmDelete">{{ $t('inspectionPlan.confirm') }}</el-button>
  13 + </div>
  14 + </el-dialog>
  15 +</template>
  16 +
  17 +<script>
  18 +import { deleteInspectionPlan } from '@/api/inspection/inspectionPlanApi'
  19 +
  20 +export default {
  21 + name: 'DeleteInspectionPlan',
  22 + data() {
  23 + return {
  24 + visible: false,
  25 + currentPlanId: null
  26 + }
  27 + },
  28 + methods: {
  29 + open(plan) {
  30 + this.currentPlanId = plan.inspectionPlanId
  31 + this.visible = true
  32 + },
  33 +
  34 + async confirmDelete() {
  35 + try {
  36 + await deleteInspectionPlan({ inspectionPlanId: this.currentPlanId })
  37 + this.$message.success(this.$t('inspectionPlan.deleteSuccess'))
  38 + this.visible = false
  39 + this.$emit('success')
  40 + } catch (error) {
  41 + this.$message.error(this.$t('inspectionPlan.deleteError'))
  42 + }
  43 + }
  44 + }
  45 +}
  46 +</script>
  47 +
  48 +<style scoped>
  49 +.text-center {
  50 + text-align: center;
  51 +}
  52 +</style>
0 \ No newline at end of file 53 \ No newline at end of file
src/components/inspection/deleteInspectionPoint.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('deleteInspectionPoint.title')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + @close="handleClose"
  7 + >
  8 + <p>{{ $t('deleteInspectionPoint.confirmText') }}</p>
  9 + <span slot="footer" class="dialog-footer">
  10 + <el-button @click="visible = false">{{ $t('deleteInspectionPoint.cancel') }}</el-button>
  11 + <el-button type="primary" @click="handleConfirm">{{ $t('deleteInspectionPoint.confirm') }}</el-button>
  12 + </span>
  13 + </el-dialog>
  14 +</template>
  15 +
  16 +<script>
  17 +import { deleteInspectionPoint } from '@/api/inspection/deleteInspectionPointApi'
  18 +import { getCommunityId } from '@/api/community/communityApi'
  19 +
  20 +export default {
  21 + name: 'DeleteInspectionPoint',
  22 + data() {
  23 + return {
  24 + visible: false,
  25 + inspectionPointId: ''
  26 + }
  27 + },
  28 + methods: {
  29 + open(inspectionPointId) {
  30 + this.inspectionPointId = inspectionPointId
  31 + this.visible = true
  32 + },
  33 +
  34 + handleClose() {
  35 + this.inspectionPointId = ''
  36 + },
  37 +
  38 + async handleConfirm() {
  39 + try {
  40 + await deleteInspectionPoint({
  41 + inspectionId: this.inspectionPointId,
  42 + communityId: getCommunityId()
  43 + })
  44 + this.$message.success(this.$t('common.deleteSuccess'))
  45 + this.visible = false
  46 + this.$emit('deleted')
  47 + } catch (error) {
  48 + console.error('删除巡检点失败:', error)
  49 + this.$message.error(error.message || this.$t('common.deleteFailed'))
  50 + }
  51 + }
  52 + }
  53 +}
  54 +</script>
0 \ No newline at end of file 55 \ No newline at end of file
src/components/inspection/editInspectionPlan.vue 0 → 100644
  1 +<template>
  2 + <el-dialog :title="$t('inspectionPlan.modify')" :visible.sync="visible" width="80%" @close="resetForm">
  3 + <el-form ref="form" :model="formData" label-width="150px">
  4 + <el-row :gutter="20">
  5 + <el-col :span="12">
  6 + <el-form-item :label="$t('inspectionPlan.planName')" prop="inspectionPlanName" required>
  7 + <el-input v-model="formData.inspectionPlanName" />
  8 + </el-form-item>
  9 + </el-col>
  10 + <el-col :span="12">
  11 + <el-form-item :label="$t('inspectionPlan.planRoute')" prop="inspectionRouteId" required>
  12 + <el-select v-model="formData.inspectionRouteId" style="width:100%" @change="handleRouteChange">
  13 + <el-option v-for="route in routeOptions" :key="route.inspectionRouteId" :label="route.routeName"
  14 + :value="route.inspectionRouteId" />
  15 + </el-select>
  16 + </el-form-item>
  17 + </el-col>
  18 + </el-row>
  19 +
  20 + <el-row :gutter="20">
  21 + <el-col :span="12">
  22 + <el-form-item :label="$t('inspectionPlan.planCycle')" prop="inspectionPlanPeriod" required>
  23 + <el-select v-model="formData.inspectionPlanPeriod" style="width:100%" @change="handlePeriodChange">
  24 + <el-option label="月/天" value="2020022" />
  25 + <el-option label="按周" value="2020023" />
  26 + </el-select>
  27 + </el-form-item>
  28 + </el-col>
  29 + <el-col :span="12">
  30 + <el-form-item :label="$t('inspectionPlan.taskAdvance')">
  31 + <el-input-number v-model="formData.beforeTime" :min="1" />
  32 + <span class="margin-left">{{ $t('editInspectionPlan.minutesGenerate') }}</span>
  33 + </el-form-item>
  34 + </el-col>
  35 + </el-row>
  36 +
  37 + <!-- 月/天选择 -->
  38 + <template v-if="formData.inspectionPlanPeriod === '2020022'">
  39 + <el-row>
  40 + <el-form-item :label="$t('editInspectionPlan.month')">
  41 + <el-checkbox-group v-model="formData.months">
  42 + <el-checkbox v-for="month in 12" :key="month" :label="month">
  43 + {{ month }}{{ $t('editInspectionPlan.month') }}
  44 + </el-checkbox>
  45 + </el-checkbox-group>
  46 + </el-form-item>
  47 + </el-row>
  48 +
  49 + <el-row>
  50 + <el-form-item :label="$t('editInspectionPlan.day')">
  51 + <el-checkbox-group v-model="formData.days">
  52 + <el-checkbox v-for="day in 31" :key="day" :label="day">
  53 + {{ day }}{{ $t('editInspectionPlan.day') }}
  54 + </el-checkbox>
  55 + </el-checkbox-group>
  56 + </el-form-item>
  57 + </el-row>
  58 + </template>
  59 +
  60 + <!-- 按周选择 -->
  61 + <template v-if="formData.inspectionPlanPeriod === '2020023'">
  62 + <el-row>
  63 + <el-form-item :label="$t('editInspectionPlan.week')">
  64 + <el-checkbox-group v-model="formData.workdays">
  65 + <el-checkbox v-for="(day, index) in weekDays" :key="index" :label="index + 1">
  66 + {{ day }}
  67 + </el-checkbox>
  68 + </el-checkbox-group>
  69 + </el-form-item>
  70 + </el-row>
  71 + </template>
  72 +
  73 + <el-row :gutter="20">
  74 + <el-col :span="12">
  75 + <el-form-item :label="$t('editInspectionPlan.startDate')" required>
  76 + <el-date-picker v-model="formData.startDate" type="date" value-format="yyyy-MM-dd" style="width:100%" />
  77 + </el-form-item>
  78 + </el-col>
  79 + <el-col :span="12">
  80 + <el-form-item :label="$t('editInspectionPlan.endDate')" required>
  81 + <el-date-picker v-model="formData.endDate" type="date" value-format="yyyy-MM-dd" style="width:100%" />
  82 + </el-form-item>
  83 + </el-col>
  84 + </el-row>
  85 +
  86 + <el-row :gutter="20">
  87 + <el-col :span="12">
  88 + <el-form-item :label="$t('editInspectionPlan.startTime')" required>
  89 + <el-time-picker v-model="formData.startTime" value-format="HH:mm" style="width:100%" />
  90 + </el-form-item>
  91 + </el-col>
  92 + <el-col :span="12">
  93 + <el-form-item :label="$t('editInspectionPlan.endTime')" required>
  94 + <el-time-picker v-model="formData.endTime" value-format="HH:mm" style="width:100%" />
  95 + </el-form-item>
  96 + </el-col>
  97 + </el-row>
  98 +
  99 + <el-row :gutter="20">
  100 + <el-col :span="12">
  101 + <el-form-item :label="$t('editInspectionPlan.signMethod')" required>
  102 + <el-select v-model="formData.signType" style="width:100%">
  103 + <el-option v-for="sign in signTypeOptions" :key="sign.statusCd" :label="sign.name" :value="sign.statusCd" />
  104 + </el-select>
  105 + </el-form-item>
  106 + </el-col>
  107 + <el-col :span="12">
  108 + <el-form-item :label="$t('editInspectionPlan.allowRecheck')">
  109 + <el-select v-model="formData.canReexamine" style="width:100%">
  110 + <el-option :label="$t('inspectionPlan.disallowRecheck')" value="1000" />
  111 + <el-option :label="$t('inspectionPlan.allowRecheck')" value="2000" />
  112 + </el-select>
  113 + </el-form-item>
  114 + </el-col>
  115 + </el-row>
  116 +
  117 + <el-row>
  118 + <el-form-item :label="$t('editInspectionPlan.selectStaff')">
  119 + <select-staff-div ref="selectStaffDiv" @selectStaffs="handleSelectStaffs" />
  120 + </el-form-item>
  121 + </el-row>
  122 + </el-form>
  123 +
  124 + <div slot="footer">
  125 + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button>
  126 + <el-button type="primary" @click="savePlan">{{ $t('common.save') }}</el-button>
  127 + </div>
  128 + </el-dialog>
  129 +</template>
  130 +
  131 +<script>
  132 +import { updateInspectionPlan, listInspectionRoutes, listInspectionPlanStaffs } from '@/api/inspection/inspectionPlanApi'
  133 +import SelectStaffDiv from '@/components/staff/selectStaffsDiv'
  134 +import {getDict} from '@/api/community/communityApi'
  135 +
  136 +export default {
  137 + name: 'EditInspectionPlan',
  138 + components: {
  139 + SelectStaffDiv
  140 + },
  141 + data() {
  142 + return {
  143 + visible: false,
  144 + formData: {
  145 + inspectionPlanId: '',
  146 + inspectionPlanName: '',
  147 + inspectionRouteId: '',
  148 + inspectionPlanPeriod: '',
  149 + startDate: '',
  150 + endDate: '',
  151 + beforeTime: 30,
  152 + startTime: '',
  153 + endTime: '',
  154 + signType: '',
  155 + canReexamine: '1000',
  156 + months: [],
  157 + days: [],
  158 + workdays: [],
  159 + staffs: []
  160 + },
  161 + routeOptions: [],
  162 + signTypeOptions: [],
  163 + weekDays: [
  164 + this.$t('inspectionPlan.monday'),
  165 + this.$t('inspectionPlan.tuesday'),
  166 + this.$t('inspectionPlan.wednesday'),
  167 + this.$t('inspectionPlan.thursday'),
  168 + this.$t('inspectionPlan.friday'),
  169 + this.$t('inspectionPlan.saturday'),
  170 + this.$t('inspectionPlan.sunday')
  171 + ]
  172 + }
  173 + },
  174 + async created() {
  175 + await this.loadDictData()
  176 + this.loadRoutes()
  177 + },
  178 + methods: {
  179 + async loadDictData() {
  180 + try {
  181 + this.signTypeOptions = await getDict('inspection_plan', 'sign_type')
  182 + } catch (error) {
  183 + console.error('Failed to load sign types:', error)
  184 + }
  185 + },
  186 +
  187 + async loadRoutes() {
  188 + try {
  189 + const { data } = await listInspectionRoutes({
  190 + page: 1,
  191 + row: 100
  192 + })
  193 + this.routeOptions = data
  194 + } catch (error) {
  195 + console.error('Failed to load routes:', error)
  196 + }
  197 + },
  198 +
  199 + open(plan) {
  200 + this.formData = {
  201 + ...this.formData,
  202 + ...plan,
  203 + months: plan.inspectionMonth ? plan.inspectionMonth.split(',').map(Number) : [],
  204 + days: plan.inspectionDay ? plan.inspectionDay.split(',').map(Number) : [],
  205 + workdays: plan.inspectionWorkday ? plan.inspectionWorkday.split(',').map(Number) : []
  206 + }
  207 + this.loadStaffs(plan.inspectionPlanId)
  208 + this.visible = true
  209 + },
  210 +
  211 + async loadStaffs(planId) {
  212 + try {
  213 + const { inspectionPlanStaffs } = await listInspectionPlanStaffs({ inspectionPlanId: planId,page: 1, row: 100 })
  214 + this.formData.staffs = inspectionPlanStaffs.map(item => ({
  215 + userId: item.staffId,
  216 + name: item.staffName
  217 + }))
  218 + this.$refs.selectStaffDiv.setStaffs(this.formData.staffs)
  219 + } catch (error) {
  220 + console.error('Failed to load staffs:', error)
  221 + }
  222 + },
  223 +
  224 + handleSelectStaffs(staffs) {
  225 + this.formData.staffs = staffs
  226 + },
  227 +
  228 + handleRouteChange() {
  229 + // 处理路线变更逻辑
  230 + },
  231 +
  232 + handlePeriodChange() {
  233 + // 处理周期变更逻辑
  234 + },
  235 +
  236 + resetForm() {
  237 + this.$refs.form.resetFields()
  238 + },
  239 +
  240 + async savePlan() {
  241 + try {
  242 + // 获取选中的员工
  243 + // 准备数据
  244 + const payload = {
  245 + ...this.formData,
  246 + inspectionMonth: this.formData.months.join(','),
  247 + inspectionDay: this.formData.days.join(','),
  248 + inspectionWorkday: this.formData.workdays.join(',')
  249 + }
  250 +
  251 + // 调用API
  252 + await updateInspectionPlan(payload)
  253 + this.$message.success(this.$t('inspectionPlan.updateSuccess'))
  254 + this.visible = false
  255 + this.$emit('success')
  256 + } catch (error) {
  257 +
  258 + this.$message.error(this.$t('inspectionPlan.updateError'))
  259 + }
  260 + }
  261 + }
  262 +}
  263 +</script>
  264 +
  265 +<style scoped>
  266 +.margin-left {
  267 + margin-left: 10px;
  268 +}
  269 +</style>
0 \ No newline at end of file 270 \ No newline at end of file
src/components/inspection/editInspectionPoint.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('editInspectionPoint.title')"
  4 + :visible.sync="visible"
  5 + width="80%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form :model="editInspectionPointInfo" label-width="120px">
  9 + <el-row :gutter="20">
  10 + <el-col :span="12">
  11 + <el-form-item :label="$t('editInspectionPoint.pointName')" required>
  12 + <el-input
  13 + v-model="editInspectionPointInfo.inspectionName"
  14 + :placeholder="$t('editInspectionPoint.pointNamePlaceholder')"
  15 + ></el-input>
  16 + </el-form-item>
  17 + </el-col>
  18 + <el-col :span="12">
  19 + <el-form-item :label="$t('editInspectionPoint.inspectionType')" required>
  20 + <el-select
  21 + v-model="editInspectionPointInfo.pointObjType"
  22 + @change="handleTypeChange"
  23 + :placeholder="$t('editInspectionPoint.typePlaceholder')"
  24 + >
  25 + <el-option
  26 + v-for="item in editInspectionPointInfo.pointObjTypes"
  27 + :key="item.statusCd"
  28 + :label="item.name"
  29 + :value="item.statusCd"
  30 + ></el-option>
  31 + </el-select>
  32 + </el-form-item>
  33 + </el-col>
  34 + </el-row>
  35 +
  36 + <el-row :gutter="20" v-if="editInspectionPointInfo.pointObjType === '2002'">
  37 + <el-col :span="12">
  38 + <el-form-item :label="$t('editInspectionPoint.location')" required>
  39 + <el-input
  40 + v-model="editInspectionPointInfo.pointObjName"
  41 + :placeholder="$t('editInspectionPoint.locationPlaceholder')"
  42 + ></el-input>
  43 + </el-form-item>
  44 + </el-col>
  45 + </el-row>
  46 +
  47 + <el-row :gutter="20" v-if="editInspectionPointInfo.pointObjType === '1001'">
  48 + <el-col :span="12">
  49 + <el-form-item :label="$t('editInspectionPoint.inspectionDevice')" required>
  50 + <machine-select
  51 + @machine-selected="handleMachineSelected"
  52 + :initial-machine="initialMachine"
  53 + />
  54 + </el-form-item>
  55 + </el-col>
  56 + </el-row>
  57 +
  58 + <el-row :gutter="20">
  59 + <el-col :span="12">
  60 + <el-form-item :label="$t('editInspectionPoint.inspectionItem')" required>
  61 + <el-select
  62 + v-model="editInspectionPointInfo.itemId"
  63 + :placeholder="$t('editInspectionPoint.itemPlaceholder')"
  64 + >
  65 + <el-option
  66 + v-for="item in editInspectionPointInfo.items"
  67 + :key="item.itemId"
  68 + :label="item.itemName"
  69 + :value="item.itemId"
  70 + ></el-option>
  71 + </el-select>
  72 + </el-form-item>
  73 + </el-col>
  74 + <el-col :span="12">
  75 + <el-form-item label="NFC编码">
  76 + <el-input
  77 + v-model="editInspectionPointInfo.nfcCode"
  78 + :placeholder="$t('editInspectionPoint.nfcPlaceholder')"
  79 + ></el-input>
  80 + </el-form-item>
  81 + </el-col>
  82 + </el-row>
  83 +
  84 + <el-row :gutter="20">
  85 + <el-col :span="12">
  86 + <el-form-item :label="$t('editInspectionPoint.longitude')">
  87 + <el-input
  88 + v-model="editInspectionPointInfo.lng"
  89 + disabled
  90 + :placeholder="$t('editInspectionPoint.longitudePlaceholder')"
  91 + ></el-input>
  92 + </el-form-item>
  93 + </el-col>
  94 + <el-col :span="12">
  95 + <el-form-item :label="$t('editInspectionPoint.latitude')">
  96 + <el-input
  97 + v-model="editInspectionPointInfo.lat"
  98 + disabled
  99 + :placeholder="$t('editInspectionPoint.latitudePlaceholder')"
  100 + ></el-input>
  101 + </el-form-item>
  102 + </el-col>
  103 + </el-row>
  104 +
  105 + <el-row :gutter="20">
  106 + <el-col :span="12">
  107 + <el-form-item :label="$t('editInspectionPoint.remark')">
  108 + <el-input
  109 + type="textarea"
  110 + v-model="editInspectionPointInfo.remark"
  111 + :placeholder="$t('editInspectionPoint.remarkPlaceholder')"
  112 + ></el-input>
  113 + </el-form-item>
  114 + </el-col>
  115 + </el-row>
  116 +
  117 + <el-row>
  118 + <el-col :span="24">
  119 + <div id="editInspectionPointMap" style="width:100%;height:300px;"></div>
  120 + </el-col>
  121 + </el-row>
  122 + </el-form>
  123 +
  124 + <div slot="footer" class="dialog-footer">
  125 + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button>
  126 + <el-button type="primary" @click="handleSave">{{ $t('common.save') }}</el-button>
  127 + </div>
  128 + </el-dialog>
  129 +</template>
  130 +
  131 +<script>
  132 +import { updateInspectionPoint } from '@/api/inspection/editInspectionPointApi'
  133 +import { listInspectionItem } from '@/api/inspection/inspectionItemApi'
  134 +import { getDict } from '@/api/community/communityApi'
  135 +import MachineSelect from '@/components/property/machineSelect2'
  136 +
  137 +export default {
  138 + name: 'EditInspectionPoint',
  139 + components: {
  140 + MachineSelect
  141 + },
  142 + data() {
  143 + return {
  144 + visible: false,
  145 + editInspectionPointInfo: {
  146 + inspectionId: '',
  147 + pointObjId: '',
  148 + pointObjType: '',
  149 + pointObjTypes: [],
  150 + pointObjName: '',
  151 + inspectionName: '',
  152 + communityId: '',
  153 + remark: '',
  154 + items: [],
  155 + itemId: '',
  156 + nfcCode: '',
  157 + lng: '',
  158 + lat: ''
  159 + },
  160 + initialMachine: null
  161 + }
  162 + },
  163 + methods: {
  164 + async open(editData) {
  165 + this.resetForm()
  166 +
  167 + // 加载字典数据
  168 + try {
  169 + const pointObjTypes = await getDict('inspection_point', 'point_obj_type')
  170 + this.editInspectionPointInfo.pointObjTypes = pointObjTypes
  171 + } catch (error) {
  172 + console.error('获取字典数据失败:', error)
  173 + }
  174 +
  175 + // 加载巡检项目
  176 + try {
  177 + const items = await listInspectionItem({
  178 + communityId: this.editInspectionPointInfo.communityId,
  179 + page: 1,
  180 + row: 100
  181 + })
  182 + this.editInspectionPointInfo.items = items.data
  183 + } catch (error) {
  184 + console.error('加载巡检项目失败:', error)
  185 + }
  186 +
  187 + // 填充表单数据
  188 + Object.keys(editData).forEach(key => {
  189 + if (this.editInspectionPointInfo.hasOwnProperty(key)) {
  190 + this.editInspectionPointInfo[key] = editData[key]
  191 + }
  192 + })
  193 +
  194 + // 设置初始设备(如果是设备类型)
  195 + if (this.editInspectionPointInfo.pointObjType === '1001') {
  196 + this.initialMachine = {
  197 + machineId: this.editInspectionPointInfo.pointObjId,
  198 + machineName: this.editInspectionPointInfo.pointObjName
  199 + }
  200 + }
  201 +
  202 + this.visible = true
  203 +
  204 + this.$nextTick(() => {
  205 + this.initMap()
  206 + })
  207 + },
  208 +
  209 + resetForm() {
  210 + this.editInspectionPointInfo = {
  211 + inspectionId: '',
  212 + pointObjId: '',
  213 + pointObjType: '',
  214 + pointObjTypes: [],
  215 + pointObjName: '',
  216 + inspectionName: '',
  217 + communityId: getCommunityId(),
  218 + remark: '',
  219 + items: [],
  220 + itemId: '',
  221 + nfcCode: '',
  222 + lng: '',
  223 + lat: ''
  224 + }
  225 + this.initialMachine = null
  226 + },
  227 +
  228 + handleClose() {
  229 + this.resetForm()
  230 + },
  231 +
  232 + handleTypeChange(value) {
  233 + if (value === '1001') {
  234 + this.editInspectionPointInfo.pointObjId = ''
  235 + this.editInspectionPointInfo.pointObjName = ''
  236 + } else if (value === '2002') {
  237 + this.editInspectionPointInfo.pointObjId = '-1'
  238 + }
  239 + },
  240 +
  241 + handleMachineSelected(machine) {
  242 + this.editInspectionPointInfo.pointObjId = machine.machineId
  243 + this.editInspectionPointInfo.pointObjName = machine.machineName
  244 + },
  245 +
  246 + initMap() {
  247 + // 这里初始化地图,实际实现需要根据地图API
  248 + console.log('初始化编辑巡检点地图')
  249 + },
  250 +
  251 + async handleSave() {
  252 + // 表单验证
  253 + if (!this.validateForm()) return
  254 +
  255 + try {
  256 + await updateInspectionPoint(this.editInspectionPointInfo)
  257 + this.$message.success(this.$t('common.saveSuccess'))
  258 + this.visible = false
  259 + this.$emit('saved')
  260 + } catch (error) {
  261 + console.error('保存巡检点失败:', error)
  262 + this.$message.error(error.message || this.$t('common.saveFailed'))
  263 + }
  264 + },
  265 +
  266 + validateForm() {
  267 + if (!this.editInspectionPointInfo.inspectionName) {
  268 + this.$message.warning(this.$t('editInspectionPoint.validate.pointName'))
  269 + return false
  270 + }
  271 +
  272 + if (!this.editInspectionPointInfo.pointObjType) {
  273 + this.$message.warning(this.$t('editInspectionPoint.validate.pointType'))
  274 + return false
  275 + }
  276 +
  277 + if (this.editInspectionPointInfo.pointObjType === '2002' && !this.editInspectionPointInfo.pointObjName) {
  278 + this.$message.warning(this.$t('editInspectionPoint.validate.location'))
  279 + return false
  280 + }
  281 +
  282 + if (this.editInspectionPointInfo.pointObjType === '1001' && !this.editInspectionPointInfo.pointObjId) {
  283 + this.$message.warning(this.$t('editInspectionPoint.validate.device'))
  284 + return false
  285 + }
  286 +
  287 + if (!this.editInspectionPointInfo.itemId) {
  288 + this.$message.warning(this.$t('editInspectionPoint.validate.item'))
  289 + return false
  290 + }
  291 +
  292 + return true
  293 + }
  294 + }
  295 +}
  296 +</script>
0 \ No newline at end of file 297 \ No newline at end of file
src/components/inspection/inspectionPlanState.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('inspectionPlan.confirmOperation')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + >
  7 + <div class="text-center">
  8 + <p>{{ $t('inspectionPlan.confirmStateChange', { state: stateName }) }}</p>
  9 + </div>
  10 + <div slot="footer">
  11 + <el-button @click="visible = false">{{ $t('inspectionPlan.cancel') }}</el-button>
  12 + <el-button type="primary" @click="confirmChange">{{ $t('inspectionPlan.confirm') }}</el-button>
  13 + </div>
  14 + </el-dialog>
  15 +</template>
  16 +
  17 +<script>
  18 +import { updateInspectionPlanState } from '@/api/inspection/inspectionPlanApi'
  19 +
  20 +export default {
  21 + name: 'InspectionPlanState',
  22 + data() {
  23 + return {
  24 + visible: false,
  25 + inspectionPlanId: null,
  26 + state: null,
  27 + stateName: ''
  28 + }
  29 + },
  30 + methods: {
  31 + open({ inspectionPlanId, state, stateName }) {
  32 + this.inspectionPlanId = inspectionPlanId
  33 + this.state = state
  34 + this.stateName = stateName
  35 + this.visible = true
  36 + },
  37 +
  38 + async confirmChange() {
  39 + try {
  40 + await updateInspectionPlanState({
  41 + inspectionPlanId: this.inspectionPlanId,
  42 + state: this.state
  43 + })
  44 + this.$message.success(this.$t('inspectionPlan.stateChangeSuccess'))
  45 + this.visible = false
  46 + this.$emit('success')
  47 + } catch (error) {
  48 + this.$message.error(this.$t('inspectionPlan.stateChangeError'))
  49 + }
  50 + }
  51 + }
  52 +}
  53 +</script>
  54 +
  55 +<style scoped>
  56 +.text-center {
  57 + text-align: center;
  58 +}
  59 +</style>
0 \ No newline at end of file 60 \ No newline at end of file
src/components/inspection/inspectionPointQrCode.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('inspectionPointQrCode.title')"
  4 + :visible.sync="visible"
  5 + width="400px"
  6 + @close="handleClose"
  7 + >
  8 + <div class="qr-container">
  9 + <div ref="qrcode" class="qrcode"></div>
  10 + <div class="point-name">{{ inspectionPointQrCodeInfo.inspectionName }}</div>
  11 + <p class="tip">{{ $t('inspectionPointQrCode.tip') }}</p>
  12 + </div>
  13 + <div slot="footer" class="dialog-footer">
  14 + <el-button @click="visible = false">{{ $t('common.close') }}</el-button>
  15 + </div>
  16 + </el-dialog>
  17 +</template>
  18 +
  19 +<script>
  20 +import QRCode from 'qrcodejs2'
  21 +
  22 +export default {
  23 + name: 'InspectionPointQrCode',
  24 + data() {
  25 + return {
  26 + visible: false,
  27 + inspectionPointQrCodeInfo: {
  28 + url: '',
  29 + inspectionName: ''
  30 + },
  31 + qrCode: null
  32 + }
  33 + },
  34 + methods: {
  35 + open(qrInfo) {
  36 + this.inspectionPointQrCodeInfo = { ...qrInfo }
  37 + this.visible = true
  38 +
  39 + this.$nextTick(() => {
  40 + this.generateQrCode()
  41 + })
  42 + },
  43 +
  44 + handleClose() {
  45 + this.inspectionPointQrCodeInfo = {
  46 + url: '',
  47 + inspectionName: ''
  48 + }
  49 + if (this.qrCode) {
  50 + this.qrCode.clear()
  51 + }
  52 + },
  53 +
  54 + generateQrCode() {
  55 + if (this.qrCode) {
  56 + this.qrCode.clear()
  57 + }
  58 +
  59 + this.qrCode = new QRCode(this.$refs.qrcode, {
  60 + text: this.inspectionPointQrCodeInfo.url,
  61 + width: 200,
  62 + height: 200,
  63 + colorDark: '#000000',
  64 + colorLight: '#ffffff',
  65 + correctLevel: QRCode.CorrectLevel.L
  66 + })
  67 + }
  68 + },
  69 + beforeDestroy() {
  70 + if (this.qrCode) {
  71 + this.qrCode.clear()
  72 + }
  73 + }
  74 +}
  75 +</script>
  76 +
  77 +<style scoped>
  78 +.qr-container {
  79 + text-align: center;
  80 +}
  81 +
  82 +.qrcode {
  83 + display: inline-block;
  84 + margin: 0 auto;
  85 +}
  86 +
  87 +.point-name {
  88 + margin-top: 15px;
  89 + font-size: 16px;
  90 + font-weight: bold;
  91 +}
  92 +
  93 +.tip {
  94 + margin-top: 10px;
  95 + color: #999;
  96 + font-size: 14px;
  97 +}
  98 +</style>
0 \ No newline at end of file 99 \ No newline at end of file
src/components/inspection/pointPlan.vue 0 → 100644
  1 +<template>
  2 + <div class="margin-top">
  3 + <el-row class="margin-top-lg">
  4 + <el-col :span="8" class="text-right"></el-col>
  5 + </el-row>
  6 + <div class="margin-top">
  7 + <el-table :data="pointPlanInfo.plans" style="width: 100%">
  8 + <el-table-column prop="inspectionPlanName" :label="$t('inspectionPlan.planName')" align="center"></el-table-column>
  9 + <el-table-column prop="inspectionRouteName" :label="$t('inspectionPlan.planRoute')" align="center"></el-table-column>
  10 + <el-table-column prop="inspectionPlanPeriodName" :label="$t('inspectionPlan.planPeriod')" align="center"></el-table-column>
  11 + <el-table-column prop="signTypeName" :label="$t('inspectionPlan.signType')" align="center"></el-table-column>
  12 + <el-table-column :label="$t('inspectionPlan.dateRange')" align="center">
  13 + <template slot-scope="scope">
  14 + {{ scope.row.startDate }}~{{ scope.row.endDate }}
  15 + </template>
  16 + </el-table-column>
  17 + <el-table-column :label="$t('inspectionPlan.timeRange')" align="center">
  18 + <template slot-scope="scope">
  19 + {{ scope.row.startTime }}~{{ scope.row.endTime }}
  20 + </template>
  21 + </el-table-column>
  22 + <el-table-column prop="beforeTime" :label="$t('inspectionPlan.taskAhead')" align="center"></el-table-column>
  23 + <el-table-column prop="createUserName" :label="$t('inspectionPlan.creator')" align="center"></el-table-column>
  24 + <el-table-column prop="createTime" :label="$t('inspectionPlan.createTime')" align="center"></el-table-column>
  25 + <el-table-column :label="$t('inspectionPlan.inspector')" align="center">
  26 + <template slot-scope="scope">
  27 + <div v-for="(staff, i) in scope.row.staffs" :key="i">{{ staff.staffName }}</div>
  28 + </template>
  29 + </el-table-column>
  30 + <el-table-column prop="stateName" :label="$t('inspectionPlan.status')" align="center"></el-table-column>
  31 + </el-table>
  32 +
  33 + <el-row class="margin-top">
  34 + <el-col :span="4"></el-col>
  35 + <el-col :span="20" class="text-right">
  36 + <el-pagination
  37 + @current-change="handlePageChange"
  38 + :current-page.sync="currentPage"
  39 + :page-size="pageSize"
  40 + layout="prev, pager, next, jumper"
  41 + :total="total">
  42 + </el-pagination>
  43 + </el-col>
  44 + </el-row>
  45 + </div>
  46 + </div>
  47 +</template>
  48 +
  49 +<script>
  50 +import { queryPointInspectionPlan } from '@/api/inspection/pointPlanApi'
  51 +import { getCommunityId } from '@/api/community/communityApi'
  52 +
  53 +export default {
  54 + name: 'PointPlan',
  55 + props: {
  56 + inspectionId: {
  57 + type: String,
  58 + default: ''
  59 + }
  60 + },
  61 + data() {
  62 + return {
  63 + pointPlanInfo: {
  64 + plans: [],
  65 + planUserName: '',
  66 + inspectionStartTime: '',
  67 + inspectionEndTime: ''
  68 + },
  69 + currentPage: 1,
  70 + pageSize: 10,
  71 + total: 0
  72 + }
  73 + },
  74 + watch: {
  75 + inspectionId(newVal) {
  76 + if (newVal) {
  77 + this._loadPointPlanData(this.currentPage, this.pageSize)
  78 + }
  79 + }
  80 + },
  81 + methods: {
  82 + async _loadPointPlanData(page, row) {
  83 + try {
  84 + const communityId = getCommunityId()
  85 + const params = {
  86 + communityId,
  87 + inspectionId: this.inspectionId,
  88 + planUserName: this.pointPlanInfo.planUserName,
  89 + inspectionStartTime: this.pointPlanInfo.inspectionStartTime,
  90 + inspectionEndTime: this.pointPlanInfo.inspectionEndTime,
  91 + page,
  92 + row
  93 + }
  94 +
  95 + const res = await queryPointInspectionPlan(params)
  96 + this.pointPlanInfo.plans = res.data
  97 + this.total = res.total
  98 + } catch (error) {
  99 + console.error('加载计划数据失败:', error)
  100 + }
  101 + },
  102 +
  103 + handlePageChange(currentPage) {
  104 + this._loadPointPlanData(currentPage, this.pageSize)
  105 + },
  106 +
  107 + refresh() {
  108 + this.currentPage = 1
  109 + this._loadPointPlanData(this.currentPage, this.pageSize)
  110 + },
  111 +
  112 + setPlanUserName(name) {
  113 + this.pointPlanInfo.planUserName = name
  114 + },
  115 +
  116 + setDateRange(startTime, endTime) {
  117 + this.pointPlanInfo.inspectionStartTime = startTime
  118 + this.pointPlanInfo.inspectionEndTime = endTime
  119 + }
  120 + }
  121 +}
  122 +</script>
0 \ No newline at end of file 123 \ No newline at end of file
src/components/inspection/pointPlanDemo.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <point-plan ref="pointPlan" :inspection-id="currentInspectionId" />
  4 + </div>
  5 +</template>
  6 +
  7 +<script>
  8 +import PointPlan from '@/components/inspection/pointPlan'
  9 +
  10 +export default {
  11 + components: {
  12 + PointPlan
  13 + },
  14 + data() {
  15 + return {
  16 + currentInspectionId: '123456' // 示例巡检点ID
  17 + }
  18 + },
  19 + mounted() {
  20 + // 模拟切换巡检点
  21 + this.$refs.pointPlan.refresh()
  22 +
  23 + // 示例:设置筛选条件
  24 + this.$refs.pointPlan.setPlanUserName('张三')
  25 + this.$refs.pointPlan.setDateRange('2023-01-01', '2023-12-31')
  26 + }
  27 +}
  28 +</script>
0 \ No newline at end of file 29 \ No newline at end of file
src/components/staff/AStaffDetailInspection.vue
@@ -110,8 +110,8 @@ @@ -110,8 +110,8 @@
110 110
111 <script> 111 <script>
112 import { listAdminInspectionTaskDetails } from '@/api/staff/adminStaffDetailApi' 112 import { listAdminInspectionTaskDetails } from '@/api/staff/adminStaffDetailApi'
113 - import ViewMap from '@/components/staff/ViewMap.vue'  
114 - import ViewImage from '@/components/staff/ViewImage.vue' 113 + import ViewMap from '@/components/system/ViewMap.vue'
  114 + import ViewImage from '@/components/system/viewImage.vue'
115 115
116 export default { 116 export default {
117 name: 'AStaffDetailInspection', 117 name: 'AStaffDetailInspection',
src/components/staff/selectStaffsDiv.vue 0 → 100644
  1 +<template>
  2 + <el-row :gutter="20">
  3 + <el-col :span="6" class="border-right">
  4 + <div class="text-center">
  5 + <h4>{{ $t('selectStaff.orgInfo') }}</h4>
  6 + </div>
  7 + <div class="tree-container">
  8 + <org-tree-show @org-selected="handleNodeClick" />
  9 + </div>
  10 + </el-col>
  11 +
  12 + <el-col :span="6" class="border-right">
  13 + <div class="text-center">
  14 + <h4>{{ $t('selectStaff.staffInfo') }}</h4>
  15 + </div>
  16 + <div class="staff-list">
  17 + <div
  18 + v-for="staff in staffList"
  19 + :key="staff.staffId"
  20 + class="staff-item"
  21 + :class="{ selected: currentStaffId === staff.userId }"
  22 + @click="selectStaff(staff)"
  23 + >
  24 + <i class="el-icon-user"></i>
  25 + <span>{{ staff.name }}</span>
  26 + <div>{{ staff.tel }}</div>
  27 + </div>
  28 + </div>
  29 + </el-col>
  30 +
  31 + <el-col :span="6">
  32 + <div class="text-center">
  33 + <h4>{{ $t('selectStaff.selectedStaff') }}</h4>
  34 + </div>
  35 + <div class="selected-staff">
  36 + <div v-for="staff in selectedStaffs" :key="staff.userId" class="selected-item">
  37 + <span>{{ staff.name }}</span>
  38 + <i class="el-icon-close remove-icon" @click="removeStaff(staff)"></i>
  39 + </div>
  40 + </div>
  41 + </el-col>
  42 + </el-row>
  43 + </template>
  44 +
  45 + <script>
  46 + import { listStaffsByOrgId } from '@/api/inspection/inspectionPlanApi'
  47 + import OrgTreeShow from '@/components/org/OrgTreeShow'
  48 +
  49 + export default {
  50 + name: 'SelectStaffs',
  51 + components: {
  52 + OrgTreeShow
  53 + },
  54 + data() {
  55 + return {
  56 + staffList: [],
  57 + selectedStaffs: [],
  58 + currentStaffId: null,
  59 + currentOrgId: null
  60 + }
  61 + },
  62 + methods: {
  63 + setStaffs(staffs) {
  64 + this.selectedStaffs = [...staffs]
  65 + },
  66 +
  67 + getSelectedStaffs() {
  68 + return this.selectedStaffs
  69 + },
  70 +
  71 + async handleNodeClick(node) {
  72 + this.currentOrgId = node.id
  73 + try {
  74 + const { staffs } = await listStaffsByOrgId({
  75 + orgId: node.id,
  76 + page: 1,
  77 + row: 100
  78 + })
  79 + this.staffList = staffs
  80 + } catch (error) {
  81 + console.error('Failed to load staffs:', error)
  82 + }
  83 + },
  84 +
  85 + selectStaff(staff) {
  86 + this.currentStaffId = staff.userId
  87 + // 检查是否已选择
  88 + const isSelected = this.selectedStaffs.some(s => s.userId === staff.userId)
  89 + if (!isSelected) {
  90 + this.selectedStaffs.push({
  91 + userId: staff.userId,
  92 + name: staff.userName
  93 + })
  94 + }
  95 + this.$emit('selectStaffs', this.selectedStaffs)
  96 + },
  97 +
  98 + removeStaff(staff) {
  99 + this.selectedStaffs = this.selectedStaffs.filter(s => s.staffId !== staff.staffId)
  100 + }
  101 + }
  102 + }
  103 + </script>
  104 +
  105 + <style scoped>
  106 + .border-right {
  107 + border-right: 1px solid #eee;
  108 + }
  109 + .tree-container {
  110 + height: 300px;
  111 + overflow: auto;
  112 + padding: 10px;
  113 + }
  114 + .staff-list {
  115 + height: 300px;
  116 + overflow: auto;
  117 + padding: 10px;
  118 + }
  119 + .staff-item {
  120 + padding: 10px;
  121 + cursor: pointer;
  122 + border-bottom: 1px solid #eee;
  123 + }
  124 + .staff-item:hover {
  125 + background-color: #f5f7fa;
  126 + }
  127 + .staff-item.selected {
  128 + background-color: #ecf5ff;
  129 + }
  130 + .selected-staff {
  131 + height: 300px;
  132 + overflow: auto;
  133 + padding: 10px;
  134 + }
  135 + .selected-item {
  136 + display: flex;
  137 + justify-content: space-between;
  138 + align-items: center;
  139 + padding: 8px;
  140 + margin-bottom: 5px;
  141 + border: 1px solid #ebeef5;
  142 + border-radius: 4px;
  143 + }
  144 + .remove-icon {
  145 + cursor: pointer;
  146 + color: #f56c6c;
  147 + }
  148 + .text-center {
  149 + text-align: center;
  150 + padding: 10px 0;
  151 + }
  152 + </style>
0 \ No newline at end of file 153 \ No newline at end of file
src/components/staff/ViewMap.vue renamed to src/components/system/ViewMap.vue
src/components/system/viewImage.vue 0 → 100644
  1 +<template>
  2 + <div class="image-viewer">
  3 + <el-dialog
  4 + :visible.sync="dialogVisible"
  5 + fullscreen
  6 + :show-close="false"
  7 + @close="closeDialog">
  8 + <div class="image-container">
  9 + <el-image
  10 + :src="imageUrl"
  11 + fit="contain"
  12 + :style="{ width: imageWidth + 'px', height: imageHeight + 'px' }">
  13 + </el-image>
  14 + <i class="el-icon-close close-icon" @click="closeDialog"></i>
  15 + </div>
  16 + </el-dialog>
  17 + </div>
  18 +</template>
  19 +
  20 +<script>
  21 +export default {
  22 + name: 'ViewImage',
  23 + data() {
  24 + return {
  25 + dialogVisible: false,
  26 + imageUrl: '',
  27 + imageWidth: 800,
  28 + imageHeight: 800
  29 + }
  30 + },
  31 + methods: {
  32 + open(url) {
  33 + this.imageUrl = url
  34 + this.dialogVisible = true
  35 +
  36 + // 计算图片宽高比例
  37 + const img = new Image()
  38 + img.src = url
  39 + img.onload = () => {
  40 + const ratio = img.width / img.height
  41 + this.imageWidth = 800
  42 + this.imageHeight = 800 / ratio
  43 + }
  44 + },
  45 + closeDialog() {
  46 + this.dialogVisible = false
  47 + }
  48 + }
  49 +}
  50 +</script>
  51 +
  52 +<style lang="scss" scoped>
  53 +.image-viewer {
  54 + .image-container {
  55 + position: fixed;
  56 + top: 50%;
  57 + left: 50%;
  58 + transform: translate(-50%, -50%);
  59 + background-color: #fff;
  60 + padding: 20px;
  61 +
  62 + .close-icon {
  63 + position: absolute;
  64 + right: 20px;
  65 + top: 20px;
  66 + font-size: 24px;
  67 + color: #F56C6C;
  68 + cursor: pointer;
  69 + }
  70 + }
  71 +}
  72 +</style>
0 \ No newline at end of file 73 \ No newline at end of file
src/i18n/index.js
@@ -172,6 +172,11 @@ import { messages as repairReturnVisitMessages } from &#39;../views/work/repairRetur @@ -172,6 +172,11 @@ import { messages as repairReturnVisitMessages } from &#39;../views/work/repairRetur
172 import { messages as repairForceFinishManageMessages } from '../views/work/repairForceFinishManageLang' 172 import { messages as repairForceFinishManageMessages } from '../views/work/repairForceFinishManageLang'
173 import { messages as inspectionItemManageMessages } from '../views/inspection/inspectionItemManageLang' 173 import { messages as inspectionItemManageMessages } from '../views/inspection/inspectionItemManageLang'
174 import { messages as inspectionItemTitleManageMessages } from '../views/inspection/inspectionItemTitleManageLang' 174 import { messages as inspectionItemTitleManageMessages } from '../views/inspection/inspectionItemTitleManageLang'
  175 +import { messages as inspectionPlanMessages } from '../views/inspection/inspectionPlanLang'
  176 +import { messages as addInspectionPlanMessages } from '../views/inspection/addInspectionPlanLang'
  177 +import { messages as inspectionTaskMessages } from '../views/inspection/inspectionTaskLang'
  178 +import { messages as inspectionTaskDetailsMessages } from '../views/inspection/inspectionTaskDetailsLang'
  179 +
175 Vue.use(VueI18n) 180 Vue.use(VueI18n)
176 181
177 // 合并所有语言配置 182 // 合并所有语言配置
@@ -347,6 +352,10 @@ const messages = { @@ -347,6 +352,10 @@ const messages = {
347 ...repairForceFinishManageMessages.en, 352 ...repairForceFinishManageMessages.en,
348 ...inspectionItemManageMessages.en, 353 ...inspectionItemManageMessages.en,
349 ...inspectionItemTitleManageMessages.en, 354 ...inspectionItemTitleManageMessages.en,
  355 + ...inspectionPlanMessages.en,
  356 + ...addInspectionPlanMessages.en,
  357 + ...inspectionTaskMessages.en,
  358 + ...inspectionTaskDetailsMessages.en,
350 }, 359 },
351 zh: { 360 zh: {
352 ...loginMessages.zh, 361 ...loginMessages.zh,
@@ -519,6 +528,10 @@ const messages = { @@ -519,6 +528,10 @@ const messages = {
519 ...repairForceFinishManageMessages.zh, 528 ...repairForceFinishManageMessages.zh,
520 ...inspectionItemManageMessages.zh, 529 ...inspectionItemManageMessages.zh,
521 ...inspectionItemTitleManageMessages.zh, 530 ...inspectionItemTitleManageMessages.zh,
  531 + ...inspectionPlanMessages.zh,
  532 + ...addInspectionPlanMessages.zh,
  533 + ...inspectionTaskMessages.zh,
  534 + ...inspectionTaskDetailsMessages.zh,
522 } 535 }
523 } 536 }
524 537
src/router/index.js
@@ -842,15 +842,35 @@ const routes = [ @@ -842,15 +842,35 @@ const routes = [
842 component: () => import('@/views/work/repairForceFinishManageList.vue') 842 component: () => import('@/views/work/repairForceFinishManageList.vue')
843 }, 843 },
844 { 844 {
845 - path:'/pages/property/inspectionItemManage',  
846 - name:'/pages/property/inspectionItemManage', 845 + path: '/pages/property/inspectionItemManage',
  846 + name: '/pages/property/inspectionItemManage',
847 component: () => import('@/views/inspection/inspectionItemManageList.vue') 847 component: () => import('@/views/inspection/inspectionItemManageList.vue')
  848 + },
  849 + {
  850 + path: '/views/inspection/inspectionItemTitleManage',
  851 + name: '/views/inspection/inspectionItemTitleManage',
  852 + component: () => import('@/views/inspection/inspectionItemTitleManageList.vue')
  853 + },
  854 + {
  855 + path: '/pages/inspection/inspectionPlan',
  856 + name: '/pages/inspection/inspectionPlan',
  857 + component: () => import('@/views/inspection/inspectionPlanList.vue')
  858 + },
  859 + {
  860 + path:'/views/inspection/addInspectionPlan',
  861 + name:'/views/inspection/addInspectionPlan',
  862 + component: () => import('@/views/inspection/addInspectionPlanList.vue')
848 }, 863 },
849 { 864 {
850 - path:'/views/inspection/inspectionItemTitleManage',  
851 - name:'/views/inspection/inspectionItemTitleManage',  
852 - component: () => import('@/views/inspection/inspectionItemTitleManageList.vue') 865 + path:'/pages/inspection/inspectionTask',
  866 + name:'/pages/inspection/inspectionTask',
  867 + component: () => import('@/views/inspection/InspectionTaskList.vue')
853 }, 868 },
  869 + {
  870 + path:'/pages/property/inspectionTaskDetails',
  871 + name:'/pages/property/inspectionTaskDetails',
  872 + component: () => import('@/views/inspection/inspectionTaskDetailsList.vue')
  873 + },
854 // 其他子路由可以在这里添加 874 // 其他子路由可以在这里添加
855 ] 875 ]
856 }, 876 },
src/views/inspection/InspectionTaskList.vue 0 → 100644
  1 +<template>
  2 + <div class="inspection-task-container">
  3 + <el-row :gutter="20">
  4 + <el-col :span="3">
  5 + <el-card class="plan-list-card">
  6 + <div class="plan-list">
  7 + <div v-for="item in plans" :key="item.inspectionPlanId" class="plan-item"
  8 + :class="{ 'active-plan': conditions.inspectionPlanId === item.inspectionPlanId }" @click="switchPlan(item)">
  9 + {{ item.inspectionPlanName }}
  10 + </div>
  11 + </div>
  12 + </el-card>
  13 + </el-col>
  14 +
  15 + <el-col :span="21">
  16 + <el-card>
  17 + <div slot="header" class="flex justify-between">
  18 + <span>{{ $t('inspectionTask.queryConditions') }}</span>
  19 + </div>
  20 +
  21 + <el-row :gutter="20">
  22 + <el-col :span="4">
  23 + <el-input v-model="conditions.planUserName" :placeholder="$t('inspectionTask.executor')"
  24 + clearable></el-input>
  25 + </el-col>
  26 +
  27 + <el-col :span="4">
  28 + <el-date-picker v-model="conditions.startTime" type="datetime"
  29 + :placeholder="$t('inspectionTask.actualStartTime')" value-format="yyyy-MM-dd HH:mm:ss"
  30 + style="width: 100%"></el-date-picker>
  31 + </el-col>
  32 +
  33 + <el-col :span="4">
  34 + <el-date-picker v-model="conditions.endTime" type="datetime"
  35 + :placeholder="$t('inspectionTask.actualEndTime')" value-format="yyyy-MM-dd HH:mm:ss"
  36 + style="width: 100%"></el-date-picker>
  37 + </el-col>
  38 +
  39 + <el-col :span="4">
  40 + <el-select v-model="conditions.state" :placeholder="$t('inspectionTask.inspectionStatus')" clearable
  41 + style="width: 100%">
  42 + <el-option v-for="item in stateTypes" :key="item.statusCd" :label="item.name"
  43 + :value="item.statusCd"></el-option>
  44 + </el-select>
  45 + </el-col>
  46 + <el-col :span="4" >
  47 + <el-button type="primary" @click="queryInspectionTasks">
  48 + <i class="el-icon-search"></i> {{ $t('inspectionTask.query') }}
  49 + </el-button>
  50 + <el-button @click="resetConditions">
  51 + <i class="el-icon-refresh"></i> {{ $t('inspectionTask.reset') }}
  52 + </el-button>
  53 + </el-col>
  54 + </el-row>
  55 + </el-card>
  56 +
  57 + <el-card style="margin-top: 20px;">
  58 + <div slot="header" class="flex justify-between">
  59 + <span>{{ $t('inspectionTask.inspectionTask') }}</span>
  60 + </div>
  61 +
  62 + <el-table :data="inspectionTasks" border style="width: 100%">
  63 + <el-table-column prop="taskId" :label="$t('inspectionTask.taskCode')" align="center" />
  64 + <el-table-column prop="inspectionPlanName" :label="$t('inspectionTask.inspectionPlan')" align="center" />
  65 + <el-table-column :label="$t('inspectionTask.inspectorTime')" align="center">
  66 + <template slot-scope="{row}">
  67 + {{ row.planInsTime }}<br>{{ row.planEndTime }}
  68 + </template>
  69 + </el-table-column>
  70 + <el-table-column prop="actInsTime" :label="$t('inspectionTask.actualTime')" align="center">
  71 + <template slot-scope="{row}">
  72 + {{ row.actInsTime || '-' }}
  73 + </template>
  74 + </el-table-column>
  75 + <el-table-column prop="originalPlanUserName" :label="$t('inspectionTask.plannedInspector')" align="center">
  76 + <template slot-scope="{row}">
  77 + {{ row.originalPlanUserName || '-' }}
  78 + </template>
  79 + </el-table-column>
  80 + <el-table-column prop="planUserName" :label="$t('inspectionTask.currentInspector')" align="center" />
  81 + <el-table-column prop="transferDesc" :label="$t('inspectionTask.transferDesc')" align="center">
  82 + <template slot-scope="{row}">
  83 + {{ row.transferDesc || '-' }}
  84 + </template>
  85 + </el-table-column>
  86 + <el-table-column prop="signTypeName" :label="$t('inspectionTask.inspectionMethod')" align="center" />
  87 + <el-table-column :label="$t('inspectionTask.inspectionStatus')" align="center">
  88 + <template slot-scope="{row}">
  89 + <span v-if="row.state === '20200408'" class="text-danger font-bold">
  90 + {{ row.stateName }}
  91 + </span>
  92 + <span v-else>{{ row.stateName }}</span>
  93 + </template>
  94 + </el-table-column>
  95 + <el-table-column :label="$t('inspectionTask.operation')" align="center" width="220">
  96 + <template slot-scope="{row}">
  97 + <el-button v-if="row.state === '20200406' || row.state === '20200405'" size="mini"
  98 + @click="openTransfer(row)">
  99 + {{ $t('inspectionTask.flow') }}
  100 + </el-button>
  101 + <el-button size="mini" type="primary" @click="openDetail(row)">
  102 + {{ $t('inspectionTask.detail') }}
  103 + </el-button>
  104 + <el-button v-if="hasPrivilege('502022031612550001')" size="mini" type="danger" @click="openDelete(row)">
  105 + {{ $t('inspectionTask.delete') }}
  106 + </el-button>
  107 + </template>
  108 + </el-table-column>
  109 + </el-table>
  110 +
  111 + <el-row style="margin-top: 20px;">
  112 + <el-col :span="18">
  113 + <div class="note">{{ $t('inspectionTask.note') }}</div>
  114 + </el-col>
  115 + <el-col :span="6">
  116 + <el-pagination :current-page="currentPage" :page-size="pageSize" :total="total"
  117 + layout="total, prev, pager, next, jumper" @current-change="handlePageChange" />
  118 + </el-col>
  119 + </el-row>
  120 + </el-card>
  121 + </el-col>
  122 + </el-row>
  123 +
  124 + <InspectionTaskDetail ref="inspectionTaskDetail" />
  125 + <InspectionTaskTransfer ref="inspectionTaskTransfer" @success="loadInspectionTasks" />
  126 + <DeleteInspectionTask ref="deleteInspectionTask" @success="loadInspectionTasks" />
  127 + </div>
  128 +</template>
  129 +
  130 +<script>
  131 +import InspectionTaskDetail from '@/components/inspection/InspectionTaskDetail'
  132 +import InspectionTaskTransfer from '@/components/inspection/InspectionTaskTransfer'
  133 +import DeleteInspectionTask from '@/components/inspection/DeleteInspectionTask'
  134 +import {
  135 + listInspectionPlans,
  136 + listInspectionTasks,
  137 +} from '@/api/inspection/inspectionTaskApi'
  138 +import {getDict} from '@/api/community/communityApi'
  139 +
  140 +export default {
  141 + name: 'InspectionTaskList',
  142 + components: { InspectionTaskDetail, InspectionTaskTransfer, DeleteInspectionTask },
  143 + data() {
  144 + return {
  145 + plans: [],
  146 + inspectionTasks: [],
  147 + stateTypes: [],
  148 + conditions: {
  149 + planUserName: '',
  150 + inspectionPlanId: '',
  151 + startTime: '',
  152 + endTime: '',
  153 + state: '',
  154 + orderByDesc: 'desc'
  155 + },
  156 + currentPage: 1,
  157 + pageSize: 10,
  158 + total: 0
  159 + }
  160 + },
  161 + async created() {
  162 + await this.loadPlans()
  163 + await this.loadStateTypes()
  164 + this.loadInspectionTasks()
  165 + },
  166 + methods: {
  167 + async loadPlans() {
  168 + try {
  169 + const {data} = await listInspectionPlans()
  170 + this.plans = [{ inspectionPlanName: this.$t('common.all'), inspectionPlanId: '' }, ...data]
  171 + } catch (error) {
  172 + console.error('加载巡检计划失败:', error)
  173 + }
  174 + },
  175 + async loadStateTypes() {
  176 + try {
  177 + this.stateTypes = await getDict('inspection_task', 'state')
  178 + } catch (error) {
  179 + console.error('加载状态类型失败:', error)
  180 + }
  181 + },
  182 + async loadInspectionTasks() {
  183 + try {
  184 + const params = {
  185 + ...this.conditions,
  186 + page: this.currentPage,
  187 + row: this.pageSize
  188 + }
  189 + const res = await listInspectionTasks(params)
  190 + this.inspectionTasks = res.inspectionTasks || []
  191 + this.total = res.total || 0
  192 + } catch (error) {
  193 + console.error('加载巡检任务失败:', error)
  194 + }
  195 + },
  196 + switchPlan(plan) {
  197 + this.conditions.inspectionPlanId = plan.inspectionPlanId
  198 + this.currentPage = 1
  199 + this.loadInspectionTasks()
  200 + },
  201 + queryInspectionTasks() {
  202 + this.currentPage = 1
  203 + this.loadInspectionTasks()
  204 + },
  205 + resetConditions() {
  206 + this.conditions = {
  207 + planUserName: '',
  208 + inspectionPlanId: '',
  209 + startTime: '',
  210 + endTime: '',
  211 + state: '',
  212 + orderByDesc: 'desc'
  213 + }
  214 + this.currentPage = 1
  215 + this.loadInspectionTasks()
  216 + },
  217 + handlePageChange(page) {
  218 + this.currentPage = page
  219 + this.loadInspectionTasks()
  220 + },
  221 + openDetail(task) {
  222 + this.$refs.inspectionTaskDetail.open(task)
  223 + },
  224 + openTransfer(task) {
  225 + this.$refs.inspectionTaskTransfer.open(task)
  226 + },
  227 + openDelete(task) {
  228 + this.$refs.deleteInspectionTask.open(task)
  229 + },
  230 + }
  231 +}
  232 +</script>
  233 +
  234 +<style scoped>
  235 +.inspection-task-container {
  236 + padding: 20px;
  237 +}
  238 +
  239 +.plan-list-card {
  240 + height: calc(100vh - 100px);
  241 +}
  242 +
  243 +.plan-list {
  244 + max-height: calc(100vh - 150px);
  245 + overflow-y: auto;
  246 +}
  247 +
  248 +.plan-item {
  249 + padding: 12px 15px;
  250 + margin-bottom: 5px;
  251 + border-radius: 4px;
  252 + cursor: pointer;
  253 + transition: all 0.3s;
  254 +}
  255 +
  256 +.plan-item:hover {
  257 + background-color: #f5f7fa;
  258 +}
  259 +
  260 +.active-plan {
  261 + background-color: #409EFF;
  262 + color: white;
  263 +}
  264 +
  265 +.note {
  266 + font-size: 12px;
  267 + color: #909399;
  268 + padding: 10px;
  269 + background-color: #f8f8f9;
  270 + border-radius: 4px;
  271 +}
  272 +
  273 +.text-danger {
  274 + color: #F56C6C;
  275 +}
  276 +
  277 +.font-bold {
  278 + font-weight: bold;
  279 +}
  280 +</style>
0 \ No newline at end of file 281 \ No newline at end of file
src/views/inspection/addInspectionPlanLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + addInspectionPlan: {
  4 + title: 'Add Plan',
  5 + planName: 'Plan Name',
  6 + inspectionRoute: 'Inspection Route',
  7 + inspectionPeriod: 'Inspection Period',
  8 + taskAdvance: 'Task Advance',
  9 + minutesGenerate: 'minutes generate',
  10 + month: 'Month',
  11 + day: 'Day',
  12 + week: 'Week',
  13 + startDate: 'Start Date',
  14 + endDate: 'End Date',
  15 + startTime: 'Start Time',
  16 + endTime: 'End Time',
  17 + signMethod: 'Sign Method',
  18 + allowRecheck: 'Allow Recheck',
  19 + selectStaff: 'Select Staff',
  20 + save: 'Save',
  21 + back: 'Back',
  22 + required: 'Required',
  23 + monthlyDaily: 'Month/Day',
  24 + weekly: 'Weekly',
  25 + notAllowed: 'Not Allowed',
  26 + allowed: 'Allowed',
  27 + monday: 'Monday',
  28 + tuesday: 'Tuesday',
  29 + wednesday: 'Wednesday',
  30 + thursday: 'Thursday',
  31 + friday: 'Friday',
  32 + saturday: 'Saturday',
  33 + sunday: 'Sunday'
  34 + }
  35 + },
  36 + zh: {
  37 + addInspectionPlan: {
  38 + title: '添加计划',
  39 + planName: '计划名称',
  40 + inspectionRoute: '巡检路线',
  41 + inspectionPeriod: '巡检周期',
  42 + taskAdvance: '任务提前',
  43 + minutesGenerate: '分钟生成',
  44 + month: '月',
  45 + day: '日',
  46 + week: '周',
  47 + startDate: '开始日期',
  48 + endDate: '结束日期',
  49 + startTime: '开始时间',
  50 + endTime: '结束时间',
  51 + signMethod: '签到方式',
  52 + allowRecheck: '允许补检',
  53 + selectStaff: '选择员工',
  54 + save: '保存',
  55 + back: '返回',
  56 + required: '必填',
  57 + monthlyDaily: '月/天',
  58 + weekly: '按周',
  59 + notAllowed: '不允许补检',
  60 + allowed: '允许补检',
  61 + monday: '星期一',
  62 + tuesday: '星期二',
  63 + wednesday: '星期三',
  64 + thursday: '星期四',
  65 + friday: '星期五',
  66 + saturday: '星期六',
  67 + sunday: '星期日'
  68 + }
  69 + }
  70 +}
0 \ No newline at end of file 71 \ No newline at end of file
src/views/inspection/addInspectionPlanList.vue 0 → 100644
  1 +<template>
  2 + <div class="add-inspection-plan-container">
  3 + <el-card class="box-card">
  4 + <div slot="header">
  5 + <h5>{{ $t('addInspectionPlan.title') }}</h5>
  6 + </div>
  7 +
  8 + <el-form ref="form" :model="form" label-width="150px" label-position="right">
  9 + <el-row :gutter="20">
  10 + <el-col :span="12">
  11 + <el-form-item :label="$t('addInspectionPlan.planName')" prop="inspectionPlanName" required>
  12 + <el-input v-model="form.inspectionPlanName"
  13 + :placeholder="$t('addInspectionPlan.required') + $t('addInspectionPlan.planName')"></el-input>
  14 + </el-form-item>
  15 + </el-col>
  16 + <el-col :span="12">
  17 + <el-form-item :label="$t('addInspectionPlan.inspectionRoute')" prop="inspectionRouteId" required>
  18 + <el-select v-model="form.inspectionRouteId"
  19 + :placeholder="$t('addInspectionPlan.required') + $t('addInspectionPlan.inspectionRoute')"
  20 + style="width:100%" @change="changeInspectionPeriod">
  21 + <el-option v-for="item in inspectionRoutes" :key="item.inspectionRouteId" :label="item.routeName"
  22 + :value="item.inspectionRouteId"></el-option>
  23 + </el-select>
  24 + </el-form-item>
  25 + </el-col>
  26 + </el-row>
  27 +
  28 + <el-row :gutter="20">
  29 + <el-col :span="12">
  30 + <el-form-item :label="$t('addInspectionPlan.inspectionPeriod')" prop="inspectionPlanPeriod" required>
  31 + <el-select v-model="form.inspectionPlanPeriod"
  32 + :placeholder="$t('addInspectionPlan.required') + $t('addInspectionPlan.inspectionPeriod')"
  33 + style="width:100%" @change="changeInspectionPeriod">
  34 + <el-option v-for="item in inspectionPlanPeriods" :key="item.id" :label="item.name"
  35 + :value="item.statusCd"></el-option>
  36 + </el-select>
  37 + </el-form-item>
  38 + </el-col>
  39 + <el-col :span="12">
  40 + <el-form-item :label="$t('addInspectionPlan.taskAdvance')">
  41 + <el-input v-model="form.beforeTime" :placeholder="$t('addInspectionPlan.minutesGenerate')"
  42 + style="width: calc(100% - 100px); margin-right: 10px;"></el-input>
  43 + <span>{{ $t('addInspectionPlan.minutesGenerate') }}</span>
  44 + </el-form-item>
  45 + </el-col>
  46 + </el-row>
  47 +
  48 + <template v-if="form.inspectionPlanPeriod === '2020022'">
  49 + <el-row :gutter="20">
  50 + <el-col :span="24">
  51 + <el-form-item :label="$t('addInspectionPlan.month')">
  52 + <el-checkbox-group v-model="form.months">
  53 + <el-checkbox v-for="index in 12" :key="index" :label="index">{{ index }}{{ $t('addInspectionPlan.month')
  54 + }}</el-checkbox>
  55 + </el-checkbox-group>
  56 + </el-form-item>
  57 + </el-col>
  58 + </el-row>
  59 +
  60 + <el-row :gutter="20">
  61 + <el-col :span="24">
  62 + <el-form-item :label="$t('addInspectionPlan.day')">
  63 + <el-checkbox-group v-model="form.days">
  64 + <el-checkbox v-for="index in 31" :key="index" :label="index">{{ index }}{{ $t('addInspectionPlan.day')
  65 + }}</el-checkbox>
  66 + </el-checkbox-group>
  67 + </el-form-item>
  68 + </el-col>
  69 + </el-row>
  70 + </template>
  71 +
  72 + <template v-if="form.inspectionPlanPeriod === '2020023'">
  73 + <el-row :gutter="20">
  74 + <el-col :span="24">
  75 + <el-form-item :label="$t('addInspectionPlan.week')">
  76 + <el-checkbox-group v-model="form.workdays">
  77 + <el-checkbox :label="1">{{ $t('addInspectionPlan.monday') }}</el-checkbox>
  78 + <el-checkbox :label="2">{{ $t('addInspectionPlan.tuesday') }}</el-checkbox>
  79 + <el-checkbox :label="3">{{ $t('addInspectionPlan.wednesday') }}</el-checkbox>
  80 + <el-checkbox :label="4">{{ $t('addInspectionPlan.thursday') }}</el-checkbox>
  81 + <el-checkbox :label="5">{{ $t('addInspectionPlan.friday') }}</el-checkbox>
  82 + <el-checkbox :label="6">{{ $t('addInspectionPlan.saturday') }}</el-checkbox>
  83 + <el-checkbox :label="7">{{ $t('addInspectionPlan.sunday') }}</el-checkbox>
  84 + </el-checkbox-group>
  85 + </el-form-item>
  86 + </el-col>
  87 + </el-row>
  88 + </template>
  89 +
  90 + <el-row :gutter="20">
  91 + <el-col :span="12">
  92 + <el-form-item :label="$t('addInspectionPlan.startDate')" prop="startDate" required>
  93 + <el-date-picker v-model="form.startDate" type="date"
  94 + :placeholder="$t('addInspectionPlan.required') + $t('addInspectionPlan.startDate')"
  95 + value-format="yyyy-MM-dd" style="width:100%"></el-date-picker>
  96 + </el-form-item>
  97 + </el-col>
  98 + <el-col :span="12">
  99 + <el-form-item :label="$t('addInspectionPlan.endDate')" prop="endDate" required>
  100 + <el-date-picker v-model="form.endDate" type="date"
  101 + :placeholder="$t('addInspectionPlan.required') + $t('addInspectionPlan.endDate')"
  102 + value-format="yyyy-MM-dd" style="width:100%"></el-date-picker>
  103 + </el-form-item>
  104 + </el-col>
  105 + </el-row>
  106 +
  107 + <el-row :gutter="20">
  108 + <el-col :span="12">
  109 + <el-form-item :label="$t('addInspectionPlan.startTime')" prop="startTime" required>
  110 + <el-time-picker v-model="form.startTime"
  111 + :placeholder="$t('addInspectionPlan.required') + $t('addInspectionPlan.startTime')" value-format="HH:mm"
  112 + style="width:100%"></el-time-picker>
  113 + </el-form-item>
  114 + </el-col>
  115 + <el-col :span="12">
  116 + <el-form-item :label="$t('addInspectionPlan.endTime')" prop="endTime" required>
  117 + <el-time-picker v-model="form.endTime"
  118 + :placeholder="$t('addInspectionPlan.required') + $t('addInspectionPlan.endTime')" value-format="HH:mm"
  119 + style="width:100%"></el-time-picker>
  120 + </el-form-item>
  121 + </el-col>
  122 + </el-row>
  123 +
  124 + <el-row :gutter="20">
  125 + <el-col :span="12">
  126 + <el-form-item :label="$t('addInspectionPlan.signMethod')" prop="signType" required>
  127 + <el-select v-model="form.signType"
  128 + :placeholder="$t('addInspectionPlan.required') + $t('addInspectionPlan.signMethod')" style="width:100%">
  129 + <el-option v-for="item in signTypes" :key="item.statusCd" :label="item.name"
  130 + :value="item.statusCd"></el-option>
  131 + </el-select>
  132 + </el-form-item>
  133 + </el-col>
  134 + <el-col :span="12">
  135 + <el-form-item :label="$t('addInspectionPlan.allowRecheck')">
  136 + <el-select v-model="form.canReexamine" style="width:100%">
  137 + <el-option :label="$t('addInspectionPlan.notAllowed')" value="1000"></el-option>
  138 + <el-option :label="$t('addInspectionPlan.allowed')" value="2000"></el-option>
  139 + </el-select>
  140 + </el-form-item>
  141 + </el-col>
  142 + </el-row>
  143 +
  144 + <el-row :gutter="20">
  145 + <el-col :span="24">
  146 + <el-form-item :label="$t('addInspectionPlan.selectStaff')">
  147 + <select-staffs-div ref="selectStaffs" @selectStaffs="handleStaffSelected" />
  148 + </el-form-item>
  149 + </el-col>
  150 + </el-row>
  151 +
  152 + <el-row>
  153 + <el-col :span="24" class="text-right">
  154 + <el-button type="warning" @click="goBack">
  155 + <i class="el-icon-close"></i> {{ $t('addInspectionPlan.back') }}
  156 + </el-button>
  157 + <el-button type="primary" @click="saveInspectionPlan">
  158 + <i class="el-icon-check"></i> {{ $t('addInspectionPlan.save') }}
  159 + </el-button>
  160 + </el-col>
  161 + </el-row>
  162 + </el-form>
  163 + </el-card>
  164 + </div>
  165 +</template>
  166 +
  167 +<script>
  168 +import { listInspectionRoutes, saveInspectionPlan } from '@/api/inspection/addInspectionPlanApi'
  169 +import { getDict } from '@/api/community/communityApi'
  170 +import { getCommunityId } from '@/api/community/communityApi'
  171 +import SelectStaffsDiv from '@/components/staff/selectStaffsDiv'
  172 +
  173 +export default {
  174 + name: 'AddInspectionPlan',
  175 + components: {
  176 + SelectStaffsDiv
  177 + },
  178 + data() {
  179 + return {
  180 + form: {
  181 + inspectionPlanId: '',
  182 + inspectionPlanName: '',
  183 + inspectionRouteId: '',
  184 + inspectionPlanPeriod: '',
  185 + startDate: this.formatDate(new Date()),
  186 + endDate: '2050-01-01',
  187 + beforeTime: '30',
  188 + startTime: '',
  189 + endTime: '',
  190 + signType: '',
  191 + canReexamine: '1000',
  192 + state: '2020025',
  193 + remark: '',
  194 + months: Array.from({ length: 12 }, (_, i) => i + 1),
  195 + days: Array.from({ length: 31 }, (_, i) => i + 1),
  196 + workdays: Array.from({ length: 7 }, (_, i) => i + 1),
  197 + staffs: []
  198 + },
  199 + inspectionRoutes: [],
  200 + inspectionPlanPeriods: [],
  201 + signTypes: [],
  202 + communityId: ''
  203 + }
  204 + },
  205 + created() {
  206 + this.communityId = getCommunityId()
  207 + this.loadData()
  208 + },
  209 + methods: {
  210 + formatDate(date) {
  211 + const year = date.getFullYear()
  212 + const month = String(date.getMonth() + 1).padStart(2, '0')
  213 + const day = String(date.getDate()).padStart(2, '0')
  214 + return `${year}-${month}-${day}`
  215 + },
  216 + async loadData() {
  217 + try {
  218 + // 加载巡检路线
  219 + const params = {
  220 + communityId: this.communityId,
  221 + page: 1,
  222 + row: 100
  223 + }
  224 + this.inspectionRoutes = await listInspectionRoutes( params )
  225 +
  226 + // 加载字典数据
  227 + this.inspectionPlanPeriods = await getDict('inspection_plan', 'inspection_plan_period')
  228 + this.signTypes = await getDict('inspection_plan', 'sign_type')
  229 + } catch (error) {
  230 + console.error('加载数据失败:', error)
  231 + this.$message.error(this.$t('addInspectionPlan.fetchDataError'))
  232 + }
  233 + },
  234 + changeInspectionPeriod() {
  235 + console.log(this.form.inspectionPlanPeriod)
  236 + if (this.form.inspectionPlanPeriod === '2020022') {
  237 + this.form.months = Array.from({ length: 12 }, (_, i) => i + 1)
  238 + this.form.days = Array.from({ length: 31 }, (_, i) => i + 1)
  239 + } else if (this.form.inspectionPlanPeriod === '2020023') {
  240 + this.form.workdays = Array.from({ length: 7 }, (_, i) => i + 1)
  241 + }
  242 + },
  243 + handleStaffSelected(staffs) {
  244 + console.log(staffs)
  245 + this.form.staffs = staffs
  246 + },
  247 + validateForm() {
  248 + const requiredFields = [
  249 + 'inspectionPlanName',
  250 + 'inspectionRouteId',
  251 + 'inspectionPlanPeriod',
  252 + 'startDate',
  253 + 'endDate',
  254 + 'startTime',
  255 + 'endTime',
  256 + 'signType'
  257 + ]
  258 +
  259 + for (const field of requiredFields) {
  260 + if (!this.form[field]) {
  261 + this.$message.warning(this.$t('addInspectionPlan.required') + this.$t(`addInspectionPlan.${field}`))
  262 + return false
  263 + }
  264 + }
  265 +
  266 + if (new Date(this.form.startDate) > new Date(this.form.endDate)) {
  267 + this.$message.warning(this.$t('addInspectionPlan.startDateMustBeforeEndDate'))
  268 + return false
  269 + }
  270 +
  271 + return true
  272 + },
  273 + async saveInspectionPlan() {
  274 + if (!this.validateForm()) return
  275 +
  276 + try {
  277 + const formData = {
  278 + ...this.form,
  279 + communityId: this.communityId,
  280 + inspectionMonth: this.form.months.join(','),
  281 + inspectionDay: this.form.days.join(','),
  282 + inspectionWorkday: this.form.workdays.join(','),
  283 + staffs: this.form.staffs
  284 + }
  285 +
  286 + await saveInspectionPlan(formData)
  287 + this.$message.success(this.$t('addInspectionPlan.saveSuccess'))
  288 + this.goBack()
  289 + } catch (error) {
  290 + console.error('保存巡检计划失败:', error)
  291 + this.$message.error(error.message || this.$t('addInspectionPlan.saveError'))
  292 + }
  293 + },
  294 + goBack() {
  295 + this.$router.go(-1)
  296 + },
  297 + getWorkDay(index) {
  298 + const days = [
  299 + this.$t('addInspectionPlan.monday'),
  300 + this.$t('addInspectionPlan.tuesday'),
  301 + this.$t('addInspectionPlan.wednesday'),
  302 + this.$t('addInspectionPlan.thursday'),
  303 + this.$t('addInspectionPlan.friday'),
  304 + this.$t('addInspectionPlan.saturday'),
  305 + this.$t('addInspectionPlan.sunday')
  306 + ]
  307 + return days[index - 1] || ''
  308 + }
  309 + }
  310 +}
  311 +</script>
  312 +
  313 +<style scoped>
  314 +.add-inspection-plan-container {
  315 + padding: 20px;
  316 +}
  317 +
  318 +.box-card {
  319 + margin-bottom: 20px;
  320 +}
  321 +
  322 +.text-right {
  323 + text-align: right;
  324 +}
  325 +
  326 +.el-checkbox {
  327 + margin-right: 15px;
  328 +}
  329 +</style>
0 \ No newline at end of file 330 \ No newline at end of file
src/views/inspection/inspectionPlanLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + inspectionPlan: {
  4 + queryCondition: 'Query Conditions',
  5 + inspectionPlanIdPlaceholder: 'Please enter plan ID',
  6 + inspectionPlanNamePlaceholder: 'Please enter plan name',
  7 + staffNamePlaceholder: 'Please enter inspector name',
  8 + statePlaceholder: 'Please select status',
  9 + query: 'Search',
  10 + reset: 'Reset',
  11 + inspectionPlanTitle: 'Inspection Plan (Updated at 2:00 AM)',
  12 + add: 'Add',
  13 + planName: 'Plan Name',
  14 + planRoute: 'Plan Route',
  15 + planCycle: 'Plan Cycle',
  16 + signMethod: 'Sign-in Method',
  17 + dateRange: 'Date Range',
  18 + timeRange: 'Time Range',
  19 + taskAdvance: 'Task Advance (minutes)',
  20 + maker: 'Created By',
  21 + createTime: 'Created Time',
  22 + status: 'Status',
  23 + inspectionStaff: 'Inspection Staff',
  24 + operation: 'Operations',
  25 + modify: 'Edit',
  26 + delete: 'Delete',
  27 + disable: 'Disable',
  28 + enable: 'Enable',
  29 + detail: 'Details',
  30 + note: 'Please ensure the plan start and end times are valid and inspectors are assigned, otherwise inspection tasks cannot be generated.',
  31 + fetchError: 'Failed to fetch inspection plans',
  32 + confirmDeleteTitle: 'Confirm Deletion',
  33 + confirmDeleteContent: 'Are you sure you want to delete this inspection plan?',
  34 + cancel: 'Cancel',
  35 + confirm: 'Confirm'
  36 + },
  37 + editInspectionPlan: {
  38 + title: 'Edit Plan',
  39 + planName: 'Plan Name',
  40 + inspectionRoute: 'Inspection Route',
  41 + inspectionPeriod: 'Inspection Period',
  42 + taskAdvance: 'Task Advance',
  43 + minutesGenerate: 'minutes generate',
  44 + month: 'Month',
  45 + day: 'Day',
  46 + week: 'Week',
  47 + startDate: 'Start Date',
  48 + endDate: 'End Date',
  49 + startTime: 'Start Time',
  50 + endTime: 'End Time',
  51 + signMethod: 'Sign Method',
  52 + allowRecheck: 'Allow Recheck',
  53 + selectStaff: 'Select Staff',
  54 + save: 'Save',
  55 + back: 'Back',
  56 + required: 'Required',
  57 + monthlyDaily: 'Month/Day',
  58 + weekly: 'Weekly',
  59 + notAllowed: 'Not Allowed',
  60 + allowed: 'Allowed',
  61 + monday: 'Monday',
  62 + tuesday: 'Tuesday',
  63 + wednesday: 'Wednesday',
  64 + thursday: 'Thursday',
  65 + friday: 'Friday',
  66 + saturday: 'Saturday',
  67 + sunday: 'Sunday'
  68 + }
  69 + },
  70 + zh: {
  71 + inspectionPlan: {
  72 + queryCondition: '查询条件',
  73 + inspectionPlanIdPlaceholder: '请输入计划ID',
  74 + inspectionPlanNamePlaceholder: '请输入计划名称',
  75 + staffNamePlaceholder: '请输入巡检人',
  76 + statePlaceholder: '请选择状态',
  77 + query: '查询',
  78 + reset: '重置',
  79 + inspectionPlanTitle: '巡检计划(凌晨2点更新)',
  80 + add: '添加',
  81 + planName: '计划名称',
  82 + planRoute: '计划路线',
  83 + planCycle: '计划周期',
  84 + signMethod: '签到方式',
  85 + dateRange: '日期范围',
  86 + timeRange: '时间范围',
  87 + taskAdvance: '任务提前(分钟)',
  88 + maker: '制定人',
  89 + createTime: '制定时间',
  90 + status: '状态',
  91 + inspectionStaff: '巡检人员',
  92 + operation: '操作',
  93 + modify: '修改',
  94 + delete: '删除',
  95 + disable: '停用',
  96 + enable: '启用',
  97 + detail: '详情',
  98 + note: '请确保计划开始时间和计划结束时间是有效时间范围,并且设置了巡检人,不然无法生成巡检任务',
  99 + fetchError: '获取巡检计划失败',
  100 + confirmDeleteTitle: '确认删除',
  101 + confirmDeleteContent: '确定删除巡检计划吗?',
  102 + cancel: '取消',
  103 + confirm: '确定'
  104 + },
  105 + editInspectionPlan: {
  106 + title: '修改计划',
  107 + planName: '计划名称',
  108 + inspectionRoute: '巡检路线',
  109 + inspectionPeriod: '巡检周期',
  110 + taskAdvance: '任务提前',
  111 + minutesGenerate: '分钟生成',
  112 + month: '月',
  113 + day: '日',
  114 + week: '周',
  115 + startDate: '开始日期',
  116 + endDate: '结束日期',
  117 + startTime: '开始时间',
  118 + endTime: '结束时间',
  119 + signMethod: '签到方式',
  120 + allowRecheck: '允许补检',
  121 + selectStaff: '选择员工',
  122 + save: '保存',
  123 + back: '返回',
  124 + required: '必填',
  125 + monthlyDaily: '月/天',
  126 + weekly: '按周',
  127 + notAllowed: '不允许补检',
  128 + allowed: '允许补检',
  129 + monday: '星期一',
  130 + tuesday: '星期二',
  131 + wednesday: '星期三',
  132 + thursday: '星期四',
  133 + friday: '星期五',
  134 + saturday: '星期六',
  135 + sunday: '星期日'
  136 + }
  137 + }
  138 +}
0 \ No newline at end of file 139 \ No newline at end of file
src/views/inspection/inspectionPlanList.vue 0 → 100644
  1 +<template>
  2 + <div class="animated fadeInRight padding">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="flex justify-between">
  5 + <div>{{ $t('inspectionPlan.queryCondition') }}</div>
  6 + </div>
  7 + <div class="card-content">
  8 + <el-row :gutter="20">
  9 + <el-col :span="5">
  10 + <el-input
  11 + :placeholder="$t('inspectionPlan.inspectionPlanIdPlaceholder')"
  12 + v-model="searchConditions.inspectionPlanId"
  13 + clearable
  14 + />
  15 + </el-col>
  16 + <el-col :span="5">
  17 + <el-input
  18 + :placeholder="$t('inspectionPlan.inspectionPlanNamePlaceholder')"
  19 + v-model="searchConditions.inspectionPlanName"
  20 + clearable
  21 + />
  22 + </el-col>
  23 + <el-col :span="5">
  24 + <el-input
  25 + :placeholder="$t('inspectionPlan.staffNamePlaceholder')"
  26 + v-model="searchConditions.staffNameLike"
  27 + clearable
  28 + />
  29 + </el-col>
  30 + <el-col :span="5">
  31 + <el-select
  32 + v-model="searchConditions.state"
  33 + :placeholder="$t('inspectionPlan.statePlaceholder')"
  34 + style="width:100%"
  35 + >
  36 + <el-option
  37 + v-for="(item, index) in stateOptions"
  38 + :key="index"
  39 + :label="item.name"
  40 + :value="item.statusCd"
  41 + />
  42 + </el-select>
  43 + </el-col>
  44 + <el-col :span="4">
  45 + <el-button type="primary" @click="fetchInspectionPlans">
  46 + {{ $t('inspectionPlan.query') }}
  47 + </el-button>
  48 + <el-button @click="resetSearch">
  49 + {{ $t('inspectionPlan.reset') }}
  50 + </el-button>
  51 + </el-col>
  52 + </el-row>
  53 + </div>
  54 + </el-card>
  55 +
  56 + <el-card class="box-card margin-top">
  57 + <div slot="header" class="flex justify-between">
  58 + <div>{{ $t('inspectionPlan.inspectionPlanTitle') }}</div>
  59 + <div style="">
  60 + <el-button type="primary" size="small" @click="openAddModal">
  61 + {{ $t('inspectionPlan.add') }}
  62 + </el-button>
  63 + </div>
  64 + </div>
  65 + <el-table :data="planList" border style="width: 100%">
  66 + <el-table-column prop="inspectionPlanName" :label="$t('inspectionPlan.planName')" align="center" />
  67 + <el-table-column prop="inspectionRouteName" :label="$t('inspectionPlan.planRoute')" align="center" />
  68 + <el-table-column prop="inspectionPlanPeriodName" :label="$t('inspectionPlan.planCycle')" align="center" />
  69 + <el-table-column prop="signTypeName" :label="$t('inspectionPlan.signMethod')" align="center" />
  70 + <el-table-column :label="$t('inspectionPlan.dateRange')" align="center">
  71 + <template slot-scope="scope">
  72 + {{ scope.row.startDate }}~{{ scope.row.endDate }}
  73 + </template>
  74 + </el-table-column>
  75 + <el-table-column :label="$t('inspectionPlan.timeRange')" align="center">
  76 + <template slot-scope="scope">
  77 + {{ scope.row.startTime }}~{{ scope.row.endTime }}
  78 + </template>
  79 + </el-table-column>
  80 + <el-table-column prop="beforeTime" :label="$t('inspectionPlan.taskAdvance')" align="center" />
  81 + <el-table-column prop="createUserName" :label="$t('inspectionPlan.maker')" align="center" />
  82 + <el-table-column prop="createTime" :label="$t('inspectionPlan.createTime')" align="center" />
  83 + <el-table-column prop="stateName" :label="$t('inspectionPlan.status')" align="center" />
  84 + <el-table-column :label="$t('inspectionPlan.inspectionStaff')" align="center">
  85 + <template slot-scope="scope">
  86 + <div v-for="(staff, i) in scope.row.staffs" :key="i">
  87 + {{ staff.staffName }}
  88 + </div>
  89 + </template>
  90 + </el-table-column>
  91 + <el-table-column :label="$t('inspectionPlan.operation')" align="center" width="280">
  92 + <template slot-scope="scope">
  93 + <el-button-group>
  94 + <el-button size="mini" @click="openEditModal(scope.row)">
  95 + {{ $t('inspectionPlan.modify') }}
  96 + </el-button>
  97 + <el-button size="mini" @click="openDeleteModal(scope.row)">
  98 + {{ $t('inspectionPlan.delete') }}
  99 + </el-button>
  100 + <el-button
  101 + v-if="scope.row.state === '2020025'"
  102 + size="mini"
  103 + @click="openStateModal(scope.row, '2020026', $t('inspectionPlan.disable'))"
  104 + >
  105 + {{ $t('inspectionPlan.disable') }}
  106 + </el-button>
  107 + <el-button
  108 + v-else
  109 + size="mini"
  110 + @click="openStateModal(scope.row, '2020025', $t('inspectionPlan.enable'))"
  111 + >
  112 + {{ $t('inspectionPlan.enable') }}
  113 + </el-button>
  114 + <el-button size="mini" @click="viewDetail(scope.row)">
  115 + {{ $t('inspectionPlan.detail') }}
  116 + </el-button>
  117 + </el-button-group>
  118 + </template>
  119 + </el-table-column>
  120 + </el-table>
  121 +
  122 + <el-row class="margin-top">
  123 + <el-col :span="18">
  124 + <div>{{ $t('inspectionPlan.note') }}</div>
  125 + </el-col>
  126 + <el-col :span="6">
  127 + <el-pagination
  128 + :current-page.sync="pagination.current"
  129 + :page-sizes="[10, 20, 30, 50]"
  130 + :page-size="pagination.size"
  131 + layout="total, sizes, prev, pager, next"
  132 + :total="pagination.total"
  133 + @size-change="handleSizeChange"
  134 + @current-change="handlePageChange"
  135 + />
  136 + </el-col>
  137 + </el-row>
  138 + </el-card>
  139 +
  140 + <edit-inspection-plan ref="editModal" @success="handleSuccess" />
  141 + <delete-inspection-plan ref="deleteModal" @success="handleSuccess" />
  142 + <inspection-plan-state ref="stateModal" @success="handleSuccess" />
  143 + </div>
  144 +</template>
  145 +
  146 +<script>
  147 +import { listInspectionPlans } from '@/api/inspection/inspectionPlanApi'
  148 +import EditInspectionPlan from '@/components/inspection/editInspectionPlan'
  149 +import DeleteInspectionPlan from '@/components/inspection/deleteInspectionPlan'
  150 +import InspectionPlanState from '@/components/inspection/inspectionPlanState'
  151 +import {getDict} from '@/api/community/communityApi'
  152 +export default {
  153 + name: 'InspectionPlanList',
  154 + components: {
  155 + EditInspectionPlan,
  156 + DeleteInspectionPlan,
  157 + InspectionPlanState
  158 + },
  159 + data() {
  160 + return {
  161 + searchConditions: {
  162 + inspectionPlanId: '',
  163 + inspectionPlanName: '',
  164 + staffNameLike: '',
  165 + state: ''
  166 + },
  167 + planList: [],
  168 + stateOptions: [],
  169 + pagination: {
  170 + current: 1,
  171 + size: 10,
  172 + total: 0
  173 + }
  174 + }
  175 + },
  176 + async created() {
  177 + await this.loadDictData()
  178 + this.fetchInspectionPlans()
  179 + },
  180 + methods: {
  181 + async loadDictData() {
  182 + try {
  183 + this.stateOptions = await getDict('inspection_plan', 'state')
  184 + } catch (error) {
  185 + console.error('Failed to load dictionary data:', error)
  186 + }
  187 + },
  188 +
  189 + async fetchInspectionPlans() {
  190 + try {
  191 + const params = {
  192 + ...this.searchConditions,
  193 + page: this.pagination.current,
  194 + row: this.pagination.size
  195 + }
  196 +
  197 + const { data, total } = await listInspectionPlans(params)
  198 + this.planList = data
  199 + this.pagination.total = total
  200 + } catch (error) {
  201 + this.$message.error(this.$t('inspectionPlan.fetchError'))
  202 + }
  203 + },
  204 +
  205 + resetSearch() {
  206 + this.searchConditions = {
  207 + inspectionPlanId: '',
  208 + inspectionPlanName: '',
  209 + staffNameLike: '',
  210 + state: ''
  211 + }
  212 + this.pagination.current = 1
  213 + this.fetchInspectionPlans()
  214 + },
  215 +
  216 + handleSizeChange(size) {
  217 + this.pagination.size = size
  218 + this.fetchInspectionPlans()
  219 + },
  220 +
  221 + handlePageChange(page) {
  222 + this.pagination.current = page
  223 + this.fetchInspectionPlans()
  224 + },
  225 +
  226 + openAddModal() {
  227 + this.$router.push({ path: '/views/inspection/addInspectionPlan' })
  228 + },
  229 +
  230 + openEditModal(plan) {
  231 + this.$refs.editModal.open(plan)
  232 + },
  233 +
  234 + openDeleteModal(plan) {
  235 + this.$refs.deleteModal.open(plan)
  236 + },
  237 +
  238 + openStateModal(plan, state, stateName) {
  239 + this.$refs.stateModal.open({
  240 + inspectionPlanId: plan.inspectionPlanId,
  241 + state,
  242 + stateName
  243 + })
  244 + },
  245 +
  246 + viewDetail(plan) {
  247 + window.open(`/#/pages/inspection/inspectionPlanDetail?inspectionPlanId=${plan.inspectionPlanId}`)
  248 + },
  249 +
  250 + handleSuccess() {
  251 + this.fetchInspectionPlans()
  252 + }
  253 + }
  254 +}
  255 +</script>
  256 +
  257 +<style scoped>
  258 +.margin-top {
  259 + margin-top: 20px;
  260 +}
  261 +.card-content {
  262 + padding: 20px;
  263 +}
  264 +</style>
0 \ No newline at end of file 265 \ No newline at end of file
src/views/inspection/inspectionTaskDetailsLang.js 0 → 100644
  1 +
  2 +export const messages = {
  3 + en: {
  4 + inspectionTaskDetails: {
  5 + searchCondition: 'Search Condition',
  6 + more: 'More',
  7 + hide: 'Hide',
  8 + inputInspector: 'Please enter inspector',
  9 + inputStartTime: 'Please enter actual inspection start time',
  10 + inputEndTime: 'Please enter actual inspection end time',
  11 + search: 'Search',
  12 + reset: 'Reset',
  13 + selectInspectionPlan: 'Please select inspection plan',
  14 + selectInspectionRoute: 'Please select inspection route',
  15 + selectInspectionPoint: 'Please select inspection point',
  16 + inputTaskDetailId: 'Please enter task detail ID',
  17 + selectSignStatus: 'Please select sign status',
  18 + selectInspectionPointStatus: 'Please select inspection point status',
  19 + selectTaskStatus: 'Please select task status',
  20 + selectPatrolStatus: 'Please select patrol status',
  21 + inspectionDetails: 'Inspection Details',
  22 + export: 'Export',
  23 + taskDetailId: 'Task Detail ID',
  24 + inspectionPointName: 'Inspection Point Name',
  25 + inspectionPlanName: 'Inspection Plan Name',
  26 + inspectionRouteName: 'Inspection Route Name',
  27 + inspector: 'Inspector',
  28 + startEndTime: 'Start/End Time',
  29 + inspectionPoint: 'Inspection Point',
  30 + actualInspectionTime: 'Actual Inspection Time',
  31 + actualSignStatus: 'Actual Sign Status',
  32 + plannedInspector: 'Planned Inspector',
  33 + actualInspector: 'Actual Inspector',
  34 + inspectionMethod: 'Inspection Method',
  35 + taskStatus: 'Task Status',
  36 + inspectionPointStatus: 'Inspection Point Status',
  37 + patrolStatus: 'Patrol Status',
  38 + inspectionPhotos: 'Inspection Photos',
  39 + createTime: 'Create Time',
  40 + locationInfo: 'Location Info',
  41 + view: 'View'
  42 + }
  43 + },
  44 + zh: {
  45 + inspectionTaskDetails: {
  46 + searchCondition: '查询条件',
  47 + more: '更多',
  48 + hide: '隐藏',
  49 + inputInspector: '请输入巡检人',
  50 + inputStartTime: '请输入实际巡检开始时间',
  51 + inputEndTime: '请输入实际巡检结束时间',
  52 + search: '查询',
  53 + reset: '重置',
  54 + selectInspectionPlan: '请选择巡检计划',
  55 + selectInspectionRoute: '请选择巡检路线',
  56 + selectInspectionPoint: '请选择巡检点',
  57 + inputTaskDetailId: '请输入任务详情ID',
  58 + selectSignStatus: '请选择签到状态',
  59 + selectInspectionPointStatus: '请选择巡检点状态',
  60 + selectTaskStatus: '请选择任务状态',
  61 + selectPatrolStatus: '请选择巡检情况',
  62 + inspectionDetails: '巡检明细',
  63 + export: '导出',
  64 + taskDetailId: '任务详情ID',
  65 + inspectionPointName: '巡检点名称',
  66 + inspectionPlanName: '巡检计划名称',
  67 + inspectionRouteName: '巡检路线名称',
  68 + inspector: '巡检人',
  69 + startEndTime: '开始/结束时间',
  70 + inspectionPoint: '巡检点',
  71 + actualInspectionTime: '实际巡检时间',
  72 + actualSignStatus: '实际签到状态',
  73 + plannedInspector: '计划巡检人',
  74 + actualInspector: '实际巡检人',
  75 + inspectionMethod: '巡检方式',
  76 + taskStatus: '任务状态',
  77 + inspectionPointStatus: '巡检点状态',
  78 + patrolStatus: '巡检情况',
  79 + inspectionPhotos: '巡检照片',
  80 + createTime: '创建时间',
  81 + locationInfo: '位置信息',
  82 + view: '查看'
  83 + }
  84 + }
  85 +}
0 \ No newline at end of file 86 \ No newline at end of file
src/views/inspection/inspectionTaskDetailsList.vue 0 → 100644
  1 +<template>
  2 + <div class="padding">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="flex justify-between">
  5 + <div>{{ $t('inspectionTaskDetails.searchCondition') }}</div>
  6 + <div class="" >
  7 + <el-button type="text" @click="toggleMoreCondition">
  8 + {{ inspectionTaskDetailManageInfo.moreCondition ? $t('inspectionTaskDetails.hide') :
  9 + $t('inspectionTaskDetails.more') }}
  10 + </el-button>
  11 + </div>
  12 + </div>
  13 + <div class="">
  14 + <el-row :gutter="20">
  15 + <el-col :span="6">
  16 + <div class="form-group">
  17 + <el-input :placeholder="$t('inspectionTaskDetails.inputInspector')"
  18 + v-model="inspectionTaskDetailManageInfo.conditions.planUserName" clearable></el-input>
  19 + </div>
  20 + </el-col>
  21 + <el-col :span="6">
  22 + <div class="form-group">
  23 + <el-date-picker v-model="inspectionTaskDetailManageInfo.conditions.inspectionStartTime" type="datetime"
  24 + :placeholder="$t('inspectionTaskDetails.inputStartTime')" value-format="yyyy-MM-dd HH:mm:ss"
  25 + style="width:100%"></el-date-picker>
  26 + </div>
  27 + </el-col>
  28 + <el-col :span="6">
  29 + <div class="form-group">
  30 + <el-date-picker v-model="inspectionTaskDetailManageInfo.conditions.inspectionEndTime" type="datetime"
  31 + :placeholder="$t('inspectionTaskDetails.inputEndTime')" value-format="yyyy-MM-dd HH:mm:ss"
  32 + style="width:100%"></el-date-picker>
  33 + </div>
  34 + </el-col>
  35 + <el-col :span="6">
  36 + <el-button type="primary" @click="queryInspectionTaskMethod">
  37 + <i class="el-icon-search"></i>
  38 + <span>{{ $t('inspectionTaskDetails.search') }}</span>
  39 + </el-button>
  40 + <el-button type="primary" @click="resetInspectionTaskMethod">
  41 + <i class="el-icon-refresh"></i>
  42 + <span>{{ $t('inspectionTaskDetails.reset') }}</span>
  43 + </el-button>
  44 + </el-col>
  45 + </el-row>
  46 +
  47 + <div v-show="inspectionTaskDetailManageInfo.moreCondition">
  48 + <el-row :gutter="20">
  49 + <el-col :span="8">
  50 + <el-select v-model="inspectionTaskDetailManageInfo.conditions.inspectionPlanId"
  51 + :placeholder="$t('inspectionTaskDetails.selectInspectionPlan')" style="width:100%">
  52 + <el-option v-for="(item, index) in inspectionTaskDetailManageInfo.inspectionPlanList" :key="index"
  53 + :label="item.inspectionPlanName" :value="item.inspectionPlanId"></el-option>
  54 + </el-select>
  55 + </el-col>
  56 + <el-col :span="8">
  57 + <el-select v-model="inspectionTaskDetailManageInfo.conditions.inspectionRouteId"
  58 + :placeholder="$t('inspectionTaskDetails.selectInspectionRoute')" style="width:100%">
  59 + <el-option v-for="(item, index) in inspectionTaskDetailManageInfo.inspectionRouteList" :key="index"
  60 + :label="item.routeName" :value="item.inspectionRouteId"></el-option>
  61 + </el-select>
  62 + </el-col>
  63 + <el-col :span="8">
  64 + <el-select v-model="inspectionTaskDetailManageInfo.conditions.inspectionId"
  65 + :placeholder="$t('inspectionTaskDetails.selectInspectionPoint')" style="width:100%">
  66 + <el-option v-for="(item, index) in inspectionTaskDetailManageInfo.inspectionPointList" :key="index"
  67 + :label="item.inspectionName" :value="item.inspectionId"></el-option>
  68 + </el-select>
  69 + </el-col>
  70 + </el-row>
  71 +
  72 + <el-row :gutter="20" class="margin-top">
  73 + <el-col :span="8">
  74 + <div class="form-group">
  75 + <el-input :placeholder="$t('inspectionTaskDetails.inputTaskDetailId')"
  76 + v-model="inspectionTaskDetailManageInfo.conditions.taskDetailId" clearable></el-input>
  77 + </div>
  78 + </el-col>
  79 + <el-col :span="8">
  80 + <el-select v-model="inspectionTaskDetailManageInfo.conditions.inspectionState"
  81 + :placeholder="$t('inspectionTaskDetails.selectSignStatus')" style="width:100%">
  82 + <el-option v-for="(item, index) in inspectionTaskDetailManageInfo.inspectionStateTypes" :key="index"
  83 + :label="item.name" :value="item.statusCd"></el-option>
  84 + </el-select>
  85 + </el-col>
  86 + <el-col :span="8">
  87 + <el-select v-model="inspectionTaskDetailManageInfo.conditions.state"
  88 + :placeholder="$t('inspectionTaskDetails.selectInspectionPointStatus')" style="width:100%">
  89 + <el-option v-for="(item, index) in inspectionTaskDetailManageInfo.stateTypes" :key="index"
  90 + :label="item.name" :value="item.statusCd"></el-option>
  91 + </el-select>
  92 + </el-col>
  93 + </el-row>
  94 +
  95 + <el-row :gutter="20">
  96 + <el-col :span="8">
  97 + <el-select v-model="inspectionTaskDetailManageInfo.conditions.taskState"
  98 + :placeholder="$t('inspectionTaskDetails.selectTaskStatus')" style="width:100%">
  99 + <el-option v-for="(item, index) in inspectionTaskDetailManageInfo.taskStates" :key="index"
  100 + :label="item.name" :value="item.statusCd"></el-option>
  101 + </el-select>
  102 + </el-col>
  103 + <el-col :span="8">
  104 + <el-select v-model="inspectionTaskDetailManageInfo.conditions.patrolType"
  105 + :placeholder="$t('inspectionTaskDetails.selectPatrolStatus')" style="width:100%">
  106 + <el-option v-for="(item, index) in inspectionTaskDetailManageInfo.patrolTypes" :key="index"
  107 + :label="item.name" :value="item.statusCd"></el-option>
  108 + </el-select>
  109 + </el-col>
  110 + </el-row>
  111 + </div>
  112 + </div>
  113 + </el-card>
  114 +
  115 + <el-card class="box-card margin-top">
  116 + <div slot="header" class="flex justify-between">
  117 + <div>{{ $t('inspectionTaskDetails.inspectionDetails') }}</div>
  118 + <div class="ibox-tools" style="top:10px;">
  119 + <el-button type="primary" size="small" @click="exportExcel">
  120 + <i class="el-icon-download"></i>
  121 + <span>{{ $t('inspectionTaskDetails.export') }}</span>
  122 + </el-button>
  123 + </div>
  124 + </div>
  125 + <div class="ibox-content">
  126 + <el-table :data="inspectionTaskDetailManageInfo.inspectionTasks" border style="width: 100%" v-loading="loading">
  127 + <el-table-column prop="taskDetailId" :label="$t('inspectionTaskDetails.taskDetailId')"
  128 + align="center"></el-table-column>
  129 + <el-table-column prop="inspectionName" :label="$t('inspectionTaskDetails.inspectionPointName')"
  130 + align="center"></el-table-column>
  131 + <el-table-column prop="inspectionPlanName" :label="$t('inspectionTaskDetails.inspectionPlanName')"
  132 + align="center"></el-table-column>
  133 + <el-table-column prop="routeName" :label="$t('inspectionTaskDetails.inspectionRouteName')"
  134 + align="center"></el-table-column>
  135 +
  136 + <el-table-column :label="$t('inspectionTaskDetails.inspector')" align="center">
  137 + <template slot-scope="scope">
  138 + {{ scope.row.planInsTime }}<br />{{ scope.row.planEndTime }}
  139 + </template>
  140 + </el-table-column>
  141 +
  142 + <el-table-column :label="$t('inspectionTaskDetails.inspectionPoint')" align="center">
  143 + <template slot-scope="scope">
  144 + {{ scope.row.pointStartTime }}<br />{{ scope.row.pointEndTime }}
  145 + </template>
  146 + </el-table-column>
  147 +
  148 + <el-table-column prop="inspectionTime" :label="$t('inspectionTaskDetails.actualInspectionTime')" align="center">
  149 + <template slot-scope="scope">
  150 + {{ scope.row.inspectionTime || '-' }}
  151 + </template>
  152 + </el-table-column>
  153 +
  154 + <el-table-column :label="$t('inspectionTaskDetails.actualSignStatus')" align="center">
  155 + <template slot-scope="scope">
  156 + <span v-if="scope.row.inspectionState == '60000'" class="text-primary">
  157 + {{ scope.row.inspectionStateName || '-' }}
  158 + </span>
  159 + <span v-else class="text-danger">
  160 + {{ scope.row.inspectionStateName || '-' }}
  161 + </span>
  162 + </template>
  163 + </el-table-column>
  164 +
  165 + <el-table-column prop="planUserName" :label="$t('inspectionTaskDetails.plannedInspector')"
  166 + align="center"></el-table-column>
  167 +
  168 + <el-table-column :label="$t('inspectionTaskDetails.actualInspector')" align="center">
  169 + <template slot-scope="scope">
  170 + {{ scope.row.actUserName || '-' }}
  171 + </template>
  172 + </el-table-column>
  173 +
  174 + <el-table-column prop="signTypeName" :label="$t('inspectionTaskDetails.inspectionMethod')"
  175 + align="center"></el-table-column>
  176 + <el-table-column prop="taskStateName" :label="$t('inspectionTaskDetails.taskStatus')"
  177 + align="center"></el-table-column>
  178 +
  179 + <el-table-column :label="$t('inspectionTaskDetails.inspectionPointStatus')" align="center">
  180 + <template slot-scope="scope">
  181 + <span v-if="scope.row.state == '20200408'" class="text-danger">
  182 + {{ scope.row.stateName }}
  183 + </span>
  184 + <span v-else>
  185 + {{ scope.row.stateName }}
  186 + </span>
  187 + </template>
  188 + </el-table-column>
  189 +
  190 + <el-table-column :label="$t('inspectionTaskDetails.patrolStatus')" align="center">
  191 + <template slot-scope="scope">
  192 + <span class="text-primary">
  193 + {{ scope.row.description || '-' }}
  194 + </span>
  195 + </template>
  196 + </el-table-column>
  197 +
  198 + <el-table-column :label="$t('inspectionTaskDetails.inspectionPhotos')" align="center">
  199 + <template slot-scope="scope">
  200 + <span v-for="_photo in scope.row.photos" :key="_photo.url">
  201 + <el-image style="width: 60px; height: 60px; margin-right: 5px;" :src="_photo.url"
  202 + :preview-src-list="[_photo.url]" fit="cover"></el-image>
  203 + </span>
  204 + </template>
  205 + </el-table-column>
  206 +
  207 + <el-table-column prop="createTime" :label="$t('inspectionTaskDetails.createTime')"
  208 + align="center"></el-table-column>
  209 +
  210 + <el-table-column :label="$t('inspectionTaskDetails.locationInfo')" align="center" width="100">
  211 + <template slot-scope="scope">
  212 + <el-button type="primary" size="mini" @click="openMap(scope.row.latitude, scope.row.longitude)">
  213 + {{ $t('inspectionTaskDetails.view') }}
  214 + </el-button>
  215 + </template>
  216 + </el-table-column>
  217 + </el-table>
  218 +
  219 + <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
  220 + :current-page="inspectionTaskDetailManageInfo.conditions.page" :page-sizes="[10, 20, 30, 50]"
  221 + :page-size="inspectionTaskDetailManageInfo.conditions.row" layout="total, sizes, prev, pager, next, jumper"
  222 + :total="inspectionTaskDetailManageInfo.total" class="pagination-container"></el-pagination>
  223 + </div>
  224 + </el-card>
  225 +
  226 + <view-map ref="viewMap"></view-map>
  227 + <view-image ref="viewImage"></view-image>
  228 + </div>
  229 +</template>
  230 +
  231 +<script>
  232 +import { listInspectionTaskDetails, exportInspectionTaskDetails } from '@/api/inspection/inspectionTaskDetailsApi'
  233 +import { getDict } from '@/api/community/communityApi'
  234 +import { getCommunityId } from '@/api/community/communityApi'
  235 +import ViewMap from '@/components/system/ViewMap'
  236 +import ViewImage from '@/components/system/viewImage'
  237 +
  238 +export default {
  239 + name: 'InspectionTaskDetailsList',
  240 + components: {
  241 + ViewMap,
  242 + ViewImage
  243 + },
  244 + data() {
  245 + return {
  246 + loading: false,
  247 + inspectionTaskDetailManageInfo: {
  248 + inspectionTasks: [],
  249 + total: 0,
  250 + records: 1,
  251 + moreCondition: false,
  252 + stateTypes: [],
  253 + inspectionStateTypes: [],
  254 + taskStates: [],
  255 + patrolTypes: [],
  256 + inspectionPointList: [],
  257 + inspectionPlanList: [],
  258 + inspectionRouteList: [],
  259 + conditions: {
  260 + planUserName: '',
  261 + taskDetailId: '',
  262 + inspectionPlanName: '',
  263 + inspectionStartTime: '',
  264 + inspectionEndTime: '',
  265 + state: '',
  266 + inspectionState: '',
  267 + inspectionId: '',
  268 + inspectionPlanId: '',
  269 + inspectionRouteId: '',
  270 + taskState: '',
  271 + patrolType: '',
  272 + page: 1,
  273 + row: 10,
  274 + communityId: ''
  275 + }
  276 + }
  277 + }
  278 + },
  279 + created() {
  280 + this.communityId = getCommunityId()
  281 + this.initData()
  282 + },
  283 + methods: {
  284 + async initData() {
  285 + this.loading = true
  286 + try {
  287 + await this.getDictData()
  288 + await this.listInspectionTasksDetailList()
  289 + await this.listInspectionPlanInfo()
  290 + await this.listInspectionRouteInfo()
  291 + await this.listInspectionPointInfo()
  292 + } catch (error) {
  293 + console.error('初始化数据失败:', error)
  294 + this.$message.error(this.$t('common.error'))
  295 + } finally {
  296 + this.loading = false
  297 + }
  298 + },
  299 +
  300 + async getDictData() {
  301 + try {
  302 + const [stateTypes, inspectionStateTypes, taskStates, patrolTypes] = await Promise.all([
  303 + getDict('inspection_task', 'state'),
  304 + getDict('inspection_task_detail', 'inspection_state'),
  305 + getDict('inspection_task_detail', 'state'),
  306 + getDict('inspection_task_detail', 'patrol_type')
  307 + ])
  308 +
  309 + this.inspectionTaskDetailManageInfo.stateTypes = stateTypes
  310 + this.inspectionTaskDetailManageInfo.inspectionStateTypes = inspectionStateTypes
  311 + this.inspectionTaskDetailManageInfo.taskStates = taskStates
  312 + this.inspectionTaskDetailManageInfo.patrolTypes = patrolTypes
  313 + } catch (error) {
  314 + console.error('获取字典数据失败:', error)
  315 + }
  316 + },
  317 +
  318 + async listInspectionTasksDetailList() {
  319 + try {
  320 + this.inspectionTaskDetailManageInfo.conditions.communityId = this.communityId
  321 + const res = await listInspectionTaskDetails(this.inspectionTaskDetailManageInfo.conditions)
  322 + this.inspectionTaskDetailManageInfo.total = res.total
  323 + this.inspectionTaskDetailManageInfo.records = res.records
  324 + this.inspectionTaskDetailManageInfo.inspectionTasks = res.inspectionTaskDetails
  325 + } catch (error) {
  326 + console.error('获取巡检任务明细列表失败:', error)
  327 + this.$message.error(this.$t('common.error'))
  328 + }
  329 + },
  330 +
  331 + async listInspectionPlanInfo() {
  332 + try {
  333 + const params = {
  334 + communityId: this.communityId,
  335 + page: 1,
  336 + row: 200
  337 + }
  338 + const res = await listInspectionTaskDetails(params)
  339 + this.inspectionTaskDetailManageInfo.inspectionPlanList = res.data.data
  340 + } catch (error) {
  341 + console.error('获取巡检计划列表失败:', error)
  342 + }
  343 + },
  344 +
  345 + async listInspectionRouteInfo() {
  346 + try {
  347 + const params = {
  348 + communityId: this.communityId,
  349 + page: 1,
  350 + row: 200
  351 + }
  352 + const res = await listInspectionTaskDetails(params)
  353 + this.inspectionTaskDetailManageInfo.inspectionRouteList = res.data.inspectionRoutes
  354 + } catch (error) {
  355 + console.error('获取巡检路线列表失败:', error)
  356 + }
  357 + },
  358 +
  359 + async listInspectionPointInfo() {
  360 + try {
  361 + const params = {
  362 + communityId: this.communityId,
  363 + page: 1,
  364 + row: 200
  365 + }
  366 + const res = await listInspectionTaskDetails(params)
  367 + this.inspectionTaskDetailManageInfo.inspectionPointList = res.data.inspectionPoints
  368 + } catch (error) {
  369 + console.error('获取巡检点列表失败:', error)
  370 + }
  371 + },
  372 +
  373 + queryInspectionTaskMethod() {
  374 + this.inspectionTaskDetailManageInfo.conditions.page = 1
  375 + this.listInspectionTasksDetailList()
  376 + },
  377 +
  378 + resetInspectionTaskMethod() {
  379 + this.inspectionTaskDetailManageInfo.conditions = {
  380 + planUserName: '',
  381 + taskDetailId: '',
  382 + inspectionPlanName: '',
  383 + inspectionStartTime: '',
  384 + inspectionEndTime: '',
  385 + state: '',
  386 + inspectionState: '',
  387 + inspectionId: '',
  388 + inspectionPlanId: '',
  389 + inspectionRouteId: '',
  390 + taskState: '',
  391 + patrolType: '',
  392 + page: 1,
  393 + row: 10,
  394 + communityId: this.communityId
  395 + }
  396 + this.listInspectionTasksDetailList()
  397 + },
  398 +
  399 + toggleMoreCondition() {
  400 + this.inspectionTaskDetailManageInfo.moreCondition = !this.inspectionTaskDetailManageInfo.moreCondition
  401 + },
  402 +
  403 + handleSizeChange(val) {
  404 + this.inspectionTaskDetailManageInfo.conditions.row = val
  405 + this.listInspectionTasksDetailList()
  406 + },
  407 +
  408 + handleCurrentChange(val) {
  409 + this.inspectionTaskDetailManageInfo.conditions.page = val
  410 + this.listInspectionTasksDetailList()
  411 + },
  412 +
  413 + openFile(photo) {
  414 + this.$refs.viewImage.open(photo.url)
  415 + },
  416 +
  417 + openMap(lat, lng) {
  418 + this.$refs.viewMap.open(lat, lng)
  419 + },
  420 +
  421 + async exportExcel() {
  422 + try {
  423 + const params = {
  424 + ...this.inspectionTaskDetailManageInfo.conditions,
  425 + pagePath: 'inspectionTaskDetails'
  426 + }
  427 + const res = await exportInspectionTaskDetails(params)
  428 + if (res.code === 0) {
  429 + this.$message.success(this.$t('common.exportSuccess'))
  430 + // 这里需要根据实际项目调整跳转逻辑
  431 + this.$router.push({ path: '/pages/property/downloadTempFile', query: { tab: this.$t('common.downloadCenter') } })
  432 + } else {
  433 + this.$message.error(res.msg || this.$t('common.exportFail'))
  434 + }
  435 + } catch (error) {
  436 + console.error('导出失败:', error)
  437 + this.$message.error(this.$t('common.exportFail'))
  438 + }
  439 + }
  440 + }
  441 +}
  442 +</script>
  443 +
  444 +<style scoped>
  445 +.text-primary {
  446 + color: #409EFF;
  447 +}
  448 +
  449 +.text-danger {
  450 + color: #F56C6C;
  451 +}
  452 +
  453 +.margin-top {
  454 + margin-top: 20px;
  455 +}
  456 +
  457 +.pagination-container {
  458 + margin-top: 20px;
  459 + text-align: right;
  460 +}
  461 +</style>
0 \ No newline at end of file 462 \ No newline at end of file
src/views/inspection/inspectionTaskLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + inspectionTask: {
  4 + queryConditions: 'Query Conditions',
  5 + executor: 'Executor',
  6 + actualStartTime: 'Actual Inspection Start Time',
  7 + actualEndTime: 'Actual Inspection End Time',
  8 + inspectionStatus: 'Inspection Status',
  9 + query: 'Query',
  10 + reset: 'Reset',
  11 + inspectionTask: 'Inspection Task',
  12 + taskCode: 'Task Code',
  13 + inspectionPlan: 'Inspection Plan',
  14 + inspectorTime: 'Inspector/Start-End Time',
  15 + actualTime: 'Actual Inspection Time',
  16 + plannedInspector: 'Planned Inspector',
  17 + currentInspector: 'Current Inspector',
  18 + transferDesc: 'Transfer Description',
  19 + inspectionMethod: 'Inspection Method',
  20 + operation: 'Operation',
  21 + flow: 'Flow',
  22 + detail: 'Detail',
  23 + delete: 'Delete',
  24 + note: 'Inspection tasks are automatically generated every day at 2 AM based on inspection plans. If not generated, please confirm whether the scheduled task is enabled or if the inspection plan is set correctly.'
  25 + },
  26 + inspectionTaskDetail: {
  27 + taskDetails: 'Task Details',
  28 + inspectionPoint: 'Inspection Point',
  29 + inspectionStatus: 'Inspection Status',
  30 + signStatus: 'Sign Status',
  31 + inspectorTime: 'Inspector/Start-End Time',
  32 + pointTime: 'Point Start/End Time',
  33 + actualTime: 'Actual Inspection Time',
  34 + inspectionSituation: 'Inspection Situation',
  35 + inspectionPhotos: 'Inspection Photos',
  36 + locationInfo: 'Location Info',
  37 + view: 'View',
  38 + start: 'Start',
  39 + end: 'End'
  40 + },
  41 + inspectionTaskTransfer: {
  42 + transfer: 'Transfer',
  43 + transferObject: 'Transfer Object',
  44 + transferDesc: 'Transfer Description',
  45 + required: 'Required, please fill in',
  46 + submit: 'Submit',
  47 + cancel: 'Cancel'
  48 + },
  49 + deleteInspectionTask: {
  50 + confirmOperation: 'Please confirm your operation',
  51 + confirmDelete: 'Confirm deletion of inspection task',
  52 + mistake: 'Mistake',
  53 + confirmDeleteBtn: 'Confirm Delete'
  54 + }
  55 + },
  56 + zh: {
  57 + inspectionTask: {
  58 + queryConditions: '查询条件',
  59 + executor: '执行人',
  60 + actualStartTime: '实际巡检开始时间',
  61 + actualEndTime: '实际巡检结束时间',
  62 + inspectionStatus: '巡检状态',
  63 + query: '查询',
  64 + reset: '重置',
  65 + inspectionTask: '巡检任务',
  66 + taskCode: '任务编码',
  67 + inspectionPlan: '巡检计划',
  68 + inspectorTime: '巡检人/开始结束时间',
  69 + actualTime: '实际巡检时间',
  70 + plannedInspector: '计划巡检人',
  71 + currentInspector: '当前巡检人',
  72 + transferDesc: '转移描述',
  73 + inspectionMethod: '巡检方式',
  74 + operation: '操作',
  75 + flow: '流转',
  76 + detail: '详情',
  77 + delete: '删除',
  78 + note: '巡检任务是根据巡检计划,每天晚上2点钟自动生成,如果没有生成 请确认是否开启了定时任务,或者巡检计划是否设置正确'
  79 + },
  80 + inspectionTaskDetail: {
  81 + taskDetails: '任务详情',
  82 + inspectionPoint: '巡检点',
  83 + inspectionStatus: '巡检状态',
  84 + signStatus: '签到状态',
  85 + inspectorTime: '巡检人/开始结束时间',
  86 + pointTime: '巡检点开始结束时间',
  87 + actualTime: '实际巡检时间',
  88 + inspectionSituation: '巡检情况',
  89 + inspectionPhotos: '巡检照片',
  90 + locationInfo: '位置信息',
  91 + view: '查看',
  92 + start: '开始',
  93 + end: '结束'
  94 + },
  95 + inspectionTaskTransfer: {
  96 + transfer: '流转',
  97 + transferObject: '流转对象',
  98 + transferDesc: '流转说明',
  99 + required: '必填,请填写',
  100 + submit: '提交',
  101 + cancel: '取消'
  102 + },
  103 + deleteInspectionTask: {
  104 + confirmOperation: '请确认您的操作',
  105 + confirmDelete: '确定删除巡检任务',
  106 + mistake: '点错了',
  107 + confirmDeleteBtn: '确认删除'
  108 + }
  109 + }
  110 +}
0 \ No newline at end of file 111 \ No newline at end of file
src/views/inspection/pointPlanLang.js 0 → 100644
  1 +export default {
  2 + en: {
  3 + inspectionPlan: {
  4 + planName: 'Plan Name',
  5 + planRoute: 'Plan Route',
  6 + planPeriod: 'Plan Cycle',
  7 + signType: 'Sign-in Method',
  8 + dateRange: 'Date Range',
  9 + timeRange: 'Time Range',
  10 + taskAhead: 'Task Ahead (minutes)',
  11 + creator: 'Creator',
  12 + createTime: 'Create Time',
  13 + inspector: 'Inspector',
  14 + status: 'Status'
  15 + }
  16 + },
  17 + zh: {
  18 + inspectionPlan: {
  19 + planName: '计划名称',
  20 + planRoute: '计划路线',
  21 + planPeriod: '计划周期',
  22 + signType: '签到方式',
  23 + dateRange: '日期范围',
  24 + timeRange: '时间范围',
  25 + taskAhead: '任务提前(分钟)',
  26 + creator: '制定人',
  27 + createTime: '制定时间',
  28 + inspector: '巡检人',
  29 + status: '状态'
  30 + }
  31 + }
  32 +}
0 \ No newline at end of file 33 \ No newline at end of file
src/views/work/repairTypeUserLang.js
@@ -15,7 +15,8 @@ export const messages = { @@ -15,7 +15,8 @@ export const messages = {
15 title: 'Select Staff', 15 title: 'Select Staff',
16 orgInfo: 'Organization Information', 16 orgInfo: 'Organization Information',
17 staffInfo: 'Staff Information', 17 staffInfo: 'Staff Information',
18 - selectStaffFirst: 'Please select a staff first' 18 + selectStaffFirst: 'Please select a staff first',
  19 + selectedStaff: 'Selected Staff'
19 }, 20 },
20 deleteRepairTypeUser: { 21 deleteRepairTypeUser: {
21 title: 'Confirm Operation', 22 title: 'Confirm Operation',
@@ -47,7 +48,8 @@ export const messages = { @@ -47,7 +48,8 @@ export const messages = {
47 title: '选择员工', 48 title: '选择员工',
48 orgInfo: '组织信息', 49 orgInfo: '组织信息',
49 staffInfo: '员工信息', 50 staffInfo: '员工信息',
50 - selectStaffFirst: '请先选择员工' 51 + selectStaffFirst: '请先选择员工',
  52 + selectedStaff: '已选择员工'
51 }, 53 },
52 deleteRepairTypeUser: { 54 deleteRepairTypeUser: {
53 title: '请确认您的操作', 55 title: '请确认您的操作',