Brak opisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.vue 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. <template>
  2. <div class="page-container">
  3. <van-sticky>
  4. <van-nav-bar
  5. title="事故报告台账"
  6. @click-left="onClickLeft" >
  7. </van-nav-bar>
  8. </van-sticky>
  9. <div class="scroll-container">
  10. <van-pull-refresh
  11. v-model="refreshing"
  12. success-text="刷新成功"
  13. @refresh="onRefresh"
  14. >
  15. <van-list
  16. class="listDiv"
  17. :immediate-check="false"
  18. v-model:loading="loading"
  19. :finished="finished"
  20. finished-text="没有更多了"
  21. @load="onLoad"
  22. >
  23. <div v-for="item in list" :key="item.id" class="card">
  24. <van-cell @click="handleLookRow(item)">
  25. <template #title>
  26. <span v-if="false" class="cell-title">{{ item.hdDescription }}</span>
  27. </template>
  28. <template #label>
  29. <div class="label-content">
  30. <div>事故地点:{{ item.accidentLocation }}</div>
  31. <div>发生时间:{{ item.accidentTime }}</div>
  32. <div>事故类型:{{ item.accidentType }}</div>
  33. </div>
  34. </template>
  35. </van-cell>
  36. </div>
  37. </van-list>
  38. </van-pull-refresh>
  39. </div>
  40. <van-popup :close-on-click-overlay="false" :lazy-render="false" v-model:show="showBottom" position="bottom">
  41. <OrganizationalWithLeaf :cached-dept-code="cachedDeptCode" @init="getDeptInfo" @close="showBottom = false" @update:selected-node="handleTableDataUserDeptUpdate" />
  42. </van-popup>
  43. <van-dialog v-model:show="showDialogVisible" title="提示" show-cancel-button
  44. confirm-button-color="#ee0124" message="确定删除本条数据吗" @confirm="onDelete"/>
  45. </div>
  46. </template>
  47. <script setup>
  48. import { getCurrentInstance, onMounted, ref } from 'vue';
  49. import { onBeforeRouteLeave, useRouter } from 'vue-router';
  50. import { showConfirmDialog, showDialog, showFailToast, showSuccessToast } from 'vant';
  51. import { useEmergencyStore } from '@/stores/emergencyManager.js';
  52. const emergencyInfo = useEmergencyStore()
  53. const {
  54. proxy
  55. } = getCurrentInstance()
  56. /**
  57. * 组织树组件初始化返回方法
  58. * @param currentDeptInfo 用户部门信息(userCode-userName)
  59. */
  60. const cachedDeptCode = ref('')
  61. const getDeptInfo = (currentDeptInfo) => {
  62. postBackRegimeScope.value = currentDeptInfo
  63. currentDeptName.value = currentDeptInfo.split('-')[1]
  64. /* Pinia初始化属性 */
  65. if (emergencyInfo.currentDeptCode) {
  66. postBackRegimeScope.value = emergencyInfo.currentDeptCode + '-' + emergencyInfo.currentDeptName
  67. currentDeptName.value = emergencyInfo.currentDeptName
  68. fetchData.value.regimeName = emergencyInfo.conditionalQueryAttributes
  69. }
  70. basicReset()
  71. onLoad()
  72. }
  73. /**
  74. * 数据传回组织树组件
  75. */
  76. if (emergencyInfo.currentDeptCode) {
  77. cachedDeptCode.value = emergencyInfo.currentDeptCode
  78. }
  79. /**
  80. * 路由跳转前,pinia中缓存数据
  81. */
  82. onBeforeRouteLeave((to, from, next) => {
  83. /* 跳转子页面赋值 */
  84. if (to.path === '/yinhuan/hdLedger_detail') {
  85. emergencyInfo.$patch({
  86. currentDeptCode: postBackRegimeScope.value.split('-')[0],
  87. currentDeptName: postBackRegimeScope.value.split('-')[1],
  88. conditionalQueryAttributes: fetchData.value.regimeName
  89. })
  90. } else {
  91. /* 跳转其他页面均清空,避免混乱赋值 */
  92. emergencyInfo.clearMainDeptInfo()
  93. }
  94. next()
  95. })
  96. /* 通用方法: 重置list数据 */
  97. const basicReset = () => {
  98. finished.value = false;
  99. loading.value = true;
  100. pageNum.value = 1
  101. list.value = []
  102. }
  103. /* 返回上一级页面 */
  104. const router = useRouter()
  105. const onClickLeft = () => {
  106. router.go(-1)
  107. }
  108. /* 查询数据 */
  109. const pageNum = ref(1)
  110. const pageSize = ref(10)
  111. const total = ref(0)
  112. const resultData = ref([])
  113. const fetchData = ref({
  114. regimeName: '',
  115. regimeScope: '',
  116. })
  117. const onSearch = () => {
  118. basicReset()
  119. onLoad()
  120. }
  121. const resetCondition = () => {
  122. basicReset()
  123. fetchData.value = {
  124. regimeName:'',
  125. regimeScope: ''
  126. }
  127. onLoad()
  128. }
  129. /* 查询请求 */
  130. const queryFetch = async () => {
  131. fetchData.value.regimeScope = postBackRegimeScope.value
  132. const url = '/sgsafe/AccidentReport/query'
  133. const param = {
  134. page: pageNum.value,
  135. rows: pageSize.value,
  136. params: JSON.stringify(fetchData.value)
  137. }
  138. try {
  139. const res = await proxy.$axios.post(url,param);
  140. if (res.data.code === 0) {
  141. total.value = res.data.data.total
  142. resultData.value = res.data.data.records
  143. } else {
  144. console.log('操作失败!' + res.data.msg)
  145. }
  146. } catch (error) {
  147. console.error('请求出错:', error);
  148. }
  149. };
  150. /* 列表加载与下拉刷新 */
  151. const list = ref([]);
  152. const refreshing = ref(false)
  153. const loading = ref(false)
  154. const finished = ref(false)
  155. const onRefresh = () => {
  156. basicReset()
  157. onLoad();
  158. };
  159. const onLoad = async () => {
  160. if (refreshing.value) {
  161. list.value = [];
  162. pageNum.value = 1;
  163. refreshing.value = false;
  164. }
  165. try {
  166. await queryFetch();
  167. if (pageSize.value * pageNum.value < total.value) {
  168. list.value = [...list.value,...resultData.value ]
  169. pageNum.value++;
  170. } else {
  171. list.value = [...list.value,...resultData.value ]
  172. finished.value = true;
  173. }
  174. } catch (error) {
  175. console.log(error);
  176. finished.value = true;
  177. } finally {
  178. loading.value = false;
  179. }
  180. };
  181. /* 组织树选择 */
  182. const showBottom = ref(false)
  183. const currentDeptName = ref('')
  184. const postBackRegimeScope = ref()
  185. import OrganizationalWithLeaf from '@/components/OrganizationalWithLeaf.vue';
  186. const showPickerHandle = () => {
  187. showBottom.value = true
  188. }
  189. const handleTableDataUserDeptUpdate = async (nodeData) => {
  190. console.log('你哦的Date',nodeData)
  191. currentDeptName.value = nodeData.split('-')[1]
  192. postBackRegimeScope.value = nodeData
  193. basicReset()
  194. await onLoad()
  195. showBottom.value = false
  196. }
  197. const getTypeState = (state) => {
  198. const typeMap = {
  199. '0': 'danger',
  200. '1': 'success'
  201. }
  202. return typeMap[state] || ''
  203. }
  204. const getPlanState = (state) => {
  205. const typeMap = {
  206. '0': '未完成',
  207. '1': '已完成'
  208. }
  209. return typeMap[state] || ''
  210. }
  211. const showDialogVisible = ref(false)
  212. const deleteInfo = ref()
  213. const handleDelete = (item) => {
  214. showDialogVisible.value = true
  215. deleteInfo.value = item
  216. }
  217. /* 数据删除 */
  218. const onDelete = () => {
  219. const item = deleteInfo.value
  220. const url = '/safe/EmergencyDrillPlan/delete'
  221. const param = {
  222. json: JSON.stringify(item)
  223. }
  224. proxy.$axios.post(url,param).then(res=>{
  225. if (res.data.code === 0) {
  226. showSuccessToast('删除成功')
  227. basicReset()
  228. onLoad()
  229. } else {
  230. showFailToast('操作失败!' + res.data.msg)
  231. }
  232. })
  233. }
  234. //点击详情跳转
  235. const handleLookRow = (row) =>{
  236. proxy.$router.push({
  237. path: '/accidentManager/accidentBaoGaoLedger/accidentBaoGaoLedger_edit/index',
  238. query: {
  239. id:row.id,
  240. flag:'look'
  241. }
  242. })
  243. }
  244. //颜色事件
  245. const getStatusClass = (status) => {
  246. switch (status) {
  247. case '-1':
  248. return 'status-pending';
  249. case '0':
  250. return 'status-registered';
  251. case '1':
  252. return 'status-analyzing';
  253. case '2':
  254. return 'status-rectifying';
  255. case '3':
  256. return 'status-accepting';
  257. case '4':
  258. return 'status-closed';
  259. case '5':
  260. return 'status-finished';
  261. default:
  262. return 'status-unknown';
  263. }
  264. };
  265. </script>
  266. <style scoped>
  267. .page-container {
  268. height: 100vh; /* 关键:外层容器高度设为视口高度 */
  269. display: flex;
  270. flex-direction: column;
  271. }
  272. /* overflow-y: auto; !* 启用垂直滚动 *!*/
  273. .scroll-container {
  274. flex: 1;
  275. overflow: auto;
  276. -webkit-overflow-scrolling: touch; /* iOS 平滑滚动 */
  277. }
  278. /* 可选:隐藏滚动条(视觉优化) */
  279. .scroll-container::-webkit-scrollbar {
  280. display: none;
  281. }
  282. .card {
  283. margin: 10px;
  284. border-radius: 8px;
  285. overflow: hidden;
  286. box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  287. background-color: #fff;
  288. }
  289. .label-content {
  290. display: flex;
  291. flex-direction: column;
  292. gap: 4px;
  293. }
  294. .cell-title {
  295. display: -webkit-box; /* 旧版弹性盒子模型 */
  296. -webkit-box-orient: vertical; /* 内容垂直排列 */
  297. -webkit-line-clamp: 2; /* 限制显示行数 */
  298. overflow: hidden; /* 超出隐藏 */
  299. text-overflow: ellipsis; /* 省略号 */
  300. line-height: 1.5; /* 可选:设置行高 */
  301. max-height: calc(1.5em * 2); /* 可选:根据行高限制最大高度 */
  302. font-size: 16px;
  303. font-weight: bold;
  304. color: #333;/* 字号 */
  305. }
  306. .status-pending {
  307. background-color: #fff3cd;
  308. color: #856404;
  309. padding: 2px 4px;
  310. border-radius: 4px;
  311. }
  312. .status-registered {
  313. background-color: #d1ecf1;
  314. color: #0c5460;
  315. padding: 2px 4px;
  316. border-radius: 4px;
  317. }
  318. .status-analyzing {
  319. background-color: #fff8e1;
  320. color: #ff8f00;
  321. padding: 2px 4px;
  322. border-radius: 4px;
  323. }
  324. .status-rectifying {
  325. background-color: #e8f5e9;
  326. color: #2e7d32;
  327. padding: 2px 4px;
  328. border-radius: 4px;
  329. }
  330. .status-accepting {
  331. background-color: #e3f2fd;
  332. color: #1565c0;
  333. padding: 2px 4px;
  334. border-radius: 4px;
  335. }
  336. .status-closed {
  337. background-color: #f8bbd0;
  338. color: #b71c1c;
  339. padding: 2px 4px;
  340. border-radius: 4px;
  341. }
  342. .status-finished {
  343. background-color: #e8eaf6;
  344. color: #311b92;
  345. padding: 2px 4px;
  346. border-radius: 4px;
  347. }
  348. .status-unknown {
  349. background-color: #efebe9;
  350. color: #424242;
  351. padding: 2px 4px;
  352. border-radius: 4px;
  353. }
  354. </style>