@@ -40,8 +40,7 @@ namespace Learun.Application.WebApi.Modules | |||
public Response WxUpload(dynamic _) | |||
{ | |||
var files = (List<HttpFile>)this.Context.Request.Files; | |||
//var folderId = this.GetReqData(); | |||
string folderId = Guid.NewGuid().ToString(); | |||
string folderId = Request.Form["folderId"]; | |||
string filePath = Config.GetValue("AnnexesFile"); | |||
string uploadDate = DateTime.Now.ToString("yyyyMMdd"); | |||
string fileEextension = Path.GetExtension(files[0].Name); | |||
@@ -24,274 +24,310 @@ import moment from 'moment' | |||
*/ | |||
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.split(',') | |||
const fileList = [] | |||
for (const uid of uidList || []) { | |||
const fileInfo = await this.FETCH_FILEINFO(uid) | |||
if (!fileInfo) { continue } | |||
const fileType = fileInfo.F_FileType | |||
const fileSize = fileInfo.F_FileSize | |||
const path = this.API + '/annexes/wxdown?' + this.URL_QUERY(uid, true) | |||
fileList.push({ path, type: fileType, uid, 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) { | |||
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': | |||
const uploadUid = [] | |||
for (const item of val) { | |||
if (item.uid) { | |||
uploadUid.push(item.uid) | |||
continue | |||
} | |||
const fileId = await this.HTTP_UPLOAD(item.path||item) | |||
if (fileId) { | |||
uploadUid.push(fileId) | |||
} | |||
} | |||
return uploadUid.join(',') | |||
default: | |||
return val || '' | |||
} | |||
} | |||
} | |||
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 || '' | |||
} | |||
} | |||
} | |||
} |
@@ -257,7 +257,6 @@ export default { | |||
const fileSize = fileInfo.F_FileSize | |||
const path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(uid, true) | |||
fileList.push({ path, type: fileType, uid, size: fileSize }) | |||
} | |||
return fileList | |||
@@ -229,6 +229,14 @@ export default { | |||
return await this.HTTP_GET('learun/adms/annexes/wxfileinfo', fileId) | |||
}, | |||
//获取文件夹下文件列表 | |||
async FETCH_FILEList(folderId) { | |||
if (!folderId) { | |||
return null | |||
} | |||
return await this.HTTP_GET('learun/adms/annexes/wxlist', folderId) | |||
}, | |||
// 封装的 GET 请求,集成了验证信息 | |||
// 返回请求结果或 null | |||
@@ -258,8 +266,8 @@ export default { | |||
// url 为请求地址 | |||
// filePath 为临时文件的路径 | |||
// formData 为请求附带的提交数据 | |||
async HTTP_UPLOAD(filePath, formData) { | |||
const [err, res] = await this.UPLOAD('/learun/adms/annexes/wxupload', filePath, formData) | |||
async HTTP_UPLOAD(filePath, formData,guid) { | |||
const [err, res] = await this.UPLOAD('/learun/adms/annexes/wxupload', filePath, formData,guid) | |||
return this.handleResult(err, res) | |||
}, | |||
@@ -308,11 +316,12 @@ export default { | |||
// 返回结果是一个数组: [error, result] | |||
// error 表示错误,一般是网络错误,请求很可能根本没有发出 | |||
// result 包含 { statusCode, data } 分别表示状态码、接口返回的数据 | |||
async UPLOAD(url, filePath, formData) { | |||
async UPLOAD(url, filePath, formData,guid) { | |||
const uploadUrl = this.handleUrl(url) | |||
const query = { | |||
loginMark: this.getLoginMark(), | |||
token: this.GET_GLOBAL('token') | |||
token: this.GET_GLOBAL('token'), | |||
folderId:guid | |||
} | |||
if (formData && typeof formData === 'object') { | |||
@@ -21,8 +21,8 @@ export default { | |||
// "http://192.168.2.98:8088/" | |||
// ], | |||
"apiHost": [ | |||
// "http://localhost:31173/" | |||
"http://192.168.10.68:8002/" | |||
"http://localhost:31173/" | |||
//"http://192.168.10.68:8002/" | |||
], | |||
"webHost":"http://localhost:20472/", | |||
// 开发环境下自动填充登录账号密码,与接口地址一一对应,只在开发环境下显示 | |||
@@ -132,7 +132,7 @@ export default { | |||
return null | |||
} | |||
return this.API + `/user/img?data=${item.F_OtherUserId}` | |||
return this.API + `/learun/adms/user/img?data=${item.F_OtherUserId}` | |||
} | |||
}, | |||
@@ -186,7 +186,7 @@ export default { | |||
// 获取用户头像图片 url | |||
avatar(id) { | |||
return id === this.chatUserId && this.isSystem ? null : this.API + `/user/img?data=${id}` | |||
return id === this.chatUserId && this.isSystem ? null : this.API + `/learun/adms/user/img?data=${id}` | |||
} | |||
}, | |||
@@ -156,7 +156,7 @@ export default { | |||
return '' | |||
} | |||
return this.API + `/user/img?data=${this.currentUser.userId}` | |||
return this.API + `/learun/adms/user/img?data=${this.currentUser.userId}` | |||
} | |||
}, | |||
@@ -34,7 +34,7 @@ export default { | |||
// 头像图片 url | |||
avatarSrc() { | |||
return this.API + `/user/img?data=${this.currentUser.userId}` | |||
return this.API + `/learun/adms/user/img?data=${this.currentUser.userId}` | |||
} | |||
} | |||
} | |||
@@ -30,7 +30,7 @@ export default { | |||
// 头像图片 url | |||
avatar() { | |||
return this.API + `/user/img?data=${this.currentUser.userId}` | |||
return this.API + `/learun/adms/user/img?data=${this.currentUser.userId}` | |||
}, | |||
// 用户公司部门 tag | |||
@@ -95,7 +95,6 @@ export default { | |||
// t.formId 使用表单,根据这个 formId 来获取 scheme 等信息 | |||
// t.appurl 使用移动页面,直接跳转到本地的页面;表单结构等均写死在页面里 | |||
const { wfForms } = this.currentNode | |||
console.log(wfForms); | |||
// 处理没有有效表单的情况,停止加载 | |||
if (!wfForms || wfForms.every(t => !t.formId && !t.appurl)) { | |||
@@ -144,7 +143,6 @@ export default { | |||
code: this.code, | |||
useDefault: true | |||
}) | |||
console.log("formValue",formValue,"scheme",scheme) | |||
this.scheme = scheme | |||
this.formValue = formValue | |||
this.rel = rel | |||
@@ -152,8 +150,6 @@ export default { | |||
// 不是子流程,可以直接渲染 | |||
const schemeData = await this.fetchSchemeData(this.currentNode) | |||
const formData = await this.fetchFormData(this.currentNode, this.processId) | |||
console.log(schemeData) | |||
console.log(formData) | |||
const { formValue, scheme, rel } = await this.getCustomForm({ | |||
formData, | |||
schemeData, | |||
@@ -161,7 +157,6 @@ export default { | |||
processId: this.processId, | |||
code: null | |||
}) | |||
console.log("formValue",formValue,"scheme",scheme) | |||
this.scheme = scheme | |||
this.formValue = formValue | |||
this.rel = rel | |||
@@ -110,7 +110,9 @@ export default { | |||
this.needTitle = this.type !== 'again' && Number(currentNode.isTitle) === 1 | |||
const formData = await this.fetchFormData(currentNode, processId) | |||
const schemeData = await this.fetchSchemeData(currentNode) | |||
const { formValue, scheme, rel } = await this.getCustomForm({ | |||
schemeData, | |||
processId, | |||
@@ -119,14 +121,16 @@ export default { | |||
code: this.type === 'again' ? null : code, | |||
useDefault: true | |||
}) | |||
this.rel = rel | |||
this.scheme = scheme | |||
this.formValue = formValue | |||
this.code = code | |||
this.processId = processId | |||
console.log(this.formValue,'=====',this.scheme ,) | |||
this.ready = true | |||
this.HIDE_LOADING() | |||
}, | |||
// 提交草稿按钮 | |||
@@ -194,7 +198,6 @@ export default { | |||
verifyValue() { | |||
const errList = this.$refs.form.verifyValue() | |||
console.log(errList,'errList') | |||
if (this.needTitle && !this.title) { | |||
errList.push(`流程的标题不能为空`) | |||
} | |||
@@ -32,301 +32,355 @@ import customForm from '@/common/customform.js' | |||
* (以上只是简单介绍;实际使用中,如果打开子流程,需要拉取父/子两个流程信息) | |||
*/ | |||
export default { | |||
mixins: [customForm], | |||
methods: { | |||
/** | |||
* 从流程信息中生成 scheme、formValue | |||
* 参数: { schemeData (必填), processId, currentNode, formData (新建时为 null), code, useDefault } | |||
* 返回: { scheme, formValue, rel } | |||
* | |||
* 参数: | |||
* schemeData: 使用 fetchSchemeData 方法拉取到的原始 scheme 数据,未经过格式化处理 | |||
* processId: 表单 GUID;如果是新建表单,可以用 this.GUID('-') 生成一个 | |||
* currentNode: 使用 getCurrentNode 方法拉取到的当前节点信息,用于权限控制 | |||
* formData: 填入表单的表单值,新建表单时此项为 null 即可 | |||
* code: 表单编号 code,会被赋值到返回的 formValue.code;重新发起流程的场合赋 null | |||
* useDefault: 如果 formData 中某一项为空,是否对这一项填入默认值;通常在编辑草稿时启用 | |||
* | |||
* 该方法返回的 scheme 项可能带有以下属性: | |||
* __valuePath__: 表单值在 formValue 中的路径,使用 lodash 的 get、set 方法即可读写 | |||
* __sourceData__: 表单值的选单数据 | |||
* __defaultItem__: 类型为 girdtable 的表单项带有此属性,表示添加一行表格时候表格项的默认值 | |||
* __schemeIndex__: (暂时用不到)表单项位于 schemeData 根级内的第几个子项中 | |||
* __dataIndex__: (暂时用不到)表单项位于 F_Scheme.data 中的第几个子项中 | |||
*/ | |||
async getCustomForm(prop) { | |||
const { schemeData, formData, currentNode, code, processId, useDefault } = prop | |||
console.log(prop,'prop') | |||
// 处理字段之间的级联、绑定关系 | |||
// 需要绑定 change 事件的: | |||
// datetime: 修改后重新计算 datetimerange | |||
// organize: 修改后重设级联到该组件的其他组件的值,user 一级无需处理 | |||
// 需要绑定某值的: | |||
// organize: 级联到某个组件,company 一级无需处理 | |||
const schemeRef = {} | |||
const refList = [] | |||
// 最终返回值:scheme、rel、formValue | |||
const scheme = [] | |||
const rel = {} | |||
const formValue = { processId, formreq: [] } | |||
if (code) { | |||
formValue.code = code | |||
} | |||
// 遍历 schemeData 中所有的 scheme | |||
const schemeList = Array.isArray(schemeData) ? schemeData : Object.values(schemeData) | |||
for (let schemeIndex = 0; schemeIndex < schemeList.length; ++schemeIndex) { | |||
const schemeItem = schemeList[schemeIndex] | |||
schemeItem.F_Scheme = JSON.parse(schemeItem.F_Scheme) | |||
// 已有表单值的时候,舍弃掉不存在表单值中的 scheme | |||
if (formData && !formData[schemeItem.F_SchemeInfoId]) { | |||
continue | |||
} | |||
// 设置 formreq 的内容,非新建模式下需要设置 keyValue | |||
const { formId, field } = get(currentNode, `wfForms.${schemeIndex}`, {}) | |||
const formreqObj = { schemeInfoId: formId, processIdName: field, formData: {} } | |||
if (formData) { | |||
if (Object.values(get(formData, `${schemeItem.F_SchemeInfoId}`, {})).some(t => t && t.length > 0)) { | |||
formreqObj.keyValue = processId | |||
} | |||
} | |||
formValue.formreq[schemeIndex] = formreqObj | |||
for (let dataIndex = 0; dataIndex < schemeItem.F_Scheme.data.length; ++dataIndex) { | |||
const { componts } = schemeItem.F_Scheme.data[dataIndex] | |||
for (const t of componts) { | |||
// 之后的 t 即表示每个 scheme 项 | |||
t.__valuePath__ = `formreq.${schemeIndex}.formData.${t.id}` | |||
// 以下两个属性暂时用不到 | |||
t.__schemeIndex__ = schemeIndex | |||
t.__dataIndex__ = dataIndex | |||
if (t.type === 'girdtable' && t.table) { | |||
// 数据项是表格的情况 | |||
// 先设置源数据,不然无法获取默认值 | |||
for (const fieldItem of t.fieldsData) { | |||
fieldItem.__sourceData__ = await this.getSourceData(fieldItem) | |||
} | |||
t.__defaultItem__ = await this.getDefaultData(t, prop) | |||
if (formData) { | |||
// 有表单值的情况,从表单值中获取数据 | |||
const val = [] | |||
for (const valueItem of get(formData, `${schemeItem.F_SchemeInfoId}.${t.table}`, [])) { | |||
const tableItemValue = {} | |||
for (const fieldItem of t.fieldsData.filter(t => t.field)) { | |||
const formDataValue = get(valueItem, fieldItem.field.toLowerCase()) | |||
tableItemValue[fieldItem.field] = await this.convertToFormValue(fieldItem, formDataValue) | |||
} | |||
val.push(tableItemValue) | |||
} | |||
// useDefault 表示在从 formData 取不到值的时候使用默认值 | |||
if ((!val || val.length <= 0) && useDefault) { | |||
set(formValue, t.__valuePath__, [this.COPY(t.__defaultItem__)]) | |||
} else { | |||
set(formValue, t.__valuePath__, val) | |||
} | |||
} else { | |||
// 无表单值的情况,默认值 | |||
set(formValue, t.__valuePath__, [this.COPY(t.__defaultItem__)]) | |||
} | |||
} else if (t.field) { | |||
// 数据项不是表格的情况 | |||
// 先设置源数据,不然无法获取默认值 | |||
t.__sourceData__ = await this.getSourceData(t) | |||
if (formData) { | |||
// 有表单值的情况,从表单值中获取数据 | |||
const path = `${schemeItem.F_SchemeInfoId}.${t.table}.${dataIndex}.${t.field.toLowerCase()}` | |||
const formDataValue = get(formData, path) | |||
// useDefault 表示在从 formData 取不到值的时候使用默认值 | |||
if (!formDataValue && useDefault) { | |||
set(formValue, t.__valuePath__, await this.getDefaultData(t, prop)) | |||
} else { | |||
set(formValue, t.__valuePath__, await this.convertToFormValue(t, formDataValue)) | |||
} | |||
} else { | |||
// 无表单值的情况,默认值 | |||
set(formValue, t.__valuePath__, await this.getDefaultData(t, prop)) | |||
} | |||
} | |||
// 权限控制 | |||
const authObj = get(currentNode, `wfForms.${schemeIndex}.authorize.${t.id}`, {}) | |||
t.edit = authObj.isEdit | |||
if (Number(t.isHide) !== 1 && authObj.isLook !== 0) { | |||
// 加入 scheme | |||
scheme.push(t) | |||
// organize、datetime 可能作为其他 organize 或 datetimerange 的依赖项,引用它们 | |||
if (['organize', 'datetime'].includes(t.type)) { | |||
schemeRef[t.id] = t | |||
} | |||
// datetimerange、带有 relation 级联字段的 organize,依赖其他项 | |||
if ((t.type === 'datetimerange' && t.startTime && t.endTime) || (t.type === 'organize' && t.relation)) { | |||
refList.push(t) | |||
} | |||
} | |||
} | |||
} | |||
} | |||
// 依次处理表单关联 | |||
refList.forEach(t => { | |||
if (t.type === 'organize') { | |||
// 处理组件结构级联 | |||
// 给当前组件赋上级级联的值路径 __relationPath__ | |||
const parent = schemeRef[t.relation] | |||
t.__relationPath__ = parent.__valuePath__ | |||
// 给上级级联的组件注册自动重置当前组件的 change 事件 | |||
const relItem = { type: 'organize', id: t.id, path: t.__valuePath__ } | |||
rel[parent.id] = rel[parent.id] ? rel[parent.id].concat(relItem) : [relItem] | |||
} else if (t.type === 'datetimerange') { | |||
// 处理日期区间 | |||
const start = schemeRef[t.startTime] | |||
const end = schemeRef[t.endTime] | |||
const relItem = { | |||
type: 'datetimerange', | |||
path: t.__valuePath__, | |||
id: t.id, | |||
startPath: start.__valuePath__, | |||
endPath: end.__valuePath__, | |||
} | |||
rel[start.id] = rel[start.id] ? rel[start.id].concat(relItem) : [relItem] | |||
rel[end.id] = rel[end.id] ? rel[end.id].concat(relItem) : [relItem] | |||
} | |||
}) | |||
return { scheme, formValue, rel } | |||
}, | |||
/** | |||
* 获取最终需要 POST 的数据 | |||
* 参数:formValue, scheme | |||
* 返回:用于提交的数据 | |||
* | |||
* 遍历 formValue,将其中的表单值依次使用 convertToPostData 这个方法转化为提交值 | |||
*/ | |||
async getPostData(originFormValue, scheme) { | |||
const formValue = this.COPY(originFormValue) | |||
// 依次按照 scheme 项目遍历 | |||
for (const item of scheme) { | |||
if (item.field) { | |||
// 不是表格的情况 | |||
const path = item.__valuePath__ | |||
const val = get(formValue, path) | |||
console.log(val,'val=======') | |||
const result = await this.convertToPostData(item, val, originFormValue, scheme) | |||
set(formValue, path, result) | |||
} else if (item.table && item.fieldsData) { | |||
// 是表格的情况 | |||
const tableValue = get(formValue, item.__valuePath__, []) | |||
for (let valueIndex = 0; valueIndex < tableValue.length; ++valueIndex) { | |||
for (const schemeItem of item.fieldsData) { | |||
const path = `${item.__valuePath__}.${valueIndex}.${schemeItem.field}` | |||
const val = get(formValue, path) | |||
const result = await this.convertToPostData(schemeItem, val, originFormValue, scheme) | |||
set(formValue, path, result) | |||
} | |||
} | |||
} | |||
} | |||
formValue.formreq.forEach(t => { t.formData = JSON.stringify(t.formData) }) | |||
formValue.formreq = JSON.stringify(formValue.formreq) | |||
return formValue | |||
}, | |||
/** | |||
* 获取流程信息 | |||
* 参数: { code, processId, taskId } | |||
* | |||
*/ | |||
async fetchProcessInfo({ code, processId, taskId }) { | |||
const url = processId ? 'learun/adms/newwf/processinfo' : 'learun/adms/newwf/scheme' | |||
const reqObj = { processId } | |||
if (taskId) { | |||
reqObj.taskId = taskId | |||
} | |||
const data = processId ? reqObj : code | |||
const result = await this.HTTP_GET(url, data) | |||
if (!result) { return {} } | |||
if (result.info) { | |||
result.info.Scheme = JSON.parse(result.info.Scheme) | |||
} else if (result.F_Content) { | |||
result.F_Content = JSON.parse(result.F_Content) | |||
} | |||
return result | |||
}, | |||
/** | |||
* 从 processInfo 流程信息中,提取出 currentNode | |||
* 参数: processInfo | |||
* | |||
*/ | |||
getCurrentNode(processInfo) { | |||
if (processInfo.info) { | |||
return processInfo.info.Scheme.nodes.find(t => t.id === processInfo.info.CurrentNodeId) | |||
} else if (processInfo.F_Content) { | |||
return processInfo.F_Content.nodes.find(t => t.type === 'startround') | |||
} | |||
return {} | |||
}, | |||
/** | |||
* 拉取表单的 schemeData | |||
* 参数: currentNode | |||
* | |||
* 从当前节点 currentNode 中提取出表单 id,然后自 API 地址 /form/scheme 中拉取表单数据并返回 | |||
*/ | |||
async fetchSchemeData(currentNode, currentTask, type) { | |||
const { wfForms } = currentNode | |||
const data = wfForms.filter(t => t.formId).map(t => ({ id: t.formId, ver: '' })) | |||
const schemeData = await this.HTTP_GET('learun/adms/form/scheme', data) | |||
return schemeData || {} | |||
}, | |||
/** | |||
* 拉取表单的 formData | |||
* 参数: currentNode, keyValue | |||
* | |||
* 提取当前节点信息、表单主键信息,从 API 地址 /form/data 中拉取表单数据 | |||
*/ | |||
async fetchFormData({ wfForms }, keyValue) { | |||
const reqData = wfForms | |||
.filter(t => t.formId) | |||
.map(t => ({ | |||
schemeInfoId: t.formId, | |||
processIdName: t.field, | |||
keyValue | |||
})) | |||
const formData = await this.HTTP_GET('learun/adms/form/data', reqData) | |||
return formData || {} | |||
} | |||
} | |||
mixins: [customForm], | |||
methods: { | |||
/** | |||
* 从流程信息中生成 scheme、formValue | |||
* 参数: { schemeData (必填), processId, currentNode, formData (新建时为 null), code, useDefault } | |||
* 返回: { scheme, formValue, rel } | |||
* | |||
* 参数: | |||
* schemeData: 使用 fetchSchemeData 方法拉取到的原始 scheme 数据,未经过格式化处理 | |||
* processId: 表单 GUID;如果是新建表单,可以用 this.GUID('-') 生成一个 | |||
* currentNode: 使用 getCurrentNode 方法拉取到的当前节点信息,用于权限控制 | |||
* formData: 填入表单的表单值,新建表单时此项为 null 即可 | |||
* code: 表单编号 code,会被赋值到返回的 formValue.code;重新发起流程的场合赋 null | |||
* useDefault: 如果 formData 中某一项为空,是否对这一项填入默认值;通常在编辑草稿时启用 | |||
* | |||
* 该方法返回的 scheme 项可能带有以下属性: | |||
* __valuePath__: 表单值在 formValue 中的路径,使用 lodash 的 get、set 方法即可读写 | |||
* __sourceData__: 表单值的选单数据 | |||
* __defaultItem__: 类型为 girdtable 的表单项带有此属性,表示添加一行表格时候表格项的默认值 | |||
* __schemeIndex__: (暂时用不到)表单项位于 schemeData 根级内的第几个子项中 | |||
* __dataIndex__: (暂时用不到)表单项位于 F_Scheme.data 中的第几个子项中 | |||
*/ | |||
async getCustomForm(prop) { | |||
const { | |||
schemeData, | |||
formData, | |||
currentNode, | |||
code, | |||
processId, | |||
useDefault | |||
} = prop | |||
// 处理字段之间的级联、绑定关系 | |||
// 需要绑定 change 事件的: | |||
// datetime: 修改后重新计算 datetimerange | |||
// organize: 修改后重设级联到该组件的其他组件的值,user 一级无需处理 | |||
// 需要绑定某值的: | |||
// organize: 级联到某个组件,company 一级无需处理 | |||
const schemeRef = {} | |||
const refList = [] | |||
// 最终返回值:scheme、rel、formValue | |||
const scheme = [] | |||
const rel = {} | |||
const formValue = { | |||
processId, | |||
formreq: [] | |||
} | |||
if (code) { | |||
formValue.code = code | |||
} | |||
// 遍历 schemeData 中所有的 scheme | |||
const schemeList = Array.isArray(schemeData) ? schemeData : Object.values(schemeData) | |||
for (let schemeIndex = 0; schemeIndex < schemeList.length; ++schemeIndex) { | |||
const schemeItem = schemeList[schemeIndex] | |||
schemeItem.F_Scheme = JSON.parse(schemeItem.F_Scheme) | |||
// 已有表单值的时候,舍弃掉不存在表单值中的 scheme | |||
if (formData && !formData[schemeItem.F_SchemeInfoId]) { | |||
continue | |||
} | |||
// 设置 formreq 的内容,非新建模式下需要设置 keyValue | |||
const { | |||
formId, | |||
field | |||
} = get(currentNode, `wfForms.${schemeIndex}`, {}) | |||
const formreqObj = { | |||
schemeInfoId: formId, | |||
processIdName: field, | |||
formData: {} | |||
} | |||
if (formData) { | |||
if (Object.values(get(formData, `${schemeItem.F_SchemeInfoId}`, {})).some(t => t && t.length > | |||
0)) { | |||
formreqObj.keyValue = processId | |||
} | |||
} | |||
formValue.formreq[schemeIndex] = formreqObj | |||
for (let dataIndex = 0; dataIndex < schemeItem.F_Scheme.data.length; ++dataIndex) { | |||
const { | |||
componts | |||
} = schemeItem.F_Scheme.data[dataIndex] | |||
for (const t of componts) { | |||
// 之后的 t 即表示每个 scheme 项 | |||
t.__valuePath__ = `formreq.${schemeIndex}.formData.${t.id}` | |||
// 以下两个属性暂时用不到 | |||
t.__schemeIndex__ = schemeIndex | |||
t.__dataIndex__ = dataIndex | |||
if (t.type === 'girdtable' && t.table) { | |||
// 数据项是表格的情况 | |||
// 先设置源数据,不然无法获取默认值 | |||
for (const fieldItem of t.fieldsData) { | |||
fieldItem.__sourceData__ = await this.getSourceData(fieldItem) | |||
} | |||
t.__defaultItem__ = await this.getDefaultData(t, prop) | |||
if (formData) { | |||
// 有表单值的情况,从表单值中获取数据 | |||
const val = [] | |||
for (const valueItem of get(formData, `${schemeItem.F_SchemeInfoId}.${t.table}`, | |||
[])) { | |||
const tableItemValue = {} | |||
for (const fieldItem of t.fieldsData.filter(t => t.field)) { | |||
const formDataValue = get(valueItem, fieldItem.field.toLowerCase()) | |||
tableItemValue[fieldItem.field] = await this.convertToFormValue(fieldItem, | |||
formDataValue) | |||
} | |||
val.push(tableItemValue) | |||
} | |||
// useDefault 表示在从 formData 取不到值的时候使用默认值 | |||
if ((!val || val.length <= 0) && useDefault) { | |||
set(formValue, t.__valuePath__, [this.COPY(t.__defaultItem__)]) | |||
} else { | |||
set(formValue, t.__valuePath__, val) | |||
} | |||
} else { | |||
// 无表单值的情况,默认值 | |||
set(formValue, t.__valuePath__, [this.COPY(t.__defaultItem__)]) | |||
} | |||
} else if (t.field) { | |||
// 数据项不是表格的情况 | |||
// 先设置源数据,不然无法获取默认值 | |||
t.__sourceData__ = await this.getSourceData(t) | |||
if (formData) { | |||
// 有表单值的情况,从表单值中获取数据 | |||
const path = | |||
`${schemeItem.F_SchemeInfoId}.${t.table}.${dataIndex}.${t.field.toLowerCase()}` | |||
const formDataValue = get(formData, path) | |||
// useDefault 表示在从 formData 取不到值的时候使用默认值 | |||
if (!formDataValue && useDefault) { | |||
set(formValue, t.__valuePath__, await this.getDefaultData(t, prop)) | |||
} else { | |||
set(formValue, t.__valuePath__, await this.convertToFormValue(t, formDataValue)) | |||
} | |||
} else { | |||
// 无表单值的情况,默认值 | |||
set(formValue, t.__valuePath__, await this.getDefaultData(t, prop)) | |||
} | |||
} | |||
// 权限控制 | |||
const authObj = get(currentNode, `wfForms.${schemeIndex}.authorize.${t.id}`, {}) | |||
t.edit = authObj.isEdit | |||
if (Number(t.isHide) !== 1 && authObj.isLook !== 0) { | |||
// 加入 scheme | |||
scheme.push(t) | |||
// organize、datetime 可能作为其他 organize 或 datetimerange 的依赖项,引用它们 | |||
if (['organize', 'datetime'].includes(t.type)) { | |||
schemeRef[t.id] = t | |||
} | |||
// datetimerange、带有 relation 级联字段的 organize,依赖其他项 | |||
if ((t.type === 'datetimerange' && t.startTime && t.endTime) || (t.type === | |||
'organize' && t.relation)) { | |||
refList.push(t) | |||
} | |||
} | |||
} | |||
} | |||
} | |||
// 依次处理表单关联 | |||
refList.forEach(t => { | |||
if (t.type === 'organize') { | |||
// 处理组件结构级联 | |||
// 给当前组件赋上级级联的值路径 __relationPath__ | |||
const parent = schemeRef[t.relation] | |||
t.__relationPath__ = parent.__valuePath__ | |||
// 给上级级联的组件注册自动重置当前组件的 change 事件 | |||
const relItem = { | |||
type: 'organize', | |||
id: t.id, | |||
path: t.__valuePath__ | |||
} | |||
rel[parent.id] = rel[parent.id] ? rel[parent.id].concat(relItem) : [relItem] | |||
} else if (t.type === 'datetimerange') { | |||
// 处理日期区间 | |||
const start = schemeRef[t.startTime] | |||
const end = schemeRef[t.endTime] | |||
const relItem = { | |||
type: 'datetimerange', | |||
path: t.__valuePath__, | |||
id: t.id, | |||
startPath: start.__valuePath__, | |||
endPath: end.__valuePath__, | |||
} | |||
rel[start.id] = rel[start.id] ? rel[start.id].concat(relItem) : [relItem] | |||
rel[end.id] = rel[end.id] ? rel[end.id].concat(relItem) : [relItem] | |||
} | |||
}) | |||
return { | |||
scheme, | |||
formValue, | |||
rel | |||
} | |||
}, | |||
newguid(){ | |||
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | |||
var r = Math.random() * 16 | 0, | |||
v = c == 'x' ? r : (r & 0x3 | 0x8); | |||
return v.toString(16); | |||
}); | |||
}, | |||
/** | |||
* 获取最终需要 POST 的数据 | |||
* 参数:formValue, scheme | |||
* 返回:用于提交的数据 | |||
* | |||
* 遍历 formValue,将其中的表单值依次使用 convertToPostData 这个方法转化为提交值 | |||
*/ | |||
async getPostData(originFormValue, scheme) { | |||
const formValue = this.COPY(originFormValue) | |||
var guid =this.newguid(); | |||
// 依次按照 scheme 项目遍历 | |||
for (const item of scheme) { | |||
if (item.field) { | |||
// 不是表格的情况 | |||
const path = item.__valuePath__ | |||
const val = get(formValue, path) | |||
const result = await this.convertToPostData(item, val, originFormValue, scheme, guid) | |||
set(formValue, path, result) | |||
} else if (item.table && item.fieldsData) { | |||
// 是表格的情况 | |||
const tableValue = get(formValue, item.__valuePath__, []) | |||
for (let valueIndex = 0; valueIndex < tableValue.length; ++valueIndex) { | |||
for (const schemeItem of item.fieldsData) { | |||
const path = `${item.__valuePath__}.${valueIndex}.${schemeItem.field}` | |||
const val = get(formValue, path) | |||
const result = await this.convertToPostData(schemeItem, val, originFormValue, scheme, | |||
guid) | |||
set(formValue, path, result) | |||
} | |||
} | |||
} | |||
} | |||
formValue.formreq.forEach(t => { | |||
t.formData = JSON.stringify(t.formData) | |||
}) | |||
formValue.formreq = JSON.stringify(formValue.formreq) | |||
return formValue | |||
}, | |||
/** | |||
* 获取流程信息 | |||
* 参数: { code, processId, taskId } | |||
* | |||
*/ | |||
async fetchProcessInfo({ | |||
code, | |||
processId, | |||
taskId | |||
}) { | |||
const url = processId ? 'learun/adms/newwf/processinfo' : 'learun/adms/newwf/scheme' | |||
const reqObj = { | |||
processId | |||
} | |||
if (taskId) { | |||
reqObj.taskId = taskId | |||
} | |||
const data = processId ? reqObj : code | |||
const result = await this.HTTP_GET(url, data) | |||
if (!result) { | |||
return {} | |||
} | |||
if (result.info) { | |||
result.info.Scheme = JSON.parse(result.info.Scheme) | |||
} else if (result.F_Content) { | |||
result.F_Content = JSON.parse(result.F_Content) | |||
} | |||
return result | |||
}, | |||
/** | |||
* 从 processInfo 流程信息中,提取出 currentNode | |||
* 参数: processInfo | |||
* | |||
*/ | |||
getCurrentNode(processInfo) { | |||
if (processInfo.info) { | |||
return processInfo.info.Scheme.nodes.find(t => t.id === processInfo.info.CurrentNodeId) | |||
} else if (processInfo.F_Content) { | |||
return processInfo.F_Content.nodes.find(t => t.type === 'startround') | |||
} | |||
return {} | |||
}, | |||
/** | |||
* 拉取表单的 schemeData | |||
* 参数: currentNode | |||
* | |||
* 从当前节点 currentNode 中提取出表单 id,然后自 API 地址 /form/scheme 中拉取表单数据并返回 | |||
*/ | |||
async fetchSchemeData(currentNode, currentTask, type) { | |||
const { | |||
wfForms | |||
} = currentNode | |||
const data = wfForms.filter(t => t.formId).map(t => ({ | |||
id: t.formId, | |||
ver: '' | |||
})) | |||
const schemeData = await this.HTTP_GET('learun/adms/form/scheme', data) | |||
return schemeData || {} | |||
}, | |||
/** | |||
* 拉取表单的 formData | |||
* 参数: currentNode, keyValue | |||
* | |||
* 提取当前节点信息、表单主键信息,从 API 地址 /form/data 中拉取表单数据 | |||
*/ | |||
async fetchFormData({ | |||
wfForms | |||
}, keyValue) { | |||
const reqData = wfForms | |||
.filter(t => t.formId) | |||
.map(t => ({ | |||
schemeInfoId: t.formId, | |||
processIdName: t.field, | |||
keyValue | |||
})) | |||
const formData = await this.HTTP_GET('learun/adms/form/data', reqData) | |||
return formData || {} | |||
} | |||
} | |||
} |