@jx3box/jx3box-common-ui 5.3.8 → 5.4.2

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,328 @@
1
+ <template>
2
+ <header class="m-single-header" v-if="post">
3
+ <!-- 标题 -->
4
+ <div class="m-single-title">
5
+ <span class="u-title u-sub-block" :href="url" :title="title">
6
+ <i class="u-original" v-if="isOriginal">原创</i>
7
+ <i class="u-private" v-if="post.post_status != 'publish'">
8
+ <i class="el-icon-lock" v-if="post.post_status == 'draft' || post.post_status == 'pending' || ~~post.visible" style="color:#fb9b24"></i>
9
+ <i class="el-icon-delete" v-if="post.post_status == 'dustbin'" style="color:#c00"></i>
10
+ </i>
11
+ <span class="u-title-text">{{ title }}</span>
12
+ </span>
13
+ </div>
14
+
15
+ <!-- 信息 -->
16
+ <div class="m-single-info">
17
+ <!-- 用户名 -->
18
+ <div class="u-author u-sub-block">
19
+ <i class="u-author-icon">
20
+ <img svg-inline src="../../assets/img/single/author.svg" />
21
+ </i>
22
+ <a class="u-name" :href="author_link">{{ author_name }}</a>
23
+ </div>
24
+
25
+ <!-- 自定义字段 -->
26
+ <!-- <template v-if="metas && metas.length">
27
+ <div class="u-meta u-sub-block" v-for="(meta_value,meta_key) in metas" :key="meta_key">
28
+ <em class="u-label">{{meta_key}}</em>
29
+ <span class="u-value">{{meta_value}}</span>
30
+ </div>
31
+ </template> -->
32
+ <slot></slot>
33
+
34
+ <!-- 客户端 -->
35
+ <div class="u-meta u-sub-block">
36
+ <em class="u-label">适用客户端</em>
37
+ <span class="u-value u-client" :class="client">{{ client | showClientLabel }}</span>
38
+ </div>
39
+
40
+ <!-- 发布日期 -->
41
+ <span class="u-podate u-sub-block" :title="'发布日期:' + post_time">
42
+ <i class="u-icon-podate">
43
+ <img svg-inline src="../../assets/img/single/podate.svg" />
44
+ </i>
45
+ <time>{{ post_date }}</time>
46
+ </span>
47
+
48
+ <!-- 最后更新 -->
49
+ <span class="u-modate u-sub-block" :title="'最后更新:' + update_time">
50
+ <i class="u-icon-modate">
51
+ <img svg-inline src="../../assets/img/single/modate.svg" />
52
+ </i>
53
+ <time>{{ update_date }}</time>
54
+ </span>
55
+
56
+ <!-- 查看次数 -->
57
+ <span class="u-views u-sub-block">
58
+ <i class="el-icon-view"></i>
59
+ {{ views }}
60
+ </span>
61
+
62
+ <!-- 编辑 -->
63
+ <a class="u-edit u-sub-block" :href="edit_link" v-if="canEdit">
64
+ <i class="u-icon-edit el-icon-edit-outline"></i>
65
+ <span>编辑</span>
66
+ </a>
67
+ </div>
68
+ </header>
69
+ </template>
70
+
71
+ <script>
72
+ import { __Root } from "@jx3box/jx3box-common/data/jx3box.json";
73
+ import { showDate, showTime } from "@jx3box/jx3box-common/js/moment";
74
+ import { editLink, authorLink } from "@jx3box/jx3box-common/js/utils.js";
75
+ import User from "@jx3box/jx3box-common/js/user.js";
76
+ import client_map from "../../assets/data/clients.json";
77
+ export default {
78
+ name: "single-header",
79
+ props: ["post", "stat"],
80
+ data: function() {
81
+ return {};
82
+ },
83
+ computed: {
84
+ url: function() {
85
+ return location.href;
86
+ },
87
+ isOriginal: function() {
88
+ return !!~~this.post?.original;
89
+ },
90
+ title: function() {
91
+ return this.post?.post_title || "无标题";
92
+ },
93
+ author_link: function() {
94
+ return authorLink(this.post?.post_author);
95
+ },
96
+ author_name: function() {
97
+ return this.post?.author || "匿名";
98
+ },
99
+ post_date: function() {
100
+ return showDate(new Date(this.post?.post_date));
101
+ },
102
+ update_date: function() {
103
+ return showDate(new Date(this.post?.post_modified));
104
+ },
105
+ post_time: function() {
106
+ return showTime(new Date(this.post?.post_date));
107
+ },
108
+ update_time: function() {
109
+ return showTime(new Date(this.post?.post_modified));
110
+ },
111
+ views: function() {
112
+ return this.stat?.views || "-";
113
+ },
114
+ edit_link: function() {
115
+ return editLink(this.post?.post_type, this.post?.ID);
116
+ },
117
+ canEdit: function() {
118
+ return this.post?.post_author == User.getInfo().uid || User.isEditor();
119
+ },
120
+ client: function() {
121
+ return this.post?.client || "std";
122
+ },
123
+ },
124
+ methods: {},
125
+ mounted: function() {},
126
+ filters: {
127
+ showClientLabel: function(val) {
128
+ return client_map[val];
129
+ },
130
+ },
131
+ };
132
+ </script>
133
+
134
+ <style lang="less">
135
+ .m-single-header {
136
+ padding-top: 20px;
137
+ padding-bottom: 20px;
138
+ padding-right: 280px;
139
+ .pr;
140
+ .u-sub-block {
141
+ .dbi;
142
+ .y(top);
143
+ }
144
+ }
145
+ @media screen and (max-width: @phone) {
146
+ .m-single-header {
147
+ padding-right: 0;
148
+ }
149
+ }
150
+ @media print {
151
+ .m-single-header {
152
+ padding-right: 0;
153
+ }
154
+ }
155
+
156
+ .m-single-title {
157
+ .fz(32px);
158
+ padding: 1px 0;
159
+
160
+ .u-title {
161
+ color: @color;
162
+ // &:hover {
163
+ // color: @primary;
164
+ // }
165
+ letter-spacing: 0.5px;
166
+ font-weight: 300;
167
+ .db;
168
+ .nobreak;
169
+ }
170
+ .u-author {
171
+ .pr;
172
+ }
173
+
174
+ .u-original {
175
+ background-color: #6f42c1;
176
+ color: #fff;
177
+ .fz(14px, 20px);
178
+ font-style: normal;
179
+ font-weight: normal;
180
+ padding: 2px 5px;
181
+ .mr(5px);
182
+ // .fl;
183
+ }
184
+
185
+ .u-private {
186
+ .y(-2px);
187
+ margin-right: 5px;
188
+ color: #111;
189
+ }
190
+ }
191
+ @media screen and (max-width: @phone) {
192
+ .m-single-title {
193
+ .fz(1rem, 1.8);
194
+ .u-title {
195
+ word-break: break-all;
196
+ white-space: normal;
197
+ font-weight: normal;
198
+ }
199
+ }
200
+ }
201
+ @media print {
202
+ .m-single-title {
203
+ .x;
204
+ }
205
+ }
206
+
207
+ .m-single-info {
208
+ margin-top: 10px;
209
+ .clearfix;
210
+ .fz(12px, 20px);
211
+ color: #666;
212
+
213
+ @origin: #0eb7ce;
214
+ @std: #f0b400;
215
+ @all: #a26ef7;
216
+
217
+ .u-client {
218
+ // .fl;
219
+ font-style: normal;
220
+ .fz(12px);
221
+ padding: 0px 5px;
222
+ .r(3px);
223
+ // .mr(10px);
224
+
225
+ &.std {
226
+ border: 1px solid @std;
227
+ color: @std;
228
+ }
229
+
230
+ &.origin {
231
+ border: 1px solid @origin;
232
+ color: @origin;
233
+ }
234
+
235
+ &.all {
236
+ border: 1px solid @all;
237
+ color: @all;
238
+ }
239
+ }
240
+
241
+ * {
242
+ .dbi;
243
+ }
244
+
245
+ svg {
246
+ fill: #666;
247
+ .size(16px);
248
+ .y;
249
+ .mr(3px);
250
+ }
251
+
252
+ .u-sub-block {
253
+ .mr(15px);
254
+ .fl;
255
+ }
256
+
257
+ .u-author {
258
+ a:hover {
259
+ box-shadow: 0 1px 0 @color-link;
260
+ }
261
+ i {
262
+ .pr;
263
+ top: -2px;
264
+ }
265
+ }
266
+
267
+ .u-label {
268
+ .mr(5px);
269
+ background-color: #eee;
270
+ padding: 0 5px;
271
+ .r(2px);
272
+ font-style: normal;
273
+ }
274
+ .u-value {
275
+ }
276
+
277
+ .u-views {
278
+ i {
279
+ .fz(15px);
280
+ .y;
281
+ }
282
+ }
283
+
284
+ .u-edit {
285
+ i {
286
+ &:before {
287
+ font-size: 16px;
288
+ }
289
+ .pr;
290
+ top: 2px;
291
+ .mr(3px);
292
+ }
293
+ &:hover {
294
+ box-shadow: 0 1px 0 @color-link;
295
+ }
296
+ }
297
+ }
298
+ @media screen and (max-width: @ipad) {
299
+ .m-single-info {
300
+ .u-meta {
301
+ .none;
302
+ }
303
+ }
304
+ }
305
+ @media screen and (max-width: @phone) {
306
+ .m-single-info {
307
+ .u-podate {
308
+ .none;
309
+ }
310
+ }
311
+ }
312
+ @media print {
313
+ .m-single-info {
314
+ .u-meta,
315
+ .u-views,
316
+ .u-edit {
317
+ .none;
318
+ }
319
+ .x;
320
+ .u-sub-block {
321
+ float: none;
322
+ }
323
+ .u-name {
324
+ color: @color;
325
+ }
326
+ }
327
+ }
328
+ </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,120 @@
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
+ <ArticleMarkdown v-if="isMarkdown" :content="post_content" />
22
+ <Article v-else :content="post_content" />
23
+ <slot></slot>
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
+ <Thx class="m-single-thx" :postId="id" :postType="post_type" :userId="author_id" :adminBoxcoinEnable="true" :userBoxcoinEnable="true"/>
34
+
35
+ <slot name="single-append"></slot>
36
+
37
+ <!-- 评论 -->
38
+ <div class="m-single-comment">
39
+ <el-divider content-position="left">评论</el-divider>
40
+ <Comment :id="id" category="post" v-if="id && allow_comment" />
41
+ <el-alert title="作者没有开启评论功能" type="warning" show-icon v-else></el-alert>
42
+ </div>
43
+ </div>
44
+
45
+ <!-- 底部 -->
46
+ <footer class="m-single-footer">
47
+ <slot name="single-footer"></slot>
48
+ </footer>
49
+ </div>
50
+ </template>
51
+
52
+ <script>
53
+ import PostHeader from "./PostHeader.vue";
54
+ import Creators from "./Creators.vue";
55
+ import Collection from "./Collection.vue";
56
+ import Thx from "./Thx.vue";
57
+ import Article from "@jx3box/jx3box-editor/src/Article.vue";
58
+ import ArticleMarkdown from "@jx3box/jx3box-editor/src/ArticleMarkdown.vue";
59
+ import Comment from "@jx3box/jx3box-comment-ui/src/Comment.vue";
60
+ import { __visibleMap } from "@jx3box/jx3box-common/data/jx3box.json";
61
+ export default {
62
+ name: "cms-single",
63
+ components: {
64
+ PostHeader,
65
+ Creators,
66
+ Collection,
67
+ Thx,
68
+ Article,
69
+ ArticleMarkdown,
70
+ Comment,
71
+ },
72
+ props: ["post", "stat"],
73
+ data: function() {
74
+ return {
75
+ };
76
+ },
77
+ computed: {
78
+ id: function() {
79
+ return ~~this.post?.ID || 0;
80
+ },
81
+ post_type: function() {
82
+ return this.post?.post_type;
83
+ },
84
+ author_id : function (){
85
+ return this.post?.post_author
86
+ },
87
+ collection_id: function() {
88
+ return this.post?.post_collection;
89
+ },
90
+ collection_collapse: function() {
91
+ return this.post?.collection_collapse;
92
+ },
93
+ visible: function() {
94
+ return !!this.post?._check;
95
+ },
96
+ null_tip: function() {
97
+ let str = "作者设置了【";
98
+ str += __visibleMap[this.post?.visible];
99
+ str += "】";
100
+ return str;
101
+ },
102
+ post_content: function() {
103
+ return this.post?.post_content || "";
104
+ },
105
+ post_mode: function() {
106
+ return this.post?.post_mode || "tinymce";
107
+ },
108
+ isMarkdown: function() {
109
+ return this.post_mode == "markdown";
110
+ },
111
+ allow_comment : function (){
112
+ return !this.post?.comment
113
+ }
114
+ },
115
+ };
116
+ </script>
117
+
118
+ <style lang="less">
119
+ @import "../../assets/css/cms-single.less";
120
+ </style>