disasterAssessment.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <template>
  2. <Dialog custom-show type="lg" title="灾害评估" hide-footer @close="closeDialog">
  3. <!-- 表格组件 -->
  4. <div class="common-table">
  5. <div class="table-header">
  6. <div class="td">行政区划</div>
  7. <div class="td">受灾人数(人)</div>
  8. <div class="td">失踪人数(人)</div>
  9. <div class="td">死亡人数(人)</div>
  10. <div class="td">紧急转移(人)</div>
  11. <div class="td">直接经济损失(万元)</div>
  12. </div>
  13. <div v-for="(item, index) in fixedTableData" :key="index" class="tr">
  14. <div class="td">
  15. <div class="address-box">
  16. <div class="address-text" :title="item.address">{{ item.address }}</div>
  17. </div>
  18. </div>
  19. <div class="td">
  20. <div class="address-box">
  21. <el-input-number v-if="isEditing" v-model="item.numone" class="custom-input" :min="0" />
  22. <div v-else class="address-text">{{ item.numone }}</div>
  23. </div>
  24. </div>
  25. <div class="td">
  26. <div class="address-box">
  27. <el-input-number v-if="isEditing" v-model="item.numtwo" class="custom-input" :min="0" />
  28. <div v-else class="address-text">{{ item.numtwo }}</div>
  29. </div>
  30. </div>
  31. <div class="td">
  32. <div class="address-box">
  33. <el-input-number v-if="isEditing" v-model="item.numthree" class="custom-input" :min="0" />
  34. <div v-else class="address-text">{{ item.numthree }}</div>
  35. </div>
  36. </div>
  37. <div class="td">
  38. <div class="address-box">
  39. <el-input-number v-if="isEditing" v-model="item.numfour" class="custom-input" :min="0" />
  40. <div v-else class="address-text">{{ item.numfour }}</div>
  41. </div>
  42. </div>
  43. <div class="td">
  44. <div class="address-box">
  45. <el-input-number v-if="isEditing" v-model="item.numfive" class="custom-input" :min="0" />
  46. <div v-else class="address-text">{{ item.numfive }}</div>
  47. </div>
  48. </div>
  49. </div>
  50. <!-- 合计行 -->
  51. <div class="tr total-row">
  52. <div class="td">
  53. <div class="address-box">
  54. <div class="address-text">合计</div>
  55. </div>
  56. </div>
  57. <div class="td">
  58. <div class="address-box">
  59. <div class="address-text">{{ total.numone }}</div>
  60. </div>
  61. </div>
  62. <div class="td">
  63. <div class="address-box">
  64. <div class="address-text">{{ total.numtwo }}</div>
  65. </div>
  66. </div>
  67. <div class="td">
  68. <div class="address-box">
  69. <div class="address-text">{{ total.numthree }}</div>
  70. </div>
  71. </div>
  72. <div class="td">
  73. <div class="address-box">
  74. <div class="address-text">{{ total.numfour }}</div>
  75. </div>
  76. </div>
  77. <div class="td">
  78. <div class="address-box">
  79. <div class="address-text">{{ total.numfive }}</div>
  80. </div>
  81. </div>
  82. </div>
  83. </div>
  84. <div v-if="!isEditing" class="btn-box">
  85. <div class="btn" @click="toggleEdit">
  86. <div class="text">编辑</div>
  87. </div>
  88. </div>
  89. <div v-if="isEditing" style="display: flex">
  90. <div class="btn-box">
  91. <div class="common-btn" @click="cancelEdit">
  92. <div class="text">取消</div>
  93. </div>
  94. <div class="common-btn-primary" @click="saveEdit">
  95. <div class="text">保存</div>
  96. </div>
  97. </div>
  98. </div>
  99. </Dialog>
  100. </template>
  101. <script setup lang="ts">
  102. import { computed, ref } from 'vue';
  103. // 固定的行政区域列表
  104. const fixedRegions = ['茂名市', '茂南区', '电白区', '化州市', '高州市', '信宜市'];
  105. // 编辑状态
  106. const isEditing = ref(false);
  107. // 保存编辑前的原始数据
  108. const originalData = ref([]);
  109. // 原始数据
  110. const tableData = ref([]);
  111. // 固定区域的数据
  112. const fixedTableData = ref([]);
  113. // 合并固定区域和数据的函数
  114. const mergeDataWithFixedRegions = () => {
  115. fixedTableData.value = fixedRegions.map((region) => {
  116. // 查找是否有该区域的数据
  117. const foundData = tableData.value.find((item) => item.address === region);
  118. // 如果有数据则使用,否则使用默认值0
  119. return (
  120. foundData || {
  121. address: region,
  122. numone: 0,
  123. numtwo: 0,
  124. numthree: 0,
  125. numfour: 0,
  126. numfive: 0
  127. }
  128. );
  129. });
  130. };
  131. // 计算合计值
  132. const total = computed(() => {
  133. return {
  134. numone: fixedTableData.value.reduce((sum, item) => sum + (Number(item.numone) || 0), 0),
  135. numtwo: fixedTableData.value.reduce((sum, item) => sum + (Number(item.numtwo) || 0), 0),
  136. numthree: fixedTableData.value.reduce((sum, item) => sum + (Number(item.numthree) || 0), 0),
  137. numfour: fixedTableData.value.reduce((sum, item) => sum + (Number(item.numfour) || 0), 0),
  138. numfive: fixedTableData.value.reduce((sum, item) => sum + (Number(item.numfive) || 0), 0)
  139. };
  140. });
  141. // 切换编辑状态
  142. const toggleEdit = () => {
  143. // 进入编辑时保存当前数据快照
  144. originalData.value = JSON.parse(JSON.stringify(fixedTableData.value));
  145. isEditing.value = true;
  146. };
  147. const saveEdit = () => {
  148. isEditing.value = false;
  149. // 保存数据到tableData
  150. tableData.value = fixedTableData.value.filter(
  151. (item) => item.numone !== 0 || item.numtwo !== 0 || item.numthree !== 0 || item.numfour !== 0 || item.numfive !== 0
  152. );
  153. };
  154. const cancelEdit = () => {
  155. // 恢复编辑前的数据
  156. fixedTableData.value = JSON.parse(JSON.stringify(originalData.value));
  157. isEditing.value = false;
  158. };
  159. const emit = defineEmits(['update:show']);
  160. const closeDialog = () => {
  161. emit('update:show', false);
  162. };
  163. onMounted(() => {
  164. tableData.value = [
  165. {
  166. address: '',
  167. numone: 0,
  168. numtwo: 0,
  169. numthree: 0,
  170. numfour: 0,
  171. numfive: 0
  172. }
  173. ];
  174. mergeDataWithFixedRegions();
  175. });
  176. </script>
  177. <style scoped lang="scss">
  178. .common-table {
  179. .total-row {
  180. font-weight: bold;
  181. }
  182. .table-header,
  183. .tr {
  184. display: flex;
  185. height: 130px;
  186. .td {
  187. flex: 1;
  188. padding: 8px;
  189. .address-box {
  190. .address-text {
  191. white-space: nowrap;
  192. overflow: hidden;
  193. text-overflow: ellipsis;
  194. }
  195. .edit-input {
  196. width: 100%;
  197. padding: 4px;
  198. border: 1px solid #ccc;
  199. border-radius: 4px;
  200. text-align: center;
  201. }
  202. :deep(.el-input-number) {
  203. width: 60%;
  204. }
  205. }
  206. }
  207. }
  208. }
  209. .custom-input {
  210. :deep(.el-input-number__increase) {
  211. background-color: #ffffff;
  212. width: 50px;
  213. font-size: 25px;
  214. }
  215. :deep(.el-input-number__decrease) {
  216. background-color: #ffffff;
  217. width: 50px;
  218. font-size: 25px;
  219. }
  220. }
  221. .btn-box {
  222. flex: 1;
  223. //height: 421px;
  224. display: flex;
  225. justify-content: center;
  226. align-items: center;
  227. .btn {
  228. width: 361px;
  229. height: 136px;
  230. background: url('@/assets/images/emergencyCommandMap/communication/btn.png') no-repeat;
  231. display: flex;
  232. align-items: center;
  233. justify-content: center;
  234. cursor: pointer;
  235. .icon1,
  236. .icon2,
  237. .icon3 {
  238. margin-right: 20px;
  239. margin-top: 10px;
  240. }
  241. .icon1 {
  242. width: 64px;
  243. height: 67px;
  244. background: url('@/assets/images/emergencyCommandMap/communication/icon1.png') no-repeat;
  245. }
  246. .icon2 {
  247. width: 64px;
  248. height: 65px;
  249. background: url('@/assets/images/emergencyCommandMap/communication/icon2.png') no-repeat;
  250. }
  251. .icon3 {
  252. width: 64px;
  253. height: 63px;
  254. background: url('@/assets/images/emergencyCommandMap/communication/icon3.png') no-repeat;
  255. }
  256. .text {
  257. color: #fff;
  258. font-size: 38px;
  259. }
  260. }
  261. }
  262. </style>