GenerateFormItem.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <template>
  2. <div class="fm-form-item" :data-id="widget.model" v-if="widget.key">
  3. <el-form-item
  4. v-if="widget.type != 'divider' && widget.type != 'alert' && elementDisplay"
  5. :prop="fieldNode ? fieldNode + '.' + widget.model : widget.model"
  6. :rules="rules[ruleProp]"
  7. :class="{
  8. [widget.options && widget.options.customClass]: widget.options && widget.options.customClass?true: false,
  9. 'no-label-form-item': widget.options.isLabelWidth && widget.options.labelWidth == 0,
  10. 'fm-label-wrap': widget.options.labelWrap
  11. }"
  12. :label="(widget.options.hideLabel || (isTable && !isMobile)) ? '' : widget.name"
  13. :label-width="widget.options.hideLabel ? '0px' : (widget.options.isLabelWidth ? widget.options.labelWidth + 'px' : '')"
  14. :key="widget.key"
  15. :required="widget.options.required"
  16. ref="generateFormItem"
  17. >
  18. <div v-if="widget.options.tip" class="fm-item-tooltip" v-html="widget.options.tip.replace(/\n/g, '<br/>')"></div>
  19. <generate-element-item
  20. :blanks="blanks"
  21. :is-table="isTable"
  22. :table-name="tableName"
  23. :widget="widget"
  24. :models="dataModels"
  25. :remote="remote"
  26. :edit="edit"
  27. :remote-option="remoteOption"
  28. :key="widget.key"
  29. :rules="rules"
  30. v-model="dataModel"
  31. :platform="platform"
  32. :preview="preview"
  33. :data-source-value="dataSourceValue"
  34. :event-function="eventFunction"
  35. :print-read="printRead"
  36. :container-key="containerKey"
  37. :is-subform="isSubform"
  38. :row-index="rowIndex"
  39. :sub-name="subName"
  40. :is-dialog="isDialog"
  41. :dialog-name="dialogName"
  42. ref="generateElementItem"
  43. :is-group="isGroup"
  44. :group="group"
  45. :field-node="fieldNode ? fieldNode + '.' + widget.model : widget.model"
  46. >
  47. <template v-slot:[blank.name]="scope" v-for="blank in blanks">
  48. <slot :name="blank.name" :model="scope.model"></slot>
  49. </template>
  50. </generate-element-item>
  51. </el-form-item>
  52. <el-form-item v-if="widget.type == 'divider' && elementDisplay" label-width="0">
  53. <el-divider
  54. :content-position="widget.options.contentPosition"
  55. v-bind="widget.options.customProps"
  56. :ref="'fm-'+widget.model"
  57. >
  58. {{widget.name}}
  59. </el-divider>
  60. </el-form-item>
  61. <el-form-item v-if="widget.type == 'alert' && elementDisplay" label-width="0">
  62. <el-alert
  63. :title="widget.options.title"
  64. :type="widget.options.type"
  65. :description="widget.options.description"
  66. :closable="widget.options.closable"
  67. :center="widget.options.center"
  68. :show-icon="widget.options.showIcon"
  69. :effect="widget.options.effect"
  70. :style="{width: widget.options.width}"
  71. v-bind="widget.options.customProps"
  72. :ref="'fm-'+widget.model"
  73. ></el-alert>
  74. </el-form-item>
  75. </div>
  76. </template>
  77. <script>
  78. import GenerateElementItem from './GenerateElementItem'
  79. import _ from 'lodash'
  80. import {executeExpression, isExpression, extractExpression} from '../util/expression'
  81. export default {
  82. components: {
  83. GenerateElementItem
  84. },
  85. props: ['widget', 'models', 'rules', 'remote', 'blanks', 'display', 'edit',
  86. 'remoteOption', 'platform', 'preview', 'containerKey', 'dataSourceValue', 'eventFunction',
  87. 'printRead', 'isSubform', 'rowIndex', 'subName', 'subHideFields', 'subDisabledFields',
  88. 'isDialog', 'dialogName', 'group', 'fieldNode', 'isGroup', 'isTable', 'isMobile', 'tableName'],
  89. data () {
  90. return {
  91. dataModel: Object.keys(this.models).includes(this.widget.model) ? this.models[this.widget.model] : _.cloneDeep(this.widget.options.defaultValue),
  92. dataModels: this.models
  93. }
  94. },
  95. computed: {
  96. ruleProp () {
  97. let currentProp = this.widget.model
  98. if (this.group) {
  99. currentProp = this.group + '.' + currentProp
  100. }
  101. return currentProp
  102. },
  103. currentOptions () {
  104. if (this.isTable || this.isSubform) {
  105. return {
  106. value: this.dataModel,
  107. fieldNode: this.fieldNode ? this.fieldNode + '.' + this.widget.model : this.widget.model,
  108. currentRef: this.$refs['generateElementItem']?.$refs[`fm-${this.widget.model}`],
  109. rowIndex: this.rowIndex,
  110. row: _.cloneDeep(this.models),
  111. field: this.widget.model,
  112. group: this.group
  113. }
  114. } else {
  115. return {
  116. value: this.dataModel,
  117. fieldNode: this.fieldNode ? this.fieldNode + '.' + this.widget.model : this.widget.model,
  118. currentRef: this.$refs['generateElementItem']?.$refs[`fm-${this.widget.model}`],
  119. field: this.widget.model,
  120. group: this.group
  121. }
  122. }
  123. },
  124. elementDisplay () {
  125. let curFullField = this.fieldNode ? this.fieldNode + '.' + this.widget.model : this.widget.model
  126. let curField = this.group ? this.group + '.' + this.widget.model : this.widget.model
  127. if (this.dynamicHideFields[curFullField] != undefined) {
  128. return !this.dynamicHideFields[curFullField]
  129. }
  130. if (this.dynamicHideFields[curField] != undefined) {
  131. return !this.dynamicHideFields[curField]
  132. }
  133. if (typeof this.widget.options.hidden === 'boolean') {
  134. return !this.widget.options.hidden
  135. } else {
  136. if (isExpression(this.widget.options.hidden)) {
  137. return !executeExpression(extractExpression(this.widget.options.hidden), this.currentOptions, this.formContext)
  138. }
  139. }
  140. return true
  141. },
  142. groupNode () {
  143. return this.group ? this.group + '.' + this.widget.model : this.widget.model
  144. },
  145. elementNode () {
  146. return this.fieldNode ? this.fieldNode + '.' + this.widget.model : this.widget.model
  147. }
  148. },
  149. inject: {
  150. setSubformData: {
  151. default: () => {}
  152. },
  153. setDialogData: {
  154. default: () => {}
  155. },
  156. setGroupData: {
  157. default: () => {}
  158. },
  159. setTableData: {
  160. default: () => {}
  161. },
  162. onChange: {
  163. default: () => {}
  164. },
  165. dynamicValueData: {
  166. default: []
  167. },
  168. formContext: {
  169. default: {}
  170. },
  171. dynamicHideFields: {
  172. default: {}
  173. },
  174. generateFormItemContext: {
  175. default: () => {}
  176. },
  177. deleteFormItemContext: {
  178. default: () => {}
  179. },
  180. sendRequest: {
  181. default: () => {}
  182. }
  183. },
  184. created () {
  185. this.refreshDynamicValue()
  186. },
  187. mounted () {
  188. this.generateFormItemContext(this.elementNode, this)
  189. },
  190. beforeDestroy () {
  191. this.deleteFormItemContext(this.elementNode)
  192. },
  193. methods: {
  194. refreshDynamicValue (args) {
  195. return new Promise((resolve, reject) => {
  196. if (this.widget.options.isDynamicValue
  197. && this.widget.options.dynamicValueType == 'datasource'
  198. && this.widget.options.dynamicValueDataSource) {
  199. let key = this.group ? this.group + '.' + this.widget.model + '.' + this.widget.options.dynamicValueDataSource
  200. : this.widget.model + '.' + this.widget.options.dynamicValueDataSource
  201. let curArgs = {...this.widget.options.dynamicValueArgs}
  202. for (let key in curArgs) {
  203. if (isExpression(curArgs[key])) {
  204. curArgs[key] = executeExpression(extractExpression(curArgs[key]), this.currentOptions, this.formContext)
  205. }
  206. }
  207. if (args && typeof args === 'object') {
  208. curArgs = {...curArgs, ...args}
  209. }
  210. let _data = this.dynamicValueData.find(item => item.key === key && _.isEqual(item.args, curArgs))
  211. if (_data) {
  212. if (this.widget.options.dynamicValueStruct) {
  213. try {
  214. this.dataModel = (new Function('data', `return data.${this.widget.options.dynamicValueStruct}`))(_data.value)
  215. resolve(this.dataModel)
  216. } catch (e) {reject(e)}
  217. } else {
  218. this.dataModel = _data.value
  219. resolve(this.dataModel)
  220. }
  221. } else {
  222. this.sendRequest(this.widget.options.dynamicValueDataSource, curArgs).then(resData => {
  223. if (this.widget.options.dynamicValueStruct) {
  224. try{
  225. this.dataModel = (new Function('data', `return data.${this.widget.options.dynamicValueStruct}`))(resData)
  226. resolve(this.dataModel)
  227. } catch (e) {reject(e)}
  228. } else {
  229. this.dataModel = resData
  230. resolve(this.dataModel)
  231. }
  232. })
  233. }
  234. }
  235. if (this.widget.options.isDynamicValue
  236. && this.widget.options.dynamicValueType == 'fx'
  237. && this.widget.options.dynamicValueFx) {
  238. let value = executeExpression(this.widget.options.dynamicValueFx, this.currentOptions, this.formContext)
  239. if (value !== null) {
  240. this.$nextTick(() => {
  241. this.dataModel = value
  242. })
  243. }
  244. resolve(value)
  245. }
  246. })
  247. },
  248. },
  249. watch: {
  250. dataModel: {
  251. deep: true,
  252. handler (val, oldValue) {
  253. if (JSON.stringify(val) == JSON.stringify(oldValue)) {
  254. return false
  255. }
  256. if (this.isTable) {
  257. this.setTableData(val, this.rowIndex, this.widget.model)
  258. } else if (this.isSubform) {
  259. this.setSubformData(val, this.rowIndex, this.widget.model)
  260. } else if (this.isDialog) {
  261. this.setDialogData(val, this.widget.model)
  262. } else if (this.isGroup) {
  263. this.setGroupData(val, this.widget.model)
  264. } else {
  265. this.onChange(val, this.widget.model)
  266. }
  267. // 执行 onChange 方法
  268. this.$nextTick(() => {
  269. this.eventFunction['onFormChange'] && this.eventFunction['onFormChange'](this.currentOptions)
  270. if (this.widget.events && this.widget.events.onChange) {
  271. let funcKey = this.widget.events.onChange
  272. this.eventFunction[funcKey](this.currentOptions)
  273. }
  274. })
  275. }
  276. },
  277. models: {
  278. deep: true,
  279. handler (val) {
  280. this.dataModels = val
  281. this.dataModel = Object.keys(val).includes(this.widget.model) ? val[this.widget.model] : _.cloneDeep(this.widget.options.defaultValue)
  282. }
  283. }
  284. }
  285. }
  286. </script>