mirror of
https://gitee.com/bootx/dax-pay-h5.git
synced 2025-10-14 14:10:26 +00:00
feat 调整各种配置,适应对接到DaxPay项目中
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
# 网站根目录
|
# 网站根目录 和 接口 (api) 前缀 这个是嵌入式模式
|
||||||
VITE_PUBLIC_PATH = /
|
VITE_PUBLIC_PATH = /h5
|
||||||
|
VITE_GLOB_API_URL_PREFIX = /
|
||||||
|
|
||||||
|
# 网站根目录 和 接口 (api) 前缀 这个是独立部署模式
|
||||||
|
#VITE_PUBLIC_PATH = /
|
||||||
|
#VITE_GLOB_API_URL_PREFIX = /api
|
||||||
|
|
||||||
# 是否删除console
|
# 是否删除console
|
||||||
VITE_DROP_CONSOLE = true
|
VITE_DROP_CONSOLE = true
|
||||||
@@ -13,9 +18,6 @@ VITE_GLOB_UPLOAD_URL =
|
|||||||
# 图片前缀地址
|
# 图片前缀地址
|
||||||
VITE_GLOB_IMG_URL =
|
VITE_GLOB_IMG_URL =
|
||||||
|
|
||||||
# 接口 (api) 前缀
|
|
||||||
VITE_GLOB_API_URL_PREFIX = /api
|
|
||||||
|
|
||||||
# 是否启用gzip压缩或brotli压缩
|
# 是否启用gzip压缩或brotli压缩
|
||||||
# 可选: gzip | brotli | none
|
# 可选: gzip | brotli | none
|
||||||
# 如果你需要多种形式,你可以用','来分隔
|
# 如果你需要多种形式,你可以用','来分隔
|
||||||
|
214
LICENSE
214
LICENSE
@@ -1,21 +1,201 @@
|
|||||||
MIT License
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
Copyright (c) 2022 傲慢或香橙
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
1. Definitions.
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
copies or substantial portions of the Software.
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
the copyright owner that is granting the License.
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
other entities that control, are controlled by, or are under common
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
control with that entity. For the purposes of this definition,
|
||||||
SOFTWARE.
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright (c) 2021 bootx Authors. All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
10
components.d.ts
vendored
10
components.d.ts
vendored
@@ -8,20 +8,10 @@ export {}
|
|||||||
declare module '@vue/runtime-core' {
|
declare module '@vue/runtime-core' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
SvgIcon: typeof import('./src/components/SvgIcon.vue')['default']
|
SvgIcon: typeof import('./src/components/SvgIcon.vue')['default']
|
||||||
VanActionSheet: typeof import('vant/es')['ActionSheet']
|
|
||||||
VanButton: typeof import('vant/es')['Button']
|
VanButton: typeof import('vant/es')['Button']
|
||||||
VanCell: typeof import('vant/es')['Cell']
|
|
||||||
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
VanConfigProvider: typeof import('vant/es')['ConfigProvider']
|
||||||
VanDivider: typeof import('vant/es')['Divider']
|
|
||||||
VanField: typeof import('vant/es')['Field']
|
|
||||||
VanForm: typeof import('vant/es')['Form']
|
|
||||||
VanImage: typeof import('vant/es')['Image']
|
|
||||||
VanNavBar: typeof import('vant/es')['NavBar']
|
VanNavBar: typeof import('vant/es')['NavBar']
|
||||||
VanPicker: typeof import('vant/es')['Picker']
|
|
||||||
VanPopup: typeof import('vant/es')['Popup']
|
|
||||||
VanSwitch: typeof import('vant/es')['Switch']
|
|
||||||
VanTabbar: typeof import('vant/es')['Tabbar']
|
VanTabbar: typeof import('vant/es')['Tabbar']
|
||||||
VanTabbarItem: typeof import('vant/es')['TabbarItem']
|
VanTabbarItem: typeof import('vant/es')['TabbarItem']
|
||||||
VanUploader: typeof import('vant/es')['Uploader']
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { useRouteStore } from '@/store/modules/route'
|
import { useRouteStore } from '@/store/modules/route'
|
||||||
|
|
||||||
@@ -51,7 +51,9 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
const getShowHeader = computed(() => currentRoute.meta.showHeader)
|
const getShowHeader = computed(() => currentRoute.meta.showHeader)
|
||||||
const getShowTabbar = computed(() => !currentRoute.meta.hiddenTabbar)
|
// const getShowTabbar = computed(() => !currentRoute.meta.hiddenTabbar)
|
||||||
|
// TODO 默认不显示tabbar
|
||||||
|
const getShowTabbar = ref<boolean>(false)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
@@ -33,12 +33,3 @@ export const RootRoute: RouteRecordRaw = {
|
|||||||
title: 'Root',
|
title: 'Root',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LoginRoute: RouteRecordRaw = {
|
|
||||||
path: '/login',
|
|
||||||
name: 'Login',
|
|
||||||
component: () => import('@/views/login/Login.vue'),
|
|
||||||
meta: {
|
|
||||||
title: '登录',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
@@ -11,23 +11,35 @@ export const DemoRoute: RouteRecordRaw = {
|
|||||||
component: Layout,
|
component: Layout,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/t',
|
path: '/cashier/alipay',
|
||||||
name: 'DispatchRouter',
|
name: 'AlipayCashier',
|
||||||
component: () => import('@/views/system/dispatch/DispatchRouter.vue'),
|
component: () => import('@/views/demo/cashier/AlipayCashier.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: '中转页',
|
title: '支付宝收银台',
|
||||||
ignoreAuth: true,
|
|
||||||
hiddenTabbar: true,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/x/x/x',
|
path: '/cashier/wxJsapiPay',
|
||||||
name: 'xx',
|
name: 'WechatJsapiPay',
|
||||||
component: () => import('@/views/modules/demo/xx.vue'),
|
component: () => import('@/views/demo/cashier/WechatJsapiPay.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: 'xx',
|
title: '支付宝收银台',
|
||||||
hiddenTabbar: true,
|
},
|
||||||
ignoreAuth: true,
|
},
|
||||||
|
{
|
||||||
|
path: '/exception/timeout',
|
||||||
|
name: 'TimeoutPay',
|
||||||
|
component: () => import('@/views/demo/exception/TimeoutPay.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '支付超时',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/exception/errorPay',
|
||||||
|
name: 'TimeoutPay',
|
||||||
|
component: () => import('@/views/demo/exception/ErrorPay.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '支付超时',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
import { App } from 'vue'
|
import { App } from 'vue'
|
||||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
|
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
|
||||||
import { LoginRoute, RootRoute, ErrorPageRoute } from '@/router/base'
|
import { RootRoute, ErrorPageRoute } from '@/router/base'
|
||||||
import { createRouterGuards } from './router-guards'
|
|
||||||
import { useRouteStoreWidthOut } from '@/store/modules/route'
|
import { useRouteStoreWidthOut } from '@/store/modules/route'
|
||||||
|
|
||||||
// 菜单
|
// 菜单
|
||||||
import routeModuleList from './modules'
|
import routeModuleList from './modules'
|
||||||
import { BusinessRoute } from '@/router/business'
|
import { BusinessRoute } from '@/router/business'
|
||||||
|
import { DemoRoute } from '@/router/demo'
|
||||||
|
|
||||||
// 普通路由
|
// 普通路由
|
||||||
export const constantRouter: RouteRecordRaw[] = [
|
export const constantRouter: RouteRecordRaw[] = [
|
||||||
LoginRoute,
|
DemoRoute,
|
||||||
RootRoute,
|
RootRoute,
|
||||||
ErrorPageRoute,
|
ErrorPageRoute,
|
||||||
BusinessRoute,
|
BusinessRoute,
|
||||||
@@ -30,8 +30,8 @@ const router = createRouter({
|
|||||||
|
|
||||||
export function setupRouter(app: App) {
|
export function setupRouter(app: App) {
|
||||||
app.use(router)
|
app.use(router)
|
||||||
// 创建路由守卫
|
// TODO 不使用路由守卫
|
||||||
createRouterGuards(router)
|
// createRouterGuards(router)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
@@ -23,83 +23,6 @@ const routeModuleList: Array<RouteRecordRaw> = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/my',
|
|
||||||
name: 'My',
|
|
||||||
redirect: '/my/index',
|
|
||||||
component: Layout,
|
|
||||||
meta: {
|
|
||||||
title: '我的',
|
|
||||||
icon: 'manager',
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'index',
|
|
||||||
name: 'MyPage',
|
|
||||||
meta: {
|
|
||||||
keepAlive: false,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/my/index.vue'),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
// my innerPage
|
|
||||||
{
|
|
||||||
path: '/editUserInfo',
|
|
||||||
name: 'EditUserInfo',
|
|
||||||
meta: {
|
|
||||||
title: '编辑个人信息',
|
|
||||||
innerPage: true,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/my/EditUserInfo.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/editNickname',
|
|
||||||
name: 'EditNickname',
|
|
||||||
meta: {
|
|
||||||
title: '修改昵称',
|
|
||||||
innerPage: true,
|
|
||||||
keepAlive: false,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/my/EditNickname.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/editSign',
|
|
||||||
name: 'EditSign',
|
|
||||||
meta: {
|
|
||||||
title: '修改签名',
|
|
||||||
innerPage: true,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/my/EditSign.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/accountSetting',
|
|
||||||
name: 'AccountSetting',
|
|
||||||
meta: {
|
|
||||||
title: '账号与安全',
|
|
||||||
innerPage: true,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/my/AccountSetting.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/changePassword',
|
|
||||||
name: 'ChangePassword',
|
|
||||||
meta: {
|
|
||||||
title: '修改登录密码',
|
|
||||||
innerPage: true,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/my/ChangePassword.vue'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/themeSetting',
|
|
||||||
name: 'ThemeSetting',
|
|
||||||
meta: {
|
|
||||||
title: '主题设置',
|
|
||||||
innerPage: true,
|
|
||||||
},
|
|
||||||
component: () => import('@/views/my/ThemeSetting.vue'),
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export default routeModuleList
|
export default routeModuleList
|
||||||
|
12
src/views/demo/cashier/AlipayCashier.vue
Normal file
12
src/views/demo/cashier/AlipayCashier.vue
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
345
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
|
||||||
|
</style>
|
11
src/views/demo/cashier/WechatJsapiPay.vue
Normal file
11
src/views/demo/cashier/WechatJsapiPay.vue
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
123
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
|
||||||
|
</style>
|
11
src/views/demo/exception/ErrorPay.vue
Normal file
11
src/views/demo/exception/ErrorPay.vue
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
支付错误
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
|
||||||
|
</style>
|
11
src/views/demo/exception/TimeoutPay.vue
Normal file
11
src/views/demo/exception/TimeoutPay.vue
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
支付超时
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
|
||||||
|
</style>
|
@@ -1,107 +0,0 @@
|
|||||||
<template>
|
|
||||||
<van-form ref="formRef" v-if="getShow" class="flex flex-col items-center" @submit="handleReset">
|
|
||||||
<van-field
|
|
||||||
class="enter-y items-center mb-25px !rounded-md"
|
|
||||||
v-model="formData.username"
|
|
||||||
name="username"
|
|
||||||
placeholder="用户名"
|
|
||||||
:rules="getFormRules.username"
|
|
||||||
>
|
|
||||||
<template #left-icon>
|
|
||||||
<Icon>
|
|
||||||
<UserOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
class="enter-y items-center mb-25px !rounded-md"
|
|
||||||
v-model="formData.mobile"
|
|
||||||
name="password"
|
|
||||||
placeholder="手机号码"
|
|
||||||
:rules="getFormRules.mobile"
|
|
||||||
>
|
|
||||||
<template #left-icon>
|
|
||||||
<Icon>
|
|
||||||
<MobileOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
class="enter-y items-center mb-70px !rounded-md"
|
|
||||||
v-model="formData.sms"
|
|
||||||
center
|
|
||||||
clearable
|
|
||||||
placeholder="请输入短信验证码"
|
|
||||||
:rules="getFormRules.sms"
|
|
||||||
>
|
|
||||||
<template #left-icon>
|
|
||||||
<Icon>
|
|
||||||
<EditOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
<template #button>
|
|
||||||
<van-button size="small" type="primary">发送验证码</van-button>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
|
|
||||||
<van-button
|
|
||||||
class="enter-y !mb-25px !rounded-md"
|
|
||||||
type="primary"
|
|
||||||
block
|
|
||||||
native-type="submit"
|
|
||||||
:loading="loading"
|
|
||||||
>
|
|
||||||
重 置
|
|
||||||
</van-button>
|
|
||||||
|
|
||||||
<van-button
|
|
||||||
class="enter-y !mb-150px !rounded-md"
|
|
||||||
plain
|
|
||||||
type="primary"
|
|
||||||
block
|
|
||||||
@click="handleBackLogin"
|
|
||||||
>
|
|
||||||
返 回
|
|
||||||
</van-button>
|
|
||||||
</van-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed, reactive, ref, unref } from 'vue'
|
|
||||||
import type { FormInstance } from 'vant'
|
|
||||||
import { Icon } from '@vicons/utils'
|
|
||||||
import { UserOutlined, MobileOutlined, EditOutlined } from '@vicons/antd'
|
|
||||||
import { LoginStateEnum, useLoginState, useFormRules } from './useLogin'
|
|
||||||
|
|
||||||
const { handleBackLogin, getLoginState } = useLoginState()
|
|
||||||
const { getFormRules } = useFormRules()
|
|
||||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.RESET_PASSWORD)
|
|
||||||
|
|
||||||
const loading = ref(false)
|
|
||||||
const formRef = ref<FormInstance>()
|
|
||||||
const formData = reactive({
|
|
||||||
username: '',
|
|
||||||
mobile: '',
|
|
||||||
sms: '',
|
|
||||||
})
|
|
||||||
|
|
||||||
function handleReset() {
|
|
||||||
formRef.value
|
|
||||||
?.validate()
|
|
||||||
.then(async () => {
|
|
||||||
try {
|
|
||||||
loading.value = true
|
|
||||||
// do something
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
console.error('验证失败')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less"></style>
|
|
@@ -1,28 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div class="flex justify-center h-screen p-8">
|
|
||||||
<div class="flex flex-col w-full">
|
|
||||||
<LoginTitle />
|
|
||||||
<LoginForm />
|
|
||||||
<ForgetPasswordForm />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<LoginWave />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import LoginTitle from './LoginTitle.vue'
|
|
||||||
import LoginForm from './LoginForm.vue'
|
|
||||||
import ForgetPasswordForm from './ForgetPasswordForm.vue'
|
|
||||||
import LoginWave from './LoginWave.vue'
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
:deep(.van-field__left-icon) {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
:deep(.van-field__right-icon) {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,116 +0,0 @@
|
|||||||
<template>
|
|
||||||
<van-form ref="formRef" v-if="getShow" class="flex flex-col items-center" @submit="handleSubmit">
|
|
||||||
<van-field
|
|
||||||
class="enter-y items-center mb-25px !rounded-md"
|
|
||||||
v-model="formData.username"
|
|
||||||
name="username"
|
|
||||||
placeholder="用户名"
|
|
||||||
:rules="getFormRules.username"
|
|
||||||
>
|
|
||||||
<template #left-icon>
|
|
||||||
<Icon>
|
|
||||||
<UserOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
<van-field
|
|
||||||
class="enter-y items-center mb-25px !rounded-md"
|
|
||||||
v-model="formData.password"
|
|
||||||
:type="switchPassType ? 'password' : 'text'"
|
|
||||||
name="password"
|
|
||||||
placeholder="密码"
|
|
||||||
:rules="getFormRules.password"
|
|
||||||
@click-right-icon="switchPassType = !switchPassType"
|
|
||||||
>
|
|
||||||
<template #left-icon>
|
|
||||||
<Icon>
|
|
||||||
<LockOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
<template #right-icon>
|
|
||||||
<Icon v-if="switchPassType">
|
|
||||||
<EyeInvisibleOutlined />
|
|
||||||
</Icon>
|
|
||||||
<Icon v-else>
|
|
||||||
<EyeOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
|
|
||||||
<div class="enter-y w-full px-5px flex justify-between mb-100px"> </div>
|
|
||||||
|
|
||||||
<van-button
|
|
||||||
class="enter-y !rounded-md !mb-25px"
|
|
||||||
type="primary"
|
|
||||||
block
|
|
||||||
native-type="submit"
|
|
||||||
:loading="loading"
|
|
||||||
>
|
|
||||||
登 录
|
|
||||||
</van-button>
|
|
||||||
</van-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed, onMounted, reactive, ref, unref } from 'vue'
|
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
|
||||||
import { showFailToast, showLoadingToast, showSuccessToast } from 'vant'
|
|
||||||
import type { FormInstance } from 'vant'
|
|
||||||
import { Icon } from '@vicons/utils'
|
|
||||||
import { UserOutlined, LockOutlined, EyeOutlined, EyeInvisibleOutlined } from '@vicons/antd'
|
|
||||||
import { useUserStore } from '@/store/modules/user'
|
|
||||||
import { ResultEnum } from '@/enums/httpEnum'
|
|
||||||
import { PageEnum } from '@/enums/pageEnum'
|
|
||||||
import { LoginStateEnum, useLoginState, useFormRules } from './useLogin'
|
|
||||||
|
|
||||||
const { getLoginState } = useLoginState()
|
|
||||||
const { getFormRules } = useFormRules()
|
|
||||||
const userStore = useUserStore()
|
|
||||||
const router = useRouter()
|
|
||||||
const route = useRoute()
|
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
|
||||||
const loading = ref(false)
|
|
||||||
const switchPassType = ref(true)
|
|
||||||
const formData = reactive({
|
|
||||||
username: '',
|
|
||||||
password: '',
|
|
||||||
})
|
|
||||||
|
|
||||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN)
|
|
||||||
|
|
||||||
function handleSubmit() {
|
|
||||||
formRef.value
|
|
||||||
?.validate()
|
|
||||||
.then(async () => {
|
|
||||||
try {
|
|
||||||
loading.value = true
|
|
||||||
showLoadingToast('登录中...')
|
|
||||||
const { code, msg } = await userStore.Login({
|
|
||||||
account: formData.username,
|
|
||||||
password: formData.password,
|
|
||||||
client: 'dax-pay',
|
|
||||||
loginType: 'password',
|
|
||||||
})
|
|
||||||
if (code == ResultEnum.SUCCESS) {
|
|
||||||
const toPath = decodeURIComponent((route.query?.redirect || '/') as string)
|
|
||||||
showSuccessToast('登录成功,即将进入系统')
|
|
||||||
if (route.name === PageEnum.BASE_LOGIN_NAME) {
|
|
||||||
router.replace('/')
|
|
||||||
} else router.replace(toPath)
|
|
||||||
} else {
|
|
||||||
showFailToast(msg || '登录失败')
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
console.error('验证失败')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less"></style>
|
|
@@ -1,20 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="flex flex-col items-center justify-center">
|
|
||||||
<div class="logo my-35px enter-y">
|
|
||||||
<SvgIcon class="!h-250px !w-250px" name="logo" />
|
|
||||||
</div>
|
|
||||||
<div class="mb-80px text-darkBlue dark:text-garyWhite text-45px font-black enter-y">
|
|
||||||
{{ title }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { useGlobSetting } from '@/hooks/setting'
|
|
||||||
|
|
||||||
const globSetting = useGlobSetting()
|
|
||||||
|
|
||||||
const { title } = globSetting
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less"></style>
|
|
@@ -1,105 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="enter-y fixed bottom-0 w-full !-z-5 wave-wrapper">
|
|
||||||
<svg
|
|
||||||
class="ignore-waves"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
viewBox="0 24 150 28"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
shape-rendering="auto"
|
|
||||||
>
|
|
||||||
<defs>
|
|
||||||
<path
|
|
||||||
id="gentle-wave"
|
|
||||||
d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"
|
|
||||||
/>
|
|
||||||
</defs>
|
|
||||||
<g class="parallax">
|
|
||||||
<use
|
|
||||||
xlink:href="#gentle-wave"
|
|
||||||
x="48"
|
|
||||||
y="0"
|
|
||||||
:fill="hexToRgba(designStore.getAppTheme, 0.4)"
|
|
||||||
/>
|
|
||||||
<use
|
|
||||||
xlink:href="#gentle-wave"
|
|
||||||
x="48"
|
|
||||||
y="3"
|
|
||||||
:fill="hexToRgba(designStore.getAppTheme, 0.5)"
|
|
||||||
/>
|
|
||||||
<use
|
|
||||||
xlink:href="#gentle-wave"
|
|
||||||
x="48"
|
|
||||||
y="5"
|
|
||||||
:fill="hexToRgba(designStore.getAppTheme, 0.6)"
|
|
||||||
/>
|
|
||||||
<use
|
|
||||||
xlink:href="#gentle-wave"
|
|
||||||
x="48"
|
|
||||||
y="7"
|
|
||||||
:fill="hexToRgba(designStore.getAppTheme, 0.7)"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
|
||||||
import { hexToRgba } from '@/utils/index'
|
|
||||||
|
|
||||||
const designStore = useDesignSettingStore()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.wave-wrapper {
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
.ignore-waves {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 50px;
|
|
||||||
min-height: 40px;
|
|
||||||
max-height: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Animation */
|
|
||||||
.parallax > use {
|
|
||||||
animation: move-forever 12s cubic-bezier(0.55, 0.5, 0.45, 0.5) infinite;
|
|
||||||
animation: move-forever 12s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
.parallax > use:nth-child(1) {
|
|
||||||
animation-delay: -2s;
|
|
||||||
animation-duration: 7s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.parallax > use:nth-child(2) {
|
|
||||||
animation-delay: -3s;
|
|
||||||
animation-duration: 10s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.parallax > use:nth-child(3) {
|
|
||||||
animation-delay: -4s;
|
|
||||||
animation-duration: 13s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.parallax > use:nth-child(4) {
|
|
||||||
animation-delay: -5s;
|
|
||||||
animation-duration: 16s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes move-forever {
|
|
||||||
0% {
|
|
||||||
transform: translate3d(-90px, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: translate3d(85px, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,188 +0,0 @@
|
|||||||
<template>
|
|
||||||
<van-form ref="formRef" v-if="getShow" class="flex flex-col" @submit="handleRegister">
|
|
||||||
<van-cell-group inset class="enter-y !mx-0 !mb-60px">
|
|
||||||
<van-field
|
|
||||||
class="enter-y items-center !rounded-md"
|
|
||||||
v-model="formData.username"
|
|
||||||
name="username"
|
|
||||||
placeholder="用户名"
|
|
||||||
:rules="getFormRules.username"
|
|
||||||
>
|
|
||||||
<template #left-icon>
|
|
||||||
<Icon>
|
|
||||||
<UserOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
class="enter-y items-center !rounded-md"
|
|
||||||
v-model="formData.mobile"
|
|
||||||
name="password"
|
|
||||||
placeholder="手机号码"
|
|
||||||
:rules="getFormRules.mobile"
|
|
||||||
>
|
|
||||||
<template #left-icon>
|
|
||||||
<Icon>
|
|
||||||
<MobileOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
class="enter-y items-center !rounded-md"
|
|
||||||
v-model="formData.sms"
|
|
||||||
center
|
|
||||||
clearable
|
|
||||||
placeholder="请输入短信验证码"
|
|
||||||
:rules="getFormRules.sms"
|
|
||||||
>
|
|
||||||
<template #left-icon>
|
|
||||||
<Icon>
|
|
||||||
<EditOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
<template #button>
|
|
||||||
<van-button size="small" type="primary">发送验证码</van-button>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
class="enter-y items-center !rounded-md"
|
|
||||||
v-model="formData.password"
|
|
||||||
:type="switchPassType ? 'password' : 'text'"
|
|
||||||
name="password"
|
|
||||||
placeholder="密码"
|
|
||||||
:rules="getFormRules.password"
|
|
||||||
@click-right-icon="switchPassType = !switchPassType"
|
|
||||||
>
|
|
||||||
<template #left-icon>
|
|
||||||
<Icon>
|
|
||||||
<LockOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
<template #right-icon>
|
|
||||||
<Icon v-if="switchPassType">
|
|
||||||
<EyeInvisibleOutlined />
|
|
||||||
</Icon>
|
|
||||||
<Icon v-else>
|
|
||||||
<EyeOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
class="enter-y items-center !rounded-md"
|
|
||||||
v-model="formData.confirmPassword"
|
|
||||||
:type="switchConfirmPassType ? 'password' : 'text'"
|
|
||||||
name="confirmPassword"
|
|
||||||
placeholder="确认密码"
|
|
||||||
:rules="getFormRules.confirmPassword"
|
|
||||||
@click-right-icon="switchConfirmPassType = !switchConfirmPassType"
|
|
||||||
>
|
|
||||||
<template #left-icon>
|
|
||||||
<Icon>
|
|
||||||
<LockOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
<template #right-icon>
|
|
||||||
<Icon v-if="switchConfirmPassType">
|
|
||||||
<EyeInvisibleOutlined />
|
|
||||||
</Icon>
|
|
||||||
<Icon v-else>
|
|
||||||
<EyeOutlined />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
name="policy"
|
|
||||||
class="enter-y items-center px-1 !rounded-md"
|
|
||||||
:rules="getFormRules.policy"
|
|
||||||
>
|
|
||||||
<template #input>
|
|
||||||
<van-checkbox v-model="formData.policy" icon-size="14px" shape="square">
|
|
||||||
我同意 xxx 隐私政策
|
|
||||||
</van-checkbox>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
</van-cell-group>
|
|
||||||
|
|
||||||
<van-button
|
|
||||||
class="enter-y !mb-25px !rounded-md"
|
|
||||||
type="primary"
|
|
||||||
block
|
|
||||||
native-type="submit"
|
|
||||||
:loading="loading"
|
|
||||||
>
|
|
||||||
注 册
|
|
||||||
</van-button>
|
|
||||||
|
|
||||||
<van-button
|
|
||||||
class="enter-y !mb-150px !rounded-md"
|
|
||||||
plain
|
|
||||||
type="primary"
|
|
||||||
block
|
|
||||||
@click="handleBackLogin"
|
|
||||||
>
|
|
||||||
返 回
|
|
||||||
</van-button>
|
|
||||||
</van-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed, reactive, ref, unref } from 'vue'
|
|
||||||
import type { FormInstance } from 'vant'
|
|
||||||
import { Icon } from '@vicons/utils'
|
|
||||||
import {
|
|
||||||
UserOutlined,
|
|
||||||
MobileOutlined,
|
|
||||||
EditOutlined,
|
|
||||||
LockOutlined,
|
|
||||||
EyeOutlined,
|
|
||||||
EyeInvisibleOutlined,
|
|
||||||
} from '@vicons/antd'
|
|
||||||
import { LoginStateEnum, useLoginState, useFormRules } from './useLogin'
|
|
||||||
|
|
||||||
const { handleBackLogin, getLoginState } = useLoginState()
|
|
||||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.REGISTER)
|
|
||||||
|
|
||||||
const loading = ref(false)
|
|
||||||
const formRef = ref<FormInstance>()
|
|
||||||
|
|
||||||
const formData = reactive({
|
|
||||||
username: '',
|
|
||||||
mobile: '',
|
|
||||||
sms: '',
|
|
||||||
password: '',
|
|
||||||
confirmPassword: '',
|
|
||||||
policy: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
const { getFormRules } = useFormRules(formData)
|
|
||||||
|
|
||||||
const switchPassType = ref(true)
|
|
||||||
const switchConfirmPassType = ref(true)
|
|
||||||
|
|
||||||
function handleRegister() {
|
|
||||||
formRef.value
|
|
||||||
?.validate()
|
|
||||||
.then(async () => {
|
|
||||||
try {
|
|
||||||
loading.value = true
|
|
||||||
// do something
|
|
||||||
|
|
||||||
console.log('%c [ ]-167', 'font-size:13px; background:pink; color:#bf2c9f;')
|
|
||||||
} finally {
|
|
||||||
loading.value = false
|
|
||||||
|
|
||||||
console.log('%c [ ]-171', 'font-size:13px; background:pink; color:#bf2c9f;')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
console.error('验证失败')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less"></style>
|
|
@@ -1,97 +0,0 @@
|
|||||||
import type { FieldRule } from 'vant'
|
|
||||||
import { computed, ref, unref } from 'vue'
|
|
||||||
|
|
||||||
export enum LoginStateEnum {
|
|
||||||
LOGIN,
|
|
||||||
REGISTER,
|
|
||||||
RESET_PASSWORD,
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentState = ref(LoginStateEnum.LOGIN)
|
|
||||||
|
|
||||||
export function useLoginState() {
|
|
||||||
function setLoginState(state: LoginStateEnum) {
|
|
||||||
currentState.value = state
|
|
||||||
}
|
|
||||||
|
|
||||||
const getLoginState = computed(() => currentState.value)
|
|
||||||
|
|
||||||
function handleBackLogin() {
|
|
||||||
setLoginState(LoginStateEnum.LOGIN)
|
|
||||||
}
|
|
||||||
|
|
||||||
return { setLoginState, getLoginState, handleBackLogin }
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useFormRules(formData?: Recordable) {
|
|
||||||
const getUsernameFormRule = computed(() => createRule('请输入用户名'))
|
|
||||||
const getPasswordFormRule = computed(() => createRule('请输入密码'))
|
|
||||||
const getSmsFormRule = computed(() => createRule('请输入短信验证码'))
|
|
||||||
const getMobileFormRule = computed(() => createRule('请输入手机号码'))
|
|
||||||
|
|
||||||
const validatePolicy = async (value: any, _: FieldRule) => {
|
|
||||||
return !value ? Promise.resolve('勾选后才能注册') : Promise.resolve(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const validateConfirmPassword = (password: string) => {
|
|
||||||
return async (value: string) => {
|
|
||||||
if (!value) {
|
|
||||||
return Promise.resolve('请输入确认密码')
|
|
||||||
}
|
|
||||||
if (value !== password) {
|
|
||||||
return Promise.resolve('两次输入密码不一致')
|
|
||||||
}
|
|
||||||
return Promise.resolve(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const getFormRules = computed((): { [k: string]: FieldRule[] } => {
|
|
||||||
const usernameFormRule = unref(getUsernameFormRule)
|
|
||||||
const passwordFormRule = unref(getPasswordFormRule)
|
|
||||||
const smsFormRule = unref(getSmsFormRule)
|
|
||||||
const mobileFormRule = unref(getMobileFormRule)
|
|
||||||
|
|
||||||
const mobileRule = {
|
|
||||||
sms: smsFormRule,
|
|
||||||
mobile: mobileFormRule,
|
|
||||||
}
|
|
||||||
switch (unref(currentState)) {
|
|
||||||
// register form rules
|
|
||||||
case LoginStateEnum.REGISTER:
|
|
||||||
return {
|
|
||||||
username: usernameFormRule,
|
|
||||||
password: passwordFormRule,
|
|
||||||
confirmPassword: [
|
|
||||||
{ validator: validateConfirmPassword(formData?.password), trigger: 'onChange' },
|
|
||||||
],
|
|
||||||
policy: [{ validator: validatePolicy, trigger: 'onBlur' }],
|
|
||||||
...mobileRule,
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset password form rules
|
|
||||||
case LoginStateEnum.RESET_PASSWORD:
|
|
||||||
return {
|
|
||||||
username: usernameFormRule,
|
|
||||||
...mobileRule,
|
|
||||||
}
|
|
||||||
|
|
||||||
// login form rules
|
|
||||||
default:
|
|
||||||
return {
|
|
||||||
username: usernameFormRule,
|
|
||||||
password: passwordFormRule,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return { getFormRules }
|
|
||||||
}
|
|
||||||
|
|
||||||
function createRule(message: string): FieldRule[] {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message,
|
|
||||||
trigger: 'onBlur',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
@@ -1,55 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<van-field
|
|
||||||
label="用户名"
|
|
||||||
readonly
|
|
||||||
label-class="font-bold"
|
|
||||||
input-align="right"
|
|
||||||
:center="true"
|
|
||||||
:border="false"
|
|
||||||
v-model="username"
|
|
||||||
/>
|
|
||||||
<van-field
|
|
||||||
label="手机号"
|
|
||||||
readonly
|
|
||||||
is-link
|
|
||||||
label-class="font-bold"
|
|
||||||
input-align="right"
|
|
||||||
:center="true"
|
|
||||||
:border="false"
|
|
||||||
v-model="afterPhone"
|
|
||||||
/>
|
|
||||||
<van-field
|
|
||||||
label="修改登录密码"
|
|
||||||
readonly
|
|
||||||
label-class="font-bold"
|
|
||||||
input-align="right"
|
|
||||||
:center="true"
|
|
||||||
:border="false"
|
|
||||||
is-link
|
|
||||||
to="/changePassword"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import NavBar from './components/NavBar.vue'
|
|
||||||
import { useUserStore } from '@/store/modules/user'
|
|
||||||
import { computed } from 'vue'
|
|
||||||
|
|
||||||
const userStore = useUserStore()
|
|
||||||
const { username, phone } = userStore.getUserInfo
|
|
||||||
|
|
||||||
const phoneDesensitize = (phone: string) => {
|
|
||||||
const reg = /(\d{3})\d{4}(\d{4})/
|
|
||||||
return phone.replace(reg, '$1****$2')
|
|
||||||
}
|
|
||||||
|
|
||||||
const afterPhone = computed(() => phoneDesensitize(phone))
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
:deep(.van-field__control) {
|
|
||||||
color: var(--van-text-color-2);
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,9 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div> 修改登录密码页面 </div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import NavBar from './components/NavBar.vue'
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
@@ -1,87 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<NavBar>
|
|
||||||
<template #right><span class="text-32px" @click="handleNickname">保存</span></template>
|
|
||||||
</NavBar>
|
|
||||||
<van-form ref="formRef">
|
|
||||||
<van-field
|
|
||||||
class="mt-20px"
|
|
||||||
name="nickname"
|
|
||||||
v-model="formValue.nickname"
|
|
||||||
placeholder="请输入昵称(2-12字)"
|
|
||||||
:rules="[
|
|
||||||
{
|
|
||||||
validator: validateNickname(),
|
|
||||||
trigger: 'onChange',
|
|
||||||
},
|
|
||||||
]"
|
|
||||||
/>
|
|
||||||
</van-form>
|
|
||||||
|
|
||||||
<div class="note px-30px">
|
|
||||||
<p>昵称支持2-12个中文字符或3-24个英文字符,</p>
|
|
||||||
<p>符号仅支持”-“和”_“和”.“以及“·”</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import NavBar from './components/NavBar.vue'
|
|
||||||
import { useUserStore } from '@/store/modules/user'
|
|
||||||
import { onMounted, reactive, ref } from 'vue'
|
|
||||||
import type { FormInstance } from 'vant'
|
|
||||||
import { showToast } from 'vant'
|
|
||||||
|
|
||||||
const userStore = useUserStore()
|
|
||||||
|
|
||||||
const { nickname } = userStore.getUserInfo
|
|
||||||
const formRef = ref<FormInstance>()
|
|
||||||
|
|
||||||
const formValue = reactive({
|
|
||||||
nickname: '',
|
|
||||||
})
|
|
||||||
|
|
||||||
const validateNickname = () => {
|
|
||||||
return async (value: string) => {
|
|
||||||
const pattern = /^[\u4E00-\u9FA5A-Za-z0-9-_.·]+$/
|
|
||||||
if (!pattern.test(value)) {
|
|
||||||
return Promise.resolve('请输入正确内容')
|
|
||||||
}
|
|
||||||
if (value.length < 2 || value.length > 12) {
|
|
||||||
return Promise.resolve('长度不符合')
|
|
||||||
}
|
|
||||||
return Promise.resolve(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleNickname() {
|
|
||||||
formRef.value
|
|
||||||
?.validate()
|
|
||||||
.then(async () => {
|
|
||||||
try {
|
|
||||||
const formValue = formRef.value?.getValues()
|
|
||||||
showToast({
|
|
||||||
message: `当前表单值:${JSON.stringify(formValue)}`,
|
|
||||||
})
|
|
||||||
// do something
|
|
||||||
} finally {
|
|
||||||
// after successful
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
console.error('验证失败')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
formValue.nickname = nickname
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.note {
|
|
||||||
margin-top: 15px;
|
|
||||||
font-size: 25px;
|
|
||||||
color: var(--van-text-color-2);
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,70 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<NavBar>
|
|
||||||
<template #right><span class="text-32px" @click="handleNickname">保存</span></template>
|
|
||||||
</NavBar>
|
|
||||||
<van-form ref="formRef">
|
|
||||||
<van-field
|
|
||||||
class="mt-20px"
|
|
||||||
name="sign"
|
|
||||||
clearable
|
|
||||||
v-model="formValue.sign"
|
|
||||||
rows="4"
|
|
||||||
autosize
|
|
||||||
label="签名"
|
|
||||||
type="textarea"
|
|
||||||
maxlength="70"
|
|
||||||
placeholder="介绍一下你自己"
|
|
||||||
show-word-limit
|
|
||||||
/>
|
|
||||||
</van-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import NavBar from './components/NavBar.vue'
|
|
||||||
import { useUserStore } from '@/store/modules/user'
|
|
||||||
import { onMounted, reactive, ref } from 'vue'
|
|
||||||
import type { FormInstance } from 'vant'
|
|
||||||
import { showToast } from 'vant'
|
|
||||||
|
|
||||||
const userStore = useUserStore()
|
|
||||||
|
|
||||||
const { sign } = userStore.getUserInfo
|
|
||||||
const formRef = ref<FormInstance>()
|
|
||||||
|
|
||||||
const formValue = reactive({
|
|
||||||
sign: '',
|
|
||||||
})
|
|
||||||
|
|
||||||
function handleNickname() {
|
|
||||||
formRef.value
|
|
||||||
?.validate()
|
|
||||||
.then(async () => {
|
|
||||||
try {
|
|
||||||
const formValue = formRef.value?.getValues()
|
|
||||||
showToast({
|
|
||||||
message: `当前表单值:${JSON.stringify(formValue)}`,
|
|
||||||
})
|
|
||||||
// do something
|
|
||||||
} finally {
|
|
||||||
// after successful
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
console.error('验证失败')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
formValue.sign = sign ?? ''
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.note {
|
|
||||||
margin-top: 15px;
|
|
||||||
font-size: 25px;
|
|
||||||
color: var(--van-text-color-2);
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,179 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<van-field
|
|
||||||
label="头像"
|
|
||||||
label-class="font-bold"
|
|
||||||
input-align="right"
|
|
||||||
:center="true"
|
|
||||||
:border="false"
|
|
||||||
is-link
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
<template #input>
|
|
||||||
<UploaderImage>
|
|
||||||
<van-image class="avatar" round fit="cover" :src="avatar" />
|
|
||||||
</UploaderImage>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
label="昵称"
|
|
||||||
readonly
|
|
||||||
label-class="font-bold"
|
|
||||||
input-align="right"
|
|
||||||
:center="true"
|
|
||||||
:border="false"
|
|
||||||
v-model="state.nickname"
|
|
||||||
is-link
|
|
||||||
to="/editNickname"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
label="性别"
|
|
||||||
readonly
|
|
||||||
label-class="font-bold"
|
|
||||||
input-align="right"
|
|
||||||
:center="true"
|
|
||||||
:border="false"
|
|
||||||
v-model="state.genderText"
|
|
||||||
is-link
|
|
||||||
@click="showGenderPicker = true"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
label="签名"
|
|
||||||
readonly
|
|
||||||
label-class="font-bold"
|
|
||||||
input-align="right"
|
|
||||||
:center="true"
|
|
||||||
:border="false"
|
|
||||||
v-model="state.sign"
|
|
||||||
is-link
|
|
||||||
to="/editSign"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
label="主页封面"
|
|
||||||
label-class="font-bold"
|
|
||||||
input-align="right"
|
|
||||||
:center="true"
|
|
||||||
:border="false"
|
|
||||||
is-link
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
<template #input>
|
|
||||||
<UploaderImage>
|
|
||||||
<van-image class="cover" fit="cover" :src="cover ? cover : avatar" />
|
|
||||||
</UploaderImage>
|
|
||||||
</template>
|
|
||||||
</van-field>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
label="行业"
|
|
||||||
readonly
|
|
||||||
label-class="font-bold"
|
|
||||||
input-align="right"
|
|
||||||
:center="true"
|
|
||||||
:border="false"
|
|
||||||
v-model="state.industryText"
|
|
||||||
is-link
|
|
||||||
@click="showIndustryPicker = true"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<van-popup v-model:show="showGenderPicker" position="bottom" round>
|
|
||||||
<van-picker
|
|
||||||
visible-option-num="3"
|
|
||||||
v-model="state.genderValues"
|
|
||||||
:columns="genderColumns"
|
|
||||||
@confirm="handleGender"
|
|
||||||
@cancel="showGenderPicker = false"
|
|
||||||
/>
|
|
||||||
</van-popup>
|
|
||||||
|
|
||||||
<van-popup v-model:show="showIndustryPicker" position="bottom" round>
|
|
||||||
<van-picker
|
|
||||||
v-model="state.industryValues"
|
|
||||||
:columns="industryColumns"
|
|
||||||
@confirm="handleIndustry"
|
|
||||||
@cancel="showIndustryPicker = false"
|
|
||||||
/>
|
|
||||||
</van-popup>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { onMounted, reactive, ref } from 'vue'
|
|
||||||
import NavBar from './components/NavBar.vue'
|
|
||||||
import UploaderImage from './components/UploaderImage.vue'
|
|
||||||
import { useUserStore } from '@/store/modules/user'
|
|
||||||
import { FormColumns, genderColumns, industryColumns } from './pickColumns'
|
|
||||||
import { showToast } from 'vant'
|
|
||||||
|
|
||||||
const userStore = useUserStore()
|
|
||||||
const { avatar, gender, industry, cover } = userStore.getUserInfo
|
|
||||||
|
|
||||||
const showGenderPicker = ref(false)
|
|
||||||
const showIndustryPicker = ref(false)
|
|
||||||
|
|
||||||
const state = reactive({
|
|
||||||
nickname: '',
|
|
||||||
sign: '',
|
|
||||||
// the field v-model
|
|
||||||
genderText: '',
|
|
||||||
industryText: '',
|
|
||||||
// the pick v-model
|
|
||||||
industryValues: [0],
|
|
||||||
genderValues: [0],
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleGender = ({ selectedOptions }) => {
|
|
||||||
state.genderText = selectedOptions[0].text
|
|
||||||
showToast(JSON.stringify(selectedOptions))
|
|
||||||
// do something
|
|
||||||
showGenderPicker.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleIndustry = ({ selectedOptions }) => {
|
|
||||||
state.industryText = selectedOptions[0].text
|
|
||||||
showToast(JSON.stringify(selectedOptions))
|
|
||||||
// do something
|
|
||||||
showIndustryPicker.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
const getFromText = (columns: FormColumns[], value = 0) =>
|
|
||||||
columns.find((item) => item.value === value)?.text
|
|
||||||
|
|
||||||
function initState() {
|
|
||||||
Object.keys(state).forEach((key) => {
|
|
||||||
state[key] = userStore.getUserInfo[key]
|
|
||||||
})
|
|
||||||
// set field text value.
|
|
||||||
state.genderText = getFromText(genderColumns, gender) ?? ''
|
|
||||||
state.industryText = getFromText(industryColumns, industry) ?? ''
|
|
||||||
// set the pick selected value.
|
|
||||||
state.industryValues = [industry ?? 0]
|
|
||||||
state.genderValues = [gender]
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
initState()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.avatar {
|
|
||||||
width: 140px;
|
|
||||||
height: 140px;
|
|
||||||
}
|
|
||||||
.cover {
|
|
||||||
width: 170px;
|
|
||||||
height: 100px;
|
|
||||||
:deep(.van-image__img) {
|
|
||||||
border-radius: 10px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.van-field__control) {
|
|
||||||
color: var(--van-text-color-2);
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,105 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<van-cell center title="暗黑模式">
|
|
||||||
<template #right-icon>
|
|
||||||
<van-switch v-model="getDarkMode" />
|
|
||||||
</template>
|
|
||||||
</van-cell>
|
|
||||||
|
|
||||||
<van-divider>系统主题色</van-divider>
|
|
||||||
<div flex="~" justify="center">
|
|
||||||
<div grid="~ cols-8 gap-2">
|
|
||||||
<span
|
|
||||||
h="70px"
|
|
||||||
w="70px"
|
|
||||||
border="2 rounded-md border-white"
|
|
||||||
flex="~"
|
|
||||||
align="items-center"
|
|
||||||
justify="center"
|
|
||||||
v-for="(item, index) in designStore.appThemeList"
|
|
||||||
:key="index"
|
|
||||||
:style="{ 'background-color': item }"
|
|
||||||
@click="togTheme(item)"
|
|
||||||
>
|
|
||||||
<Icon v-if="item === designStore.appTheme">
|
|
||||||
<CheckOutlined h="!60px" w="!60px" text="white" />
|
|
||||||
</Icon>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<van-divider>页面切换动画</van-divider>
|
|
||||||
<van-cell center title="开启动画">
|
|
||||||
<template #right-icon>
|
|
||||||
<van-switch v-model="designStore.isPageAnimate" />
|
|
||||||
</template>
|
|
||||||
</van-cell>
|
|
||||||
|
|
||||||
<van-field
|
|
||||||
label="动画类型"
|
|
||||||
readonly
|
|
||||||
:disabled="!designStore.isPageAnimate"
|
|
||||||
is-link
|
|
||||||
label-class="font-bold"
|
|
||||||
input-align="right"
|
|
||||||
:center="true"
|
|
||||||
:border="false"
|
|
||||||
v-model="animateState.text"
|
|
||||||
@click="openAnimatePick"
|
|
||||||
/>
|
|
||||||
<van-popup v-model:show="animateState.showPicker" position="bottom" round>
|
|
||||||
<van-picker
|
|
||||||
v-model="animateState.value"
|
|
||||||
:columns="animateOptions"
|
|
||||||
@confirm="handleSaveAnimateType"
|
|
||||||
@cancel="animateState.showPicker = false"
|
|
||||||
/>
|
|
||||||
</van-popup>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed, reactive } from 'vue'
|
|
||||||
import { Icon } from '@vicons/utils'
|
|
||||||
import { updateDarkSign } from '@/theme'
|
|
||||||
import { CheckOutlined } from '@vicons/antd'
|
|
||||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
|
||||||
import { animates as animateOptions } from '@/settings/animateSetting'
|
|
||||||
import NavBar from './components/NavBar.vue'
|
|
||||||
|
|
||||||
const designStore = useDesignSettingStore()
|
|
||||||
const getDarkMode = computed({
|
|
||||||
get: () => designStore.getDarkMode === 'dark',
|
|
||||||
set: (value) => {
|
|
||||||
const darkMode = value ? 'dark' : 'light'
|
|
||||||
updateDarkSign(darkMode)
|
|
||||||
designStore.setDarkMode(darkMode)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
function togTheme(color: string) {
|
|
||||||
designStore.appTheme = color
|
|
||||||
}
|
|
||||||
|
|
||||||
const findCurrentAnimateType = animateOptions.find(
|
|
||||||
(item) => item.value === designStore.pageAnimateType,
|
|
||||||
)
|
|
||||||
|
|
||||||
const animateState = reactive({
|
|
||||||
text: findCurrentAnimateType?.text,
|
|
||||||
value: [designStore.pageAnimateType],
|
|
||||||
showPicker: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
const openAnimatePick = () => {
|
|
||||||
if (designStore.isPageAnimate) animateState.showPicker = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSaveAnimateType = ({ selectedOptions }) => {
|
|
||||||
animateState.text = selectedOptions[0].text
|
|
||||||
designStore.setPageAnimateType(selectedOptions[0].value)
|
|
||||||
animateState.showPicker = false
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less"></style>
|
|
@@ -1,29 +0,0 @@
|
|||||||
<template>
|
|
||||||
<van-nav-bar @click-left="router.back">
|
|
||||||
<template #title>
|
|
||||||
{{ getTitle }}
|
|
||||||
</template>
|
|
||||||
<template #left>
|
|
||||||
<Icon>
|
|
||||||
<ChevronBack />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
<template #right>
|
|
||||||
<slot name="right"></slot>
|
|
||||||
</template>
|
|
||||||
</van-nav-bar>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { Icon } from '@vicons/utils'
|
|
||||||
import { ChevronBack } from '@vicons/ionicons5'
|
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
|
||||||
import { computed } from 'vue'
|
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
const currentRoute = useRoute()
|
|
||||||
|
|
||||||
const getTitle = computed(() => currentRoute.meta.title as string)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less"></style>
|
|
@@ -1,32 +0,0 @@
|
|||||||
<template>
|
|
||||||
<van-uploader
|
|
||||||
:max-size="700 * 1024"
|
|
||||||
:max-count="1"
|
|
||||||
:before-read="beforeRead"
|
|
||||||
:after-read="afterRead"
|
|
||||||
accept="image/*"
|
|
||||||
>
|
|
||||||
<template #default>
|
|
||||||
<slot name="default"></slot>
|
|
||||||
</template>
|
|
||||||
</van-uploader>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { showFailToast } from 'vant'
|
|
||||||
|
|
||||||
function beforeRead(file) {
|
|
||||||
if (file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg') {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
showFailToast('请上传正确格式的图片')
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
function afterRead(file) {
|
|
||||||
console.log('%c [ file ]-43', 'font-size:13px; background:pink; color:#bf2c9f;', file)
|
|
||||||
// 这里写上传逻辑
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less"></style>
|
|
@@ -1,123 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div :style="getUserCoverBg" class="my-bg h-550px -z-19"> </div>
|
|
||||||
<div
|
|
||||||
class="my-card shadow-xl relative -top-150px mx-40px rounded-2xl flex flex-col items-center pb-20px"
|
|
||||||
>
|
|
||||||
<van-image
|
|
||||||
class="border-4 !absolute -top-90px h-170px w-170px"
|
|
||||||
round
|
|
||||||
fit="cover"
|
|
||||||
:src="avatar"
|
|
||||||
/>
|
|
||||||
<div class="flex flex-col items-center mt-90px">
|
|
||||||
<p class="font-black text-40px mb-20px">{{ nickname }}</p>
|
|
||||||
<p class="text-30px px-36px">{{ sign }}</p>
|
|
||||||
</div>
|
|
||||||
<van-divider class="w-full" />
|
|
||||||
|
|
||||||
<!-- <van-cell :border="false" title="个人信息" is-link to="/editUserInfo">-->
|
|
||||||
<!-- <template #icon>-->
|
|
||||||
<!-- <Icon>-->
|
|
||||||
<!-- <IdcardFilled />-->
|
|
||||||
<!-- </Icon>-->
|
|
||||||
<!-- </template>-->
|
|
||||||
<!-- </van-cell>-->
|
|
||||||
|
|
||||||
<!-- <van-cell :border="false" title="账号与安全" is-link to="/accountSetting">-->
|
|
||||||
<!-- <template #icon>-->
|
|
||||||
<!-- <Icon>-->
|
|
||||||
<!-- <Person />-->
|
|
||||||
<!-- </Icon>-->
|
|
||||||
<!-- </template>-->
|
|
||||||
<!-- </van-cell>-->
|
|
||||||
|
|
||||||
<van-cell :border="false" title="主题设置" is-link to="/themeSetting">
|
|
||||||
<template #icon>
|
|
||||||
<Icon>
|
|
||||||
<ColorPalette />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
</van-cell>
|
|
||||||
|
|
||||||
<!-- <van-cell :border="false" title="隐私政策" is-link>-->
|
|
||||||
<!-- <template #icon>-->
|
|
||||||
<!-- <Icon>-->
|
|
||||||
<!-- <DocumentText />-->
|
|
||||||
<!-- </Icon>-->
|
|
||||||
<!-- </template>-->
|
|
||||||
<!-- </van-cell>-->
|
|
||||||
|
|
||||||
<van-cell :border="false" title="退出登录" is-link @click="showLogoutAction = true">
|
|
||||||
<template #icon>
|
|
||||||
<Icon>
|
|
||||||
<LogOut />
|
|
||||||
</Icon>
|
|
||||||
</template>
|
|
||||||
</van-cell>
|
|
||||||
|
|
||||||
<van-action-sheet
|
|
||||||
teleport="body"
|
|
||||||
v-model:show="showLogoutAction"
|
|
||||||
:actions="logoutActions"
|
|
||||||
cancel-text="取消"
|
|
||||||
description="确认退出登录吗"
|
|
||||||
close-on-click-action
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { computed, onMounted, ref } from 'vue'
|
|
||||||
import { Icon } from '@vicons/utils'
|
|
||||||
import { IdcardFilled } from '@vicons/antd'
|
|
||||||
import { Person, ColorPalette, DocumentText, LogOut } from '@vicons/ionicons5'
|
|
||||||
import { useUserStore } from '@/store/modules/user'
|
|
||||||
import { showToast } from 'vant'
|
|
||||||
|
|
||||||
const userStore = useUserStore()
|
|
||||||
const showLogoutAction = ref(false)
|
|
||||||
|
|
||||||
const { nickname, avatar, cover, sign } = userStore.getUserInfo
|
|
||||||
|
|
||||||
const logoutActions = [
|
|
||||||
{
|
|
||||||
name: '退出登录',
|
|
||||||
color: '#ee0a24',
|
|
||||||
callback: () => {
|
|
||||||
userStore.Logout()
|
|
||||||
showToast('退出成功')
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
const getUserCoverBg = computed(() => {
|
|
||||||
return { backgroundImage: `url(${cover ? cover : avatar})` }
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.my-bg {
|
|
||||||
clip-path: inset(0 -55% 0 -55% round 0 0 100% 100%);
|
|
||||||
background-size: cover;
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-image: linear-gradient(180deg, rgba(0, 0, 0, 0), #000);
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.van-cell {
|
|
||||||
align-items: center;
|
|
||||||
background: transparent;
|
|
||||||
&:active {
|
|
||||||
background-color: var(--van-cell-active-color);
|
|
||||||
}
|
|
||||||
.xicon {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,30 +0,0 @@
|
|||||||
export interface FormColumns {
|
|
||||||
text: string
|
|
||||||
value: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export const genderColumns: FormColumns[] = [
|
|
||||||
{ text: '男', value: 0 },
|
|
||||||
{ text: '女', value: 1 },
|
|
||||||
]
|
|
||||||
|
|
||||||
export const industryColumns: FormColumns[] = [
|
|
||||||
{ text: '不展示', value: 0 },
|
|
||||||
{ text: '学生', value: 1 },
|
|
||||||
{ text: '自由职业', value: 2 },
|
|
||||||
{ text: 'IT/互联网/通信', value: 3 },
|
|
||||||
{ text: '金融', value: 4 },
|
|
||||||
{ text: '健康/医疗', value: 5 },
|
|
||||||
{ text: '工业/制造业', value: 6 },
|
|
||||||
{ text: '零售', value: 7 },
|
|
||||||
{ text: '贸易', value: 8 },
|
|
||||||
{ text: '教育/科研', value: 9 },
|
|
||||||
{ text: '培训', value: 10 },
|
|
||||||
{ text: '房地产/建筑', value: 11 },
|
|
||||||
{ text: '文化/艺术', value: 12 },
|
|
||||||
{ text: '影视/娱乐', value: 13 },
|
|
||||||
{ text: '法律/会计/咨询', value: 14 },
|
|
||||||
{ text: '媒体/广告/公关', value: 15 },
|
|
||||||
{ text: '体育/健身', value: 16 },
|
|
||||||
{ text: '企事业单位', value: 17 },
|
|
||||||
]
|
|
@@ -1,106 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="flex flex-col items-center justify-center h-screen p-8">
|
|
||||||
<!-- <van-cell center title="🌗 暗黑模式">
|
|
||||||
<template #right-icon>
|
|
||||||
<van-switch v-model="getDarkMode" size="18px" />
|
|
||||||
</template>
|
|
||||||
</van-cell> -->
|
|
||||||
<div class="wel-box flex flex-col justify-between w-full">
|
|
||||||
<div class="wel-top">
|
|
||||||
<div class="logo enter-y">
|
|
||||||
<SvgIcon :size="130" name="logo" />
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="text-darkBlue dark:text-garyWhite text-2xl font-black mt-12 mb-4 text-center enter-y"
|
|
||||||
>欢迎来到 {{ title }}</div
|
|
||||||
>
|
|
||||||
<div class="w-full mt-4 mb-6 enter-y">
|
|
||||||
<van-swipe class="h-30" :autoplay="3000" :indicator-color="designStore.appTheme">
|
|
||||||
<van-swipe-item
|
|
||||||
class="text-gray-700 dark:text-gray-400 leading-relaxed text-center"
|
|
||||||
v-for="(text, index) in getSwipeText"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<p class="text-lg">{{ text.title }}</p>
|
|
||||||
<p class="text-sm">{{ text.details }}</p>
|
|
||||||
</van-swipe-item>
|
|
||||||
</van-swipe>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="wel-bottom">
|
|
||||||
<van-button
|
|
||||||
class="enter-y !rounded-md"
|
|
||||||
type="primary"
|
|
||||||
block
|
|
||||||
@click="router.push({ name: 'Login' })"
|
|
||||||
>Let's Get Started</van-button
|
|
||||||
>
|
|
||||||
<a class="enter-y text-sm mt-6">创建账户?</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed } from 'vue'
|
|
||||||
import { useDesignSettingStore } from '@/store/modules/designSetting'
|
|
||||||
import SvgIcon from '@/components/SvgIcon.vue'
|
|
||||||
import { useGlobSetting } from '@/hooks/setting'
|
|
||||||
import { useRouter } from 'vue-router'
|
|
||||||
|
|
||||||
import { updateDarkSign } from '@/theme'
|
|
||||||
|
|
||||||
const getDarkMode = computed({
|
|
||||||
get: () => designStore.getDarkMode === 'dark',
|
|
||||||
set: (value) => {
|
|
||||||
const darkMode = value ? 'dark' : 'light'
|
|
||||||
updateDarkSign(darkMode)
|
|
||||||
designStore.setDarkMode(darkMode)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const designStore = useDesignSettingStore()
|
|
||||||
const globSetting = useGlobSetting()
|
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
const { title } = globSetting
|
|
||||||
|
|
||||||
const getSwipeText = computed(() => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
title: '💡 最新技术栈',
|
|
||||||
details: '基于Vue3、Vant4、Vite、TypeScript等最新技术栈开发',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '⚡️ 轻量快速的热重载',
|
|
||||||
details: '无论应用程序大小如何,都始终极快的模块热重载(HMR)',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '🔩 主题配置',
|
|
||||||
details: '具备主题配置及黑暗主题适配,且持久化保存',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '🛠️ 丰富的 Vite 插件',
|
|
||||||
details: '集成大部分 Vite 插件,无需繁琐配置,开箱即用',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.wel-box {
|
|
||||||
min-height: 50vh;
|
|
||||||
max-width: 45vh;
|
|
||||||
min-width: 30vh;
|
|
||||||
.wel-top {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.wel-bottom {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
Reference in New Issue
Block a user