mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-23 23:39:47 +08:00
Compare commits
17 Commits
1eb0a3dac2
...
dev
Author | SHA1 | Date | |
---|---|---|---|
2c248d82f2 | |||
28101cb2f1 | |||
4e27f3b5a5 | |||
e623b560e4 | |||
8aeb73627a | |||
3f148a4e62 | |||
34ab7d5da2 | |||
513dc31eaa | |||
dc2fbbd556 | |||
56fd5434ca | |||
ad207255bb | |||
3146c039f0 | |||
d5bbc37dec | |||
2f794c4b73 | |||
378aa869bf | |||
4a4244b5c4 | |||
ecad1c3e78 |
@ -16,7 +16,7 @@
|
||||
},
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": ["@playwright/mcp@0.0.29"]
|
||||
"args": ["@playwright/mcp@latest"]
|
||||
},
|
||||
"mcp-server-time": {
|
||||
"command": "uvx",
|
||||
@ -26,14 +26,21 @@
|
||||
"command": "npx",
|
||||
"args": ["-y", "mcp-shrimp-task-manager"],
|
||||
"env": {
|
||||
"DATA_DIR": "D:/workspace/mcp-shrimp-task-manager/data",
|
||||
"DATA_DIR": "D:/workspace/tools/mcp-shrimp-task-manager/data",
|
||||
"TEMPLATES_USE": "en",
|
||||
"ENABLE_GUI": "false"
|
||||
"ENABLE_GUI": "true"
|
||||
}
|
||||
},
|
||||
"mcp-deepwiki": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "mcp-deepwiki@latest"]
|
||||
},
|
||||
"memory": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-memory"],
|
||||
"env": {
|
||||
"MEMORY_FILE_PATH": "D:/workspace/tools/server-memory/memory.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
**# RIPER-5 + 多维度思维 + 代理执行协议 (v4.9.1 - MCP工具驱动版)**
|
||||
|
||||
**元指令:** 此协议旨在最大化你的战略规划与执行效率。你的核心任务是**指挥和利用MCP工具集**来驱动项目进展。严格遵守核心原则,利用 `mcp-shrimp-task-manager` 进行项目规划与追踪,使用 `deepwiki-mcp` 进行深度研究。主动管理 `/project_document` 作为知识库。**每轮主要响应后,调用 `mcp.feedback_enhanced` 进行交互或通知。**
|
||||
@ -167,5 +164,4 @@ alwaysApply: false
|
||||
|
||||
* **极致效率:** AI应最大限度地减少手动干预,让MCP工具处理所有可以自动化的工作。
|
||||
* **战略聚焦:** 将AI的“思考”集中在无法被工具替代的领域:战略决策、创新构想、复杂问题诊断 (`mcp.sequential_thinking`) 和最终质量把关。
|
||||
|
||||
* **无缝集成:** 期望AI能流畅地在不同MCP工具之间传递信息,形成一个高度整合的自动化工作流。
|
||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -31,7 +31,8 @@
|
||||
"vue.server.hybridMode": true,
|
||||
"files.exclude": { "/docs": true },
|
||||
"search.exclude": {
|
||||
"/docs": true
|
||||
"/docs": true,
|
||||
"**/dist/**": true
|
||||
},
|
||||
"cSpell.words": ["Axios", "tinymce"]
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import org.apache.velocity.VelocityContext;
|
||||
import org.dromara.common.core.utils.DateUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.mybatis.enums.DataBaseType;
|
||||
import org.dromara.common.mybatis.helper.DataBaseHelper;
|
||||
import org.dromara.generator.constant.GenConstants;
|
||||
import org.dromara.generator.domain.GenTable;
|
||||
@ -58,7 +59,7 @@ public class VelocityUtils {
|
||||
velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】");
|
||||
velocityContext.put("ClassName", genTable.getClassName());
|
||||
velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName()));
|
||||
velocityContext.put("moduleName", genTable.getModuleName());
|
||||
velocityContext.put("moduleName", StrUtil.toSymbolCase(genTable.getModuleName(), '-'));
|
||||
velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName()));
|
||||
velocityContext.put("businessName", genTable.getBusinessName());
|
||||
velocityContext.put("business_name", StrUtil.toUnderlineCase(genTable.getBusinessName()));
|
||||
@ -124,11 +125,12 @@ public class VelocityUtils {
|
||||
templates.add("vm/java/serviceImpl.java.vm");
|
||||
templates.add("vm/java/controller.java.vm");
|
||||
templates.add("vm/xml/mapper.xml.vm");
|
||||
if (DataBaseHelper.isOracle()) {
|
||||
DataBaseType dataBaseType = DataBaseHelper.getDataBaseType();
|
||||
if (dataBaseType.isOracle()) {
|
||||
templates.add("vm/sql/oracle/sql.vm");
|
||||
} else if (DataBaseHelper.isPostgerSql()) {
|
||||
} else if (dataBaseType.isPostgreSql()) {
|
||||
templates.add("vm/sql/postgres/sql.vm");
|
||||
} else if (DataBaseHelper.isSqlServer()) {
|
||||
} else if (dataBaseType.isSqlServer()) {
|
||||
templates.add("vm/sql/sqlserver/sql.vm");
|
||||
} else {
|
||||
templates.add("vm/sql/sql.vm");
|
||||
@ -163,7 +165,7 @@ public class VelocityUtils {
|
||||
String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/");
|
||||
String mybatisPath = MYBATIS_PATH + "/" + moduleName;
|
||||
String soybeanPath = "soy";
|
||||
|
||||
String soybeanModuleName = StrUtil.toSymbolCase(moduleName, '-');
|
||||
if (template.contains("domain.java.vm")) {
|
||||
fileName = StringUtils.format("{}/domain/{}.java", javaPath, className);
|
||||
}
|
||||
@ -186,17 +188,17 @@ public class VelocityUtils {
|
||||
} else if (template.contains("sql.vm")) {
|
||||
fileName = businessName + "Menu.sql";
|
||||
} else if (template.contains("index.vue.vm")) {
|
||||
fileName = StringUtils.format("{}/views/{}/{}/index.vue", soybeanPath, moduleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
fileName = StringUtils.format("{}/views/{}/{}/index.vue", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
} else if (template.contains("index-tree.vue.vm")) {
|
||||
fileName = StringUtils.format("{}/views/{}/{}/index.vue", soybeanPath, moduleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
fileName = StringUtils.format("{}/views/{}/{}/index.vue", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
} else if (template.contains("api.d.ts.vm")) {
|
||||
fileName = StringUtils.format("{}/typings/api/{}.{}.api.d.ts", soybeanPath, moduleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
fileName = StringUtils.format("{}/typings/api/{}.{}.api.d.ts", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
} else if (template.contains("api.ts.vm")) {
|
||||
fileName = StringUtils.format("{}/service/api/{}/{}.ts", soybeanPath, moduleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
fileName = StringUtils.format("{}/service/api/{}/{}.ts", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
} else if (template.contains("search.vue.vm")) {
|
||||
fileName = StringUtils.format("{}/views/{}/{}/modules/{}-search.vue", soybeanPath, moduleName, StrUtil.toSymbolCase(businessName, '-'), StrUtil.toSymbolCase(businessName, '-'));
|
||||
fileName = StringUtils.format("{}/views/{}/{}/modules/{}-search.vue", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'), StrUtil.toSymbolCase(businessName, '-'));
|
||||
} else if (template.contains("operate-drawer.vue.vm")) {
|
||||
fileName = StringUtils.format("{}/views/{}/{}/modules/{}-operate-drawer.vue", soybeanPath, moduleName, StrUtil.toSymbolCase(businessName, '-'), StrUtil.toSymbolCase(businessName, '-'));
|
||||
fileName = StringUtils.format("{}/views/{}/{}/modules/{}-operate-drawer.vue", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'), StrUtil.toSymbolCase(businessName, '-'));
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ const events = computed(() => {
|
||||
<style lang="scss">
|
||||
.tox.tox-silver-sink.tox-tinymce-aux {
|
||||
/** 该样式默认为1300的zIndex */
|
||||
z-index: 2025;
|
||||
z-index: 2025 !important;
|
||||
}
|
||||
|
||||
.app-tinymce {
|
||||
|
681
pnpm-lock.yaml
generated
681
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@
|
||||
import { computed } from 'vue';
|
||||
import hljs from 'highlight.js/lib/core';
|
||||
import json from 'highlight.js/lib/languages/json';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
hljs.registerLanguage('json', json);
|
||||
|
||||
@ -10,15 +11,19 @@ defineOptions({
|
||||
});
|
||||
|
||||
interface Props {
|
||||
class?: string;
|
||||
code?: string;
|
||||
showLineNumbers?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
class: '',
|
||||
code: '',
|
||||
showLineNumbers: false
|
||||
});
|
||||
|
||||
const DEFAULT_CLASS = 'max-h-500px';
|
||||
|
||||
/** 格式化JSON数据 */
|
||||
const jsonData = computed<string>(() => {
|
||||
if (!props.code) return '';
|
||||
@ -33,9 +38,9 @@ const jsonData = computed<string>(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="json-preview">
|
||||
<NCode :code="jsonData" :hljs="hljs" language="json" :show-line-numbers="showLineNumbers" />
|
||||
</div>
|
||||
<NScrollbar :class="twMerge(DEFAULT_CLASS, props.class)">
|
||||
<NCode :code="jsonData" :hljs="hljs" language="json" :show-line-numbers="showLineNumbers" :word-wrap="true" />
|
||||
</NScrollbar>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@ -44,18 +49,4 @@ html[class='dark'] {
|
||||
background-color: #7c7777;
|
||||
}
|
||||
}
|
||||
.json-preview {
|
||||
width: 100%;
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
@include scrollbar();
|
||||
.empty-data {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -4,5 +4,6 @@ export enum SetupStoreId {
|
||||
Auth = 'auth-store',
|
||||
Route = 'route-store',
|
||||
Tab = 'tab-store',
|
||||
Notice = 'notice-store'
|
||||
Notice = 'notice-store',
|
||||
Dict = 'dict-store'
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ const toGitee = () => {
|
||||
</NBadge>
|
||||
</NButton>
|
||||
</template>
|
||||
消息
|
||||
{{ $t('page.home.message') }}
|
||||
</NTooltip>
|
||||
</template>
|
||||
<NCard
|
||||
|
@ -43,3 +43,10 @@ export function fetchGetPostSelect(deptId?: CommonType.IdType, postIds?: CommonT
|
||||
params: { postIds, deptId }
|
||||
});
|
||||
}
|
||||
/** 获取部门选择框列表 */
|
||||
export function fetchGetPostDeptSelect() {
|
||||
return request<Api.Common.CommonTreeRecord>({
|
||||
url: '/system/post/deptTree',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import { localStg } from '@/utils/storage';
|
||||
import { SetupStoreId } from '@/enum';
|
||||
import { useRouteStore } from '../route';
|
||||
import { useTabStore } from '../tab';
|
||||
import useNoticeStore from '../notice';
|
||||
import { clearAuthStorage, getToken } from './shared';
|
||||
|
||||
export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
|
||||
@ -15,6 +16,7 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
|
||||
const authStore = useAuthStore();
|
||||
const routeStore = useRouteStore();
|
||||
const tabStore = useTabStore();
|
||||
const noticeStore = useNoticeStore();
|
||||
const { toLogin, redirectFromLogin } = useRouterPush(false);
|
||||
const { loading: loginLoading, startLoading, endLoading } = useLoading();
|
||||
|
||||
@ -48,6 +50,7 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
|
||||
await toLogin();
|
||||
}
|
||||
|
||||
noticeStore.clearNotice();
|
||||
tabStore.cacheTabs();
|
||||
routeStore.resetStore();
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { ref } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { $t } from '@/locales';
|
||||
import { SetupStoreId } from '@/enum';
|
||||
|
||||
export const useDictStore = defineStore('dict', () => {
|
||||
export const useDictStore = defineStore(SetupStoreId.Dict, () => {
|
||||
const dictData = ref<{ [key: string]: Api.System.DictData[] }>({});
|
||||
|
||||
const getDict = (key: string) => {
|
||||
|
@ -6,6 +6,7 @@ html,
|
||||
body,
|
||||
#app {
|
||||
height: 100%;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
html {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { watch } from 'vue';
|
||||
import { useEventSource } from '@vueuse/core';
|
||||
import useNoticeStore from '@/store/modules/notice';
|
||||
import { $t } from '@/locales';
|
||||
import { localStg } from './storage';
|
||||
|
||||
// 初始化
|
||||
@ -34,9 +35,14 @@ export const initSSE = (url: any) => {
|
||||
read: false,
|
||||
time: new Date().toLocaleString()
|
||||
});
|
||||
let content = data.value;
|
||||
const noticeType = content.match(/\[dict\.(.*?)\]/)?.[1];
|
||||
if (noticeType) {
|
||||
content = content.replace(`dict.${noticeType}`, $t(`dict.${noticeType}` as App.I18n.I18nKey));
|
||||
}
|
||||
window.$notification?.create({
|
||||
title: '消息',
|
||||
content: data.value,
|
||||
content,
|
||||
type: 'success',
|
||||
duration: 3000
|
||||
});
|
||||
|
@ -39,8 +39,7 @@ const activeModule = computed(() => moduleMap[props.module || 'pwd-login']);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Copyright By https://github.com/Daymychen/art-design-pro/blob/main/src/components/core/views/login/LoginLeftView.vue -->
|
||||
<div class="box-border size-full flex">
|
||||
<div class="scroll box-border size-full flex">
|
||||
<div class="relative box-border hidden h-full w-65vw overflow-hidden bg-primary-50 xl:block dark:bg-primary-900">
|
||||
<div class="relative z-100 flex items-center pl-30px pt-30px">
|
||||
<SystemLogo class="text-32px text-primary" />
|
||||
@ -55,13 +54,13 @@ const activeModule = computed(() => moduleMap[props.module || 'pwd-login']);
|
||||
</div>
|
||||
<WaveBg />
|
||||
</div>
|
||||
<header class="relative h-full flex-1 xl:m-auto sm:!w-full">
|
||||
<div class="relative z-100 block flex items-center pl-30px pt-30px xl:hidden">
|
||||
<SystemLogo class="text-32px text-primary" />
|
||||
<h3 class="ml-10px text-20px font-400">{{ $t('system.title') }}</h3>
|
||||
</div>
|
||||
<div class="position-fixed right-30px top-24px z-100 flex items-center justify-end">
|
||||
<div class="ml-15px inline-block flex cursor-pointer select-none p-5px">
|
||||
<div class="relative h-full flex-1 xl:m-auto sm:!w-full">
|
||||
<header class="flex-y-center justify-between px-30px pt-30px xl:justify-end">
|
||||
<div class="relative z-100 block flex items-center xl:hidden">
|
||||
<SystemLogo class="text-32px text-primary" />
|
||||
<h3 class="ml-10px text-20px font-400">{{ $t('system.title') }}</h3>
|
||||
</div>
|
||||
<div class="flex items-center justify-end">
|
||||
<ThemeSchemaSwitch
|
||||
:theme-schema="themeStore.themeScheme"
|
||||
:show-tooltip="false"
|
||||
@ -77,14 +76,32 @@ const activeModule = computed(() => moduleMap[props.module || 'pwd-login']);
|
||||
@change-lang="appStore.changeLocale"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<main class="absolute inset-0 m-auto h-630px max-w-450px w-full overflow-hidden rounded-5px bg-cover px-24px">
|
||||
</header>
|
||||
<main
|
||||
class="m-auto mt-10% h-630px max-w-450px w-full rounded-5px bg-cover px-24px xl:absolute xl:inset-0 lg:mt-15% xl:mt-auto"
|
||||
>
|
||||
<Transition :name="themeStore.page.animateMode" mode="out-in" appear>
|
||||
<component :is="activeModule.component" />
|
||||
</Transition>
|
||||
</main>
|
||||
</header>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
.scroll {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.scroll::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scroll {
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.scroll {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
</style>
|
||||
|
@ -40,6 +40,7 @@ const deptData = ref<Api.System.Dept[]>([]);
|
||||
const userOptions = ref<CommonType.Option<CommonType.IdType>[]>([]);
|
||||
const placeholder = ref<string>($t('page.system.dept.placeholder.defaultLeaderPlaceHolder'));
|
||||
const disabled = ref<boolean>(false);
|
||||
const expandedKeys = ref<CommonType.IdType[]>([]);
|
||||
|
||||
const title = computed(() => {
|
||||
const titles: Record<NaiveUI.TableOperateType, string> = {
|
||||
@ -55,7 +56,7 @@ const model: Model = reactive(createDefaultModel());
|
||||
|
||||
function createDefaultModel(): Model {
|
||||
return {
|
||||
parentId: '',
|
||||
parentId: props.rowData?.deptId || '',
|
||||
deptName: '',
|
||||
deptCategory: '',
|
||||
orderNum: null,
|
||||
@ -80,7 +81,6 @@ const rules: Record<RuleKey, App.Global.FormRule> = {
|
||||
function handleUpdateModelWhenEdit() {
|
||||
if (props.operateType === 'add') {
|
||||
Object.assign(model, createDefaultModel());
|
||||
model.parentId = props.rowData?.deptId || 0;
|
||||
}
|
||||
|
||||
if (props.operateType === 'edit' && props.rowData) {
|
||||
@ -144,6 +144,7 @@ async function getDeptData() {
|
||||
|
||||
if (data) {
|
||||
deptData.value = handleTree(data, { idField: 'deptId' });
|
||||
expandedKeys.value = [deptData.value[0].deptId];
|
||||
}
|
||||
endDeptLoading();
|
||||
}
|
||||
@ -186,15 +187,15 @@ watch(visible, () => {
|
||||
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
|
||||
<NDrawerContent :title="title" :native-scrollbar="false" closable>
|
||||
<NForm ref="formRef" :model="model" :rules="rules">
|
||||
<NFormItem v-if="model.parentId != 0" :label="$t('page.system.dept.parentId')" path="parentId">
|
||||
<NFormItem v-if="model.parentId !== 0" :label="$t('page.system.dept.parentId')" path="parentId">
|
||||
<NTreeSelect
|
||||
v-model:value="model.parentId"
|
||||
v-model:expanded-keys="expandedKeys"
|
||||
:loading="deptLoading"
|
||||
clearable
|
||||
:options="deptData"
|
||||
label-field="deptName"
|
||||
key-field="deptId"
|
||||
default-expand-all
|
||||
:placeholder="$t('page.system.dept.form.parentId.required')"
|
||||
/>
|
||||
</NFormItem>
|
||||
|
@ -38,6 +38,8 @@ const visible = defineModel<boolean>('visible', {
|
||||
default: false
|
||||
});
|
||||
|
||||
const defaultIcon = import.meta.env.VITE_MENU_ICON;
|
||||
|
||||
const iconType = ref<Api.System.IconType>('1');
|
||||
const { formRef, validate, restoreValidation } = useNaiveForm();
|
||||
const { createRequiredRule, createNumberRequiredRule } = useFormRules();
|
||||
@ -69,7 +71,7 @@ function createDefaultModel(): Model {
|
||||
visible: '0',
|
||||
status: '0',
|
||||
perms: '',
|
||||
icon: undefined,
|
||||
icon: defaultIcon,
|
||||
remark: ''
|
||||
};
|
||||
}
|
||||
@ -118,6 +120,7 @@ const localIconOptions = localIcons.map<SelectOption>(item => ({
|
||||
|
||||
function handleInitModel() {
|
||||
queryList.value = [];
|
||||
iconType.value = '1';
|
||||
Object.assign(model, createDefaultModel());
|
||||
|
||||
if (props.operateType === 'edit' && props.rowData) {
|
||||
@ -208,7 +211,7 @@ async function handleSubmit() {
|
||||
visible: menuVisible,
|
||||
status,
|
||||
perms,
|
||||
icon,
|
||||
icon: icon || defaultIcon,
|
||||
component: processComponent(component),
|
||||
remark
|
||||
};
|
||||
|
@ -2,8 +2,7 @@
|
||||
import { computed, ref } from 'vue';
|
||||
import { NButton, NDivider } from 'naive-ui';
|
||||
import { useLoading } from '@sa/hooks';
|
||||
import { fetchBatchDeletePost, fetchGetPostList } from '@/service/api/system/post';
|
||||
import { fetchGetDeptTree } from '@/service/api/system';
|
||||
import { fetchBatchDeletePost, fetchGetPostDeptSelect, fetchGetPostList } from '@/service/api/system/post';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useAuth } from '@/hooks/business/auth';
|
||||
import { useDownload } from '@/hooks/business/download';
|
||||
@ -191,16 +190,17 @@ const { loading: treeLoading, startLoading: startTreeLoading, endLoading: endTre
|
||||
const deptPattern = ref<string>();
|
||||
const deptData = ref<Api.Common.CommonTreeRecord>([]);
|
||||
const selectedKeys = ref<string[]>([]);
|
||||
async function getTreeData() {
|
||||
|
||||
async function getDeptOptions() {
|
||||
// 加载
|
||||
startTreeLoading();
|
||||
const { data: tree, error } = await fetchGetDeptTree();
|
||||
const { data: tree, error } = await fetchGetPostDeptSelect();
|
||||
if (!error) {
|
||||
deptData.value = tree;
|
||||
}
|
||||
endTreeLoading();
|
||||
}
|
||||
|
||||
getTreeData();
|
||||
getDeptOptions();
|
||||
|
||||
function handleClickTree(keys: string[]) {
|
||||
searchParams.belongDeptId = keys.length ? keys[0] : null;
|
||||
@ -210,7 +210,7 @@ function handleClickTree(keys: string[]) {
|
||||
|
||||
function handleResetTreeData() {
|
||||
deptPattern.value = undefined;
|
||||
getTreeData();
|
||||
getDeptOptions();
|
||||
}
|
||||
|
||||
function handleResetSearch() {
|
||||
@ -323,11 +323,11 @@ function handleResetSearch() {
|
||||
}
|
||||
|
||||
:deep(.n-tree-node) {
|
||||
height: 33px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
:deep(.n-tree-node-switcher) {
|
||||
height: 33px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
:deep(.n-tree-node-switcher__icon) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script setup lang="tsx">
|
||||
import { computed, ref } from 'vue';
|
||||
import { NButton, NDivider } from 'naive-ui';
|
||||
import { NAvatar, NButton, NDivider, NEllipsis } from 'naive-ui';
|
||||
import { useBoolean, useLoading } from '@sa/hooks';
|
||||
import { jsonClone } from '@sa/utils';
|
||||
import { fetchBatchDeleteUser, fetchGetDeptTree, fetchGetUserList, fetchUpdateUserStatus } from '@/service/api/system';
|
||||
@ -12,6 +12,7 @@ import { useDownload } from '@/hooks/business/download';
|
||||
import ButtonIcon from '@/components/custom/button-icon.vue';
|
||||
import { $t } from '@/locales';
|
||||
import StatusSwitch from '@/components/custom/status-switch.vue';
|
||||
import DictTag from '@/components/custom/dict-tag.vue';
|
||||
import UserOperateDrawer from './modules/user-operate-drawer.vue';
|
||||
import UserImportModal from './modules/user-import-modal.vue';
|
||||
import UserPasswordDrawer from './modules/user-password-drawer.vue';
|
||||
@ -65,41 +66,64 @@ const {
|
||||
key: 'index',
|
||||
title: $t('common.index'),
|
||||
align: 'center',
|
||||
width: 64
|
||||
width: 48
|
||||
},
|
||||
{
|
||||
key: 'userName',
|
||||
title: $t('page.system.user.userName'),
|
||||
align: 'center',
|
||||
minWidth: 120,
|
||||
ellipsis: true
|
||||
align: 'left',
|
||||
width: 200,
|
||||
ellipsis: true,
|
||||
render: row => {
|
||||
return (
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<NAvatar src={row.avatar} class="bg-primary">
|
||||
{row.avatar ? undefined : row.nickName.charAt(0)}
|
||||
</NAvatar>
|
||||
<div class="max-w-160px flex flex-col">
|
||||
<NEllipsis>{row.userName}</NEllipsis>
|
||||
<NEllipsis>{row.nickName}</NEllipsis>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'nickName',
|
||||
title: $t('page.system.user.nickName'),
|
||||
key: 'sex',
|
||||
title: $t('page.system.user.sex'),
|
||||
align: 'center',
|
||||
minWidth: 120,
|
||||
ellipsis: true
|
||||
width: 80,
|
||||
ellipsis: true,
|
||||
render(row) {
|
||||
return <DictTag value={row.sex} dictCode="sys_user_sex" />;
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'deptName',
|
||||
title: $t('page.system.user.deptName'),
|
||||
align: 'center',
|
||||
minWidth: 120,
|
||||
width: 120,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
key: 'email',
|
||||
title: $t('page.system.user.email'),
|
||||
align: 'center',
|
||||
width: 120,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
key: 'phonenumber',
|
||||
title: $t('page.system.user.phonenumber'),
|
||||
align: 'center',
|
||||
minWidth: 120,
|
||||
width: 120,
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
key: 'status',
|
||||
title: $t('page.system.user.status'),
|
||||
align: 'center',
|
||||
minWidth: 80,
|
||||
width: 80,
|
||||
render(row) {
|
||||
return (
|
||||
<StatusSwitch
|
||||
@ -115,7 +139,7 @@ const {
|
||||
key: 'createTime',
|
||||
title: $t('page.system.user.createTime'),
|
||||
align: 'center',
|
||||
minWidth: 120
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
key: 'operate',
|
||||
@ -341,7 +365,7 @@ function handleResetSearch() {
|
||||
:data="data"
|
||||
size="small"
|
||||
:flex-height="!appStore.isMobile"
|
||||
:scroll-x="962"
|
||||
:scroll-x="1200"
|
||||
:loading="loading"
|
||||
remote
|
||||
:row-key="row => row.userId"
|
||||
@ -391,11 +415,11 @@ function handleResetSearch() {
|
||||
}
|
||||
|
||||
:deep(.n-tree-node) {
|
||||
height: 25px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
:deep(.n-tree-node-switcher) {
|
||||
height: 25px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
:deep(.n-tree-node-switcher__icon) {
|
||||
|
@ -356,7 +356,7 @@ const columns: NaiveUI.TableColumn<Api.Tool.GenTableColumn>[] = [
|
||||
<NFormItemGi span="24 s:12" path="moduleName">
|
||||
<template #label>
|
||||
<div class="flex-center">
|
||||
<FormTip content="可理解为子系统名,例如 system" />
|
||||
<FormTip content="可理解为子系统名,例如 system,flow-instance。避免驼峰命名" />
|
||||
<span class="pl-3px">生成模块名</span>
|
||||
</div>
|
||||
</template>
|
||||
|
Reference in New Issue
Block a user