【优化】优化前端打包、表格组件、按需引入、模块选中问题修复

This commit is contained in:
俞宝山
2025-12-23 21:53:32 +08:00
parent 6b7d2ecbed
commit e4de5d5d2c
14 changed files with 159 additions and 130 deletions

View File

@@ -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",

View File

@@ -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

View File

@@ -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)

View File

@@ -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) => {

View File

@@ -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>

View File

@@ -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

View File

@@ -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()

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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)
} }
} }

View File

@@ -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>

View File

@@ -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: {

View File

@@ -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'
}) })
} }
} }

View File

@@ -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>