app-form-view 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,7 +31,7 @@ export default {
31
31
  const { ...rest } = this.attrs;
32
32
  const { widget } = this.conf;
33
33
  rest.type = widget == 'password' ? 'password' : widget == 'inputNumber' ? 'number' : widget == 'textarea' ? 'textarea' : 'text'
34
- if (this.mode == 'view') { rest.readonly = true; rest.disabled = true; rest.clearable = false }
34
+ if (this.mode == 'view') { rest.readonly = true; rest.clearable = false }
35
35
  if (rest.class == 'form-control') rest.class = ''
36
36
  return rest;
37
37
  }
@@ -139,14 +139,32 @@ export default {
139
139
  },
140
140
  onConfirm(rows) {
141
141
  this.showRPicker = false
142
- this.tableData = [...rows.map(item => {
142
+ let rowArray = Array.isArray(rows) ? rows : [rows],
143
+ data = []
144
+ rowArray.forEach((row) => {
145
+ const emptyRow = {}
146
+ this.conf.columnsData.forEach((col) => {
147
+ if (
148
+ this.conf.referenceAddApi &&
149
+ this.conf.referenceAddApi.mappings &&
150
+ this.conf.referenceAddApi.mappings.filter((item) => item.name == col.name).length > 0
151
+ ) {
152
+ emptyRow[col.name] =
153
+ row[this.conf.referenceAddApi.mappings.filter((item) => item.name == col.name)[0].field]
154
+ } else {
155
+ emptyRow[col.name] = col.defaultValue || ''
156
+ }
157
+ })
158
+ JSON.stringify(emptyRow) !== '{}' && data.push(emptyRow)
159
+ })
160
+ this.innerValue = JSON.stringify(data)
161
+ this.tableData = [...data.map(item => {
143
162
  return {
144
163
  ...item,
145
164
  checked: false
146
165
  }
147
166
  })]
148
- console.log(rows)
149
- this.innerValue = JSON.stringify(this.tableData)
167
+ console.log(rows, 'onConfirm', this.tableData, this.tableColumns)
150
168
  this.$emit('input', this.innerValue)
151
169
  //this.updateCallback(rows)
152
170
  //this.$emit('input', this.innerValue);
@@ -6,10 +6,10 @@
6
6
  <van-field v-model="innerValueLabel" :label="conf.hideLabel ? '' : conf.label" v-bind="filterAttrs"
7
7
  :rules="rules" @click-right-icon="showPicker = true" right-icon="arrow"></van-field>
8
8
  <van-popup v-model="showPicker" position="bottom" get-container="#myForm" class="select-popup" closeable
9
- :style="{ height: '40%' }">
10
- <div class="custom-picker-container">
11
- <van-sticky>
12
- <van-nav-bar title="选择" :border="false" />
9
+ :style="{ height: attrs.multiple ? '40%' : 'auto' }">
10
+ <div class="custom-picker-container flex flex-column h100">
11
+ <van-sticky class="w100">
12
+ <van-nav-bar :title="'选择' + conf.label" :border="false" />
13
13
  </van-sticky>
14
14
 
15
15
  <div class="popup-body scroll-wrap" v-if="attrs.multiple">
@@ -23,7 +23,7 @@
23
23
  </div>
24
24
  </div>
25
25
 
26
- <van-picker :columns="selectOptions" value-key="label" class="flex-item" ref="myPicker" v-else>
26
+ <van-picker :columns="selectOptions" value-key="label" ref="myPicker" v-else>
27
27
  </van-picker>
28
28
  <div class="bottom-btn">
29
29
  <van-button type="primary" round block @click="onConfirm" icon="checked">确认</van-button>
@@ -145,16 +145,16 @@ export default {
145
145
  </script>
146
146
 
147
147
  <style scoped>
148
- /deep/ .bs-suggest-ul {
148
+ .bs-suggest-ul {
149
149
  max-height: 300px;
150
150
  overflow-y: auto;
151
151
  }
152
152
 
153
- /deep/ .bs-suggest-ul li {
153
+ .bs-suggest-ul li {
154
154
  padding: 6px 12px;
155
155
  }
156
156
 
157
- /deep/ .bs-suggest-ul li.active {
157
+ .bs-suggest-ul li.active {
158
158
  background-color: #337ab7;
159
159
  color: #fff;
160
160
  }
@@ -260,7 +260,7 @@ export default {
260
260
  if (data && data.length > 0 && this.uploadColumns.length > 0) {
261
261
  data = this.convertFiles(data)
262
262
  }
263
-
263
+ console.log(columns, 'columns')
264
264
  this.tableOptions = {
265
265
  id: this.tableId,
266
266
  sidePagination: 'client',
package/src/index.js CHANGED
@@ -16,7 +16,7 @@ import createStore from './store/index'
16
16
  import ElementUI from 'element-ui';
17
17
  import 'element-ui/lib/theme-chalk/index.css';
18
18
  import Build from './views/build/index.vue'
19
- //import Build from './views/build/viewAppForm.vue'
19
+ //import Build from './views/build/viewForm.vue'
20
20
  import FormItem from '@/components/form/FormItem.vue'
21
21
  import Form from '@/components/form/Form.vue'
22
22
  import SubRow from '@/components/form/SubRow.vue'
@@ -178,8 +178,6 @@ export default {
178
178
  </script>
179
179
 
180
180
  <style scoped>
181
- .dialog-footer {}
182
-
183
181
  .el-select {
184
182
  margin: 0 auto;
185
183
  }
@@ -197,11 +195,6 @@ export default {
197
195
  color: #409eff;
198
196
  }
199
197
 
200
- .flex {
201
- display: flex;
202
- align-items: center;
203
- }
204
-
205
198
  .align-center {
206
199
  align-items: center;
207
200
  }
@@ -1076,7 +1076,6 @@ export default {
1076
1076
  this.changeActiveData('allowedFileType')
1077
1077
  },
1078
1078
  changeActiveData(key) {
1079
- console.log(this.activeDataOptions[key])
1080
1079
  if (this.activeDataOptions[key] !== undefined && this.currentData[key] !== this.activeData[key]) {
1081
1080
  this.$emit('update', key, this.activeData[key])
1082
1081
  }
@@ -1797,19 +1797,4 @@ $lighterBlue: #1e88e5;
1797
1797
  }
1798
1798
 
1799
1799
  }
1800
-
1801
- /* 全局美化滚动条(窄滚动条) */
1802
- /deep/ ::-webkit-scrollbar {
1803
- width: 3px !important;
1804
- height: 3px !important;
1805
- }
1806
-
1807
- /deep/ ::-webkit-scrollbar-thumb {
1808
- background: #ccc !important;
1809
- border-radius: 3px !important;
1810
- }
1811
-
1812
- /deep/ ::-webkit-scrollbar-track {
1813
- background: transparent !important;
1814
- }
1815
1800
  </style>
@@ -22,7 +22,7 @@
22
22
  <script>
23
23
  import { baseComponents } from '@/utils/generator/config'
24
24
  import { mapActions, mapState } from 'vuex'
25
- import AppFormItem from './AppFormItem'
25
+ import AppFormItem from './AppFormItem.vue'
26
26
  import { getFormData, getFormInitData, getViewData } from '@/api/form'
27
27
  import { findFirstNodeByNameAndSjbName } from '@/utils/index'
28
28
  export default {
@@ -30,6 +30,15 @@ export default {
30
30
  AppFormItem
31
31
  },
32
32
  props: {
33
+ formId: {
34
+ type: String,
35
+ },
36
+ buttonCode: {
37
+ type: String,
38
+ },
39
+ ywid: {
40
+ type: String,
41
+ },
33
42
  formData: {
34
43
  type: Object,
35
44
  default: () => { }
@@ -101,6 +110,15 @@ export default {
101
110
  }
102
111
  },
103
112
  deep: true
113
+ },
114
+ formId() {
115
+ this.initData(this.formId, this.buttonCode, this.ywid)
116
+ },
117
+ buttonCode() {
118
+ this.initData(this.formId, this.buttonCode, this.ywid)
119
+ },
120
+ ywid() {
121
+ this.initData(this.formId, this.buttonCode, this.ywid)
104
122
  }
105
123
  },
106
124
  created() {
@@ -114,132 +132,153 @@ export default {
114
132
 
115
133
  // 调用修改后的方法,获取formId
116
134
  const { formId, buttonCode, ywid } = this.getFormParamsFromUrl();
117
- if (!formId) {
135
+ if (formId) this.initData(formId, buttonCode, ywid)
136
+ if (this.formId) this.initData(this.formId, this.buttonCode, this.ywid)
137
+ if (!formId || !this.formId) {
118
138
  console.warn('未从URL中获取到表单ID');
119
139
  return; // 无ID时终止请求,避免接口报错
120
140
  }
121
- // 原有接口请求逻辑不变
122
- getFormData({ id: formId }).then(res => {
123
- if (res.code == 0) {
124
- const data = res.data;
125
- const formCode = data.formCode
126
- this.openType = data.openType
127
- let formJson = JSON.parse(data.formJson);
128
141
 
129
- let currentType = 'add'
130
- if (formJson.sceneList && formJson.sceneList.length > 0 && buttonCode && formJson.sceneList.filter(item => item.sceneCode == buttonCode).length > 0) {
131
- currentType = formJson.sceneList.filter(item => item.sceneCode == buttonCode)[0].operationType
132
- }
133
- this.drawingList = JSON.parse(JSON.stringify(formJson.fields))
134
- delete formJson.fields
135
- this.formConf = formJson
136
- this.formConf.mode = currentType == 'detail' ? 'view' : currentType
137
- this.formConf.model = {}
138
- if (this.formConf && this.formConf.buttons && this.formConf.buttons.length > 0) {
139
- if (this.$refs.detailBtns) {
140
- this.paddingBottom = this.$refs.detailBtns.offsetHeight + 'px';
141
- } else {
142
- this.paddingBottom = '60px'
143
- this.$nextTick(() => {
144
- if (this.$refs.detailBtns) this.paddingBottom = this.$refs.detailBtns.offsetHeight + 'px';
145
- })
146
- }
142
+ },
143
+ mounted() {
147
144
 
148
- } else {
149
- this.paddingBottom = '0px';
150
- }
151
- if (this.formConf.mode == 'add') {
152
- if (formCode) getFormInitData({ formCode }).then(res => {
153
- if (res.code == 0) {
154
- this.formConf.model = res.data
145
+ },
146
+ methods: {
147
+ ...mapActions('user', ['fetchUserInfo']),
148
+ initData(formId, buttonCode, ywid) {
149
+ // 原有接口请求逻辑不变
150
+ getFormData({ id: formId }).then(res => {
151
+ if (res.code == 0) {
152
+ const data = res.data;
153
+ const formCode = data.formCode
154
+ this.openType = data.openType
155
+ let formJson = JSON.parse(data.formJson);
156
+
157
+ let currentType = 'add'
158
+ if (formJson.sceneList && formJson.sceneList.length > 0 && buttonCode && formJson.sceneList.filter(item => item.sceneCode == buttonCode).length > 0) {
159
+ currentType = formJson.sceneList.filter(item => item.sceneCode == buttonCode)[0].operationType
160
+ }
161
+ this.drawingList = JSON.parse(JSON.stringify(formJson.fields))
162
+ delete formJson.fields
163
+ this.formConf = formJson
164
+ this.formConf.mode = currentType == 'detail' ? 'view' : currentType
165
+ this.formConf.model = {}
166
+ if (this.formConf && this.formConf.buttons && this.formConf.buttons.length > 0) {
167
+ if (this.$refs.detailBtns) {
168
+ this.paddingBottom = this.$refs.detailBtns.offsetHeight + 'px';
169
+ } else {
170
+ this.paddingBottom = '60px'
171
+ this.$nextTick(() => {
172
+ if (this.$refs.detailBtns) this.paddingBottom = this.$refs.detailBtns.offsetHeight + 'px';
173
+ })
155
174
  }
156
- })
157
- }
158
- else if (this.formConf.mode == 'edit' || this.formConf.mode == 'view') {
159
- //编辑
160
- if (!ywid) {
161
- $.modal.confirm('编辑状态下未从URL中获取到表单ywid,是否返回?', () => {
162
- //关闭当前页面
163
- //根据页面打开方式
164
- if (this.openType == 'dialog') {
165
- var index = parent.layer.getFrameIndex(window.name); // 获取当前层的索引
166
- parent.layer.close(index);
167
- } else if (this.openType == 'blank') {
168
- window.close();
169
- } else {
170
- $.modal.closeTab();
171
- }
172
- })
173
- } else if (formCode && ywid) {
174
- //获取表单数据
175
- getViewData({ formCode, id: ywid }).then(res => {
175
+
176
+ } else {
177
+ this.paddingBottom = '0px';
178
+ }
179
+ if (this.formConf.mode == 'add') {
180
+ if (formCode) getFormInitData({ formCode }).then(res => {
176
181
  if (res.code == 0) {
177
182
  this.formConf.model = res.data
178
- let uploadData = {}
179
- for (let key in this.formConf.model) {
180
- const keyMap = this.multiplyUploadList[key]
181
- if (keyMap) {
182
- const bizType = keyMap.bizType
183
- this.formConf.model[key].forEach(item => {
184
- if (!uploadData[key + '@' + item[bizType]]) {
185
- uploadData[key + '@' + item[bizType]] = []
186
- }
187
- uploadData[key + '@' + item[bizType]].push({
188
- [keyMap.path]: item.path.fileBase64,
189
- [keyMap.name]: item.path.fileName,
190
- [keyMap.type]: item.path.fileType,
191
- [keyMap.size]: item.size,
192
- [bizType]: item[bizType]
183
+ }
184
+ })
185
+ }
186
+ else if (this.formConf.mode == 'edit' || this.formConf.mode == 'view') {
187
+ //编辑
188
+ if (!ywid) {
189
+ $.modal.confirm('编辑状态下未从URL中获取到表单ywid,是否返回?', () => {
190
+ //关闭当前页面
191
+ //根据页面打开方式
192
+ if (this.openType == 'dialog') {
193
+ var index = parent.layer.getFrameIndex(window.name); // 获取当前层的索引
194
+ parent.layer.close(index);
195
+ } else if (this.openType == 'blank') {
196
+ window.close();
197
+ } else {
198
+ $.modal.closeTab();
199
+ }
200
+ })
201
+ } else if (formCode && ywid) {
202
+ //获取表单数据
203
+ getViewData({ formCode, id: ywid }).then(res => {
204
+ if (res.code == 0) {
205
+ this.formConf.model = res.data
206
+ let uploadData = {}
207
+ for (let key in this.formConf.model) {
208
+ const keyMap = this.multiplyUploadList[key]
209
+ if (keyMap) {
210
+ const bizType = keyMap.bizType
211
+ this.formConf.model[key].forEach(item => {
212
+ if (!uploadData[key + '@' + item[bizType]]) {
213
+ uploadData[key + '@' + item[bizType]] = []
214
+ }
215
+ uploadData[key + '@' + item[bizType]].push({
216
+ [keyMap.path]: item.path.fileBase64,
217
+ [keyMap.name]: item.path.fileName,
218
+ [keyMap.type]: item.path.fileType,
219
+ [keyMap.size]: item.size,
220
+ [bizType]: item[bizType]
221
+ })
193
222
  })
194
- })
195
- delete this.multiplyUploadList[key]
196
- delete this.formConf.model[key]
197
- }
198
- const keyMap2 = this.multiplySingleUploadList[key]
199
- if (keyMap2 && this.formConf.model[key]) {
200
- this.formConf.model[key] = this.formConf.model[key].map(item => {
201
- return {
202
- [keyMap2.path]: item.path.fileBase64,
203
- [keyMap2.name]: item.path.fileName,
204
- [keyMap2.type]: item.path.fileType,
205
- [keyMap2.size]: item.size,
206
- [keyMap2.bizType]: item[keyMap2.bizType]
223
+ delete this.multiplyUploadList[key]
224
+ delete this.formConf.model[key]
225
+ }
226
+ const keyMap2 = this.multiplySingleUploadList[key]
227
+ if (keyMap2 && this.formConf.model[key]) {
228
+ this.formConf.model[key] = this.formConf.model[key].map(item => {
229
+ return {
230
+ [keyMap2.path]: item.path.fileBase64,
231
+ [keyMap2.name]: item.path.fileName,
232
+ [keyMap2.type]: item.path.fileType,
233
+ [keyMap2.size]: item.size,
234
+ [keyMap2.bizType]: item[keyMap2.bizType]
235
+ }
207
236
  }
237
+ )
208
238
  }
209
- )
210
- }
211
- const tableMap = this.tableList.filter(item => item.name == key)
239
+ const tableMap = this.tableList.filter(item => item.name == key)
212
240
 
213
- if (tableMap && tableMap.length > 0) {
214
- this.formConf.model[key] = JSON.stringify(this.formConf.model[key])
241
+ if (tableMap && tableMap.length > 0) {
242
+ this.formConf.model[key] = JSON.stringify(this.formConf.model[key])
243
+ }
215
244
  }
245
+ for (let key in uploadData) {
246
+ this.formConf.model[key] = uploadData[key]
247
+ }
248
+ console.log(this.formConf.model, '回显数据')
216
249
  }
217
- for (let key in uploadData) {
218
- this.formConf.model[key] = uploadData[key]
219
- }
220
- console.log(this.formConf.model, '回显数据')
221
- }
222
- })
223
- }
224
- } else {
250
+ })
251
+ }
252
+ } else {
225
253
 
254
+ }
226
255
  }
227
- }
228
- }).catch(err => {
229
- console.error('获取表单数据失败:', err);
230
- })
231
- },
232
- mounted() {
233
-
234
- },
235
- methods: {
236
- ...mapActions('user', ['fetchUserInfo']),
256
+ }).catch(err => {
257
+ console.error('获取表单数据失败:', err);
258
+ })
259
+ },
237
260
  onClickLeft() { },
238
261
  // 抽取方法:返回处理后的 fields 数组
239
262
  getDrawingList(fields) {
240
263
  const len = fields.length;
264
+
265
+ // 先深拷贝一份,避免修改原数组
266
+ const fieldList = [...fields];
267
+
268
+ // 第一步:遍历处理 subTitle 与 table 联动
269
+ for (let i = 0; i < len; i++) {
270
+ const current = fieldList[i];
271
+ const next = fieldList[i + 1];
272
+ // 当前是 subTitle 且下一个存在、并且是 table
273
+ if (current.widget === 'subTitle' && next && next.widget === 'table') {
274
+ // subTitle 设为显示
275
+ current.appVisible = false;
276
+ // table 的 label 赋值为 subTitle 的 label
277
+ next.label = current.label;
278
+ }
279
+ }
241
280
  // 直接 return map 结果
242
- return fields.map((item, index) => {
281
+ return fieldList.map((item, index) => {
243
282
  const { class: cls, ...rest } = item;
244
283
  const isFirst = index === 0;
245
284
  const isLast = index === len - 1;
@@ -247,8 +286,9 @@ export default {
247
286
 
248
287
  let KClass = '';
249
288
  // 最后一个
250
- if (isLast && isInBase) {
251
- KClass = 'last-cell-child';
289
+ if (isLast) {
290
+ if (isInBase)
291
+ KClass = 'last-cell-child';
252
292
  }
253
293
  // 第一个
254
294
  else if (isFirst) {
@@ -256,11 +296,10 @@ export default {
256
296
  KClass = 'first-cell-child';
257
297
  }
258
298
  }
259
-
260
299
  // 中间元素
261
300
  else {
262
- const prev = fields[index - 1];
263
- const next = fields[index + 1];
301
+ const prev = fieldList[index - 1];
302
+ const next = fieldList[index + 1];
264
303
  const prevIn = this.baseWidget.indexOf(prev.widget) > -1;
265
304
  const nextIn = this.baseWidget.indexOf(next.widget) > -1;
266
305
  const isPrevSubTitle = prev.widget === 'subTitle';
@@ -3,9 +3,9 @@
3
3
  <div class="gray-bg dialog-content" :style="{ 'padding-bottom': paddingBottom }">
4
4
  <c-form :conf="formConf" ref="cform" :model="formConf.model || {}" :openType="openType"
5
5
  :singleUploadList="singleUploadList" :multiplySingleUploadList="multiplySingleUploadList"
6
- @updateItem="updateItem">
6
+ @updateItem="updateItem" class="h100">
7
7
  <div class="container-div animated fadeInRight">
8
- <div class="row">
8
+ <div class="row" style="overflow:auto">
9
9
  <div class="col-xs-12 col-lg-12 col-md-12 search-collapse">
10
10
  <div class="detail-title" v-if="formConf.showName && formConf.name">{{ sceneName }}{{
11
11
  formConf.name }}</div>
@@ -90,13 +90,15 @@ button[disabled] { opacity: 0.6; }
90
90
 
91
91
  .app-page { height: 100%; overflow: hidden; }
92
92
 
93
+ .app-page .bottom-btns { gap: 15px; padding-left: 10px; padding-right: 10px; }
94
+
93
95
  .app-page .bottom-btns .widget-button { display: -webkit-box; display: -ms-flexbox; display: flex; margin: 0; -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; -webkit-box-align: center; -ms-flex-align: center; align-items: center; color: #646566; }
94
96
 
95
97
  .app-page .bottom-btns .widget-button .van-icon { display: none; }
96
98
 
97
99
  .app-page .bottom-btns .widget-button .icon { margin: 0 auto 2px; font-size: 18px; }
98
100
 
99
- .app-page .bottom-btns .widget-button:last-child { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; -webkit-box-align: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; color: white; border-radius: 15px; height: 40px; font-size: 14px; margin-right: 5px; background: -webkit-gradient(linear, left top, right top, from(var(--primary-color-60)), to(var(--primary-color))); background: -o-linear-gradient(left, var(--primary-color-60), var(--primary-color)); background: linear-gradient(to right, var(--primary-color-60), var(--primary-color)); }
101
+ .app-page .bottom-btns .widget-button:last-child { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; -webkit-box-align: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; color: white; border-radius: 15px; height: 40px; font-size: 14px; margin-right: 5px; -webkit-box-flex: 1; -ms-flex: 1; flex: 1; background: -webkit-gradient(linear, left top, right top, from(var(--primary-color-60)), to(var(--primary-color))); background: -o-linear-gradient(left, var(--primary-color-60), var(--primary-color)); background: linear-gradient(to right, var(--primary-color-60), var(--primary-color)); }
100
102
 
101
103
  .app-page .bottom-btns .widget-button:last-child .icon { color: #fff; margin: 0 5px 0 0; }
102
104
 
@@ -81,9 +81,13 @@ button[disabled]{
81
81
  height:100%;
82
82
  overflow:hidden;
83
83
  .bottom-btns{
84
+ gap:15px;
85
+ padding-left: 10px;
86
+ padding-right: 10px;
84
87
  .widget-button{
85
88
  display:flex;
86
89
  margin:0;
90
+
87
91
  flex-direction: column;
88
92
  align-items: center;
89
93
  color: #646566;
@@ -101,6 +105,7 @@ button[disabled]{
101
105
  height: 40px;
102
106
  font-size: 14px;
103
107
  margin-right: 5px;
108
+ flex:1;
104
109
  background: linear-gradient(to right, var(--primary-color-60), var(--primary-color));
105
110
  .icon{color:#fff;margin:0 5px 0 0;}
106
111
  }