ol-base-components 2.5.1 → 2.7.0

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.
@@ -0,0 +1,396 @@
1
+ <template>
2
+ <div>
3
+ <el-form
4
+ ref="formRef"
5
+ :model="form.value"
6
+ :rules="form.rules"
7
+ style="display: flex; flex-wrap: wrap"
8
+ v-bind="{
9
+ labelWidth: '130px',
10
+ disabled: !form.type,
11
+ ...$attrs,
12
+ ...form.attrs,
13
+ }"
14
+ v-on="$listeners"
15
+ >
16
+ <template v-for="(item, index) in form.model">
17
+ <el-form-item
18
+ v-if="!item.hidden"
19
+ :key="index"
20
+ :label="item.label"
21
+ :prop="item.prop"
22
+ :required="item.required || false"
23
+ :style="{ width: width(item) }"
24
+ >
25
+ <el-input
26
+ v-if="item.type == 'input'"
27
+ v-model="form.value[item.prop]"
28
+ :placeholder="
29
+ item.readonly
30
+ ? item.placeholder || item.label
31
+ : `请输入${item.placeholder || item.label}`
32
+ "
33
+ :clearable="item.clearable || true"
34
+ :readonly="item.readonly || false"
35
+ :show-password="item.showPassword || false"
36
+ v-bind="{
37
+ ...item.props,
38
+ disabled: inputDisabled(item),
39
+ }"
40
+ />
41
+ <el-input-number
42
+ v-else-if="item.type == 'number'"
43
+ v-model="form.value[item.prop]"
44
+ :placeholder="`请输入${item.placeholder || item.label}`"
45
+ :clearable="item.clearable || true"
46
+ :readonly="item.readonly || false"
47
+ v-bind="{ min: 0, ...item.props }"
48
+ />
49
+ <el-input
50
+ v-else-if="item.type == 'textarea'"
51
+ v-model="form.value[item.prop]"
52
+ type="textarea"
53
+ :placeholder="`请输入${item.placeholder || item.label}`"
54
+ :autosize="item.autosize"
55
+ :readonly="item.readonly || false"
56
+ :clearable="item.clearable || true"
57
+ :maxlength="item.length || ''"
58
+ />
59
+ <el-switch
60
+ v-else-if="item.type == 'switch'"
61
+ v-model="form.value[item.prop]"
62
+ class="switchStyle"
63
+ active-text="启用"
64
+ inactive-text="禁用"
65
+ v-bind="item.props || {}"
66
+ />
67
+ <el-radio-group v-else-if="item.type == 'radio'" v-model="form.value[item.prop]">
68
+ <el-radio v-for="ctem in item.child" :key="ctem.key" :label="ctem.key">{{
69
+ ctem.value
70
+ }}</el-radio>
71
+ </el-radio-group>
72
+ <!-- v-bind="item.props || { type: 'date' }" -->
73
+ <el-date-picker
74
+ v-else-if="item.type == 'date'"
75
+ v-model="form.value[item.prop]"
76
+ :placeholder="item.placeholder || '请选择日期'"
77
+ style="width: 100%"
78
+ v-bind="{ type: 'date', ...item.props }"
79
+ :clearable="item.clearable || true"
80
+ v-on="{
81
+ ...item.listeners,
82
+ change: event => changeHandle(event, item),
83
+ }"
84
+ />
85
+ <Tree-select
86
+ v-else-if="item.type == 'treeSelect'"
87
+ v-model="form.value[item.prop]"
88
+ v-bind="item.props || {}"
89
+ :options="item.child"
90
+ @getValue="item.change && item.change(form.value[item.prop])"
91
+ />
92
+ <!-- <el-select v-else-if="item.type == 'select'" v-model="form.value[item.prop]"
93
+ :placeholder="`请选择${item.placeholder || item.label}`"
94
+ :clearable="'clearable' in item ? item.clearable : true" :disabled="item.disabled || false"
95
+ v-bind="item.props || {}" v-on="{ ...item.listeners, change: selectChangeHandle(item) }">
96
+ <el-option v-for="(jtem, jindex) in item.child" :key="jindex" :label="jtem.value"
97
+ :value="jtem.key"></el-option>
98
+ </el-select> -->
99
+ <!-- v-on="{ ...item.listeners, change: (event) => selectChangeHandle(event,
100
+ item), }" -->
101
+ <el-select
102
+ v-else-if="item.type == 'select'"
103
+ v-model="form.value[item.prop]"
104
+ :placeholder="`请选择${item.placeholder || item.label}`"
105
+ :clearable="'clearable' in item ? item.clearable : true"
106
+ v-bind="{ disabled: !!item.disabled, ...(item.props || {}) }"
107
+ v-on="{
108
+ ...item.listeners,
109
+ change: event => selectChangeHandle(event, item),
110
+ }"
111
+ @keyup.native="
112
+ $event =>
113
+ item.keyup({
114
+ event: $event,
115
+ item,
116
+ form: form.value,
117
+ })
118
+ "
119
+ >
120
+ <el-option
121
+ v-for="(jtem, jindex) in item.child"
122
+ :key="jindex"
123
+ :label="jtem.value"
124
+ :value="jtem.key"
125
+ />
126
+ </el-select>
127
+ <div v-else-if="item.type == 'inputSpecial'">
128
+ <el-col :span="6">
129
+ <el-form-item :prop="item.layerprop">
130
+ <el-input
131
+ v-model="form.value[item.layerprop]"
132
+ :clearable="item.clearable || true"
133
+ />
134
+ </el-form-item>
135
+ </el-col>
136
+ <el-col class="line" style="text-align: center" :span="3">- </el-col>
137
+ <el-col :span="6">
138
+ <el-form-item :prop="item.rowprop">
139
+ <el-input v-model="form.value[item.rowprop]" :clearable="item.clearable || true" />
140
+ </el-form-item>
141
+ </el-col>
142
+ <el-col class="line" style="text-align: center" :span="3">- </el-col>
143
+ <el-col :span="6">
144
+ <el-form-item :prop="item.columnprop">
145
+ <el-input
146
+ v-model="form.value[item.columnprop]"
147
+ :clearable="item.clearable || true"
148
+ />
149
+ </el-form-item>
150
+ </el-col>
151
+ </div>
152
+ <!-- 自定义输入框插槽 -->
153
+ <template v-else-if="item.type == 'slot'">
154
+ <slot :name="item.name" :item="item" />
155
+ </template>
156
+ <!-- 兜底 -->
157
+ <div v-else style="color: red">"{{ item.type }}"类型暂不支持,请手动添加</div>
158
+ </el-form-item>
159
+ </template>
160
+ </el-form>
161
+ <div v-if="showBtn" slot="footer" class="dialog-footer">
162
+ <slot v-if="$slots.btnSlot" name="btnSlot" :form="form" />
163
+ <template v-else>
164
+ <el-button @click="onCancel">取消</el-button>
165
+ <el-button v-if="form.type" type="primary" @click="onConfirm">确定</el-button>
166
+ </template>
167
+ <slot name="btnAfterSlot" />
168
+ </div>
169
+ </div>
170
+ </template>
171
+ <!--
172
+ # BaseForm 基础表单组件
173
+
174
+ ## Props 属性
175
+ | 属性名 | 类型 | 默认值 | 必填 | 说明 |
176
+ |-------------|----------|---------|------|--------------|
177
+ | form | Object | - | 是 | 表单配置对象 |
178
+ | defaultValue| Object | {} | 否 | 表单默认值 |
179
+ | showBtn | Boolean | true | 否 | 是否显示底部按钮 |
180
+
181
+ ## form 对象结构
182
+ {
183
+ type: Number, // 表单类型:0-详情,1-新建,2-编辑
184
+ title: String, // 表单标题(会根据type自动设置)
185
+ value: Object, // 表单数据对象
186
+ rules: Object, // 表单验证规则
187
+ attrs: Object, // el-form的属性配置
188
+ model: Array // 表单项配置数组
189
+ }
190
+
191
+ ## model 项配置
192
+ | 字段 | 类型 | 说明 |
193
+ |-------------|----------------|---------|
194
+ | type | String | 表单项类型:input/number/textarea/switch/radio/date/treeSelect/select/projectCodeSelect/inputSpecial/slot |
195
+ | label | String | 表单项标签 |
196
+ | prop | String | 表单项字段名 |
197
+ | placeholder | String | 占位文本 |
198
+ | required | Boolean | 是否必填 |
199
+ | hidden | Boolean | 是否隐藏 |
200
+ | clearable | Boolean | 是否可清空 |
201
+ | readonly | Boolean | 是否只读 |
202
+ | disabled | Boolean/Function| 是否禁用 |
203
+ | props | Object | 对应表单控件的属性配置 |
204
+ | listeners | Object | 事件监听器配置 |
205
+
206
+ ## Events 事件
207
+ | 事件名 | 说明 | 回调参数 |
208
+ |-------------|---------------|---------|
209
+ | onSubmit | 表单提交事件 | {form: 表单配置, data: 表单数据} |
210
+ | onCancel | 取消按钮点击事件 | - |
211
+ | selectChange| 选择器值变化事件 | {obj: 当前项配置, val: 变化后的值} |
212
+ -->
213
+ <script>
214
+ import { getData } from "../../index.js";
215
+ import { initForm } from "../../../utils/initData.js";
216
+
217
+ // interface FormItem {
218
+ // type: Number;
219
+ // title?: String;
220
+ // model: IModelItem[]; //src\utils\interface\dialogInterface.ts
221
+ // rules:Form.rules;
222
+ // attrs: Form; //import { Form } from "element-ui";
223
+ // }
224
+ export default {
225
+ name: "form",
226
+ props: {
227
+ url: {
228
+ type: String,
229
+ // default: "/api/app/warehouse/warehouse",
230
+ default: "",
231
+ },
232
+ form: Object,
233
+ // 默认值
234
+ defaultValue: {
235
+ type: Object,
236
+ default: () => ({}),
237
+ },
238
+ showBtn: {
239
+ type: Boolean,
240
+ default: true,
241
+ },
242
+ },
243
+ data() {
244
+ return {
245
+ // model: [],
246
+ formInit: {}, // 初始化表单,用于重置表单用
247
+ // formValue: {}, // 表单数据
248
+ };
249
+ },
250
+ computed: {
251
+ width() {
252
+ return function (item) {
253
+ if (this.form.model.length > 18 && item.type != "textarea") {
254
+ return "25%";
255
+ } else if (
256
+ this.form.model.length > 10 &&
257
+ this.form.model.length <= 18 &&
258
+ item.type != "textarea"
259
+ ) {
260
+ return "calc(100% / 3)";
261
+ } else if (
262
+ this.form.model.length > 6 &&
263
+ this.form.model.length <= 10 &&
264
+ item.type != "textarea"
265
+ ) {
266
+ return "50%";
267
+ } else {
268
+ return item.type == "textarea" && item.width ? item.width : "100%";
269
+ }
270
+ };
271
+ },
272
+ },
273
+ watch: {
274
+ // 副作用以便父级直接使用
275
+ "form.type": {
276
+ handler(newValue) {
277
+ // 如果没有type则默认值为1
278
+ if (!Object.keys(this.form).includes("type")) {
279
+ this.$set(this.form, "type", 1);
280
+ }
281
+ let result;
282
+ switch (newValue) {
283
+ case 0:
284
+ result = "详情"; // 当 newValue 为 0 时,标题为 "详情"
285
+ break;
286
+ case 1:
287
+ result = "新建";
288
+ break;
289
+ case 2:
290
+ result = "编辑";
291
+ break;
292
+ default:
293
+ result = "弹框";
294
+ break;
295
+ }
296
+ this.form.title = result;
297
+ },
298
+ immediate: true,
299
+ },
300
+ // "form.model": {
301
+ // handler() {
302
+
303
+ // },
304
+ // immediate: true,
305
+ // deep: true
306
+ // }
307
+ },
308
+ created() {
309
+ // 默认值复制
310
+ if (Object.keys(this.defaultValue)?.length) {
311
+ Object.keys(this.defaultValue).forEach(key => {
312
+ form.value[key] = this.defaultValue[key];
313
+ });
314
+ }
315
+ initForm({
316
+ url: this.url,
317
+ form: this.form,
318
+ });
319
+ },
320
+ // beforeDestroy() {},
321
+ methods: {
322
+ // 保留之前的change调用方式,并添扩展新的
323
+ selectChangeHandle(val, item) {
324
+ (item &&
325
+ item.listeners &&
326
+ item.listeners.change &&
327
+ item.listeners.change(item, this.form.value[item.prop])) ||
328
+ item.change
329
+ ? item.change(val)
330
+ : this.selectChange(item, val);
331
+ },
332
+ changeHandle(val, item) {
333
+ if (
334
+ item &&
335
+ item.listeners &&
336
+ item.listeners.change &&
337
+ item.listeners.change(item, this.form.value[item.prop])
338
+ ) {
339
+ this.selectChange(item, val);
340
+ }
341
+ },
342
+ selectChange(obj, val) {
343
+ let temp = {
344
+ obj: obj,
345
+ val: val,
346
+ };
347
+ this.$emit("selectChange", temp);
348
+ },
349
+ inputDisabled(item) {
350
+ if (!item.props) return false;
351
+ if (!Object.keys(item.props).includes("disabled")) return false;
352
+ // disabled是函数还是Boolean值,如果boolean值直接返回,如果是函数执行函数并返回boolean
353
+ return typeof item.props.disabled === "function"
354
+ ? item.props.disabled({ item, form: this.form })
355
+ : item.props.disabled;
356
+ },
357
+ validate() {
358
+ return new Promise((resolve, reject) => {
359
+ this.$refs.formRef.validate(valid => {
360
+ if (valid) {
361
+ resolve({
362
+ valid,
363
+ formData: this.form?.value || {},
364
+ });
365
+ } else {
366
+ reject("表单验证失败");
367
+ }
368
+ });
369
+ });
370
+ },
371
+ onCancel() {
372
+ this.$refs.formRef.resetFields();
373
+ this.$refs.formRef.clearValidate();
374
+ this.$emit("onCancel");
375
+ },
376
+ onConfirm() {
377
+ console.log("BaseForm数据", this.form);
378
+ this.validate()
379
+ .then(() => {
380
+ this.$emit("onSubmit", { form: this.form, data: this.form.value });
381
+ })
382
+ .catch(err => {
383
+ console.log("校验失败", err);
384
+ });
385
+ },
386
+ },
387
+ };
388
+ </script>
389
+
390
+ <style lang="scss" scoped>
391
+ .dialog-footer {
392
+ display: flex;
393
+ justify-content: flex-end;
394
+ }
395
+ </style>
396
+
@@ -1,6 +1,7 @@
1
1
  import OlTable from "./table";
2
2
  import OlSearch from "./formSearch";
3
3
  import Dialog from "./dialog";
4
+ import OlForm from "./form";
4
5
  import SwaggerClient from "swagger-client";
5
6
 
6
7
  const consoleTooltip = () => {
@@ -143,7 +144,6 @@ const swaggerUnload = async function () {
143
144
  await clearData(); // 清空 IndexedDB 中的缓存数据
144
145
  };
145
146
 
146
- const components = [OlTable, OlSearch, Dialog];
147
147
 
148
148
  // 自定义加载指示器
149
149
  function showLoading() {
@@ -203,6 +203,8 @@ function hideLoading() {
203
203
  }
204
204
  }
205
205
 
206
+
207
+ const components = [OlTable, OlSearch, Dialog, OlForm];
206
208
  const install = async function (Vue) {
207
209
  // 设置全局数据
208
210
  components.map((item) => {
@@ -212,5 +214,5 @@ const install = async function (Vue) {
212
214
  };
213
215
 
214
216
  export default install;
215
- export { OlTable, OlSearch, Dialog };
217
+ export { OlTable, OlSearch, Dialog, OlForm };
216
218
  export { swaggerInstall, swaggerUnload };
@@ -0,0 +1,84 @@
1
+ import { getData } from "../package/index.js";
2
+ // java数据类型转成js数据类型
3
+ const javaTypeToJsType = javaType => {
4
+ switch (javaType) {
5
+ case "integer":
6
+ return "number";
7
+ case "array":
8
+ return "Array";
9
+ case "object":
10
+ return "Object";
11
+ default:
12
+ return javaType;
13
+ }
14
+ };
15
+
16
+ const javaTypeToformType = javaType => {
17
+ switch (javaType) {
18
+ case "integer":
19
+ return "number";
20
+ case "boolean":
21
+ return "switch";
22
+ case "string":
23
+ return "input";
24
+ default:
25
+ return javaType;
26
+ }
27
+ };
28
+
29
+ export const initForm = options => {
30
+ const { url, form } = options;
31
+ getData().then(swaggerData => {
32
+ const entity = swaggerData.paths[url].post;
33
+ // 添加title
34
+ // if (!form.title) form.title = entity.summary;
35
+ const schema = entity.requestBody.content["application/json"].schema;
36
+ const properties = schema.properties;
37
+ // 生成model
38
+ // 1.循环model,将properties中prop相同的匹配,属性合并,model权限大,properties权限小,且保持响应式
39
+ form.model.forEach(item => {
40
+ const property = properties[item.prop];
41
+ if (property) {
42
+ Object.assign(item, {
43
+ prop: item.prop,
44
+ label: property.description,
45
+ type: javaTypeToformType(property.type),
46
+ hidden: false,
47
+ listeners: () => {},
48
+ props: {},
49
+ ...item,
50
+ });
51
+ }
52
+ });
53
+ // 2.将properties都push到model中(只提取swagger中有的type和description)
54
+ Object.keys(properties).forEach(key => {
55
+ const property = properties[key];
56
+ if (!form.model.find(item => item.prop == key) && property.description) {
57
+ // 删除对象的某些属性
58
+ const temp = {
59
+ prop: key,
60
+ label: property.description,
61
+ type: javaTypeToformType(property.type),
62
+ hidden: false,
63
+ listeners: () => {},
64
+ props: {},
65
+ };
66
+ form.model.push(temp);
67
+ }
68
+ });
69
+
70
+ // 校验规则
71
+ if (schema.required && Array.isArray(schema.required)) {
72
+ schema.required.forEach(item => {
73
+ if (!Object.keys(form.rules).includes(item)) {
74
+ form.rules[item] = [
75
+ {
76
+ required: true,
77
+ message: `${properties[item].description}不能为空`,
78
+ },
79
+ ];
80
+ }
81
+ });
82
+ }
83
+ });
84
+ };