vue2-client 1.14.93 → 1.14.95
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/base-client/components/common/AmapMarker/index.js +3 -3
- package/src/base-client/components/common/XDetailsView/index.js +3 -3
- package/src/base-client/components/common/XFormGroupDetails/index.js +3 -3
- package/src/base-client/components/common/XTab/XTab.vue +40 -8
- package/src/base-client/components/common/XTable/XTable.vue +23 -21
- package/src/base-client/components/his/XCharge/XCharge.vue +1 -0
- package/src/base-client/components/his/XList/XList.vue +35 -35
- package/src/base-client/components/his/XQuestionnaire/XQuestionnaireItem.vue +7 -6
- package/src/base-client/components/his/XShiftSchedule/XShiftSchedule.vue +1 -1
- package/src/base-client/components/layout/XPageView/RenderRow.vue +30 -32
- package/src/base-client/components/layout/XPageView/XPageRowTemplate.vue +37 -0
- package/src/base-client/components/layout/XPageView/XPageView.vue +10 -9
- package/src/base-client/components/layout/XPageView/XTab/XTab.vue +96 -0
- package/src/base-client/components/layout/XPageView/XTab/index.js +3 -0
- package/src/base-client/components/layout/XPageView/componentTypes.js +22 -0
- package/src/base-client/components/layout/XPageView/index.js +1 -0
- package/src/base-client/components/layout/XPageView/index.md +19 -0
- package/src/pages/WorkflowDetail/WorkFlowDemo.vue +36 -82
- package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowHandle.vue +10 -4
- package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowTimeline.vue +1 -1
- package/src/pages/XPageViewExample/index.vue +125 -47
- package/src/pages/addressSelect/addressDemo.vue +24 -24
- package/src/router/async/router.map.js +7 -3
- package/vue.config.js +2 -2
package/package.json
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
import AmapPointRendering from './AmapPointRendering'
|
2
|
-
|
3
|
-
export default AmapPointRendering
|
1
|
+
import AmapPointRendering from './AmapPointRendering'
|
2
|
+
|
3
|
+
export default AmapPointRendering
|
@@ -1,3 +1,3 @@
|
|
1
|
-
import XDetailsView from './XDetailsView'
|
2
|
-
|
3
|
-
export default XDetailsView
|
1
|
+
import XDetailsView from './XDetailsView'
|
2
|
+
|
3
|
+
export default XDetailsView
|
@@ -1,3 +1,3 @@
|
|
1
|
-
import XFormGroupDetails from './XFormGroupDetails'
|
2
|
-
|
3
|
-
export default XFormGroupDetails
|
1
|
+
import XFormGroupDetails from './XFormGroupDetails'
|
2
|
+
|
3
|
+
export default XFormGroupDetails
|
@@ -1,6 +1,12 @@
|
|
1
1
|
<template>
|
2
2
|
<a-card :bordered="false" :body-style="bodyStyle">
|
3
|
-
<a-tabs
|
3
|
+
<a-tabs
|
4
|
+
:tabBarGutter="tabBarGutter"
|
5
|
+
:activeKey="activeKey"
|
6
|
+
@change="tabPaneChange"
|
7
|
+
:hideAdd="true"
|
8
|
+
:tabBarStyle="{ display: showTabBar ? 'block' : 'none' }"
|
9
|
+
>
|
4
10
|
<slot name="extraBeforeTabs"></slot>
|
5
11
|
<a-tab-pane
|
6
12
|
:forceRender="true"
|
@@ -79,21 +85,40 @@ export default {
|
|
79
85
|
}
|
80
86
|
const oldKey = this.activeKey
|
81
87
|
if (this.config.changeFunc) {
|
88
|
+
let oldRef
|
89
|
+
let oldTabName
|
90
|
+
let newRef
|
91
|
+
let newTabName
|
92
|
+
if (!this.config.data[oldKey]) {
|
93
|
+
oldTabName = `tab_com_${oldKey}`
|
94
|
+
oldRef = this.$refs[oldTabName]
|
95
|
+
} else {
|
96
|
+
const oldTabSlotType = this.config.data[oldKey].slotType
|
97
|
+
oldTabName = `tab_com_${oldTabSlotType}_${oldKey}`
|
98
|
+
oldRef = this.$refs[oldTabName]
|
99
|
+
}
|
100
|
+
if (!this.config.data[newKey]) {
|
101
|
+
newTabName = `tab_com_${newKey}`
|
102
|
+
newRef = this.$refs[newTabName]
|
103
|
+
} else {
|
104
|
+
const newTabSlotType = this.config.data[newKey].slotType
|
105
|
+
newTabName = `tab_com_${newTabSlotType}_${newKey}`
|
106
|
+
newRef = this.$refs[newTabName]
|
107
|
+
}
|
82
108
|
const args = [
|
83
109
|
oldKey,
|
84
110
|
newKey,
|
85
111
|
this.config.data[oldKey],
|
86
112
|
this.config.data[newKey],
|
87
|
-
|
88
|
-
`tab_com_${this.config.data[newKey].slotType}_${newKey}`,
|
89
|
-
this.$refs[`tab_com_${this.config.data[oldKey].slotType}_${oldKey}`][0]
|
113
|
+
oldRef ? oldRef[0] : undefined,
|
90
114
|
]
|
91
|
-
if (!
|
115
|
+
if (!newRef) {
|
92
116
|
args.push(null)
|
93
117
|
console.warn('新页签示例切换页签时暂未初始化,仅调用该页签初始化方法不调用切换函数')
|
94
118
|
} else {
|
95
|
-
args.push(
|
119
|
+
args.push(newRef[0])
|
96
120
|
}
|
121
|
+
args.push(this.extraData)
|
97
122
|
result = executeStrFunctionByContext(this, this.config.changeFunc, args)
|
98
123
|
if (result && result.noChange) {
|
99
124
|
console.info('不切换页签作为按钮使用')
|
@@ -102,12 +127,12 @@ export default {
|
|
102
127
|
if (result && result.callback && typeof result.callback === 'function') {
|
103
128
|
// 使用 $nextTick 等待 DOM 更新完成后再获取组件实例
|
104
129
|
this.$nextTick(() => {
|
105
|
-
const newComponent =
|
130
|
+
const newComponent = newRef
|
106
131
|
if (!newComponent || !newComponent[0]) {
|
107
132
|
console.warn('组件实例尚未创建,等待组件mounted事件')
|
108
133
|
// 使用 MutationObserver 监听DOM变化
|
109
134
|
const observer = new MutationObserver((mutations, obs) => {
|
110
|
-
const newComp =
|
135
|
+
const newComp = newRef
|
111
136
|
if (newComp && newComp[0]) {
|
112
137
|
obs.disconnect()
|
113
138
|
console.log('组件已创建,执行回调')
|
@@ -236,6 +261,13 @@ export default {
|
|
236
261
|
default: () => {
|
237
262
|
return {}
|
238
263
|
}
|
264
|
+
},
|
265
|
+
// 额外数据
|
266
|
+
extraData: {
|
267
|
+
type: Object,
|
268
|
+
default: () => {
|
269
|
+
return {}
|
270
|
+
}
|
239
271
|
}
|
240
272
|
},
|
241
273
|
watch: {
|
@@ -930,29 +930,31 @@ export default {
|
|
930
930
|
this.innerSelectedRowKeys = currentPageSelectedRows.map(row => row[primaryKeyName])
|
931
931
|
this.innerSelectedRows = currentPageSelectedRows
|
932
932
|
// 更新表格显示
|
933
|
-
this.$refs.table
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
currentRow
|
933
|
+
if (this.$refs.table) {
|
934
|
+
this.$refs.table.updateSelect(this.innerSelectedRowKeys, this.innerSelectedRows)
|
935
|
+
// 更新总选中状态
|
936
|
+
if (currentPageSelectedRows.length > 0) {
|
937
|
+
// 保留不在当前页面的已选中行
|
938
|
+
const otherPageSelectedRows = this.selectedRows.filter(row =>
|
939
|
+
!currentPageSelectedRows.some(currentRow =>
|
940
|
+
currentRow[primaryKeyName] === row[primaryKeyName]
|
941
|
+
)
|
940
942
|
)
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
943
|
+
// 合并当前页面和其他页面的选中行
|
944
|
+
const rowsMap = new Map()
|
945
|
+
// 先添加其他页面的行
|
946
|
+
otherPageSelectedRows.forEach(row => {
|
947
|
+
rowsMap.set(row[primaryKeyName], row)
|
948
|
+
})
|
949
|
+
// 再添加当前页面的行(会覆盖重复的)
|
950
|
+
currentPageSelectedRows.forEach(row => {
|
951
|
+
rowsMap.set(row[primaryKeyName], row)
|
952
|
+
})
|
953
|
+
this.selectedRows = Array.from(rowsMap.values())
|
954
|
+
}
|
955
|
+
// 触发选择事件
|
956
|
+
this.$emit('selectRow', this.selectedRowKeys, this.selectedRows)
|
953
957
|
}
|
954
|
-
// 触发选择事件
|
955
|
-
this.$emit('selectRow', this.selectedRowKeys, this.selectedRows)
|
956
958
|
})
|
957
959
|
}
|
958
960
|
})
|
@@ -10,46 +10,46 @@
|
|
10
10
|
@mouseleave="handleMouseLeave"
|
11
11
|
:class="{ 'hover-active': enableHoverOptions && hoveredIndex === index }"
|
12
12
|
>
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
13
|
+
<i
|
14
|
+
v-if="icon"
|
15
|
+
class="icon-menu"
|
16
|
+
:style="getIconStyle(item)"
|
17
|
+
></i>
|
18
|
+
<span
|
19
|
+
class="item-text">
|
20
|
+
{{ item.number }} {{ item.name }}
|
21
|
+
</span>
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
<div v-if="button" class="button-group">
|
24
|
+
<a-button
|
25
|
+
v-for="(name, idx) in buttonNames"
|
26
|
+
:key="idx"
|
27
|
+
type="link"
|
28
|
+
:class="['confirm-btn', buttonMode ? 'hover-btn' : '']"
|
29
|
+
@click.stop="click(index, idx)"
|
30
|
+
>
|
31
|
+
<span :class="{ 'hover-active': enableHoverOptions && hoveredIndex === index }">{{ name }}</span>
|
32
|
+
</a-button>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<!-- 悬浮选项框 -->
|
36
|
+
<div
|
37
|
+
v-show="enableHoverOptions && hoveredIndex === index"
|
38
|
+
class="hover-options"
|
39
|
+
@mouseenter="handleOptionsEnter"
|
40
|
+
@mouseleave="handleOptionsLeave"
|
41
|
+
>
|
42
|
+
<div class="hover-options-content">
|
43
|
+
<div
|
44
|
+
v-for="(item, idx) in select_options"
|
26
45
|
:key="idx"
|
27
|
-
|
28
|
-
|
29
|
-
@click.stop="click(index, idx)"
|
46
|
+
class="option-item"
|
47
|
+
@click="handleOptionClick(index, item)"
|
30
48
|
>
|
31
|
-
|
32
|
-
</a-button>
|
33
|
-
</div>
|
34
|
-
|
35
|
-
<!-- 悬浮选项框 -->
|
36
|
-
<div
|
37
|
-
v-show="enableHoverOptions && hoveredIndex === index"
|
38
|
-
class="hover-options"
|
39
|
-
@mouseenter="handleOptionsEnter"
|
40
|
-
@mouseleave="handleOptionsLeave"
|
41
|
-
>
|
42
|
-
<div class="hover-options-content">
|
43
|
-
<div
|
44
|
-
v-for="(item, idx) in select_options"
|
45
|
-
:key="idx"
|
46
|
-
class="option-item"
|
47
|
-
@click="handleOptionClick(index, item)"
|
48
|
-
>
|
49
|
-
{{ item }}
|
50
|
-
</div>
|
49
|
+
{{ item }}
|
51
50
|
</div>
|
52
51
|
</div>
|
52
|
+
</div>
|
53
53
|
</a-list-item>
|
54
54
|
</a-list>
|
55
55
|
</div>
|
@@ -1,11 +1,12 @@
|
|
1
1
|
<template>
|
2
2
|
<div class="list-wrapper">
|
3
|
-
<a-list
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
<a-list
|
4
|
+
size="large"
|
5
|
+
:data-source="data"
|
6
|
+
itemLayout="horizontal"
|
7
|
+
class="list-container"
|
8
|
+
ref="listRef"
|
9
|
+
split="config.split"
|
9
10
|
>
|
10
11
|
<template v-if="config.header" #header>
|
11
12
|
<div >{{ config.header }}</div>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<div v-for="(item, index) in weekDays" :key="index" :slot="item.key" class="week_last_next_btn">
|
11
11
|
<a-button slot="lastWeek" icon="left" size="large" @click="handleLastWeek" v-if="item.title == '周一'" />
|
12
12
|
<div class="time-title">
|
13
|
-
<span>{{item.title}}</span>
|
13
|
+
<span>{{ item.title }}</span>
|
14
14
|
<span>{{ currentWeekDates[index].toLocaleDateString() }}</span>
|
15
15
|
</div>
|
16
16
|
<a-button slot="nextWeek" icon="right" size="large" @click="handleNextWeek" v-if="item.title == '周日'"/>
|
@@ -18,29 +18,37 @@
|
|
18
18
|
>
|
19
19
|
<!-- 行类型,递归渲染子行 -->
|
20
20
|
<template v-if="col.type === 'row'">
|
21
|
-
<
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
<x-page-row-template :template="col.template">
|
22
|
+
<render-row
|
23
|
+
v-for="(nestedRow, index) in col.children"
|
24
|
+
:row="nestedRow"
|
25
|
+
:key="`nested-row-${col.id}-${index}`"
|
26
|
+
/>
|
27
|
+
</x-page-row-template>
|
26
28
|
</template>
|
27
29
|
|
28
30
|
<!-- 组件类型,渲染动态组件 -->
|
29
31
|
<template v-else>
|
30
|
-
<
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
<
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
32
|
+
<x-page-row-template :template="col.template">
|
33
|
+
<component
|
34
|
+
:ref="(el) => registerComponentRef(col.id, el)"
|
35
|
+
:is="resolveComponentType(col.type)"
|
36
|
+
v-bind="col.props"
|
37
|
+
>
|
38
|
+
<!-- 如果组件有子组件,递归渲染子行 -->
|
39
|
+
<template v-if="col.children && col.children.length">
|
40
|
+
<!-- 处理纯文本节点 -->
|
41
|
+
<template v-for="(nestedItem, index) in col.children">
|
42
|
+
<template v-if="nestedItem.text">{{ nestedItem.text }}</template>
|
43
|
+
<render-row
|
44
|
+
v-else
|
45
|
+
:row="nestedItem"
|
46
|
+
:key="`comp-child-${col.id}-${index}`"
|
47
|
+
/>
|
48
|
+
</template>
|
49
|
+
</template>
|
50
|
+
</component>
|
51
|
+
</x-page-row-template>
|
44
52
|
</template>
|
45
53
|
</a-col>
|
46
54
|
</a-row>
|
@@ -48,17 +56,13 @@
|
|
48
56
|
|
49
57
|
<script setup>
|
50
58
|
import { defineProps, inject, computed } from 'vue'
|
59
|
+
import XPageRowTemplate from './XPageRowTemplate.vue'
|
60
|
+
|
61
|
+
import { resolveComponentType } from './componentTypes'
|
51
62
|
|
52
63
|
// 注入注册组件方法
|
53
64
|
const registerComponent = inject('registerComponent')
|
54
65
|
|
55
|
-
// 支持的组件类型映射
|
56
|
-
const components = {
|
57
|
-
XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable'),
|
58
|
-
XAddNativeForm: () => import('@vue2-client/base-client/components/common/XAddNativeForm'),
|
59
|
-
XErrorView: () => import('@vue2-client/base-client/components/layout/XPageView/XErrorView')
|
60
|
-
}
|
61
|
-
|
62
66
|
// 定义属性
|
63
67
|
const props = defineProps({
|
64
68
|
row: {
|
@@ -72,12 +76,6 @@ const getColumns = computed(() => {
|
|
72
76
|
return props.row.type === 'row' ? props.row.children : [props.row]
|
73
77
|
})
|
74
78
|
|
75
|
-
// 解析组件类型
|
76
|
-
const resolveComponentType = (type) => {
|
77
|
-
if (!type) return components.XErrorView
|
78
|
-
return components[type] || components.XErrorView
|
79
|
-
}
|
80
|
-
|
81
79
|
// 注册组件引用
|
82
80
|
const registerComponentRef = (id, el) => {
|
83
81
|
if (el) {
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<template>
|
2
|
+
<div>
|
3
|
+
<template v-if="finalTemplate === 'card'">
|
4
|
+
<a-card :bordered="false" class="x-page-row-template-card">
|
5
|
+
<slot></slot>
|
6
|
+
</a-card>
|
7
|
+
</template>
|
8
|
+
<template v-else>
|
9
|
+
<div class="simple-template-card">
|
10
|
+
<slot></slot>
|
11
|
+
</div>
|
12
|
+
</template>
|
13
|
+
</div>
|
14
|
+
</template>
|
15
|
+
|
16
|
+
<script setup>
|
17
|
+
import { computed } from 'vue'
|
18
|
+
|
19
|
+
// 定义组件属性
|
20
|
+
const props = defineProps({
|
21
|
+
template: {
|
22
|
+
type: String,
|
23
|
+
default: 'card'
|
24
|
+
}
|
25
|
+
})
|
26
|
+
|
27
|
+
// 计算最终使用的模板类型
|
28
|
+
const finalTemplate = computed(() => {
|
29
|
+
return props.template || 'card'
|
30
|
+
})
|
31
|
+
</script>
|
32
|
+
|
33
|
+
<style scoped lang="less">
|
34
|
+
.x-page-row-template-card {
|
35
|
+
border-radius: 8px;
|
36
|
+
}
|
37
|
+
</style>
|
@@ -27,7 +27,8 @@ const dataContext = reactive({
|
|
27
27
|
comps: componentRefMap,
|
28
28
|
func: {
|
29
29
|
getConfigByName
|
30
|
-
}
|
30
|
+
},
|
31
|
+
data: {}
|
31
32
|
})
|
32
33
|
|
33
34
|
/**
|
@@ -78,17 +79,16 @@ const registerComponent = (name, vm) => {
|
|
78
79
|
registerComponentTotal.value++
|
79
80
|
console.debug(`总组件数量:${componentTotal.value},已注册数量:${registerComponentTotal.value}`)
|
80
81
|
|
81
|
-
// 初始化页面
|
82
|
-
if (layout.value?.onMounted && registerComponentTotal.value === 1) {
|
83
|
-
initPage()
|
84
|
-
}
|
85
|
-
|
86
82
|
// 所有组件都已注册完成
|
87
83
|
if (registerComponentTotal.value >= componentTotal.value) {
|
88
84
|
registerEvents(layout.value.children)
|
85
|
+
// 初始化页面
|
86
|
+
initPage()
|
89
87
|
}
|
90
88
|
}
|
91
89
|
provide('registerComponent', registerComponent)
|
90
|
+
// 提供数据上下文给子组件
|
91
|
+
provide('dataContext', dataContext)
|
92
92
|
|
93
93
|
/**
|
94
94
|
* 初始化页面
|
@@ -96,6 +96,7 @@ provide('registerComponent', registerComponent)
|
|
96
96
|
const initPage = () => {
|
97
97
|
if (!layout.value?.onMounted) return
|
98
98
|
|
99
|
+
console.info('开始初始化页面')
|
99
100
|
try {
|
100
101
|
// 使用 Function 构造函数替代 eval
|
101
102
|
// eslint-disable-next-line no-new-func
|
@@ -113,8 +114,8 @@ const setComponentTotal = (children) => {
|
|
113
114
|
if (!children?.length) return
|
114
115
|
|
115
116
|
children.forEach((child) => {
|
116
|
-
// 如果不是row类型,追加组件数量
|
117
|
-
if (child.type !== 'row') {
|
117
|
+
// 如果不是row和text类型,追加组件数量
|
118
|
+
if (child.type !== 'row' && child.type !== 'text') {
|
118
119
|
componentTotal.value++
|
119
120
|
}
|
120
121
|
|
@@ -172,7 +173,7 @@ defineExpose({ init })
|
|
172
173
|
class="liuli-page">
|
173
174
|
<template v-if="loaded === loadingStatus.LOADED">
|
174
175
|
<template v-if="layout.children?.length">
|
175
|
-
<a-col v-for="row in layout.children" :key="`page-col-${row.id}`">
|
176
|
+
<a-col v-for="row in layout.children" :key="`page-col-${row.id}`" :span="24">
|
176
177
|
<render-row :row="row"/>
|
177
178
|
</a-col>
|
178
179
|
</template>
|
@@ -0,0 +1,96 @@
|
|
1
|
+
<template>
|
2
|
+
<a-card :bordered="false" :body-style="bodyStyle">
|
3
|
+
<a-tabs
|
4
|
+
:tabBarGutter="tabBarGutter"
|
5
|
+
:activeKey="activeKey"
|
6
|
+
@change="tabPaneChange"
|
7
|
+
:hideAdd="true"
|
8
|
+
:tabBarStyle="{ display: showTabBar ? 'block' : 'none' }"
|
9
|
+
>
|
10
|
+
<slot name="extraBeforeTabs"></slot>
|
11
|
+
<a-tab-pane
|
12
|
+
:forceRender="true"
|
13
|
+
v-for="(tab, index) in data"
|
14
|
+
:key="index"
|
15
|
+
:tab="tab.title"
|
16
|
+
>
|
17
|
+
<component
|
18
|
+
:is="resolveComponentType(tab.type)"
|
19
|
+
:key="`xTabPaneComp${index}`"
|
20
|
+
:ref="`tab_comp_${index}`"
|
21
|
+
v-bind="tab.props || {}"
|
22
|
+
/>
|
23
|
+
</a-tab-pane>
|
24
|
+
</a-tabs>
|
25
|
+
</a-card>
|
26
|
+
</template>
|
27
|
+
|
28
|
+
<script setup>
|
29
|
+
import { ref, onMounted } from 'vue'
|
30
|
+
import { resolveComponentType } from '../componentTypes'
|
31
|
+
|
32
|
+
const props = defineProps({
|
33
|
+
// 标签页数据
|
34
|
+
data: {
|
35
|
+
type: Array,
|
36
|
+
required: true
|
37
|
+
},
|
38
|
+
// 是否显示标签栏
|
39
|
+
showTabBar: {
|
40
|
+
type: Boolean,
|
41
|
+
default: true
|
42
|
+
},
|
43
|
+
// 标签页切换时的回调函数
|
44
|
+
onChange: {
|
45
|
+
type: [String, Function],
|
46
|
+
default: null
|
47
|
+
},
|
48
|
+
// Tab间距
|
49
|
+
tabBarGutter: {
|
50
|
+
type: Number,
|
51
|
+
default: 10
|
52
|
+
},
|
53
|
+
// 卡片样式
|
54
|
+
bodyStyle: {
|
55
|
+
type: Object,
|
56
|
+
default: () => ({})
|
57
|
+
},
|
58
|
+
// 默认激活的标签页
|
59
|
+
defaultActiveKey: {
|
60
|
+
type: [String, Number],
|
61
|
+
default: 0
|
62
|
+
}
|
63
|
+
})
|
64
|
+
|
65
|
+
// 激活的标签页
|
66
|
+
const activeKey = ref(0)
|
67
|
+
|
68
|
+
// 切换标签页
|
69
|
+
const tabPaneChange = (newKey) => {
|
70
|
+
if (activeKey.value === newKey) return
|
71
|
+
|
72
|
+
const oldKey = activeKey.value
|
73
|
+
activeKey.value = newKey
|
74
|
+
|
75
|
+
// 触发标签页切换事件
|
76
|
+
if (props.onChange) {
|
77
|
+
try {
|
78
|
+
if (props.onChange instanceof Function) {
|
79
|
+
props.onChange(oldKey, newKey, props.data[oldKey], props.data[newKey])
|
80
|
+
} else {
|
81
|
+
// 创建一个安全的函数执行环境
|
82
|
+
// eslint-disable-next-line no-new-func
|
83
|
+
const onChange = new Function('oldKey', 'newKey', 'oldTab', 'newTab', `return (${props.onChange})(oldKey, newKey, oldTab, newTab)`)
|
84
|
+
onChange(oldKey, newKey, props.data[oldKey], props.data[newKey])
|
85
|
+
}
|
86
|
+
} catch (error) {
|
87
|
+
console.error('执行标签页切换回调错误:', error)
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
// 生命周期
|
93
|
+
onMounted(() => {
|
94
|
+
activeKey.value = props.defaultActiveKey
|
95
|
+
})
|
96
|
+
</script>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
// 支持的组件类型映射
|
2
|
+
export const components = {
|
3
|
+
XTab: () => import('@vue2-client/base-client/components/layout/XPageView/XTab'),
|
4
|
+
XFormTable: () => import('@vue2-client/base-client/components/common/XFormTable'),
|
5
|
+
XAddNativeForm: () => import('@vue2-client/base-client/components/common/XAddNativeForm'),
|
6
|
+
XReportGrid: () => import('@vue2-client/base-client/components/common/XReportGrid/XReport.vue'),
|
7
|
+
XErrorView: () => import('@vue2-client/base-client/components/layout/XPageView/XErrorView'),
|
8
|
+
// 全局组件不需要导入,直接返回null,让Vue使用全局注册的组件
|
9
|
+
}
|
10
|
+
|
11
|
+
// 组件类型解析函数
|
12
|
+
export const resolveComponentType = (type) => {
|
13
|
+
if (!type) return components.XErrorView
|
14
|
+
|
15
|
+
// 如果是Ant Design Vue组件(以'a-'开头),直接返回原名称
|
16
|
+
if (type.startsWith('a-')) {
|
17
|
+
return type
|
18
|
+
}
|
19
|
+
|
20
|
+
// 否则从已注册的组件集合中查找
|
21
|
+
return components[type] || components.XErrorView
|
22
|
+
}
|
@@ -59,6 +59,7 @@ const initView = () => {
|
|
59
59
|
"type": "row",
|
60
60
|
"id": "row1",
|
61
61
|
"gutter": 16,
|
62
|
+
"template": "card",
|
62
63
|
"children": [
|
63
64
|
{
|
64
65
|
"type": "XFormTable",
|
@@ -75,3 +76,21 @@ const initView = () => {
|
|
75
76
|
"onMounted": "function(data) { console.log('页面已加载') }"
|
76
77
|
}
|
77
78
|
```
|
79
|
+
|
80
|
+
### row类型的属性
|
81
|
+
|
82
|
+
| 属性名 | 说明 | 类型 | 可选值 | 默认值 |
|
83
|
+
| --- | --- | --- | --- | --- |
|
84
|
+
| template | row的渲染模板类型 | String | card/none | card |
|
85
|
+
|
86
|
+
## 内部组件
|
87
|
+
|
88
|
+
### XPageRowTemplate
|
89
|
+
|
90
|
+
用于根据template属性决定是否使用卡片包装内容的组件。
|
91
|
+
|
92
|
+
#### 属性
|
93
|
+
|
94
|
+
| 属性名 | 说明 | 类型 | 可选值 | 默认值 |
|
95
|
+
| --- | --- | --- | --- | --- |
|
96
|
+
| template | 渲染模板类型 | String | card/none | card |
|
@@ -1,93 +1,47 @@
|
|
1
|
-
<template>
|
2
|
-
<a-card :bordered="false">
|
3
|
-
<x-form-table
|
4
|
-
title="示例页面"
|
5
|
-
:queryParamsName="queryParamsName"
|
6
|
-
:fixed-query-form="{
|
7
|
-
users_f_handler_id: currUser.id,
|
8
|
-
}"
|
9
|
-
@action="toDetail">
|
10
|
-
<template slot="button">
|
11
|
-
<a-button @click="add">
|
12
|
-
<a-icon type="plus"/>
|
13
|
-
发起报建
|
14
|
-
</a-button>
|
15
|
-
</template>
|
16
|
-
</x-form-table>
|
17
|
-
<a-modal
|
18
|
-
v-model="applyAddFlag"
|
19
|
-
:footer="null"
|
20
|
-
:dialog-style="{ top: '5rem' }"
|
21
|
-
:z-index="1001"
|
22
|
-
title="发起报建"
|
23
|
-
:destroyOnClose="true">
|
24
|
-
<x-add-native-form ref="xForm" @onSubmit="applySubmit"/>
|
25
|
-
</a-modal>
|
26
|
-
<WorkflowDetail ref="workFlow" @success="success" @nextClick="nextClick"></WorkflowDetail>
|
27
|
-
</a-card>
|
28
|
-
</template>
|
29
|
-
|
30
1
|
<script>
|
31
2
|
import WorkflowDetail from '@vue2-client/pages/WorkflowDetail/WorkflowDetail.vue'
|
32
|
-
import XFormTable from '@vue2-client/base-client/components/common/XFormTable/XFormTable'
|
33
|
-
import XAddNativeForm from '@vue2-client/base-client/components/common/XAddNativeForm/XAddNativeForm.vue'
|
34
|
-
import { getConfigByName, runLogic } from '@vue2-client/services/api/common'
|
35
|
-
import { mapState } from 'vuex'
|
36
3
|
|
37
4
|
export default {
|
38
|
-
name: '
|
39
|
-
components: {
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
data () {
|
45
|
-
return {
|
46
|
-
// 查询配置文件名
|
47
|
-
queryParamsName: 'applyCRUD',
|
48
|
-
// 发起报建弹框控制
|
49
|
-
applyAddFlag: false
|
50
|
-
}
|
51
|
-
},
|
52
|
-
computed: {
|
53
|
-
...mapState('account', { currUser: 'user' }),
|
5
|
+
name: 'WorkFlowDemo',
|
6
|
+
components: { WorkflowDetail },
|
7
|
+
mounted () {
|
8
|
+
this.$refs.workFlow.init({
|
9
|
+
workflowId: '58'
|
10
|
+
})
|
54
11
|
},
|
55
12
|
methods: {
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
...res
|
65
|
-
})
|
66
|
-
})
|
67
|
-
}
|
68
|
-
)
|
69
|
-
},
|
70
|
-
applySubmit (formData) {
|
71
|
-
runLogic('addApply', formData).then(
|
72
|
-
res => {
|
73
|
-
this.$message.success('发起报建成功')
|
74
|
-
this.applyAddFlag = false
|
75
|
-
}
|
76
|
-
).catch(() => {
|
77
|
-
this.applyAddFlag = false
|
78
|
-
})
|
13
|
+
/**
|
14
|
+
* 流程详情页成功
|
15
|
+
* @param note 备注信息
|
16
|
+
* @param form 表单信息
|
17
|
+
* @param workflowId
|
18
|
+
*/
|
19
|
+
success ({ note, form, workflowId }) {
|
20
|
+
console.log('success', note, form, workflowId)
|
79
21
|
},
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
22
|
+
/**
|
23
|
+
* 流程详情页成功
|
24
|
+
* @param note 备注信息
|
25
|
+
* @param form 表单信息
|
26
|
+
* @param workflowId 工作流id
|
27
|
+
* @param fromStepId 起ID
|
28
|
+
* @param toStepId 往ID
|
29
|
+
* @param successStepId 完成步骤id
|
30
|
+
* @param successStep 完成步骤名称
|
31
|
+
* @param fromStep 起步骤名称
|
32
|
+
* @param toStep 往步骤名称
|
33
|
+
*/
|
34
|
+
nextClick ({ note, form, workflowId, fromStepId, toStepId, fromStep, toStep, successStepId, successStep }) {
|
35
|
+
console.log('success', note, form, workflowId, fromStepId, toStepId, fromStep, toStep, successStepId, successStep)
|
90
36
|
}
|
91
37
|
}
|
92
38
|
}
|
93
39
|
</script>
|
40
|
+
|
41
|
+
<template>
|
42
|
+
<WorkflowDetail ref="workFlow" @success="success" @nextClick="nextClick"></WorkflowDetail>
|
43
|
+
</template>
|
44
|
+
|
45
|
+
<style scoped lang="less">
|
46
|
+
|
47
|
+
</style>
|
@@ -38,7 +38,13 @@
|
|
38
38
|
<a-card :bordered="false" :loading="loadingHistory" :body-style="{ paddingTop: 0 }">
|
39
39
|
<!-- 当前步骤历史记录 -->
|
40
40
|
<template v-if="showTab">
|
41
|
-
<x-tab
|
41
|
+
<x-tab
|
42
|
+
:compProp="{ buttonState: { add: false, edit: false, delete: false, import: false }}"
|
43
|
+
:local-config="tabDesigner"
|
44
|
+
:body-style="{ padding: 0 }"
|
45
|
+
:tabBarGutter="24"
|
46
|
+
:extra-data="{ workflowId: workflowId }"
|
47
|
+
default-active-key="workFlowTab">
|
42
48
|
<a-tab-pane
|
43
49
|
:forceRender="true"
|
44
50
|
v-if="formCompletedDataPreview"
|
@@ -64,7 +70,7 @@
|
|
64
70
|
<a-tab-pane key="1" tab="业务操作">
|
65
71
|
<a-card :bordered="false" :loading="loadingHistory" :body-style="{ paddingTop: 0 }">
|
66
72
|
<template v-if="showTab">
|
67
|
-
<x-tab :local-config="tabDesigner" :body-style="{ padding: 0 }" :tabBarGutter="24" default-active-key="workFlowTab">
|
73
|
+
<x-tab :local-config="tabDesigner" :extra-data="{ workflowId:workflowId }" :body-style="{ padding: 0 }" :tabBarGutter="24" default-active-key="workFlowTab">
|
68
74
|
<a-tab-pane
|
69
75
|
:forceRender="true"
|
70
76
|
v-if="showForm"
|
@@ -257,7 +263,7 @@ export default {
|
|
257
263
|
...mapState('account', { currUser: 'user' }),
|
258
264
|
canSubmit () {
|
259
265
|
// 对于超级管理员直接认为可以提交
|
260
|
-
if (this.currUser.
|
266
|
+
if (this.currUser.rolesnames.indexOf('超级管理员') > -1) {
|
261
267
|
return true
|
262
268
|
}
|
263
269
|
// currentStepId可能还没初始化,此处拿不到先返回false
|
@@ -413,7 +419,7 @@ export default {
|
|
413
419
|
},
|
414
420
|
props: {
|
415
421
|
workflowId: {
|
416
|
-
type: String,
|
422
|
+
type: [String, Number],
|
417
423
|
required: true
|
418
424
|
},
|
419
425
|
visible: {
|
@@ -6,59 +6,137 @@ const xPageViewRef = ref(null)
|
|
6
6
|
|
7
7
|
onMounted(() => {
|
8
8
|
xPageViewRef.value.init({
|
9
|
-
configValue:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
configValue: {
|
10
|
+
type: 'page',
|
11
|
+
onMounted: function (curr) {
|
12
|
+
console.warn(curr.data)
|
13
|
+
// 设置Tab配置数据
|
14
|
+
curr.data.tabData = {
|
15
|
+
index: 0,
|
16
|
+
items: [
|
17
|
+
// 第一组配置
|
18
|
+
{
|
19
|
+
tabConfigs: [
|
20
|
+
{ title: '表单列表', type: 'XFormTable', props: { serviceName: 'af-system', queryParamsName: 'crud_dictionary_manage' } },
|
21
|
+
{ title: '新增表单', type: 'XAddNativeForm', props: { serviceName: 'af-system', configName: 'crud_dictionary_manage_add_form' } }
|
22
|
+
]
|
23
|
+
},
|
24
|
+
// 第二组配置
|
25
|
+
{
|
26
|
+
tabConfigs: [
|
27
|
+
{ title: '数据列表', type: 'XFormTable', props: { serviceName: 'af-system', queryParamsName: 'crud_dictionary_manage' } },
|
28
|
+
{ title: '编辑表单', type: 'XAddNativeForm', props: { serviceName: 'af-system', configName: 'crud_dictionary_manage_add_form' } },
|
29
|
+
{ title: '查看记录', type: 'XFormTable', props: { serviceName: 'af-system', queryParamsName: 'crud_dictionary_manage' } }
|
30
|
+
]
|
31
|
+
}
|
32
|
+
]
|
33
|
+
}
|
34
|
+
console.log('页面初始化完成,全局数据上下文已创建')
|
35
|
+
},
|
36
|
+
gutter: [16, 16],
|
37
|
+
children: [
|
38
|
+
{
|
39
|
+
id: 'controlRow',
|
40
|
+
type: 'row',
|
41
|
+
gutter: 16,
|
42
|
+
template: 'card',
|
43
|
+
children: [
|
44
|
+
{
|
45
|
+
id: 'buttonContainer',
|
46
|
+
span: '24',
|
47
|
+
type: 'row',
|
48
|
+
gutter: 8,
|
49
|
+
children: [
|
50
|
+
{
|
51
|
+
id: 'reloadButton',
|
52
|
+
span: '6',
|
53
|
+
type: 'a-button',
|
54
|
+
props: {
|
55
|
+
type: 'primary',
|
56
|
+
value: '切换Tab配置'
|
57
|
+
},
|
58
|
+
children: [
|
59
|
+
{
|
60
|
+
type: 'text',
|
61
|
+
text: '切换Tab配置'
|
62
|
+
}
|
63
|
+
],
|
64
|
+
event: {
|
65
|
+
click: function (e, context) {
|
66
|
+
// 切换Tab配置
|
67
|
+
const tabData = context.data.tabData
|
68
|
+
tabData.index = tabData.index === 0 ? 1 : 0
|
69
|
+
|
70
|
+
// 获取当前配置和Tab组件
|
71
|
+
const currentConfig = tabData.items[tabData.index]
|
72
|
+
const tabComponent = context.comps.pageTab
|
73
|
+
|
74
|
+
if (tabComponent) {
|
75
|
+
// 更新Tab组件配置
|
76
|
+
tabComponent.$props.data = currentConfig.tabConfigs
|
77
|
+
console.log('Tab配置已更新,当前配置索引:', tabData.index)
|
78
|
+
|
79
|
+
// 更新状态文本
|
80
|
+
const statusText = context.comps.statusText
|
81
|
+
if (statusText && statusText.$el) {
|
82
|
+
statusText.message = `点击按钮切换不同的Tab配置,当前是第${tabData.index + 1}组配置`
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
},
|
88
|
+
{
|
89
|
+
id: 'statusText',
|
90
|
+
span: '18',
|
91
|
+
type: 'a-alert',
|
92
|
+
props: {
|
93
|
+
message: '点击按钮切换不同的Tab配置,当前是第1组配置',
|
94
|
+
type: 'success'
|
95
|
+
}
|
96
|
+
}
|
97
|
+
]
|
98
|
+
}
|
99
|
+
]
|
100
|
+
},
|
101
|
+
{
|
102
|
+
id: 'row2',
|
103
|
+
type: 'row',
|
104
|
+
gutter: 16,
|
105
|
+
template: 'none',
|
106
|
+
children: [
|
14
107
|
{
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
108
|
+
id: 'pageTab',
|
109
|
+
span: '24',
|
110
|
+
type: 'XTab',
|
111
|
+
props: {
|
112
|
+
showTabBar: true,
|
113
|
+
data: [
|
19
114
|
{
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
"serviceName": "af-system",
|
27
|
-
"queryParamsName": "crud_dictionary_manage"
|
28
|
-
},
|
29
|
-
"children": [
|
30
|
-
]
|
115
|
+
title: '表单列表',
|
116
|
+
type: 'XFormTable',
|
117
|
+
props: {
|
118
|
+
serviceName: 'af-system',
|
119
|
+
queryParamsName: 'crud_dictionary_manage'
|
120
|
+
}
|
31
121
|
},
|
32
122
|
{
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
"serviceName": "af-system",
|
40
|
-
"queryParamsName": "crud_dictionary_manage"
|
41
|
-
},
|
42
|
-
"children": [
|
43
|
-
]
|
123
|
+
title: '新增表单',
|
124
|
+
type: 'XAddNativeForm',
|
125
|
+
props: {
|
126
|
+
serviceName: 'af-system',
|
127
|
+
configName: 'crud_dictionary_manage_add_form'
|
128
|
+
}
|
44
129
|
}
|
45
|
-
]
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
"event": {
|
51
|
-
},
|
52
|
-
"props": {
|
53
|
-
"serviceName": "af-system",
|
54
|
-
"queryParamsName": "crud_dictionary_manage"
|
55
|
-
},
|
56
|
-
"children": [
|
57
|
-
]
|
130
|
+
],
|
131
|
+
onChange: function (oldKey, newKey, oldTab, newTab) {
|
132
|
+
console.log('Tab changed:', oldKey, newKey)
|
133
|
+
}
|
134
|
+
}
|
58
135
|
}
|
59
|
-
|
60
|
-
|
61
|
-
|
136
|
+
]
|
137
|
+
}
|
138
|
+
]
|
139
|
+
},
|
62
140
|
serviceName: 'af-his'
|
63
141
|
})
|
64
142
|
})
|
@@ -1,24 +1,24 @@
|
|
1
|
-
<template>
|
2
|
-
<!-- 测试界面——测试地址选择新增组件-->
|
3
|
-
<div>
|
4
|
-
<a-button @click="open">打开选择地址弹窗</a-button>
|
5
|
-
<address-select :addressShow="showDialog"/>
|
6
|
-
</div>
|
7
|
-
</template>
|
8
|
-
|
9
|
-
<script>
|
10
|
-
import AddressSelect from '@/pages/addressSelect'
|
11
|
-
|
12
|
-
export default {
|
13
|
-
components: { AddressSelect },
|
14
|
-
data: () => ({
|
15
|
-
showDialog: false
|
16
|
-
}),
|
17
|
-
methods: {
|
18
|
-
open () {
|
19
|
-
console.log('打开选择地址弹窗')
|
20
|
-
this.showDialog = true
|
21
|
-
}
|
22
|
-
}
|
23
|
-
}
|
24
|
-
</script>
|
1
|
+
<template>
|
2
|
+
<!-- 测试界面——测试地址选择新增组件-->
|
3
|
+
<div>
|
4
|
+
<a-button @click="open">打开选择地址弹窗</a-button>
|
5
|
+
<address-select :addressShow="showDialog"/>
|
6
|
+
</div>
|
7
|
+
</template>
|
8
|
+
|
9
|
+
<script>
|
10
|
+
import AddressSelect from '@/pages/addressSelect'
|
11
|
+
|
12
|
+
export default {
|
13
|
+
components: { AddressSelect },
|
14
|
+
data: () => ({
|
15
|
+
showDialog: false
|
16
|
+
}),
|
17
|
+
methods: {
|
18
|
+
open () {
|
19
|
+
console.log('打开选择地址弹窗')
|
20
|
+
this.showDialog = true
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
</script>
|
@@ -55,6 +55,9 @@ routerResource.newDynamicStatistics = () => import('@vue2-client/pages/NewDynami
|
|
55
55
|
routerResource.example = {
|
56
56
|
path: 'example',
|
57
57
|
name: '示例主页面',
|
58
|
+
component: () => import('@vue2-client/pages/WorkflowDetail/WorkFlowDemo2.vue'),
|
59
|
+
// component: () => import('@vue2-client/pages/WorkflowDetail/WorkFlowDemo.vue'),
|
60
|
+
// component: () => import('@vue2-client/pages/addressSelect/addressDemo.vue'),
|
58
61
|
// component: () => import('@vue2-client/base-client/components/common/XDescriptions/demo.vue'),
|
59
62
|
// component: () => import('@vue2-client/base-client/components/common/XAddNativeForm/demo.vue'),
|
60
63
|
// component: () => import('@vue2-client/base-client/components/common/XFormGroup/demo.vue'),
|
@@ -65,9 +68,10 @@ routerResource.example = {
|
|
65
68
|
// component: () => import('@vue2-client/base-client/components/common/XRate/demo.vue'),
|
66
69
|
// component: () => import('@vue2-client/base-client/components/common/XForm/demo.vue'),
|
67
70
|
// component: () => import('@vue2-client/base-client/components/his/XTimeSelect/XTimeSelectDemo.vue'),
|
68
|
-
component: () => import('@vue2-client/pages/WorkflowDetail/WorkFlowDemo.vue'),
|
69
|
-
// component: () => import('@vue2-client/
|
70
|
-
// component: () => import('@vue2-client/
|
71
|
+
// component: () => import('@vue2-client/pages/WorkflowDetail/WorkFlowDemo.vue'),
|
72
|
+
// component: () => import('@vue2-client/pages/WorkflowDetail/WorkFlowDemo.vue'),
|
73
|
+
// component: () => import('@vue2-client/pages/XPageViewExample/index.vue'),
|
74
|
+
// component: () => import('@vue2-client/base-client/components/common/XButtons/XButtonDemo.vue'),
|
71
75
|
// component: () => import('@vue2-client/base-client/components/common/XLabelSelect/XLabelSelectDemo.vue'),
|
72
76
|
// component: () => import('@vue2-client/base-client/components/common/XCheckList/XCheckList.vue'),
|
73
77
|
// component: () => import('@vue2-client/base-client/components/common/XPrint/Demo.vue'),
|
package/vue.config.js
CHANGED
@@ -11,12 +11,12 @@ const productionGzipExtensions = ['js', 'css']
|
|
11
11
|
const isProd = process.env.NODE_ENV === 'production'
|
12
12
|
|
13
13
|
// v4 产品演示
|
14
|
-
const v3Server = 'http://
|
14
|
+
const v3Server = 'http://aote-office.8866.org:31567'
|
15
15
|
// const gateway = 'http://192.168.50.67:31467'
|
16
16
|
// const testUpload = 'http://123.60.214.109:8406'
|
17
17
|
const OSSServerDev = 'http://192.168.50.67:30351'
|
18
18
|
// const revenue = 'http://aote-office.8866.org:31567'
|
19
|
-
const revenue = 'http://
|
19
|
+
const revenue = 'http://aote-office.8866.org:31567'
|
20
20
|
// const OSSServerProd = 'http://192.168.50.67:31351'
|
21
21
|
// const testUploadLocal = 'http://127.0.0.1:9001'
|
22
22
|
// v3 铜川
|