iam-audit-user-child-table.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. <template>
  2. <div :class="[$style.wrapper, $style.sdFormforxmchild]">
  3. <div v-if="captionvisiable" :class="[$style.caption]">
  4. {{ label }}
  5. <div v-if="!readOnly" :class="$style.header">
  6. <a-button v-if="addbuttonvisiable" type="link" @click="add">
  7. <a-icon type="plus-circle" :theme="'filled'" />
  8. 添加
  9. </a-button>
  10. <a-button
  11. type="link"
  12. :disabled="selectedRowKeys.length === 0"
  13. @click="remove(selectedRowKeys)"
  14. >
  15. <a-icon type="minus-circle" :theme="'filled'" />
  16. 删除
  17. </a-button>
  18. <a-button v-if="savebuttonvisiable" type="link" @click="save">
  19. <a-icon type="check-circle" :theme="'filled'" />
  20. 保存
  21. </a-button>
  22. </div>
  23. </div>
  24. <sd-table
  25. v-if="sdtableflag"
  26. ref="sdtable"
  27. size="middle"
  28. :columns="_columns"
  29. :width="width"
  30. :data-source="value"
  31. :row-key="(record, index) => index"
  32. :pagination="false"
  33. :row-selection="
  34. readOnly
  35. ? null
  36. : {
  37. getCheckboxProps(record) {
  38. return {
  39. props: { disabled: !showSelection(record) },
  40. }
  41. },
  42. selectedRowKeys: selectedRowKeys,
  43. onChange: onSelectChange,
  44. }
  45. "
  46. :custom-row="
  47. (record, index) => {
  48. return {
  49. on: {
  50. click: () => {
  51. edit(index)
  52. },
  53. },
  54. }
  55. }
  56. "
  57. @update:data-source="fnupdate"
  58. >
  59. <template
  60. v-for="(field, index) in fields"
  61. :slot="'sd_' + field.name"
  62. slot-scope="text, record, index"
  63. >
  64. <slot v-bind="{ field, text, record, value, index }" :name="field.name + '_xm'">
  65. <sdForm :ref="field.name + '_' + index" :init-values="[field]" :read-only="readOnly">
  66. <template v-if="editIndex.includes(index)" v-slot="scope">
  67. <slot v-bind="{ field, text, record, value, index }" :name="field.name">
  68. <sd-form-item
  69. v-if="field.dataType === 'date'"
  70. :hidden="field.dataType === 'id'"
  71. :name="field.name"
  72. :label="null"
  73. :input-props="{
  74. defaultValue:
  75. value[index][field.name] !== undefined
  76. ? moment(Number(value[index][field.name]))
  77. : value[index][field.name],
  78. nodename: field.name + '_' + index,
  79. }"
  80. @change="savetableh(index, field)"
  81. />
  82. <sd-attachment
  83. v-else-if="field.dataType === 'attachment'"
  84. :group-id="JSON.parse(value[index][field.name]).value"
  85. :read-only="readOnly"
  86. />
  87. <span
  88. v-else-if="
  89. dzcl &&
  90. (field.name === 'userType' || field.name === 'userId') &&
  91. (value[index]['userType'] === '04' || value[index]['userType'] === '05') &&
  92. !readOnly
  93. "
  94. >
  95. <span v-if="field.name === 'userType' || field.name === 'contactsRole'">
  96. <span
  97. v-if="value[index]['userType'] === '04' || value[index]['userType'] === '05'"
  98. >
  99. {{
  100. usertypeselectList.find((i) => i.value === value[index]['userType'])?.label
  101. }}</span
  102. >
  103. </span>
  104. <span v-else>{{ getDisplayVaule(field, text) }}</span>
  105. </span>
  106. <sd-form-item
  107. v-else-if="dzcl && (field.name === 'userType' || field.name === 'contactsRole')"
  108. :hidden="field.dataType === 'id'"
  109. :name="field.name"
  110. :label="null"
  111. >
  112. <template slot="read">
  113. <span
  114. v-if="value[index]['userType'] === '04' || value[index]['userType'] === '05'"
  115. >
  116. {{
  117. usertypeselectList.find((i) => i.value === value[index]['userType'])?.label
  118. }}</span
  119. >
  120. <span v-else>{{ getDisplayVaule(field, text) }}</span>
  121. </template>
  122. <a-select v-model="value[index][field.name]" @change="savetableh(index, field)">
  123. <a-select-option
  124. v-for="(key, index) in selectitem"
  125. :key="index"
  126. :value="key.value"
  127. >
  128. {{ key.label }}
  129. </a-select-option>
  130. </a-select>
  131. </sd-form-item>
  132. <sd-form-item
  133. v-else
  134. :hidden="field.dataType === 'id'"
  135. :name="field.name"
  136. :label="null"
  137. :input-props="{
  138. defaultValue:
  139. field.dataType === 'selectperson' && value[index][field.name] !== undefined
  140. ? JSON.parse(value[index][field.name])
  141. : !value[index][field.name]
  142. ? ''
  143. : value[index][field.name],
  144. }"
  145. @blur="savetableh(index, field)"
  146. @change="savetableh(index, field)"
  147. />
  148. </slot>
  149. </template>
  150. <template v-else v-slot="scope">
  151. <slot v-bind="{ field, text, record, value, index }" :name="field.name">
  152. <!-- 开始以及结束时间 -->
  153. <span v-if="field.dataType === 'date'">
  154. {{
  155. value[index][field.name] !== undefined
  156. ? moment(Number(value[index][field.name])).format('YYYY-MM-DD')
  157. : value[index][field.name]
  158. }}
  159. </span>
  160. <!-- 姓名及角色只读 -->
  161. <span
  162. v-else-if="
  163. dzcl &&
  164. (field.name === 'userType' || field.name === 'userId') &&
  165. (value[index]['userType'] === '04' || value[index]['userType'] === '05') &&
  166. !readOnly
  167. "
  168. >
  169. <span v-if="field.name === 'userType'">
  170. <span
  171. v-if="value[index]['userType'] === '04' || value[index]['userType'] === '05'"
  172. >
  173. {{
  174. usertypeselectList.find((i) => i.value === value[index]['userType'])?.label
  175. }}</span
  176. ><span v-else></span
  177. ></span>
  178. <span>{{ getDisplayVaule(field, text) }}</span>
  179. </span>
  180. <!-- 角色 -->
  181. <span v-else-if="dzcl && field.name === 'userType'">
  182. <span
  183. v-if="value[index]['userType'] === '04' || value[index]['userType'] === '05'"
  184. >
  185. {{
  186. usertypeselectList.find((i) => i.value === value[index]['userType'])?.label
  187. }}</span
  188. >
  189. <span v-else>{{ getDisplayVaule(field, text) }}</span>
  190. </span>
  191. <span v-else-if="dzcl && field.name === 'contactsRole'">
  192. <span>{{ getDisplayVaule(field, text) }}</span>
  193. </span>
  194. <!-- 姓名及其他字段 -->
  195. <span v-else :hidden="field.dataType === 'id'">
  196. {{
  197. field.dataType === 'selectperson' && value[index][field.name] !== undefined
  198. ? JSON.parse(value[index][field.name])[0].name
  199. : value[index][field.name]
  200. }}
  201. </span>
  202. </slot>
  203. </template>
  204. </sdForm>
  205. </slot>
  206. </template>
  207. </sd-table>
  208. <a-modal
  209. v-model="visible"
  210. :title="label || '详情'"
  211. destroy-on-close
  212. v-bind="{ width: 800 }"
  213. :mask-closable="false"
  214. :footer="readOnly ? null : undefined"
  215. @ok="save"
  216. @cancel="attkeys[action] = Math.random()"
  217. >
  218. <sdForm ref="form" :init-values="editRecord" :read-only="readOnly">
  219. <template v-slot="scope">
  220. <!--
  221. @slot 详情表单内容,8.0.4及以后版本支持
  222. @binding {object} model 整个表单的数据,可用于 v-model 绑定
  223. @binding {object} fields 后台返回的字段定义
  224. -->
  225. <slot v-bind="scope" name="form">
  226. <sd-form-item
  227. v-for="field in fields"
  228. :key="field.name"
  229. :hidden="field.dataType === 'id'"
  230. :name="field.name"
  231. />
  232. </slot>
  233. </template>
  234. </sdForm>
  235. </a-modal>
  236. <div :class="$style.loading">
  237. <a-spin v-if="!sdtableflag" />
  238. </div>
  239. </div>
  240. </template>
  241. <script>
  242. import { Modal } from 'ant-design-vue'
  243. import { getComponentSpec } from '@/common/components/sd-form'
  244. import moment from 'moment'
  245. import components from './_import-components/xm-child-table-import'
  246. // Vue.use(DatePicker)
  247. // Vue.use(TimePicker)
  248. /**
  249. * 主子表、动态表格字段
  250. * @displayName XmChildTable 主子表
  251. */
  252. export default {
  253. name: 'IamAuditUserChildTable',
  254. components: {
  255. ...components,
  256. sdForm: () => import('@/common/components/sd-form'),
  257. },
  258. model: {
  259. prop: 'value',
  260. event: 'change',
  261. },
  262. props: {
  263. /**
  264. * 字表的值,{key:value}的格式
  265. */
  266. value: {
  267. type: Array,
  268. default: () => [],
  269. },
  270. /**
  271. * 字表的字段属性
  272. */
  273. fields: {
  274. type: Array,
  275. default: () => [],
  276. },
  277. /**
  278. * 是否只读
  279. */
  280. readOnly: {
  281. type: Boolean,
  282. default: false,
  283. },
  284. /**
  285. * 标签名
  286. */
  287. label: {
  288. type: String,
  289. default: '',
  290. },
  291. /**
  292. * 自定义子表列属性,如[{dataIndex:'shuxingmingzi15',width:'120px'}],8.0.4及以后版本支持
  293. */
  294. columns: {
  295. type: Array,
  296. default: () => [],
  297. },
  298. /**
  299. * 某行是否可选
  300. * @since 8.0.11
  301. */
  302. showSelection: {
  303. type: Function,
  304. default: () => true,
  305. },
  306. width: {
  307. type: Number,
  308. default: 100,
  309. },
  310. datachange: {
  311. type: Function,
  312. default: null,
  313. },
  314. dzcl: {
  315. type: Boolean,
  316. default: false,
  317. },
  318. addfun: {
  319. type: Function,
  320. default: null,
  321. },
  322. captionvisiable: {
  323. type: Boolean,
  324. default: true,
  325. },
  326. addbuttonvisiable: {
  327. type: Boolean,
  328. default: true,
  329. },
  330. savebuttonvisiable: {
  331. type: Boolean,
  332. default: false,
  333. },
  334. fncheckdelete: {
  335. type: Function,
  336. default: null,
  337. },
  338. // 是否批量提交
  339. patchSave: {
  340. type: Boolean,
  341. default: false,
  342. },
  343. },
  344. data() {
  345. return {
  346. editIndex: [],
  347. selectedRowKeys: [],
  348. visible: false,
  349. editRecord: this.fields, // 待修改或编辑的记录
  350. attkeys: {}, // 附件组件的key,行编辑了就修改对应的附件key,强制更新附件列表
  351. savevisible: true,
  352. adddataxm: {},
  353. selectitem: [],
  354. sjjs: this.getsjsl(),
  355. ndata: [],
  356. newfield: [],
  357. validflag: true,
  358. sdtableflag: true,
  359. localLoading: false,
  360. usertypeselectList: [],
  361. }
  362. },
  363. computed: {
  364. _columns() {
  365. const fields = JSON.parse(JSON.stringify(this.fields))
  366. return fields
  367. .filter((item) => item.dataType !== 'id')
  368. .map((item) => {
  369. const t = {
  370. dataIndex: item.name,
  371. key: item.name,
  372. title: item.caption,
  373. scopedSlots: { customRender: 'sd_' + item.name },
  374. width: item.width || '40',
  375. }
  376. const column = this.columns.find((c) => c.dataIndex === item.name)
  377. if (column) Object.assign(t, column)
  378. return t
  379. })
  380. .filter((item) => item.sdHidden !== true)
  381. },
  382. },
  383. mounted() {
  384. if (this.datachange) {
  385. this.datachange()
  386. }
  387. if (this.dzcl) {
  388. this.fields.forEach((item) => {
  389. if (item.name === 'userType') {
  390. this.usertypeselectList = [...item.attr.selectListItem]
  391. let index = item.attr.selectListItem.findIndex((item) => item.value === '04')
  392. if (index > -1) item.attr.selectListItem.splice(index, 1)
  393. index = item.attr.selectListItem.findIndex((item) => item.value === '05')
  394. if (index > -1) item.attr.selectListItem.splice(index, 1)
  395. this.selectitem = item.attr.selectListItem
  396. } else if (item.name === 'contactsRole') {
  397. const index = item.attr.selectListItem.findIndex((item) => item.label === '任务创建人')
  398. // item.attr.selectListItem.splice(index, 1)
  399. this.selectitem = item.attr.selectListItem
  400. }
  401. })
  402. }
  403. },
  404. destroyed() {
  405. const data = this.value || [] // 兼容初始值是null的情况
  406. const index = data.findIndex((item) => item.editable === true)
  407. if (index !== -1) {
  408. this.optbuttonClick('delete', [], index)
  409. }
  410. },
  411. methods: {
  412. fnupdate(data) {
  413. this.sdtableflag = false
  414. this.value = data
  415. setTimeout(() => {
  416. this.sdtableflag = true
  417. }, 100)
  418. this.$emit('change', this.value)
  419. },
  420. moment,
  421. getsjsl() {
  422. let index
  423. this.fields.forEach((f) => {
  424. if (f.sdHidden === true) {
  425. index = index + 1
  426. }
  427. })
  428. return index
  429. },
  430. fngetfield(field, value) {
  431. const editRecord = [field]
  432. editRecord.forEach((item) => {
  433. // 把值放到字段信息fields里
  434. item.value = value[item.name]
  435. if (item.attr.controlType === 'DictType') {
  436. if (item.attr.selectListItem.find((t) => t.value === item.value) !== undefined) {
  437. item.attr.displayValue = item.attr.selectListItem.find(
  438. (t) => t.value === item.value
  439. ).label
  440. }
  441. }
  442. })
  443. return editRecord
  444. },
  445. getDisplayVaule(field, text) {
  446. if (getComponentSpec(field).getDisplayValue) {
  447. if (typeof text !== 'undefined' && text !== null) {
  448. const value = getComponentSpec(field).parseBackendValue?.(text) || text
  449. return getComponentSpec(field).getDisplayValue(value)
  450. } else {
  451. return ''
  452. }
  453. }
  454. return text
  455. },
  456. changolddata() {
  457. const h = new Promise((resolve) => {
  458. if (this.value !== null) {
  459. if (this.value.length > 0) {
  460. this.value.forEach((d, index) => {
  461. if (d.mainId === 0) {
  462. // 获取该行数据
  463. d.mainId = Math.random()
  464. }
  465. this.savetableh(index, null).then((r) => {
  466. if (index === this.value.length - 1) {
  467. resolve(true)
  468. }
  469. })
  470. })
  471. } else {
  472. resolve(false)
  473. }
  474. } else {
  475. resolve(true)
  476. }
  477. })
  478. return h
  479. },
  480. savetableh(i, field) {
  481. // 保存最新增的行
  482. const data = this.value || [] // 兼容初始值是null的情况
  483. const value = data[i]
  484. let fields = this.fields
  485. if (field !== null) {
  486. fields = [field]
  487. }
  488. const savef = new Promise((resolve) => {
  489. fields.forEach((item, index) => {
  490. const refname = item.name
  491. const dataType = item.dataType
  492. if (this.$refs[refname + '_' + i]) {
  493. if (dataType === 'attachment') {
  494. } else if (
  495. typeof this.$refs[refname + '_' + i][0].model[refname] === 'object' &&
  496. dataType !== 'date'
  497. ) {
  498. if (this.$refs[refname + '_' + i][0].model[refname] !== undefined) {
  499. value[item.name] = JSON.stringify(this.$refs[refname + '_' + i][0].model[refname])
  500. }
  501. } else if (dataType === 'date') {
  502. if (this.$refs[refname + '_' + i][0].model[refname] !== undefined) {
  503. value[item.name] = this.$refs[refname + '_' + i][0].getFieldValue(refname).valueOf()
  504. }
  505. } else {
  506. if (this.dzcl && refname === 'userType') {
  507. if (value[item.name] !== '04' && value[item.name] !== '05') {
  508. this.$refs[refname + '_' + i][0].setFieldValue(refname, value[item.name])
  509. }
  510. } else {
  511. if (this.$refs[refname + '_' + i][0].model[refname] !== undefined) {
  512. value[item.name] = this.$refs[refname + '_' + i][0].getFieldValue(refname)
  513. }
  514. }
  515. }
  516. }
  517. })
  518. // 一行数据已存储
  519. data[i] = value
  520. this.value = data
  521. if (!this.patchSave) {
  522. this.$emit('saved', data)
  523. }
  524. // this.$emit('change', data)
  525. resolve(true)
  526. // 打开结束时间
  527. if (field && field.name === 'joinStartTime') {
  528. document
  529. .querySelector("[nodename='joinEndTime_" + i + "'] .ant-calendar-picker-input")
  530. .click()
  531. }
  532. })
  533. return savef
  534. },
  535. add() {
  536. this.action = 'add'
  537. this.editIndex.push(this.value.length)
  538. const data = this.value || [] // 兼容初始值是null的情况
  539. // 判断当前动态表格中是否有已打开编辑的行,如果有则需要保存后才能再新增
  540. // if (data.length > 0) {
  541. // 有数据则再新增时需要先保存前面的数据
  542. this.changolddata().then((res) => {
  543. this.editRecord = this.fields
  544. const attachobj = this.fields.find((obj) => obj.dataType === 'attachment')
  545. let d1 = { mainId: 0 }
  546. if (attachobj !== undefined) {
  547. d1[attachobj.name] =
  548. '{"value":"' + Math.round(Math.random() * 100000000000000000).toString() + '"}'
  549. }
  550. this.editRecord.mainId = 0
  551. if (this.addfun) {
  552. d1 = this.addfun(d1)
  553. data.push(d1)
  554. this.adddataxm = d1
  555. if (!this.patchSave) {
  556. this.$emit('change', data)
  557. }
  558. } else {
  559. data.push(d1)
  560. this.adddataxm = d1
  561. if (!this.patchSave) {
  562. this.$emit('change', data)
  563. }
  564. }
  565. })
  566. },
  567. edit(index) {
  568. if (this.readOnly) return false
  569. this.editIndex.push(index)
  570. },
  571. setvalid() {
  572. this.value.forEach((h, index) => {
  573. // if (this.validflag) {
  574. const value = {}
  575. this.fields.forEach((item, fi) => {
  576. const refname = item.name
  577. const dataType = item.dataType
  578. if (this.$refs[refname + '_' + index]) {
  579. this.$refs[refname + '_' + index][0].validateFields().then((res) => {})
  580. }
  581. })
  582. })
  583. },
  584. valid() {
  585. this.validflag = true
  586. const data = this.value || [] // 兼容初始值是null的情况
  587. // 特殊处理userType
  588. if (this.dzcl) {
  589. const usertypeobj = this.fields.find((item) => item.name === 'userType')
  590. if (usertypeobj !== undefined) {
  591. data.forEach((h, hi) => {
  592. if (
  593. h.userType !== '04' &&
  594. h.userType !== '05' &&
  595. h.userType !== '' &&
  596. h.userType !== undefined
  597. ) {
  598. if (this.$refs['userType_' + hi]) {
  599. this.$refs['userType_' + hi][0].setFieldValue('userType', h.userType)
  600. }
  601. }
  602. })
  603. }
  604. }
  605. const valid = new Promise((resolve) => {
  606. // 轮询所有行数据
  607. if (data.length === 0) {
  608. resolve(true)
  609. } else {
  610. data.forEach((h, index) => {
  611. // if (this.validflag) {
  612. const value = {}
  613. this.fields.forEach((item, fi) => {
  614. const refname = item.name
  615. const dataType = item.dataType
  616. if (this.$refs[refname + '_' + index]) {
  617. this.$refs[refname + '_' + index][0]
  618. .validateFields()
  619. .then((res) => {
  620. if (!res) {
  621. this.validflag = false
  622. } else {
  623. if (index === data.length - 1 && fi === this.fields.length - 1) {
  624. setTimeout(() => {
  625. if (this.validflag) {
  626. resolve(true)
  627. } else {
  628. resolve(false)
  629. }
  630. }, 1000)
  631. }
  632. }
  633. })
  634. .catch(() => {
  635. this.validflag = false
  636. })
  637. } else {
  638. if (index === data.length - 1 && fi === this.fields.length - 1) {
  639. setTimeout(() => {
  640. if (this.validflag) {
  641. resolve(true)
  642. } else {
  643. resolve(false)
  644. }
  645. }, 1000)
  646. }
  647. }
  648. })
  649. })
  650. }
  651. })
  652. return valid
  653. },
  654. save() {
  655. if (this.readOnly || !this.visible) {
  656. // 判断visable为false时,modal没有是为了防止快速重复点击确定
  657. this.visible = false
  658. }
  659. this.changolddata().then((res) => {})
  660. this.editIndex = []
  661. const save = new Promise((resolve, reject) => {
  662. const data = this.value || [] // 兼容初始值是null的情况
  663. // 轮询所有行数据
  664. if (data.length === 0) {
  665. resolve(false)
  666. } else {
  667. let canSubmit = true
  668. data.forEach((h, index) => {
  669. const value = {}
  670. this.fields.forEach((item, fi) => {
  671. const refname = item.name
  672. const dataType = item.dataType
  673. if (this.$refs[refname + '_' + index]) {
  674. return this.$refs[refname + '_' + index][0]
  675. .validateFields()
  676. .then(() => {
  677. if (index === data.length - 1 && fi === this.fields.length - 1) {
  678. setTimeout(() => {
  679. if (canSubmit) {
  680. resolve(true)
  681. this.$emit('change', this.value)
  682. } else {
  683. resolve(false)
  684. }
  685. }, 0)
  686. }
  687. })
  688. .catch(() => {
  689. canSubmit = false
  690. })
  691. }
  692. })
  693. if (index === data.length - 1) {
  694. // resolve(true)
  695. if (canSubmit) {
  696. // this.$emit('change', this.value)
  697. // resolve(true)
  698. }
  699. }
  700. })
  701. }
  702. })
  703. return save
  704. },
  705. onSelectChange(selectedRowKeys) {
  706. if (selectedRowKeys.length > 1 || selectedRowKeys.findIndex((i) => i === 0) > -1) {
  707. if (this.selectedRowKeys.length - selectedRowKeys.length > 1) {
  708. // 去掉全选
  709. selectedRowKeys = []
  710. } else if (selectedRowKeys.findIndex((i) => i === 0) > -1) {
  711. // 全选
  712. for (var s = 0; s < this.value.length; s++) {
  713. selectedRowKeys.push(s)
  714. }
  715. selectedRowKeys = this.removeDuplicate(selectedRowKeys)
  716. }
  717. }
  718. this.selectedRowKeys = selectedRowKeys
  719. },
  720. removeDuplicate(arr) {
  721. let len = arr.length
  722. for (let i = 0; i < len; i++) {
  723. for (let j = i + 1; j < len; j++) {
  724. if (arr[i] === arr[j]) {
  725. arr.splice(j, 1)
  726. len-- // 减少循环次数提高性能
  727. j-- // 保证j的值自加后不变
  728. }
  729. }
  730. }
  731. return arr
  732. },
  733. remove(keys) {
  734. const removeKeys = keys.sort((a, b) => b - a)
  735. let xdelet = []
  736. if (this.showSelection !== null) {
  737. removeKeys.forEach((k, i) => {
  738. if (!this.showSelection(this.value[k])) {
  739. xdelet.push(i)
  740. }
  741. })
  742. }
  743. xdelet = xdelet.sort((a, b) => b - a)
  744. xdelet.forEach((x) => {
  745. removeKeys.splice(x, 1)
  746. })
  747. // 用的序号作key,从大往小删,防止串了
  748. if (this.fncheckdelete !== null) {
  749. if (this.fncheckdelete(this.value, removeKeys)) {
  750. const v = this.value
  751. this.sdtableflag = false
  752. removeKeys.forEach((key) => {
  753. this.value.splice(key, 1)
  754. })
  755. this.selectedRowKeys = []
  756. this.$emit('change', this.value)
  757. setTimeout(() => {
  758. this.sdtableflag = true
  759. }, 100)
  760. // 增加发布删除后事件
  761. this.$emit('deleted')
  762. } else {
  763. Modal.warning({
  764. title: '提示',
  765. content: '选择的子表数据不允许删除,请检查!',
  766. })
  767. return false
  768. }
  769. } else {
  770. this.sdtableflag = false
  771. removeKeys.forEach((key) => {
  772. this.value.splice(key, 1)
  773. })
  774. this.selectedRowKeys = []
  775. // 增加发布删除后事件
  776. this.$emit('deleted')
  777. setTimeout(() => {
  778. this.sdtableflag = true
  779. }, 100)
  780. this.$emit('change', this.value)
  781. }
  782. },
  783. optbuttonClick(val, record, i) {
  784. let value = {}
  785. const data = this.value || [] // 兼容初始值是null的情况
  786. const adddata = this.adddataxm || {}
  787. let index = 0
  788. const qqcs = this._columns.length - 2
  789. const editrow = data.find((c) => c.editable === true)
  790. switch (val) {
  791. case 'save':
  792. value = data[i]
  793. this.fields.forEach((item) => {
  794. const refname = item.name
  795. const dataType = item.dataType
  796. if (this.$refs[refname]) {
  797. this.$refs[refname][0].validateFields().then(() => {
  798. this.$refs[refname][0].getBackendValues().forEach((item) => {
  799. if (item.name === refname) {
  800. if (dataType === 'attachment') {
  801. if (adddata[refname] !== undefined) {
  802. var obj = JSON.parse(adddata[refname])
  803. value[item.name] = '{"value":"' + obj.value + '"}'
  804. } else {
  805. value[item.name] = item.value
  806. }
  807. } else {
  808. value[item.name] = item.value
  809. }
  810. }
  811. })
  812. index = index + 1
  813. if (index === qqcs) {
  814. this.attkeys[0] = Math.random()
  815. value.editable = false
  816. data.splice(i, 1)
  817. data.splice(i, 0, value)
  818. this.$emit('change', data)
  819. this.value = data
  820. }
  821. })
  822. }
  823. })
  824. this.adddataxm = {}
  825. // event.stopPropagation()
  826. break
  827. case 'delete':
  828. if (this.fncheckdelete !== null) {
  829. if (this.fncheckdelete(data, i)) {
  830. data.splice(i, 1)
  831. this.$emit('change', data)
  832. this.adddataxm = {}
  833. } else {
  834. Modal.warning({
  835. title: '提示',
  836. content: '选择的子表数据不允许删除,请检查!',
  837. })
  838. return false
  839. }
  840. } else {
  841. data.splice(i, 1)
  842. this.$emit('change', data)
  843. this.adddataxm = {}
  844. }
  845. this.value = data
  846. break
  847. case 'edit':
  848. // 判断当前动态表格中是否有已打开编辑的行,如果有则需要保存后才能再新增
  849. if (editrow !== undefined) {
  850. Modal.warning({
  851. title: '提示',
  852. content: '请先保存动态表格中内容!',
  853. })
  854. return false
  855. }
  856. if (data[i].editable === undefined || data[i].editable === false) {
  857. data[i].editable = true
  858. const value = data[i]
  859. data.splice(i, 1)
  860. data.splice(i, 0, value)
  861. this.$emit('change', data)
  862. this.editRecord = JSON.parse(JSON.stringify(this.fields))
  863. this.editRecord[0].editable = true
  864. this.editRecord.forEach((item) => {
  865. // 把值放到字段信息fields里
  866. item.value = value[item.name]
  867. if (item.attr.controlType === 'DictType') {
  868. if (item.attr.selectListItem.find((t) => t.value === item.value) !== undefined) {
  869. item.attr.displayValue = item.attr.selectListItem.find(
  870. (t) => t.value === item.value
  871. ).label
  872. }
  873. }
  874. })
  875. this.adddataxm = value
  876. }
  877. break
  878. }
  879. },
  880. fnsettablesize() {
  881. const obj = this.$refs.sdtable
  882. obj.columnInfos.forEach((col) => {
  883. col.width = col.defaultWidth
  884. col.show = col.defaultShow
  885. })
  886. },
  887. },
  888. }
  889. </script>
  890. <style module lang="scss">
  891. @use '@/common/design' as *;
  892. @use "@/common/components/sd-web-print.scss" as print;
  893. .header {
  894. position: absolute;
  895. top: 0;
  896. right: 0;
  897. :global .ant-input-search {
  898. width: 200px;
  899. }
  900. :global .ant-btn {
  901. margin: 5px;
  902. }
  903. }
  904. .caption {
  905. position: relative;
  906. width: 100%;
  907. min-height: 40px;
  908. margin: 3px 0;
  909. text-align: center;
  910. }
  911. .wrapper {
  912. :global(.ant-table-tbody) {
  913. .clickable-cell {
  914. color: $primary-color;
  915. cursor: pointer;
  916. &:hover {
  917. color: $primary-5;
  918. }
  919. &:active {
  920. color: $primary-7;
  921. }
  922. }
  923. }
  924. }
  925. // 打印状态下 子表上选择列的按钮
  926. @include print.wrapper-for-printer {
  927. .wrapper {
  928. :global(.ant-table-thead .anticon) {
  929. display: none;
  930. }
  931. }
  932. }
  933. .operatecol {
  934. // display: flex;
  935. // flex-wrap: wrap;
  936. justify-content: flex-end;
  937. width: 100px;
  938. :global(.ant-btn-sm) {
  939. padding: 0 0;
  940. }
  941. :global(.menu_sd-table-header_common) {
  942. display: none;
  943. }
  944. }
  945. .sdFormforxmchild {
  946. :global(.ant-upload.ant-upload-drag p.ant-upload-drag-icon) {
  947. margin-bottom: 0;
  948. }
  949. :global(.ant-upload-text) {
  950. display: none !important;
  951. }
  952. :global(.ant-upload.ant-upload-drag .ant-upload) {
  953. padding: 0 0;
  954. }
  955. :global(.ant-form-item) {
  956. margin-bottom: 6px;
  957. }
  958. :global(.actionlist_sd-attachment_common > span) {
  959. overflow: hidden;
  960. text-overflow: ellipsis;
  961. white-space: nowrap;
  962. }
  963. :global(.actionlist_sd-attachment_common > span :hover) {
  964. white-space: normal;
  965. // overflow: auto;
  966. }
  967. :global(.ant-upload.ant-upload-drag) {
  968. text-align: left;
  969. background: none;
  970. border: none;
  971. }
  972. :global(.ant-upload.ant-upload-drag p.ant-upload-drag-icon .anticon) {
  973. font-size: 28px;
  974. }
  975. :global(.form_sd-form_common > .ant-form-item > .ant-form-item-control-wrapper) {
  976. width: 100%;
  977. }
  978. .loading {
  979. position: fixed;
  980. top: 310px;
  981. left: 50%;
  982. text-align: center;
  983. }
  984. :global(.ant-calendar-cell) {
  985. border: none !important;
  986. }
  987. }
  988. </style>