Compare commits
No commits in common. "5b2d55897b7b8a6c6890825b2a5da7988b633aea" and "5a563b86251275359ae8ad76524bb2040253b234" have entirely different histories.
5b2d55897b
...
5a563b8625
|
@ -5,9 +5,7 @@ VITE_DROP_CONSOLE=false
|
||||||
|
|
||||||
# axios
|
# axios
|
||||||
VITE_APP_BASE_API=/api
|
VITE_APP_BASE_API=/api
|
||||||
# VITE_APP_PROXY_URL=http://localhost:8765
|
VITE_APP_PROXY_URL=http://localhost:8765
|
||||||
VITE_APP_PROXY_URL=http://172.10.10.151:8765
|
|
||||||
|
|
||||||
|
|
||||||
# rsa 公钥
|
# rsa 公钥
|
||||||
VITE_APP_RSA_PUBLIC_KEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJps/EXxxSpEM1Ix4R0NWIOBciHCr7P7coDT8tNKfelgR7txcJOqHCO/MIWe7T04aHQTcpQxqx9hMca7dbqz8TZpz9jvLzE/6ZonVKxHsoFnNlHMp1/CPAJ9f6D9wYicum2KltJkmQ0g//D9W2zPCYoGOmSRFcZx/KEBa4EM53jQIDAQAB
|
VITE_APP_RSA_PUBLIC_KEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJps/EXxxSpEM1Ix4R0NWIOBciHCr7P7coDT8tNKfelgR7txcJOqHCO/MIWe7T04aHQTcpQxqx9hMca7dbqz8TZpz9jvLzE/6ZonVKxHsoFnNlHMp1/CPAJ9f6D9wYicum2KltJkmQ0g//D9W2zPCYoGOmSRFcZx/KEBa4EM53jQIDAQAB
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
/* eslint-disable */
|
|
||||||
// @ts-nocheck
|
|
||||||
// Generated by unplugin-vue-components
|
|
||||||
// Read more: https://github.com/vuejs/core/pull/3399
|
|
||||||
export {}
|
|
||||||
|
|
||||||
/* prettier-ignore */
|
|
||||||
declare module 'vue' {
|
|
||||||
export interface GlobalComponents {
|
|
||||||
AAvatar: typeof import('ant-design-vue/es')['Avatar']
|
|
||||||
AButton: typeof import('ant-design-vue/es')['Button']
|
|
||||||
ACascader: typeof import('ant-design-vue/es')['Cascader']
|
|
||||||
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
|
||||||
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
|
|
||||||
ADivider: typeof import('ant-design-vue/es')['Divider']
|
|
||||||
ADrawer: typeof import('ant-design-vue/es')['Drawer']
|
|
||||||
AForm: typeof import('ant-design-vue/es')['Form']
|
|
||||||
AFormItem: typeof import('ant-design-vue/es')['FormItem']
|
|
||||||
AInput: typeof import('ant-design-vue/es')['Input']
|
|
||||||
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
|
|
||||||
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
|
|
||||||
ALayout: typeof import('ant-design-vue/es')['Layout']
|
|
||||||
ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent']
|
|
||||||
ALayoutHeader: typeof import('ant-design-vue/es')['LayoutHeader']
|
|
||||||
ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider']
|
|
||||||
AMenu: typeof import('ant-design-vue/es')['Menu']
|
|
||||||
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
|
|
||||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
|
||||||
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
|
|
||||||
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
|
||||||
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
|
||||||
HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
|
|
||||||
Layout: typeof import('./src/components/layout/layout.vue')['default']
|
|
||||||
LayoutHeader: typeof import('./src/components/layout/header/LayoutHeader.vue')['default']
|
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
|
||||||
Sliber: typeof import('./src/components/layout/sliber/sliber.vue')['default']
|
|
||||||
TelephoneLogin: typeof import('./src/components/login/TelephoneLogin.vue')['default']
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,41 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
defineProps<{ msg: string }>()
|
||||||
|
|
||||||
|
const count = ref(0)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<button type="button" @click="count++">count is {{ count }}</button>
|
||||||
|
<p>
|
||||||
|
Edit
|
||||||
|
<code>components/HelloWorld.vue</code> to test HMR
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Check out
|
||||||
|
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
||||||
|
>create-vue</a
|
||||||
|
>, the official Vue + Vite starter
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Learn more about IDE Support for Vue in the
|
||||||
|
<a
|
||||||
|
href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
|
||||||
|
target="_blank"
|
||||||
|
>Vue Docs Scaling up Guide</a
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.read-the-docs {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,7 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex-justify-between h-f">
|
<div class="flex-justify-between h-f">
|
||||||
<div class="flex-center">
|
<div class="flex-center">
|
||||||
<menu-unfold-outlined v-if="collapsed" class="trigger" @click="() => (collapsed = !collapsed)" />
|
<menu-unfold-outlined
|
||||||
|
v-if="collapsed"
|
||||||
|
class="trigger"
|
||||||
|
@click="() => (collapsed = !collapsed)"
|
||||||
|
/>
|
||||||
<menu-fold-outlined v-else class="trigger" @click="() => (collapsed = !collapsed)"/>
|
<menu-fold-outlined v-else class="trigger" @click="() => (collapsed = !collapsed)"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="margin-right flex-center">
|
<div class="margin-right flex-center">
|
||||||
|
@ -11,8 +15,8 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { staticRouter } from '@/router/staticRouters'
|
import {MenuFoldOutlined, MenuUnfoldOutlined} from "@ant-design/icons-vue";
|
||||||
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons-vue'
|
|
||||||
|
|
||||||
const collapsed = defineModel<boolean>('collapsed')
|
const collapsed = defineModel<boolean>('collapsed')
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,33 +1,27 @@
|
||||||
<template>
|
<template>
|
||||||
<a-layout class="main-content">
|
<a-layout class="main-content">
|
||||||
<a-layout-sider :collapsed="collapsed" theme="light" :trigger="null" collapsible>
|
<a-layout-sider
|
||||||
|
:collapsed="collapsed"
|
||||||
|
theme="light"
|
||||||
|
:trigger="null"
|
||||||
|
collapsible
|
||||||
|
>
|
||||||
<div v-if="!collapsed" class="title flex-center">
|
<div v-if="!collapsed" class="title flex-center">
|
||||||
<div>超级后台</div>
|
<div>超级后台</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="logo flex-center">
|
<div v-else class="logo flex-center">
|
||||||
<img src="@/assets/vue.svg" title="超级后台" alt="xx" />
|
<img src="@/assets/vue.svg" title="超级后台" alt="xx">
|
||||||
</div>
|
</div>
|
||||||
<!-- -->
|
|
||||||
<a-menu v-model:selectedKeys="selectedKeys" theme="light" mode="inline">
|
|
||||||
<a-menu-item key="1">
|
|
||||||
<router-link to="/index">
|
|
||||||
<pie-chart-outlined />
|
|
||||||
<span>首页</span>
|
|
||||||
</router-link>
|
|
||||||
</a-menu-item>
|
|
||||||
<a-menu-item key="2">
|
|
||||||
<router-link to="/register/index">
|
|
||||||
<pie-chart-outlined />
|
|
||||||
<span>注册</span>
|
|
||||||
</router-link>
|
|
||||||
</a-menu-item>
|
|
||||||
</a-menu>
|
|
||||||
</a-layout-sider>
|
</a-layout-sider>
|
||||||
<a-layout>
|
<a-layout>
|
||||||
<a-layout-header class="layout-header">
|
<a-layout-header
|
||||||
|
class="layout-header"
|
||||||
|
>
|
||||||
<layout-header v-model:collapsed="collapsed"/>
|
<layout-header v-model:collapsed="collapsed"/>
|
||||||
</a-layout-header>
|
</a-layout-header>
|
||||||
<a-layout-content class="layout-content">
|
<a-layout-content
|
||||||
|
class="layout-content"
|
||||||
|
>
|
||||||
<router-view v-slot="{ Component, route }">
|
<router-view v-slot="{ Component, route }">
|
||||||
<transition appear name="fade-transform" mode="out-in">
|
<transition appear name="fade-transform" mode="out-in">
|
||||||
<keep-alive :include="keepAliveNames">
|
<keep-alive :include="keepAliveNames">
|
||||||
|
@ -41,30 +35,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import LayoutHeader from '@/components/layout/header/LayoutHeader.vue'
|
import {ref} from "vue";
|
||||||
import { computed } from 'vue'
|
import LayoutHeader from "@/components/layout/header/LayoutHeader.vue";
|
||||||
// import Sliber from '@/components/layout/sliber/sliber.vue'
|
|
||||||
import { staticRouter } from '@/router/staticRouters'
|
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
const route = useRoute()
|
|
||||||
|
|
||||||
// 控制菜单折叠
|
const collapsed = ref<boolean>(false);
|
||||||
// const collapsed = ref(false)
|
|
||||||
|
|
||||||
// 当前选中的菜单项
|
|
||||||
// const selectedKeys = computed(() => route.path)
|
|
||||||
const selectedKeys = computed(() => [route.path])
|
|
||||||
// 过滤出需要在菜单中显示的路由
|
|
||||||
const menuRoutes = computed(() => staticRouter.filter((route) => route.meta && route.meta.title))
|
|
||||||
|
|
||||||
// 示例:动态控制缓存页面的名称
|
|
||||||
// const keepAliveNames = ref(['index'])
|
|
||||||
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
const collapsed = ref<boolean>(false)
|
|
||||||
|
|
||||||
const keepAliveNames = ref<string[]>([])
|
const keepAliveNames = ref<string[]>([])
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
@ -94,7 +72,7 @@ const keepAliveNames = ref<string[]>([])
|
||||||
margin: 16px;
|
margin: 16px;
|
||||||
color: black;
|
color: black;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 20px;
|
font-size: 20px
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
|
@ -102,7 +80,7 @@ const keepAliveNames = ref<string[]>([])
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,53 @@
|
||||||
<template>
|
<template>
|
||||||
<a-form ref="formRef" :model="loginParams" :rules="loginParamsRule" @finish="login" layout="vertical" size="large" class="login-form">
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="loginParams"
|
||||||
|
:rules="loginParamsRule"
|
||||||
|
@finish="login"
|
||||||
|
layout="vertical"
|
||||||
|
size="large"
|
||||||
|
class="login-form"
|
||||||
|
>
|
||||||
<a-form-item name="telephone">
|
<a-form-item name="telephone">
|
||||||
<a-input v-model:value="loginParams.telephone" placeholder="请输入账号/手机号" :max-length="64" allow-clear />
|
<a-input
|
||||||
|
v-model:value="loginParams.telephone"
|
||||||
|
placeholder="请输入账号/手机号"
|
||||||
|
:max-length="64"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item name="password">
|
<a-form-item name="password">
|
||||||
<a-input-password v-model:value="loginParams.password" placeholder="请输入密码" :max-length="32" />
|
<a-input-password
|
||||||
|
v-model:value="loginParams.password"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
:max-length="32"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<div class="remember-me">
|
<div class="remember-me">
|
||||||
<a-checkbox disabled> 记住我 </a-checkbox>
|
<a-checkbox disabled>
|
||||||
|
记住我
|
||||||
|
</a-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<a-button class="btn" type="primary" html-type="submit">立即登录 </a-button>
|
<a-button
|
||||||
|
class="btn"
|
||||||
|
type="primary"
|
||||||
|
html-type="submit"
|
||||||
|
>立即登录
|
||||||
|
</a-button>
|
||||||
</a-form>
|
</a-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {ref} from 'vue'
|
import {ref} from 'vue'
|
||||||
import { FormInstance, message, notification } from 'ant-design-vue'
|
import {FormInstance, message, notification} from "ant-design-vue";
|
||||||
import { Rule } from 'ant-design-vue/es/form'
|
import {Rule} from "ant-design-vue/es/form";
|
||||||
import { LoginParams } from '@/types/views/login.ts'
|
import {LoginParams} from "@/types/views/login.ts";
|
||||||
import api from '@/axios'
|
import api from "@/axios";
|
||||||
import { CLIENT_TYPE } from '@/config'
|
import {CLIENT_TYPE} from "@/config";
|
||||||
import rsaUtil from '@/utils/rsaUtil.ts'
|
import rsaUtil from "@/utils/rsaUtil.ts";
|
||||||
import { TokenInfo } from '@/types/stores/userStore.ts'
|
import {TokenInfo} from "@/types/stores/userStore.ts";
|
||||||
import { useUserStore } from '@/stores/modules/userStore.ts'
|
import {useUserStore} from "@/stores/modules/userStore.ts";
|
||||||
import { useRouter } from 'vue-router'
|
import {useRouter} from "vue-router";
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
@ -32,7 +56,7 @@ const formRef = ref<FormInstance>(null!)
|
||||||
const loginParamsRule: Record<keyof LoginParams, Rule[]> = {
|
const loginParamsRule: Record<keyof LoginParams, Rule[]> = {
|
||||||
telephone: [
|
telephone: [
|
||||||
{required: true, message: '请输入手机号', trigger: 'change'},
|
{required: true, message: '请输入手机号', trigger: 'change'},
|
||||||
{ len: 11, message: '长度不够', trigger: 'blur' },
|
{len: 11, message: "长度不够", trigger: 'blur'},
|
||||||
],
|
],
|
||||||
password: [
|
password: [
|
||||||
{required: true, message: '请输入密码', trigger: 'change'},
|
{required: true, message: '请输入密码', trigger: 'change'},
|
||||||
|
@ -40,9 +64,9 @@ const loginParamsRule: Record<keyof LoginParams, Rule[]> = {
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
const loginParams = ref<LoginParams>({
|
const loginParams = ref<LoginParams>({
|
||||||
telephone: __APP_ENV.VITE_APP_ENV === 'development' ? '15576404472' : '',
|
telephone: __APP_ENV.VITE_APP_ENV === "development" ? '15576404472' : '',
|
||||||
password: __APP_ENV.VITE_APP_ENV === 'development' ? '123456' : '',
|
password: __APP_ENV.VITE_APP_ENV === "development" ? '123456' : ''
|
||||||
})
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录
|
* 登录
|
||||||
|
@ -55,21 +79,22 @@ const login = async () => {
|
||||||
clientType: CLIENT_TYPE,
|
clientType: CLIENT_TYPE,
|
||||||
loginParams: {
|
loginParams: {
|
||||||
telephone: loginParams.value.telephone,
|
telephone: loginParams.value.telephone,
|
||||||
password: rsaUtil.encryptStr(loginParams.value.password),
|
password: rsaUtil.encryptStr(loginParams.value.password)
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
//保存token
|
//保存token
|
||||||
userStore.saveTokenInfo(resp.data as TokenInfo)
|
userStore.saveTokenInfo(resp.data as TokenInfo)
|
||||||
//跳转页面
|
//跳转页面
|
||||||
router.push('/index').then(() => {
|
router.push("/index").then(() => {
|
||||||
notification.success({
|
notification.success({
|
||||||
message: '登录成功',
|
message: '登录成功',
|
||||||
duration: 2,
|
duration: 2,
|
||||||
description: '欢迎来到本系统!',
|
description: '欢迎来到本系统!',
|
||||||
placement: 'topRight',
|
placement: 'topRight'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -94,7 +119,8 @@ const login = async () => {
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 0 0 1px #05f, 0 2px 1px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 0 0 1px #05f,
|
||||||
|
0 2px 1px rgba(0, 0, 0, 0.15);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
|
|
@ -1,72 +1,33 @@
|
||||||
|
|
||||||
|
|
||||||
import {RouteRecordRaw} from "vue-router";
|
import {RouteRecordRaw} from "vue-router";
|
||||||
export const Layout = () => import("@/components/layout/layout.vue");
|
|
||||||
export const staticRouter: RouteRecordRaw[] =
|
|
||||||
[
|
|
||||||
{
|
|
||||||
path: "/",
|
|
||||||
redirect: '/index',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
//导航页
|
|
||||||
path: '/',
|
|
||||||
name: '/',
|
|
||||||
// redirect: '/layout/index',
|
|
||||||
meta: {
|
|
||||||
title: '首页',
|
|
||||||
keepalive: true
|
|
||||||
},
|
|
||||||
component: Layout,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
//欢迎页
|
|
||||||
path: 'index',
|
|
||||||
name: 'welcome',
|
|
||||||
meta: {
|
|
||||||
title: '首页',
|
|
||||||
keepalive: true
|
|
||||||
},
|
|
||||||
component: () => import('@/views/dashboard/index.vue')
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
|
export const staticRouter: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
//导航页
|
|
||||||
path: '/register',
|
|
||||||
name: 'register',
|
|
||||||
meta: {
|
|
||||||
title: '注册',
|
|
||||||
keepalive: true
|
|
||||||
},
|
|
||||||
component: Layout,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: 'index', // 这里使用相对路径而不是 '/register'
|
|
||||||
name: 'register-index',
|
|
||||||
meta: {
|
|
||||||
title: '注册',
|
|
||||||
keepalive: true
|
|
||||||
},
|
|
||||||
component: () => import('@/views/register.vue')
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
//登录页面
|
|
||||||
path: '/login',
|
path: '/login',
|
||||||
name: 'login',
|
name: 'login',
|
||||||
meta: {
|
meta: {
|
||||||
title: '登录',
|
title: '登录',
|
||||||
keepalive: true
|
|
||||||
},
|
},
|
||||||
component: () => import('@/views/register.vue')
|
component: () => import("@/views/login.vue"),
|
||||||
|
}, {
|
||||||
|
path: "/",
|
||||||
|
redirect: '/index',
|
||||||
|
}, {
|
||||||
|
path: '/layout',
|
||||||
|
name: 'layout',
|
||||||
|
redirect: '/index',
|
||||||
|
component: () => import("@/components/layout/layout.vue"),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/index',
|
||||||
|
name: 'index',
|
||||||
|
meta: {
|
||||||
|
title: '首页',
|
||||||
|
icon: 'icon-shouye',
|
||||||
|
fixed: true,
|
||||||
|
isKeepAlive: false
|
||||||
},
|
},
|
||||||
|
component: () => import('@/views/index.vue')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
<template><div>111111</div></template>
|
|
||||||
|
|
||||||
<script setup lang="ts"></script>
|
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
|
||||||
<!-- <template>
|
|
||||||
<div>11111111</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup></script> -->
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<template>
|
||||||
|
index页面
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
|
@ -7,7 +7,9 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="left-banner"></div>
|
<div class="left-banner"></div>
|
||||||
<div class="login-card">
|
<div class="login-card">
|
||||||
<div class="title">欢迎来到超级后台</div>
|
<div class="title">
|
||||||
|
欢迎来到超级后台
|
||||||
|
</div>
|
||||||
<a-tabs class="account-tab" v-model:active-key="activeKey">
|
<a-tabs class="account-tab" v-model:active-key="activeKey">
|
||||||
<a-tab-pane :key="0" tab="账号登录">
|
<a-tab-pane :key="0" tab="账号登录">
|
||||||
<TelephoneLogin/>
|
<TelephoneLogin/>
|
||||||
|
@ -36,10 +38,11 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {QqOutlined, WechatOutlined} from '@ant-design/icons-vue'
|
import {QqOutlined, WechatOutlined} from '@ant-design/icons-vue'
|
||||||
import TelephoneLogin from '@/components/login/TelephoneLogin.vue'
|
import TelephoneLogin from '@/components/login/TelephoneLogin.vue';
|
||||||
import { ref } from 'vue'
|
import {ref} from "vue";
|
||||||
|
|
||||||
const activeKey = ref(0)
|
const activeKey = ref(0)
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
<template>
|
|
||||||
<div style="height: 100%; width: 100%">
|
|
||||||
<a-form ref="formRef" name="custom-validation" :model="formState" :rules="rules" v-bind="layout" @finish="handleFinish" @validate="handleValidate" @finishFailed="handleFinishFailed">
|
|
||||||
<div style="height: 100%">
|
|
||||||
<a-form-item v-if="options.length > 0" label="行政区划">
|
|
||||||
<a-cascader
|
|
||||||
:field-names="{ label: 'label', value: 'value', children: 'children' }"
|
|
||||||
@change="cascaderChange"
|
|
||||||
style="width: 200px"
|
|
||||||
v-if="options.length > 0"
|
|
||||||
v-model:value="value"
|
|
||||||
:options="options"
|
|
||||||
:show-search="{ filter }"
|
|
||||||
placeholder="请输入搜索关键词"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item v-else label="行政区划">
|
|
||||||
<div style="width: 200px; display: flex; justify-content: center; align-items: center"><a-spin />  数据加载中~~~</div>
|
|
||||||
</a-form-item>
|
|
||||||
</div>
|
|
||||||
<a-form-item has-feedback label="代码" name="code">
|
|
||||||
<a-input v-model:value="formState.code" autocomplete="off" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item has-feedback label="名称" name="name">
|
|
||||||
<a-input v-model:value="formState.name" autocomplete="off" />
|
|
||||||
</a-form-item>
|
|
||||||
|
|
||||||
<a-form-item has-feedback label="详细地址" name="address">
|
|
||||||
<a-input v-model:value="formState.address" autocomplete="off" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item has-feedback label="联系人姓名" name="contactPersonInfo">
|
|
||||||
<a-input v-model:value="formState.contactPersonInfo.name" autocomplete="off" />
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item has-feedback label="联系人电话" name="contactPersonInfo">
|
|
||||||
<a-input v-model:value="formState.contactPersonInfo.telephone" autocomplete="off" />
|
|
||||||
</a-form-item>
|
|
||||||
|
|
||||||
<!-- -->
|
|
||||||
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
|
|
||||||
<a-button type="primary" html-type="submit">提交</a-button>
|
|
||||||
<a-button style="margin-left: 10px" @click="resetForm">重置表单</a-button>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { message } from 'ant-design-vue'
|
|
||||||
// import type { CascaderProps } from 'ant-design-vue';
|
|
||||||
import api from '@/axios/index.ts'
|
|
||||||
import type { ShowSearchType } from 'ant-design-vue/es/cascader'
|
|
||||||
import { onMounted, reactive, ref } from 'vue'
|
|
||||||
onMounted(() => {
|
|
||||||
getTree()
|
|
||||||
})
|
|
||||||
const filter: ShowSearchType['filter'] = (inputValue, path) => {
|
|
||||||
return path.some((option) => option.title.toLowerCase().indexOf(inputValue.toLowerCase()) > -1)
|
|
||||||
}
|
|
||||||
const value = ref<string[]>([])
|
|
||||||
const options = ref<any[]>([])
|
|
||||||
const cascaderChange = (value: any, selectedOptions: any): void => {
|
|
||||||
formState.administrativeDivisionCodes = [...value]
|
|
||||||
// formState.province = value[0]
|
|
||||||
// formState.city = value[1]
|
|
||||||
// formState.districts = value[2]
|
|
||||||
// formState.street = value[3]
|
|
||||||
}
|
|
||||||
|
|
||||||
const getTree = async () => {
|
|
||||||
const res = await api.get<any>('/common/administrativeDivisionTree')
|
|
||||||
console.log(res)
|
|
||||||
options.value = res.data
|
|
||||||
}
|
|
||||||
import type { Rule } from 'ant-design-vue/es/form'
|
|
||||||
import type { FormInstance } from 'ant-design-vue'
|
|
||||||
interface FormState {
|
|
||||||
name: string
|
|
||||||
code: number | string
|
|
||||||
administrativeDivisionCodes: any[]
|
|
||||||
// province: string
|
|
||||||
// city: string
|
|
||||||
// districts: string
|
|
||||||
// street: string
|
|
||||||
address: string
|
|
||||||
contactPersonInfo: ContactPersonInfo
|
|
||||||
}
|
|
||||||
const formRef = ref<FormInstance>()
|
|
||||||
interface ContactPersonInfo {
|
|
||||||
telephone: string
|
|
||||||
name: string
|
|
||||||
}
|
|
||||||
const formState = reactive<FormState>({
|
|
||||||
name: '',
|
|
||||||
code: '',
|
|
||||||
administrativeDivisionCodes: [],
|
|
||||||
// province: '',
|
|
||||||
// city: '',
|
|
||||||
// districts: '',
|
|
||||||
// street: '',
|
|
||||||
address: '',
|
|
||||||
contactPersonInfo: {
|
|
||||||
telephone: '',
|
|
||||||
name: '',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const checkIsNull = async (_rule: Rule, value: string) => {
|
|
||||||
if (value === '') {
|
|
||||||
return Promise.reject('请输入')
|
|
||||||
} else {
|
|
||||||
return Promise.resolve()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const rules: Record<string, Rule[]> = {
|
|
||||||
name: [{ required: true, validator: checkIsNull, trigger: 'change' }],
|
|
||||||
code: [{ required: true, validator: checkIsNull, trigger: 'change' }],
|
|
||||||
address: [{ required: true, validator: checkIsNull, trigger: 'change' }],
|
|
||||||
// contactPersonInfo: [{ required: true, validator: checkIsNull, trigger: 'change' }],
|
|
||||||
}
|
|
||||||
const layout = {
|
|
||||||
labelCol: { span: 4 },
|
|
||||||
wrapperCol: { span: 14 },
|
|
||||||
}
|
|
||||||
const handleFinish = (values: FormState) => {
|
|
||||||
console.log(values, formState)
|
|
||||||
if (value.value.length === 0) {
|
|
||||||
message.error('请选择行政区划')
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
api.post<any>('/common/policeUnitRegister', { ...formState }).then((res) => {
|
|
||||||
console.log(res)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const handleFinishFailed = (errors: any) => {
|
|
||||||
console.log(errors)
|
|
||||||
}
|
|
||||||
const resetForm = () => {
|
|
||||||
formRef.value.resetFields()
|
|
||||||
}
|
|
||||||
const handleValidate = (...args: any[]) => {
|
|
||||||
console.log(args)
|
|
||||||
}
|
|
||||||
//
|
|
||||||
</script>
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{
|
||||||
// "compilerOptions": {
|
|
||||||
// "paths": {
|
|
||||||
// "@/*": ["src/*"]
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
"files": [],
|
"files": [],
|
||||||
"references": [
|
"references": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,6 @@ export default defineConfig(({ mode }) => {
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': pathSrc,
|
'@': pathSrc,
|
||||||
// '@': '/src'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
|
|
Loading…
Reference in New Issue