crmTodoList.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. <template>
  2. <div class="todo-list">
  3. <Header />
  4. <div class="content-wrapper mt-15 max-w-[1200px] mx-auto">
  5. <div class="flex gap-5 items-center mb-4 bg-[#fff] py-2 pl-4 rounded-sm">
  6. <p class="flex items-center">
  7. <Icon
  8. icon="mynaui:arrow-up-down"
  9. class="icon pr-1 h-6 w-6"
  10. color="#014099"
  11. />CRM待办任务列表
  12. </p>
  13. <el-button
  14. type="primary"
  15. round
  16. size="small"
  17. color="#02409b"
  18. @click="router.back()"
  19. ><Icon
  20. icon="mynaui:corner-up-left"
  21. class="icon pr-1"
  22. width="20"
  23. height="20"
  24. />返回</el-button
  25. >
  26. </div>
  27. <div v-loading="loading" class="table-wrapper">
  28. <el-table
  29. v-loading="loading"
  30. :data="oaTasks"
  31. style="width: 100%"
  32. height="70vh"
  33. stripe
  34. element-loading-text="加载中..."
  35. :empty-text="loading ? '' : '暂无数据'"
  36. :header-cell-style="{
  37. backgroundColor: '#e9f7ff',
  38. color: 'black',
  39. fontWeight: '400',
  40. }"
  41. :cell-style="{
  42. color: 'black',
  43. }"
  44. >
  45. <el-table-column
  46. type="index"
  47. label="序号"
  48. width="80"
  49. fixed="left"
  50. align="center"
  51. />
  52. <el-table-column
  53. prop="instTitle"
  54. label="流程标题"
  55. min-width="220"
  56. fixed="left"
  57. align="center"
  58. />
  59. <el-table-column
  60. prop="entityTypeId"
  61. label="业务类型"
  62. width="140"
  63. align="center"
  64. />
  65. <el-table-column
  66. prop="priority"
  67. label="优先级别"
  68. width="100"
  69. align="center"
  70. >
  71. <template #default="scope">
  72. <el-tag v-if="scope.row.priority == 50" type="warning" size="mini"
  73. >一般</el-tag
  74. >
  75. <el-tag
  76. v-else-if="scope.row.priority === 90"
  77. type="danger"
  78. size="mini"
  79. >
  80. 紧急
  81. </el-tag>
  82. <span v-else></span>
  83. </template>
  84. </el-table-column>
  85. <el-table-column
  86. prop="createAt"
  87. label="任务提交时间"
  88. width="180"
  89. align="center"
  90. >
  91. <template #default="scope">
  92. {{ timestampToDateTime(scope.row.submitAt) }}
  93. </template>
  94. </el-table-column>
  95. <el-table-column
  96. prop="createAt"
  97. label="任务创建时间"
  98. width="180"
  99. align="center"
  100. >
  101. <template #default="scope">
  102. {{ timestampToDateTime(scope.row.createdAt) }}
  103. </template>
  104. </el-table-column>
  105. <el-table-column
  106. prop="endAt"
  107. label="任务完成时间"
  108. width="180"
  109. align="center"
  110. >
  111. <template #default="scope">
  112. {{ timestampToDateTime(scope.row.endAt) }}
  113. </template>
  114. </el-table-column>
  115. <el-table-column
  116. prop="userName"
  117. label="任务提交人"
  118. width="120"
  119. align="center"
  120. />
  121. <el-table-column
  122. prop="status"
  123. label="任务状态"
  124. width="100"
  125. align="center"
  126. >
  127. <template #default="scope">
  128. <el-tag v-if="scope.row.status === 1" type="info" size="mini"
  129. >待提交</el-tag
  130. >
  131. <el-tag
  132. v-else-if="scope.row.status === 2"
  133. type="info"
  134. size="mini"
  135. >
  136. 待重新提交
  137. </el-tag>
  138. <el-tag
  139. v-else-if="scope.row.status === 3"
  140. type="info"
  141. size="mini"
  142. >
  143. 待提交到退回节点
  144. </el-tag>
  145. <el-tag
  146. v-else-if="scope.row.status === 4"
  147. type="primary"
  148. size="mini"
  149. >
  150. 已提交
  151. </el-tag>
  152. <el-tag
  153. v-else-if="scope.row.status === 5"
  154. type="info"
  155. size="mini"
  156. >
  157. 待办理
  158. </el-tag>
  159. <el-tag
  160. v-else-if="scope.row.status === 6"
  161. type="success"
  162. size="mini"
  163. >
  164. 已同意
  165. </el-tag>
  166. <el-tag
  167. v-else-if="scope.row.status === 7"
  168. type="danger"
  169. size="mini"
  170. >
  171. 已拒绝
  172. </el-tag>
  173. <el-tag
  174. v-else-if="scope.row.status === 8"
  175. type="danger"
  176. size="mini"
  177. >
  178. 已转办
  179. </el-tag>
  180. <el-tag
  181. v-else-if="scope.row.status === 9"
  182. type="primary"
  183. size="mini"
  184. >
  185. 已抄送
  186. </el-tag>
  187. <el-tag
  188. v-else-if="scope.row.status === 10"
  189. type="warning"
  190. size="mini"
  191. >
  192. 加签挂起
  193. </el-tag>
  194. <el-tag
  195. v-else-if="scope.row.status === 11"
  196. type="warning"
  197. size="mini"
  198. >
  199. 任务挂起
  200. </el-tag>
  201. <el-tag
  202. v-else-if="scope.row.status === 12"
  203. type="warning"
  204. size="mini"
  205. >
  206. 已收回
  207. </el-tag>
  208. <el-tag
  209. v-else-if="scope.row.status === 13"
  210. type="warning"
  211. size="mini"
  212. >
  213. 已移交
  214. </el-tag>
  215. <el-tag
  216. v-else-if="scope.row.status === 14"
  217. type="warning"
  218. size="mini"
  219. >
  220. 已委托
  221. </el-tag>
  222. <el-tag
  223. v-else-if="scope.row.status === 99"
  224. type="success"
  225. size="mini"
  226. >
  227. 无需办理
  228. </el-tag>
  229. <span v-else></span>
  230. </template>
  231. </el-table-column>
  232. <el-table-column
  233. label="操作"
  234. width="120"
  235. fixed="right"
  236. align="center"
  237. >
  238. <template #default="scope">
  239. <span
  240. class="text-[#02409b] cursor-pointer"
  241. @click="goBackPage(scope.row)"
  242. >处理</span
  243. >
  244. </template>
  245. </el-table-column>
  246. </el-table>
  247. </div>
  248. <div class="pagination-container">
  249. <el-pagination
  250. v-model:current-page="pagination.pageNum"
  251. v-model:page-size="pagination.pageSize"
  252. :total="pagination.total"
  253. :page-sizes="[10, 20, 50, 100]"
  254. layout="total, sizes, prev, pager, next"
  255. background
  256. @current-change="handleCurrentChange"
  257. @size-change="handleSizeChange"
  258. />
  259. </div>
  260. </div>
  261. <Footer />
  262. </div>
  263. </template>
  264. <script setup>
  265. import Header from "@components/home/header.vue";
  266. import { ref, onMounted } from "vue";
  267. import { getCRMTasks, ssoLogin } from "@/api/user";
  268. import { useUserStore } from "@/stores/useUserStore";
  269. import { Icon } from "@iconify/vue";
  270. import router from "@/router";
  271. const userStore = useUserStore();
  272. const oaTasks = ref([]);
  273. const loading = ref(false);
  274. const pagination = ref({
  275. pageNum: 1,
  276. pageSize: 10,
  277. total: 0,
  278. });
  279. const handleCurrentChange = async (page) => {
  280. pagination.value.pageNum = page;
  281. loading.value = true;
  282. try {
  283. const res = await getCRMTasks({
  284. id: userStore.getUser.username,
  285. type: "pending",
  286. pageNum: pagination.value.pageNum,
  287. pageSize: pagination.value.pageSize,
  288. });
  289. oaTasks.value = res.todoList;
  290. pagination.value.total = res.todoCount;
  291. } finally {
  292. loading.value = false;
  293. }
  294. };
  295. const handleSizeChange = async (size) => {
  296. pagination.value.pageSize = size;
  297. pagination.value.pageNum = 1;
  298. loading.value = true;
  299. try {
  300. const res = await getCRMTasks({
  301. id: userStore.getUser.username,
  302. type: "pending",
  303. pageNum: pagination.value.pageNum,
  304. pageSize: pagination.value.pageSize,
  305. });
  306. oaTasks.value = res.todoList;
  307. pagination.value.total = res.todoCount;
  308. } finally {
  309. loading.value = false;
  310. }
  311. };
  312. const goBackPage = async (row) => {
  313. // const res = await ssoLogin({
  314. // username: userStore.getUser.username,
  315. // });
  316. // if (res) {
  317. // const newTab = window.open("", "_blank");
  318. // newTab.location.href =
  319. // "https://yfoa.keruioil.com/wui/index.html" +
  320. // "?ssoToken=" +
  321. // res +
  322. // "#/main";
  323. // setTimeout(function () {
  324. // newTab.location.href = `https://yfoa.keruioil.com/spa/workflow/static4form/index.html?_rdm=1776063595284#/main/workflow/req?requestid=${row.requestId}`;
  325. // }, 50);
  326. // }
  327. };
  328. function timestampToDateTime(timestamp) {
  329. // 兼容 10位(秒) / 13位(毫秒)
  330. const len = String(timestamp).length;
  331. const date = new Date(Number(timestamp) * (len === 10 ? 1000 : 1));
  332. // 年
  333. const year = date.getFullYear();
  334. // 月(0~11 → +1)
  335. const month = String(date.getMonth() + 1).padStart(2, "0");
  336. // 日
  337. const day = String(date.getDate()).padStart(2, "0");
  338. // 时
  339. const hours = String(date.getHours()).padStart(2, "0");
  340. // 分
  341. const minutes = String(date.getMinutes()).padStart(2, "0");
  342. // 秒
  343. const seconds = String(date.getSeconds()).padStart(2, "0");
  344. return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  345. }
  346. onMounted(async () => {
  347. if (userStore.getUser.username) {
  348. loading.value = true;
  349. try {
  350. const res = await getCRMTasks({
  351. id: userStore.getUser.username,
  352. type: "pending",
  353. pageNum: pagination.value.pageNum,
  354. pageSize: pagination.value.pageSize,
  355. });
  356. oaTasks.value = res.todoList;
  357. pagination.value.total = res.todoCount;
  358. } finally {
  359. loading.value = false;
  360. }
  361. }
  362. });
  363. </script>
  364. <style scoped>
  365. .todo-list {
  366. min-height: 100vh;
  367. display: flex;
  368. flex-direction: column;
  369. background-color: #f5f7fa;
  370. }
  371. .content {
  372. padding: 16px 20px;
  373. margin-top: 100px;
  374. }
  375. .pagination-wrap {
  376. display: flex;
  377. justify-content: flex-end;
  378. margin-top: 16px;
  379. }
  380. .news-container {
  381. min-height: 100vh;
  382. display: flex;
  383. flex-direction: column;
  384. background-color: #f5f7fa;
  385. }
  386. .content-wrapper {
  387. flex: 1;
  388. max-width: 1200px;
  389. /* margin: 0 auto; */
  390. padding: 20px;
  391. width: 100%;
  392. box-sizing: border-box;
  393. }
  394. .page-title {
  395. margin-bottom: 20px;
  396. color: #303133;
  397. border-left: 5px solid #409eff;
  398. padding-left: 10px;
  399. }
  400. .table-wrapper {
  401. min-height: 400px;
  402. background: #fff;
  403. padding: 20px;
  404. border-radius: 4px;
  405. }
  406. .table-title {
  407. font-weight: 500;
  408. color: #303133;
  409. }
  410. .table-summary {
  411. color: #606266;
  412. font-size: 13px;
  413. }
  414. .pagination-container {
  415. display: flex;
  416. justify-content: center;
  417. margin-top: 0px;
  418. padding: 20px 0;
  419. }
  420. </style>