@jx3box/jx3box-common-ui 5.3.9 → 5.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,354 @@
1
+ // 列表搜索
2
+ .m-archive-search{
3
+ .mb(10px);
4
+ .el-select .el-input {
5
+ width: 80px;
6
+ }
7
+ .u-switch{
8
+ .el-switch__label{
9
+ .bold;
10
+ color:#666;
11
+ }
12
+ }
13
+ .pl(122px);
14
+ .pr;
15
+ .u-publish{
16
+ .pa;.lt(0);
17
+ }
18
+ }
19
+ @media screen and (max-width:@phone){
20
+ .m-archive-search{
21
+ .pl(0);
22
+ .u-publish{
23
+ .none;
24
+ }
25
+ }
26
+ }
27
+ // 排序
28
+ .m-archive-filter {
29
+ .fz(12px);
30
+ margin-bottom: 10px;
31
+ padding-bottom: 5px;
32
+ .clearfix;
33
+ border-bottom: 1px solid #eee;
34
+ .u-publish {
35
+ .fl;
36
+ .h(32px);
37
+ .mr(10px);
38
+ .ml(0);
39
+ }
40
+ .w-filter-mark,.w-filter-tag,.w-filter-client{
41
+ .fl;
42
+ }
43
+ .w-filter-client{
44
+ margin-top:(32px - 28px )/2;
45
+ .mr(10px);
46
+ }
47
+ .w-filter-mark,.w-filter-tag{
48
+ margin-top:8px;
49
+ }
50
+ .w-filter-menu{
51
+ .fl;
52
+ .mt(6px);
53
+ .mr(15px);
54
+ }
55
+
56
+ .w-filter-order{
57
+ .fr;
58
+ margin-top:8px;
59
+ }
60
+ }
61
+ @media screen and (max-width: @ipad) {
62
+ .m-archive-filter {
63
+ .u-publish {
64
+ .mr(10px);
65
+ }
66
+ .w-filter-mark,.w-filter-tag,.w-filter-order{
67
+ margin-top:0;
68
+ }
69
+ .w-filter-mark,.w-filter-tag{
70
+ .mr(10px);
71
+ }
72
+ }
73
+ }
74
+ @media screen and (max-width: @phone) {
75
+ .m-archive-filter {
76
+ .none;
77
+ }
78
+ }
79
+ // 为空
80
+ .m-archive-null {
81
+ margin-top: 10px;
82
+ }
83
+
84
+ // 加载更多
85
+ .m-archive-more {
86
+ .mb(10px);
87
+ .w(100%);
88
+ .none;
89
+ }
90
+ .m-archive-more.show {
91
+ .db;
92
+ }
93
+
94
+ // 分页
95
+ .m-archive-pages {
96
+ overflow-x: auto;
97
+ }
98
+ @media screen and (max-width:@phone){
99
+ .m-archive-pages{
100
+ .el-pagination__jump{
101
+ .none !important;
102
+ }
103
+ }
104
+ }
105
+
106
+ // 普通列表
107
+ .m-archive-list {
108
+ .u-list {
109
+ padding: 0;
110
+ margin: 0;
111
+ list-style: none;
112
+ }
113
+
114
+ .u-item {
115
+ border-bottom: 1px solid @border-hr;
116
+ padding-bottom: 20px;
117
+ .mb(20px);
118
+ .clearfix;
119
+ .pr;
120
+ }
121
+
122
+ // 海报
123
+ .u-banner {
124
+ .fl;
125
+ .mr(10px);
126
+ .w(180px);
127
+ .h(100px);
128
+ overflow: hidden;
129
+ .db;
130
+ .pr;
131
+ .z(1);
132
+ border: 1px solid #eee;
133
+ padding: 5px;
134
+ box-sizing: border-box;
135
+ img {
136
+ .size(100%);
137
+ filter: saturate(120%);
138
+ transition: 0.06s all ease-in-out;
139
+ }
140
+ transition: 0.06s border ease-in-out;
141
+ &:hover {
142
+ img {
143
+ filter: saturate(140%) brightness(120%);
144
+ }
145
+ border-color: @border;
146
+ }
147
+ }
148
+
149
+ // 标题
150
+ .u-post {
151
+ margin: 0;
152
+ padding: 0;
153
+ .nobreak;
154
+ .mb(5px);
155
+ .u-icon {
156
+ .size(16px);
157
+ .y(-3px);
158
+ .mr(5px);
159
+ }
160
+ &.isSticky {
161
+ .u-title::before {
162
+ content: "🎯";
163
+ .mr(5px);
164
+ }
165
+ // .u-title:hover{
166
+ // box-shadow: 0 1px 0 #f00;
167
+ // }
168
+ }
169
+ .u-title {
170
+ // color:@darkblue;
171
+ font-weight:400;
172
+ &:hover {
173
+ box-shadow: 0 1px 0 @primary;
174
+ }
175
+ }
176
+ .fz(15px, 2);
177
+ font-weight: normal;
178
+ .lh(2);
179
+ font-weight: 400;
180
+ }
181
+
182
+ // 角标
183
+ .u-marks {
184
+ }
185
+ .u-mark {
186
+ font-style: normal;
187
+ font-size: 12px;
188
+ padding: 1px 5px 2px 5px;
189
+ margin-left: 5px;
190
+ border-radius: 2px;
191
+ background-color: #6f42c1;
192
+ color: #fff;
193
+ .ml(5px);
194
+ }
195
+
196
+ // 内容
197
+ .u-content {
198
+ .db;
199
+ padding-left: 20px;
200
+ .pr;
201
+ }
202
+
203
+ // 内容·描述类
204
+ .u-desc {
205
+ .db;
206
+ .fz(12px, 1.8);
207
+ color: #555;
208
+ .break(2);
209
+ .mb(6px);
210
+ padding: 0 2px;
211
+ }
212
+
213
+ // 内容·meta列表
214
+ .u-metalist {
215
+ .nobreak;
216
+ .db;
217
+ .fz(12px, 25px);
218
+ .mb(4px);
219
+ strong {
220
+ .dbi;
221
+ .y(top);
222
+ padding: 0 10px;
223
+ .mr(10px);
224
+ .r(4px);
225
+ background-color: #f1f8ff;
226
+ color: @color-link;
227
+ font-weight: normal;
228
+ }
229
+ em {
230
+ font-style: normal;
231
+ }
232
+ b {
233
+ font-weight: normal;
234
+ }
235
+ a {
236
+ color: #333;
237
+ &:hover {
238
+ color: @color-link;
239
+ box-shadow: 0 1px 0 @color-link;
240
+ }
241
+ }
242
+ }
243
+ .u-tag {
244
+ .db;
245
+ .nobreak;
246
+ a,
247
+ b {
248
+ padding: 0.2em 0.8em;
249
+ margin: 0 0.5em 0 0;
250
+ background-color: #f1f8ff;
251
+ border-radius: 3px;
252
+ .fz(12px);
253
+ color: #4989d2;
254
+ }
255
+ a:hover {
256
+ background-color: #def;
257
+ }
258
+ }
259
+ .u-types {
260
+ .db;
261
+ .nobreak;
262
+ b {
263
+ padding: 0.1em 0.8em;
264
+ margin: 0 0.5em 0.5em 0;
265
+ border-radius: 3px;
266
+ .fz(12px);
267
+ .dbi;
268
+ .y(top);
269
+ }
270
+ }
271
+
272
+ // 底部
273
+ .u-misc {
274
+ .db;
275
+ .pa;
276
+ .rb(10px, 24px);
277
+ .x(right);
278
+ .fz(12px, 20px);
279
+ color: #777;
280
+ }
281
+
282
+ .u-author{
283
+ // .pa;.rt(0);
284
+ }
285
+ .u-author-avatar {
286
+ .size(24px);
287
+ .y;
288
+ .r(2px);
289
+ .mr(5px);
290
+ // .fr;
291
+ // .ml(5px);
292
+ }
293
+ .u-author-name {
294
+ .fz(12px,24px);
295
+ // .fl;
296
+ color:#666;
297
+ &:hover {
298
+ color:@pink;
299
+ }
300
+ }
301
+ .u-date {
302
+ .db;
303
+ .mt(3px);
304
+ .clear;
305
+ }
306
+
307
+ .u-down {
308
+ // .u-btn-white;
309
+ i {
310
+ .size(12px);
311
+ .y(-1px);
312
+ }
313
+ }
314
+ .u-pipe {
315
+ margin: 0 5px;
316
+ color: #999;
317
+ }
318
+ }
319
+ @media screen and (max-width: @ipad) {
320
+ .m-archive-list {
321
+ .u-banner {
322
+ .w(100px);
323
+ .h(55px);
324
+ padding: 3px;
325
+ .fr;
326
+ margin-left: 10px;
327
+ margin-right: 0;
328
+ }
329
+
330
+ .u-post {
331
+ white-space: normal;
332
+ word-break: break-all;
333
+ .break(2);
334
+ .fz(14px, 22px);
335
+ }
336
+
337
+ .u-metalist,
338
+ .u-down,
339
+ .u-view {
340
+ .none;
341
+ }
342
+ .u-tag {
343
+ .mb(8px);
344
+ }
345
+
346
+ .u-misc {
347
+ .ps;
348
+ .x(left);
349
+ }
350
+ .u-author-name {
351
+ color: #555;
352
+ }
353
+ }
354
+ }
@@ -0,0 +1,49 @@
1
+ .m-single-box {
2
+ padding:0 30px;
3
+ .el-divider__text {
4
+ color: #888;
5
+ font-weight:300;
6
+ }
7
+ .pr;
8
+ }
9
+ @media screen and (max-width:@phone){
10
+ .m-single-box{
11
+ padding:0 15px;
12
+ }
13
+ }
14
+
15
+ .m-single-prepend {
16
+ .pr;
17
+ }
18
+
19
+ .m-single-collection,.m-single-creators{
20
+ .mb(10px);
21
+ }
22
+
23
+ .m-single-post {
24
+ .mb(10px);
25
+ .pr;
26
+ .el-divider{
27
+ margin:10px auto 20px auto;
28
+ }
29
+ overflow: hidden;
30
+ }
31
+
32
+
33
+ .m-single-content{
34
+ height: auto !important;
35
+ }
36
+ @media print{
37
+ .m-single-content{
38
+ table{
39
+ width: 100% !important;
40
+ }
41
+ }
42
+ }
43
+ @media print{
44
+ .m-single-comment{.none;}
45
+ }
46
+
47
+ .m-single-null{
48
+ padding:20px 0;
49
+ }
@@ -10,3 +10,8 @@
10
10
  }
11
11
  }
12
12
  }
13
+ @media screen and (max-width: @phone) {
14
+ .c-crumb {
15
+ .none;
16
+ }
17
+ }
@@ -405,4 +405,4 @@
405
405
  "hasMark": false,
406
406
  "markcls": "ishot"
407
407
  }
408
- ]
408
+ ]
@@ -2,4 +2,4 @@
2
2
  "std": "正式服",
3
3
  "origin": "怀旧服",
4
4
  "all": "双端"
5
- }
5
+ }
@@ -287,4 +287,4 @@
287
287
  "status": true,
288
288
  "parentKey": "bbs"
289
289
  }
290
- ]
290
+ ]
@@ -1,5 +1,5 @@
1
1
  {
2
- "std":["北天药宗","奉天证道"],
3
- "origin":["藏剑山庄","物华天宝"],
4
- "all":["北天药宗","奉天证道","藏剑山庄","物华天宝"]
5
- }
2
+ "std": ["北天药宗", "奉天证道"],
3
+ "origin": ["藏剑山庄", "物华天宝"],
4
+ "all": ["北天药宗", "奉天证道", "藏剑山庄", "物华天宝"]
5
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jx3box/jx3box-common-ui",
3
- "version": "5.3.9",
3
+ "version": "5.4.3",
4
4
  "description": "JX3BOX UI",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -30,8 +30,10 @@
30
30
  "last 2 versions"
31
31
  ],
32
32
  "dependencies": {
33
+ "@jx3box/jx3box-comment-ui": "^1.6.6",
33
34
  "@jx3box/jx3box-common": "^6.7.8",
34
35
  "@jx3box/jx3box-data": "^1.8.3",
36
+ "@jx3box/jx3box-editor": "^1.0.4",
35
37
  "axios": "^0.19.2",
36
38
  "element-ui": "^2.13.2",
37
39
  "jquery": "^3.5.1",
package/src/App.vue CHANGED
@@ -1,14 +1,7 @@
1
1
  <template>
2
2
  <div class="container-page">
3
3
  <Header></Header>
4
- <Breadcrumb
5
- name="频道名称"
6
- slug="slug"
7
- root="/slug"
8
- :publishEnable="true"
9
- :feedbackEnable="true"
10
- :adminEnable="true"
11
- >
4
+ <Breadcrumb name="频道名称" slug="slug" root="/slug" :publishEnable="true" :feedbackEnable="true" :adminEnable="true">
12
5
  <img slot="logo" svg-inline src="../assets/img/jx3.svg" />
13
6
  bread info
14
7
  </Breadcrumb>
@@ -20,67 +13,74 @@
20
13
  </LeftSidebar>
21
14
 
22
15
  <Main :withoutLeft="false" :withoutRight="false">
23
- <PostHeader :post="post"/>
24
-
25
- <Creators :postId="30432" style="margin-bottom:10px"/>
26
- <Collection :id="59" :defaultVisible="true"/>
27
- <UserPop title="添加用户" v-model="visible" @confirm="addUser"/>
28
- <el-button @click="visible = true">用户POP</el-button>
29
-
30
- <Thx :postId="23865" postType="bbs" :userId="7" :adminBoxcoinEnable="true" :userBoxcoinEnable="true"/>
31
-
32
- <hr />
33
-
34
- <Like mode="heart" :count="100" :showCount="true" />
35
- <Down :count="100" :showCount="true" />
36
- <Mark label="KEY" value="VALUE" BGL="#000" BGR="#F39" />
37
- <Fav post-id="90" post-type="jx3dat" />
38
- <Feed post-id="90" post-type="jx3dat" />
39
- <Print title="传入标题" />
40
- <QRcode />
41
- <Sharing />
42
-
43
- <hr />
44
-
45
- <markBy />
46
- <menuBy :data="['test1', 'test2']" />
47
- <orderBy />
48
- <tagBy :data="['PVE', 'PVX']" :type="tag"/>
49
- <clientBy type=""/>
50
- <zlpBy/>
51
-
52
- <hr />
53
-
54
- <WikiPanel :wiki-post="wikiPost">
55
- <template slot="head-title">
56
- <i class="el-icon-location-information"></i>
57
- <span class="u-title">通识正文</span>
58
- </template>
59
- <template slot="head-actions">
60
- <a class="el-button el-button--primary u-publish">
61
- <i class="el-icon-edit"></i>
62
- <span>完善百科通识</span>
63
- </a>
64
- <span class="u-more">查看更多</span>
65
- </template>
66
- <template slot="body"
67
- >正文内容正文内容正文内容正文内容正文内容正文内容正文内容正文内容正文内容</template
68
- >
69
- </WikiPanel>
70
- <hr />
71
-
72
- <WikiRevisions type="achievement" source-id="9096" />
73
- <hr>
74
-
75
- <WikiComments type="achievement" source-id="9096" />
76
- <hr>
16
+ <el-tabs v-model="tab" type="card">
17
+ <el-tab-pane label="CMS作品" name="post">
18
+ <el-radio-group v-model="post_id">
19
+ <el-radio label="35605">测试Markdown</el-radio>
20
+ <el-radio label="32035">仅小册</el-radio>
21
+ <el-radio label="30017">仅联合创作者</el-radio>
22
+ <el-radio label="30582">小册和联合创作者</el-radio>
23
+ <el-radio label="31129">无小册和联合创作者</el-radio>
24
+ </el-radio-group>
25
+ <singlebox :post="post" />
26
+ </el-tab-pane>
27
+ <el-tab-pane label="通用组件" name="widget">
28
+ <PostHeader :post="post" />
29
+ <Creators :postId="30432" style="margin-bottom:10px" />
30
+ <Collection :id="59" :defaultVisible="true" />
31
+ <UserPop title="添加用户" v-model="visible" @confirm="addUser" />
32
+ <el-button @click="visible = true">用户POP</el-button>
33
+
34
+ <Thx :postId="23865" postType="bbs" :userId="7" :adminBoxcoinEnable="true" :userBoxcoinEnable="true" />
35
+
36
+ <hr />
37
+
38
+ <Like mode="heart" :count="100" :showCount="true" />
39
+ <Down :count="100" :showCount="true" />
40
+ <Mark label="KEY" value="VALUE" BGL="#000" BGR="#F39" />
41
+ <Fav post-id="90" post-type="jx3dat" />
42
+ <Feed post-id="90" post-type="jx3dat" />
43
+ <Print title="传入标题" />
44
+ <QRcode />
45
+ <Sharing />
46
+
47
+ <hr />
48
+
49
+ <markBy />
50
+ <menuBy :data="['test1', 'test2']" />
51
+ <orderBy />
52
+ <tagBy :data="['PVE', 'PVX']" :type="tag" />
53
+ <clientBy type="" />
54
+ <zlpBy />
55
+ </el-tab-pane>
56
+ <el-tab-pane label="百科组件" name="wiki"
57
+ ><WikiPanel :wiki-post="wikiPost">
58
+ <template slot="head-title">
59
+ <i class="el-icon-location-information"></i>
60
+ <span class="u-title">通识正文</span>
61
+ </template>
62
+ <template slot="head-actions">
63
+ <a class="el-button el-button--primary u-publish">
64
+ <i class="el-icon-edit"></i>
65
+ <span>完善百科通识</span>
66
+ </a>
67
+ <span class="u-more">查看更多</span>
68
+ </template>
69
+ <template slot="body">正文内容正文内容正文内容正文内容正文内容正文内容正文内容正文内容正文内容</template>
70
+ </WikiPanel>
71
+ <hr />
72
+
73
+ <WikiRevisions type="achievement" source-id="9096"/>
74
+ <hr />
75
+
76
+ <WikiComments type="achievement" source-id="9096"/>
77
+ <hr
78
+ /></el-tab-pane>
79
+ </el-tabs>
77
80
 
78
81
  <RightSidebar>
79
- <div style="height:1200px;">
80
- <RightSideMsg>Test</RightSideMsg>
81
-
82
- <Author :author="author" uid="5" />
83
- </div>
82
+ <RightSideMsg>Hello</RightSideMsg>
83
+ <PostCollection :id="59" />
84
84
  </RightSidebar>
85
85
 
86
86
  <Footer></Footer>
@@ -105,7 +105,9 @@ import RightSideMsg from "./RightSideMsg.vue";
105
105
  import Footer from "./Footer.vue";
106
106
  import Bottom from "./Bottom.vue";
107
107
 
108
+ import singlebox from "./single/cms-single.vue";
108
109
  import PostHeader from "./single/PostHeader.vue";
110
+ import PostCollection from "./single/PostCollection.vue";
109
111
 
110
112
  import Thx from "./single/Thx.vue";
111
113
  import Collection from "./single/Collection.vue";
@@ -147,7 +149,9 @@ export default {
147
149
  Bottom,
148
150
  RightSidebar,
149
151
 
152
+ singlebox,
150
153
  PostHeader,
154
+ PostCollection,
151
155
 
152
156
  Thx,
153
157
  Collection,
@@ -178,39 +182,51 @@ export default {
178
182
  WikiRevisions,
179
183
  WikiComments,
180
184
 
181
- UserPop
185
+ UserPop,
182
186
  },
183
187
  data: function() {
184
188
  return {
189
+ tab: "post",
190
+
191
+ post: "",
192
+ post_id: "35605",
193
+
185
194
  author: "",
186
195
  wikiPost: null,
187
- tag : '',
188
- visible : false,
189
-
190
- post : ''
196
+ tag: "",
197
+ visible: false,
191
198
  };
192
199
  },
193
200
  created: function() {
194
- WikiPost.view(11042).then(
195
- (res) => {
196
- res = res.data;
197
- if (res.code === 200) this.wikiPost = res.data;
198
- }
199
- );
200
- axios.get('/api/cms/post/32035').then((res) => {
201
- this.post = res.data.data
202
- })
201
+ WikiPost.view(11042).then((res) => {
202
+ res = res.data;
203
+ if (res.code === 200) this.wikiPost = res.data;
204
+ });
203
205
  },
204
206
  methods: {
205
- addUser : function (val){
206
- console.log(val)
207
- }
207
+ addUser: function(val) {
208
+ console.log(val);
209
+ },
210
+ loadPost: function() {
211
+ axios.get(`/api/cms/post/${this.post_id}`).then((res) => {
212
+ this.post = res.data.data;
213
+ this.$forceUpdate()
214
+ });
215
+ },
216
+ },
217
+ watch: {
218
+ post_id: {
219
+ immediate: true,
220
+ handler: function(val) {
221
+ this.loadPost();
222
+ },
223
+ },
208
224
  },
209
225
  };
210
226
  </script>
211
227
 
212
228
  <style lang="less">
213
- body{
214
- padding-top:0;
215
- }
216
- </style>
229
+ body {
230
+ padding-top: 0;
231
+ }
232
+ </style>
@@ -16,7 +16,7 @@
16
16
  <el-dropdown-menu slot="dropdown" class="c-header-menu">
17
17
  <el-dropdown-item
18
18
  v-for="subitem in item.children"
19
- :key="subitem.key"
19
+ :key="'header-nav-drop-' + subitem.key"
20
20
  class="u-menu-item"
21
21
  >
22
22
  <a
@@ -1,18 +1,12 @@
1
1
  <template>
2
2
  <div class="w-collection" v-if="list && list.length">
3
3
  <div class="w-collection-title" @click="handleShow" :class="{ on: visible }">
4
- <span>
5
- <i class="el-icon-notebook-1"></i> 该作品已被收录至作者的剑三小册
6
- </span>
4
+ <span> <i class="el-icon-notebook-1"></i> 该作品已被收录至作者的剑三小册 </span>
7
5
  <a @click.stop :href="id | collectionLink" target="_blank">《{{ title }}》</a>
8
6
  </div>
9
7
  <transition name="fade">
10
8
  <div class="w-collection-list" v-if="visible">
11
- <ol
12
- v-if="list && list.length"
13
- class="u-list"
14
- :style="{ display: visible ? 'block' : 'none' }"
15
- >
9
+ <ol v-if="list && list.length" class="u-list" :style="{ display: visible ? 'block' : 'none' }">
16
10
  <li v-for="(item, i) in list" :key="i" class="u-item">
17
11
  <a v-if="item" :href="item | showLink" target="_blank">
18
12
  <!-- <i class="el-icon-link"></i> -->
@@ -30,10 +24,10 @@ import { getLink } from "@jx3box/jx3box-common/js/utils";
30
24
  import { getCollection } from "../../service/helper";
31
25
  export default {
32
26
  name: "Collection",
33
- props: ["id",'defaultVisible'],
27
+ props: ["id", "defaultVisible"],
34
28
  inject: [],
35
29
  components: {},
36
- data: function () {
30
+ data: function() {
37
31
  return {
38
32
  visible: this.defaultVisible || false,
39
33
  data: {
@@ -43,39 +37,46 @@ export default {
43
37
  };
44
38
  },
45
39
  computed: {
46
- title: function () {
40
+ title: function() {
47
41
  return this.data?.title;
48
42
  },
49
- list: function () {
43
+ list: function() {
50
44
  return this.data?.posts;
51
45
  },
52
46
  },
53
47
  watch: {
54
48
  id: {
55
49
  immediate: true,
56
- handler: function (val) {
57
- !!~~val && this.loadData();
50
+ handler: function(val) {
51
+ if (!!~~val) {
52
+ this.loadData();
53
+ } else {
54
+ this.data = {
55
+ title: "",
56
+ posts: [],
57
+ };
58
+ }
58
59
  },
59
60
  },
60
- defaultVisible : function (val){
61
- this.visible = val
62
- }
61
+ defaultVisible: function(val) {
62
+ this.visible = val;
63
+ },
63
64
  },
64
65
  methods: {
65
- handleShow: function () {
66
+ handleShow: function() {
66
67
  this.visible = !this.visible;
67
68
  },
68
- loadData: function () {
69
+ loadData: function() {
69
70
  getCollection(this.id).then((res) => {
70
71
  this.data = res.data?.data?.collection;
71
72
  });
72
73
  },
73
74
  },
74
75
  filters: {
75
- collectionLink: function (id) {
76
+ collectionLink: function(id) {
76
77
  return getLink("collection", id);
77
78
  },
78
- showLink: function (item) {
79
+ showLink: function(item) {
79
80
  if (item.type == "custom") {
80
81
  return item.url;
81
82
  } else {
@@ -83,12 +84,12 @@ export default {
83
84
  }
84
85
  },
85
86
  },
86
- created: function () {},
87
- mounted: function () {},
87
+ created: function() {},
88
+ mounted: function() {},
88
89
  };
89
90
  </script>
90
91
 
91
- <style scoped lang="less">
92
+ <style lang="less">
92
93
  .w-collection {
93
94
  &-title {
94
95
  cursor: pointer;
@@ -126,7 +127,7 @@ export default {
126
127
 
127
128
  counter-reset: collection;
128
129
  .u-item {
129
- .fz(13px,32px);
130
+ .fz(13px, 32px);
130
131
  border-bottom: 1px solid #eee;
131
132
  transition: 0.15s ease-in-out;
132
133
  .nobreak;
@@ -143,8 +144,8 @@ export default {
143
144
  color: @pink;
144
145
  }
145
146
  }
146
- &:last-child{
147
- border-bottom:none;
147
+ &:last-child {
148
+ border-bottom: none;
148
149
  }
149
150
  }
150
151
 
@@ -172,4 +173,4 @@ export default {
172
173
  opacity: 0;
173
174
  }
174
175
  }
175
- </style>
176
+ </style>
@@ -0,0 +1,86 @@
1
+ <template>
2
+ <div class="m-single-collection" v-if="list && list.length">
3
+ <div class="u-title"><i class="el-icon-connection"></i> 关联</div>
4
+ <ul class="u-list">
5
+ <li v-for="(item, i) in list" :key="i">
6
+ <el-tooltip class="item" effect="dark" :content="item.title" placement="left">
7
+ <a :href="item | showLink" target="_blank">
8
+ <i class="el-icon-link"></i>
9
+ {{ item.title }}
10
+ </a>
11
+ </el-tooltip>
12
+ </li>
13
+ </ul>
14
+ </div>
15
+ </template>
16
+
17
+ <script>
18
+ import { getLink } from "@jx3box/jx3box-common/js/utils";
19
+ import { getCollection } from "../../service/helper";
20
+ export default {
21
+ name: "PostCollection",
22
+ props: ["id", "store"],
23
+ components: {},
24
+ data: function() {
25
+ return {
26
+ data: {
27
+ title: "",
28
+ posts: [],
29
+ },
30
+ };
31
+ },
32
+ computed: {
33
+ list: function() {
34
+ return this.data?.posts || this.store?.posts;
35
+ },
36
+ },
37
+ watch: {
38
+ id: {
39
+ immediate: true,
40
+ handler: function(val) {
41
+ !!~~val && this.loadData();
42
+ },
43
+ },
44
+ },
45
+ methods: {
46
+ loadData: function() {
47
+ getCollection(this.id).then((res) => {
48
+ this.data = res.data?.data?.collection;
49
+ });
50
+ },
51
+ },
52
+ filters: {
53
+ showLink: function(item) {
54
+ if (item.type == "custom") {
55
+ return item.url;
56
+ } else {
57
+ return getLink(item.type, item.id);
58
+ }
59
+ },
60
+ },
61
+ };
62
+ </script>
63
+ <style scoped lang="less">
64
+ .m-single-collection {
65
+ .u-title {
66
+ font-weight: 300;
67
+ font-size: 20px;
68
+ }
69
+ .u-list {
70
+ list-style: none;
71
+ padding: 10px 20px;
72
+ margin: 0;
73
+ li {
74
+ .fz(13px, 36px);
75
+ }
76
+ a {
77
+ .db;
78
+ transition: 0.15s ease-in-out;
79
+ .nobreak;
80
+ &:hover {
81
+ background-color: #e6f0fb;
82
+ }
83
+ }
84
+ }
85
+ }
86
+ </style>
@@ -0,0 +1,77 @@
1
+ <template>
2
+ <div class="m-archive-box">
3
+ <!-- 搜索靠前 -->
4
+ <slot name="search-before"></slot>
5
+ <!-- 筛选 -->
6
+ <div class="m-archive-filter" v-if="$slots.filter">
7
+ <slot name="filter"></slot>
8
+ </div>
9
+ <!-- 搜索靠后 -->
10
+ <slot name="search-after"></slot>
11
+ <!-- 列表 -->
12
+ <slot></slot>
13
+ <!-- 空 -->
14
+ <el-alert v-if="!list.length" class="m-archive-null" title="没有找到相关条目" type="info" center show-icon></el-alert>
15
+ <!-- 下一页 -->
16
+ <el-button class="m-archive-more" :class="{ show: hasNextPage }" type="primary" @click="appendPage">加载更多</el-button>
17
+ <!-- 分页 -->
18
+ <el-pagination
19
+ class="m-archive-pages"
20
+ background
21
+ layout="total, prev, pager, next,jumper"
22
+ :hide-on-single-page="true"
23
+ :page-size="perPage"
24
+ :total="totalRecords"
25
+ :current-page.sync="currentPage"
26
+ @current-change="changePage"
27
+ ></el-pagination>
28
+ </div>
29
+ </template>
30
+ <script>
31
+ export default {
32
+ name: "cms-list",
33
+ props: ["data", "total", "per", "pages", "page"],
34
+ data: function() {
35
+ return {
36
+ currentPage: this.page || 1,
37
+ };
38
+ },
39
+ computed: {
40
+ list: function() {
41
+ return this.data;
42
+ },
43
+ totalRecords: function() {
44
+ return this.total;
45
+ },
46
+ totalPages: function() {
47
+ return this.pages;
48
+ },
49
+ perPage: function() {
50
+ return this.per;
51
+ },
52
+ hasNextPage: function() {
53
+ return this.totalRecords > 1 && this.currentPage < this.totalPages;
54
+ },
55
+ },
56
+ methods: {
57
+ appendPage: function() {
58
+ this.$emit("appendPage", ++this.currentPage);
59
+ },
60
+ changePage: function(i) {
61
+ this.$emit("changePage", i);
62
+ this.$route.query.page = i;
63
+ },
64
+ },
65
+ watch: {
66
+ page: function(page) {
67
+ this.currentPage = page;
68
+ },
69
+ },
70
+ mounted: function() {},
71
+ components: {},
72
+ };
73
+ </script>
74
+
75
+ <style lang="less">
76
+ @import "../../assets/css/cms-list.less";
77
+ </style>
@@ -0,0 +1,121 @@
1
+ <template>
2
+ <div class="m-single-box">
3
+ <!-- 头部 -->
4
+ <PostHeader :post="post" :stat="stat">
5
+ <slot name="single-header"></slot>
6
+ </PostHeader>
7
+
8
+ <!-- 文章前 -->
9
+ <div class="m-single-prepend">
10
+ <!-- 联合创作者 -->
11
+ <Creators class="m-single-creators" :postId="id" :postType="post_type" />
12
+ <!-- 文集小册 -->
13
+ <Collection class="m-single-collection" :id="collection_id" :defaultVisible="collection_collapse" />
14
+ <slot name="single-prepend"></slot>
15
+ </div>
16
+
17
+ <!-- 文章内容 -->
18
+ <div class="m-single-post" v-if="visible">
19
+ <el-divider content-position="left">JX3BOX</el-divider>
20
+ <div class="m-single-content">
21
+ <slot></slot>
22
+ <ArticleMarkdown v-if="isMarkdown" :content="post_content" />
23
+ <Article v-else :content="post_content" />
24
+ </div>
25
+ </div>
26
+ <div class="m-single-null" v-else>
27
+ <el-alert :title="null_tip" type="warning" show-icon></el-alert>
28
+ </div>
29
+
30
+ <!-- 文章后 -->
31
+ <div class="m-single-append">
32
+
33
+ <slot name="single-append"></slot>
34
+
35
+ <!-- 打赏 -->
36
+ <Thx class="m-single-thx" :postId="id" :postType="post_type" :userId="author_id" :adminBoxcoinEnable="true" :userBoxcoinEnable="true"/>
37
+
38
+ <!-- 评论 -->
39
+ <div class="m-single-comment">
40
+ <el-divider content-position="left">评论</el-divider>
41
+ <Comment :id="id" category="post" v-if="id && allow_comment" />
42
+ <el-alert title="作者没有开启评论功能" type="warning" show-icon v-else></el-alert>
43
+ </div>
44
+ </div>
45
+
46
+ <!-- 底部 -->
47
+ <footer class="m-single-footer">
48
+ <slot name="single-footer"></slot>
49
+ </footer>
50
+ </div>
51
+ </template>
52
+
53
+ <script>
54
+ import PostHeader from "./PostHeader.vue";
55
+ import Creators from "./Creators.vue";
56
+ import Collection from "./Collection.vue";
57
+ import Thx from "./Thx.vue";
58
+ import Article from "@jx3box/jx3box-editor/src/Article.vue";
59
+ import ArticleMarkdown from "@jx3box/jx3box-editor/src/ArticleMarkdown.vue";
60
+ import Comment from "@jx3box/jx3box-comment-ui/src/Comment.vue";
61
+ import { __visibleMap } from "@jx3box/jx3box-common/data/jx3box.json";
62
+ export default {
63
+ name: "cms-single",
64
+ components: {
65
+ PostHeader,
66
+ Creators,
67
+ Collection,
68
+ Thx,
69
+ Article,
70
+ ArticleMarkdown,
71
+ Comment,
72
+ },
73
+ props: ["post", "stat"],
74
+ data: function() {
75
+ return {
76
+ };
77
+ },
78
+ computed: {
79
+ id: function() {
80
+ return ~~this.post?.ID || 0;
81
+ },
82
+ post_type: function() {
83
+ return this.post?.post_type;
84
+ },
85
+ author_id : function (){
86
+ return this.post?.post_author
87
+ },
88
+ collection_id: function() {
89
+ return this.post?.post_collection;
90
+ },
91
+ collection_collapse: function() {
92
+ return this.post?.collection_collapse;
93
+ },
94
+ visible: function() {
95
+ return !!this.post?._check;
96
+ },
97
+ null_tip: function() {
98
+ let str = "作者设置了【";
99
+ str += __visibleMap[this.post?.visible];
100
+ str += "】";
101
+ return str;
102
+ },
103
+ post_content: function() {
104
+ return this.post?.post_content || "";
105
+ },
106
+ post_mode: function() {
107
+ return this.post?.post_mode || "tinymce";
108
+ },
109
+ isMarkdown: function() {
110
+ return this.post_mode == "markdown";
111
+ },
112
+ allow_comment : function (){
113
+ return !this.post?.comment
114
+ }
115
+ },
116
+ };
117
+ </script>
118
+
119
+ <style lang="less">
120
+ @import "../../assets/css/cms-single.less";
121
+ </style>