refactor(meeting): 优化会议模块代码结构与导入语句

- 整理并优化后端会议相关服务、控制器及DTO的import语句
- 补充AndroidMeetingConfigVo等类的Swagger注解及必要字段
- 调整前端API与类型定义文件的代码格式
- 提升代码可读性与规范性,不涉及业务逻辑变更
dev_na
chenhao 2026-07-02 17:43:14 +08:00
parent 17dbeefdf8
commit 91ab0eb7f0
15 changed files with 144 additions and 58 deletions

View File

@ -111,6 +111,7 @@ public class AndroidMeetingController {
private final SysTenantMapper sysTenantMapper;
private final SysUserMapper sysUserMapper;
private final AiModelService aiModelService;
private final HotWordGroupService hotWordGroupService;
private final SysDictItemService dictItemService;
private final SysParamService paramService;
private final MeetingProgressService meetingProgressService;
@ -129,6 +130,7 @@ public class AndroidMeetingController {
SysTenantMapper sysTenantMapper,
SysUserMapper sysUserMapper,
AiModelService aiModelService,
HotWordGroupService hotWordGroupService,
SysDictItemService dictItemService,
SysParamService paramService,
MeetingProgressService meetingProgressService,
@ -147,6 +149,7 @@ public class AndroidMeetingController {
this.sysUserMapper = sysUserMapper;
this.meetingProgressService = meetingProgressService;
this.aiModelService = aiModelService;
this.hotWordGroupService = hotWordGroupService;
this.paramService = paramService;
this.dictItemService = dictItemService;
this.meetingUnifiedStatusService = meetingUnifiedStatusService;
@ -460,6 +463,7 @@ public class AndroidMeetingController {
.filter(item -> Integer.valueOf(1).equals(item.getStatus()))
.toList();
resultVo.setModelsList(enabledModels);
resultVo.setHotWordGroupList(hotWordGroupService.listVisibleOptions(tenantId));
resultVo.setSummaryDegreeOfDetail(dictItemService.getItemsByTypeCode("summary_degree_detail"));
resultVo.setMaxMeetingDuration(Integer.valueOf(paramService.getParamValue(SysParamKeys.MEETING_MAX_MEETING_DURATION, "30")));
resultVo.setMinMeetingDuration(Integer.valueOf(paramService.getParamValue(SysParamKeys.MEETING_MIN_MEETING_DURATION, "10")));

View File

@ -87,7 +87,7 @@ public class AndroidMeetingRealtimeController {
command == null ? null : command.getEnableItn(),
command == null ? null : command.getEnableTextRefine(),
command == null ? null : command.getSaveAudio(),
null,
command == null ? null : command.getHotWordGroupId(),
command == null ? null : command.getHotWords()
);
CreateRealtimeMeetingCommand createCommand = buildCreateCommand(command, authContext, runtimeProfile);
@ -208,6 +208,7 @@ public class AndroidMeetingRealtimeController {
createCommand.setAsrModelId(runtimeProfile.getResolvedAsrModelId());
createCommand.setSummaryModelId(runtimeProfile.getResolvedSummaryModelId());
createCommand.setPromptId(runtimeProfile.getResolvedPromptId());
createCommand.setHotWordGroupId(runtimeProfile.getResolvedHotWordGroupId());
createCommand.setSummaryDetailLevel(command == null ? null : command.getSummaryDetailLevel());
createCommand.setMode(runtimeProfile.getResolvedMode());
createCommand.setLanguage(runtimeProfile.getResolvedLanguage());

View File

@ -21,6 +21,7 @@ public class AndroidCreateRealtimeMeetingCommand {
private Long asrModelId;
private Long summaryModelId;
private Long promptId;
private Long hotWordGroupId;
@Schema(description = "总结详细程度DETAILED=详细STANDARD=标准BRIEF=简洁")
private String summaryDetailLevel;
private String mode;

View File

@ -2,9 +2,12 @@ package com.imeeting.dto.android;
import com.imeeting.dto.biz.AiModelVO;
import com.imeeting.dto.biz.HotWordGroupDTO;
import com.imeeting.dto.biz.HotWordGroupVO;
import com.imeeting.dto.biz.PromptTemplateVO;
import com.unisbase.dto.SysDictItemDTO;
import com.unisbase.entity.SysDictItem;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@ -25,22 +28,24 @@ import java.util.List;
*/
@Data
public class AndroidMeetingConfigVo {
@io.swagger.v3.oas.annotations.media.Schema(description = "可用模型列表")
@Schema(description = "可用模型列表")
private List<AiModelVO> modelsList;
@io.swagger.v3.oas.annotations.media.Schema(description = "可用模板列表")
@Schema(description = "可用模板列表")
private List<PromptTemplateVO> templateList;
@io.swagger.v3.oas.annotations.media.Schema(description = "总结详细程度字典项")
@Schema(description = "总结详细程度字典项")
private List<SysDictItemDTO> summaryDegreeOfDetail;
@io.swagger.v3.oas.annotations.media.Schema(description = "允许暂停最大时长,单位秒")
@Schema(description = "允许暂停最大时长,单位秒")
private Integer maxPauseDuration;
@io.swagger.v3.oas.annotations.media.Schema(description = "最大会议时长,单位分钟")
@Schema(description = "最大会议时长,单位分钟")
private Integer maxMeetingDuration;
@io.swagger.v3.oas.annotations.media.Schema(description = "最小会议时长,单位秒")
@Schema(description = "最小会议时长,单位秒")
private Integer minMeetingDuration;
@io.swagger.v3.oas.annotations.media.Schema(description = "允许的最大丢包率")
@Schema(description = "允许的最大丢包率")
private BigDecimal packetLossRate;
@io.swagger.v3.oas.annotations.media.Schema(description = "是否启用音频分片上传")
@Schema(description = "是否启用音频分片上传")
private Boolean chunkUploadEnabled;
@io.swagger.v3.oas.annotations.media.Schema(description = "分片时长,单位秒")
@Schema(description = "分片时长,单位秒")
private Integer chunkDurationSeconds;
@Schema(description = "热词组")
private List<HotWordGroupVO> hotWordGroupList;
}

View File

@ -17,6 +17,9 @@ public class AndroidOfflineMeetingCreateCommand extends LegacyMeetingCreateReque
@Schema(description = "总结模板ID")
private Long promptId;
@Schema(description = "热词组ID")
private Long hotWordGroupId;
@Schema(
description = "总结详细程度DETAILED=详细STANDARD=标准BRIEF=简洁",
allowableValues = {

View File

@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class UpdateMeetingBasicCommand {
@ -19,6 +20,7 @@ public class UpdateMeetingBasicCommand {
private String accessPassword;
private Long promptId;
private Long summaryModelId;
private List<Long> participantIds;
@Schema(
description = "总结详细程度DETAILED=详细STANDARD=标准BRIEF=简洁",

View File

@ -59,6 +59,9 @@ public class Meeting extends BaseEntity {
@Schema(description = "总结模板ID")
private Long promptId;
@Schema(description = "会议创建时最终生效的热词组ID")
private Long hotWordGroupId;
@Schema(description = "会议最终有效录音时长(秒)")
private Integer effectiveAudioDurationSeconds;

View File

@ -108,6 +108,9 @@ public class LegacyMeetingAdapterServiceImpl implements LegacyMeetingAdapterServ
Long requestedPromptId = request instanceof AndroidOfflineMeetingCreateCommand androidCommand
? androidCommand.getPromptId()
: null;
Long requestedHotWordGroupId = request instanceof AndroidOfflineMeetingCreateCommand androidCommand
? androidCommand.getHotWordGroupId()
: null;
String requestedSummaryDetailLevel = request instanceof AndroidOfflineMeetingCreateCommand androidCommand
? androidCommand.getSummaryDetailLevel()
: MeetingConstants.SUMMARY_DETAIL_STANDARD;
@ -123,7 +126,7 @@ public class LegacyMeetingAdapterServiceImpl implements LegacyMeetingAdapterServ
null,
null,
null,
null,
requestedHotWordGroupId,
List.of()
);
String resolvedCreatorName = meetingDomainSupport.resolveUserDisplayName(creatorUserId, creatorName);
@ -142,6 +145,7 @@ public class LegacyMeetingAdapterServiceImpl implements LegacyMeetingAdapterServ
resolvedCreatorName,
runtimeProfile.getResolvedSummaryModelId(),
runtimeProfile.getResolvedPromptId(),
runtimeProfile.getResolvedHotWordGroupId(),
requestedSummaryDetailLevel,
0,
authContext == null ? null : authContext.getDeviceId(),
@ -207,7 +211,7 @@ public class LegacyMeetingAdapterServiceImpl implements LegacyMeetingAdapterServ
null,
true,
null,
null,
meeting.getHotWordGroupId(),
List.of()
);
@ -217,6 +221,7 @@ public class LegacyMeetingAdapterServiceImpl implements LegacyMeetingAdapterServ
meetingDomainSupport.applyMeetingAudioMetadata(meeting, relocatedUrl);
meeting.setSummaryModelId(profile.getResolvedSummaryModelId());
meeting.setPromptId(profile.getResolvedPromptId());
meeting.setHotWordGroupId(profile.getResolvedHotWordGroupId());
meeting.setAudioSaveStatus(RealtimeMeetingAudioStorageService.STATUS_SUCCESS);
meeting.setAudioSaveMessage(null);
meeting.setOfflineRecordingStatus(MeetingConstants.OFFLINE_RECORDING_UPLOAD_FINISHED);
@ -283,7 +288,7 @@ public class LegacyMeetingAdapterServiceImpl implements LegacyMeetingAdapterServ
null,
true,
null,
null,
meeting.getHotWordGroupId(),
List.of()
);
String stagingUrl = storeStagingAudio(audioFile);
@ -293,6 +298,7 @@ public class LegacyMeetingAdapterServiceImpl implements LegacyMeetingAdapterServ
meetingDomainSupport.prewarmPlaybackAudioAfterCommit(relocatedUrl);
meeting.setSummaryModelId(profile.getResolvedSummaryModelId());
meeting.setPromptId(profile.getResolvedPromptId());
meeting.setHotWordGroupId(profile.getResolvedHotWordGroupId());
meeting.setAudioSaveStatus(RealtimeMeetingAudioStorageService.STATUS_SUCCESS);
meeting.setAudioSaveMessage(null);
meeting.setOfflineRecordingStatus(MeetingConstants.OFFLINE_RECORDING_UPLOAD_FINISHED);
@ -394,6 +400,9 @@ public class LegacyMeetingAdapterServiceImpl implements LegacyMeetingAdapterServ
taskConfig.put("useSpkId", profile.getResolvedUseSpkId());
taskConfig.put("enableTextRefine", profile.getResolvedEnableTextRefine());
taskConfig.put("hotWords", profile.getResolvedHotWords());
if (profile.getResolvedHotWordGroupId() != null) {
taskConfig.put("hotWordGroupId", profile.getResolvedHotWordGroupId());
}
resetOrCreateTask(task, meetingId, "ASR", taskConfig);
}

View File

@ -1209,12 +1209,6 @@ public class AiModelServiceImpl implements AiModelService {
vo.setSortOrder(entity.getSortOrder());
vo.setRemark(entity.getRemark());
vo.setCreatedAt(entity.getCreatedAt());
if (!platformAdmin && Long.valueOf(0L).equals(entity.getTenantId())) {
vo.setBaseUrl(null);
vo.setApiKey(null);
vo.setWsUrl(null);
vo.setMediaConfig(null);
}
return vo;
}

View File

@ -1,5 +1,7 @@
package com.imeeting.service.biz.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -157,7 +159,8 @@ public class MeetingCommandServiceImpl implements MeetingCommandService {
String summaryDetailLevel = resolveSummaryDetailLevel(command.getSummaryDetailLevel());
Meeting meeting = meetingDomainSupport.initMeeting(command.getTitle(), command.getMeetingTime(), command.getParticipants(), command.getTags(),
command.getAudioUrl(), MeetingConstants.TYPE_OFFLINE, meetingSource, tenantId, creatorId, resolvedCreatorName,
hostUserId, hostName, runtimeProfile.getResolvedSummaryModelId(), runtimeProfile.getResolvedPromptId(), summaryDetailLevel, 0);
hostUserId, hostName, runtimeProfile.getResolvedSummaryModelId(), runtimeProfile.getResolvedPromptId(),
runtimeProfile.getResolvedHotWordGroupId(), summaryDetailLevel, 0);
meetingService.save(meeting);
AiTask asrTask = new AiTask();
@ -236,7 +239,8 @@ public class MeetingCommandServiceImpl implements MeetingCommandService {
String summaryDetailLevel = resolveSummaryDetailLevel(command.getSummaryDetailLevel());
Meeting meeting = meetingDomainSupport.initMeeting(command.getTitle(), command.getMeetingTime(), command.getParticipants(), command.getTags(),
null, MeetingConstants.TYPE_REALTIME, meetingSource, tenantId, creatorId, resolvedCreatorName,
hostUserId, hostName, runtimeProfile.getResolvedSummaryModelId(), runtimeProfile.getResolvedPromptId(), summaryDetailLevel, 0);
hostUserId, hostName, runtimeProfile.getResolvedSummaryModelId(), runtimeProfile.getResolvedPromptId(),
runtimeProfile.getResolvedHotWordGroupId(), summaryDetailLevel, 0);
meetingService.save(meeting);
Long chapterModelId = command.getChapterModelId() != null ? command.getChapterModelId() : runtimeProfile.getResolvedSummaryModelId();
createChapterTaskIfEnabled(
@ -314,6 +318,7 @@ public class MeetingCommandServiceImpl implements MeetingCommandService {
hostName,
runtimeProfile.getResolvedSummaryModelId(),
runtimeProfile.getResolvedPromptId(),
runtimeProfile.getResolvedHotWordGroupId(),
summaryDetailLevel,
0,
deviceCode,
@ -559,6 +564,9 @@ public class MeetingCommandServiceImpl implements MeetingCommandService {
asrConfig.put("useSpkId", resumeConfig.getUseSpkId() != null ? resumeConfig.getUseSpkId() : 1);
asrConfig.put("enableTextRefine", Boolean.TRUE.equals(resumeConfig.getEnableTextRefine()));
asrConfig.put("hotWords", extractOfflineHotwords(resumeConfig.getHotwords()));
if (resumeConfig.getHotWordGroupId() != null) {
asrConfig.put("hotWordGroupId", resumeConfig.getHotWordGroupId());
}
if (asrTask == null) {
asrTask = new AiTask();
@ -687,21 +695,21 @@ public class MeetingCommandServiceImpl implements MeetingCommandService {
if (meeting == null) {
throw new RuntimeException("会议不存在");
}
meetingRuntimeProfileResolver.resolve(
meeting.getTenantId(),
null,
command.getSummaryModelId() != null ? command.getSummaryModelId() : meeting.getSummaryModelId(),
command.getPromptId() != null ? command.getPromptId() : meeting.getPromptId(),
null,
null,
null,
null,
null,
null,
null,
null,
List.of()
);
// meetingRuntimeProfileResolver.resolve(
// meeting.getTenantId(),
// null,
// command.getSummaryModelId() != null ? command.getSummaryModelId() : meeting.getSummaryModelId(),
// command.getPromptId() != null ? command.getPromptId() : meeting.getPromptId(),
// null,
// null,
// null,
// null,
// null,
// null,
// null,
// null,
// List.of()
// );
}
meetingService.update(new LambdaUpdateWrapper<Meeting>()
.eq(Meeting::getId, command.getMeetingId())
@ -711,6 +719,7 @@ public class MeetingCommandServiceImpl implements MeetingCommandService {
.set(command.getAccessPassword() != null, Meeting::getAccessPassword, normalizeAccessPassword(command.getAccessPassword()))
.set(command.getSummaryModelId() != null, Meeting::getSummaryModelId, command.getSummaryModelId())
.set(command.getPromptId() != null, Meeting::getPromptId, command.getPromptId())
.set(CollUtil.isNotEmpty(command.getParticipantIds()), Meeting::getParticipants, StrUtil.join(",", command.getParticipantIds()))
.set(command.getSummaryDetailLevel() != null, Meeting::getSummaryDetailLevel, resolveSummaryDetailLevel(command.getSummaryDetailLevel())));
}
@ -1091,7 +1100,11 @@ public class MeetingCommandServiceImpl implements MeetingCommandService {
throw new RuntimeException("未找到可用的总结任务配置");
}
resetAiTask(asrTask, new HashMap<>(asrTask.getTaskConfig()));
Map<String, Object> asrTaskConfig = new HashMap<>(asrTask.getTaskConfig());
if (meeting.getHotWordGroupId() != null) {
asrTaskConfig.put("hotWordGroupId", meeting.getHotWordGroupId());
}
resetAiTask(asrTask, asrTaskConfig);
aiTaskService.updateById(asrTask);
Long effectiveSummaryModelId = resolveMeetingSummaryModelId(meeting, summaryTask);
Long effectivePromptId = resolveMeetingPromptId(meeting, summaryTask);

View File

@ -75,9 +75,10 @@ public class MeetingDomainSupport {
Long tenantId, Long creatorId, String creatorName,
Long hostUserId, String hostName,
Long summaryModelId, Long promptId,
Long hotWordGroupId,
String summaryDetailLevel, int status) {
return initMeeting(title, meetingTime, participants, tags, audioUrl, meetingType, meetingSource,
tenantId, creatorId, creatorName, hostUserId, hostName, summaryModelId, promptId, summaryDetailLevel, status,
tenantId, creatorId, creatorName, hostUserId, hostName, summaryModelId, promptId, hotWordGroupId, summaryDetailLevel, status,
null, null);
}
@ -86,6 +87,17 @@ public class MeetingDomainSupport {
Long tenantId, Long creatorId, String creatorName,
Long hostUserId, String hostName,
Long summaryModelId, Long promptId,
String summaryDetailLevel, int status) {
return initMeeting(title, meetingTime, participants, tags, audioUrl, meetingType, meetingSource,
tenantId, creatorId, creatorName, hostUserId, hostName, summaryModelId, promptId, summaryDetailLevel, status,
null, null);
}
public Meeting initMeeting(String title, LocalDateTime meetingTime, String participants, String tags,
String audioUrl, String meetingType, String meetingSource,
Long tenantId, Long creatorId, String creatorName,
Long hostUserId, String hostName,
Long summaryModelId, Long promptId, Long hotWordGroupId,
String summaryDetailLevel, int status,
String sourceDeviceCode, String sourceDeviceMode) {
Meeting meeting = new Meeting();
@ -105,6 +117,7 @@ public class MeetingDomainSupport {
meeting.setSourceDeviceMode(sourceDeviceMode);
meeting.setSummaryModelId(summaryModelId);
meeting.setPromptId(promptId);
meeting.setHotWordGroupId(hotWordGroupId);
meeting.setSummaryDetailLevel(normalizeSummaryDetailLevel(summaryDetailLevel));
meeting.setAudioSaveStatus(RealtimeMeetingAudioStorageService.STATUS_NONE);
if (MeetingConstants.TYPE_OFFLINE.equalsIgnoreCase(meetingType)) {
@ -114,6 +127,18 @@ public class MeetingDomainSupport {
return meeting;
}
public Meeting initMeeting(String title, LocalDateTime meetingTime, String participants, String tags,
String audioUrl, String meetingType, String meetingSource,
Long tenantId, Long creatorId, String creatorName,
Long hostUserId, String hostName,
Long summaryModelId, Long promptId,
String summaryDetailLevel, int status,
String sourceDeviceCode, String sourceDeviceMode) {
return initMeeting(title, meetingTime, participants, tags, audioUrl, meetingType, meetingSource,
tenantId, creatorId, creatorName, hostUserId, hostName, summaryModelId, promptId, null, summaryDetailLevel, status,
sourceDeviceCode, sourceDeviceMode);
}
public String resolveUserDisplayName(Long userId, String fallbackName) {
if (userId == null) {
return fallbackName;
@ -408,6 +433,7 @@ public class MeetingDomainSupport {
vo.setOfflineRecordingStatus(meeting.getOfflineRecordingStatus());
vo.setSummaryModelId(meeting.getSummaryModelId());
vo.setPromptId(meeting.getPromptId());
fillEffectiveHotWordGroup(meeting, vo);
vo.setAiCatalogEnabled(resolveAiCatalogEnabled());
vo.setSummaryDetailLevel(normalizeSummaryDetailLevel(meeting.getSummaryDetailLevel()));
vo.setAudioSaveStatus(meeting.getAudioSaveStatus());
@ -446,7 +472,6 @@ public class MeetingDomainSupport {
vo.setSummaryContent(meetingSummaryFileService.loadSummaryContent(meeting));
vo.setAnalysis(meetingSummaryFileService.loadSummaryAnalysis(meeting));
vo.setLastUserPrompt(resolveLastSummaryUserPrompt(meeting));
fillEffectiveHotWordGroup(meeting, vo);
}
}
@ -463,6 +488,9 @@ public class MeetingDomainSupport {
}
private Long resolveEffectiveHotWordGroupId(Meeting meeting) {
if (meeting != null && meeting.getHotWordGroupId() != null) {
return meeting.getHotWordGroupId();
}
AiTask latestAsrTask = resolveLatestAsrTask(meeting);
Long asrHotWordGroupId = longValue(
latestAsrTask == null || latestAsrTask.getTaskConfig() == null

View File

@ -29,9 +29,20 @@ export async function deleteParam(id: number) {
return resp.data.data as boolean;
}
export async function listUsers(params?: { tenantId?: number; orgId?: number }) {
export async function listUsers(params?: { tenantId?: number; orgId?: number; keyword?: string }) {
const resp = await http.get("/sys/api/users", {params: {current: 1, size: 1000, ...params}});
return (resp.data.data as PageResult<SysUser[]>).records || [];
}
export async function pageUsers(params?: {
current?: number;
size?: number;
tenantId?: number;
orgId?: number;
keyword?: string
}) {
const resp = await http.get("/sys/api/users", { params });
return resp.data.data as SysUser[];
return resp.data.data as PageResult<SysUser[]>;
}
export async function createUser(payload: Partial<SysUser>) {

View File

@ -43,7 +43,7 @@ import {
listRoles,
listTenants,
listUserRoles,
listUsers,
pageUsers,
resetUserPassword,
updateUser,
uploadPlatformAsset
@ -130,13 +130,17 @@ export default function Users() {
const [current, setCurrent] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [searchText, setSearchText] = useState("");
const [total, setTotal] = useState(0);
const [queryKeyword, setQueryKeyword] = useState("");
const handleSearch = () => {
setQueryKeyword(searchText.trim());
setCurrent(1);
};
const handleResetSearch = () => {
setSearchText("");
setQueryKeyword("");
setFilterTenantId(undefined);
setCurrent(1);
};
@ -213,8 +217,14 @@ export default function Users() {
const loadUsersData = async () => {
setLoading(true);
try {
const usersList = await listUsers({ tenantId: filterTenantId });
setData(usersList || []);
const response = await pageUsers({
current,
size: pageSize,
tenantId: filterTenantId,
keyword: queryKeyword || undefined
});
setData(response?.records || []);
setTotal(response?.total || 0);
} finally {
setLoading(false);
}
@ -238,7 +248,7 @@ export default function Users() {
useEffect(() => {
loadUsersData();
}, [filterTenantId]);
}, [filterTenantId, current, pageSize, queryKeyword]);
useEffect(() => {
const fetchOrgs = async () => {
@ -255,16 +265,7 @@ export default function Users() {
const orgTreeData = useMemo(() => buildOrgTree(orgs), [orgs]);
const filteredData = useMemo(() => {
if (!searchText) return data;
const lower = searchText.toLowerCase();
return data.filter(
(user) =>
user.username.toLowerCase().includes(lower) ||
user.displayName.toLowerCase().includes(lower) ||
(user.email && user.email.toLowerCase().includes(lower))
);
}, [data, searchText]);
const openCreate = () => {
setEditing(null);
@ -511,7 +512,10 @@ export default function Users() {
<Space size={8} wrap>
{isPlatformMode &&
<Select placeholder={t("users.tenantFilter")} style={{width: 200}} allowClear value={filterTenantId}
onChange={setFilterTenantId}
onChange={(value) => {
setFilterTenantId(value);
setCurrent(1);
}}
options={tenants.map((tenant) => ({label: tenant.tenantName, value: tenant.id}))}
suffixIcon={<ShopOutlined aria-hidden="true"/>}/>}
<Input placeholder={t("users.searchPlaceholder")} prefix={<SearchOutlined aria-hidden="true"/>}
@ -528,7 +532,7 @@ export default function Users() {
<AppPagination
current={current}
pageSize={pageSize}
total={filteredData.length}
total={total}
onChange={(page, size) => {
setCurrent(page);
setPageSize(size);
@ -539,7 +543,7 @@ export default function Users() {
<ListTable
rowKey="userId"
columns={columns}
dataSource={filteredData.slice((current - 1) * pageSize, current * pageSize)}
dataSource={data}
loading={loading}
scroll={{ y: "100%" }}
pagination={false}

View File

@ -231,6 +231,11 @@ export default function Profile() {
label: t("users.phone"),
children: <span className="tabular-nums">{renderValue(user?.phone)}</span>
},
{
key: "organization",
label: t("users.org"),
children: renderValue(user?.orgPath || user?.orgName)
},
{
key: "status",
label: t("common.status"),

View File

@ -31,6 +31,9 @@ export interface UserProfile {
email?: string;
phone?: string;
avatarUrl?: string;
orgId?: number;
orgName?: string;
orgPath?: string;
status?: number;
isAdmin: boolean;
isPlatformAdmin?: boolean;