Merge branch 'dev' of https://gitee.com/xlsea/ruoyi-plus-soybean into flow
This commit is contained in:
commit
188533adc9
48
package.json
48
package.json
@ -57,7 +57,8 @@
|
||||
"@sa/materials": "workspace:*",
|
||||
"@sa/tinymce": "workspace:*",
|
||||
"@sa/utils": "workspace:*",
|
||||
"@vueuse/core": "13.3.0",
|
||||
"@types/streamsaver": "^2.0.5",
|
||||
"@vueuse/core": "13.4.0",
|
||||
"clipboard": "2.0.11",
|
||||
"dayjs": "1.11.13",
|
||||
"defu": "6.1.4",
|
||||
@ -65,50 +66,51 @@
|
||||
"highlight.js": "^11.11.1",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"json5": "2.2.3",
|
||||
"monaco-editor": "^0.52.0",
|
||||
"naive-ui": "2.41.1",
|
||||
"monaco-editor": "^0.52.2",
|
||||
"naive-ui": "2.42.0",
|
||||
"nprogress": "0.2.0",
|
||||
"pinia": "3.0.3",
|
||||
"tailwind-merge": "3.3.0",
|
||||
"vue": "3.5.16",
|
||||
"streamsaver": "^2.0.6",
|
||||
"tailwind-merge": "3.3.1",
|
||||
"vue": "3.5.17",
|
||||
"vue-advanced-cropper": "^2.8.9",
|
||||
"vue-draggable-plus": "0.6.0",
|
||||
"vue-i18n": "11.1.5",
|
||||
"vue-i18n": "11.1.7",
|
||||
"vue-router": "4.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@elegant-router/vue": "0.3.8",
|
||||
"@iconify/json": "2.2.347",
|
||||
"@iconify/json": "2.2.352",
|
||||
"@sa/scripts": "workspace:*",
|
||||
"@sa/uno-preset": "workspace:*",
|
||||
"@soybeanjs/eslint-config": "1.6.1",
|
||||
"@types/node": "22.15.30",
|
||||
"@types/node": "24.0.4",
|
||||
"@types/nprogress": "0.2.3",
|
||||
"@unocss/eslint-config": "66.1.4",
|
||||
"@unocss/preset-icons": "66.1.4",
|
||||
"@unocss/preset-uno": "66.1.4",
|
||||
"@unocss/transformer-directives": "66.1.4",
|
||||
"@unocss/transformer-variant-group": "66.1.4",
|
||||
"@unocss/vite": "66.1.4",
|
||||
"@vitejs/plugin-vue": "5.2.4",
|
||||
"@vitejs/plugin-vue-jsx": "4.2.0",
|
||||
"@unocss/eslint-config": "66.2.3",
|
||||
"@unocss/preset-icons": "66.2.3",
|
||||
"@unocss/preset-uno": "66.2.3",
|
||||
"@unocss/transformer-directives": "66.2.3",
|
||||
"@unocss/transformer-variant-group": "66.2.3",
|
||||
"@unocss/vite": "66.2.3",
|
||||
"@vitejs/plugin-vue": "6.0.0",
|
||||
"@vitejs/plugin-vue-jsx": "5.0.0",
|
||||
"consola": "3.4.2",
|
||||
"eslint": "9.28.0",
|
||||
"eslint": "9.29.0",
|
||||
"eslint-plugin-vue": "10.2.0",
|
||||
"kolorist": "1.8.0",
|
||||
"sass": "1.89.1",
|
||||
"sass": "1.89.2",
|
||||
"simple-git-hooks": "2.13.0",
|
||||
"tsx": "4.19.4",
|
||||
"tsx": "4.20.3",
|
||||
"typescript": "5.8.3",
|
||||
"unplugin-icons": "22.1.0",
|
||||
"unplugin-vue-components": "28.7.0",
|
||||
"vite": "6.3.5",
|
||||
"vite": "7.0.0",
|
||||
"vite-plugin-monaco-editor": "^1.1.0",
|
||||
"vite-plugin-progress": "0.0.7",
|
||||
"vite-plugin-static-copy": "^3.0.0",
|
||||
"vite-plugin-static-copy": "^3.0.2",
|
||||
"vite-plugin-svg-icons": "2.0.1",
|
||||
"vite-plugin-vue-devtools": "7.7.6",
|
||||
"vue-eslint-parser": "10.1.3",
|
||||
"vite-plugin-vue-devtools": "7.7.7",
|
||||
"vue-eslint-parser": "10.1.4",
|
||||
"vue-tsc": "2.2.10"
|
||||
},
|
||||
"simple-git-hooks": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/alova",
|
||||
"version": "1.3.14",
|
||||
"version": "1.3.15",
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./fetch": "./src/fetch.ts",
|
||||
@ -13,8 +13,8 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@alova/mock": "2.0.16",
|
||||
"@alova/mock": "2.0.17",
|
||||
"@sa/utils": "workspace:*",
|
||||
"alova": "3.3.0"
|
||||
"alova": "3.3.3"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/axios",
|
||||
"version": "1.3.14",
|
||||
"version": "1.3.15",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
@ -11,7 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@sa/utils": "workspace:*",
|
||||
"axios": "1.9.0",
|
||||
"axios": "1.10.0",
|
||||
"axios-retry": "4.5.0",
|
||||
"qs": "6.14.0"
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/color",
|
||||
"version": "1.3.14",
|
||||
"version": "1.3.15",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/hooks",
|
||||
"version": "1.3.14",
|
||||
"version": "1.3.15",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/materials",
|
||||
"version": "1.3.14",
|
||||
"version": "1.3.15",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/fetch",
|
||||
"version": "1.3.14",
|
||||
"version": "1.3.15",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/scripts",
|
||||
"version": "1.3.14",
|
||||
"version": "1.3.15",
|
||||
"bin": {
|
||||
"sa": "./bin.ts"
|
||||
},
|
||||
@ -14,7 +14,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@soybeanjs/changelog": "0.3.24",
|
||||
"bumpp": "10.1.1",
|
||||
"bumpp": "10.2.0",
|
||||
"c12": "3.0.4",
|
||||
"cac": "6.7.14",
|
||||
"consola": "3.4.2",
|
||||
|
@ -10,9 +10,9 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"tinymce": "7.8.0"
|
||||
"tinymce": "7.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tinymce/tinymce-vue": "6.1.0"
|
||||
"@tinymce/tinymce-vue": "6.2.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/uno-preset",
|
||||
"version": "1.3.14",
|
||||
"version": "1.3.15",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sa/utils",
|
||||
"version": "1.3.14",
|
||||
"version": "1.3.15",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
|
3085
pnpm-lock.yaml
3085
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -4,8 +4,8 @@ import { NConfigProvider, darkTheme } from 'naive-ui';
|
||||
import type { WatermarkProps } from 'naive-ui';
|
||||
import { useAppStore } from './store/modules/app';
|
||||
import { useThemeStore } from './store/modules/theme';
|
||||
import { naiveDateLocales, naiveLocales } from './locales/naive';
|
||||
import { useAuthStore } from './store/modules/auth';
|
||||
import { naiveDateLocales, naiveLocales } from './locales/naive';
|
||||
|
||||
defineOptions({
|
||||
name: 'App'
|
||||
@ -27,8 +27,12 @@ const naiveDateLocale = computed(() => {
|
||||
|
||||
const watermarkProps = computed<WatermarkProps>(() => {
|
||||
const appTitle = import.meta.env.VITE_APP_TITLE || 'RuoYi-Vue-Plus';
|
||||
const content =
|
||||
themeStore.watermark.enableUserName && userInfo.user?.userName
|
||||
? `${userInfo.user?.nickName}@${appTitle} ${userInfo.user?.userName}`
|
||||
: appTitle;
|
||||
return {
|
||||
content: userInfo.user?.userName ? `${userInfo.user?.nickName}@${appTitle} ${userInfo.user?.userName}` : appTitle,
|
||||
content,
|
||||
cross: true,
|
||||
fullscreen: true,
|
||||
fontSize: 14,
|
||||
|
@ -31,13 +31,25 @@ const tooltipContent = computed(() => {
|
||||
return $t('icon.lang');
|
||||
});
|
||||
|
||||
/** Add bottom margin to all options except the last one for proper visual separation */
|
||||
const dropdownOptions = computed(() => {
|
||||
const lastIndex = props.langOptions.length - 1;
|
||||
|
||||
return props.langOptions.map((option, index) => ({
|
||||
...option,
|
||||
props: {
|
||||
class: index < lastIndex ? 'mb-1' : undefined
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
function changeLang(lang: App.I18n.LangType) {
|
||||
emit('changeLang', lang);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NDropdown :value="lang" :options="langOptions" trigger="hover" @select="changeLang">
|
||||
<NDropdown :value="lang" :options="dropdownOptions" trigger="hover" @select="changeLang">
|
||||
<div>
|
||||
<ButtonIcon :tooltip-content="tooltipContent" tooltip-placement="left">
|
||||
<SvgIcon icon="heroicons:language" />
|
||||
|
@ -1,109 +1,151 @@
|
||||
import StreamSaver from 'streamsaver';
|
||||
import { errorCodeRecord } from '@/constants/common';
|
||||
import { localStg } from '@/utils/storage';
|
||||
import { getServiceBaseURL } from '@/utils/service';
|
||||
import { transformToURLSearchParams } from '@/utils/common';
|
||||
|
||||
interface RequestConfig {
|
||||
method: 'GET' | 'POST';
|
||||
url: string;
|
||||
params?: Record<string, any>;
|
||||
filename?: string;
|
||||
contentType?: string;
|
||||
}
|
||||
|
||||
export function useDownload() {
|
||||
const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y';
|
||||
const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy);
|
||||
|
||||
function downloadByData(data: BlobPart, filename: string, type: string = 'application/octet-stream') {
|
||||
const blobData = [data];
|
||||
const blob = new Blob(blobData, { type });
|
||||
/** 获取通用请求头 */
|
||||
const getCommonHeaders = (contentType = 'application/octet-stream') => ({
|
||||
Authorization: `Bearer ${localStg.get('token')}`,
|
||||
Clientid: import.meta.env.VITE_APP_CLIENT_ID!,
|
||||
'Content-Type': contentType
|
||||
});
|
||||
|
||||
/** 通用下载方法 */
|
||||
function downloadByData(data: BlobPart, filename: string, type = 'application/octet-stream') {
|
||||
const blob = new Blob([data], { type });
|
||||
const blobURL = window.URL.createObjectURL(blob);
|
||||
const tempLink = document.createElement('a');
|
||||
tempLink.style.display = 'none';
|
||||
tempLink.href = blobURL;
|
||||
tempLink.setAttribute('download', filename);
|
||||
|
||||
const tempLink = Object.assign(document.createElement('a'), {
|
||||
style: { display: 'none' },
|
||||
href: blobURL,
|
||||
download: filename
|
||||
});
|
||||
|
||||
if (typeof tempLink.download === 'undefined') {
|
||||
tempLink.setAttribute('target', '_blank');
|
||||
}
|
||||
|
||||
document.body.appendChild(tempLink);
|
||||
tempLink.click();
|
||||
document.body.removeChild(tempLink);
|
||||
window.URL.revokeObjectURL(blobURL);
|
||||
}
|
||||
|
||||
function download(url: string, params: Record<string, any>, fileName: string) {
|
||||
window.$loading?.startLoading('正在下载数据,请稍候...');
|
||||
const token = localStg.get('token');
|
||||
const clientId = import.meta.env.VITE_APP_CLIENT_ID;
|
||||
const now = Date.now();
|
||||
const searchParams = transformToURLSearchParams(params);
|
||||
/** 流式下载 */
|
||||
async function downloadByStream(
|
||||
readableStream: ReadableStream<Uint8Array>,
|
||||
filename: string,
|
||||
contentLength?: number
|
||||
): Promise<void> {
|
||||
window.$loading?.endLoading();
|
||||
const fileStream = StreamSaver.createWriteStream(filename, { size: contentLength });
|
||||
|
||||
fetch(`${baseURL}${url}?t=${now}`, {
|
||||
method: 'post',
|
||||
body: searchParams,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
Clientid: clientId!,
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
})
|
||||
.then(async response => {
|
||||
if (response.headers.get('Content-Type')?.includes('application/json')) {
|
||||
const res = await response.json();
|
||||
const code = res.code as CommonType.ErrorCode;
|
||||
throw new Error(errorCodeRecord[code] || res.msg || errorCodeRecord.default);
|
||||
}
|
||||
return response.blob();
|
||||
})
|
||||
.then(data => downloadByData(data, fileName, 'application/zip'))
|
||||
.catch(err => window.$message?.error(err.message))
|
||||
.finally(() => window.$loading?.endLoading());
|
||||
if (window.WritableStream && readableStream?.pipeTo) {
|
||||
await readableStream.pipeTo(fileStream);
|
||||
window.$message?.success('下载完成');
|
||||
return;
|
||||
}
|
||||
|
||||
// 降级处理
|
||||
const writer = fileStream.getWriter();
|
||||
const reader = readableStream.getReader();
|
||||
|
||||
const pump = async (): Promise<void> => {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) return writer.close();
|
||||
await writer.write(value);
|
||||
return pump();
|
||||
};
|
||||
|
||||
await pump();
|
||||
}
|
||||
|
||||
function oss(ossId: CommonType.IdType) {
|
||||
window.$loading?.startLoading('正在下载数据,请稍候...');
|
||||
const token = localStg.get('token');
|
||||
const clientId = import.meta.env.VITE_APP_CLIENT_ID;
|
||||
const url = `/resource/oss/download/${ossId}`;
|
||||
const now = Date.now();
|
||||
let fileName = String(`${ossId}-${now}`);
|
||||
fetch(`${baseURL}${url}?t=${now}`, {
|
||||
method: 'get',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
Clientid: clientId!,
|
||||
'Content-Type': 'application/octet-stream'
|
||||
}
|
||||
})
|
||||
.then(async response => {
|
||||
fileName = String(response.headers.get('Download-Filename'));
|
||||
return response.blob();
|
||||
})
|
||||
.then(data => downloadByData(data, fileName))
|
||||
.catch(err => window.$message?.error(err.message))
|
||||
.finally(() => window.$loading?.endLoading());
|
||||
/** 处理响应 */
|
||||
async function handleResponse(response: Response) {
|
||||
if (response.headers.get('Content-Type')?.includes('application/json')) {
|
||||
const res = await response.json();
|
||||
const code = res.code as CommonType.ErrorCode;
|
||||
throw new Error(errorCodeRecord[code] || res.msg || errorCodeRecord.default);
|
||||
}
|
||||
}
|
||||
|
||||
function zip(url: string, fileName: string) {
|
||||
/** 核心下载逻辑 */
|
||||
async function executeDownload(config: RequestConfig): Promise<void> {
|
||||
const { method, url, params, filename, contentType } = config;
|
||||
const timestamp = Date.now();
|
||||
const fullUrl = `${baseURL}${url}${url.includes('?') ? '&' : '?'}t=${timestamp}`;
|
||||
|
||||
window.$loading?.startLoading('正在下载数据,请稍候...');
|
||||
const token = localStg.get('token');
|
||||
const clientId = import.meta.env.VITE_APP_CLIENT_ID;
|
||||
const now = Date.now();
|
||||
fetch(`${baseURL}${url}${url.includes('?') ? '&' : '?'}t=${now}`, {
|
||||
method: 'get',
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
Clientid: clientId!,
|
||||
'Content-Type': 'application/octet-stream'
|
||||
|
||||
try {
|
||||
const requestOptions: RequestInit = {
|
||||
method,
|
||||
headers: getCommonHeaders(contentType)
|
||||
};
|
||||
|
||||
if (method === 'POST' && params) {
|
||||
requestOptions.body = transformToURLSearchParams(params);
|
||||
requestOptions.headers = {
|
||||
...requestOptions.headers,
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
};
|
||||
}
|
||||
})
|
||||
.then(async response => {
|
||||
if (response.headers.get('Content-Type')?.includes('application/json')) {
|
||||
const res = await response.json();
|
||||
const code = res.code as CommonType.ErrorCode;
|
||||
throw new Error(errorCodeRecord[code] || res.msg || errorCodeRecord.default);
|
||||
}
|
||||
return response.blob();
|
||||
})
|
||||
.then(data => downloadByData(data, fileName, 'application/zip'))
|
||||
.catch(err => window.$message?.error(err.message))
|
||||
.finally(() => window.$loading?.endLoading());
|
||||
|
||||
const response = await fetch(fullUrl, requestOptions);
|
||||
|
||||
await handleResponse(response);
|
||||
|
||||
const finalFilename = filename || response.headers.get('Download-Filename') || `download-${timestamp}`;
|
||||
|
||||
if (response.body) {
|
||||
const contentLength = Number(response.headers.get('Content-Length'));
|
||||
await downloadByStream(response.body, finalFilename, contentLength);
|
||||
return;
|
||||
}
|
||||
|
||||
const responseContentType = response.headers.get('Content-Type');
|
||||
const mainType = responseContentType?.split(';')[0]?.trim() || 'application/octet-stream';
|
||||
downloadByData(await response.blob(), finalFilename, mainType);
|
||||
} catch (error: any) {
|
||||
window.$message?.error(error.message);
|
||||
} finally {
|
||||
window.$loading?.endLoading();
|
||||
}
|
||||
}
|
||||
|
||||
/** 公共下载接口 */
|
||||
const download = (url: string, params: Record<string, any>, filename: string) =>
|
||||
executeDownload({ method: 'POST', url, params, filename });
|
||||
|
||||
/** OSS文件下载 */
|
||||
const oss = (ossId: CommonType.IdType) =>
|
||||
executeDownload({
|
||||
method: 'GET',
|
||||
url: `/resource/oss/download/${ossId}`
|
||||
});
|
||||
|
||||
/** ZIP文件下载 */
|
||||
const zip = (url: string, filename: string) =>
|
||||
executeDownload({
|
||||
method: 'GET',
|
||||
url,
|
||||
filename,
|
||||
contentType: 'application/octet-stream'
|
||||
});
|
||||
|
||||
return {
|
||||
oss,
|
||||
zip,
|
||||
|
@ -117,7 +117,10 @@ const isWrapperScrollMode = computed(() => themeStore.layout.scrollMode === 'wra
|
||||
<SettingItem key="8" :label="$t('theme.watermark.visible')">
|
||||
<NSwitch v-model:value="themeStore.watermark.visible" />
|
||||
</SettingItem>
|
||||
<SettingItem v-if="themeStore.watermark.visible" key="8-1" :label="$t('theme.watermark.text')">
|
||||
<SettingItem v-if="themeStore.watermark.visible" key="8-1" :label="$t('theme.watermark.enableUserName')">
|
||||
<NSwitch v-model:value="themeStore.watermark.enableUserName" />
|
||||
</SettingItem>
|
||||
<SettingItem v-if="themeStore.watermark.visible" key="8-2" :label="$t('theme.watermark.text')">
|
||||
<NInput
|
||||
v-model:value="themeStore.watermark.text"
|
||||
autosize
|
||||
|
@ -166,7 +166,8 @@ const local: App.I18n.Schema = {
|
||||
},
|
||||
watermark: {
|
||||
visible: 'Watermark Full Screen Visible',
|
||||
text: 'Watermark Text'
|
||||
text: 'Watermark Text',
|
||||
enableUserName: 'Enable User Name Watermark'
|
||||
},
|
||||
tablePropsTitle: 'Table Props',
|
||||
table: {
|
||||
|
@ -166,7 +166,8 @@ const local: App.I18n.Schema = {
|
||||
},
|
||||
watermark: {
|
||||
visible: '显示全屏水印',
|
||||
text: '水印文本'
|
||||
text: '水印文本',
|
||||
enableUserName: '启用用户名水印'
|
||||
},
|
||||
tablePropsTitle: '表格配置',
|
||||
table: {
|
||||
|
@ -95,7 +95,6 @@ async function getHtmlBuildTime(): Promise<string | null> {
|
||||
const res = await fetch(`${baseUrl}index.html?time=${Date.now()}`);
|
||||
|
||||
if (!res.ok) {
|
||||
console.error('getHtmlBuildTime error:', res.status, res.statusText);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -103,7 +102,7 @@ async function getHtmlBuildTime(): Promise<string | null> {
|
||||
const match = html.match(/<meta name="buildTime" content="(.*)">/);
|
||||
return match?.[1] || null;
|
||||
} catch (error) {
|
||||
console.error('getHtmlBuildTime error:', error);
|
||||
window.console.error('getHtmlBuildTime error:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -10,4 +10,5 @@ body,
|
||||
|
||||
html {
|
||||
overflow-x: hidden;
|
||||
color: rgb(var(--base-text-color));
|
||||
}
|
||||
|
@ -58,7 +58,8 @@ export const themeSettings: App.Theme.ThemeSetting = {
|
||||
},
|
||||
watermark: {
|
||||
visible: import.meta.env.VITE_WATERMARK === 'Y',
|
||||
text: 'RuoYi-Vue-Plus'
|
||||
text: 'RuoYi-Vue-Plus',
|
||||
enableUserName: false
|
||||
},
|
||||
table: {
|
||||
bordered: true,
|
||||
|
3
src/typings/app.d.ts
vendored
3
src/typings/app.d.ts
vendored
@ -112,6 +112,8 @@ declare namespace App {
|
||||
visible: boolean;
|
||||
/** Watermark text */
|
||||
text: string;
|
||||
/** Whether to use user name as watermark text */
|
||||
enableUserName: boolean;
|
||||
};
|
||||
table: {
|
||||
/** Whether to show the table border */
|
||||
@ -446,6 +448,7 @@ declare namespace App {
|
||||
watermark: {
|
||||
visible: string;
|
||||
text: string;
|
||||
enableUserName: string;
|
||||
};
|
||||
tablePropsTitle: string;
|
||||
table: {
|
||||
|
2
src/typings/vite-env.d.ts
vendored
2
src/typings/vite-env.d.ts
vendored
@ -25,7 +25,7 @@ declare namespace Env {
|
||||
*
|
||||
* This prefix is start with the icon prefix
|
||||
*/
|
||||
readonly VITE_ICON_LOCAL_PREFIX: 'local-icon';
|
||||
readonly VITE_ICON_LOCAL_PREFIX: 'icon-local';
|
||||
/** backend service base url */
|
||||
readonly VITE_SERVICE_BASE_URL: string;
|
||||
/**
|
||||
|
@ -1,21 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { onActivated, onMounted } from 'vue';
|
||||
|
||||
interface Props {
|
||||
url: string;
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
|
||||
onMounted(() => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('mounted');
|
||||
});
|
||||
|
||||
onActivated(() => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('activated');
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -169,7 +169,7 @@ async function handleExport() {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<DemoSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard title="测试单表列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="测试单表列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -179,7 +179,7 @@ function handleExport() {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<TreeSearch v-model:model="searchParams" :tree-list="data" @reset="resetSearchParams" @search="getData" />
|
||||
<NCard title="测试树列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="测试树列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -228,7 +228,7 @@ async function handleUnlockLoginInfor(username: string) {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<LoginInforSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard title="登录日志列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="登录日志列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -141,7 +141,7 @@ async function handleForceLogout(tokenId: string) {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<OnlineSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" />
|
||||
<NCard title="在线用户列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="在线用户列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -174,7 +174,7 @@ async function handleCleanOperLog() {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<OperLogSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard title="操作日志列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="操作日志列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -207,7 +207,7 @@ async function handleExport() {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<ClientSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard :title="$t('page.system.client.title')" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard :title="$t('page.system.client.title')" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -193,7 +193,7 @@ async function handleRefreshCache() {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<ConfigSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard :title="$t('page.system.config.title')" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard :title="$t('page.system.config.title')" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -168,7 +168,7 @@ async function handleAddOperate() {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<DeptSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getData" />
|
||||
<NCard :title="$t('page.system.dept.title')" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard :title="$t('page.system.dept.title')" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -362,7 +362,7 @@ const selectable = computed(() => {
|
||||
<div class="h-full flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto">
|
||||
<DictDataSearch v-model:model="searchParams" @reset="handleReset" @search="getDataByPage" />
|
||||
<TableRowCheckAlert v-model:checked-row-keys="checkedRowKeys" />
|
||||
<NCard :title="$t('page.system.dict.title')" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard :title="$t('page.system.dict.title')" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -163,7 +163,7 @@ async function edit(noticeId: CommonType.IdType) {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<NoticeSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard title="通知公告列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="通知公告列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -221,7 +221,7 @@ async function handleStatusChange(
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<OssConfigSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard title="OSS配置列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="OSS配置列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -270,7 +270,7 @@ function handleToOssConfig() {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<OssSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard title="OSS 对象存储列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="OSS 对象存储列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -255,7 +255,7 @@ function handleResetSearch() {
|
||||
</template>
|
||||
<div class="h-full flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto">
|
||||
<PostSearch v-model:model="searchParams" @reset="handleResetSearch" @search="getDataByPage" />
|
||||
<NCard title="岗位信息列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="岗位信息列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -17,7 +17,7 @@ const { formRef, validate, restoreValidation } = useNaiveForm();
|
||||
|
||||
const model = defineModel<Api.System.PostSearchParams>('model', { required: true });
|
||||
|
||||
const { options: sysCommonStatusOptions } = useDict('sys_normal_disable');
|
||||
const { options: sysCommonStatusOptions } = useDict('sys_normal_disable', false);
|
||||
|
||||
async function reset() {
|
||||
await restoreValidation();
|
||||
|
@ -8,6 +8,7 @@ import { useAppStore } from '@/store/modules/app';
|
||||
import { useAuth } from '@/hooks/business/auth';
|
||||
import { useDownload } from '@/hooks/business/download';
|
||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||
import { useDict } from '@/hooks/business/dict';
|
||||
import { $t } from '@/locales';
|
||||
import ButtonIcon from '@/components/custom/button-icon.vue';
|
||||
import StatusSwitch from '@/components/custom/status-switch.vue';
|
||||
@ -24,6 +25,8 @@ const appStore = useAppStore();
|
||||
const { download } = useDownload();
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
useDict('sys_normal_disable');
|
||||
|
||||
const { bool: dataScopeDrawerVisible, setTrue: openDataScopeDrawer } = useBoolean(false);
|
||||
const { bool: authUserDrawerVisible, setTrue: openAuthUserDrawer } = useBoolean(false);
|
||||
const {
|
||||
@ -249,7 +252,7 @@ function handleAuthUser(row: Api.System.Role) {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<RoleSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard title="角色列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="角色列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -32,7 +32,7 @@ const appStore = useAppStore();
|
||||
|
||||
const title = computed(() => '分配用户权限');
|
||||
|
||||
useDict('sys_normal_disable');
|
||||
useDict('sys_normal_disable', false);
|
||||
|
||||
const { columns, data, getData, getDataByPage, loading, mobilePagination, searchParams, resetSearchParams } = useTable({
|
||||
immediate: false,
|
||||
@ -177,7 +177,7 @@ watch(visible, () => {
|
||||
</NGrid>
|
||||
</NForm>
|
||||
<TableRowCheckAlert v-model:checked-row-keys="checkedRowKeys" />
|
||||
<NCard :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<NDataTable
|
||||
v-model:checked-row-keys="checkedRowKeys"
|
||||
:columns="columns"
|
||||
|
@ -33,7 +33,7 @@ const visible = defineModel<boolean>('visible', {
|
||||
default: false
|
||||
});
|
||||
|
||||
const { options: sysNormalDisableOptions } = useDict('sys_normal_disable');
|
||||
const { options: sysNormalDisableOptions } = useDict('sys_normal_disable', false);
|
||||
|
||||
const menuOptions = ref<Api.System.MenuList>([]);
|
||||
|
||||
|
@ -21,7 +21,7 @@ const dateRangeCreateTime = ref<[string, string] | null>(null);
|
||||
|
||||
const model = defineModel<Api.System.RoleSearchParams>('model', { required: true });
|
||||
|
||||
const { options: sysNormalDisableOptions } = useDict('sys_normal_disable');
|
||||
const { options: sysNormalDisableOptions } = useDict('sys_normal_disable', false);
|
||||
|
||||
function onDateRangeCreateTimeUpdate(value: [string, string] | null) {
|
||||
if (value?.length) {
|
||||
|
@ -10,12 +10,14 @@ import { useAppStore } from '@/store/modules/app';
|
||||
import { useAuth } from '@/hooks/business/auth';
|
||||
import { useDownload } from '@/hooks/business/download';
|
||||
import { useTable, useTableOperate } from '@/hooks/common/table';
|
||||
import { useDict } from '@/hooks/business/dict';
|
||||
import { $t } from '@/locales';
|
||||
import ButtonIcon from '@/components/custom/button-icon.vue';
|
||||
import TableHeaderOperation from '@/components/advanced/table-header-operation.vue';
|
||||
import StatusSwitch from '@/components/custom/status-switch.vue';
|
||||
import TenantPackageSearch from './modules/tenant-package-search.vue';
|
||||
import TenantPackageOperateDrawer from './modules/tenant-package-operate-drawer.vue';
|
||||
|
||||
defineOptions({
|
||||
name: 'TenantPackageList'
|
||||
});
|
||||
@ -24,6 +26,8 @@ const appStore = useAppStore();
|
||||
const { download } = useDownload();
|
||||
const { hasAuth } = useAuth();
|
||||
|
||||
useDict('sys_normal_disable', false);
|
||||
|
||||
const {
|
||||
columns,
|
||||
columnChecks,
|
||||
@ -196,7 +200,7 @@ async function handleStatusChange(
|
||||
:title="$t('page.system.tenantPackage.title')"
|
||||
:bordered="false"
|
||||
size="small"
|
||||
class="sm:flex-1-hidden card-wrapper"
|
||||
class="card-wrapper sm:flex-1-hidden"
|
||||
>
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
|
@ -18,7 +18,7 @@ const { formRef, validate, restoreValidation } = useNaiveForm();
|
||||
|
||||
const model = defineModel<Api.System.TenantPackageSearchParams>('model', { required: true });
|
||||
|
||||
const { options: sysNormalDisableOptions } = useDict('sys_normal_disable');
|
||||
const { options: sysNormalDisableOptions } = useDict('sys_normal_disable', false);
|
||||
|
||||
async function reset() {
|
||||
await restoreValidation();
|
||||
|
@ -220,7 +220,7 @@ async function handleExport() {
|
||||
<template>
|
||||
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
|
||||
<TenantSearch v-model:model="searchParams" @reset="resetSearchParams" @search="getDataByPage" />
|
||||
<NCard title="租户列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="租户列表" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -311,7 +311,7 @@ function handleResetSearch() {
|
||||
<div class="h-full flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto">
|
||||
<UserSearch v-model:model="searchParams" @reset="handleResetSearch" @search="getDataByPage" />
|
||||
<TableRowCheckAlert v-model:checked-row-keys="checkedRowKeys" />
|
||||
<NCard :title="$t('page.system.user.title')" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard :title="$t('page.system.user.title')" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -268,7 +268,7 @@ getDataNames();
|
||||
@search="getDataByPage"
|
||||
/>
|
||||
<TableRowCheckAlert v-model:checked-row-keys="checkedRowKeys" />
|
||||
<NCard title="代码生成" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
|
||||
<NCard title="代码生成" :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
|
||||
<template #header-extra>
|
||||
<TableHeaderOperation
|
||||
v-model:columns="columnChecks"
|
||||
|
@ -6,7 +6,7 @@
|
||||
"lib": ["DOM", "ESNext"],
|
||||
"baseUrl": ".",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"moduleResolution": "bundler",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"~/*": ["./*"]
|
||||
|
Loading…
Reference in New Issue
Block a user