Merge pull request !60 from 小诺/dev
This commit is contained in:
小诺 2022-11-23 17:10:50 +00:00 committed by Gitee
commit 18e74e0243
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
13 changed files with 313 additions and 502 deletions

View File

@ -1,7 +1,5 @@
<template> <template>
<div class="sceditor"> <Editor v-model="contentValue" :init="init" :disabled="disabled" :placeholder="placeholder" @onClick="onClick" />
<Editor v-model="contentValue" :init="init" :disabled="disabled" :placeholder="placeholder" @onClick="onClick" />
</div>
</template> </template>
<script> <script>
@ -69,15 +67,16 @@
resize: true, resize: true,
elementpath: true, elementpath: true,
content_style: '', content_style: '',
images_upload_handler: async (blobInfo, success, failure) => { images_upload_handler(blobInfo, progress) {
const data = new FormData() return new Promise((resolve, reject) => {
data.append('file', blobInfo.blob(), blobInfo.filename()) const data = new FormData()
try { data.append('file', blobInfo.blob(), blobInfo.filename())
const res = await fileApi.fileUploadDynamicReturnUrl(data) fileApi.fileUploadDynamicReturnUrl(data).then((res) => {
success(res) return resolve(res)
} catch (error) { }).catch((err) => {
failure('Image upload failed') return reject('err:' + err)
} })
})
}, },
setup: (editor) => { setup: (editor) => {
editor.on('init', function () { editor.on('init', function () {
@ -106,5 +105,3 @@
} }
} }
</script> </script>
<style></style>

View File

@ -8,10 +8,10 @@
* 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作 * 5.不可二次分发开源参与同类竞品如有想法可联系团队xiaonuobase@qq.com商议合作
* 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip * 6.若您的项目无法满足以上几点需要更多功能代码获取Snowy商业授权许可请在官网购买授权地址为 https://www.xiaonuo.vip
*/ */
export const required = (text, method = ['blur', 'change']) => ({ export const required = (message, trigger = ['blur', 'change']) => ({
required: true, required: true,
message: text, message,
trigger: method trigger
}) })
// 常用正则规则大全https://any86.github.io/any-rule/ // 常用正则规则大全https://any86.github.io/any-rule/

View File

@ -8,7 +8,7 @@
<h2>三方登录</h2> <h2>三方登录</h2>
</div> </div>
<a-spin tip="正在登录中..."> <a-spin tip="正在登录中...">
<div style="height: 300px"> <div class="h-[300px]">
<a-skeleton /> <a-skeleton />
</div> </div>
</a-spin> </a-spin>
@ -20,7 +20,6 @@
<script setup name="loginCallback"> <script setup name="loginCallback">
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
import { nextTick } from 'vue'
import tool from '@/utils/tool' import tool from '@/utils/tool'
import router from '@/router' import router from '@/router'
import thirdApi from '@/api/auth/thirdApi' import thirdApi from '@/api/auth/thirdApi'
@ -31,24 +30,21 @@
onMounted(() => { onMounted(() => {
// url // url
const url = window.location.href const url = new URL(window.location.href)
let parameter = url.split('?')[1] let argLength = 0
if (!parameter) { const params = {}
// 访 url.searchParams.forEach((value, key) => {
window.location.href = '/login' argLength += 1
} params[key] = value
const parameterArray = parameter.split('&') })
// //
if (!parameterArray) { if (argLength < 2) {
window.location.href = '/login' window.location.href = '/login'
return
} }
const parameterObject = {}
// json
for (let i = 0; i < parameterArray.length; i++) {
parameterObject[parameterArray[i].split('=')[0]] = parameterArray[i].split('=')[1]
}
thirdApi thirdApi
.thirdCallback(parameterObject) .thirdCallback(params)
.then((data) => { .then((data) => {
tool.data.set('TOKEN', data) tool.data.set('TOKEN', data)
// //
@ -64,11 +60,9 @@
path: indexMenu path: indexMenu
}) })
message.success('登录成功') message.success('登录成功')
nextTick(() => { dictApi.dictTree().then((dictData) => {
dictApi.dictTree().then((dictData) => { // store
// store tool.data.set('DICT_TYPE_TREE_DATA', dictData)
tool.data.set('DICT_TYPE_TREE_DATA', dictData)
})
}) })
}) })
}) })
@ -79,155 +73,5 @@
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.login_background { @import 'login';
width: 100%;
height: 100%;
overflow: hidden;
background-size: cover;
background-position: center;
background-image: url(/img/login_background.png);
}
.login_background_front {
width: 450px;
height: 450px;
margin-left: 100px;
margin-top: 15%;
overflow: hidden;
/*position: relative;*/
background-size: cover;
background-position: center;
background-image: url(/img/login_background_front.png);
animation-name: myfirst;
animation-duration: 5s;
animation-timing-function: linear;
animation-delay: 1s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-play-state: running;
/* Safari and Chrome: */
-webkit-animation-name: myfirst;
-webkit-animation-duration: 5s;
-webkit-animation-timing-function: linear;
-webkit-animation-delay: 1s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: alternate;
-webkit-animation-play-state: running;
}
@keyframes myfirst {
0% {
left: 0px;
top: 0px;
}
50% {
left: 50px;
top: 0px;
}
100% {
left: 0px;
top: 0px;
}
}
@-webkit-keyframes myfirst /* Safari and Chrome */ {
0% {
left: 0px;
top: 0px;
}
50% {
left: 50px;
top: 0px;
}
100% {
left: 0px;
top: 0px;
}
}
.login_adv__title h2 {
font-size: 40px;
}
.login_adv__title h4 {
font-size: 18px;
margin-top: 10px;
font-weight: normal;
}
.login_adv__title p {
font-size: 14px;
margin-top: 10px;
line-height: 1.8;
color: rgba(255, 255, 255, 0.6);
}
.login_adv__title div {
margin-top: 10px;
display: flex;
align-items: center;
}
.login_adv__title div span {
margin-right: 15px;
}
.login_adv__title div i {
font-size: 40px;
}
.login_adv__title div i.add {
font-size: 20px;
color: rgba(255, 255, 255, 0.6);
}
/*background-image:linear-gradient(transparent, #000);*/
.login_main {
flex: 1;
overflow: auto;
display: flex;
}
.login-form {
top: 15%;
right: 15%;
position: absolute;
width: 450px;
margin-left: 10%;
margin-top: 20px;
padding: 10px 0;
}
.login-header {
margin-bottom: 20px;
}
.login-header .logo {
display: flex;
align-items: center;
}
.login-header .logo img {
width: 35px;
height: 35px;
vertical-align: bottom;
margin-right: 10px;
}
.login-header .logo label {
font-size: 24px;
}
.login-header h2 {
font-size: 24px;
font-weight: bold;
margin-top: 40px;
}
.login_config {
position: absolute;
top: 20px;
right: 20px;
}
@media (max-width: 1200px) {
.login-form {
width: 340px;
}
}
@media (max-width: 1000px) {
.login_main {
display: block;
}
.login_background_front {
display: none;
}
.login-form {
width: 100%;
padding: 20px 40px;
right: 0 !important;
top: 0 !important;
}
}
</style> </style>

View File

@ -0,0 +1,152 @@
.login-icon-gray {
color: rgba(0, 0, 0, 0.25);
}
.login-validCode-img {
border: 1px solid var(--border-color-split);
cursor: pointer;
width: 100%;
height: 40px;
}
.login_background {
width: 100%;
height: 100%;
overflow: hidden;
background-size: cover;
background-position: center;
background-image: url(/img/login_background.png);
}
.login_background_front {
width: 450px;
height: 450px;
margin-left: 100px;
margin-top: 15%;
overflow: hidden;
/*position: relative;*/
background-size: cover;
background-position: center;
background-image: url(/img/login_background_front.png);
animation-name: myfirst;
animation-duration: 5s;
animation-timing-function: linear;
animation-delay: 1s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-play-state: running;
}
@keyframes myfirst {
0% {
left: 0px;
top: 0px;
}
50% {
left: 50px;
top: 0px;
}
100% {
left: 0px;
top: 0px;
}
}
@-webkit-keyframes myfirst /* Safari and Chrome */ {
0% {
left: 0px;
top: 0px;
}
50% {
left: 50px;
top: 0px;
}
100% {
left: 0px;
top: 0px;
}
}
.login_adv__title h2 {
font-size: 40px;
}
.login_adv__title h4 {
font-size: 18px;
margin-top: 10px;
font-weight: normal;
}
.login_adv__title p {
font-size: 14px;
margin-top: 10px;
line-height: 1.8;
color: rgba(255, 255, 255, 0.6);
}
.login_adv__title div {
margin-top: 10px;
display: flex;
align-items: center;
}
.login_adv__title div span {
margin-right: 15px;
}
.login_adv__title div i {
font-size: 40px;
}
.login_adv__title div i.add {
font-size: 20px;
color: rgba(255, 255, 255, 0.6);
}
/*background-image:linear-gradient(transparent, #000);*/
.login_main {
flex: 1;
overflow: auto;
display: flex;
}
.login-form {
top: 15%;
right: 15%;
position: absolute;
width: 450px;
margin-left: 10%;
margin-top: 20px;
padding: 10px 0;
}
.login-header {
margin-bottom: 20px;
}
.login-header .logo {
display: flex;
align-items: center;
}
.login-header .logo img {
width: 35px;
height: 35px;
vertical-align: bottom;
margin-right: 10px;
}
.login-header .logo label {
font-size: 24px;
}
.login-header h2 {
font-size: 24px;
font-weight: bold;
margin-top: 40px;
}
.login_config {
position: absolute;
top: 20px;
right: 20px;
}
@media (max-width: 1200px) {
.login-form {
width: 340px;
}
}
@media (max-width: 1000px) {
.login_main {
display: block;
}
.login_background_front {
display: none;
}
.login-form {
width: 100%;
padding: 20px 40px;
right: 0 !important;
top: 0 !important;
}
}

View File

@ -33,9 +33,14 @@
<a-tab-pane key="userAccount" :tab="$t('login.accountPassword')"> <a-tab-pane key="userAccount" :tab="$t('login.accountPassword')">
<a-form ref="loginForm" :model="ruleForm" :rules="rules"> <a-form ref="loginForm" :model="ruleForm" :rules="rules">
<a-form-item name="account"> <a-form-item name="account">
<a-input v-model:value="ruleForm.account" :placeholder="$t('login.accountPlaceholder')" size="large"> <a-input
v-model:value="ruleForm.account"
:placeholder="$t('login.accountPlaceholder')"
size="large"
@keyup.enter="login"
>
<template #prefix> <template #prefix>
<UserOutlined style="color: rgba(0, 0, 0, 0.25)" /> <UserOutlined class="login-icon-gray" />
</template> </template>
</a-input> </a-input>
</a-form-item> </a-form-item>
@ -45,13 +50,14 @@
:placeholder="$t('login.PWPlaceholder')" :placeholder="$t('login.PWPlaceholder')"
size="large" size="large"
autocomplete="off" autocomplete="off"
@keyup.enter="login"
> >
<template #prefix> <template #prefix>
<LockOutlined style="color: rgba(0, 0, 0, 0.25)" /> <LockOutlined class="login-icon-gray" />
</template> </template>
</a-input-password> </a-input-password>
</a-form-item> </a-form-item>
<a-form-item name="validCode" v-if="sysBaseConfig.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN === 'true'"> <a-form-item name="validCode" v-if="captchaOpen">
<a-row :gutter="8"> <a-row :gutter="8">
<a-col :span="17"> <a-col :span="17">
<a-input <a-input
@ -60,16 +66,12 @@
size="large" size="large"
> >
<template #prefix> <template #prefix>
<verified-outlined style="color: rgba(0, 0, 0, 0.25)" /> <verified-outlined class="login-icon-gray" />
</template> </template>
</a-input> </a-input>
</a-col> </a-col>
<a-col :span="7"> <a-col :span="7">
<img <img :src="validCodeBase64" class="login-validCode-img" @click="loginCaptcha" />
:src="validCodeBase64"
style="border: 1px solid var(--border-color-split); cursor: pointer; width: 100%; height: 40px"
@click="loginCaptcha"
/>
</a-col> </a-col>
</a-row> </a-row>
</a-form-item> </a-form-item>
@ -78,7 +80,7 @@
<a href="/findpwd" style="color: #0d84ff">{{ $t('login.forgetPassword') }}</a> <a href="/findpwd" style="color: #0d84ff">{{ $t('login.forgetPassword') }}</a>
</a-form-item> </a-form-item>
<a-form-item> <a-form-item>
<a-button type="primary" style="width: 100%" :loading="islogin" round size="large" @click="login" <a-button type="primary" class="w-full" :loading="loading" round size="large" @click="login"
>{{ $t('login.signIn') }} >{{ $t('login.signIn') }}
</a-button> </a-button>
</a-form-item> </a-form-item>
@ -97,17 +99,19 @@
<script> <script>
import loginApi from '@/api/auth/loginApi' import loginApi from '@/api/auth/loginApi'
import userCenterApi from '@/api/sys/userCenterApi'
import dictApi from '@/api/dev/dictApi'
import phoneLoginForm from './phoneLoginForm.vue' import phoneLoginForm from './phoneLoginForm.vue'
import threeLogin from './threeLogin.vue' import threeLogin from './threeLogin.vue'
import smCrypto from '@/utils/smCrypto' import smCrypto from '@/utils/smCrypto'
import { required } from '@/utils/formRules'
import { afterLogin } from './util'
export default { export default {
name: 'Login',
components: { components: {
phoneLoginForm, phoneLoginForm,
threeLogin threeLogin
}, },
data() { data() {
return { return {
activeKey: 'userAccount', activeKey: 'userAccount',
@ -121,10 +125,10 @@
autologin: false autologin: false
}, },
rules: { rules: {
account: [{ required: true, message: this.$t('login.accountError'), trigger: 'blur' }], account: [required(this.$t('login.accountError'), 'blur')],
password: [{ required: true, message: this.$t('login.PWError'), trigger: 'blur' }] password: [required(this.$t('login.PWError'), 'blur')]
}, },
islogin: false, loading: false,
config: { config: {
lang: this.$TOOL.data.get('APP_LANG') || this.$CONFIG.LANG, lang: this.$TOOL.data.get('APP_LANG') || this.$CONFIG.LANG,
theme: this.$TOOL.data.get('APP_THEME') || 'default' theme: this.$TOOL.data.get('APP_THEME') || 'default'
@ -142,8 +146,8 @@
} }
}, },
computed: { computed: {
sysBaseConfigWatch() { captchaOpen() {
return this.$store.state.global.sysBaseConfig return this.sysBaseConfig.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN === 'true'
} }
}, },
watch: { watch: {
@ -153,10 +157,6 @@
'config.lang': function (val) { 'config.lang': function (val) {
this.$i18n.locale = val this.$i18n.locale = val
this.$TOOL.data.set('APP_LANG', val) this.$TOOL.data.set('APP_LANG', val)
},
sysBaseConfigWatch(val) {
this.sysBaseConfig = val
this.refreshSwitch()
} }
}, },
created() { created() {
@ -166,27 +166,16 @@
}, },
mounted() { mounted() {
this.refreshSwitch() this.refreshSwitch()
//
document.onkeydown = (e) => {
if (e.defaultPrevented) {
return;
}
const body = document.getElementsByTagName('body')[0];
// match(httpshttpwww)
if (e.keyCode === 13 && e.target.baseURI.match("/login") && e.target === body) {
this.login()
}
}
}, },
methods: { methods: {
// //
refreshSwitch() { refreshSwitch() {
// //
if (this.sysBaseConfig.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN === 'true') { if (this.captchaOpen) {
// //
this.loginCaptcha() this.loginCaptcha()
// //
this.rules.validCode = [{ required: true, message: this.$t('login.validError'), trigger: 'blur' }] this.rules.validCode = [required(this.$t('login.validError'), 'blur')]
} }
}, },
// //
@ -198,45 +187,22 @@
}, },
// //
async login() { async login() {
const validate = await this.$refs.loginForm.validate().catch(() => {}) this.$refs.loginForm.validate().then(async () => {
if (!validate) return false this.loading = true
const loginData = {
this.islogin = true account: this.ruleForm.account,
const loginData = { // SM2使hash
account: this.ruleForm.account, password: smCrypto.doSm2Encrypt(this.ruleForm.password),
// SM2使hash validCode: this.ruleForm.validCode,
password: smCrypto.doSm2Encrypt(this.ruleForm.password), validCodeReqNo: this.ruleForm.validCodeReqNo
validCode: this.ruleForm.validCode, }
validCodeReqNo: this.ruleForm.validCodeReqNo // token
} try {
// token const loginToken = await loginApi.login(loginData)
const login = await loginApi.login(loginData).finally(() => { afterLogin(loginToken)
this.islogin = false } catch (err) {
}) this.loading = false
this.$TOOL.data.set('TOKEN', login) }
//
const loginUser = await loginApi.getLoginUser()
this.$TOOL.data.set('USER_INFO', loginUser)
//
const menu = await userCenterApi.userLoginMenu().catch(() => {
this.islogin = false
return
})
this.islogin = false
const indexMenu = menu[0].children[0].path
this.$TOOL.data.set('MENU', menu)
//
this.$TOOL.data.set('SNOWY_MENU_MODULE_ID', menu[0].id)
this.$router.replace({
path: indexMenu
})
this.$message.success('登录成功')
this.$nextTick(() => {
dictApi.dictTree().then((data) => {
// store
this.$TOOL.data.set('DICT_TYPE_TREE_DATA', data)
})
}) })
}, },
configLang(key) { configLang(key) {
@ -246,156 +212,6 @@
} }
</script> </script>
<style lang="less" scoped> <style lang="less">
.login_background { @import 'login';
width: 100%;
height: 100%;
overflow: hidden;
background-size: cover;
background-position: center;
background-image: url(/img/login_background.png);
}
.login_background_front {
width: 450px;
height: 450px;
margin-left: 100px;
margin-top: 15%;
overflow: hidden;
/*position: relative;*/
background-size: cover;
background-position: center;
background-image: url(/img/login_background_front.png);
animation-name: myfirst;
animation-duration: 5s;
animation-timing-function: linear;
animation-delay: 1s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-play-state: running;
/* Safari and Chrome: */
-webkit-animation-name: myfirst;
-webkit-animation-duration: 5s;
-webkit-animation-timing-function: linear;
-webkit-animation-delay: 1s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: alternate;
-webkit-animation-play-state: running;
}
@keyframes myfirst {
0% {
left: 0px;
top: 0px;
}
50% {
left: 50px;
top: 0px;
}
100% {
left: 0px;
top: 0px;
}
}
@-webkit-keyframes myfirst /* Safari and Chrome */ {
0% {
left: 0px;
top: 0px;
}
50% {
left: 50px;
top: 0px;
}
100% {
left: 0px;
top: 0px;
}
}
.login_adv__title h2 {
font-size: 40px;
}
.login_adv__title h4 {
font-size: 18px;
margin-top: 10px;
font-weight: normal;
}
.login_adv__title p {
font-size: 14px;
margin-top: 10px;
line-height: 1.8;
color: rgba(255, 255, 255, 0.6);
}
.login_adv__title div {
margin-top: 10px;
display: flex;
align-items: center;
}
.login_adv__title div span {
margin-right: 15px;
}
.login_adv__title div i {
font-size: 40px;
}
.login_adv__title div i.add {
font-size: 20px;
color: rgba(255, 255, 255, 0.6);
}
/*background-image:linear-gradient(transparent, #000);*/
.login_main {
flex: 1;
overflow: auto;
display: flex;
}
.login-form {
top: 15%;
right: 15%;
position: absolute;
width: 450px;
margin-left: 10%;
margin-top: 20px;
padding: 10px 0;
}
.login-header {
margin-bottom: 20px;
}
.login-header .logo {
display: flex;
align-items: center;
}
.login-header .logo img {
width: 35px;
height: 35px;
vertical-align: bottom;
margin-right: 10px;
}
.login-header .logo label {
font-size: 24px;
}
.login-header h2 {
font-size: 24px;
font-weight: bold;
margin-top: 40px;
}
.login_config {
position: absolute;
top: 20px;
right: 20px;
}
@media (max-width: 1200px) {
.login-form {
width: 340px;
}
}
@media (max-width: 1000px) {
.login_main {
display: block;
}
.login_background_front {
display: none;
}
.login-form {
width: 100%;
padding: 20px 40px;
right: 0 !important;
top: 0 !important;
}
}
</style> </style>

View File

@ -3,7 +3,7 @@
<a-form-item name="phone"> <a-form-item name="phone">
<a-input v-model:value="phoneFormData.phone" :placeholder="$t('login.phonePlaceholder')" size="large"> <a-input v-model:value="phoneFormData.phone" :placeholder="$t('login.phonePlaceholder')" size="large">
<template #prefix> <template #prefix>
<mobile-outlined style="color: rgba(0, 0, 0, 0.25)" /> <mobile-outlined class="text-black text-opacity-25" />
</template> </template>
</a-input> </a-input>
</a-form-item> </a-form-item>
@ -16,21 +16,21 @@
size="large" size="large"
> >
<template #prefix> <template #prefix>
<mail-outlined style="color: rgba(0, 0, 0, 0.25)" /> <mail-outlined class="text-black text-opacity-25" />
</template> </template>
</a-input> </a-input>
</a-col> </a-col>
<a-col :span="7"> <a-col :span="7">
<a-button size="large" style="width: 100%" @click="getPhoneValidCode" :disabled="state.smsSendBtn">{{ <a-button size="large" style="width: 100%" @click="getPhoneValidCode" :disabled="state.smsSendBtn">
(!state.smsSendBtn && $t('login.getSmsCode')) || state.time + ' s' {{ (!state.smsSendBtn && $t('login.getSmsCode')) || state.time + ' s' }}
}}</a-button> </a-button>
</a-col> </a-col>
</a-row> </a-row>
</a-form-item> </a-form-item>
<a-form-item> <a-form-item>
<a-button type="primary" style="width: 100%" :loading="islogin" round size="large" @click="submitLogin">{{ <a-button type="primary" style="width: 100%" :loading="loading" round size="large" @click="submitLogin">
$t('login.signIn') {{ $t('login.signIn') }}
}}</a-button> </a-button>
</a-form-item> </a-form-item>
</a-form> </a-form>
<a-modal <a-modal
@ -50,7 +50,7 @@
size="large" size="large"
> >
<template #prefix> <template #prefix>
<verified-outlined style="color: rgba(0, 0, 0, 0.25)" /> <verified-outlined class="text-black text-opacity-25" />
</template> </template>
</a-input> </a-input>
</a-col> </a-col>
@ -69,16 +69,13 @@
<script setup name="smsLoginForm"> <script setup name="smsLoginForm">
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
import { nextTick } from 'vue'
import tool from '@/utils/tool'
import router from '@/router'
import { required, rules } from '@/utils/formRules' import { required, rules } from '@/utils/formRules'
import loginApi from '@/api/auth/loginApi' import loginApi from '@/api/auth/loginApi'
import userCenterApi from '@/api/sys/userCenterApi' import { afterLogin } from './util'
import dictApi from '@/api/dev/dictApi'
const phoneLoginFormRef = ref() const phoneLoginFormRef = ref()
const phoneFormData = ref({}) const phoneFormData = ref({})
const islogin = ref(false) const loading = ref(false)
let state = ref({ let state = ref({
time: 60, time: 60,
smsSendBtn: false smsSendBtn: false
@ -109,36 +106,13 @@
// delete phoneFormData.value.phoneValidCode // delete phoneFormData.value.phoneValidCode
phoneFormData.value.validCodeReqNo = phoneValidCodeReqNo.value phoneFormData.value.validCodeReqNo = phoneValidCodeReqNo.value
islogin.value = true loading.value = true
const token = await loginApi.loginByPhone(phoneFormData.value).finally(() => { try {
islogin.value = false const token = await loginApi.loginByPhone(phoneFormData.value)
}) afterLogin(token)
} catch (err) {
tool.data.set('TOKEN', token) loading.value = false
// }
const loginUser = await loginApi.getLoginUser()
tool.data.set('USER_INFO', loginUser)
//
const menu = await userCenterApi.userLoginMenu().catch(() => {
islogin.value = false
return
})
islogin.value = false
const indexMenu = menu[0].children[0].path
tool.data.set('MENU', menu)
//
tool.data.set('SNOWY_MENU_MODULE_ID', menu[0].id)
router.replace({
path: indexMenu
})
message.success('登录成功')
nextTick(() => {
dictApi.dictTree().then((data) => {
// store
tool.data.set('DICT_TYPE_TREE_DATA', data)
})
})
} }
// //

View File

@ -1,6 +1,6 @@
<template> <template>
<a-divider>{{ $t('login.signInOther') }}</a-divider> <a-divider>{{ $t('login.signInOther') }}</a-divider>
<div class="login-oauth"> <div class="login-oauth layout-center">
<a-space align="start"> <a-space align="start">
<a @click="getLoginRenderUrl('gitee')"><GiteeIcon /></a> <a @click="getLoginRenderUrl('gitee')"><GiteeIcon /></a>
<a-button type="primary" shape="circle"> <a-button type="primary" shape="circle">
@ -23,9 +23,4 @@
} }
</script> </script>
<style scoped> <style scoped></style>
.login-oauth {
display: flex;
justify-content: center;
}
</style>

View File

@ -0,0 +1,28 @@
import loginApi from '@/api/auth/loginApi'
import userCenterApi from '@/api/sys/userCenterApi'
import dictApi from '@/api/dev/dictApi'
import router from '@/router'
import tool from '@/utils/tool'
import { message } from 'ant-design-vue'
export const afterLogin = async (loginToken) => {
tool.data.set('TOKEN', loginToken)
// 获取登录的用户信息
const loginUser = await loginApi.getLoginUser()
tool.data.set('USER_INFO', loginUser)
// 获取用户的菜单
const menu = await userCenterApi.userLoginMenu()
const indexMenu = menu[0].children[0].path
tool.data.set('MENU', menu)
// 重置系统默认应用
tool.data.set('SNOWY_MENU_MODULE_ID', menu[0].id)
message.success('登录成功')
router.replace({
path: indexMenu
})
dictApi.dictTree().then((data) => {
// 设置字典到store中
tool.data.set('DICT_TYPE_TREE_DATA', data)
})
}

View File

@ -41,7 +41,6 @@
</template> </template>
<script setup name="sysModule"> <script setup name="sysModule">
import { message } from 'ant-design-vue'
import Form from './form.vue' import Form from './form.vue'
import configApi from '@/api/dev/configApi' import configApi from '@/api/dev/configApi'
let searchFormState = reactive({}) let searchFormState = reactive({})
@ -87,7 +86,7 @@
let params = { let params = {
id: record.id id: record.id
} }
configApi.configDetail(params).then(() => { configApi.configDelete(params).then(() => {
table.value.refresh(true) table.value.refresh(true)
}) })
} }

View File

@ -192,31 +192,31 @@
tableColumns: [] tableColumns: []
} }
}) })
if (record) {
const params = {
id: record.id
}
submitLoading.value = true
genBasicApi.basicDetail(params).then((data) => {
formData.value = data
//
selectTableColumnsData(data.dbTable, true)
//
moduleChange(data.module, true)
}).finally(() => {
submitLoading.value = false
})
} else {
formData.value = {
sortCode: 99,
tablePrefix: 'Y',
generateType: 'ZIP',
packageName: 'vip.xiaonuo',
formLayout: 'vertical',
gridWhether: 'N'
}
}
}) })
if (record) {
const params = {
id: record.id
}
submitLoading.value = true
genBasicApi.basicDetail(params).then((data) => {
formData.value = data
//
selectTableColumnsData(data.dbTable, true)
//
moduleChange(data.module, true)
}).finally(() => {
submitLoading.value = false
})
} else {
formData.value = {
sortCode: 99,
tablePrefix: 'Y',
generateType: 'ZIP',
packageName: 'vip.xiaonuo',
formLayout: 'vertical',
gridWhether: 'N'
}
}
} }
// //
const formRules = { const formRules = {

View File

@ -356,7 +356,7 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
String genProjectBackendPath = System.getProperty("user.dir") + File.separator + GEN_PROJECT_PLUGIN_BIZ_KEY + File.separator + "src" + String genProjectBackendPath = System.getProperty("user.dir") + File.separator + GEN_PROJECT_PLUGIN_BIZ_KEY + File.separator + "src" +
File.separator + "main" + File.separator + "java"; File.separator + "main" + File.separator + "java";
if(!FileUtil.exist(genProjectFrontendPath)) { if(!FileUtil.exist(genProjectBackendPath)) {
throw new CommonException("后端代码生成位置:{}不存在,请检查位置", genProjectBackendPath); throw new CommonException("后端代码生成位置:{}不存在,请检查位置", genProjectBackendPath);
} }
try { try {

View File

@ -21,7 +21,7 @@
<% } else if (configList[i].effectType == 'select') {%> <% } else if (configList[i].effectType == 'select') {%>
<a-select v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" /> <a-select v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" />
<% } else if (configList[i].effectType == 'radio') {%> <% } else if (configList[i].effectType == 'radio') {%>
<a-radio-group v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="formData.${configList[i].fieldNameCamelCase}Options" /> <a-radio-group v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" />
<% } else if (configList[i].effectType == 'checkbox') {%> <% } else if (configList[i].effectType == 'checkbox') {%>
<a-checkbox-group v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" /> <a-checkbox-group v-model:value="formData.${configList[i].fieldNameCamelCase}" placeholder="请选择${configList[i].fieldRemark}" :options="${configList[i].fieldNameCamelCase}Options" />
<% } else if (configList[i].effectType == 'datepicker') {%> <% } else if (configList[i].effectType == 'datepicker') {%>

View File

@ -132,15 +132,21 @@
<script setup name="${busName}"> <script setup name="${busName}">
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
<% if (searchCount > 0) { %> <%
<% for(var i = 0; i < configList.~size; i++) { %> var iptTool = 0;
<% if(!configList[i].needTableId && configList[i].needPage) { %> if (searchCount > 0) {
<% if (configList[i].effectType == 'select' || configList[i].effectType == 'radio' || configList[i].effectType == 'checkbox') { %> for(var i = 0; i < configList.~size; i++) {
if(!configList[i].needTableId) {
if(configList[i].effectType == 'select' || configList[i].effectType == 'radio' || configList[i].effectType == 'checkbox') {
iptTool++;
}
}
}
}
%>
<% if(iptTool > 0) { %>
import tool from '@/utils/tool' import tool from '@/utils/tool'
<% } %> <% } %>
<% } %>
<% } %>
<% } %>
import Form from './form.vue' import Form from './form.vue'
import ${classNameFirstLower}Api from '@/api/${moduleName}/${classNameFirstLower}Api' import ${classNameFirstLower}Api from '@/api/${moduleName}/${classNameFirstLower}Api'
<% if (searchCount > 0) { %> <% if (searchCount > 0) { %>