You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

402 lines
13 KiB

  1. import get from 'lodash/get'
  2. import omit from 'lodash/omit'
  3. import moment from 'moment'
  4. /**
  5. * 用于代码生成器页面,加载表单数据使用
  6. *
  7. * 提供以下工具方法:
  8. *
  9. * 【新建表单时使用】:
  10. * async getDefaultForm()
  11. * async getDefaultValue(path, scheme)
  12. * 根据表单 scheme 获取初始化的空表单数据 / 获取单条表单项的初始数据
  13. *
  14. * 【提交表单时使用】:
  15. * async getPostData()
  16. * async convertToPostData()
  17. * 生成 POST 提交用的表单数据 / 获取单条表单项的提交数据
  18. *
  19. * verifyForm()
  20. * 验证表单数据,返回一个输入错误信息的数组
  21. *
  22. * 【打开一个表单时使用】:
  23. * async formatFormData(formData)
  24. * async convertToFormValue(scheme, val, dataSource)
  25. * 将拉取的表单值转化为表单数据 / 将单条表单项的表单值转化为表单数据
  26. *
  27. */
  28. export default {
  29. methods: {
  30. // 获取表单默认值
  31. async getDefaultForm() {
  32. const result = {}
  33. for (const [tableName, tableItem] of Object.entries(this.scheme)) {
  34. const itemData = {}
  35. for (const [fieldName, scheme] of Object.entries(tableItem)) {
  36. if (fieldName !== '__GIRDTABLE__') {
  37. itemData[fieldName] = await this.getDefaultValue(`${tableName}.${fieldName}`, scheme,tableName,fieldName)
  38. }
  39. }
  40. result[tableName] = '__GIRDTABLE__' in tableItem ? [itemData] : itemData
  41. }
  42. return result
  43. },
  44. // 获取单条表单项的默认值
  45. async getDefaultValue(path, schemeItem,tableName,fieldName) {
  46. switch (schemeItem.type) {
  47. case 'keyValue':
  48. return this.processId
  49. case 'currentInfo':
  50. switch (schemeItem.dataType) {
  51. case 'user':
  52. return this.GET_GLOBAL('loginUser').userId
  53. case 'department':
  54. return this.GET_GLOBAL('loginUser').departmentId
  55. case 'company':
  56. return this.GET_GLOBAL('loginUser').companyId
  57. case 'time':
  58. return moment().format('YYYY-MM-DD HH:mm:ss')
  59. default:
  60. return ''
  61. }
  62. case 'datetime':
  63. const datetimeFormat = (Number(schemeItem.dateformat) === 0 ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss')
  64. const today = moment()
  65. const dfDatetime = [
  66. today.subtract(1, 'day'),
  67. today,
  68. today.add(1, 'day')
  69. ][Number(schemeItem.dfvalue)] || today
  70. return dfDatetime.format(datetimeFormat) || ''
  71. case 'radio':
  72. case 'select':
  73. const radioItem = get(this.dataSource, path).find(t => t.value === schemeItem.dfvalue) ||
  74. get(this.dataSource, path)[0]
  75. return schemeItem.type === 'radio' ? radioItem.value : ''
  76. case 'checkbox':
  77. if (!schemeItem.dfvalue) { return [] }
  78. return schemeItem.dfvalue.split(',').filter(t => get(this.dataSource, path, []).find(s => s.value === t))
  79. case 'encode':
  80. if (!schemeItem.rulecode) { return '' }
  81. const result = await this.FETCH_ENCODE(schemeItem.rulecode)
  82. return result || ''
  83. case 'upload':
  84. let folderIds = {}
  85. let getstData = uni.getStorageSync('folderIds');
  86. if(getstData){
  87. folderIds = JSON.parse(getstData)
  88. }
  89. if(folderIds[tableName]){
  90. folderIds[tableName][fieldName] = ''
  91. }else{
  92. let obj = {}
  93. obj[fieldName] = ''
  94. folderIds[tableName] = obj
  95. }
  96. uni.setStorageSync('folderIds',JSON.stringify(folderIds));
  97. return []
  98. case 'guid':
  99. return this.GUID('-')
  100. default:
  101. return schemeItem.dfvalue || ''
  102. }
  103. },
  104. // 验证表单项输入是否正确,返回一个包含所有错误信息的数组
  105. verifyForm() {
  106. const result = []
  107. Object.entries(this.scheme).forEach(([tableName, tableItem]) => {
  108. if ('__GIRDTABLE__' in tableItem) {
  109. this.getValue(tableName).forEach((tableValue, index) => {
  110. Object.entries(tableItem).forEach(([fieldName, scheme]) => {
  111. if (fieldName === '__GIRDTABLE__' || !scheme.verify) { return }
  112. const val = tableValue[fieldName]
  113. const verifyResult = this.verify[scheme.verify](val)
  114. if (verifyResult !== true) {
  115. result.push(`[表格${tableItem.__GIRDTABLE__}第${index}行${scheme.title}列]: ${verifyResult}`)
  116. }
  117. })
  118. })
  119. } else {
  120. Object.entries(tableItem).forEach(([fieldName, scheme]) => {
  121. if (!scheme.verify) { return }
  122. const val = this.getValue(`${tableName}.${fieldName}`)
  123. const verifyResult = this.verify[scheme.verify](val)
  124. if (verifyResult !== true) {
  125. result.push(`[${scheme.title}]: ${verifyResult}`)
  126. }
  127. })
  128. }
  129. })
  130. return result
  131. },
  132. // 获取要提交的表单数据(提交时使用)
  133. async getPostData(keyValue) {
  134. const result = {}
  135. for (const [tableName, tableItem] of Object.entries(this.scheme)) {
  136. if ('__GIRDTABLE__' in tableItem) {
  137. // 从表
  138. const tableArray = []
  139. const tableData = this.current[tableName]
  140. for (let index = 0; index < tableData.length; ++index) {
  141. const tableValue = tableData[index]
  142. const tableObj = {}
  143. for (const [fieldName, scheme] of Object.entries(tableItem)) {
  144. if (fieldName === '__GIRDTABLE__') { continue }
  145. tableObj[fieldName] = await this.convertToPostData(scheme, tableValue[fieldName],tableName,fieldName)
  146. }
  147. tableArray.push(tableObj)
  148. }
  149. result[`str${tableName}Entity`] = JSON.stringify(tableArray)
  150. } else {
  151. // 主表
  152. const strEntity = {}
  153. for (const [fieldName, scheme] of Object.entries(tableItem)) {
  154. strEntity[fieldName] = await this.convertToPostData(scheme, this.current[tableName][fieldName],tableName,fieldName)
  155. }
  156. result['strEntity'] = JSON.stringify(strEntity)
  157. }
  158. }
  159. if (keyValue) {
  160. result.keyValue = keyValue
  161. }
  162. return result
  163. },
  164. newguid() {
  165. return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  166. var r = Math.random() * 16 | 0,
  167. v = c == 'x' ? r : (r & 0x3 | 0x8);
  168. return v.toString(16);
  169. });
  170. },
  171. // 将单项表单数据转为 post 数据(提交时使用)
  172. async convertToPostData(scheme, val,tableName,fieldName) {
  173. switch (scheme.type) {
  174. case 'checkbox':
  175. return val ? val.join(',') : ''
  176. case 'datetimerange':
  177. const startTime = this.getValue(scheme.startTime)
  178. const endTime = this.getValue(scheme.endTime)
  179. if (!startTime || !endTime || moment(endTime).isBefore(startTime)) {
  180. return ''
  181. } else {
  182. return moment.duration(moment(endTime).diff(moment(startTime))).asDays().toFixed(0)
  183. }
  184. case 'datetime':
  185. return val ? moment(val).format('YYYY-MM-DD HH:mm') : ''
  186. case 'upload':
  187. // const uploadUid = []
  188. // for (const entity of val) {
  189. // if (entity.uid) {
  190. // uploadUid.push(entity.uid)
  191. // continue
  192. // } else {
  193. // const fileId = await this.HTTP_UPLOAD(entity)
  194. // if (fileId) {
  195. // uploadUid.push(fileId)
  196. // }
  197. // }
  198. // }
  199. var uploadUid = '';
  200. let folderIds = uni.getStorageSync('folderIds');
  201. if(folderIds){
  202. folderIds = JSON.parse(folderIds)
  203. if(folderIds[tableName]&&folderIds[tableName][fieldName]){
  204. uploadUid = folderIds[tableName][fieldName]
  205. }
  206. }
  207. if(!uploadUid){
  208. uploadUid = this.newguid()
  209. }
  210. for (const item of val) {
  211. if (item.uid) {
  212. uploadUid = item.uid
  213. continue
  214. }
  215. const fileId = await this.HTTP_UPLOAD(item.path || item, undefined, uploadUid)
  216. if (fileId) {
  217. uploadUid = fileId;
  218. }
  219. }
  220. return uploadUid;
  221. default:
  222. return val || ''
  223. }
  224. },
  225. // 格式化处理表单数据(拉取时使用)
  226. async formatFormData(formData) {
  227. const data = omit(formData, 'keyValue')
  228. for (const [tableName, schemeItem] of Object.entries(this.scheme)) {
  229. if ('__GIRDTABLE__' in schemeItem) {
  230. if (!data[tableName] || data[tableName].length <= 0) { data[tableName] = [{}] }
  231. const tableData = data[tableName]
  232. for (let index = 0; index < tableData.length; ++index) {
  233. const tableValue = tableData[index]
  234. for (const [fieldName, scheme] of Object.entries(schemeItem)) {
  235. if (fieldName === '__GIRDTABLE__') { continue }
  236. const dataSource = get(this.dataSource, `${tableName}.${fieldName}`)
  237. tableValue[fieldName] = await this.convertToFormValue(scheme, tableValue[fieldName], dataSource,tableName,fieldName)
  238. }
  239. }
  240. } else {
  241. for (const [fieldName, scheme] of Object.entries(schemeItem)) {
  242. const dataSource = get(this.dataSource, `${tableName}.${fieldName}`)
  243. data[tableName][fieldName] = await this.convertToFormValue(scheme, data[tableName][fieldName], dataSource,tableName,fieldName)
  244. }
  245. }
  246. }
  247. return data
  248. },
  249. // 将单项表单数据格式化(拉取时使用)
  250. async convertToFormValue(scheme, val, dataSource,tableName,fieldName) {
  251. switch (scheme.type) {
  252. case 'upload':
  253. // if (!val) { return [] }
  254. // const uidList = val.split(',')
  255. // const fileList = []
  256. // for (const uid of uidList || []) {
  257. // const fileInfo = await this.FETCH_FILEINFO(uid)
  258. // if (!fileInfo) { continue }
  259. // const fileType = fileInfo.F_FileType
  260. // const fileSize = fileInfo.F_FileSize
  261. // const fileName = fileInfo.F_FileName
  262. // const path = this.API + '/annexes/wxdown?' + this.URL_QUERY(uid, true)
  263. // fileList.push({ path, type: fileType, uid, size: fileSize, name:fileName })
  264. // }
  265. // return fileList
  266. let folderIds = {}
  267. let getstData = uni.getStorageSync('folderIds');
  268. if(getstData){
  269. folderIds = JSON.parse(getstData)
  270. }
  271. if(folderIds[tableName]){
  272. folderIds[tableName][fieldName] = val
  273. }else{
  274. let obj = {}
  275. obj[fieldName] = val
  276. folderIds[tableName] = obj
  277. }
  278. uni.setStorageSync('folderIds',JSON.stringify(folderIds));
  279. if (!val) {
  280. return []
  281. }
  282. const uidList = val;
  283. const fileList = []
  284. const wxlist = await this.FETCH_FILEList(uidList);
  285. for (const wxfile of wxlist) {
  286. const fileInfo = await this.FETCH_FILEINFO(wxfile.F_Id)
  287. if (!fileInfo) {
  288. continue
  289. }
  290. const fileType = fileInfo.F_FileType
  291. const fileSize = fileInfo.F_FileSize
  292. const fileName = fileInfo.F_FileName
  293. const path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(wxfile.F_Id, true)
  294. fileList.push({
  295. path,
  296. type: fileType,
  297. uid:wxfile.F_Id,
  298. folderId:wxfile.F_FolderId,
  299. size: fileSize,
  300. name:fileName
  301. })
  302. }
  303. return fileList
  304. case 'radio':
  305. case 'select':
  306. if (!val || !dataSource.map(t => t.value).includes(String(val))) { return '' }
  307. return String(val)
  308. case 'checkbox':
  309. if (!val) { return [] }
  310. const validValue = dataSource.map(t => t.value)
  311. const checkboxVal = val.split(',') || []
  312. return checkboxVal.filter(t => validValue.includes(t))
  313. case 'datetime':
  314. if (!val) { return '' }
  315. return moment(val).format(
  316. Number(scheme.dateformat) === 0 || scheme.datetime === 'date' ?
  317. 'YYYY-MM-DD' :
  318. 'YYYY-MM-DD HH:mm:ss'
  319. )
  320. default:
  321. return val === null || val === undefined ? '' : val
  322. }
  323. }
  324. },
  325. computed: {
  326. // 验证函数
  327. verify() {
  328. return {
  329. NotNull: t => t.length > 0 || '不能为空',
  330. Num: t => !isNaN(t) || '须输入数值',
  331. NumOrNull: t => t.length <= 0 || !isNaN(t) || '须留空或输入数值',
  332. Email: t => /^[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_]+.[a-zA-Z0-9]+$/.test(t) || '须符合Email格式',
  333. EmailOrNull: t => t.length <= 0 || /^[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_]+.[a-zA-Z0-9]+$/.test(t) ||
  334. '须留空或符合Email格式',
  335. EnglishStr: t => /^[a-zA-Z]*$/.test(t) || '须由英文字母组成',
  336. EnglishStrOrNull: t => t.length <= 0 || /^[a-zA-Z]*$/.test(t) || '须留空或由英文字母组成',
  337. Phone: t => /^[+0-9- ]*$/.test(t) || '须符合电话号码格式',
  338. PhoneOrNull: t => t.length <= 0 || /^[+0-9- ]*$/.test(t) || '须留空或符合电话号码格式',
  339. Fax: t => /^[+0-9- ]*$/.test(t) || '须符合传真号码格式',
  340. Mobile: t => /^1[0-9]{10}$/.test(t) || '须符合手机号码格式',
  341. MobileOrPhone: t => /^[+0-9- ]*$/.test(t) || /^1[0-9]{10}$/.test(t) || '须符合电话或手机号码格式',
  342. MobileOrNull: t => t.length <= 0 || /^1[0-9]{10}$/.test(t) || '须留空或符合手机号码格式',
  343. MobileOrPhoneOrNull: t => t.length <= 0 || /^1[0-9]{10}$/.test(t) || /^[+0-9- ]*$/.test(t) ||
  344. '须留空或符合手机/电话号码格式',
  345. Uri: t => /^[a-zA-z]+:\/\/[^\s]*$/.test(t) || '须符合网址Url格式',
  346. UriOrNull: t => t.length <= 0 || /^[a-zA-z]+:\/\/[^\s]*$/.test(t) || '须留空或符合网址Url格式'
  347. }
  348. }
  349. }
  350. }