mirror of
https://gitee.com/xiaonuobase/snowy.git
synced 2026-03-22 10:47:16 +08:00
【优化】优化前端打包、表格组件、按需引入、模块选中问题修复
This commit is contained in:
@@ -51,7 +51,6 @@
|
|||||||
"sm-crypto": "0.3.13",
|
"sm-crypto": "0.3.13",
|
||||||
"snowflake-id": "1.1.0",
|
"snowflake-id": "1.1.0",
|
||||||
"sortablejs": "1.15.3",
|
"sortablejs": "1.15.3",
|
||||||
"tinymce": "7.3.0",
|
|
||||||
"vue": "3.5.13",
|
"vue": "3.5.13",
|
||||||
"vue-cropper": "1.1.4",
|
"vue-cropper": "1.1.4",
|
||||||
"vue-i18n": "10.0.0",
|
"vue-i18n": "10.0.0",
|
||||||
|
|||||||
@@ -93,6 +93,7 @@
|
|||||||
v-bind="{ ...renderTableProps }"
|
v-bind="{ ...renderTableProps }"
|
||||||
:loading="data.localLoading"
|
:loading="data.localLoading"
|
||||||
@change="loadData"
|
@change="loadData"
|
||||||
|
@resizeColumn="handleResize"
|
||||||
@expand="
|
@expand="
|
||||||
(expanded, record) => {
|
(expanded, record) => {
|
||||||
emit('onExpand', expanded, record)
|
emit('onExpand', expanded, record)
|
||||||
@@ -102,6 +103,10 @@
|
|||||||
(record, index) => (data.localSettings.rowClassNameSwitch ? ((index + 1) % 2 == 0 ? 'odd' : '') : null)
|
(record, index) => (data.localSettings.rowClassNameSwitch ? ((index + 1) % 2 == 0 ? 'odd' : '') : null)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
<template #headerCell="{ title, column }">
|
||||||
|
<slot v-if="slots.headerCell" name="headerCell" :column="column" :title="title"></slot>
|
||||||
|
<template v-else>{{ title }}</template>
|
||||||
|
</template>
|
||||||
<template #[item]="scope" v-for="item in renderSlots">
|
<template #[item]="scope" v-for="item in renderSlots">
|
||||||
<slot
|
<slot
|
||||||
v-if="item && renderTableProps.columns && renderTableProps.columns.length > 0"
|
v-if="item && renderTableProps.columns && renderTableProps.columns.length > 0"
|
||||||
@@ -123,7 +128,8 @@
|
|||||||
const slots = useSlots()
|
const slots = useSlots()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const emit = defineEmits(['onExpand', 'onSelectionChange'])
|
const emit = defineEmits(['onExpand', 'onSelectionChange'])
|
||||||
const renderSlots = Object.keys(slots)
|
// 过滤掉headerCell插槽,因为我们显式定义了它
|
||||||
|
const renderSlots = computed(() => Object.keys(slots).filter((key) => key !== 'headerCell'))
|
||||||
|
|
||||||
// 是否存在 operator 插槽内容(过滤掉空白、注释、空 Fragment)
|
// 是否存在 operator 插槽内容(过滤掉空白、注释、空 Fragment)
|
||||||
const hasOperatorContent = computed(() => {
|
const hasOperatorContent = computed(() => {
|
||||||
@@ -237,6 +243,7 @@
|
|||||||
const data = reactive({
|
const data = reactive({
|
||||||
needTotalList: [],
|
needTotalList: [],
|
||||||
localDataSource: [],
|
localDataSource: [],
|
||||||
|
localColumns: null,
|
||||||
localPagination: Object.assign({}, props.pagination),
|
localPagination: Object.assign({}, props.pagination),
|
||||||
isFullscreen: false,
|
isFullscreen: false,
|
||||||
customSize: props.compSize,
|
customSize: props.compSize,
|
||||||
@@ -312,6 +319,7 @@
|
|||||||
...col,
|
...col,
|
||||||
checked: col.checked === undefined ? true : col.checked
|
checked: col.checked === undefined ? true : col.checked
|
||||||
}))
|
}))
|
||||||
|
data.localColumns = data.columnsSetting.filter((value) => value.checked === undefined || value.checked)
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
)
|
)
|
||||||
@@ -453,6 +461,14 @@
|
|||||||
data.localColumns = v.filter((value) => value.checked === undefined || value.checked)
|
data.localColumns = v.filter((value) => value.checked === undefined || value.checked)
|
||||||
getTableProps() // 调用getTableProps以确保表格重新渲染
|
getTableProps() // 调用getTableProps以确保表格重新渲染
|
||||||
}
|
}
|
||||||
|
// 列拖拽
|
||||||
|
const handleResize = (width, column) => {
|
||||||
|
column.width = width
|
||||||
|
// 强制更新列数组引用,触发表格重渲染
|
||||||
|
if (data.localColumns) {
|
||||||
|
data.localColumns = [...data.localColumns]
|
||||||
|
}
|
||||||
|
}
|
||||||
const init = () => {
|
const init = () => {
|
||||||
const { current } = route.params
|
const { current } = route.params
|
||||||
const localPageNum = (current && parseInt(current)) || props.pageNum
|
const localPageNum = (current && parseInt(current)) || props.pageNum
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import Antd from 'ant-design-vue'
|
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
|
|
||||||
import './style/index.less'
|
import './style/index.less'
|
||||||
@@ -11,7 +10,6 @@ import './tailwind.css'
|
|||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
app.use(createPinia())
|
app.use(createPinia())
|
||||||
app.use(Antd)
|
|
||||||
app.use(i18n)
|
app.use(i18n)
|
||||||
app.use(snowy)
|
app.use(snowy)
|
||||||
app.use(router)
|
app.use(router)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<div class="login-form">
|
<div class="login-form">
|
||||||
<a-card>
|
<a-card>
|
||||||
<div class="login-header">
|
<div class="login-header">
|
||||||
<h2>{{tipText}}</h2>
|
<h2>{{ tipText }}</h2>
|
||||||
</div>
|
</div>
|
||||||
<a-spin :tip="tipText" v-if="showLoading">
|
<a-spin :tip="tipText" v-if="showLoading">
|
||||||
<div class="h-[300px]">
|
<div class="h-[300px]">
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<a-button type="primary" class="w-full" :loading="loading" round size="large" @click="bindAccount"
|
<a-button type="primary" class="w-full" :loading="loading" round size="large" @click="bindAccount"
|
||||||
>{{ $t('login.bindAccount') }}
|
>{{ $t('login.bindAccount') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
@@ -93,11 +93,11 @@
|
|||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
import thirdApi from '@/api/auth/thirdApi'
|
import thirdApi from '@/api/auth/thirdApi'
|
||||||
import { globalStore } from '@/store'
|
import { globalStore } from '@/store'
|
||||||
import {afterLogin} from "@/views/auth/login/util";
|
import { afterLogin } from '@/views/auth/login/util'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import {required} from "@/utils/formRules";
|
import { required } from '@/utils/formRules'
|
||||||
import tool from "@/utils/tool";
|
import tool from '@/utils/tool'
|
||||||
import loginApi from "@/api/auth/loginApi";
|
import loginApi from '@/api/auth/loginApi'
|
||||||
import smCrypto from '@/utils/smCrypto'
|
import smCrypto from '@/utils/smCrypto'
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
const route = router.currentRoute.value
|
const route = router.currentRoute.value
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
const showError = (msg, alert) => {
|
const showError = (msg, alert) => {
|
||||||
if(alert) {
|
if (alert) {
|
||||||
message.error(msg)
|
message.error(msg)
|
||||||
}
|
}
|
||||||
tipText.value = msg
|
tipText.value = msg
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if(!route.params.platform) {
|
if (!route.params.platform) {
|
||||||
showError(proxy.$t('login.paramError'), true)
|
showError(proxy.$t('login.paramError'), true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
.then(async (data) => {
|
.then(async (data) => {
|
||||||
if (data.startsWith('needBind')) {
|
if (data.startsWith('needBind')) {
|
||||||
showError(proxy.$t('login.bindAccount'), true)
|
showError(proxy.$t('login.bindAccount'), true)
|
||||||
thirdId.value = data.split(":")[1];
|
thirdId.value = data.split(':')[1]
|
||||||
showBind.value = true
|
showBind.value = true
|
||||||
refreshSwitch()
|
refreshSwitch()
|
||||||
} else {
|
} else {
|
||||||
@@ -210,8 +210,8 @@
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
if (captchaOpen.value === 'true') {
|
if (captchaOpen.value === 'true') {
|
||||||
loginCaptcha()
|
loginCaptcha()
|
||||||
}}
|
}
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
// logo链接
|
// logo链接
|
||||||
const handleLink = (e) => {
|
const handleLink = (e) => {
|
||||||
|
|||||||
@@ -10,7 +10,11 @@
|
|||||||
<a-form-item name="emailValidCode">
|
<a-form-item name="emailValidCode">
|
||||||
<a-row :gutter="8">
|
<a-row :gutter="8">
|
||||||
<a-col :span="16">
|
<a-col :span="16">
|
||||||
<a-input v-model:value="emailFormData.emailValidCode" :placeholder="$t('login.emailCodePlaceholder')" size="large">
|
<a-input
|
||||||
|
v-model:value="emailFormData.emailValidCode"
|
||||||
|
:placeholder="$t('login.emailCodePlaceholder')"
|
||||||
|
size="large"
|
||||||
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<mail-outlined class="text-black text-opacity-25" />
|
<mail-outlined class="text-black text-opacity-25" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -104,10 +104,20 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="userSms" :tab="$t('login.phoneLogin')" force-render v-if="loginTypes.phoneLogin === 'true'">
|
<a-tab-pane
|
||||||
|
key="userSms"
|
||||||
|
:tab="$t('login.phoneLogin')"
|
||||||
|
force-render
|
||||||
|
v-if="loginTypes.phoneLogin === 'true'"
|
||||||
|
>
|
||||||
<phone-login-form />
|
<phone-login-form />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="userEmail" :tab="$t('login.emailLogin')" force-render v-if="loginTypes.emailLogin === 'true'">
|
<a-tab-pane
|
||||||
|
key="userEmail"
|
||||||
|
:tab="$t('login.emailLogin')"
|
||||||
|
force-render
|
||||||
|
v-if="loginTypes.emailLogin === 'true'"
|
||||||
|
>
|
||||||
<email-login-form />
|
<email-login-form />
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="userOtp" :tab="$t('login.otpLogin')" force-render v-if="loginTypes.otpLogin === 'true'">
|
<a-tab-pane key="userOtp" :tab="$t('login.otpLogin')" force-render v-if="loginTypes.otpLogin === 'true'">
|
||||||
@@ -118,12 +128,14 @@
|
|||||||
<a href="/front/client/index" class="xn-color-0d84ff">{{ $t('login.frontLogin') }}</a>
|
<a href="/front/client/index" class="xn-color-0d84ff">{{ $t('login.frontLogin') }}</a>
|
||||||
</div>
|
</div>
|
||||||
<three-login v-if="configData.THREE_LOGIN_SHOW && !appId" />
|
<three-login v-if="configData.THREE_LOGIN_SHOW && !appId" />
|
||||||
<three-login-for-app ref="threeLoginForAppRef"
|
<three-login-for-app
|
||||||
v-if="configData.THREE_LOGIN_SHOW && appId"
|
ref="threeLoginForAppRef"
|
||||||
:appId="appId"
|
v-if="configData.THREE_LOGIN_SHOW && appId"
|
||||||
:loginTypes="loginTypes"
|
:appId="appId"
|
||||||
@updateLoginTypes="updateLoginTypes"
|
:loginTypes="loginTypes"
|
||||||
@updateSystemName="updateSystemName"/>
|
@updateLoginTypes="updateLoginTypes"
|
||||||
|
@updateSystemName="updateSystemName"
|
||||||
|
/>
|
||||||
</a-card>
|
</a-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -297,8 +309,8 @@
|
|||||||
loading.value = false
|
loading.value = false
|
||||||
if (captchaOpen.value === 'true') {
|
if (captchaOpen.value === 'true') {
|
||||||
loginCaptcha()
|
loginCaptcha()
|
||||||
}}
|
}
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
const configLang = (key) => {
|
const configLang = (key) => {
|
||||||
config.value.lang = key
|
config.value.lang = key
|
||||||
|
|||||||
@@ -17,11 +17,7 @@
|
|||||||
<a-form-item name="validCodeForOtp" v-if="captchaOpen === 'true'">
|
<a-form-item name="validCodeForOtp" v-if="captchaOpen === 'true'">
|
||||||
<a-row :gutter="8">
|
<a-row :gutter="8">
|
||||||
<a-col :span="17">
|
<a-col :span="17">
|
||||||
<a-input
|
<a-input v-model:value="ruleForm.validCodeForOtp" :placeholder="$t('login.validPlaceholder')" size="large">
|
||||||
v-model:value="ruleForm.validCodeForOtp"
|
|
||||||
:placeholder="$t('login.validPlaceholder')"
|
|
||||||
size="large"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<verified-outlined class="login-icon-gray" />
|
<verified-outlined class="login-icon-gray" />
|
||||||
</template>
|
</template>
|
||||||
@@ -43,7 +39,7 @@
|
|||||||
<script setup name="otpLoginForm">
|
<script setup name="otpLoginForm">
|
||||||
import loginApi from '@/api/auth/loginApi'
|
import loginApi from '@/api/auth/loginApi'
|
||||||
import { afterLogin } from './util'
|
import { afterLogin } from './util'
|
||||||
import {required} from "@/utils/formRules";
|
import { required } from '@/utils/formRules'
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
captchaOpen: {
|
captchaOpen: {
|
||||||
@@ -105,7 +101,8 @@
|
|||||||
.loginByOtp(loginData)
|
.loginByOtp(loginData)
|
||||||
.then(async (loginToken) => {
|
.then(async (loginToken) => {
|
||||||
await afterLogin(loginToken)
|
await afterLogin(loginToken)
|
||||||
}).catch(() => {
|
})
|
||||||
|
.catch(() => {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
if (props.captchaOpen === 'true') {
|
if (props.captchaOpen === 'true') {
|
||||||
loginCaptcha()
|
loginCaptcha()
|
||||||
|
|||||||
@@ -3,17 +3,17 @@
|
|||||||
<div class="login-oauth layout-center">
|
<div class="login-oauth layout-center">
|
||||||
<a-space align="start">
|
<a-space align="start">
|
||||||
<a v-if="formData.SNOWY_THIRD_IAM_ALLOW_LOGIN_FLAG" @click="getLoginRenderUrl('IAM')">
|
<a v-if="formData.SNOWY_THIRD_IAM_ALLOW_LOGIN_FLAG" @click="getLoginRenderUrl('IAM')">
|
||||||
<img style="width: 32px; height: 32px;" src="/src/assets/images/authSource/iam.png" alt="" />
|
<img style="width: 32px; height: 32px" src="/src/assets/images/authSource/iam.png" alt="" />
|
||||||
</a>
|
</a>
|
||||||
<a v-if="formData.SNOWY_THIRD_WECHAT_ALLOW_LOGIN_FLAG" @click="getLoginRenderUrl('WECHAT')">
|
<a v-if="formData.SNOWY_THIRD_WECHAT_ALLOW_LOGIN_FLAG" @click="getLoginRenderUrl('WECHAT')">
|
||||||
<img style="width: 32px; height: 32px;" src="/src/assets/images/authSource/wechat.png" alt="" />
|
<img style="width: 32px; height: 32px" src="/src/assets/images/authSource/wechat.png" alt="" />
|
||||||
</a>
|
</a>
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="threeLogin">
|
<script setup name="threeLogin">
|
||||||
import configApi from "@/api/dev/configApi";
|
import configApi from '@/api/dev/configApi'
|
||||||
import thirdApi from '@/api/auth/thirdApi'
|
import thirdApi from '@/api/auth/thirdApi'
|
||||||
const formData = ref({})
|
const formData = ref({})
|
||||||
const getConfigSysThirdAllowFlagList = () => {
|
const getConfigSysThirdAllowFlagList = () => {
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
window.location.href = data.authorizeUrl
|
window.location.href = data.authorizeUrl
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
getConfigSysThirdAllowFlagList();
|
getConfigSysThirdAllowFlagList()
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.bind-icon {
|
.bind-icon {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="login-oauth layout-center">
|
<div class="login-oauth layout-center">
|
||||||
<a-space align="start">
|
<a-space align="start">
|
||||||
<a @click="renderAuthSource(record)" v-for="record in appAuthSourceList" :key="record.authSourceId">
|
<a @click="renderAuthSource(record)" v-for="record in appAuthSourceList" :key="record.authSourceId">
|
||||||
<img :src="record.authSourceLogo" class="record-img"/>
|
<img :src="record.authSourceLogo" class="record-img" />
|
||||||
</a>
|
</a>
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
@@ -59,8 +59,8 @@
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.record-img {
|
.record-img {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { message } from 'ant-design-vue'
|
|||||||
import routerUtil from '@/utils/routerUtil'
|
import routerUtil from '@/utils/routerUtil'
|
||||||
import { useMenuStore } from '@/store/menu'
|
import { useMenuStore } from '@/store/menu'
|
||||||
import { useUserStore } from '@/store/user'
|
import { useUserStore } from '@/store/user'
|
||||||
|
import { globalStore } from '@/store'
|
||||||
|
|
||||||
export const afterLogin = async (loginToken) => {
|
export const afterLogin = async (loginToken) => {
|
||||||
const route = router.currentRoute.value
|
const route = router.currentRoute.value
|
||||||
@@ -21,6 +22,7 @@ export const afterLogin = async (loginToken) => {
|
|||||||
|
|
||||||
// 重置系统默认应用
|
// 重置系统默认应用
|
||||||
tool.data.set('SNOWY_MENU_MODULE_ID', menu[0].id)
|
tool.data.set('SNOWY_MENU_MODULE_ID', menu[0].id)
|
||||||
|
globalStore().setModule(menu[0].id)
|
||||||
|
|
||||||
if (tool.data.get('LAST_VIEWS_PATH')) {
|
if (tool.data.get('LAST_VIEWS_PATH')) {
|
||||||
// 如果有缓存,将其登录跳转到最后访问的路由
|
// 如果有缓存,将其登录跳转到最后访问的路由
|
||||||
@@ -47,38 +49,40 @@ export const afterLogin = async (loginToken) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 此处判断是否存在跳转页面,如存在则跳转,否则走原来逻辑
|
// 此处判断是否存在跳转页面,如存在则跳转,否则走原来逻辑
|
||||||
if(route.query.redirect_uri) {
|
if (route.query.redirect_uri) {
|
||||||
// 跳转到回调页
|
// 跳转到回调页
|
||||||
message.success('登录成功,即将跳转...')
|
message.success('登录成功,即将跳转...')
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
window.location.href = route.query.redirect_uri;
|
window.location.href = route.query.redirect_uri
|
||||||
}, 500);
|
}, 500)
|
||||||
} else if(route.query.redirect) {
|
} else if (route.query.redirect) {
|
||||||
// 跳转到回调页
|
// 跳转到回调页
|
||||||
message.success('登录成功,即将跳转...')
|
message.success('登录成功,即将跳转...')
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
window.location.href = route.query.redirect;
|
window.location.href = route.query.redirect
|
||||||
}, 500);
|
}, 500)
|
||||||
} else if(route.query.back) {
|
} else if (route.query.back) {
|
||||||
// 跳转到回调页
|
// 跳转到回调页
|
||||||
message.success('登录成功,即将跳转...')
|
message.success('登录成功,即将跳转...')
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
window.location.href = route.query.back;
|
window.location.href = route.query.back
|
||||||
}, 500);
|
}, 500)
|
||||||
} else {
|
} else {
|
||||||
message.success('登录成功,即将跳转...')
|
message.success('登录成功,即将跳转...')
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
// 跳转到首页
|
// 跳转到首页
|
||||||
router.replace({
|
router
|
||||||
path: indexMenu
|
.replace({
|
||||||
}).then(() => {
|
path: indexMenu
|
||||||
// 判断用户密码是否过期
|
|
||||||
userCenterApi.userCenterIsUserPasswordExpired().then((expired) => {
|
|
||||||
if (expired) {
|
|
||||||
message.warning('当前登录密码已过期,请及时更改!')
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
.then(() => {
|
||||||
}, 500);
|
// 判断用户密码是否过期
|
||||||
|
userCenterApi.userCenterIsUserPasswordExpired().then((expired) => {
|
||||||
|
if (expired) {
|
||||||
|
message.warning('当前登录密码已过期,请及时更改!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}, 500)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,90 +20,90 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="ssoLogin">
|
<script setup name="ssoLogin">
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from 'vue-router'
|
||||||
import ssoApi from "@/api/auth/ssoApi";
|
import ssoApi from '@/api/auth/ssoApi'
|
||||||
import { afterLogin } from "@/views/auth/login/util";
|
import { afterLogin } from '@/views/auth/login/util'
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue'
|
||||||
import tool from "@/utils/tool";
|
import tool from '@/utils/tool'
|
||||||
import loginApi from "@/api/auth/loginApi";
|
import loginApi from '@/api/auth/loginApi'
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute()
|
||||||
const tipText = ref('加载中...');
|
const tipText = ref('加载中...')
|
||||||
const loading = ref(true); // 新增加载状态控制
|
const loading = ref(true) // 新增加载状态控制
|
||||||
|
|
||||||
// 从url中查询到指定名称的参数值
|
// 从url中查询到指定名称的参数值
|
||||||
const getParam = (name, defaultValue) => {
|
const getParam = (name, defaultValue) => {
|
||||||
const query = window.location.search.substring(1);
|
const query = window.location.search.substring(1)
|
||||||
const vars = query.split("&");
|
const vars = query.split('&')
|
||||||
for (let i = 0; i < vars.length; i++) {
|
for (let i = 0; i < vars.length; i++) {
|
||||||
const pair = vars[i].split("=");
|
const pair = vars[i].split('=')
|
||||||
if (pair[0] === name) {
|
if (pair[0] === name) {
|
||||||
return pair[1];
|
return pair[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return defaultValue === undefined ? null : defaultValue;
|
return defaultValue === undefined ? null : defaultValue
|
||||||
};
|
}
|
||||||
|
|
||||||
const ticket = getParam('ticket') || route.query.ticket;
|
const ticket = getParam('ticket') || route.query.ticket
|
||||||
|
|
||||||
// 生命周期
|
// 生命周期
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await tryJump();
|
await tryJump()
|
||||||
});
|
})
|
||||||
|
|
||||||
// 跳转
|
// 跳转
|
||||||
const tryJump = async () => {
|
const tryJump = async () => {
|
||||||
// 重置加载状态
|
// 重置加载状态
|
||||||
loading.value = true;
|
loading.value = true
|
||||||
tipText.value = '加载中...';
|
tipText.value = '加载中...'
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let existToken = tool.data.get('TOKEN');
|
let existToken = tool.data.get('TOKEN')
|
||||||
if (existToken) {
|
if (existToken) {
|
||||||
const isLogin = await loginApi.isLogin();
|
const isLogin = await loginApi.isLogin()
|
||||||
if (isLogin) {
|
if (isLogin) {
|
||||||
await goHome(existToken);
|
await goHome(existToken)
|
||||||
} else {
|
} else {
|
||||||
await redirectSsoAuthUrl(window.location.href);
|
await redirectSsoAuthUrl(window.location.href)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ticket) {
|
if (ticket) {
|
||||||
await doLoginByTicket(ticket);
|
await doLoginByTicket(ticket)
|
||||||
} else {
|
} else {
|
||||||
await redirectSsoAuthUrl(window.location.href);
|
await redirectSsoAuthUrl(window.location.href)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
loading.value = false;
|
loading.value = false
|
||||||
tipText.value = '处理失败,请重试';
|
tipText.value = '处理失败,请重试'
|
||||||
console.error('SSO登录失败:', error);
|
console.error('SSO登录失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跳转首页
|
// 跳转首页
|
||||||
const goHome = async (loginToken) => {
|
const goHome = async (loginToken) => {
|
||||||
tipText.value = '验证成功,即将跳转...';
|
tipText.value = '验证成功,即将跳转...'
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await afterLogin(loginToken);
|
await afterLogin(loginToken)
|
||||||
}, 500);
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理SSO登录回调
|
// 处理SSO登录回调
|
||||||
const doLoginByTicket = async (ticket) => {
|
const doLoginByTicket = async (ticket) => {
|
||||||
const loginToken = await ssoApi.doLoginByTicket({ ticket: ticket });
|
const loginToken = await ssoApi.doLoginByTicket({ ticket: ticket })
|
||||||
tipText.value = '验证成功,即将跳转...';
|
tipText.value = '验证成功,即将跳转...'
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await afterLogin(loginToken);
|
await afterLogin(loginToken)
|
||||||
}, 500);
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重定向到SSO登录页
|
// 重定向到SSO登录页
|
||||||
const redirectSsoAuthUrl = async (redirectUrl) => {
|
const redirectSsoAuthUrl = async (redirectUrl) => {
|
||||||
const authUrl = await ssoApi.getSsoAuthUrl({ redirectUrl: redirectUrl });
|
const authUrl = await ssoApi.getSsoAuthUrl({ redirectUrl: redirectUrl })
|
||||||
tipText.value = '即将跳转至SSO登录页...';
|
tipText.value = '即将跳转至SSO登录页...'
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = authUrl;
|
window.location.href = authUrl
|
||||||
}, 500);
|
}, 500)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -199,6 +199,8 @@
|
|||||||
|
|
||||||
/* 旋转动画 */
|
/* 旋转动画 */
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
to { transform: rotate(360deg); }
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { resolve } from 'path'
|
|||||||
import { defineConfig, loadEnv } from 'vite'
|
import { defineConfig, loadEnv } from 'vite'
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
import Components from 'unplugin-vue-components/vite'
|
import Components from 'unplugin-vue-components/vite'
|
||||||
|
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
|
||||||
import VueJSX from '@vitejs/plugin-vue-jsx'
|
import VueJSX from '@vitejs/plugin-vue-jsx'
|
||||||
import AutoImport from 'unplugin-auto-import/vite'
|
import AutoImport from 'unplugin-auto-import/vite'
|
||||||
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
|
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
|
||||||
@@ -87,7 +88,6 @@ export default defineConfig(({ command, mode }) => {
|
|||||||
// 第三方库分包配置保持不变
|
// 第三方库分包配置保持不变
|
||||||
'vue-vendor': ['vue', 'vue-router', 'pinia', 'vue-i18n'],
|
'vue-vendor': ['vue', 'vue-router', 'pinia', 'vue-i18n'],
|
||||||
'ant-design-vendor': ['ant-design-vue', '@ant-design/icons-vue', 'lodash-es', 'axios', 'dayjs'],
|
'ant-design-vendor': ['ant-design-vue', '@ant-design/icons-vue', 'lodash-es', 'axios', 'dayjs'],
|
||||||
'echarts-vendor': ['echarts', 'echarts-stat'],
|
|
||||||
'office-vendor': ['@vue-office/docx', 'vue-pdf-embed', '@vue-office/excel']
|
'office-vendor': ['@vue-office/docx', 'vue-pdf-embed', '@vue-office/excel']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,18 +110,15 @@ export default defineConfig(({ command, mode }) => {
|
|||||||
dts: r('src/auto-imports.d.ts')
|
dts: r('src/auto-imports.d.ts')
|
||||||
}),
|
}),
|
||||||
// 组件按需引入
|
// 组件按需引入
|
||||||
Components(
|
Components({
|
||||||
{
|
dirs: [r('src/components'), r('src/components/HomeCard')],
|
||||||
dirs: [r('src/components')],
|
dts: false,
|
||||||
dts: false,
|
resolvers: [
|
||||||
resolvers: []
|
AntDesignVueResolver({
|
||||||
},
|
importStyle: false // css in js
|
||||||
{
|
})
|
||||||
dirs: [r('src/components/HomeCard')],
|
]
|
||||||
dts: false,
|
}),
|
||||||
resolvers: []
|
|
||||||
}
|
|
||||||
),
|
|
||||||
visualizer()
|
visualizer()
|
||||||
],
|
],
|
||||||
css: {
|
css: {
|
||||||
|
|||||||
@@ -27,18 +27,18 @@ export default {
|
|||||||
},
|
},
|
||||||
// 下载${functionName}导入模板
|
// 下载${functionName}导入模板
|
||||||
${classNameFirstLower}DownloadTemplate(data) {
|
${classNameFirstLower}DownloadTemplate(data) {
|
||||||
return request('downloadImportTemplate', data, 'get', {
|
return request('downloadImportTemplate', data, 'get', {
|
||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 导入${functionName}
|
// 导入${functionName}
|
||||||
${classNameFirstLower}Import(data) {
|
${classNameFirstLower}Import(data) {
|
||||||
return request('importData', data)
|
return request('importData', data)
|
||||||
},
|
},
|
||||||
// 导出${functionName}
|
// 导出${functionName}
|
||||||
${classNameFirstLower}Export(data) {
|
${classNameFirstLower}Export(data) {
|
||||||
return request('exportData', data, 'post', {
|
return request('exportData', data, 'post', {
|
||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<% for(var i = 0; i < configList.~size; i++) { %>
|
<% for(var i = 0; i < configList.~size; i++) { %>
|
||||||
<% if(!configList[i].needTableId && configList[i].needPage) { searchCount ++; }%>
|
<% if(!configList[i].needTableId && configList[i].needPage) { searchCount ++; }%>
|
||||||
<% } %>
|
<% } %>
|
||||||
<a-card :bordered="false" style="width: 100%">
|
<xn-panel>
|
||||||
<% if (searchCount > 0) { %>
|
<% if (searchCount > 0) { %>
|
||||||
<a-form ref="searchFormRef" :model="searchFormState">
|
<a-form ref="searchFormRef" :model="searchFormState">
|
||||||
<a-row :gutter="10">
|
<a-row :gutter="10">
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</s-table>
|
</s-table>
|
||||||
</a-card>
|
</xn-panel>
|
||||||
<ImportModel ref="importModelRef" />
|
<ImportModel ref="importModelRef" />
|
||||||
<Form ref="formRef" @successful="tableRef.refresh()" />
|
<Form ref="formRef" @successful="tableRef.refresh()" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user