basic-form.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. <!--
  2. @description: 基础表单
  3. @Author: linqian
  4. @Date: 2021-07-10
  5. -->
  6. <template>
  7. <div>
  8. <el-form
  9. :class="isDetail ? '' : 'v-form-text'"
  10. ref="ruleForm"
  11. :model="sizeForm"
  12. :rules="rules"
  13. label-width="160px"
  14. v-if="show"
  15. >
  16. <dg-row>
  17. <dg-col :span="12">
  18. <el-form-item label="审批类型:" prop="applyType">
  19. <div v-if="isDetail">
  20. <div class="u-detail__text" v-translate="{ enum: 'SelfAuthApplyTypeEnum' }">
  21. {{ sizeForm.applyType }}
  22. </div>
  23. </div>
  24. <div v-else>
  25. <dg-select
  26. enum="SelfAuthApplyTypeEnum"
  27. v-model="sizeForm.applyType"
  28. :disabled="type == 'edit'"
  29. @change="handleChangeApplyType"
  30. ></dg-select>
  31. </div>
  32. </el-form-item>
  33. </dg-col>
  34. <dg-col :span="12">
  35. <el-form-item label="流程名称:" prop="processName">
  36. <div v-if="isDetail">{{ sizeForm.processName }}</div>
  37. <div v-else>
  38. <el-input v-model="sizeForm.processName" :disabled="true"></el-input>
  39. </div>
  40. </el-form-item>
  41. </dg-col>
  42. <!-- <dg-col :span="12" v-if="isDetail">
  43. <el-form-item label="流程编号:" prop="businessCode">
  44. <div>{{ sizeForm.businessCode }}</div>
  45. </el-form-item>
  46. </dg-col> -->
  47. <dg-col :span="12" v-if="isDetail">
  48. <el-form-item label="审批单编号:" prop="applicantOrdNo">
  49. <div>{{ sizeForm.applicantOrdNo }}</div>
  50. </el-form-item>
  51. </dg-col>
  52. <dg-col :span="12">
  53. <!-- 流程名称+申请人姓名+日期 -->
  54. <el-form-item label="审批单标题:" prop="flowTitle">
  55. <div v-if="isDetail">{{ sizeForm.flowTitle }}</div>
  56. <div v-else>
  57. <el-input v-model="sizeForm.flowTitle" :disabled="true"></el-input>
  58. </div>
  59. </el-form-item>
  60. </dg-col>
  61. <dg-col :span="12">
  62. <el-form-item label="申请人姓名:" prop="applicantName">
  63. <div v-if="isDetail">{{ sizeForm.applicantName }}</div>
  64. <div v-else>
  65. <el-input v-model="sizeForm.applicantName" :disabled="true"></el-input>
  66. </div>
  67. </el-form-item>
  68. </dg-col>
  69. <dg-col :span="12">
  70. <el-form-item label="申请人身份证号码:" prop="applicantIdcard">
  71. <div v-if="isDetail">{{ sizeForm.applicantIdcard }}</div>
  72. <div v-else>
  73. <el-input v-model="sizeForm.applicantIdcard" :disabled="true"></el-input>
  74. </div>
  75. </el-form-item>
  76. </dg-col>
  77. <dg-col :span="12">
  78. <el-form-item label="申请人手机号码:" prop="applicantPhoneNo">
  79. <div v-if="isDetail">{{ sizeForm.applicantPhoneNo }}</div>
  80. <div v-else>
  81. <el-input v-model="sizeForm.applicantPhoneNo"></el-input>
  82. </div>
  83. </el-form-item>
  84. </dg-col>
  85. <dg-col :span="12">
  86. <el-form-item label="申请人单位代码:" prop="applicantOrgCode">
  87. <div v-if="isDetail">{{ sizeForm.applicantOrgCode }}</div>
  88. <div v-else>
  89. <el-input v-model="sizeForm.applicantOrgCode" :disabled="true"></el-input>
  90. </div>
  91. </el-form-item>
  92. </dg-col>
  93. <dg-col :span="12">
  94. <el-form-item label="申请人单位名称:" prop="applicantOrgName">
  95. <div v-if="isDetail">{{ sizeForm.applicantOrgName }}</div>
  96. <div v-else>
  97. <el-input v-model="sizeForm.applicantOrgName" :disabled="true"></el-input>
  98. </div>
  99. </el-form-item>
  100. </dg-col>
  101. <dg-col :span="12" v-if="isDetail">
  102. <el-form-item label="创建时间:">
  103. {{ sizeForm.createTime }}
  104. </el-form-item>
  105. </dg-col>
  106. <dg-col :span="12" v-if="sizeForm.applyType == 'SERVICE_AUTH'">
  107. <el-form-item label="应用方:" prop="applyId">
  108. <div v-if="isDetail">{{ sizeForm.applyId }}</div>
  109. <div v-else>
  110. <dg-select :data="appList" v-model="sizeForm.applyId"></dg-select>
  111. </div>
  112. </el-form-item>
  113. </dg-col>
  114. </dg-row>
  115. <dg-row>
  116. <dg-col :span="24">
  117. <!-- <component :is="approveComponent"></component> -->
  118. <el-form-item label="审批内容:" class="self-form-item" prop="flowContent">
  119. <div style="display: flex" v-if="!isDetail">
  120. <el-input type="textarea" :autosize="{ minRows: 5 }" :value="flowContentStr" :disabled="true"></el-input>
  121. <dg-button style="margin-left: 10px" @click="handleChoice" v-if="sizeForm.applyType">选择</dg-button>
  122. </div>
  123. <div v-else>
  124. {{ flowContentStr }}
  125. </div>
  126. </el-form-item>
  127. </dg-col>
  128. </dg-row>
  129. <dg-row>
  130. <dg-col :span="24">
  131. <el-form-item prop="applyReason" label="申请理由:">
  132. <div v-if="isDetail">
  133. {{ sizeForm.applyReason }}
  134. </div>
  135. <div v-else>
  136. <el-input
  137. v-model="sizeForm.applyReason"
  138. type="textarea"
  139. maxlength="300"
  140. show-word-limit
  141. :autosize="{ minRows: 5 }"
  142. ></el-input>
  143. </div>
  144. </el-form-item>
  145. </dg-col>
  146. <!-- 数据资源访问权限 -->
  147. <div v-if="sizeForm.applyType == 'DATA_AUTH'">
  148. <dg-col :span="13">
  149. <el-form-item label="案件/事件/线索/被查询人员类别:" prop="userType" label-width="250px">
  150. <div v-if="isDetail">{{ sizeForm.userType }}</div>
  151. <div v-else>
  152. <dg-select :data="[]" v-model="sizeForm.userType"></dg-select>
  153. </div>
  154. </el-form-item>
  155. </dg-col>
  156. <dg-col :span="13">
  157. <el-form-item label="案件/事件/线索/被查询人员姓名:" prop="userName" label-width="250px">
  158. <div v-if="isDetail">{{ sizeForm.userName }}</div>
  159. <div v-else>
  160. <el-input v-model="sizeForm.userName"></el-input>
  161. </div>
  162. </el-form-item>
  163. </dg-col>
  164. <dg-col :span="13">
  165. <el-form-item label="案件/事件/线索/被查询人员编码:" prop="userCode" label-width="250px">
  166. <div v-if="isDetail">{{ sizeForm.userCode }}</div>
  167. <div v-else>
  168. <el-input :data="[]" v-model="sizeForm.userCode"></el-input>
  169. </div>
  170. </el-form-item>
  171. </dg-col>
  172. </div>
  173. </dg-row>
  174. <dg-row>
  175. <dg-col :span="24">
  176. <el-form-item label="权限有效期:" prop="permissionValidType">
  177. <div v-if="isDetail">
  178. <span v-if="sizeForm.permissionValidType == '01'"
  179. >{{ sizeForm.startTime | dateFormatter }} 至 {{ sizeForm.endTime | dateFormatter }}</span
  180. >
  181. <span v-else>长期</span>
  182. </div>
  183. <div v-else>
  184. <dg-row>
  185. <dg-col :span="6">
  186. <dg-radio
  187. v-model="sizeForm.permissionValidType"
  188. :label="radio.code"
  189. call-off
  190. v-for="radio in shortBtns"
  191. :key="radio.code"
  192. >{{ radio.text }}</dg-radio
  193. >
  194. </dg-col>
  195. <dg-col :span="10">
  196. <dg-date-picker
  197. :start-value.sync="sizeForm.startTime"
  198. :end-value.sync="sizeForm.endTime"
  199. type="daterange"
  200. range-separator="至"
  201. start-placeholder="开始日期"
  202. end-placeholder="结束日期"
  203. value-format="yyyy-MM-dd HH:mm:ss"
  204. :default-time="['00:00:00', '23:59:59']"
  205. v-show="sizeForm.permissionValidType !== '02'"
  206. :picker-options="pickerOptions"
  207. clearable
  208. :unlink-panels="true"
  209. >
  210. </dg-date-picker>
  211. </dg-col>
  212. </dg-row>
  213. </div>
  214. </el-form-item>
  215. </dg-col>
  216. </dg-row>
  217. <!-- v1.0.0不实现 -->
  218. <!-- <dg-row>
  219. <dg-col :span="12">
  220. <el-form-item label="附件:">
  221. <div v-if="!isDetail">
  222. <p v-for="item in sizeForm.fj" :key="item.url">
  223. <dg-button type="text" class="dg-color-text-65" @click="handleDownLoad(item)"
  224. ><i class="icon iconfont iconl-link dg-color-text-25"></i>
  225. {{ item.name }}</dg-button
  226. >
  227. </p>
  228. </div>
  229. <div v-else>
  230. <dg-upload
  231. ref="upload"
  232. list-type="button"
  233. action="http://192.168.10.14:7300/mock/5d0a8c81e711b09fc48914c0/example/upload"
  234. :on-remove="handleFileRemove"
  235. :before-remove="beforeFileRemove"
  236. multiple
  237. :on-exceed="handleFileExceed"
  238. :on-success="handleFileSuccess"
  239. size="5m"
  240. v-model="sizeForm.fj"
  241. >
  242. </dg-upload>
  243. </div>
  244. </el-form-item>
  245. </dg-col>
  246. </dg-row> -->
  247. </el-form>
  248. <div v-footer>
  249. <div v-if="type !== 'detail'">
  250. <dg-button @click="handleCancel">取消</dg-button>
  251. <!-- <dg-button type="primary" @click="handleSave">保存</dg-button> -->
  252. <dg-button type="primary" @click="handleSubmit">提交</dg-button>
  253. </div>
  254. </div>
  255. </div>
  256. </template>
  257. <script>
  258. import { checkPhone } from '@/utils/regular';
  259. import appFuncForm from './app-func-form.vue';
  260. import serviceSourceForm from './service-source-form.vue';
  261. import dataSourceForm from './data-source-form.vue';
  262. import moment from 'moment';
  263. import * as Api from '@/api/permission-selfhelp-manage';
  264. export default {
  265. name: 'FormItem',
  266. // 接收父页面传过来的属性
  267. props: {
  268. applyOrdNo: [String],
  269. type: {
  270. type: String
  271. }
  272. },
  273. // 页面数据绑定
  274. data() {
  275. // 验证手机号码
  276. const checkPhoneValid = (rule, val, callback) => {
  277. if (!val) {
  278. return callback(new Error('请输入手机号码'));
  279. }
  280. if (val && !checkPhone(val)) {
  281. return callback(new Error('请输入正确格式的手机号码'));
  282. }
  283. callback();
  284. };
  285. // 验证有效期间
  286. const checkPermissionValid = (rule, val, callback) => {
  287. if (val == '01') {
  288. if (!this.sizeForm.startTime && !this.sizeForm.endTime) {
  289. return callback(new Error('请选择开始时间和结束时间'));
  290. } else {
  291. callback();
  292. }
  293. } else {
  294. callback();
  295. }
  296. };
  297. return {
  298. sizeForm: {},
  299. approveComponent: 'appFuncForm',
  300. rules: {
  301. flowContent: { required: true, message: '请选择审批内容', trigger: 'change' },
  302. applyType: { required: true, message: '请选择审批类型', trigger: 'change' },
  303. flowTitle: { required: true, message: '请输入审批单标题', trigger: 'change' },
  304. applicantName: { required: true, message: '请输入申请人姓名', trigger: 'change' },
  305. applicantIdcard: { required: true, message: '请输入申请人身份证号码', trigger: 'change' },
  306. applicantOrgCode: { required: true, message: '请输入申请人单位代码', trigger: 'change' },
  307. applicantOrgName: { required: true, message: '请输入申请人单位名称', trigger: 'change' },
  308. processName: { required: true, message: '请输入流程名称', trigger: 'change' },
  309. applyReason: [{ required: true, message: '请输入申请理由', trigger: 'change' }],
  310. applicantPhoneNo: [
  311. { required: true, message: '请输入申请人电话号码', trigger: 'change' },
  312. { validator: checkPhoneValid, trigger: 'change' }
  313. ],
  314. permissionValidType: { required: true, validator: checkPermissionValid, trigger: 'change' },
  315. applyId: [{ required: true, message: '请选择应用方', trigger: 'change' }], // 应用方
  316. userName: [{ required: true, message: '请输入人员名称', trigger: 'change' }],
  317. userType: [{ required: true, message: '请选择人员类型', trigger: 'change' }],
  318. userCode: [{ required: true, message: '请输入人员编号', trigger: 'change' }]
  319. },
  320. shortBtns: [
  321. {
  322. text: '自定义',
  323. time: '01',
  324. code: '01'
  325. },
  326. {
  327. text: '长期',
  328. time: '02',
  329. code: '02'
  330. }
  331. ],
  332. pickerOptions: {
  333. disabledDate(currentDate) {
  334. return currentDate.getTime() < Date.now() - 8.64e7;
  335. }
  336. },
  337. applySelectKeys: [],
  338. appList: [
  339. {
  340. value: '测试应用',
  341. label: '测试应用'
  342. }
  343. ],
  344. applyContentCom: appFuncForm,
  345. show: false,
  346. applyContentOperateObj: {
  347. 'function-auth-apply': {
  348. applyText: '申请访问资源:',
  349. cancelText: '申请撤销资源:'
  350. },
  351. 'service-auth-apply': {
  352. applyText: '申请服务:',
  353. cancelText: '申请撤销服务:'
  354. }
  355. },
  356. needFilter: true
  357. };
  358. },
  359. components: {},
  360. computed: {
  361. isDetail() {
  362. return this.type == 'detail';
  363. },
  364. flowContentStr() {
  365. let str = '';
  366. if (this.sizeForm.flowContent) {
  367. const { visitorName, visitResourceName, cancelResourceName } = JSON.parse(this.sizeForm.flowContent);
  368. const { applyText, cancelText } = this.applyContentOperateObj[this.sizeForm.businessCode] || {};
  369. const applyContent = visitResourceName ? `${applyText}${visitResourceName}。\n` : '';
  370. const cancelContent = cancelResourceName ? `${cancelText}${cancelResourceName}。` : '';
  371. str = `${visitorName}${applyContent}${cancelContent}`;
  372. }
  373. return str;
  374. }
  375. },
  376. watch: {
  377. 'sizeForm.applyType': {
  378. handler(val) {
  379. let component;
  380. if (val == 'DATA_AUTH') {
  381. component = dataSourceForm;
  382. } else if (val == 'SERVICE_AUTH') {
  383. component = serviceSourceForm;
  384. } else {
  385. component = appFuncForm;
  386. }
  387. this.applyContentCom = component;
  388. }
  389. }
  390. },
  391. methods: {
  392. // 获取流程名称
  393. getProcessName(val) {
  394. Api.getFlowDefine(val).then((res) => {
  395. const { content, result, msg } = res.data;
  396. if (result == '200') {
  397. this.sizeForm.processName = content.processName;
  398. this.sizeForm.businessCode = content.businessCode;
  399. this.sizeForm.processType = content.processTypeCode;
  400. // 审批单标题 = 流程名称 + 申请人姓名 + 日期
  401. this.sizeForm.flowTitle = `${content.processName}-${this.sizeForm.applicantName}-${moment().format(
  402. 'YYYY-MM-DD'
  403. )}`;
  404. } else {
  405. this.$message.warning(msg);
  406. }
  407. });
  408. },
  409. // 切换审批类型,清空审批内容
  410. handleChangeApplyType(val) {
  411. this.sizeForm.flowContent = '';
  412. this.sizeForm.resourceInfos = [];
  413. this.applySelectKeys = [];
  414. this.getProcessName(val);
  415. },
  416. // 取消/关闭
  417. handleCancel() {
  418. this.$emit('close');
  419. },
  420. // 保存
  421. handleSave() {
  422. if (this.sizeForm.applyType !== 'APP_FUN_AUTH') return;
  423. this.sizeForm.operateType = '1';
  424. this.save();
  425. },
  426. // 提交
  427. handleSubmit() {
  428. if (this.sizeForm.applyType == 'APP_FUN_AUTH' || !this.sizeForm.applyType) {
  429. this.$refs.ruleForm.validate((valid) => {
  430. if (valid) {
  431. this.sizeForm.operateType = '2';
  432. this.save();
  433. }
  434. });
  435. }
  436. },
  437. save() {
  438. const { resourceInfos, applyId, userType, userName, userCode, ...otherInfo } = this.sizeForm;
  439. let params = {
  440. resourceInfos
  441. };
  442. let api = '';
  443. if (this.type == 'add') {
  444. params['workFlow'] = otherInfo;
  445. api = 'savePermissionApply';
  446. } else {
  447. const { permissionValidType, operateType, applicantPhoneNo, applyReason, startTime, endTime, flowContent } =
  448. this.sizeForm;
  449. // 只选可编辑的字段
  450. params = {
  451. resourceInfos,
  452. permissionValidType,
  453. operateType,
  454. applicantPhoneNo,
  455. applyReason,
  456. startTime,
  457. endTime,
  458. flowContent,
  459. applyOrdNo: this.applyOrdNo
  460. };
  461. api = 'updateApply';
  462. }
  463. Api[api](params).then((res) => {
  464. if (this.sizeForm.operateType == '2') {
  465. this.$message.success('提交成功!');
  466. } else {
  467. this.$message.success('保存成功!');
  468. }
  469. this.$emit('success');
  470. });
  471. },
  472. // 选择
  473. handleChoice() {
  474. const vm = this;
  475. // const keys = [...this.applySelectKeys, ...this.sizeForm.resourceInfos.map((item) => item.funId)];
  476. const layer = this.$dgLayer({
  477. title: '选择资源',
  478. shadow: [0.4, '#fff'],
  479. props: {
  480. selectKeys: this.applySelectKeys,
  481. needFilter: this.needFilter,
  482. type: this.type
  483. },
  484. content: this.applyContentCom,
  485. area: ['1200px', '700px'],
  486. on: {
  487. success(visitResourceName, cancelResourceName, selectKeys, resourceInfos = []) {
  488. vm.sizeForm.resourceInfos = resourceInfos;
  489. vm.applySelectKeys = selectKeys;
  490. const visitorName =
  491. vm.sizeForm.applyType !== 'SERVICE_AUTH' ? vm.sizeForm.applicantName : vm.sizeForm.applyId;
  492. const resourceObj = { visitorName, visitResourceName, cancelResourceName };
  493. vm.sizeForm.flowContent = JSON.stringify(resourceObj);
  494. vm.needFilter = false;
  495. layer.close(layer.dialogIndex);
  496. },
  497. close() {
  498. layer.close(layer.dialogIndex);
  499. }
  500. }
  501. });
  502. },
  503. /**
  504. * 下载附件
  505. */
  506. handleDownLoad(item) {},
  507. /**
  508. * 文件列表移除文件时,sizebool false为文件超出
  509. */
  510. handleFileRemove(file, fileList) {
  511. console.log(file, fileList);
  512. },
  513. /**
  514. * 文件上传成功
  515. */
  516. handleFileSuccess(response, file, fileList) {
  517. console.log(response, file, fileList);
  518. },
  519. /**
  520. * 文件超出个数限制时
  521. */
  522. handleFileExceed(files, fileList) {
  523. this.$message.warning(
  524. `当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`
  525. );
  526. },
  527. /**
  528. * 删除文件之前,参数为上传的文件和文件列表,若返回 false 或者返回 Promise 且被 reject,则停止删除。
  529. */
  530. beforeFileRemove(file, fileList, sizeBool) {
  531. if (sizeBool === false) {
  532. return;
  533. }
  534. return this.$confirm(`确定移除 ${file.name}?`);
  535. },
  536. getDetail() {
  537. const params = {
  538. applyOrdNo: this.applyOrdNo,
  539. needFlowInfo: true
  540. };
  541. Api.applyDetail(params).then((res) => {
  542. const { workFlow, resourceInfos, ...otherInfo } = res.data.content;
  543. this.sizeForm = {
  544. ...workFlow,
  545. resourceInfos,
  546. ...otherInfo
  547. };
  548. this.applySelectKeys = this.sizeForm.resourceInfos.map((item) => item.funId);
  549. this.show = true;
  550. });
  551. }
  552. },
  553. created() {
  554. const { name, idcard, securityOrgs, securityOrgName, mobile, id } = this.$store.getters.user;
  555. if (!this.applyOrdNo) {
  556. this.sizeForm = {
  557. flowTitle: '',
  558. applicantIdcard: idcard,
  559. applicantName: name,
  560. applicantOrgCode: securityOrgs[0],
  561. applicantOrgName: securityOrgName,
  562. applicantPhoneNo: mobile,
  563. flowContent: '',
  564. applyReason: '',
  565. businessCode: '',
  566. processType: '',
  567. operateType: '', // 1--保存 2--提交
  568. applyType: '',
  569. processName: '',
  570. permissionValidType: '02',
  571. startTime: '',
  572. endTime: '',
  573. resourceInfos: [],
  574. applyId: '', // 应用方
  575. userType: '',
  576. userName: '',
  577. userCode: ''
  578. };
  579. this.show = true;
  580. } else {
  581. this.getDetail();
  582. if (this.type == 'detail') {
  583. this.rules = {};
  584. }
  585. }
  586. },
  587. mounted() {}
  588. };
  589. </script>
  590. <style scoped lang="scss">
  591. // @import './index.scss';
  592. </style>