wl-design-mobile 0.8.2 → 0.8.4

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 (41) hide show
  1. package/doc/file/compoents/lambo-file-row.vue +5 -92
  2. package/doc/file-type/file-type.js +286 -0
  3. package/doc/file-type/icons/icon-file-ai.svg +1 -0
  4. package/doc/file-type/icons/icon-file-avi.svg +1 -0
  5. package/doc/file-type/icons/icon-file-default.svg +1 -0
  6. package/doc/file-type/icons/icon-file-epub.svg +1 -0
  7. package/doc/file-type/icons/icon-file-excel.svg +1 -0
  8. package/doc/file-type/icons/icon-file-flv.svg +1 -0
  9. package/doc/file-type/icons/icon-file-gif.svg +1 -0
  10. package/doc/file-type/icons/icon-file-html.svg +1 -0
  11. package/doc/file-type/icons/icon-file-java.svg +1 -0
  12. package/doc/file-type/icons/icon-file-js.svg +1 -0
  13. package/doc/file-type/icons/icon-file-jsp.svg +1 -0
  14. package/doc/file-type/icons/icon-file-mp3.svg +1 -0
  15. package/doc/file-type/icons/icon-file-msi.svg +1 -0
  16. package/doc/file-type/icons/icon-file-pdf.svg +1 -0
  17. package/doc/file-type/icons/icon-file-png.svg +1 -0
  18. package/doc/file-type/icons/icon-file-ppt.svg +1 -0
  19. package/doc/file-type/icons/icon-file-psd.svg +1 -0
  20. package/doc/file-type/icons/icon-file-rar.svg +1 -0
  21. package/doc/file-type/icons/icon-file-raw.svg +1 -0
  22. package/doc/file-type/icons/icon-file-txt.svg +1 -0
  23. package/doc/file-type/icons/icon-file-word.svg +1 -0
  24. package/doc/img/comonents/lambo-img-grid.vue +6 -1
  25. package/flow/approval/flow-approval.vue +550 -0
  26. package/flow/comps/flow-attachment-list.vue +230 -0
  27. package/flow/comps/flow-attachment-modal.vue +132 -0
  28. package/flow/comps/flow-copy-users.vue +358 -0
  29. package/flow/comps/flow-node-card.vue +150 -0
  30. package/flow/comps/flow-node-header.vue +172 -0
  31. package/flow/comps/flow-util.js +156 -0
  32. package/flow/comps/icons/approved.svg +11 -0
  33. package/flow/comps/icons/canceled.svg +11 -0
  34. package/flow/comps/icons/rejected.svg +11 -0
  35. package/flow/comps/icons/underway.svg +11 -0
  36. package/flow/detail/flow-detail.vue +466 -0
  37. package/flow/index.js +51 -0
  38. package/flow/lambo-flow-detail.vue +894 -12
  39. package/flow/lambo-flow-edit.vue +6 -21
  40. package/flow/submit/flow-submit.vue +381 -0
  41. package/package.json +1 -1
@@ -1,30 +1,15 @@
1
1
  <template>
2
- <div>
3
-
4
- </div>
2
+ <FlowSubmit v-bind="$attrs" v-on="$listeners" />
5
3
  </template>
4
+
6
5
  <script>
6
+ import FlowSubmit from './submit/flow-submit.vue'
7
7
 
8
8
  export default {
9
9
  name: 'LamboFlowEdit',
10
- components: {},
11
- props: {},
12
- data() {
13
- return {
14
-
15
- }
16
- },
17
- methods: {
18
-
19
- },
20
- created() {
21
-
10
+ components: {
11
+ FlowSubmit
22
12
  },
23
- mounted() {
24
-
25
- }
13
+ inheritAttrs: false
26
14
  }
27
15
  </script>
28
- <style scoped>
29
- @import "../styles/index.less";
30
- </style>
@@ -0,0 +1,381 @@
1
+ <template>
2
+ <div class="flow-submit-container">
3
+ <!-- 流程头部信息 -->
4
+ <div class="flow-header" v-if="showHeader">
5
+ <div class="flow-title">
6
+ <span class="flow-name">{{ flowInfo.flowName || '审批流程提交' }}</span>
7
+ </div>
8
+ <FlowCopyUsers
9
+ :copy-users="copyUsers"
10
+ :available-users="availableCopyUsers"
11
+ :editable="copyUsersEditable"
12
+ @change="handleCopyUsersChange"
13
+ />
14
+ </div>
15
+
16
+ <!-- 流程节点时间线 -->
17
+ <div class="flow-timeline">
18
+ <div v-for="(item, index) in sortedFlowNodes" :key="index" class="timeline-item">
19
+ <!-- 左侧时间线 -->
20
+ <div class="timeline-col">
21
+ <div class="timeline-dot" :class="'dot-' + getStatusClass(item.status)">
22
+ <van-icon :name="getStatusIcon(item.status)" size="14"></van-icon>
23
+ </div>
24
+ <div class="timeline-line" v-if="index !== sortedFlowNodes.length - 1"></div>
25
+ </div>
26
+
27
+ <!-- 右侧内容 -->
28
+ <div class="content-col">
29
+ <!-- 节点头部信息 -->
30
+ <FlowNodeHeader
31
+ :node-info="item"
32
+ :node-index="index"
33
+ />
34
+
35
+ <!-- 第一个节点:申请描述输入 + 附件上传 -->
36
+ <div v-if="index === 0" class="submit-card">
37
+ <div class="submit-label">申请描述</div>
38
+ <van-field
39
+ v-model="applyDescription"
40
+ type="textarea"
41
+ :rows="4"
42
+ placeholder="请输入申请描述..."
43
+ />
44
+
45
+ <!-- 附件上传 -->
46
+ <FlowAttachmentList
47
+ :attachments="attachments"
48
+ :show-title="true"
49
+ :editable="true"
50
+ @click="handleAttachmentClick"
51
+ @upload-success="handleUploadSuccess"
52
+ @remove="removeAttachment"
53
+ />
54
+
55
+ <div class="submit-actions">
56
+ <van-button type="primary" @click="handleSubmit" :loading="submitting" block>
57
+ 提交审批
58
+ </van-button>
59
+ </div>
60
+ </div>
61
+
62
+ <!-- 其他节点:显示待审批提示 -->
63
+ <div v-else class="pending-tip">
64
+ <van-icon name="clock-o" size="14" color="#ff976a"></van-icon>
65
+ <span>等待审批中...</span>
66
+ </div>
67
+ </div>
68
+ </div>
69
+
70
+ <!-- 空状态 -->
71
+ <div v-if="sortedFlowNodes.length === 0" class="flow-empty">
72
+ <van-icon name="info-o" size="48" color="#ccc"></van-icon>
73
+ <p>暂无流程节点信息</p>
74
+ </div>
75
+ </div>
76
+
77
+ <!-- 附件预览弹窗 -->
78
+ <FlowAttachmentModal
79
+ :visible.sync="previewModalVisible"
80
+ :file-url="previewFileUrl"
81
+ :file-name="previewFileName"
82
+ :modal-width="previewModalWidth"
83
+ />
84
+ </div>
85
+ </template>
86
+
87
+ <script>
88
+ import FlowNodeHeader from '../comps/flow-node-header.vue'
89
+ import FlowAttachmentList from '../comps/flow-attachment-list.vue'
90
+ import FlowAttachmentModal from '../comps/flow-attachment-modal.vue'
91
+ import FlowCopyUsers from '../comps/flow-copy-users.vue'
92
+ import { fileGetUrl } from '../../api/doc'
93
+ import {
94
+ getStatusIcon,
95
+ getStatusClass
96
+ } from '../comps/flow-util.js'
97
+
98
+ export default {
99
+ name: 'FlowSubmit',
100
+ components: {
101
+ FlowNodeHeader,
102
+ FlowAttachmentList,
103
+ FlowAttachmentModal,
104
+ FlowCopyUsers
105
+ },
106
+ props: {
107
+ /**
108
+ * 流程基本信息
109
+ * @property {string} flowName - 流程名称
110
+ */
111
+ flowInfo: {
112
+ type: Object,
113
+ default: () => ({})
114
+ },
115
+ /**
116
+ * 流程节点数组
117
+ * @property {number} seq - 节点序号
118
+ * @property {string} taskName - 节点任务名称
119
+ * @property {string} auditUserName - 审批人姓名
120
+ * @property {string} auditUserAvatar - 审批人头像
121
+ * @property {string} status - 节点状态
122
+ */
123
+ flowNodes: {
124
+ type: Array,
125
+ default: () => []
126
+ },
127
+ /**
128
+ * 是否显示头部区域
129
+ * @default true
130
+ */
131
+ showHeader: {
132
+ type: Boolean,
133
+ default: true
134
+ },
135
+ initAttachments: {
136
+ type: Array,
137
+ default: () => []
138
+ },
139
+ copyUsersEditable: {
140
+ type: Boolean,
141
+ default: true
142
+ },
143
+ /**
144
+ * 抄送人列表
145
+ * @property {string} id - 抄送人ID
146
+ * @property {string} name - 抄送人姓名
147
+ * @property {string} avatar - 抄送人头像地址
148
+ */
149
+ copyUsers: {
150
+ type: Array,
151
+ default: () => []
152
+ },
153
+ /**
154
+ * 可选抄送人列表
155
+ */
156
+ availableCopyUsers: {
157
+ type: Array,
158
+ default: () => [
159
+ { id: '1', name: '张三' },
160
+ { id: '2', name: '李四' },
161
+ { id: '3', name: '王五' },
162
+ { id: '4', name: '赵六' },
163
+ { id: '5', name: '钱七' },
164
+ { id: '6', name: '孙八' }
165
+ ]
166
+ }
167
+ },
168
+ data() {
169
+ return {
170
+ applyDescription: '',
171
+ submitting: false,
172
+ attachments: [...this.initAttachments],
173
+ previewModalVisible: false,
174
+ previewFileUrl: '',
175
+ previewFileName: '',
176
+ previewModalWidth: '320px'
177
+ }
178
+ },
179
+ computed: {
180
+ sortedFlowNodes() {
181
+ return [...this.flowNodes].sort((a, b) => (a.seq || 0) - (b.seq || 0))
182
+ }
183
+ },
184
+ watch: {
185
+ initAttachments: {
186
+ deep: true,
187
+ handler(val) {
188
+ this.attachments = [...val]
189
+ }
190
+ }
191
+ },
192
+ methods: {
193
+ getStatusIcon,
194
+ getStatusClass,
195
+ handleCopyUsersChange(users) {
196
+ this.$emit('update:copyUsers', users)
197
+ },
198
+ handleUploadSuccess(fileData) {
199
+ this.attachments.push(fileData)
200
+ },
201
+ removeAttachment(index) {
202
+ this.attachments.splice(index, 1)
203
+ },
204
+ handleAttachmentClick(file) {
205
+ if (!file || !file.fileName) return
206
+ const previewUrl = file.fileUrl || (file.fileId ? fileGetUrl + file.fileId : '')
207
+ if (!previewUrl) return
208
+ this.previewFileUrl = previewUrl
209
+ this.previewFileName = file.fileName
210
+ this.previewModalVisible = true
211
+ },
212
+ handleSubmit() {
213
+ if (!this.applyDescription.trim()) {
214
+ this.$toast({ message: '请输入申请描述', position: 'middle' })
215
+ return
216
+ }
217
+ this.submitting = true
218
+ this.$emit('submit', {
219
+ applyDescription: this.applyDescription,
220
+ flowInfo: this.flowInfo,
221
+ flowNodes: this.sortedFlowNodes,
222
+ copyUsers: this.copyUsers,
223
+ attachments: this.attachments
224
+ })
225
+ this.submitting = false
226
+ }
227
+ }
228
+ }
229
+ </script>
230
+
231
+ <style scoped>
232
+ .flow-submit-container {
233
+ border-radius: 4px;
234
+ padding: 16px;
235
+ background: #fff;
236
+ }
237
+
238
+ .flow-header {
239
+ border-bottom: 1px solid #f0f0f0;
240
+ margin-bottom: 16px;
241
+ padding-bottom: 12px;
242
+ }
243
+
244
+ .flow-title {
245
+ margin-bottom: 8px;
246
+ }
247
+
248
+ .flow-name {
249
+ font-size: 16px;
250
+ font-weight: 600;
251
+ color: #262626;
252
+ }
253
+
254
+ .flow-timeline {
255
+ position: relative;
256
+ }
257
+
258
+ .timeline-item {
259
+ display: flex;
260
+ margin-bottom: 16px;
261
+ }
262
+
263
+ .timeline-item:last-child {
264
+ margin-bottom: 0;
265
+ }
266
+
267
+ .timeline-col {
268
+ display: flex;
269
+ flex-direction: column;
270
+ align-items: center;
271
+ margin-right: 12px;
272
+ width: 28px;
273
+ flex-shrink: 0;
274
+ }
275
+
276
+ .timeline-dot {
277
+ width: 28px;
278
+ height: 28px;
279
+ border-radius: 50%;
280
+ display: flex;
281
+ align-items: center;
282
+ justify-content: center;
283
+ background: #f0f0f0;
284
+ color: #999;
285
+ border: 2px solid #fff;
286
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
287
+ z-index: 2;
288
+ }
289
+
290
+ .timeline-dot.dot-success {
291
+ background: #07c160;
292
+ color: #fff;
293
+ }
294
+
295
+ .timeline-dot.dot-process {
296
+ background: #1989fa;
297
+ color: #fff;
298
+ animation: pulse 2s infinite;
299
+ }
300
+
301
+ .timeline-dot.dot-error {
302
+ background: #ee0a24;
303
+ color: #fff;
304
+ }
305
+
306
+ .timeline-dot.dot-warning {
307
+ background: #ff976a;
308
+ color: #fff;
309
+ }
310
+
311
+ .timeline-dot.dot-wait {
312
+ background: #f0f0f0;
313
+ color: #999;
314
+ }
315
+
316
+ @keyframes pulse {
317
+ 0%,
318
+ 100% {
319
+ box-shadow: 0 0 0 0 rgba(25, 137, 250, 0.4);
320
+ }
321
+ 50% {
322
+ box-shadow: 0 0 0 8px rgba(25, 137, 250, 0);
323
+ }
324
+ }
325
+
326
+ .timeline-line {
327
+ width: 2px;
328
+ flex: 1;
329
+ min-height: 24px;
330
+ background: #e8e8e8;
331
+ margin-top: 4px;
332
+ }
333
+
334
+ .content-col {
335
+ flex: 1;
336
+ min-width: 0;
337
+ }
338
+
339
+ .submit-card {
340
+ border-radius: 4px;
341
+ padding: 12px;
342
+ border: 1px solid #e8e8e8;
343
+ }
344
+
345
+ .submit-label {
346
+ font-size: 13px;
347
+ font-weight: 500;
348
+ color: #595959;
349
+ margin-bottom: 8px;
350
+ }
351
+
352
+ .submit-actions {
353
+ margin-top: 16px;
354
+ }
355
+
356
+ .pending-tip {
357
+ display: flex;
358
+ align-items: center;
359
+ gap: 6px;
360
+ padding: 8px 12px;
361
+ background: #fff7e8;
362
+ border: 1px solid #ffd9b3;
363
+ border-radius: 4px;
364
+ font-size: 13px;
365
+ color: #ff976a;
366
+ }
367
+
368
+ .flow-empty {
369
+ display: flex;
370
+ flex-direction: column;
371
+ align-items: center;
372
+ justify-content: center;
373
+ padding: 60px 20px;
374
+ color: #999;
375
+ }
376
+
377
+ .flow-empty p {
378
+ margin: 12px 0 0 0;
379
+ font-size: 14px;
380
+ }
381
+ </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wl-design-mobile",
3
- "version": "0.8.2",
3
+ "version": "0.8.4",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "author": "finch",