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.
Files changed (25) hide show
  1. package/package.json +1 -1
  2. package/src/base-client/components/common/AmapMarker/index.js +3 -3
  3. package/src/base-client/components/common/XDetailsView/index.js +3 -3
  4. package/src/base-client/components/common/XFormGroupDetails/index.js +3 -3
  5. package/src/base-client/components/common/XTab/XTab.vue +40 -8
  6. package/src/base-client/components/common/XTable/XTable.vue +23 -21
  7. package/src/base-client/components/his/XCharge/XCharge.vue +1 -0
  8. package/src/base-client/components/his/XList/XList.vue +35 -35
  9. package/src/base-client/components/his/XQuestionnaire/XQuestionnaireItem.vue +7 -6
  10. package/src/base-client/components/his/XShiftSchedule/XShiftSchedule.vue +1 -1
  11. package/src/base-client/components/layout/XPageView/RenderRow.vue +30 -32
  12. package/src/base-client/components/layout/XPageView/XPageRowTemplate.vue +37 -0
  13. package/src/base-client/components/layout/XPageView/XPageView.vue +10 -9
  14. package/src/base-client/components/layout/XPageView/XTab/XTab.vue +96 -0
  15. package/src/base-client/components/layout/XPageView/XTab/index.js +3 -0
  16. package/src/base-client/components/layout/XPageView/componentTypes.js +22 -0
  17. package/src/base-client/components/layout/XPageView/index.js +1 -0
  18. package/src/base-client/components/layout/XPageView/index.md +19 -0
  19. package/src/pages/WorkflowDetail/WorkFlowDemo.vue +36 -82
  20. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowHandle.vue +10 -4
  21. package/src/pages/WorkflowDetail/WorkflowPageDetail/WorkFlowTimeline.vue +1 -1
  22. package/src/pages/XPageViewExample/index.vue +125 -47
  23. package/src/pages/addressSelect/addressDemo.vue +24 -24
  24. package/src/router/async/router.map.js +7 -3
  25. package/vue.config.js +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2-client",
3
- "version": "1.14.93",
3
+ "version": "1.14.95",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --no-eslint",
@@ -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 :tabBarGutter="tabBarGutter" :activeKey="activeKey" @change="tabPaneChange" :hideAdd="true" :tabBarStyle="{ display: showTabBar ? 'block' : 'none' }">
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
- `tab_com_${this.config.data[oldKey].slotType}_${oldKey}`,
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 (!this.$refs[`tab_com_${this.config.data[newKey].slotType}_${newKey}`]) {
115
+ if (!newRef) {
92
116
  args.push(null)
93
117
  console.warn('新页签示例切换页签时暂未初始化,仅调用该页签初始化方法不调用切换函数')
94
118
  } else {
95
- args.push(this.$refs[`tab_com_${this.config.data[newKey].slotType}_${newKey}`][0])
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 = this.$refs[`tab_com_${this.config.data[newKey].slotType}_${newKey}`]
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 = this.$refs[`tab_com_${this.config.data[newKey].slotType}_${newKey}`]
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.updateSelect(this.innerSelectedRowKeys, this.innerSelectedRows)
934
- // 更新总选中状态
935
- if (currentPageSelectedRows.length > 0) {
936
- // 保留不在当前页面的已选中行
937
- const otherPageSelectedRows = this.selectedRows.filter(row =>
938
- !currentPageSelectedRows.some(currentRow =>
939
- currentRow[primaryKeyName] === row[primaryKeyName]
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
- const rowsMap = new Map()
944
- // 先添加其他页面的行
945
- otherPageSelectedRows.forEach(row => {
946
- rowsMap.set(row[primaryKeyName], row)
947
- })
948
- // 再添加当前页面的行(会覆盖重复的)
949
- currentPageSelectedRows.forEach(row => {
950
- rowsMap.set(row[primaryKeyName], row)
951
- })
952
- this.selectedRows = Array.from(rowsMap.values())
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
  })
@@ -5,6 +5,7 @@
5
5
  <a-col v-for="item in config.amountFields" :key="item.field" :span="6" class="form-row">
6
6
  <label class="form-label">{{ item.label }}</label>
7
7
  <a-input
8
+ v-model="data[item.field]"
8
9
  :value="data[item.field]"
9
10
  :disabled="item.disabled"
10
11
  class="form-input"
@@ -10,46 +10,46 @@
10
10
  @mouseleave="handleMouseLeave"
11
11
  :class="{ 'hover-active': enableHoverOptions && hoveredIndex === index }"
12
12
  >
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>
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
- <div v-if="button" class="button-group">
24
- <a-button
25
- v-for="(name, idx) in buttonNames"
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
- type="link"
28
- :class="['confirm-btn', buttonMode ? 'hover-btn' : '']"
29
- @click.stop="click(index, idx)"
46
+ class="option-item"
47
+ @click="handleOptionClick(index, item)"
30
48
  >
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"
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 size="large"
4
- :data-source="data"
5
- itemLayout="horizontal"
6
- class="list-container"
7
- ref="listRef"
8
- split="config.split"
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
- <render-row
22
- v-for="(nestedRow, index) in col.children"
23
- :row="nestedRow"
24
- :key="`nested-row-${col.id}-${index}`"
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
- <component
31
- :ref="(el) => registerComponentRef(col.id, el)"
32
- :is="resolveComponentType(col.type)"
33
- v-bind="col.props"
34
- >
35
- <!-- 如果组件有子组件,递归渲染子行 -->
36
- <template v-if="col.children?.length">
37
- <render-row
38
- v-for="(nestedRow, index) in col.children"
39
- :row="nestedRow"
40
- :key="`comp-child-${col.id}-${index}`"
41
- />
42
- </template>
43
- </component>
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,3 @@
1
+ import XTab from './XTab.vue'
2
+
3
+ export default XTab
@@ -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
+ }
@@ -1 +1,2 @@
1
1
  export { default } from './XPageView'
2
+ export { default as XPageRowTemplate } from './XPageRowTemplate'
@@ -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: 'Apply',
39
- components: {
40
- XFormTable,
41
- XAddNativeForm,
42
- WorkflowDetail
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
- add () {
57
- this.applyAddFlag = true
58
- this.$nextTick(
59
- () => {
60
- getConfigByName('addApplyForm', 'af-apply', (res) => {
61
- this.$refs.xForm.init({
62
- businessType: '新增',
63
- title: '发起报建',
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
- success () {
81
- console.log('完工')
82
- },
83
- nextClick(data) {
84
- console.log('提交下一步', data)
85
- },
86
- toDetail (record, id) {
87
- this.$refs.workFlow.init({
88
- workflowId: record.twf_id
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 :compProp="{ buttonState: { add: false, edit: false, delete: false, import: false }}" :local-config="tabDesigner" :body-style="{ padding: 0 }" :tabBarGutter="24" default-active-key="workFlowTab">
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.ename === '1') {
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: {
@@ -45,7 +45,7 @@ export default {
45
45
  name: 'WorkFlowTimeline',
46
46
  props: {
47
47
  workflowId: {
48
- type: String,
48
+ type: [String, Number],
49
49
  required: true
50
50
  },
51
51
  currentStepId: {
@@ -6,59 +6,137 @@ const xPageViewRef = ref(null)
6
6
 
7
7
  onMounted(() => {
8
8
  xPageViewRef.value.init({
9
- configValue: `{
10
- "type": "page",
11
- "onMounted": "function (data) {}",
12
- "gutter": [16, 16],
13
- "children": [
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
- "id": "row1",
16
- "type": "row",
17
- "gutter": 16,
18
- "children": [
108
+ id: 'pageTab',
109
+ span: '24',
110
+ type: 'XTab',
111
+ props: {
112
+ showTabBar: true,
113
+ data: [
19
114
  {
20
- "id": "xFormTable2",
21
- "span": "12",
22
- "type": "XFormTable",
23
- "event": {
24
- },
25
- "props": {
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
- "id": "xFormTable3",
34
- "span": "12",
35
- "type": "XFormTable",
36
- "event": {
37
- },
38
- "props": {
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
- "id": "xFormTable",
49
- "type": "XFormTable",
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
- // configName: 'templateManageConfig',
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/base-client/components/common/XConversation/XConversationDemo.vue'),
70
- // component: () => import('@vue2-client/base-client/components/common/XButtons/XButtonexampleDemo.vue'),
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://192.168.50.67:31567'
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://192.168.50.67:31567'
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 铜川