xs-common-plugins 1.3.7 → 1.3.9

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,60 @@
1
+ <component name="ProjectCodeStyleConfiguration">
2
+ <code_scheme name="Project" version="173">
3
+ <option name="RIGHT_MARGIN" value="300" />
4
+ <HTMLCodeStyleSettings>
5
+ <option name="HTML_ATTRIBUTE_WRAP" value="0" />
6
+ <option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
7
+ </HTMLCodeStyleSettings>
8
+ <JSCodeStyleSettings version="0">
9
+ <option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
10
+ <option name="FORCE_SEMICOLON_STYLE" value="true" />
11
+ <option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
12
+ <option name="USE_DOUBLE_QUOTES" value="false" />
13
+ <option name="FORCE_QUOTE_STYlE" value="true" />
14
+ <option name="ENFORCE_TRAILING_COMMA" value="Remove" />
15
+ <option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
16
+ <option name="SPACES_WITHIN_IMPORTS" value="true" />
17
+ </JSCodeStyleSettings>
18
+ <TypeScriptCodeStyleSettings version="0">
19
+ <option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
20
+ <option name="FORCE_SEMICOLON_STYLE" value="true" />
21
+ <option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
22
+ <option name="USE_DOUBLE_QUOTES" value="false" />
23
+ <option name="FORCE_QUOTE_STYlE" value="true" />
24
+ <option name="ENFORCE_TRAILING_COMMA" value="Remove" />
25
+ <option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
26
+ <option name="SPACES_WITHIN_IMPORTS" value="true" />
27
+ </TypeScriptCodeStyleSettings>
28
+ <VueCodeStyleSettings>
29
+ <option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
30
+ <option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
31
+ </VueCodeStyleSettings>
32
+ <codeStyleSettings language="HTML">
33
+ <option name="SOFT_MARGINS" value="400" />
34
+ <indentOptions>
35
+ <option name="CONTINUATION_INDENT_SIZE" value="4" />
36
+ <option name="USE_TAB_CHARACTER" value="true" />
37
+ </indentOptions>
38
+ </codeStyleSettings>
39
+ <codeStyleSettings language="JavaScript">
40
+ <option name="SOFT_MARGINS" value="400" />
41
+ <indentOptions>
42
+ <option name="USE_TAB_CHARACTER" value="true" />
43
+ </indentOptions>
44
+ </codeStyleSettings>
45
+ <codeStyleSettings language="TypeScript">
46
+ <option name="SOFT_MARGINS" value="400" />
47
+ <indentOptions>
48
+ <option name="USE_TAB_CHARACTER" value="true" />
49
+ </indentOptions>
50
+ </codeStyleSettings>
51
+ <codeStyleSettings language="Vue">
52
+ <option name="SOFT_MARGINS" value="400" />
53
+ <indentOptions>
54
+ <option name="INDENT_SIZE" value="4" />
55
+ <option name="TAB_SIZE" value="4" />
56
+ <option name="USE_TAB_CHARACTER" value="true" />
57
+ </indentOptions>
58
+ </codeStyleSettings>
59
+ </code_scheme>
60
+ </component>
@@ -0,0 +1,5 @@
1
+ <component name="ProjectCodeStyleConfiguration">
2
+ <state>
3
+ <option name="USE_PER_PROJECT_SETTINGS" value="true" />
4
+ </state>
5
+ </component>
package/.prettierrc ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "useTabs": true,
3
+ "tabWidth": 4,
4
+ "printWidth": 400,
5
+ "singleQuote": true,
6
+ "jsxSingleQuote": true,
7
+ "trailingComma": "none",
8
+ "semi": false,
9
+ "arrowParens": "avoid",
10
+ "bracketSameLine": true,
11
+ "vueIndentScriptAndStyle": false,
12
+ "embeddedLanguageFormatting": "auto",
13
+ "htmlWhitespaceSensitivity": "css"
14
+ }
package/README.md CHANGED
@@ -324,3 +324,13 @@
324
324
  2.新增 ca.js 用于埋点统计
325
325
  3.修改 permission.js 页面路由beforeEach方法,增加埋点数据发送
326
326
  ```
327
+ ```
328
+ 1.3.8
329
+ 1. Navbar 新增 ChangeLog 组件
330
+ ```
331
+
332
+ ```
333
+ 1.3.9
334
+ 1. 新增UpdateChecker组件, 用于检测更新
335
+ 2. 优化了买点发送函数
336
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xs-common-plugins",
3
- "version": "1.3.7",
3
+ "version": "1.3.9",
4
4
  "private": false,
5
5
  "description": "向上公共代码部分",
6
6
  "author": "祝玲云 <1902733517@qq.com>",
package/src/App.vue CHANGED
@@ -2,10 +2,18 @@
2
2
  <div id="app">
3
3
  <router-view/>
4
4
  <router-view name="websocket"/>
5
+ <UpdateChecker />
5
6
  </div>
6
7
  </template>
7
8
 
8
9
  <script>
10
+ import UpdateChecker from './components/UpdateChecker'
11
+ export default {
12
+ name: 'App',
13
+ components: {
14
+ UpdateChecker
15
+ }
16
+ }
9
17
 
10
18
  </script>
11
19
 
@@ -0,0 +1,88 @@
1
+ <script>
2
+ import md5 from 'js-md5'
3
+ import { defineComponent } from 'vue'
4
+ import trackerSend from "@/router/ca";
5
+
6
+ function trackerSendUpdateChecker({action} = {}) {
7
+ trackerSend({
8
+ title: "检测到新版本",
9
+ action
10
+ })
11
+ }
12
+
13
+ const DURATION = 1000 * 60 * 60 * 2
14
+ export default {
15
+ name: 'UpdateChecker',
16
+ data () {
17
+ return {
18
+ md5: '',
19
+ interval: null
20
+ }
21
+ },
22
+ methods: {
23
+ check() {
24
+ return fetch(`${location.origin}${location.pathname}`, {
25
+ cache: 'no-cache',
26
+ }).then(async (res) => {
27
+ return res.text()
28
+ })
29
+ },
30
+ start() {
31
+ this.stop()
32
+ this.interval = setInterval(() => {
33
+ this.check().then(text => {
34
+ const newMd5 = md5(text)
35
+ if (newMd5 !== this.md5) {
36
+ this.stop()
37
+ this.notify()
38
+ trackerSendUpdateChecker({action: "检测到新版本通知用户"})
39
+ }
40
+ })
41
+ }, DURATION)
42
+ },
43
+ stop() {
44
+ if (!this.interval) return
45
+ clearInterval(this.interval)
46
+ },
47
+ refresh() {
48
+ trackerSendUpdateChecker({action: "检测到新版本刷新页面"})
49
+ window.location.reload()
50
+ },
51
+ onClose() {
52
+ this.start()
53
+ trackerSendUpdateChecker({action: "检测到新版本关闭提示"})
54
+ },
55
+ notify() {
56
+ this.$common.popup({
57
+ title: '检测到新版本',
58
+ component: defineComponent({
59
+ template: `<div>
60
+ <div style="font-size: 14px;color: #606266;line-height: 20px;padding: 10px 20px">
61
+ 检测到有新版本已经发布,请刷新页面
62
+ </div>
63
+ <div style="text-align: center"><el-button type="primary" @click="refresh">刷新</el-button></div>
64
+ </div>`,
65
+ methods: {
66
+ refresh: () => this.refresh(),
67
+ beforeClose: (done) => {done(); this.onClose()}
68
+ },
69
+ }),
70
+ dialogCfg: {
71
+ closeOnClickModal: false,
72
+ closeOnPressEscape: false
73
+ }
74
+ })
75
+ }
76
+ },
77
+ mounted() {
78
+ this.check().then(text => {
79
+ this.md5 = md5(text)
80
+ this.start()
81
+ })
82
+ },
83
+ render() {
84
+ return null
85
+ }
86
+ }
87
+
88
+ </script>
package/src/router/ca.js CHANGED
@@ -1,21 +1,40 @@
1
1
  import tracker from "./tracker";
2
2
  import moment from "moment";
3
- export default function trackerSend({userName, router = {}, clientId}) {
4
- tracker.send({
5
- title: "页面访问",
6
- action: "后台页面路由跳转",
7
- url: location.href,
8
- qt: {
9
- clientId,
10
- userName,
11
- date: moment(Date.now()).format("YYYY-MM-DD HH:mm:ss"),
12
- fullPath: router.fullPath,
13
- title: getRouterBreadcrumbs(router)
14
- }
15
- });
3
+ import { getToken } from "@/utils/auth"; // get token from cookie
4
+ import { getConfig } from "@/utils/global-config";
5
+
6
+ /**
7
+ * Sends tracking data to the tracker.
8
+ *
9
+ * @param {Object} options - The options for tracking.
10
+ * @param {string} options.title - The title of the tracking event.
11
+ * @param {string} options.action - The action being tracked.
12
+ * @param {Object} [options.qt] - Additional tracking data.
13
+ * @return {void}
14
+ */
15
+ export default function trackerSend({title, action, qt}) {
16
+ try {
17
+ tracker.send({
18
+ title,
19
+ action,
20
+ url: location.href,
21
+ qt: {
22
+ clientId: getConfig("CLIENT_ID"),
23
+ userName: getToken("LoginUserName"),
24
+ date: moment(Date.now()).format("YYYY-MM-DD HH:mm:ss"),
25
+ ...qt
26
+ }
27
+ });
28
+ } catch (error) {}
16
29
  }
17
30
 
18
- function getRouterBreadcrumbs(router) {
31
+ /**
32
+ * Returns a string representing the breadcrumbs of the current router.
33
+ *
34
+ * @param {Object} router - The router object.
35
+ * @return {string} The breadcrumbs string.
36
+ */
37
+ export function getRouterBreadcrumbs(router) {
19
38
  return router.matched
20
39
  .map((item) => (item.meta && item.meta.title) || item.name)
21
40
  .filter((item) => item && item !== "首页")
@@ -10,7 +10,7 @@ import "nprogress/nprogress.css"; // progress bar style
10
10
  import Oidc from "oidc-client";
11
11
  import { requestApi as HTTP } from "xs-request";
12
12
  import router from "./index";
13
- import trackerSend from "./ca";
13
+ import trackerSend, {getRouterBreadcrumbs} from "./ca";
14
14
 
15
15
  NProgress.configure({
16
16
  showSpinner: false,
@@ -73,9 +73,12 @@ router.beforeEach((to, from, next) => {
73
73
  } // 没登录 & 没在登录页 => 跳转到登录页
74
74
 
75
75
  trackerSend({
76
- clientId: id4config.client_id,
77
- userName: getToken("LoginUserName"),
78
- router: to
76
+ title: "页面访问",
77
+ action: "前台页面路由跳转",
78
+ qt: {
79
+ fullPath: to.fullPath,
80
+ title: getRouterBreadcrumbs(to)
81
+ }
79
82
  })
80
83
  });
81
84
 
@@ -0,0 +1,59 @@
1
+ <template>
2
+ <div v-if="list.length > 0">
3
+ <el-dropdown :hide-on-click="false" @command="handleCommand">
4
+ <el-badge is-dot class="item">
5
+ <i class="el-icon-bell"></i>
6
+ </el-badge>
7
+ <el-dropdown-menu slot="dropdown">
8
+ <el-dropdown-item v-for="(item, index) in list" :key="index" :command="index">{{ item.title }}</el-dropdown-item>
9
+ </el-dropdown-menu>
10
+ </el-dropdown>
11
+ </div>
12
+ </template>
13
+
14
+ <script>
15
+ import {defineComponent, h} from "vue";
16
+ import { getConfig } from "@/utils/global-config";
17
+ export default {
18
+ name: 'changeLog',
19
+ data () {
20
+ return {
21
+ list: []
22
+ }
23
+ },
24
+ methods: {
25
+ handleCommand (command) {
26
+ this.$common.popup({
27
+ title: this.list[command].remark,
28
+ component: defineComponent({
29
+ template: `<div>
30
+ <div style="font-size: 14px;color: #606266;line-height: 20px;padding: 10px 20px">${this.list[command].remark}</div>
31
+ <div style="text-align: center"><el-button type="primary" @click="$emit('close')">关闭</el-button></div>
32
+ </div>`
33
+ })
34
+ });
35
+ },
36
+ getChangeLog () {
37
+ this.$ask.commng.api.commmng.Banner.Query.post({pageInfo: {
38
+ page: 1,
39
+ pageSize: 3
40
+ },
41
+ codeLike: `changelog#${getConfig('CLIENT_ID')}`
42
+ }).then((result) => {
43
+ if (result.code === 0 && result.data.data.length > 0) {
44
+ this.list = result.data.data;
45
+ }
46
+ }).catch((err) => {
47
+
48
+ }).finally(() => {
49
+ setTimeout(() => {
50
+ this.getChangeLog();
51
+ }, 1000 * 60 * 60 * 12);
52
+ })
53
+ }
54
+ },
55
+ mounted () {
56
+ this.getChangeLog();
57
+ }
58
+ }
59
+ </script>
@@ -45,6 +45,9 @@
45
45
  />
46
46
  </el-badge>
47
47
  </div>
48
+ <div class="changelog">
49
+ <ChangeLog />
50
+ </div>
48
51
  <div>
49
52
  <el-tag style="margin: 0 3px;">{{
50
53
  userProfile &&
@@ -116,6 +119,7 @@ import { mapGetters } from "vuex";
116
119
  import Breadcrumb from "@/components/Breadcrumb";
117
120
  import Hamburger from "@/components/Hamburger";
118
121
  import AllSearch from "./AllSearch";
122
+ import ChangeLog from "./ChangeLog";
119
123
  import { getConfig } from "@/utils/global-config";
120
124
  import { getToken, removeToken, removeLocalToken } from "@/utils/auth"; // get token from cookie
121
125
  import ImCom from "@/components/im";
@@ -129,6 +133,7 @@ export default {
129
133
  Hamburger,
130
134
  AllSearch,
131
135
  ImCom,
136
+ ChangeLog,
132
137
  },
133
138
  data() {
134
139
  return {
@@ -393,4 +398,15 @@ export default {
393
398
  }
394
399
  }
395
400
  }
401
+ .changelog {
402
+ display: flex;
403
+ flex-direction: row;
404
+ justify-content: center;
405
+ align-items: center;
406
+ line-height: 16px;
407
+ margin: 0 8px;
408
+ &:empty {
409
+ display: none;
410
+ }
411
+ }
396
412
  </style>