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

View File

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

View File

@ -8,7 +8,7 @@
<h2>三方登录</h2>
</div>
<a-spin tip="正在登录中...">
<div style="height: 300px">
<div class="h-[300px]">
<a-skeleton />
</div>
</a-spin>
@ -20,7 +20,6 @@
<script setup name="loginCallback">
import { message } from 'ant-design-vue'
import { nextTick } from 'vue'
import tool from '@/utils/tool'
import router from '@/router'
import thirdApi from '@/api/auth/thirdApi'
@ -31,24 +30,21 @@
onMounted(() => {
// url
const url = window.location.href
let parameter = url.split('?')[1]
if (!parameter) {
// 访
window.location.href = '/login'
}
const parameterArray = parameter.split('&')
const url = new URL(window.location.href)
let argLength = 0
const params = {}
url.searchParams.forEach((value, key) => {
argLength += 1
params[key] = value
})
//
if (!parameterArray) {
if (argLength < 2) {
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
.thirdCallback(parameterObject)
.thirdCallback(params)
.then((data) => {
tool.data.set('TOKEN', data)
//
@ -64,11 +60,9 @@
path: indexMenu
})
message.success('登录成功')
nextTick(() => {
dictApi.dictTree().then((dictData) => {
// store
tool.data.set('DICT_TYPE_TREE_DATA', dictData)
})
dictApi.dictTree().then((dictData) => {
// store
tool.data.set('DICT_TYPE_TREE_DATA', dictData)
})
})
})
@ -79,155 +73,5 @@
</script>
<style lang="less" scoped>
.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;
/* 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;
}
}
@import 'login';
</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-form ref="loginForm" :model="ruleForm" :rules="rules">
<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>
<UserOutlined style="color: rgba(0, 0, 0, 0.25)" />
<UserOutlined class="login-icon-gray" />
</template>
</a-input>
</a-form-item>
@ -45,13 +50,14 @@
:placeholder="$t('login.PWPlaceholder')"
size="large"
autocomplete="off"
@keyup.enter="login"
>
<template #prefix>
<LockOutlined style="color: rgba(0, 0, 0, 0.25)" />
<LockOutlined class="login-icon-gray" />
</template>
</a-input-password>
</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-col :span="17">
<a-input
@ -60,16 +66,12 @@
size="large"
>
<template #prefix>
<verified-outlined style="color: rgba(0, 0, 0, 0.25)" />
<verified-outlined class="login-icon-gray" />
</template>
</a-input>
</a-col>
<a-col :span="7">
<img
:src="validCodeBase64"
style="border: 1px solid var(--border-color-split); cursor: pointer; width: 100%; height: 40px"
@click="loginCaptcha"
/>
<img :src="validCodeBase64" class="login-validCode-img" @click="loginCaptcha" />
</a-col>
</a-row>
</a-form-item>
@ -78,7 +80,7 @@
<a href="/findpwd" style="color: #0d84ff">{{ $t('login.forgetPassword') }}</a>
</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') }}
</a-button>
</a-form-item>
@ -97,17 +99,19 @@
<script>
import loginApi from '@/api/auth/loginApi'
import userCenterApi from '@/api/sys/userCenterApi'
import dictApi from '@/api/dev/dictApi'
import phoneLoginForm from './phoneLoginForm.vue'
import threeLogin from './threeLogin.vue'
import smCrypto from '@/utils/smCrypto'
import { required } from '@/utils/formRules'
import { afterLogin } from './util'
export default {
name: 'Login',
components: {
phoneLoginForm,
threeLogin
},
data() {
return {
activeKey: 'userAccount',
@ -121,10 +125,10 @@
autologin: false
},
rules: {
account: [{ required: true, message: this.$t('login.accountError'), trigger: 'blur' }],
password: [{ required: true, message: this.$t('login.PWError'), trigger: 'blur' }]
account: [required(this.$t('login.accountError'), 'blur')],
password: [required(this.$t('login.PWError'), 'blur')]
},
islogin: false,
loading: false,
config: {
lang: this.$TOOL.data.get('APP_LANG') || this.$CONFIG.LANG,
theme: this.$TOOL.data.get('APP_THEME') || 'default'
@ -142,8 +146,8 @@
}
},
computed: {
sysBaseConfigWatch() {
return this.$store.state.global.sysBaseConfig
captchaOpen() {
return this.sysBaseConfig.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN === 'true'
}
},
watch: {
@ -153,10 +157,6 @@
'config.lang': function (val) {
this.$i18n.locale = val
this.$TOOL.data.set('APP_LANG', val)
},
sysBaseConfigWatch(val) {
this.sysBaseConfig = val
this.refreshSwitch()
}
},
created() {
@ -166,27 +166,16 @@
},
mounted() {
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: {
//
refreshSwitch() {
//
if (this.sysBaseConfig.SNOWY_SYS_DEFAULT_CAPTCHA_OPEN === 'true') {
if (this.captchaOpen) {
//
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() {
const validate = await this.$refs.loginForm.validate().catch(() => {})
if (!validate) return false
this.islogin = true
const loginData = {
account: this.ruleForm.account,
// SM2使hash
password: smCrypto.doSm2Encrypt(this.ruleForm.password),
validCode: this.ruleForm.validCode,
validCodeReqNo: this.ruleForm.validCodeReqNo
}
// token
const login = await loginApi.login(loginData).finally(() => {
this.islogin = 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)
})
this.$refs.loginForm.validate().then(async () => {
this.loading = true
const loginData = {
account: this.ruleForm.account,
// SM2使hash
password: smCrypto.doSm2Encrypt(this.ruleForm.password),
validCode: this.ruleForm.validCode,
validCodeReqNo: this.ruleForm.validCodeReqNo
}
// token
try {
const loginToken = await loginApi.login(loginData)
afterLogin(loginToken)
} catch (err) {
this.loading = false
}
})
},
configLang(key) {
@ -246,156 +212,6 @@
}
</script>
<style lang="less" scoped>
.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;
/* 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 lang="less">
@import 'login';
</style>

View File

@ -3,7 +3,7 @@
<a-form-item name="phone">
<a-input v-model:value="phoneFormData.phone" :placeholder="$t('login.phonePlaceholder')" size="large">
<template #prefix>
<mobile-outlined style="color: rgba(0, 0, 0, 0.25)" />
<mobile-outlined class="text-black text-opacity-25" />
</template>
</a-input>
</a-form-item>
@ -16,21 +16,21 @@
size="large"
>
<template #prefix>
<mail-outlined style="color: rgba(0, 0, 0, 0.25)" />
<mail-outlined class="text-black text-opacity-25" />
</template>
</a-input>
</a-col>
<a-col :span="7">
<a-button size="large" style="width: 100%" @click="getPhoneValidCode" :disabled="state.smsSendBtn">{{
(!state.smsSendBtn && $t('login.getSmsCode')) || state.time + ' s'
}}</a-button>
<a-button size="large" style="width: 100%" @click="getPhoneValidCode" :disabled="state.smsSendBtn">
{{ (!state.smsSendBtn && $t('login.getSmsCode')) || state.time + ' s' }}
</a-button>
</a-col>
</a-row>
</a-form-item>
<a-form-item>
<a-button type="primary" style="width: 100%" :loading="islogin" round size="large" @click="submitLogin">{{
$t('login.signIn')
}}</a-button>
<a-button type="primary" style="width: 100%" :loading="loading" round size="large" @click="submitLogin">
{{ $t('login.signIn') }}
</a-button>
</a-form-item>
</a-form>
<a-modal
@ -50,7 +50,7 @@
size="large"
>
<template #prefix>
<verified-outlined style="color: rgba(0, 0, 0, 0.25)" />
<verified-outlined class="text-black text-opacity-25" />
</template>
</a-input>
</a-col>
@ -69,16 +69,13 @@
<script setup name="smsLoginForm">
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 loginApi from '@/api/auth/loginApi'
import userCenterApi from '@/api/sys/userCenterApi'
import dictApi from '@/api/dev/dictApi'
import { afterLogin } from './util'
const phoneLoginFormRef = ref()
const phoneFormData = ref({})
const islogin = ref(false)
const loading = ref(false)
let state = ref({
time: 60,
smsSendBtn: false
@ -109,36 +106,13 @@
// delete phoneFormData.value.phoneValidCode
phoneFormData.value.validCodeReqNo = phoneValidCodeReqNo.value
islogin.value = true
const token = await loginApi.loginByPhone(phoneFormData.value).finally(() => {
islogin.value = false
})
tool.data.set('TOKEN', token)
//
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)
})
})
loading.value = true
try {
const token = await loginApi.loginByPhone(phoneFormData.value)
afterLogin(token)
} catch (err) {
loading.value = false
}
}
//

View File

@ -1,6 +1,6 @@
<template>
<a-divider>{{ $t('login.signInOther') }}</a-divider>
<div class="login-oauth">
<div class="login-oauth layout-center">
<a-space align="start">
<a @click="getLoginRenderUrl('gitee')"><GiteeIcon /></a>
<a-button type="primary" shape="circle">
@ -23,9 +23,4 @@
}
</script>
<style scoped>
.login-oauth {
display: flex;
justify-content: center;
}
</style>
<style scoped></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>
<script setup name="sysModule">
import { message } from 'ant-design-vue'
import Form from './form.vue'
import configApi from '@/api/dev/configApi'
let searchFormState = reactive({})
@ -87,7 +86,7 @@
let params = {
id: record.id
}
configApi.configDetail(params).then(() => {
configApi.configDelete(params).then(() => {
table.value.refresh(true)
})
}

View File

@ -192,31 +192,31 @@
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 = {

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" +
File.separator + "main" + File.separator + "java";
if(!FileUtil.exist(genProjectFrontendPath)) {
if(!FileUtil.exist(genProjectBackendPath)) {
throw new CommonException("后端代码生成位置:{}不存在,请检查位置", genProjectBackendPath);
}
try {

View File

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

View File

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