index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. <template>
  2. <div class="user-management-container">
  3. <div class="side-layout">
  4. <div class="tree-side">
  5. <span class="type">操作类型</span>
  6. <div
  7. :style="{
  8. color: queryForm.operateType != '1' ? '#999999' : '#1D66DC',
  9. 'margin-top': '20px',
  10. cursor: 'pointer',
  11. }"
  12. @click="search('1')">
  13. <i class="el-icon-message-solid" style="margin-right: 10px"></i>
  14. 我的待办({{ statisticsForm.toDoNumber }})
  15. </div>
  16. <div
  17. :style="{
  18. color: queryForm.operateType != '2' ? '#999999' : '#1D66DC',
  19. 'margin-top': '20px',
  20. cursor: 'pointer',
  21. }"
  22. @click="search('2')">
  23. <i class="el-icon-video-play" style="margin-right: 10px"></i>
  24. 我发起的
  25. </div>
  26. <div
  27. :style="{
  28. color: queryForm.operateType != '3' ? '#999999' : '#1D66DC',
  29. 'margin-top': '20px',
  30. cursor: 'pointer',
  31. }"
  32. @click="search('3')">
  33. <i class="el-icon-folder-checked" style="margin-right: 10px"></i>
  34. 我处理的
  35. </div>
  36. <div class="type" style="margin-top: 50px">督办类型</div>
  37. <div
  38. :style="{ color: queryForm.taskType != '' ? '#999999' : '#1D66DC', 'margin-top': '20px', cursor: 'pointer' }"
  39. @click="searchType('')">
  40. 全部
  41. </div>
  42. <div
  43. v-for="item in types"
  44. :key="item.dictCode"
  45. :style="{
  46. color: queryForm.taskType != item.dictValue ? '#999999' : '#1D66DC',
  47. 'margin-top': '20px',
  48. cursor: 'pointer',
  49. }"
  50. @click="searchType(item.dictValue)">
  51. {{ item.dictLabel }}
  52. </div>
  53. </div>
  54. <div class="tree-table">
  55. <vab-query-form>
  56. <vab-query-form-top-panel>
  57. <el-form :inline="true" :model="queryForm" @submit.native.prevent>
  58. <el-form-item>
  59. <el-input v-model.trim="queryForm.taskTitle" clearable placeholder="请输入督办标题" />
  60. </el-form-item>
  61. <el-form-item>
  62. <el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
  63. <el-button icon="el-icon-refresh-right" @click="reset">重置</el-button>
  64. </el-form-item>
  65. </el-form>
  66. </vab-query-form-top-panel>
  67. <vab-query-form-left-panel :span="12">
  68. <el-button icon="el-icon-plus" type="primary" @click="handleAdd">添加</el-button>
  69. </vab-query-form-left-panel>
  70. <vab-query-form-right-panel :span="12">
  71. <!-- <el-button icon="el-icon-download" @click="exportData" /> -->
  72. <table-tool :check-list.sync="checkList" :columns="columns" />
  73. </vab-query-form-right-panel>
  74. </vab-query-form>
  75. <!-- 主页面 -->
  76. <el-table v-loading="listLoading" border :data="list" :height="height" width="100%">
  77. <el-table-column
  78. v-for="(item, index) in finallyColumns"
  79. :key="index"
  80. align="center"
  81. :label="item.label"
  82. :prop="item.prop"
  83. show-overflow-tooltip
  84. :sortable="item.sortable"
  85. :width="item.width">
  86. <template #default="{ row }">
  87. <el-button v-if="item.prop === 'taskTitle'" class="link-button" type="text" @click="showDetail(row)">
  88. {{ row.taskTitle }}
  89. </el-button>
  90. <span v-if="item.prop === 'taskType'">
  91. {{ typeMap[row.taskType] }}
  92. </span>
  93. <span v-else-if="item.prop === 'taskStatus'">
  94. <span v-if="row.taskStatus === '10'">发起</span>
  95. <span v-if="row.taskStatus === '20'">进行中</span>
  96. <span v-if="row.taskStatus === '30'">流程完成</span>
  97. </span>
  98. <span v-else-if="item.prop === 'isOverdue'">
  99. {{ row.isOverdue === '10' ? '否' : '是' }}
  100. </span>
  101. <span v-else-if="item.prop === 'mainUserId' || item.prop === 'supervisorUserId'">
  102. {{ userMap[row[item.prop]] }}
  103. </span>
  104. <span v-else-if="item.prop === 'ownerUserId'">
  105. {{ generateTeamMembers(row[item.prop]) }}
  106. </span>
  107. <span
  108. v-else-if="item.prop === 'taskStartDate' || item.prop === 'taskEndDate' || item.prop === 'createdTime'">
  109. {{ parseTime(row[item.prop], '{y}-{m}-{d}') }}
  110. </span>
  111. <span v-else>{{ row[item.prop] }}</span>
  112. </template>
  113. </el-table-column>
  114. <template #empty>
  115. <el-image class="vab-data-empty" :src="require('@/assets/empty_images/data_empty.png')" />
  116. </template>
  117. </el-table>
  118. <el-pagination
  119. background
  120. :current-page="queryForm.pageNum"
  121. :layout="layout"
  122. :page-size="queryForm.pageSize"
  123. :total="total"
  124. @current-change="handleCurrentChange"
  125. @size-change="handleSizeChange" />
  126. </div>
  127. </div>
  128. <!-- 新建督办 -->
  129. <taskAdd ref="taskAdd" :do-refresh="doRefresh" :types="types" :users="users" />
  130. <!-- 查看详情 -->
  131. <taskDetail
  132. :do-refresh="doRefresh"
  133. :self-visible.sync="detailDialogVisible"
  134. :the-task="theTask"
  135. :type-map="typeMap"
  136. :user-map="userMap" />
  137. </div>
  138. </template>
  139. <script>
  140. import taskApi from '@/api/plat/task'
  141. import userApi from '@/api/system/user'
  142. import dictApi from '@/api/system/dict'
  143. import taskAdd from './components/TaskAdd.vue'
  144. import taskDetail from './components/TaskDetail.vue'
  145. import TableTool from '@/components/table/TableTool'
  146. import downloadFileByByte from '@/utils/base64ToFile'
  147. export default {
  148. name: 'Task',
  149. components: { taskAdd, taskDetail, TableTool },
  150. data() {
  151. return {
  152. height: this.$baseTableHeight(2),
  153. // 各督办数量统计
  154. statisticsForm: {
  155. toDoNumber: 0,
  156. createNumber: 0,
  157. completedNumber: 0,
  158. },
  159. // 督办详情查看
  160. detailDialogVisible: false,
  161. // 新建弹窗控制
  162. addDialogVisible: false,
  163. // 展示的督办数据
  164. theTask: {},
  165. list: [],
  166. listLoading: true,
  167. layout: 'total, sizes, prev, pager, next, jumper',
  168. total: 0,
  169. queryForm: {
  170. pageNum: 1,
  171. pageSize: 10,
  172. taskTitle: undefined,
  173. taskType: '',
  174. operateType: '1',
  175. },
  176. // 用户信息
  177. userMap: {},
  178. users: [],
  179. // 类型信息
  180. typeMap: {},
  181. types: [],
  182. // 自定义列表
  183. checkList: [],
  184. columns: [
  185. {
  186. label: '督办标题',
  187. width: '280px',
  188. prop: 'taskTitle',
  189. sortable: false,
  190. disableCheck: true,
  191. },
  192. {
  193. label: '督办类型',
  194. width: '120px',
  195. prop: 'taskType',
  196. sortable: false,
  197. },
  198. {
  199. label: '状态',
  200. width: '120px',
  201. prop: 'taskStatus',
  202. sortable: false,
  203. },
  204. {
  205. label: '超期',
  206. width: '120px',
  207. prop: 'isOverdue',
  208. sortable: false,
  209. },
  210. {
  211. label: '督办说明',
  212. width: '120px',
  213. prop: 'taskDesc',
  214. sortable: false,
  215. },
  216. {
  217. label: '关联对象',
  218. width: '120px',
  219. prop: 'targetName',
  220. sortable: false,
  221. },
  222. {
  223. label: '负责人',
  224. width: '120px',
  225. prop: 'mainUserId',
  226. sortable: false,
  227. },
  228. {
  229. label: '团队成员',
  230. width: '180px',
  231. prop: 'ownerUserId',
  232. sortable: false,
  233. },
  234. {
  235. label: '督办人',
  236. width: '120px',
  237. prop: 'supervisorUserId',
  238. sortable: false,
  239. },
  240. {
  241. label: '开始时间',
  242. width: '160px',
  243. prop: 'taskStartDate',
  244. sortable: false,
  245. },
  246. {
  247. label: '结束时间',
  248. width: '160px',
  249. prop: 'taskEndDate',
  250. sortable: false,
  251. },
  252. {
  253. label: '创建时间',
  254. width: '160px',
  255. prop: 'createdTime',
  256. sortable: false,
  257. },
  258. ],
  259. }
  260. },
  261. computed: {
  262. finallyColumns() {
  263. return this.columns.filter((item) => this.checkList.includes(item.label))
  264. },
  265. },
  266. async created() {
  267. this.queryForm.operateType = '1'
  268. this.statistics()
  269. await this.initData()
  270. this.fetchData()
  271. },
  272. methods: {
  273. // 刷新表数据和数量统计
  274. doRefresh() {
  275. this.fetchData()
  276. this.statistics()
  277. },
  278. // 统计各类型督办数量
  279. statistics() {
  280. taskApi
  281. .statisticsTaskNumber()
  282. .then((res) => {
  283. if (res.data.list) {
  284. this.statisticsForm = res.data.list
  285. }
  286. })
  287. .catch((err) => {
  288. console.error(err)
  289. })
  290. },
  291. // 数据导出
  292. exportData() {
  293. let exportFrom = JSON.parse(JSON.stringify(this.queryForm))
  294. exportFrom.columns = this.finallyColumns.map((item) => item.label)
  295. taskApi
  296. .exportTasks(exportFrom)
  297. .then((res) => {
  298. if (res.data.list.content) {
  299. downloadFileByByte(res.data.list.content, '督办数据.xlsx')
  300. }
  301. })
  302. .catch((err) => {
  303. console.error(err)
  304. })
  305. },
  306. // 重置查询数据
  307. reset() {
  308. this.queryForm.pageNum = 1
  309. this.queryForm.pageSize = 10
  310. this.queryForm.taskTitle = undefined
  311. this.queryForm.operateType = '1'
  312. this.queryForm.taskType = ''
  313. this.queryData()
  314. },
  315. // 左侧操作栏搜索
  316. search(type) {
  317. this.queryForm.operateType = type
  318. this.queryData()
  319. },
  320. // 督办类型搜索
  321. searchType(type) {
  322. this.queryForm.taskType = type
  323. this.queryData()
  324. },
  325. // 初始化数据
  326. async initData() {
  327. await dictApi
  328. .getDictDataList({ dictType: 'TaskType' })
  329. .then((res) => {
  330. if (res.data.list) {
  331. this.types = res.data.list
  332. for (let type of this.types) {
  333. this.typeMap[type.dictValue] = type.dictLabel
  334. }
  335. }
  336. })
  337. .catch((err) => {
  338. console.error(err)
  339. })
  340. await userApi
  341. .getList()
  342. .then((res) => {
  343. if (res.data.list) {
  344. this.users = res.data.list
  345. for (let user of this.users) {
  346. this.userMap[user.id] = user.nickName
  347. }
  348. }
  349. })
  350. .catch((err) => {
  351. console.error(err)
  352. })
  353. },
  354. // 显示详情数据
  355. showDetail(row) {
  356. // this.theTask = JSON.parse(JSON.stringify(row))
  357. // this.detailDialogVisible = true
  358. this.$store.state.task.theTask = { ...row }
  359. this.$router.push({
  360. path: '/customer/plat/task/detail',
  361. query: {
  362. type: this.queryForm.operateType,
  363. },
  364. })
  365. },
  366. // 处理新增
  367. handleAdd() {
  368. // this.addDialogVisible = true
  369. this.$refs.taskAdd.selfVisible = true
  370. },
  371. // 更换页数据大小
  372. handleSizeChange(val) {
  373. this.queryForm.pageSize = val
  374. this.fetchData()
  375. },
  376. // 更换当前页
  377. handleCurrentChange(val) {
  378. this.queryForm.pageNum = val
  379. this.fetchData()
  380. },
  381. // 查询
  382. queryData() {
  383. this.queryForm.pageNum = 1
  384. this.fetchData()
  385. },
  386. // 获取数据
  387. fetchData() {
  388. this.listLoading = true
  389. this.list = []
  390. taskApi
  391. .getTaskList(this.queryForm)
  392. .then((res) => {
  393. if (res.data.list) {
  394. this.list = res.data.list
  395. }
  396. this.total = res.data.total
  397. this.listLoading = false
  398. })
  399. .catch((err) => {
  400. this.listLoading = false
  401. console.error(err)
  402. })
  403. },
  404. // 团队成员
  405. generateTeamMembers(ids) {
  406. if (!ids) {
  407. return ''
  408. } else {
  409. let names = ''
  410. let idArray = ids.split(',')
  411. for (let id of idArray) {
  412. if (names == '') {
  413. names = this.userMap[parseInt(id)]
  414. } else {
  415. names += ',' + this.userMap[parseInt(id)]
  416. }
  417. }
  418. return names
  419. }
  420. },
  421. },
  422. }
  423. </script>
  424. <style lang="scss" scoped>
  425. .type {
  426. font-weight: bold;
  427. }
  428. $base: '.list';
  429. .link-button {
  430. font-size: 14px;
  431. width: 100%;
  432. overflow: hidden;
  433. text-overflow: ellipsis;
  434. white-space: nowrap;
  435. }
  436. </style>