merge(sj_map_reduce): 合并 sa 1.2.6

This commit is contained in:
xlsea 2024-06-26 17:30:11 +08:00
parent 03f6db667a
commit 6f6c00b0ae
31 changed files with 1204 additions and 870 deletions

View File

@ -3,7 +3,7 @@
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
"eslint.experimental.useFlatConfig": true,
"eslint.useFlatConfig": true,
"editor.formatOnSave": false,
"eslint.validate": ["html", "css", "scss", "json", "jsonc"],
"i18n-ally.displayLanguage": "zh-cn",

View File

@ -1 +1,2 @@
export * from './proxy';
export * from './time';

12
build/config/time.ts Normal file
View File

@ -0,0 +1,12 @@
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
export function getBuildTime() {
dayjs.extend(utc);
dayjs.extend(timezone);
const buildTime = dayjs.tz(Date.now(), 'Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss');
return buildTime;
}

View File

@ -4,6 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark" />
<title>%VITE_APP_TITLE%</title>
</head>
<body>

View File

@ -1,7 +1,7 @@
{
"name": "snail-job",
"type": "module",
"version": "1.0.0",
"version": "1.1.0",
"description": "A flexible, reliable, and fast platform for distributed task retry and distributed task scheduling.",
"license": "Apache-2.0",
"homepage": "https://gitee.com/aizuda/snail-job",
@ -56,7 +56,7 @@
"@sa/hooks": "workspace:*",
"@sa/materials": "workspace:*",
"@sa/utils": "workspace:*",
"@vueuse/core": "10.10.0",
"@vueuse/core": "10.11.0",
"clipboard": "2.0.11",
"dayjs": "1.11.11",
"echarts": "5.5.0",
@ -67,46 +67,46 @@
"pinia": "2.1.7",
"tailwind-merge": "^2.3.0",
"ts-md5": "1.3.1",
"vue": "3.4.27",
"vue": "3.4.30",
"vue-codemirror6": "^1.3.0",
"vue-drag-resize": "^1.5.4",
"vue-draggable-plus": "0.5.0",
"vue-i18n": "9.13.1",
"vue-router": "4.3.2",
"vue-router": "4.4.0",
"vue3-puzzle-vcode": "^1.1.7"
},
"devDependencies": {
"@elegant-router/vue": "0.3.7",
"@iconify/json": "2.2.217",
"@iconify/json": "2.2.221",
"@sa/scripts": "workspace:*",
"@sa/uno-preset": "workspace:*",
"@soybeanjs/eslint-config": "1.3.6",
"@soybeanjs/eslint-config": "1.3.7",
"@types/lodash-es": "4.17.12",
"@types/node": "20.14.2",
"@types/node": "20.14.8",
"@types/nprogress": "0.2.3",
"@unocss/eslint-config": "0.60.4",
"@unocss/preset-icons": "0.60.4",
"@unocss/preset-uno": "0.60.4",
"@unocss/transformer-directives": "0.60.4",
"@unocss/transformer-variant-group": "0.60.4",
"@unocss/vite": "0.60.4",
"@unocss/eslint-config": "0.61.0",
"@unocss/preset-icons": "0.61.0",
"@unocss/preset-uno": "0.61.0",
"@unocss/transformer-directives": "0.61.0",
"@unocss/transformer-variant-group": "0.61.0",
"@unocss/vite": "0.61.0",
"@vitejs/plugin-vue": "5.0.5",
"@vitejs/plugin-vue-jsx": "4.0.0",
"eslint": "9.4.0",
"eslint": "9.5.0",
"eslint-plugin-vue": "9.26.0",
"lint-staged": "15.2.5",
"sass": "1.77.4",
"lint-staged": "15.2.7",
"sass": "1.77.6",
"simple-git-hooks": "2.11.1",
"tsx": "4.12.0",
"typescript": "5.4.5",
"tsx": "4.15.7",
"typescript": "5.5.2",
"unplugin-icons": "0.19.0",
"unplugin-vue-components": "0.27.0",
"vite": "5.2.12",
"vite": "5.3.1",
"vite-plugin-progress": "0.0.7",
"vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-devtools": "7.2.1",
"vite-plugin-vue-devtools": "7.3.4",
"vue-eslint-parser": "9.4.3",
"vue-tsc": "2.0.19"
"vue-tsc": "2.0.22"
},
"simple-git-hooks": {
"commit-msg": "pnpm sa git-commit-verify",

View File

@ -1,6 +1,6 @@
{
"name": "@sa/axios",
"version": "1.2.1",
"version": "1.2.6",
"exports": {
".": "./src/index.ts"
},
@ -12,7 +12,7 @@
"dependencies": {
"@sa/utils": "workspace:*",
"axios": "1.7.2",
"axios-retry": "4.4.0",
"axios-retry": "4.4.1",
"qs": "6.12.1"
},
"devDependencies": {

View File

@ -2,4 +2,4 @@
export const REQUEST_ID_KEY = 'X-Request-Id';
/** the backend error code key */
export const BACKEND_ERROR_CODE = '0';
export const BACKEND_ERROR_CODE = '-1';

View File

@ -1,6 +1,6 @@
{
"name": "@sa/color",
"version": "1.2.1",
"version": "1.2.6",
"exports": {
".": "./src/index.ts"
},

View File

@ -1,6 +1,6 @@
{
"name": "@sa/hooks",
"version": "1.2.1",
"version": "1.2.6",
"exports": {
".": "./src/index.ts"
},

View File

@ -1,6 +1,6 @@
{
"name": "@sa/materials",
"version": "1.2.1",
"version": "1.2.6",
"exports": {
".": "./src/index.ts"
},
@ -11,7 +11,7 @@
},
"dependencies": {
"@sa/utils": "workspace:*",
"simplebar-vue": "2.3.4"
"simplebar-vue": "2.3.5"
},
"devDependencies": {
"typed-css-modules": "0.9.1"

View File

@ -1,6 +1,6 @@
{
"name": "@sa/fetch",
"version": "1.2.1",
"version": "1.2.6",
"exports": {
".": "./src/index.ts"
},

View File

@ -1,6 +1,6 @@
{
"name": "@sa/scripts",
"version": "1.2.1",
"version": "1.2.6",
"bin": {
"sa": "./bin.ts"
},
@ -15,11 +15,11 @@
"devDependencies": {
"@soybeanjs/changelog": "0.3.24",
"bumpp": "9.4.1",
"c12": "1.10.0",
"c12": "1.11.1",
"cac": "6.7.14",
"consola": "3.2.3",
"enquirer": "2.4.1",
"execa": "9.2.0",
"execa": "9.3.0",
"kolorist": "1.8.0",
"npm-check-updates": "16.14.20",
"rimraf": "5.0.7"

View File

@ -1,6 +1,6 @@
{
"name": "@sa/uno-preset",
"version": "1.2.1",
"version": "1.2.6",
"exports": {
".": "./src/index.ts"
},

View File

@ -1,6 +1,6 @@
{
"name": "@sa/utils",
"version": "1.2.1",
"version": "1.2.6",
"exports": {
".": "./src/index.ts"
},

File diff suppressed because it is too large Load Diff

View File

@ -41,6 +41,7 @@ const icon = computed(() => {
<template>
<ButtonIcon
:key="String(collapsed)"
:tooltip-content="collapsed ? $t('icon.expand') : $t('icon.collapse')"
tooltip-placement="bottom-start"
:z-index="zIndex"

View File

@ -160,6 +160,24 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl
Object.assign(pagination, update);
}
/**
* get data by page number
*
* @param pageNum the page number. default is 1
*/
async function getDataByPage(pageNum: number = 1) {
updatePagination({
page: pageNum
});
updateSearchParams({
page: pageNum,
size: pagination.pageSize!
});
await getData();
}
scope.run(() => {
watch(
() => appStore.locale,
@ -189,6 +207,7 @@ export function useTable<A extends NaiveUI.TableApiFn>(config: NaiveUI.NaiveTabl
mobilePagination,
updatePagination,
getData,
getDataByPage,
searchParams,
updateSearchParams,
resetSearchParams

View File

@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed } from 'vue';
import { LAYOUT_SCROLL_EL_ID } from '@sa/materials';
import { useAppStore } from '@/store/modules/app';
import { useThemeStore } from '@/store/modules/theme';
import { useRouteStore } from '@/store/modules/route';
@ -24,6 +25,12 @@ const routeStore = useRouteStore();
const tabStore = useTabStore();
const transitionName = computed(() => (themeStore.page.animate ? themeStore.page.animateMode : ''));
function resetScroll() {
const el = document.querySelector(`#${LAYOUT_SCROLL_EL_ID}`);
el?.scrollTo({ left: 0, top: 0 });
}
</script>
<template>
@ -32,6 +39,7 @@ const transitionName = computed(() => (themeStore.page.animate ? themeStore.page
:name="transitionName"
mode="out-in"
@before-leave="appStore.setContentXScrollable(true)"
@after-leave="resetScroll"
@after-enter="appStore.setContentXScrollable(false)"
>
<KeepAlive :include="routeStore.cacheRoutes">

View File

@ -36,6 +36,7 @@ const local: App.I18n.Schema = {
exportAll: 'Are you sure to export all?',
exportPar: 'Are you sure to export {num} pieces of data?',
edit: 'Edit',
error: 'Error',
detail: 'Detail',
index: 'Index',
keywordSearch: 'Please enter keyword',

View File

@ -36,6 +36,7 @@ const local: App.I18n.Schema = {
exportAll: '确认导出列表中全部数据吗?',
exportPar: '确认导出{num}条数据吗?',
edit: '编辑',
error: '错误',
detail: '详情',
index: '序号',
keywordSearch: '请输入关键词搜索',

View File

@ -3,11 +3,22 @@ import { NButton } from 'naive-ui';
import { $t } from '../locales';
export function setupAppVersionNotification() {
let isShow = false;
document.addEventListener('visibilitychange', async () => {
const preConditions = [!isShow, document.visibilityState === 'visible', !import.meta.env.DEV];
if (!preConditions.every(Boolean)) return;
const buildTime = await getHtmlBuildTime();
const { VITE_UPDATE_NOTIFY } = import.meta.env;
if (buildTime !== BUILD_TIME && document.visibilityState === 'visible' && VITE_UPDATE_NOTIFY === 'Y') {
if (buildTime === BUILD_TIME && VITE_UPDATE_NOTIFY !== 'Y') {
return;
}
isShow = true;
const n = window.$notification?.create({
title: $t('system.updateTitle'),
content: $t('system.updateContent'),
@ -33,9 +44,11 @@ export function setupAppVersionNotification() {
() => $t('system.updateConfirm')
)
]);
},
onClose() {
isShow = false;
}
});
}
});
}

View File

@ -6,6 +6,7 @@ import type {
Router
} from 'vue-router';
import type { RouteKey, RoutePath } from '@elegant-router/types';
import { getRouteName } from '@/router/elegant/transform';
import { useAuthStore } from '@/store/modules/auth';
import { useRouteStore } from '@/store/modules/route';
import { localStg } from '@/utils/storage';
@ -153,9 +154,7 @@ async function initRoute(to: RouteLocationNormalized): Promise<RouteLocationRaw
// initialize the auth route requires the user to be logged in, if not, redirect to the login page
if (!isLogin) {
const loginRoute: RouteKey = 'login';
const redirect = to.fullPath;
const query: LocationQueryRaw = to.name !== loginRoute ? { redirect } : {};
const query = getRouteQueryOfLoginRoute(to, routeStore.routeHome);
const location: RouteLocationRaw = {
name: loginRoute,
@ -202,3 +201,20 @@ function handleRouteSwitch(to: RouteLocationNormalized, from: RouteLocationNorma
next();
}
function getRouteQueryOfLoginRoute(to: RouteLocationNormalized, routeHome: RouteKey) {
const loginRoute: RouteKey = 'login';
const redirect = to.fullPath;
const [redirectPath, redirectQuery] = redirect.split('?');
const redirectName = getRouteName(redirectPath as RoutePath);
const isRedirectHome = routeHome === redirectName;
const query: LocationQueryRaw = to.name !== loginRoute && !isRedirectHome ? { redirect } : {};
if (isRedirectHome && redirectQuery) {
query.redirect = `/?${redirectQuery}`;
}
return query;
}

View File

@ -1,5 +1,5 @@
import type { AxiosResponse } from 'axios';
import { createFlatRequest } from '@sa/axios';
import { BACKEND_ERROR_CODE, createFlatRequest } from '@sa/axios';
import { useAuthStore } from '@/store/modules/auth';
import { $t } from '@/locales';
import { localStg } from '@/utils/storage';
@ -72,7 +72,7 @@ export const request = createFlatRequest<App.Service.Response, RequestInstanceSt
if (!request.state.isLogout) {
request.state.isLogout = true;
window.$dialog?.error({
title: 'Error',
title: $t('common.error'),
content: $t('request.logoutWithModalMsg'),
positiveText: $t('common.confirm'),
maskClosable: false,
@ -118,8 +118,10 @@ export const request = createFlatRequest<App.Service.Response, RequestInstanceSt
let backendErrorCode = '';
// get backend error message and code
if (String(error.code) === BACKEND_ERROR_CODE) {
message = error.response?.data?.message || message;
backendErrorCode = error.response?.data?.status?.toString() || '';
backendErrorCode = error.response?.data?.status || '';
}
// the error message is displayed in the modal
const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || [];

View File

@ -36,6 +36,9 @@ export function showErrorMsg(state: RequestInstanceState, message: string) {
state.errMsgStack = [];
}
const isExist = state.errMsgStack.includes(message);
if (!isExist) {
state.errMsgStack.push(message);
window.$message?.error(message, {
@ -47,4 +50,5 @@ export function showErrorMsg(state: RequestInstanceState, message: string) {
}, 5000);
}
});
}
}

View File

@ -9,11 +9,13 @@ import { localStg } from '@/utils/storage';
import { $t } from '@/locales';
import { roleTypeRecord } from '@/constants/business';
import { useRouteStore } from '../route';
import { useTabStore } from '../tab';
import { clearAuthStorage, getToken } from './shared';
export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
const route = useRoute();
const routeStore = useRouteStore();
const tabStore = useTabStore();
const { toLogin, redirectFromLogin } = useRouterPush(false);
const { loading: loginLoading, startLoading, endLoading } = useLoading();
@ -56,6 +58,7 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
await toLogin();
}
tabStore.cacheTabs();
routeStore.resetStore();
}

View File

@ -219,7 +219,7 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
/** Init auth route */
async function initAuthRoute() {
if (authRouteMode.value === 'static') {
await initStaticAuthRoute();
initStaticAuthRoute();
} else {
await initDynamicAuthRoute();
}
@ -228,7 +228,7 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
}
/** Init static auth route */
async function initStaticAuthRoute() {
function initStaticAuthRoute() {
const { authRoutes: staticAuthRoutes } = createStaticRoutes();
if (authStore.isStaticSuper) {

View File

@ -290,6 +290,7 @@ export const useTabStore = defineStore(SetupStoreId.Tab, () => {
resetTabLabel,
isTabRetain,
updateTabsByLocale,
getTabIdByRoute
getTabIdByRoute,
cacheTabs
};
});

View File

@ -288,6 +288,7 @@ declare namespace App {
exportAll: string;
exportPar: string;
edit: string;
error: string;
detail: string;
index: string;
keywordSearch: string;

View File

@ -108,3 +108,7 @@ declare namespace Env {
readonly VITE_LOGIN_CODE?: string;
}
}
interface ImportMeta {
readonly env: Env.ImportMeta;
}

View File

@ -1,4 +1,7 @@
interface Window {
export {};
declare global {
export interface Window {
/** NProgress instance */
NProgress?: import('nprogress').NProgress;
/** Loading bar instance */
@ -9,20 +12,18 @@ interface Window {
$message?: import('naive-ui').MessageProviderInst;
/** Notification instance */
$notification?: import('naive-ui').NotificationProviderInst;
/** Table loading */
$loading?: import('@sa/hooks').LoadingApiInst;
}
}
interface ViewTransition {
interface ViewTransition {
ready: Promise<void>;
}
}
interface Document {
export interface Document {
startViewTransition?: (callback: () => Promise<void> | void) => ViewTransition;
}
}
interface ImportMeta {
readonly env: Env.ImportMeta;
/** Build time of the project */
export const BUILD_TIME: string;
}
/** Build time of the project */
declare const BUILD_TIME: string;

View File

@ -1,14 +1,13 @@
import process from 'node:process';
import { URL, fileURLToPath } from 'node:url';
import { defineConfig, loadEnv } from 'vite';
import dayjs from 'dayjs';
import { setupVitePlugins } from './build/plugins';
import { createViteProxy } from './build/config';
import { createViteProxy, getBuildTime } from './build/config';
export default defineConfig(configEnv => {
const viteEnv = loadEnv(configEnv.mode, process.cwd()) as unknown as Env.ImportMeta;
const buildTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
const buildTime = getBuildTime();
return {
base: viteEnv.VITE_BASE_URL,