cloud-web-corejs 1.0.54-dev.790 → 1.0.54-dev.791
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.
- package/package.json +1 -1
- package/src/components/xform/form-designer/designer.js +15 -11
- package/src/components/xform/form-designer/form-widget/container-widget/detail-plain-widget.vue +76 -0
- package/src/components/xform/form-designer/form-widget/field-widget/mixins/time-limit-mixin.js +92 -0
- package/src/components/xform/form-designer/form-widget/field-widget/time-widget.vue +44 -5
- package/src/components/xform/form-designer/indexMixin.js +1 -0
- package/src/components/xform/form-designer/setting-panel/form-dynamicField-setting.vue +1 -0
- package/src/components/xform/form-designer/setting-panel/property-editor/container-detail-plain/detail-plain-editor.vue +75 -0
- package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-defaultValue-editor.vue +23 -2
- package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-timeLimit-editor.vue +56 -0
- package/src/components/xform/form-designer/setting-panel/propertyRegister.js +2 -0
- package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +26 -0
- package/src/components/xform/form-render/container-item/detail-plain-item.vue +92 -0
- package/src/components/xform/form-render/indexMixin.js +3 -1
- package/src/components/xform/lang/zh-CN.js +1 -0
- package/src/components/xform/utils/util.js +1 -1
- package/src/index.js +10 -7
- package/src/views/bd/setting/formVersion/button.vue +5 -0
- package/src/views/bd/setting/formVersion/ftHistoryDialog.vue +21 -12
- package/src/views/bd/setting/formVersion/link.vue +5 -0
- package/src/views/bd/setting/form_script/edit.vue +1 -0
- package/src/views/bd/setting/form_script/edit1.vue +1 -0
- package/src/views/bd/setting/form_script/form_list.vue +1 -0
- package/src/views/bd/setting/form_script/list.vue +1 -0
- package/src/views/bd/setting/form_script/list1.vue +1 -0
- package/src/views/bd/setting/form_template/edit.vue +1 -0
- package/src/views/bd/setting/form_template/list.vue +1 -0
- package/src/views/bd/setting/table_model/edit.vue +1 -0
- package/src/views/bd/setting/table_model/list.vue +1 -0
- package/src/views/user/wf/wfReport/index.vue +24 -1
package/package.json
CHANGED
|
@@ -203,6 +203,7 @@ let chartContainers = [],
|
|
|
203
203
|
"vf-box": "widgetList",
|
|
204
204
|
card: "widgetList",
|
|
205
205
|
detail: "panes",
|
|
206
|
+
"detail-plain": "panes",
|
|
206
207
|
"detail-pane": "widgetList",
|
|
207
208
|
"detail-h5": "panes",
|
|
208
209
|
"h5-card": "panes",
|
|
@@ -1404,19 +1405,22 @@ let chartContainers = [],
|
|
|
1404
1405
|
newCon.options.name +
|
|
1405
1406
|
"').openEditDialog();";
|
|
1406
1407
|
newCon.buttons.push(add_button);
|
|
1407
|
-
} else if (newCon.type === "detail") {
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1408
|
+
} else if (newCon.type === "detail" || newCon.type === "detail-plain") {
|
|
1409
|
+
/* detail-plain 无标题栏,不预置标题栏按钮;其余 panes 结构与 detail 一致 */
|
|
1410
|
+
if (newCon.type === "detail") {
|
|
1411
|
+
let buttonCon1 = this.copyNewFieldWidget(
|
|
1412
|
+
this.getFieldWidgetByType("reset_button")
|
|
1413
|
+
);
|
|
1414
|
+
// buttonCon1.options.label = "重置";
|
|
1412
1415
|
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1416
|
+
let buttonCon2 = this.copyNewFieldWidget(
|
|
1417
|
+
this.getFieldWidgetByType("save_button")
|
|
1418
|
+
);
|
|
1419
|
+
buttonCon2.options.label = "保存";
|
|
1417
1420
|
|
|
1418
|
-
|
|
1419
|
-
|
|
1421
|
+
newCon.widgetList.push(buttonCon1);
|
|
1422
|
+
newCon.widgetList.push(buttonCon2);
|
|
1423
|
+
}
|
|
1420
1424
|
|
|
1421
1425
|
let newCol = baseRefUtil.deepClone(
|
|
1422
1426
|
this.getContainerByType("detail-pane")
|
package/src/components/xform/form-designer/form-widget/container-widget/detail-plain-widget.vue
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
/**
|
|
3
|
+
* 简洁详情模块(detail-plain)设计态:无标题栏、无按钮拖放区,仅 panes(详情tab)。
|
|
4
|
+
*/
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<container-wrapper :designer="designer" :widget="widget" :parent-widget="parentWidget" :parent-list="parentList"
|
|
9
|
+
:index-of-parent-list="indexOfParentList" :class="widget.options.isFullscreen ? 'full-height':''">
|
|
10
|
+
<div class="detail-wrap grid-container" :key="widget.id"
|
|
11
|
+
:class="{'selected': selected}" @click.stop="selectWidget(widget)">
|
|
12
|
+
<baseTabs style="height: auto;" :showNav="!widget.options.hideNav">
|
|
13
|
+
<detail-pane-widget v-for="(paneWidget, index) in widget.panes" :key="index" :widget="paneWidget"
|
|
14
|
+
:designer="designer" :parent-list="widget.panes"
|
|
15
|
+
:index-of-parent-list="index" :parent-widget="widget"
|
|
16
|
+
:col-height="widget.options.colHeight" tabRef="baseTabRef"
|
|
17
|
+
:tabPaneGrade="2"></detail-pane-widget>
|
|
18
|
+
</baseTabs>
|
|
19
|
+
</div>
|
|
20
|
+
</container-wrapper>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script>
|
|
24
|
+
import i18n from "../../../../../components/xform/utils/i18n"
|
|
25
|
+
import detailPaneWidget from "../../../../../components/xform/form-designer/form-widget/container-widget/detail-pane-widget"
|
|
26
|
+
import containerMixin from "../../../../../components/xform/form-designer/form-widget/container-widget/containerMixin"
|
|
27
|
+
import ContainerWrapper from "../../../../../components/xform/form-designer/form-widget/container-widget/container-wrapper"
|
|
28
|
+
import refMixinDesign from "../../../../../components/xform/form-designer/refMixinDesign"
|
|
29
|
+
import FieldComponents from "../../../../../components/xform/form-designer/form-widget/field-widget";
|
|
30
|
+
|
|
31
|
+
export default {
|
|
32
|
+
name: "detail-plain-widget",
|
|
33
|
+
componentName: 'ContainerWidget',
|
|
34
|
+
mixins: [i18n, containerMixin, refMixinDesign],
|
|
35
|
+
inject: ['refList'],
|
|
36
|
+
components: {
|
|
37
|
+
ContainerWrapper,
|
|
38
|
+
detailPaneWidget,
|
|
39
|
+
...FieldComponents,
|
|
40
|
+
},
|
|
41
|
+
props: {
|
|
42
|
+
widget: Object,
|
|
43
|
+
parentWidget: Object,
|
|
44
|
+
parentList: Array,
|
|
45
|
+
indexOfParentList: Number,
|
|
46
|
+
designer: Object,
|
|
47
|
+
},
|
|
48
|
+
computed: {
|
|
49
|
+
selected() {
|
|
50
|
+
return this.widget.id === this.designer.selectedId
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
customClass() {
|
|
54
|
+
return this.widget.options.customClass || ''
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
created() {
|
|
58
|
+
this.initRefList()
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<style lang="scss" scoped>
|
|
64
|
+
.grid-container {
|
|
65
|
+
min-height: 50px;
|
|
66
|
+
outline: 1px dashed #336699;
|
|
67
|
+
> div{height:100%;}
|
|
68
|
+
.form-widget-list {
|
|
69
|
+
height: 100%;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.grid-container.selected, .grid-cell.selected {
|
|
74
|
+
outline: 2px solid $--color-primary !important;
|
|
75
|
+
}
|
|
76
|
+
</style>
|
package/src/components/xform/form-designer/form-widget/field-widget/mixins/time-limit-mixin.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/* 时间组件的最小时间、默认值支持配置为「当前时间」,此处统一解析 */
|
|
2
|
+
export const TIME_VALUE_TYPE_NOW = "now";
|
|
3
|
+
|
|
4
|
+
const MAX_TIME_VALUE = "23:59:59";
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
methods: {
|
|
8
|
+
getTimeLimitOptions() {
|
|
9
|
+
return this.field.options || {};
|
|
10
|
+
},
|
|
11
|
+
isNowTimeValueType(valueType) {
|
|
12
|
+
return valueType === TIME_VALUE_TYPE_NOW;
|
|
13
|
+
},
|
|
14
|
+
getNowTimeValue() {
|
|
15
|
+
const now = new Date();
|
|
16
|
+
const pad = (val) => (val < 10 ? "0" + val : String(val));
|
|
17
|
+
return `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(
|
|
18
|
+
now.getSeconds()
|
|
19
|
+
)}`;
|
|
20
|
+
},
|
|
21
|
+
normalizeTimeValue(val) {
|
|
22
|
+
if (val === null || val === undefined || val === "") {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const matched = /^(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?$/.exec(String(val).trim());
|
|
26
|
+
if (!matched) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const hour = Number(matched[1]);
|
|
30
|
+
const minute = Number(matched[2]);
|
|
31
|
+
const second = Number(matched[3] || 0);
|
|
32
|
+
if (hour > 23 || minute > 59 || second > 59) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const pad = (v) => (v < 10 ? "0" + v : String(v));
|
|
36
|
+
return `${pad(hour)}:${pad(minute)}:${pad(second)}`;
|
|
37
|
+
},
|
|
38
|
+
parseTimeLimitValue(val) {
|
|
39
|
+
const normalized = this.normalizeTimeValue(val);
|
|
40
|
+
if (normalized === null) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const parts = normalized.split(":");
|
|
44
|
+
return Number(parts[0]) * 3600 + Number(parts[1]) * 60 + Number(parts[2]);
|
|
45
|
+
},
|
|
46
|
+
/* 最小时间:固定时间或当前时间 */
|
|
47
|
+
getTimeLimitMinValue() {
|
|
48
|
+
const options = this.getTimeLimitOptions();
|
|
49
|
+
if (this.isNowTimeValueType(options.minTimeType)) {
|
|
50
|
+
return this.getNowTimeValue();
|
|
51
|
+
}
|
|
52
|
+
return this.normalizeTimeValue(options.minTime);
|
|
53
|
+
},
|
|
54
|
+
initTimeLimitPickerOptions() {
|
|
55
|
+
const pickerOptions = { ...(this.pickerOptions || {}) };
|
|
56
|
+
const minTime = this.getTimeLimitMinValue();
|
|
57
|
+
if (minTime === null) {
|
|
58
|
+
delete pickerOptions.selectableRange;
|
|
59
|
+
} else {
|
|
60
|
+
pickerOptions.selectableRange = `${minTime} - ${MAX_TIME_VALUE}`;
|
|
61
|
+
}
|
|
62
|
+
this.pickerOptions = pickerOptions;
|
|
63
|
+
},
|
|
64
|
+
isTimeLimitViolated(value) {
|
|
65
|
+
const currentTime = this.parseTimeLimitValue(value);
|
|
66
|
+
if (currentTime === null) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
const minTime = this.parseTimeLimitValue(this.getTimeLimitMinValue());
|
|
70
|
+
return minTime !== null && currentTime < minTime;
|
|
71
|
+
},
|
|
72
|
+
getTimeLimitViolationMessage() {
|
|
73
|
+
return `时间不能小于${this.getTimeLimitMinValue()}`;
|
|
74
|
+
},
|
|
75
|
+
/* 默认值配置为「当前时间」时,临时替换 defaultValue 后再走通用的取值逻辑 */
|
|
76
|
+
initTimeFieldModel() {
|
|
77
|
+
const options = this.getTimeLimitOptions();
|
|
78
|
+
if (!this.isNowTimeValueType(options.defaultValueType)) {
|
|
79
|
+
this.initFieldModel();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const rawDefaultValue = options.defaultValue;
|
|
84
|
+
options.defaultValue = this.getNowTimeValue();
|
|
85
|
+
try {
|
|
86
|
+
this.initFieldModel();
|
|
87
|
+
} finally {
|
|
88
|
+
options.defaultValue = rawDefaultValue;
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
};
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
:clearable="field.options.clearable" :editable="field.options.editable"
|
|
9
9
|
:format="field.options.format" value-format="HH:mm:ss"
|
|
10
10
|
:placeholder="getI18nLabel(field.options.placeholder || '选择时间')"
|
|
11
|
-
|
|
12
|
-
@
|
|
11
|
+
:picker-options="pickerOptions"
|
|
12
|
+
@focus="handleTimeFocusEvent" @blur="handleBlurCustomEvent"
|
|
13
|
+
@change="handleTimeChangeEvent">
|
|
13
14
|
</el-time-picker>
|
|
14
15
|
</form-item-wrapper>
|
|
15
16
|
</template>
|
|
@@ -19,12 +20,13 @@
|
|
|
19
20
|
import emitter from '../../../../../components/xform/utils/emitter'
|
|
20
21
|
import i18n from "../../../../../components/xform/utils/i18n";
|
|
21
22
|
import fieldMixin from "../../../../../components/xform/form-designer/form-widget/field-widget/fieldMixin";
|
|
23
|
+
import timeLimitMixin from "../../../../../components/xform/form-designer/form-widget/field-widget/mixins/time-limit-mixin";
|
|
22
24
|
import utcTransformMixin from "../../../../../components/xform/form-designer/form-widget/field-widget/mixins/utc-transform-mixin";
|
|
23
25
|
|
|
24
26
|
export default {
|
|
25
27
|
name: "time-widget",
|
|
26
28
|
componentName: 'FieldWidget', //必须固定为FieldWidget,用于接收父级组件的broadcast事件
|
|
27
|
-
mixins: [emitter, fieldMixin, i18n, utcTransformMixin],
|
|
29
|
+
mixins: [emitter, fieldMixin, i18n, timeLimitMixin, utcTransformMixin],
|
|
28
30
|
props: {
|
|
29
31
|
field: Object,
|
|
30
32
|
parentWidget: Object,
|
|
@@ -60,10 +62,19 @@
|
|
|
60
62
|
oldFieldValue: null, //field组件change之前的值
|
|
61
63
|
fieldModel: null,
|
|
62
64
|
rules: [],
|
|
65
|
+
pickerOptions: {},
|
|
63
66
|
}
|
|
64
67
|
},
|
|
65
68
|
computed: {
|
|
66
69
|
|
|
70
|
+
},
|
|
71
|
+
watch: {
|
|
72
|
+
"field.options.minTime"() {
|
|
73
|
+
this.initTimeLimitPickerOptions()
|
|
74
|
+
},
|
|
75
|
+
"field.options.minTimeType"() {
|
|
76
|
+
this.initTimeLimitPickerOptions()
|
|
77
|
+
},
|
|
67
78
|
},
|
|
68
79
|
beforeCreate() {
|
|
69
80
|
/* 这里不能访问方法和属性!! */
|
|
@@ -72,12 +83,13 @@
|
|
|
72
83
|
created() {
|
|
73
84
|
/* 注意:子组件mounted在父组件created之后、父组件mounted之前触发,故子组件mounted需要用到的prop
|
|
74
85
|
需要在父组件created中初始化!! */
|
|
75
|
-
this.
|
|
86
|
+
this.initTimeFieldModel()
|
|
76
87
|
this.registerToRefList()
|
|
77
88
|
this.initEventHandler()
|
|
78
89
|
this.buildFieldRules()
|
|
79
90
|
|
|
80
91
|
this.handleOnCreated()
|
|
92
|
+
this.initTimeLimitPickerOptions()
|
|
81
93
|
},
|
|
82
94
|
|
|
83
95
|
mounted() {
|
|
@@ -89,7 +101,34 @@
|
|
|
89
101
|
},
|
|
90
102
|
|
|
91
103
|
methods: {
|
|
92
|
-
|
|
104
|
+
handleTimeFocusEvent(event) {
|
|
105
|
+
/* 最小时间为「当前时间」时,每次展开面板都需按当前时刻重新计算 */
|
|
106
|
+
if (this.isNowTimeValueType(this.field.options.minTimeType)) {
|
|
107
|
+
this.initTimeLimitPickerOptions()
|
|
108
|
+
}
|
|
109
|
+
this.handleFocusCustomEvent(event)
|
|
110
|
+
},
|
|
111
|
+
handleTimeChangeEvent(value) {
|
|
112
|
+
if (this.isTimeLimitViolated(value)) {
|
|
113
|
+
this.$message.warning(this.getTimeLimitViolationMessage())
|
|
114
|
+
this.fieldModel = this.oldFieldValue
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
this.handleChangeEvent(value)
|
|
118
|
+
},
|
|
119
|
+
setNow() {
|
|
120
|
+
this.setValue(this.getNowTimeValue())
|
|
121
|
+
},
|
|
122
|
+
refreshDefaultValue() {
|
|
123
|
+
if (this.designState !== true) {
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
if (this.isNowTimeValueType(this.field.options.defaultValueType)) {
|
|
127
|
+
this.fieldModel = this.getNowTimeValue()
|
|
128
|
+
} else if (this.field.options.defaultValue !== undefined) {
|
|
129
|
+
this.fieldModel = this.field.options.defaultValue
|
|
130
|
+
}
|
|
131
|
+
},
|
|
93
132
|
}
|
|
94
133
|
}
|
|
95
134
|
</script>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<el-form-item label-width="0">
|
|
4
|
+
<el-divider class="custom-divider">{{ i18nt('designer.setting.columnSetting') }}</el-divider>
|
|
5
|
+
</el-form-item>
|
|
6
|
+
<el-form-item :label="i18nt('隐藏导航')">
|
|
7
|
+
<el-switch v-model="optionModel.hideNav"></el-switch>
|
|
8
|
+
<span style="margin-left: 8px; color: #999; font-size: 12px">
|
|
9
|
+
简洁详情默认隐藏模块导航
|
|
10
|
+
</span>
|
|
11
|
+
</el-form-item>
|
|
12
|
+
<el-form-item :label="i18nt('designer.setting.colsOfGrid')"></el-form-item>
|
|
13
|
+
<el-form-item label-width="0">
|
|
14
|
+
<draggable tag="ul" class="draggable-box" :list="selectedWidget.panes"
|
|
15
|
+
v-bind="{ group: 'optionsGroup', ghostClass: 'ghost', handle: '.drag-option' }">
|
|
16
|
+
<li v-for="(colItem, colIdx) in selectedWidget.panes" :key="colIdx" class="col-item">
|
|
17
|
+
<i class="el-icon-s-operation drag-option"></i>
|
|
18
|
+
<el-input v-model="colItem.options.label" class="cell-span-input"></el-input>
|
|
19
|
+
<el-button circle plain size="mini" type="danger" @click="deleteCol(selectedWidget, colIdx)"
|
|
20
|
+
icon="el-icon-minus" class="col-delete-button" style="position: unset;"></el-button>
|
|
21
|
+
</li>
|
|
22
|
+
</draggable>
|
|
23
|
+
<div>
|
|
24
|
+
<el-button type="text" @click="addNewCol(selectedWidget)" icon="el-icon-circle-plus-outline" class="add-option">
|
|
25
|
+
{{ i18nt('designer.setting.addColumn') }}
|
|
26
|
+
</el-button>
|
|
27
|
+
</div>
|
|
28
|
+
</el-form-item>
|
|
29
|
+
</div>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script>
|
|
33
|
+
import Draggable from 'vuedraggable';
|
|
34
|
+
import i18n from "../../../../../../components/xform/utils/i18n"
|
|
35
|
+
|
|
36
|
+
export default {
|
|
37
|
+
name: "detail-plain-editor",
|
|
38
|
+
mixins: [i18n],
|
|
39
|
+
components: {
|
|
40
|
+
Draggable,
|
|
41
|
+
},
|
|
42
|
+
props: {
|
|
43
|
+
designer: Object,
|
|
44
|
+
selectedWidget: Object,
|
|
45
|
+
optionModel: Object,
|
|
46
|
+
},
|
|
47
|
+
methods: {
|
|
48
|
+
deleteCol(curGrid, colIdx) {
|
|
49
|
+
this.designer.deletePaneOfDetail(curGrid, colIdx)
|
|
50
|
+
this.designer.emitHistoryChange()
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
addNewCol(curGrid) {
|
|
54
|
+
this.designer.addNewPaneOfDetail(curGrid)
|
|
55
|
+
this.designer.emitHistoryChange()
|
|
56
|
+
},
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<style lang="scss" scoped>
|
|
62
|
+
li.col-item {
|
|
63
|
+
list-style: none;
|
|
64
|
+
|
|
65
|
+
span.col-span-title {
|
|
66
|
+
display: inline-block;
|
|
67
|
+
font-size: 13px;
|
|
68
|
+
width: 120px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.col-delete-button {
|
|
72
|
+
margin-left: 6px;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
</style>
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<el-form-item :label="i18nt('designer.setting.defaultValue')">
|
|
3
|
-
<el-
|
|
4
|
-
|
|
3
|
+
<el-radio-group v-model="defaultValueType" size="mini">
|
|
4
|
+
<el-radio-button label="">固定时间</el-radio-button>
|
|
5
|
+
<el-radio-button label="now">当前时间</el-radio-button>
|
|
6
|
+
</el-radio-group>
|
|
7
|
+
<el-time-picker v-if="defaultValueType !== 'now'" v-model="optionModel.defaultValue"
|
|
8
|
+
@change="emitDefaultValueChange"
|
|
9
|
+
:format="optionModel.format" value-format="HH:mm:ss"
|
|
10
|
+
style="width: 100%; margin-top: 5px">
|
|
5
11
|
</el-time-picker>
|
|
6
12
|
</el-form-item>
|
|
7
13
|
</template>
|
|
@@ -18,6 +24,21 @@
|
|
|
18
24
|
selectedWidget: Object,
|
|
19
25
|
optionModel: Object,
|
|
20
26
|
},
|
|
27
|
+
computed: {
|
|
28
|
+
/* 老表单的options可能没有defaultValueType属性,用$set赋值保证响应式 */
|
|
29
|
+
defaultValueType: {
|
|
30
|
+
get() {
|
|
31
|
+
return this.optionModel.defaultValueType || ''
|
|
32
|
+
},
|
|
33
|
+
set(value) {
|
|
34
|
+
this.$set(this.optionModel, 'defaultValueType', value)
|
|
35
|
+
if (value === 'now') {
|
|
36
|
+
this.$set(this.optionModel, 'defaultValue', null)
|
|
37
|
+
}
|
|
38
|
+
this.emitDefaultValueChange()
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
21
42
|
}
|
|
22
43
|
</script>
|
|
23
44
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<el-form-item label="最小时间">
|
|
4
|
+
<el-radio-group v-model="minTimeType" size="mini">
|
|
5
|
+
<el-radio-button label="">固定时间</el-radio-button>
|
|
6
|
+
<el-radio-button label="now">当前时间</el-radio-button>
|
|
7
|
+
</el-radio-group>
|
|
8
|
+
<el-time-picker v-if="minTimeType !== 'now'" v-model="minTime"
|
|
9
|
+
:format="optionModel.format" value-format="HH:mm:ss"
|
|
10
|
+
style="width: 100%; margin-top: 5px"
|
|
11
|
+
clearable placeholder="留空则不限制">
|
|
12
|
+
</el-time-picker>
|
|
13
|
+
</el-form-item>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script>
|
|
18
|
+
import i18n from "../../../../../../components/xform/utils/i18n"
|
|
19
|
+
import propertyMixin from "../../../../../../components/xform/form-designer/setting-panel/property-editor/propertyMixin"
|
|
20
|
+
|
|
21
|
+
export default {
|
|
22
|
+
name: "time-timeLimit-editor",
|
|
23
|
+
mixins: [i18n, propertyMixin],
|
|
24
|
+
props: {
|
|
25
|
+
designer: Object,
|
|
26
|
+
selectedWidget: Object,
|
|
27
|
+
optionModel: Object,
|
|
28
|
+
},
|
|
29
|
+
computed: {
|
|
30
|
+
/* 老表单的options可能没有这些属性,统一用$set赋值,保证响应式 */
|
|
31
|
+
minTimeType: {
|
|
32
|
+
get() {
|
|
33
|
+
return this.optionModel.minTimeType || ''
|
|
34
|
+
},
|
|
35
|
+
set(value) {
|
|
36
|
+
this.$set(this.optionModel, 'minTimeType', value)
|
|
37
|
+
if (value === 'now') {
|
|
38
|
+
this.$set(this.optionModel, 'minTime', null)
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
minTime: {
|
|
43
|
+
get() {
|
|
44
|
+
return this.optionModel.minTime || null
|
|
45
|
+
},
|
|
46
|
+
set(value) {
|
|
47
|
+
this.$set(this.optionModel, 'minTime', value || null)
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<style scoped>
|
|
55
|
+
|
|
56
|
+
</style>
|
|
@@ -44,6 +44,7 @@ const COMMON_PROPERTIES = {
|
|
|
44
44
|
format: "format-editor",
|
|
45
45
|
valueFormat: "valueFormat-editor",
|
|
46
46
|
dateLimit: "dateLimit-editor",
|
|
47
|
+
timeLimit: "timeLimit-editor",
|
|
47
48
|
utcTransformEnabled: "utcTransformEnabled-editor",
|
|
48
49
|
defaultTime: "defaultTime-editor",
|
|
49
50
|
filterable: "filterable-editor",
|
|
@@ -106,6 +107,7 @@ const COMMON_PROPERTIES = {
|
|
|
106
107
|
pull: "pull-editor",
|
|
107
108
|
height: "height-editor",
|
|
108
109
|
detailContainer: "detail-editor",
|
|
110
|
+
detailPlainContainer: "detail-plain-editor",
|
|
109
111
|
detailPaneContainer: "detail-pane-editor",
|
|
110
112
|
vabSearchField: "vabSearchField-editor",
|
|
111
113
|
fullWidth: "table-fullWidth-editor",
|
|
@@ -453,6 +453,27 @@ export const containers = [
|
|
|
453
453
|
onMounted: "",
|
|
454
454
|
},
|
|
455
455
|
},
|
|
456
|
+
{
|
|
457
|
+
/* 简洁详情:与 detail 同构,去标题栏(标题/按钮区),模块导航默认关闭 */
|
|
458
|
+
type: "detail-plain",
|
|
459
|
+
category: "container",
|
|
460
|
+
icon: "form",
|
|
461
|
+
commonFlag: !0,
|
|
462
|
+
layoutType: "PC",
|
|
463
|
+
panes: [],
|
|
464
|
+
widgetList: [],
|
|
465
|
+
options: {
|
|
466
|
+
name: "",
|
|
467
|
+
hidden: !1,
|
|
468
|
+
label: "单据详情",
|
|
469
|
+
detailPlainContainer: true,
|
|
470
|
+
hideNav: true,
|
|
471
|
+
// colHeight: null,
|
|
472
|
+
customClass: "",
|
|
473
|
+
onCreated: "",
|
|
474
|
+
onMounted: "",
|
|
475
|
+
},
|
|
476
|
+
},
|
|
456
477
|
{
|
|
457
478
|
type: "detail-pane",
|
|
458
479
|
category: "container",
|
|
@@ -1601,6 +1622,7 @@ export const basicFields = [
|
|
|
1601
1622
|
formField: "",
|
|
1602
1623
|
labelAlign: "",
|
|
1603
1624
|
defaultValue: null,
|
|
1625
|
+
defaultValueType: "", //默认值类型:空为固定时间,now为当前时间
|
|
1604
1626
|
placeholder: "",
|
|
1605
1627
|
columnWidth: "200px",
|
|
1606
1628
|
size: "",
|
|
@@ -1612,6 +1634,9 @@ export const basicFields = [
|
|
|
1612
1634
|
clearable: !0,
|
|
1613
1635
|
editable: !0,
|
|
1614
1636
|
format: "HH:mm:ss",
|
|
1637
|
+
timeLimit: null,
|
|
1638
|
+
minTime: null,
|
|
1639
|
+
minTimeType: "", //最小时间类型:空为固定时间,now为当前时间
|
|
1615
1640
|
utcTransformEnabled: !1,
|
|
1616
1641
|
required: !1,
|
|
1617
1642
|
requiredHint: "",
|
|
@@ -4437,6 +4462,7 @@ export const widgetPanelOrder = {
|
|
|
4437
4462
|
"data-table",
|
|
4438
4463
|
"table-column",
|
|
4439
4464
|
"detail",
|
|
4465
|
+
"detail-plain",
|
|
4440
4466
|
"detail-pane",
|
|
4441
4467
|
"tree-pane",
|
|
4442
4468
|
"tree",
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
/**
|
|
3
|
+
* 简洁详情模块(detail-plain):与 detail 同构,但不渲染标题栏(标题/翻单/流程/按钮控件),
|
|
4
|
+
* 模块导航默认关闭。仅保留 panes(详情tab)内容区。
|
|
5
|
+
*/
|
|
6
|
+
-->
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<container-item-wrapper :widget="widget">
|
|
10
|
+
<div
|
|
11
|
+
class="detail-wrap grid-container"
|
|
12
|
+
:class="[customClass]"
|
|
13
|
+
:ref="widget.id"
|
|
14
|
+
>
|
|
15
|
+
<baseTabs :showNav="!widget.options.hideNav && !plainMode">
|
|
16
|
+
<detail-pane-widget
|
|
17
|
+
v-for="(paneWidget, index) in widget.panes"
|
|
18
|
+
:key="index"
|
|
19
|
+
:widget="paneWidget"
|
|
20
|
+
:parent-list="widget.panes"
|
|
21
|
+
:index-of-parent-list="index"
|
|
22
|
+
:parent-widget="widget"
|
|
23
|
+
:col-height="widget.options.colHeight"
|
|
24
|
+
tabRef="baseTabRef"
|
|
25
|
+
:tabPaneGrade="2"
|
|
26
|
+
></detail-pane-widget>
|
|
27
|
+
</baseTabs>
|
|
28
|
+
</div>
|
|
29
|
+
</container-item-wrapper>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script>
|
|
33
|
+
import emitter from "../../../../components/xform/utils/emitter";
|
|
34
|
+
import i18n from "../../../../components/xform/utils/i18n";
|
|
35
|
+
import refMixin from "../../../../components/xform/form-render/refMixin";
|
|
36
|
+
import ContainerItemWrapper from "./container-item-wrapper";
|
|
37
|
+
import containerItemMixin from "./containerItemMixin";
|
|
38
|
+
import detailPaneWidget from "../../../../components/xform/form-render/container-item/detail-pane-item";
|
|
39
|
+
import FieldComponents from "../../../../components/xform/form-designer/form-widget/field-widget/index";
|
|
40
|
+
|
|
41
|
+
export default {
|
|
42
|
+
name: "detail-plain-item",
|
|
43
|
+
componentName: "ContainerItem",
|
|
44
|
+
mixins: [emitter, i18n, refMixin, containerItemMixin],
|
|
45
|
+
components: {
|
|
46
|
+
ContainerItemWrapper,
|
|
47
|
+
detailPaneWidget,
|
|
48
|
+
...FieldComponents,
|
|
49
|
+
},
|
|
50
|
+
props: {
|
|
51
|
+
widget: Object,
|
|
52
|
+
},
|
|
53
|
+
inject: ["refList", "sfRefList", "globalModel", "previewState"],
|
|
54
|
+
created() {
|
|
55
|
+
this.initRefList();
|
|
56
|
+
this.handleOnCreated();
|
|
57
|
+
},
|
|
58
|
+
mounted() {
|
|
59
|
+
this.handleOnMounted();
|
|
60
|
+
},
|
|
61
|
+
beforeDestroy() {
|
|
62
|
+
this.unregisterFromRefList();
|
|
63
|
+
},
|
|
64
|
+
computed: {
|
|
65
|
+
// 素身详情模式(宿主 VFormRender 传 plainDetailMode):强制关闭模块导航
|
|
66
|
+
plainMode() {
|
|
67
|
+
let formRef = this.getFormRef && this.getFormRef();
|
|
68
|
+
return !!(formRef && formRef.plainDetailMode);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<style lang="scss" scoped>
|
|
75
|
+
.grid-container {
|
|
76
|
+
min-height: 50px;
|
|
77
|
+
outline: 1px dashed #336699;
|
|
78
|
+
|
|
79
|
+
> div {
|
|
80
|
+
height: 100%;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.form-widget-list {
|
|
84
|
+
height: 100%;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.grid-container.selected,
|
|
89
|
+
.grid-cell.selected {
|
|
90
|
+
outline: 2px solid $--color-primary !important;
|
|
91
|
+
}
|
|
92
|
+
</style>
|
|
@@ -1660,7 +1660,7 @@ modules = {
|
|
|
1660
1660
|
t.buildDataFromWidget(e);
|
|
1661
1661
|
});
|
|
1662
1662
|
});
|
|
1663
|
-
else if ("detail" === e.type)
|
|
1663
|
+
else if ("detail" === e.type || "detail-plain" === e.type)
|
|
1664
1664
|
e.panes &&
|
|
1665
1665
|
e.panes.length > 0 &&
|
|
1666
1666
|
e.panes.forEach(function (e) {
|
|
@@ -3601,6 +3601,7 @@ modules = {
|
|
|
3601
3601
|
"vf-box": "widgetList",
|
|
3602
3602
|
card: "widgetList",
|
|
3603
3603
|
detail: "panes",
|
|
3604
|
+
"detail-plain": "panes",
|
|
3604
3605
|
"detail-pane": "widgetList",
|
|
3605
3606
|
"detail-h5": "panes",
|
|
3606
3607
|
"h5-card": "panes",
|
|
@@ -3787,6 +3788,7 @@ modules = {
|
|
|
3787
3788
|
"vf-box": "widgetList",
|
|
3788
3789
|
card: "widgetList",
|
|
3789
3790
|
detail: "panes",
|
|
3791
|
+
"detail-plain": "panes",
|
|
3790
3792
|
"detail-pane": "widgetList",
|
|
3791
3793
|
"detail-h5": "panes",
|
|
3792
3794
|
"h5-card": "panes",
|
|
@@ -1554,7 +1554,7 @@ function loopHandleWidgetItem(e, p, callback) {
|
|
|
1554
1554
|
loopHandleWidgetItem(childItem, e, callback);
|
|
1555
1555
|
});
|
|
1556
1556
|
});
|
|
1557
|
-
} else if ("detail" === e.type) {
|
|
1557
|
+
} else if ("detail" === e.type || "detail-plain" === e.type) {
|
|
1558
1558
|
if (e.panes) {
|
|
1559
1559
|
e.panes.forEach(function (childItem) {
|
|
1560
1560
|
loopHandleWidgetItem(childItem, e, callback);
|
package/src/index.js
CHANGED
|
@@ -189,13 +189,16 @@ Vue.component("advancedSearchDialog", () =>
|
|
|
189
189
|
import("@base/components/advancedSearchDialog/index.vue")
|
|
190
190
|
);
|
|
191
191
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
192
|
+
// baseTabs/baseTabPane 必须同步注册,不可懒注册:
|
|
193
|
+
// xform 详情容器(detail-item)把所有 detail-pane 及其内部字段组件放在 <baseTabs> 的默认插槽里。
|
|
194
|
+
// 异步组件未解析时 Vue 只渲染占位注释节点,插槽内的组件不会被实例化,
|
|
195
|
+
// 于是 detail-item 的 mounted 早于内部字段组件的 created(registerToRefList)执行,
|
|
196
|
+
// 模板脚本 onMounted 里的 getWidgetRef('xxx') 首次进入必然拿到 undefined(二次进入因异步工厂已缓存而正常)。
|
|
197
|
+
import baseTabs from "@base/components/baseTabs/index.vue";
|
|
198
|
+
import baseTabPane from "@base/components/baseTabs/baseTabPane.vue";
|
|
199
|
+
|
|
200
|
+
Vue.component(baseTabs.name, baseTabs);
|
|
201
|
+
Vue.component(baseTabPane.name, baseTabPane);
|
|
199
202
|
|
|
200
203
|
import vb_tabs from "@base/components/vb-tabs/index.vue";
|
|
201
204
|
import vb_tab_pane from "@base/components/vb-tabs/tab-pane.vue";
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
:objType="objType"
|
|
14
14
|
:objCode="objCode"
|
|
15
15
|
:relationCode="relationCode"
|
|
16
|
+
:sid="sid"
|
|
16
17
|
@reverCallback="reverCallback"
|
|
17
18
|
/>
|
|
18
19
|
</el-button>
|
|
@@ -33,6 +34,10 @@ export default {
|
|
|
33
34
|
type: String,
|
|
34
35
|
default: null,
|
|
35
36
|
},
|
|
37
|
+
sid: {
|
|
38
|
+
type: String,
|
|
39
|
+
default: null,
|
|
40
|
+
},
|
|
36
41
|
},
|
|
37
42
|
components: {
|
|
38
43
|
ftHistoryDialog: () =>
|
|
@@ -199,7 +199,7 @@ import { selectDialogMixins } from "@base/mixins/selectDialog";
|
|
|
199
199
|
|
|
200
200
|
export default {
|
|
201
201
|
name: "ftHistoryDialog",
|
|
202
|
-
props: ["visiable", "objType", "objCode", "relationCode"],
|
|
202
|
+
props: ["visiable", "objType", "objCode", "relationCode", "sid"],
|
|
203
203
|
mixins: [selectDialogMixins],
|
|
204
204
|
components: {
|
|
205
205
|
formDesignerDialog: () =>
|
|
@@ -326,8 +326,7 @@ export default {
|
|
|
326
326
|
return {
|
|
327
327
|
...this.formData,
|
|
328
328
|
objType: this.objType,
|
|
329
|
-
|
|
330
|
-
relationCode: this.relationCode,
|
|
329
|
+
sid: this.sid,
|
|
331
330
|
};
|
|
332
331
|
},
|
|
333
332
|
columns: [
|
|
@@ -373,6 +372,16 @@ export default {
|
|
|
373
372
|
field: "modifyDate",
|
|
374
373
|
width: 150,
|
|
375
374
|
},
|
|
375
|
+
{
|
|
376
|
+
title: this.$t1("导入发布人"),
|
|
377
|
+
field: "importBy",
|
|
378
|
+
width: 150,
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
title: this.$t1("导入发布时间"),
|
|
382
|
+
field: "importDate",
|
|
383
|
+
width: 150,
|
|
384
|
+
},
|
|
376
385
|
{
|
|
377
386
|
width: 90,
|
|
378
387
|
fixed: "right",
|
|
@@ -478,13 +487,13 @@ export default {
|
|
|
478
487
|
},
|
|
479
488
|
};
|
|
480
489
|
</script>
|
|
481
|
-
<style scoped lang="scss">
|
|
482
|
-
.designer-drawer{
|
|
483
|
-
left:0;top:50px;
|
|
484
|
-
}
|
|
485
|
-
::v-deep .dialog-style.list-dialog{
|
|
486
|
-
.designer-drawer .el-drawer__body .designer-box{
|
|
487
|
-
height:100%
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
+
<style scoped lang="scss">
|
|
491
|
+
.designer-drawer{
|
|
492
|
+
left:0;top:50px;
|
|
493
|
+
}
|
|
494
|
+
::v-deep .dialog-style.list-dialog{
|
|
495
|
+
.designer-drawer .el-drawer__body .designer-box{
|
|
496
|
+
height:100%
|
|
497
|
+
}
|
|
498
|
+
}
|
|
490
499
|
</style>
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
:objType="objType"
|
|
15
15
|
:objCode="objCode"
|
|
16
16
|
:relationCode="relationCode"
|
|
17
|
+
:sid="sid"
|
|
17
18
|
@reverCallback="reverCallback"
|
|
18
19
|
/>
|
|
19
20
|
</i>
|
|
@@ -36,6 +37,10 @@ export default {
|
|
|
36
37
|
type: String,
|
|
37
38
|
default: null,
|
|
38
39
|
},
|
|
40
|
+
sid: {
|
|
41
|
+
type: String,
|
|
42
|
+
default: null,
|
|
43
|
+
},
|
|
39
44
|
},
|
|
40
45
|
components: {
|
|
41
46
|
ftHistoryDialog: () =>
|
|
@@ -526,8 +526,31 @@ export default {
|
|
|
526
526
|
}
|
|
527
527
|
}
|
|
528
528
|
.filter-btns {
|
|
529
|
+
display: flex;
|
|
530
|
+
align-items: center;
|
|
531
|
+
flex-wrap: nowrap;
|
|
532
|
+
gap: 8px;
|
|
529
533
|
.f-btn {
|
|
530
|
-
margin-right:
|
|
534
|
+
margin-right: 0;
|
|
535
|
+
}
|
|
536
|
+
// 内联的 128px !important 无法被覆盖,但 flex-shrink 依然生效,
|
|
537
|
+
// 让各查询项按比例收缩,保证刷新/搜索按钮不换行掉下去
|
|
538
|
+
::v-deep .el-select,
|
|
539
|
+
::v-deep .el-input,
|
|
540
|
+
::v-deep .el-date-editor {
|
|
541
|
+
flex: 0 1 auto;
|
|
542
|
+
min-width: 76px;
|
|
543
|
+
}
|
|
544
|
+
.button-sty {
|
|
545
|
+
display: flex;
|
|
546
|
+
align-items: center;
|
|
547
|
+
gap: 4px;
|
|
548
|
+
min-width: 0;
|
|
549
|
+
margin: 0;
|
|
550
|
+
}
|
|
551
|
+
> .el-button {
|
|
552
|
+
flex: none;
|
|
553
|
+
white-space: nowrap;
|
|
531
554
|
}
|
|
532
555
|
}
|
|
533
556
|
.sum-statistics {
|