vue2-client 1.14.50 → 1.14.52

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.
@@ -1,122 +1,388 @@
1
- <template>
2
- <a-spin size="large" :spinning="messageLoading">
3
- <a-comment>
4
- <a-avatar slot="avatar" size="large" style="background:#6877ee">{{ user.name.substr(0, 1) }}</a-avatar>
5
- <div slot="content">
6
- <a-textarea v-model="messageText" :rows="4" placeholder="请输入留言" class="text-input"></a-textarea>
7
- <a-space>
8
- <a-button type="primary" :loading="submitting" :disabled="messageText.trim() === ''" @click="onSubmit">提交
9
- </a-button>
10
- </a-space>
11
- </div>
12
- </a-comment>
13
- <a-empty v-if="!messageList.length"/>
14
- <div class="comment">
15
- <a-comment
16
- v-for="message in messageList"
17
- :key="message.id"
18
- :author="message.f_created_by"
19
- :content="message.f_content"
20
- :datetime="format(message.f_create_date)">
21
- <a-avatar
22
- slot="avatar"
23
- size="large"
24
- :style="{background: user.name === message.f_created_by ? '#6877ee' : '#34d5ae'}">
25
- {{ message.f_created_by.substr(0, 1) }}
26
- </a-avatar>
27
- </a-comment>
28
- </div>
29
- </a-spin>
30
- </template>
31
-
32
- <script>
33
- import { formatDate } from '@vue2-client/utils/util'
34
- import { mapState } from 'vuex'
35
- import { postByServiceName } from '@vue2-client/services/api/restTools'
36
- import { workFlowViewApi } from '@vue2-client/services/api/workFlow'
37
-
38
- export default {
39
- name: 'LeaveMessage',
40
- props: {
41
- projectName: {
42
- type: String,
43
- required: true
44
- },
45
- workflowId: {
46
- type: String,
47
- required: true
48
- },
49
- },
50
- data () {
51
- return {
52
- messageList: [],
53
- submitting: false,
54
- summaryVisible: false,
55
- messageText: '',
56
- messageLoading: false
57
- }
58
- },
59
- mounted () {},
60
- computed: {
61
- ...mapState('account', ['user'])
62
- },
63
- methods: {
64
- format (date) {
65
- return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
66
- },
67
- onSubmit () {
68
- this.submitting = true
69
- this.submitMessage({
70
- f_created_by: this.user.name,
71
- f_content: this.messageText.trim()
72
- }).then(() => {
73
- this.submitting = false
74
- this.$message.success('留言成功')
75
- this.messageText = ''
76
- this.$emit('refresh')
77
- }).catch(() => {
78
- this.submitting = false
79
- this.$message.error('留言失败,请重试')
80
- })
81
- },
82
- // 获取留言
83
- getMessage () {
84
- this.messageLoading = true
85
- postByServiceName(workFlowViewApi.getWorkFlowLeaveMessage, {
86
- workflowId: this.workflowId
87
- }).then(res => {
88
- this.messageList = res
89
- this.messageLoading = false
90
- })
91
- },
92
- // 提交留言
93
- submitMessage (data) {
94
- data.f_workflow_id = this.workflowId
95
- return postByServiceName('/entity/save/t_workflow_leave_message', data)
96
- },
97
- }
98
- }
99
- </script>
100
-
101
- <style lang="less" scoped>
102
- .comment {
103
- /deep/ .ant-comment-content-author-name {
104
- font-size: 14px;
105
- color: #00000099;
106
- }
107
-
108
- /deep/ .ant-comment-content-author-time {
109
- font-size: 14px;
110
- color: #999;
111
- }
112
-
113
- /deep/ .ant-comment-content-detail {
114
- font-size: 16px;
115
- white-space: pre-wrap;
116
- }
117
- }
118
-
119
- .text-input {
120
- margin-bottom: 14px;
121
- }
122
- </style>
1
+ <template>
2
+ <div class="message-container">
3
+ <a-spin size="large" :spinning="messageLoading">
4
+ <!-- 留言输入区域 -->
5
+ <div class="message-input-area">
6
+ <div class="user-avatar">
7
+ <a-avatar :style="avatarStyle(user.name)">
8
+ {{ user.name.substr(0, 1) }}
9
+ </a-avatar>
10
+ <span class="user-name">{{ user.name }}</span>
11
+ </div>
12
+ <div class="input-wrapper">
13
+ <a-textarea
14
+ v-model="messageText"
15
+ placeholder="写下你的留言..."
16
+ class="text-input"
17
+ :autoSize="{ minRows: 3, maxRows: 6 }"
18
+ />
19
+ <div class="action-area">
20
+ <div></div> <!-- 占位,保持右对齐 -->
21
+ <a-button
22
+ type="primary"
23
+ :loading="submitting"
24
+ :disabled="messageText.trim() === ''"
25
+ @click="onSubmit"
26
+ class="submit-btn"
27
+ >
28
+ 发送
29
+ </a-button>
30
+ </div>
31
+ </div>
32
+ </div>
33
+
34
+ <!-- 留言列表分割线 -->
35
+ <div class="message-divider" v-if="messageList.length">
36
+ <span class="divider-text">全部留言</span>
37
+ </div>
38
+
39
+ <!-- 留言统计 -->
40
+ <div class="message-stats" v-if="messageList.length">
41
+ <span>共 {{ messageList.length }} 条留言</span>
42
+ </div>
43
+
44
+ <!-- 空状态 -->
45
+ <a-empty v-if="!messageList.length" description="暂无留言,发表第一条留言吧" />
46
+
47
+ <!-- 留言列表 -->
48
+ <div class="comment-list" v-else>
49
+ <div
50
+ v-for="message in sortedMessages"
51
+ :key="message.id"
52
+ class="comment-item"
53
+ >
54
+ <!-- 留言主体 -->
55
+ <div class="comment-main">
56
+ <div class="comment-avatar">
57
+ <a-avatar :style="commentAvatarStyle(message.f_created_by)">
58
+ {{ message.f_created_by.substr(0, 1) }}
59
+ </a-avatar>
60
+ </div>
61
+ <div class="comment-content">
62
+ <div class="comment-author">
63
+ <span class="author-name">{{ message.f_created_by }}</span>
64
+ <span class="author-badge" v-if="isCurrentUser(message.f_created_by)">我</span>
65
+ </div>
66
+ <div class="comment-text">{{ message.f_content }}</div>
67
+ <div class="comment-footer">
68
+ <span class="comment-time">{{ format(message.f_create_date) }}</span>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </div>
74
+
75
+ <!-- 加载更多 -->
76
+ <div class="load-more" v-if="messageList.length > 5">
77
+ <a-button type="link">查看更多留言</a-button>
78
+ </div>
79
+ </a-spin>
80
+ </div>
81
+ </template>
82
+
83
+ <script>
84
+ import { formatDate } from '@vue2-client/utils/util'
85
+ import { mapState } from 'vuex'
86
+ import { postByServiceName } from '@vue2-client/services/api/restTools'
87
+ import { workFlowViewApi } from '@vue2-client/services/api/workFlow'
88
+
89
+ export default {
90
+ name: 'LeaveMessage',
91
+ props: {
92
+ projectName: {
93
+ type: String,
94
+ required: true
95
+ },
96
+ workflowId: {
97
+ type: String,
98
+ required: true
99
+ },
100
+ },
101
+ data () {
102
+ return {
103
+ messageList: [],
104
+ submitting: false,
105
+ summaryVisible: false,
106
+ messageText: '',
107
+ messageLoading: false,
108
+ colorMap: {}
109
+ }
110
+ },
111
+ mounted () {
112
+ this.getMessage()
113
+ },
114
+ computed: {
115
+ ...mapState('account', ['user']),
116
+ // 对留言列表按创建时间倒序排序
117
+ sortedMessages () {
118
+ // 创建一个副本,避免直接修改原数组
119
+ return [...this.messageList].sort((a, b) => {
120
+ // 否则按ID倒序排序
121
+ return b.id - a.id
122
+ })
123
+ }
124
+ },
125
+ methods: {
126
+ format (date) {
127
+ return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
128
+ },
129
+ onSubmit () {
130
+ this.submitting = true
131
+ this.submitMessage({
132
+ f_created_by: this.user.name,
133
+ f_content: this.messageText.trim()
134
+ }).then(() => {
135
+ this.submitting = false
136
+ this.$message.success('留言成功')
137
+ this.messageText = ''
138
+ this.getMessage()
139
+ this.$emit('refresh')
140
+ }).catch(() => {
141
+ this.submitting = false
142
+ this.$message.error('留言失败,请重试')
143
+ })
144
+ },
145
+ // 获取留言
146
+ getMessage () {
147
+ this.messageLoading = true
148
+ postByServiceName(workFlowViewApi.getWorkFlowLeaveMessage, {
149
+ workflowId: this.workflowId
150
+ }).then(res => {
151
+ this.messageList = res
152
+ this.messageLoading = false
153
+ })
154
+ },
155
+ // 提交留言
156
+ submitMessage (data) {
157
+ data.f_workflow_id = this.workflowId
158
+ return postByServiceName('/entity/save/t_workflow_leave_message', data)
159
+ },
160
+ // 生成头像样式
161
+ avatarStyle (name) {
162
+ return {
163
+ background: this.getAvatarColor(name),
164
+ color: '#fff'
165
+ }
166
+ },
167
+ // 生成评论头像样式
168
+ commentAvatarStyle (name) {
169
+ return {
170
+ background: this.getAvatarColor(name),
171
+ color: '#fff',
172
+ fontSize: '16px',
173
+ display: 'flex',
174
+ alignItems: 'center',
175
+ justifyContent: 'center'
176
+ }
177
+ },
178
+ // 根据用户名生成固定的头像颜色
179
+ getAvatarColor (name) {
180
+ if (!name) return '#1890ff'
181
+
182
+ // 如果已经生成过这个用户的颜色,直接返回
183
+ if (this.colorMap[name]) {
184
+ return this.colorMap[name]
185
+ }
186
+
187
+ // 预定义一组好看的颜色
188
+ const colors = [
189
+ '#1890ff', '#52c41a', '#722ed1', '#fa8c16', '#eb2f96',
190
+ '#13c2c2', '#faad14', '#a0d911', '#fa541c', '#2f54eb'
191
+ ]
192
+
193
+ // 根据名字计算一个固定的索引
194
+ let hash = 0
195
+ for (let i = 0; i < name.length; i++) {
196
+ hash = name.charCodeAt(i) + ((hash << 5) - hash)
197
+ }
198
+
199
+ const index = Math.abs(hash) % colors.length
200
+ this.colorMap[name] = colors[index]
201
+ return colors[index]
202
+ },
203
+ // 判断是否是当前用户
204
+ isCurrentUser (name) {
205
+ return name === this.user.name
206
+ }
207
+ }
208
+ }
209
+ </script>
210
+
211
+ <style lang="less" scoped>
212
+ .message-container {
213
+ padding: 24px;
214
+ background: #fff;
215
+ border-radius: 8px;
216
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
217
+ }
218
+
219
+ // 留言统计
220
+ .message-stats {
221
+ margin-bottom: 20px;
222
+ color: #8c8c8c;
223
+ font-size: 14px;
224
+ }
225
+
226
+ // 留言输入区域
227
+ .message-input-area {
228
+ margin-bottom: 32px;
229
+ background: #f9fafb;
230
+ border-radius: 8px;
231
+ padding: 16px;
232
+
233
+ .user-avatar {
234
+ display: flex;
235
+ align-items: center;
236
+ margin-bottom: 12px;
237
+
238
+ .ant-avatar {
239
+ margin-right: 8px;
240
+ }
241
+
242
+ .user-name {
243
+ font-size: 14px;
244
+ font-weight: 500;
245
+ color: #262626;
246
+ }
247
+ }
248
+
249
+ .input-wrapper {
250
+ width: 100%;
251
+ }
252
+
253
+ .text-input {
254
+ margin-bottom: 12px;
255
+ border-radius: 4px;
256
+ resize: none;
257
+ background: #fff;
258
+
259
+ /deep/ .ant-input {
260
+ padding: 12px 16px;
261
+ font-size: 14px;
262
+ }
263
+ }
264
+
265
+ .action-area {
266
+ display: flex;
267
+ justify-content: space-between;
268
+ align-items: center;
269
+ }
270
+
271
+ .submit-btn {
272
+ padding: 0 16px;
273
+ border-radius: 4px;
274
+ font-size: 14px;
275
+ }
276
+ }
277
+
278
+ // 分割线
279
+ .message-divider {
280
+ position: relative;
281
+ text-align: center;
282
+ margin: 24px 0;
283
+
284
+ &::before {
285
+ content: '';
286
+ position: absolute;
287
+ top: 50%;
288
+ left: 0;
289
+ width: 100%;
290
+ height: 1px;
291
+ background: #f0f0f0;
292
+ z-index: 0;
293
+ }
294
+
295
+ .divider-text {
296
+ position: relative;
297
+ display: inline-block;
298
+ padding: 0 16px;
299
+ background: #fff;
300
+ font-size: 14px;
301
+ color: #8c8c8c;
302
+ z-index: 1;
303
+ }
304
+ }
305
+
306
+ // 留言列表
307
+ .comment-list {
308
+ .comment-item {
309
+ padding: 16px 0;
310
+ border-bottom: 1px solid #f0f0f0;
311
+
312
+ &:last-child {
313
+ border-bottom: none;
314
+ }
315
+ }
316
+
317
+ .comment-main {
318
+ display: flex;
319
+
320
+ .comment-avatar {
321
+ margin-right: 16px;
322
+ flex-shrink: 0;
323
+ }
324
+
325
+ .comment-content {
326
+ flex: 1;
327
+ overflow: hidden;
328
+
329
+ .comment-author {
330
+ margin-bottom: 8px;
331
+ display: flex;
332
+ align-items: center;
333
+
334
+ .author-name {
335
+ font-size: 15px;
336
+ font-weight: 600;
337
+ color: #262626;
338
+ }
339
+
340
+ .author-badge {
341
+ margin-left: 8px;
342
+ background: #e6f7ff;
343
+ color: #1890ff;
344
+ padding: 0 6px;
345
+ border-radius: 10px;
346
+ font-size: 12px;
347
+ line-height: 18px;
348
+ }
349
+ }
350
+
351
+ .comment-text {
352
+ font-size: 15px;
353
+ line-height: 1.6;
354
+ color: #333;
355
+ margin-bottom: 8px;
356
+ word-break: break-word;
357
+ }
358
+
359
+ .comment-footer {
360
+ display: flex;
361
+ justify-content: space-between;
362
+ align-items: center;
363
+ margin-bottom: 4px;
364
+
365
+ .comment-time {
366
+ font-size: 13px;
367
+ color: #8c8c8c;
368
+ }
369
+ }
370
+ }
371
+ }
372
+ }
373
+
374
+ // 加载更多
375
+ .load-more {
376
+ text-align: center;
377
+ margin-top: 16px;
378
+ }
379
+
380
+ // 空状态
381
+ /deep/ .ant-empty {
382
+ margin: 32px 0;
383
+
384
+ .ant-empty-description {
385
+ color: #8c8c8c;
386
+ }
387
+ }
388
+ </style>
@@ -2,7 +2,7 @@
2
2
  <div id="ApplyBaseInformation">
3
3
  <a-card :loading="loading" :bordered="false" class="info-card-container">
4
4
  <div class="info-cards-wrapper">
5
- <!-- 第一个 -->
5
+ <!-- 正在进行 -->
6
6
  <div class="info-card">
7
7
  <div class="info-icon" :class="details.f_state === 1 ? 'status-completed' : 'status-progress'">
8
8
  <a-icon type="appstore" theme="filled" />
@@ -27,18 +27,7 @@
27
27
  </div>
28
28
  </div>
29
29
 
30
- <!-- 第二个 -->
31
- <div class="info-card">
32
- <div class="info-icon date-icon">
33
- <a-icon type="carry-out" theme="filled" />
34
- </div>
35
- <div class="info-content">
36
- <div class="info-title">{{ format(details.f_workflow_date, 'yyyy-MM-dd') }}</div>
37
- <div class="info-label">创建日期</div>
38
- </div>
39
- </div>
40
-
41
- <!-- 第三个 -->
30
+ <!-- 流程信息 -->
42
31
  <div v-show="details.f_state !== 1" class="info-card">
43
32
  <div class="info-icon workflow-icon">
44
33
  <a-icon type="profile" theme="filled" />
@@ -49,7 +38,18 @@
49
38
  </div>
50
39
  </div>
51
40
 
52
- <!-- 第四个 -->
41
+ <!-- 创建日期 -->
42
+ <div class="info-card">
43
+ <div class="info-icon date-icon">
44
+ <a-icon type="carry-out" theme="filled" />
45
+ </div>
46
+ <div class="info-content">
47
+ <div class="info-title">{{ format(details.f_workflow_date, 'yyyy-MM-dd') }}</div>
48
+ <div class="info-label">创建日期</div>
49
+ </div>
50
+ </div>
51
+
52
+ <!-- 截止时间 -->
53
53
  <div class="info-card" title="若要修改完成时间,请通知部门领导进行修改!">
54
54
  <div class="info-icon time-icon">
55
55
  <a-icon type="clock-circle" theme="filled" />
@@ -99,7 +99,7 @@
99
99
  <a-icon type="edit" theme="filled" class="edit-icon" />
100
100
  </a-popover>
101
101
  </div>
102
- <div class="info-label">完成时间</div>
102
+ <div class="info-label">截止时间</div>
103
103
  </div>
104
104
  </div>
105
105
 
@@ -202,7 +202,6 @@ export default {
202
202
  methods: {
203
203
  init () {
204
204
  this.loading = this.details.f_entry_name === undefined
205
- console.log(this.currUser)
206
205
  // this.isCreatedBy = this.currUser.roles.includes('14524271')
207
206
  this.completeTime = undefined
208
207
  this.overdueTime = undefined
@@ -258,20 +257,6 @@ export default {
258
257
  if (newVal) {
259
258
  this.init()
260
259
  }
261
- },
262
- details: {
263
- deep: true,
264
- handler (newVal) {
265
- if (newVal.person) {
266
- // 删除值为空的键
267
- for (const key in newVal.person) {
268
- if (!newVal.person[key]) {
269
- delete newVal.person[key]
270
- }
271
- }
272
- }
273
- this.init()
274
- }
275
260
  }
276
261
  }
277
262
  }