doway-coms 2.2.21 → 2.2.23

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 (73) hide show
  1. package/.browserslistrc +2 -2
  2. package/README.md +28 -28
  3. package/package.json +53 -53
  4. package/packages/AuditsList/index.js +7 -7
  5. package/packages/AuditsList/src/index.vue +262 -262
  6. package/packages/BaseButton/index.js +7 -7
  7. package/packages/BaseButton/src/index.vue +241 -241
  8. package/packages/BaseCheckbox/index.js +7 -7
  9. package/packages/BaseCheckbox/src/index.vue +134 -134
  10. package/packages/BaseDate/index.js +7 -7
  11. package/packages/BaseDate/src/index.vue +197 -197
  12. package/packages/BaseDateWeek/index.js +7 -7
  13. package/packages/BaseDateWeek/src/index.vue +163 -163
  14. package/packages/BaseDatetime/index.js +7 -7
  15. package/packages/BaseDatetime/src/index.vue +196 -196
  16. package/packages/BaseForm/index.js +7 -7
  17. package/packages/BaseForm/src/index.vue +729 -728
  18. package/packages/BaseGantt/index.js +9 -9
  19. package/packages/BaseGantt/src/index.vue +608 -608
  20. package/packages/BaseGrid/index.js +9 -9
  21. package/packages/BaseGrid/src/SeqSetting.vue +278 -278
  22. package/packages/BaseGrid/src/index.vue +3580 -3580
  23. package/packages/BaseGridAdjust/index.js +9 -9
  24. package/packages/BaseGridAdjust/src/index.vue +482 -482
  25. package/packages/BaseInput/index.js +7 -7
  26. package/packages/BaseInput/src/index.vue +164 -164
  27. package/packages/BaseIntervalInput/index.js +7 -7
  28. package/packages/BaseIntervalInput/src/index.vue +310 -310
  29. package/packages/BaseKanbanEmpty/index.js +7 -7
  30. package/packages/BaseKanbanEmpty/src/index.vue +176 -176
  31. package/packages/BaseNumberInput/index.js +7 -7
  32. package/packages/BaseNumberInput/src/index.vue +291 -293
  33. package/packages/BasePagination/index.js +7 -7
  34. package/packages/BasePagination/src/index.vue +91 -91
  35. package/packages/BasePictureCard/index.js +7 -7
  36. package/packages/BasePictureCard/src/index.vue +580 -580
  37. package/packages/BasePrintPreview/index.js +7 -7
  38. package/packages/BasePrintPreview/src/index.vue +129 -129
  39. package/packages/BasePulldown/index.js +7 -7
  40. package/packages/BasePulldown/src/index.vue +1265 -1265
  41. package/packages/BaseSearch/index.js +7 -7
  42. package/packages/BaseSearch/src/index.vue +935 -935
  43. package/packages/BaseSelect/index.js +7 -7
  44. package/packages/BaseSelect/src/index.vue +155 -155
  45. package/packages/BaseSelectMulti/index.js +7 -7
  46. package/packages/BaseSelectMulti/src/index.vue +148 -148
  47. package/packages/BaseTextArea/index.js +7 -7
  48. package/packages/BaseTextArea/src/index.vue +178 -178
  49. package/packages/BaseTime/index.js +7 -7
  50. package/packages/BaseTime/src/index.vue +166 -166
  51. package/packages/BaseTool/index.js +7 -7
  52. package/packages/BaseTool/src/index.vue +349 -349
  53. package/packages/BaseToolStatus/index.js +7 -7
  54. package/packages/BaseToolStatus/src/index.vue +388 -388
  55. package/packages/BaseTreeSelect/index.js +8 -8
  56. package/packages/BaseTreeSelect/src/index.vue +437 -437
  57. package/packages/LeaveAMessage/index.js +7 -7
  58. package/packages/LeaveAMessage/src/index.vue +597 -597
  59. package/packages/index.js +191 -191
  60. package/packages/styles/default.css +78 -78
  61. package/packages/styles/default.less +84 -84
  62. package/packages/utils/api.js +107 -107
  63. package/packages/utils/auth.js +38 -38
  64. package/packages/utils/common.js +610 -610
  65. package/packages/utils/dom.js +181 -181
  66. package/packages/utils/enum.js +86 -86
  67. package/packages/utils/filters.js +472 -472
  68. package/packages/utils/gridFormat.js +66 -66
  69. package/packages/utils/msg.js +84 -84
  70. package/packages/utils/patchFiles.js +44 -44
  71. package/packages/utils/request.js +178 -178
  72. package/packages/utils/store.js +303 -305
  73. package/vue.config.js +59 -59
@@ -1,598 +1,598 @@
1
- <template>
2
- <div>
3
- <div class="odoo" @click="showOdoo = !showOdoo">
4
- <a-icon type="snippets" style="font-size: 30px; color: #fff" />
5
- </div>
6
- <vxe-modal
7
- v-model="showOdoo"
8
- :zIndex="1000"
9
- :showHeader="false"
10
- :mask="false"
11
- :mask-closable="true"
12
- :position="{
13
- left: '72%',
14
- top: '15%'
15
- }"
16
- destroy-on-close
17
- >
18
- <div class="liu-yan" style="background-color: #eaeef1">
19
- <div class="input-box">
20
- <a-tabs default-active-key="msg" @change="tabChange">
21
- <a-tab-pane key="msg" tab="发送消息">
22
- <!-- <div style="display:flex">
23
- <div
24
- style="display:flex;justify-content: center;align-items: center;margin-bottom:5px;margin-left:5px;flex:1"
25
- >
26
- <div style="flex:1">发送给:</div>
27
- <a-select
28
- v-model:value="sendUser"
29
- show-search
30
- mode="multiple"
31
- style="width: 85%;flex:3"
32
- :options="userList"
33
- size="small"
34
- :filter-option="selectPinYin"
35
- ></a-select>
36
- </div>
37
- </div>
38
- <a-textarea placeholder="写些什么..." v-model:value="remark" />-->
39
-
40
- <a-mentions
41
- placeholder="写些什么..."
42
- split=";"
43
- v-model:value="remark"
44
- rows="3"
45
- >
46
- <a-mentions-option
47
- v-for="(item, index) in userList"
48
- :key="index"
49
- :value="item.value"
50
- >{{ item.label }}</a-mentions-option>
51
- </a-mentions>
52
- <!-- <a-upload
53
- list-type="picture"
54
- :headers="uploadHeaders"
55
- :action="uploadData.picAction"
56
- :data="uploadData"
57
- :before-upload="beforeAvatarUpload"
58
- @change="handleAvatarSuccess"
59
- :file-list="fileList"
60
- style="padding-top: 10px"
61
- >
62
- <a-icon style="font-size: 16px; cursor: pointer; margin: 5px 10px" type="paper-clip" />
63
- </a-upload>-->
64
- <div style="display: flex; justify-content: flex-end;margin-top:5px">
65
- <a-button @click="sendMsg" :disabled="remark ===''">发送</a-button>
66
- </div>
67
- </a-tab-pane>
68
- <a-tab-pane key="remark" tab="记录备注">
69
- <a-textarea placeholder="写些什么..." v-model:value="remark" />
70
- <a-upload
71
- list-type="picture"
72
- :headers="uploadHeaders"
73
- :action="uploadData.picAction"
74
- :data="uploadData"
75
- :before-upload="beforeAvatarUpload"
76
- @change="handleAvatarSuccess"
77
- :file-list="fileList"
78
- style="padding-top: 10px"
79
- >
80
- <a-icon
81
- style="font-size: 16px; cursor: pointer; margin: 5px 10px"
82
- type="paper-clip"
83
- />
84
- </a-upload>
85
- <div style="display: flex; justify-content: flex-end">
86
- <a-button @click="addMsgRemark" :disabled="remark ===''">记录</a-button>
87
- </div>
88
- </a-tab-pane>
89
- </a-tabs>
90
- </div>
91
- <div class="list" :style="{ height: moduleHeight - 215 + 'px' }">
92
- <a-list
93
- v-if="remarkData.length > 0"
94
- item-layout="horizontal"
95
- :data-source="remarkData"
96
- style="box-shadow: 3px 3px 6px #cad1d7"
97
- >
98
- <a-list-item
99
- slot="renderItem"
100
- slot-scope="item"
101
- :style="{
102
- borderBottom: item.type === 'date' ? '0' : '1px solid #ddd',
103
- backgroundColor: item.type === 'date' ? '#fff' : '#fff',
104
- }"
105
- >
106
- <template v-if="item.type !== 'date'">
107
- <a-popconfirm
108
- placement="topRight"
109
- title="确认删除当前备注吗?"
110
- ok-text="确认"
111
- cancel-text="取消"
112
- @confirm="delMsgRemark(item)"
113
- >
114
- <div v-show="userId === item.createUserId" class="close-icon">
115
- <a-icon type="close" />
116
- </div>
117
- </a-popconfirm>
118
- <a-comment :author="item.createUserName" :avatar="item.avatar">
119
- <!-- <template slot="actions">
120
- <span v-for="(action,index) in item.actions" :key="index">{{ action }}</span>
121
- </template>-->
122
- <template slot="content">
123
- <template v-if="item.receiver!==null">
124
- <div style="display:flex;flex-wrap: wrap;">
125
- <div
126
- v-for="(item,index) in item.atUser"
127
- :key="index"
128
- style="background-color:#eee;margin-right:3px"
129
- >@{{item}}</div>
130
- </div>
131
- </template>
132
- <div style="margin-bottom: 5px">{{ item.body }}</div>
133
- <div
134
- v-if="item.objectCommentAttachDtos.length > 0"
135
- style="display: flex; flex-wrap: wrap"
136
- >
137
- <div
138
- v-for="(item, index) in item.objectCommentAttachDtos"
139
- :key="index"
140
- class="msg-content"
141
- @click="downloadFile(item)"
142
- >
143
- <div class="download-icon">
144
- <a-icon type="vertical-align-bottom" style="font-size: 30px" />
145
- </div>
146
- <a-icon type="file-text" style="font-size: 25px; margin-right: 5px" />
147
- <span class="file-title">{{ item.attachName }}</span>
148
- </div>
149
- </div>
150
- </template>
151
- <a-tooltip slot="datetime" :title="item.createTime">
152
- <span>{{ item.fromNowTime }}</span>
153
- </a-tooltip>
154
- </a-comment>
155
- </template>
156
- <template v-else>
157
- <a-divider>{{ item.createTime }}</a-divider>
158
- </template>
159
- </a-list-item>
160
- </a-list>
161
- <div v-else></div>
162
- </div>
163
- </div>
164
- </vxe-modal>
165
- </div>
166
- </template>
167
-
168
- <script>
169
- import moment from "moment";
170
- import { notification } from "ant-design-vue";
171
- import {
172
- attachGetAttachUrlApi,
173
- readObjectCommentApi,
174
- searchObjectCommentApi,
175
- addObjectCommentApi,
176
- deleteObjectCommentApi,
177
- sendMsgApi,
178
- userInfoSearchApi
179
- } from "../../utils/api";
180
- export default {
181
- name: "LeaveAMessage",
182
- props: {
183
- topic: {
184
- type: String
185
- },
186
- moduleHeight: {
187
- type: Number
188
- },
189
- limitSize: {
190
- // 限制上传大小
191
- type: Number,
192
- default: 5
193
- },
194
- limitType: {
195
- // 限制上传类型
196
- type: Array,
197
- default: () => {
198
- return [];
199
- }
200
- },
201
- resId: {
202
- type: String
203
- },
204
- picType: {
205
- type: String,
206
- default: "cust"
207
- },
208
- dataName: {
209
- type: String
210
- }
211
- // formRow: {
212
- // type: Object,
213
- // default: () => {
214
- // return {};
215
- // },
216
- // },
217
- },
218
- watch: {
219
- resId: {
220
- handler: function(newVal) {
221
- this.uploadData.resId = newVal;
222
- }
223
- },
224
- showOdoo(newVal, oldVal) {
225
- if (newVal) {
226
- this.getUserInfo();
227
- this.getMsgRemarkData();
228
- }
229
- },
230
- immediate: true
231
- },
232
- created() {
233
- let viewDatas = this.$store.getters.moduleViewInfo[
234
- this.$route.meta.moduleCode
235
- ];
236
- this.objectName = viewDatas.objectName;
237
- this.userId = this.$store.getters.userId;
238
- },
239
- mounted() {
240
- this.uploadHeaders.Authorization = `Bearer ${this.$store.getters.token}`;
241
- this.uploadData.picType = this.picType;
242
- this.uploadData.resId = this.resId;
243
- this.internalServiceUrl = attachGetAttachUrlApi();
244
- this.uploadData.picAction = this.internalServiceUrl + "/UploadAttach";
245
- },
246
- data() {
247
- return {
248
- showOdoo: false,
249
- userId: null,
250
- fileList: [],
251
- remarkData: [],
252
- uploadData: {
253
- picType: "",
254
- picAction: "",
255
- resId: ""
256
- },
257
- uploadHeaders: {
258
- Authorization: null
259
- },
260
- sendUser: [],
261
- userList: [],
262
- remark: "",
263
- attachment: [],
264
- objectName: ""
265
- };
266
- },
267
- methods: {
268
- beforeAvatarUpload(file) {
269
- // const isPic = file.type === 'image/jpeg' || file.type === 'image/png'
270
- if (file.size / 1024 / 1024 > this.limitSize) {
271
- notification.error({
272
- message: "错误",
273
- description: "上传图片大小不能超过 " + this.limitSize + "MB!"
274
- });
275
- }
276
- if (this.limitType.length > 0 && !this.limitType[file.type]) {
277
- notification.error({
278
- message: "错误",
279
- description: "上传附件格式错误!"
280
- });
281
- }
282
- return true;
283
- },
284
- handleAvatarSuccess(info) {
285
- this.fileList = info.fileList;
286
- if (info.file.status == "done") {
287
- this.attachment.push(info.file.response.content.id);
288
- // this.$emit("add", this.dataName, info.file.response.content);
289
- }
290
- },
291
- getMsgRemarkData() {
292
- let postData = {
293
- begin: 1,
294
- size: 0,
295
- expression: {
296
- expressions: [
297
- {
298
- field: "objectName",
299
- operator: "EQ",
300
- value: this.objectName
301
- },
302
- {
303
- field: "resId",
304
- operator: "EQ",
305
- value: this.resId
306
- }
307
- ],
308
- operator: "and"
309
- },
310
- sorts: [["createTime", "desc"]]
311
- };
312
- searchObjectCommentApi(postData).then(res => {
313
- let tmp = [];
314
- res.content.forEach(item => {
315
- if (item.receiver !== null) {
316
- item["atUser"] = [];
317
- let atUser = item.receiver.split(",");
318
- this.userList.forEach(uitem => {
319
- if (atUser.indexOf(uitem.code) > -1) {
320
- item.atUser.push(uitem.label);
321
- }
322
- });
323
- }
324
-
325
- let flag = tmp.findIndex(titem => {
326
- return (
327
- titem.createTime ===
328
- moment(item.createTime).format("YYYY年MM月DD")
329
- );
330
- });
331
- if (flag < 0) {
332
- tmp.push({
333
- type: "date",
334
- createTime: moment(item.createTime).format("YYYY年MM月DD")
335
- });
336
- }
337
- item["avatar"] =
338
- "https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png";
339
- item["fromNowTime"] = moment(item.createTime).fromNow();
340
- tmp.push(item);
341
- });
342
- this.remarkData = tmp;
343
- });
344
- },
345
- downloadFile(val) {
346
- window.open(
347
- this.internalServiceUrl +
348
- "/DownAttachFile/" +
349
- val.msgAttachId +
350
- `?accessToken=${this.$store.getters.token}`
351
- );
352
- },
353
- addMsgRemark() {
354
- if (this.remark === "" && this.attachment.length < 1) {
355
- return;
356
- } else {
357
- let postData = {
358
- resId: this.resId,
359
- objectName: this.objectName,
360
- body: this.remark,
361
- objectCommentAttachIds: this.attachment
362
- };
363
- addObjectCommentApi(postData).then(res => {
364
- this.remark = "";
365
- this.attachment = [];
366
- this.fileList = [];
367
- this.getMsgRemarkData();
368
- });
369
- }
370
- },
371
- delMsgRemark(val) {
372
- deleteObjectCommentApi({
373
- keyIds: [val.id]
374
- }).then(res => {
375
- this.getMsgRemarkData();
376
- });
377
- },
378
- getUserInfo() {
379
- userInfoSearchApi().then(res => {
380
- this.userList = [];
381
- res.content.forEach(item => {
382
- this.userList.push({
383
- value: item.userName,
384
- label: item.name,
385
- code: item.id
386
- });
387
- });
388
- });
389
- },
390
- sendMsg() {
391
- let reg = /@(.*?);/;
392
- let result;
393
- let arr = [];
394
- while ((result = reg.exec(this.remark))) {
395
- arr.push(result[1]);
396
- this.remark = this.remark.replace(/@(.*?);/, "");
397
- }
398
-
399
- let receiver = [];
400
- arr.forEach(item => {
401
- this.userList.forEach(uitem => {
402
- if (uitem.value === item) {
403
- receiver.push(uitem.code);
404
- }
405
- });
406
- });
407
- receiver = receiver.join(",");
408
- let postData = {
409
- content: this.remark,
410
- receiver: receiver,
411
- subject: this.topic,
412
- objectName: this.objectName,
413
- resId: this.resId
414
- };
415
- sendMsgApi(postData).then(res => {
416
- this.remark = "";
417
- this.sendUser = [];
418
- this.getMsgRemarkData();
419
- });
420
- },
421
- selectPinYin(input, option) {
422
- if (input.charCodeAt() >= 32 && input.charCodeAt() <= 126) {
423
- return (
424
- option.componentOptions.children[0].text
425
- .toLowerCase()
426
- .indexOf(input.toLowerCase()) >= 0
427
- );
428
- } else {
429
- return (
430
- option.componentOptions.children[0].text
431
- .toLowerCase()
432
- .indexOf(input.toLowerCase()) >= 0
433
- );
434
- }
435
- },
436
- tabChange(activeKey) {
437
- this.remark = "";
438
- }
439
- }
440
- };
441
- </script>
442
-
443
- <style lang="less" scoped>
444
- ::v-deep(.ant-upload-list-picture .ant-upload-list-item) {
445
- max-width: 185px;
446
- min-width: 185px;
447
- margin-right: 10px;
448
- }
449
- ::v-deep(.ant-upload-list-picture .ant-upload-list-item-name) {
450
- padding-right: 24px !important;
451
- }
452
- ::v-deep(.ant-upload-list) {
453
- display: flex;
454
- overflow-x: auto;
455
- margin-bottom: 10px;
456
- // flex-wrap: wrap;
457
- }
458
- ::v-deep(.ant-upload-list::-webkit-scrollbar) {
459
- width: 5px;
460
- height: 5px;
461
- z-index: 10;
462
- }
463
- ::v-deep(.ant-upload-list::-webkit-scrollbar-track) {
464
- background-color: #ffffff;
465
- z-index: 10;
466
- }
467
- /*滚动条里面的小方块,能向上向下移动*/
468
- ::v-deep(.ant-upload-list::-webkit-scrollbar-thumb) {
469
- background-color: #bfbfbf;
470
- border-radius: 5px;
471
- border: 1px solid #f1f1f1;
472
- box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
473
- z-index: 10;
474
- }
475
- ::v-deep(.ant-upload-list::-webkit-scrollbar-thumb:hover) {
476
- background-color: #a8a8a8;
477
- z-index: 10;
478
- }
479
- ::v-deep(.ant-upload-list::-webkit-scrollbar-thumb:active) {
480
- background-color: #787878;
481
- z-index: 10;
482
- }
483
- /*边角,即两个滚动条的交汇处*/
484
- ::v-deep(.ant-upload-list::-webkit-scrollbar-corner) {
485
- background-color: #ffffff;
486
- z-index: 10;
487
- }
488
-
489
- ::v-deep(.ant-list-item) {
490
- padding: 12px 10px;
491
- position: relative;
492
- }
493
- .list {
494
- padding: 10px 15px;
495
- padding-top: 0;
496
- margin-top: 10px;
497
- overflow: auto;
498
- .close-icon {
499
- position: absolute;
500
- top: 30%;
501
- right: 5%;
502
- cursor: pointer;
503
- }
504
- }
505
- /*滚动条整体部分*/
506
- .list::-webkit-scrollbar {
507
- width: 5px;
508
- height: 5px;
509
- z-index: 10;
510
- }
511
- /*滚动条的轨道*/
512
- .list::-webkit-scrollbar-track {
513
- background-color: #ffffff;
514
- z-index: 10;
515
- }
516
- /*滚动条里面的小方块,能向上向下移动*/
517
- .list::-webkit-scrollbar-thumb {
518
- background-color: #bfbfbf;
519
- border-radius: 5px;
520
- border: 1px solid #f1f1f1;
521
- box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
522
- z-index: 10;
523
- }
524
- .list::-webkit-scrollbar-thumb:hover {
525
- background-color: #a8a8a8;
526
- z-index: 10;
527
- }
528
- .list::-webkit-scrollbar-thumb:active {
529
- background-color: #787878;
530
- z-index: 10;
531
- }
532
- /*边角,即两个滚动条的交汇处*/
533
- .list::-webkit-scrollbar-corner {
534
- background-color: #ffffff;
535
- z-index: 10;
536
- }
537
- ::v-deep .vxe-modal--wrapper .vxe-modal--content {
538
- padding: 0;
539
- }
540
- .input-box {
541
- background-color: #fff;
542
- padding: 10px 10px 0;
543
- min-height: 180px;
544
- // max-height: 210px;
545
- }
546
- .msg-content {
547
- box-sizing: border-box;
548
- max-height: 40px;
549
- min-height: 40px;
550
- max-width: 140px;
551
- min-width: 140px;
552
- display: flex;
553
- align-items: center;
554
- border-bottom: 1px solid #ccc;
555
- background: #eee;
556
- border-radius: 5px;
557
- padding: 0 10px;
558
- margin-right: 8px;
559
- margin-bottom: 8px;
560
- cursor: pointer;
561
- position: relative;
562
- }
563
- .download-icon {
564
- position: absolute;
565
- line-height: 50%;
566
- left: 45%;
567
- opacity: 0;
568
- }
569
- .msg-content:hover {
570
- background: #ccc;
571
- }
572
- .msg-content:hover .download-icon {
573
- opacity: 1;
574
- }
575
- .file-title {
576
- overflow: hidden; //超出的文本隐藏
577
- text-overflow: ellipsis; //溢出用省略号显示
578
- white-space: nowrap; // 默认不换行;
579
- }
580
-
581
- .odoo {
582
- position: fixed;
583
- top: 40%;
584
- right: 5px;
585
- z-index: 100;
586
- cursor: pointer;
587
- width: 40px;
588
- height: 40px;
589
- display: flex;
590
- justify-content: center;
591
- align-items: center;
592
- border-radius: 5px;
593
- background: #089def;
594
- }
595
- ::v-deep .vxe-modal--wrapper .vxe-modal--content {
596
- padding: 0;
597
- }
1
+ <template>
2
+ <div>
3
+ <div class="odoo" @click="showOdoo = !showOdoo">
4
+ <a-icon type="snippets" style="font-size: 30px; color: #fff" />
5
+ </div>
6
+ <vxe-modal
7
+ v-model="showOdoo"
8
+ :zIndex="1000"
9
+ :showHeader="false"
10
+ :mask="false"
11
+ :mask-closable="true"
12
+ :position="{
13
+ left: '72%',
14
+ top: '15%'
15
+ }"
16
+ destroy-on-close
17
+ >
18
+ <div class="liu-yan" style="background-color: #eaeef1">
19
+ <div class="input-box">
20
+ <a-tabs default-active-key="msg" @change="tabChange">
21
+ <a-tab-pane key="msg" tab="发送消息">
22
+ <!-- <div style="display:flex">
23
+ <div
24
+ style="display:flex;justify-content: center;align-items: center;margin-bottom:5px;margin-left:5px;flex:1"
25
+ >
26
+ <div style="flex:1">发送给:</div>
27
+ <a-select
28
+ v-model:value="sendUser"
29
+ show-search
30
+ mode="multiple"
31
+ style="width: 85%;flex:3"
32
+ :options="userList"
33
+ size="small"
34
+ :filter-option="selectPinYin"
35
+ ></a-select>
36
+ </div>
37
+ </div>
38
+ <a-textarea placeholder="写些什么..." v-model:value="remark" />-->
39
+
40
+ <a-mentions
41
+ placeholder="写些什么..."
42
+ split=";"
43
+ v-model:value="remark"
44
+ rows="3"
45
+ >
46
+ <a-mentions-option
47
+ v-for="(item, index) in userList"
48
+ :key="index"
49
+ :value="item.value"
50
+ >{{ item.label }}</a-mentions-option>
51
+ </a-mentions>
52
+ <!-- <a-upload
53
+ list-type="picture"
54
+ :headers="uploadHeaders"
55
+ :action="uploadData.picAction"
56
+ :data="uploadData"
57
+ :before-upload="beforeAvatarUpload"
58
+ @change="handleAvatarSuccess"
59
+ :file-list="fileList"
60
+ style="padding-top: 10px"
61
+ >
62
+ <a-icon style="font-size: 16px; cursor: pointer; margin: 5px 10px" type="paper-clip" />
63
+ </a-upload>-->
64
+ <div style="display: flex; justify-content: flex-end;margin-top:5px">
65
+ <a-button @click="sendMsg" :disabled="remark ===''">发送</a-button>
66
+ </div>
67
+ </a-tab-pane>
68
+ <a-tab-pane key="remark" tab="记录备注">
69
+ <a-textarea placeholder="写些什么..." v-model:value="remark" />
70
+ <a-upload
71
+ list-type="picture"
72
+ :headers="uploadHeaders"
73
+ :action="uploadData.picAction"
74
+ :data="uploadData"
75
+ :before-upload="beforeAvatarUpload"
76
+ @change="handleAvatarSuccess"
77
+ :file-list="fileList"
78
+ style="padding-top: 10px"
79
+ >
80
+ <a-icon
81
+ style="font-size: 16px; cursor: pointer; margin: 5px 10px"
82
+ type="paper-clip"
83
+ />
84
+ </a-upload>
85
+ <div style="display: flex; justify-content: flex-end">
86
+ <a-button @click="addMsgRemark" :disabled="remark ===''">记录</a-button>
87
+ </div>
88
+ </a-tab-pane>
89
+ </a-tabs>
90
+ </div>
91
+ <div class="list" :style="{ height: moduleHeight - 215 + 'px' }">
92
+ <a-list
93
+ v-if="remarkData.length > 0"
94
+ item-layout="horizontal"
95
+ :data-source="remarkData"
96
+ style="box-shadow: 3px 3px 6px #cad1d7"
97
+ >
98
+ <a-list-item
99
+ slot="renderItem"
100
+ slot-scope="item"
101
+ :style="{
102
+ borderBottom: item.type === 'date' ? '0' : '1px solid #ddd',
103
+ backgroundColor: item.type === 'date' ? '#fff' : '#fff',
104
+ }"
105
+ >
106
+ <template v-if="item.type !== 'date'">
107
+ <a-popconfirm
108
+ placement="topRight"
109
+ title="确认删除当前备注吗?"
110
+ ok-text="确认"
111
+ cancel-text="取消"
112
+ @confirm="delMsgRemark(item)"
113
+ >
114
+ <div v-show="userId === item.createUserId" class="close-icon">
115
+ <a-icon type="close" />
116
+ </div>
117
+ </a-popconfirm>
118
+ <a-comment :author="item.createUserName" :avatar="item.avatar">
119
+ <!-- <template slot="actions">
120
+ <span v-for="(action,index) in item.actions" :key="index">{{ action }}</span>
121
+ </template>-->
122
+ <template slot="content">
123
+ <template v-if="item.receiver!==null">
124
+ <div style="display:flex;flex-wrap: wrap;">
125
+ <div
126
+ v-for="(item,index) in item.atUser"
127
+ :key="index"
128
+ style="background-color:#eee;margin-right:3px"
129
+ >@{{item}}</div>
130
+ </div>
131
+ </template>
132
+ <div style="margin-bottom: 5px">{{ item.body }}</div>
133
+ <div
134
+ v-if="item.objectCommentAttachDtos.length > 0"
135
+ style="display: flex; flex-wrap: wrap"
136
+ >
137
+ <div
138
+ v-for="(item, index) in item.objectCommentAttachDtos"
139
+ :key="index"
140
+ class="msg-content"
141
+ @click="downloadFile(item)"
142
+ >
143
+ <div class="download-icon">
144
+ <a-icon type="vertical-align-bottom" style="font-size: 30px" />
145
+ </div>
146
+ <a-icon type="file-text" style="font-size: 25px; margin-right: 5px" />
147
+ <span class="file-title">{{ item.attachName }}</span>
148
+ </div>
149
+ </div>
150
+ </template>
151
+ <a-tooltip slot="datetime" :title="item.createTime">
152
+ <span>{{ item.fromNowTime }}</span>
153
+ </a-tooltip>
154
+ </a-comment>
155
+ </template>
156
+ <template v-else>
157
+ <a-divider>{{ item.createTime }}</a-divider>
158
+ </template>
159
+ </a-list-item>
160
+ </a-list>
161
+ <div v-else></div>
162
+ </div>
163
+ </div>
164
+ </vxe-modal>
165
+ </div>
166
+ </template>
167
+
168
+ <script>
169
+ import moment from "moment";
170
+ import { notification } from "ant-design-vue";
171
+ import {
172
+ attachGetAttachUrlApi,
173
+ readObjectCommentApi,
174
+ searchObjectCommentApi,
175
+ addObjectCommentApi,
176
+ deleteObjectCommentApi,
177
+ sendMsgApi,
178
+ userInfoSearchApi
179
+ } from "../../utils/api";
180
+ export default {
181
+ name: "LeaveAMessage",
182
+ props: {
183
+ topic: {
184
+ type: String
185
+ },
186
+ moduleHeight: {
187
+ type: Number
188
+ },
189
+ limitSize: {
190
+ // 限制上传大小
191
+ type: Number,
192
+ default: 5
193
+ },
194
+ limitType: {
195
+ // 限制上传类型
196
+ type: Array,
197
+ default: () => {
198
+ return [];
199
+ }
200
+ },
201
+ resId: {
202
+ type: String
203
+ },
204
+ picType: {
205
+ type: String,
206
+ default: "cust"
207
+ },
208
+ dataName: {
209
+ type: String
210
+ }
211
+ // formRow: {
212
+ // type: Object,
213
+ // default: () => {
214
+ // return {};
215
+ // },
216
+ // },
217
+ },
218
+ watch: {
219
+ resId: {
220
+ handler: function(newVal) {
221
+ this.uploadData.resId = newVal;
222
+ }
223
+ },
224
+ showOdoo(newVal, oldVal) {
225
+ if (newVal) {
226
+ this.getUserInfo();
227
+ this.getMsgRemarkData();
228
+ }
229
+ },
230
+ immediate: true
231
+ },
232
+ created() {
233
+ let viewDatas = this.$store.getters.moduleViewInfo[
234
+ this.$route.meta.moduleCode
235
+ ];
236
+ this.objectName = viewDatas.objectName;
237
+ this.userId = this.$store.getters.userId;
238
+ },
239
+ mounted() {
240
+ this.uploadHeaders.Authorization = `Bearer ${this.$store.getters.token}`;
241
+ this.uploadData.picType = this.picType;
242
+ this.uploadData.resId = this.resId;
243
+ this.internalServiceUrl = attachGetAttachUrlApi();
244
+ this.uploadData.picAction = this.internalServiceUrl + "/UploadAttach";
245
+ },
246
+ data() {
247
+ return {
248
+ showOdoo: false,
249
+ userId: null,
250
+ fileList: [],
251
+ remarkData: [],
252
+ uploadData: {
253
+ picType: "",
254
+ picAction: "",
255
+ resId: ""
256
+ },
257
+ uploadHeaders: {
258
+ Authorization: null
259
+ },
260
+ sendUser: [],
261
+ userList: [],
262
+ remark: "",
263
+ attachment: [],
264
+ objectName: ""
265
+ };
266
+ },
267
+ methods: {
268
+ beforeAvatarUpload(file) {
269
+ // const isPic = file.type === 'image/jpeg' || file.type === 'image/png'
270
+ if (file.size / 1024 / 1024 > this.limitSize) {
271
+ notification.error({
272
+ message: "错误",
273
+ description: "上传图片大小不能超过 " + this.limitSize + "MB!"
274
+ });
275
+ }
276
+ if (this.limitType.length > 0 && !this.limitType[file.type]) {
277
+ notification.error({
278
+ message: "错误",
279
+ description: "上传附件格式错误!"
280
+ });
281
+ }
282
+ return true;
283
+ },
284
+ handleAvatarSuccess(info) {
285
+ this.fileList = info.fileList;
286
+ if (info.file.status == "done") {
287
+ this.attachment.push(info.file.response.content.id);
288
+ // this.$emit("add", this.dataName, info.file.response.content);
289
+ }
290
+ },
291
+ getMsgRemarkData() {
292
+ let postData = {
293
+ begin: 1,
294
+ size: 0,
295
+ expression: {
296
+ expressions: [
297
+ {
298
+ field: "objectName",
299
+ operator: "EQ",
300
+ value: this.objectName
301
+ },
302
+ {
303
+ field: "resId",
304
+ operator: "EQ",
305
+ value: this.resId
306
+ }
307
+ ],
308
+ operator: "and"
309
+ },
310
+ sorts: [["createTime", "desc"]]
311
+ };
312
+ searchObjectCommentApi(postData).then(res => {
313
+ let tmp = [];
314
+ res.content.forEach(item => {
315
+ if (item.receiver !== null) {
316
+ item["atUser"] = [];
317
+ let atUser = item.receiver.split(",");
318
+ this.userList.forEach(uitem => {
319
+ if (atUser.indexOf(uitem.code) > -1) {
320
+ item.atUser.push(uitem.label);
321
+ }
322
+ });
323
+ }
324
+
325
+ let flag = tmp.findIndex(titem => {
326
+ return (
327
+ titem.createTime ===
328
+ moment(item.createTime).format("YYYY年MM月DD")
329
+ );
330
+ });
331
+ if (flag < 0) {
332
+ tmp.push({
333
+ type: "date",
334
+ createTime: moment(item.createTime).format("YYYY年MM月DD")
335
+ });
336
+ }
337
+ item["avatar"] =
338
+ "https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png";
339
+ item["fromNowTime"] = moment(item.createTime).fromNow();
340
+ tmp.push(item);
341
+ });
342
+ this.remarkData = tmp;
343
+ });
344
+ },
345
+ downloadFile(val) {
346
+ window.open(
347
+ this.internalServiceUrl +
348
+ "/DownAttachFile/" +
349
+ val.msgAttachId +
350
+ `?accessToken=${this.$store.getters.token}`
351
+ );
352
+ },
353
+ addMsgRemark() {
354
+ if (this.remark === "" && this.attachment.length < 1) {
355
+ return;
356
+ } else {
357
+ let postData = {
358
+ resId: this.resId,
359
+ objectName: this.objectName,
360
+ body: this.remark,
361
+ objectCommentAttachIds: this.attachment
362
+ };
363
+ addObjectCommentApi(postData).then(res => {
364
+ this.remark = "";
365
+ this.attachment = [];
366
+ this.fileList = [];
367
+ this.getMsgRemarkData();
368
+ });
369
+ }
370
+ },
371
+ delMsgRemark(val) {
372
+ deleteObjectCommentApi({
373
+ keyIds: [val.id]
374
+ }).then(res => {
375
+ this.getMsgRemarkData();
376
+ });
377
+ },
378
+ getUserInfo() {
379
+ userInfoSearchApi().then(res => {
380
+ this.userList = [];
381
+ res.content.forEach(item => {
382
+ this.userList.push({
383
+ value: item.userName,
384
+ label: item.name,
385
+ code: item.id
386
+ });
387
+ });
388
+ });
389
+ },
390
+ sendMsg() {
391
+ let reg = /@(.*?);/;
392
+ let result;
393
+ let arr = [];
394
+ while ((result = reg.exec(this.remark))) {
395
+ arr.push(result[1]);
396
+ this.remark = this.remark.replace(/@(.*?);/, "");
397
+ }
398
+
399
+ let receiver = [];
400
+ arr.forEach(item => {
401
+ this.userList.forEach(uitem => {
402
+ if (uitem.value === item) {
403
+ receiver.push(uitem.code);
404
+ }
405
+ });
406
+ });
407
+ receiver = receiver.join(",");
408
+ let postData = {
409
+ content: this.remark,
410
+ receiver: receiver,
411
+ subject: this.topic,
412
+ objectName: this.objectName,
413
+ resId: this.resId
414
+ };
415
+ sendMsgApi(postData).then(res => {
416
+ this.remark = "";
417
+ this.sendUser = [];
418
+ this.getMsgRemarkData();
419
+ });
420
+ },
421
+ selectPinYin(input, option) {
422
+ if (input.charCodeAt() >= 32 && input.charCodeAt() <= 126) {
423
+ return (
424
+ option.componentOptions.children[0].text
425
+ .toLowerCase()
426
+ .indexOf(input.toLowerCase()) >= 0
427
+ );
428
+ } else {
429
+ return (
430
+ option.componentOptions.children[0].text
431
+ .toLowerCase()
432
+ .indexOf(input.toLowerCase()) >= 0
433
+ );
434
+ }
435
+ },
436
+ tabChange(activeKey) {
437
+ this.remark = "";
438
+ }
439
+ }
440
+ };
441
+ </script>
442
+
443
+ <style lang="less" scoped>
444
+ ::v-deep(.ant-upload-list-picture .ant-upload-list-item) {
445
+ max-width: 185px;
446
+ min-width: 185px;
447
+ margin-right: 10px;
448
+ }
449
+ ::v-deep(.ant-upload-list-picture .ant-upload-list-item-name) {
450
+ padding-right: 24px !important;
451
+ }
452
+ ::v-deep(.ant-upload-list) {
453
+ display: flex;
454
+ overflow-x: auto;
455
+ margin-bottom: 10px;
456
+ // flex-wrap: wrap;
457
+ }
458
+ ::v-deep(.ant-upload-list::-webkit-scrollbar) {
459
+ width: 5px;
460
+ height: 5px;
461
+ z-index: 10;
462
+ }
463
+ ::v-deep(.ant-upload-list::-webkit-scrollbar-track) {
464
+ background-color: #ffffff;
465
+ z-index: 10;
466
+ }
467
+ /*滚动条里面的小方块,能向上向下移动*/
468
+ ::v-deep(.ant-upload-list::-webkit-scrollbar-thumb) {
469
+ background-color: #bfbfbf;
470
+ border-radius: 5px;
471
+ border: 1px solid #f1f1f1;
472
+ box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
473
+ z-index: 10;
474
+ }
475
+ ::v-deep(.ant-upload-list::-webkit-scrollbar-thumb:hover) {
476
+ background-color: #a8a8a8;
477
+ z-index: 10;
478
+ }
479
+ ::v-deep(.ant-upload-list::-webkit-scrollbar-thumb:active) {
480
+ background-color: #787878;
481
+ z-index: 10;
482
+ }
483
+ /*边角,即两个滚动条的交汇处*/
484
+ ::v-deep(.ant-upload-list::-webkit-scrollbar-corner) {
485
+ background-color: #ffffff;
486
+ z-index: 10;
487
+ }
488
+
489
+ ::v-deep(.ant-list-item) {
490
+ padding: 12px 10px;
491
+ position: relative;
492
+ }
493
+ .list {
494
+ padding: 10px 15px;
495
+ padding-top: 0;
496
+ margin-top: 10px;
497
+ overflow: auto;
498
+ .close-icon {
499
+ position: absolute;
500
+ top: 30%;
501
+ right: 5%;
502
+ cursor: pointer;
503
+ }
504
+ }
505
+ /*滚动条整体部分*/
506
+ .list::-webkit-scrollbar {
507
+ width: 5px;
508
+ height: 5px;
509
+ z-index: 10;
510
+ }
511
+ /*滚动条的轨道*/
512
+ .list::-webkit-scrollbar-track {
513
+ background-color: #ffffff;
514
+ z-index: 10;
515
+ }
516
+ /*滚动条里面的小方块,能向上向下移动*/
517
+ .list::-webkit-scrollbar-thumb {
518
+ background-color: #bfbfbf;
519
+ border-radius: 5px;
520
+ border: 1px solid #f1f1f1;
521
+ box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
522
+ z-index: 10;
523
+ }
524
+ .list::-webkit-scrollbar-thumb:hover {
525
+ background-color: #a8a8a8;
526
+ z-index: 10;
527
+ }
528
+ .list::-webkit-scrollbar-thumb:active {
529
+ background-color: #787878;
530
+ z-index: 10;
531
+ }
532
+ /*边角,即两个滚动条的交汇处*/
533
+ .list::-webkit-scrollbar-corner {
534
+ background-color: #ffffff;
535
+ z-index: 10;
536
+ }
537
+ ::v-deep .vxe-modal--wrapper .vxe-modal--content {
538
+ padding: 0;
539
+ }
540
+ .input-box {
541
+ background-color: #fff;
542
+ padding: 10px 10px 0;
543
+ min-height: 180px;
544
+ // max-height: 210px;
545
+ }
546
+ .msg-content {
547
+ box-sizing: border-box;
548
+ max-height: 40px;
549
+ min-height: 40px;
550
+ max-width: 140px;
551
+ min-width: 140px;
552
+ display: flex;
553
+ align-items: center;
554
+ border-bottom: 1px solid #ccc;
555
+ background: #eee;
556
+ border-radius: 5px;
557
+ padding: 0 10px;
558
+ margin-right: 8px;
559
+ margin-bottom: 8px;
560
+ cursor: pointer;
561
+ position: relative;
562
+ }
563
+ .download-icon {
564
+ position: absolute;
565
+ line-height: 50%;
566
+ left: 45%;
567
+ opacity: 0;
568
+ }
569
+ .msg-content:hover {
570
+ background: #ccc;
571
+ }
572
+ .msg-content:hover .download-icon {
573
+ opacity: 1;
574
+ }
575
+ .file-title {
576
+ overflow: hidden; //超出的文本隐藏
577
+ text-overflow: ellipsis; //溢出用省略号显示
578
+ white-space: nowrap; // 默认不换行;
579
+ }
580
+
581
+ .odoo {
582
+ position: fixed;
583
+ top: 40%;
584
+ right: 5px;
585
+ z-index: 100;
586
+ cursor: pointer;
587
+ width: 40px;
588
+ height: 40px;
589
+ display: flex;
590
+ justify-content: center;
591
+ align-items: center;
592
+ border-radius: 5px;
593
+ background: #089def;
594
+ }
595
+ ::v-deep .vxe-modal--wrapper .vxe-modal--content {
596
+ padding: 0;
597
+ }
598
598
  </style>