Commit e0196f8a45fe3008ee10107b3520d9b9fe057601

Authored by wuxw
1 parent 2e540c8d

开发完成admin下巡检任务

Showing 33 changed files with 3574 additions and 26 deletions
src/api/inspection/aInspectionPlanDetailApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取巡检计划详情
  4 +export function getInspectionPlanDetail(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/inspectionPlan.listAdminInspectionPlans',
  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 listAdminInspectionPlanStaffs(params) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/inspection.listAdminInspectionPlanStaffs',
  28 + method: 'get',
  29 + params
  30 + }).then(response => {
  31 + const res = response.data
  32 +
  33 + resolve(res)
  34 +
  35 + }).catch(error => {
  36 + reject(error)
  37 + })
  38 + })
  39 +}
  40 +
  41 +// 获取巡检路线列表
  42 +export function listAdminInspectionRoutes(params) {
  43 + return new Promise((resolve, reject) => {
  44 + request({
  45 + url: '/inspectionRoute.listAdminInspectionRoutes',
  46 + method: 'get',
  47 + params
  48 + }).then(response => {
  49 + const res = response.data
  50 +
  51 + resolve(res)
  52 +
  53 + }).catch(error => {
  54 + reject(error)
  55 + })
  56 + })
  57 +}
  58 +
  59 +// 获取巡检路线点列表
  60 +export function listAdminInspectionRoutePoints(params) {
  61 + return new Promise((resolve, reject) => {
  62 + request({
  63 + url: '/inspectionRoute.listAdminInspectionRoutePoints',
  64 + method: 'get',
  65 + params
  66 + }).then(response => {
  67 + const res = response.data
  68 +
  69 + resolve(res)
  70 +
  71 + }).catch(error => {
  72 + reject(error)
  73 + })
  74 + })
  75 +}
  76 +
  77 +// 获取巡检任务列表
  78 +export function queryAdminRouteInspectionTask(params) {
  79 + return new Promise((resolve, reject) => {
  80 + request({
  81 + url: '/inspection.queryAdminRouteInspectionTask',
  82 + method: 'get',
  83 + params
  84 + }).then(response => {
  85 + const res = response.data
  86 +
  87 + resolve(res)
  88 +
  89 + }).catch(error => {
  90 + reject(error)
  91 + })
  92 + })
  93 +}
  94 +
  95 +// 获取巡检任务详情
  96 +export function listAdminInspectionTaskDetails(params) {
  97 + return new Promise((resolve, reject) => {
  98 + request({
  99 + url: '/inspectionTaskDetail.listAdminInspectionTaskDetails',
  100 + method: 'get',
  101 + params
  102 + }).then(response => {
  103 + const res = response.data
  104 +
  105 + resolve(res)
  106 +
  107 + }).catch(error => {
  108 + reject(error)
  109 + })
  110 + })
  111 +}
0 112 \ No newline at end of file
... ...
src/api/inspection/adminInspectionPlanApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取管理员小区列表
  4 +export function listAdminCommunitys(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/community.listAdminCommunitys',
  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 listAdminInspectionPlans(params) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/inspectionPlan.listAdminInspectionPlans',
  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 +}
0 42 \ No newline at end of file
... ...
src/api/inspection/adminInspectionTaskApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 查询巡检任务列表
  4 +export function listAdminInspectionTasks(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/inspectionTask.listAdminInspectionTasks',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + resolve(res)
  13 + }).catch(error => {
  14 + reject(error)
  15 + })
  16 + })
  17 +}
  18 +
  19 +// 查询社区巡检树
  20 +export function queryCommunityInspectionTree(params) {
  21 + return new Promise((resolve, reject) => {
  22 + request({
  23 + url: '/community.queryCommunityInspectionTree',
  24 + method: 'get',
  25 + params
  26 + }).then(response => {
  27 + const res = response.data
  28 + if (res.code === 0) {
  29 + resolve(res)
  30 + } else {
  31 + reject(new Error(res.msg || '获取社区巡检树失败'))
  32 + }
  33 + }).catch(error => {
  34 + reject(error)
  35 + })
  36 + })
  37 +}
0 38 \ No newline at end of file
... ...
src/api/inspection/adminInspectionTaskDetailApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取巡检任务详情列表
  4 +export function getAdminInspectionTaskDetail(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/inspectionTask.listAdminInspectionTasks',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 +
  13 + resolve(res)
  14 +
  15 + }).catch(error => {
  16 + reject(error)
  17 + })
  18 + })
  19 +}
  20 +
  21 +// 获取巡检点任务详情列表
  22 +export function listAdminInspectionTaskDetails(params) {
  23 + return new Promise((resolve, reject) => {
  24 + request({
  25 + url: '/inspectionTaskDetail.listAdminInspectionTaskDetails',
  26 + method: 'get',
  27 + params
  28 + }).then(response => {
  29 + const res = response.data
  30 +
  31 + resolve({
  32 + data: res.inspectionTaskDetails,
  33 + records: res.records,
  34 + total: res.total
  35 + })
  36 + }).catch(error => {
  37 + reject(error)
  38 + })
  39 + })
  40 +}
  41 +
  42 +// 查询巡检任务地图数据
  43 +export function queryAdminInspectionTaskDetail(params) {
  44 + return new Promise((resolve, reject) => {
  45 + request({
  46 + url: '/inspection.queryAdminInspectionTaskDetail',
  47 + method: 'get',
  48 + params
  49 + }).then(response => {
  50 + const res = response.data
  51 +
  52 + resolve({
  53 + data: res.data
  54 + })
  55 +
  56 + }).catch(error => {
  57 + reject(error)
  58 + })
  59 + })
  60 +}
  61 +
  62 +// 查询巡检路线计划
  63 +export function queryAdminRouteInspectionPlan(params) {
  64 + return new Promise((resolve, reject) => {
  65 + request({
  66 + url: '/inspection.queryAdminRouteInspectionPlan',
  67 + method: 'get',
  68 + params
  69 + }).then(response => {
  70 + const res = response.data
  71 +
  72 + resolve({
  73 + data: res.data,
  74 + records: res.records,
  75 + total: res.total
  76 + })
  77 + }).catch(error => {
  78 + reject(error)
  79 + })
  80 + })
  81 +}
  82 +
  83 +// 获取巡检路线列表
  84 +export function listAdminInspectionRoutes(params) {
  85 + return new Promise((resolve, reject) => {
  86 + request({
  87 + url: '/inspectionRoute.listAdminInspectionRoutes',
  88 + method: 'get',
  89 + params
  90 + }).then(response => {
  91 + const res = response.data
  92 +
  93 + resolve({
  94 + data: res.inspectionRoutes
  95 + })
  96 + }).catch(error => {
  97 + reject(error)
  98 + })
  99 + })
  100 +}
  101 +
  102 +// 获取巡检路线点列表
  103 +export function listAdminInspectionRoutePoints(params) {
  104 + return new Promise((resolve, reject) => {
  105 + request({
  106 + url: '/inspectionRoute.listAdminInspectionRoutePoints',
  107 + method: 'get',
  108 + params
  109 + }).then(response => {
  110 + const res = response.data
  111 +
  112 + resolve({
  113 + data: res.inspectionPoints,
  114 + records: res.records,
  115 + total: res.total
  116 + })
  117 + }).catch(error => {
  118 + reject(error)
  119 + })
  120 + })
  121 +}
0 122 \ No newline at end of file
... ...
src/api/work/adminRepairApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 查询小区报修树形数据
  4 +export function queryCommunityRepairTree() {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/community.queryCommunityRepairTree',
  8 + method: 'get',
  9 + params: { hc: 1.8 }
  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 listAdminOwnerRepairs(params) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/ownerRepair.listAdminOwnerRepairs',
  28 + method: 'get',
  29 + params
  30 + }).then(response => {
  31 + const res = response.data
  32 + if (res.code === 0) {
  33 + resolve({
  34 + data: res.data,
  35 + total: res.total
  36 + })
  37 + } else {
  38 + reject(new Error(res.msg || '获取报修列表失败'))
  39 + }
  40 + }).catch(error => {
  41 + reject(error)
  42 + })
  43 + })
  44 +}
0 45 \ No newline at end of file
... ...
src/api/work/adminRepairDetailApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取报修详情
  4 +export function getRepairDetail(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/ownerRepair.listAdminOwnerRepairs',
  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 listRepairStaffs(params) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/ownerRepair.listAdminRepairStaffs',
  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 listStoreUseRecords(params) {
  45 + return new Promise((resolve, reject) => {
  46 + request({
  47 + url: '/resourceStore.listAdminStoreUseRecords',
  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 replyRepairAppraise(data) {
  65 + return new Promise((resolve, reject) => {
  66 + request({
  67 + url: '/repair.replyRepairAppraise',
  68 + method: 'post',
  69 + data
  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 +}
0 82 \ No newline at end of file
... ...
src/components/inspection/AInspectionPlanDetailStaff.vue 0 → 100644
  1 +<template>
  2 + <div class="staff-container">
  3 + <el-table :data="staffs" border style="width: 100%" v-loading="loading">
  4 + <el-table-column prop="staffName" :label="$t('aInspectionPlanDetail.staffName')" align="center" />
  5 + <el-table-column prop="startTime" :label="$t('aInspectionPlanDetail.startTime')" align="center" />
  6 + <el-table-column prop="endTime" :label="$t('aInspectionPlanDetail.endTime')" align="center" />
  7 + </el-table>
  8 +
  9 + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size"
  10 + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  11 + @current-change="handleCurrentChange" />
  12 + </div>
  13 +</template>
  14 +
  15 +<script>
  16 +import { listAdminInspectionPlanStaffs } from '@/api/inspection/aInspectionPlanDetailApi'
  17 +
  18 +export default {
  19 + name: 'AInspectionPlanDetailStaff',
  20 + data() {
  21 + return {
  22 + loading: false,
  23 + staffs: [],
  24 + inspectionPlanId: '',
  25 + page: {
  26 + current: 1,
  27 + size: 10,
  28 + total: 0
  29 + }
  30 + }
  31 + },
  32 + methods: {
  33 + async loadData(params) {
  34 + this.inspectionPlanId = params.inspectionPlanId
  35 + await this.getStaffList()
  36 + },
  37 + async getStaffList() {
  38 + try {
  39 + this.loading = true
  40 + const params = {
  41 + inspectionPlanId: this.inspectionPlanId,
  42 + page: this.page.current,
  43 + row: this.page.size
  44 + }
  45 + const { inspectionPlanStaffs, total } = await listAdminInspectionPlanStaffs(params)
  46 + this.staffs = inspectionPlanStaffs
  47 + this.page.total = total
  48 + } catch (error) {
  49 + this.$message.error(this.$t('common.fetchError'))
  50 + } finally {
  51 + this.loading = false
  52 + }
  53 + },
  54 + handleSizeChange(val) {
  55 + this.page.size = val
  56 + this.getStaffList()
  57 + },
  58 + handleCurrentChange(val) {
  59 + this.page.current = val
  60 + this.getStaffList()
  61 + }
  62 + }
  63 +}
  64 +</script>
  65 +
  66 +<style scoped>
  67 +.staff-container {
  68 + padding: 20px;
  69 +}
  70 +</style>
0 71 \ No newline at end of file
... ...
src/components/inspection/AInspectionRouteMap.vue 0 → 100644
  1 +<template>
  2 + <div id="aInspectionRouteMap" class="map-container"></div>
  3 +</template>
  4 +
  5 +<script>
  6 +import { listAdminInspectionRoutePoints } from '@/api/inspection/aInspectionPlanDetailApi'
  7 +
  8 +export default {
  9 + name: 'AInspectionRouteMap',
  10 + data() {
  11 + return {
  12 + map: null,
  13 + points: []
  14 + }
  15 + },
  16 + methods: {
  17 + async initMap(params) {
  18 + try {
  19 + const { data } = await listAdminInspectionRoutePoints({
  20 + inspectionRouteId: params.inspectionRouteId,
  21 + page: 1,
  22 + row: 1000
  23 + })
  24 + this.points = data
  25 + this.initMapView()
  26 + } catch (error) {
  27 + this.$message.error(this.$t('common.fetchError'))
  28 + }
  29 + },
  30 + initMapView() {
  31 + if (!this.points || this.points.length === 0) return
  32 +
  33 + // 这里需要根据实际地图API实现地图初始化
  34 + // 示例代码,需要替换为实际地图API调用
  35 + console.log('Initialize map with points:', this.points)
  36 +
  37 + // 示例:使用腾讯地图API
  38 + if (window.TMap) {
  39 + const center = new TMap.LatLng(this.points[0].lat, this.points[0].lng)
  40 + this.map = new TMap.Map(document.getElementById('aInspectionRouteMap'), {
  41 + center: center,
  42 + zoom: 17
  43 + })
  44 +
  45 + // 添加标记点
  46 + const markers = this.points.map(point => ({
  47 + position: new TMap.LatLng(point.lat, point.lng),
  48 + properties: {
  49 + title: point.inspectionName
  50 + }
  51 + }))
  52 +
  53 + new TMap.MultiMarker({
  54 + map: this.map,
  55 + geometries: markers
  56 + })
  57 + }
  58 + }
  59 + }
  60 +}
  61 +</script>
  62 +
  63 +<style scoped>
  64 +.map-container {
  65 + height: 600px;
  66 + width: 100%;
  67 +}
  68 +</style>
0 69 \ No newline at end of file
... ...
src/components/inspection/AInspectionRoutePoint.vue 0 → 100644
  1 +<template>
  2 + <div class="point-container">
  3 + <el-table :data="points" border style="width: 100%" v-loading="loading">
  4 + <el-table-column prop="inspectionId" :label="$t('aInspectionPlanDetail.pointId')" align="center" />
  5 + <el-table-column prop="inspectionName" :label="$t('aInspectionPlanDetail.pointName')" align="center" />
  6 + <el-table-column prop="pointTypeName" :label="$t('aInspectionPlanDetail.pointType')" align="center" />
  7 + <el-table-column prop="pointObjName" :label="$t('aInspectionPlanDetail.pointLocation')" align="center" />
  8 + <el-table-column :label="$t('aInspectionPlanDetail.startTime')" align="center">
  9 + <template slot-scope="scope">
  10 + {{ scope.row.pointStartTime || '-' }}
  11 + </template>
  12 + </el-table-column>
  13 + <el-table-column :label="$t('aInspectionPlanDetail.endTime')" align="center">
  14 + <template slot-scope="scope">
  15 + {{ scope.row.pointEndTime || '-' }}
  16 + </template>
  17 + </el-table-column>
  18 + <el-table-column :label="$t('aInspectionPlanDetail.sort')" align="center">
  19 + <template slot-scope="scope">
  20 + {{ scope.row.sortNumber || '-' }}
  21 + </template>
  22 + </el-table-column>
  23 + </el-table>
  24 +
  25 + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size"
  26 + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  27 + @current-change="handleCurrentChange" />
  28 + </div>
  29 +</template>
  30 +
  31 +<script>
  32 +import { listAdminInspectionRoutePoints } from '@/api/inspection/aInspectionPlanDetailApi'
  33 +
  34 +export default {
  35 + name: 'AInspectionRoutePoint',
  36 + data() {
  37 + return {
  38 + loading: false,
  39 + points: [],
  40 + inspectionRouteId: '',
  41 + page: {
  42 + current: 1,
  43 + size: 10,
  44 + total: 0
  45 + }
  46 + }
  47 + },
  48 + methods: {
  49 + async loadData(params) {
  50 + this.inspectionRouteId = params.inspectionRouteId
  51 + await this.getPointList()
  52 + },
  53 + async getPointList() {
  54 + try {
  55 + this.loading = true
  56 + const params = {
  57 + inspectionRouteId: this.inspectionRouteId,
  58 + page: this.page.current,
  59 + row: this.page.size
  60 + }
  61 + const { inspectionPoints, total } = await listAdminInspectionRoutePoints(params)
  62 + this.points = inspectionPoints
  63 + this.page.total = total
  64 + } catch (error) {
  65 + this.$message.error(this.$t('common.fetchError'))
  66 + } finally {
  67 + this.loading = false
  68 + }
  69 + },
  70 + handleSizeChange(val) {
  71 + this.page.size = val
  72 + this.getPointList()
  73 + },
  74 + handleCurrentChange(val) {
  75 + this.page.current = val
  76 + this.getPointList()
  77 + }
  78 + }
  79 +}
  80 +</script>
  81 +
  82 +<style scoped>
  83 +.point-container {
  84 + padding: 20px;
  85 +}
  86 +</style>
0 87 \ No newline at end of file
... ...
src/components/inspection/AInspectionTaskMap.vue 0 → 100644
  1 +<template>
  2 + <div id="aInspectionTaskMap" class="map-container"></div>
  3 +</template>
  4 +
  5 +<script>
  6 +import { queryAdminInspectionTaskDetail } from '@/api/inspection/aInspectionPlanDetailApi'
  7 +
  8 +export default {
  9 + name: 'AInspectionTaskMap',
  10 + data() {
  11 + return {
  12 + map: null,
  13 + points: []
  14 + }
  15 + },
  16 + methods: {
  17 + loadData(params) {
  18 + console.log(params)
  19 + //this.initMap(params)
  20 + },
  21 + async initMap(params) {
  22 + try {
  23 + const { data } = await queryAdminInspectionTaskDetail({
  24 + taskId: params.taskId,
  25 + page: 1,
  26 + row: 1000
  27 + })
  28 + this.points = data
  29 + this.initMapView()
  30 + } catch (error) {
  31 + this.$message.error(this.$t('common.fetchError'))
  32 + }
  33 + },
  34 + initMapView() {
  35 + let TMap = {}
  36 + if (!this.points || this.points.length === 0) return
  37 +
  38 + // 这里需要根据实际地图API实现地图初始化
  39 + // 示例代码,需要替换为实际地图API调用
  40 + console.log('Initialize task map with points:', this.points)
  41 +
  42 + // 示例:使用腾讯地图API
  43 + if (window.TMap) {
  44 + const center = new TMap.LatLng(this.points[0].lat, this.points[0].lng)
  45 + this.map = new TMap.Map(document.getElementById('aInspectionTaskMap'), {
  46 + center: center,
  47 + zoom: 17
  48 + })
  49 +
  50 + // 添加标记点
  51 + const markers = this.points.map(point => ({
  52 + position: new TMap.LatLng(point.lat, point.lng),
  53 + properties: {
  54 + title: point.inspectionName,
  55 + status: point.state
  56 + }
  57 + }))
  58 +
  59 + new TMap.MultiMarker({
  60 + map: this.map,
  61 + styles: {
  62 + normal: new TMap.MarkerStyle({
  63 + width: 25,
  64 + height: 35,
  65 + src: '/img/inspection.png',
  66 + anchor: { x: 16, y: 32 }
  67 + }),
  68 + done: new TMap.MarkerStyle({
  69 + width: 25,
  70 + height: 35,
  71 + src: '/img/inspection_done.png',
  72 + anchor: { x: 16, y: 32 }
  73 + })
  74 + },
  75 + geometries: markers.map(marker => ({
  76 + ...marker,
  77 + styleId: marker.properties.status === '20200405' ? 'done' : 'normal'
  78 + }))
  79 + })
  80 + }
  81 + }
  82 + }
  83 +}
  84 +</script>
  85 +
  86 +<style scoped>
  87 +.map-container {
  88 + height: 600px;
  89 + width: 100%;
  90 +}
  91 +</style>
0 92 \ No newline at end of file
... ...
src/components/inspection/AdminPointRoute.vue 0 → 100644
  1 +<template>
  2 + <div class="route-container">
  3 + <el-row :gutter="20">
  4 + <el-col :span="6">
  5 + <el-card class="route-list">
  6 + <el-scrollbar>
  7 + <ul class="route-ul">
  8 + <li v-for="(route, index) in routes" :key="index"
  9 + :class="{ 'active': route.inspectionRouteId === currentRouteId }" @click="switchRoute(route)">
  10 + {{ route.routeName }}
  11 + </li>
  12 + </ul>
  13 + </el-scrollbar>
  14 + </el-card>
  15 + </el-col>
  16 + <el-col :span="18">
  17 + <a-inspection-route-map ref="routeMap" />
  18 + </el-col>
  19 + </el-row>
  20 + </div>
  21 +</template>
  22 +
  23 +<script>
  24 +import { listAdminInspectionRoutes } from '@/api/inspection/aInspectionPlanDetailApi'
  25 +import AInspectionRouteMap from './AInspectionRouteMap'
  26 +
  27 +export default {
  28 + name: 'AdminPointRoute',
  29 + components: {
  30 + AInspectionRouteMap
  31 + },
  32 + data() {
  33 + return {
  34 + loading: false,
  35 + routes: [],
  36 + currentRouteId: '',
  37 + inspectionId: ''
  38 + }
  39 + },
  40 + methods: {
  41 + async loadData(params) {
  42 + this.inspectionId = params.inspectionPlanId
  43 + await this.getRouteList()
  44 + },
  45 + async getRouteList() {
  46 + try {
  47 + this.loading = true
  48 + const params = {
  49 + inspectionId: this.inspectionId,
  50 + page: 1,
  51 + row: 100
  52 + }
  53 + const { inspectionRoutes } = await listAdminInspectionRoutes(params)
  54 + this.routes = inspectionRoutes
  55 + if (this.routes.length > 0) {
  56 + this.switchRoute(this.routes[0])
  57 + }
  58 + } catch (error) {
  59 + this.$message.error(this.$t('common.fetchError'))
  60 + } finally {
  61 + this.loading = false
  62 + }
  63 + },
  64 + switchRoute(route) {
  65 + this.currentRouteId = route.inspectionRouteId
  66 + this.$refs.routeMap.initMap({
  67 + inspectionRouteId: route.inspectionRouteId
  68 + })
  69 + }
  70 + }
  71 +}
  72 +</script>
  73 +
  74 +<style scoped>
  75 +.route-container {
  76 + padding: 20px;
  77 +}
  78 +
  79 +.route-list {
  80 + height: 600px;
  81 +}
  82 +
  83 +.route-ul {
  84 + list-style: none;
  85 + padding: 0;
  86 + margin: 0;
  87 +}
  88 +
  89 +.route-ul li {
  90 + padding: 10px;
  91 + cursor: pointer;
  92 + border-bottom: 1px solid #eee;
  93 +}
  94 +
  95 +.route-ul li:hover {
  96 + background-color: #f5f5f5;
  97 +}
  98 +
  99 +.route-ul li.active {
  100 + background-color: #409EFF;
  101 + color: white;
  102 +}
  103 +</style>
0 104 \ No newline at end of file
... ...
src/components/inspection/AdminPointTaskDetail.vue 0 → 100644
  1 +<template>
  2 + <div class="detail-container">
  3 + <el-form :inline="true" class="search-form text-left">
  4 + <el-form-item :label="$t('aInspectionPlanDetail.staffName')">
  5 + <el-input v-model="searchForm.planUserName" clearable />
  6 + </el-form-item>
  7 + <el-form-item :label="$t('aInspectionPlanDetail.startTime')">
  8 + <el-date-picker v-model="searchForm.inspectionStartTime" type="datetime"
  9 + value-format="yyyy-MM-dd HH:mm:ss" />
  10 + </el-form-item>
  11 + <el-form-item :label="$t('aInspectionPlanDetail.endTime')">
  12 + <el-date-picker v-model="searchForm.inspectionEndTime" type="datetime"
  13 + value-format="yyyy-MM-dd HH:mm:ss" />
  14 + </el-form-item>
  15 + <el-form-item>
  16 + <el-button type="primary" @click="handleSearch">
  17 + {{ $t('common.search') }}
  18 + </el-button>
  19 + </el-form-item>
  20 + </el-form>
  21 +
  22 + <el-table :data="details" border style="width: 100%" v-loading="loading">
  23 + <el-table-column prop="taskDetailId" :label="$t('aInspectionPlanDetail.detailId')" align="center" width="120" />
  24 + <el-table-column prop="inspectionName" :label="$t('aInspectionPlanDetail.pointName')" align="center" />
  25 + <el-table-column prop="inspectionPlanName" :label="$t('aInspectionPlanDetail.planName')" align="center" />
  26 + <el-table-column prop="routeName" :label="$t('aInspectionPlanDetail.route')" align="center" />
  27 + <el-table-column :label="$t('aInspectionPlanDetail.staffTime')" align="center">
  28 + <template slot-scope="scope">
  29 + <div>{{ scope.row.planInsTime }}</div>
  30 + <div>{{ scope.row.planEndTime }}</div>
  31 + </template>
  32 + </el-table-column>
  33 + <el-table-column :label="$t('aInspectionPlanDetail.pointTime')" align="center">
  34 + <template slot-scope="scope">
  35 + <div>{{ scope.row.pointStartTime }}</div>
  36 + <div>{{ scope.row.pointEndTime }}</div>
  37 + </template>
  38 + </el-table-column>
  39 + <el-table-column :label="$t('aInspectionPlanDetail.actualTime')" align="center">
  40 + <template slot-scope="scope">
  41 + {{ scope.row.inspectionTime || '-' }}
  42 + </template>
  43 + </el-table-column>
  44 + <el-table-column :label="$t('aInspectionPlanDetail.signStatus')" align="center">
  45 + <template slot-scope="scope">
  46 + <el-tag :type="scope.row.inspectionState === '60000' ? 'success' : 'danger'">
  47 + {{ scope.row.inspectionStateName || '-' }}
  48 + </el-tag>
  49 + </template>
  50 + </el-table-column>
  51 + <el-table-column prop="planUserName" :label="$t('aInspectionPlanDetail.planStaff')" align="center" />
  52 + <el-table-column prop="actUserName" :label="$t('aInspectionPlanDetail.actualStaff')" align="center">
  53 + <template slot-scope="scope">
  54 + {{ scope.row.actUserName || '-' }}
  55 + </template>
  56 + </el-table-column>
  57 + <el-table-column prop="signTypeName" :label="$t('aInspectionPlanDetail.signType')" align="center" />
  58 + <el-table-column prop="taskStateName" :label="$t('aInspectionPlanDetail.taskStatus')" align="center" />
  59 + <el-table-column :label="$t('aInspectionPlanDetail.pointStatus')" align="center">
  60 + <template slot-scope="scope">
  61 + <el-tag :type="scope.row.state === '20200408' ? 'danger' : ''">
  62 + {{ scope.row.stateName }}
  63 + </el-tag>
  64 + </template>
  65 + </el-table-column>
  66 + <el-table-column prop="description" :label="$t('aInspectionPlanDetail.inspectionResult')" align="center">
  67 + <template slot-scope="scope">
  68 + {{ scope.row.description || '-' }}
  69 + </template>
  70 + </el-table-column>
  71 + <el-table-column :label="$t('aInspectionPlanDetail.photos')" align="center">
  72 + <template slot-scope="scope">
  73 + <el-image v-for="(photo, index) in scope.row.photos" :key="index"
  74 + style="width: 60px; height: 60px; margin-right: 5px;" :src="photo.url" :preview-src-list="[photo.url]"
  75 + fit="cover" />
  76 + </template>
  77 + </el-table-column>
  78 + <el-table-column prop="createTime" :label="$t('aInspectionPlanDetail.createTime')" align="center" />
  79 + </el-table>
  80 +
  81 + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size"
  82 + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  83 + @current-change="handleCurrentChange" />
  84 + </div>
  85 +</template>
  86 +
  87 +<script>
  88 +import { listAdminInspectionTaskDetails } from '@/api/inspection/aInspectionPlanDetailApi'
  89 +
  90 +export default {
  91 + name: 'AdminPointTaskDetail',
  92 + data() {
  93 + return {
  94 + loading: false,
  95 + details: [],
  96 + taskId: '',
  97 + inspectionRouteId: '',
  98 + searchForm: {
  99 + planUserName: '',
  100 + inspectionStartTime: '',
  101 + inspectionEndTime: ''
  102 + },
  103 + page: {
  104 + current: 1,
  105 + size: 10,
  106 + total: 0
  107 + }
  108 + }
  109 + },
  110 + methods: {
  111 + async loadData(params) {
  112 + this.taskId = params.taskId
  113 + this.inspectionRouteId = params.inspectionRouteId
  114 + await this.getDetailList()
  115 + },
  116 + async getDetailList() {
  117 + try {
  118 + this.loading = true
  119 + const params = {
  120 + taskId: this.taskId,
  121 + inspectionRouteId: this.inspectionRouteId,
  122 + planUserName: this.searchForm.planUserName,
  123 + inspectionStartTime: this.searchForm.inspectionStartTime,
  124 + inspectionEndTime: this.searchForm.inspectionEndTime,
  125 + page: this.page.current,
  126 + row: this.page.size
  127 + }
  128 + const { inspectionTaskDetails, total } = await listAdminInspectionTaskDetails(params)
  129 + this.details = inspectionTaskDetails
  130 + this.page.total = total
  131 + } catch (error) {
  132 + this.$message.error(this.$t('common.fetchError'))
  133 + } finally {
  134 + this.loading = false
  135 + }
  136 + },
  137 + handleSearch() {
  138 + this.page.current = 1
  139 + this.getDetailList()
  140 + },
  141 + handleSizeChange(val) {
  142 + this.page.size = val
  143 + this.getDetailList()
  144 + },
  145 + handleCurrentChange(val) {
  146 + this.page.current = val
  147 + this.getDetailList()
  148 + }
  149 + }
  150 +}
  151 +</script>
  152 +
  153 +<style scoped>
  154 +.detail-container {
  155 + padding: 20px;
  156 +}
  157 +
  158 +.search-form {
  159 + margin-bottom: 20px;
  160 +}
  161 +
  162 +.el-image {
  163 + cursor: pointer;
  164 +}
  165 +</style>
0 166 \ No newline at end of file
... ...
src/components/inspection/AdminRoutePlan.vue 0 → 100644
  1 +<template>
  2 + <div class="admin-route-plan">
  3 + <el-table
  4 + :data="tableData"
  5 + border
  6 + style="width: 100%"
  7 + v-loading="loading"
  8 + >
  9 + <el-table-column
  10 + prop="inspectionPlanName"
  11 + :label="$t('adminRoutePlan.table.planName')"
  12 + align="center"
  13 + />
  14 + <el-table-column
  15 + prop="inspectionRouteName"
  16 + :label="$t('adminRoutePlan.table.routeName')"
  17 + align="center"
  18 + />
  19 + <el-table-column
  20 + prop="inspectionPlanPeriodName"
  21 + :label="$t('adminRoutePlan.table.planPeriod')"
  22 + align="center"
  23 + />
  24 + <el-table-column
  25 + prop="signTypeName"
  26 + :label="$t('adminRoutePlan.table.signType')"
  27 + align="center"
  28 + />
  29 + <el-table-column
  30 + :label="$t('adminRoutePlan.table.dateRange')"
  31 + align="center"
  32 + >
  33 + <template slot-scope="scope">
  34 + {{ scope.row.startDate }}~{{ scope.row.endDate }}
  35 + </template>
  36 + </el-table-column>
  37 + <el-table-column
  38 + :label="$t('adminRoutePlan.table.timeRange')"
  39 + align="center"
  40 + >
  41 + <template slot-scope="scope">
  42 + {{ scope.row.startTime }}~{{ scope.row.endTime }}
  43 + </template>
  44 + </el-table-column>
  45 + <el-table-column
  46 + prop="beforeTime"
  47 + :label="$t('adminRoutePlan.table.beforeTime')"
  48 + align="center"
  49 + />
  50 + <el-table-column
  51 + prop="createUserName"
  52 + :label="$t('adminRoutePlan.table.creator')"
  53 + align="center"
  54 + />
  55 + <el-table-column
  56 + prop="createTime"
  57 + :label="$t('adminRoutePlan.table.createTime')"
  58 + align="center"
  59 + />
  60 + <el-table-column
  61 + :label="$t('adminRoutePlan.table.inspectors')"
  62 + align="center"
  63 + >
  64 + <template slot-scope="scope">
  65 + <div v-for="(staff, index) in scope.row.staffs" :key="index">
  66 + {{ staff.staffName }}
  67 + </div>
  68 + </template>
  69 + </el-table-column>
  70 + <el-table-column
  71 + prop="stateName"
  72 + :label="$t('adminRoutePlan.table.status')"
  73 + align="center"
  74 + />
  75 + </el-table>
  76 +
  77 + <el-pagination
  78 + class="margin-top"
  79 + :current-page.sync="pagination.current"
  80 + :page-sizes="[10, 20, 30, 50]"
  81 + :page-size="pagination.size"
  82 + :total="pagination.total"
  83 + layout="total, sizes, prev, pager, next, jumper"
  84 + @size-change="handleSizeChange"
  85 + @current-change="handleCurrentChange"
  86 + />
  87 + </div>
  88 + </template>
  89 +
  90 + <script>
  91 + import { queryAdminRouteInspectionPlan } from '@/api/inspection/adminInspectionTaskDetailApi'
  92 +
  93 + export default {
  94 + name: 'AdminRoutePlan',
  95 + data() {
  96 + return {
  97 + loading: false,
  98 + searchForm: {
  99 + inspectionRouteId: '',
  100 + inspectionPlanId: ''
  101 + },
  102 + tableData: [],
  103 + pagination: {
  104 + current: 1,
  105 + size: 10,
  106 + total: 0
  107 + }
  108 + }
  109 + },
  110 + methods: {
  111 + initData(params) {
  112 + console.log(params)
  113 + this.searchForm.inspectionRouteId = params.inspectionRouteId
  114 + this.searchForm.inspectionPlanId = params.inspectionPlanId
  115 + this.loadData()
  116 + },
  117 + async loadData(_param) {
  118 + try {
  119 + this.loading = true
  120 + const params = {
  121 + ..._param,
  122 + page: this.pagination.current,
  123 + row: this.pagination.size
  124 + }
  125 + const { data, total } = await queryAdminRouteInspectionPlan(params)
  126 + this.tableData = data
  127 + this.pagination.total = total
  128 + } catch (error) {
  129 + this.$message.error(this.$t('common.fetchError'))
  130 + } finally {
  131 + this.loading = false
  132 + }
  133 + },
  134 + handleSizeChange(val) {
  135 + this.pagination.size = val
  136 + this.loadData()
  137 + },
  138 + handleCurrentChange(val) {
  139 + this.pagination.current = val
  140 + this.loadData()
  141 + }
  142 + }
  143 + }
  144 + </script>
  145 +
  146 + <style lang="scss" scoped>
  147 + .admin-route-plan {
  148 + .margin-top {
  149 + margin-top: 20px;
  150 + }
  151 + }
  152 + </style>
0 153 \ No newline at end of file
... ...
src/components/inspection/AdminRouteTask.vue 0 → 100644
  1 +<template>
  2 + <div class="task-container">
  3 + <el-row :gutter="20">
  4 + <el-col :span="6">
  5 + <el-card class="task-list">
  6 + <el-scrollbar>
  7 + <ul class="task-ul">
  8 + <li v-for="(task, index) in tasks" :key="index" :class="{ 'active': task.taskId === currentTaskId }"
  9 + @click="switchTask(task)">
  10 + <div>{{ task.planUserName }}({{ task.inspectionPlanName }})</div>
  11 + <div>{{ task.planInsTime }}</div>
  12 + </li>
  13 + </ul>
  14 + </el-scrollbar>
  15 + </el-card>
  16 + </el-col>
  17 + <el-col :span="18">
  18 + <a-inspection-task-map ref="taskMap" />
  19 + </el-col>
  20 + </el-row>
  21 + </div>
  22 +</template>
  23 +
  24 +<script>
  25 +import { queryAdminRouteInspectionTask } from '@/api/inspection/aInspectionPlanDetailApi'
  26 +import AInspectionTaskMap from './AInspectionTaskMap'
  27 +
  28 +export default {
  29 + name: 'AdminRouteTask',
  30 + components: {
  31 + AInspectionTaskMap
  32 + },
  33 + data() {
  34 + return {
  35 + loading: false,
  36 + tasks: [],
  37 + currentTaskId: '',
  38 + inspectionRouteId: ''
  39 + }
  40 + },
  41 + methods: {
  42 + async loadData(params) {
  43 + this.inspectionRouteId = params.inspectionRouteId
  44 + await this.getTaskList()
  45 + },
  46 + async getTaskList() {
  47 + try {
  48 + this.loading = true
  49 + const params = {
  50 + inspectionRouteId: this.inspectionRouteId,
  51 + page: 1,
  52 + row: 100
  53 + }
  54 + const { data } = await queryAdminRouteInspectionTask(params)
  55 + this.tasks = data
  56 + if (this.tasks.length > 0) {
  57 + this.switchTask(this.tasks[0])
  58 + }
  59 + } catch (error) {
  60 + this.$message.error(this.$t('common.fetchError'))
  61 + } finally {
  62 + this.loading = false
  63 + }
  64 + },
  65 + switchTask(task) {
  66 + this.currentTaskId = task.taskId
  67 + this.$refs.taskMap.initMap({
  68 + taskId: task.taskId
  69 + })
  70 + }
  71 + }
  72 +}
  73 +</script>
  74 +
  75 +<style scoped>
  76 +.task-container {
  77 + padding: 20px;
  78 +}
  79 +
  80 +.task-list {
  81 + height: 600px;
  82 +}
  83 +
  84 +.task-ul {
  85 + list-style: none;
  86 + padding: 0;
  87 + margin: 0;
  88 +}
  89 +
  90 +.task-ul li {
  91 + padding: 10px;
  92 + cursor: pointer;
  93 + border-bottom: 1px solid #eee;
  94 +}
  95 +
  96 +.task-ul li:hover {
  97 + background-color: #f5f5f5;
  98 +}
  99 +
  100 +.task-ul li.active {
  101 + background-color: #409EFF;
  102 + color: white;
  103 +}
  104 +</style>
0 105 \ No newline at end of file
... ...
src/components/inspection/communityInspectionTree.vue 0 → 100644
  1 +<template>
  2 + <div class="community-inspection-tree">
  3 + <el-card class="box-card">
  4 + <el-tree
  5 + ref="tree"
  6 + :data="treeData"
  7 + node-key="id"
  8 + :props="defaultProps"
  9 + :highlight-current="true"
  10 + :expand-on-click-node="false"
  11 + @node-click="handleNodeClick"
  12 + ></el-tree>
  13 + </el-card>
  14 + </div>
  15 +</template>
  16 +
  17 +<script>
  18 +import { queryCommunityInspectionTree } from '@/api/inspection/adminInspectionTaskApi'
  19 +
  20 +export default {
  21 + name: 'CommunityInspectionTree',
  22 + data() {
  23 + return {
  24 + treeData: [],
  25 + defaultProps: {
  26 + children: 'children',
  27 + label: 'text'
  28 + }
  29 + }
  30 + },
  31 + mounted() {
  32 + this.loadTreeData()
  33 + },
  34 + methods: {
  35 + async loadTreeData() {
  36 + try {
  37 + const response = await queryCommunityInspectionTree({ hc: 1.8 })
  38 + this.treeData = response.data || []
  39 + } catch (error) {
  40 + console.error('Failed to load tree data:', error)
  41 + }
  42 + },
  43 + handleNodeClick(data, node) {
  44 + console.log(node)
  45 + const params = {
  46 + communityId: '',
  47 + inspectionPlanId: '',
  48 + staffId: ''
  49 + }
  50 +
  51 + if (data.id.startsWith('c_')) {
  52 + params.communityId = data.original.communityId
  53 + params.communityName = data.original.communityName
  54 + } else if (data.id.startsWith('p_')) {
  55 + params.communityId = data.original.communityId
  56 + params.inspectionPlanId = data.original.inspectionPlanId
  57 + } else if (data.id.startsWith('s_')) {
  58 + params.communityId = data.original.communityId
  59 + params.inspectionPlanId = data.original.inspectionPlanId
  60 + params.staffId = data.original.staffId
  61 + }
  62 +
  63 + this.$emit('notifyQuery', params)
  64 + }
  65 + }
  66 +}
  67 +</script>
  68 +
  69 +<style lang="scss" scoped>
  70 +.community-inspection-tree {
  71 + .box-card {
  72 + border-radius: 4px;
  73 + }
  74 +}
  75 +</style>
0 76 \ No newline at end of file
... ...
src/components/work/CommunityRepairTree.vue 0 → 100644
  1 +<template>
  2 + <el-card class="tree-card">
  3 + <el-tree
  4 + ref="repairTree"
  5 + :data="treeData"
  6 + node-key="id"
  7 + :props="defaultProps"
  8 + :default-expand-all="true"
  9 + @node-click="handleNodeClick"
  10 + />
  11 + </el-card>
  12 +</template>
  13 +
  14 +<script>
  15 +import { queryCommunityRepairTree } from '@/api/work/adminRepairApi'
  16 +
  17 +export default {
  18 + name: 'CommunityRepairTree',
  19 + data() {
  20 + return {
  21 + treeData: [],
  22 + defaultProps: {
  23 + children: 'children',
  24 + label: 'text'
  25 + }
  26 + }
  27 + },
  28 + created() {
  29 + this.loadTreeData()
  30 + },
  31 + methods: {
  32 + async loadTreeData() {
  33 + try {
  34 + const { data } = await queryCommunityRepairTree()
  35 + this.treeData = data
  36 + } catch (error) {
  37 + this.$message.error(this.$t('adminRepair.treeFetchError'))
  38 + }
  39 + },
  40 + handleNodeClick(data, node) {
  41 + console.log(node)
  42 + if (data.id.startsWith('c_')) {
  43 + this.$emit('selectCommunity', {
  44 + communityName: data.communityName,
  45 + communityId: data.communityId
  46 + })
  47 + } else if (data.id.startsWith('r_')) {
  48 + this.$emit('selectRepairSetting', {
  49 + communityId: data.communityId,
  50 + repairType: data.repairType
  51 + })
  52 + } else if (data.id.startsWith('s_')) {
  53 + this.$emit('selectState', {
  54 + communityId: data.communityId,
  55 + repairType: data.repairType,
  56 + state: data.state
  57 + })
  58 + }
  59 + }
  60 + }
  61 +}
  62 +</script>
  63 +
  64 +<style lang="scss" scoped>
  65 +.tree-card {
  66 + height: 100%;
  67 +}
  68 +</style>
0 69 \ No newline at end of file
... ...
src/components/work/ReplyRepairAppraise.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('adminRepairDetail.replyAppraise')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="resetForm"
  7 + >
  8 + <el-form :model="form" :rules="rules" ref="form" label-width="120px">
  9 + <el-form-item :label="$t('adminRepairDetail.content')" prop="replyContext">
  10 + <el-input
  11 + type="textarea"
  12 + :rows="5"
  13 + v-model="form.replyContext"
  14 + :placeholder="$t('adminRepairDetail.replyPlaceholder')"
  15 + ></el-input>
  16 + </el-form-item>
  17 + </el-form>
  18 +
  19 + <div slot="footer" class="dialog-footer">
  20 + <el-button @click="visible = false">{{ $t('common.cancel') }}</el-button>
  21 + <el-button type="primary" @click="submitForm">{{ $t('common.submit') }}</el-button>
  22 + </div>
  23 + </el-dialog>
  24 +</template>
  25 +
  26 +<script>
  27 +import { replyRepairAppraise } from '@/api/work/adminRepairDetailApi'
  28 +
  29 +export default {
  30 + name: 'ReplyRepairAppraise',
  31 + data() {
  32 + return {
  33 + visible: false,
  34 + form: {
  35 + repairId: '',
  36 + ruId: '',
  37 + replyContext: ''
  38 + },
  39 + rules: {
  40 + replyContext: [
  41 + { required: true, message: this.$t('adminRepairDetail.replyRequired'), trigger: 'blur' },
  42 + { max: 512, message: this.$t('adminRepairDetail.replyMaxLength'), trigger: 'blur' }
  43 + ]
  44 + }
  45 + }
  46 + },
  47 + methods: {
  48 + open(data) {
  49 + this.form.repairId = data.repairId
  50 + this.form.ruId = data.ruId
  51 + this.visible = true
  52 + this.$nextTick(() => {
  53 + this.$refs.form && this.$refs.form.clearValidate()
  54 + })
  55 + },
  56 + submitForm() {
  57 + this.$refs.form.validate(async valid => {
  58 + if (!valid) return
  59 +
  60 + try {
  61 + await replyRepairAppraise({
  62 + ...this.form,
  63 + communityId: this.$store.getters.communityId
  64 + })
  65 + this.$message.success(this.$t('adminRepairDetail.replySuccess'))
  66 + this.visible = false
  67 + this.$emit('success')
  68 + } catch (error) {
  69 + this.$message.error(error.message || this.$t('adminRepairDetail.replyError'))
  70 + }
  71 + })
  72 + },
  73 + resetForm() {
  74 + this.form = {
  75 + repairId: '',
  76 + ruId: '',
  77 + replyContext: ''
  78 + }
  79 + this.$refs.form && this.$refs.form.clearValidate()
  80 + }
  81 + }
  82 +}
  83 +</script>
0 84 \ No newline at end of file
... ...
src/components/work/viewImage.vue 0 → 100644
  1 +<template>
  2 + <div v-show="visible" class="image-viewer">
  3 + <div class="image-container">
  4 + <img :src="imageUrl" :style="{ width: imgWidth + 'px', height: imgHeight + 'px' }" />
  5 + <i class="el-icon-close close-icon" @click="close"></i>
  6 + </div>
  7 + </div>
  8 +</template>
  9 +
  10 +<script>
  11 +export default {
  12 + name: 'ViewImage',
  13 + data() {
  14 + return {
  15 + visible: false,
  16 + imageUrl: '',
  17 + imgWidth: 800,
  18 + imgHeight: 800
  19 + }
  20 + },
  21 + methods: {
  22 + open(url) {
  23 + this.imageUrl = url
  24 + this.visible = true
  25 + this.enterFullscreen()
  26 +
  27 + const img = new Image()
  28 + img.src = url
  29 + img.onload = () => {
  30 + const imgScale = img.width / img.height
  31 + this.imgWidth = 800
  32 + this.imgHeight = 800 / imgScale
  33 + }
  34 + },
  35 + close() {
  36 + this.exitFullscreen()
  37 + this.visible = false
  38 + },
  39 + enterFullscreen() {
  40 + const element = document.documentElement
  41 + if (element.requestFullscreen) {
  42 + element.requestFullscreen()
  43 + } else if (element.mozRequestFullScreen) {
  44 + element.mozRequestFullScreen()
  45 + } else if (element.webkitRequestFullscreen) {
  46 + element.webkitRequestFullscreen()
  47 + } else if (element.msRequestFullscreen) {
  48 + element.msRequestFullscreen()
  49 + }
  50 + },
  51 + exitFullscreen() {
  52 + if (document.exitFullscreen) {
  53 + document.exitFullscreen()
  54 + } else if (document.mozCancelFullScreen) {
  55 + document.mozCancelFullScreen()
  56 + } else if (document.webkitExitFullscreen) {
  57 + document.webkitExitFullscreen()
  58 + }
  59 + }
  60 + },
  61 + mounted() {
  62 + document.addEventListener('fullscreenchange', () => {
  63 + if (!document.fullscreenElement) {
  64 + this.visible = false
  65 + }
  66 + })
  67 + }
  68 +}
  69 +</script>
  70 +
  71 +<style lang="scss" scoped>
  72 +.image-viewer {
  73 + position: fixed;
  74 + top: 0;
  75 + left: 0;
  76 + width: 100%;
  77 + height: 100%;
  78 + background-color: rgba(0, 0, 0, 0.7);
  79 + z-index: 9999;
  80 + display: flex;
  81 + justify-content: center;
  82 + align-items: center;
  83 +
  84 + .image-container {
  85 + position: relative;
  86 +
  87 + img {
  88 + max-width: 90vw;
  89 + max-height: 90vh;
  90 + object-fit: contain;
  91 + }
  92 +
  93 + .close-icon {
  94 + position: absolute;
  95 + top: 10px;
  96 + right: 10px;
  97 + font-size: 24px;
  98 + color: #f56c6c;
  99 + cursor: pointer;
  100 + background: rgba(255, 255, 255, 0.7);
  101 + border-radius: 50%;
  102 + padding: 5px;
  103 +
  104 + &:hover {
  105 + color: #f00;
  106 + }
  107 + }
  108 + }
  109 +}
  110 +</style>
0 111 \ No newline at end of file
... ...
src/i18n/index.js
... ... @@ -66,6 +66,12 @@ import { messages as adminAccountDetailMessages } from &#39;../views/account/adminAc
66 66 import { messages as adminFeeConfigMessages } from '../views/fee/adminFeeConfigLang'
67 67 import { messages as adminEquipmentMessages } from '../views/resource/adminEquipmentLang'
68 68 import { messages as adminRoomFeeMessages } from '../views/fee/adminRoomFeeLang'
  69 +import { messages as adminRepairMessages } from '../views/work/adminRepairLang'
  70 +import { messages as adminRepairDetailMessages } from '../views/work/adminRepairDetailLang'
  71 +import { messages as adminInspectionPlanMessages } from '../views/inspection/adminInspectionPlanLang'
  72 +import { messages as aInspectionPlanDetailMessages } from '../views/inspection/aInspectionPlanDetailLang'
  73 +import { messages as adminInspectionTaskMessages } from '../views/inspection/adminInspectionTaskLang'
  74 +import { messages as adminInspectionTaskDetailMessages } from '../views/inspection/adminInspectionTaskDetailLang'
69 75  
70 76 Vue.use(VueI18n)
71 77  
... ... @@ -136,6 +142,12 @@ const messages = {
136 142 ...adminFeeConfigMessages.en,
137 143 ...adminEquipmentMessages.en,
138 144 ...adminRoomFeeMessages.en,
  145 + ...adminRepairMessages.en,
  146 + ...adminRepairDetailMessages.en,
  147 + ...adminInspectionPlanMessages.en,
  148 + ...aInspectionPlanDetailMessages.en,
  149 + ...adminInspectionTaskMessages.en,
  150 + ...adminInspectionTaskDetailMessages.en,
139 151 },
140 152 zh: {
141 153 ...loginMessages.zh,
... ... @@ -202,6 +214,12 @@ const messages = {
202 214 ...adminFeeConfigMessages.zh,
203 215 ...adminEquipmentMessages.zh,
204 216 ...adminRoomFeeMessages.zh,
  217 + ...adminRepairMessages.zh,
  218 + ...adminRepairDetailMessages.zh,
  219 + ...adminInspectionPlanMessages.zh,
  220 + ...aInspectionPlanDetailMessages.zh,
  221 + ...adminInspectionTaskMessages.zh,
  222 + ...adminInspectionTaskDetailMessages.zh,
205 223 }
206 224 }
207 225  
... ...
src/main.js (需要添加的部分) deleted
1   -import Vue from 'vue'
2   -import ElementUI from 'element-ui'
3   -import 'element-ui/lib/theme-chalk/index.css'
4   -import VueI18n from 'vue-i18n'
5   -import { messages } from '@/views/account/adminAccountLang'
6   -
7   -Vue.use(ElementUI)
8   -Vue.use(VueI18n)
9   -
10   -const i18n = new VueI18n({
11   - locale: 'zh', // 设置默认语言
12   - messages
13   -})
14   -
15   -new Vue({
16   - i18n,
17   - // ...其他配置
18   -}).$mount('#app')
19 0 \ No newline at end of file
src/router/index.js
... ... @@ -307,15 +307,45 @@ const routes = [
307 307 component: () => import('@/views/fee/adminFeeConfigList.vue')
308 308 },
309 309 {
310   - path:'/pages/resource/adminEquipment',
311   - name:'/pages/resource/adminEquipment',
  310 + path: '/pages/resource/adminEquipment',
  311 + name: '/pages/resource/adminEquipment',
312 312 component: () => import('@/views/resource/adminEquipmentList.vue')
313   - },
314   - {
315   - path:'/pages/fee/adminRoomFee',
316   - name:'/pages/fee/adminRoomFee',
317   - component: () => import('@/views/fee/adminRoomFeeList.vue')
318   - },
  313 + },
  314 + {
  315 + path: '/pages/fee/adminRoomFee',
  316 + name: '/pages/fee/adminRoomFee',
  317 + component: () => import('@/views/fee/adminRoomFeeList.vue')
  318 + },
  319 + {
  320 + path: '/pages/work/adminRepair',
  321 + name: '/pages/work/adminRepair',
  322 + component: () => import('@/views/work/adminRepairList.vue')
  323 + },
  324 + {
  325 + path: '/views/work/adminRepairDetail',
  326 + name: '/views/work/adminRepairDetail',
  327 + component: () => import('@/views/work/adminRepairDetailList.vue')
  328 + },
  329 + {
  330 + path: '/pages/inspection/adminInspectionPlan',
  331 + name: '/pages/inspection/adminInspectionPlan',
  332 + component: () => import('@/views/inspection/adminInspectionPlanList.vue')
  333 + },
  334 + {
  335 + path: '/pages/inspection/aInspectionPlanDetail',
  336 + name: '/pages/inspection/aInspectionPlanDetail',
  337 + component: () => import('@/views/inspection/aInspectionPlanDetailList.vue')
  338 + },
  339 + {
  340 + path: '/pages/inspection/adminInspectionTask',
  341 + name: '/pages/inspection/adminInspectionTask',
  342 + component: () => import('@/views/inspection/adminInspectionTaskList.vue')
  343 + },
  344 + {
  345 + path: '/views/inspection/adminInspectionTaskDetail',
  346 + name: '/views/inspection/adminInspectionTaskDetail',
  347 + component: () => import('@/views/inspection/adminInspectionTaskDetailList.vue')
  348 + },
319 349 // 其他子路由可以在这里添加
320 350 ]
321 351 },
... ...
src/views/inspection/aInspectionPlanDetailLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + aInspectionPlanDetail: {
  4 + title: 'Inspection Plan',
  5 + planName: 'Plan Name',
  6 + planRoute: 'Plan Route',
  7 + planPeriod: 'Plan Period',
  8 + signType: 'Sign Type',
  9 + dateRange: 'Date Range',
  10 + timeRange: 'Time Range',
  11 + taskAdvance: 'Task Advance(min)',
  12 + creator: 'Creator',
  13 + createTime: 'Create Time',
  14 + status: 'Status',
  15 + staff: 'Staff',
  16 + route: 'Route',
  17 + point: 'Point',
  18 + task: 'Task',
  19 + detail: 'Detail',
  20 + staffName: 'Staff Name',
  21 + startTime: 'Start Time',
  22 + endTime: 'End Time',
  23 + pointId: 'Point ID',
  24 + pointName: 'Point Name',
  25 + pointType: 'Point Type',
  26 + pointLocation: 'Point Location',
  27 + sort: 'Sort',
  28 + detailId: 'Detail ID',
  29 + staffTime: 'Staff Time',
  30 + pointTime: 'Point Time',
  31 + actualTime: 'Actual Time',
  32 + signStatus: 'Sign Status',
  33 + planStaff: 'Plan Staff',
  34 + actualStaff: 'Actual Staff',
  35 + taskStatus: 'Task Status',
  36 + pointStatus: 'Point Status',
  37 + inspectionResult: 'Inspection Result',
  38 + photos: 'Photos',
  39 + // 新增字段
  40 + inspectionMethod: 'Inspection Method',
  41 + taskState: 'Task State',
  42 + pointState: 'Point State',
  43 + createUser: 'Create User',
  44 + inspectionPhotos: 'Inspection Photos'
  45 + }
  46 + },
  47 + zh: {
  48 + aInspectionPlanDetail: {
  49 + title: '巡检计划',
  50 + planName: '计划名称',
  51 + planRoute: '计划路线',
  52 + planPeriod: '计划周期',
  53 + signType: '签到方式',
  54 + dateRange: '日期范围',
  55 + timeRange: '时间范围',
  56 + taskAdvance: '任务提前(分钟)',
  57 + creator: '制定人',
  58 + createTime: '制定时间',
  59 + status: '状态',
  60 + staff: '巡检人员',
  61 + route: '巡检路线',
  62 + point: '巡检点',
  63 + task: '巡检任务',
  64 + detail: '巡检明细',
  65 + staffName: '巡检人员',
  66 + startTime: '开始时间',
  67 + endTime: '结束时间',
  68 + pointId: '巡检点ID',
  69 + pointName: '巡检点名称',
  70 + pointType: '巡检点类型',
  71 + pointLocation: '巡检位置',
  72 + sort: '排序',
  73 + detailId: '任务详情ID',
  74 + staffTime: '巡检人时间',
  75 + pointTime: '巡检点时间',
  76 + actualTime: '实际巡检时间',
  77 + signStatus: '实际签到状态',
  78 + planStaff: '计划巡检人',
  79 + actualStaff: '实际巡检人',
  80 + taskStatus: '任务状态',
  81 + pointStatus: '巡检点状态',
  82 + inspectionResult: '巡检情况',
  83 + photos: '巡检照片',
  84 + // 新增字段
  85 + inspectionMethod: '巡检方式',
  86 + taskState: '任务状态',
  87 + pointState: '巡检点状态',
  88 + createUser: '创建人',
  89 + inspectionPhotos: '巡检照片'
  90 + }
  91 + }
  92 + }
0 93 \ No newline at end of file
... ...
src/views/inspection/aInspectionPlanDetailList.vue 0 → 100644
  1 +<template>
  2 + <div class="aInspectionPlanDetail-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="clearfix flex justify-between">
  5 + <span>{{ $t('aInspectionPlanDetail.title') }}</span>
  6 + </div>
  7 + <el-row :gutter="20">
  8 + <el-col :span="8">
  9 + <div class="form-group">
  10 + <label class="col-form-label">{{ $t('aInspectionPlanDetail.planName') }}:</label>
  11 + <label>{{ aInspectionPlanDetailInfo.inspectionPlanName }}</label>
  12 + </div>
  13 + </el-col>
  14 + <el-col :span="8">
  15 + <div class="form-group">
  16 + <label class="col-form-label">{{ $t('aInspectionPlanDetail.planRoute') }}:</label>
  17 + <label>{{ aInspectionPlanDetailInfo.inspectionRouteName }}</label>
  18 + </div>
  19 + </el-col>
  20 + <el-col :span="8">
  21 + <div class="form-group">
  22 + <label class="col-form-label">{{ $t('aInspectionPlanDetail.planPeriod') }}:</label>
  23 + <label>{{ aInspectionPlanDetailInfo.inspectionPlanPeriodName }}</label>
  24 + </div>
  25 + </el-col>
  26 + <el-col :span="8">
  27 + <div class="form-group">
  28 + <label class="col-form-label">{{ $t('aInspectionPlanDetail.signType') }}:</label>
  29 + <label>{{ aInspectionPlanDetailInfo.signTypeName }}</label>
  30 + </div>
  31 + </el-col>
  32 + <el-col :span="8">
  33 + <div class="form-group">
  34 + <label class="col-form-label">{{ $t('aInspectionPlanDetail.dateRange') }}:</label>
  35 + <label>{{ aInspectionPlanDetailInfo.startDate }}~{{ aInspectionPlanDetailInfo.endDate }}</label>
  36 + </div>
  37 + </el-col>
  38 + <el-col :span="8">
  39 + <div class="form-group">
  40 + <label class="col-form-label">{{ $t('aInspectionPlanDetail.timeRange') }}:</label>
  41 + <label>{{ aInspectionPlanDetailInfo.startTime }}~{{ aInspectionPlanDetailInfo.endTime }}</label>
  42 + </div>
  43 + </el-col>
  44 + <el-col :span="8">
  45 + <div class="form-group">
  46 + <label class="col-form-label">{{ $t('aInspectionPlanDetail.taskAdvance') }}:</label>
  47 + <label>{{ aInspectionPlanDetailInfo.beforeTime }}</label>
  48 + </div>
  49 + </el-col>
  50 + <el-col :span="8">
  51 + <div class="form-group">
  52 + <label class="col-form-label">{{ $t('aInspectionPlanDetail.creator') }}:</label>
  53 + <label>{{ aInspectionPlanDetailInfo.createUserName }}</label>
  54 + </div>
  55 + </el-col>
  56 + <el-col :span="8">
  57 + <div class="form-group">
  58 + <label class="col-form-label">{{ $t('aInspectionPlanDetail.createTime') }}:</label>
  59 + <label>{{ aInspectionPlanDetailInfo.createTime }}</label>
  60 + </div>
  61 + </el-col>
  62 + <el-col :span="8">
  63 + <div class="form-group">
  64 + <label class="col-form-label">{{ $t('aInspectionPlanDetail.status') }}:</label>
  65 + <label>{{ aInspectionPlanDetailInfo.stateName }}</label>
  66 + </div>
  67 + </el-col>
  68 + </el-row>
  69 + <divider></divider>
  70 + <div class="margin-top-sm">
  71 + <el-tabs v-model="aInspectionPlanDetailInfo._currentTab"
  72 + @tab-click="changeTab(aInspectionPlanDetailInfo._currentTab)">
  73 + <el-tab-pane :label="$t('aInspectionPlanDetail.staff')" name="aInspectionPlanDetailStaff">
  74 + <a-inspection-plan-detail-staff ref="aInspectionPlanDetailStaff" />
  75 + </el-tab-pane>
  76 + <el-tab-pane :label="$t('aInspectionPlanDetail.route')" name="adminPointRoute">
  77 + <admin-point-route ref="adminPointRoute" />
  78 + </el-tab-pane>
  79 + <el-tab-pane :label="$t('aInspectionPlanDetail.point')" name="aInspectionRoutePoint">
  80 + <a-inspection-route-point ref="aInspectionRoutePoint" />
  81 + </el-tab-pane>
  82 + <el-tab-pane :label="$t('aInspectionPlanDetail.task')" name="adminRouteTask">
  83 + <admin-route-task ref="adminRouteTask" />
  84 + </el-tab-pane>
  85 + <el-tab-pane :label="$t('aInspectionPlanDetail.detail')" name="adminPointTaskDetail">
  86 + <admin-point-task-detail ref="adminPointTaskDetail" />
  87 + </el-tab-pane>
  88 + </el-tabs>
  89 + </div>
  90 + </el-card>
  91 + </div>
  92 +</template>
  93 +
  94 +<script>
  95 +import { getInspectionPlanDetail } from '@/api/inspection/aInspectionPlanDetailApi'
  96 +import AInspectionPlanDetailStaff from '@/components/inspection/AInspectionPlanDetailStaff'
  97 +import AdminPointRoute from '@/components/inspection/AdminPointRoute'
  98 +import AInspectionRoutePoint from '@/components/inspection/AInspectionRoutePoint'
  99 +import AdminRouteTask from '@/components/inspection/AdminRouteTask'
  100 +import AdminPointTaskDetail from '@/components/inspection/AdminPointTaskDetail'
  101 +import divider from '@/components/system/divider'
  102 +
  103 +export default {
  104 + name: 'AInspectionPlanDetailList',
  105 + components: {
  106 + AInspectionPlanDetailStaff,
  107 + AdminPointRoute,
  108 + AInspectionRoutePoint,
  109 + AdminRouteTask,
  110 + AdminPointTaskDetail,
  111 + divider
  112 + },
  113 + data() {
  114 + return {
  115 + aInspectionPlanDetailInfo: {
  116 + beforeTime: '',
  117 + createTime: '',
  118 + createUserId: '',
  119 + createUserName: '',
  120 + endDate: '',
  121 + endTime: '',
  122 + inspectionPlanId: '',
  123 + inspectionPlanName: '',
  124 + inspectionPlanPeriod: '',
  125 + inspectionPlanPeriodName: '',
  126 + inspectionRouteId: '',
  127 + inspectionRouteName: '',
  128 + signType: '',
  129 + signTypeName: '',
  130 + startDate: '',
  131 + startTime: '',
  132 + state: '',
  133 + stateName: '',
  134 + _currentTab: 'aInspectionPlanDetailStaff'
  135 + }
  136 + }
  137 + },
  138 + created() {
  139 + this.aInspectionPlanDetailInfo.inspectionPlanId = this.$route.query.inspectionPlanId
  140 + this.getInspectionPlanDetail()
  141 + },
  142 + methods: {
  143 + async getInspectionPlanDetail() {
  144 + try {
  145 + const params = {
  146 + inspectionPlanId: this.aInspectionPlanDetailInfo.inspectionPlanId,
  147 + page: 1,
  148 + row: 1
  149 + }
  150 + const { data } = await getInspectionPlanDetail(params)
  151 + if (data && data.length > 0) {
  152 + Object.assign(this.aInspectionPlanDetailInfo, data[0])
  153 + this.changeTab(this.aInspectionPlanDetailInfo._currentTab)
  154 + }
  155 + } catch (error) {
  156 + this.$message.error(this.$t('common.fetchError'))
  157 + }
  158 + },
  159 + changeTab(tab) {
  160 + this.aInspectionPlanDetailInfo._currentTab = tab
  161 + setTimeout(() => {
  162 + if (this.$refs[tab]) {
  163 + this.$refs[tab].loadData({
  164 + inspectionPlanId: this.aInspectionPlanDetailInfo.inspectionPlanId,
  165 + inspectionRouteId: this.aInspectionPlanDetailInfo.inspectionRouteId
  166 + })
  167 + }
  168 + }, 500)
  169 + }
  170 + }
  171 +}
  172 +</script>
  173 +
  174 +<style lang="scss" scoped>
  175 +.aInspectionPlanDetail-container {
  176 + padding: 20px;
  177 +
  178 + .box-card {
  179 + margin-bottom: 20px;
  180 + }
  181 +
  182 + .form-group {
  183 + margin-bottom: 15px;
  184 + text-align: left;
  185 + font-size: 15px;
  186 +
  187 + .col-form-label {
  188 + margin-right: 10px;
  189 + }
  190 + }
  191 +
  192 + .margin-top {
  193 + margin-top: 20px;
  194 + }
  195 +
  196 + .margin-top-sm {
  197 + margin-top: 10px;
  198 + }
  199 +}
  200 +</style>
0 201 \ No newline at end of file
... ...
src/views/inspection/adminInspectionPlanLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + adminInspectionPlan: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + inspectionPlanId: 'Please enter plan ID',
  7 + inspectionPlanName: 'Please enter plan name',
  8 + staffName: 'Please enter inspector',
  9 + state: 'Please select status'
  10 + },
  11 + list: {
  12 + title: 'Inspection Plan'
  13 + },
  14 + table: {
  15 + planName: 'Plan Name',
  16 + communityName: 'Community Name',
  17 + inspectionRoute: 'Plan Route',
  18 + planPeriod: 'Plan Period',
  19 + signType: 'Sign Type',
  20 + dateRange: 'Date Range',
  21 + timeRange: 'Time Range',
  22 + beforeTime: 'Before Time (minutes)',
  23 + creator: 'Creator',
  24 + createTime: 'Create Time',
  25 + state: 'Status',
  26 + inspectionStaff: 'Inspection Staff'
  27 + },
  28 + tip: {
  29 + ensureValid: 'Please ensure the plan start time and end time are valid time ranges and inspectors are set, otherwise inspection tasks cannot be generated'
  30 + },
  31 + community: {
  32 + all: 'All Communities'
  33 + },
  34 + error: {
  35 + fetchListFailed: 'Failed to fetch inspection plan list',
  36 + fetchCommunityFailed: 'Failed to fetch community list',
  37 + fetchStateFailed: 'Failed to fetch status options'
  38 + }
  39 + }
  40 + },
  41 + zh: {
  42 + adminInspectionPlan: {
  43 + search: {
  44 + title: '查询条件',
  45 + inspectionPlanId: '请输入计划ID',
  46 + inspectionPlanName: '请输入计划名称',
  47 + staffName: '请输入巡检人',
  48 + state: '请选择状态'
  49 + },
  50 + list: {
  51 + title: '巡检计划'
  52 + },
  53 + table: {
  54 + planName: '计划名称',
  55 + communityName: '小区名称',
  56 + inspectionRoute: '计划路线',
  57 + planPeriod: '计划周期',
  58 + signType: '签到方式',
  59 + dateRange: '日期范围',
  60 + timeRange: '时间范围',
  61 + beforeTime: '任务提前(分钟)',
  62 + creator: '制定人',
  63 + createTime: '制定时间',
  64 + state: '状态',
  65 + inspectionStaff: '巡检人员'
  66 + },
  67 + tip: {
  68 + ensureValid: '请确保计划开始时间和计划结束时间是有效时间范围,并且设置了巡检人,不然无法生成巡检任务'
  69 + },
  70 + community: {
  71 + all: '全部小区'
  72 + },
  73 + error: {
  74 + fetchListFailed: '获取巡检计划列表失败',
  75 + fetchCommunityFailed: '获取小区列表失败',
  76 + fetchStateFailed: '获取状态选项失败'
  77 + }
  78 + }
  79 + }
  80 +}
0 81 \ No newline at end of file
... ...
src/views/inspection/adminInspectionPlanList.vue 0 → 100644
  1 +<template>
  2 + <div class="admin-inspection-plan-container animated fadeInRight">
  3 + <el-row :gutter="20">
  4 + <el-col :span="3">
  5 + <select-admin-community ref="selectCommunity" @changeCommunity="handleCommunityChange" />
  6 + </el-col>
  7 + <el-col :span="21">
  8 + <el-card class="box-card">
  9 + <div slot="header" class="clearfix flex justify-between">
  10 + <span>{{ $t('adminInspectionPlan.search.title') }}</span>
  11 + </div>
  12 + <el-row :gutter="20">
  13 + <el-col :span="4">
  14 + <el-input v-model="searchForm.inspectionPlanId"
  15 + :placeholder="$t('adminInspectionPlan.search.inspectionPlanId')" clearable />
  16 + </el-col>
  17 + <el-col :span="4">
  18 + <el-input v-model="searchForm.adminInspectionPlanName"
  19 + :placeholder="$t('adminInspectionPlan.search.inspectionPlanName')" clearable />
  20 + </el-col>
  21 + <el-col :span="4">
  22 + <el-input v-model="searchForm.staffNameLike" :placeholder="$t('adminInspectionPlan.search.staffName')"
  23 + clearable />
  24 + </el-col>
  25 + <el-col :span="4">
  26 + <el-select v-model="searchForm.state" :placeholder="$t('adminInspectionPlan.search.state')" clearable>
  27 + <el-option v-for="item in stateOptions" :key="item.statusCd" :label="item.name" :value="item.statusCd" />
  28 + </el-select>
  29 + </el-col>
  30 + <el-col :span="4" class="text-right">
  31 + <el-button type="primary" @click="handleSearch">{{ $t('common.search') }}</el-button>
  32 + <el-button @click="handleReset">{{ $t('common.reset') }}</el-button>
  33 + </el-col>
  34 + </el-row>
  35 +
  36 +
  37 + </el-card>
  38 +
  39 + <el-card class="box-card mt-20">
  40 + <div slot="header" class="clearfix flex justify-between">
  41 + <span>{{ $t('adminInspectionPlan.list.title') }}</span>
  42 + </div>
  43 + <el-table v-loading="loading" :data="tableData" border style="width: 100%">
  44 + <el-table-column prop="inspectionPlanName" :label="$t('adminInspectionPlan.table.planName')" align="center" />
  45 + <el-table-column prop="communityName" :label="$t('adminInspectionPlan.table.communityName')" align="center" />
  46 + <el-table-column prop="inspectionRouteName" :label="$t('adminInspectionPlan.table.inspectionRoute')"
  47 + align="center" />
  48 + <el-table-column prop="inspectionPlanPeriodName" :label="$t('adminInspectionPlan.table.planPeriod')"
  49 + align="center" />
  50 + <el-table-column prop="signTypeName" :label="$t('adminInspectionPlan.table.signType')" align="center" />
  51 + <el-table-column :label="$t('adminInspectionPlan.table.dateRange')" align="center">
  52 + <template slot-scope="scope">
  53 + {{ scope.row.startDate }}~{{ scope.row.endDate }}
  54 + </template>
  55 + </el-table-column>
  56 + <el-table-column :label="$t('adminInspectionPlan.table.timeRange')" align="center">
  57 + <template slot-scope="scope">
  58 + {{ scope.row.startTime }}~{{ scope.row.endTime }}
  59 + </template>
  60 + </el-table-column>
  61 + <el-table-column prop="beforeTime" :label="$t('adminInspectionPlan.table.beforeTime')" align="center" />
  62 + <el-table-column prop="createUserName" :label="$t('adminInspectionPlan.table.creator')" align="center" />
  63 + <el-table-column prop="createTime" :label="$t('adminInspectionPlan.table.createTime')" align="center" />
  64 + <el-table-column prop="stateName" :label="$t('adminInspectionPlan.table.state')" align="center" />
  65 + <el-table-column :label="$t('adminInspectionPlan.table.inspectionStaff')" align="center">
  66 + <template slot-scope="scope">
  67 + <div v-for="(staff, i) in scope.row.staffs" :key="i">{{ staff.staffName }}</div>
  68 + </template>
  69 + </el-table-column>
  70 + <el-table-column :label="$t('common.operation')" align="center" width="120">
  71 + <template slot-scope="scope">
  72 + <el-button size="mini" type="primary" @click="handleDetail(scope.row)">
  73 + {{ $t('common.detail') }}
  74 + </el-button>
  75 + </template>
  76 + </el-table-column>
  77 + </el-table>
  78 +
  79 + <el-row class="mt-20">
  80 + <el-col :span="12">
  81 + <div class="tip-text">
  82 + {{ $t('adminInspectionPlan.tip.ensureValid') }}
  83 + </div>
  84 + </el-col>
  85 + <el-col :span="12" class="text-right">
  86 + <el-pagination :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]"
  87 + :page-size="pagination.size" :total="pagination.total" layout="total, sizes, prev, pager, next, jumper"
  88 + @size-change="handleSizeChange" @current-change="handleCurrentChange" />
  89 + </el-col>
  90 + </el-row>
  91 + </el-card>
  92 + </el-col>
  93 + </el-row>
  94 + </div>
  95 +</template>
  96 +
  97 +<script>
  98 +import SelectAdminCommunity from '@/components/community/selectAdminCommunity'
  99 +import { listAdminInspectionPlans } from '@/api/inspection/adminInspectionPlanApi'
  100 +import { getDict } from '@/api/community/communityApi'
  101 +
  102 +export default {
  103 + name: 'AdminInspectionPlanList',
  104 + components: {
  105 + SelectAdminCommunity
  106 + },
  107 + data() {
  108 + return {
  109 + loading: false,
  110 + searchForm: {
  111 + inspectionPlanId: '',
  112 + adminInspectionPlanName: '',
  113 + staffNameLike: '',
  114 + state: '',
  115 + communityId: ''
  116 + },
  117 + tableData: [],
  118 + stateOptions: [],
  119 + pagination: {
  120 + current: 1,
  121 + size: 10,
  122 + total: 0
  123 + }
  124 + }
  125 + },
  126 + created() {
  127 + this.getStateOptions()
  128 + this.getList()
  129 + },
  130 + methods: {
  131 + async getStateOptions() {
  132 + try {
  133 + const res = await getDict('inspection_plan', 'state')
  134 + this.stateOptions = res.data
  135 + } catch (error) {
  136 + this.$message.error(this.$t('adminInspectionPlan.error.fetchStateFailed'))
  137 + }
  138 + },
  139 + async getList() {
  140 + try {
  141 + this.loading = true
  142 + const params = {
  143 + ...this.searchForm,
  144 + page: this.pagination.current,
  145 + row: this.pagination.size
  146 + }
  147 + const res = await listAdminInspectionPlans(params)
  148 + this.tableData = res.data
  149 + this.pagination.total = res.total
  150 + } catch (error) {
  151 + this.$message.error(this.$t('adminInspectionPlan.error.fetchListFailed'))
  152 + } finally {
  153 + this.loading = false
  154 + }
  155 + },
  156 + handleCommunityChange(community) {
  157 + this.searchForm.communityId = community.communityId
  158 + this.getList()
  159 + },
  160 + handleSearch() {
  161 + this.pagination.current = 1
  162 + this.getList()
  163 + },
  164 + handleReset() {
  165 + this.searchForm = {
  166 + inspectionPlanId: '',
  167 + adminInspectionPlanName: '',
  168 + staffNameLike: '',
  169 + state: '',
  170 + communityId: this.searchForm.communityId
  171 + }
  172 + this.getList()
  173 + },
  174 + handleDetail(row) {
  175 + window.open(`/#/pages/inspection/aInspectionPlanDetail?inspectionPlanId=${row.inspectionPlanId}`)
  176 + },
  177 + handleSizeChange(val) {
  178 + this.pagination.size = val
  179 + this.getList()
  180 + },
  181 + handleCurrentChange(val) {
  182 + this.pagination.current = val
  183 + this.getList()
  184 + }
  185 + }
  186 +}
  187 +</script>
  188 +
  189 +<style lang="scss" scoped>
  190 +.admin-inspection-plan-container {
  191 + padding: 20px;
  192 +
  193 + .mt-10 {
  194 + margin-top: 10px;
  195 + }
  196 +
  197 + .mt-20 {
  198 + margin-top: 20px;
  199 + }
  200 +
  201 + .text-right {
  202 + text-align: right;
  203 + }
  204 +
  205 + .tip-text {
  206 + color: #999;
  207 + font-size: 12px;
  208 + line-height: 30px;
  209 + }
  210 +}
  211 +</style>
0 212 \ No newline at end of file
... ...
src/views/inspection/adminInspectionTaskDetailLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + adminInspectionTaskDetail: {
  4 + title: 'Inspection Task',
  5 + taskId: 'Task Code',
  6 + inspectionPlanName: 'Inspection Plan',
  7 + planTime: 'Start/End Time',
  8 + actInsTime: 'Actual Inspection Time',
  9 + originalPlanUser: 'Planned Inspector',
  10 + currentPlanUser: 'Current Inspector',
  11 + transferDesc: 'Transfer Description',
  12 + signType: 'Inspection Method',
  13 + state: 'Inspection Status',
  14 + tab: {
  15 + detail: 'Inspection Details',
  16 + map: 'Inspection Map',
  17 + plan: 'Inspection Plan',
  18 + route: 'Inspection Route',
  19 + point: 'Inspection Points'
  20 + }
  21 + },
  22 + adminRoutePlan: {
  23 + table: {
  24 + planName: 'Plan Name',
  25 + routeName: 'Route Name',
  26 + planPeriod: 'Plan Period',
  27 + signType: 'Sign Type',
  28 + dateRange: 'Date Range',
  29 + timeRange: 'Time Range',
  30 + beforeTime: 'Before Time (minutes)',
  31 + creator: 'Creator',
  32 + createTime: 'Create Time',
  33 + inspectors: 'Inspectors',
  34 + status: 'Status'
  35 + }
  36 + }
  37 + },
  38 + zh: {
  39 + adminInspectionTaskDetail: {
  40 + title: '巡检任务',
  41 + taskId: '任务编码',
  42 + inspectionPlanName: '巡检计划',
  43 + planTime: '开始/结束时间',
  44 + actInsTime: '实际巡检时间',
  45 + originalPlanUser: '计划巡检人',
  46 + currentPlanUser: '当前巡检人',
  47 + transferDesc: '转移描述',
  48 + signType: '巡检方式',
  49 + state: '巡检状态',
  50 + tab: {
  51 + detail: '巡检明细',
  52 + map: '巡检地图',
  53 + plan: '巡检计划',
  54 + route: '巡检路线',
  55 + point: '巡检点'
  56 + }
  57 + },
  58 + adminRoutePlan: {
  59 + table: {
  60 + planName: '计划名称',
  61 + routeName: '计划路线',
  62 + planPeriod: '计划周期',
  63 + signType: '签到方式',
  64 + dateRange: '日期范围',
  65 + timeRange: '时间范围',
  66 + beforeTime: '任务提前(分钟)',
  67 + creator: '制定人',
  68 + createTime: '制定时间',
  69 + inspectors: '巡检人',
  70 + status: '状态'
  71 + }
  72 + }
  73 + }
  74 + }
0 75 \ No newline at end of file
... ...
src/views/inspection/adminInspectionTaskDetailList.vue 0 → 100644
  1 +<template>
  2 + <div class="admin-inspection-task-detail-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="clearfix flex justify-between">
  5 + <span>{{ $t('adminInspectionTaskDetail.title') }}</span>
  6 + </div>
  7 + <div class="card-content">
  8 + <el-row :gutter="20">
  9 + <el-col :span="6">
  10 + <div class="form-group">
  11 + <label class="col-form-label">
  12 + {{ $t('adminInspectionTaskDetail.taskId') }}:
  13 + </label>
  14 + <label>{{ adminInspectionTaskDetailInfo.taskId }}</label>
  15 + </div>
  16 + </el-col>
  17 + <el-col :span="6">
  18 + <div class="form-group">
  19 + <label class="col-form-label">
  20 + {{ $t('adminInspectionTaskDetail.inspectionPlanName') }}:
  21 + </label>
  22 + <label>{{ adminInspectionTaskDetailInfo.inspectionPlanName }}</label>
  23 + </div>
  24 + </el-col>
  25 + <el-col :span="6">
  26 + <div class="form-group">
  27 + <label class="col-form-label">
  28 + {{ $t('adminInspectionTaskDetail.planTime') }}:
  29 + </label>
  30 + <label>
  31 + {{ adminInspectionTaskDetailInfo.planInsTime }}<br>~{{
  32 + adminInspectionTaskDetailInfo.planEndTime }}
  33 + </label>
  34 + </div>
  35 + </el-col>
  36 + <el-col :span="6">
  37 + <div class="form-group">
  38 + <label class="col-form-label">
  39 + {{ $t('adminInspectionTaskDetail.actInsTime') }}:
  40 + </label>
  41 + <label>{{ adminInspectionTaskDetailInfo.actInsTime || '-' }}</label>
  42 + </div>
  43 + </el-col>
  44 + </el-row>
  45 + <el-row :gutter="20">
  46 + <el-col :span="6">
  47 + <div class="form-group">
  48 + <label class="col-form-label">
  49 + {{ $t('adminInspectionTaskDetail.originalPlanUser') }}:
  50 + </label>
  51 + <label>{{ adminInspectionTaskDetailInfo.originalPlanUserName || '-' }}</label>
  52 + </div>
  53 + </el-col>
  54 + <el-col :span="6">
  55 + <div class="form-group">
  56 + <label class="col-form-label">
  57 + {{ $t('adminInspectionTaskDetail.currentPlanUser') }}:
  58 + </label>
  59 + <label>{{ adminInspectionTaskDetailInfo.planUserName }}</label>
  60 + </div>
  61 + </el-col>
  62 + <el-col :span="6">
  63 + <div class="form-group">
  64 + <label class="col-form-label">
  65 + {{ $t('adminInspectionTaskDetail.transferDesc') }}:
  66 + </label>
  67 + <label>{{ adminInspectionTaskDetailInfo.transferDesc || '-' }}</label>
  68 + </div>
  69 + </el-col>
  70 + <el-col :span="6">
  71 + <div class="form-group">
  72 + <label class="col-form-label">
  73 + {{ $t('adminInspectionTaskDetail.signType') }}:
  74 + </label>
  75 + <label>{{ adminInspectionTaskDetailInfo.signTypeName }}</label>
  76 + </div>
  77 + </el-col>
  78 + <el-col :span="6">
  79 + <div class="form-group">
  80 + <label class="col-form-label">
  81 + {{ $t('adminInspectionTaskDetail.state') }}:
  82 + </label>
  83 + <label>{{ adminInspectionTaskDetailInfo.stateName }}</label>
  84 + </div>
  85 + </el-col>
  86 + </el-row>
  87 + </div>
  88 + </el-card>
  89 +
  90 + <el-card class="box-card margin-top">
  91 + <div class="card-content">
  92 + <el-tabs v-model="adminInspectionTaskDetailInfo._currentTab"
  93 + @tab-click="handleTabClick(adminInspectionTaskDetailInfo._currentTab)">
  94 + <el-tab-pane :label="$t('adminInspectionTaskDetail.tab.detail')" name="adminPointTaskDetail">
  95 + <admin-point-task-detail ref="adminPointTaskDetail" />
  96 + </el-tab-pane>
  97 + <el-tab-pane :label="$t('adminInspectionTaskDetail.tab.map')" name="aInspectionTaskMap">
  98 + <a-inspection-task-map ref="aInspectionTaskMap" />
  99 + </el-tab-pane>
  100 + <el-tab-pane :label="$t('adminInspectionTaskDetail.tab.plan')" name="adminRoutePlan">
  101 + <admin-route-plan ref="adminRoutePlan" />
  102 + </el-tab-pane>
  103 + <el-tab-pane :label="$t('adminInspectionTaskDetail.tab.route')" name="adminPointRoute">
  104 + <admin-point-route ref="adminPointRoute" />
  105 + </el-tab-pane>
  106 + <el-tab-pane :label="$t('adminInspectionTaskDetail.tab.point')" name="aInspectionRoutePoint">
  107 + <a-inspection-route-point ref="aInspectionRoutePoint" />
  108 + </el-tab-pane>
  109 + </el-tabs>
  110 + </div>
  111 + </el-card>
  112 + </div>
  113 +</template>
  114 +
  115 +<script>
  116 +import AdminPointTaskDetail from '@/components/inspection/AdminPointTaskDetail'
  117 +import AInspectionTaskMap from '@/components/inspection/AInspectionTaskMap'
  118 +import AdminRoutePlan from '@/components/inspection/AdminRoutePlan'
  119 +import AdminPointRoute from '@/components/inspection/AdminPointRoute'
  120 +import AInspectionRoutePoint from '@/components/inspection/AInspectionRoutePoint'
  121 +import { getAdminInspectionTaskDetail } from '@/api/inspection/adminInspectionTaskDetailApi'
  122 +
  123 +export default {
  124 + name: 'AdminInspectionTaskDetailList',
  125 + components: {
  126 + AdminPointTaskDetail,
  127 + AInspectionTaskMap,
  128 + AdminRoutePlan,
  129 + AdminPointRoute,
  130 + AInspectionRoutePoint
  131 + },
  132 + data() {
  133 + return {
  134 + adminInspectionTaskDetailInfo: {
  135 + inspectionPlanId: '',
  136 + inspectionPlanName: '',
  137 + originalPlanUserId: '',
  138 + originalPlanUserName: '',
  139 + planEndTime: '',
  140 + planInsTime: '',
  141 + planUserId: '',
  142 + planUserName: '',
  143 + signType: '',
  144 + signTypeName: '',
  145 + state: '',
  146 + stateName: '',
  147 + taskId: '',
  148 + taskType: '',
  149 + inspectionRouteId: '',
  150 + total: 0,
  151 + records: 1,
  152 + moreCondition: false,
  153 + inspectionName: '',
  154 + pointObjTypes: [],
  155 + _currentTab: 'adminPointTaskDetail'
  156 + }
  157 + }
  158 + },
  159 + created() {
  160 + this.adminInspectionTaskDetailInfo.taskId = this.$route.query.taskId
  161 + this.loadAdminInspectionTaskDetail()
  162 + },
  163 + methods: {
  164 + async loadAdminInspectionTaskDetail() {
  165 + try {
  166 + const params = {
  167 + page: 1,
  168 + row: 1,
  169 + taskId: this.adminInspectionTaskDetailInfo.taskId
  170 + }
  171 + const { inspectionTasks } = await getAdminInspectionTaskDetail(params)
  172 + Object.assign(this.adminInspectionTaskDetailInfo, inspectionTasks[0])
  173 + this.handleTabClick(this.adminInspectionTaskDetailInfo._currentTab)
  174 + } catch (error) {
  175 + this.$message.error(this.$t('common.fetchError'))
  176 + }
  177 + },
  178 + handleTabClick(tab) {
  179 + this.adminInspectionTaskDetailInfo._currentTab = tab
  180 + setTimeout(() => {
  181 + if (this.$refs[tab]) {
  182 + this.$refs[tab].loadData({
  183 + taskId: this.adminInspectionTaskDetailInfo.taskId,
  184 + inspectionPlanId: this.adminInspectionTaskDetailInfo.inspectionPlanId,
  185 + inspectionRouteId: this.adminInspectionTaskDetailInfo.inspectionRouteId
  186 + })
  187 + }
  188 + }, 500)
  189 + }
  190 + }
  191 +}
  192 +</script>
  193 +
  194 +<style lang="scss" scoped>
  195 +.admin-inspection-task-detail-container {
  196 + padding: 20px;
  197 +
  198 + .box-card {
  199 + margin-bottom: 20px;
  200 +
  201 + .card-content {
  202 + padding: 20px;
  203 + }
  204 + }
  205 +
  206 + .form-group {
  207 + margin-bottom: 15px;
  208 + text-align: left;
  209 +
  210 + .col-form-label {
  211 + margin-right: 5px;
  212 + }
  213 + }
  214 +
  215 + .margin-top {
  216 + margin-top: 20px;
  217 + }
  218 +}
  219 +</style>
0 220 \ No newline at end of file
... ...
src/views/inspection/adminInspectionTaskLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + adminInspectionTask: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + startTime: 'Please enter actual inspection start time',
  7 + endTime: 'Please enter actual inspection end time',
  8 + state: 'Please select inspection status',
  9 + button: 'Search'
  10 + },
  11 + list: {
  12 + title: 'Inspection Tasks',
  13 + tip: 'Inspection tasks are automatically generated at 2:00 am every day according to the inspection plan. If they are not generated, please confirm whether the scheduled task is enabled or whether the inspection plan is set correctly'
  14 + },
  15 + table: {
  16 + taskId: 'Task Code',
  17 + communityName: 'Community Name',
  18 + inspectionPlanName: 'Inspection Plan',
  19 + planTime: 'Plan Time',
  20 + actInsTime: 'Actual Inspection Time',
  21 + originalPlanUserName: 'Original Inspector',
  22 + planUserName: 'Current Inspector',
  23 + transferDesc: 'Transfer Description',
  24 + signTypeName: 'Inspection Method',
  25 + stateName: 'Inspection Status',
  26 + operation: 'Operation',
  27 + detail: 'Detail'
  28 + }
  29 + }
  30 + },
  31 + zh: {
  32 + adminInspectionTask: {
  33 + search: {
  34 + title: '查询条件',
  35 + startTime: '请输入实际巡检开始时间',
  36 + endTime: '请输入实际巡检结束时间',
  37 + state: '请选择巡检状态',
  38 + button: '查询'
  39 + },
  40 + list: {
  41 + title: '巡检任务',
  42 + tip: '巡检任务是根据巡检计划,每天晚上2点钟自动生成,如果没有生成请确认是否开启了定时任务,或者巡检计划是否设置正确'
  43 + },
  44 + table: {
  45 + taskId: '任务编码',
  46 + communityName: '小区名称',
  47 + inspectionPlanName: '巡检计划',
  48 + planTime: '计划时间',
  49 + actInsTime: '实际巡检时间',
  50 + originalPlanUserName: '计划巡检人',
  51 + planUserName: '当前巡检人',
  52 + transferDesc: '转移描述',
  53 + signTypeName: '巡检方式',
  54 + stateName: '巡检状态',
  55 + operation: '操作',
  56 + detail: '详情'
  57 + }
  58 + }
  59 + }
  60 +}
0 61 \ No newline at end of file
... ...
src/views/inspection/adminInspectionTaskList.vue 0 → 100644
  1 +<template>
  2 + <div class="admin-inspection-task-container">
  3 + <el-row class="flex justify-start">
  4 + <el-col :span="4" class="room-floor-unit-tree">
  5 + <community-inspection-tree ref="communityTree" @notifyQuery="handleTreeQuery"></community-inspection-tree>
  6 + </el-col>
  7 + <el-col :span="20" class=" margin-left-sm">
  8 + <el-card class="box-card">
  9 + <div slot="header" class="clearfix flex justify-between">
  10 + <span>{{ $t('adminInspectionTask.search.title') }}</span>
  11 + </div>
  12 + <el-row :gutter="20">
  13 + <el-col :span="6">
  14 + <el-date-picker
  15 + v-model="searchForm.startTime"
  16 + type="datetime"
  17 + :placeholder="$t('adminInspectionTask.search.startTime')"
  18 + style="width: 100%"
  19 + value-format="yyyy-MM-dd HH:mm:ss"
  20 + ></el-date-picker>
  21 + </el-col>
  22 + <el-col :span="6">
  23 + <el-date-picker
  24 + v-model="searchForm.endTime"
  25 + type="datetime"
  26 + :placeholder="$t('adminInspectionTask.search.endTime')"
  27 + style="width: 100%"
  28 + value-format="yyyy-MM-dd HH:mm:ss"
  29 + ></el-date-picker>
  30 + </el-col>
  31 + <el-col :span="6">
  32 + <el-select
  33 + v-model="searchForm.state"
  34 + :placeholder="$t('adminInspectionTask.search.state')"
  35 + style="width: 100%"
  36 + >
  37 + <el-option
  38 + v-for="item in stateTypes"
  39 + :key="item.statusCd"
  40 + :label="item.name"
  41 + :value="item.statusCd"
  42 + ></el-option>
  43 + </el-select>
  44 + </el-col>
  45 + <el-col :span="6">
  46 + <el-button type="primary" @click="handleSearch">{{ $t('adminInspectionTask.search.button') }}</el-button>
  47 + </el-col>
  48 + </el-row>
  49 + </el-card>
  50 +
  51 + <el-card class="box-card margin-top">
  52 + <div slot="header" class="clearfix flex justify-between">
  53 + <span>{{ $t('adminInspectionTask.list.title') }}</span>
  54 + </div>
  55 + <el-table :data="tableData" border style="width: 100%">
  56 + <el-table-column prop="taskId" :label="$t('adminInspectionTask.table.taskId')" align="center"></el-table-column>
  57 + <el-table-column prop="communityName" :label="$t('adminInspectionTask.table.communityName')" align="center"></el-table-column>
  58 + <el-table-column prop="inspectionPlanName" :label="$t('adminInspectionTask.table.inspectionPlanName')" align="center"></el-table-column>
  59 + <el-table-column :label="$t('adminInspectionTask.table.planTime')" align="center">
  60 + <template slot-scope="scope">
  61 + <div>{{ scope.row.planInsTime }}</div>
  62 + <div>{{ scope.row.planEndTime }}</div>
  63 + </template>
  64 + </el-table-column>
  65 + <el-table-column prop="actInsTime" :label="$t('adminInspectionTask.table.actInsTime')" align="center">
  66 + <template slot-scope="scope">
  67 + {{ scope.row.actInsTime || '-' }}
  68 + </template>
  69 + </el-table-column>
  70 + <el-table-column prop="originalPlanUserName" :label="$t('adminInspectionTask.table.originalPlanUserName')" align="center">
  71 + <template slot-scope="scope">
  72 + {{ scope.row.originalPlanUserName || '-' }}
  73 + </template>
  74 + </el-table-column>
  75 + <el-table-column prop="planUserName" :label="$t('adminInspectionTask.table.planUserName')" align="center"></el-table-column>
  76 + <el-table-column prop="transferDesc" :label="$t('adminInspectionTask.table.transferDesc')" align="center">
  77 + <template slot-scope="scope">
  78 + {{ scope.row.transferDesc || '-' }}
  79 + </template>
  80 + </el-table-column>
  81 + <el-table-column prop="signTypeName" :label="$t('adminInspectionTask.table.signTypeName')" align="center"></el-table-column>
  82 + <el-table-column prop="stateName" :label="$t('adminInspectionTask.table.stateName')" align="center">
  83 + <template slot-scope="scope">
  84 + <span v-if="scope.row.state === '20200408'" class="text-danger">{{ scope.row.stateName }}</span>
  85 + <span v-else>{{ scope.row.stateName }}</span>
  86 + </template>
  87 + </el-table-column>
  88 + <el-table-column :label="$t('adminInspectionTask.table.operation')" align="center" width="120">
  89 + <template slot-scope="scope">
  90 + <el-button size="mini" @click="handleDetail(scope.row)">{{ $t('adminInspectionTask.table.detail') }}</el-button>
  91 + </template>
  92 + </el-table-column>
  93 + </el-table>
  94 +
  95 + <el-row class="margin-top">
  96 + <el-col :span="18">
  97 + <div class="tip-text">
  98 + {{ $t('adminInspectionTask.list.tip') }}
  99 + </div>
  100 + </el-col>
  101 + <el-col :span="6">
  102 + <el-pagination
  103 + :current-page.sync="pagination.current"
  104 + :page-sizes="[10, 20, 30, 50]"
  105 + :page-size="pagination.size"
  106 + :total="pagination.total"
  107 + layout="total, sizes, prev, pager, next, jumper"
  108 + @size-change="handleSizeChange"
  109 + @current-change="handleCurrentChange"
  110 + ></el-pagination>
  111 + </el-col>
  112 + </el-row>
  113 + </el-card>
  114 + </el-col>
  115 + </el-row>
  116 + </div>
  117 +</template>
  118 +
  119 +<script>
  120 +import { listAdminInspectionTasks } from '@/api/inspection/adminInspectionTaskApi'
  121 +import CommunityInspectionTree from '@/components/inspection/communityInspectionTree'
  122 +import {getDict} from '@/api/community/communityApi'
  123 +
  124 +export default {
  125 + name: 'AdminInspectionTaskList',
  126 + components: {
  127 + CommunityInspectionTree
  128 + },
  129 + data() {
  130 + return {
  131 + searchForm: {
  132 + startTime: '',
  133 + endTime: '',
  134 + state: '',
  135 + communityId: '',
  136 + inspectionPlanId: '',
  137 + staffId: '',
  138 + orderByDesc: 'desc'
  139 + },
  140 + stateTypes: [],
  141 + tableData: [],
  142 + pagination: {
  143 + current: 1,
  144 + size: 10,
  145 + total: 0
  146 + },
  147 + loading: false
  148 + }
  149 + },
  150 + created() {
  151 + this.getDictData()
  152 + this.getList()
  153 + },
  154 + methods: {
  155 + async getDictData() {
  156 + try {
  157 + const response = await getDict('inspection_task', 'state')
  158 + this.stateTypes = response || []
  159 + } catch (error) {
  160 + console.error('Failed to get dict data:', error)
  161 + }
  162 + },
  163 + async getList() {
  164 + this.loading = true
  165 + try {
  166 + const params = {
  167 + ...this.searchForm,
  168 + page: this.pagination.current,
  169 + row: this.pagination.size
  170 + }
  171 + const response = await listAdminInspectionTasks(params)
  172 + this.tableData = response.inspectionTasks || []
  173 + this.pagination.total = response.data.total || 0
  174 + } catch (error) {
  175 + console.error('Failed to get inspection tasks:', error)
  176 + } finally {
  177 + this.loading = false
  178 + }
  179 + },
  180 + handleTreeQuery(params) {
  181 + this.searchForm.communityId = params.communityId
  182 + this.searchForm.inspectionPlanId = params.inspectionPlanId
  183 + this.searchForm.staffId = params.staffId
  184 + this.getList()
  185 + },
  186 + handleSearch() {
  187 + this.pagination.current = 1
  188 + this.getList()
  189 + },
  190 + handleDetail(row) {
  191 + window.open(`/#/views/inspection/adminInspectionTaskDetail?taskId=${row.taskId}`)
  192 + },
  193 + handleSizeChange(val) {
  194 + this.pagination.size = val
  195 + this.getList()
  196 + },
  197 + handleCurrentChange(val) {
  198 + this.pagination.current = val
  199 + this.getList()
  200 + }
  201 + }
  202 +}
  203 +</script>
  204 +
  205 +<style lang="scss" scoped>
  206 +.admin-inspection-task-container {
  207 + padding: 20px;
  208 +
  209 + .margin-top {
  210 + margin-top: 20px;
  211 + }
  212 +
  213 + .margin-top-xs {
  214 + margin-top: 10px;
  215 + }
  216 +
  217 + .margin-left-sm {
  218 + margin-left: 10px;
  219 + }
  220 +
  221 + .room-floor-unit-tree {
  222 + padding-right: 0;
  223 + }
  224 +
  225 + .tip-text {
  226 + padding: 10px;
  227 + color: #666;
  228 + font-size: 14px;
  229 + }
  230 +
  231 + .text-danger {
  232 + color: #f56c6c;
  233 + font-weight: bold;
  234 + }
  235 +}
  236 +</style>
0 237 \ No newline at end of file
... ...
src/views/work/adminRepairDetailLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + adminRepairDetail: {
  4 + title: 'Repair Detail',
  5 + back: 'Back',
  6 + repairId: 'Work Order Code',
  7 + repairType: 'Repair Type',
  8 + repairName: 'Repairer',
  9 + tel: 'Contact',
  10 + location: 'Location',
  11 + appointmentTime: 'Appointment Time',
  12 + status: 'Status',
  13 + repairContent: 'Repair Content',
  14 + maintenanceType: 'Maintenance Type',
  15 + paidService: 'Paid Service',
  16 + freeService: 'Free Service',
  17 + needMaterials: 'Need Materials',
  18 + noMaterials: 'No Materials',
  19 + materials: 'Materials',
  20 + feeDetails: 'Fee Details',
  21 + yuan: 'Yuan (Unit Price * Quantity)',
  22 + comprehensiveScore: 'Comprehensive Score',
  23 + doorSpeedScore: 'Door Speed Score',
  24 + serviceScore: 'Service Score',
  25 + averageScore: 'Average Score',
  26 + points: 'Points',
  27 + visitSatisfaction: 'Visit Satisfaction',
  28 + satisfied: 'Satisfied',
  29 + dissatisfied: 'Dissatisfied',
  30 + visitContent: 'Visit Content',
  31 + repairPhotos: 'Work Order Photos',
  32 + beforePhotos: 'Before Repair Photos',
  33 + afterPhotos: 'After Repair Photos',
  34 + relatedItems: 'Related Items',
  35 + itemId: 'Item ID',
  36 + itemType: 'Item Type',
  37 + itemName: 'Item Name',
  38 + itemSpec: 'Item Specification',
  39 + itemQuantity: 'Item Quantity',
  40 + itemPrice: 'Item Price',
  41 + user: 'User',
  42 + time: 'Time',
  43 + workflow: 'Work Order Flow',
  44 + serial: 'No.',
  45 + handler: 'Handler',
  46 + startTime: 'Start Time',
  47 + endTime: 'End Time',
  48 + duration: 'Duration',
  49 + comment: 'Comment',
  50 + reply: 'Reply',
  51 + replyAppraise: 'Reply Appraise',
  52 + content: 'Content',
  53 + replyPlaceholder: 'Required, please fill in the reply content',
  54 + replyRequired: 'Reply content is required',
  55 + replyMaxLength: 'Reply content cannot exceed 512 characters',
  56 + replySuccess: 'Reply submitted successfully',
  57 + replyError: 'Failed to submit reply',
  58 + invalidOperation: 'Invalid operation',
  59 + dataError: 'Data error',
  60 + loadError: 'Failed to load repair details',
  61 + loadResourceError: 'Failed to load resource records',
  62 + loadUserError: 'Failed to load repair staff'
  63 + }
  64 + },
  65 + zh: {
  66 + adminRepairDetail: {
  67 + title: '报修详情',
  68 + back: '返回',
  69 + repairId: '工单编码',
  70 + repairType: '报修类型',
  71 + repairName: '报修人',
  72 + tel: '联系方式',
  73 + location: '位置',
  74 + appointmentTime: '预约时间',
  75 + status: '状态',
  76 + repairContent: '报修内容',
  77 + maintenanceType: '维修类型',
  78 + paidService: '有偿服务',
  79 + freeService: '无偿服务',
  80 + needMaterials: '需要用料',
  81 + noMaterials: '无需用料',
  82 + materials: '用料',
  83 + feeDetails: '费用明细',
  84 + yuan: '元(单价*数量)',
  85 + comprehensiveScore: '综合评价得分',
  86 + doorSpeedScore: '上门速度评分',
  87 + serviceScore: '维修员服务评分',
  88 + averageScore: '平均分',
  89 + points: '分',
  90 + visitSatisfaction: '回访满意度',
  91 + satisfied: '满意',
  92 + dissatisfied: '不满意',
  93 + visitContent: '回访内容',
  94 + repairPhotos: '工单图片',
  95 + beforePhotos: '维修前图片',
  96 + afterPhotos: '维修后图片',
  97 + relatedItems: '相关物品',
  98 + itemId: '物品资源编号',
  99 + itemType: '物品资源类型',
  100 + itemName: '物品资源名称',
  101 + itemSpec: '物品资源规格',
  102 + itemQuantity: '物品使用数量',
  103 + itemPrice: '物品价格',
  104 + user: '使用人',
  105 + time: '时间',
  106 + workflow: '工单流转',
  107 + serial: '序号',
  108 + handler: '处理人',
  109 + startTime: '处理开始时间',
  110 + endTime: '处理结束时间',
  111 + duration: '耗时',
  112 + comment: '意见',
  113 + reply: '回复',
  114 + replyAppraise: '回复评价',
  115 + content: '内容',
  116 + replyPlaceholder: '必填,请填写回复内容',
  117 + replyRequired: '回复内容不能为空',
  118 + replyMaxLength: '回复内容超过500个字',
  119 + replySuccess: '回复成功',
  120 + replyError: '回复失败',
  121 + invalidOperation: '非法操作',
  122 + dataError: '数据异常',
  123 + loadError: '加载报修详情失败',
  124 + loadResourceError: '加载物品记录失败',
  125 + loadUserError: '加载维修人员失败'
  126 + }
  127 + }
  128 +}
0 129 \ No newline at end of file
... ...
src/views/work/adminRepairDetailList.vue 0 → 100644
  1 +<template>
  2 + <div class="admin-repair-detail-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="clearfix">
  5 + <span>{{ $t('adminRepairDetail.title') }}</span>
  6 + <el-button type="primary" size="small" class="float-right" @click="goBack">
  7 + {{ $t('adminRepairDetail.back') }}
  8 + </el-button>
  9 + </div>
  10 +
  11 + <el-row :gutter="20">
  12 + <el-col :span="8">
  13 + <div class="form-item">
  14 + <label>{{ $t('adminRepairDetail.repairId') }}:</label>
  15 + <span>{{ adminRepairDetailInfo.repairId }}</span>
  16 + </div>
  17 + </el-col>
  18 + <el-col :span="8">
  19 + <div class="form-item">
  20 + <label>{{ $t('adminRepairDetail.repairType') }}:</label>
  21 + <span>{{ adminRepairDetailInfo.repairTypeName }}</span>
  22 + </div>
  23 + </el-col>
  24 + <el-col :span="8">
  25 + <div class="form-item">
  26 + <label>{{ $t('adminRepairDetail.repairName') }}:</label>
  27 + <span>{{ adminRepairDetailInfo.repairName }}</span>
  28 + </div>
  29 + </el-col>
  30 + <el-col :span="8">
  31 + <div class="form-item">
  32 + <label>{{ $t('adminRepairDetail.tel') }}:</label>
  33 + <span>{{ adminRepairDetailInfo.tel }}</span>
  34 + </div>
  35 + </el-col>
  36 + <el-col :span="8">
  37 + <div class="form-item">
  38 + <label>{{ $t('adminRepairDetail.location') }}:</label>
  39 + <span>{{ adminRepairDetailInfo.repairObjName }}</span>
  40 + </div>
  41 + </el-col>
  42 + <el-col :span="8">
  43 + <div class="form-item">
  44 + <label>{{ $t('adminRepairDetail.appointmentTime') }}:</label>
  45 + <span>{{ adminRepairDetailInfo.appointmentTime }}</span>
  46 + </div>
  47 + </el-col>
  48 + <el-col :span="8">
  49 + <div class="form-item">
  50 + <label>{{ $t('adminRepairDetail.status') }}:</label>
  51 + <span>{{ adminRepairDetailInfo.stateName }}</span>
  52 + </div>
  53 + </el-col>
  54 + <el-col :span="8">
  55 + <div class="form-item">
  56 + <label>{{ $t('adminRepairDetail.repairContent') }}:</label>
  57 + <span>{{ adminRepairDetailInfo.context }}</span>
  58 + </div>
  59 + </el-col>
  60 + </el-row>
  61 + </el-card>
  62 +
  63 + <!-- 其他信息展示部分,按照相同模式转换 -->
  64 + <!-- 图片展示部分 -->
  65 + <el-card v-if="adminRepairDetailInfo.repairPhotos.length > 0" class="box-card margin-top">
  66 + <div slot="header" class="clearfix">
  67 + <span>{{ $t('adminRepairDetail.repairPhotos') }}</span>
  68 + </div>
  69 + <el-row :gutter="20">
  70 + <el-col v-for="(item, index) in adminRepairDetailInfo.repairPhotos" :key="index" :span="4">
  71 + <el-image style="width: 120px; height: 120px;" :src="item.url" :preview-src-list="[item.url]" fit="cover" />
  72 + </el-col>
  73 + </el-row>
  74 + </el-card>
  75 +
  76 + <!-- 维修前图片 -->
  77 + <el-card v-if="adminRepairDetailInfo.beforePhotos.length > 0" class="box-card margin-top">
  78 + <div slot="header" class="clearfix">
  79 + <span>{{ $t('adminRepairDetail.beforePhotos') }}</span>
  80 + </div>
  81 + <el-row :gutter="20">
  82 + <el-col v-for="(item, index) in adminRepairDetailInfo.beforePhotos" :key="index" :span="4">
  83 + <el-image style="width: 120px; height: 120px;" :src="item.url" :preview-src-list="[item.url]" fit="cover" />
  84 + </el-col>
  85 + </el-row>
  86 + </el-card>
  87 +
  88 + <!-- 维修后图片 -->
  89 + <el-card v-if="adminRepairDetailInfo.afterPhotos.length > 0" class="box-card margin-top">
  90 + <div slot="header" class="clearfix">
  91 + <span>{{ $t('adminRepairDetail.afterPhotos') }}</span>
  92 + </div>
  93 + <el-row :gutter="20">
  94 + <el-col v-for="(item, index) in adminRepairDetailInfo.afterPhotos" :key="index" :span="4">
  95 + <el-image style="width: 120px; height: 120px;" :src="item.url" :preview-src-list="[item.url]" fit="cover" />
  96 + </el-col>
  97 + </el-row>
  98 + </el-card>
  99 +
  100 + <!-- 相关物品表格 -->
  101 + <el-card v-if="adminRepairDetailInfo.maintenanceType === '1001' || adminRepairDetailInfo.maintenanceType === '1003'"
  102 + class="box-card margin-top">
  103 + <div slot="header" class="clearfix">
  104 + <span>{{ $t('adminRepairDetail.relatedItems') }}</span>
  105 + </div>
  106 + <el-table :data="adminRepairDetailInfo.resourceStoreInfo" border>
  107 + <el-table-column prop="resId" :label="$t('adminRepairDetail.itemId')" align="center" />
  108 + <el-table-column :label="$t('adminRepairDetail.itemType')" align="center">
  109 + <template slot-scope="scope">
  110 + {{ scope.row.parentRstName }} > {{ scope.row.rstName }}
  111 + </template>
  112 + </el-table-column>
  113 + <el-table-column prop="resourceStoreName" :label="$t('adminRepairDetail.itemName')" align="center" />
  114 + <el-table-column prop="specName" :label="$t('adminRepairDetail.itemSpec')" align="center">
  115 + <template slot-scope="scope">
  116 + {{ scope.row.specName || '-' }}
  117 + </template>
  118 + </el-table-column>
  119 + <el-table-column :label="$t('adminRepairDetail.itemQuantity')" align="center">
  120 + <template slot-scope="scope">
  121 + {{ scope.row.quantity }}{{ scope.row.miniUnitCodeName }}
  122 + </template>
  123 + </el-table-column>
  124 + <el-table-column prop="unitPrice" :label="$t('adminRepairDetail.itemPrice')" align="center">
  125 + <template slot-scope="scope">
  126 + {{ scope.row.unitPrice || '-' }}
  127 + </template>
  128 + </el-table-column>
  129 + <el-table-column prop="createUserName" :label="$t('adminRepairDetail.user')" align="center" />
  130 + <el-table-column prop="createTime" :label="$t('adminRepairDetail.time')" align="center" />
  131 + </el-table>
  132 + </el-card>
  133 +
  134 + <!-- 工单流转表格 -->
  135 + <el-card class="box-card margin-top">
  136 + <div slot="header" class="clearfix">
  137 + <span>{{ $t('adminRepairDetail.workflow') }}</span>
  138 + </div>
  139 + <el-table :data="adminRepairDetailInfo.repairUsers" border>
  140 + <el-table-column type="index" :label="$t('adminRepairDetail.serial')" align="center" width="60" />
  141 + <el-table-column prop="staffName" :label="$t('adminRepairDetail.handler')" align="center" />
  142 + <el-table-column :label="$t('adminRepairDetail.status')" align="center">
  143 + <template slot-scope="scope">
  144 + <span v-if="(scope.row.state === '10009' || scope.row.state === '12000') && scope.row.payTypeName">
  145 + {{ scope.row.stateName }}({{ scope.row.payTypeName }})
  146 + </span>
  147 + <span v-else>
  148 + {{ scope.row.stateName }}
  149 + <span v-if="scope.row.state === '10007'">
  150 + (<el-link type="primary" @click="openRepairAppraise(scope.row)">{{ $t('adminRepairDetail.reply')
  151 + }}</el-link>)
  152 + </span>
  153 + </span>
  154 + </template>
  155 + </el-table-column>
  156 + <el-table-column prop="startTime" :label="$t('adminRepairDetail.startTime')" align="center" />
  157 + <el-table-column prop="endTime" :label="$t('adminRepairDetail.endTime')" align="center" />
  158 + <el-table-column prop="duration" :label="$t('adminRepairDetail.duration')" align="center" />
  159 + <el-table-column prop="context" :label="$t('adminRepairDetail.comment')" align="center" />
  160 + </el-table>
  161 + </el-card>
  162 +
  163 +
  164 + <reply-repair-appraise ref="replyRepairAppraise" @success="loadRepairUser" />
  165 + </div>
  166 +</template>
  167 +
  168 +<script>
  169 +import { getRepairDetail, listRepairStaffs, listStoreUseRecords } from '@/api/work/adminRepairDetailApi'
  170 +import ReplyRepairAppraise from '@/components/work/ReplyRepairAppraise'
  171 +
  172 +export default {
  173 + name: 'AdminRepairDetail',
  174 + components: {
  175 + ReplyRepairAppraise
  176 + },
  177 + data() {
  178 + return {
  179 + adminRepairDetailInfo: {
  180 + repairId: '',
  181 + repairType: '',
  182 + repairTypeName: '',
  183 + repairName: '',
  184 + tel: '',
  185 + roomId: '',
  186 + roomName: '',
  187 + repairObjName: '',
  188 + appointmentTime: '',
  189 + context: '',
  190 + stateName: '',
  191 + userId: '',
  192 + userName: '',
  193 + repairUsers: [],
  194 + photos: [],
  195 + repairPhotos: [],
  196 + beforePhotos: [],
  197 + afterPhotos: [],
  198 + visitType: '',
  199 + visitContext: '',
  200 + maintenanceType: '',
  201 + repairMaterials: '',
  202 + repairFee: '',
  203 + resourceStoreInfo: [],
  204 + appraiseScore: 0,
  205 + doorSpeedScore: 0,
  206 + repairmanServiceScore: 0,
  207 + average: 0.0
  208 + }
  209 + }
  210 + },
  211 + created() {
  212 + const repairId = this.$route.query.repairId
  213 + if (!repairId) {
  214 + this.$message.error(this.$t('adminRepairDetail.invalidOperation'))
  215 + this.$router.push('/work/repairPoolManage')
  216 + return
  217 + }
  218 + this.adminRepairDetailInfo.repairId = repairId
  219 + this.loadRepairDetail()
  220 + },
  221 + methods: {
  222 + async loadRepairDetail() {
  223 + try {
  224 + const params = {
  225 + page: 1,
  226 + row: 1,
  227 + repairId: this.adminRepairDetailInfo.repairId
  228 + }
  229 + const { data } = await getRepairDetail(params)
  230 + if (data.length < 1) {
  231 + this.$message.error(this.$t('adminRepairDetail.dataError'))
  232 + this.$router.push('/work/repairPoolManage')
  233 + return
  234 + }
  235 + this.adminRepairDetailInfo = { ...this.adminRepairDetailInfo, ...data[0] }
  236 +
  237 + if (this.adminRepairDetailInfo.maintenanceType === '1001' || this.adminRepairDetailInfo.maintenanceType === '1003') {
  238 + this.loadResourceStoreList()
  239 + }
  240 + this.loadRepairUser()
  241 + } catch (error) {
  242 + this.$message.error(error.message || this.$t('adminRepairDetail.loadError'))
  243 + }
  244 + },
  245 + async loadResourceStoreList() {
  246 + try {
  247 + const params = {
  248 + page: 1,
  249 + row: 100,
  250 + repairId: this.adminRepairDetailInfo.repairId
  251 + }
  252 + const { data } = await listStoreUseRecords(params)
  253 + this.adminRepairDetailInfo.resourceStoreInfo = data.map(item => {
  254 + if (item.resId === '666666') {
  255 + return { ...item, rstName: '自定义', specName: '自定义' }
  256 + }
  257 + return item
  258 + })
  259 + } catch (error) {
  260 + this.$message.error(error.message || this.$t('adminRepairDetail.loadResourceError'))
  261 + }
  262 + },
  263 + async loadRepairUser() {
  264 + try {
  265 + const params = {
  266 + page: 1,
  267 + row: 100,
  268 + repairId: this.adminRepairDetailInfo.repairId
  269 + }
  270 + const { data } = await listRepairStaffs(params)
  271 + this.adminRepairDetailInfo.repairUsers = data
  272 + } catch (error) {
  273 + this.$message.error(error.message || this.$t('adminRepairDetail.loadUserError'))
  274 + }
  275 + },
  276 + goBack() {
  277 + this.$router.go(-1)
  278 + },
  279 + openRepairAppraise(row) {
  280 + this.$refs.replyRepairAppraise.open(row)
  281 + }
  282 + }
  283 +}
  284 +</script>
  285 +
  286 +<style lang="scss" scoped>
  287 +.admin-repair-detail-container {
  288 + padding: 20px;
  289 +
  290 + .box-card {
  291 + margin-bottom: 20px;
  292 +
  293 + .clearfix {
  294 + display: flex;
  295 + justify-content: space-between;
  296 + align-items: center;
  297 + }
  298 + }
  299 +
  300 + .form-item {
  301 + margin-bottom: 15px;
  302 + text-align: left;
  303 + color: #666;
  304 +
  305 + label {
  306 + margin-right: 10px;
  307 + }
  308 + }
  309 +
  310 + .margin-top {
  311 + margin-top: 20px;
  312 + }
  313 +
  314 + .float-right {
  315 + float: right;
  316 + }
  317 +}
  318 +</style>
0 319 \ No newline at end of file
... ...
src/views/work/adminRepairLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + adminRepair: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + repairId: 'Please enter work order number',
  7 + repairName: 'Please enter repairer name',
  8 + tel: 'Please enter repair phone'
  9 + },
  10 + list: {
  11 + title: 'Community Repair'
  12 + },
  13 + table: {
  14 + repairId: 'Work Order Code',
  15 + communityName: 'Community Name',
  16 + repairObjName: 'Location',
  17 + repairTypeName: 'Repair Type',
  18 + maintenanceType: 'Maintenance Type',
  19 + repairName: 'Repairer',
  20 + tel: 'Contact',
  21 + appointmentTime: 'Appointment Time',
  22 + createTime: 'Submission Time',
  23 + submitHours: 'Submission Duration',
  24 + finishTime: 'Completion Time',
  25 + state: 'Status',
  26 + timedTask: 'Timed Task Processing'
  27 + },
  28 + maintenanceType: {
  29 + paid: 'Paid Service',
  30 + free: 'Free Service',
  31 + withMaterial: 'Need Materials',
  32 + withoutMaterial: 'No Materials Needed'
  33 + },
  34 + fetchError: 'Failed to get repair list',
  35 + treeFetchError: 'Failed to get tree data'
  36 + }
  37 + },
  38 + zh: {
  39 + adminRepair: {
  40 + search: {
  41 + title: '查询条件',
  42 + repairId: '请输入工单编号',
  43 + repairName: '请输入报修人',
  44 + tel: '请输入报修电话'
  45 + },
  46 + list: {
  47 + title: '小区报修'
  48 + },
  49 + table: {
  50 + repairId: '工单编码',
  51 + communityName: '小区名称',
  52 + repairObjName: '位置',
  53 + repairTypeName: '报修类型',
  54 + maintenanceType: '维修类型',
  55 + repairName: '报修人',
  56 + tel: '联系方式',
  57 + appointmentTime: '预约时间',
  58 + createTime: '提交时间',
  59 + submitHours: '提单时长',
  60 + finishTime: '完成时间',
  61 + state: '状态',
  62 + timedTask: '定时任务处理'
  63 + },
  64 + maintenanceType: {
  65 + paid: '有偿服务',
  66 + free: '无偿服务',
  67 + withMaterial: '需要用料',
  68 + withoutMaterial: '无需用料'
  69 + },
  70 + fetchError: '获取报修列表失败',
  71 + treeFetchError: '获取树形数据失败'
  72 + }
  73 + }
  74 +}
0 75 \ No newline at end of file
... ...
src/views/work/adminRepairList.vue 0 → 100644
  1 +<template>
  2 + <div class="admin-repair-container">
  3 + <div class="flex-container">
  4 + <div class="tree-container">
  5 + <community-repair-tree ref="communityRepairTree" @selectCommunity="handleSelectCommunity"
  6 + @selectRepairSetting="handleSelectRepairSetting" @selectState="handleSelectState" />
  7 + </div>
  8 + <div class="content-container">
  9 + <el-card class="search-card">
  10 + <div slot="header" class="clearfix flex justify-between">
  11 + <span>{{ $t('adminRepair.search.title') }}</span>
  12 + </div>
  13 + <el-row :gutter="20">
  14 + <el-col :span="6">
  15 + <el-input v-model.trim="searchForm.repairId" :placeholder="$t('adminRepair.search.repairId')" clearable />
  16 + </el-col>
  17 + <el-col :span="6">
  18 + <el-input v-model.trim="searchForm.repairName" :placeholder="$t('adminRepair.search.repairName')" clearable />
  19 + </el-col>
  20 + <el-col :span="6">
  21 + <el-input v-model.trim="searchForm.tel" :placeholder="$t('adminRepair.search.tel')" clearable />
  22 + </el-col>
  23 + <el-col :span="6">
  24 + <el-button type="primary" @click="handleSearch">{{ $t('common.search') }}</el-button>
  25 + </el-col>
  26 + </el-row>
  27 + </el-card>
  28 +
  29 + <el-card class="table-card">
  30 + <div slot="header" class="clearfix flex justify-between">
  31 + <span>{{ $t('adminRepair.list.title') }}</span>
  32 + </div>
  33 + <el-table :data="tableData" border style="width: 100%" v-loading="loading">
  34 + <el-table-column prop="repairId" :label="$t('adminRepair.table.repairId')" align="center" />
  35 + <el-table-column prop="communityName" :label="$t('adminRepair.table.communityName')" align="center" />
  36 + <el-table-column prop="repairObjName" :label="$t('adminRepair.table.repairObjName')" align="center" />
  37 + <el-table-column prop="repairTypeName" :label="$t('adminRepair.table.repairTypeName')" align="center" />
  38 + <el-table-column :label="$t('adminRepair.table.maintenanceType')" align="center">
  39 + <template slot-scope="scope">
  40 + {{ getMaintenanceTypeName(scope.row.maintenanceType) }}
  41 + </template>
  42 + </el-table-column>
  43 + <el-table-column prop="repairName" :label="$t('adminRepair.table.repairName')" align="center" />
  44 + <el-table-column prop="tel" :label="$t('adminRepair.table.tel')" align="center" />
  45 + <el-table-column :label="$t('adminRepair.table.appointmentTime')" align="center">
  46 + <template slot-scope="scope">
  47 + <div>{{ scope.row.appointmentTime }}</div>
  48 + <div>~{{ scope.row.timeout }}</div>
  49 + </template>
  50 + </el-table-column>
  51 + <el-table-column prop="createTime" :label="$t('adminRepair.table.createTime')" align="center" />
  52 + <el-table-column prop="submitHours" :label="$t('adminRepair.table.submitHours')" align="center">
  53 + <template slot-scope="scope">
  54 + {{ scope.row.submitHours || '0' }}
  55 + </template>
  56 + </el-table-column>
  57 + <el-table-column prop="finishTime" :label="$t('adminRepair.table.finishTime')" align="center">
  58 + <template slot-scope="scope">
  59 + {{ scope.row.finishTime || '-' }}
  60 + </template>
  61 + </el-table-column>
  62 + <el-table-column :label="$t('adminRepair.table.state')" align="center">
  63 + <template slot-scope="scope">
  64 + <span v-if="scope.row.state === '1800' && (scope.row.returnVisitFlag === '001' || scope.row.returnVisitFlag === '002')">
  65 + {{ scope.row.stateName }}({{ $t('adminRepair.table.timedTask') }})
  66 + </span>
  67 + <span v-else>
  68 + {{ scope.row.stateName }}
  69 + </span>
  70 + </template>
  71 + </el-table-column>
  72 + <el-table-column :label="$t('common.operation')" align="center" width="120">
  73 + <template slot-scope="scope">
  74 + <el-button size="mini" type="primary" @click="handleDetail(scope.row)">
  75 + {{ $t('common.detail') }}
  76 + </el-button>
  77 + </template>
  78 + </el-table-column>
  79 + </el-table>
  80 + <el-pagination
  81 + :current-page="pagination.current"
  82 + :page-sizes="[10, 20, 30, 50]"
  83 + :page-size="pagination.size"
  84 + :total="pagination.total"
  85 + layout="total, sizes, prev, pager, next, jumper"
  86 + @size-change="handleSizeChange"
  87 + @current-change="handlePageChange"
  88 + />
  89 + </el-card>
  90 + </div>
  91 + </div>
  92 + </div>
  93 +</template>
  94 +
  95 +<script>
  96 +import { listAdminOwnerRepairs } from '@/api/work/adminRepairApi'
  97 +import CommunityRepairTree from '@/components/work/CommunityRepairTree'
  98 +
  99 +export default {
  100 + name: 'AdminRepairList',
  101 + components: {
  102 + CommunityRepairTree
  103 + },
  104 + data() {
  105 + return {
  106 + loading: false,
  107 + searchForm: {
  108 + communityId: '',
  109 + repairId: '',
  110 + state: '',
  111 + repairType: '',
  112 + repairName: '',
  113 + tel: ''
  114 + },
  115 + tableData: [],
  116 + pagination: {
  117 + current: 1,
  118 + size: 10,
  119 + total: 0
  120 + }
  121 + }
  122 + },
  123 + created() {
  124 + this.getList()
  125 + },
  126 + methods: {
  127 + async getList() {
  128 + try {
  129 + this.loading = true
  130 + const params = {
  131 + ...this.searchForm,
  132 + page: this.pagination.current,
  133 + row: this.pagination.size
  134 + }
  135 + const { data, total } = await listAdminOwnerRepairs(params)
  136 + this.tableData = data
  137 + this.pagination.total = total
  138 + } catch (error) {
  139 + this.$message.error(this.$t('adminRepair.fetchError'))
  140 + } finally {
  141 + this.loading = false
  142 + }
  143 + },
  144 + handleSearch() {
  145 + this.pagination.current = 1
  146 + this.getList()
  147 + },
  148 + handleSelectCommunity({ communityId }) {
  149 + this.searchForm.communityId = communityId
  150 + this.searchForm.repairType = ''
  151 + this.searchForm.state = ''
  152 + this.getList()
  153 + },
  154 + handleSelectRepairSetting({ communityId, repairType }) {
  155 + this.searchForm.communityId = communityId
  156 + this.searchForm.repairType = repairType
  157 + this.searchForm.state = ''
  158 + this.getList()
  159 + },
  160 + handleSelectState({ communityId, repairType, state }) {
  161 + this.searchForm.communityId = communityId
  162 + this.searchForm.repairType = repairType
  163 + this.searchForm.state = state
  164 + this.getList()
  165 + },
  166 + handleDetail(row) {
  167 + this.$router.push(`/views/work/adminRepairDetail?repairId=${row.repairId}`)
  168 + },
  169 + handleSizeChange(size) {
  170 + this.pagination.size = size
  171 + this.getList()
  172 + },
  173 + handlePageChange(current) {
  174 + this.pagination.current = current
  175 + this.getList()
  176 + },
  177 + getMaintenanceTypeName(type) {
  178 + switch (type) {
  179 + case '1001': return this.$t('adminRepair.maintenanceType.paid')
  180 + case '1002': return this.$t('adminRepair.maintenanceType.free')
  181 + case '1003': return this.$t('adminRepair.maintenanceType.withMaterial')
  182 + case '1004': return this.$t('adminRepair.maintenanceType.withoutMaterial')
  183 + default: return '--'
  184 + }
  185 + }
  186 + }
  187 +}
  188 +</script>
  189 +
  190 +<style lang="scss" scoped>
  191 +.admin-repair-container {
  192 + padding: 20px;
  193 +
  194 + .flex-container {
  195 + display: flex;
  196 +
  197 + .tree-container {
  198 + width: 250px;
  199 + margin-right: 20px;
  200 + }
  201 +
  202 + .content-container {
  203 + flex: 1;
  204 + }
  205 + }
  206 +
  207 + .search-card {
  208 + margin-bottom: 20px;
  209 + }
  210 +
  211 + .el-pagination {
  212 + margin-top: 20px;
  213 + text-align: right;
  214 + }
  215 +}
  216 +</style>
0 217 \ No newline at end of file
... ...