gc_i18n 1.2.0 → 1.2.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.
@@ -1,11 +1,18 @@
1
1
  <script lang="jsx">
2
2
  import _ from "lodash-es";
3
- import { getAllTranslate, getLanguages, saveTranslate } from "../libs/service";
4
- import { Message } from "view-ui-plus";
3
+ import {
4
+ getAllTranslate,
5
+ getLanguages,
6
+ saveTranslate,
7
+ userDicts
8
+ } from "../libs/service";
9
+ import { Message, Tooltip } from "view-ui-plus";
10
+ import store2 from "store2";
5
11
 
6
12
  export default {
7
13
  data() {
8
14
  return {
15
+ LanguageSettingVisible: false,
9
16
  isModalVisible: false,
10
17
  loading: false,
11
18
  searchText: "",
@@ -28,93 +35,113 @@ export default {
28
35
  },
29
36
 
30
37
  columns() {
31
- let arr =
32
- this.type === "pageData"
33
- ? [
34
- {
35
- title: "状态",
36
- width: 90,
37
- key: "icon",
38
- fixed: "left",
39
- render: (h, { row }) => {
40
- return row.localhost ? (
41
- <span style={{ color: "red" }}>
42
- <span style={{ marginRight: "2px" }}>本地</span>
43
- <Tooltip
44
- content="该字段未在翻译数据库中"
45
- placement="top"
46
- transfer
47
- >
48
- <Icon type="ios-alert-outline" />
49
- </Tooltip>
50
- </span>
51
- ) : (
52
- <span style={{ color: "green" }}>
53
- {row.common ? "全局" : "当前页"}
54
- </span>
55
- );
56
- }
57
- },
58
- {
59
- title: "关键词",
60
- fixed: "left",
61
- width: 80,
62
- key: "dictKey"
63
- }
64
- ]
65
- : [
66
- {
67
- title: "状态",
68
- fixed: "left",
69
- width: 90,
70
- key: "page",
71
- render: (h, { row }) => {
72
- return h(
73
- "span",
74
- {},
75
- row.page === "common" ? "全局" : row.page
76
- );
77
- }
78
- },
79
- {
80
- title: "关键词",
81
- fixed: "left",
82
- width: 80,
83
- key: "dictKey"
84
- }
85
- ];
38
+ let arr = [
39
+ // this.type === "pageData"
40
+ // ? [
41
+ // {
42
+ // title: "状态",
43
+ // width: 100,
44
+ // key: "icon",
45
+ // fixed: "left",
46
+ // render: (h, { row }) => {
47
+ // return row.localhost ? (
48
+ // <span style={{ color: "red" }}>
49
+ // <span style={{ marginRight: "2px" }}>本地</span>
50
+ // <Tooltip
51
+ // content="该字段未在翻译数据库中"
52
+ // placement="top"
53
+ // transfer
54
+ // >
55
+ // <Icon type="ios-alert-outline" />
56
+ // </Tooltip>
57
+ // </span>
58
+ // ) : row.page === this.name ? (
59
+ // <span style={{ color: "green" }}>当前页</span>
60
+ // ) : (
61
+ // <span>
62
+ // 全局{" "}
63
+ // <Tooltip
64
+ // maxWidth={150}
65
+ // content="编辑该字段转化为当前页,不会覆盖全局"
66
+ // placement="top"
67
+ // transfer
68
+ // >
69
+ // <Icon type="ios-alert-outline" />
70
+ // </Tooltip>
71
+ // </span>
72
+ // );
73
+ // }
74
+ // },
75
+ // {
76
+ // title: "关键词",
77
+ // fixed: "left",
78
+ // width: 90,
79
+ // key: "dictKey"
80
+ // }
81
+ // ]
82
+ // : [
83
+ {
84
+ title: "状态",
85
+ fixed: "left",
86
+ width: 90,
87
+ key: "page",
88
+ render: (h, { row }) => {
89
+ return h(
90
+ "span",
91
+ {},
92
+ row.page === "common"
93
+ ? "全局"
94
+ : row.page === this.name
95
+ ? "当前页"
96
+ : "登录页"
97
+ );
98
+ }
99
+ },
100
+ {
101
+ title: "关键词",
102
+ fixed: "left",
103
+ width: 90,
104
+ key: "dictKey"
105
+ }
106
+ ];
86
107
  _.map(this.languages, (lang) => {
87
108
  const key = lang.code;
109
+ if (!lang.unChecked) {
110
+ return arr.push({
111
+ title: lang.name,
112
+ key,
113
+ render: (h, { row, index }) => {
114
+ const data = row[key];
115
+ const { localhost } = row;
116
+ return localhost ? null : (
117
+ <Input
118
+ modelValue={data}
119
+ onOnChange={(e) => {
120
+ const value = e.target.value;
121
+ const { dictKey } = row;
122
+ console.log("dictKey", dictKey);
123
+ const findIndex = _.findIndex(this.mySaveData, { dictKey });
88
124
 
89
- return arr.push({
90
- title: lang.name,
91
- key,
92
- render: (h, { row, index }) => {
93
- const data = row[key];
94
- const { localhost } = row;
95
- return localhost ? null : (
96
- <Input
97
- modelValue={data}
98
- onOnChange={(e) => {
99
- const value = e.target.value;
100
- const { dictKey } = row;
101
- console.log("dictKey", dictKey);
102
- const findIndex = _.findIndex(this.mySaveData, { dictKey });
103
-
104
- if (findIndex > -1) {
105
- this.mySaveData[findIndex][key] = value;
106
- } else {
107
- this.mySaveData.push({
108
- ...row,
109
- [key]: value,
110
- page: this.type === "pageData" ? this.name : "common"
111
- });
112
- }
113
- }}
114
- ></Input>
115
- );
116
- }
117
- });
125
+ if (findIndex > -1) {
126
+ this.mySaveData[findIndex][key] = value;
127
+ } else {
128
+ this.mySaveData.push({
129
+ ...row,
130
+ [key]: value,
131
+ page:
132
+ this.type === "loginData"
133
+ ? this.loginRouteName
134
+ : this.type === "pageData"
135
+ ? this.name
136
+ : "common"
137
+ });
138
+ }
139
+ }}
140
+ ></Input>
141
+ );
142
+ }
143
+ });
144
+ }
118
145
  });
119
146
  return arr;
120
147
  }
@@ -124,9 +151,28 @@ export default {
124
151
  setLanguage: Function,
125
152
  token: String,
126
153
  translationKeys: Array,
154
+ loginRouteName: String, // 登录页路由名称
155
+ loginTranslationKeys: Array, // 登录页翻译键
127
156
  emitter: Object // 接收事件总线
128
157
  },
129
158
  methods: {
159
+ saveLanguageSetting(val) {
160
+ const settings = _.map(
161
+ _.filter(this.languages, (val) => {
162
+ return val.unChecked;
163
+ }),
164
+ "code"
165
+ );
166
+ console.log("settings", settings);
167
+
168
+ store2.set("I18N_LANGUAGE_SETTING", settings);
169
+ },
170
+ handleLanguageSettingOpen() {
171
+ this.LanguageSettingVisible = !this.LanguageSettingVisible;
172
+ },
173
+ onClickOutside() {
174
+ this.LanguageSettingVisible = false;
175
+ },
130
176
  inputSearch() {
131
177
  if (this.type === "pageData") {
132
178
  this.getPageData();
@@ -211,15 +257,29 @@ export default {
211
257
  "pageData"
212
258
  );
213
259
  },
260
+ async getLoginData(data) {
261
+ this.search(
262
+ {
263
+ ...data,
264
+ page: this.loginRouteName,
265
+ commaSeparatedKeys: this.loginTranslationKeys.toString()
266
+ },
267
+ "pageData"
268
+ );
269
+ },
214
270
  async search(data, type) {
215
271
  this.loading = true;
216
- const res = await getAllTranslate(
272
+ const res = await userDicts(
217
273
  {
218
274
  appCode: this.appCode,
219
- page: "common",
220
275
  searchBlur: this.searchText,
221
276
  commaSeparatedLangs: _.map(this.languages, "code").toString(),
222
- firstResult: 0,
277
+ page:
278
+ type === "loginData"
279
+ ? this.loginRouteName
280
+ : type === "pageData"
281
+ ? this.name
282
+ : "common",
223
283
  pageSize: 10,
224
284
  ...data
225
285
  },
@@ -228,18 +288,6 @@ export default {
228
288
  if (res) {
229
289
  this.initialData = _.cloneDeep(res.data.retVal.datas);
230
290
  let data = res.data.retVal.datas;
231
- // if (type === "pageData") {
232
- // _.forEach(this.translationKeys, (key) => {
233
- // if (!_.find(data, { dictKey: key })) {
234
- // data.push({
235
- // dictKey: key,
236
- // page: this.name,
237
- // "zh-CN": key,
238
- // localhost: true
239
- // });
240
- // }
241
- // });
242
- // }
243
291
  this.data = _.cloneDeep(data);
244
292
  this.page = {
245
293
  firstResult: res.data.retVal.firstResult,
@@ -253,14 +301,22 @@ export default {
253
301
  this.type = name;
254
302
  if (name === "data") {
255
303
  this.search();
256
- } else {
304
+ } else if (name === "pageData") {
257
305
  this.getPageData();
306
+ } else if (name === "loginData") {
307
+ this.getLoginData(); // 假设登录页面的标识为 "login"
258
308
  }
259
309
  },
260
310
  async init() {
261
311
  const res = await getLanguages(this.token);
262
312
  if (res && res.data.result == 0) {
263
- this.languages = res.data.retVal;
313
+ let arr = res.data.retVal;
314
+ _.map(arr, (val) => {
315
+ if (_.includes(store2.get("I18N_LANGUAGE_SETTING"), val.code)) {
316
+ val.unChecked = true;
317
+ }
318
+ });
319
+ this.languages = arr;
264
320
  this.getPageData();
265
321
  } else {
266
322
  Message.error("获取语言失败,出错了");
@@ -319,9 +375,60 @@ export default {
319
375
  :data="data"
320
376
  ></Table
321
377
  ></TabPane>
378
+ <TabPane
379
+ name="loginData"
380
+ label="登录页面"
381
+ >
382
+ <Spin
383
+ class="gc_i18n_spin"
384
+ v-if="loading"
385
+ ></Spin>
386
+ <Table
387
+ v-else
388
+ border
389
+ :height="380"
390
+ :columns="columns"
391
+ :data="data"
392
+ ></Table
393
+ ></TabPane>
322
394
  <template #extra>
323
395
  <div class="extra">
396
+ <Dropdown
397
+ style="width: 80px"
398
+ transfer
399
+ trigger="custom"
400
+ placement="bottom-start"
401
+ v-click-away="onClickOutside"
402
+ :visible="LanguageSettingVisible"
403
+ >
404
+ <a
405
+ href="javascript:void(0)"
406
+ @click="handleLanguageSettingOpen"
407
+ >
408
+ 语言
409
+ <Icon type="ios-arrow-down"></Icon>
410
+ </a>
411
+ <template #list>
412
+ <!-- {{ languages }} -->
413
+ <DropdownMenu>
414
+ <DropdownItem
415
+ v-for="lang in languages"
416
+ :key="lang.code"
417
+ >
418
+ <Checkbox
419
+ v-model="lang.unChecked"
420
+ @on-change="saveLanguageSetting"
421
+ :true-value="false"
422
+ :false-value="true"
423
+ >
424
+ <span>{{ lang.name }}</span>
425
+ </Checkbox>
426
+ </DropdownItem>
427
+ </DropdownMenu>
428
+ </template>
429
+ </Dropdown>
324
430
  <Input
431
+ class="gc_i18n_search"
325
432
  prefix="ios-search"
326
433
  placeholder="请输入搜索内容"
327
434
  v-model="searchText"
@@ -344,9 +451,11 @@ export default {
344
451
  @on-change="changePage"
345
452
  />
346
453
  <div>
347
-
348
- {{ page.totalRows }}
349
- 项数据
454
+ <span>
455
+
456
+ {{ page.totalRows }}
457
+ 项当前页数据
458
+ </span>
350
459
  </div>
351
460
  </div>
352
461
  <div>
@@ -385,6 +494,8 @@ export default {
385
494
  .extra {
386
495
  position: relative;
387
496
  top: -3px;
497
+ display: flex;
498
+ align-items: center;
388
499
  }
389
500
  }
390
501
 
package/packages/index.js CHANGED
@@ -7,11 +7,11 @@ import configVue from "./components/config.vue";
7
7
  import { getLanguages, getTranslate } from "./libs/service";
8
8
  import { convertArrayToObject } from "./libs/utils";
9
9
  import { extractTranslationKeys } from "./libs/i18nUtils";
10
- import "./libs/http";
11
10
  import _ from "lodash-es";
12
11
  import store2 from "store2";
13
12
  import mitt from "mitt";
14
13
  import { jws } from "jsrsasign";
14
+ import VueClickAway from "vue3-click-away";
15
15
 
16
16
  // 生成 JWT 的函数
17
17
  function generateJWT(orgCode) {
@@ -29,7 +29,15 @@ function generateJWT(orgCode) {
29
29
  }
30
30
  export default class I18n {
31
31
  constructor(options = {}) {
32
- const { router, appCode, messages, token, orgCode } = options;
32
+ const {
33
+ router,
34
+ appCode,
35
+ messages,
36
+ token,
37
+ orgCode,
38
+ loginRouteName,
39
+ keyboard
40
+ } = options;
33
41
  this.token = token || generateJWT(orgCode);
34
42
  this.loadI18n = true;
35
43
  this.appCode = appCode;
@@ -38,25 +46,17 @@ export default class I18n {
38
46
  this.name = "";
39
47
  this.messages = messages || {};
40
48
  this.translationKeys = [];
41
-
49
+ this.loginRouteName = loginRouteName || "login";
50
+ this.loginTranslationKeys = [];
51
+ this.keyboard = keyboard || "shift>t";
42
52
  // 初始化路由守卫
43
53
  this.initRouterGuards();
44
54
 
45
55
  // 初始化 i18n 实例
46
56
  this.initI18n(options);
47
57
 
48
- // // 路由首次加载完成后设置语言
49
- // this.router
50
- // .isReady()
51
- // .then(async () => {
52
- // // await this.setLanguage(this.locale);
53
- // this.createModal();
54
- // })
55
- // .catch((error) => {
56
- // console.error("路由首次加载出错:", error);
57
- // });
58
-
59
- keyboardJS.bind("shift > t", (e) => {
58
+ keyboardJS.bind(this.keyboard, (e) => {
59
+ // && _.toLower(this.name) != this.loginRouteName
60
60
  if (!this.configInstance) {
61
61
  this.configInstance = this.createModal(this.name);
62
62
  // 打开弹窗
@@ -93,6 +93,33 @@ export default class I18n {
93
93
  // this.createModal(to.name);
94
94
  }
95
95
  this.loadI18n = false;
96
+ const loginRoute = this.router.getRoutes().find((route) => {
97
+ return (
98
+ route.name === this.loginRouteName ||
99
+ route.path === `/${this.loginRouteName}`
100
+ );
101
+ });
102
+
103
+ if (loginRoute) {
104
+ let loginComponent = loginRoute.components.default;
105
+ if (
106
+ typeof loginComponent === "function" &&
107
+ loginComponent.toString().includes("import(")
108
+ ) {
109
+ try {
110
+ // 加载异步组件
111
+ loginComponent = await loginComponent();
112
+ loginComponent = loginComponent.default;
113
+ } catch (error) {
114
+ console.error("加载异步组件时出错:", error);
115
+ next();
116
+ return;
117
+ }
118
+ }
119
+ const loginRouteKeys = extractTranslationKeys(loginComponent);
120
+ // 如果当前路由是登录路由,则提取翻译键
121
+ this.loginTranslationKeys = loginRouteKeys;
122
+ }
96
123
  if (to.matched.length > 0) {
97
124
  // 存储所有组件的翻译键
98
125
  const allTranslationKeys = [];
@@ -254,9 +281,12 @@ export default class I18n {
254
281
  setLanguage: this.setLanguage.bind(this, this.locale),
255
282
  name: name || this.name,
256
283
  translationKeys: this.translationKeys,
284
+ loginRouteName: this.loginRouteName, // 登录页路由名称
285
+ loginTranslationKeys: this.loginTranslationKeys,
257
286
  emitter // 将事件总线作为 prop 传递
258
287
  })
259
288
  .use(iview)
289
+ .use(VueClickAway)
260
290
  .mount(document.createElement("div")); // 挂载到一个临时的 div
261
291
  }
262
292
  install(app, opts = {}) {
@@ -3,6 +3,7 @@ import store2 from "store2";
3
3
  import _ from "lodash-es";
4
4
  import { mergeArraysByKey } from "./utils";
5
5
  export const service = "https://test.ihotel.cn";
6
+ // export const service = "http://192.168.1.170:2018";
6
7
 
7
8
  export const getLanguages = async (token) => {
8
9
  return axios.get(service + "/i18n-web/sysoption/getsupportedlangs", {
@@ -11,6 +12,7 @@ export const getLanguages = async (token) => {
11
12
  }
12
13
  });
13
14
  };
15
+
14
16
  export const fetchTranslate = async ({
15
17
  appCode,
16
18
  language = "zh-CN",
@@ -49,6 +51,18 @@ export const getAllTranslate = async (data, token) => {
49
51
  headers: { Authorization: token }
50
52
  });
51
53
  };
54
+
55
+ export const userDicts = async (data, token) => {
56
+ return axios({
57
+ url: service + "/i18n-web/kv_translate/userDicts",
58
+ method: "POST",
59
+ headers: {
60
+ Authorization: token
61
+ },
62
+ data
63
+ });
64
+ };
65
+
52
66
  export const saveTranslate = async (data, token) => {
53
67
  return axios({
54
68
  url: service + "/i18n-web/kv_translate/batch",
@@ -7,9 +7,9 @@ const routes = [
7
7
  component: () => import("../view/Home.vue")
8
8
  },
9
9
  {
10
- path: "/test",
11
- name: "test",
12
- component: () => import("../view/test.vue")
10
+ path: "/login",
11
+ name: "Login",
12
+ component: () => import("../view/login.vue")
13
13
  }
14
14
  ];
15
15
  const router = createRouter({
@@ -0,0 +1,14 @@
1
+ <script setup>
2
+ const change = async (lang) => {
3
+ await $changeLocale(lang);
4
+ location.reload();
5
+ };
6
+ </script>
7
+
8
+ <template>
9
+ <h1>十多个十多个</h1>
10
+ <h1>蓝色灯光</h1>
11
+ <h1>{{ $t("xxx") }}</h1>
12
+ <button @click="change('en-US')">en</button>
13
+ <button @click="change('zh-CN')">zh</button>
14
+ </template>
package/vite.config.js CHANGED
@@ -48,8 +48,12 @@ export default defineConfig({
48
48
  outDir: "lib"
49
49
  // outDir:
50
50
  // "/Users/huqiliang/Documents/github/auto-i18n-translation-plugins/example/vue3/node_modules/gc_i18n/lib"
51
- // outDir:
52
- // "/Users/huqiliang/Documents/lvyun/dpms-front/node_modules/gc_i18n/lib"
51
+ // outDir:
52
+ // "/Users/huqiliang/Documents/lvyun/dpms-front/node_modules/gc_i18n/lib"
53
+ //
54
+ },
55
+ server: {
56
+ host: "0.0.0.0"
53
57
  },
54
58
  plugins: [
55
59
  vue(),
@@ -1,64 +0,0 @@
1
- import * as Vue from "vue";
2
- import axios from "axios";
3
- import { Message } from "view-ui-plus";
4
- import * as _ from "lodash-es";
5
- // Vue.prototype.$http = axios;
6
-
7
- Message.config({
8
- duration: 3
9
- });
10
- axios.defaults.timeout = 60000;
11
-
12
- axios.interceptors.request.use(
13
- (config) => {
14
- config.headers["Content-Type"] = "application/json";
15
- return config;
16
- },
17
- (err) => {
18
- Message.error({
19
- content: "请求超时!"
20
- });
21
- return Promise.resolve(err);
22
- }
23
- );
24
- axios.interceptors.response.use(
25
- (res) => {
26
- const { nomsg } = res.config.headers;
27
- if (res.status && res.status != 200) {
28
- if (!nomsg) {
29
- Message.error({
30
- content: res.data.message || "未知错误"
31
- });
32
- }
33
- } else {
34
- res.data.success = true;
35
- }
36
- return res;
37
- },
38
- (err) => {
39
- if (err.response) {
40
- if (err.response.status == 504 || err.response.status == 404) {
41
- Message.error({ content: "服务器被吃了⊙﹏⊙∥" });
42
- } else if (err.response.status == 403) {
43
- Message.error({ content: "权限不足,请联系管理员!" });
44
- } else
45
- Message.error({
46
- content: `${err.response.status}:${
47
- err.response.statusText || err.response.error
48
- }`
49
- });
50
- } else if (
51
- err.code === "ECONNABORTED" &&
52
- err.message.indexOf("timeout") !== -1
53
- ) {
54
- Message.error({
55
- content: "请求超时!"
56
- });
57
- } else {
58
- Message.error({ content: err.message || "未知错误!" });
59
- }
60
- return Promise.resolve(err);
61
- }
62
- );
63
-
64
- export default { axios };
package/src/view/test.vue DELETED
@@ -1,7 +0,0 @@
1
- <script setup></script>
2
-
3
- <template>
4
- <h1>首页</h1>
5
- <h1>测试</h1>
6
- <h1>页面独有</h1>
7
- </template>