index.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. <template>
  2. <u-form class="jnpf-wrap-form" ref="dataForm" :rules="rules" :model="formData" :errorType="['toast']"
  3. :label-position="formConf.labelPosition==='top'?'top':'left'"
  4. :label-width="formConf.labelWidth?formConf.labelWidth*1.5:150"
  5. :label-align="formConf.labelPosition==='right'?'right':'left'" :class="formClass+' '+formConfCopy.className">
  6. <view v-for="(item, index) in formConfCopy.fields" :key="item.__config__.renderKey">
  7. <Item v-if="!item.__config__.noShow && item.__config__.isVisibility" :itemData="item" :formConf="formConf"
  8. :formData="formData" :ref="'ref'+item.__config__.formId" :class="item.__config__.className"
  9. @clickIcon='clickIcon' @clickFun="onClick" @collapse-change="onCollapseChange" @tab-change="onTabChange"
  10. @input="setValue" />
  11. </view>
  12. <u-modal v-model="showTipsModal" width='70%' border-radius="16" :content-style="contentStyle"
  13. :content="tipsContent" :titleStyle="titleStyle" :title="tipsTitle" :confirm-style="confirmStyle"
  14. :confirm-text="$t('common.okText')" />
  15. </u-form>
  16. </template>
  17. <script>
  18. import Item from './Item'
  19. import {
  20. getDataInterfaceRes,
  21. getDictionaryDataSelector
  22. } from '@/api/common'
  23. const dyOptionsList = ['radio', 'checkbox', 'select', 'cascader', 'treeSelect']
  24. export default {
  25. components: {
  26. Item
  27. },
  28. props: {
  29. formConf: {
  30. type: Object,
  31. required: true
  32. },
  33. loading: {
  34. type: Boolean,
  35. default: false
  36. },
  37. isShortLink: {
  38. type: Boolean,
  39. default: false
  40. },
  41. },
  42. data() {
  43. const data = {
  44. formClass: 'form-' + this.jnpf.idGenerator(),
  45. formConfCopy: this.$u.deepClone(this.formConf),
  46. formData: {},
  47. rules: {},
  48. options: {},
  49. tableRefs: {},
  50. relations: {},
  51. refList: [],
  52. contentStyle: {
  53. fontSize: '28rpx',
  54. padding: '20rpx',
  55. lineHeight: '44rpx',
  56. textAlign: 'left'
  57. },
  58. titleStyle: {
  59. padding: '20rpx'
  60. },
  61. confirmStyle: {
  62. height: '80rpx',
  63. lineHeight: '80rpx',
  64. },
  65. tipsContent: '',
  66. tipsTitle: this.$t('common.tipTitle'),
  67. showTipsModal: false
  68. }
  69. this.beforeInit(data.formConfCopy.fields)
  70. this.initRelationForm(data.formConfCopy.fields)
  71. this.initFormData(data.formConfCopy.fields, data.formData, data.tableRefs)
  72. this.buildRules(this.$u.deepClone(data.formConfCopy.fields), data.rules)
  73. this.buildOptions(data.formConfCopy.fields, data.options, data.formData)
  74. this.buildRelations(data.formConfCopy.fields, data.relations)
  75. this.$nextTick(() => {
  76. this.onLoadFunc(data.formConfCopy)
  77. this.getRefList()
  78. })
  79. return data
  80. },
  81. provide() {
  82. return {
  83. parameter: this.parameter,
  84. relations: this.relations,
  85. isShortLink: this.isShortLink
  86. }
  87. },
  88. computed: {
  89. parameter() {
  90. const oldFormData = this.formConfCopy.formData ? this.formConfCopy.formData : {}
  91. this.formData.id = oldFormData.id || null
  92. this.formData.flowId = oldFormData.flowId || ''
  93. return {
  94. formData: this.formData,
  95. setFormData: this.setFormData,
  96. setShowOrHide: this.setShowOrHide,
  97. setRequired: this.setRequired,
  98. setDisabled: this.setDisabled,
  99. onlineUtils: this.jnpf.onlineUtils,
  100. }
  101. }
  102. },
  103. mounted() {
  104. this.$refs.dataForm.setRules(this.rules);
  105. this.initRelationData()
  106. uni.$on('subChange', (field) => {
  107. this.handleRelation(field.__vModel__)
  108. })
  109. this.initCss(this.formConfCopy)
  110. },
  111. methods: {
  112. beforeInit(fields) {
  113. const loop = (list) => {
  114. for (var index = 0; index < list.length; index++) {
  115. const config = list[index].__config__
  116. if (config.children && config.children.length) loop(config.children)
  117. if (config.jnpfKey == 'tableGrid') {
  118. let newList = []
  119. for (var i = 0; i < config.children.length; i++) {
  120. let element = config.children[i]
  121. for (var j = 0; j < element.__config__.children.length; j++) {
  122. let item = element.__config__.children[j]
  123. newList.push(...item.__config__.children)
  124. }
  125. }
  126. list.splice(index, 1, ...newList)
  127. }
  128. }
  129. }
  130. loop(fields)
  131. },
  132. initRelationForm(componentList) {
  133. componentList.forEach(cur => {
  134. const config = cur.__config__
  135. if (config.jnpfKey == 'relationFormAttr' || config.jnpfKey == 'popupAttr') {
  136. const relationKey = cur.relationField.split("_jnpfTable_")[0]
  137. componentList.forEach(item => {
  138. const noVisibility = Array.isArray(item.__config__.visibility) && !item
  139. .__config__.visibility.includes('app')
  140. if ((relationKey == item.__vModel__) && (noVisibility || !!item.__config__
  141. .noShow) && !cur.__vModel__) {
  142. cur.__config__.noShow = true
  143. }
  144. })
  145. }
  146. if (cur.__config__.children && cur.__config__.children.length) this.initRelationForm(cur
  147. .__config__.children)
  148. })
  149. },
  150. initFormData(componentList, formData, tableRefs) {
  151. componentList.forEach(cur => {
  152. const config = cur.__config__
  153. if (cur.__vModel__) {
  154. formData[cur.__vModel__] = config.defaultValue
  155. if (cur.__config__.jnpfKey == 'table' && !cur.__config__.noShow) {
  156. tableRefs[cur.__vModel__] = cur
  157. }
  158. }
  159. if (config.children && cur.__config__.jnpfKey !== 'table') {
  160. this.initFormData(config.children, formData, tableRefs)
  161. }
  162. })
  163. },
  164. buildOptions(componentList, data, formData) {
  165. componentList.forEach(cur => {
  166. const config = cur.__config__
  167. if (dyOptionsList.indexOf(config.jnpfKey) > -1) {
  168. if (config.dataType === 'dictionary' && config.dictionaryType) {
  169. cur.options = []
  170. getDictionaryDataSelector(config.dictionaryType).then(res => {
  171. cur.options = res.data.list || []
  172. data[cur.__vModel__ + 'Options'] = cur.options
  173. this.setFieldOptions(cur.__vModel__, cur.options)
  174. this.$nextTick(() => {
  175. uni.$emit("initCollapse")
  176. })
  177. })
  178. } else if (config.dataType === 'dynamic' && config.propsUrl) {
  179. cur.options = []
  180. let query = {
  181. paramList: this.jnpf.getParamList(config.templateJson, formData),
  182. }
  183. getDataInterfaceRes(config.propsUrl, query).then(res => {
  184. cur.options = Array.isArray(res.data) ? res.data : []
  185. data[cur.__vModel__ + 'Options'] = cur.options
  186. this.setFieldOptions(cur.__vModel__, cur.options)
  187. uni.$emit("initCollapse")
  188. })
  189. } else {
  190. data[cur.__vModel__ + 'Options'] = cur.options
  191. }
  192. }
  193. if (config.children && config.jnpfKey !== 'table') this.buildOptions(config.children, data,
  194. formData)
  195. })
  196. },
  197. buildRules(componentList, rules) {
  198. componentList.forEach(cur => {
  199. const config = cur.__config__
  200. const jnpfKey = config.jnpfKey
  201. const useNumList = ['inputNumber', 'switch', 'datePicker', 'rate', 'slider', 'calculate']
  202. const useArrayList = ['select', 'posSelect', 'userSelect', 'treeSelect', 'popupTableSelect',
  203. 'organizeSelect'
  204. ]
  205. config.regList = !config.regList ? [] : config.regList
  206. if (config.required) {
  207. const label = config.labelI18nCode ?
  208. this.$t(config.labelI18nCode, config.label) : config.label;
  209. let requiredItem = {
  210. required: config.required,
  211. message: `${label} ${this.$t('sys.validate.textRequiredSuffix')}`
  212. };
  213. config.regList.push(requiredItem)
  214. }
  215. const rule = config.regList.map(item => {
  216. if (item.pattern) {
  217. item.pattern = item.pattern.toString()
  218. let start = item.pattern.indexOf('/')
  219. let stop = item.pattern.lastIndexOf('/')
  220. let str = item.pattern.substring(start + 1, stop)
  221. let reg = new RegExp(str)
  222. item.pattern = reg
  223. }
  224. item.trigger = config.trigger || 'change, blur'
  225. if (Array.isArray(config.defaultValue)) item.type = 'array'
  226. if (useNumList.includes(jnpfKey)) item.type = 'number'
  227. if (useArrayList.includes(jnpfKey) && cur.multiple) item.type = 'array'
  228. if (jnpfKey === 'usersSelect' || jnpfKey === 'areaSelect' || jnpfKey ===
  229. 'checkbox' || jnpfKey === 'cascader') item.type = 'array'
  230. if (jnpfKey === 'relationForm' || jnpfKey === 'popupSelect' || jnpfKey ===
  231. 'select' || jnpfKey === 'radio' || jnpfKey === 'treeSelect') {
  232. item.type = 'any',
  233. item.validator = (rule, value, callback) => {
  234. if (value || value === 0) {
  235. callback();
  236. } else {
  237. callback(new Error(config.label + '不能为空'));
  238. }
  239. }
  240. }
  241. if (item.messageI18nCode) {
  242. item.message = this.$t(item.messageI18nCode, item.message);
  243. }
  244. return item
  245. })
  246. if (rule.length) rules[cur.__vModel__] = rule
  247. if (config.children && jnpfKey !== 'table') this.buildRules(this.$u.deepClone(config.children),
  248. rules)
  249. })
  250. },
  251. /**
  252. * cur 对象
  253. * relationField 关联的数据项
  254. * relations 包含所有相关的配置信息
  255. * opType 类型
  256. **/
  257. addRelationItem(cur, relationField, relations, opType) {
  258. let realVModel = cur.__config__.isSubTable ? `${cur.__config__.parentVModel}-${cur.__vModel__}` : cur
  259. .__vModel__;
  260. let item = {
  261. ...cur,
  262. realVModel,
  263. opType
  264. };
  265. if (relations.hasOwnProperty(relationField)) {
  266. if (!relations[relationField].some(o => o.realVModel === item.realVModel)) {
  267. relations[relationField].push(item);
  268. }
  269. } else {
  270. relations[relationField] = [item];
  271. }
  272. },
  273. /**
  274. * config 对象
  275. * type 开始或者结束类型
  276. * target 目标字段
  277. * value 开始或者结束时间值
  278. **/
  279. processTimeRule(config, type, target, value) {
  280. let time;
  281. switch (type) {
  282. case 1:
  283. return value || (type === 'startTime' ? '00:00:00' : '23:59:59');
  284. case 3:
  285. return this.jnpf.toDate(new Date(), config.format === 'HH:mm' ? 'HH:mm:00' : config.format);
  286. default:
  287. let offset = Number(value);
  288. if (target === 1) {
  289. time = new Date().setHours(type === 4 ? new Date().getHours() - offset : new Date()
  290. .getHours() + offset);
  291. } else if (target === 2) {
  292. time = new Date().setMinutes(type === 4 ? new Date().getMinutes() - offset : new Date()
  293. .getMinutes() + offset);
  294. } else if (target === 3) {
  295. time = new Date().setSeconds(type === 4 ? new Date().getSeconds() - offset : new Date()
  296. .getSeconds() + offset);
  297. }
  298. return this.$u.timeFormat(time, 'hh:MM:ss');
  299. }
  300. },
  301. /**
  302. * type 开始或者结束类型
  303. * target 目标字段
  304. * value 开始或者结束时间值
  305. **/
  306. calculateDateOffset(type, value, target) {
  307. let date = new Date();
  308. switch (type) {
  309. case 1:
  310. return Number(value);
  311. case 3:
  312. return date.getTime();
  313. default:
  314. let offset = Number(value);
  315. if (target === 1) {
  316. date.setFullYear(date.getFullYear() + (type === 4 ? -offset : offset));
  317. } else if (target === 2) {
  318. date.setMonth(date.getMonth() + (type === 4 ? -offset : offset));
  319. } else if (target === 3) {
  320. date.setDate(date.getDate() + (type === 4 ? -offset : offset));
  321. }
  322. return date.getTime();
  323. }
  324. },
  325. buildRelations(componentList, relations) {
  326. const selectType = ['org', 'pos', 'role', 'group'];
  327. componentList.forEach(cur => {
  328. const config = cur.__config__;
  329. const vModel = cur.__vModel__;
  330. if (config.jnpfKey === 'userSelect' && selectType.includes(cur.selectType)) {
  331. if (cur.relationField) this.addRelationItem(cur, cur.relationField, relations,
  332. 'setUserOptions');
  333. }
  334. if (dyOptionsList.indexOf(config.jnpfKey) > -1 && config.dataType === 'dynamic' && config
  335. .templateJson && config.templateJson.length) {
  336. config.templateJson.forEach(e => {
  337. if (e.relationField) this.addRelationItem(cur, e.relationField, relations,
  338. 'setOptions');
  339. });
  340. }
  341. if (config.jnpfKey === 'datePicker') {
  342. if (config.startTimeRule) cur.startTime = this.calculateDateOffset(config.startTimeType,
  343. config.startTimeValue, config.startTimeTarget);
  344. if (config.endTimeRule) cur.endTime = this.calculateDateOffset(config.endTimeType,
  345. config.endTimeValue, config.endTimeTarget);
  346. if (config.startRelationField) this.addRelationItem(cur, config.startRelationField,
  347. relations, 'setDate');
  348. if (config.endRelationField) this.addRelationItem(cur, config.endRelationField, relations,
  349. 'setDate');
  350. }
  351. if (config.jnpfKey === 'timePicker') {
  352. if (config.startTimeRule) cur.startTime = this.processTimeRule(config,
  353. config.startTimeType, config.startTimeTarget, config.startTimeValue);
  354. if (config.endTimeRule) cur.endTime = this.processTimeRule(config, config.endTimeType,
  355. config.endTimeTarget, config.endTimeValue);
  356. if (config.startRelationField) this.addRelationItem(cur, config.startRelationField,
  357. relations, 'setTime');
  358. if (config.endRelationField) this.addRelationItem(cur, config.endRelationField, relations,
  359. 'setTime');
  360. }
  361. if (config.jnpfKey === 'popupSelect' && cur.templateJson && cur.templateJson.length) {
  362. cur.templateJson.forEach(e => {
  363. if (e.relationField) this.addRelationItem(cur, e.relationField, relations,
  364. 'setPopupOptions');
  365. });
  366. }
  367. if (config.children) this.buildRelations(config.children, relations);
  368. });
  369. },
  370. onLoadFunc(formConfCopy) {
  371. if (!formConfCopy || !formConfCopy.funcs || !formConfCopy.funcs.onLoad) return
  372. const onLoadFunc = this.jnpf.getScriptFunc(formConfCopy.funcs.onLoad)
  373. if (!onLoadFunc) return
  374. onLoadFunc(this.parameter)
  375. },
  376. initRelationData() {
  377. const handleRelationFun = (list) => {
  378. list.forEach(cur => {
  379. const config = cur.__config__
  380. this.handleDefaultRelation(cur.__vModel__)
  381. if (config.children) handleRelationFun(config.children)
  382. })
  383. }
  384. handleRelationFun(this.formConfCopy.fields)
  385. },
  386. initCss(formCopy) {
  387. // #ifdef H5
  388. if (!formCopy.classJson) return
  389. if (document.getElementById('styleId')) document.getElementById('styleId').remove()
  390. let head = document.getElementsByTagName('head')[0]
  391. let style = document.createElement('style')
  392. style.type = 'text/css'
  393. style.id = 'styleId'
  394. style.innerText = this.buildCSS(formCopy.classJson)
  395. head.appendChild(style)
  396. //#endif
  397. },
  398. buildCSS(str) {
  399. str = str.trim();
  400. let newStr = '';
  401. let cut = str.split('}');
  402. cut.forEach(item => {
  403. if (item) {
  404. item = '.' + this.formClass + ' ' + item + '}';
  405. newStr += item;
  406. }
  407. });
  408. return newStr;
  409. },
  410. handleRelation(field) {
  411. if (!field) return
  412. const currRelations = this.relations
  413. for (let key in currRelations) {
  414. if (key === field) {
  415. for (let i = 0; i < currRelations[key].length; i++) {
  416. const e = currRelations[key][i];
  417. let vModel = e.realVModel || e.__vModel__
  418. const config = e.__config__
  419. const jnpfKey = config.jnpfKey
  420. let defaultValue = ''
  421. if (['checkbox', 'cascader'].includes(jnpfKey) || (['select', 'treeSelect', 'popupSelect',
  422. 'popupTableSelect', 'userSelect'
  423. ].includes(jnpfKey) && e.multiple)) {
  424. defaultValue = []
  425. }
  426. if (vModel.includes('-')) { // 子表字段
  427. const tableVModel = vModel.split('-')[0]
  428. uni.$emit('handleRelation', e, defaultValue, true)
  429. } else {
  430. this.setFormData(vModel, defaultValue)
  431. if (e.opType === 'setOptions') {
  432. let query = {
  433. paramList: this.jnpf.getParamList(config.templateJson, this.formData)
  434. }
  435. getDataInterfaceRes(config.propsUrl, query).then(res => {
  436. let realData = res.data || []
  437. this.setFieldOptions(vModel, realData)
  438. uni.$emit("initCollapse")
  439. })
  440. }
  441. if (e.opType === 'setUserOptions') {
  442. let value = this.formData[e.relationField] || []
  443. this.comSet('ableRelationIds', vModel, Array.isArray(value) ? value : [value])
  444. }
  445. if (e.opType === 'setDate' || e.opType === 'setTime') {
  446. let startTime = ''
  447. let endTime = ''
  448. if (config.startTimeType == 2) {
  449. startTime = this.formData[config.startRelationField] || 0
  450. if (e.opType === 'setTime') {
  451. startTime = this.formData[config.startRelationField] ||
  452. '00:00:00'
  453. if (startTime && (startTime.split(':').length == 3)) {
  454. startTime = startTime
  455. } else {
  456. startTime = startTime + ':00'
  457. }
  458. }
  459. } else {
  460. startTime = e.startTime
  461. }
  462. if (config.endTimeType == 2) {
  463. endTime = this.formData[config.endRelationField] || 0
  464. if (e.opType === 'setTime') {
  465. endTime = this.formData[config.endRelationField] ||
  466. '00:00:00'
  467. if (endTime && (endTime.split(':').length == 3)) {
  468. endTime = endTime
  469. } else {
  470. endTime = endTime + ':00'
  471. }
  472. }
  473. } else {
  474. endTime = e.endTime
  475. }
  476. this.comSet('startTime', vModel, startTime)
  477. this.comSet('endTime', vModel, endTime)
  478. }
  479. }
  480. }
  481. }
  482. }
  483. },
  484. handleDefaultRelation(field) {
  485. if (!field) return
  486. const currRelations = this.relations
  487. for (let key in currRelations) {
  488. if (key === field) {
  489. for (let i = 0; i < currRelations[key].length; i++) {
  490. const e = currRelations[key][i];
  491. let vModel = e.realVModel || e.__vModel__
  492. const config = e.__config__
  493. let defaultValue = ''
  494. if (vModel.includes('-')) { // 子表字段
  495. const tableVModel = vModel.split('-')[0]
  496. uni.$emit('handleRelation', e, defaultValue)
  497. } else {
  498. if (e.opType === 'setUserOptions') {
  499. let value = this.formData[e.relationField] || []
  500. this.comSet('ableRelationIds', e.__vModel__, Array.isArray(value) ? value : [value])
  501. }
  502. if (e.opType === 'setDate' || e.opType === 'setTime') {
  503. let startTime = ''
  504. let endTime = ''
  505. if (config.startTimeType == 2) {
  506. startTime = this.formData[config.startRelationField] || 0
  507. if (e.opType === 'setTime') {
  508. startTime = this.formData[config.startRelationField] ||
  509. '00:00:00'
  510. if (startTime && (startTime.split(':').length == 3)) {
  511. startTime = startTime
  512. } else {
  513. startTime = startTime + ':00'
  514. }
  515. }
  516. } else {
  517. startTime = e.startTime
  518. }
  519. if (config.endTimeType == 2) {
  520. endTime = this.formData[config.endRelationField] || 0
  521. if (e.opType === 'setTime') {
  522. endTime = this.formData[config.endRelationField] ||
  523. '23:59:59'
  524. if (endTime && (endTime.split(':').length == 3)) {
  525. endTime = endTime
  526. } else {
  527. endTime = endTime + ':00'
  528. }
  529. }
  530. } else {
  531. endTime = e.endTime
  532. }
  533. this.comSet('startTime', e.__vModel__, startTime)
  534. this.comSet('endTime', e.__vModel__, endTime)
  535. }
  536. }
  537. }
  538. }
  539. }
  540. },
  541. onChange(field) {
  542. this.handleRelation(field.__vModel__)
  543. },
  544. setValue(item) {
  545. if (item.__vModel__) {
  546. this.$set(this.formData, item.__vModel__, item.__config__.defaultValue)
  547. }
  548. },
  549. setFormData(prop, value) {
  550. if (!prop || this.formData[prop] === value) return;
  551. const isChildTable = prop.indexOf('.') > -1
  552. if (isChildTable) {
  553. const list = prop.split('.')
  554. for (let i = 0; i < this.refList.length; i++) {
  555. const item = this.refList[i]
  556. if (item[0] == list[0]) {
  557. const tableRef = Array.isArray(item[1]) ? item[1][0] : item[1]
  558. tableRef.setTableFormData(list[1], value)
  559. break
  560. }
  561. }
  562. } else {
  563. this.comSet('defaultValue', prop, value)
  564. this.formData[prop] = value
  565. }
  566. this.handleRelation(prop)
  567. },
  568. setShowOrHide(prop, value) {
  569. const newVal = !!value
  570. const isChildTable = prop.indexOf('.') > -1
  571. if (!isChildTable) {
  572. this.comSet('noShow', prop, !newVal)
  573. }
  574. },
  575. setRequired(prop, value) {
  576. const newVal = !!value
  577. const isChildTable = prop.indexOf('.') > -1
  578. if (!isChildTable) {
  579. this.comSet('required', prop, newVal)
  580. this.rules = {}
  581. this.buildRules(this.$u.deepClone(this.formConfCopy.fields), this.rules)
  582. this.$refs.dataForm.setRules(this.rules);
  583. }
  584. },
  585. setDisabled(prop, value) {
  586. const newVal = !!value
  587. const isChildTable = prop.indexOf('.') > -1
  588. if (!isChildTable) {
  589. this.comSet('disabled', prop, newVal)
  590. }
  591. },
  592. setFieldOptions(prop, value) {
  593. const newVal = Array.isArray(value) ? value : []
  594. const isChildTable = prop.indexOf('.') > -1
  595. if (!isChildTable) {
  596. this.comSet('options', prop, newVal)
  597. }
  598. },
  599. comSet(field, prop, value) {
  600. if (!prop) return
  601. const loop = list => {
  602. for (let i = 0; i < list.length; i++) {
  603. let item = list[i]
  604. const config = item.__config__
  605. if (item.__vModel__ && item.__vModel__ === prop) {
  606. config.defaultValue = this.formData[prop]
  607. switch (field) {
  608. case 'disabled':
  609. item[field] = value
  610. break;
  611. case 'ableRelationIds':
  612. this.$set(item, field, value)
  613. case 'options':
  614. if (dyOptionsList.indexOf(config.jnpfKey) > -1) item.options = value
  615. break;
  616. case 'startTime':
  617. this.$set(item, field, value)
  618. break;
  619. case 'endTime':
  620. this.$set(item, field, value)
  621. break;
  622. default:
  623. config[field] = value
  624. this.setValue(item)
  625. break;
  626. }
  627. config.renderKey = +new Date() + item.__vModel__
  628. break;
  629. }
  630. if (config && config.jnpfKey !== 'table' && config.children && Array.isArray(config
  631. .children)) loop(config.children)
  632. }
  633. }
  634. loop(this.formConfCopy.fields)
  635. },
  636. submitForm() {
  637. try {
  638. this.beforeSubmit().then(() => {
  639. this.submit()
  640. })
  641. } catch (e) {
  642. this.submit()
  643. }
  644. },
  645. submit() {
  646. this.$refs.dataForm.validate(valid => {
  647. if (!valid) return
  648. if (!this.checkTableData()) return
  649. this.$emit('submit', this.formData, this.afterSubmit)
  650. });
  651. },
  652. beforeSubmit() {
  653. if (!this.formConfCopy || !this.formConfCopy.funcs || !this.formConfCopy.funcs.beforeSubmit) return Promise
  654. .resolve()
  655. const func = this.jnpf.getScriptFunc(this.formConfCopy.funcs.beforeSubmit)
  656. if (!func) return Promise.resolve()
  657. return func(this.parameter)
  658. },
  659. afterSubmit() {
  660. if (!this.formConfCopy || !this.formConfCopy.funcs || !this.formConfCopy.funcs.afterSubmit) return
  661. const func = this.jnpf.getScriptFunc(this.formConfCopy.funcs.afterSubmit)
  662. if (!func) return
  663. func(this.parameter)
  664. },
  665. // 子表必填验证,子表赋值
  666. checkTableData() {
  667. this.getRefList();
  668. let isValid = true;
  669. for (const vModel in this.tableRefs) {
  670. const config = this.tableRefs[vModel].__config__;
  671. if (!config.isVisibility || config.noShow) continue;
  672. const tableRef = this.findTableRef(vModel);
  673. if (!tableRef) continue;
  674. const submitResult = this.getTableSubmitResult(tableRef, vModel);
  675. if (submitResult) {
  676. this.formData[vModel] = submitResult;
  677. } else {
  678. isValid = false;
  679. }
  680. }
  681. return isValid;
  682. },
  683. findTableRef(vModel) {
  684. for (const item of this.refList) {
  685. if (item[0] === vModel) {
  686. return Array.isArray(item[1]) ? item[1][0] : item[1];
  687. }
  688. }
  689. return null;
  690. },
  691. getTableSubmitResult(tableRef, vModel) {
  692. const refToSubmit = tableRef.$refs && tableRef.$refs[vModel] ? tableRef.$refs[vModel] : tableRef;
  693. return refToSubmit.submit ? refToSubmit.submit() : false;
  694. },
  695. //获取子表实例ref
  696. getRefList() {
  697. this.refList = [];
  698. const refList = this.$refs || [];
  699. const loopRefs = (refs) => {
  700. if (!refs) return
  701. for (const key in refs) {
  702. const ref = refs[key];
  703. if (Array.isArray(ref)) {
  704. ref.forEach(item => loopRefs(item));
  705. } else {
  706. this.refList.push([key, ref]);
  707. }
  708. }
  709. };
  710. if (Array.isArray(refList)) {
  711. refList.forEach(item => loopRefs(item));
  712. } else {
  713. loopRefs(refList);
  714. }
  715. },
  716. clickIcon(e) {
  717. if (!e?.__config__) return;
  718. const {
  719. tipLabel,
  720. label: configLabel,
  721. jnpfKey
  722. } = e.__config__;
  723. const {
  724. helpMessage
  725. } = e;
  726. if (!tipLabel && !helpMessage) return;
  727. this.tipsContent = helpMessage || tipLabel;
  728. this.tipsTitle =
  729. jnpfKey === 'card' ? e.header :
  730. jnpfKey === 'groupTitle' ? e.content :
  731. configLabel;
  732. this.showTipsModal = true;
  733. },
  734. onBlur(item, data) {
  735. this.setValue(item)
  736. this.setScriptFunc(data, item, 'blur')
  737. },
  738. onTabChange(item, data) {
  739. this.setScriptFunc(data, item, 'tabClick')
  740. },
  741. onClick(item, data) {
  742. this.setScriptFunc(data, item, 'click')
  743. },
  744. onCollapseChange(item, data) {
  745. this.setScriptFunc(data, item)
  746. },
  747. setScriptFunc(val, data, type = 'change') {
  748. if (data && data.on && data.on[type]) {
  749. const func = this.jnpf.getScriptFunc(data.on[type]);
  750. if (!func) return
  751. func.call(this, {
  752. data: val,
  753. ...this.parameter
  754. })
  755. }
  756. },
  757. }
  758. }
  759. </script>