MrTable.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. <template>
  2. <div @click.stop>
  3. <div v-if="isExpand" v-html="analyticFeedback" />
  4. <el-table
  5. :data="tableData"
  6. border
  7. style="width: 100%;margin-top: 10px;"
  8. highlight-current-row
  9. row-key="rowKey"
  10. :expand-row-keys="expandRowKeys"
  11. :header-cell-style="{
  12. background: '#F7F7F7',
  13. color: '#4a4a4a',
  14. 'font-size': '14px',
  15. 'font-weight': '500'
  16. }"
  17. :cell-style="{ 'font-size': '14px', color: 'rgb(102,102,102)' }"
  18. size="small"
  19. show-overflow-tooltip="true"
  20. >
  21. <!-- <el-table-column v-if="index === 0 && tabsActive.indexOf('本月重点问题') > -1
  22. && pageType !== 'edit' ? 'expand' : ''" label="展开" type="expand"> -->
  23. <el-table-column
  24. v-for="(item, index) in setColumns(columns)"
  25. :key="item.headerKey"
  26. :data-index="index"
  27. :prop="item.headerKey"
  28. :align="item.align"
  29. :label="item.name"
  30. :type="item.type"
  31. :min-width="setMinWidth(item)"
  32. :fixed="isFixed(item, index, columns)"
  33. >
  34. <template slot-scope="scope">
  35. <!-- 展开 -->
  36. <div v-if="item.type === 'expand'">
  37. <TableExpandRow
  38. :analytic-feedback="scope.row.analyticFeedback"
  39. @upAnalyticFeedback="setAnalyticFeedback"
  40. />
  41. </div>
  42. <!-- 操作列 -->
  43. <div v-else-if="item.name === '操作'">
  44. <div v-if="isExpand">
  45. <el-button
  46. v-if="isShowButton(scope.row, item)"
  47. type="text"
  48. @click.stop="btnFun({ value: '分析反馈' }, scope)"
  49. >分析反馈
  50. </el-button>
  51. </div>
  52. <span v-else>
  53. <span
  54. v-for="(btnItem, btnIndex) in item.defaultValue"
  55. :key="btnIndex"
  56. >
  57. <el-button
  58. v-if="isShowButton(scope.row, item)"
  59. style="margin-right: 10px;"
  60. type="text"
  61. @click.stop="btnFun(btnItem, scope)"
  62. >{{ btnItem.value }}</el-button
  63. >
  64. </span>
  65. </span>
  66. </div>
  67. <div
  68. v-else
  69. class="edit-wrapper"
  70. :style="{
  71. cursor: pageDate.status < 20 ? 'pointer' : 'auto'
  72. }"
  73. >
  74. <!-- <div v-if="editKeys.indexOf(`${scope.row.rowKey}_${index}`) > -1"> -->
  75. <div v-if="editKeys.indexOf(domKey) > -1 && !item.defaultValue">
  76. <div v-if="item.displayType === 'Select'">
  77. <div v-if="item.selectType && item.selectType === 'Time'">
  78. <el-date-picker
  79. v-model="scope.row[item.headerKey]"
  80. type="date"
  81. style="width: 90%"
  82. value-format="yyyy-MM-dd"
  83. size="mini"
  84. placeholder="选择日期"
  85. />
  86. </div>
  87. <div
  88. v-else-if="
  89. item.selectType && item.selectType === 'SinglePeople'
  90. "
  91. >
  92. <searchPeople :value.sync="scope.row[item.headerKey]" />
  93. </div>
  94. <div
  95. v-else-if="
  96. item.selectType && item.selectType === 'MultiplePeople'
  97. "
  98. >
  99. <searchPeople
  100. :value.sync="scope.row[item.headerKey]"
  101. :multiple="true"
  102. />
  103. </div>
  104. <div
  105. v-else-if="item.selectType && item.selectType === 'people'"
  106. >
  107. <searchPeople
  108. :value.sync="scope.row[item.headerKey]"
  109. :multiple="true"
  110. />
  111. </div>
  112. <el-select
  113. v-else
  114. v-model="scope.row[item.headerKey]"
  115. size="mini"
  116. placeholder="请选择"
  117. style="width: 80%"
  118. >
  119. <el-option
  120. v-for="optionItem in item.selectEnum"
  121. :key="optionItem"
  122. :label="optionItem"
  123. :value="optionItem"
  124. >{{ optionItem }}
  125. </el-option>
  126. </el-select>
  127. </div>
  128. <el-input
  129. v-else-if="item.displayType === 'Texterea'"
  130. v-model="scope.row[item.headerKey]"
  131. type="textarea"
  132. placeholder="请输入"
  133. maxlength="300"
  134. :autosize="{ minRows: 2, maxRows: 30 }"
  135. show-word-limit
  136. />
  137. <div v-else-if="item.displayType === 'Cascader'">
  138. <Cascader v-model="scope.row[item.headerKey]" />
  139. </div>
  140. <div v-else-if="item.defaultValue === 'Select'" />
  141. <el-input
  142. v-else
  143. v-model="scope.row[item.headerKey]"
  144. size="mini"
  145. maxlength="100"
  146. show-word-limit
  147. placeholder="请输入"
  148. />
  149. </div>
  150. <span v-else-if="item.displayType === 'Text'">{{ item.defaultValue[0].value }}</span>
  151. <!-- <div v-else class="edit-cell" @click.stop="editLine(scope.row, index)"> -->
  152. <div v-else class="edit-cell" @click.stop="editLine(scope.row, index)">
  153. <div v-if="item.displayType === 'Cascader'">
  154. <CascaderInfo :team-data="scope.row[item.headerKey]" />
  155. </div>
  156. <div v-else-if="item.displayType === 'Select'">
  157. <!-- 单个人员选择 -->
  158. <div v-if="item.selectType && item.selectType === 'SinglePeople'">
  159. <MultiplePeopleInfo :team-data="scope.row[item.headerKey]" />
  160. </div>
  161. <!-- 多个人员选择 -->
  162. <div v-else-if="item.selectType && item.selectType === 'MultiplePeople'">
  163. <!-- <searchPeople :value.sync="scope.row[item.headerKey]"
  164. :multiple="true" disabled />-->
  165. <MultiplePeopleInfo :team-data="scope.row[item.headerKey]" />
  166. </div>
  167. <!-- 多个人员选择 -->
  168. <div v-else-if="item.selectType && item.selectType === 'people'">
  169. <MultiplePeopleInfo :team-data="scope.row[item.headerKey]" />
  170. </div>
  171. <div v-else>
  172. {{ scope.row[item.headerKey] }}
  173. </div>
  174. </div>
  175. <div v-else>
  176. <span v-html="scope.row[item.headerKey]" />
  177. </div>
  178. </div>
  179. </div>
  180. </template>
  181. </el-table-column>
  182. </el-table>
  183. <div class="plus-table-data" :style="{ marginBottom: plusTableDataBottom }">
  184. <el-button v-if="pageDate && pageDate.status < 20" type="text" @click.stop="addTableData">
  185. <svg-icon icon-class="data-plus" class="icon" />
  186. 新增
  187. </el-button>
  188. </div>
  189. <slot name="fixedText" />
  190. <markingIssues ref="markingIssues" />
  191. <Analysis ref="Analysis" @upData="upDataAnalysis" />
  192. </div>
  193. </template>
  194. <script>
  195. import _ from 'lodash'
  196. import { uuid10 } from '@/utils'
  197. import Analysis from './Analysis'
  198. import Cascader from './Cascader'
  199. import CascaderInfo from './CascaderInfo'
  200. import MultiplePeopleInfo from './MultiplePeopleInfo'
  201. import TableExpandRow from './TableExpandRow'
  202. import markingIssues from './markingIssues'
  203. import searchPeople from '@/components/select/searchPeople' // 人员select
  204. import { updateAnalyticFeedback } from '@/api/qualityMonthlyReport/edit'
  205. import { reportDataBack } from '@/store/modules/monthlyReport/edit/utils.js'
  206. // import { getDeptByKeyWord } from '@/api/qualityMonthlyReport'
  207. export default {
  208. name: 'MrTable',
  209. components: {
  210. Analysis,
  211. Cascader,
  212. CascaderInfo,
  213. searchPeople,
  214. MultiplePeopleInfo,
  215. TableExpandRow,
  216. markingIssues
  217. },
  218. props: {
  219. plusTableDataBottom: {
  220. type: String,
  221. required: false,
  222. default: () => '18px'
  223. },
  224. domKey: {
  225. type: String,
  226. required: false,
  227. default: () => ''
  228. },
  229. columns: {
  230. type: Array,
  231. required: false,
  232. default: () => []
  233. },
  234. // 分析反馈时使用的数据
  235. title: {
  236. type: String,
  237. required: false,
  238. default: () => ''
  239. },
  240. tableData: {
  241. type: Array,
  242. required: false,
  243. default: () => []
  244. }
  245. },
  246. data() {
  247. this.setAnalyticFeedback = _.debounce(this.setAnalyticFeedback, 3000)
  248. return {
  249. analyticFeedback: '',
  250. expandRowKeys: [],
  251. username: localStorage.getItem('username')
  252. }
  253. },
  254. computed: {
  255. isExpand() {
  256. return this.pageDate && this.pageDate.status && this.pageDate.status === 30 && ((this.tabsActive.search(/本月重点问题/) > -1 && this.pageType === 'readAll') || (this.pageType === 'read' && this.title === '本月重点问题'))
  257. },
  258. selectEnum() {
  259. return this.$store.state.monthlyReportEdit.selectEnum
  260. },
  261. tabPageData() {
  262. return this.$store.state.monthlyReportEdit.tabPageData
  263. },
  264. pageType() {
  265. return this.$store.state.monthlyReportEdit.pageType
  266. },
  267. tabsActive() {
  268. return this.$store.state.monthlyReportEdit.tabsActive
  269. },
  270. pageDate() {
  271. return this.$store.state.monthlyReportEdit.pageDate
  272. },
  273. subReportName() {
  274. return this.$store.state.monthlyReportEdit.subReportName
  275. },
  276. editKeys() {
  277. return this.$store.state.monthlyReportEdit.editKeys
  278. }
  279. },
  280. mounted() {
  281. this.$nextTick(() => {
  282. this.setExpandRowKeys()
  283. })
  284. setTimeout(() => {
  285. if (!this.analyticFeedback) {
  286. this.setAnalyticFeedback()
  287. }
  288. }, 3000)
  289. },
  290. methods: {
  291. isEdit() {},
  292. setMinWidth(item) {
  293. let width = 100
  294. if (item.name === '操作') {
  295. if (item.defaultValue.length) {
  296. width = item.defaultValue.length * 50
  297. }
  298. if (this.isExpand) {
  299. width = 90
  300. }
  301. }
  302. return `${width}px`
  303. },
  304. isFixed(item, index, columns) {
  305. if (item.name === '操作') return 'right'
  306. return false
  307. },
  308. editLine(row, index) {
  309. // console.log(this.pageDate.status, this.domKey, this.editKeys)
  310. console.log(typeof this.pageDate.status)
  311. if (this.pageDate.status < 20) {
  312. this.$store.commit('monthlyReportEdit/ADD_EDIT_KEYS', this.domKey)
  313. }
  314. this.$forceUpdate()
  315. },
  316. btnFun(btnItem, scope) {
  317. this.$store.commit('monthlyReportEdit/INIT_EDIT_KEYS')
  318. if (btnItem.value === '删除') {
  319. this.tableData.splice(scope.$index, 1)
  320. }
  321. if (btnItem.value === '标记') {
  322. this.$refs.markingIssues.modalShow = true
  323. this.$nextTick(() => {
  324. this.$refs.markingIssues.openModal({
  325. title: '标记为重点问题',
  326. scope,
  327. columns: this.columns
  328. })
  329. })
  330. }
  331. if (btnItem.value === '分析反馈') {
  332. console.log(293, btnItem, scope)
  333. this.$refs.Analysis.open(scope.row.analyticFeedback, scope.$index)
  334. }
  335. },
  336. // 分析反馈问题更新
  337. upDataAnalysis({ rowIndex, analyticFeedback }) {
  338. if (this.pageType.search(/edit/) < 0) {
  339. console.log(rowIndex, analyticFeedback)
  340. this.tableData[rowIndex].analyticFeedback = _.cloneDeep(
  341. analyticFeedback
  342. )
  343. this.setAnalyticFeedback()
  344. }
  345. },
  346. addTableData() {
  347. const item = {
  348. rowKey: uuid10()
  349. }
  350. this.columns.forEach((elm) => {
  351. item[elm.headerKey] = ''
  352. })
  353. this.tableData.push(item)
  354. this.$nextTick(() => {
  355. this.$store.commit('monthlyReportEdit/GET_ALL_OFFSETTOP')
  356. })
  357. this.editLine()
  358. },
  359. cascaderChange(value, headerKey, row) {
  360. console.log(value, headerKey, row)
  361. },
  362. // 添加插入
  363. setColumns(columns) {
  364. let newColumns = _.cloneDeep(columns)
  365. if (this.isExpand) {
  366. newColumns = [
  367. {
  368. dataType: 'Single',
  369. defaultValue: null,
  370. displayType: 'Cascader',
  371. name: '',
  372. align: 'left',
  373. type: 'expand',
  374. selectEnum: null,
  375. selectType: null,
  376. headerKey: uuid10(6)
  377. },
  378. ...newColumns
  379. ]
  380. newColumns[1].align = 'left'
  381. }
  382. newColumns.forEach((elm) => {
  383. if (!elm.align) {
  384. elm.align = 'center'
  385. }
  386. })
  387. // if (this.pageDate.status > 10 && this.tabsActive.indexOf('本月重点问题') < 0) {
  388. // 非编辑状态,并且不是·本月重点问题·,删除操作按钮
  389. if (this.pageDate && this.pageDate.status > 10 && !this.isExpand) {
  390. newColumns.splice(newColumns.length - 1, 1)
  391. }
  392. return newColumns
  393. },
  394. arraySpanMethod({ row, column, rowIndex, columnIndex }) {
  395. if (
  396. columnIndex === 0 &&
  397. this.tabsActive.indexOf('本月重点问题') > -1 &&
  398. this.pageType.search(/edit/) < 0
  399. ) {
  400. return [1, 2]
  401. } else if (columnIndex === 1) {
  402. return [0, 0]
  403. }
  404. },
  405. // 查看页面数据分析
  406. setAnalyticFeedback() {
  407. if (
  408. // this.pageType.search(/edit/) < 0 &&
  409. // this.pageDate.status > 10 &&
  410. // this.tabsActive.indexOf('本月重点问题') > -1
  411. this.isExpand
  412. ) {
  413. const tabPageData = reportDataBack(_.cloneDeep(this.tabPageData))
  414. let obj = null
  415. const run = (arr) => {
  416. arr.forEach((elm) => {
  417. if (elm.content.length) {
  418. elm.content.forEach((item) => {
  419. if (item.domKey === this.domKey) {
  420. console.log(elm)
  421. obj = _.cloneDeep(elm)
  422. }
  423. })
  424. }
  425. })
  426. }
  427. run(tabPageData.children)
  428. const params = {
  429. reportId: this.$route.query.reportId,
  430. subReportName: this.subReportName,
  431. reportCatalog: obj
  432. }
  433. if (this.$route.query.pageType === 'readAll') {
  434. params.subReportName = `${obj.title}`
  435. }
  436. // console.log(params)
  437. // 提交数据
  438. if (obj && obj.content[0].tableRows.length) {
  439. updateAnalyticFeedback(params).then((res) => {
  440. if (res.code === 200) {
  441. if (res.data.search(/yellow/) > -1) {
  442. res.data.replace(/yellow/, '#F0B044')
  443. }
  444. this.analyticFeedback = res.data
  445. }
  446. })
  447. }
  448. }
  449. },
  450. /**
  451. * 操作按钮是否显示隐藏
  452. * 1、首先判断 页面 为编辑页面时 展示所有按钮
  453. * 2、判读分析反馈是否已经提交,已经提交的话,不展示按钮
  454. * 3、再判断当前表格是否有责任人
  455. * 有责任人
  456. * 判断当前用户是否存在负责人中,存在展示按钮,不存在则不展示
  457. * 无责任人不展示按钮
  458. * @param row 表格行数据
  459. * @returns {boolean}
  460. */
  461. isShowButton(row) {
  462. if (this.pageType.search(/edit/) > -1 && this.pageDate && this.pageDate.status < 20) {
  463. return true
  464. }
  465. if (row.analyticFeedback && row.analyticFeedback.isCommitted) {
  466. return false
  467. }
  468. // 默认所有情况都展示
  469. if (this.pageType) {
  470. return true
  471. }
  472. if (this.pageDate.createBy === this.username) return true
  473. for (let i = 0; i < this.columns.length; i++) {
  474. const elm = this.columns[i]
  475. if (elm.name === '责任人') {
  476. if (!row[elm.headrKey]) return false
  477. return row[elm.headrKey].indexOf(this.username) > -1
  478. }
  479. }
  480. return false
  481. },
  482. setExpandRowKeys() {
  483. if (this.isExpand && this.tableData && this.tableData.length) {
  484. this.tableData.forEach(elm => {
  485. if (elm.analyticFeedback && elm.analyticFeedback.hasOwnProperty('isCommitted') && elm.analyticFeedback.isCommitted && this.expandRowKeys.indexOf(elm.rowKey) < 0) {
  486. this.expandRowKeys.push(elm.rowKey)
  487. }
  488. })
  489. }
  490. }
  491. }
  492. }
  493. </script>
  494. <style scoped lang="less">
  495. .edit-wrapper {
  496. .edit-cell {
  497. min-height: 23px;
  498. width: 100%;
  499. }
  500. }
  501. .plus-table-data {
  502. margin-top: 2px;
  503. }
  504. /deep/ .el-table__expand-column {
  505. border-right: 0;
  506. .el-icon-arrow-right:before {
  507. // 这是展开图标
  508. border: 1px solid rgba(0, 0, 0, 0.14901960784313725);
  509. }
  510. }
  511. /deep/ .el-table__expand-column .cell {
  512. .el-table__expand-icon {
  513. .el-icon-arrow-right:before {
  514. // 这是展开图标
  515. content: '\e6d9';
  516. //content: "\e6d8";
  517. }
  518. }
  519. .el-table__expand-icon--expanded {
  520. // 这是点击后的旋转角度
  521. //transform: rotate(180deg);
  522. transform: rotate(0deg);
  523. .el-icon-arrow-right:before {
  524. // 这是展开图标
  525. //content: "\e6d9";
  526. content: '\e6d8' !important;
  527. }
  528. }
  529. }
  530. /deep/.el-button{
  531. font-weight: 400;
  532. }
  533. /deep/.red {
  534. color: red;
  535. }
  536. /deep/.green {
  537. color: green;
  538. }
  539. /deep/.yellow {
  540. color: yellow;
  541. }
  542. </style>