vue2-client 1.14.35 → 1.14.36

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.
@@ -6,7 +6,7 @@ export default {
6
6
  components: { WorkflowDetail },
7
7
  mounted () {
8
8
  this.$refs.workFlow.init({
9
- workflowId: '1'
9
+ workflowId: '5'
10
10
  })
11
11
  },
12
12
  methods: {
@@ -123,39 +123,54 @@
123
123
  <div style="text-align: center">
124
124
  <a-radio-group style="margin-top: 20px">
125
125
  <a-space>
126
- <a-popover v-if="operationType === 'submit'">
127
- <template slot="content">
128
- <p>{{ nextBtnTitle }}</p>
129
- </template>
126
+ <!-- 动态按钮渲染 -->
127
+ <template v-if="buttonGroup && buttonGroup.actionArr">
130
128
  <a-button
131
- v-show="!lastStep"
132
- :disabled="!showNextBtn && !stepDone"
133
- type="primary"
134
- @click="nextClick"
129
+ v-for="(button, index) in buttonGroup.actionArr"
130
+ :key="index"
131
+ v-show="checkButtonVisible(button)"
132
+ :type="button.type ? button.type : 'default'"
133
+ @click="handleCustomButtonClick(button)"
135
134
  >
136
- 提交
137
- <a-icon type="right"/>
135
+ {{ button.text }}
138
136
  </a-button>
139
- </a-popover>
140
- <a-popover v-else :title="stepNextBtnTitle">
141
- <template slot="content">
142
- <p v-for="(item,index) in stepNextBtnText" :key="index">{{ item }}</p>
143
- </template>
137
+ </template>
138
+ <!-- 原有的按钮逻辑 -->
139
+ <template>
140
+ <a-popover v-if="operationType === 'submit'">
141
+ <template slot="content">
142
+ <p>{{ nextBtnTitle }}</p>
143
+ </template>
144
+ <a-button
145
+ v-show="!lastStep"
146
+ :disabled="!showNextBtn && !stepDone"
147
+ type="primary"
148
+ @click="nextClick"
149
+ >
150
+ 提交
151
+ <a-icon type="right"/>
152
+ </a-button>
153
+ </a-popover>
154
+ <a-popover v-else :title="stepNextBtnTitle">
155
+ <template slot="content">
156
+ <p v-for="(item,index) in stepNextBtnText" :key="index">{{ item }}</p>
157
+ </template>
158
+ <a-button
159
+ v-if="showStepNextBtn && !lastStep"
160
+ type="primary"
161
+ @click="stepNextClick"
162
+ >
163
+ 跳跃
164
+ </a-button>
165
+ </a-popover>
144
166
  <a-button
145
- v-if="showStepNextBtn && !lastStep"
167
+ v-show="lastStep"
146
168
  type="primary"
147
- @click="stepNextClick"
169
+ @click="lastStepNextClick"
148
170
  >
149
- 跳跃
171
+ 确认完工
150
172
  </a-button>
151
- </a-popover>
152
- <a-button
153
- v-show="lastStep"
154
- type="primary"
155
- @click="lastStepNextClick"
156
- >
157
- 确认完工
158
- </a-button>
173
+ </template>
159
174
  </a-space>
160
175
  </a-radio-group>
161
176
  </div>
@@ -220,6 +235,9 @@ import WorkFlowTimeline from './WorkFlowTimeline.vue'
220
235
  import { FileItem, ImageItem } from '@vue2-client/components/FileImageItem'
221
236
  import WorkflowListResolution from './WorkflowListResolution'
222
237
  import { commonApi } from '@vue2-client/services/api'
238
+ import { executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
239
+ import * as util from '@vue2-client/utils/util'
240
+ import { getConfigByNameAsync, runLogic } from '@vue2-client/services/api/common'
223
241
 
224
242
  export default {
225
243
  name: 'WorkFlowHandle',
@@ -350,7 +368,9 @@ export default {
350
368
  // 是否需要选择人员
351
369
  needSelectPerson: true,
352
370
  // 下一环节人员信息
353
- chargePerson: {}
371
+ chargePerson: {},
372
+ // 动态按钮配置
373
+ buttonGroup: null
354
374
  }
355
375
  },
356
376
  async mounted () {
@@ -410,6 +430,21 @@ export default {
410
430
  this.formCompletedDataPreview = null
411
431
  this.operationType = 'submit'
412
432
  },
433
+ async showQueryFormItemFunc () {
434
+ if (this.attr.showQueryFormItemFunc) {
435
+ const obj = executeStrFunctionByContext(this, this.attr.showQueryFormItemFunc, [this.form, this.setForm, this.attr, util, this.mode])
436
+ // 判断是 bool 还是 obj 兼容
437
+ if (typeof obj === 'boolean') {
438
+ this.show = obj
439
+ } else if (obj && typeof obj === 'object') {
440
+ // obj 是一个对象,并且不是数组
441
+ this.show = obj?.show
442
+ this.readOnly = obj?.readOnly
443
+ }
444
+ } else {
445
+ this.show = true
446
+ }
447
+ },
413
448
  // 获取单个步骤的定义
414
449
  getSingleStepDefine (name) {
415
450
  for (const step of this.stepsDefine) {
@@ -677,6 +712,13 @@ export default {
677
712
  },
678
713
  // 加载完成
679
714
  resolveStep () {
715
+ // 获取当前步骤的按钮组配置
716
+ const currentStep = this.stepsDefine[this.currentStepId - 1]
717
+ if (currentStep && currentStep.properties && currentStep.properties.buttonGroup) {
718
+ this.buttonGroup = currentStep.properties.buttonGroup
719
+ } else {
720
+ this.buttonGroup = null
721
+ }
680
722
  this.loading = false
681
723
  },
682
724
  // 流程图组件给当前组件传值用,stepNo为用户点击的非当前步骤
@@ -928,6 +970,38 @@ export default {
928
970
  if (this.chargePersonOptions.length === 1) {
929
971
  this.checkedChargePerson = this.chargePersonOptions[0].value
930
972
  }
973
+ },
974
+ // 处理动态按钮点击
975
+ handleCustomButtonClick (button) {
976
+ try {
977
+ // 执行自定义函数
978
+ if (button.func) {
979
+ const result = executeStrFunctionByContext(this, button.func, [this.details, this.$refs.xAddForm.form, util, runLogic, getConfigByNameAsync])
980
+ if (result) {
981
+ // 如果返回true,执行对应的操作
982
+ if (button.text === '提交') {
983
+ this.nextClick()
984
+ } else if (button.text === '取消') {
985
+ this.$emit('cancel')
986
+ }
987
+ }
988
+ }
989
+ } catch (error) {
990
+ console.error('执行自定义按钮函数失败:', error)
991
+ this.$message.error('执行操作失败')
992
+ }
993
+ },
994
+ // 检查按钮是否显示
995
+ checkButtonVisible (button) {
996
+ try {
997
+ if (button.customFunction) {
998
+ return executeStrFunctionByContext(this, button.customFunction, [this.details, this.$refs.xAddForm.form, util, runLogic, getConfigByNameAsync])
999
+ }
1000
+ return true
1001
+ } catch (error) {
1002
+ console.error('执行按钮显示函数失败:', error)
1003
+ return false
1004
+ }
931
1005
  }
932
1006
  },
933
1007
  watch: {}
@@ -1,36 +0,0 @@
1
- <script>
2
- export default {
3
- props: {
4
- weekDays: {
5
- type: Array,
6
- default: () => []
7
- }
8
- },
9
- computed: {
10
- columns () {
11
- const baseColumns = [
12
- { title: '序号', dataIndex: 'index', width: 60 },
13
- { title: '科室', dataIndex: 'department', width: 120 },
14
- { title: '医生', dataIndex: 'doctor', width: 100 },
15
- { title: '上/下/晚', dataIndex: 'shiftType', width: 80 },
16
- ]
17
-
18
- // 增加防御判断,确保 weekDays 存在
19
- const dayColumns = this.weekDays.length > 0
20
- ? this.weekDays.map((day, dayIndex) => ({
21
- title: `${day.label} ${day.date}`,
22
- dataIndex: `shifts-${dayIndex}`, // 改为字符串形式
23
- dayIndex: dayIndex,
24
- width: 120,
25
- }))
26
- : []
27
-
28
- const tailColumns = [
29
- { title: '排班数', dataIndex: 'count', width: 80 }
30
- ]
31
-
32
- return [...baseColumns, ...dayColumns, ...tailColumns]
33
- }
34
- }
35
- }
36
- </script>
@@ -1,91 +0,0 @@
1
- <template>
2
- <div class="tree-container">
3
- <div class="tree-list">
4
- <tree-node
5
- v-for="node in treeData"
6
- :key="node.id"
7
- :node="node"
8
- @toggle="toggleNode"/>
9
- </div>
10
- </div>
11
- </template>
12
-
13
- <script>
14
- import TreeNode from './TreeNode.vue'
15
-
16
- export default {
17
- name: 'TreeList',
18
- components: {
19
- TreeNode
20
- },
21
- data() {
22
- return {
23
- treeData: [
24
- {
25
- id: '1',
26
- title: '体征',
27
- expanded: false,
28
- children: [
29
- {
30
- id: '1-1',
31
- title: '一般情况'
32
- },
33
- {
34
- id: '1-2',
35
- title: '皮肤粘膜'
36
- },
37
- {
38
- id: '1-3',
39
- title: '头颈',
40
- expanded: false,
41
- children: [
42
- {
43
- id: '1-3-1',
44
- title: '头部'
45
- },
46
- {
47
- id: '1-3-2',
48
- title: '颈部'
49
- }
50
- ]
51
- }
52
- ]
53
- }
54
- ]
55
- }
56
- },
57
- methods: {
58
- toggleNode(node) {
59
- node.expanded = !node.expanded
60
- }
61
- }
62
- }
63
- </script>
64
-
65
- <style scoped>
66
- .tree-container {
67
- width: 240px;
68
- height: 400px;
69
- border: 1px solid #e8e8e8;
70
- overflow-y: auto;
71
- padding: 8px;
72
- }
73
-
74
- /* 自定义滚动条样式 */
75
- .tree-container::-webkit-scrollbar {
76
- width: 6px;
77
- }
78
-
79
- .tree-container::-webkit-scrollbar-thumb {
80
- background-color: #ccc;
81
- border-radius: 3px;
82
- }
83
-
84
- .tree-container::-webkit-scrollbar-track {
85
- background-color: #f5f5f5;
86
- }
87
-
88
- .tree-list {
89
- font-size: 14px;
90
- }
91
- </style>
@@ -1,81 +0,0 @@
1
- <template>
2
- <div class="tree-node">
3
- <div class="node-content" @click="handleClick">
4
- <span v-if="hasChildren" class="toggle-icon">
5
- {{ node.expanded ? '-' : '+' }}
6
- </span>
7
- <span class="node-title">{{ node.title }}</span>
8
- </div>
9
- <div v-if="hasChildren && node.expanded" class="node-children">
10
- <tree-node
11
- v-for="child in node.children"
12
- :key="child.id"
13
- :node="child"
14
- @toggle="$emit('toggle', $event)"
15
- :level="level + 1"/>
16
- </div>
17
- </div>
18
- </template>
19
-
20
- <script>
21
- export default {
22
- name: 'TreeNode',
23
- props: {
24
- node: {
25
- type: Object,
26
- required: true
27
- },
28
- level: {
29
- type: Number,
30
- default: 0
31
- }
32
- },
33
- computed: {
34
- hasChildren() {
35
- return this.node.children && this.node.children.length > 0
36
- }
37
- },
38
- methods: {
39
- handleClick() {
40
- if (this.hasChildren) {
41
- this.$emit('toggle', this.node)
42
- }
43
- }
44
- }
45
- }
46
- </script>
47
-
48
- <style scoped>
49
- .tree-node {
50
- margin: 2px 0;
51
- }
52
-
53
- .node-content {
54
- display: flex;
55
- align-items: center;
56
- padding: 4px 0;
57
- user-select: none;
58
- }
59
-
60
- .toggle-icon {
61
- width: 16px;
62
- text-align: center;
63
- font-size: 14px;
64
- color: #666;
65
- margin-right: 4px;
66
- cursor: pointer;
67
- }
68
-
69
- .node-title {
70
- flex: 1;
71
- cursor: default;
72
- }
73
-
74
- .node-content:hover {
75
- background-color: #f5f5f5;
76
- }
77
-
78
- .node-children {
79
- padding-left: 20px;
80
- }
81
- </style>
@@ -1,191 +0,0 @@
1
- <template>
2
- <a-row
3
- class="title_box"
4
- :style="{backgroundColor: requiredParameters.backgroundColor,height:requiredParameters.height}"
5
- type="flex"
6
- v-model="requiredParameters">
7
- <a-col class="title_col_left" :flex="3">
8
- <div class="title_img_box">
9
- <img src="../img/header10086.png" class="title_img" alt="">
10
- </div>
11
- <div class="title_name">{{ requiredParameters.title }}</div>
12
- </a-col>
13
- <a-col class="title_col_right" id="titleSelect" :flex="3" style="padding-right: 3%" v-model="dateData">
14
- <div class="title_date_box">
15
- <div class="title_data">{{ dateData.date }}</div>
16
- <div class="title_week">{{ dateData.dayOfWeek }}</div>
17
- </div>
18
- <div class="title_time">{{ dateData.time }}</div>
19
- <div style="font-size: x-large;margin-left: 1%">|</div>
20
- <div class="title_refresh" @click="refreshTitle"><a-icon type="undo" style="font-size: x-large;"/></div>
21
- <div class="title_refresh_box">
22
- <div class="title_refresh_time">{{ dateData.refreshTime }}</div>
23
- <div class="latest_update_time">最新更新时间</div>
24
- </div>
25
- </a-col>
26
- </a-row>
27
- </template>
28
-
29
- <script>
30
-
31
- export default {
32
- name: 'TitleComponent',
33
- components: {},
34
- data () {
35
- return {
36
- dateData: {
37
- date: '',
38
- dayOfWeek: '',
39
- time: '',
40
- refreshTime: ''
41
- },
42
- timer: null
43
- }
44
- },
45
- props: {
46
- requiredParameters: {
47
- type: Object,
48
- default: () => ({
49
- title: '',
50
- backgroundColor: '',
51
- height: ''
52
- }),
53
- }
54
- },
55
- created () {
56
- this.updateDateData()
57
- this.startTimer()
58
- },
59
- beforeDestroy () {
60
- this.stopTimer()
61
- },
62
- methods: {
63
- // 刷新页面
64
- refreshTitle () {
65
- this.$forceUpdate()
66
- const now = new Date()
67
- this.dateData.refreshTime = now.toLocaleTimeString()
68
- this.$emit('refreshTitle')
69
- },
70
- updateDateData () {
71
- const now = new Date()
72
- const options = { weekday: 'long' }
73
- this.dateData.date = this.formatDate(now)
74
- this.dateData.time = this.formatTime(now)
75
- this.dateData.dayOfWeek = now.toLocaleDateString(undefined, options)
76
- this.dateData.refreshTime = now.toLocaleTimeString()
77
- },
78
- formatDate (date) {
79
- const month = date.getMonth() + 1
80
- const day = date.getDate()
81
- return `${month}月${day}日`
82
- },
83
- formatTime (date) {
84
- const hours = String(date.getHours()).padStart(2, '0')
85
- const minutes = String(date.getMinutes()).padStart(2, '0')
86
- return `${hours}:${minutes}`
87
- },
88
- startTimer () {
89
- this.timer = setInterval(() => {
90
- const now = new Date()
91
- this.dateData.time = this.formatTime(now)
92
- }, 10000) // 每秒更新一次
93
- },
94
- stopTimer () {
95
- if (this.timer) {
96
- clearInterval(this.timer)
97
- this.timer = null
98
- }
99
- }
100
- }
101
- }
102
- </script>
103
-
104
- <style scoped>
105
- .title_box {
106
- width: 100%;
107
- min-height:42px;
108
- }
109
- .title_col_left {
110
- height: 100%;
111
- color: white;
112
- display: flex;
113
- align-content: center;
114
- align-items: center;
115
- }
116
- .title_col_right {
117
- height: 100%;
118
- color: white;
119
- display: flex;
120
- align-content: center;
121
- align-items: center;
122
- justify-content: flex-end;
123
- }
124
- .title_img_box {
125
- height: 80%;
126
- width: auto;
127
- margin-left: 1%;
128
- border-radius: 50%;
129
- background-color: #35baf6;
130
- }
131
- .title_img{
132
- width: 100%;
133
- height: 100%;
134
- }
135
- .title_name {
136
- font-size: medium !important;
137
- font-weight: bold;
138
- margin-left: 1%;
139
- }
140
- .title_date_box{
141
- width: 20%;
142
- height: 100%;
143
- display: flex;
144
- flex-direction: column;
145
- justify-content: center;
146
- }
147
- .title_data{
148
- display: flex;
149
- justify-content: center;
150
- align-items: center;
151
- font-size: smaller;
152
- }
153
- .title_week{
154
- display: flex;
155
- justify-content: center;
156
- align-items: center;
157
- font-size: smaller;
158
- }
159
- .title_time{
160
- font-size: x-large;
161
- }
162
- .title_refresh{
163
- margin-left: 1%;
164
- height: 100%;
165
- align-content: center;
166
- align-items: center;
167
- cursor: pointer;
168
- display: flex;
169
- width: 7%;
170
- justify-content: center;
171
- min-width: 31px;
172
- }
173
- .title_refresh:hover{
174
- background-color: rgb(31, 138, 137);
175
- }
176
- .title_refresh:active{
177
- background-color: rgb(26, 129, 128);
178
- }
179
- .title_refresh_box{
180
- margin-right: 1%;
181
- }
182
- .latest_update_time{
183
- font-size: x-small;
184
- }
185
- .title_refresh_time{
186
- display: flex;
187
- font-size: x-small;
188
- align-content: center;
189
- justify-content: center;
190
- }
191
- </style>