feat(首页): 优化最近会议布局并调整创建会议表单

- 将最近会议网格布局从3列改为4列,并添加响应式设计
- 调整首页标题为"最近会议",优化查看全部按钮样式和布局
- 移除热词选择功能,简化创建会议表单
- 默认启用声纹区分功能,优化高级设置面板视觉样式
- 修复创建会议时表单初始化逻辑
dev_na
alanpaine 2026-04-08 17:30:31 +08:00
parent c802f63ada
commit e83a0ece32
3 changed files with 30 additions and 35 deletions

View File

@ -142,7 +142,8 @@ export const MeetingCreateDrawer: React.FC<MeetingCreateDrawerProps> = ({ open,
const currentTitle = form.getFieldValue('title'); const currentTitle = form.getFieldValue('title');
if (currentTitle && (currentTitle.startsWith('文件会议') || currentTitle.startsWith('实时会议'))) { if (currentTitle && (currentTitle.startsWith('文件会议') || currentTitle.startsWith('实时会议'))) {
form.setFieldsValue({ form.setFieldsValue({
title: type === 'upload' ? `文件会议 ${dayjs().format("MM-DD HH:mm")}` : `实时会议 ${dayjs().format("MM-DD HH:mm")}` title: type === 'upload' ? `文件会议 ${dayjs().format("MM-DD HH:mm")}` : `实时会议 ${dayjs().format("MM-DD HH:mm")}`,
useSpkId: 1
}); });
} }
}, [type, form, open]); }, [type, form, open]);
@ -197,10 +198,7 @@ export const MeetingCreateDrawer: React.FC<MeetingCreateDrawerProps> = ({ open,
onSuccess(); onSuccess();
onCancel(); onCancel();
} else { } else {
const selectedHotwords = (values.hotWords?.length const selectedHotwords = hotwordList.map((item) => ({
? hotwordList.filter((item) => values.hotWords.includes(item.word))
: hotwordList
).map((item) => ({
hotword: item.word, hotword: item.word,
weight: Number(item.weight || 2) / 10, weight: Number(item.weight || 2) / 10,
})); }));
@ -218,7 +216,6 @@ export const MeetingCreateDrawer: React.FC<MeetingCreateDrawerProps> = ({ open,
enableItn: meetingValues.enableItn !== false, enableItn: meetingValues.enableItn !== false,
enableTextRefine: !!meetingValues.enableTextRefine, enableTextRefine: !!meetingValues.enableTextRefine,
saveAudio: !!meetingValues.saveAudio, saveAudio: !!meetingValues.saveAudio,
hotWords: meetingValues.hotWords,
}; };
const res = await createRealtimeMeeting(payload); const res = await createRealtimeMeeting(payload);
@ -390,36 +387,28 @@ export const MeetingCreateDrawer: React.FC<MeetingCreateDrawerProps> = ({ open,
)} )}
</Form.Item> </Form.Item>
<Row gutter={32}>
<Col span={24}>
<Form.Item name="hotWords" label={<span> <Tooltip title="不选择时将带上系统当前启用的热词"><QuestionCircleOutlined /></Tooltip></span>}>
<Select mode="multiple" allowClear placeholder="请选择需要增强识别的热词" size="large" style={{ width: '100%' }}>
{hotwordList.map((item) => (
<Option key={item.word} value={item.word}>{item.word}</Option>
))}
</Select>
</Form.Item>
</Col>
</Row>
<Collapse <Collapse
ghost ghost
expandIconPosition="end" expandIconPosition="end"
style={{ marginBottom: 24, background: 'var(--app-bg-layout)', borderRadius: 8 }} style={{ marginBottom: 24, background: 'var(--app-bg-surface)', border: '1px solid var(--app-border-color)', borderRadius: 8, overflow: 'hidden' }}
items={[ items={[
{ {
key: 'advanced', key: 'advanced',
label: ( label: (
<span style={{ fontWeight: 500, color: 'var(--app-text-secondary)' }}> <div style={{ display: 'flex', alignItems: 'center', width: '100%', height: '32px' }}>
<SettingOutlined style={{ marginRight: 8 }} /> <div style={{ display: 'flex', alignItems: 'center', fontWeight: 600, color: 'var(--app-text-main)', fontSize: 15 }}>
<div style={{ width: 32, height: 32, borderRadius: 8, background: '#f0f5ff', color: '#1677ff', display: 'flex', alignItems: 'center', justifyContent: 'center', marginRight: 12 }}>
<SettingOutlined style={{ fontSize: 16 }} />
</div>
</span> </div>
</div>
), ),
children: ( children: (
<div style={{ paddingTop: 8 }}> <div style={{ paddingTop: 8, borderTop: '1px dashed var(--app-border-color)' }}>
<Row gutter={32}> <Row gutter={32}>
<Col span={8}> <Col span={8}>
<Form.Item name="useSpkId" label={<span> <Tooltip title="开启后将尝试区分不同发言人"><QuestionCircleOutlined /></Tooltip></span>} valuePropName="checked" getValueProps={(v) => ({ checked: v === 1 || v === true })} normalize={(v) => (v ? 1 : 0)}> <Form.Item name="useSpkId" label={<span> <Tooltip title="开启后将尝试区分不同发言人"><QuestionCircleOutlined /></Tooltip></span>} valuePropName="checked" getValueProps={(v) => ({ checked: !!v })} normalize={(v) => (v ? 1 : 0)}>
<Switch /> <Switch />
</Form.Item> </Form.Item>
</Col> </Col>

View File

@ -285,8 +285,8 @@
.home-section-header { .home-section-header {
display: flex; display: flex;
align-items: baseline; align-items: center;
gap: 16px; justify-content: space-between;
margin-bottom: 24px; margin-bottom: 24px;
h3 { h3 {
@ -298,14 +298,21 @@
} }
.home-view-all { .home-view-all {
display: none; font-size: 14px;
display: flex;
align-items: center;
padding: 0;
margin-left: auto;
} }
.home-recent-grid { .home-recent-grid {
display: grid; display: grid;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(4, 1fr);
gap: 24px; gap: 24px;
@media (max-width: 1200px) {
grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 1024px) { @media (max-width: 1024px) {
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
} }

View File

@ -1,7 +1,6 @@
import { useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import { import {
AudioOutlined, AudioOutlined,
ArrowRightOutlined,
VideoCameraOutlined, VideoCameraOutlined,
VideoCameraAddOutlined VideoCameraAddOutlined
} from "@ant-design/icons"; } from "@ant-design/icons";
@ -214,15 +213,15 @@ export default function HomePage() {
<section className="home-recent-section"> <section className="home-recent-section">
<div className="home-section-header"> <div className="home-section-header">
<Title level={3}></Title> <Title level={3}></Title>
<Button type="link" onClick={() => navigate("/meetings")} className="home-view-all"> <Button type="link" onClick={() => navigate("/meetings")} className="home-view-all">
<ArrowRightOutlined /> &gt;
</Button> </Button>
</div> </div>
{loading ? ( {loading ? (
<div className="home-recent-grid"> <div className="home-recent-grid">
{[...Array(3)].map((_, i) => ( {[...Array(4)].map((_, i) => (
<div key={i} className="home-recent-skeleton"> <div key={i} className="home-recent-skeleton">
<Skeleton active paragraph={{ rows: 2 }} title={{ width: "60%" }} /> <Skeleton active paragraph={{ rows: 2 }} title={{ width: "60%" }} />
</div> </div>
@ -230,7 +229,7 @@ export default function HomePage() {
</div> </div>
) : recentCards.length ? ( ) : recentCards.length ? (
<div className="home-recent-grid"> <div className="home-recent-grid">
{recentCards.map((card) => ( {recentCards.slice(0, 4).map((card) => (
<article <article
key={card.id} key={card.id}
className="home-recent-card" className="home-recent-card"
@ -244,7 +243,7 @@ export default function HomePage() {
role="button" role="button"
tabIndex={0} tabIndex={0}
> >
{!readCardIds.includes(String(card.id)) && <span className="home-recent-card-dot" />} {/* {!readCardIds.includes(String(card.id)) && <span className="home-recent-card-dot" />} */}
<div className="home-recent-card-head"> <div className="home-recent-card-head">
<Title level={4} className="home-recent-card-title">{card.title}</Title> <Title level={4} className="home-recent-card-title">{card.title}</Title>
<div className="home-recent-card-icon"> <div className="home-recent-card-icon">