process.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <template>
  2. <view class="process-list">
  3. <view class="search-row">
  4. <input
  5. class="search-input"
  6. v-model="searchName"
  7. placeholder="事故事件名称"
  8. />
  9. <view class="dept-btn" @click="showDeptPicker"
  10. ><text>{{ deptName || "责任单位" }}</text
  11. ><text class="arrow">▾</text></view
  12. >
  13. <button class="search-btn" @click="handleSearch">搜索</button>
  14. </view>
  15. <u-list @scrolltolower="loadMore" class="list-content">
  16. <view v-for="(item, idx) in listData" :key="item.id" class="card-wrapper">
  17. <myCard
  18. :item="item"
  19. :index="idx + 1"
  20. :btnList="getBtnList(item)"
  21. :columns="processColumns"
  22. :title="item.acdntName"
  23. :status="getStatusLabel(item.approvalStatus)"
  24. @goDetail="goDetail"
  25. @handleProcess="handleProcess"
  26. />
  27. </view>
  28. <view style="height: 20rpx"></view>
  29. <view v-if="loading" class="load-more">加载中...</view>
  30. <view v-if="isEnd && listData.length > 0" class="load-more"
  31. >没有更多了</view
  32. >
  33. <u-empty v-if="!loading && listData.length === 0" text="暂无待处理事故" />
  34. </u-list>
  35. <!-- 弹窗 -->
  36. <processDialog ref="processDialogRef" @reload="reloadList" />
  37. <accidentDialog ref="dialogRef" @reload="reloadList" />
  38. <ba-tree-picker
  39. ref="treePicker"
  40. key="dept"
  41. :multiple="false"
  42. @select-change="onDeptConfirm"
  43. title="选择部门"
  44. :localdata="deptList"
  45. valueKey="id"
  46. textKey="name"
  47. />
  48. <u-toast ref="uToast" />
  49. </view>
  50. </template>
  51. <script>
  52. import myCard from "@/components/myCard.vue";
  53. import processDialog from "./processDialog.vue";
  54. import accidentDialog from "./accidentDialog.vue";
  55. import baTreePicker from "@/components/ba-tree-picker/ba-tree-picker.vue";
  56. import { pageApproved } from "@/api/accidentReport/index.js";
  57. import { listOrganizations } from "@/api/common.js";
  58. export default {
  59. components: { myCard, processDialog, accidentDialog, baTreePicker },
  60. data() {
  61. return {
  62. searchName: "",
  63. deptId: null,
  64. deptName: "责任单位",
  65. deptList: [],
  66. listData: [],
  67. page: 1,
  68. size: 10,
  69. isEnd: false,
  70. loading: false,
  71. processColumns: [
  72. [{ prop: "acdntCode", label: "编码", className: "perce100" }],
  73. [
  74. { prop: "dutyUnitName", label: "责任单位", className: "perce50" },
  75. { prop: "acdntPlace", label: "地点", className: "perce50" },
  76. ],
  77. [{ prop: "occurrenceTime", label: "发生时间", className: "perce100" }],
  78. [
  79. {
  80. prop: "ascertainedStatus",
  81. label: "事故原因",
  82. className: "perce33",
  83. formatter: (row) =>
  84. row.ascertainedStatus == 1 ? "已查清" : "未查清",
  85. },
  86. {
  87. prop: "responsibilityStatus",
  88. label: "责任人员",
  89. className: "perce33",
  90. formatter: (row) =>
  91. row.responsibilityStatus == 1 ? "已处理" : "未处理",
  92. },
  93. {
  94. prop: "correctiveMeasuresStatus",
  95. label: "整改措施",
  96. className: "perce33",
  97. formatter: (row) =>
  98. row.correctiveMeasuresStatus == 1 ? "已落实" : "未落实",
  99. },
  100. ],
  101. [
  102. {
  103. label: "操作",
  104. prop: "action",
  105. type: "action",
  106. className: "perce100",
  107. },
  108. ],
  109. ],
  110. };
  111. },
  112. mounted() {
  113. this.loadDeptList();
  114. this.getList();
  115. },
  116. methods: {
  117. async loadDeptList() {
  118. try {
  119. const res = await listOrganizations({});
  120. this.deptList = res || [];
  121. } catch (e) {}
  122. },
  123. showDeptPicker() {
  124. this.$refs.treePicker._show();
  125. },
  126. onDeptConfirm(data) {
  127. const id = data[0];
  128. this.deptId = id;
  129. const find = (list) => {
  130. for (const item of list) {
  131. if (item.id === id) return item.name;
  132. if (item.children) {
  133. const f = find(item.children);
  134. if (f) return f;
  135. }
  136. }
  137. return null;
  138. };
  139. this.deptName = find(this.deptList) || "责任单位";
  140. this.page = 1;
  141. this.isEnd = false;
  142. this.getList();
  143. },
  144. getStatusLabel(status) {
  145. return (
  146. { 0: "待提交", 1: "审批中", 2: "已通过", 3: "已驳回" }[status] || status
  147. );
  148. },
  149. getBtnList(item) {
  150. return [
  151. {
  152. name: "查看",
  153. apiName: "goDetail",
  154. btnType: "info",
  155. judge: [{ fn: () => true }],
  156. },
  157. {
  158. name: "处理",
  159. apiName: "handleProcess",
  160. btnType: "primary",
  161. judge: [{ fn: () => true }],
  162. },
  163. ];
  164. },
  165. goDetail(item) {
  166. this.$refs.dialogRef.open(item, "view");
  167. },
  168. handleProcess(item) {
  169. this.$refs.processDialogRef.open(item);
  170. },
  171. handleSearch() {
  172. this.page = 1;
  173. this.isEnd = false;
  174. this.getList();
  175. },
  176. reloadList() {
  177. this.page = 1;
  178. this.isEnd = false;
  179. this.getList();
  180. },
  181. async getList() {
  182. if (this.loading || this.isEnd) return;
  183. this.loading = true;
  184. try {
  185. const params = {
  186. pageNum: this.page,
  187. size: this.size,
  188. acdntName: this.searchName || undefined,
  189. dutyUnitId: this.deptId || undefined,
  190. };
  191. const res = await pageApproved(params);
  192. const list = res.list || [];
  193. if (this.page === 1) this.listData = list;
  194. else this.listData = this.listData.concat(list);
  195. this.isEnd =
  196. list.length < this.size || this.listData.length >= res.count;
  197. this.page += 1;
  198. } catch (e) {
  199. this.$refs.uToast.show({ type: "error", message: e.message });
  200. } finally {
  201. this.loading = false;
  202. }
  203. },
  204. loadMore() {
  205. if (!this.isEnd && !this.loading) this.getList();
  206. },
  207. },
  208. };
  209. </script>
  210. <style lang="scss" scoped>
  211. .process-list {
  212. .search-row {
  213. display: flex;
  214. align-items: center;
  215. gap: 12rpx;
  216. padding: 16rpx 20rpx;
  217. background: #fff;
  218. border-radius: 24rpx;
  219. margin-bottom: 16rpx;
  220. .search-input {
  221. flex: 1;
  222. height: 60rpx;
  223. background: #f5f7fb;
  224. border-radius: 48rpx;
  225. padding: 0 20rpx;
  226. font-size: 26rpx;
  227. }
  228. .dept-btn {
  229. display: flex;
  230. align-items: center;
  231. height: 60rpx;
  232. padding: 0 20rpx;
  233. background: #e8edf4;
  234. border-radius: 48rpx;
  235. color: #2979ff;
  236. font-size: 24rpx;
  237. gap: 4rpx;
  238. .arrow {
  239. font-size: 18rpx;
  240. }
  241. }
  242. .search-btn {
  243. height: 60rpx;
  244. padding: 0 28rpx;
  245. background: $theme-color;
  246. border-radius: 48rpx;
  247. color: #fff;
  248. font-size: 26rpx;
  249. line-height: 60rpx;
  250. }
  251. }
  252. .list-content {
  253. height: calc(100vh - 300rpx);
  254. }
  255. .card-wrapper {
  256. margin-top: 16rpx;
  257. }
  258. .load-more {
  259. text-align: center;
  260. font-size: 26rpx;
  261. color: #aaa;
  262. padding: 20rpx 0;
  263. }
  264. }
  265. </style>