generateElementItem.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. import _ from 'lodash'
  2. import {executeExpression, isExpression, extractExpression} from '../util/expression'
  3. import { EventBus } from '../util/event-bus'
  4. export const generateElementItemMixin = {
  5. props: ['config','widget', 'modelValue', 'models', 'remote', 'isTable', 'blanks', 'disabled', 'edit',
  6. 'remoteOption', 'rules', 'platform', 'preview', 'dataSourceValue', 'eventFunction',
  7. 'rowIndex', 'tableName', 'printRead', 'isMobile', 'isSubform', 'subName',
  8. 'isDialog', 'dialogName', 'group', 'fieldNode', 'containerKey', 'isGroup'],
  9. emits: ['update:modelValue', 'on-table-change'],
  10. data () {
  11. return {
  12. dataModel: this.modelValue,
  13. dataModels: this.models,
  14. key: new Date().getTime(),
  15. modelName: this.widget.model,
  16. remoteOptions: [],
  17. dynamicEvents: this.handleOnDynamicEvent(),
  18. generateDisabled: undefined,
  19. remoteToken: ''
  20. }
  21. },
  22. computed: {
  23. elementDisabled () {
  24. let currentDisabled = this.widget.options.disabled
  25. if (isExpression(this.widget.options.disabled)) {
  26. currentDisabled = executeExpression(extractExpression(this.widget.options.disabled), this.currentOptions, this.formContext)
  27. }
  28. if (typeof this.generateDisabled === 'boolean') {
  29. return !this.edit || this.generateDisabled
  30. } else {
  31. return !this.edit || Boolean(currentDisabled)
  32. }
  33. },
  34. currentOptions () {
  35. if (this.isTable || this.isSubform) {
  36. return {
  37. value: this.dataModel,
  38. fieldNode: this.fieldNode,
  39. currentRef: this.$refs['fm-'+this.widget.model],
  40. rowIndex: this.rowIndex,
  41. row: _.cloneDeep(this.models),
  42. field: this.widget.model,
  43. group: this.group
  44. }
  45. } else {
  46. return {
  47. value: this.dataModel,
  48. fieldNode: this.fieldNode,
  49. currentRef: this.$refs['fm-'+this.widget.model],
  50. field: this.widget.model,
  51. group: this.group
  52. }
  53. }
  54. },
  55. extendProps () {
  56. let obj = {}
  57. this.widget.options.extendProps && Object.keys(this.widget.options.extendProps).forEach(key => {
  58. let value = this.widget.options.extendProps[key]
  59. if (!isExpression(value)) {
  60. obj[key] = value
  61. } else {
  62. obj[key] = executeExpression(extractExpression(value), this.currentOptions, this.formContext)
  63. }
  64. })
  65. return obj
  66. },
  67. groupNode () {
  68. return this.group ? this.group + '.' + this.widget.model : this.widget.model
  69. }
  70. },
  71. inject: ['generateComponentInstance', 'deleteComponentInstance', 'eventScriptConfig', 'dynamicValueData', 'formContext', 'sendRequest'],
  72. created () {
  73. if (!this.widget.options.remote) {
  74. if (this.widget.type == 'steps') {
  75. this.loadOptions(this.widget.options.steps)
  76. } else if (this.widget.type == 'transfer') {
  77. this.loadOptions(this.widget.options.data)
  78. } else {
  79. this.loadOptions(this.widget.options.options)
  80. }
  81. }
  82. if (this.widget.options.remote
  83. && (Object.keys(this.widget.options).indexOf('remoteType') >= 0 ? this.widget.options.remoteType == 'func' : true)
  84. && this.remote[this.widget.options.remoteFunc]) {
  85. this.remote[this.widget.options.remoteFunc]((data) => {
  86. this.loadOptions(data)
  87. })
  88. }
  89. if (this.widget.options.remote
  90. && this.widget.options.remoteType == 'option'
  91. && this.remoteOption[this.widget.options.remoteOption]) {
  92. this.loadOptions(this.remoteOption[this.widget.options.remoteOption])
  93. }
  94. if (this.widget.options.remote
  95. && this.widget.options.remoteType == 'datasource'
  96. && this.dataSourceValue) {
  97. let options = this.getDataSourceOptions()
  98. options && options.value && this.loadOptions(options.value)
  99. }
  100. if (this.widget.options.remote && this.widget.options.remoteType == 'fx' ) {
  101. let options = executeExpression(this.widget.options.remoteFx, {}, this.formContext)
  102. options && this.loadOptions(options)
  103. }
  104. if ((this.widget.type === 'imgupload' || this.widget.type === 'fileupload') && this.widget.options.isQiniu) {
  105. this.loadUploadConfig()
  106. }
  107. if (this.widget.type == 'component') {
  108. const _pthis = this
  109. this.$options.components[`component-${this.widget.key}-${this.key}`] = {
  110. template: `${this.widget.options.template}`,
  111. props: ['modelValue'],
  112. emits: ['update:modelValue'],
  113. data: () => ({
  114. dataModel: this.modelValue,
  115. formState: this.formContext
  116. }),
  117. watch: {
  118. dataModel (val) {
  119. if (this.ui == 'antd') {
  120. EventBus.$emit('on-field-change', this.$attrs.id, val)
  121. } else {
  122. this.$emit('update:modelValue', val)
  123. }
  124. },
  125. modelValue (val) {
  126. this.dataModel = val
  127. }
  128. },
  129. methods: {
  130. triggerEvent (eventName, arg) {
  131. if (_pthis.eventScriptConfig()) {
  132. let currentEventScript = _pthis.eventScriptConfig().find(item => item.name == eventName)
  133. if (currentEventScript) {
  134. _pthis.eventFunction[currentEventScript.key]({
  135. ..._pthis.currentOptions,
  136. $eventArgs: arg})
  137. }
  138. }
  139. }
  140. }
  141. }
  142. }
  143. },
  144. mounted () {
  145. this.generateComponentInstance && this.generateComponentInstance(
  146. this.fieldNode,
  147. this.$refs['fm-'+this.widget.model]
  148. )
  149. this.handleOnMounted()
  150. },
  151. beforeUnmount () {
  152. this.deleteComponentInstance && this.deleteComponentInstance(this.fieldNode)
  153. if (this.$options.components[`component-${this.widget.key}-${this.key}`]) {
  154. this.$options.components[`component-${this.widget.key}-${this.key}`] = null
  155. }
  156. },
  157. methods: {
  158. handleOnDynamicEvent () {
  159. let currentEvents = {}
  160. for (let i in this.widget.events) {
  161. let funcKey = this.widget.events[i]
  162. funcKey && (
  163. currentEvents[i] = this.callbackDynamicFunc(funcKey)
  164. )
  165. }
  166. return currentEvents
  167. },
  168. callbackDynamicFunc (funcKey) {
  169. let callback = (...arg) => {
  170. this.eventFunction[funcKey]({
  171. ...this.currentOptions,
  172. $eventArgs: arg})
  173. }
  174. return callback
  175. },
  176. refreshOptionData (args) {
  177. return new Promise((resolve, reject) => {
  178. if (this.widget.options.remote && this.widget.options.remoteType === 'fx' && this.widget.options.remoteFx) {
  179. let value = executeExpression(this.widget.options.remoteFx, this.currentOptions, this.formContext)
  180. if (value !== null) {
  181. this.loadOptions(value)
  182. }
  183. resolve(value)
  184. }
  185. if (this.widget.options.remote && this.widget.options.remoteType === 'datasource' && this.widget.options.remoteDataSource) {
  186. let curArgs = typeof this.widget.options.remoteArgs === 'string' ? {} : {...this.widget.options.remoteArgs}
  187. for (let key in curArgs) {
  188. if (isExpression(curArgs[key])) {
  189. curArgs[key] = executeExpression(extractExpression(curArgs[key]), this.currentOptions, this.formContext)
  190. }
  191. }
  192. if (args && typeof args === 'object') {
  193. curArgs = {...curArgs, ...args}
  194. }
  195. let key = this.group ? this.group + '.' + this.widget.model + '.' + this.widget.options.remoteDataSource
  196. : this.widget.model + '.' + this.widget.options.remoteDataSource
  197. let sourceValue = this.dataSourceValue.find(item => item.key === key && _.isEqual(item.args, curArgs))
  198. if (sourceValue) {
  199. this.loadOptions(sourceValue.value)
  200. resolve(sourceValue.value)
  201. } else {
  202. this.sendRequest(this.widget.options.remoteDataSource, curArgs).then(resData => {
  203. this.loadOptions(resData)
  204. resolve(resData)
  205. }).catch(e => {
  206. reject(e)
  207. })
  208. }
  209. }
  210. })
  211. },
  212. loadOptions (data) {
  213. if (!Array.isArray(data)) return
  214. this.remoteOptions = data.map(item => {
  215. if (this.widget.options.props.children
  216. && this.widget.options.props.children.length
  217. && Object.keys(item).includes(this.widget.options.props.children)) {
  218. return {
  219. value: item[this.widget.options.props.value],
  220. label: item[this.widget.options.props.label],
  221. children: this.processRemoteProps(item[this.widget.options.props.children], this.widget.options.props)
  222. }
  223. } else {
  224. if (this.widget.type == 'steps') {
  225. return {
  226. title: item[this.widget.options.props.title] + '',
  227. description: item[this.widget.options.props.description]
  228. }
  229. } else if (this.widget.type == 'transfer') {
  230. return item
  231. } else {
  232. return {
  233. value: item[this.widget.options.props.value],
  234. label: item[this.widget.options.props.label]
  235. }
  236. }
  237. }
  238. })
  239. },
  240. getOptions () {
  241. return JSON.parse(JSON.stringify(this.remoteOptions))
  242. },
  243. processRemoteProps (children, props) {
  244. if (children && children.length) {
  245. return children.map(item => {
  246. if (this.processRemoteProps(item[props.children], props).length) {
  247. return {
  248. value: item[props.value],
  249. label: item[props.label],
  250. children: this.processRemoteProps(item[props.children], props)
  251. }
  252. } else{
  253. return {
  254. value: item[props.value],
  255. label: item[props.label],
  256. }
  257. }
  258. })
  259. } else {
  260. return []
  261. }
  262. },
  263. getCascaderText (value, options, texts = []) {
  264. if (value.length >= 1) {
  265. let currentOpt = options?.find(opt => opt.value == value[0])
  266. if (currentOpt) {
  267. texts.push(currentOpt.label)
  268. }
  269. value.splice(0, 1)
  270. return this.getCascaderText(value, currentOpt?.children, texts)
  271. } else if (value.length == 0) {
  272. return texts
  273. }
  274. },
  275. getTreeText (value, options) {
  276. for (let i = 0; i < options.length; i++) {
  277. let currentOpt = options[i]
  278. if (currentOpt.value == value) {
  279. return currentOpt.label
  280. }
  281. if (currentOpt.children && currentOpt.children.length > 0) {
  282. let res = this.getTreeText(value, currentOpt.children)
  283. if (res == '-') {
  284. continue
  285. } else {
  286. return res
  287. }
  288. }
  289. }
  290. return '-'
  291. },
  292. loadUploadConfig () {
  293. if (this.widget.options.tokenType === 'func') {
  294. !this.widget.options.token && this.remote[this.widget.options.tokenFunc]((data) => {
  295. this.remoteToken = data
  296. })
  297. } else if (this.widget.options.tokenType === 'fx') {
  298. let token = executeExpression(this.widget.options.tokenFx, this.currentOptions, this.formContext)
  299. token && (this.remoteToken = token)
  300. } else {
  301. if (this.dataSourceValue) {
  302. let token = this.getDataSourceOptions('tokenDataSource')
  303. token && token.value && (this.remoteToken = token.value)
  304. }
  305. }
  306. },
  307. handleOnMounted () {
  308. this.execFunction('onMounted', {})
  309. },
  310. handleOnClick () {
  311. this.execFunction('onClick', {})
  312. },
  313. handleOnFocus () {
  314. this.execFunction('onFocus', {})
  315. },
  316. handleOnBlur () {
  317. this.execFunction('onBlur', {})
  318. },
  319. handleOnUploadSelect (file) {
  320. return this.execFunction('onSelect', {file: file})
  321. },
  322. handleOnUploadSuccess (file) {
  323. this.execFunction('onUploadSuccess', {file: file})
  324. },
  325. handleOnUploadError (file) {
  326. this.execFunction('onUploadError', {file: file})
  327. },
  328. handleOnUploadProgress (file) {
  329. this.execFunction('onUploadProgress', {file: file})
  330. },
  331. handleOnUploadRemove (file) {
  332. this.execFunction('onRemove', {file: file})
  333. },
  334. handlePageChange (val) {
  335. this.execFunction('onPageChange', val)
  336. },
  337. handleCurrentRow (val) {
  338. this.execFunction('onCurrentRow', val)
  339. },
  340. handleSelectionChange (val) {
  341. this.execFunction('onSelectionChange', {
  342. selection: val
  343. })
  344. },
  345. handleOperate ({funcKey, $index, column, row}) {
  346. return this.eventFunction[funcKey]({
  347. field: this.widget.model,
  348. currentRef: this.$refs['fm-'+this.widget.model],
  349. group: this.group,
  350. fieldNode: this.fieldNode,
  351. rowIndex: $index,
  352. $index: $index,
  353. column: column,
  354. row: {...row}
  355. })
  356. },
  357. execFunction (method, arg) {
  358. if (this.widget.events && this.widget.events[method]) {
  359. let funcKey = this.widget.events[method]
  360. return this.eventFunction[funcKey]({
  361. ...this.currentOptions,
  362. ...arg,
  363. })
  364. }
  365. },
  366. getDataSourceOptions (remoteName = 'remoteDataSource') {
  367. let key = this.group ? this.group + '.' + this.widget.model + '.' + this.widget.options[remoteName]
  368. : this.widget.model + '.' + this.widget.options[remoteName]
  369. return this.dataSourceValue.find(item => item.key === key)
  370. },
  371. disabledElement (disabled) {
  372. this.generateDisabled = disabled
  373. },
  374. },
  375. watch: {
  376. modelValue (val) {
  377. this.dataModel = val
  378. },
  379. dataModel (val, oldValue) {
  380. if (JSON.stringify(val) != JSON.stringify(oldValue)) {
  381. this.$emit('update:modelValue', val)
  382. }
  383. },
  384. 'remoteOption': {
  385. deep: true,
  386. handler: function (val) {
  387. if (Object.keys(this.remoteOption).indexOf(this.widget.options.remoteOption) >= 0
  388. && this.widget.options.remote
  389. && this.widget.options.remoteType == 'option'
  390. ) {
  391. this.loadOptions(this.remoteOption[this.widget.options.remoteOption])
  392. }
  393. }
  394. },
  395. 'dataSourceValue': {
  396. deep: true,
  397. handler: function(val) {
  398. if (this.dataSourceValue) {
  399. let options = this.getDataSourceOptions()
  400. options && options.value && this.loadOptions(options.value)
  401. }
  402. if ((this.widget.type === 'imgupload' || this.widget.type === 'fileupload') && this.widget.options.isQiniu) {
  403. this.loadUploadConfig()
  404. }
  405. }
  406. }
  407. }
  408. }