index.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <template>
  2. <div class="work-order-management">
  3. <el-card class="work-order-list">
  4. <h3>待办工单列表</h3>
  5. <el-table :data="workOrders" style="width: 100%" @row-click="handleRowClick">
  6. <el-table-column prop="orderNumber" label="工单编号"></el-table-column>
  7. <el-table-column prop="caseNumber" label="案件编号"></el-table-column>
  8. <el-table-column prop="alarmLevel" label="报警级别"></el-table-column>
  9. <el-table-column prop="alarmType" label="报警类型"></el-table-column>
  10. <el-table-column prop="alarmDescription" label="报警描述"></el-table-column>
  11. <el-table-column prop="purpose" label="用途"></el-table-column>
  12. <el-table-column prop="assignedUnit" label="权属单位"></el-table-column>
  13. <el-table-column prop="address" label="详细地址"></el-table-column>
  14. <el-table-column fixed="right" label="操作">
  15. <template #default="{ row }">
  16. <el-button type="primary" link @click="handleDispatch(row)">下发</el-button>
  17. <el-button type="warning" link @click="handleDelay(row)">延期</el-button>
  18. <el-button type="info" link @click="handlePostpone(row)">缓办</el-button>
  19. </template>
  20. </el-table-column>
  21. </el-table>
  22. </el-card>
  23. <el-card v-if="selectedWorkOrder" class="work-order-details">
  24. <h3>工单详情</h3>
  25. <el-descriptions :column="1" border>
  26. <el-descriptions-item label="案件编号">{{ selectedWorkOrder.caseNumber }}</el-descriptions-item>
  27. <el-descriptions-item label="报警名称">{{ selectedWorkOrder.alarmName }}</el-descriptions-item>
  28. <el-descriptions-item label="报警时间">{{ selectedWorkOrder.alarmTime }}</el-descriptions-item>
  29. <el-descriptions-item label="报警描述">{{ selectedWorkOrder.alarmDescription }}</el-descriptions-item>
  30. <el-descriptions-item label="井盖设备编号">{{ selectedWorkOrder.deviceSerial }}</el-descriptions-item>
  31. <el-descriptions-item label="井盖设备名称">{{ selectedWorkOrder.deviceName }}</el-descriptions-item>
  32. <el-descriptions-item label="井盖设备用途">{{ selectedWorkOrder.purpose }}</el-descriptions-item>
  33. <el-descriptions-item label="权属单位">{{ selectedWorkOrder.assignedUnit }}</el-descriptions-item>
  34. <el-descriptions-item label="权属单位电话">{{ selectedWorkOrder.unitPhone }}</el-descriptions-item>
  35. <el-descriptions-item label="安装时间">{{ selectedWorkOrder.installationTime }}</el-descriptions-item>
  36. <el-descriptions-item label="区">{{ selectedWorkOrder.district }}</el-descriptions-item>
  37. <el-descriptions-item label="街道">{{ selectedWorkOrder.street }}</el-descriptions-item>
  38. <el-descriptions-item label="道路">{{ selectedWorkOrder.road }}</el-descriptions-item>
  39. <el-descriptions-item label="辅助定位地址">{{ selectedWorkOrder.auxiliaryAddress }}</el-descriptions-item>
  40. <el-descriptions-item label="井盖设备材质">{{ selectedWorkOrder.material }}</el-descriptions-item>
  41. <el-descriptions-item label="工单办理经过">
  42. <p>{{ selectedWorkOrder.process }}</p>
  43. </el-descriptions-item>
  44. <el-descriptions-item label="附件多媒体信息">
  45. <el-image v-for="(media, index) in selectedWorkOrder.media" :key="index" :src="media.url" fit="cover" />
  46. </el-descriptions-item>
  47. </el-descriptions>
  48. </el-card>
  49. <div v-if="selectedWorkOrder && selectedWorkOrder.location" class="map-container">
  50. <h3>井盖设备位置</h3>
  51. <l-map :zoom="15" :center="selectedWorkOrder.location" style="height: 400px">
  52. <l-tile-layer :url="tileLayerUrl" />
  53. <l-marker :lat-lng="selectedWorkOrder.location">
  54. <l-icon :icon-url="markerIconUrl" :icon-size="[30, 41]" :icon-anchor="[15, 41]" />
  55. </l-marker>
  56. </l-map>
  57. </div>
  58. <!-- 延期弹窗 -->
  59. <el-dialog title="延期处理" v-model="dialogDelayVisible" width="30%">
  60. <el-form :model="delayForm">
  61. <el-form-item label="延期截止时间" :label-width="formLabelWidth">
  62. <el-date-picker
  63. v-model="delayForm.deadline"
  64. type="datetime"
  65. placeholder="选择日期时间"
  66. />
  67. </el-form-item>
  68. <el-form-item label="延期理由" :label-width="formLabelWidth">
  69. <el-input v-model="delayForm.reason" autocomplete="off" />
  70. </el-form-item>
  71. </el-form>
  72. <template #footer>
  73. <span class="dialog-footer">
  74. <el-button @click="dialogDelayVisible = false">取 消</el-button>
  75. <el-button type="primary" @click="handleConfirmDelay">确 定</el-button>
  76. </span>
  77. </template>
  78. </el-dialog>
  79. <!-- 缓办弹窗 -->
  80. <el-dialog title="缓办处理" v-model="dialogPostponeVisible" width="30%">
  81. <el-form :model="postponeForm">
  82. <el-form-item label="缓办截止时间" :label-width="formLabelWidth">
  83. <el-date-picker
  84. v-model="postponeForm.deadline"
  85. type="datetime"
  86. placeholder="选择日期时间"
  87. />
  88. </el-form-item>
  89. <el-form-item label="缓办理由" :label-width="formLabelWidth">
  90. <el-input v-model="postponeForm.reason" autocomplete="off" />
  91. </el-form-item>
  92. </el-form>
  93. <template #footer>
  94. <span class="dialog-footer">
  95. <el-button @click="dialogPostponeVisible = false">取 消</el-button>
  96. <el-button type="primary" @click="handleConfirmPostpone">确 定</el-button>
  97. </span>
  98. </template>
  99. </el-dialog>
  100. <!-- 下发弹窗 -->
  101. <el-dialog title="下发工单" v-model="dialogDispatchVisible" width="30%">
  102. <el-form :model="dispatchForm">
  103. <el-form-item label="维修负责人" :label-width="formLabelWidth">
  104. <el-select v-model="dispatchForm.responsible" placeholder="请选择">
  105. <el-option
  106. v-for="item in responsibleOptions"
  107. :key="item.value"
  108. :label="item.label"
  109. :value="item.value"
  110. />
  111. </el-select>
  112. </el-form-item>
  113. </el-form>
  114. <template #footer>
  115. <span class="dialog-footer">
  116. <el-button @click="dialogDispatchVisible = false">取 消</el-button>
  117. <el-button type="primary" @click="handleConfirmDispatch">确 定</el-button>
  118. </span>
  119. </template>
  120. </el-dialog>
  121. </div>
  122. </template>
  123. <script setup>
  124. import { ref, onMounted } from 'vue';
  125. import { ElMessage } from 'element-plus';
  126. import L from 'leaflet';
  127. import 'leaflet/dist/leaflet.css';
  128. // 模拟数据
  129. const workOrders = ref([
  130. {
  131. orderNumber: 'W20230915001',
  132. caseNumber: 'C20230915001',
  133. alarmLevel: '紧急',
  134. alarmType: '损坏',
  135. alarmDescription: '井盖破损严重,存在安全隐患。',
  136. purpose: '排水',
  137. assignedUnit: '水务局',
  138. address: '上海市浦东新区陆家嘴环路1000号',
  139. location: [31.2304, 121.4737],
  140. media: [
  141. { url: 'https://example.com/image1.jpg' },
  142. { url: 'https://example.com/image2.jpg' }
  143. ]
  144. },
  145. // 更多模拟数据...
  146. ]);
  147. const selectedWorkOrder = ref(null);
  148. const dialogDelayVisible = ref(false);
  149. const dialogPostponeVisible = ref(false);
  150. const dialogDispatchVisible = ref(false);
  151. const delayForm = ref({ deadline: null, reason: '' });
  152. const postponeForm = ref({ deadline: null, reason: '' });
  153. const dispatchForm = ref({ responsible: '' });
  154. const formLabelWidth = ref('120px');
  155. const responsibleOptions = ref([
  156. { value: 'person1', label: '张三' },
  157. { value: 'person2', label: '李四' },
  158. // 更多选项...
  159. ]);
  160. // 处理表格点击事件
  161. function handleRowClick(row) {
  162. selectedWorkOrder.value = row;
  163. }
  164. // 延期处理
  165. function handleDelay(row) {
  166. selectedWorkOrder.value = row;
  167. dialogDelayVisible.value = true;
  168. }
  169. // 缓办处理
  170. function handlePostpone(row) {
  171. selectedWorkOrder.value = row;
  172. dialogPostponeVisible.value = true;
  173. }
  174. // 下发处理
  175. function handleDispatch(row) {
  176. selectedWorkOrder.value = row;
  177. dialogDispatchVisible.value = true;
  178. }
  179. // 确认延期
  180. function handleConfirmDelay() {
  181. // 这里可以添加逻辑来处理延期操作
  182. ElMessage.success('延期成功');
  183. dialogDelayVisible.value = false;
  184. }
  185. // 确认缓办
  186. function handleConfirmPostpone() {
  187. // 这里可以添加逻辑来处理缓办操作
  188. ElMessage.success('缓办成功');
  189. dialogPostponeVisible.value = false;
  190. }
  191. // 确认下发
  192. function handleConfirmDispatch() {
  193. // 这里可以添加逻辑来处理下发操作
  194. ElMessage.success('下发成功');
  195. dialogDispatchVisible.value = false;
  196. }
  197. onMounted(() => {
  198. // 初始化 Leaflet 地图
  199. const tileLayerUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
  200. const markerIconUrl = 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png';
  201. // 初始化地图
  202. // const map = new L.Map('map').setView([31.2304, 121.4737], 15);
  203. // L.tileLayer(tileLayerUrl).addTo(map);
  204. // L.marker([31.2304, 121.4737]).addTo(map)
  205. // .bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
  206. // .openPopup();
  207. });
  208. </script>
  209. <style scoped>
  210. .work-order-management {
  211. display: flex;
  212. flex-direction: column;
  213. gap: 20px;
  214. }
  215. .map-container {
  216. height: 400px;
  217. position: relative;
  218. }
  219. #map {
  220. height: 100%;
  221. }
  222. </style>