10 Commits

Author SHA1 Message Date
wcg
9afeb59766 fix(rbac): 角色菜单树接口增加菜单来源参数 2026-01-27 18:11:52 +08:00
chenchun
960d8a309c fix: 允许静态文件返回未知文件类型并设置默认内容类型
在 UseStaticFiles 配置中启用 ServeUnknownFileTypes 并将 DefaultContentType 设为 application/octet-stream,确保像
2026-01-23 16:52:58 +08:00
dubai
adf09f4753 feat(menu): 添加 Vben5 路由构建功能并优化菜单转换逻辑
- 为 MenuAggregateRoot 添加 Vben5RouterBuild 扩展方法,支持 Vben5 框架的路由构建
- 在 Vben5RouterBuild 中实现完整的 URL 类型检测和内嵌 iframe 处理逻辑
- 添加对内嵌链接、外部链接和普通路由的不同处理策略
- 优化路由名称生成规则,支持开头大写处理
- 在种子数据中添加示例并注释说明
2026-01-11 20:49:47 +08:00
dubai
dc0c83a620 chore(menu): 注释代码生成菜单种子数据 2026-01-11 19:14:34 +08:00
dubai
a1210c1efd fix(menu): 修复菜单列表接口参数缺失menuSource
- 不传递参数时后端默认为ruoyi菜单
2026-01-11 18:41:53 +08:00
dubai
18f253371b fix(rbac): 修复角色授权用户菜单数据种子中的父子关系配置
- 为 roleAuthUser 菜单实体添加了正确的 ParentId系统管理
2026-01-11 18:33:22 +08:00
dubai
bd410087af fix(profile): 暂不支持社交账号绑定提示 2026-01-11 14:28:05 +08:00
dubai
d4678f2fe3 refactor(system): 移除旧用户个人主页信息接口定义 2026-01-11 14:24:21 +08:00
dubai
6f64ebfba3 fix(profile): 修复个人中心接口报错 2026-01-11 14:23:26 +08:00
dubai
689b136724 fix(core): 统一创建时间字段名从 createTime 到 creationTime 2026-01-11 14:15:58 +08:00
43 changed files with 357 additions and 159 deletions

View File

@@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Application.Services;
using Yi.Framework.Ddd.Application.Contracts;
using Yi.Framework.Rbac.Application.Contracts.Dtos.Role;
using Yi.Framework.Rbac.Domain.Shared.Enums;
namespace Yi.Framework.Rbac.Application.Contracts.IServices
{
@@ -15,7 +16,7 @@ namespace Yi.Framework.Rbac.Application.Contracts.IServices
/// </summary>
/// <param name="roleId">角色ID</param>
/// <returns>角色菜单树数据包含已选中的菜单ID和菜单树结构</returns>
Task<ActionResult> GetMenuTreeAsync(Guid roleId);
Task<ActionResult> GetMenuTreeAsync(Guid roleId,MenuSourceEnum menuSource);
/// <summary>
/// 获取角色部门树

View File

@@ -417,7 +417,7 @@ namespace Yi.Framework.Rbac.Application.Services
{
//将后端菜单转换成前端路由,组件级别需要过滤
output =
ObjectMapper.Map<List<MenuDto>, List<MenuAggregateRoot>>(menus.Where(x=>x.MenuSource==MenuSourceEnum.Ruoyi).ToList()).Vue3RuoYiRouterBuild(MenuSourceEnum.Ruoyi);
ObjectMapper.Map<List<MenuDto>, List<MenuAggregateRoot>>(menus.Where(x=>x.MenuSource==MenuSourceEnum.Ruoyi).ToList()).Vue3RuoYiRouterBuild();
}
else if (routerType == "pure")
{
@@ -429,7 +429,7 @@ namespace Yi.Framework.Rbac.Application.Services
{
//将后端菜单转换成前端路由,组件级别需要过滤
output =
ObjectMapper.Map<List<MenuDto>, List<MenuAggregateRoot>>(menus.Where(x=>x.MenuSource==MenuSourceEnum.Vben5).ToList()).Vue3RuoYiRouterBuild(MenuSourceEnum.Vben5);
ObjectMapper.Map<List<MenuDto>, List<MenuAggregateRoot>>(menus.Where(x=>x.MenuSource==MenuSourceEnum.Vben5).ToList()).Vben5RouterBuild();
}
return output;

View File

@@ -227,12 +227,12 @@ namespace Yi.Framework.Rbac.Application.Services.System
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
public async Task<ActionResult> GetMenuTreeAsync(Guid roleId)
public async Task<ActionResult> GetMenuTreeAsync(Guid roleId, MenuSourceEnum menuSource = MenuSourceEnum.Vben5)
{
var checkedKeys = await _menuRepository._DbQueryable
.Where(m => SqlFunc.Subqueryable<RoleMenuEntity>().Where(rm => rm.RoleId == roleId && rm.MenuId == m.Id).Any())
.Select(x => x.Id).ToListAsync();
var menus = await _menuRepository._DbQueryable.ToListAsync();
var menus = await _menuRepository._DbQueryable.Where(x => x.State == true && x.MenuSource == menuSource).ToListAsync();
var menuTrees = menus.TreeDtoBuild();
return new JsonResult(new
{

View File

@@ -1,4 +1,5 @@
using System.Web;
using System.Text.RegularExpressions;
using System.Web;
using NUglify.Helpers;
using SqlSugar;
using Volo.Abp;
@@ -168,12 +169,12 @@ namespace Yi.Framework.Rbac.Domain.Entities
/// </summary>
/// <param name="menus"></param>
/// <returns></returns>
public static List<Vue3RouterDto> Vue3RuoYiRouterBuild(this List<MenuAggregateRoot> menus,MenuSourceEnum menuSource)
public static List<Vue3RouterDto> Vue3RuoYiRouterBuild(this List<MenuAggregateRoot> menus)
{
menus = menus
.Where(m => m.State == true)
.Where(m => m.MenuType != MenuTypeEnum.Component)
.Where(m => m.MenuSource == menuSource)
.Where(m => m.MenuSource == MenuSourceEnum.Ruoyi)
.ToList();
List<Vue3RouterDto> routers = new();
foreach (var m in menus)
@@ -231,7 +232,194 @@ namespace Yi.Framework.Rbac.Domain.Entities
return TreeHelper.SetTree(routers);
}
/// <summary>
/// 构建vue3路由
/// </summary>
/// <param name="menus"></param>
/// <returns></returns>
public static List<Vue3RouterDto> Vben5RouterBuild(this List<MenuAggregateRoot> menus)
{
menus = menus
.Where(m => m.State == true)
.Where(m => m.MenuType != MenuTypeEnum.Component)
.Where(m => m.MenuSource == MenuSourceEnum.Vben5)
.ToList();
List<Vue3RouterDto> routers = new();
foreach (var m in menus)
{
var r = new Vue3RouterDto();
r.OrderNum = m.OrderNum;
r.Id = m.Id;
r.ParentId = m.ParentId;
r.Hidden = !m.IsShow;
// 检测是否为 URL 链接http:// 或 https:// 开头)
bool isUrl = !string.IsNullOrEmpty(m.Router) &&
(m.Router.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
m.Router.StartsWith("https://", StringComparison.OrdinalIgnoreCase));
// 判断是否为内嵌 iframe
// 1. Component 明确设置为 "InnerLink"(优先级最高)
// 2. 或者检测到是 URL 且 isLink = false自动识别为内嵌
bool isInnerLink = (!string.IsNullOrEmpty(m.Component) &&
m.Component.Equals("InnerLink", StringComparison.OrdinalIgnoreCase)) ||
(isUrl && !m.IsLink);
// 判断是否为外链(新标签页打开):
// 检测到是 URL 且 isLink = true且不是内嵌 iframe
bool isExternalLink = isUrl && m.IsLink && !isInnerLink;
// 生成路由名称
string routerName;
if (isInnerLink)
{
// 内嵌 iframe从 path 或 router 中提取名称
routerName = m.Router?.Split("/").LastOrDefault() ?? "InnerLink";
}
else if (isExternalLink)
{
// 外链:从 URL 中提取名称
try
{
var uri = new Uri(m.Router!);
routerName = uri.Host.Replace(".", "").Replace("-", "");
}
catch
{
// 如果 URL 格式不正确,使用默认名称
routerName = "ExternalLink";
}
}
else
{
// 普通路由:从 router 中提取名称
routerName = m.Router?.Split("/").LastOrDefault() ?? string.Empty;
}
// 开头大写处理
if (string.IsNullOrEmpty(routerName))
{
r.Name = routerName;
}
else if (routerName.Length == 1)
{
r.Name = routerName.ToUpper();
}
else
{
r.Name = routerName.First().ToString().ToUpper() + routerName.Substring(1);
}
// 设置路径
r.Path = m.Router ?? string.Empty;
// 处理内嵌 iframe 场景(优先级最高)
// 触发条件Component = "InnerLink" 或 (检测到 URL 且 isLink = false)
if (isInnerLink)
{
// 内嵌 iframecomponent 为 InnerLinkmeta.link 包含完整 iframe 地址
r.Redirect = "noRedirect";
r.AlwaysShow = false;
r.Component = "InnerLink";
// meta.link 应该包含完整的 iframe 地址,优先使用 Router
string iframeUrl = !string.IsNullOrEmpty(m.Router) ? m.Router : m.Component ?? string.Empty;
// 清理 path去除协议和特殊字符避免前端路由拼接时出现问题
string cleanedPath = m.Router ?? m.Component ?? string.Empty;
if (!string.IsNullOrEmpty(cleanedPath))
{
// 去除 http:// 或 https://
cleanedPath = Regex.Replace(cleanedPath, @"^https?://", "", RegexOptions.IgnoreCase);
// 去除 /#/
cleanedPath = cleanedPath.Replace("/#/", "");
// 去除 #
cleanedPath = cleanedPath.Replace("#", "");
// 去除 ? 和 &
cleanedPath = cleanedPath.Replace("?", "").Replace("&", "");
}
// 使用清理后的 path用于前端路由匹配
r.Path = cleanedPath;
r.Meta = new Meta
{
Title = m.MenuName!,
Icon = m.MenuIcon ?? string.Empty,
NoCache = !m.IsCache,
link = iframeUrl // meta.link 保持完整的 URL用于 iframe 加载
};
}
// 处理外链场景(新标签页打开)
// 触发条件:检测到 URL 且 isLink = true
else if (isExternalLink)
{
// 外链path 保持原样component 为 Layout 或 ParentViewmeta.link 包含完整外链地址
r.Redirect = "noRedirect";
r.AlwaysShow = false;
// 判断是否为最顶层的路由
if (Guid.Empty == m.ParentId)
{
r.Component = "Layout";
}
else
{
r.Component = "ParentView";
}
r.Meta = new Meta
{
Title = m.MenuName!,
Icon = m.MenuIcon ?? string.Empty,
NoCache = !m.IsCache,
link = m.Router! // 完整的外链地址
};
}
// 处理普通路由菜单
else
{
if (m.MenuType == MenuTypeEnum.Catalogue)
{
r.Redirect = "noRedirect";
r.AlwaysShow = true;
// 判断是否为最顶层的路由
if (Guid.Empty == m.ParentId)
{
r.Component = "Layout";
}
else
{
r.Component = "ParentView";
}
}
else if (m.MenuType == MenuTypeEnum.Menu)
{
r.Redirect = "noRedirect";
r.AlwaysShow = false;
r.Component = m.Component ?? string.Empty;
}
r.Meta = new Meta
{
Title = m.MenuName!,
Icon = m.MenuIcon ?? string.Empty,
NoCache = !m.IsCache
};
// 如果 IsLink 为 true 但不是外链,则可能是其他类型的链接
if (m.IsLink && !string.IsNullOrEmpty(m.Router))
{
r.Meta.link = m.Router;
}
}
routers.Add(r);
}
return TreeHelper.SetTree(routers);
}
/// <summary>
/// 构建vue3 pure路由

View File

@@ -44,72 +44,72 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
};
entities.Add(system);
//代码生成
MenuAggregateRoot code = new MenuAggregateRoot(_guidGenerator.Create(), Guid.Empty)
{
MenuName = "代码生成",
MenuType = MenuTypeEnum.Catalogue,
Router = "/code",
IsShow = true,
IsLink = false,
MenuIcon = "tabler:code",
OrderNum = 91,
IsDeleted = false,
};
entities.Add(code);
// //代码生成
// MenuAggregateRoot code = new MenuAggregateRoot(_guidGenerator.Create(), Guid.Empty)
// {
// MenuName = "代码生成",
// MenuType = MenuTypeEnum.Catalogue,
// Router = "/code",
// IsShow = true,
// IsLink = false,
// MenuIcon = "tabler:code",
// OrderNum = 91,
// IsDeleted = false,
// };
// entities.Add(code);
//数据表管理
MenuAggregateRoot table = new MenuAggregateRoot(_guidGenerator.Create(), code.Id)
{
MenuName = "数据表管理",
PermissionCode = "code:table:list",
MenuType = MenuTypeEnum.Menu,
Router = "table",
IsShow = true,
IsLink = false,
IsCache = true,
Component = "code/table/index",
MenuIcon = "tabler:table",
OrderNum = 100,
IsDeleted = false
};
entities.Add(table);
//字段管理
MenuAggregateRoot field = new MenuAggregateRoot(_guidGenerator.Create(), code.Id)
{
MenuName = "字段管理",
PermissionCode = "code:field:list",
MenuType = MenuTypeEnum.Menu,
Router = "field",
IsShow = true,
IsLink = false,
IsCache = true,
Component = "code/field/index",
MenuIcon = "tabler:file-code",
OrderNum = 99,
ParentId = code.Id,
IsDeleted = false
};
entities.Add(field);
//模板管理
MenuAggregateRoot template = new MenuAggregateRoot(_guidGenerator.Create(), code.Id)
{
MenuName = "模板管理",
PermissionCode = "code:template:list",
MenuType = MenuTypeEnum.Menu,
Router = "template",
IsShow = true,
IsLink = false,
IsCache = true,
Component = "code/template/index",
MenuIcon = "tabler:template",
OrderNum = 98,
IsDeleted = false
};
entities.Add(template);
// //数据表管理
// MenuAggregateRoot table = new MenuAggregateRoot(_guidGenerator.Create(), code.Id)
// {
// MenuName = "数据表管理",
// PermissionCode = "code:table:list",
// MenuType = MenuTypeEnum.Menu,
// Router = "table",
// IsShow = true,
// IsLink = false,
// IsCache = true,
// Component = "code/table/index",
// MenuIcon = "tabler:table",
// OrderNum = 100,
// IsDeleted = false
// };
// entities.Add(table);
//
// //字段管理
// MenuAggregateRoot field = new MenuAggregateRoot(_guidGenerator.Create(), code.Id)
// {
// MenuName = "字段管理",
// PermissionCode = "code:field:list",
// MenuType = MenuTypeEnum.Menu,
// Router = "field",
// IsShow = true,
// IsLink = false,
// IsCache = true,
// Component = "code/field/index",
// MenuIcon = "tabler:file-code",
// OrderNum = 99,
// ParentId = code.Id,
// IsDeleted = false
// };
// entities.Add(field);
//
//
// //模板管理
// MenuAggregateRoot template = new MenuAggregateRoot(_guidGenerator.Create(), code.Id)
// {
// MenuName = "模板管理",
// PermissionCode = "code:template:list",
// MenuType = MenuTypeEnum.Menu,
// Router = "template",
// IsShow = true,
// IsLink = false,
// IsCache = true,
// Component = "code/template/index",
// MenuIcon = "tabler:template",
// OrderNum = 98,
// IsDeleted = false
// };
// entities.Add(template);
//系统监控
@@ -184,7 +184,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
{
MenuName = "定时任务",
MenuType = MenuTypeEnum.Menu,
Router = "http://127.0.0.1:19002/hangfire",
Router = "http://127.0.0.1:19001/hangfire",
IsShow = true,
IsLink = true,
MenuIcon = "tabler:calendar-clock",
@@ -212,9 +212,9 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
{
MenuName = "接口文档",
MenuType = MenuTypeEnum.Menu,
Router = "http://127.0.0.1:19002/swagger",
Router = "http://127.0.0.1:19001/swagger",
IsShow = true,
IsLink = true,
IsLink = false, // Vben5RouterBuild方法会基于Router属性判断是否为链接如果是再根据IsLink字段判断是内嵌还是跳转
MenuIcon = "devicon:swagger",
OrderNum = 100,
IsDeleted = false,
@@ -465,7 +465,8 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
Component = "system/role/authUser",
MenuIcon = "tabler:user-shield",
OrderNum = 15,
IsDeleted = false
IsDeleted = false,
ParentId = system.Id
};
entities.Add(roleAuthUser);

View File

@@ -368,7 +368,9 @@ namespace Yi.Abp.Web
{
[".wxss"] = "text/css"
}
}
},
ServeUnknownFileTypes = true,
DefaultContentType = "application/octet-stream"
});
app.UseDefaultFiles();
app.UseDirectoryBrowser("/api/app/wwwroot");

View File

@@ -21,7 +21,7 @@ function generateMockDataList(count: number) {
pid: 0,
name: faker.commerce.department(),
status: faker.helpers.arrayElement([0, 1]),
createTime: formatterCN.format(
creationTime: formatterCN.format(
faker.date.between({ from: '2021-01-01', to: '2022-12-31' }),
),
remark: faker.lorem.sentence(),
@@ -34,7 +34,7 @@ function generateMockDataList(count: number) {
pid: dataItem.id,
name: faker.commerce.department(),
status: faker.helpers.arrayElement([0, 1]),
createTime: formatterCN.format(
creationTime: formatterCN.format(
faker.date.between({ from: '2023-01-01', to: '2023-12-31' }),
),
remark: faker.lorem.sentence(),

View File

@@ -23,7 +23,7 @@ function generateMockDataList(count: number) {
id: faker.string.uuid(),
name: faker.commerce.product(),
status: faker.helpers.arrayElement([0, 1]),
createTime: formatterCN.format(
creationTime: formatterCN.format(
faker.date.between({ from: '2022-01-01', to: '2025-01-01' }),
),
permissions: faker.helpers.arrayElements(menuIds),
@@ -71,10 +71,10 @@ export default eventHandler(async (event) => {
);
}
if (startTime) {
listData = listData.filter((item) => item.createTime >= startTime);
listData = listData.filter((item) => item.creationTime >= startTime);
}
if (endTime) {
listData = listData.filter((item) => item.createTime <= endTime);
listData = listData.filter((item) => item.creationTime <= endTime);
}
if (['0', '1'].includes(status as string)) {
listData = listData.filter((item) => item.status === Number(status));

View File

@@ -4,7 +4,7 @@ export type IDS = (number | string)[];
export interface BaseEntity {
createBy?: string;
createDept?: string;
createTime?: string;
creationTime?: string;
updateBy?: string;
updateTime?: string;
}
@@ -24,9 +24,9 @@ export interface PageResult<T = any> {
*
* 排序支持的用法如下:
* {isAsc:"asc",orderByColumn:"id"} order by id asc
* {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc
* {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc
* {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc
* {isAsc:"asc",orderByColumn:"id,creationTime"} order by id asc,create_time asc
* {isAsc:"desc",orderByColumn:"id,creationTime"} order by id desc,create_time desc
* {isAsc:"asc,desc",orderByColumn:"id,creationTime"} order by id asc,create_time desc
*
* @param SkipCount 当前页
* @param MaxResultCount 每页大小

View File

@@ -13,7 +13,7 @@ export interface Role {
export interface User {
avatar: string;
createTime: string;
creationTime: string;
deptId: number;
deptName: string;
email: string;

View File

@@ -54,4 +54,5 @@ export interface MenuQuery {
menuName?: string;
isShow?: boolean;
state?: boolean;
menuSource: number;
}

View File

@@ -4,7 +4,7 @@ export interface OssFile {
originalName: string;
fileSuffix: string;
url: string;
createTime: string;
creationTime: string;
createBy: number;
createByName: string;
service: string;

View File

@@ -1,21 +1,27 @@
import type { FileCallBack, UpdatePasswordParam, UserProfile } from './model';
import type { FileCallBack, UpdatePasswordParam } from './model';
import type { UserInfoResp } from '#/api/core/user';
import { buildUUID } from '@vben/utils';
import { requestClient } from '#/api/request';
import { getUserInfoApi } from '#/api/core/user';
enum Api {
root = '/user/profile',
updateAvatar = '/user/profile/avatar',
updatePassword = '/user/profile/updatePwd',
updatePassword = '/account/password',
}
/**
* 用户个人主页信息
* @returns userInformation
*/
export function userProfile() {
return requestClient.get<UserProfile>(Api.root);
export async function userProfile() {
const resp = await getUserInfoApi() as UserInfoResp;
if (!resp) {
throw new Error('获取用户信息失败');
}
return resp;
}
/**

View File

@@ -9,7 +9,7 @@ export interface Dept {
phone?: any;
email: string;
status: string;
createTime?: any;
creationTime?: any;
}
export interface Role {
@@ -22,7 +22,7 @@ export interface Role {
deptCheckStrictly?: any;
status: string;
remark: string;
createTime?: any;
creationTime?: any;
flag: boolean;
superAdmin: boolean;
}
@@ -42,7 +42,7 @@ export interface User {
loginIp: string;
loginDate: string;
remark: string;
createTime: string;
creationTime: string;
dept: Dept;
roles: Role[];
roleIds?: string[];
@@ -51,18 +51,6 @@ export interface User {
deptName: string;
}
/**
* @description 用户个人主页信息
* @param user 用户信息
* @param roleGroup 角色名称
* @param postGroup 岗位名称
*/
export interface UserProfile {
user: User;
roleGroup: string;
postGroup: string;
}
export interface UpdatePasswordParam {
oldPassword: string;
newPassword: string;

View File

@@ -157,5 +157,5 @@ export function roleDeptTree(roleId: ID) {
* @returns resp
*/
export function roleMenuTreeSelect(roleId: ID) {
return requestClient.get<MenuResp>(`${Api.roleMenuTree}/${roleId}`);
return requestClient.get<MenuResp>(`${Api.roleMenuTree}/${roleId}?menuSource=Vben5`);
}

View File

@@ -22,5 +22,5 @@ export interface SocialInfo {
code?: any;
oauthToken?: any;
oauthTokenSecret?: any;
createTime: string;
creationTime: string;
}

View File

@@ -28,7 +28,7 @@ export interface Role {
deptCheckStrictly?: boolean;
status: string;
remark: string;
createTime?: string;
creationTime?: string;
flag: boolean;
superAdmin: boolean;
}
@@ -68,7 +68,7 @@ export interface Post {
postSort: number;
status: string;
remark: string;
createTime: string;
creationTime: string;
}
/**

View File

@@ -1,7 +1,7 @@
export interface Column {
createDept?: any;
createBy?: any;
createTime?: any;
creationTime?: any;
updateBy?: any;
updateTime?: any;
columnId: string;
@@ -37,7 +37,7 @@ export interface Column {
export interface Table {
createDept?: any;
createBy?: any;
createTime?: any;
creationTime?: any;
updateBy?: any;
updateTime?: any;
tableId: string;
@@ -72,7 +72,7 @@ export interface Table {
export interface Row {
createDept: number;
createBy: number;
createTime: string;
creationTime: string;
updateBy: number;
updateTime: string;
columnId: string;
@@ -108,7 +108,7 @@ export interface Row {
export interface Column {
createDept?: any;
createBy?: any;
createTime?: any;
creationTime?: any;
updateBy?: any;
updateTime?: any;
columnId: string;
@@ -144,7 +144,7 @@ export interface Column {
export interface Info {
createDept?: any;
createBy?: any;
createTime?: any;
creationTime?: any;
updateBy?: any;
updateTime?: any;
tableId: string;

View File

@@ -1,6 +1,6 @@
export interface ProcessDefinition {
id: string;
createTime: string;
creationTime: string;
updateTime: string;
tenantId: string;
delFlag: string;

View File

@@ -1,6 +1,6 @@
export interface Flow {
id: string;
createTime: string;
creationTime: string;
updateTime: string;
tenantId: string;
delFlag: string;

View File

@@ -7,7 +7,7 @@ export interface ButtonWithPermission {
export interface TaskInfo {
id: string;
categoryName: string;
createTime: string;
creationTime: string;
updateTime: string;
tenantId: string;
delFlag?: any;
@@ -85,7 +85,7 @@ export type TaskOperationType =
export interface NextNodeInfo {
skipList: string[];
id: string;
createTime: string;
creationTime: string;
updateTime: string;
tenantId: string;
delFlag: string;

View File

@@ -4,7 +4,7 @@ import type { BindItem } from '../../oauth-common';
import type { SocialInfo } from '#/api/system/social/model';
import { onMounted, ref } from 'vue';
import { message } from 'ant-design-vue';
import { Alert, Avatar, Card, Empty, Modal, Tooltip } from 'ant-design-vue';
import { authUnbinding } from '#/api';
@@ -20,7 +20,15 @@ interface BindItemWithInfo extends BindItem {
const bindList = ref<BindItemWithInfo[]>([]);
async function loadData() {
const resp = await socialList();
// const resp = await socialList();
const resp = [];
// messgae提示暂不支持
message.error('暂不支持');
const list: BindItemWithInfo[] = [...accountBindList];
list.forEach((item) => {
@@ -96,7 +104,7 @@ const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
<template #title>
<div class="flex flex-col items-center gap-2 p-2">
<Avatar :size="36" :src="item.info.avatar" />
<div>绑定时间: {{ item.info.createTime }}</div>
<div>绑定时间: {{ item.info.creationTime }}</div>
</div>
</template>
<div class="cursor-pointer">

View File

@@ -1,8 +1,6 @@
<script setup lang="ts">
import type { Recordable } from '@vben/types';
import type { UserProfile } from '#/api/system/profile/model';
import type { UserInfoResp } from '#/api/core/user';
import { onMounted } from 'vue';
import { DictEnum } from '@vben/constants';
@@ -17,7 +15,7 @@ import { getDictOptions } from '#/utils/dict';
import { emitter } from '../mitt';
const props = defineProps<{ profile: UserProfile }>();
const props = defineProps<{ profile: UserInfoResp }>();
const userStore = useUserStore();
const authStore = useAuthStore();

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import type { UserProfile } from '#/api/system/profile/model';
import type { UserInfoResp } from '#/api/core/user';
import { onMounted, onUnmounted, ref } from 'vue';
@@ -13,10 +13,14 @@ import { emitter } from './mitt';
import ProfilePanel from './profile-panel.vue';
import SettingPanel from './setting-panel.vue';
const profile = ref<UserProfile>();
async function loadProfile() {
const resp = await userProfile();
profile.value = resp;
const profile = ref<UserInfoResp>();
async function loadProfile() {
try {
const resp = await userProfile();
profile.value = resp;
} catch (error) {
console.error('加载用户信息失败:', error);
}
}
onMounted(loadProfile);

View File

@@ -32,7 +32,7 @@ export const querySchema: FormSchemaGetter = () => [
},
{
component: 'RangePicker',
fieldName: 'createTime',
fieldName: 'creationTime',
label: '操作时间',
componentProps: {
valueFormat: 'YYYY-MM-DD HH:mm:ss',

View File

@@ -39,7 +39,7 @@ const formOptions: VbenFormProps = {
// 日期选择格式化
fieldMappingTime: [
[
'createTime',
'creationTime',
['startTime', 'endTime'],
['YYYY-MM-DD 00:00:00', 'YYYY-MM-DD 23:59:59'],
],

View File

@@ -50,6 +50,7 @@ const gridOptions: VxeGridProps<Record<string, any>> = {
query: async (_, formValues = {}) => {
const resp = await menuList({
...formValues,
menuSource: 2 // 不传后端会默认为ruoyi的菜单
});
// 统一处理数据:确保 menuId 和 parentId 存在,并将根节点的 parentId 置为 null
const items = (resp || []).map((item) => {

View File

@@ -46,7 +46,7 @@ const [BasicForm, formApi] = useVbenForm({
async function setupMenuSelect() {
// menu
const menuArray = await menuList();
const menuArray = await menuList({ menuSource: 2 }); // 不传后端会默认为ruoyi的菜单
// support i18n
menuArray.forEach((item) => {
item.menuName = $t(item.menuName);

View File

@@ -24,7 +24,7 @@ export const querySchema: FormSchemaGetter = () => [
},
{
component: 'RangePicker',
fieldName: 'createTime',
fieldName: 'creationTime',
label: '创建时间',
},
];
@@ -53,7 +53,7 @@ export const columns: VxeGridProps['columns'] = [
},
{
title: '创建时间',
field: 'createTime',
field: 'creationTime',
sortable: true,
},
{

View File

@@ -51,7 +51,7 @@ const formOptions: VbenFormProps = {
// 日期选择格式化
fieldMappingTime: [
[
'createTime',
'creationTime',
['params[beginCreateTime]', 'params[endCreateTime]'],
['YYYY-MM-DD 00:00:00', 'YYYY-MM-DD 23:59:59'],
],

View File

@@ -23,7 +23,7 @@ export const querySchema: FormSchemaGetter = () => [
},
{
component: 'RangePicker',
fieldName: 'createTime',
fieldName: 'creationTime',
label: '创建时间',
},
];
@@ -43,7 +43,7 @@ export const columns: VxeGridProps['columns'] = [
title: '实体类',
},
{
field: 'createTime',
field: 'creationTime',
title: '创建时间',
},
{

View File

@@ -67,7 +67,7 @@ async function initTreeSelect(columns: Column[]) {
* 加载菜单选择
*/
async function initMenuSelect() {
const list = await menuList();
const list = await menuList({ menuSource: 2 }); // 不传后端会默认为ruoyi的菜单
// support i18n
list.forEach((item) => {
item.menuName = $t(item.menuName);

View File

@@ -40,7 +40,7 @@ const formOptions: VbenFormProps = {
// 日期选择格式化
fieldMappingTime: [
[
'createTime',
'creationTime',
['startTime', 'endTime'],
['YYYY-MM-DD 00:00:00', 'YYYY-MM-DD 23:59:59'],
],

View File

@@ -63,7 +63,7 @@ const gridOptions: VxeGridProps = {
},
{
title: '创建时间',
field: 'createTime',
field: 'creationTime',
},
{
title: '更新时间',

View File

@@ -25,7 +25,7 @@ export const columns: VxeGridProps['columns'] = [
title: '排序',
},
{
field: 'createTime',
field: 'creationTime',
title: '创建时间',
},
{

View File

@@ -53,7 +53,7 @@ const diffUpdateTimeString = computed(() => {
<div class="font-bold">{{ info.nodeName }}</div>
</DescriptionsItem>
<DescriptionsItem label="提交时间">
{{ info.createTime }}
{{ info.creationTime }}
</DescriptionsItem>
<!-- <DescriptionsItem label="更新时间">
{{ info.updateTime }}

View File

@@ -428,7 +428,7 @@ async function handleCopy(text: string) {
<Divider type="vertical" />
<div class="flex items-center gap-1">
<span class="icon-[mdi--clock-outline] size-[16px]"></span>
提交时间: {{ task.createTime }}
提交时间: {{ task.creationTime }}
</div>
</div>
</div>

View File

@@ -139,7 +139,7 @@ function handleReductionSignature(userList: User[]) {
{{ taskInfo.nodeCode }}
</DescriptionsItem>
<DescriptionsItem label="开始时间">
{{ taskInfo.createTime }}
{{ taskInfo.creationTime }}
</DescriptionsItem>
<DescriptionsItem label="流程实例ID">
{{ taskInfo.instanceId }}

View File

@@ -5,7 +5,7 @@
"title": "Department Management",
"deptName": "Department Name",
"status": "Status",
"createTime": "Create Time",
"creationTime": "Create Time",
"remark": "Remark",
"operation": "Operation",
"parentDept": "Parent Department"
@@ -57,7 +57,7 @@
"id": "Role ID",
"status": "Status",
"remark": "Remark",
"createTime": "Creation Time",
"creationTime": "Creation Time",
"operation": "Operation",
"permissions": "Permissions",
"setPermissions": "Permissions"

View File

@@ -1,7 +1,7 @@
{
"dept": {
"list": "部门列表",
"createTime": "创建时间",
"creationTime": "创建时间",
"deptName": "部门名称",
"name": "部门",
"operation": "操作",
@@ -58,7 +58,7 @@
"id": "角色ID",
"status": "状态",
"remark": "备注",
"createTime": "创建时间",
"creationTime": "创建时间",
"operation": "操作",
"permissions": "权限",
"setPermissions": "授权"

View File

@@ -93,9 +93,9 @@ export function useColumns(
width: 100,
},
{
field: 'createTime',
field: 'creationTime',
resizable: false,
title: $t('system.dept.createTime'),
title: $t('system.dept.creationTime'),
width: 'auto',
},
{

View File

@@ -68,8 +68,8 @@ export function useGridFormSchema(): VbenFormSchema[] {
},
{
component: 'RangePicker',
fieldName: 'createTime',
label: $t('system.role.createTime'),
fieldName: 'creationTime',
label: $t('system.role.creationTime'),
},
];
}
@@ -104,8 +104,8 @@ export function useColumns<T = SystemRoleApi.SystemRole>(
title: $t('system.role.remark'),
},
{
field: 'createTime',
title: $t('system.role.createTime'),
field: 'creationTime',
title: $t('system.role.creationTime'),
width: 200,
},
{

View File

@@ -26,7 +26,7 @@ const [FormDrawer, formDrawerApi] = useVbenDrawer({
const [Grid, gridApi] = useVbenVxeGrid({
formOptions: {
fieldMappingTime: [['createTime', ['startTime', 'endTime']]],
fieldMappingTime: [['creationTime', ['startTime', 'endTime']]],
schema: useGridFormSchema(),
submitOnChange: true,
},