af-mobile-client-vue3 1.1.53 → 1.2.1
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/.env +4 -1
- package/.node-version +1 -0
- package/.vscode/extensions.json +6 -1
- package/.vscode/settings.json +32 -27
- package/build/vite/index.ts +29 -29
- package/build/vite/optimize.ts +34 -0
- package/build/vite/vconsole.ts +5 -2
- package/commitlint.config.ts +32 -0
- package/eslint.config.ts +30 -0
- package/index.html +15 -9
- package/mock/data.ts +15 -15
- package/mock/index.ts +2 -0
- package/mock/modules/prose.mock.ts +5 -8
- package/mock/util.ts +19 -0
- package/netlify.toml +2 -2
- package/package.json +66 -66
- package/postcss.config.ts +27 -0
- package/public/favicon.ico +0 -0
- package/public/pwa-192x192.png +0 -0
- package/public/pwa-512x512.png +0 -0
- package/public/safari-pinned-tab.svg +3 -31
- package/src/App.vue +45 -7
- package/src/components/core/ImageUploader/index.vue +159 -159
- package/src/components/core/NavBar/index.vue +33 -2
- package/src/components/core/Tabbar/index.vue +17 -25
- package/src/components/data/XBadge/index.vue +4 -9
- package/src/components/data/XCellDetail/index.vue +0 -1
- package/src/components/data/XCellList/index.vue +2 -1
- package/src/components/data/XFormItem/index.vue +1 -1
- package/src/components/data/XOlMap/utils/wgs84ToGcj02.js +154 -154
- package/src/composables/dark.ts +5 -0
- package/src/config/routes.ts +5 -0
- package/src/layout/PageLayout.vue +1 -43
- package/src/locales/en-US.json +81 -2
- package/src/locales/zh-CN.json +81 -2
- package/src/main.ts +6 -6
- package/src/router/index.ts +13 -39
- package/src/router/routes.ts +6 -4
- package/src/stores/index.ts +4 -0
- package/src/stores/modules/routeCache.ts +1 -1
- package/src/stores/modules/user.ts +11 -10
- package/src/styles/app.less +16 -57
- package/src/styles/login.less +22 -8
- package/src/styles/var.less +16 -0
- package/src/{vue-router.d.ts → types/vue-router.d.ts} +2 -0
- package/src/utils/i18n.ts +72 -41
- package/src/utils/inline-px-to-vw.ts +28 -0
- package/src/utils/set-page-title.ts +1 -1
- package/src/views/component/XCellListView/index.vue +96 -13
- package/src/views/component/XFormGroupView/index.vue +39 -2
- package/src/views/component/XFormView/index.vue +9 -30
- package/src/views/component/XOlMapView/XLocationPicker/index.vue +118 -118
- package/src/views/component/index.vue +36 -6
- package/src/views/user/login/LoginForm.vue +6 -6
- package/src/views/user/login/LoginTitle.vue +14 -6
- package/src/views/user/my/index.vue +17 -14
- package/tsconfig.json +0 -1
- package/uno.config.ts +39 -24
- package/vite.config.ts +7 -29
- package/.husky/commit-msg +0 -1
- package/.husky/pre-commit +0 -1
- package/LICENSE +0 -21
- package/eslint.config.js +0 -15
- package/mock/modules/demo.mock.ts +0 -20
- package/src/components.d.ts +0 -53
- package/src/stores/modules/routeTransitionName.ts +0 -26
- package/src/typing.ts +0 -3
- package/src/views/component/XFormView/oldindex.vue +0 -70
- /package/src/{env.d.ts → types/env.d.ts} +0 -0
- /package/src/{settings.ts → types/settings.ts} +0 -0
package/src/router/index.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EnhancedRouteLocation } from '@af-mobile-client-vue3/router/types'
|
|
2
2
|
import routes from '@af-mobile-client-vue3/router/routes'
|
|
3
|
-
import
|
|
4
|
-
import useRouteTransitionNameStore from '@af-mobile-client-vue3/stores/modules/routeTransitionName'
|
|
3
|
+
import useRouteCacheStore from '@af-mobile-client-vue3/stores/modules/routeCache'
|
|
5
4
|
import setPageTitle from '@af-mobile-client-vue3/utils/set-page-title'
|
|
5
|
+
import NProgress from 'nprogress'
|
|
6
6
|
// https://router.vuejs.org/zh/
|
|
7
7
|
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'
|
|
8
8
|
import 'nprogress/nprogress.css'
|
|
9
9
|
|
|
10
|
+
NProgress.configure({ showSpinner: true, parent: '#system-app' })
|
|
11
|
+
|
|
10
12
|
const baseUrl = import.meta.env.VITE_APP_PUBLIC_PATH
|
|
11
13
|
// 创建路由实例并传递 `routes` 配置
|
|
12
14
|
const router = createRouter({
|
|
@@ -14,48 +16,20 @@ const router = createRouter({
|
|
|
14
16
|
routes,
|
|
15
17
|
})
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
title?: string
|
|
20
|
-
noCache?: boolean
|
|
21
|
-
index?: number
|
|
22
|
-
}
|
|
23
|
-
}
|
|
19
|
+
router.beforeEach((to: EnhancedRouteLocation) => {
|
|
20
|
+
NProgress.start()
|
|
24
21
|
|
|
25
|
-
router.beforeEach((to: toRouteType, _from: toRouteType, next) => {
|
|
26
|
-
const toDepth = to.path.split('/').length
|
|
27
|
-
const fromDepth = _from.path.split('/').length
|
|
28
|
-
// 路由过渡动画
|
|
29
|
-
const routeTransitionNameStore = useRouteTransitionNameStore()
|
|
30
|
-
let name: string
|
|
31
|
-
if (toDepth > fromDepth || to.name === '404') {
|
|
32
|
-
console.warn('in')
|
|
33
|
-
// 进入动画
|
|
34
|
-
name = 'slide-fadein-left'
|
|
35
|
-
}
|
|
36
|
-
else if (toDepth < fromDepth) {
|
|
37
|
-
// 返回动画
|
|
38
|
-
name = 'slide-fadein-right'
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
const toIndex = to.meta.index ? to.meta.index : 0
|
|
42
|
-
const fromIndex = _from.meta.index ? _from.meta.index : 0
|
|
43
|
-
if (toIndex > fromIndex)
|
|
44
|
-
name = 'slide-right'
|
|
45
|
-
else if (toIndex < fromIndex)
|
|
46
|
-
name = 'slide-left'
|
|
47
|
-
else
|
|
48
|
-
name = ''
|
|
49
|
-
}
|
|
50
|
-
routeTransitionNameStore.setName(name)
|
|
51
22
|
// 路由缓存
|
|
52
|
-
|
|
23
|
+
const routeCacheStore = useRouteCacheStore()
|
|
24
|
+
routeCacheStore.addRoute(to)
|
|
25
|
+
|
|
53
26
|
// 页面 title
|
|
54
27
|
setPageTitle(to.meta.title)
|
|
55
|
-
next()
|
|
56
28
|
})
|
|
57
29
|
|
|
58
|
-
router.afterEach(() => {
|
|
30
|
+
router.afterEach(() => {
|
|
31
|
+
NProgress.done()
|
|
32
|
+
})
|
|
59
33
|
|
|
60
34
|
// 导出路由实例,并在 `main.ts` 挂载
|
|
61
35
|
export default router
|
package/src/router/routes.ts
CHANGED
|
@@ -2,8 +2,6 @@ import type { RouteRecordRaw } from 'vue-router'
|
|
|
2
2
|
import XForm from '@af-mobile-client-vue3/components/data/XForm/index.vue'
|
|
3
3
|
import XReport from '@af-mobile-client-vue3/components/data/XReportGrid/XReport.vue'
|
|
4
4
|
import GridView from '@af-mobile-client-vue3/layout/GridView/index.vue'
|
|
5
|
-
import PageLayout from '@af-mobile-client-vue3/layout/PageLayout.vue'
|
|
6
|
-
import SingleLayout from '@af-mobile-client-vue3/layout/SingleLayout.vue'
|
|
7
5
|
import NotFound from '@af-mobile-client-vue3/views/common/NotFound.vue'
|
|
8
6
|
import EvaluateRecordView from '@af-mobile-client-vue3/views/component/EvaluateRecordView/index.vue'
|
|
9
7
|
import IconifyView from '@af-mobile-client-vue3/views/component/IconifyView/index.vue'
|
|
@@ -21,12 +19,12 @@ import XReportGridView from '@af-mobile-client-vue3/views/component/XReportGridV
|
|
|
21
19
|
import XRequestView from '@af-mobile-client-vue3/views/component/XRequestView/index.vue'
|
|
22
20
|
import XSignatureView from '@af-mobile-client-vue3/views/component/XSignatureView/index.vue'
|
|
23
21
|
import login from '@af-mobile-client-vue3/views/user/login/index.vue'
|
|
22
|
+
import my from '@af-mobile-client-vue3/views/user/my/index.vue'
|
|
24
23
|
|
|
25
24
|
const routes: Array<RouteRecordRaw> = [
|
|
26
25
|
{
|
|
27
26
|
path: '/',
|
|
28
27
|
name: 'root',
|
|
29
|
-
component: PageLayout,
|
|
30
28
|
redirect: { name: 'Component' },
|
|
31
29
|
children: [
|
|
32
30
|
{
|
|
@@ -51,7 +49,6 @@ const routes: Array<RouteRecordRaw> = [
|
|
|
51
49
|
{
|
|
52
50
|
path: '/Component',
|
|
53
51
|
name: 'Component',
|
|
54
|
-
component: SingleLayout,
|
|
55
52
|
redirect: { name: 'ComponentView' },
|
|
56
53
|
children: [
|
|
57
54
|
{
|
|
@@ -153,6 +150,11 @@ const routes: Array<RouteRecordRaw> = [
|
|
|
153
150
|
name: 'login',
|
|
154
151
|
component: login,
|
|
155
152
|
},
|
|
153
|
+
{
|
|
154
|
+
path: '/user/my',
|
|
155
|
+
name: 'userProfile',
|
|
156
|
+
component: my,
|
|
157
|
+
},
|
|
156
158
|
{
|
|
157
159
|
path: '/404',
|
|
158
160
|
name: '404',
|
package/src/stores/index.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { createPinia } from 'pinia'
|
|
2
2
|
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
|
3
3
|
|
|
4
|
+
import useRouteCacheStore from './modules/routeCache'
|
|
5
|
+
import useUserStore from './modules/user'
|
|
6
|
+
|
|
4
7
|
const pinia = createPinia()
|
|
5
8
|
pinia.use(piniaPluginPersistedstate)
|
|
6
9
|
|
|
10
|
+
export { useRouteCacheStore, useUserStore }
|
|
7
11
|
export default pinia
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EnhancedRouteLocation } from '@af-mobile-client-vue3
|
|
1
|
+
import type { EnhancedRouteLocation } from '@af-mobile-client-vue3/router/types'
|
|
2
2
|
import type { RouteRecordName } from 'vue-router'
|
|
3
3
|
import { defineStore } from 'pinia'
|
|
4
4
|
import { ref } from 'vue'
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
APP_PERMISSIONS_KEY,
|
|
9
9
|
APP_ROLES_KEY,
|
|
10
10
|
APP_ROUTES_KEY,
|
|
11
|
+
APP_WEB_CONFIG_KEY,
|
|
11
12
|
CURRENT_USER,
|
|
12
13
|
} from '@af-mobile-client-vue3/stores/mutation-type'
|
|
13
14
|
import crypto from '@af-mobile-client-vue3/utils/crypto'
|
|
@@ -185,17 +186,17 @@ export const useUserStore = defineStore('app-user', () => {
|
|
|
185
186
|
}
|
|
186
187
|
setToken(undefined)
|
|
187
188
|
setUserInfo(null)
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
189
|
+
Storage.remove(CURRENT_USER)
|
|
190
|
+
Storage.remove(ACCESS_TOKEN)
|
|
191
|
+
Storage.remove(APP_LOGIN_KEY)
|
|
192
|
+
Storage.remove(APP_PERMISSIONS_KEY)
|
|
193
|
+
Storage.remove(APP_ROLES_KEY)
|
|
194
|
+
Storage.remove(APP_ROUTES_KEY)
|
|
195
|
+
Storage.remove(APP_WEB_CONFIG_KEY)
|
|
196
|
+
Storage.remove('LoginTicket')
|
|
197
|
+
await indexedDB.clearDB()
|
|
198
|
+
await useSettingStore().init()
|
|
195
199
|
try {
|
|
196
|
-
Storage.clear()
|
|
197
|
-
await indexedDB.clearDB()
|
|
198
|
-
await useSettingStore().init()
|
|
199
200
|
// 添加页面刷新
|
|
200
201
|
await router.replace('/login')
|
|
201
202
|
window.location.reload()
|
package/src/styles/app.less
CHANGED
|
@@ -1,72 +1,31 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
--base-interval-0: 7px;
|
|
3
|
-
--base-interval-1: 14px;
|
|
4
|
-
--base-interval-2: 28px;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
:root:root {
|
|
8
|
-
// 覆盖 primary 颜色
|
|
9
|
-
--van-blue: #2563EB;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
#system-app {
|
|
13
|
-
min-height: 100vh;
|
|
14
|
-
position: relative;
|
|
15
|
-
overflow-x: hidden;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
html {
|
|
19
|
-
background: var(--van-gray-1);
|
|
20
|
-
color-scheme: light;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
1
|
*,
|
|
24
2
|
*::before,
|
|
25
3
|
*::after {
|
|
26
4
|
box-sizing: border-box;
|
|
27
5
|
}
|
|
28
6
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
position: absolute;
|
|
34
|
-
top: 0;
|
|
35
|
-
left: 0;
|
|
36
|
-
transition: opacity 0.3s, transform 0.4s, -webkit-transform 0.4s;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.slide-fadein-left-enter-from,
|
|
40
|
-
.slide-fadein-right-leave-to {
|
|
41
|
-
transform: translateX(20px);
|
|
42
|
-
opacity: 0;
|
|
7
|
+
html {
|
|
8
|
+
background: var(--van-gray-1);
|
|
9
|
+
font-size: var(--van-font-size-lg);
|
|
10
|
+
color-scheme: light;
|
|
43
11
|
}
|
|
44
12
|
|
|
45
|
-
.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
opacity: 0;
|
|
13
|
+
html.dark {
|
|
14
|
+
background: #222;
|
|
15
|
+
color-scheme: dark;
|
|
49
16
|
}
|
|
50
17
|
|
|
51
|
-
|
|
52
|
-
.slide-left-leave-active,
|
|
53
|
-
.slide-right-enter-active,
|
|
54
|
-
.slide-right-leave-active {
|
|
55
|
-
will-change: transform;
|
|
56
|
-
transition: transform .3s;
|
|
18
|
+
#system-app {
|
|
57
19
|
height: 100%;
|
|
58
|
-
|
|
59
|
-
top: 0;
|
|
60
|
-
position: absolute;
|
|
61
|
-
backface-visibility: hidden;
|
|
20
|
+
position: relative;
|
|
62
21
|
}
|
|
63
22
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
23
|
+
::-webkit-scrollbar {
|
|
24
|
+
width: 0;
|
|
25
|
+
background: transparent;
|
|
67
26
|
}
|
|
68
27
|
|
|
69
|
-
|
|
70
|
-
.
|
|
71
|
-
|
|
72
|
-
}
|
|
28
|
+
// 解决Tabbar的固定定位被覆盖的问题
|
|
29
|
+
.van-tabbar--fixed {
|
|
30
|
+
position: fixed !important;
|
|
31
|
+
}
|
package/src/styles/login.less
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
html:not(.dark) {
|
|
2
|
+
.form {
|
|
3
|
+
.form_field {
|
|
4
|
+
:deep(.van-field__label) {
|
|
5
|
+
color: rgb(88, 88, 88);
|
|
6
|
+
}
|
|
7
|
+
:deep(.van-field__body) {
|
|
8
|
+
background: rgb(251, 251, 251);
|
|
9
|
+
box-shadow: inset 0 0 1px 0 rgba(0, 0, 0, 0.1);
|
|
10
|
+
color: rgb(71, 71, 71);
|
|
11
|
+
}
|
|
12
|
+
:deep(.van-cell) {
|
|
13
|
+
background: #ffffff;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
.extra_setting {
|
|
17
|
+
.extra_setting_for_remember_password {
|
|
18
|
+
color: rgb(88, 88, 88);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
1
23
|
.form {
|
|
2
24
|
width: 100%;
|
|
3
25
|
padding: 0 40px;
|
|
@@ -6,7 +28,6 @@
|
|
|
6
28
|
padding-left: 0;
|
|
7
29
|
:deep(.van-field__label) {
|
|
8
30
|
opacity: 0.7;
|
|
9
|
-
color: rgb(88, 88, 88);
|
|
10
31
|
font-size: 16px;
|
|
11
32
|
font-weight: 400;
|
|
12
33
|
line-height: 23px;
|
|
@@ -16,9 +37,6 @@
|
|
|
16
37
|
:deep(.van-field__body) {
|
|
17
38
|
height: 40px;
|
|
18
39
|
border-radius: 5px;
|
|
19
|
-
background: rgb(251, 251, 251);
|
|
20
|
-
box-shadow: inset 0 0 1px 0 rgba(0, 0, 0, 0.1);
|
|
21
|
-
color: rgb(71, 71, 71);
|
|
22
40
|
font-size: 16px;
|
|
23
41
|
font-weight: 400;
|
|
24
42
|
padding: 8px 10px;
|
|
@@ -31,7 +49,6 @@
|
|
|
31
49
|
line-height: 12px;
|
|
32
50
|
.extra_setting_for_remember_password {
|
|
33
51
|
opacity: 0.7;
|
|
34
|
-
color: rgb(88, 88, 88);
|
|
35
52
|
span {
|
|
36
53
|
position: relative;
|
|
37
54
|
bottom: 3px;
|
|
@@ -66,9 +83,6 @@
|
|
|
66
83
|
color: rgb(56, 149, 250);
|
|
67
84
|
}
|
|
68
85
|
}
|
|
69
|
-
:deep(.van-cell) {
|
|
70
|
-
background: #ffffff;
|
|
71
|
-
}
|
|
72
86
|
:deep(.van-cell:after) {
|
|
73
87
|
border-bottom: none;
|
|
74
88
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
注意:为什么要写两个重复的 :root?
|
|
3
|
+
由于 vant 中的主题变量也是在 :root 下声明的,所以在有些情况下会由于优先级的问题无法成功覆盖。
|
|
4
|
+
通过 :root:root 可以显式地让你所写内容的优先级更高一些,从而确保主题变量的成功覆盖。
|
|
5
|
+
**/
|
|
6
|
+
|
|
7
|
+
:root:root {
|
|
8
|
+
// van-cell-group
|
|
9
|
+
--van-cell-group-inset-padding: 0;
|
|
10
|
+
// 覆盖 primary 颜色
|
|
11
|
+
--van-blue: #2563eb;
|
|
12
|
+
// 自定义变量
|
|
13
|
+
--base-interval-0: 7px;
|
|
14
|
+
--base-interval-1: 14px;
|
|
15
|
+
--base-interval-2: 28px;
|
|
16
|
+
}
|
package/src/utils/i18n.ts
CHANGED
|
@@ -1,41 +1,72 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
1
|
+
import type { PickerColumn } from 'vant'
|
|
2
|
+
import { Locale } from 'vant'
|
|
3
|
+
import enUS from 'vant/es/locale/lang/en-US'
|
|
4
|
+
import zhCN from 'vant/es/locale/lang/zh-CN'
|
|
5
|
+
import { computed } from 'vue'
|
|
6
|
+
import { createI18n } from 'vue-i18n'
|
|
7
|
+
|
|
8
|
+
const FALLBACK_LOCALE = 'zh-CN'
|
|
9
|
+
|
|
10
|
+
const vantLocales = {
|
|
11
|
+
'zh-CN': zhCN,
|
|
12
|
+
'en-US': enUS,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const languageColumns: PickerColumn = [
|
|
16
|
+
{ text: '简体中文', value: 'zh-CN' },
|
|
17
|
+
{ text: 'English', value: 'en-US' },
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
export const i18n = setupI18n()
|
|
21
|
+
type I18n = typeof i18n
|
|
22
|
+
|
|
23
|
+
export const locale = computed({
|
|
24
|
+
get() {
|
|
25
|
+
return i18n.global.locale.value
|
|
26
|
+
},
|
|
27
|
+
set(language: string) {
|
|
28
|
+
setLang(language, i18n)
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
function setupI18n() {
|
|
33
|
+
const locale = getI18nLocale()
|
|
34
|
+
const i18n = createI18n({
|
|
35
|
+
locale,
|
|
36
|
+
legacy: false,
|
|
37
|
+
})
|
|
38
|
+
setLang(locale, i18n)
|
|
39
|
+
return i18n
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function setLang(lang: string, i18n: I18n) {
|
|
43
|
+
await loadLocaleMsg(lang, i18n)
|
|
44
|
+
|
|
45
|
+
document.querySelector('html').setAttribute('lang', lang)
|
|
46
|
+
localStorage.setItem('language', lang)
|
|
47
|
+
i18n.global.locale.value = lang
|
|
48
|
+
|
|
49
|
+
// 设置 vant 组件语言包
|
|
50
|
+
Locale.use(lang, vantLocales[lang])
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 加载本地语言包
|
|
54
|
+
async function loadLocaleMsg(locale: string, i18n: I18n) {
|
|
55
|
+
const messages = await import(`../locales/${locale}.json`)
|
|
56
|
+
i18n.global.setLocaleMessage(locale, messages.default)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 获取当前语言对应的语言包名称
|
|
60
|
+
function getI18nLocale() {
|
|
61
|
+
const storedLocale = localStorage.getItem('language') || navigator.language
|
|
62
|
+
|
|
63
|
+
const langs = languageColumns.map(v => v.value as string)
|
|
64
|
+
|
|
65
|
+
// 存在当前语言的语言包 或 存在当前语言的任意地区的语言包
|
|
66
|
+
const foundLocale = langs.find(v => v === storedLocale || v.indexOf(storedLocale) === 0)
|
|
67
|
+
|
|
68
|
+
// 若未找到,则使用 默认语言包
|
|
69
|
+
const locale = foundLocale || FALLBACK_LOCALE
|
|
70
|
+
|
|
71
|
+
return locale
|
|
72
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 支持行内样式 px 转 vw
|
|
3
|
+
* 本文件代码来自于 scale-view 开源项目
|
|
4
|
+
* 源代码链接:https://github.com/wswmsword/scale-view
|
|
5
|
+
* 非常感谢作者 @wswmsword 的支持
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { round } from 'lodash-es'
|
|
9
|
+
|
|
10
|
+
// 理想宽度,设计稿的宽度
|
|
11
|
+
const idealWidth = 375
|
|
12
|
+
|
|
13
|
+
// 表示伸缩视图的最大宽度
|
|
14
|
+
const maxWidth = 800
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 限制大小的 vw 转换
|
|
18
|
+
* @param {number} n
|
|
19
|
+
*/
|
|
20
|
+
export default function vw(n: number) {
|
|
21
|
+
if (n === 0)
|
|
22
|
+
return n
|
|
23
|
+
|
|
24
|
+
const vwN = round(n * 100 / idealWidth, 3)
|
|
25
|
+
const maxN = round(n * maxWidth / idealWidth, 3)
|
|
26
|
+
const cssF = n > 0 ? 'min' : 'max'
|
|
27
|
+
return `${cssF}(${vwN}vw, ${maxN}px)`
|
|
28
|
+
}
|
|
@@ -1,24 +1,107 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import XCellList from '@af-mobile-client-vue3/components/data/XCellList/index.vue'
|
|
3
|
-
import
|
|
3
|
+
import NormalDataLayout from '@af-mobile-client-vue3/components/layout/NormalDataLayout/index.vue'
|
|
4
|
+
import { defineEmits, ref } from 'vue'
|
|
4
5
|
import { useRouter } from 'vue-router'
|
|
5
6
|
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
})
|
|
10
|
-
|
|
7
|
+
// 定义事件
|
|
8
|
+
const emit = defineEmits(['deleteRow'])
|
|
9
|
+
// 访问路由
|
|
11
10
|
const router = useRouter()
|
|
12
|
-
|
|
13
|
-
const
|
|
11
|
+
// 获取默认值
|
|
12
|
+
const idKey = ref('o_id')
|
|
13
|
+
|
|
14
|
+
// 简易crud表单测试
|
|
15
|
+
const configName = ref('lngChargeAuditMobileCRUD')
|
|
16
|
+
const serviceName = ref('af-gaslink')
|
|
17
|
+
|
|
18
|
+
// 资源权限测试
|
|
19
|
+
// const configName = ref('crud_sources_test')
|
|
20
|
+
// const serviceName = ref('af-system')
|
|
21
|
+
|
|
22
|
+
// 实际业务测试
|
|
23
|
+
// const configName = ref('lngChargeAuditMobileCRUD')
|
|
24
|
+
// const serviceName = ref('af-gaslink')
|
|
25
|
+
|
|
26
|
+
// 跳转到详情页面
|
|
27
|
+
// function toDetail(item) {
|
|
28
|
+
// router.push({
|
|
29
|
+
// name: 'XCellDetailView',
|
|
30
|
+
// params: { id: item[idKey.value] }, // 如果使用命名路由,推荐使用路由参数而不是直接构建 URL
|
|
31
|
+
// query: {
|
|
32
|
+
// operName: item[operNameKey.value],
|
|
33
|
+
// method:item[methodKey.value],
|
|
34
|
+
// requestMethod:item[requestMethodKey.value],
|
|
35
|
+
// operatorType:item[operatorTypeKey.value],
|
|
36
|
+
// operUrl:item[operUrlKey.value],
|
|
37
|
+
// operIp:item[operIpKey.value],
|
|
38
|
+
// costTime:item[costTimeKey.value],
|
|
39
|
+
// operTime:item[operTimeKey.value],
|
|
40
|
+
//
|
|
41
|
+
// title: item[titleKey.value],
|
|
42
|
+
// businessType: item[businessTypeKey.value],
|
|
43
|
+
// status:item[statusKey.value]
|
|
44
|
+
// }
|
|
45
|
+
// })
|
|
46
|
+
// }
|
|
47
|
+
|
|
48
|
+
// 跳转到表单——以表单组来渲染纯表单
|
|
49
|
+
function toDetail(item) {
|
|
50
|
+
router.push({
|
|
51
|
+
name: 'XFormGroupView',
|
|
52
|
+
query: {
|
|
53
|
+
id: item[idKey.value],
|
|
54
|
+
// id: item.rr_id,
|
|
55
|
+
// o_id: item.o_id,
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 新增功能
|
|
61
|
+
// function addOption(totalCount) {
|
|
62
|
+
// router.push({
|
|
63
|
+
// name: 'XFormView',
|
|
64
|
+
// params: { id: totalCount, openid: totalCount },
|
|
65
|
+
// query: {
|
|
66
|
+
// configName: configName.value,
|
|
67
|
+
// serviceName: serviceName.value,
|
|
68
|
+
// mode: '新增',
|
|
69
|
+
// },
|
|
70
|
+
// })
|
|
71
|
+
// }
|
|
72
|
+
|
|
73
|
+
// 修改功能
|
|
74
|
+
// function updateRow(result) {
|
|
75
|
+
// router.push({
|
|
76
|
+
// name: 'XFormView',
|
|
77
|
+
// params: { id: result.o_id, openid: result.o_id },
|
|
78
|
+
// query: {
|
|
79
|
+
// configName: configName.value,
|
|
80
|
+
// serviceName: serviceName.value,
|
|
81
|
+
// mode: '修改',
|
|
82
|
+
// },
|
|
83
|
+
// })
|
|
84
|
+
// }
|
|
85
|
+
|
|
86
|
+
// 删除功能
|
|
87
|
+
function deleteRow(result) {
|
|
88
|
+
emit('deleteRow', result.o_id)
|
|
89
|
+
}
|
|
14
90
|
</script>
|
|
15
91
|
|
|
16
92
|
<template>
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
93
|
+
<NormalDataLayout id="XCellListView" title="工作计划">
|
|
94
|
+
<template #layout_content>
|
|
95
|
+
<XCellList
|
|
96
|
+
:config-name="configName"
|
|
97
|
+
:service-name="serviceName"
|
|
98
|
+
:fix-query-form="{ o_f_oper_name: 'edu_test' }"
|
|
99
|
+
:id-key="idKey"
|
|
100
|
+
@to-detail="toDetail"
|
|
101
|
+
@delete-row="deleteRow"
|
|
102
|
+
/>
|
|
103
|
+
</template>
|
|
104
|
+
</NormalDataLayout>
|
|
22
105
|
</template>
|
|
23
106
|
|
|
24
107
|
<style scoped lang="less">
|
|
@@ -6,8 +6,15 @@ import { ref } from 'vue'
|
|
|
6
6
|
import { useRoute } from 'vue-router'
|
|
7
7
|
|
|
8
8
|
// 纯表单
|
|
9
|
-
const configName = ref('
|
|
10
|
-
const serviceName = ref('af-
|
|
9
|
+
const configName = ref('form_check_test')
|
|
10
|
+
const serviceName = ref('af-system')
|
|
11
|
+
|
|
12
|
+
// const configName = ref("计划下发Form")
|
|
13
|
+
// const serviceName = ref("af-linepatrol")
|
|
14
|
+
|
|
15
|
+
// 表单组
|
|
16
|
+
// const configName = ref('lngChargeAuditMobileFormGroup')
|
|
17
|
+
// const serviceName = ref('af-gaslink')
|
|
11
18
|
|
|
12
19
|
const formData = ref({})
|
|
13
20
|
const formGroup = ref(null)
|
|
@@ -18,6 +25,36 @@ function submit(_result) {
|
|
|
18
25
|
history.back()
|
|
19
26
|
})
|
|
20
27
|
}
|
|
28
|
+
|
|
29
|
+
// 表单组——数据
|
|
30
|
+
// function initComponents () {
|
|
31
|
+
// runLogic('getlngChargeAuditMobileFormGroupData', {id: 29}, 'af-gaslink').then((res) => {
|
|
32
|
+
// formData.value = {...res}
|
|
33
|
+
// })
|
|
34
|
+
// }
|
|
35
|
+
|
|
36
|
+
// 纯表单——数据
|
|
37
|
+
// function initComponents() {
|
|
38
|
+
// formData.value = { plan_name: 'af-llllll', plan_point: '1号点位', plan_single: '1号点位', plan_range: '2024-12-12' }
|
|
39
|
+
// }
|
|
40
|
+
|
|
41
|
+
// function initComponents() {
|
|
42
|
+
// runLogic('getlngChargeAuditMobileFormGroupData', { id: route.query?.id, o_id: route.query?.o_id }, 'af-gaslink').then((res) => {
|
|
43
|
+
// console.log('res------', res)
|
|
44
|
+
// formData.value = { ...res }
|
|
45
|
+
// formGroup.value.init({
|
|
46
|
+
// configName: configName.value,
|
|
47
|
+
// serviceName: serviceName.value,
|
|
48
|
+
// groupFormData: { ...res },
|
|
49
|
+
// mode: "新增"
|
|
50
|
+
// })
|
|
51
|
+
// isInit.value = true
|
|
52
|
+
// })
|
|
53
|
+
// }
|
|
54
|
+
|
|
55
|
+
// onBeforeMount(() => {
|
|
56
|
+
// initComponents()
|
|
57
|
+
// })
|
|
21
58
|
</script>
|
|
22
59
|
|
|
23
60
|
<template>
|