index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. <template>
  2. <el-dialog
  3. v-loading="loading"
  4. :title="title"
  5. :visible.sync="dialogVisible"
  6. :close-on-click-modal="false"
  7. :close-on-press-escape="false"
  8. :show-close="false"
  9. append-to-body
  10. fullscreen
  11. class="dialog paper-detail-dialog"
  12. top="0"
  13. >
  14. <div slot="title" class="dialog-title">
  15. <span class="dialogtitle">{{ title }}</span>
  16. <div>
  17. <ibps-toolbar :actions="toolbars" @action-event="handleActionEvent" />
  18. </div>
  19. </div>
  20. <div class="container">
  21. <div class="left" :style="{width:initWidth}">
  22. <div class="form">
  23. <el-form ref="form" label-width="120px" :model="form" :rules="rules">
  24. <el-row :gutter="20">
  25. <el-col :span="12">
  26. <el-form-item label="部门" prop="bian_zhi_bu_men_" class="required">
  27. <ibps-user-selector
  28. v-model="form.bian_zhi_bu_men_"
  29. type="position"
  30. readonly-text="text"
  31. :disabled="false"
  32. :multiple="false"
  33. size="mini"
  34. :filter="filter"
  35. filtrate
  36. />
  37. </el-form-item>
  38. </el-col>
  39. <el-col :span="12">
  40. <el-form-item label="岗位分组" prop="bu_men_fen_zu_">
  41. <ibps-custom-dialog
  42. v-model="form.bu_men_fen_zu_"
  43. size="mini"
  44. :template-key="config?'gwzzdhkrcwh':'gwfzdhk'"
  45. store="id"
  46. :multiple="false"
  47. :dynamic-params="{
  48. suo_shu_bu_men_: form.bian_zhi_bu_men_
  49. }"
  50. type="dialog"
  51. class="custom-dialog"
  52. placeholder="请选择"
  53. icon="el-icon-search"
  54. />
  55. </el-form-item>
  56. </el-col>
  57. </el-row>
  58. <el-row>
  59. <el-col :span="24">
  60. <el-form-item label="表单名称" prop="biao_dan_ming_che" class="required">
  61. <el-input v-model="form.biao_dan_ming_che" size="mini" placeholder="请输入" />
  62. </el-form-item>
  63. </el-col>
  64. </el-row>
  65. <el-row>
  66. <el-col :span="24">
  67. <el-form-item label="表单模板" prop="biao_dan_mo_ban_" class="required">
  68. <ibps-attachment
  69. v-model="form.biao_dan_mo_ban_"
  70. :download="true"
  71. :multiple="false"
  72. accept=".docx"
  73. :readonly="false"
  74. operation_status="saveAdd"
  75. size="mini"
  76. />
  77. </el-form-item>
  78. </el-col>
  79. </el-row>
  80. <el-row>
  81. <el-col :span="24">
  82. <el-form-item label="归档路径" prop="gui_dang_lu_jing_" class="required">
  83. <ibps-custom-dialog
  84. v-model="form.gui_dang_lu_jing_"
  85. size="mini"
  86. template-key="bdmbgdljdhk"
  87. :multiple="false"
  88. type="dialog"
  89. class="custom-dialog"
  90. placeholder="请选择"
  91. icon="el-icon-search"
  92. />
  93. </el-form-item>
  94. </el-col>
  95. </el-row>
  96. <el-row>
  97. <el-col :span="24">
  98. <el-form-item label="审批流程" prop="shen_pi_liu_cheng" class="required">
  99. <el-radio-group v-model="form.shen_pi_liu_cheng">
  100. <el-radio label="无需审批">无需审批</el-radio>
  101. <el-radio label="需要审批">需要审批</el-radio>
  102. </el-radio-group>
  103. </el-form-item>
  104. </el-col>
  105. </el-row>
  106. <el-row>
  107. <el-col :span="24">
  108. <el-form-item label="备注" prop="bei_zhu_">
  109. <el-input
  110. v-model="form.bei_zhu_"
  111. type="textarea"
  112. :maxlength="400"
  113. show-word-limit
  114. :rows="4"
  115. />
  116. </el-form-item>
  117. </el-col>
  118. </el-row>
  119. </el-form>
  120. </div>
  121. <div v-show="form.shen_pi_liu_cheng==='需要审批'" class="table">
  122. <el-row>
  123. <el-col :span="24" style="margin:0 0 5px 0">
  124. <div class="button">
  125. <el-button type="danger" size="mini" icon="ibps-icon-close" @click="goSubRemove">删除</el-button>
  126. <el-button type="success" size="mini" icon="ibps-icon-plus" @click="goSubAdd">添加</el-button>
  127. </div>
  128. </el-col>
  129. </el-row>
  130. <el-row>
  131. <el-col :span="24">
  132. <el-table border :data="subForm" @selection-change="handleSelectionChange">
  133. <el-table-column
  134. width="50"
  135. type="selection"
  136. />
  137. <el-table-column
  138. prop=""
  139. label="序号"
  140. width="50"
  141. type="index"
  142. :index="showIndex"
  143. />
  144. <el-table-column prop="jie_dian_ming_cheng_" label="节点名称" width="200">
  145. <template slot-scope="{row}">
  146. <el-input v-model="row.jie_dian_ming_cheng_" size="mini" />
  147. </template>
  148. </el-table-column>
  149. <el-table-column prop="fang_shi_" label="方式" width="120">
  150. <template slot-scope="{row}">
  151. <el-select v-model="row.fang_shi_" placeholder="请选择" size="mini">
  152. <el-tooltip
  153. v-for="item in typeOption"
  154. :key="item.value"
  155. effect="dark"
  156. :content="item.tips"
  157. placement="right"
  158. >
  159. <el-option :label="item.label" :value="item.value" />
  160. </el-tooltip>
  161. </el-select>
  162. </template>
  163. </el-table-column>
  164. <el-table-column prop="yong_hu_lei_xing_" label="用户类型" width="100">
  165. <template slot-scope="{row}">
  166. <el-select v-model="row.yong_hu_lei_xing_" placeholder="请选择" size="mini" @change="onCategoryChange(row)">
  167. <el-option
  168. v-for="item in [{label:'人员',value:'employee'},{label:'角色',value:'role'},{label:'全部',value:'all'}]"
  169. :key="item.value"
  170. :label="item.label"
  171. :value="item.value"
  172. />
  173. </el-select>
  174. </template>
  175. </el-table-column>
  176. <el-table-column prop="chu_li_ren_" label="人员/角色" align="center">
  177. <template slot-scope="{row}">
  178. <ibps-user-selector
  179. v-if="row.yong_hu_lei_xing_==='employee'"
  180. v-model="row.chu_li_ren_"
  181. size="mini"
  182. type="user"
  183. readonly-text="text"
  184. :disabled="false"
  185. placeholder="请选择人员"
  186. :multiple="true"
  187. :filter="filter"
  188. filtrate
  189. />
  190. <ibps-role-selector
  191. v-if="row.yong_hu_lei_xing_==='role'"
  192. v-model="row.chu_li_ren_"
  193. :disabled="false"
  194. placeholder="请选择指定角色"
  195. :multiple="false"
  196. />
  197. <span v-if="row.yong_hu_lei_xing_==='all'">/</span>
  198. </template>
  199. </el-table-column>
  200. <!-- <el-table-column prop="zhi_xing_fang_shi_" label="执行方式" width="100">
  201. <template slot-scope="{row}">
  202. <el-select v-model="row.zhi_xing_fang_shi_" placeholder="请选择" size="mini">
  203. <el-option
  204. v-for="item in ['或签','与签']"
  205. :key="item"
  206. :label="item"
  207. :value="item"
  208. />
  209. </el-select>
  210. </template>
  211. </el-table-column> -->
  212. </el-table>
  213. </el-col>
  214. </el-row>
  215. </div>
  216. </div>
  217. </div>
  218. </el-dialog>
  219. </template>
  220. <script>
  221. import dayjs from 'dayjs'
  222. import ibpsUserSelector from '@/business/platform/org/selector'
  223. import IbpsRoleSelector from '@/business/platform/org/role/selector'
  224. import IbpsAttachment from '@/business/platform/file/attachment/selector'
  225. export default {
  226. components: {
  227. IbpsCustomDialog: () => import('@/business/platform/data/templaterender/custom-dialog'),
  228. ibpsUserSelector,
  229. IbpsRoleSelector,
  230. IbpsAttachment
  231. },
  232. props: {
  233. params: {
  234. type: Object,
  235. default: function () {
  236. return {}
  237. }
  238. }
  239. },
  240. data () {
  241. const { userId, position, level, mainPosition, setting } = this.$store.getters
  242. return {
  243. config: setting?.postJob?.allocation || false,
  244. filter: [{
  245. descVal: '1',
  246. includeSub: true,
  247. old: 'position',
  248. partyId: this.$store.getters.userInfo.employee.positions,
  249. partyName: '',
  250. scriptContent: '',
  251. type: 'user',
  252. userType: 'position'
  253. }],
  254. dialogVisible: true,
  255. userId: userId,
  256. position: position,
  257. mainPosition,
  258. level: level.second || level.first,
  259. loading: false,
  260. title: '表单模板配置',
  261. toolbars: [
  262. { key: 'save', label: '保存' },
  263. { key: 'cancel', label: '退出', type: 'danger', icon: 'ibps-icon-close' }
  264. ],
  265. initWidth: '1280px',
  266. isEdit: false,
  267. isFinished: false,
  268. readonly: false,
  269. preParams: {},
  270. Ids: [],
  271. form: {
  272. biao_dan_ming_che: '',
  273. biao_dan_mo_ban_: '',
  274. gui_dang_lu_jing_: '',
  275. shen_pi_liu_cheng: '',
  276. bian_zhi_bu_men_: '',
  277. bu_men_fen_zu_: '',
  278. bei_zhu_: ''
  279. },
  280. typeOption: [
  281. { label: '提前预设', value: 'presets', tips: '流程流转时,将直接推送到指定人员或角色的待办' },
  282. { label: '临时指定', value: 'temp', tips: '流程流转时,由上一节点的操作人在指定人员或角色范围内自行选择流程下一节点的处理人' }
  283. ],
  284. rules: {
  285. biao_dan_ming_che: [
  286. { required: true, message: '表单名称不能为空', trigger: 'blur' }
  287. ],
  288. biao_dan_mo_ban_: [
  289. { required: true, message: '表单模板不能为空', trigger: 'blur' }
  290. ],
  291. gui_dang_lu_jing_: [
  292. { required: true, message: '归档路径不能为空', trigger: 'blur' }
  293. ],
  294. shen_pi_liu_cheng: [
  295. { required: true, message: '审批流程不能为空', trigger: 'blur' }
  296. ],
  297. bian_zhi_bu_men_: [
  298. { required: true, message: '部门不能为空', trigger: 'blur' }
  299. ]
  300. },
  301. subForm: [],
  302. multipleSelection: [],
  303. isInit: false
  304. }
  305. },
  306. watch: {
  307. 'form.bian_zhi_bu_men_': {
  308. handler (val) {
  309. if (!this.isInit) {
  310. this.isInit = true
  311. return
  312. }
  313. this.form.bu_men_fen_zu_ = ''
  314. },
  315. deep: true
  316. }
  317. },
  318. mounted () {
  319. console.log('params', this.params)
  320. this.init()
  321. },
  322. methods: {
  323. handleActionEvent ({ key }) {
  324. switch (key) {
  325. case 'cancel':
  326. this.closeDialog(true)
  327. break
  328. case 'save':
  329. this.goSave('close')
  330. break
  331. default:
  332. break
  333. }
  334. },
  335. showIndex (index) {
  336. // return index + 1 + (this.currentPage - 1) * this.pageSize
  337. return index + 1
  338. },
  339. handleSelectionChange (val) {
  340. this.multipleSelection = val
  341. },
  342. // 用户类型发生改变
  343. onCategoryChange (row) {
  344. const item = this.subForm.find(i => i === row)
  345. item.chu_li_ren_ = ''
  346. },
  347. // 子表添加
  348. goSubAdd () {
  349. if (this.subForm.length >= 4) {
  350. return this.$message.warning('超过流程节点的最大限制!')
  351. }
  352. this.subForm.push({
  353. jie_dian_ming_cheng_: '',
  354. chu_li_ren_: '',
  355. // zhi_xing_fang_shi_: '或签',
  356. yong_hu_lei_xing_: 'employee',
  357. fang_shi_: 'presets'
  358. })
  359. },
  360. // 子表删除
  361. goSubRemove () {
  362. this.subForm = this.subForm.filter(item => !this.multipleSelection.includes(item))
  363. },
  364. // 获取人员部门
  365. getPersonPosition (id) {
  366. const userList = this.$store.getters.userList
  367. const bianzhiUserid = userList.find(i => i.userId === id)
  368. if (bianzhiUserid) {
  369. return bianzhiUserid.positionId
  370. }
  371. },
  372. checkRequired (flag) {
  373. if (this.form.shen_pi_liu_cheng === '需要审批') {
  374. if (this.subForm.length === 0) throw new Error('请填写流程配置!')
  375. for (let i = 0; i < this.subForm.length; i++) {
  376. const item = this.subForm[i]
  377. if (!item.jie_dian_ming_cheng_) throw new Error(`第${i + 1}行缺少节点名称!`)
  378. if (item.yong_hu_lei_xing_ !== 'all' && !item.chu_li_ren_) throw new Error(`第${i + 1}行缺少处理人!`)
  379. }
  380. }
  381. },
  382. async goAdd () {
  383. try {
  384. const obj = this.formatData()
  385. const addParamsRecord = {
  386. tableName: 't_bdmbpzb',
  387. paramWhere: [obj]
  388. }
  389. const { variables: { cont }} = await this.$common.request('add', addParamsRecord)
  390. if (cont.length) {
  391. this.$message.success('添加成功')
  392. this.closeDialog(true)
  393. }
  394. } catch (error) {
  395. this.$message.warning(error.message)
  396. }
  397. },
  398. formatData () {
  399. const obj = {
  400. ...this.form,
  401. liu_cheng_shu_ju_: JSON.stringify({
  402. hasProcess: this.form.shen_pi_liu_cheng === '需要审批' ? 'Y' : 'N',
  403. nodeList: this.form.shen_pi_liu_cheng === '需要审批' ? this.subForm.map((item, index) => ({
  404. sn: index + 1,
  405. nodeName: item.jie_dian_ming_cheng_,
  406. conditionType: item.fang_shi_,
  407. executeType: item.yong_hu_lei_xing_,
  408. executor: item.chu_li_ren_
  409. })) : []
  410. })
  411. }
  412. return obj
  413. },
  414. async goEdit (flag) {
  415. try {
  416. const obj = this.formatData()
  417. const updateParamsRecord = {
  418. tableName: 't_bdmbpzb',
  419. updList: [{
  420. where: {
  421. id_: this.params.id_
  422. },
  423. param: obj
  424. }]
  425. }
  426. await this.$common.request('update', updateParamsRecord)
  427. this.$message.success('修改成功!')
  428. this.closeDialog(true)
  429. } catch (error) {
  430. this.$message.warning(error.message)
  431. throw new Error(error.message)
  432. }
  433. },
  434. goSave (flag) {
  435. try {
  436. this.$refs.form.validate((valid) => {
  437. if (valid) {
  438. this.checkRequired()
  439. if (this.isEdit) {
  440. this.goEdit(flag)
  441. } else {
  442. this.goAdd()
  443. }
  444. } else {
  445. console.log('error submit!!')
  446. return false
  447. }
  448. })
  449. } catch (error) {
  450. this.$message.warning(error.message)
  451. }
  452. },
  453. // 刷新
  454. async goRefresh () {
  455. },
  456. // 关闭当前窗口
  457. closeDialog (needRefresh) {
  458. this.dialogVisible = false
  459. if (needRefresh) {
  460. this.$emit('close')
  461. }
  462. },
  463. async init () {
  464. this.isEdit = !!(this.params && this.params.id_)
  465. if (this.isEdit) {
  466. this.form = this.params
  467. // JSON 解析
  468. const liu_cheng_shu_ju_ = JSON.parse(this.form.liu_cheng_shu_ju_)
  469. // console.log(liu_cheng_shu_ju_.nodeList)
  470. liu_cheng_shu_ju_.nodeList.forEach((item, index) => {
  471. this.$set(this.subForm, index, {
  472. jie_dian_ming_cheng_: item.nodeName,
  473. chu_li_ren_: item.executor,
  474. fang_shi_: item.conditionType,
  475. yong_hu_lei_xing_: item.executeType
  476. })
  477. })
  478. } else {
  479. this.form.di_dian_ = this.level
  480. this.form.bian_zhi_ren_ = this.userId
  481. const positons = this.position.split(',')
  482. this.form.bian_zhi_bu_men_ = this.mainPosition ? this.mainPosition.id : positons[positons.length - 1]
  483. this.form.bu_men_fen_zu_ = ''
  484. this.form.bian_zhi_shi_jian = dayjs().format('YYYY-MM-DD HH:mm:ss')
  485. this.form.shen_pi_liu_cheng = '不需要审批'
  486. this.form.bei_zhu_ = ''
  487. }
  488. }
  489. }
  490. }
  491. </script>
  492. <style lang="scss" scoped>
  493. .paper-detail-dialog {
  494. ::v-deep {
  495. .el-dialog__header {
  496. text-align: center;
  497. }
  498. .el-form-item__label {
  499. text-align: left;
  500. font-size: 12px !important;
  501. padding-left: 30px;
  502. position: relative;
  503. &:before {
  504. position: absolute;
  505. left: 24px;
  506. }
  507. }
  508. .el-form-item__content{
  509. font-size: 12px !important;
  510. }
  511. }
  512. .dialog-title{
  513. display: flex;
  514. align-items: center;
  515. justify-content: center;
  516. div{
  517. z-index: 99999999;
  518. position: absolute;
  519. right:8vw;
  520. }
  521. .dialogtitle{
  522. font-size: 22px;
  523. font-family: SimHei;
  524. font-weight: bold;
  525. color: #222;
  526. }
  527. }
  528. .container {
  529. display: flex;
  530. width: 100%;
  531. justify-content: center;
  532. .left{
  533. height: calc(100vh - 100px);
  534. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  535. padding:20px;
  536. overflow-y: auto;
  537. .item{
  538. width: 100%;
  539. }
  540. .title{
  541. margin: 16px 0 6px -16px;
  542. }
  543. .button{
  544. display: flex;
  545. flex-direction: row-reverse;
  546. .el-button{
  547. margin-left: 5px;
  548. }
  549. }
  550. }
  551. }
  552. }
  553. </style>