index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. <template>
  2. <div v-loading="loading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)" class="PublicPageForm">
  3. <el-form ref="ruleForm" :model="tableForm" :label-width="labelWidth">
  4. <el-row :gutter="20">
  5. <el-col v-for="(item, index) in formItemArr" :key=" index" :span="formType == 'horizontal' ? formSpan : 24" v-show="isShow(item.isdisplay)">
  6. <el-form-item :rules="fromDataReq(item)" :prop="item.pagecode" :label="item.pagename">
  7. <template v-if="fromDataType(item.datatype) == 'SELECT' || fromDataType(item.datatype) == 'SELECTS'">
  8. <el-select class="input-shadow" size="small" :multiple="fromDataType(item.datatype) == 'SELECTS'?true:false" filterable default-first-option style="width: 100%" v-model="tableForm[item.pagecode]" @change="changeSelect(item.pagecode, item)" placeholder="请选择" clearable @clear="tableForm[item.pagecode] = ''">
  9. <el-option v-for="itemParams in tableOptions[item.pagecode]" :key="itemParams[item['dropdownlistid']]" :label="itemParams[item['dropdownlistlabel']]" :value="itemParams[item['dropdownlistid']]">
  10. </el-option>
  11. </el-select>
  12. </template>
  13. <template v-else-if="fromDataType(item.datatype) == 'DROP'">
  14. <el-select class="input-shadow" size="small" multiple filterable default-first-option style="width: 100%" v-model="tableForm[item.pagecode]" @change="changeSelect(item.pagecode, item)" placeholder="请选择" clearable @clear="tableForm[item.pagecode] = ''">
  15. <el-option v-for="itemParams in tableOptions[item.pagecode]" :key="itemParams['dropdownlistid']" :label="itemParams['dropdownlistlabel']" :value="itemParams['dropdownlistid']">
  16. </el-option>
  17. </el-select>
  18. </template>
  19. <template v-else-if="fromDataType(item.datatype) == 'ICON' || fromDataType(item.datatype) == 'icon'">
  20. <el-select size="small" clearable v-model="tableForm[item.pagecode]" placeholder="请选择图标">
  21. <el-option v-for="(item,index) in formIcons" :key="index" :label="item.name" :value="item.value">
  22. <i style="font-size: 18px;" :class="item.name"></i>
  23. </el-option>
  24. </el-select>
  25. </template>
  26. <template v-else-if="fromDataType(item.datatype) == 'TEXT' || fromDataType(item.datatype) == 'VARCHAR'">
  27. <el-input size="small" @change="inputChangeHandler(item.pagecode)" v-model="tableForm[item.pagecode]"></el-input>
  28. </template>
  29. <template v-else-if="fromDataType(item.datatype) == 'TEXTAREA'">
  30. <el-input type="textarea" v-model="tableForm[item.pagecode]"></el-input>
  31. </template>
  32. <template v-else-if="fromDataType(item.datatype) == 'PASSWORD'">
  33. <el-input show-password v-model="tableForm[item.pagecode]"></el-input>
  34. </template>
  35. <template v-else-if="fromDataType(item.datatype) == 'UNPASSWORD'">
  36. <el-input show-password v-model="tableForm[item.pagecode]"></el-input>
  37. </template>
  38. <template v-else-if="fromDataType(item.datatype) == 'UPLOAD'">
  39. <upload-item :id="index" :base-img="tableForm[item.pagecode]" ref="upload" />
  40. </template>
  41. <template v-else-if="fromDataType(item.datatype) == 'SWITCH'">
  42. <el-switch v-model="tableForm[item.pagecode]"></el-switch>
  43. </template>
  44. <template v-else-if="fromDataType(item.datatype) == 'CASCADER'">
  45. <el-cascader v-model="tableForm[item.pagecode]" :options="tableOptions[item.pagecode]"></el-cascader>
  46. </template>
  47. <template v-else-if="fromDataType(item.datatype) == 'CHECKBOX'">
  48. <el-checkbox-group v-model="tableForm[item.pagecode]">
  49. <el-checkbox v-for="itemParams in tableOptions[item.pagecode]" :key="itemParams[item['dropdownlistid']]" :label="itemParams[item['dropdownlistid']]" name="type">{{ [item['dropdownlistlabel']] }}</el-checkbox>
  50. </el-checkbox-group>
  51. </template>
  52. <template v-else-if="fromDataType(item.datatype) == 'RADIO'">
  53. <el-radio-group v-model="tableForm[item.pagecode]">
  54. <el-radio v-for="itemParams in tableOptions[item.pagecode]" :key="itemParams[item['dropdownlistid']]" :label="itemParams[item['dropdownlistid']]" name="type">{{ [item['dropdownlistlabel']] }}</el-radio>
  55. </el-radio-group>
  56. </template>
  57. <template v-else-if="fromDataType(item.datatype) == 'TIME'">
  58. <el-time-picker size="small" :picker-options="{selectableRange: '00:00:00 - 23:59:59'}" v-model="tableForm[item.pagecode]" placeholder="选择任意时间段" @change="inputChangeHandler(item.pagecode)">
  59. </el-time-picker>
  60. </template>
  61. <template v-else-if="fromDataType(item.datatype) == 'DATE'">
  62. <el-date-picker size="small" class="datetimes" value-format="yyyy-MM-dd" v-model="tableForm[item.pagecode]" type="date" placeholder="选择日期" @change="inputChangeHandler(item.pagecode)">
  63. </el-date-picker>
  64. </template>
  65. <template v-else-if="fromDataType(item.datatype) == 'DATETIME'">
  66. <el-date-picker size="small" class="datetimes" value-format="yyyy-MM-dd HH:mm:ss" v-model="tableForm[item.pagecode]" type="datetime" placeholder="选择日期时间" @change="inputChangeHandler(item.pagecode)">
  67. </el-date-picker>
  68. </template>
  69. <template v-else-if="fromDataType(item.datatype) == 'INT' || fromDataType(item.datatype) == 'tinyint' || fromDataType(item.datatype) == 'NUMBER'">
  70. <el-input size="small" v-model.number="tableForm[item.pagecode]" onkeyup="value=value.replace(/[^1-9]/g,'')" @change="inputChangeHandler(item.pagecode)"></el-input>
  71. </template>
  72. <template v-else>
  73. <el-input size="small" v-model="tableForm[item.pagecode]" @change="inputChangeHandler(item.pagecode)"></el-input>
  74. </template>
  75. </el-form-item>
  76. </el-col>
  77. </el-row>
  78. </el-form>
  79. </div>
  80. </template>
  81. <script>
  82. import { Query } from "@/api/webApi"
  83. import uploadItem from './upload.vue'
  84. import JSEncrypt from "jsencrypt"
  85. import allIcons from '@/utils/icons'
  86. export default {
  87. name: 'PublicPageForm',
  88. components: { uploadItem },
  89. props: {
  90. formType: {
  91. type: String,
  92. default: 'vertical' //horizontal--水平布局 默认一行3列
  93. },
  94. formItem: {
  95. type: Array,
  96. default: () => new Array()
  97. },
  98. formPass: {
  99. type: Array,
  100. default: () => new Array()
  101. },
  102. formData: {
  103. type: Object,
  104. default: () => new Object()
  105. },
  106. formSpan: {
  107. type: Number,
  108. default: 8
  109. },
  110. labelWidth: {
  111. type: String,
  112. default: '80px'
  113. }
  114. },
  115. data () {
  116. return {
  117. tableForm: {},
  118. tableOptions: {},
  119. formItemArr: [],
  120. formPassCopy: [],
  121. loading: false,
  122. formIcons: allIcons
  123. }
  124. },
  125. watch: {
  126. formItem: {
  127. handler (array) {
  128. this.getSelectData(array)
  129. },
  130. deep: true,
  131. immediate: true
  132. },
  133. formPass: {
  134. handler (array) {
  135. this.setPassters(array)
  136. },
  137. deep: true
  138. },
  139. formData: {
  140. handler (obj) {
  141. if (!Object.keys(obj).length) {
  142. const nload = this.formItemArr.filter(item => item.datatype == 'upload' || item.datatype == 'UPLOAD')
  143. if (nload?.length) this.clearTypeUpload(nload)
  144. }
  145. this.tableForm = obj
  146. },
  147. deep: true,
  148. immediate: true
  149. }
  150. },
  151. computed: {
  152. //设置新增修改表单类型
  153. fromDataType () {
  154. return function (type) {
  155. if (type) {
  156. return type.toLocaleUpperCase().replace(/\([^\)]*\)/g, "");
  157. }
  158. }
  159. },
  160. //设置新增修改表单必填类型
  161. fromDataReq () {
  162. return function (item) {
  163. const { dropdownlist, datatype, pagename, isrequired, formatrule } = item
  164. const itemType = datatype.replace(/\([^\)]*\)/g, "")
  165. const itemReq = isrequired ? true : false
  166. const itemRule = formatrule ? true : false
  167. if (dropdownlist || dropdownlist == 0) return [{ required: itemReq, message: `${pagename}不能为空`, trigger: 'change' }]
  168. else if (itemType == 'date' || itemType == 'datetime') return [{ required: itemReq, type: 'date', message: `${pagename}不能为空`, trigger: 'change' }]
  169. else
  170. if (itemReq && itemRule) return [{ required: itemReq, message: `${pagename}不能为空`, trigger: 'blur' }, { pattern: new RegExp(formatrule), message: `请输入合法的${pagename}规则`, trigger: 'blur' }]
  171. return [{ required: itemReq, message: `${pagename}不能为空`, trigger: 'blur' }]
  172. }
  173. },
  174. },
  175. methods: {
  176. //格式化传递参数数据
  177. formatDefault (item) {
  178. if (typeof item != 'string') return {}
  179. const filterItem = {}
  180. const parameters = item.replace('{', '').replace('}', '')
  181. const parametersSplit = parameters?.split(',')
  182. parametersSplit.map(item => {
  183. const [key, val] = item?.split(':')
  184. filterItem[key] = val
  185. })
  186. return filterItem
  187. },
  188. //去除重复请求
  189. reduceHttp (arr = [], formItem = []) {
  190. const datas = _.cloneDeep(arr)
  191. const dataMap = new Map()
  192. const [columnArrs1, columnArrs2, allResult, allResultKey] = [[], [], [], []]
  193. if (!datas.length) return
  194. datas.map(item => {
  195. const { datacontent, dropdownlist } = item
  196. const nameter = Object.entries(datacontent.filter)[0]
  197. const namekey = dropdownlist + nameter[0] + nameter[1]
  198. if (!dataMap.get(namekey)) {
  199. dataMap.set(namekey, item)
  200. columnArrs1.push(item)
  201. } else {
  202. columnArrs2.push(item)
  203. }
  204. })
  205. columnArrs1.map(({ dropdownlist, pagecode, datacontent }) => {
  206. allResultKey.push(pagecode)
  207. allResult.push(Query({ serviceid: dropdownlist, datacontent, event: '0', page: 1, size: 9999 }))
  208. })
  209. this.getAnscyData(allResultKey, allResult, _.cloneDeep(formItem), _.cloneDeep(columnArrs1), _.cloneDeep(columnArrs2))
  210. },
  211. //获取表单下拉数据
  212. getSelectData (formItem = []) {
  213. if (!formItem.length || !Array.isArray(formItem)) return
  214. const formItemCopy = _.cloneDeep(formItem)
  215. const [allResult, allResultKey, allResultList] = [[], [], []]
  216. formItemCopy.map(({ dropdownlist, pagecode, defaultparameters }) => {
  217. if (((dropdownlist || dropdownlist == 0) && dropdownlist != "")) {
  218. const datacontent = defaultparameters ? { filter: this.formatDefault(defaultparameters) } : { filter: { 1: 1 } }
  219. const params = {
  220. dropdownlist,
  221. pagecode,
  222. datacontent
  223. }
  224. allResultList.push(params)
  225. }
  226. })
  227. if (allResultList?.length) {
  228. this.reduceHttp(allResultList, formItemCopy)
  229. } else {
  230. this.formItemArr = formItemCopy
  231. }
  232. },
  233. //获取异步数据
  234. async getAnscyData (allResultKey = [], allResult = [], formItem = [], columnArrs1 = [], columnArrs2 = []) {
  235. this.loading = true
  236. if (allResult.length && allResultKey.length) {
  237. const results = await Promise.allSettled(allResult)
  238. const resultDatas = []
  239. results.map((item, index) => {
  240. const { status, value } = item
  241. if (status == 'fulfilled') {
  242. const { code, returnData } = value
  243. const nitem = {
  244. pagecode: allResultKey[index],
  245. dropdownlist: columnArrs1[index].dropdownlist,
  246. returnData
  247. }
  248. resultDatas.push(nitem)
  249. this.tableOptions[allResultKey[index]] = code == 0 && returnData?.length ? this.formatData(returnData) : []
  250. }
  251. })
  252. if (resultDatas?.length) this.serRepets(_.cloneDeep(resultDatas), columnArrs1, columnArrs2)
  253. this.formItemArr = formItem
  254. } else {
  255. this.formItemArr = formItem
  256. }
  257. this.setPassters(this.formPass)
  258. this.loading = false
  259. },
  260. //设置重复下拉数据
  261. serRepets (resultDatas = [], columnArrs1, columnArrs2) {
  262. resultDatas.map(item => {
  263. columnArrs1.map(ci => {
  264. if (item.pagecode == ci.pagecode) {
  265. item.datacontent = ci.datacontent
  266. }
  267. })
  268. })
  269. const result = [...resultDatas]
  270. result.map(item => {
  271. const { datacontent, dropdownlist, returnData } = item
  272. const nameterItem = Object.entries(datacontent.filter)[0]
  273. const namekeyItem = dropdownlist + nameterItem[0] + nameterItem[1]
  274. columnArrs2.map(ci => {
  275. const { datacontent, dropdownlist, pagecode } = ci
  276. const nameterCi = Object.entries(datacontent.filter)[0]
  277. const namekeyCi = dropdownlist + nameterCi[0] + nameterCi[1]
  278. if (namekeyItem == namekeyCi) {
  279. this.tableOptions[pagecode] = _.cloneDeep(returnData)
  280. }
  281. })
  282. })
  283. },
  284. //设置下拉数据
  285. setPassters (array = []) {
  286. const passitem = this.formItemArr.filter(item => item.pagecode == 'passparameters')
  287. if (passitem?.length) {
  288. const ndata = _.cloneDeep(array)
  289. const passitemkey = passitem[0]
  290. passitemkey.datatype = 'DROP'
  291. ndata.map(item => {
  292. item.dropdownlistid = item.pageconfigurationid
  293. item.dropdownlistlabel = item.pagename
  294. })
  295. this.tableOptions['passparameters'] = ndata
  296. this.formPassCopy = ndata
  297. }
  298. },
  299. formatData (returnData) {
  300. return typeof returnData == 'string' ? JSON.parse(returnData) : returnData
  301. },
  302. //获取表单下拉数据
  303. changeSelect (code) {
  304. if (code == 'passparameters') return
  305. const datas = this.$store.state.auth.authMsg
  306. if (!datas?.length) return
  307. const ndata = datas.filter(item => item.labelcode && item.pagecode == code)
  308. if (ndata?.length) {
  309. const nitem = ndata[0]
  310. const nval = this.tableForm[code]
  311. const { dropdownlistlabel, labelcode, dropdownlistid } = nitem
  312. const wdata = this.tableOptions[code].filter(item => item[dropdownlistid] == nval)
  313. if (!wdata.length) return
  314. const witem = wdata[0]
  315. this.tableForm[labelcode] = witem[dropdownlistlabel]
  316. }
  317. },
  318. inputChangeHandler (data) {
  319. if (!this.tableForm[data]) this.tableForm[data] = null
  320. },
  321. restForm () {
  322. this.$refs['ruleForm'].resetFields()
  323. },
  324. addTypePassWord (ndata = []) {
  325. if (ndata?.length) {
  326. const pubKeyStr = sessionStorage.getItem('pubKeyStr')
  327. if (!pubKeyStr) return
  328. ndata.map(({ pagecode }) => {
  329. if (this.tableForm[pagecode]) {
  330. const jse = new JSEncrypt()
  331. jse.setPublicKey(pubKeyStr)
  332. this.tableForm[pagecode] = jse.encrypt(this.tableForm[pagecode].replace(/\s+/g, ""))
  333. }
  334. })
  335. }
  336. },
  337. addTypeUpload (nload = []) {
  338. if (nload?.length) {
  339. const files = this.$refs['upload']
  340. files.map((item, index) => {
  341. this.tableForm[nload[index]['pagecode']] = item.imageUrl
  342. })
  343. }
  344. },
  345. formatPass (npass = []) {
  346. const datas = []
  347. const maps = []
  348. if (Array.isArray(npass) && npass?.length) {
  349. this.formPassCopy.filter(item => {
  350. npass.map(p => {
  351. if (item.dropdownlistid == p) {
  352. datas.push(item)
  353. }
  354. })
  355. })
  356. } else {
  357. this.tableForm.passparameters = null
  358. }
  359. if (datas?.length) {
  360. datas.map(item => {
  361. const nitem = {}
  362. nitem['pagecode'] = item.pagecode;
  363. nitem['alias'] = item.alias;
  364. nitem['pageconfigurationid'] = item.pageconfigurationid
  365. maps.push(nitem)
  366. })
  367. this.tableForm.passparameters = JSON.stringify(maps)
  368. } else {
  369. this.tableForm.passparameters = null
  370. }
  371. },
  372. clearTypeUpload (nload = []) {
  373. if (nload?.length) {
  374. const files = this.$refs['upload']
  375. files.map((item) => {
  376. item.imageUrl = ''
  377. item.$el.firstChild.value = ''
  378. })
  379. }
  380. },
  381. formatDataNull () {
  382. for (const key in this.tableForm) {
  383. if (Object.hasOwnProperty.call(this.tableForm, key)) {
  384. const element = this.tableForm[key]
  385. if (!element && element != 0) {
  386. this.tableForm[key] = null
  387. }
  388. }
  389. }
  390. },
  391. // 新增/编辑-确认
  392. submitClickHandler () {
  393. let flag = false
  394. const ndata = this.formItemArr.filter(item => item.datatype == 'password' || item.datatype == 'PASSWORD')
  395. const nload = this.formItemArr.filter(item => item.datatype == 'upload' || item.datatype == 'UPLOAD')
  396. const npass = this.tableForm.passparameters
  397. if (nload?.length) this.addTypeUpload(nload)
  398. if (ndata?.length) this.addTypePassWord(ndata)
  399. if (npass) { this.formatPass(npass) }
  400. this.formatDataNull()
  401. this.$refs["ruleForm"].validate((valid) => {
  402. if (valid) {
  403. flag = true
  404. if (this.tableForm.hasOwnProperty('passparameters') && !this.tableForm.passparameters) {
  405. delete this.tableForm.passparameters
  406. }
  407. this.clearTypeUpload(nload)
  408. } else {
  409. flag = false;
  410. }
  411. });
  412. return flag
  413. },
  414. isShow (isdisplay) {
  415. let show = false
  416. if (eval(isdisplay)) {
  417. show = true
  418. }
  419. else {
  420. show = false
  421. }
  422. return show
  423. }
  424. }
  425. }
  426. </script>