image.png
    image.png
    image.pngimage.png

    1. <template>
    2. <div class="approve-template-dynamic-form">
    3. <div class="approve-template-dynamic-form-model">
    4. <a-form-model ref="ruleForm" :model="form" :rules="rules">
    5. <a-spin :spinning="spinning" style="height: 70px;">
    6. <a-page-header style="border-bottom: 1px solid rgb(235, 237, 240)" title="审批信息"/>
    7. <div style="display:flex;margin-bottom:50px" v-if="isShowApprovalPerson">
    8. <div style="margin-left:50px; margin-top:15px; font-size:16px">审批人:</div>
    9. <div>
    10. <approval-man
    11. v-for="item in approveProcessesList"
    12. :key="item.id"
    13. :form="approveManageProcessPersonList"
    14. :mainProcess="item"
    15. :subProcess="item.childrenApproveProcesses"
    16. :approveStage="item.approveStage"
    17. :selectOption="userListOptions"
    18. />
    19. </div>
    20. </div>
    21. <!--展示项目、日期、时间等每项的组件-->
    22. <approve-template-dynamic-form-item
    23. ref="approveTemplateDynamicFormRef"
    24. :manageId="baseInfo.manageId"
    25. :extrasInfo="extrasInfo"
    26. :extrasInfoExt="extrasInfoExt"
    27. @changeExtrasInfo="changeExtrasInfo"
    28. @clearValidate="clearValidate"
    29. :form="form"
    30. :key="item.fieldGroupId"
    31. v-for="item in templateInfoList" // 传递每个字段的信息
    32. :infoItem="item"
    33. ></approve-template-dynamic-form-item>
    34. <div
    35. class="approval-detail-card-item-content-process-content"
    36. v-if="baseInfo.approveProcessDetailList"
    37. >
    38. <span style="display: block">处理流程</span>
    39. <ApprovalStageShow
    40. :approveProcessDetailList="baseInfo.approveProcessDetailList"
    41. />
    42. </div>
    43. </a-spin>
    44. </a-form-model>
    45. </div>
    46. <div class="approve-template-dynamic-form-bottom">
    47. <a-space>
    48. <a-button @click="resetFormValue" :disabled="spinning">重置</a-button>
    49. </a-space>
    50. <a-space v-if="onlyShowCommit">
    51. <a-button
    52. :disabled="spinning"
    53. type="primary"
    54. @click="saveOrCommitEvent(ApproveStatusEnum.COMMIT)"
    55. >提交</a-button
    56. >
    57. </a-space>
    58. <a-space v-else>
    59. <slot
    60. name="bottomAction"
    61. :handelSlotButtonEvent="handelSlotButtonEvent"
    62. >
    63. <a-space>
    64. <span>自动创建</span>
    65. <a-switch
    66. checked-children="开"
    67. un-checked-children="关"
    68. :disabled="true"
    69. :checked="isAutoCreate"
    70. @change="handleChangeAutoSwitch"
    71. />
    72. </a-space>
    73. <a-button @click="saveOrCommitEvent(ApproveStatusEnum.SAVE)"
    74. >保存</a-button
    75. >
    76. <a-button
    77. :disabled="spinning"
    78. type="primary"
    79. @click="saveOrCommitEvent(ApproveStatusEnum.COMMIT)"
    80. >提交</a-button
    81. >
    82. </slot>
    83. </a-space>
    84. </div>
    85. </div>
    86. </template>
    87. <script>
    88. import {
    89. ApproveStatusEnum,
    90. ApproveAutoCreateEnum,
    91. CustomPropertyIndex,
    92. ParamsTypeStringEnum
    93. } from './constant'
    94. import { getApproveTemplateDetailWithoutProcess } from '@/api/module-setting/approval'
    95. import { startApproval } from '@/api/approveManage'
    96. import { getUsersList } from '@/api/common'
    97. import { paramTypeColumn } from '@/common/global'
    98. import {
    99. validateInteger,
    100. validateFloat,
    101. validateRequired
    102. } from '@/common/inspectFunction'
    103. import { ApprovalManageListTypeEnum, OperationFlagEnum } from '@/common/global'
    104. import { isJSON } from '@/common/util'
    105. import { handleCustomExtraValidateRequired } from './comm/util'
    106. import ApproveTemplateDynamicFormItem from './ApproveTemplateDynamicFormItem'
    107. import ApprovalMan from './ApprovalMan'
    108. import ApprovalStageShow from './ApprovalStageShow'
    109. export default {
    110. props: {
    111. successCallback: {
    112. type: Function,
    113. default: () => () => {}
    114. }
    115. },
    116. components: {
    117. ApproveTemplateDynamicFormItem,
    118. ApprovalMan,
    119. ApprovalStageShow
    120. },
    121. data() {
    122. return {
    123. ApproveStatusEnum,
    124. ApproveStatusEnumInfo: {
    125. [ApproveStatusEnum.SAVE]: '保存',
    126. [ApproveStatusEnum.COMMIT]: '提交'
    127. },
    128. autoCreate: ApproveAutoCreateEnum.IS_AUTO_CREATE,
    129. // isAutoCreate: false,
    130. baseInfo: {},
    131. templateInfoList: [],
    132. oldFormValue: {}, // 旧的表单值
    133. form: {},
    134. rules: {},
    135. extrasInfo: {}, // 额外的附加信息
    136. extrasInfoExt: {}, // 额外的附加信息扩展 TODO
    137. spinning: false,
    138. approveProcessesList: [],
    139. approveManageProcessPersonList: {},
    140. userListOptions: [],
    141. isShowApprovalPerson: true,
    142. onlyShowCommit: false
    143. }
    144. },
    145. computed: {
    146. isAutoCreate() {
    147. return this.autoCreate === ApproveAutoCreateEnum.IS_AUTO_CREATE
    148. }
    149. },
    150. methods: {
    151. /**
    152. * 开启/关闭自动
    153. */
    154. handleChangeAutoSwitch(checked) {
    155. this.autoCreate = Number(checked)
    156. },
    157. /**
    158. * 改变额外的附加信息
    159. */
    160. changeExtrasInfo(field, value) {
    161. this.$set(this.extrasInfo, field, value)
    162. },
    163. /**
    164. * 清空指定字段的校验
    165. */
    166. clearValidate(field) {
    167. this.$refs.ruleForm.clearValidate(field)
    168. },
    169. /**
    170. * 重置表单
    171. */
    172. resetFormValue() {
    173. this.$refs.ruleForm.clearValidate()
    174. this.form = _.cloneDeep(this.oldFormValue)
    175. Array.isArray(this.$refs.approveTemplateDynamicFormRef) &&
    176. this.$refs.approveTemplateDynamicFormRef.forEach(item => {
    177. item.resetData()
    178. })
    179. },
    180. /**
    181. * 获取实例表单字段和值
    182. */
    183. getBusinessInfo(businessInfo = {}, isShowApprovalPerson = true) {
    184. this.isShowApprovalPerson = isShowApprovalPerson
    185. this.templateInfoList = businessInfo.approveTemplateValueGroupBoList || []
    186. this.baseInfo.businessTemplateId = businessInfo.businissTemplateId
    187. this.baseInfo.manageId = businessInfo.id
    188. this.baseInfo.approveProcessDetailList =
    189. businessInfo.approveProcessDetailList
    190. this.autoCreate = businessInfo.autoCreate
    191. ? businessInfo.autoCreate
    192. : this.autoCreate
    193. this.handleFormAndRules()
    194. },
    195. /**
    196. * 获取模板字段分组详情
    197. */
    198. async getTemplateDetail(id, defaultValue = {}) {
    199. this.spinning = true
    200. if (Object.keys(defaultValue).length) {
    201. this.onlyShowCommit = true
    202. }
    203. this.baseInfo.jobId = defaultValue?.id
    204. this.baseInfo.jobType = defaultValue?.jobType
    205. this.baseInfo.statusId = defaultValue?.statusId
    206. const res = await getApproveTemplateDetailWithoutProcess({
    207. id,
    208. jobType: defaultValue?.jobType,
    209. jobTypeBase: defaultValue?.jobTypeBase
    210. }).finally(() => {
    211. this.approveManageProcessPersonList = {}
    212. this.spinning = false
    213. })
    214. const users = JSON.parse(localStorage.getItem('personList'))
    215. this.templateInfoList = res.data?.approveFieldTemplateGroupList || []
    216. this.baseInfo.businessTemplateId = res.data?.id
    217. this.baseInfo.manageId = ''
    218. this.approveProcessesList = res.data?.approveProcessesBoList
    219. this.autoCreate = res.data.autoCreate
    220. ? res.data.autoCreate
    221. : ApproveAutoCreateEnum.IS_AUTO_CREATE
    222. if (Object.keys(defaultValue).length) {
    223. const jobMappingConfig = JSON.parse(res.data.jobMappingConfig)
    224. const props = {}
    225. for (const bolist of res.data.approveFieldTemplateGroupList) {
    226. for (const field of bolist.approveTemplateValueBoList) {
    227. const index = jobMappingConfig.find(item => {
    228. return (
    229. item.approveFieldName === field.approveFieldTemplateBo.fieldName
    230. )
    231. })
    232. if (
    233. field.approveFieldTemplateBo.fieldType === 80 &&
    234. index !== undefined
    235. ) {
    236. props[
    237. `${field.approveFieldTemplateBo.id}--${field.approveFieldTemplateBo.fieldType}`
    238. ] =
    239. field.approveFieldTemplateBo.multipleValue === 1
    240. ? users.filter(user =>
    241. defaultValue[index?.dataFieldName].includes(user.userId)
    242. )
    243. : users.find(user =>
    244. defaultValue[index?.dataFieldName].includes(user.userId)
    245. )
    246. } else {
    247. props[
    248. `${field.approveFieldTemplateBo.id}--${field.approveFieldTemplateBo.fieldType}`
    249. ] = defaultValue[index?.dataFieldName] || null
    250. }
    251. }
    252. }
    253. this.handleFormAndRules(props)
    254. } else {
    255. this.handleFormAndRules()
    256. }
    257. this.userListOptions = users
    258. },
    259. /**
    260. * TODO
    261. * 返回审批表单提交信息
    262. */
    263. approveFormInfo() {
    264. const target = []
    265. Object.keys(this.form).forEach(item => {
    266. target.push({
    267. extras: this.extrasInfo[item],
    268. fieldTemplateId: item.split('-')[
    269. CustomPropertyIndex.FIELD_TEMPLATE_ID
    270. ],
    271. fieldId: item.split('-')[CustomPropertyIndex.FIELD_ID],
    272. fieldValue:
    273. typeof this.form[item].mainInfo === 'string' ||
    274. item.split('-')[CustomPropertyIndex.FIELD_TYPE] ===
    275. ParamsTypeStringEnum.TIME
    276. ? this.form[item].mainInfo
    277. : JSON.stringify(this.form[item].mainInfo),
    278. approveTableBody:
    279. item.split('-')[CustomPropertyIndex.FIELD_TYPE] ===
    280. ParamsTypeStringEnum.TABLE
    281. ? this.form[item].mainInfo
    282. : null,
    283. operationFlag: this.form[item].operationFlag,
    284. extensionObj: this.form[item].extensionObj
    285. })
    286. })
    287. return target.filter(
    288. item => item.operationFlag !== OperationFlagEnum.READ_ONLY
    289. )
    290. },
    291. /**
    292. * 保存/提交 审批
    293. */
    294. async saveOrCommitEvent(type) {
    295. let flag = true
    296. if (ApproveStatusEnum.COMMIT === type) {
    297. flag = this.isPassFormValidate()
    298. }
    299. if (flag) {
    300. await this.startApproval(type, this.approveFormInfo())
    301. this.$emit('handleCancelDrawer')
    302. }
    303. },
    304. /**
    305. * 是否通过表单验证
    306. */
    307. isPassFormValidate() {
    308. let flag = false
    309. this.$refs.ruleForm.validate(valid => {
    310. flag = valid
    311. })
    312. return flag
    313. },
    314. /**
    315. * 保存/提交插槽按钮
    316. */
    317. handelSlotButtonEvent(callback, ...args) {
    318. this.isPassFormValidate() &&
    319. _.isFunction(callback) &&
    320. callback(...args, this.approveFormInfo())
    321. },
    322. /**
    323. * 发起/保存审批 => 后端
    324. */
    325. async startApproval(type, fieldValueList) {
    326. const res = await startApproval({
    327. ...Object.assign(this.baseInfo, {
    328. approveStatus: type,
    329. autoCreate: this.autoCreate
    330. }),
    331. approveFieldTemplateValueList: fieldValueList,
    332. approveManageProcessPersonList: this.getProcessPersonList()
    333. })
    334. this.$message.success(`${this.ApproveStatusEnumInfo[type]}成功`)
    335. if (type === ApproveStatusEnum.COMMIT) {
    336. this.$store.commit('SET_QUEREY_APPROVE_MANAGE_LIST_REQUEST_PARAMS', {
    337. type: ApprovalManageListTypeEnum.STARTED
    338. })
    339. }
    340. if (type === ApproveStatusEnum.SAVE) {
    341. this.$store.commit('SET_QUEREY_APPROVE_MANAGE_LIST_REQUEST_PARAMS', {
    342. type: ApprovalManageListTypeEnum.UNCOMMIT
    343. })
    344. }
    345. this.successCallback()
    346. },
    347. /**
    348. * 处理 form 表单和 rules
    349. */
    350. handleFormAndRules(props = {}) {
    351. this.extrasInfo = {}
    352. ;(this.form = {}), (this.rules = {})
    353. this.templateInfoList.forEach(element => {
    354. element.approveTemplateValueBoList.forEach(item => {
    355. const DYNAMIC_ID = `${item.approveFieldTemplateBo.id}-${item
    356. .approveFieldValueBo.id || ''}-${
    357. item.approveFieldTemplateBo.fieldType
    358. }`
    359. this.$set(
    360. this.extrasInfo,
    361. DYNAMIC_ID,
    362. item.approveFieldValueBo.extras || undefined
    363. )
    364. this.$set(
    365. this.extrasInfoExt,
    366. DYNAMIC_ID,
    367. item.approveFieldValueBo.projectName
    368. )
    369. // 将字段值处理成JSON格式传递给后端
    370. let tempJSON = undefined
    371. if (isJSON(item.approveFieldValueBo.fieldValue)) {
    372. tempJSON = JSON.parse(item.approveFieldValueBo.fieldValue)
    373. } else {
    374. tempJSON = item.approveFieldValueBo.fieldValue
    375. }
    376. this.$set(
    377. this.form,
    378. DYNAMIC_ID,
    379. tempJSON
    380. ? {
    381. mainInfo: tempJSON,
    382. operationFlag: item.operationFlag,
    383. extensionObj: item.approveFieldValueBo.extensionObj || {}
    384. }
    385. : item.approveFieldTemplateBo.multipleValue === 1
    386. ? {
    387. mainInfo: [],
    388. operationFlag: item.operationFlag,
    389. extensionObj: item.approveFieldValueBo.extensionObj || {}
    390. }
    391. : {
    392. mainInfo: '',
    393. operationFlag: item.operationFlag,
    394. extensionObj: item.approveFieldValueBo.extensionObj || {}
    395. }
    396. )
    397. // 必填项
    398. if (item.approveFieldTemplateBo.required === 1) {
    399. this.rules[DYNAMIC_ID] =
    400. this.rules[DYNAMIC_ID] || this.$set(this.rules, DYNAMIC_ID, [])
    401. this.rules[DYNAMIC_ID].push({
    402. required: true
    403. })
    404. if (item.approveFieldTemplateBo.fieldType === 100) {
    405. this.rules[DYNAMIC_ID].push({
    406. validator: (...args) =>
    407. handleCustomExtraValidateRequired(
    408. args[0],
    409. args[1].mainInfo,
    410. args[2]
    411. ),
    412. trigger: 'blur'
    413. })
    414. }
    415. else {
    416. this.rules[DYNAMIC_ID].push({
    417. validator: (...args) =>
    418. validateRequired(args[0], args[1].mainInfo, args[2]),
    419. trigger:
    420. item.approveFieldTemplateBo.fieldType === 120
    421. ? 'change'
    422. : 'blur'
    423. })
    424. }
    425. }
    426. // 整数
    427. if (
    428. item.approveFieldTemplateBo.fieldType === paramTypeColumn.integer
    429. ) {
    430. this.rules[DYNAMIC_ID] =
    431. this.rules[DYNAMIC_ID] || this.$set(this.rules, DYNAMIC_ID, [])
    432. this.rules[DYNAMIC_ID].push({
    433. validator: (...args) =>
    434. validateInteger(args[0], args[1].mainInfo, args[2])
    435. })
    436. }
    437. // 浮点数
    438. if (item.approveFieldTemplateBo.fieldType === paramTypeColumn.float) {
    439. this.rules[DYNAMIC_ID] =
    440. this.rules[DYNAMIC_ID] || this.$set(this.rules, DYNAMIC_ID, [])
    441. this.rules[DYNAMIC_ID].push({
    442. validator: (...args) =>
    443. validateFloat(args[0], args[1].mainInfo, args[2])
    444. })
    445. }
    446. })
    447. })
    448. this.oldFormValue = _.cloneDeep(this.form)
    449. for (const item in props) {
    450. if (props[item]) {
    451. this.form[item].mainInfo = props[item]
    452. }
    453. }
    454. },
    455. getProcessPersonList() {
    456. const keys = Object.keys(this.approveManageProcessPersonList)
    457. const values = Object.values(this.approveManageProcessPersonList)
    458. const ret = []
    459. for (const index in keys) {
    460. ret.push({
    461. processId: keys[index],
    462. approvePersonList: values[index]
    463. })
    464. }
    465. return ret
    466. },
    467. clearData() {
    468. this.baseInfo = {}
    469. this.templateInfoList = []
    470. this.oldFormValue = {}
    471. this.form = {}
    472. this.rules = {}
    473. this.extrasInfo = {}
    474. this.extrasInfoExt = {}
    475. this.approveProcessesList = []
    476. this.approveManageProcessPersonList = {}
    477. this.userListOptions = []
    478. },
    479. /**
    480. * 人员接口
    481. */
    482. async getAllUser() {
    483. const { data } = await getUsersList({ state: 1 })
    484. localStorage.setItem('personList', JSON.stringify(data))
    485. }
    486. },
    487. created() {
    488. this.getAllUser()
    489. }
    490. }
    491. </script>
    492. <style lang="scss" scoped>
    493. .approve-template-dynamic-form {
    494. height: 100%;
    495. padding-bottom: 20px;
    496. .approve-template-dynamic-form-model {
    497. height: calc(100% - 30px);
    498. overflow-y: scroll;
    499. }
    500. .approve-template-dynamic-form-bottom {
    501. height: 50px;
    502. margin: 0 16px 0 8px;
    503. padding: 0 8px;
    504. // background-color: red;
    505. box-shadow: 0 0 2px 0 rgb(31 31 31 / 5%), 0 4px 6px 0 rgb(31 31 31 / 20%);
    506. display: flex;
    507. justify-content: space-between;
    508. }
    509. .approval-detail-card-item-content-process-content {
    510. margin-left: 10px;
    511. }
    512. .approval-detail-card-item-content-process-content-person {
    513. cursor: pointer;
    514. }
    515. }
    516. </style>
    1. <template>
    2. <div class="approve-template-dynamic-form-item" v-if="infoItem.approveTemplateValueBoList && infoItem.approveTemplateValueBoList.length > 0">
    3. <a-card>
    4. <template v-slot:title>
    5. {{ infoItem.fieldGroupName }}
    6. </template>
    7. <div class="approve-template-dynamic-form-item-content">
    8. <a-row class="form-row" :gutter="16">
    9. <a-col
    10. :span="6"
    11. :key="item.approveFieldTemplateBo.id"
    12. v-for="item in infoItem.approveTemplateValueBoList" // 每个字段信息分别展示的组件
    13. >
    14. <component
    15. ref="componentRef"
    16. v-bind="$attrs"
    17. v-on="$listeners"
    18. :form="form"
    19. :item="item"
    20. :is="ComponentName[item.approveFieldTemplateBo.fieldType]"
    21. :extrasInfo="extrasInfo"
    22. :info="{
    23. id: `${item.approveFieldTemplateBo.id}-${
    24. item.approveFieldValueBo.id || ''
    25. }-${item.approveFieldTemplateBo.fieldType}`,
    26. label: item.approveFieldTemplateBo.fieldName,
    27. isMultiple: item.approveFieldTemplateBo.multipleValue === 1,
    28. isRequired: item.approveFieldTemplateBo.required === 1,
    29. preDefinedValues: item.approveFieldTemplateBo.extras || [],
    30. selectType: item.approveFieldTemplateBo.extrasType || -1,
    31. isAll: item.approveFieldTemplateBo.isAll === 1,
    32. disabled: item.operationFlag === OperationFlagEnum.READ_ONLY,
    33. relationTypeExtras: item.approveFieldTemplateBo.relationTypeExtras || {},
    34. instanceTypeExtras: item.approveFieldTemplateBo.instanceTypeExtras || {}
    35. }"
    36. ></component>
    37. </a-col>
    38. </a-row>
    39. </div>
    40. </a-card>
    41. </div>
    42. </template>
    43. <script>
    44. import { paramTypeColumn, OperationFlagEnum } from '@/common/global'
    45. import TextAreaFieldCom from './fieldTypeComponent/TextAreaFieldCom'
    46. import RadioSelectFieldCom from './fieldTypeComponent/RadioSelectFieldCom'
    47. import MultipleSelectFieldCom from './fieldTypeComponent/MultipleSelectFieldCom'
    48. import TimeFieldCom from './fieldTypeComponent/TimeFieldCom'
    49. import ProductLinkFieldCom from './fieldTypeComponent/ProductLinkFieldCom'
    50. import RelationFieldCom from './fieldTypeComponent/RelationFieldCom'
    51. import TextOrIntegerOrFloatFIeldCom from './fieldTypeComponent/TextOrIntegerOrFloatFIeldCom'
    52. import TableFieldCom from './fieldTypeComponent/TableFieldCom'
    53. import ExtraAccessoryFieldCom from './fieldTypeComponent/ExtraAccessoryFieldCom'
    54. import UserFieldCom from './fieldTypeComponent/UserFieldCom'
    55. import UserGroupFieldCom from './fieldTypeComponent/UserGroupFieldCom'
    56. import IdentificationFieldCom from './fieldTypeComponent/IdentificationFieldCom'
    57. import TaskOrNoteFieldCom from './fieldTypeComponent/TaskOrNoteFieldCom'
    58. import ProjectSelectFieldCom from './fieldTypeComponent/ProjectSelectFieldCom'
    59. import DateFieldCom from './fieldTypeComponent/DateFieldCom'
    60. export default {
    61. inheritAttrs: false,
    62. components: {
    63. TextAreaFieldCom,
    64. RadioSelectFieldCom,
    65. MultipleSelectFieldCom,
    66. TimeFieldCom,
    67. ProductLinkFieldCom,
    68. RelationFieldCom,
    69. TextOrIntegerOrFloatFIeldCom,
    70. TableFieldCom,
    71. ExtraAccessoryFieldCom,
    72. UserFieldCom,
    73. UserGroupFieldCom,
    74. IdentificationFieldCom,
    75. TaskOrNoteFieldCom,
    76. ProjectSelectFieldCom,
    77. DateFieldCom
    78. },
    79. props: {
    80. infoItem: {
    81. type: Object,
    82. default: () => ({}),
    83. },
    84. form: {
    85. type: Object,
    86. default: () => ({}),
    87. },
    88. extrasInfo: {
    89. type: Object,
    90. default: () => ({}),
    91. },
    92. },
    93. data() {
    94. return {
    95. OperationFlagEnum,
    96. ComponentName: {
    97. [paramTypeColumn.text]: 'TextOrIntegerOrFloatFIeldCom',
    98. [paramTypeColumn.textArea]: 'TextAreaFieldCom',
    99. [paramTypeColumn.radioSelect]: 'RadioSelectFieldCom',
    100. [paramTypeColumn.multiSelect]: 'MultipleSelectFieldCom',
    101. [paramTypeColumn.integer]: 'TextOrIntegerOrFloatFIeldCom',
    102. [paramTypeColumn.float]: 'TextOrIntegerOrFloatFIeldCom',
    103. [paramTypeColumn.time]: 'TimeFieldCom',
    104. [paramTypeColumn.link]: 'ProductLinkFieldCom',
    105. [paramTypeColumn.task_note]: 'TaskOrNoteFieldCom',
    106. // TODO
    107. 60: 'RelationFieldCom',
    108. // TODO
    109. 70: 'TableFieldCom',
    110. // TODO
    111. 80: 'UserFieldCom',
    112. // TODO
    113. 90: 'UserGroupFieldCom',
    114. // TODO
    115. 100: 'ExtraAccessoryFieldCom',
    116. // TODO
    117. 110: 'IdentificationFieldCom',
    118. 160: 'ProjectSelectFieldCom',
    119. 170: 'DateFieldCom'
    120. },
    121. }
    122. },
    123. methods: {
    124. resetData() {
    125. Array.isArray(this.$refs.componentRef) && this.$refs.componentRef.forEach(item => {
    126. item.resetData && item.resetData()
    127. })
    128. }
    129. }
    130. }
    131. </script>
    132. <style lang="scss" scoped>
    133. .approve-template-dynamic-form-item {
    134. padding: 0 8px 8px;
    135. }
    136. </style>
    1. <template>
    2. <a-form-model-item :label="info.label" :prop="info.id">
    3. <a-date-picker :disabled="info.disabled" v-model="form[info.id].mainInfo" />
    4. </a-form-model-item>
    5. </template>
    6. <script>
    7. export default {
    8. props: {
    9. info: {
    10. type: Object,
    11. default: () => ({})
    12. },
    13. form: {
    14. type: Object,
    15. default: () => ({})
    16. }
    17. }
    18. }
    19. </script>

    项目字段,根据单值还是多值展示不同的arco组件。

    1. <template>
    2. <a-form-model-item :prop="info.id" :label="info.label">
    3. <a-select
    4. v-if="info.isMultiple"
    5. mode="multiple"
    6. :filterOption="filterOption"
    7. :disabled="info.disabled"
    8. :allowClear="true"
    9. show-search
    10. placeholder="请选择"
    11. @change="handleChange"
    12. :defaultValue="form[info.id].mainInfo"
    13. >
    14. <a-select-option
    15. :value="element.id"
    16. :key="element.id"
    17. v-for="(element, index) in project"
    18. >{{ element.projectName }}</a-select-option
    19. >
    20. </a-select>
    21. <a-select
    22. v-else
    23. :filterOption="filterOption"
    24. :disabled="info.disabled"
    25. :allowClear="true"
    26. show-search
    27. placeholder="请选择"
    28. @change="handleChange"
    29. :defaultValue="form[info.id].mainInfo"
    30. >
    31. <a-select-option
    32. :value="element.id"
    33. :key="element.id"
    34. v-for="(element, index) in project"
    35. >{{ element.projectName }}</a-select-option
    36. >
    37. </a-select>
    38. </a-form-model-item>
    39. </template>
    40. <script>
    41. import { filterOption } from '@/views/settings/module/comm/util'
    42. import { getProject } from '@/api/templateManagement'
    43. export default {
    44. data() {
    45. return {
    46. project: []
    47. }
    48. },
    49. props: {
    50. info: {
    51. type: Object,
    52. default: () => ({})
    53. },
    54. form: {
    55. type: Object,
    56. default: () => ({})
    57. }
    58. },
    59. methods: {
    60. filterOption,
    61. async getProject() {
    62. const res = await getProject({
    63. notTemplate: 0,
    64. teamType: 3,
    65. projectTemplateId: '',
    66. pageIndex: 1,
    67. pageSize: -1
    68. })
    69. if (res.code === '200') {
    70. this.project = res.data
    71. }
    72. },
    73. handleChange(value) {
    74. // console.log(value)
    75. if (typeof value == 'string') {
    76. value = [value]
    77. }
    78. this.form[this.info.id].mainInfo = []
    79. value.forEach(item => {
    80. let proj = this.project.find(i => {
    81. return i.id === item
    82. })
    83. this.form[this.info.id].mainInfo.push({
    84. projectId: proj.id,
    85. projectName: proj.projectName
    86. })
    87. })
    88. // console.log(this.form[this.info.id])
    89. }
    90. },
    91. created() {
    92. this.getProject()
    93. this.form[this.info.id].mainInfo = []
    94. }
    95. }
    96. </script>
    97. <style lang="scss" scoped></style>

    审批详情页面:
    image.png

    1. <template>
    2. <a-card v-if="isShowDetail">
    3. <template v-slot:title>
    4. <a-tag :color="ApprovalStatusInfoEnum[dataInfo.approveStatus].color">{{
    5. ApprovalStatusInfoEnum[dataInfo.approveStatus].title
    6. }}</a-tag>
    7. <b v-if="dataInfo.approveBusinissTemplateBo">{{
    8. dataInfo.approveBusinissTemplateBo.templateName
    9. }}</b>
    10. </template>
    11. <template v-slot:extra> {{ dataInfo.createTime }} </template>
    12. <div class="approval-detail-card-item-content">
    13. <div v-if="dataInfo.labNoteApproveRecords">
    14. <div class="item approval-key">审批实验:</div>
    15. <div
    16. class="item approval-note"
    17. :key="item.id"
    18. v-for="item in dataInfo.labNoteApproveRecords"
    19. >
    20. <div>
    21. <a
    22. @click="handleApprovalNoteClick(item)"
    23. :style="{ marginRight: '8px' }"
    24. >
    25. <svg-icon
    26. icon-class="note"
    27. :style="{
    28. fontSize: '14px',
    29. color: '#08979c'
    30. }"
    31. />
    32. {{ item.noteName }}</a
    33. >
    34. {{ `负责人: ${item.noteLeaderName || '未指派'}` }}
    35. </div>
    36. </div>
    37. </div>
    38. <div class="item approval-key">申请人:</div>
    39. <a-avatar icon="user" />
    40. {{ dataInfo.createMan }}
    41. <div class="item approval-key">审批编号:</div>
    42. {{ dataInfo.manageNo }}
    43. <div
    44. class="item"
    45. :key="item.approveFieldTemplateBo.id"
    46. v-for="item in dataInfo.approveTemplateValueBoList"
    47. >
    48. <span
    49. v-if="paramTypeColumn.table === item.approveFieldTemplateBo.fieldType"
    50. >
    51. <div class="approval-key">
    52. {{ item.approveFieldTemplateBo.fieldName }}:
    53. </div>
    54. <a-button
    55. size="small"
    56. @click="
    57. showTableParams(
    58. dataInfo.id,
    59. item.approveFieldTemplateBo.id,
    60. item.approveFieldTemplateBo.fieldName
    61. )
    62. "
    63. ><a-icon type="fullscreen" />展开表格</a-button
    64. >
    65. </span>
    66. <span
    67. v-else-if="
    68. paramTypeColumn.table !== item.approveFieldTemplateBo.fieldType
    69. "
    70. >
    71. <div class="approval-key">
    72. {{ item.approveFieldTemplateBo.fieldName }}:
    73. </div>
    74. <span
    75. v-if="
    76. paramTypeColumn.extra === item.approveFieldTemplateBo.fieldType
    77. "
    78. >
    79. <a-space>
    80. <template
    81. v-for="(item, index) in handleExtraParams(
    82. item.approveFieldValueBo.fieldValue
    83. )"
    84. >
    85. <span
    86. @click.stop="
    87. customDownloadFile({
    88. fileName: item.fileName,
    89. relativePath: item.relativePath
    90. })
    91. "
    92. style="color: #1890ff; cursor: pointer"
    93. :key="index"
    94. >
    95. <a-icon type="download" /> {{ item.fileName }}
    96. </span>
    97. </template>
    98. </a-space>
    99. </span>
    100. <a-table
    101. v-else-if="
    102. paramTypeColumn.relation === item.approveFieldTemplateBo.fieldType
    103. "
    104. :columns="realationColumns"
    105. :data-source="getRelationTableData(item.approveFieldValueBo)"
    106. :pagination="false"
    107. >
    108. <template v-slot:name="name,record">
    109. <span :class="{'light-height': isShowProtocolExtra(record.operationFlag)}" @click="isShowProtocolExtra(record.operationFlag) ? handleSubService(record) : () => {}">{{name}}</span>
    110. </template>
    111. </a-table>
    112. <a-table
    113. v-else-if="
    114. paramTypeColumn.task_note ===
    115. item.approveFieldTemplateBo.fieldType
    116. "
    117. :columns="taskAndNoteColumns"
    118. :data-source="item.approveFieldValueBo.jobBOList"
    119. :pagination="false"
    120. :expandIconAsCell="false"
    121. :expandIconColumnIndex="-1"
    122. >
    123. <a
    124. slot="name"
    125. slot-scope="text, item"
    126. @click="handleNoteClick(item)"
    127. >
    128. <svg-icon
    129. slot="avatar"
    130. :icon-class="item.jobType === 30 ? 'task' : 'note'"
    131. :style="{
    132. fontSize: '14px',
    133. color: item.jobType === 30 ? '#2F54EB' : '#08979c'
    134. }"
    135. />
    136. {{ text }}</a
    137. >
    138. <span slot="jobType" slot-scope="text">{{
    139. DiffTypeShowInfo[text]
    140. }}</span>
    141. <span slot="path" slot-scope="text">{{
    142. showPath(text)
    143. }}</span>
    144. </a-table>
    145. <span v-else>
    146. {{
    147. transformData(
    148. item.approveFieldValueBo.fieldValue,
    149. item.approveFieldTemplateBo.multipleValue === 1,
    150. item.approveFieldTemplateBo.fieldType,
    151. item
    152. )
    153. }}
    154. <!-- <template
    155. v-if="
    156. paramTypeColumn.relation ===
    157. item.approveFieldTemplateBo.fieldType
    158. "
    159. >
    160. <a-space>
    161. <a-button
    162. :disabled="
    163. isDisabledSkip ||
    164. !(
    165. dataInfo.approveStatus ===
    166. ApprovalStatusEnum.APPROVE_PASS
    167. )
    168. "
    169. size="small"
    170. @click="handleSkipProject(item.approveFieldValueBo.extras)"
    171. style="color: #1890ff;"
    172. >{{ item.approveFieldValueBo.projectName }}</a-button
    173. >
    174. <a-tag
    175. v-if="
    176. item.approveFieldValueBo.extensionObj &&
    177. item.approveFieldValueBo.extensionObj.referenceName
    178. "
    179. >{{
    180. item.approveFieldValueBo.extensionObj.referenceName
    181. }}</a-tag
    182. >
    183. </a-space>
    184. </template> -->
    185. </span>
    186. </span>
    187. </div>
    188. <a-divider />
    189. <div class="approval-detail-card-item-content-process">
    190. <span style="display: block">处理流程</span>
    191. <div class="approval-detail-card-item-content-process-content">
    192. <ApprovalStageShow
    193. :approveProcessDetailList="dataInfo.approveProcessDetailList"
    194. />
    195. </div>
    196. </div>
    197. </div>
    198. <relation-field-com-modal ref="relationFieldComModalRef" />
    199. <ApprovalComment :approveManageId="dataInfo.id" />
    200. </a-card>
    201. </template>
    202. <script>
    203. import { ApprovalStatusInfoEnum, ApprovalStatusEnum, JOB_TYPE } from '@/common/global'
    204. import { handleDiffFieldMixins } from './mixins'
    205. import { isShowProtocolExtra } from './comm/util'
    206. import ApprovalStageShow from './ApprovalStageShow'
    207. import ApprovalComment from './ApprovalComment'
    208. import RelationFieldComModal from './fieldTypeComponent/components/RelationFieldComModal'
    209. import action from '@/micro-store'
    210. const realationColumns = [
    211. {
    212. title: '名称',
    213. dataIndex: 'referenceName',
    214. key: 'referenceName',
    215. scopedSlots: { customRender: 'name' }
    216. },
    217. {
    218. title: '附表类型',
    219. dataIndex: 'referenceTypeName',
    220. key: 'referenceTypeName'
    221. },
    222. {
    223. title: '负责人',
    224. dataIndex: 'leaderName',
    225. key: 'leaderName'
    226. },
    227. {
    228. title: '成员',
    229. dataIndex: 'membersName',
    230. key: 'membersName'
    231. },
    232. {
    233. title: '计划时间',
    234. dataIndex: 'plannedTime',
    235. key: 'plannedTime'
    236. },
    237. {
    238. title: '计划时长',
    239. dataIndex: 'plannedDuration',
    240. key: 'plannedDuration'
    241. },
    242. {
    243. title: '所属项目',
    244. dataIndex: 'projectName',
    245. key: 'projectName'
    246. },
    247. {
    248. title: '关联任务',
    249. dataIndex: 'realationTask',
    250. key: 'realationTask'
    251. }
    252. ]
    253. const taskAndNoteColumns = [
    254. {
    255. title: '名称',
    256. dataIndex: 'jobName',
    257. key: 'jobName',
    258. scopedSlots: { customRender: 'name' }
    259. },
    260. {
    261. title: '类型',
    262. dataIndex: 'jobType',
    263. key: 'jobType',
    264. scopedSlots: { customRender: 'jobType' }
    265. },
    266. {
    267. title: '状态',
    268. dataIndex: 'jobStatusName',
    269. key: 'jobStatusName'
    270. },
    271. {
    272. title: '所属',
    273. dataIndex: 'jobPathBoList',
    274. key: 'jobPathBoList',
    275. scopedSlots: { customRender: 'path' }
    276. }
    277. ]
    278. export default {
    279. props: {
    280. isDisabledSkip: {
    281. type: Boolean,
    282. default: () => false
    283. },
    284. dataInfo: {
    285. type: Object,
    286. default: () => ({})
    287. }
    288. },
    289. components: {
    290. ApprovalStageShow,
    291. ApprovalComment,
    292. RelationFieldComModal
    293. },
    294. computed: {
    295. isShowDetail() {
    296. return !_.isEmpty(this.dataInfo)
    297. },
    298. DiffTypeShowInfo() {
    299. return {
    300. [JOB_TYPE.note]: '实验记录',
    301. [JOB_TYPE.task]: '任务'
    302. }
    303. }
    304. },
    305. mixins: [handleDiffFieldMixins],
    306. data() {
    307. return {
    308. taskAndNoteColumns,
    309. realationColumns,
    310. ApprovalStatusInfoEnum,
    311. ApprovalStatusEnum
    312. }
    313. },
    314. methods: {
    315. isShowProtocolExtra,
    316. handleApprovalNoteClick(note) {
    317. window.open(`/#/approval-note-preview/${note.id}/${note.noteName}`)
    318. },
    319. /**
    320. *
    321. */
    322. handleSubService(record) {
    323. const { referenceId: protocolId, fieldTemplateId } = record || {}
    324. action.setGlobalState({
    325. protocolId: protocolId,
    326. fieldTemplateId: fieldTemplateId,
    327. isOnlyShow: true,
    328. // 2 代表批复阶段
    329. approveProcessType: 2
    330. })
    331. this.$refs.relationFieldComModalRef.openModalEvent(true)
    332. },
    333. /**
    334. * 点击跳转
    335. */
    336. handleSkipProject(projectId) {
    337. this.$router.push({
    338. name: 'projectStatus',
    339. params: {
    340. projectId: projectId
    341. // type: "7",
    342. }
    343. })
    344. },
    345. getRelationTableData(props) {
    346. const data = JSON.parse(props.fieldValue) || []
    347. return data.map(item => {
    348. return {
    349. ...item,
    350. fieldTemplateId: props.fieldTemplateId,
    351. projectName: props.projectName,
    352. realationTask: props.extensionObj.referenceName
    353. }
    354. })
    355. },
    356. handleNoteClick(item) {
    357. if (item.jobType === JOB_TYPE.note) {
    358. window.open(`/#/preview/${item.id}/${item.jobName}`)
    359. }
    360. },
    361. showPath(path) {
    362. // console.log('path', path)
    363. return path
    364. .map(item => item.jobName)
    365. .slice(0, -1)
    366. .join('>')
    367. }
    368. },
    369. // created() {
    370. // console.log(this.dataInfo);
    371. // }
    372. }
    373. </script>
    374. <style lang="scss" scoped>
    375. .approval-detail-card-item-content {
    376. .item {
    377. margin: 8px 0;
    378. }
    379. .approval-key {
    380. margin-top: 16px;
    381. color: #bfbfbf;
    382. }
    383. }
    384. .approval-detail-card-item-content-process-content {
    385. padding-top: 8px;
    386. }
    387. .approval-detail-card-item-content-process-content-person {
    388. cursor: pointer;
    389. }
    390. .light-height {
    391. color: #1890ff;
    392. cursor: pointer;
    393. }
    394. </style>
    1. import { getApproveFieldTable } from '@/api/fieldTable'
    2. import { paramTypeColumn } from '@/common/global'
    3. import { downloadFile } from '@/common/util'
    4. import { downloadFile as asyncDownloadFile } from '@/api/fileTransfer'
    5. import { isJSON } from '@/common/util'
    6. import TableParamsDrawer from '../fieldTypeComponent/components/TableParamsDrawer'
    7. import moment from 'moment'
    8. export const handleDiffFieldMixins = {
    9. components: {
    10. TableParamsDrawer,
    11. },
    12. data() {
    13. return {
    14. paramTypeColumn: { ...paramTypeColumn, relation: 60, table: 70, extra: 100, project: 160, date: 170 },
    15. handleDiffFieldType: {
    16. [paramTypeColumn.text]: this.handleOtherParams,
    17. [paramTypeColumn.textArea]: this.handleOtherParams,
    18. [paramTypeColumn.radioSelect]: this.handleOtherParams,
    19. [paramTypeColumn.multiSelect]: this.handleOtherParams,
    20. [paramTypeColumn.integer]: this.handleOtherParams,
    21. [paramTypeColumn.float]: this.handleOtherParams,
    22. [paramTypeColumn.time]: this.handleTimeParams,
    23. [paramTypeColumn.link]: this.handlePolyParams,
    24. [paramTypeColumn.task_note]: this.handleTaskAndNoteParams,
    25. 60: this.handlePolyParams,
    26. 80: this.handleUserParams,
    27. 90: this.handleUserGroupParams,
    28. 100: this.handleExtraParams,
    29. 110: this.handleOtherParams,
    30. 160: this.handleProjectParams,
    31. 170: this.handleTimeParams2,
    32. },
    33. tableParams: {}, // 特殊 表格参数
    34. tableFieldInfo: {},
    35. }
    36. },
    37. methods: {
    38. customDownloadFile({ fileName, relativePath }) {
    39. downloadFile({ fileName, relativePath }, asyncDownloadFile)
    40. },
    41. /**
    42. * 根据不同类型是否多值转化后端给的数据
    43. */
    44. transformData(value, isMultiple, fieldType,item) {
    45. if (this.handleDiffFieldType[fieldType]) {
    46. return this.handleDiffFieldType[fieldType](value, isMultiple,item)
    47. }
    48. },
    49. /**
    50. * protocol/任务模板/产品
    51. */
    52. handlePolyParams(value) {
    53. const targetValues = JSON.parse(value) || []
    54. const showValues = targetValues.map(element => {
    55. return element.referenceName
    56. })
    57. return showValues.join('、')
    58. },
    59. /**
    60. * 处理附件
    61. */
    62. handleExtraParams(value) {
    63. const fieldValue = JSON.parse(value) || {}
    64. fieldValue.infoList = fieldValue.infoList || []
    65. return fieldValue.infoList
    66. },
    67. handleTaskAndNoteParams(value, isMultiple,item) {
    68. if(item){
    69. return item.approveFieldValueBo.jobBOList.map(item => item.jobName).join(', ')
    70. }
    71. },
    72. /**
    73. * 处理其他参数类型
    74. */
    75. handleOtherParams(value, isMultiple) {
    76. if (isMultiple) {
    77. let targetValue = JSON.parse(value) || []
    78. return targetValue.join('、')
    79. }
    80. return value
    81. },
    82. /**
    83. * 处理用户类型参数
    84. */
    85. handleUserParams(values, isMultiple) {
    86. if (!isJSON(values)) {
    87. values = JSON.stringify(values)
    88. }
    89. if (isMultiple) {
    90. let targetValues = JSON.parse(values) || []
    91. return targetValues.map(item => item.userNameCn).join('、')
    92. } else {
    93. return JSON.parse(values)?.userNameCn
    94. }
    95. },
    96. /**
    97. * 处理用户组
    98. */
    99. handleUserGroupParams(values) {
    100. let targetValues = JSON.parse(values) || []
    101. return targetValues.map(item => item.organizationalStructureName).join('、')
    102. },
    103. /**
    104. * 处理时间型参数
    105. */
    106. handleTimeParams(value) {
    107. if (value) {
    108. return moment(value).format('YYYY-MM-DD HH:mm:ss')
    109. } else {
    110. return value
    111. }
    112. },
    113. /**
    114. * 处理时间型参数,日期格式
    115. */
    116. handleTimeParams2(value) {
    117. if (value) {
    118. return moment(value).format('YYYY-MM-DD')
    119. } else {
    120. return value
    121. }
    122. },
    123. /**
    124. * 处理项目类型参数
    125. */
    126. handleProjectParams(value, isMultiple) {
    127. let arr = JSON.parse(value) || []
    128. // console.log(arr)
    129. if (typeof arr !== 'object') return arr
    130. return arr.map(item => item.projectName).join('、')
    131. },
    132. /**
    133. * 展开表格参数
    134. */
    135. async showTableParams(manageId, fieldTemplateId, title) {
    136. this.$set(this.tableFieldInfo, 'title', title)
    137. await this.getApproveFieldTable(manageId, fieldTemplateId)
    138. this.$refs.tableParamsDrawerRef.openDrawerEvent(
    139. this.tableParams
    140. )
    141. },
    142. /**
    143. * 根据审批实例id 字段模板id 获取表格
    144. */
    145. async getApproveFieldTable(manageId, fieldTemplateId) {
    146. const res = await getApproveFieldTable({
    147. approveManageId: manageId,
    148. fieldTemplateId: fieldTemplateId,
    149. })
    150. if (res.code === '200') {
    151. this.tableParams = res.data
    152. }
    153. },
    154. },
    155. }