@arkxos/arkos-theme-classic 0.1.0

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.
Files changed (97) hide show
  1. package/README.md +36 -0
  2. package/ark_dist/ark-meta.json +81 -0
  3. package/ark_dist/ark_userChunk_1.js +5 -0
  4. package/ark_dist/ark_userChunk_2.js +5 -0
  5. package/ark_dist/ark_userChunk_3.js +49 -0
  6. package/ark_dist/config.js +79 -0
  7. package/ark_dist/css/layout.93396d23.css +125 -0
  8. package/ark_dist/favicon.ico +0 -0
  9. package/ark_dist/img/401.1800ba9e.gif +0 -0
  10. package/ark_dist/img/404.458c248a.png +0 -0
  11. package/ark_dist/img/404.png +0 -0
  12. package/ark_dist/img/auth_banner.jpg +0 -0
  13. package/ark_dist/img/avatar.jpg +0 -0
  14. package/ark_dist/img/avatar2.gif +0 -0
  15. package/ark_dist/img/avatar3.gif +0 -0
  16. package/ark_dist/img/login-background.1a699c00.jpg +0 -0
  17. package/ark_dist/img/loginbg.svg +1 -0
  18. package/ark_dist/img/logo-r.png +0 -0
  19. package/ark_dist/img/logo.png +0 -0
  20. package/ark_dist/img/no-widgets.svg +57 -0
  21. package/ark_dist/img/tasks-example.png +0 -0
  22. package/ark_dist/img/ver.svg +236 -0
  23. package/ark_dist/index.html +127 -0
  24. package/ark_dist/js/app.4a68e1f9.js +1 -0
  25. package/ark_dist/js/layout.661faa0e.js +3 -0
  26. package/ark_dist/js/layout.661faa0e.js.LICENSE.txt +6 -0
  27. package/ark_dist/js/layout.661faa0e.js.map +1 -0
  28. package/ark_proxy/entry.js +28 -0
  29. package/ark_proxy_es/entry.js +16 -0
  30. package/package.json +110 -0
  31. package/scripts/check.js +13 -0
  32. package/scripts/meta.js +21 -0
  33. package/scripts/prepublishOnly.js +28 -0
  34. package/src/assets/logo.png +0 -0
  35. package/src/auto-imports.d.ts +307 -0
  36. package/src/configs/subApp.ts +9 -0
  37. package/src/entrance/libProperties.ts +28 -0
  38. package/src/entrance/libTypes.ts +26 -0
  39. package/src/loadApp.ts +16 -0
  40. package/src/main.ts +18 -0
  41. package/src/os-themes/classic/assets/401_images/401.gif +0 -0
  42. package/src/os-themes/classic/assets/404_images/404.png +0 -0
  43. package/src/os-themes/classic/assets/404_images/404_cloud.png +0 -0
  44. package/src/os-themes/classic/assets/images/login-background.jpg +0 -0
  45. package/src/os-themes/classic/i18n/en.ts +39 -0
  46. package/src/os-themes/classic/i18n/zh-cn.ts +39 -0
  47. package/src/os-themes/classic/i18nFileBuilder/index.ts +19 -0
  48. package/src/os-themes/classic/images/tabs_images/ark-tab.png +0 -0
  49. package/src/os-themes/classic/index.js +19 -0
  50. package/src/os-themes/classic/layout/components/NavMenu.vue +56 -0
  51. package/src/os-themes/classic/layout/components/iframeView.vue +69 -0
  52. package/src/os-themes/classic/layout/components/search.vue +139 -0
  53. package/src/os-themes/classic/layout/components/setting.vue +95 -0
  54. package/src/os-themes/classic/layout/components/sideM.vue +137 -0
  55. package/src/os-themes/classic/layout/components/tags.vue +476 -0
  56. package/src/os-themes/classic/layout/components/tasks.vue +83 -0
  57. package/src/os-themes/classic/layout/components/topbar.vue +49 -0
  58. package/src/os-themes/classic/layout/components/userbar.vue +238 -0
  59. package/src/os-themes/classic/layout/index.vue +347 -0
  60. package/src/os-themes/classic/layout/other/404.vue +44 -0
  61. package/src/os-themes/classic/layout/other/autoExit.js +51 -0
  62. package/src/os-themes/classic/layout/other/empty.vue +3 -0
  63. package/src/os-themes/classic/router/routerStatic.js +103 -0
  64. package/src/os-themes/classic/router/scrollBehavior.js +22 -0
  65. package/src/os-themes/classic/router/systemRouter.js +36 -0
  66. package/src/os-themes/classic/store/index.js +6 -0
  67. package/src/os-themes/classic/store/modules/global.js +25 -0
  68. package/src/os-themes/classic/store/modules/iframe.js +40 -0
  69. package/src/os-themes/classic/store/modules/keepAlive.js +25 -0
  70. package/src/os-themes/classic/store/modules/viewTags.js +48 -0
  71. package/src/os-themes/classic/style/app.scss +318 -0
  72. package/src/os-themes/classic/style/dark.scss +42 -0
  73. package/src/os-themes/classic/style/fix.scss +87 -0
  74. package/src/os-themes/classic/style/media.scss +52 -0
  75. package/src/os-themes/classic/style/pages.scss +46 -0
  76. package/src/os-themes/classic/style/style.scss +5 -0
  77. package/src/os-themes/classic/utils/useTabs.js +66 -0
  78. package/src/os-themes/classic/views/bg.png +0 -0
  79. package/src/os-themes/classic/views/error/401.vue +82 -0
  80. package/src/os-themes/classic/views/error/404.vue +230 -0
  81. package/src/os-themes/classic/views/home.vue +13 -0
  82. package/src/os-themes/classic/views/login/components/commonPage.vue +35 -0
  83. package/src/os-themes/classic/views/login/components/passwordForm.vue +174 -0
  84. package/src/os-themes/classic/views/login/components/phoneForm.vue +74 -0
  85. package/src/os-themes/classic/views/login/index.vue +210 -0
  86. package/src/os-themes/classic/views/login/resetPassword.vue +125 -0
  87. package/src/os-themes/classic/views/login/userRegister.vue +174 -0
  88. package/src/os-themes/classic/views/redirect/index.vue +14 -0
  89. package/src/os-themes/classic/views/register.vue +219 -0
  90. package/src/shims-vue.d.ts +6 -0
  91. package/src/types/axios.d.ts +13 -0
  92. package/src/types/func.ts +14 -0
  93. package/src/types/global.d.ts +108 -0
  94. package/src/types/layout.d.ts +59 -0
  95. package/src/types/mitt.d.ts +40 -0
  96. package/src/types/pinia.d.ts +93 -0
  97. package/src/types/views.d.ts +27 -0
@@ -0,0 +1,39 @@
1
+ export default {
2
+ login: {
3
+ slogan: 'High performance / delicate / grace',
4
+ describe: 'Vue3 + element plus based front-end solutions in the background.',
5
+ signInTitle: 'Sign in',
6
+ accountLogin: 'Account sign in',
7
+ mobileLogin: 'Mobile sign in',
8
+ rememberMe: 'Remember me',
9
+ forgetPassword: 'Forget password',
10
+ signIn: 'Sign in',
11
+ signInOther: 'Sign in with',
12
+ userPlaceholder: 'user / phone / email',
13
+ userError: 'Please input a user name',
14
+ PWPlaceholder: 'Please input a password',
15
+ PWError: 'Please input a password',
16
+ admin: 'Administrator',
17
+ user: 'User',
18
+ mobilePlaceholder: 'Mobile',
19
+ mobileError: 'Please input mobile',
20
+ smsPlaceholder: 'SMS Code',
21
+ smsError: 'Please input sms code',
22
+ smsGet: 'Get SMS Code',
23
+ smsSent: 'SMS sent to mobile number',
24
+ noAccount: 'No account?',
25
+ createAccount: 'Create a new account',
26
+ wechatLoginTitle: 'QR code sign in',
27
+ wechatLoginMsg: 'Please use wechat to scan and log in | Auto scan after 3 seconds of simulation',
28
+ wechatLoginResult: 'Scanned | Please click authorize login in the device'
29
+ },
30
+ user: {
31
+ dynamic: 'Dynamic',
32
+ info: 'User Info',
33
+ settings: 'Settings',
34
+ nightmode: 'night mode',
35
+ nightmode_msg: 'Suitable for low light environment,The current night mode is beta',
36
+ language: 'language',
37
+ language_msg: 'Translation in progress,Temporarily translated the text of this view',
38
+ }
39
+ }
@@ -0,0 +1,39 @@
1
+ export default {
2
+ login: {
3
+ slogan: '高性能 / 精致 / 优雅',
4
+ describe: '基于Vue3 + Element-Plus 的中后台前端解决方案。',
5
+ signInTitle: '用户登录',
6
+ accountLogin: '账号登录',
7
+ mobileLogin: '手机号登录',
8
+ rememberMe: '24小时免登录',
9
+ forgetPassword: '忘记密码',
10
+ signIn: '登录',
11
+ signInOther: '其他登录方式',
12
+ userPlaceholder: '用户名 / 手机 / 邮箱',
13
+ userError: '请输入用户名',
14
+ PWPlaceholder: '请输入密码',
15
+ PWError: '请输入密码',
16
+ admin: '管理员',
17
+ user: '用户',
18
+ mobilePlaceholder: '手机号码',
19
+ mobileError: '请输入手机号码',
20
+ smsPlaceholder: '短信验证码',
21
+ smsError: '请输入短信验证码',
22
+ smsGet: '获取验证码',
23
+ smsSent: '已发送短信至手机号码',
24
+ noAccount: '还没有账号?',
25
+ createAccount: '创建新账号',
26
+ wechatLoginTitle: '二维码登录',
27
+ wechatLoginMsg: '请使用微信扫一扫登录 | 模拟3秒后自动扫描',
28
+ wechatLoginResult: '已扫描 | 请在设备中点击授权登录'
29
+ },
30
+ user: {
31
+ dynamic: '近期动态',
32
+ info: '个人信息',
33
+ settings: '设置',
34
+ nightmode: '黑夜模式',
35
+ nightmode_msg: '适合光线较弱的环境,当前黑暗模式为beta版本',
36
+ language: '语言',
37
+ language_msg: '翻译进行中,暂翻译了本视图的文本',
38
+ }
39
+ }
@@ -0,0 +1,19 @@
1
+
2
+ import { i18nBuilder } from '@arkxos/arkos-core'
3
+
4
+ /**
5
+ * 说明:
6
+ * 须在 pages 下新建文件夹(建议 `要国际化界面目录` 与 `i18n 目录` 相同,方便查找),
7
+ * 注意国际化定义的字段,不要与原有的定义字段相同。
8
+ * 1、/src/i18n/lang 下的 ts 为框架的国际化内容
9
+ * 2、/src/i18n/pages 下的 ts 为各界面的国际化内容
10
+ */
11
+ const modules = require.context('../i18n', false, /\.ts$/) // import.meta.glob('./**/*.ts', { eager: true });
12
+
13
+ const i18nFileData = {}
14
+ modules.keys().forEach((path) => {
15
+ i18nFileData[path] = modules(path).default;
16
+ })
17
+ console.log('theme i18nFileData', i18nFileData)
18
+
19
+ export default i18nBuilder(i18nFileData)
@@ -0,0 +1,19 @@
1
+ import RouterStatic from './router/routerStatic';
2
+ import Store from './store';
3
+
4
+ // 样式
5
+ // <style lang="scss">
6
+ // @import '@/os-themes/classic/style/style.scss';
7
+ // </style>
8
+ import './style/style.scss';
9
+ import * as components from "@element-plus/icons-vue";
10
+ import i18nMessage from "@/os-themes/classic/i18nFileBuilder"
11
+ import {i18n} from '@arkxos/arkos-core'
12
+
13
+ export default myRuntimePublicPath => {
14
+ __webpack_public_path__ = myRuntimePublicPath;
15
+ return {
16
+ routerStatic: RouterStatic,
17
+ store: Store
18
+ };
19
+ };
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <div v-if="navMenus.length<=0" style="padding:20px;">
3
+ <el-alert title="无子集菜单" center type="info" :closable="false"></el-alert>
4
+ </div>
5
+ <template v-for="navMenu in navMenus" v-bind:key="navMenu">
6
+ <el-menu-item v-if="!navMenu.hidden && !hasChildren(navMenu)" :index="jsonToQuery(navMenu)">
7
+ <a v-if="navMenu.meta && navMenu.meta.type=='link'" :href="navMenu.path" target="_blank" @click.stop='()=>{}'></a>
8
+ <el-icon v-if="navMenu.meta&&navMenu.meta.icon&&'#'===navMenu.meta.icon"><component :is="'el-icon-document'"/></el-icon>
9
+ <el-icon v-else-if="navMenu.meta&&navMenu.meta.icon"><component :is="navMenu.meta.icon || 'el-icon-menu'"/></el-icon>
10
+ <template #title>
11
+ <span>{{navMenu.meta.title}}</span>
12
+ <span v-if="navMenu.meta.tag" class="menu-tag">{{navMenu.meta.tag}}</span>
13
+ </template>
14
+ </el-menu-item>
15
+ <el-sub-menu v-else-if="!navMenu.hidden" :index="navMenu.path">
16
+ <template #title>
17
+ <el-icon v-if="navMenu.meta&&navMenu.meta.icon&&'#'===navMenu.meta.icon"><component :is="'el-icon-document'"/></el-icon>
18
+ <el-icon v-else-if="navMenu.meta&&navMenu.meta.icon"><component :is="navMenu.meta.icon || 'el-icon-menu'"/></el-icon>
19
+ <span>{{navMenu.meta.title}}</span>
20
+ <span v-if="navMenu.meta.tag" class="menu-tag">{{navMenu.meta.tag}}</span>
21
+ </template>
22
+ <NavMenu :navMenus="navMenu.children"></NavMenu>
23
+ </el-sub-menu>
24
+ </template>
25
+ </template>
26
+
27
+ <script>
28
+ export default {
29
+ name: 'NavMenu',
30
+ props: ['navMenus'],
31
+ data() {
32
+ return {}
33
+ },
34
+ methods: {
35
+ hasChildren(item) {
36
+ return item.children && !item.children.every(item => item.meta && item.meta.hidden)
37
+ },
38
+ jsonToQuery(navMenu) {
39
+ let result = navMenu.path
40
+ const queryString = navMenu.query
41
+ if (!queryString) {
42
+ return result
43
+ }
44
+ const json = JSON.parse(queryString)
45
+ console.log('menu query', json)
46
+ let query = '?';
47
+ for (const i in json) { // i是对象的键值
48
+ query += i + '=' + json[i] + '&'// json[i][j]是属性值
49
+ }
50
+ query = query.substring(0, query.length - 1);
51
+ result += query
52
+ return result;
53
+ }
54
+ }
55
+ }
56
+ </script>
@@ -0,0 +1,69 @@
1
+ <!--
2
+ * @Descripttion: 处理iframe持久化,涉及store(VUEX)
3
+ * @version: 1.0
4
+ * @Author: sakuya
5
+ * @Date: 2021年6月30日13:20:41
6
+ * @LastEditors:
7
+ * @LastEditTime:
8
+ -->
9
+
10
+ <template>
11
+ <div v-show="$route.meta.type=='iframe'" class="iframe-pages">
12
+ <iframe v-for="item in iframeList" :key="item.meta.url" v-show="$route.meta.url==item.meta.url" :src="item.meta.url" frameborder='0'></iframe>
13
+ </div>
14
+ </template>
15
+
16
+ <script>
17
+ import iframeStore from '../../store/modules/iframe';
18
+ import globalStore from '../../store/modules/global';
19
+
20
+ export default {
21
+ data() {
22
+ return {
23
+
24
+ }
25
+ },
26
+ watch: {
27
+ $route(e) {
28
+ this.push(e)
29
+ },
30
+ },
31
+ created() {
32
+ this.push(this.$route);
33
+ },
34
+ computed: {
35
+ iframeList() {
36
+ return iframeStore().iframeList
37
+ },
38
+ ismobile() {
39
+ return globalStore().ismobile
40
+ },
41
+ layoutTags() {
42
+ return globalStore().layoutTags
43
+ }
44
+ },
45
+ mounted() {
46
+
47
+ },
48
+ methods: {
49
+ push(route) {
50
+ if (route.meta.type == 'iframe') {
51
+ if (this.ismobile || !this.layoutTags) {
52
+ iframeStore().setIframeList(route)
53
+ } else {
54
+ iframeStore().pushIframeList(route)
55
+ }
56
+ } else {
57
+ if (this.ismobile || !this.layoutTags) {
58
+ iframeStore().clearIframeList()
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ </script>
65
+
66
+ <style scoped>
67
+ .iframe-pages {width:100%;height:100%;background: #fff;}
68
+ iframe {border:0;width:100%;height:100%;display: block;}
69
+ </style>
@@ -0,0 +1,139 @@
1
+ <template>
2
+ <div class="sc-search">
3
+ <el-input ref="input" v-model="input" placeholder="搜索" size="large" clearable prefix-icon="el-icon-search" :trigger-on-focus="false" @input="inputChange"/>
4
+ <div class="sc-search-history" v-if="history.length>0">
5
+ <el-tag closable effect="dark" type="info" v-for="(item, index) in history" :key="item" @click="historyClick(item)" @close="historyClose(index)">{{item}}</el-tag>
6
+ </div>
7
+ <div class="sc-search-result">
8
+ <div class="sc-search-no-result" v-if="result.length<=0">暂无搜索结果</div>
9
+ <ul v-else>
10
+ <el-scrollbar max-height="366px">
11
+ <li v-for="item in result" :key="item.path" @click="to(item)">
12
+ <el-icon><component :is="item.icon || 'el-icon-menu'" /></el-icon>
13
+ <span class="title">{{ item.breadcrumb }}</span>
14
+ </li>
15
+ </el-scrollbar>
16
+ </ul>
17
+ </div>
18
+ </div>
19
+ </template>
20
+
21
+ <script>
22
+ export default {
23
+ data() {
24
+ return {
25
+ input: '',
26
+ menu: [],
27
+ result: [],
28
+ history: []
29
+ }
30
+ },
31
+ mounted() {
32
+ const searchHistory = this.$TOOL.data.get('SEARCH_HISTORY') || []
33
+ this.history = searchHistory
34
+ const menuTree = this.$TOOL.data.get('MENU')
35
+ this.filterMenu(menuTree)
36
+ this.$refs.input.focus()
37
+ },
38
+ methods: {
39
+ inputChange(value) {
40
+ if (value) {
41
+ this.result = this.menuFilter(value)
42
+ } else {
43
+ this.result = []
44
+ }
45
+ },
46
+ filterMenu(map) {
47
+ map.forEach(item => {
48
+ if (item.meta.hidden || item.meta.type == 'button') {
49
+ return false
50
+ }
51
+ if (item.meta.type == 'iframe') {
52
+ item.path = `/i/${item.name}`
53
+ }
54
+ if (item.children && item.children.length > 0 && !item.component) {
55
+ this.filterMenu(item.children)
56
+ } else {
57
+ this.menu.push(item)
58
+ }
59
+ })
60
+ },
61
+ menuFilter(queryString) {
62
+ const res = []
63
+ // 过滤菜单树
64
+ const filterMenu = this.menu.filter((item) => {
65
+ if ((item.meta.title).toLowerCase().indexOf(queryString.toLowerCase()) >= 0) {
66
+ return true
67
+ }
68
+ if ((item.name).toLowerCase().indexOf(queryString.toLowerCase()) >= 0) {
69
+ return true
70
+ }
71
+ })
72
+ // 匹配系统路由
73
+ const router = this.$router.getRoutes()
74
+ const filterRouter = filterMenu.map((m) => {
75
+ if (m.meta.type == 'link') {
76
+ return router.find(r => r.path == '/' + m.path)
77
+ } else {
78
+ return router.find(r => r.path == m.path)
79
+ }
80
+ })
81
+ // 重组对象
82
+ filterRouter.forEach(item => {
83
+ res.push({
84
+ name: item.name,
85
+ type: item.meta.type,
86
+ path: item.meta.type == 'link' ? item.path.slice(1) : item.path,
87
+ icon: item.meta.icon,
88
+ title: item.meta.title,
89
+ breadcrumb: item.meta.breadcrumb.map(v => v.meta.title).join(' - ')
90
+ })
91
+ })
92
+ return res
93
+ },
94
+ to(item) {
95
+ if (!this.history.includes(this.input)) {
96
+ this.history.push(this.input)
97
+ this.$TOOL.data.set('SEARCH_HISTORY', this.history)
98
+ }
99
+ if (item.type == 'link') {
100
+ setTimeout(() => {
101
+ const a = document.createElement('a')
102
+ a.style = 'display: none'
103
+ a.target = '_blank'
104
+ a.href = item.path
105
+ document.body.appendChild(a)
106
+ a.click()
107
+ document.body.removeChild(a)
108
+ }, 10);
109
+ } else {
110
+ this.$router.push({ path: item.path })
111
+ }
112
+ this.$emit('success', true)
113
+ },
114
+ historyClick(text) {
115
+ this.input = text
116
+ this.inputChange(text)
117
+ },
118
+ historyClose(index) {
119
+ this.history.splice(index, 1);
120
+ if (this.history.length <= 0) {
121
+ this.$TOOL.data.remove('SEARCH_HISTORY')
122
+ } else {
123
+ this.$TOOL.data.set('SEARCH_HISTORY', this.history)
124
+ }
125
+ }
126
+ }
127
+ }
128
+ </script>
129
+
130
+ <style scoped>
131
+ .sc-search {}
132
+ .sc-search-no-result {text-align: center;margin: 40px 0;color: #999;}
133
+ .sc-search-history {margin-top: 10px;}
134
+ .sc-search-history .el-tag {cursor: pointer;}
135
+ .sc-search-result {margin-top: 15px;}
136
+ .sc-search-result li {height:56px;padding:0 15px;background: var(--el-bg-color-overlay);border: 1px solid var(--el-border-color-light);list-style:none;border-radius: 4px;margin-bottom: 5px;font-size: 14px;display: flex;align-items: center;cursor: pointer;}
137
+ .sc-search-result li i {font-size: 20px;margin-right: 15px;}
138
+ .sc-search-result li:hover {background: var(--el-color-primary);color: #fff;border-color: var(--el-color-primary);}
139
+ </style>
@@ -0,0 +1,95 @@
1
+ <template>
2
+ <el-form ref="form" label-width="120px" label-position="left" style="padding:0 20px;">
3
+ <el-alert title="以下配置可实时预览,开发者可在 config/index.js 中配置默认值,非常不建议在生产环境下开放布局设置" type="error" :closable="false"></el-alert>
4
+ <el-divider></el-divider>
5
+ <el-form-item :label="$t('user.nightmode')">
6
+ <el-switch v-model="dark"></el-switch>
7
+ </el-form-item>
8
+ <el-form-item :label="$t('user.language')">
9
+ <el-select v-model="lang">
10
+ <el-option label="简体中文" value="zh-cn"></el-option>
11
+ <el-option label="English" value="en"></el-option>
12
+ </el-select>
13
+ </el-form-item>
14
+ <el-divider></el-divider>
15
+ <el-form-item label="主题颜色">
16
+ <el-color-picker v-model="colorPrimary" :predefine="colorList">></el-color-picker>
17
+ </el-form-item>
18
+ <el-divider></el-divider>
19
+ <el-form-item label="框架布局">
20
+ <el-select v-model="layout" placeholder="请选择">
21
+ <el-option label="默认" value="default"></el-option>
22
+ <el-option label="通栏" value="header"></el-option>
23
+ <el-option label="经典" value="menu"></el-option>
24
+ <el-option label="功能坞" value="dock"></el-option>
25
+ </el-select>
26
+ </el-form-item>
27
+ <el-form-item label="折叠菜单">
28
+ <el-switch v-model="menuIsCollapse"></el-switch>
29
+ </el-form-item>
30
+ <el-form-item label="标签栏">
31
+ <el-switch v-model="layoutTags"></el-switch>
32
+ </el-form-item>
33
+ <el-divider></el-divider>
34
+ </el-form>
35
+ </template>
36
+
37
+ <script>
38
+ import { color } from '@arkxos/arkos-util'
39
+ import globalStore from '../../store/modules/global';
40
+
41
+ export default {
42
+ data() {
43
+ return {
44
+ layout: globalStore().layout,
45
+ menuIsCollapse: globalStore().menuIsCollapse,
46
+ layoutTags: globalStore().layoutTags,
47
+ lang: this.$TOOL.data.get('APP_LANG') || this.$CONFIG.LANG,
48
+ dark: this.$TOOL.data.get('APP_DARK') || false,
49
+ colorList: ['#409EFF', '#009688', '#536dfe', '#ff5c93', '#c62f2f', '#fd726d'],
50
+ colorPrimary: this.$TOOL.data.get('APP_COLOR') || this.$CONFIG.COLOR || '#409EFF'
51
+ }
52
+ },
53
+ watch: {
54
+ layout(val) {
55
+ globalStore().layout = val
56
+ },
57
+ menuIsCollapse() {
58
+ globalStore().toggleMenuIsCollapse()
59
+ },
60
+ layoutTags() {
61
+ globalStore().toggleLayoutTags()
62
+ },
63
+ dark(val) {
64
+ if (val) {
65
+ document.documentElement.classList.add('dark')
66
+ this.$TOOL.data.set('APP_DARK', val)
67
+ } else {
68
+ document.documentElement.classList.remove('dark')
69
+ this.$TOOL.data.remove('APP_DARK')
70
+ }
71
+ },
72
+ lang(val) {
73
+ this.$i18n.locale = val
74
+ this.$TOOL.data.set('APP_LANG', val);
75
+ },
76
+ colorPrimary(val) {
77
+ if (!val) {
78
+ val = '#409EFF'
79
+ this.colorPrimary = '#409EFF'
80
+ }
81
+ document.documentElement.style.setProperty('--el-color-primary', val);
82
+ for (let i = 1; i <= 9; i++) {
83
+ document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, color.lighten(val, i / 10));
84
+ }
85
+ for (let i = 1; i <= 9; i++) {
86
+ document.documentElement.style.setProperty(`--el-color-primary-dark-${i}`, color.darken(val, i / 10));
87
+ }
88
+ this.$TOOL.data.set('APP_COLOR', val);
89
+ }
90
+ }
91
+ }
92
+ </script>
93
+
94
+ <style>
95
+ </style>
@@ -0,0 +1,137 @@
1
+ <template>
2
+ <div ref="" class="mobile-nav-button" @click="showMobileNav($event)" v-drag draggable="false"><el-icon><el-icon-menu /></el-icon></div>
3
+
4
+ <el-drawer ref="mobileNavBox" title="移动端菜单" :size="240" v-model="nav" direction="ltr" :with-header="false" destroy-on-close>
5
+ <el-container class="mobile-nav">
6
+ <el-header>
7
+ <div class="logo-bar"><img class="logo" src="img/logo.png"><span>{{ $CONFIG.ArkosTitle }}</span></div>
8
+ </el-header>
9
+ <el-main>
10
+ <el-scrollbar>
11
+ <el-menu :default-active="$route.meta.active || $route.path" @select="select" router background-color="#212d3d" text-color="#fff" active-text-color="#409EFF">
12
+ <NavMenu :navMenus="menu"></NavMenu>
13
+ </el-menu>
14
+ </el-scrollbar>
15
+ </el-main>
16
+ </el-container>
17
+ </el-drawer>
18
+
19
+ </template>
20
+
21
+ <script>
22
+ import NavMenu from './NavMenu.vue';
23
+
24
+ export default {
25
+ components: {
26
+ NavMenu
27
+ },
28
+ data() {
29
+ return {
30
+ nav: false,
31
+ menu: []
32
+ }
33
+ },
34
+ computed: {
35
+
36
+ },
37
+ created() {
38
+ // var menu = this.$router.sc_getMenu()
39
+ // this.menu = this.filterUrl(menu)
40
+ console.log('this.$pinia', this.$pinia)
41
+ const systemStore = this.$pinia._s.get('system');
42
+ console.log('systemStore.menus', systemStore.menus)
43
+ this.menu = systemStore.menus
44
+ },
45
+
46
+ watch: {
47
+
48
+ },
49
+ methods: {
50
+ showMobileNav(e) {
51
+ const isdrag = e.currentTarget.getAttribute('drag-flag')
52
+ if (isdrag == 'true') {
53
+ return false;
54
+ } else {
55
+ this.nav = true;
56
+ }
57
+ },
58
+ select() {
59
+ this.$refs.mobileNavBox.handleClose()
60
+ },
61
+ // 转换外部链接的路由
62
+ filterUrl(map) {
63
+ const newMap = []
64
+ map && map.forEach(item => {
65
+ item.meta = item.meta ? item.meta : {};
66
+ // 处理隐藏
67
+ if (item.meta.hidden || item.meta.type == 'button') {
68
+ return false
69
+ }
70
+ // 处理http
71
+ if (item.meta.type == 'iframe') {
72
+ item.path = `/i/${item.name}`;
73
+ }
74
+ // 递归循环
75
+ if (item.children && item.children.length > 0) {
76
+ item.children = this.filterUrl(item.children);
77
+ }
78
+ newMap.push(item)
79
+ })
80
+ return newMap;
81
+ }
82
+ },
83
+ directives: {
84
+ drag(el) {
85
+ const oDiv = el; // 当前元素
86
+ let firstTime = ''; let lastTime = '';
87
+ // 禁止选择网页上的文字
88
+ // document.onselectstart = function() {
89
+ // return false;
90
+ // };
91
+ oDiv.onmousedown = function(e) {
92
+ // 鼠标按下,计算当前元素距离可视区的距离
93
+ const disX = e.clientX - oDiv.offsetLeft;
94
+ const disY = e.clientY - oDiv.offsetTop;
95
+ document.onmousemove = function(e) {
96
+ oDiv.setAttribute('drag-flag', true);
97
+ firstTime = new Date().getTime();
98
+ // 通过事件委托,计算移动的距离
99
+ const l = e.clientX - disX;
100
+ const t = e.clientY - disY;
101
+
102
+ // 移动当前元素
103
+
104
+ if (t > 0 && t < document.body.clientHeight - 50) {
105
+ oDiv.style.top = t + 'px';
106
+ }
107
+ if (l > 0 && l < document.body.clientWidth - 50) {
108
+ oDiv.style.left = l + 'px';
109
+ }
110
+ }
111
+ document.onmouseup = function() {
112
+ lastTime = new Date().getTime();
113
+ if ((lastTime - firstTime) > 200) {
114
+ oDiv.setAttribute('drag-flag', false);
115
+ }
116
+ document.onmousemove = null;
117
+ document.onmouseup = null;
118
+ };
119
+ // return false不加的话可能导致黏连,就是拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
120
+ return false;
121
+ };
122
+ }
123
+ }
124
+ }
125
+ </script>
126
+
127
+ <style scoped>
128
+ .mobile-nav-button {position: fixed;bottom:10px;left:10px;z-index: 10;width: 50px;height: 50px;background: #409EFF;box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 1);border-radius: 50%;display: flex;align-items: center;justify-content: center;}
129
+ .mobile-nav-button i {color: #fff;font-size: 20px;}
130
+
131
+ .mobile-nav {background: #212d3d;}
132
+ .mobile-nav .el-header {background: transparent;border: 0;}
133
+ .mobile-nav .el-main {padding:0;}
134
+ .mobile-nav .logo-bar {display: flex;align-items: center;font-weight: bold;font-size: 20px;color: #fff;}
135
+ .mobile-nav .logo-bar img {width: 30px;margin-right: 10px;}
136
+ .mobile-nav .el-submenu__title:hover {background: #fff!important;}
137
+ </style>