Преглед на файлове

Merge branch 'master' of http://39.164.159.226:3000/hnsh-smart-steward/smart-steward-mobile

闪电 преди 3 седмици
родител
ревизия
d6cdb79f2c

+ 32 - 0
src/api/knowledge/index.ts

@@ -2,9 +2,41 @@ import { http } from '@/http/http'
2 2
 enum Api {
3 3
   baseknowledgeCategory = '/knowledgeCategory/category',
4 4
   queryknowledgeCategory = '/knowledgeCategory/category/list',
5
+  queryknowledgeTableContents = '/knowledgeContent/content/list',
6
+  baseknowledgeContent = '/knowledgeContent/content',
7
+  querycomment = '/commComments/comments/list',
8
+  baseaddcomment = '/commComments/comments',
9
+  queryrecord = '/knowledgeViewRecord/record/list',
10
+  queryrecentviewlist = '/knowledgeContent/content/getRecentRecords',
5 11
 }
6 12
 
7 13
 //查询知识库分类列表
8 14
 export function queryKnowledgeCategory(params: any) {
9 15
   return http.get(Api.queryknowledgeCategory, params)
10 16
 }
17
+//获取知识库内容目录列表
18
+export function queryKnowledgeContentlist({ categoryId }) {
19
+  return http.get(`${Api.queryknowledgeTableContents}/${categoryId}`)
20
+}
21
+//获取知识库内容详细信息
22
+export function getKnowledgeContentDetail({ roleId }) {
23
+  return http.get(`${Api.baseknowledgeContent}/${roleId}`)
24
+}
25
+//获取评论列表
26
+export function querycomment({ targetId, targetType }: any) {
27
+  return http.get(
28
+    `${Api.querycomment}?targetId=${targetId}&targetType=${targetType}`
29
+  )
30
+}
31
+//新增 提交评论
32
+export function addComment(data: any) {
33
+  return http.post(Api.baseaddcomment, data)
34
+}
35
+//查看记录
36
+export function queryrecord(params: any) {
37
+  return http.get(Api.queryrecord, params);
38
+}
39
+//最近查看列表
40
+export function queryrecentviewlistAPI(params: any) {
41
+  return http.get(Api.queryrecentviewlist, params);
42
+}

+ 10 - 3
src/api/workorder/index.ts

@@ -6,6 +6,8 @@ enum Api {
6 6
   queryrtodoaskslist = '/scheduleTasks/tasks/allList',
7 7
   postList = '/system/post/list',
8 8
   querybaseApi = '/taskTemplate/template/list',
9
+  menuList = '/system/user/list',
10
+  selectAllSysStation = '/sysStation/station/selectAllSysStationList',
9 11
 }
10 12
 // 查询加油站列表
11 13
 export function queryGasStationList(params: any) {
@@ -32,6 +34,11 @@ export function addtodoaskslist(data: any) {
32 34
 export function querybaseApilist(params?: any) {
33 35
   return http.get(Api.querybaseApi, params)
34 36
 }
35
-// export function login(loginForm: ILoginForm) {
36
-//   return http.post<IAuthLoginRes>('/login', loginForm)
37
-// }
37
+//抄送人列表
38
+export function queryrCCList() {
39
+  return http.get(Api.menuList)
40
+}
41
+//查询所有油站
42
+export function selectAllSysStation() {
43
+  return http.get(Api.selectAllSysStation, { isAll: true })
44
+}

+ 539 - 0
src/assets/font/demo.css

@@ -0,0 +1,539 @@
1
+/* Logo 字体 */
2
+@font-face {
3
+  font-family: "iconfont logo";
4
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
5
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
6
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
7
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
8
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
9
+}
10
+
11
+.logo {
12
+  font-family: "iconfont logo";
13
+  font-size: 160px;
14
+  font-style: normal;
15
+  -webkit-font-smoothing: antialiased;
16
+  -moz-osx-font-smoothing: grayscale;
17
+}
18
+
19
+/* tabs */
20
+.nav-tabs {
21
+  position: relative;
22
+}
23
+
24
+.nav-tabs .nav-more {
25
+  position: absolute;
26
+  right: 0;
27
+  bottom: 0;
28
+  height: 42px;
29
+  line-height: 42px;
30
+  color: #666;
31
+}
32
+
33
+#tabs {
34
+  border-bottom: 1px solid #eee;
35
+}
36
+
37
+#tabs li {
38
+  cursor: pointer;
39
+  width: 100px;
40
+  height: 40px;
41
+  line-height: 40px;
42
+  text-align: center;
43
+  font-size: 16px;
44
+  border-bottom: 2px solid transparent;
45
+  position: relative;
46
+  z-index: 1;
47
+  margin-bottom: -1px;
48
+  color: #666;
49
+}
50
+
51
+
52
+#tabs .active {
53
+  border-bottom-color: #f00;
54
+  color: #222;
55
+}
56
+
57
+.tab-container .content {
58
+  display: none;
59
+}
60
+
61
+/* 页面布局 */
62
+.main {
63
+  padding: 30px 100px;
64
+  width: 960px;
65
+  margin: 0 auto;
66
+}
67
+
68
+.main .logo {
69
+  color: #333;
70
+  text-align: left;
71
+  margin-bottom: 30px;
72
+  line-height: 1;
73
+  height: 110px;
74
+  margin-top: -50px;
75
+  overflow: hidden;
76
+  *zoom: 1;
77
+}
78
+
79
+.main .logo a {
80
+  font-size: 160px;
81
+  color: #333;
82
+}
83
+
84
+.helps {
85
+  margin-top: 40px;
86
+}
87
+
88
+.helps pre {
89
+  padding: 20px;
90
+  margin: 10px 0;
91
+  border: solid 1px #e7e1cd;
92
+  background-color: #fffdef;
93
+  overflow: auto;
94
+}
95
+
96
+.icon_lists {
97
+  width: 100% !important;
98
+  overflow: hidden;
99
+  *zoom: 1;
100
+}
101
+
102
+.icon_lists li {
103
+  width: 100px;
104
+  margin-bottom: 10px;
105
+  margin-right: 20px;
106
+  text-align: center;
107
+  list-style: none !important;
108
+  cursor: default;
109
+}
110
+
111
+.icon_lists li .code-name {
112
+  line-height: 1.2;
113
+}
114
+
115
+.icon_lists .icon {
116
+  display: block;
117
+  height: 100px;
118
+  line-height: 100px;
119
+  font-size: 42px;
120
+  margin: 10px auto;
121
+  color: #333;
122
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
123
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
124
+  transition: font-size 0.25s linear, width 0.25s linear;
125
+}
126
+
127
+.icon_lists .icon:hover {
128
+  font-size: 100px;
129
+}
130
+
131
+.icon_lists .svg-icon {
132
+  /* 通过设置 font-size 来改变图标大小 */
133
+  width: 1em;
134
+  /* 图标和文字相邻时,垂直对齐 */
135
+  vertical-align: -0.15em;
136
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
137
+  fill: currentColor;
138
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
139
+      normalize.css 中也包含这行 */
140
+  overflow: hidden;
141
+}
142
+
143
+.icon_lists li .name,
144
+.icon_lists li .code-name {
145
+  color: #666;
146
+}
147
+
148
+/* markdown 样式 */
149
+.markdown {
150
+  color: #666;
151
+  font-size: 14px;
152
+  line-height: 1.8;
153
+}
154
+
155
+.highlight {
156
+  line-height: 1.5;
157
+}
158
+
159
+.markdown img {
160
+  vertical-align: middle;
161
+  max-width: 100%;
162
+}
163
+
164
+.markdown h1 {
165
+  color: #404040;
166
+  font-weight: 500;
167
+  line-height: 40px;
168
+  margin-bottom: 24px;
169
+}
170
+
171
+.markdown h2,
172
+.markdown h3,
173
+.markdown h4,
174
+.markdown h5,
175
+.markdown h6 {
176
+  color: #404040;
177
+  margin: 1.6em 0 0.6em 0;
178
+  font-weight: 500;
179
+  clear: both;
180
+}
181
+
182
+.markdown h1 {
183
+  font-size: 28px;
184
+}
185
+
186
+.markdown h2 {
187
+  font-size: 22px;
188
+}
189
+
190
+.markdown h3 {
191
+  font-size: 16px;
192
+}
193
+
194
+.markdown h4 {
195
+  font-size: 14px;
196
+}
197
+
198
+.markdown h5 {
199
+  font-size: 12px;
200
+}
201
+
202
+.markdown h6 {
203
+  font-size: 12px;
204
+}
205
+
206
+.markdown hr {
207
+  height: 1px;
208
+  border: 0;
209
+  background: #e9e9e9;
210
+  margin: 16px 0;
211
+  clear: both;
212
+}
213
+
214
+.markdown p {
215
+  margin: 1em 0;
216
+}
217
+
218
+.markdown>p,
219
+.markdown>blockquote,
220
+.markdown>.highlight,
221
+.markdown>ol,
222
+.markdown>ul {
223
+  width: 80%;
224
+}
225
+
226
+.markdown ul>li {
227
+  list-style: circle;
228
+}
229
+
230
+.markdown>ul li,
231
+.markdown blockquote ul>li {
232
+  margin-left: 20px;
233
+  padding-left: 4px;
234
+}
235
+
236
+.markdown>ul li p,
237
+.markdown>ol li p {
238
+  margin: 0.6em 0;
239
+}
240
+
241
+.markdown ol>li {
242
+  list-style: decimal;
243
+}
244
+
245
+.markdown>ol li,
246
+.markdown blockquote ol>li {
247
+  margin-left: 20px;
248
+  padding-left: 4px;
249
+}
250
+
251
+.markdown code {
252
+  margin: 0 3px;
253
+  padding: 0 5px;
254
+  background: #eee;
255
+  border-radius: 3px;
256
+}
257
+
258
+.markdown strong,
259
+.markdown b {
260
+  font-weight: 600;
261
+}
262
+
263
+.markdown>table {
264
+  border-collapse: collapse;
265
+  border-spacing: 0px;
266
+  empty-cells: show;
267
+  border: 1px solid #e9e9e9;
268
+  width: 95%;
269
+  margin-bottom: 24px;
270
+}
271
+
272
+.markdown>table th {
273
+  white-space: nowrap;
274
+  color: #333;
275
+  font-weight: 600;
276
+}
277
+
278
+.markdown>table th,
279
+.markdown>table td {
280
+  border: 1px solid #e9e9e9;
281
+  padding: 8px 16px;
282
+  text-align: left;
283
+}
284
+
285
+.markdown>table th {
286
+  background: #F7F7F7;
287
+}
288
+
289
+.markdown blockquote {
290
+  font-size: 90%;
291
+  color: #999;
292
+  border-left: 4px solid #e9e9e9;
293
+  padding-left: 0.8em;
294
+  margin: 1em 0;
295
+}
296
+
297
+.markdown blockquote p {
298
+  margin: 0;
299
+}
300
+
301
+.markdown .anchor {
302
+  opacity: 0;
303
+  transition: opacity 0.3s ease;
304
+  margin-left: 8px;
305
+}
306
+
307
+.markdown .waiting {
308
+  color: #ccc;
309
+}
310
+
311
+.markdown h1:hover .anchor,
312
+.markdown h2:hover .anchor,
313
+.markdown h3:hover .anchor,
314
+.markdown h4:hover .anchor,
315
+.markdown h5:hover .anchor,
316
+.markdown h6:hover .anchor {
317
+  opacity: 1;
318
+  display: inline-block;
319
+}
320
+
321
+.markdown>br,
322
+.markdown>p>br {
323
+  clear: both;
324
+}
325
+
326
+
327
+.hljs {
328
+  display: block;
329
+  background: white;
330
+  padding: 0.5em;
331
+  color: #333333;
332
+  overflow-x: auto;
333
+}
334
+
335
+.hljs-comment,
336
+.hljs-meta {
337
+  color: #969896;
338
+}
339
+
340
+.hljs-string,
341
+.hljs-variable,
342
+.hljs-template-variable,
343
+.hljs-strong,
344
+.hljs-emphasis,
345
+.hljs-quote {
346
+  color: #df5000;
347
+}
348
+
349
+.hljs-keyword,
350
+.hljs-selector-tag,
351
+.hljs-type {
352
+  color: #a71d5d;
353
+}
354
+
355
+.hljs-literal,
356
+.hljs-symbol,
357
+.hljs-bullet,
358
+.hljs-attribute {
359
+  color: #0086b3;
360
+}
361
+
362
+.hljs-section,
363
+.hljs-name {
364
+  color: #63a35c;
365
+}
366
+
367
+.hljs-tag {
368
+  color: #333333;
369
+}
370
+
371
+.hljs-title,
372
+.hljs-attr,
373
+.hljs-selector-id,
374
+.hljs-selector-class,
375
+.hljs-selector-attr,
376
+.hljs-selector-pseudo {
377
+  color: #795da3;
378
+}
379
+
380
+.hljs-addition {
381
+  color: #55a532;
382
+  background-color: #eaffea;
383
+}
384
+
385
+.hljs-deletion {
386
+  color: #bd2c00;
387
+  background-color: #ffecec;
388
+}
389
+
390
+.hljs-link {
391
+  text-decoration: underline;
392
+}
393
+
394
+/* 代码高亮 */
395
+/* PrismJS 1.15.0
396
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
397
+/**
398
+ * prism.js default theme for JavaScript, CSS and HTML
399
+ * Based on dabblet (http://dabblet.com)
400
+ * @author Lea Verou
401
+ */
402
+code[class*="language-"],
403
+pre[class*="language-"] {
404
+  color: black;
405
+  background: none;
406
+  text-shadow: 0 1px white;
407
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
408
+  text-align: left;
409
+  white-space: pre;
410
+  word-spacing: normal;
411
+  word-break: normal;
412
+  word-wrap: normal;
413
+  line-height: 1.5;
414
+
415
+  -moz-tab-size: 4;
416
+  -o-tab-size: 4;
417
+  tab-size: 4;
418
+
419
+  -webkit-hyphens: none;
420
+  -moz-hyphens: none;
421
+  -ms-hyphens: none;
422
+  hyphens: none;
423
+}
424
+
425
+pre[class*="language-"]::-moz-selection,
426
+pre[class*="language-"] ::-moz-selection,
427
+code[class*="language-"]::-moz-selection,
428
+code[class*="language-"] ::-moz-selection {
429
+  text-shadow: none;
430
+  background: #b3d4fc;
431
+}
432
+
433
+pre[class*="language-"]::selection,
434
+pre[class*="language-"] ::selection,
435
+code[class*="language-"]::selection,
436
+code[class*="language-"] ::selection {
437
+  text-shadow: none;
438
+  background: #b3d4fc;
439
+}
440
+
441
+@media print {
442
+
443
+  code[class*="language-"],
444
+  pre[class*="language-"] {
445
+    text-shadow: none;
446
+  }
447
+}
448
+
449
+/* Code blocks */
450
+pre[class*="language-"] {
451
+  padding: 1em;
452
+  margin: .5em 0;
453
+  overflow: auto;
454
+}
455
+
456
+:not(pre)>code[class*="language-"],
457
+pre[class*="language-"] {
458
+  background: #f5f2f0;
459
+}
460
+
461
+/* Inline code */
462
+:not(pre)>code[class*="language-"] {
463
+  padding: .1em;
464
+  border-radius: .3em;
465
+  white-space: normal;
466
+}
467
+
468
+.token.comment,
469
+.token.prolog,
470
+.token.doctype,
471
+.token.cdata {
472
+  color: slategray;
473
+}
474
+
475
+.token.punctuation {
476
+  color: #999;
477
+}
478
+
479
+.namespace {
480
+  opacity: .7;
481
+}
482
+
483
+.token.property,
484
+.token.tag,
485
+.token.boolean,
486
+.token.number,
487
+.token.constant,
488
+.token.symbol,
489
+.token.deleted {
490
+  color: #905;
491
+}
492
+
493
+.token.selector,
494
+.token.attr-name,
495
+.token.string,
496
+.token.char,
497
+.token.builtin,
498
+.token.inserted {
499
+  color: #690;
500
+}
501
+
502
+.token.operator,
503
+.token.entity,
504
+.token.url,
505
+.language-css .token.string,
506
+.style .token.string {
507
+  color: #9a6e3a;
508
+  background: hsla(0, 0%, 100%, .5);
509
+}
510
+
511
+.token.atrule,
512
+.token.attr-value,
513
+.token.keyword {
514
+  color: #07a;
515
+}
516
+
517
+.token.function,
518
+.token.class-name {
519
+  color: #DD4A68;
520
+}
521
+
522
+.token.regex,
523
+.token.important,
524
+.token.variable {
525
+  color: #e90;
526
+}
527
+
528
+.token.important,
529
+.token.bold {
530
+  font-weight: bold;
531
+}
532
+
533
+.token.italic {
534
+  font-style: italic;
535
+}
536
+
537
+.token.entity {
538
+  cursor: help;
539
+}

+ 690 - 0
src/assets/font/demo_index.html

@@ -0,0 +1,690 @@
1
+<!DOCTYPE html>
2
+<html>
3
+<head>
4
+  <meta charset="utf-8"/>
5
+  <title>iconfont Demo</title>
6
+  <link rel="shortcut icon" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg" type="image/x-icon"/>
7
+  <link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg"/>
8
+  <link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
9
+  <link rel="stylesheet" href="demo.css">
10
+  <link rel="stylesheet" href="iconfont.css">
11
+  <script src="iconfont.js"></script>
12
+  <!-- jQuery -->
13
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
14
+  <!-- 代码高亮 -->
15
+  <script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
16
+  <style>
17
+    .main .logo {
18
+      margin-top: 0;
19
+      height: auto;
20
+    }
21
+
22
+    .main .logo a {
23
+      display: flex;
24
+      align-items: center;
25
+    }
26
+
27
+    .main .logo .sub-title {
28
+      margin-left: 0.5em;
29
+      font-size: 22px;
30
+      color: #fff;
31
+      background: linear-gradient(-45deg, #3967FF, #B500FE);
32
+      -webkit-background-clip: text;
33
+      -webkit-text-fill-color: transparent;
34
+    }
35
+  </style>
36
+</head>
37
+<body>
38
+  <div class="main">
39
+    <h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">
40
+      <img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg">
41
+      
42
+    </a></h1>
43
+    <div class="nav-tabs">
44
+      <ul id="tabs" class="dib-box">
45
+        <li class="dib active"><span>Unicode</span></li>
46
+        <li class="dib"><span>Font class</span></li>
47
+        <li class="dib"><span>Symbol</span></li>
48
+      </ul>
49
+      
50
+    </div>
51
+    <div class="tab-container">
52
+      <div class="content unicode" style="display: block;">
53
+          <ul class="icon_lists dib-box">
54
+          
55
+            <li class="dib">
56
+              <span class="icon iconfont">&#xf00a1;</span>
57
+                <div class="name">图书</div>
58
+                <div class="code-name">&amp;#xf00a1;</div>
59
+              </li>
60
+          
61
+            <li class="dib">
62
+              <span class="icon iconfont">&#xe627;</span>
63
+                <div class="name">列表</div>
64
+                <div class="code-name">&amp;#xe627;</div>
65
+              </li>
66
+          
67
+            <li class="dib">
68
+              <span class="icon iconfont">&#xe6ce;</span>
69
+                <div class="name">笔记</div>
70
+                <div class="code-name">&amp;#xe6ce;</div>
71
+              </li>
72
+          
73
+            <li class="dib">
74
+              <span class="icon iconfont">&#xe6cf;</span>
75
+                <div class="name">发现</div>
76
+                <div class="code-name">&amp;#xe6cf;</div>
77
+              </li>
78
+          
79
+            <li class="dib">
80
+              <span class="icon iconfont">&#xe6d0;</span>
81
+                <div class="name">会员</div>
82
+                <div class="code-name">&amp;#xe6d0;</div>
83
+              </li>
84
+          
85
+            <li class="dib">
86
+              <span class="icon iconfont">&#xe6d1;</span>
87
+                <div class="name">共享群</div>
88
+                <div class="code-name">&amp;#xe6d1;</div>
89
+              </li>
90
+          
91
+            <li class="dib">
92
+              <span class="icon iconfont">&#xe6d2;</span>
93
+                <div class="name">视频</div>
94
+                <div class="code-name">&amp;#xe6d2;</div>
95
+              </li>
96
+          
97
+            <li class="dib">
98
+              <span class="icon iconfont">&#xe6d3;</span>
99
+                <div class="name">识字</div>
100
+                <div class="code-name">&amp;#xe6d3;</div>
101
+              </li>
102
+          
103
+            <li class="dib">
104
+              <span class="icon iconfont">&#xe6d4;</span>
105
+                <div class="name">签到</div>
106
+                <div class="code-name">&amp;#xe6d4;</div>
107
+              </li>
108
+          
109
+            <li class="dib">
110
+              <span class="icon iconfont">&#xe6d5;</span>
111
+                <div class="name">备份</div>
112
+                <div class="code-name">&amp;#xe6d5;</div>
113
+              </li>
114
+          
115
+            <li class="dib">
116
+              <span class="icon iconfont">&#xe6d6;</span>
117
+                <div class="name">服务</div>
118
+                <div class="code-name">&amp;#xe6d6;</div>
119
+              </li>
120
+          
121
+            <li class="dib">
122
+              <span class="icon iconfont">&#xe6d7;</span>
123
+                <div class="name">圈子</div>
124
+                <div class="code-name">&amp;#xe6d7;</div>
125
+              </li>
126
+          
127
+            <li class="dib">
128
+              <span class="icon iconfont">&#xe6d8;</span>
129
+                <div class="name">文档</div>
130
+                <div class="code-name">&amp;#xe6d8;</div>
131
+              </li>
132
+          
133
+            <li class="dib">
134
+              <span class="icon iconfont">&#xe6d9;</span>
135
+                <div class="name">修复</div>
136
+                <div class="code-name">&amp;#xe6d9;</div>
137
+              </li>
138
+          
139
+            <li class="dib">
140
+              <span class="icon iconfont">&#xe6da;</span>
141
+                <div class="name">云手机</div>
142
+                <div class="code-name">&amp;#xe6da;</div>
143
+              </li>
144
+          
145
+            <li class="dib">
146
+              <span class="icon iconfont">&#xe6db;</span>
147
+                <div class="name">动态</div>
148
+                <div class="code-name">&amp;#xe6db;</div>
149
+              </li>
150
+          
151
+            <li class="dib">
152
+              <span class="icon iconfont">&#xe6dc;</span>
153
+                <div class="name">测心理</div>
154
+                <div class="code-name">&amp;#xe6dc;</div>
155
+              </li>
156
+          
157
+            <li class="dib">
158
+              <span class="icon iconfont">&#xe6dd;</span>
159
+                <div class="name">相册</div>
160
+                <div class="code-name">&amp;#xe6dd;</div>
161
+              </li>
162
+          
163
+            <li class="dib">
164
+              <span class="icon iconfont">&#xe6de;</span>
165
+                <div class="name">美图</div>
166
+                <div class="code-name">&amp;#xe6de;</div>
167
+              </li>
168
+          
169
+            <li class="dib">
170
+              <span class="icon iconfont">&#xe6df;</span>
171
+                <div class="name">AI专区</div>
172
+                <div class="code-name">&amp;#xe6df;</div>
173
+              </li>
174
+          
175
+            <li class="dib">
176
+              <span class="icon iconfont">&#xe6e0;</span>
177
+                <div class="name">自定义</div>
178
+                <div class="code-name">&amp;#xe6e0;</div>
179
+              </li>
180
+          
181
+            <li class="dib">
182
+              <span class="icon iconfont">&#xe6e1;</span>
183
+                <div class="name">智能对话</div>
184
+                <div class="code-name">&amp;#xe6e1;</div>
185
+              </li>
186
+          
187
+          </ul>
188
+          <div class="article markdown">
189
+          <h2 id="unicode-">Unicode 引用</h2>
190
+          <hr>
191
+
192
+          <p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
193
+          <ul>
194
+            <li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
195
+            <li>默认情况下不支持多色,直接添加多色图标会自动去色。</li>
196
+          </ul>
197
+          <blockquote>
198
+            <p>注意:新版 iconfont 支持两种方式引用多色图标:SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p>
199
+          </blockquote>
200
+          <p>Unicode 使用步骤如下:</p>
201
+          <h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
202
+<pre><code class="language-css"
203
+>@font-face {
204
+  font-family: 'iconfont';
205
+  src: url('iconfont.ttf?t=1769076349906') format('truetype');
206
+}
207
+</code></pre>
208
+          <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
209
+<pre><code class="language-css"
210
+>.iconfont {
211
+  font-family: "iconfont" !important;
212
+  font-size: 16px;
213
+  font-style: normal;
214
+  -webkit-font-smoothing: antialiased;
215
+  -moz-osx-font-smoothing: grayscale;
216
+}
217
+</code></pre>
218
+          <h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
219
+<pre>
220
+<code class="language-html"
221
+>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
222
+</code></pre>
223
+          <blockquote>
224
+            <p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
225
+          </blockquote>
226
+          </div>
227
+      </div>
228
+      <div class="content font-class">
229
+        <ul class="icon_lists dib-box">
230
+          
231
+          <li class="dib">
232
+            <span class="icon iconfont icon-tushu"></span>
233
+            <div class="name">
234
+              图书
235
+            </div>
236
+            <div class="code-name">.icon-tushu
237
+            </div>
238
+          </li>
239
+          
240
+          <li class="dib">
241
+            <span class="icon iconfont icon-liebiao"></span>
242
+            <div class="name">
243
+              列表
244
+            </div>
245
+            <div class="code-name">.icon-liebiao
246
+            </div>
247
+          </li>
248
+          
249
+          <li class="dib">
250
+            <span class="icon iconfont icon-biji"></span>
251
+            <div class="name">
252
+              笔记
253
+            </div>
254
+            <div class="code-name">.icon-biji
255
+            </div>
256
+          </li>
257
+          
258
+          <li class="dib">
259
+            <span class="icon iconfont icon-faxian"></span>
260
+            <div class="name">
261
+              发现
262
+            </div>
263
+            <div class="code-name">.icon-faxian
264
+            </div>
265
+          </li>
266
+          
267
+          <li class="dib">
268
+            <span class="icon iconfont icon-huiyuan"></span>
269
+            <div class="name">
270
+              会员
271
+            </div>
272
+            <div class="code-name">.icon-huiyuan
273
+            </div>
274
+          </li>
275
+          
276
+          <li class="dib">
277
+            <span class="icon iconfont icon-gongxiangqun"></span>
278
+            <div class="name">
279
+              共享群
280
+            </div>
281
+            <div class="code-name">.icon-gongxiangqun
282
+            </div>
283
+          </li>
284
+          
285
+          <li class="dib">
286
+            <span class="icon iconfont icon-shipin"></span>
287
+            <div class="name">
288
+              视频
289
+            </div>
290
+            <div class="code-name">.icon-shipin
291
+            </div>
292
+          </li>
293
+          
294
+          <li class="dib">
295
+            <span class="icon iconfont icon-shizi"></span>
296
+            <div class="name">
297
+              识字
298
+            </div>
299
+            <div class="code-name">.icon-shizi
300
+            </div>
301
+          </li>
302
+          
303
+          <li class="dib">
304
+            <span class="icon iconfont icon-qiandao"></span>
305
+            <div class="name">
306
+              签到
307
+            </div>
308
+            <div class="code-name">.icon-qiandao
309
+            </div>
310
+          </li>
311
+          
312
+          <li class="dib">
313
+            <span class="icon iconfont icon-beifen"></span>
314
+            <div class="name">
315
+              备份
316
+            </div>
317
+            <div class="code-name">.icon-beifen
318
+            </div>
319
+          </li>
320
+          
321
+          <li class="dib">
322
+            <span class="icon iconfont icon-fuwu"></span>
323
+            <div class="name">
324
+              服务
325
+            </div>
326
+            <div class="code-name">.icon-fuwu
327
+            </div>
328
+          </li>
329
+          
330
+          <li class="dib">
331
+            <span class="icon iconfont icon-quanzi"></span>
332
+            <div class="name">
333
+              圈子
334
+            </div>
335
+            <div class="code-name">.icon-quanzi
336
+            </div>
337
+          </li>
338
+          
339
+          <li class="dib">
340
+            <span class="icon iconfont icon-wendang"></span>
341
+            <div class="name">
342
+              文档
343
+            </div>
344
+            <div class="code-name">.icon-wendang
345
+            </div>
346
+          </li>
347
+          
348
+          <li class="dib">
349
+            <span class="icon iconfont icon-xiufu"></span>
350
+            <div class="name">
351
+              修复
352
+            </div>
353
+            <div class="code-name">.icon-xiufu
354
+            </div>
355
+          </li>
356
+          
357
+          <li class="dib">
358
+            <span class="icon iconfont icon-yunshouji"></span>
359
+            <div class="name">
360
+              云手机
361
+            </div>
362
+            <div class="code-name">.icon-yunshouji
363
+            </div>
364
+          </li>
365
+          
366
+          <li class="dib">
367
+            <span class="icon iconfont icon-dongtai"></span>
368
+            <div class="name">
369
+              动态
370
+            </div>
371
+            <div class="code-name">.icon-dongtai
372
+            </div>
373
+          </li>
374
+          
375
+          <li class="dib">
376
+            <span class="icon iconfont icon-cexinli"></span>
377
+            <div class="name">
378
+              测心理
379
+            </div>
380
+            <div class="code-name">.icon-cexinli
381
+            </div>
382
+          </li>
383
+          
384
+          <li class="dib">
385
+            <span class="icon iconfont icon-xiangce"></span>
386
+            <div class="name">
387
+              相册
388
+            </div>
389
+            <div class="code-name">.icon-xiangce
390
+            </div>
391
+          </li>
392
+          
393
+          <li class="dib">
394
+            <span class="icon iconfont icon-meitu"></span>
395
+            <div class="name">
396
+              美图
397
+            </div>
398
+            <div class="code-name">.icon-meitu
399
+            </div>
400
+          </li>
401
+          
402
+          <li class="dib">
403
+            <span class="icon iconfont icon-AIzhuanqu"></span>
404
+            <div class="name">
405
+              AI专区
406
+            </div>
407
+            <div class="code-name">.icon-AIzhuanqu
408
+            </div>
409
+          </li>
410
+          
411
+          <li class="dib">
412
+            <span class="icon iconfont icon-zidingyi"></span>
413
+            <div class="name">
414
+              自定义
415
+            </div>
416
+            <div class="code-name">.icon-zidingyi
417
+            </div>
418
+          </li>
419
+          
420
+          <li class="dib">
421
+            <span class="icon iconfont icon-zhinengduihua"></span>
422
+            <div class="name">
423
+              智能对话
424
+            </div>
425
+            <div class="code-name">.icon-zhinengduihua
426
+            </div>
427
+          </li>
428
+          
429
+        </ul>
430
+        <div class="article markdown">
431
+        <h2 id="font-class-">font-class 引用</h2>
432
+        <hr>
433
+
434
+        <p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
435
+        <p>与 Unicode 使用方式相比,具有如下特点:</p>
436
+        <ul>
437
+          <li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
438
+          <li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
439
+        </ul>
440
+        <p>使用步骤如下:</p>
441
+        <h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
442
+<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
443
+</code></pre>
444
+        <h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
445
+<pre><code class="language-html">&lt;span class="iconfont icon-xxx"&gt;&lt;/span&gt;
446
+</code></pre>
447
+        <blockquote>
448
+          <p>"
449
+            iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
450
+        </blockquote>
451
+      </div>
452
+      </div>
453
+      <div class="content symbol">
454
+          <ul class="icon_lists dib-box">
455
+          
456
+            <li class="dib">
457
+                <svg class="icon svg-icon" aria-hidden="true">
458
+                  <use xlink:href="#icon-tushu"></use>
459
+                </svg>
460
+                <div class="name">图书</div>
461
+                <div class="code-name">#icon-tushu</div>
462
+            </li>
463
+          
464
+            <li class="dib">
465
+                <svg class="icon svg-icon" aria-hidden="true">
466
+                  <use xlink:href="#icon-liebiao"></use>
467
+                </svg>
468
+                <div class="name">列表</div>
469
+                <div class="code-name">#icon-liebiao</div>
470
+            </li>
471
+          
472
+            <li class="dib">
473
+                <svg class="icon svg-icon" aria-hidden="true">
474
+                  <use xlink:href="#icon-biji"></use>
475
+                </svg>
476
+                <div class="name">笔记</div>
477
+                <div class="code-name">#icon-biji</div>
478
+            </li>
479
+          
480
+            <li class="dib">
481
+                <svg class="icon svg-icon" aria-hidden="true">
482
+                  <use xlink:href="#icon-faxian"></use>
483
+                </svg>
484
+                <div class="name">发现</div>
485
+                <div class="code-name">#icon-faxian</div>
486
+            </li>
487
+          
488
+            <li class="dib">
489
+                <svg class="icon svg-icon" aria-hidden="true">
490
+                  <use xlink:href="#icon-huiyuan"></use>
491
+                </svg>
492
+                <div class="name">会员</div>
493
+                <div class="code-name">#icon-huiyuan</div>
494
+            </li>
495
+          
496
+            <li class="dib">
497
+                <svg class="icon svg-icon" aria-hidden="true">
498
+                  <use xlink:href="#icon-gongxiangqun"></use>
499
+                </svg>
500
+                <div class="name">共享群</div>
501
+                <div class="code-name">#icon-gongxiangqun</div>
502
+            </li>
503
+          
504
+            <li class="dib">
505
+                <svg class="icon svg-icon" aria-hidden="true">
506
+                  <use xlink:href="#icon-shipin"></use>
507
+                </svg>
508
+                <div class="name">视频</div>
509
+                <div class="code-name">#icon-shipin</div>
510
+            </li>
511
+          
512
+            <li class="dib">
513
+                <svg class="icon svg-icon" aria-hidden="true">
514
+                  <use xlink:href="#icon-shizi"></use>
515
+                </svg>
516
+                <div class="name">识字</div>
517
+                <div class="code-name">#icon-shizi</div>
518
+            </li>
519
+          
520
+            <li class="dib">
521
+                <svg class="icon svg-icon" aria-hidden="true">
522
+                  <use xlink:href="#icon-qiandao"></use>
523
+                </svg>
524
+                <div class="name">签到</div>
525
+                <div class="code-name">#icon-qiandao</div>
526
+            </li>
527
+          
528
+            <li class="dib">
529
+                <svg class="icon svg-icon" aria-hidden="true">
530
+                  <use xlink:href="#icon-beifen"></use>
531
+                </svg>
532
+                <div class="name">备份</div>
533
+                <div class="code-name">#icon-beifen</div>
534
+            </li>
535
+          
536
+            <li class="dib">
537
+                <svg class="icon svg-icon" aria-hidden="true">
538
+                  <use xlink:href="#icon-fuwu"></use>
539
+                </svg>
540
+                <div class="name">服务</div>
541
+                <div class="code-name">#icon-fuwu</div>
542
+            </li>
543
+          
544
+            <li class="dib">
545
+                <svg class="icon svg-icon" aria-hidden="true">
546
+                  <use xlink:href="#icon-quanzi"></use>
547
+                </svg>
548
+                <div class="name">圈子</div>
549
+                <div class="code-name">#icon-quanzi</div>
550
+            </li>
551
+          
552
+            <li class="dib">
553
+                <svg class="icon svg-icon" aria-hidden="true">
554
+                  <use xlink:href="#icon-wendang"></use>
555
+                </svg>
556
+                <div class="name">文档</div>
557
+                <div class="code-name">#icon-wendang</div>
558
+            </li>
559
+          
560
+            <li class="dib">
561
+                <svg class="icon svg-icon" aria-hidden="true">
562
+                  <use xlink:href="#icon-xiufu"></use>
563
+                </svg>
564
+                <div class="name">修复</div>
565
+                <div class="code-name">#icon-xiufu</div>
566
+            </li>
567
+          
568
+            <li class="dib">
569
+                <svg class="icon svg-icon" aria-hidden="true">
570
+                  <use xlink:href="#icon-yunshouji"></use>
571
+                </svg>
572
+                <div class="name">云手机</div>
573
+                <div class="code-name">#icon-yunshouji</div>
574
+            </li>
575
+          
576
+            <li class="dib">
577
+                <svg class="icon svg-icon" aria-hidden="true">
578
+                  <use xlink:href="#icon-dongtai"></use>
579
+                </svg>
580
+                <div class="name">动态</div>
581
+                <div class="code-name">#icon-dongtai</div>
582
+            </li>
583
+          
584
+            <li class="dib">
585
+                <svg class="icon svg-icon" aria-hidden="true">
586
+                  <use xlink:href="#icon-cexinli"></use>
587
+                </svg>
588
+                <div class="name">测心理</div>
589
+                <div class="code-name">#icon-cexinli</div>
590
+            </li>
591
+          
592
+            <li class="dib">
593
+                <svg class="icon svg-icon" aria-hidden="true">
594
+                  <use xlink:href="#icon-xiangce"></use>
595
+                </svg>
596
+                <div class="name">相册</div>
597
+                <div class="code-name">#icon-xiangce</div>
598
+            </li>
599
+          
600
+            <li class="dib">
601
+                <svg class="icon svg-icon" aria-hidden="true">
602
+                  <use xlink:href="#icon-meitu"></use>
603
+                </svg>
604
+                <div class="name">美图</div>
605
+                <div class="code-name">#icon-meitu</div>
606
+            </li>
607
+          
608
+            <li class="dib">
609
+                <svg class="icon svg-icon" aria-hidden="true">
610
+                  <use xlink:href="#icon-AIzhuanqu"></use>
611
+                </svg>
612
+                <div class="name">AI专区</div>
613
+                <div class="code-name">#icon-AIzhuanqu</div>
614
+            </li>
615
+          
616
+            <li class="dib">
617
+                <svg class="icon svg-icon" aria-hidden="true">
618
+                  <use xlink:href="#icon-zidingyi"></use>
619
+                </svg>
620
+                <div class="name">自定义</div>
621
+                <div class="code-name">#icon-zidingyi</div>
622
+            </li>
623
+          
624
+            <li class="dib">
625
+                <svg class="icon svg-icon" aria-hidden="true">
626
+                  <use xlink:href="#icon-zhinengduihua"></use>
627
+                </svg>
628
+                <div class="name">智能对话</div>
629
+                <div class="code-name">#icon-zhinengduihua</div>
630
+            </li>
631
+          
632
+          </ul>
633
+          <div class="article markdown">
634
+          <h2 id="symbol-">Symbol 引用</h2>
635
+          <hr>
636
+
637
+          <p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
638
+            这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
639
+          <ul>
640
+            <li>支持多色图标了,不再受单色限制。</li>
641
+            <li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
642
+            <li>兼容性较差,支持 IE9+,及现代浏览器。</li>
643
+            <li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
644
+          </ul>
645
+          <p>使用步骤如下:</p>
646
+          <h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
647
+<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
648
+</code></pre>
649
+          <h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
650
+<pre><code class="language-html">&lt;style&gt;
651
+.icon {
652
+  width: 1em;
653
+  height: 1em;
654
+  vertical-align: -0.15em;
655
+  fill: currentColor;
656
+  overflow: hidden;
657
+}
658
+&lt;/style&gt;
659
+</code></pre>
660
+          <h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
661
+<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
662
+  &lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
663
+&lt;/svg&gt;
664
+</code></pre>
665
+          </div>
666
+      </div>
667
+
668
+    </div>
669
+  </div>
670
+  <script>
671
+  $(document).ready(function () {
672
+      $('.tab-container .content:first').show()
673
+
674
+      $('#tabs li').click(function (e) {
675
+        var tabContent = $('.tab-container .content')
676
+        var index = $(this).index()
677
+
678
+        if ($(this).hasClass('active')) {
679
+          return
680
+        } else {
681
+          $('#tabs li').removeClass('active')
682
+          $(this).addClass('active')
683
+
684
+          tabContent.hide().eq(index).fadeIn()
685
+        }
686
+      })
687
+    })
688
+  </script>
689
+</body>
690
+</html>

+ 101 - 0
src/assets/font/iconfont.css

@@ -0,0 +1,101 @@
1
+@font-face {
2
+  font-family: "iconfont"; /* Project id  */
3
+  src: url('iconfont.ttf?t=1769076349906') format('truetype');
4
+}
5
+
6
+.iconfont {
7
+  font-family: "iconfont" !important;
8
+  font-size: 16px;
9
+  font-style: normal;
10
+  -webkit-font-smoothing: antialiased;
11
+  -moz-osx-font-smoothing: grayscale;
12
+}
13
+
14
+.icon-tushu:before {
15
+  content: "\f00a1";
16
+}
17
+
18
+.icon-liebiao:before {
19
+  content: "\e627";
20
+}
21
+
22
+.icon-biji:before {
23
+  content: "\e6ce";
24
+}
25
+
26
+.icon-faxian:before {
27
+  content: "\e6cf";
28
+}
29
+
30
+.icon-huiyuan:before {
31
+  content: "\e6d0";
32
+}
33
+
34
+.icon-gongxiangqun:before {
35
+  content: "\e6d1";
36
+}
37
+
38
+.icon-shipin:before {
39
+  content: "\e6d2";
40
+}
41
+
42
+.icon-shizi:before {
43
+  content: "\e6d3";
44
+}
45
+
46
+.icon-qiandao:before {
47
+  content: "\e6d4";
48
+}
49
+
50
+.icon-beifen:before {
51
+  content: "\e6d5";
52
+}
53
+
54
+.icon-fuwu:before {
55
+  content: "\e6d6";
56
+}
57
+
58
+.icon-quanzi:before {
59
+  content: "\e6d7";
60
+}
61
+
62
+.icon-wendang:before {
63
+  content: "\e6d8";
64
+}
65
+
66
+.icon-xiufu:before {
67
+  content: "\e6d9";
68
+}
69
+
70
+.icon-yunshouji:before {
71
+  content: "\e6da";
72
+}
73
+
74
+.icon-dongtai:before {
75
+  content: "\e6db";
76
+}
77
+
78
+.icon-cexinli:before {
79
+  content: "\e6dc";
80
+}
81
+
82
+.icon-xiangce:before {
83
+  content: "\e6dd";
84
+}
85
+
86
+.icon-meitu:before {
87
+  content: "\e6de";
88
+}
89
+
90
+.icon-AIzhuanqu:before {
91
+  content: "\e6df";
92
+}
93
+
94
+.icon-zidingyi:before {
95
+  content: "\e6e0";
96
+}
97
+
98
+.icon-zhinengduihua:before {
99
+  content: "\e6e1";
100
+}
101
+

Файловите разлики са ограничени, защото са твърде много
+ 1 - 0
src/assets/font/iconfont.js


+ 163 - 0
src/assets/font/iconfont.json

@@ -0,0 +1,163 @@
1
+{
2
+  "id": "",
3
+  "name": "",
4
+  "font_family": "iconfont",
5
+  "css_prefix_text": "icon-",
6
+  "description": "",
7
+  "glyphs": [
8
+    {
9
+      "icon_id": "1090",
10
+      "name": "图书",
11
+      "font_class": "tushu",
12
+      "unicode": "f00a1",
13
+      "unicode_decimal": 983201
14
+    },
15
+    {
16
+      "icon_id": "7831447",
17
+      "name": "列表",
18
+      "font_class": "liebiao",
19
+      "unicode": "e627",
20
+      "unicode_decimal": 58919
21
+    },
22
+    {
23
+      "icon_id": "46348424",
24
+      "name": "笔记",
25
+      "font_class": "biji",
26
+      "unicode": "e6ce",
27
+      "unicode_decimal": 59086
28
+    },
29
+    {
30
+      "icon_id": "46348425",
31
+      "name": "发现",
32
+      "font_class": "faxian",
33
+      "unicode": "e6cf",
34
+      "unicode_decimal": 59087
35
+    },
36
+    {
37
+      "icon_id": "46348426",
38
+      "name": "会员",
39
+      "font_class": "huiyuan",
40
+      "unicode": "e6d0",
41
+      "unicode_decimal": 59088
42
+    },
43
+    {
44
+      "icon_id": "46348427",
45
+      "name": "共享群",
46
+      "font_class": "gongxiangqun",
47
+      "unicode": "e6d1",
48
+      "unicode_decimal": 59089
49
+    },
50
+    {
51
+      "icon_id": "46348428",
52
+      "name": "视频",
53
+      "font_class": "shipin",
54
+      "unicode": "e6d2",
55
+      "unicode_decimal": 59090
56
+    },
57
+    {
58
+      "icon_id": "46348429",
59
+      "name": "识字",
60
+      "font_class": "shizi",
61
+      "unicode": "e6d3",
62
+      "unicode_decimal": 59091
63
+    },
64
+    {
65
+      "icon_id": "46348430",
66
+      "name": "签到",
67
+      "font_class": "qiandao",
68
+      "unicode": "e6d4",
69
+      "unicode_decimal": 59092
70
+    },
71
+    {
72
+      "icon_id": "46348431",
73
+      "name": "备份",
74
+      "font_class": "beifen",
75
+      "unicode": "e6d5",
76
+      "unicode_decimal": 59093
77
+    },
78
+    {
79
+      "icon_id": "46348432",
80
+      "name": "服务",
81
+      "font_class": "fuwu",
82
+      "unicode": "e6d6",
83
+      "unicode_decimal": 59094
84
+    },
85
+    {
86
+      "icon_id": "46348433",
87
+      "name": "圈子",
88
+      "font_class": "quanzi",
89
+      "unicode": "e6d7",
90
+      "unicode_decimal": 59095
91
+    },
92
+    {
93
+      "icon_id": "46348434",
94
+      "name": "文档",
95
+      "font_class": "wendang",
96
+      "unicode": "e6d8",
97
+      "unicode_decimal": 59096
98
+    },
99
+    {
100
+      "icon_id": "46348435",
101
+      "name": "修复",
102
+      "font_class": "xiufu",
103
+      "unicode": "e6d9",
104
+      "unicode_decimal": 59097
105
+    },
106
+    {
107
+      "icon_id": "46348436",
108
+      "name": "云手机",
109
+      "font_class": "yunshouji",
110
+      "unicode": "e6da",
111
+      "unicode_decimal": 59098
112
+    },
113
+    {
114
+      "icon_id": "46348437",
115
+      "name": "动态",
116
+      "font_class": "dongtai",
117
+      "unicode": "e6db",
118
+      "unicode_decimal": 59099
119
+    },
120
+    {
121
+      "icon_id": "46348438",
122
+      "name": "测心理",
123
+      "font_class": "cexinli",
124
+      "unicode": "e6dc",
125
+      "unicode_decimal": 59100
126
+    },
127
+    {
128
+      "icon_id": "46348439",
129
+      "name": "相册",
130
+      "font_class": "xiangce",
131
+      "unicode": "e6dd",
132
+      "unicode_decimal": 59101
133
+    },
134
+    {
135
+      "icon_id": "46348440",
136
+      "name": "美图",
137
+      "font_class": "meitu",
138
+      "unicode": "e6de",
139
+      "unicode_decimal": 59102
140
+    },
141
+    {
142
+      "icon_id": "46348441",
143
+      "name": "AI专区",
144
+      "font_class": "AIzhuanqu",
145
+      "unicode": "e6df",
146
+      "unicode_decimal": 59103
147
+    },
148
+    {
149
+      "icon_id": "46348442",
150
+      "name": "自定义",
151
+      "font_class": "zidingyi",
152
+      "unicode": "e6e0",
153
+      "unicode_decimal": 59104
154
+    },
155
+    {
156
+      "icon_id": "46348443",
157
+      "name": "智能对话",
158
+      "font_class": "zhinengduihua",
159
+      "unicode": "e6e1",
160
+      "unicode_decimal": 59105
161
+    }
162
+  ]
163
+}

BIN
src/assets/font/iconfont.ttf


+ 7 - 5
src/components/fg-tree/fg-tree.vue

@@ -14,18 +14,20 @@
14 14
 </template>
15 15
 
16 16
 <script setup lang="ts">
17
+// @ts-ignore
17 18
 import { defineProps, defineEmits } from 'vue'
18 19
 import FgTreeNode from './fg-tree-node.vue'
19 20
 
20 21
 const props = defineProps({
21 22
   data: {
22 23
     type: Array,
23
-    default: () => []
24
-  },
24
+    default: () => [],
25
+  } as any,
26
+  
25 27
   defaultExpandedKeys: {
26 28
     type: Array,
27
-    default: () => []
28
-  }
29
+    default: () => [],
30
+  },
29 31
 })
30 32
 
31 33
 const emit = defineEmits(['node-click', 'node-expand', 'node-collapse'])
@@ -40,4 +42,4 @@ const emit = defineEmits(['node-click', 'node-expand', 'node-collapse'])
40 42
 //   padding: 20rpx;
41 43
 //   overflow: auto;
42 44
 // }
43
-</style>
45
+</style>

+ 2 - 0
src/main.ts

@@ -3,6 +3,8 @@ import App from './App.vue'
3 3
 import { requestInterceptor } from './http/interceptor'
4 4
 import i18n from './locale/index'
5 5
 import { routeInterceptor } from './router/interceptor'
6
+import '@/assets/font/iconfont.css';
7
+import '@/assets/font/iconfont.js';
6 8
 
7 9
 import store from './store'
8 10
 import '@/style/index.scss'

+ 134 - 83
src/pages/knowledge/index.vue

@@ -1,56 +1,41 @@
1 1
 <script setup lang="ts">
2
-import { ref } from 'vue'
3
-import searchimg from '@/assets/searchimgs.png'
4
-const list = ref([
5
-  {
6
-    backcolor: '#215ACD',
7
-  },
8
-  {
9
-    backcolor: '#38B865',
10
-  },
11
-  {
12
-    backcolor: '#EB5E12',
13
-  },
14
-  {
15
-    backcolor: '#215ACD',
16
-  },
17
-  {
18
-    backcolor: '#215ACD',
19
-  },
20
-  {
21
-    backcolor: '#38B865',
22
-  },
23
-  {
24
-    backcolor: '#215ACD',
25
-  },
26
-  {
27
-    backcolor: '#38B865',
28
-  },
29
-  {
30
-    backcolor: '#EB5E12',
31
-  },
32
-  {
33
-    backcolor: '#8848D7',
34
-  },
35
-  {
36
-    backcolor: '#EB5E12',
37
-  },
38
-  {
39
-    backcolor: '#8848D7',
40
-  },
41
-  {
42
-    backcolor: '#38B865',
43
-  },
44
-  {
45
-    backcolor: '#EB5E12',
46
-  },
47
-  {
48
-    backcolor: '#8848D7',
49
-  },
50
-  {
51
-    backcolor: '#8848D7',
52
-  },
53
-])
2
+import { ref, onMounted } from 'vue'
3
+import defimage from '@/assets/image.png'
4
+import { queryrecentviewlistAPI } from '@/api/knowledge/index'
5
+const list = ref([])
6
+const isloading = ref(false)
7
+const pageNum = ref(1)
8
+const pageSize = ref(10)
9
+const total = ref(0)
10
+const queryrecentviewlistAPIfn = async (loadMore = false) => {
11
+  try {
12
+    isloading.value = true
13
+    const res = (await queryrecentviewlistAPI({
14
+      pageNum: pageNum.value,
15
+      pageSize: pageSize.value,
16
+    })) as any
17
+    if (res.code === 200) {
18
+      if (loadMore) {
19
+        list.value = [...list.value, ...(res?.rows || [])]
20
+      } else {
21
+        list.value = res?.rows
22
+      }
23
+      total.value = res?.total
24
+    }
25
+    console.log(res)
26
+  } catch (err) {
27
+    uni.showToast({
28
+      title: '加载失败',
29
+      icon: 'none',
30
+    })
31
+  } finally {
32
+    isloading.value = false
33
+  }
34
+}
35
+
36
+onLoad(() => {
37
+  queryrecentviewlistAPIfn()
38
+})
54 39
 const handleKnowledgeSearch = () => {
55 40
   uni.navigateTo({
56 41
     url: '/pages/knowledge/search/index',
@@ -61,9 +46,24 @@ const handleMyExamination = () => {
61 46
     url: '/pages/knowledge/exam/index',
62 47
   })
63 48
 }
49
+
50
+const handleLoadMore = async () => {
51
+  if (list.value.length >= total.value) {
52
+    uni.showToast({
53
+      title: '没有更多数据了',
54
+      icon: 'none',
55
+    })
56
+    return
57
+  }
58
+  pageNum.value++
59
+  await queryrecentviewlistAPIfn(true)
60
+}
64 61
 </script>
65 62
 <template>
66 63
   <view class="knowledge">
64
+    <view v-if="isloading" class="loading-container">
65
+      <wd-loading size="40px" color="#215ACD"></wd-loading>
66
+    </view>
67 67
     <view class="header_nav">知识学院</view>
68 68
     <view class="header_nav_item">
69 69
       <view class="header_nav_item_items" @tap="handleKnowledgeSearch">
@@ -75,25 +75,50 @@ const handleMyExamination = () => {
75 75
         <view class="header_nav_item_items_icon right_items"></view>
76 76
       </view>
77 77
     </view>
78
-    <view class="main_list">
78
+    <scroll-view
79
+      class="main_list"
80
+      :scroll-y="true"
81
+      @scrolltolower="handleLoadMore"
82
+    >
79 83
       <view class="main_list_title">最近查看</view>
80 84
       <view class="main_list_items" v-for="(item, index) in list" :key="index">
81
-        <view
82
-          class="main_list_items_icon"
83
-          :style="{ background: item.backcolor }"
84
-        >
85
-          <view
86
-            class="main_list_items_icon_line"
87
-            v-for="(line, lineIndex) in 3"
88
-            :key="lineIndex"
89
-          ></view>
85
+        <view class="main_list_items_icon">
86
+          <text
87
+            v-if="item?.icon?.includes('iconfont')"
88
+            :class="[item.icon.split(',')[0]]"
89
+            :style="{ color: item.icon.split(',')[1], 'font-size': '48rpx' }"
90
+          ></text>
91
+          <image
92
+            v-else-if="item?.attachmentUrl.length > 0"
93
+            style="width: 100%; height: 100%; border-radius: 20rpx"
94
+            :src="item?.attachmentUrl[0]"
95
+            alt=""
96
+          />
97
+          <!-- iconfont icon-tushu,#1890ff,blue-book -->
98
+          <text
99
+            v-else
100
+            class="iconfont icon-tushu"
101
+            style="font-size: 48rpx; color: #1890ff"
102
+          ></text>
90 103
         </view>
91 104
         <view class="main_list_items_text">
92
-          <span>我的文件</span>
93
-          <span>文档介绍</span>
105
+          <span>{{ item.title }}</span>
106
+          <span>暂无介绍</span>
94 107
         </view>
95 108
       </view>
96
-    </view>
109
+      <view v-if="isloading && list.length > 0" class="load-more">
110
+        <wd-loading size="20px" color="#215ACD"></wd-loading>
111
+        <text style="margin-left: 10rpx; font-size: 24rpx; color: #86909c"
112
+          >加载中...</text
113
+        >
114
+      </view>
115
+      <view
116
+        v-if="!isloading && list.length > 0 && list.length >= total"
117
+        class="load-more"
118
+      >
119
+        <text style="font-size: 24rpx; color: #86909c">- 暂无数据 -</text>
120
+      </view>
121
+    </scroll-view>
97 122
   </view>
98 123
 </template>
99 124
 <style scoped lang="scss">
@@ -161,7 +186,7 @@ body {
161 186
     }
162 187
   }
163 188
   .main_list {
164
-    flex: 0.9;
189
+    flex: 1;
165 190
     width: 100%;
166 191
     // background-color: red;
167 192
     min-height: 0;
@@ -169,6 +194,9 @@ body {
169 194
     flex-direction: column;
170 195
     gap: 42rpx;
171 196
     overflow-y: auto;
197
+    overflow-x: hidden;
198
+    box-sizing: border-box;
199
+    padding-bottom: 150rpx;
172 200
     .main_list_title {
173 201
       font-family: Alibaba PuHuiTi 2;
174 202
       font-weight: 500;
@@ -178,10 +206,11 @@ body {
178 206
       line-height: 36rpx;
179 207
       letter-spacing: 0px;
180 208
       color: #31373d;
181
-      // position: sticky;
182
-      // top: 0;
183
-      // z-index: 1;
184
-      // background-color: #ffffff;
209
+      margin-bottom: 42rpx;
210
+      //  position: sticky;
211
+      //  top: 0;
212
+      //  z-index: 1;
213
+      //  background-color: #ffffff;
185 214
     }
186 215
     .main_list_items {
187 216
       width: 100%;
@@ -190,12 +219,15 @@ body {
190 219
       box-sizing: border-box;
191 220
       display: flex;
192 221
       gap: 16rpx;
222
+      margin-bottom: 42rpx;
193 223
 
194 224
       // background-color: aqua;
195 225
       .main_list_items_text {
196 226
         display: flex;
197 227
         flex-direction: column;
198 228
         justify-content: space-between;
229
+        flex: 1;
230
+        overflow: hidden;
199 231
         :nth-child(1) {
200 232
           font-family: Alibaba PuHuiTi 2;
201 233
           font-weight: 500;
@@ -205,6 +237,9 @@ body {
205 237
           line-height: 32rpx;
206 238
           letter-spacing: 0px;
207 239
           color: #31373d;
240
+          white-space: nowrap;
241
+          overflow: hidden;
242
+          text-overflow: ellipsis;
208 243
         }
209 244
         :nth-child(2) {
210 245
           font-family: Alibaba PuHuiTi 2;
@@ -215,29 +250,45 @@ body {
215 250
           line-height: 28rpx;
216 251
           letter-spacing: 0px;
217 252
           color: #86909c;
253
+          white-space: nowrap;
254
+          overflow: hidden;
255
+          text-overflow: ellipsis;
218 256
         }
219 257
       }
220 258
       .main_list_items_icon {
221 259
         width: 74rpx;
222 260
         height: 86rpx;
223
-        border-radius: 20rpx;
224
-        padding: 20rpx;
225
-        box-sizing: border-box;
261
+        // border-radius: 20rpx;
262
+        // padding: 20rpx;
263
+        // box-sizing: border-box;
226 264
         display: flex;
227 265
         flex-direction: column;
228 266
         justify-content: space-between;
229
-        .main_list_items_icon_line {
230
-          width: 100%;
231
-          height: 6rpx;
232
-          border-radius: 4rpx;
233
-          background-color: #ffffff;
234
-          &:nth-child(1) {
235
-            width: 60%;
236
-          }
237
-        }
267
+        flex-shrink: 0;
238 268
       }
239 269
     }
240 270
   }
241 271
 }
242
-</style>
272
+.loading-container {
273
+  position: fixed;
274
+  top: 0;
275
+  left: 0;
276
+  width: 100%;
277
+  height: 100%;
278
+  background-color: rgba(255, 255, 255, 0.8);
279
+  display: flex;
280
+  justify-content: center;
281
+  align-items: center;
282
+  z-index: 9999;
283
+}
243 284
 
285
+.load-more {
286
+  width: 100%;
287
+  height: 80rpx;
288
+  display: flex;
289
+  justify-content: center;
290
+  align-items: center;
291
+  margin-top: 20rpx;
292
+  margin-bottom: 20rpx;
293
+}
294
+</style>

+ 69 - 81
src/pages/knowledge/search/details/index.vue

@@ -1,94 +1,48 @@
1
-<template>
2
-  <view class="knowledgebase_details">
3
-    <view class="header_details">
4
-      <input class="details_input" type="text" placeholder="搜索" />
5
-    </view>
6
-    <view class="main_list">
7
-      <view class="main_list_title">主页</view>
8
-      <div class="main_tree">
9
-        <FgTree
10
-          :data="treeData"
11
-          :default-expanded-keys="[1, 3]"
12
-          @node-click="handleNodeClick"
13
-          @node-expand="handleNodeExpand"
14
-          @node-collapse="handleNodeCollapse"
15
-        />
16
-      </div>
17
-    </view>
18
-  </view>
19
-</template>
20
-
21 1
 <script setup lang="ts">
22 2
 import { ref } from 'vue'
23 3
 import FgTree from '@/components/fg-tree/fg-tree.vue'
24
-
4
+import { queryKnowledgeContentlist } from '@/api/knowledge/index'
25 5
 interface TreeNode {
26 6
   id: number
27 7
   label: string
28 8
   children?: TreeNode[]
29 9
 }
30
-
31
-const treeData = ref<TreeNode[]>([
32
-  {
33
-    id: 1,
34
-    label: '一级节点 1',
35
-    children: [
36
-      {
37
-        id: 11,
38
-        label: '二级节点 1-1',
39
-        children: [
40
-          {
41
-            id: 111,
42
-            label: '三级节点 1-1-1',
43
-          },
44
-          {
45
-            id: 112,
46
-            label: '三级节点 1-1-2',
47
-          },
48
-        ],
49
-      },
50
-      {
51
-        id: 12,
52
-        label: '二级节点 1-2',
53
-      },
54
-    ],
55
-  },
56
-  {
57
-    id: 2,
58
-    label: '一级节点 2',
59
-    children: [
60
-      {
61
-        id: 21,
62
-        label: '二级节点 2-1',
63
-      },
64
-      {
65
-        id: 22,
66
-        label: '二级节点 2-2',
67
-      },
68
-    ],
69
-  },
70
-  {
71
-    id: 3,
72
-    label: '一级节点 3',
73
-    children: [
74
-      {
75
-        id: 31,
76
-        label: '二级节点 3-1',
77
-        children: [
78
-          {
79
-            id: 311,
80
-            label: '三级节点 3-1-1',
81
-          },
82
-        ],
83
-      },
84
-    ],
85
-  },
86
-])
10
+const paramsoptions = ref({}) as any
11
+const treeData = ref<TreeNode[]>([])
12
+const isloading = ref(false)
13
+//获取树形列表
14
+const queryKnowledgeContentlistfn = async () => {
15
+  try {
16
+    isloading.value = true
17
+    const res = (await queryKnowledgeContentlist({
18
+      categoryId: paramsoptions.value?.id,
19
+    })) as any
20
+    if (res.code === 200) {
21
+      const deepTree = (item: any) => {
22
+        return {
23
+          id: item.id,
24
+          label: item.title,
25
+          children: item?.children?.map((child: any) => {
26
+            return deepTree(child)
27
+          }),
28
+        }
29
+      }
30
+      treeData.value = res?.data?.map((item: any) => deepTree(item))
31
+    }
32
+  } catch (error) {
33
+    console.log(error)
34
+  } finally {
35
+    isloading.value = false
36
+  }
37
+}
38
+onLoad(async (options) => {
39
+  paramsoptions.value = options
40
+  await queryKnowledgeContentlistfn()
41
+})
87 42
 
88 43
 const handleNodeClick = (node: TreeNode) => {
89
-  console.log('点击节点:', node)
90 44
   uni.navigateTo({
91
-    url: '/pages/knowledge/search/details/viewdetails/index',
45
+    url: `/pages/knowledge/search/details/viewdetails/index?id=${node?.id}&classId=${paramsoptions.value?.id}`,
92 46
   })
93 47
 }
94 48
 
@@ -100,6 +54,28 @@ const handleNodeCollapse = (node: TreeNode) => {
100 54
   console.log('折叠节点:', node)
101 55
 }
102 56
 </script>
57
+<template>
58
+  <view class="knowledgebase_details">
59
+    <view v-if="isloading" class="loading-container">
60
+      <wd-loading size="40px" color="#215ACD"></wd-loading>
61
+    </view>
62
+    <view class="header_details">
63
+      <input class="details_input" type="text" placeholder="搜索" />
64
+    </view>
65
+    <view class="main_list">
66
+      <view class="main_list_title">{{ paramsoptions?.name }}</view>
67
+      <div class="main_tree">
68
+        <FgTree
69
+          :data="treeData"
70
+          :default-expanded-keys="[1, 3]"
71
+          @node-click="handleNodeClick"
72
+          @node-expand="handleNodeExpand"
73
+          @node-collapse="handleNodeCollapse"
74
+        />
75
+      </div>
76
+    </view>
77
+  </view>
78
+</template>
103 79
 
104 80
 <style scoped lang="scss">
105 81
 html,
@@ -121,7 +97,7 @@ body {
121 97
       width: 100%;
122 98
       height: 100%;
123 99
       background-color: #f6f6f6;
124
-      background-image: url('../searchicon.png');
100
+      background-image: url('../../../../assets/searchicon.png');
125 101
       background-repeat: no-repeat;
126 102
       background-position: 20rpx center;
127 103
       background-size: 30rpx 30rpx;
@@ -156,4 +132,16 @@ body {
156 132
     }
157 133
   }
158 134
 }
135
+.loading-container {
136
+  position: fixed;
137
+  top: 0;
138
+  left: 0;
139
+  width: 100%;
140
+  height: 100%;
141
+  background-color: rgba(255, 255, 255, 0.8);
142
+  display: flex;
143
+  justify-content: center;
144
+  align-items: center;
145
+  z-index: 9999;
146
+}
159 147
 </style>

+ 467 - 94
src/pages/knowledge/search/details/viewdetails/index.vue

@@ -1,5 +1,16 @@
1 1
 <script setup lang="ts">
2
-import { ref } from 'vue'
2
+import { ref, reactive } from 'vue'
3
+import {
4
+  getKnowledgeContentDetail,
5
+  querycomment,
6
+  addComment,
7
+  queryrecord,
8
+} from '@/api/knowledge/index'
9
+import { uploadUrl } from '@/utils/uploadFile'
10
+import { useUserStore } from '@/store/user'
11
+const userStore = useUserStore()
12
+const uploadAction = uploadUrl.USER_AVATAR
13
+const isloading = ref(false)
3 14
 const footernav = ref([
4 15
   {
5 16
     name: '评论',
@@ -7,58 +18,214 @@ const footernav = ref([
7 18
   {
8 19
     name: '查看记录',
9 20
   },
10
-  {
11
-    name: '收藏记录',
12
-  },
13 21
 ])
22
+const replyContents = reactive({})
23
+const handleReplyInput = (e: any, commentId: string) => {
24
+  replyContents[commentId] = e.detail.value
25
+}
14 26
 const selected = ref('评论')
15
-const commentlist = ref([
16
-  {
17
-    name: '静静(站长)',
18
-    time: '3小时前',
19
-    content:
20
-      '评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容。',
21
-    reply: '张三:谢谢站长支持',
22
-  },
23
-  {
24
-    name: '静静(站长)',
25
-    time: '3小时前',
26
-    content:
27
-      '评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容。',
28
-    reply: '张三:谢谢站长支持',
29
-  },
30
-  {
31
-    name: '静静(站长)',
32
-    time: '3小时前',
33
-    content:
34
-      '评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容评论内容。',
35
-    reply: '张三:谢谢站长支持',
36
-  },
37
-])
27
+const commentlist = ref([]) as any
28
+const paramsoptions = ref({}) as any
29
+const maindata = ref({}) as any
30
+const isReply = ref({}) as any
31
+const commentipt = ref<string>('')
32
+const fileListup = ref([])
33
+const viewRecords = ref([])
34
+// 控制回复内容展开/收起的状态
35
+const expandedReplies = ref({}) as any
36
+//获取知识库内容详细信息
37
+const queryKnowledgeContentDetailfn = async () => {
38
+  try {
39
+    isloading.value = true
40
+    const res = (await getKnowledgeContentDetail({
41
+      roleId: paramsoptions.value?.id,
42
+    })) as any
43
+    if (res.code === 200) {
44
+      maindata.value = res?.data || {}
45
+    }
46
+  } catch (error) {
47
+    console.log(error)
48
+  } finally {
49
+    isloading.value = false
50
+  }
51
+}
52
+//获取评论列表
53
+const querycommentfn = async () => {
54
+  try {
55
+    isloading.value = true
56
+    const res = (await querycomment({
57
+      targetId: '14',
58
+      targetType: 'knowledge',
59
+    })) as any
60
+    if (res.code === 200) {
61
+      commentlist.value = res?.data || []
62
+    }
63
+  } catch (error) {
64
+    console.log(error)
65
+  } finally {
66
+    isloading.value = false
67
+  }
68
+}
69
+//获取查看记录
70
+const queryrecordfn = async () => {
71
+  try {
72
+    isloading.value = true
73
+    const res = (await queryrecord({
74
+      contentId: paramsoptions.value?.classId,
75
+      userId: userStore.userInfo.user.userId,
76
+    })) as any
77
+    viewRecords.value = res?.rows || []
78
+  } catch (error) {
79
+    console.log(error)
80
+  } finally {
81
+    isloading.value = false
82
+  }
83
+}
84
+onLoad(async (options) => {
85
+  paramsoptions.value = options
86
+  await Promise.all([
87
+    queryKnowledgeContentDetailfn(),
88
+    querycommentfn(),
89
+    queryrecordfn(),
90
+  ])
91
+})
38 92
 const navigateToReminder = () => {
39 93
   uni.navigateTo({
40 94
     url: '/pages/knowledge/search/details/viewdetails/reminder',
41 95
   })
42 96
 }
97
+const formatRelativeTime = (dateString: any) => {
98
+  const date = new Date(dateString)
99
+  const now = new Date()
100
+  const diff = now.getTime() - date.getTime()
101
+  if (diff < 60_000) {
102
+    return '刚刚'
103
+  }
104
+  const minutes = Math.floor(diff / 60_000)
105
+  const hours = Math.floor(diff / 3_600_000)
106
+  const days = Math.floor(diff / 86_400_000)
107
+
108
+  if (minutes < 60) {
109
+    return `${minutes}分钟前`
110
+  } else if (hours < 24) {
111
+    return `${hours}小时前`
112
+  } else {
113
+    return `${days}天前`
114
+  }
115
+}
116
+const download = (url) => {
117
+  uni.downloadFile({
118
+    url: url,
119
+    success: (res) => {
120
+      if (res.statusCode === 200) {
121
+        // uni.saveFile({
122
+        //   tempFilePath: res.tempFilePath,
123
+        //   success: function (res) {
124
+        //     console.log(res);
125
+        //   },
126
+        // })
127
+      }
128
+    },
129
+  })
130
+}
131
+// 提交评论
132
+const handleSend = async () => {
133
+  if (!commentipt.value.trim() && fileListup.value.length === 0) {
134
+    uni.showToast({
135
+      icon: 'error',
136
+      title: '请输入评论内容或上传图片',
137
+    })
138
+    return
139
+  }
140
+  try {
141
+    await addComment({
142
+      targetId: Number(paramsoptions.value?.classId),
143
+      targetType: 'knowledge',
144
+      attachments: fileListup.value
145
+        .map((item) => JSON.parse(item.response).data.fileName)
146
+        .join(','),
147
+      content: commentipt.value,
148
+    })
149
+    commentipt.value = ''
150
+    fileListup.value = []
151
+    querycommentfn()
152
+  } catch {
153
+    uni.showToast({
154
+      icon: 'error',
155
+      title: '评论提交失败',
156
+    })
157
+  }
158
+}
159
+
160
+const handleUploadSuccess = ({ file, fileList, formData }) => {
161
+  fileListup.value = fileList
162
+}
163
+const handleUploadRemove = ({ file }) => {
164
+  fileListup.value = fileListup.value.filter((item) => item.uid !== file.uid)
165
+}
166
+const handleReply = (data) => {
167
+  isReply.value[data.id] = !isReply.value[data.id]
168
+}
169
+const handleClose = (id) => {
170
+  isReply.value[id] = false
171
+}
172
+const handleReplySubmit = async (id: any) => {
173
+  console.log(replyContents)
174
+  if (!replyContents[id].trim()) {
175
+    uni.showToast({
176
+      icon: 'error',
177
+      title: '评论提交失败',
178
+    })
179
+    return
180
+  }
181
+  try {
182
+    await addComment({
183
+      parentId: id,
184
+      targetId: Number(paramsoptions.value?.classId),
185
+      targetType: 'knowledge',
186
+      content: replyContents[id] || '',
187
+    })
188
+    querycommentfn()
189
+    isReply.value[id] = false
190
+    replyContents[id] = ''
191
+  } catch {
192
+    uni.showToast({
193
+      icon: 'error',
194
+      title: '评论提交失败',
195
+    })
196
+  }
197
+}
198
+const toggleReplyExpand = (commentId: string, replyIndex: any) => {
199
+  const key = `${commentId}-${replyIndex}`
200
+  expandedReplies.value[key] = !expandedReplies.value[key]
201
+}
43 202
 </script>
44 203
 <template>
45 204
   <view class="viewdetails">
205
+    <view v-if="isloading" class="loading-container">
206
+      <wd-loading size="40px" color="#215ACD"></wd-loading>
207
+    </view>
46 208
     <view class="viewdetails_header">
47
-      <view class="viewdetails_header_title"> 主页 </view>
48
-      <view class="viewdetails_header_time"> 编辑于2025-01-17 18:12:38 </view>
209
+      <view class="viewdetails_header_title">
210
+        {{ maindata?.title || '' }}
211
+      </view>
212
+      <view class="viewdetails_header_time">
213
+        {{ `编辑于${maindata?.updateTime || ''}` }}
214
+      </view>
49 215
     </view>
50 216
     <view class="viewdetails_main_box">
51
-      <view class="viewdetails_main" v-for="value in 5">
52
-        <view class="viewdetails_main_title"> 编辑内容 </view>
53
-        <view class="viewdetails_main_content">
54
-          正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文正文
55
-        </view>
217
+      <view class="viewdetails_main">
218
+        <view v-html="maindata?.content || ''"></view>
56 219
       </view>
57 220
       <view class="viewdetails_upload_box">
58
-        <view class="viewdetails_upload" v-for="value in 2">
221
+        <view
222
+          class="viewdetails_upload"
223
+          @click="download(value)"
224
+          v-for="value in maindata?.attachmentUrl"
225
+        >
59 226
           <view class="viewdetails_upload_title">
60
-            <span>MWwwwwww.png</span>
61
-            <span>365kb</span>
227
+            <span>{{ value.split('?')[0].split('/').pop() || '' }}</span>
228
+            <span>kb</span>
62 229
           </view>
63 230
           <view class="viewdetails_upload_download">
64 231
             <wd-icon
@@ -89,42 +256,190 @@ const navigateToReminder = () => {
89 256
         </view>
90 257
         <view v-if="selected === '评论'">
91 258
           <view class="viewdetails_footer_comment_ipt">
92
-            <input
93
-              class="viewdetails_footer_comment_ipt_input"
94
-              type="text"
95
-              placeholder="说点什么..."
96
-            />
97
-            <view class="viewdetails_footer_comment_ipt_send"> </view>
98
-          </view>
99
-          <view
100
-            class="viewdetails_footer_comment_list"
101
-            v-for="item in commentlist"
102
-            :key="item.name"
103
-          >
104
-            <view class="viewdetails_footer_comment_list_info">
105
-              <view class="viewdetails_footer_comment_list_avatvr">{{
106
-                item.name.slice(0, 2)
107
-              }}</view>
108
-              <span class="viewdetails_footer_comment_list_name">{{
109
-                item.name
110
-              }}</span>
111
-            </view>
112
-            <view class="viewdetails_footer_comment_list_content">
113
-              {{ item.content }}
114
-            </view>
115
-            <view class="viewdetails_footer_comment_list_time">
116
-              <span class="viewdetails_footer_comment_list_time_text">{{
117
-                item.time
118
-              }}</span>
119
-              <span class="viewdetails_footer_comment_list_time_reply"
120
-                >回复</span
259
+            <view class="viewdetails_footer_comment_ipt_input">
260
+              <input
261
+                v-model="commentipt"
262
+                type="text"
263
+                placeholder="说点什么..."
264
+                :maxlength="200"
265
+                @keydown.enter="handleSend"
266
+              />
267
+              <view
268
+                style="
269
+                  position: absolute;
270
+                  bottom: 8rpx;
271
+                  right: 16rpx;
272
+                  font-size: 20rpx;
273
+                  color: #999;
274
+                "
121 275
               >
276
+                <text>{{ commentipt.length }}/200</text>
277
+              </view>
122 278
             </view>
123
-            <view class="viewdetails_footer_comment_list_reply">
124
-              {{ item.reply }}
279
+
280
+            <wd-upload
281
+              :file-list="fileListup"
282
+              :action="uploadAction"
283
+              image-mode="aspectFill"
284
+              :limit="1"
285
+              @success="handleUploadSuccess"
286
+              @remove="handleUploadRemove"
287
+            >
288
+              <template #default>
289
+                <view class="viewdetails_footer_comment_ipt_send"> </view>
290
+              </template>
291
+            </wd-upload>
292
+          </view>
293
+          <view style="display: flex; flex-direction: column; gap: 40rpx">
294
+            <view
295
+              class="viewdetails_footer_comment_list"
296
+              v-for="item in commentlist"
297
+              :key="item.name"
298
+            >
299
+              <view class="viewdetails_footer_comment_list_info">
300
+                <view class="viewdetails_footer_comment_list_avatvr">{{
301
+                  item?.username?.slice(-2) || ''
302
+                }}</view>
303
+                <span class="viewdetails_footer_comment_list_name">{{
304
+                  item?.username
305
+                }}</span>
306
+              </view>
307
+              <view class="viewdetails_footer_comment_list_content">
308
+                {{ item.content }}
309
+              </view>
310
+              <view>
311
+                <wd-img
312
+                  v-for="(value, index) in item?.attachmentsUrl"
313
+                  :key="index"
314
+                  :src="value"
315
+                  :width="50"
316
+                  :height="50"
317
+                  :enable-preview="true"
318
+                />
319
+              </view>
320
+              <view class="viewdetails_footer_comment_list_time">
321
+                <span class="viewdetails_footer_comment_list_time_text">{{
322
+                  formatRelativeTime(item?.updateTime)
323
+                }}</span>
324
+                <span
325
+                  class="viewdetails_footer_comment_list_time_reply"
326
+                  @tap="handleReply(item)"
327
+                  >回复</span
328
+                >
329
+              </view>
330
+              <view
331
+                class="viewdetails_footer_comment_list_reply"
332
+                v-for="(value, index) in item?.children"
333
+                :key="index"
334
+              >
335
+                <text>{{ value?.username }}:</text>
336
+                <template v-if="value?.content?.length > 50">
337
+                  <text class="reply-content" v-if="!expandedReplies[`${item.id}-${index}`]">
338
+                    {{ value.content.substring(0, 50) }}...
339
+                  </text>
340
+                  <text class="reply-content" v-else>
341
+                    {{ value.content }}
342
+                  </text>
343
+                  <text 
344
+                    class="reply-expand-btn" 
345
+                    @tap="toggleReplyExpand(item.id, index)"
346
+                  >
347
+                    {{ expandedReplies[`${item.id}-${index}`] ? '收起' : '展开' }}
348
+                  </text>
349
+                </template>
350
+                <template v-else>
351
+                  <text class="reply-content">{{ value?.content }}</text>
352
+                </template>
353
+              </view>
354
+              <view
355
+                class="viewdetails_footer_comment_list_reply_box"
356
+                v-if="isReply[item?.id]"
357
+              >
358
+                <view style="position: relative; width: 100%">
359
+                  <input
360
+                    class="viewdetails_footer_comment_list_reply_ipt"
361
+                    type="text"
362
+                    placeholder="写下您的回复..."
363
+                    :maxlength="200"
364
+                    v-model="replyContents[item?.id]"
365
+                    @input="(e) => handleReplyInput(e, item?.id)"
366
+                  />
367
+                  <view
368
+                    style="
369
+                      position: absolute;
370
+                      bottom: 8rpx;
371
+                      right: 16rpx;
372
+                      font-size: 20rpx;
373
+                      color: #999;
374
+                    "
375
+                  >
376
+                    <text
377
+                      >{{ (replyContents[item?.id] || '').length }}/200</text
378
+                    >
379
+                  </view>
380
+                </view>
381
+                <view style="display: flex; gap: 20rpx">
382
+                  <wd-button
383
+                    size="small"
384
+                    @tap="handleReplySubmit(item?.id)"
385
+                    style="
386
+                      padding: 6rpx 16rpx;
387
+                      font-size: 24rpx;
388
+                      border-radius: 14rpx;
389
+                    "
390
+                    >提交</wd-button
391
+                  >
392
+                  <wd-button
393
+                    plain
394
+                    size="small"
395
+                    style="
396
+                      padding: 6rpx 16rpx;
397
+                      font-size: 24rpx;
398
+                      border-radius: 14rpx;
399
+                    "
400
+                    @tap="handleClose(item?.id)"
401
+                    >收起</wd-button
402
+                  >
403
+                </view>
404
+              </view>
125 405
             </view>
126 406
           </view>
127 407
         </view>
408
+        <view
409
+          v-else
410
+          style="
411
+            display: flex;
412
+            flex-direction: column;
413
+            gap: 40rpx;
414
+            margin-top: 40rpx;
415
+          "
416
+        >
417
+          <view
418
+            v-for="item in viewRecords"
419
+            :key="item.id"
420
+            style="
421
+              display: flex;
422
+              justify-content: space-between;
423
+              align-items: center;
424
+            "
425
+          >
426
+            <view
427
+              style="
428
+                width: 80rpx;
429
+                height: 80rpx;
430
+                border-radius: 50%;
431
+                background-color: #234b9a;
432
+                display: flex;
433
+                justify-content: center;
434
+                align-items: center;
435
+                color: #fff;
436
+              "
437
+              >{{ item?.userName?.slice(-2) || '' }}</view
438
+            >
439
+            <view style="color: #31373d">{{ item?.userName }}</view>
440
+            <view style="color: #999">{{ item?.updateTime }}</view>
441
+          </view>
442
+        </view>
128 443
       </view>
129 444
     </view>
130 445
     <view class="viewdetails_footer_btn" @tap="navigateToReminder">提 醒</view>
@@ -177,27 +492,27 @@ body {
177 492
 }
178 493
 .viewdetails_main {
179 494
   width: 100%;
180
-  .viewdetails_main_title {
181
-    font-family: Alibaba PuHuiTi 2;
182
-    font-weight: 400;
183
-    font-style: 55 Regular;
184
-    font-size: 42rpx;
185
-    leading-trim: NONE;
186
-    line-height: 80rpx;
187
-    letter-spacing: 4%;
188
-    margin-bottom: 18rpx;
189
-    color: #31373d;
190
-  }
191
-  .viewdetails_main_content {
192
-    font-family: Alibaba PuHuiTi 2;
193
-    font-weight: 400;
194
-    font-style: 55 Regular;
195
-    font-size: 28rpx;
196
-    leading-trim: NONE;
197
-    line-height: 44rpx;
198
-    letter-spacing: 4%;
199
-    color: #31373d;
200
-  }
495
+  // .viewdetails_main_title {
496
+  //   font-family: Alibaba PuHuiTi 2;
497
+  //   font-weight: 400;
498
+  //   font-style: 55 Regular;
499
+  //   font-size: 42rpx;
500
+  //   leading-trim: NONE;
501
+  //   line-height: 80rpx;
502
+  //   letter-spacing: 4%;
503
+  //   margin-bottom: 18rpx;
504
+  //   color: #31373d;
505
+  // }
506
+  // .viewdetails_main_content {
507
+  //   font-family: Alibaba PuHuiTi 2;
508
+  //   font-weight: 400;
509
+  //   font-style: 55 Regular;
510
+  //   font-size: 28rpx;
511
+  //   leading-trim: NONE;
512
+  //   line-height: 44rpx;
513
+  //   letter-spacing: 4%;
514
+  //   color: #31373d;
515
+  // }
201 516
 }
202 517
 
203 518
 .viewdetails_upload_box {
@@ -283,14 +598,26 @@ body {
283 598
     width: 100%;
284 599
     height: 80rpx;
285 600
     display: flex;
601
+    align-items: center;
286 602
     gap: 32rpx;
287 603
     .viewdetails_footer_comment_ipt_input {
604
+      position: relative;
288 605
       height: 100%;
289 606
       flex: 1;
290 607
       background-color: #f5f5f5;
291 608
       border-radius: 8rpx;
292 609
       padding: 0 24rpx;
293 610
       box-sizing: border-box;
611
+      display: flex;
612
+      align-items: center;
613
+      input {
614
+        width: 100%;
615
+        height: 100%;
616
+        border: none;
617
+        background: transparent;
618
+        font-size: 28rpx;
619
+        color: #31373d;
620
+      }
294 621
     }
295 622
     .viewdetails_footer_comment_ipt_send {
296 623
       width: 45rpx;
@@ -300,13 +627,17 @@ body {
300 627
       background-size: cover;
301 628
       align-self: center;
302 629
     }
630
+    :deep(.wd-upload__preview) {
631
+      width: 110rpx;
632
+      height: 110rpx;
633
+    }
303 634
   }
304 635
   .viewdetails_footer_comment_list {
305 636
     width: 100%;
306 637
     margin-bottom: 24rpx;
307 638
     // display: flex;
308 639
     // flex-direction: column;
309
-    // gap: 24rpx;
640
+    // gap: 30rpx;
310 641
     .viewdetails_footer_comment_list_info {
311 642
       display: flex;
312 643
       gap: 16rpx;
@@ -356,15 +687,45 @@ body {
356 687
     }
357 688
     .viewdetails_footer_comment_list_reply {
358 689
       width: 100%;
359
-      height: 80rpx;
360
-      background-color: #f5f5f5;
690
+      // background-color: #f5f5f5;
361 691
       border-radius: 8rpx;
362
-      padding: 0 24rpx;
692
+      padding: 12rpx 24rpx;
363 693
       box-sizing: border-box;
364 694
       font-size: 24rpx;
365 695
       color: #86909c;
366
-      line-height: 80rpx;
696
+      line-height: 36rpx;
367 697
       margin-top: 16rpx;
698
+      word-break: break-word;
699
+      display: flex;
700
+      flex-wrap: wrap;
701
+      align-items: flex-start;
702
+      .reply-content {
703
+        display: inline;
704
+        white-space: normal;
705
+        word-wrap: break-word;
706
+        flex: 1;
707
+      }
708
+      .reply-expand-btn {
709
+        color: #215acd;
710
+        font-size: 20rpx;
711
+        margin-left: 8rpx;
712
+        cursor: pointer;
713
+        flex-shrink: 0;
714
+        align-self: center;
715
+      }
716
+    }
717
+    .viewdetails_footer_comment_list_reply_box {
718
+      display: flex;
719
+      flex-direction: column;
720
+      gap: 16rpx;
721
+      margin-top: 16rpx;
722
+      .viewdetails_footer_comment_list_reply_ipt {
723
+        border: 1px solid #f5f5f5;
724
+        border-radius: 20rpx;
725
+        padding: 12rpx;
726
+        font-size: 24rpx;
727
+        color: #86909c;
728
+      }
368 729
     }
369 730
   }
370 731
 }
@@ -378,4 +739,16 @@ body {
378 739
   line-height: 80rpx;
379 740
   text-align: center;
380 741
 }
742
+.loading-container {
743
+  position: fixed;
744
+  top: 0;
745
+  left: 0;
746
+  width: 100%;
747
+  height: 100%;
748
+  background-color: rgba(255, 255, 255, 0.8);
749
+  display: flex;
750
+  justify-content: center;
751
+  align-items: center;
752
+  z-index: 9999;
753
+}
381 754
 </style>

+ 18 - 0
src/pages/knowledge/search/details/viewdetails/reminder.vue

@@ -1,3 +1,8 @@
1
+<script setup lang="ts">
2
+const handleBack = () => {
3
+  uni.navigateBack()
4
+}
5
+</script>
1 6
 <template>
2 7
   <view class="viewdetails_reminder">
3 8
     <view>
@@ -15,6 +20,19 @@
15 20
         class="viewdetails_reminder_textarea"
16 21
       ></textarea>
17 22
     </view>
23
+    <view style="display: flex; justify-content: space-between; gap: 40rpx">
24
+      <wd-button
25
+        type="info"
26
+        plain
27
+        style="flex: 1; border-radius: 12rpx"
28
+        @click="handleBack"
29
+        >返回上一步</wd-button
30
+      >
31
+      <wd-button
32
+        style="flex: 1; border-radius: 12rpx; background-color: #215acd"
33
+        >发送</wd-button
34
+      >
35
+    </view>
18 36
   </view>
19 37
 </template>
20 38
 <style scoped lang="scss">

+ 126 - 33
src/pages/knowledge/search/index.vue

@@ -3,13 +3,22 @@ import { ref } from 'vue'
3 3
 import { queryKnowledgeCategory } from '@/api/knowledge/index'
4 4
 const isloading = ref(false)
5 5
 const categories = ref([])
6
+const pagenum = ref(1)
7
+const pagesize = ref(15)
6 8
 const total = ref(0)
7
-const createCategory = async () => {
9
+const createCategory = async (loadMore = false) => {
8 10
   try {
9 11
     isloading.value = true
10
-    const res = (await queryKnowledgeCategory({})) as any
12
+    const res = (await queryKnowledgeCategory({
13
+      pageNum: pagenum.value,
14
+      pageSize: pagesize.value,
15
+    })) as any
11 16
     if (res.code === 200) {
12
-      categories.value = res.rows || []
17
+      if (loadMore) {
18
+        categories.value = [...categories.value, ...(res.rows || [])]
19
+      } else {
20
+        categories.value = res.rows || []
21
+      }
13 22
       total.value = res.total || 0
14 23
     }
15 24
   } catch (error) {
@@ -21,45 +30,88 @@ const createCategory = async () => {
21 30
 onLoad(() => {
22 31
   createCategory()
23 32
 })
24
-const itemClick = (index: number) => {
25
-  uni.navigateTo({
26
-    url: '/pages/knowledge/search/details/index',
27
-  })
33
+
34
+// 跳转到详情页
35
+const navigateToDetail = (id: number) => {
36
+  const category = categories.value.find((item: any) => item.id === id)
37
+  const cleaned = category?.icon?.replace(/#/g, '')
38
+  if (cleaned.includes('iconfont')) {
39
+    uni.navigateTo({
40
+      url: `/pages/knowledge/search/details/index?id=${category.id}&name=${category.name}&icon=${cleaned}`,
41
+    })
42
+  } else {
43
+    const iconUrl = category?.iconUrl?.[0] || ''
44
+    uni.navigateTo({
45
+      url: `/pages/knowledge/search/details/index?id=${category.id}&name=${category.name}&icon=${encodeURIComponent(iconUrl)}`,
46
+    })
47
+  }
48
+}
49
+
50
+const itemClick = (id: number) => {
51
+  navigateToDetail(id)
52
+}
53
+
54
+// 下拉加载
55
+const handleLoadMore = async () => {
56
+  if (categories.value.length >= total.value) {
57
+    uni.showToast({
58
+      title: '没有更多数据了',
59
+      icon: 'none',
60
+    })
61
+    return
62
+  }
63
+  pagenum.value++
64
+  await createCategory(true)
28 65
 }
29 66
 </script>
30 67
 <template>
31
-  <wd-loading type="outline" v-if="isloading" />
32
-
33 68
   <view class="knowledgebase_search">
69
+    <view v-if="isloading" class="loading-container">
70
+      <wd-loading size="40px" color="#215ACD"></wd-loading>
71
+    </view>
34 72
     <view class="header_search">
35 73
       <input class="search_input" type="text" placeholder="搜索" />
36 74
     </view>
37
-    <view class="main_list">
75
+    <scroll-view
76
+      class="main_list"
77
+      :scroll-y="true"
78
+      @scrolltolower="handleLoadMore"
79
+    >
38 80
       <view
39 81
         class="main_list_items"
40 82
         v-for="(item, index) in categories"
41
-        @tap="itemClick(index)"
83
+        @tap="itemClick(item.id)"
42 84
       >
43 85
         <view
44 86
           class="main_list_items_icon"
45 87
           :style="{ background: item.backcolor }"
46 88
         >
47
-          <view
48
-            class="main_list_items_icon_line"
49
-            v-for="(line, lineIndex) in 3"
50
-            :key="lineIndex"
51
-          ></view>
89
+          <text
90
+            v-if="item.icon.includes('iconfont')"
91
+            :class="[item.icon.split(',')[0]]"
92
+            :style="{ color: item.icon.split(',')[1], 'font-size': '48rpx' }"
93
+          ></text>
94
+          <image
95
+            v-else
96
+            style="width: 100%; height: 100%;border-radius: 20rpx"
97
+            :src="item.iconUrl[0]"
98
+            alt=""
99
+          />
52 100
         </view>
53 101
         <view class="main_list_items_text">
54 102
           <span>{{ item.name }}</span>
55 103
           <span>{{ item.description }}</span>
56 104
         </view>
57 105
       </view>
58
-    </view>
106
+      <view
107
+        v-if="!isloading && categories.length > 0 && categories.length >= total"
108
+        class="load-more"
109
+      >
110
+        <text style="font-size: 24rpx; color: #86909c">- 暂无数据 -</text>
111
+      </view>
112
+    </scroll-view>
59 113
   </view>
60 114
 </template>
61
-
62
-<script setup lang="ts"></script>
63 115
 <style scoped lang="scss">
64 116
 html,
65 117
 body {
@@ -98,6 +150,9 @@ body {
98 150
     flex-direction: column;
99 151
     gap: 42rpx;
100 152
     overflow-y: auto;
153
+    overflow-x: hidden;
154
+    box-sizing: border-box;
155
+    padding-bottom: 80rpx;
101 156
     .main_list_items {
102 157
       width: 100%;
103 158
       height: 96rpx;
@@ -105,12 +160,14 @@ body {
105 160
       box-sizing: border-box;
106 161
       display: flex;
107 162
       gap: 16rpx;
163
+      margin-bottom: 42rpx;
108 164
 
109 165
       // background-color: aqua;
110 166
       .main_list_items_text {
111 167
         display: flex;
112 168
         flex-direction: column;
113 169
         justify-content: space-between;
170
+        flex: 1;
114 171
         :nth-child(1) {
115 172
           font-family: Alibaba PuHuiTi 2;
116 173
           font-weight: 500;
@@ -120,8 +177,12 @@ body {
120 177
           line-height: 32rpx;
121 178
           letter-spacing: 0px;
122 179
           color: #31373d;
180
+          white-space: nowrap;
181
+          overflow: hidden;
182
+          text-overflow: ellipsis;
123 183
         }
124 184
         :nth-child(2) {
185
+          width: 50%;
125 186
           font-family: Alibaba PuHuiTi 2;
126 187
           font-weight: 400;
127 188
           font-style: 55 Regular;
@@ -130,28 +191,60 @@ body {
130 191
           line-height: 28rpx;
131 192
           letter-spacing: 0px;
132 193
           color: #86909c;
194
+          white-space: nowrap;
195
+          overflow: hidden;
196
+          text-overflow: ellipsis;
133 197
         }
134 198
       }
135 199
       .main_list_items_icon {
136 200
         width: 74rpx;
137 201
         height: 86rpx;
138
-        border-radius: 20rpx;
139
-        padding: 20rpx;
140
-        box-sizing: border-box;
141 202
         display: flex;
142
-        flex-direction: column;
143
-        justify-content: space-between;
144
-        .main_list_items_icon_line {
145
-          width: 100%;
146
-          height: 6rpx;
147
-          border-radius: 4rpx;
148
-          background-color: #ffffff;
149
-          &:nth-child(1) {
150
-            width: 60%;
151
-          }
152
-        }
203
+        justify-content: center;
204
+        align-items: center;
205
+        flex-shrink: 0;
206
+        // .iconstyle{
207
+        //   font-size: 48rpx;
208
+        // }
209
+        // border-radius: 20rpx;
210
+        // padding: 20rpx;
211
+        // box-sizing: border-box;
212
+        // display: flex;
213
+        // flex-direction: column;
214
+        // justify-content: space-between;
215
+        // .main_list_items_icon_line {
216
+        //   width: 100%;
217
+        //   height: 6rpx;
218
+        //   border-radius: 4rpx;
219
+        //   background-color: #ffffff;
220
+        //   &:nth-child(1) {
221
+        //     width: 60%;
222
+        //   }
223
+        // }
153 224
       }
154 225
     }
155 226
   }
156 227
 }
228
+.loading-container {
229
+  position: fixed;
230
+  top: 0;
231
+  left: 0;
232
+  width: 100%;
233
+  height: 100%;
234
+  background-color: rgba(255, 255, 255, 0.8);
235
+  display: flex;
236
+  justify-content: center;
237
+  align-items: center;
238
+  z-index: 9999;
239
+}
240
+
241
+.load-more {
242
+  width: 100%;
243
+  height: 80rpx;
244
+  display: flex;
245
+  justify-content: center;
246
+  align-items: center;
247
+  margin-top: 20rpx;
248
+  margin-bottom: 20rpx;
249
+}
157 250
 </style>

+ 140 - 35
src/pages/schedule/view/components/addgasstation/index.vue

@@ -6,6 +6,8 @@ import {
6 6
   getPostList,
7 7
   queryExecutorList,
8 8
   querybaseApilist,
9
+  queryrCCList,
10
+  selectAllSysStation,
9 11
 } from '@/api/workorder/index'
10 12
 import { getDictOptions } from '@/utils/dict'
11 13
 import { uploadUrl } from '@/utils/uploadFile'
@@ -27,10 +29,14 @@ const getoptions = ref('')
27 29
 const UploadList = ref([])
28 30
 const form = ref()
29 31
 const getPostListOptions = ref([]) as any //执行岗位
32
+const getStationIdListOptions = ref([]) as any //场站名称
30 33
 const getUserListOptions = ref([]) as any //执行人名称
34
+const getCCrListOptions = ref([]) as any //抄送人名称
31 35
 const getTemplateListOptions = ref([]) as any //任务模板列表
32 36
 const postListLoading = ref(false) //执行岗位加载状态
37
+const stationIdListLoading = ref(false) //场站名称加载状态
33 38
 const userListLoading = ref(false) //执行人名称加载状态
39
+const ccListLoading = ref(false) //抄送人名称加载状态
34 40
 const getTaskTypeOptions = () => getDictOptions(DICT_KEYS.TASK_TYPE) //任务类型
35 41
 
36 42
 onLoad((options) => {
@@ -45,8 +51,9 @@ onLoad((options) => {
45 51
 const model = ref({
46 52
   type: '',
47 53
   executePosition: '',
54
+  stationId: [],
48 55
   executorIds: [],
49
-  executors: [],
56
+  // executors: [],
50 57
   formType: 'photo',
51 58
   templateId: '',
52 59
   taskName: '',
@@ -54,10 +61,11 @@ const model = ref({
54 61
   endTime: '',
55 62
   taskType: '',
56 63
   ccReceivers: [],
57
-  ccReceiversName: [],
64
+  // ccReceiversName: [],
58 65
   description: '',
59 66
   attachments: '',
60
-})
67
+}) as any
68
+
61 69
 const getPostListfn = async () => {
62 70
   if (getPostListOptions.value.length > 0) {
63 71
     return
@@ -78,18 +86,50 @@ const getPostListfn = async () => {
78 86
               }))
79 87
             : []
80 88
     } else {
81
-      showSuccess({
82
-        msg: '获取岗位列表失败',
89
+      uni.showToast({
90
+        icon: 'error',
91
+        title: '获取岗位列表失败',
83 92
       })
84 93
     }
85 94
   } catch (error) {
86
-    showSuccess({
87
-      msg: '获取岗位列表失败',
95
+    uni.showToast({
96
+      icon: 'error',
97
+      title: '获取岗位列表失败',
88 98
     })
89 99
   } finally {
90 100
     postListLoading.value = false
91 101
   }
92 102
 }
103
+
104
+// 场站名称
105
+const getstationIdListfn = async () => {
106
+  if (getStationIdListOptions.value.length > 0) {
107
+    return
108
+  }
109
+  stationIdListLoading.value = true
110
+  try {
111
+    const { code, data } = (await selectAllSysStation()) as any
112
+    if (code === 200) {
113
+      getStationIdListOptions.value = data.map((item: any) => ({
114
+        label: item.stationName,
115
+        value: item.id,
116
+      }))
117
+    } else {
118
+      uni.showToast({
119
+        icon: 'error',
120
+        title: '获取场站名称列表失败',
121
+      })
122
+    }
123
+  } catch (error) {
124
+    uni.showToast({
125
+      icon: 'error',
126
+      title: '获取场站名称列表失败',
127
+    })
128
+  } finally {
129
+    stationIdListLoading.value = false
130
+  }
131
+}
132
+//执行人
93 133
 const getUserListfn = async () => {
94 134
   if (getUserListOptions.value.length > 0) {
95 135
     return
@@ -101,30 +141,65 @@ const getUserListfn = async () => {
101 141
       getUserListOptions.value = data.map((item: any) => ({
102 142
         label: `${item.userName}-${item.postName}-${item.stationName}`,
103 143
         value: JSON.stringify(item),
144
+        postId: item.postId,
104 145
       }))
105 146
     } else {
106
-      showSuccess({
107
-        msg: '获取执行人列表失败',
147
+      uni.showToast({
148
+        icon: 'error',
149
+        title: '获取执行人列表失败',
108 150
       })
109 151
     }
110 152
   } catch (error) {
111
-    showSuccess({
112
-      msg: '获取执行人列表失败',
153
+    uni.showToast({
154
+      icon: 'error',
155
+      title: '获取执行人列表失败',
113 156
     })
114 157
   } finally {
115 158
     userListLoading.value = false
116 159
   }
117 160
 }
161
+//抄送人
162
+const getCCListfn = async () => {
163
+  if (getCCrListOptions.value.length > 0) {
164
+    return
165
+  }
166
+  ccListLoading.value = true
167
+  try {
168
+    const { code, rows } = (await queryrCCList()) as any
169
+    if (code === 200) {
170
+      getCCrListOptions.value = rows.map((item: any) => ({
171
+        label: item.userName,
172
+        value: item.userId,
173
+      }))
174
+    } else {
175
+      uni.showToast({
176
+        icon: 'error',
177
+        title: '获取抄送人列表失败',
178
+      })
179
+    }
180
+  } catch (error) {
181
+    uni.showToast({
182
+      icon: 'error',
183
+      title: '获取抄送人列表失败',
184
+    })
185
+  } finally {
186
+    ccListLoading.value = false
187
+  }
188
+}
118 189
 const querybaseApilistfn = async () => {
119 190
   if (getTemplateListOptions.value.length > 0) {
120 191
     return
121 192
   }
122 193
   try {
123
-    const { code, rows } = (await querybaseApilist({ status: 0 })) as any
194
+    const { code, rows } = (await querybaseApilist({
195
+      status: 0,
196
+      pageNum: 1,
197
+      pageSize: 1000,
198
+    })) as any
124 199
     if (code === 200) {
125 200
       getTemplateListOptions.value = rows.map((item: any) => ({
126 201
         ...item,
127
-        label: item.subFormTypeName,
202
+        label: item.taskName,
128 203
         value: item.id,
129 204
       }))
130 205
     } else {
@@ -167,27 +242,30 @@ function handleSubmit() {
167 242
             .map((item) => JSON.parse(item.response).data.fileName)
168 243
             .filter(Boolean)
169 244
             .join(','),
170
-          executorIds: model.value.executorIds.map((item) => JSON.parse(item)),
171
-          executors: model.value.executorIds.map((item) =>
172
-            String(JSON.parse(item).userId)
173
-          ),
174
-          ccReceivers: model.value.ccReceivers
175
-            .map((item) => JSON.parse(item).userId)
176
-            .join(','),
177
-          ccReceiversName: model.value.ccReceivers.map((item) =>
178
-            String(JSON.parse(item).userId)
179
-          ),
245
+            executorIds: model.value.executorIds.map((item) =>JSON.parse(item)),
246
+          // executors: model.value.executorIds.map((item) =>
247
+          //   String(JSON.parse(item).userId)
248
+          // ),
249
+          ccReceivers: model.value.ccReceivers.join(','),
250
+
251
+          // ccReceiversName: model.value.ccReceivers.map((item) =>
252
+          //   String(JSON.parse(item).userId)
253
+          // ),
180 254
         }
181
-        if (
182
-          model.value.formType === 'photo' ||
183
-          model.value.formType === 'inspection'
184
-        ) {
255
+        if (model.value.formType === 'photo' || model.value.formType === 'inspection') {
185 256
           delete submitData.templateId
186 257
         } else if (model.value.formType === '3') {
187
-          submitData.taskName =
188
-            getTemplateListOptions.value.find(
189
-              (item) => item.id === Number(model.value.templateId)
190
-            )?.subFormTypeName || ''
258
+          // delete submitData.taskName
259
+          // submitData.formType = ''
260
+          submitData.taskName = getTemplateListOptions.value.find((item) => item.id === Number(model.value.templateId))?.taskName || ''
261
+        }
262
+        if(getoptions.value==='新增油站'){
263
+          //  submitData['executorIds']=model.value.executorIds.map((item) => JSON.parse(item))
264
+           delete submitData.stationId
265
+        }else if(getoptions.value==='新增访客'){
266
+          //  submitData['executorId']=model.value.executorIds.map((item) => JSON.parse(item))
267
+          //  delete submitData.executorIds
268
+           submitData.stationId=model.value.stationId.join(',')
191 269
         }
192 270
         const res = (await addtodoaskslist(submitData)) as any
193 271
         if (res?.code === 200) {
@@ -258,6 +336,29 @@ const handleUploadRemove = ({ file }) => {
258 336
               :loading="postListLoading"
259 337
             />
260 338
           </view>
339
+
340
+          <view v-if="getoptions === '新增访客'">
341
+            <view style="display: flex; align-items: center; gap: 4rpx">
342
+              <text style="color: #fa4350; font-size: 28rpx; font-weight: bold"
343
+                >*</text
344
+              >
345
+              <text style="color: #31373d">场站名称</text>
346
+            </view>
347
+            <wd-select-picker
348
+              style="border-bottom: 1rpx solid #e5e5e5"
349
+              type="checkbox"
350
+              label-width="100px"
351
+              prop="stationId"
352
+              v-model="model.stationId"
353
+              placeholder="请选择场站名称"
354
+              :rules="[{ required: true, message: '请选择场站名称' }]"
355
+              custom-class="custom-vertical-input"
356
+              @open="getstationIdListfn"
357
+              :columns="getStationIdListOptions"
358
+              :loading="stationIdListLoading"
359
+            />
360
+          </view>
361
+
261 362
           <view>
262 363
             <view style="display: flex; align-items: center; gap: 4rpx">
263 364
               <text style="color: #fa4350; font-size: 28rpx; font-weight: bold"
@@ -275,7 +376,11 @@ const handleUploadRemove = ({ file }) => {
275 376
               :rules="[{ required: true, message: '请选择执行人名称' }]"
276 377
               custom-class="custom-vertical-input"
277 378
               @open="getUserListfn"
278
-              :columns="getUserListOptions"
379
+              :columns="
380
+                getoptions === '新增油站'
381
+                  ? getUserListOptions.filter((item: any) => item.postId === 3)
382
+                  : getUserListOptions
383
+              "
279 384
               :loading="userListLoading"
280 385
             />
281 386
           </view>
@@ -414,9 +519,9 @@ const handleUploadRemove = ({ file }) => {
414 519
               placeholder="请选择抄送人"
415 520
               :rules="[{ required: true, message: '请选择抄送人' }]"
416 521
               custom-class="custom-vertical-input"
417
-              @open="getUserListfn"
418
-              :columns="getUserListOptions"
419
-              :loading="userListLoading"
522
+              @open="getCCListfn"
523
+              :columns="getCCrListOptions"
524
+              :loading="ccListLoading"
420 525
             />
421 526
           </view>
422 527
 

+ 22 - 2
src/pages/schedule/view/index.vue

@@ -21,6 +21,7 @@ interface CalendarDate {
21 21
   isOtherMonth: boolean
22 22
   isToday: boolean
23 23
   isSelected: boolean
24
+  isPast: boolean
24 25
 }
25 26
 const mainloing = ref(false)
26 27
 const GasStationId = ref('')
@@ -146,6 +147,10 @@ watch(
146 147
 watch(
147 148
   () => radioActive.value,
148 149
   async () => {
150
+    // 切换视图时默认选中当前时间
151
+    const today = new Date()
152
+    selectedDate.value = today
153
+    currentMonth.value = today
149 154
     await queryViewlist()
150 155
   }
151 156
 )
@@ -179,6 +184,13 @@ const generateDates = () => {
179 184
     const isToday = date.toDateString() === today.toDateString()
180 185
     let isSelected = date.toDateString() === selectedDate.value.toDateString()
181 186
     
187
+    // 计算是否是过去的日期
188
+    const dateOnly = new Date(date)
189
+    dateOnly.setHours(0, 0, 0, 0)
190
+    const todayOnly = new Date(today)
191
+    todayOnly.setHours(0, 0, 0, 0)
192
+    const isPast = dateOnly < todayOnly
193
+    
182 194
     // 周模式下,标记选中日期所在周的所有日期
183 195
     if (radioActive.value === '周') {
184 196
       const selected = new Date(selectedDate.value)
@@ -202,6 +214,7 @@ const generateDates = () => {
202 214
       isOtherMonth: date.getMonth() !== month,
203 215
       isToday: isToday,
204 216
       isSelected: isSelected,
217
+      isPast: isPast,
205 218
     })
206 219
   }
207 220
 
@@ -275,7 +288,7 @@ const handleDateClick = async (date: CalendarDate) => {
275 288
 }
276 289
 const addtodoaskslistfn = (val) => {
277 290
   uni.navigateTo({
278
-    url: `/pages/schedule/view/components/addgasstation/index?type=新增${val}`,
291
+    url: `/pages/schedule/view/addgasstation/index?type=新增${val}`,
279 292
   })
280 293
 }
281 294
 const handletabs = async (val) => {
@@ -341,9 +354,10 @@ const handletabs = async (val) => {
341 354
               'Calendar-date-active': date.isToday,
342 355
               'Calendar-date-other': date.isOtherMonth,
343 356
               'Calendar-date-selected': date.isSelected && !date.isToday,
357
+              'Calendar-date-disabled': radioActive === '日' && date.isPast,
344 358
             },
345 359
           ]"
346
-          @click="handleDateClick(date)"
360
+          @click="(radioActive === '日' && date.isPast) ? null : handleDateClick(date)"
347 361
         >
348 362
           {{ date.day }}
349 363
         </view>
@@ -529,6 +543,12 @@ body {
529 543
           color: #215ACD;
530 544
           background-color: #E6E8EB;
531 545
         }
546
+
547
+        &.Calendar-date-disabled {
548
+          color: #c0c4cc;
549
+          pointer-events: none;
550
+          cursor: not-allowed;
551
+        }
532 552
       }
533 553
     }
534 554