user.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. <template>
  2. <div class="demandmanageuser" ref="localDom">
  3. <div class="topCon">
  4. <div class="topLeft">
  5. <Select
  6. isReadOnly
  7. @change="creatorCondChange"
  8. :selectdata="creatorConds"
  9. v-model="creatorCond"
  10. :placeholder="'请选择'"
  11. hideClear
  12. />
  13. </div>
  14. <div class="topRight">
  15. <Input placeholder="主题、编码" @clear="pressEnter" iconType="search" v-model="matchingCond" @pressEnter="pressEnter"/>
  16. <Badge :content="draft.count">
  17. <Button type="default" @click="openDraft">草稿箱</Button>
  18. </Badge>
  19. <Button type="primary" @click="addDemand">新增需求</Button>
  20. </div>
  21. </div>
  22. <div class="mainCon">
  23. <div class="tableCon" id="tableCon-user">
  24. <TableGrid
  25. v-if="tableHeight"
  26. width="100%"
  27. :maxHeight="tableHeight"
  28. :header="header"
  29. :data="tableData"
  30. key="tableGrid"
  31. :rowTools="rowTools"
  32. @sortHandle="sortHandle"
  33. @screenHandle="screenHandle"
  34. @rowToolHandle="rowToolHandle"
  35. />
  36. </div>
  37. <div class="paginationCon">
  38. <Pagination
  39. :pageCountShow="true"
  40. :page.sync="pagination.current"
  41. :pageSize="pagination.size"
  42. :pageCount="pageCount"
  43. :pageSizeSetting="true"
  44. @change="paginationChange"
  45. />
  46. </div>
  47. </div>
  48. <Detail
  49. v-if="showDetail"
  50. v-model="showDetail"
  51. :handle="handleDetail"
  52. @cancel="DetailCancel($event), (showDetail = false)"
  53. @confirm="DetailConfirm($event), (showDetail = false)"
  54. @save="DetailSave($event), (showDetail = false)"
  55. />
  56. <Draft v-if="showDraft"
  57. @back="DraftBack($event),(showDraft = false)"
  58. />
  59. <Modal
  60. :show="modalStatusTip"
  61. title="提示"
  62. mode="tip"
  63. type="info"
  64. @close="modalClose"
  65. >
  66. <template #content>
  67. 数据删除不可恢复,是否继续删除?
  68. </template>
  69. <template #handle>
  70. <Button @click="modalClose" type="default">取消</Button>
  71. <Button @click="modalConfirm" type="primary">确认</Button>
  72. </template>
  73. </Modal>
  74. </div>
  75. </template>
  76. <script>
  77. import { mapState } from 'vuex'
  78. import {
  79. Select,
  80. Badge,
  81. Input,
  82. TableGrid,
  83. Pagination,
  84. Modal
  85. } from 'meri-design'
  86. import Detail from './Detail'
  87. import Draft from './Draft'
  88. export default {
  89. name: 'demandmanageuser',
  90. components: {
  91. Detail,
  92. Draft,
  93. Select,
  94. Badge,
  95. Input,
  96. TableGrid,
  97. Pagination,
  98. Modal
  99. },
  100. data () {
  101. return {
  102. detailId: '',
  103. modalStatusTip: false,
  104. showDraft: false,
  105. handleDetail: {
  106. user: true,
  107. type: '详情'
  108. },
  109. showDetail: false,
  110. tableHeight: 300,
  111. pagination: {
  112. current: 1,
  113. size: 10
  114. },
  115. pageCount: 99,
  116. rowTools: {
  117. open: true, // 开启显示操作
  118. fixed: 'right', // 与header数据的fixed一样
  119. width: 120, // 与header数据的width一样
  120. align: '', // 与header数据的align一样
  121. text: '', // 头部显示的文字,默认是操作
  122. moreOpen: true,
  123. event: 'rowToolHandle'
  124. },
  125. name: 'ddd',
  126. creatorCond: 0, // 下拉筛选条件 - 0:所有需求 1:我的需求
  127. creatorConds: [{ id: 0, name: '所有需求' }, { id: 1, name: '我的需求' }],
  128. matchingCond: '', // 模糊匹配 - 编码、主题
  129. productCond: [1, 2, 3], // 产线条件
  130. stateCond: [1, 2, 3, 4, 5], // 状态条件
  131. orders: [
  132. // {
  133. // column: 'modifiedTime',
  134. // asc: false
  135. // }
  136. ],
  137. draft: {
  138. data: [],
  139. count: 0
  140. },
  141. line: { 1: '业务', 2: '研发', 3: '实施' },
  142. state: { 1: '待回复', 2: '已接受', 3: '已拒绝', 4: '待完善', 5: '论证中' },
  143. header: [
  144. {
  145. key: 'userName',
  146. text: '用户名',
  147. width: 130
  148. },
  149. {
  150. key: 'deptName',
  151. text: '部门',
  152. width: 180
  153. },
  154. {
  155. key: 'productLine',
  156. text: '条线',
  157. width: 100,
  158. screen: {
  159. open: true,
  160. status: 'single',
  161. data: [
  162. { id: 'all', name: '全部' },
  163. { id: '1', name: '业务' },
  164. { id: '2', name: '研发' },
  165. { id: '3', name: '实施' }
  166. ],
  167. selectId: '1',
  168. selectName: '业务',
  169. event: 'screenHandle'
  170. }
  171. },
  172. {
  173. key: 'code',
  174. text: '编码',
  175. width: 100
  176. },
  177. {
  178. key: 'subject',
  179. text: '主题'
  180. },
  181. {
  182. key: 'submitTime',
  183. text: '提交时间',
  184. width: 190,
  185. sort: { open: true, event: 'sortHandle' }
  186. },
  187. {
  188. key: 'answerTime',
  189. text: '回复时间',
  190. width: 190,
  191. sort: { open: true, event: 'sortHandle' }
  192. },
  193. {
  194. key: 'billState', // 需求状态 - 0:待提交 1:待回复 2:已接受 3:已拒绝 4:待完善 5:论证中
  195. text: '当前状态',
  196. width: 120,
  197. screen: {
  198. open: true,
  199. status: 'single',
  200. data: [
  201. { id: 'all', name: '全部' },
  202. { id: '1', name: '待回复' },
  203. { id: '2', name: '已接受' },
  204. { id: '3', name: '已拒绝' },
  205. { id: '4', name: '待完善' },
  206. { id: '5', name: '论证中' }
  207. ],
  208. event: 'screenHandle'
  209. }
  210. }
  211. ],
  212. temp: [
  213. {
  214. id: '1438483235070820355',
  215. valid: 1,
  216. creationTime: 1631796103000,
  217. creator: '1e7051ee780d4355813795f65809f815',
  218. code: '10002',
  219. userName: 'csgo',
  220. deptName: 'BDTP',
  221. productLine: 1,
  222. subject: '主题',
  223. content: '内容',
  224. submitTime: '202109091212',
  225. answerTime: '',
  226. billState: 1
  227. }
  228. ],
  229. tableData: [
  230. // {
  231. // id: 'id',
  232. // userName: { text: 'answerTime' },
  233. // deptName: { text: 'answerTime' },
  234. // productLine: { text: '研发' },
  235. // code: { text: 'answerTime' },
  236. // subject: { text: 'answerTime' },
  237. // content: { text: 'answerTime' },
  238. // submitTime: { text: 'answerTime' },
  239. // answerTime: { text: 'answerTime' },
  240. // billState: { text: '待回复' },
  241. // tools: {
  242. // data: [
  243. // { id: 'bj', name: '编辑' },
  244. // { id: 'sc', name: '删除' }
  245. // ]
  246. // }
  247. // }
  248. ]
  249. }
  250. },
  251. methods: {
  252. modalClose () {
  253. this.modalStatusTip = false
  254. },
  255. modalConfirm () {
  256. this.$axios.post(this.$api.demandDelete, [this.detailId]).then(() => {
  257. this.getTableData()
  258. })
  259. this.modalStatusTip = false
  260. },
  261. openDraft () {
  262. this.showDraft = true
  263. },
  264. DraftBack () {
  265. this.getTableData()
  266. this.getDraft()
  267. },
  268. // 详情 编辑 弹窗操作
  269. DetailCancel (detail) {
  270. console.log(detail)
  271. },
  272. async DetailConfirm (detail) {
  273. await this.$axios.post(this.$api.demandSubmit, detail)
  274. this.getTableData()
  275. },
  276. async DetailSave (detail) {
  277. await this.$axios.post(this.$api.demandSave, detail)
  278. this.getDraft()
  279. },
  280. // 触发 新增需求弹窗
  281. addDemand () {
  282. this.handleDetail = {
  283. user: true,
  284. type: '新增需求',
  285. userName: this.UserAndPro.userName,
  286. detail: {}
  287. }
  288. this.showDetail = true
  289. },
  290. // 列表操作按钮的处理
  291. rowToolHandle (handle) {
  292. // {itemId: '1438483235070820353', toolId: 'xq'}
  293. const { itemId, toolId } = handle
  294. const detail = this.tableData.filter(obj => obj.id === itemId)[0]?.detail
  295. if (toolId === 'xg') { // 修改
  296. this.handleDetail = {
  297. user: true,
  298. type: '修改需求',
  299. detail: detail
  300. }
  301. this.showDetail = true
  302. } else if (toolId === 'cx') {
  303. this.detailId = detail.id
  304. this.modalStatusTip = true
  305. } else {
  306. this.handleDetail = {
  307. user: true,
  308. type: '详情',
  309. detail: detail
  310. }
  311. this.showDetail = true
  312. }
  313. },
  314. // 页码操作
  315. paginationChange (page) {
  316. // {newPage: 1, newPageSize: 40}
  317. this.getTableData(page)
  318. },
  319. // 状态颜色处理
  320. toColor (detail) {
  321. const { submitTime, estimateTime, billState } = detail
  322. // 待回复:蓝色 #0091FF
  323. // 论证中回复且时间未超过的:黄色 #F58300
  324. // 论证中回复且时间超过了:红色 #F54E45
  325. // 待回复且时间超过了:红色 #F54E45
  326. // 已拒绝:灰色 #8D9399
  327. // 已接受:绿色 #34C724
  328. // 待完善:灰色 #8D9399
  329. // 需求状态 - 0:待提交 1:待回复 2:已接受 3:已拒绝 4:待完善 5:论证中
  330. let color = ''
  331. const flag = estimateTime && this.$moment(estimateTime, 'YYYYMMDDHHmmss').valueOf() < this.$moment().valueOf()
  332. const flag2 = submitTime && this.$moment().diff(this.$moment(submitTime, 'YYYYMMDDHHmmss'), 'day') >= 2
  333. switch (billState) {
  334. case 1:
  335. color = flag2 ? '#F54E45' : '#0091FF'
  336. break
  337. case 2:
  338. color = '#34C724'
  339. break
  340. case 3:
  341. color = '#8D9399'
  342. break
  343. case 4:
  344. color = '#8D9399'
  345. break
  346. default:
  347. color = flag ? '#F54E45' : '#F58300'
  348. }
  349. return color
  350. },
  351. // 列表数据格式处理
  352. toTableData (data) {
  353. const arr = []
  354. data.forEach(obj => {
  355. const temp = {}
  356. temp.detail = JSON.parse(JSON.stringify(obj))
  357. Object.keys(obj).forEach(key => {
  358. const cell = {
  359. text: ''
  360. }
  361. if (!obj[key] && obj[key] !== 0) {
  362. cell.text = '--'
  363. } else {
  364. switch (key) {
  365. case 'productLine':
  366. cell.text = this.line[obj[key]]
  367. break
  368. case 'submitTime':
  369. case 'answerTime':
  370. cell.text = this.$moment(obj[key]).format('YYYY-MM-DD HH:mm:ss')
  371. break
  372. case 'billState':
  373. cell.text = this.state[obj[key]]
  374. cell.dot = this.toColor(temp.detail)
  375. Object.assign(temp.detail, cell)
  376. break
  377. default:
  378. cell.text = obj[key]
  379. }
  380. }
  381. temp[key] = key === 'id' ? obj[key] : cell
  382. })
  383. if (obj.creator === this.UserAndPro.userId && obj.billState !== 2 && obj.billState !== 3 && obj.billState !== 5) {
  384. temp.tools = obj.billState === 4 ? {
  385. data: [
  386. { id: 'xg', name: '修改' },
  387. { id: 'cx', name: '撤销' }
  388. ]
  389. } : {
  390. data: [
  391. { id: 'xq', name: '详情' },
  392. { id: 'cx', name: '撤销' }
  393. ]
  394. }
  395. } else {
  396. temp.tools = {
  397. data: [
  398. { id: 'xq', name: '详情' }
  399. ]
  400. }
  401. }
  402. arr.push(temp)
  403. })
  404. return arr
  405. },
  406. // 所有需求 自己需求 切换
  407. creatorCondChange () {
  408. // {id: 1, name: '我的需求'}
  409. // this.creatorCond = data.id
  410. this.getTableData()
  411. },
  412. // 搜索回车查询
  413. pressEnter () {
  414. this.getTableData()
  415. },
  416. // 处理滚动条 hover显示不挤占内容位置
  417. toTableHeight () {
  418. const dom = document.getElementById('tableCon-user')
  419. if (!dom) return
  420. this.tableHeight = dom.offsetHeight
  421. },
  422. // 排序操作
  423. sortHandle (type, key) {
  424. // ord submitTime
  425. // ord submitTime
  426. this.orders = [
  427. {
  428. column: key,
  429. asc: type === 'seq'
  430. }
  431. ]
  432. this.getTableData()
  433. },
  434. // 筛选操作
  435. screenHandle (key, type) {
  436. // productLine all
  437. // billState all
  438. console.log(type)
  439. if (key === 'productLine') {
  440. this.productCond = type === 'all' ? [1, 2, 3] : [Number(type)]
  441. } else {
  442. this.stateCond = type === 'all' ? [1, 2, 3, 4, 5] : [Number(type)]
  443. }
  444. this.getTableData()
  445. },
  446. // 获取列表
  447. getTableData (page) {
  448. if (page) {
  449. if (page.newPageSize !== this.pagination.size) this.pagination.size = page.newPageSize
  450. } else {
  451. this.pagination.current = 1
  452. }
  453. this.$axios.post(this.$api.demandQuerySubmitted, {
  454. ...this.pagination,
  455. creatorCond: this.creatorCond, // 下拉筛选条件 - 0:所有需求 1:我的需求
  456. matchingCond: this.matchingCond, // 模糊匹配 - 编码、主题
  457. productCond: this.productCond, // 产线条件
  458. stateCond: this.stateCond, // 状态条件
  459. orders: this.orders
  460. }).then((res) => {
  461. const data = res.data
  462. this.pageCount = data.count
  463. this.tableData = this.toTableData(data.data)
  464. })
  465. },
  466. // 获取草稿
  467. getDraft () {
  468. this.$axios.post(this.$api.demandQueryDraft, {
  469. creatorCond: 1,
  470. matchingCond: '',
  471. productCond: [1, 2, 3],
  472. stateCond: [],
  473. size: 20,
  474. current: 1,
  475. orders: []
  476. }).then((res) => {
  477. this.draft = res.data
  478. })
  479. }
  480. },
  481. computed: {
  482. ...mapState({
  483. ProjectList: (state) =>
  484. state.userInfo.projects.map(
  485. ({ projectId: id, projectName: name, projectLocalID: localId }) => ({
  486. id,
  487. name,
  488. localId
  489. })
  490. ),
  491. UserAndPro (state) {
  492. const argu = {
  493. projectId: [],
  494. projectLocalId: [],
  495. userId: state.userInfo.userId,
  496. userName: state.userInfo.userName
  497. }
  498. state.userInfo.projects.forEach(({ projectId, projectLocalID }) => {
  499. argu.projectId.push(projectId)
  500. argu.projectLocalId.push(projectLocalID)
  501. })
  502. return argu
  503. }
  504. })
  505. },
  506. async beforeMount () {
  507. console.log('beforeMount')
  508. },
  509. mounted () {
  510. console.log('mounted')
  511. window.addEventListener('resize', this.toTableHeight, false)
  512. this.$nextTick(() => {
  513. this.toTableHeight()
  514. // this.$ploading.local({
  515. // el: this.$refs.localDom,
  516. // size: 'min'
  517. // })
  518. this.getDraft()
  519. this.getTableData()
  520. })
  521. },
  522. beforeDestroy () {
  523. // 页面刷新机制 销毁绑定事件
  524. window.removeEventListener('resize', this.toTableHeight, false)
  525. }
  526. }
  527. </script>
  528. <style lang="less" scoped>
  529. .demandmanageuser{
  530. width: 100%;
  531. height: 100%;
  532. padding: 0 14px 0 16px;
  533. .topCon{
  534. height: 72px;
  535. display: flex;
  536. align-items: center;
  537. justify-content: space-between;
  538. .topRight{
  539. &>div{
  540. margin-left: 12px;
  541. }
  542. }
  543. }
  544. .mainCon{
  545. height: calc(100% - 72px);
  546. overflow: hidden;
  547. .tableCon{
  548. height: calc(100% - 70px);
  549. }
  550. .pageCon{
  551. height: 70px;
  552. }
  553. }
  554. .paginationCon {
  555. height: 70px;
  556. display: flex;
  557. justify-content: flex-end;
  558. }
  559. }
  560. </style>