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.
 
 
 
 
 
 

416 lines
14 KiB

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