@jx3box/jx3box-vue3-ui 1.1.4 → 1.1.6

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jx3box/jx3box-vue3-ui",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "JX3BOX Vue3 UI",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/service/cms.js CHANGED
@@ -104,6 +104,11 @@ function refreshQQBotImage(data) {
104
104
  return $cms().post(`/api/cms/qqbot/picture_task`, data);
105
105
  }
106
106
 
107
+ // 获取用户permission
108
+ function getUserPermission() {
109
+ return $cms().get(`/api/cms/account/permission/i`)
110
+ }
111
+
107
112
  export {
108
113
  getPostAuthors,
109
114
  uploadImage,
@@ -122,4 +127,5 @@ export {
122
127
  loadEmotions,
123
128
  uploadFile,
124
129
  refreshQQBotImage,
130
+ getUserPermission,
125
131
  };
package/service/header.js CHANGED
@@ -28,4 +28,11 @@ function getGames() {
28
28
  return axios.get(JX3BOX.__dataPath + "data/product/games.json");
29
29
  }
30
30
 
31
- export { getMsg, getNav, getPanel, getBox, getMenu, getGames };
31
+ // 获取全局配置
32
+ function getGlobalConfig() {
33
+ return axios.get(`${JX3BOX.__ossRoot}config/global.json`).then((res) => {
34
+ return res.data;
35
+ });
36
+ }
37
+
38
+ export { getMsg, getNav, getPanel, getBox, getMenu, getGames, getGlobalConfig };
package/src/App.vue CHANGED
@@ -112,7 +112,7 @@ export default {
112
112
  },
113
113
  data() {
114
114
  return {
115
- post_id: "54842",
115
+ post_id: "74662",
116
116
  post: "",
117
117
  client: location.href.includes("origin") ? "origin" : "std",
118
118
  tag: "",
package/src/Header.vue CHANGED
@@ -38,6 +38,8 @@ import user from "./header/User.vue";
38
38
  import Box from "../src/Box.vue";
39
39
  import { isMiniProgram, miniprogramHack } from "@jx3box/jx3box-common/js/utils";
40
40
  import miniprogram from "@jx3box/jx3box-common/data/miniprogram.json";
41
+ import User from "@jx3box/jx3box-common/js/user";
42
+ import { getGlobalConfig } from "../service/header.js";
41
43
 
42
44
  export default {
43
45
  name: "CommonHeader",
@@ -54,21 +56,29 @@ export default {
54
56
  },
55
57
  },
56
58
  methods: {
59
+ // webView检测
57
60
  // webView检测
58
61
  checkIsWebView: function () {
59
62
  if (window.navigator.userAgent.includes(KW)) {
60
63
  document.documentElement.classList.add("env-app");
61
64
  }
62
65
 
66
+ const urlParams = new URLSearchParams(window.location.search);
67
+ const from = urlParams.get("from");
68
+ from && sessionStorage.setItem("from", from);
63
69
  if (isMiniProgram()) {
64
- const urlParams = new URLSearchParams(window.location.search);
65
70
  const appid = urlParams.get("appid");
66
71
  const item = miniprogram?.find((item) => item.appid === appid);
72
+ const from = urlParams.get("_from");
67
73
 
68
74
  document.documentElement.classList.add("v-miniprogram");
69
75
 
76
+ if (from) {
77
+ document.documentElement.classList.add("from-" + from);
78
+ }
79
+
70
80
  if (appid && item) {
71
- document.documentElement.classList.add("env-miniprogram" + item.id);
81
+ document.documentElement.classList.add("env-miniprogram-" + item.id);
72
82
 
73
83
  window.JX3BOX_ENV = item.id?.toUpperCase() + "_MINIPROGRAM";
74
84
  } else {
@@ -80,11 +90,80 @@ export default {
80
90
  miniprogramHack();
81
91
  }
82
92
  }
93
+
94
+ // 如果来自推栏
95
+ if (sessionStorage.getItem("from") == 'tl') {
96
+ document.documentElement.classList.add("v-miniprogram");
97
+ }
98
+
83
99
  },
84
100
 
85
101
  // 检查
86
102
  init: function () {
87
103
  this.checkIsWebView();
104
+
105
+ const token = this.getUrlParam("__token");
106
+
107
+ token && localStorage.setItem("__token", token);
108
+
109
+ if (User.isLogin()) {
110
+ this.loadAsset();
111
+ }
112
+
113
+ // 获取全局配置
114
+ getGlobalConfig().then(async (res) => {
115
+ const global_token_version = res.token_version;
116
+ const token_version = localStorage.getItem("token_version");
117
+
118
+ if (User.isLogin()) {
119
+ // 对于没有token_version或者token_version不是最新的用户,都需要登出
120
+ if (!token_version || token_version != global_token_version) {
121
+ // 先保存最新的token_version
122
+ localStorage.setItem("token_version", global_token_version);
123
+ // 然后执行登出操作
124
+ User.destroy().then(() => {
125
+ this.$refs.user?.logout();
126
+ // 清除马甲所有马甲信息
127
+ let keys = Object.keys(localStorage);
128
+ let alternate = keys.filter((key) => key.startsWith("jx3box-alternate-"));
129
+
130
+ alternate.forEach((key) => {
131
+ localStorage.removeItem(key);
132
+ });
133
+
134
+ if (
135
+ location.pathname.startsWith("/dashboard") ||
136
+ location.pathname.startsWith("/publish")
137
+ ) {
138
+ location.href = this.siteRoot;
139
+ }
140
+ });
141
+ }
142
+ } else {
143
+ // 非登录状态也更新token_version,确保用户下次登录时使用新版本
144
+ if (global_token_version) {
145
+ localStorage.setItem("token_version", global_token_version);
146
+ }
147
+ }
148
+ });
149
+ },
150
+
151
+ getUrlParam(name) {
152
+ var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
153
+ var r = window.location.search.substr(1).match(reg);
154
+ return r ? decodeURIComponent(r[2]) : null;
155
+ },
156
+ // 资产
157
+ loadAsset: function () {
158
+ User.getAsset().then((data) => {
159
+ this.asset = data;
160
+
161
+ const level = User.getLevel(this.asset?.experience);
162
+
163
+ if (level > 2) {
164
+ document.documentElement.classList.add("is-comment-show");
165
+ }
166
+ });
88
167
  },
89
168
  },
90
169
  created: function () {
@@ -1,7 +1,8 @@
1
1
  <template>
2
2
  <div class="c-author-info">
3
3
  <div class="u-author">
4
- <Avatar class="u-avatar" :uid="uid" :url="data.user_avatar" size="s" :frame="data.user_avatar_frame" />
4
+ <Avatar class="u-avatar" :uid="uid" :url="data.user_avatar" size="s" :frame="data.user_avatar_frame" v-if="!anonymous" />
5
+ <Avatar v-else class="u-avatar" :url="defaultUrl" size="s"></Avatar>
5
6
  <div class="u-info">
6
7
  <div class="u-name">
7
8
  <el-tooltip class="item" effect="dark" content="签约作者" placement="top" v-if="isSuperAuthor">
@@ -9,12 +10,13 @@
9
10
  <img :src="super_author_icon" alt="superauthor" />
10
11
  </a>
11
12
  </el-tooltip>
12
- <a class="u-displayname" :href="authorLink(uid)" target="_blank">
13
+ <a class="u-displayname" :href="authorLink(uid)" target="_blank" v-if="!anonymous">
13
14
  {{ data.display_name || "未知" }}
14
15
  </a>
16
+ <span class="u-displayname u-anonymous" v-else>神秘侠士</span>
15
17
  </div>
16
18
  <div class="u-extend">
17
- <el-tooltip class="item" effect="dark" placement="top">
19
+ <el-tooltip class="item" effect="dark" placement="top" v-if="!anonymous">
18
20
  <template #content>
19
21
  <span class="u-tips">经验值:{{ data.experience }}</span>
20
22
  </template>
@@ -27,7 +29,16 @@
27
29
  >Lv.{{ level }}</a
28
30
  >
29
31
  </el-tooltip>
30
- <el-tooltip class="item" effect="dark" :content="vipTypeTitle" placement="top" v-if="isVip">
32
+ <a
33
+ v-else
34
+ class="u-level"
35
+ :class="'lv-' + level"
36
+ :style="{ backgroundColor: showLevelColor(level) }"
37
+ href="/about/incentives"
38
+ target="_blank"
39
+ >Lv.{{ level }}</a
40
+ >
41
+ <el-tooltip class="item" effect="dark" :content="vipTypeTitle" placement="top" v-if="isVip && !anonymous">
31
42
  <a class="u-vip" href="/vip/premium?from=sidebar_author" target="_blank">
32
43
  <i class="i-icon-vip on">{{ vipType }}</i>
33
44
  </a>
@@ -49,10 +60,10 @@ import { getUserInfo } from "../../service/author";
49
60
  import Avatar from "./Avatar.vue";
50
61
  import Honor from "./AuthorHonor.vue";
51
62
 
52
- const { __imgPath, __userLevelColor } = JX3BOX;
63
+ const { __imgPath, __userLevelColor, __cdn } = JX3BOX;
53
64
  export default {
54
65
  name: "AuthorInfo",
55
- props: ["uid"],
66
+ props: ["uid", "anonymous"],
56
67
  components: {
57
68
  Avatar,
58
69
  Honor,
@@ -67,7 +78,7 @@ export default {
67
78
  computed: {
68
79
  // level
69
80
  level: function () {
70
- return User.getLevel(this.data?.experience);
81
+ return this.anonymous ? -1 : User.getLevel(this.data?.experience);
71
82
  },
72
83
 
73
84
  // vip
@@ -85,6 +96,9 @@ export default {
85
96
  isSuperAuthor: function () {
86
97
  return this.data?.sign;
87
98
  },
99
+ defaultUrl: function () {
100
+ return `${__cdn}/design/avatar/xisai/0-1.png`
101
+ },
88
102
  },
89
103
  watch: {
90
104
  uid: {
@@ -139,6 +153,12 @@ export default {
139
153
  color: #f39;
140
154
  }
141
155
  }
156
+ .u-anonymous {
157
+ color: #888;
158
+ &:hover {
159
+ color: #888;
160
+ }
161
+ }
142
162
  .u-superauthor {
143
163
  // margin-left: 4px;
144
164
  // display: inline-block;
@@ -21,7 +21,13 @@
21
21
  <i title="品鉴"><img class svg-inline src="../../assets/img/widget/admin_gift.svg" /></i>
22
22
  </template>
23
23
  </span>
24
- <a class="u-meta u-user" :href="authorLink(item.operate_user_id)" target="_blank">
24
+ <template v-if="item.ext_operate_user_info?.id == 1">
25
+ <span class="u-meta u-user u-default">
26
+ <img class="u-user-avatar" :src="showAvatar(item.ext_operate_user_info.avatar)" alt />
27
+ <span>系统</span>
28
+ </span>
29
+ </template>
30
+ <a v-else class="u-meta u-user" :href="authorLink(item.operate_user_id)" target="_blank">
25
31
  <img class="u-user-avatar" :src="showAvatar(item.ext_operate_user_info.avatar)" alt />
26
32
  <span>{{ item.ext_operate_user_info.display_name }}</span>
27
33
  </a>
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="c-author">
3
- <AuthorInfo :uid="uid" @ready="installModules" />
3
+ <AuthorInfo :uid="uid" :anonymous="anonymous" @ready="installModules" />
4
4
  <template v-if="data">
5
5
  <div class="u-interact">
6
6
  <!-- <AuthorFollow style="margin-right: 8px;" :uid="uid" /> -->
@@ -34,7 +34,7 @@ import AuthorRss from "../author/AuthorRss.vue";
34
34
  const jx3box = require("@jx3box/jx3box-common/data/jx3box.json");
35
35
  export default {
36
36
  name: "AuthorComp",
37
- props: ["uid"],
37
+ props: ["uid", "anonymous"],
38
38
  data: function () {
39
39
  return {
40
40
  data: "",
@@ -43,6 +43,9 @@ export default {
43
43
  },
44
44
  methods: {
45
45
  installModules: function (data) {
46
+ if (this.anonymous == 1) {
47
+ return;
48
+ }
46
49
  this.data = data;
47
50
  },
48
51
  onMessage: function () {
@@ -28,7 +28,8 @@
28
28
  <i class="u-author-icon">
29
29
  <img svg-inline src="../../assets/img/single/author.svg" />
30
30
  </i>
31
- <a class="u-name" :href="author_link">{{ author_name }}</a>
31
+ <a class="u-name" :href="author_link" v-if="!anonymous">{{ author_name }}</a>
32
+ <span class="u-name u-anonymous" v-else>神秘侠士</span>
32
33
  </div>
33
34
 
34
35
  <!-- 自定义字段 -->
@@ -75,7 +76,7 @@
75
76
  </span>
76
77
 
77
78
  <!-- 编辑 -->
78
- <a class="u-edit u-sub-block" :href="edit_link" v-if="canEdit">
79
+ <a class="u-edit u-sub-block" :href="edit_link" v-if="canEdit && !anonymous">
79
80
  <el-icon class="u-icon-edit" :size="16"><Edit /></el-icon>
80
81
  <span>编辑</span>
81
82
  </a>
@@ -93,7 +94,7 @@ const { __clients } = JX3BOX;
93
94
 
94
95
  export default {
95
96
  name: "PostHeader",
96
- props: ["post", "stat", "titleExtra"],
97
+ props: ["post", "stat", "titleExtra", "anonymous",],
97
98
  data: function () {
98
99
  return {
99
100
  wordCount: 0,
@@ -4,7 +4,7 @@
4
4
  <boxcoin-admin
5
5
  :postId="postId"
6
6
  :postType="postType"
7
- v-if="hasRight && adminBoxcoinEnable && boxcoin_enable"
7
+ v-if="hasRight && adminBoxcoinEnable && boxcoin_enable && hasPermission"
8
8
  :userId="userId"
9
9
  :max="admin_max"
10
10
  :min="admin_min"
@@ -14,6 +14,9 @@
14
14
  :authors="authors"
15
15
  @updateRecord="updateRecord"
16
16
  :client="finalClient"
17
+ :totalLimit="total_limit"
18
+ :postTypeUsed="post_type_used"
19
+ :category="category"
17
20
  />
18
21
  <Like :postId="postId" :postType="postType"></Like>
19
22
  <fav :postId="postId" :postType="postType" :postTitle="postTitle"></fav>
@@ -29,13 +32,14 @@
29
32
  v-if="userBoxcoinEnable && boxcoin_enable && allowGift"
30
33
  @updateRecord="updateRecord"
31
34
  :client="finalClient"
35
+ :category="category"
32
36
  />
33
37
  <Share :postId="postId" :postType="postType" :client="client" />
34
38
  <watch-later :category="postType" :title="postTitle" :author-id="authorId" :banner="banner" :content-id="contentMetaId"></watch-later>
35
39
  </div>
36
40
  <div class="w-thx-records">
37
41
  <boxcoin-records :postId="postId" :postType="postType" :postClient="finalClient" :cacheRecord="cacheRecord"
38
- :mode="mode" @update:boxcoin="updateBoxcoin" />
42
+ :mode="mode" @update:boxcoin="updateBoxcoin" v-if="showRecord" />
39
43
  </div>
40
44
  <div class="w-thx-copyright">
41
45
  &copy;
@@ -57,6 +61,7 @@ import Rss from "../interact/Rss.vue";
57
61
 
58
62
  import User from "@jx3box/jx3box-common/js/user";
59
63
  import { getBoxcoinStatus, getPostBoxcoinConfig } from "../../service/thx";
64
+ import {getConfig,getUserPermission} from "../../service/cms"
60
65
 
61
66
  export default {
62
67
  name: "ThxComp",
@@ -135,7 +140,7 @@ export default {
135
140
  data: function () {
136
141
  return {
137
142
  boxcoin: 0,
138
- hasRight: User.getInfo().group >= 32,
143
+ hasRight: User.getInfo().group >= 64,
139
144
  user: User.getInfo(),
140
145
 
141
146
  admin_max: 0,
@@ -143,6 +148,8 @@ export default {
143
148
  admin_left: 0,
144
149
  admin_total: 0,
145
150
  admin_points: [100],
151
+ total_limit: 0,
152
+ post_type_used: 0,
146
153
 
147
154
  user_left: 0,
148
155
  user_points: [100],
@@ -151,6 +158,9 @@ export default {
151
158
  boxcoin_enable: 0,
152
159
 
153
160
  showDrawer: false,
161
+
162
+ admin_boxcoin_visible: 1,
163
+ hasPermission: false,
154
164
  };
155
165
  },
156
166
  computed: {
@@ -162,6 +172,13 @@ export default {
162
172
  return "std"
163
173
  }
164
174
  return this.client
175
+ },
176
+ showRecord() {
177
+ // 当admin_boxcoin_visible为0时,作者本人和64及以上权限可见打赏记录
178
+ if (this.admin_boxcoin_visible === 0) {
179
+ return this.userId == this.user.uid || this.user.group >= 64;
180
+ }
181
+ return true;
165
182
  }
166
183
  },
167
184
  watch: {
@@ -182,6 +199,8 @@ export default {
182
199
  this.admin_points = res.data.data.limit.admin_points || [10, 1000];
183
200
  this.admin_left = res.data.data.asManagerBoxCoinRemain || 0;
184
201
  this.admin_total = res.data.data.asManagerBoxCoinTotal || 0;
202
+ this.total_limit = res.data.data.limit.total_limit || 0;
203
+ this.post_type_used = res.data.data.asPostTypeBoxcoinHasUsedTotalAtCurrentYear || 0;
185
204
 
186
205
  this.user_points = res.data.data.limit.user_points || [10, 1000];
187
206
  // 根据多端展示剩余币
@@ -200,6 +219,17 @@ export default {
200
219
  getBoxcoinStatus().then((res) => {
201
220
  this.boxcoin_enable = !!~~res.data?.data?.val;
202
221
  });
222
+
223
+ getConfig({
224
+ key: 'admin_boxcoin_visible'
225
+ }).then((res) => {
226
+ this.admin_boxcoin_visible = Number(res?.val)
227
+ });
228
+
229
+ User.isLogin() && getUserPermission().then(res => {
230
+ const permissions = res.data.data.permission?.map(item => item.action)
231
+ this.hasPermission = permissions.includes(`manage_boxcoin_${this.postType}`) || User.isSuperAdmin();
232
+ })
203
233
  },
204
234
  // 用户打赏
205
235
  updateRecord: function (data) {
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="m-single-box">
3
3
  <!-- 头部 -->
4
- <PostHeader :post="post" :stat="stat">
4
+ <PostHeader :post="post" :stat="stat" :anonymous="anonymous">
5
5
  <slot name="single-header"></slot>
6
6
  </PostHeader>
7
7
 
@@ -171,6 +171,9 @@ export default {
171
171
  community_id: function () {
172
172
  return this.post?.community_id || 0;
173
173
  },
174
+ anonymous: function () {
175
+ return this.post?.anonymous ==1;
176
+ }
174
177
  },
175
178
  methods: {
176
179
  updateCollection: function (val) {