wip: 临时提交
This commit is contained in:
@@ -56,10 +56,6 @@ export default [
|
||||
ignores: [
|
||||
"**/node_modules/**",
|
||||
"**/dist/**",
|
||||
"**/build/**",
|
||||
"**/.nuxt/**",
|
||||
"**/.output/**",
|
||||
"**/coverage/**",
|
||||
"**/*.min.*",
|
||||
"**/auto-imports.d.ts",
|
||||
"**/components.d.ts",
|
||||
@@ -114,7 +110,7 @@ export default [
|
||||
"object-shorthand": "error",
|
||||
|
||||
// 最佳实践
|
||||
eqeqeq: ["error", "always", { null: "ignore" }],
|
||||
eqeqeq: "off",
|
||||
"no-multi-spaces": "error",
|
||||
"no-multiple-empty-lines": ["error", { max: 1, maxBOF: 0, maxEOF: 0 }],
|
||||
|
||||
@@ -122,6 +118,7 @@ export default [
|
||||
"no-unused-vars": "off",
|
||||
"no-undef": "off",
|
||||
"no-redeclare": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -144,9 +141,10 @@ export default [
|
||||
"vue/require-default-prop": "off",
|
||||
"vue/require-explicit-emits": "error",
|
||||
"vue/no-unused-vars": "error",
|
||||
"vue/no-mutating-props": "error",
|
||||
"vue/attribute-hyphenation": ["error", "always"],
|
||||
"vue/v-on-event-hyphenation": ["error", "always"],
|
||||
"vue/no-mutating-props": "off",
|
||||
"vue/valid-v-for": "warn",
|
||||
"vue/no-template-shadow": "warn",
|
||||
"vue/return-in-computed-property": "warn",
|
||||
"vue/block-order": [
|
||||
"error",
|
||||
{
|
||||
@@ -166,6 +164,7 @@ export default [
|
||||
},
|
||||
],
|
||||
"vue/component-name-in-template-casing": ["error", "PascalCase"],
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -181,28 +180,14 @@ export default [
|
||||
},
|
||||
rules: {
|
||||
// TypeScript 规则
|
||||
"@typescript-eslint/no-explicit-any": "warn",
|
||||
"@typescript-eslint/no-explicit-any": "off", // 允许使用any类型,方便开发
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-empty-object-type": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
vars: "all",
|
||||
args: "after-used",
|
||||
ignoreRestSiblings: true,
|
||||
argsIgnorePattern: "^_", // 忽略以下划线开头的参数
|
||||
varsIgnorePattern: "^[A-Z][A-Z0-9_]*$", // 忽略全大写的常量/枚举
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/consistent-type-imports": [
|
||||
"error",
|
||||
{
|
||||
prefer: "type-imports",
|
||||
fixStyle: "inline-type-imports",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": "warn", // 降级为警告
|
||||
"@typescript-eslint/no-unused-expressions": "warn", // 降级为警告
|
||||
"@typescript-eslint/consistent-type-imports": "off", // 关闭强制使用type import
|
||||
"@typescript-eslint/no-import-type-side-effects": "error",
|
||||
},
|
||||
},
|
||||
@@ -216,21 +201,13 @@ export default [
|
||||
},
|
||||
},
|
||||
|
||||
// 测试文件配置
|
||||
{
|
||||
files: ["**/__tests__/**", "**/*.{test,spec}.{js,ts,vue}"],
|
||||
rules: {
|
||||
"no-console": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
},
|
||||
},
|
||||
|
||||
// CURD 组件配置
|
||||
{
|
||||
files: ["**/components/CURD/**/*.{ts,vue}"],
|
||||
rules: {
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -6,11 +6,10 @@
|
||||
<div class="flex flex-col md:flex-row justify-between gap-y-2.5 mb-2.5">
|
||||
<!-- 左侧工具栏 -->
|
||||
<div class="toolbar-left flex gap-y-2.5 gap-x-2 md:gap-x-3 flex-wrap">
|
||||
<template v-for="btn in toolbarLeftBtn">
|
||||
<template v-for="(btn, index) in toolbarLeftBtn" :key="index">
|
||||
<el-button
|
||||
v-bind="btn.attrs"
|
||||
:key="btn.name"
|
||||
v-hasPerm="btn.perm ?? '*:*:*'"
|
||||
v-bind="btn.attrs"
|
||||
:disabled="btn.name === 'delete' && removeIds.length === 0"
|
||||
@click="handleToolbar(btn.name)"
|
||||
>
|
||||
@@ -20,13 +19,13 @@
|
||||
</div>
|
||||
<!-- 右侧工具栏 -->
|
||||
<div class="toolbar-right flex gap-y-2.5 gap-x-2 md:gap-x-3 flex-wrap">
|
||||
<template v-for="btn in toolbarRightBtn">
|
||||
<template v-for="(btn, index) in toolbarRightBtn" :key="index">
|
||||
<el-popover v-if="btn.name === 'filter'" placement="bottom" trigger="click">
|
||||
<template #reference>
|
||||
<el-button v-bind="btn.attrs"></el-button>
|
||||
</template>
|
||||
<el-scrollbar max-height="350px">
|
||||
<template v-for="col in cols" :key="col">
|
||||
<template v-for="col in cols" :key="col.prop">
|
||||
<el-checkbox v-if="col.prop" v-model="col.show" :label="col.label" />
|
||||
</template>
|
||||
</el-scrollbar>
|
||||
@@ -52,7 +51,7 @@
|
||||
@selection-change="handleSelectionChange"
|
||||
@filter-change="handleFilterChange"
|
||||
>
|
||||
<template v-for="col in cols" :key="col">
|
||||
<template v-for="col in cols" :key="col.prop">
|
||||
<el-table-column v-if="col.show" v-bind="col">
|
||||
<template #default="scope">
|
||||
<!-- 显示图片 -->
|
||||
@@ -159,7 +158,7 @@
|
||||
</template>
|
||||
<!-- 列操作栏 -->
|
||||
<template v-else-if="col.templet === 'tool'">
|
||||
<template v-for="btn in tableToolbarBtn">
|
||||
<template v-for="(btn, index) in tableToolbarBtn" :key="index">
|
||||
<el-button
|
||||
v-if="btn.render === undefined || btn.render(scope.row)"
|
||||
v-hasPerm="btn.perm ?? '*:*:*'"
|
||||
@@ -239,7 +238,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="字段" prop="fields">
|
||||
<el-checkbox-group v-model="exportsFormData.fields">
|
||||
<template v-for="col in cols" :key="col">
|
||||
<template v-for="col in cols" :key="col.prop">
|
||||
<el-checkbox v-if="col.prop" :value="col.prop" :label="col.label" />
|
||||
</template>
|
||||
</el-checkbox-group>
|
||||
@@ -433,7 +432,9 @@ const tableToolbarBtn = createToolbar(tableToolbar, { link: true, size: "small"
|
||||
// 表格列
|
||||
const cols = ref(
|
||||
props.contentConfig.cols.map((col) => {
|
||||
col.initFn && col.initFn(col);
|
||||
if (col.initFn) {
|
||||
col.initFn(col);
|
||||
}
|
||||
if (col.show === undefined) {
|
||||
col.show = true;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
<component
|
||||
:is="childrenMap.get(item.type)"
|
||||
v-for="opt in item.options"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></component>
|
||||
@@ -104,6 +105,7 @@
|
||||
<component
|
||||
:is="childrenMap.get(item.type)"
|
||||
v-for="opt in item.options"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
></component>
|
||||
@@ -224,7 +226,9 @@ const handleSubmit = useThrottleFn(() => {
|
||||
|
||||
onMounted(() => {
|
||||
formItems.forEach((item) => {
|
||||
item.initFn && item.initFn(item);
|
||||
if (item.initFn) {
|
||||
item.initFn(item);
|
||||
}
|
||||
formRules[item.prop] = item?.rules ?? [];
|
||||
props.modalConfig.form = { labelWidth: "auto", ...props.modalConfig?.form };
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
v-on="item.events || {}"
|
||||
>
|
||||
<template v-if="item.type === 'select'">
|
||||
<template v-for="opt in item.options">
|
||||
<template v-for="opt in item.options" :key="opt.value">
|
||||
<el-option :label="opt.label" :value="opt.value" />
|
||||
</template>
|
||||
</template>
|
||||
@@ -72,7 +72,6 @@ const emit = defineEmits<{
|
||||
}>();
|
||||
// 组件映射表
|
||||
const componentMap = new Map<ISearchComponent, any>([
|
||||
|
||||
// @ts-ignore
|
||||
["input", markRaw(ElInput)], // @ts-ignore
|
||||
["select", markRaw(ElSelect)], // @ts-ignore
|
||||
@@ -84,7 +83,6 @@ const componentMap = new Map<ISearchComponent, any>([
|
||||
["tree-select", markRaw(ElTreeSelect)], // @ts-ignore
|
||||
["input-tag", markRaw(ElInputTag)], // @ts-ignore
|
||||
["custom-tag", markRaw(InputTag)],
|
||||
|
||||
]);
|
||||
|
||||
// 存储表单实例
|
||||
@@ -131,7 +129,9 @@ const handleReset = () => {
|
||||
|
||||
onMounted(() => {
|
||||
formItems.forEach((item) => {
|
||||
item?.initFn && item.initFn(item);
|
||||
if (item?.initFn) {
|
||||
item.initFn(item);
|
||||
}
|
||||
if (["input-tag", "custom-tag", "cascader"].includes(item?.type ?? "")) {
|
||||
queryParams[item.prop] = Array.isArray(item.initialValue) ? item.initialValue : [];
|
||||
} else if (item.type === "input-number") {
|
||||
|
||||
@@ -31,6 +31,9 @@ const hamburgerClass = computed(() => {
|
||||
) {
|
||||
return "hamburger--white";
|
||||
}
|
||||
|
||||
// 默认返回空字符串
|
||||
return "";
|
||||
});
|
||||
|
||||
function toggleClick() {
|
||||
|
||||
@@ -284,7 +284,7 @@ const selectedItems = ref<IObject[]>([]);
|
||||
const confirmText = computed(() => {
|
||||
return selectedItems.value.length > 0 ? `已选(${selectedItems.value.length})` : "确 定";
|
||||
});
|
||||
function handleSelect(selection: any[], _row: any) {
|
||||
function handleSelect(selection: any[]) {
|
||||
if (isMultiple || selection.length === 0) {
|
||||
// 多选
|
||||
selectedItems.value = selection;
|
||||
|
||||
@@ -66,6 +66,7 @@ import defaultSettings from "@/settings";
|
||||
import { DeviceEnum } from "@/enums/settings/device.enum";
|
||||
import { useAppStore, useSettingsStore, useUserStore } from "@/store";
|
||||
import { SidebarColor, ThemeMode } from "@/enums/settings/theme.enum";
|
||||
import { LayoutMode } from "@/enums";
|
||||
|
||||
const { t } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
@@ -96,18 +97,29 @@ const navbarActionsClass = computed(() => {
|
||||
|
||||
// 明亮主题下
|
||||
if (theme === ThemeMode.LIGHT) {
|
||||
// 顶部布局和混合布局的顶部区域使用深色背景,需要白色文字
|
||||
if (layout === "top" || layout === "mix") {
|
||||
// 顶部布局和混合布局的顶部区域:
|
||||
// - 如果侧边栏是经典蓝色,使用白色文字
|
||||
// - 如果侧边栏是极简白色,使用深色文字
|
||||
if (layout === LayoutMode.TOP || layout === LayoutMode.MIX) {
|
||||
if (sidebarColorScheme === SidebarColor.CLASSIC_BLUE) {
|
||||
return "navbar-actions--white-text";
|
||||
} else {
|
||||
return "navbar-actions--dark-text";
|
||||
}
|
||||
}
|
||||
|
||||
// 左侧布局下,如果侧边栏是经典蓝色,顶部导航栏使用白色文字
|
||||
if (layout === "left" && sidebarColorScheme === SidebarColor.CLASSIC_BLUE) {
|
||||
return "navbar-actions--white-text";
|
||||
}
|
||||
|
||||
// 左侧布局下,如果侧边栏是经典蓝色,顶部导航栏仍使用默认颜色
|
||||
if (layout === "left" && sidebarColorScheme === SidebarColor.CLASSIC_BLUE) {
|
||||
return ""; // 使用默认的深色文字
|
||||
// 左侧布局下的其他情况(包括极简白),使用默认深色文字
|
||||
if (layout === "left") {
|
||||
return "navbar-actions--dark-text";
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
return "navbar-actions--dark-text";
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -196,17 +208,17 @@ function logout() {
|
||||
padding: 0 8px;
|
||||
|
||||
&__avatar {
|
||||
flex-shrink: 0;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&__name {
|
||||
margin-left: 8px;
|
||||
color: var(--el-text-color-regular);
|
||||
transition: color 0.3s;
|
||||
white-space: nowrap;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,6 +244,27 @@ function logout() {
|
||||
}
|
||||
}
|
||||
|
||||
// 深色文字样式(用于浅色背景:明亮主题下的左侧布局)
|
||||
.navbar-actions--dark-text {
|
||||
.navbar-actions__item {
|
||||
:deep([class^="i-svg:"]) {
|
||||
color: var(--el-text-color-regular) !important;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
|
||||
:deep([class^="i-svg:"]) {
|
||||
color: var(--el-color-primary) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-profile__name {
|
||||
color: var(--el-text-color-regular) !important;
|
||||
}
|
||||
}
|
||||
|
||||
// 确保下拉菜单中的图标不受影响
|
||||
:deep(.el-dropdown-menu) {
|
||||
[class^="i-svg:"] {
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
:active-text-color="variables['menu-active-text']"
|
||||
>
|
||||
<MenuItem
|
||||
v-for="route in sideMenuRoutes"
|
||||
:key="route.path"
|
||||
:item="route"
|
||||
:base-path="resolvePath(route.path)"
|
||||
v-for="item in sideMenuRoutes"
|
||||
:key="item.path"
|
||||
:item="item"
|
||||
:base-path="resolvePath(item.path)"
|
||||
/>
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
@@ -121,16 +121,16 @@ console.log("🎨 MixLayout rendered");
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
padding: 0 16px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&-logo {
|
||||
flex-shrink: 0;
|
||||
width: 200px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: $sidebar-width;
|
||||
height: 100%;
|
||||
|
||||
:deep(.logo) {
|
||||
height: 100%;
|
||||
@@ -142,17 +142,17 @@ console.log("🎨 MixLayout rendered");
|
||||
}
|
||||
|
||||
&-menu {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
margin: 0 16px;
|
||||
overflow: hidden;
|
||||
|
||||
:deep(.el-menu) {
|
||||
height: 100%;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
:deep(.el-menu--horizontal) {
|
||||
@@ -178,10 +178,11 @@ console.log("🎨 MixLayout rendered");
|
||||
}
|
||||
|
||||
&-actions {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
padding: 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,23 +46,22 @@ const { routes } = useLayoutMenu();
|
||||
top: 0;
|
||||
z-index: 999;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: $navbar-height;
|
||||
padding: 0 20px;
|
||||
background-color: $menu-background;
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||
|
||||
&-left {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
|
||||
// Logo 样式
|
||||
:deep(.sidebar-logo) {
|
||||
width: 200px;
|
||||
width: $sidebar-width;
|
||||
height: $navbar-height;
|
||||
padding: 0;
|
||||
margin-right: 20px;
|
||||
@@ -90,20 +89,18 @@ const { routes } = useLayoutMenu();
|
||||
flex: 1;
|
||||
height: $navbar-height;
|
||||
line-height: $navbar-height;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
|
||||
.el-menu-item {
|
||||
height: $navbar-height;
|
||||
line-height: $navbar-height;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.el-sub-menu {
|
||||
.el-sub-menu__title {
|
||||
height: $navbar-height;
|
||||
line-height: $navbar-height;
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user