|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- import get from 'lodash/get'
- import moment from 'moment'
-
- /**
- * 表单数据处理相关方法
- * (配合 <l-customform> 使用,注意本工具类不包含拉取表单数据的代码)
- *
- * 提供以下工具方法:
- *
- * 【新建表单时使用】:
- * async getDefaultData(schemeItem, { processId })
- * 获取单个表单项的默认数据
- *
- * 【打开一个表单时使用】:
- * async getSourceData(schemeItem)
- * 获取表单中的选单数据 / 获取单条表单项的选单数据
- *
- * async convertToFormValue(schemeItem, val)
- * 将从 API 拉取的表单数据格式化规范化
- *
- * 【提交表单时使用】:
- * async convertToPostData(schemeItem, val, formValue, scheme)
- * 将本地表单数据格式化为提交时的格式
- */
-
- export default {
- methods: {
- /**
- * 获取一个 scheme 表单项的源数据 (加载表单时使用)
- * 参数: 单个 schemeItem
- *
- * radio、select、checkbox、layer 这四种表单项,需要加载额外的选单数据
- * 选单数据有两种获取方式:
- * 1、来自数据字典:
- * 数据字典在 this.GET_GLOBAL('dataDictionary')
- * 表单使用的字段在 schemeItem.itemCode
- * 选单数据中的 text 字段作为显示, value 字段作为值
- *
- * 2、来自数据源:
- * 将 schemeItem.dataSourceId 按符号「,」逗号分割为数组,分割为: [code, displayField, valueField]
- * 数据源需要请求 API 来获取,请求需要带上数据源的编号 code
- * displayField、valueField 分别为展示字段和值绑定字段
- *
- * 选单数据有两种格式:
- * 1、对于 radio、select、checkbox 来说:
- * 只需要一个数组,数组形如: [{ text: '选项文字', value: '选项值' }, ...]
- * 将获取的数据绑定到组件的 range 属性上即可
- * 全局数据中默认是对象形式,使用 Object.values() 转化即可
- *
- * 2、对于 layer 来说:
- * 返回一个对象,形如 { source, layerData, selfField }
- * source: 为弹层中列出的数据,是一个数组
- * layerData: 需要在弹层窗口中展示的字段及标题文字,形如: [{ name:'要展示的字段名', label:'标题文字' }]
- * selfField: 该表单值绑定哪个字段,默认为绑定到自身的字段
- */
- async getSourceData(schemeItem) {
- if (['radio', 'select', 'checkbox'].includes(schemeItem.type)) {
- // radio select checkbox 三种情况
- if (!schemeItem.dataSource || Number(schemeItem.dataSource) === 0) {
- // dataSource 为 0,使用 clientData
- return Object
- .values(this.GET_GLOBAL('dataDictionary')[schemeItem.itemCode])
- .map(t => ({
- value: t.value,
- text: t.text
- }))
-
- } else {
- // dataSource 不为 0,使用数据源,需要请求接口,并且提取出显示字段和实际字段
- const [code, displayField = schemeItem.showField, valueField = schemeItem.saveField] =
- schemeItem.dataSourceId
- .split(',')
- const sourceData = await this.FETCH_DATASOURCE(code)
- if (!sourceData) {
- return []
- }
-
- return sourceData.data.map(t => ({
- text: t[displayField],
- value: t[valueField]
- }))
- }
-
- } else if (['layer'].includes(schemeItem.type)) {
- // layer 需要更多属性
- if (!schemeItem.dataSource || Number(schemeItem.dataSource) === 0) {
- // dataSource 为 0,使用 clientData
- // clientData 对象转数组后,隐含 key:item.text 和 value:item.value 的关系
- const [keyItem, valueItem] = schemeItem.layerData
- const source = Object
- .values(this.GET_GLOBAL('dataDictionary')[schemeItem.itemCode])
- .map(t => ({
- value: t.value,
- text: t.text
- }))
-
- return {
- source,
- layerData: [{
- name: 'text',
- label: keyItem.label || '',
- value: keyItem.value || ''
- },
- {
- name: 'value',
- label: valueItem.label || '',
- value: valueItem.value || ''
- }
- ]
- }
- } else {
- // dataSource 不为 0,使用数据源,需要请求接口,并且提取出显示字段和实际字段
- const [code] = schemeItem.dataSourceId.split(',')
- const sourceData = await this.FETCH_DATASOURCE(code)
- if (!sourceData) {
- return []
- }
-
- const source = sourceData.data
-
- return {
- source,
- layerData: schemeItem.layerData.filter(t => (!t.hide) && (t.value || t.label))
- }
- }
- }
-
- return []
- },
-
- /**
- * 获取一个 scheme 表单项的默认值 (用户新建表单时使用,或是编辑草稿)
- * 参数: 单个 schemeItem , { processId }
- *
- * 每种类别的表单项分别获取的默认值:
- *
- * currentInfo: 根据类别取当前用户/部门/公司/时间日期
- * datetime: 根据 dfValue 字段表示昨天/今天/明天,格式化为字符串
- * radio、select: 有 dfValue 则使用,否则取第一条
- * checkbox: 有 dfValue 则使用,否则为空数组
- * encode: 根据 rulecode 请求表单编码
- * upload: 空数组
- * guid: 赋值第二个参数中的 processId,但是如果在子表格中,赋空字符串
- * girdtable: 递归所有表格项 scheme 依次为它们生成默认值
- * datetimerange: 字符串 0
- */
- async getDefaultData(item, prop) {
- const {
- processId
- } = prop
- switch (item.type) {
- case 'currentInfo':
- switch (item.dataType) {
- case 'user':
- return this.GET_GLOBAL('loginUser').userId
- case 'department':
- return this.GET_GLOBAL('loginUser').departmentId
- case 'company':
- return this.GET_GLOBAL('loginUser').companyId
- case 'time':
- return moment().format('YYYY-MM-DD HH:mm:ss')
- default:
- return ''
- }
-
- case 'datetime':
- const datetimeFormat = item.table ?
- (Number(item.dateformat) === 0 ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss') :
- (item.datetime === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD')
- const today = moment()
- const dfDatetime = [
- today.subtract(1, 'day'),
- today,
- today.add(1, 'day')
- ][Number(item.dfvalue)] || today
-
- return dfDatetime.format(datetimeFormat) || ''
-
- case 'radio':
- case 'select':
- const radioItem = item.__sourceData__.find(t => t.value === item.dfvalue) || item
- .__sourceData__[0]
- return item.type === 'radio' ? radioItem.value : ''
-
- case 'checkbox':
- if (!item.dfvalue) {
- return []
- }
- return item.dfvalue.split(',').filter(t => item.__sourceData__.find(s => s.value === t))
-
- case 'encode':
- const result = await this.FETCH_ENCODE(item.rulecode)
- return result
-
- case 'upload':
- return []
-
- case 'guid':
- return item.table ? processId : ''
-
- case 'girdtable':
- const tableItemObj = {}
- for (const fieldItem of item.fieldsData) {
- tableItemObj[fieldItem.field] = await this.getDefaultData(fieldItem, prop)
- }
- return this.COPY(tableItemObj)
-
- case 'datetimerange':
- return '0'
-
- default:
- return item.dfvalue || ''
- }
- },
-
- /**
- * 将单条 formData 值转化为 formValue 值 (拉取表单数据时使用)
- * 参数: 单个 schemeItem , 数据值
- *
- * 具体执行逻辑:
- * radio、select: 剔除无效值
- * checkbox: 分割成数组并剔除无效值
- * upload: 分割成数组,拉取其中所有文件的信息
- * datetime: 按照时间日期格式进行格式化字符串
- * 其他类型: 保留原值
- */
- async convertToFormValue(item, val) {
- switch (item.type) {
- case 'upload':
- if (!val) {
- return []
- }
- const uidList = val;
- const fileList = []
- const wxlist = await this.FETCH_FILEList(uidList);
- for (const wxfile of wxlist) {
- const fileInfo = await this.FETCH_FILEINFO(wxfile.F_Id)
- if (!fileInfo) {
- continue
- }
-
- const fileType = fileInfo.F_FileType
- const fileSize = fileInfo.F_FileSize
-
- const path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(wxfile.F_Id, true)
- fileList.push({
- path,
- type: fileType,
- uid:wxfile.F_Id,
- folderId:wxfile.F_FolderId,
- size: fileSize
- })
- }
- return fileList
-
- case 'select':
- case 'radio':
- if (!val || !item.__sourceData__.map(t => t.value).includes(val)) {
- return ''
- }
- return val
-
- case 'checkbox':
- const validValue = item.__sourceData__.map(t => t.value)
- const checkboxVal = val.split(',') || []
- return checkboxVal.filter(t => validValue.includes(t))
-
- case 'datetime':
- if (!val) {
- return ''
- }
- return moment(val).format(
- Number(item.dateformat) === 0 || item.datetime === 'date' ?
- 'YYYY-MM-DD' :
- 'YYYY-MM-DD HH:mm:ss'
- )
-
- default:
- return val || ''
- }
- },
-
- /**
- * 将一个 formValue 值转化为 post 提交值(提交表单数据时使用)
- * 参数: 单个 schemeItem , 表单项值 , 所有 formValue , scheme
- *
- * 具体执行逻辑:
- * checkbox: 将数组使用符号「,」逗号拼接成字符串
- * datetimerange: 获取开始日期、结束日期,计算差值天数并保留整数
- * datetime: 格式化为完整时间日期字符串
- * upload: 依次上传文件,将返回的文件 ID 使用符号「,」逗号拼接成字符串
- * 其他类型: 保留原值
- */
- async convertToPostData(item, val, formValue, scheme, guid) {
- switch (item.type) {
- case 'checkbox':
- return val ? val.join(',') : ''
-
- case 'datetimerange':
- const startTime = get(formValue, scheme.find(t => t.id === item.startTime).__valuePath__, null)
- const endTime = get(formValue, scheme.find(t => t.id === item.endTime).__valuePath__, null)
- if (!startTime || !endTime || moment(endTime).isBefore(startTime)) {
- return ''
- } else {
- return moment.duration(moment(endTime).diff(moment(startTime))).asDays().toFixed(0)
- }
-
- case 'datetime':
- return val ? moment(val).format('YYYY-MM-DD HH:mm:ss') : ''
-
- case 'upload':
- var uploadUid = '';
-
- for (const item of val) {
- if (item.uid) {
- uploadUid = item.uid
- continue
- }
-
- const fileId = await this.HTTP_UPLOAD(item.path || item, undefined, guid || '')
- if (fileId) {
- uploadUid = fileId;
- }
- }
-
- return uploadUid;
-
- default:
- return val || ''
- }
- }
- }
- }
|