第六轮深度测试:7个并行agent覆盖全部11章,修复21处前端问题
Ch1-2: 用户名注册邀请码错误改为友好文案(原为原始TypeError泄露给用户); 企业注册页扫描图标补上点击反馈。 Ch3-4: 发名片消息补传typeHint(此前被后端误分类成text,搜索/历史摘要显示成JSON); 文件卡片按mime大类区分图标颜色(此前所有文件都是同一个灰色通用图标); 表情面板补上专属退格/发送按钮(浅蓝禁用/深蓝启用两态);订正一处与截图不符的代码注释。 Ch5-6: 群聊设置页"群成员"补上可点击的完整成员列表页(复用MemberPicker字母分组); 群文件页去掉无依据的硬编码"/10GB"容量上限显示。 Ch7: 收藏点击图片/视频缩略图补上预览;"查找聊天记录-链接"tab补上定位回原消息; 文件下载页返回入口按来源tab纠正;批量转发成功计数改为按目标会话去重 (原公式混用"收藏条数"和"目标会话数"两个维度,混选多条收藏转发时可能显示负数); 收藏/视频tab切换补上URL路由同步。 Ch8: topic.onInfo在通话期间补上事件转发(此前通话中"对方正在输入"和已读回执静默失效); 主叫等待接听页补上"正在等待对方接受邀请…"文案;语音通话最小化胶囊的还原按钮移出 拖拽区域(原来嵌在draggable内部,指针捕获可能吞掉点击);修复中等窗宽(641-750px)下 本地摄像头预览遮挡"切换摄像头"按钮的CSS重叠。 Ch9: 部门树展开时跳过child_count=0的注定空请求;月报字数上限从硬编码1000改为读取 后端真实的10000;发起会议补上"结束时间需晚于开始时间"的本地校验和更具体的报错; 日报/月报统计接口补上department_id透传(此前包装函数注释断言后端会忽略,实际已支持)。 Ch10-11: URL风险检测补上g标志(原来一条消息只检查第一个链接,第二个链接哪怕是高危 也不会被拦截);补上"安全教育"设置入口(原功能完整实现但零入口,需手改hash才能打开); 修改密码按钮补上busy态反馈;青少年模式PIN页补上"忘记独立密码"入口(后端已支持重置, 前端未接);"关于我们"补上"联系我们"行。 7个agent同时对全部11章存量后端问题条目逐一复核,结论详见待整理的后端问题清单更新 (Ch1-2发现一条P0级后端问题:验证码固定值"123456",已记录未修复,不在此commit修改 im_be仓库范围内)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
d42591284f
commit
f42b8536e5
+159
-30
@@ -4420,8 +4420,9 @@ const updateDailyDraft = (reportId, content, version, attachments = []) => imPut
|
||||
const submitDailyReport = (reportId, version) => imPost('/reports/daily/' + encodeURIComponent(reportId) + '/submit', {
|
||||
version
|
||||
});
|
||||
const getDailyStatistics = date => imGet('/reports/daily/statistics' + qs({
|
||||
date
|
||||
const getDailyStatistics = (date, departmentId = '') => imGet('/reports/daily/statistics' + qs({
|
||||
date,
|
||||
department_id: departmentId
|
||||
}));
|
||||
const sendDailyReminders = (date, userIds = []) => imPost('/reports/daily/reminders', {
|
||||
date,
|
||||
@@ -4456,8 +4457,9 @@ const submitMonthlyReport = (reportId, version) => imPost('/reports/monthly/' +
|
||||
const reopenMonthlyReport = (reportId, version) => imPost('/reports/monthly/' + encodeURIComponent(reportId) + '/reopen', {
|
||||
version
|
||||
});
|
||||
const getMonthlyStatistics = month => imGet('/reports/monthly/statistics' + qs({
|
||||
month
|
||||
const getMonthlyStatistics = (month, departmentId = '') => imGet('/reports/monthly/statistics' + qs({
|
||||
month,
|
||||
department_id: departmentId
|
||||
}));
|
||||
const getExecutiveMailboxConfig = () => imGet('/executive-mailbox/config');
|
||||
const submitExecutiveMailboxMessage = body => imPost('/executive-mailbox/submissions', body);
|
||||
@@ -5632,6 +5634,7 @@ function Header({
|
||||
}
|
||||
function Field({
|
||||
icon,
|
||||
onIconClick,
|
||||
action,
|
||||
error,
|
||||
className = '',
|
||||
@@ -5641,7 +5644,14 @@ function Field({
|
||||
className: 'auth-field-wrap ' + className,
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxDEV)("div", {
|
||||
className: 'auth-field' + (error ? ' invalid' : ''),
|
||||
children: [icon ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxDEV)(Icon, {
|
||||
children: [icon ? onIconClick ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxDEV)("button", {
|
||||
type: "button",
|
||||
className: "auth-field-icon-button",
|
||||
onClick: onIconClick,
|
||||
children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxDEV)(Icon, {
|
||||
children: icon
|
||||
}, void 0, false)
|
||||
}, void 0, false) : (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxDEV)(Icon, {
|
||||
className: "auth-field-icon",
|
||||
children: icon
|
||||
}, void 0, false) : null, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxDEV)("input", {
|
||||
@@ -5974,7 +5984,8 @@ function EnterpriseRegister() {
|
||||
placeholder: "请输入18位统一社会信用代码",
|
||||
maxLength: "18",
|
||||
icon: "qr_code_scanner",
|
||||
error: errors.creditCode
|
||||
error: errors.creditCode,
|
||||
onIconClick: () => setToast('扫码识别暂不可用,请手动输入')
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxDEV)("p", {
|
||||
className: "auth-help",
|
||||
children: "请填写营业执照上的统一社会信用代码"
|
||||
@@ -8869,7 +8880,7 @@ const navigate = (view, params) => {
|
||||
});
|
||||
_lib_navigation_js__WEBPACK_IMPORTED_MODULE_3__["default"].navigateTo(hash);
|
||||
};
|
||||
const CONTENT_LIBRARY_VIEWS = ['favorites', 'favorites-mixed', 'favorites-files', 'favorites-text', 'favorites-voice', 'favorites-links', 'favorites-select', 'favorite-share', 'file-download', 'file-downloading', 'file-downloaded', 'history-search', 'history-files', 'history-links', 'history-images', 'history-videos'];
|
||||
const CONTENT_LIBRARY_VIEWS = ['favorites', 'favorites-mixed', 'favorites-files', 'favorites-text', 'favorites-voice', 'favorites-links', 'favorites-image', 'favorites-video', 'favorites-select', 'favorite-share', 'file-download', 'file-downloading', 'file-downloaded', 'history-search', 'history-files', 'history-links', 'history-images', 'history-videos'];
|
||||
function Icon({
|
||||
children
|
||||
}) {
|
||||
@@ -9181,7 +9192,9 @@ const TYPE_ROUTE = {
|
||||
file: 'favorites-files',
|
||||
text: 'favorites-text',
|
||||
voice: 'favorites-voice',
|
||||
link: 'favorites-links'
|
||||
link: 'favorites-links',
|
||||
image: 'favorites-image',
|
||||
video: 'favorites-video'
|
||||
};
|
||||
const TYPE_LABELS = [['all', '全部'], ['image', '图片'], ['video', '视频'], ['file', '文件'], ['voice', '语音'], ['text', '文本'], ['link', '链接']];
|
||||
function Favorites({
|
||||
@@ -9189,7 +9202,7 @@ function Favorites({
|
||||
tinode,
|
||||
onToast
|
||||
}) {
|
||||
const initialType = view === 'favorites-files' ? 'file' : view === 'favorites-text' ? 'text' : view === 'favorites-voice' ? 'voice' : view === 'favorites-links' ? 'link' : 'all';
|
||||
const initialType = view === 'favorites-files' ? 'file' : view === 'favorites-text' ? 'text' : view === 'favorites-voice' ? 'voice' : view === 'favorites-links' ? 'link' : view === 'favorites-image' ? 'image' : view === 'favorites-video' ? 'video' : 'all';
|
||||
const selecting = view === 'favorites-select';
|
||||
const [type, setType] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(selecting ? 'file' : initialType);
|
||||
const [queryInput, setQueryInput] = react__WEBPACK_IMPORTED_MODULE_0___default().useState('');
|
||||
@@ -9258,7 +9271,8 @@ function Favorites({
|
||||
const openItem = item => {
|
||||
if (item.type === 'file') {
|
||||
navigate('file-download', {
|
||||
favoriteId: item.favorite_id
|
||||
favoriteId: item.favorite_id,
|
||||
fromType: type
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -9269,6 +9283,10 @@ function Favorites({
|
||||
}).catch(() => onToast('链接安全校验失败'));
|
||||
return;
|
||||
}
|
||||
if (item.type === 'image' || item.type === 'video') {
|
||||
if (item._thumbUrl) window.open(item._thumbUrl, '_blank', 'noopener,noreferrer');else onToast('正在加载,请稍后重试');
|
||||
return;
|
||||
}
|
||||
onToast('暂不支持预览此类收藏');
|
||||
};
|
||||
const list = items || [];
|
||||
@@ -9372,8 +9390,11 @@ function FavoriteShare({
|
||||
setSending(true);
|
||||
(0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_5__.forwardFavorites)(ids, selected, comment.trim()).then(result => {
|
||||
const items = result && result.items || [];
|
||||
const failedCount = items.filter(r => r.status !== 'sent').length;
|
||||
onToast(failedCount ? `${selected.length - failedCount}/${selected.length} 个会话分享成功` : `已分享给 ${selected.length} 个会话`);
|
||||
const successTargets = selected.filter(target => {
|
||||
const forTarget = items.filter(r => r.target_topic === target);
|
||||
return forTarget.length > 0 && forTarget.every(r => r.status === 'sent');
|
||||
}).length;
|
||||
onToast(successTargets === selected.length ? `已分享给 ${selected.length} 个会话` : `${successTargets}/${selected.length} 个会话分享成功`);
|
||||
window.setTimeout(() => navigate('favorites-files'), 700);
|
||||
}).catch(err => onToast(err.message || '分享失败')).finally(() => setSending(false));
|
||||
};
|
||||
@@ -9475,9 +9496,10 @@ function DownloadPage({
|
||||
const {
|
||||
favoriteId,
|
||||
topic,
|
||||
seq
|
||||
seq,
|
||||
fromType
|
||||
} = hashParams || {};
|
||||
const backView = favoriteId ? 'favorites-files' : 'history-files';
|
||||
const backView = favoriteId ? TYPE_ROUTE[fromType] || 'favorites-files' : 'history-files';
|
||||
const backParams = favoriteId ? undefined : {
|
||||
topic
|
||||
};
|
||||
@@ -9825,8 +9847,10 @@ function History({
|
||||
}, void 0, false) : view === 'history-links' ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_8__.jsxDEV)("section", {
|
||||
className: "library-record-links",
|
||||
children: list.map(item => (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_8__.jsxDEV)((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_8__.jsxDEV)("div", {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_8__.jsxDEV)("button", {
|
||||
type: "button",
|
||||
className: "library-record-header",
|
||||
onClick: () => jump(item.seq),
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_8__.jsxDEV)("strong", {
|
||||
children: nameOf(item.from)
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_8__.jsxDEV)("small", {
|
||||
@@ -10645,7 +10669,7 @@ const navigateToProfile = (topic, userId, member) => {
|
||||
}).catch(() => {});
|
||||
}
|
||||
};
|
||||
const GROUP_MANAGEMENT_VIEWS = ['group-list', 'group-empty', 'group-invite', 'group-events', 'group-join-requests', 'group-new-request', 'group-announcement', 'group-summary', 'group-announcement-detail', 'group-settings', 'group-profile', 'group-avatar', 'group-nickname', 'group-description', 'group-my-nickname', 'group-role-message', 'group-qr', 'group-governance', 'group-admins', 'group-admin-add', 'group-admin-success', 'group-admin-partial', 'group-admin-removed', 'group-mute-add', 'group-muted', 'group-owner-select', 'group-owner-confirm', 'group-files', 'group-file-upload'];
|
||||
const GROUP_MANAGEMENT_VIEWS = ['group-list', 'group-empty', 'group-invite', 'group-events', 'group-join-requests', 'group-new-request', 'group-announcement', 'group-summary', 'group-announcement-detail', 'group-settings', 'group-profile', 'group-avatar', 'group-nickname', 'group-description', 'group-my-nickname', 'group-members', 'group-role-message', 'group-qr', 'group-governance', 'group-admins', 'group-admin-add', 'group-admin-success', 'group-admin-partial', 'group-admin-removed', 'group-mute-add', 'group-muted', 'group-owner-select', 'group-owner-confirm', 'group-files', 'group-file-upload'];
|
||||
function alphaInitial(name) {
|
||||
const ch = (name || '').trim()[0] || '#';
|
||||
if (/[A-Za-z]/.test(ch)) {
|
||||
@@ -11453,13 +11477,17 @@ function GroupSettings({
|
||||
}, void 0, false)]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("section", {
|
||||
className: "group-member-section",
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("div", {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("button", {
|
||||
type: "button",
|
||||
className: "group-member-section-title",
|
||||
onClick: () => navigate('group-members', topic),
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("strong", {
|
||||
children: "群成员"
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("small", {
|
||||
children: ["共 ", group.member_count, " 位成员"]
|
||||
}, void 0, true)]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)(Icon, {
|
||||
children: "chevron_right"
|
||||
}, void 0, false)]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("div", {
|
||||
className: "group-member-grid",
|
||||
children: [members.slice(0, 9).map(item => (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("button", {
|
||||
@@ -12057,6 +12085,64 @@ function AdminList({
|
||||
}, void 0, false)]
|
||||
}, void 0, true);
|
||||
}
|
||||
function GroupMembers({
|
||||
topic,
|
||||
onToast
|
||||
}) {
|
||||
const [members, setMembers] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(() => topic && (0,_lib_use_cached_data_js__WEBPACK_IMPORTED_MODULE_5__.readCachedData)('group-members:' + topic) || null);
|
||||
const [query, setQuery] = react__WEBPACK_IMPORTED_MODULE_0___default().useState('');
|
||||
const [loadError, setLoadError] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(false);
|
||||
react__WEBPACK_IMPORTED_MODULE_0___default().useEffect(() => {
|
||||
if (!topic) return;
|
||||
(0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_4__.getGroupMembers)(topic).then(data => {
|
||||
const items = data.items || [];
|
||||
(0,_lib_use_cached_data_js__WEBPACK_IMPORTED_MODULE_5__.writeCachedData)('group-members:' + topic, items);
|
||||
setMembers(items);
|
||||
}).catch(() => {
|
||||
onToast('加载失败');
|
||||
setLoadError(true);
|
||||
});
|
||||
}, [topic]);
|
||||
const visible = (members || []).filter(m => (m.group_nickname || m.display_name || '').includes(query));
|
||||
const groups = groupBy(visible, m => alphaInitial(m.group_nickname || m.display_name));
|
||||
const roleLabel = role => role === 'owner' ? '群主' : role === 'admin' ? '管理员' : '';
|
||||
return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("div", {
|
||||
className: "group-page",
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)(Header, {
|
||||
title: "群成员",
|
||||
back: "group-settings",
|
||||
backTopic: topic
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)(Search, {
|
||||
value: query,
|
||||
onChange: setQuery,
|
||||
placeholder: "搜索群成员"
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("main", {
|
||||
className: "group-member-picker",
|
||||
children: members === null ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("p", {
|
||||
className: "group-inline-empty",
|
||||
children: loadError ? '成员列表加载失败' : '加载中…'
|
||||
}, void 0, false) : groups.map(([letter, list]) => (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("div", {
|
||||
className: "group-section-title",
|
||||
children: letter
|
||||
}, void 0, false), list.map(item => (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("button", {
|
||||
type: "button",
|
||||
onClick: () => navigateToProfile(topic, item.user_id, item),
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)(Avatar, {
|
||||
item: item,
|
||||
icon: "person"
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("span", {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("strong", {
|
||||
children: item.group_nickname || item.display_name
|
||||
}, void 0, false), roleLabel(item.role) ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("small", {
|
||||
children: roleLabel(item.role)
|
||||
}, void 0, false) : null]
|
||||
}, void 0, true)]
|
||||
}, item.user_id, true))]
|
||||
}, letter, true))
|
||||
}, void 0, false)]
|
||||
}, void 0, true);
|
||||
}
|
||||
function MemberPicker({
|
||||
type,
|
||||
topic,
|
||||
@@ -12503,7 +12589,7 @@ function GroupFiles({
|
||||
placeholder: "搜索文件名或者上传者"
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("p", {
|
||||
className: "group-inline-hint",
|
||||
children: ["共", (files || []).length, "个文件(已使用", gb(usedBytes), "GB/10GB)"]
|
||||
children: ["共", (files || []).length, "个文件(已使用", gb(usedBytes), "GB)"]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("main", {
|
||||
className: "group-file-list",
|
||||
children: [uploading ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("article", {
|
||||
@@ -12756,6 +12842,9 @@ function GroupManagementView({
|
||||
topic: topic,
|
||||
myUserId: myUserId,
|
||||
onToast: setToast
|
||||
}, void 0, false);else if (view === 'group-members') content = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)(GroupMembers, {
|
||||
topic: topic,
|
||||
onToast: setToast
|
||||
}, void 0, false);else if (view === 'group-qr') content = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)(GroupQr, {
|
||||
topic: topic,
|
||||
onToast: setToast
|
||||
@@ -15420,6 +15509,10 @@ function SettingsList({
|
||||
title: "实名认证",
|
||||
value: realnameLabel,
|
||||
route: "realname"
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)(MenuRow, {
|
||||
icon: "shield",
|
||||
title: "安全教育",
|
||||
route: "fraud-risk-warning"
|
||||
}, void 0, false)]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("section", {
|
||||
children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)(MenuRow, {
|
||||
@@ -15582,6 +15675,8 @@ function ChangePassword({
|
||||
title: "修改密码",
|
||||
back: "android-settings",
|
||||
action: "完成",
|
||||
actionLabel: busy ? '处理中…' : '完成',
|
||||
actionDisabled: busy,
|
||||
onAction: submit
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("main", {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("label", {
|
||||
@@ -15694,6 +15789,11 @@ function AppVersion({
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)(MenuRow, {
|
||||
title: "隐私协议",
|
||||
onClick: () => onToast('隐私协议')
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)(MenuRow, {
|
||||
title: "联系我们",
|
||||
onClick: () => {
|
||||
window.location.href = _config_js__WEBPACK_IMPORTED_MODULE_4__.LINK_CONTACT_US;
|
||||
}
|
||||
}, void 0, false)]
|
||||
}, void 0, true)]
|
||||
}, void 0, true)]
|
||||
@@ -16048,6 +16148,11 @@ function YouthModeVerify({
|
||||
disabled: password.length !== 4 || busy || remainingLockSeconds > 0,
|
||||
onClick: submit,
|
||||
children: busy ? '验证中…' : remainingLockSeconds > 0 ? `请 ${remainingLockSeconds} 秒后重试` : '确定'
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("button", {
|
||||
type: "button",
|
||||
className: "auth-text-button",
|
||||
onClick: () => navigate('identity-check'),
|
||||
children: "忘记独立密码?"
|
||||
}, void 0, false)]
|
||||
}, void 0, true)]
|
||||
}, void 0, true);
|
||||
@@ -17610,7 +17715,7 @@ const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({
|
||||
description: 'Placeholder for the country selector'
|
||||
}
|
||||
});
|
||||
const SIDE_PANEL_VIEWS = ['acc_general', 'archive', 'blocked', 'contacts', 'cred', 'crop', 'edit', 'general', 'newtpk', 'notif', 'register', 'reset', 'security', 'settings', 'support', 'wallpapers', 'tenant', 'login', 'enterprise-register', 'enterprise-feedback', 'identity-check', 'realname', 'realname-verified', 'realname-reminder', 'independent-password', 'messages-home', 'messages-offline', 'messages-menu', 'message-actions', 'system-messages', 'chat-inbound-request', 'chat-inbound-message', 'chat-outbound-request', 'chat-status', 'chat-friend', 'chat-media', 'chat-blocked', 'chat-deleted', 'chat-standard', 'chat-attachments', 'chat-mixed', 'chat-contact-card', 'compose-keyboard', 'mentions-select', 'mentions-complete', 'mentions-message', 'emoji-panel', 'emoji-message', 'voice-ready', 'voice-hold', 'voice-recording', 'media-uploading', 'media-gallery', 'media-retry', 'upload-file', 'file-message', 'message-multiselect', 'favorite-success', 'forward-select', 'forward-multiple', 'forward-individual', 'forward-bundle', 'address-book', 'friend-requests', 'add-friend', 'my-friend-qr', 'friend-qr', 'friend-search-result', 'friend-verification', 'friend-profile', 'group-member-profile', 'friend-settings', 'friend-settings-blocked', 'friend-delete-confirm', 'block-list', 'block-confirm', 'clear-chat-confirm', 'group-list', 'group-empty', 'group-invite', 'group-events', 'group-join-requests', 'group-new-request', 'group-announcement', 'group-summary', 'group-announcement-detail', 'group-settings', 'group-profile', 'group-avatar', 'group-nickname', 'group-description', 'group-my-nickname', 'group-role-message', 'group-qr', 'group-governance', 'group-admins', 'group-admin-add', 'group-admin-success', 'group-admin-partial', 'group-admin-removed', 'group-mute-add', 'group-muted', 'group-owner-select', 'group-owner-confirm', 'group-files', 'group-file-upload', 'favorites', 'favorites-mixed', 'favorites-files', 'favorites-text', 'favorites-voice', 'favorites-links', 'favorites-select', 'favorite-share', 'file-download', 'file-downloading', 'file-downloaded', 'history-search', 'history-files', 'history-links', 'history-images', 'history-videos', 'call-history', 'call-incoming', 'audio-call-ringing', 'audio-call-active', 'audio-call-muted', 'audio-call-speaker', 'video-call-ringing', 'video-call-camera-off', 'video-call-active', 'video-call-peer-camera-off', 'call-minimized', 'workbench', 'organization-directory', 'meeting-organizer', 'meeting-attendee', 'meeting-create', 'meeting-detail', 'daily-report-editor', 'daily-report-mine', 'daily-report-team', 'daily-report-detail', 'monthly-report-editor', 'monthly-report-mine', 'monthly-report-team', 'monthly-report-detail', 'executive-mailbox', 'executive-mailbox-notice', 'personal-center', 'personal-profile', 'profile-nickname', 'profile-birth-date', 'profile-signature', 'profile-gender', 'profile-region', 'personal-qrcode', 'android-settings', 'cache-clear-confirm', 'clear-history-confirm', 'change-password', 'delete-account-confirm', 'app-version', 'privacy-settings', 'friend-discovery-settings', 'youth-mode-off', 'youth-mode-on', 'youth-mode-verify', 'notification-permission', 'permission-settings-reminder', 'camera-permission-info', 'microphone-permission-info', 'fraud-risk-warning', 'fraud-risk-confirmation', 'abuse-report-reasons', 'abuse-report-details', 'user-feedback', ''];
|
||||
const SIDE_PANEL_VIEWS = ['acc_general', 'archive', 'blocked', 'contacts', 'cred', 'crop', 'edit', 'general', 'newtpk', 'notif', 'register', 'reset', 'security', 'settings', 'support', 'wallpapers', 'tenant', 'login', 'enterprise-register', 'enterprise-feedback', 'identity-check', 'realname', 'realname-verified', 'realname-reminder', 'independent-password', 'messages-home', 'messages-offline', 'messages-menu', 'message-actions', 'system-messages', 'chat-inbound-request', 'chat-inbound-message', 'chat-outbound-request', 'chat-status', 'chat-friend', 'chat-media', 'chat-blocked', 'chat-deleted', 'chat-standard', 'chat-attachments', 'chat-mixed', 'chat-contact-card', 'compose-keyboard', 'mentions-select', 'mentions-complete', 'mentions-message', 'emoji-panel', 'emoji-message', 'voice-ready', 'voice-hold', 'voice-recording', 'media-uploading', 'media-gallery', 'media-retry', 'upload-file', 'file-message', 'message-multiselect', 'favorite-success', 'forward-select', 'forward-multiple', 'forward-individual', 'forward-bundle', 'address-book', 'friend-requests', 'add-friend', 'my-friend-qr', 'friend-qr', 'friend-search-result', 'friend-verification', 'friend-profile', 'group-member-profile', 'friend-settings', 'friend-settings-blocked', 'friend-delete-confirm', 'block-list', 'block-confirm', 'clear-chat-confirm', 'group-list', 'group-empty', 'group-invite', 'group-events', 'group-join-requests', 'group-new-request', 'group-announcement', 'group-summary', 'group-announcement-detail', 'group-settings', 'group-profile', 'group-avatar', 'group-nickname', 'group-description', 'group-my-nickname', 'group-members', 'group-role-message', 'group-qr', 'group-governance', 'group-admins', 'group-admin-add', 'group-admin-success', 'group-admin-partial', 'group-admin-removed', 'group-mute-add', 'group-muted', 'group-owner-select', 'group-owner-confirm', 'group-files', 'group-file-upload', 'favorites', 'favorites-mixed', 'favorites-files', 'favorites-text', 'favorites-voice', 'favorites-links', 'favorites-image', 'favorites-video', 'favorites-select', 'favorite-share', 'file-download', 'file-downloading', 'file-downloaded', 'history-search', 'history-files', 'history-links', 'history-images', 'history-videos', 'call-history', 'call-incoming', 'audio-call-ringing', 'audio-call-active', 'audio-call-muted', 'audio-call-speaker', 'video-call-ringing', 'video-call-camera-off', 'video-call-active', 'video-call-peer-camera-off', 'call-minimized', 'workbench', 'organization-directory', 'meeting-organizer', 'meeting-attendee', 'meeting-create', 'meeting-detail', 'daily-report-editor', 'daily-report-mine', 'daily-report-team', 'daily-report-detail', 'monthly-report-editor', 'monthly-report-mine', 'monthly-report-team', 'monthly-report-detail', 'executive-mailbox', 'executive-mailbox-notice', 'personal-center', 'personal-profile', 'profile-nickname', 'profile-birth-date', 'profile-signature', 'profile-gender', 'profile-region', 'personal-qrcode', 'android-settings', 'cache-clear-confirm', 'clear-history-confirm', 'change-password', 'delete-account-confirm', 'app-version', 'privacy-settings', 'friend-discovery-settings', 'youth-mode-off', 'youth-mode-on', 'youth-mode-verify', 'notification-permission', 'permission-settings-reminder', 'camera-permission-info', 'microphone-permission-info', 'fraud-risk-warning', 'fraud-risk-confirmation', 'abuse-report-reasons', 'abuse-report-details', 'user-feedback', ''];
|
||||
const AUTH_FLOW_VIEWS = ['tenant', 'login', 'register', 'reset', 'cred', 'enterprise-register', 'enterprise-feedback'];
|
||||
const CTRL_ERROR_TEXT_CN = {
|
||||
'authentication failed': '账号或密码错误',
|
||||
@@ -17631,6 +17736,16 @@ function loginErrorMessage(err) {
|
||||
if (err && (err.code === 401 || err.code === 403)) return '账号或密码错误';
|
||||
return err && err.message || '登录失败,请重试';
|
||||
}
|
||||
const INVITE_CODE_REASON_TEXT_CN = {
|
||||
INVITE_CODE_REQUIRED: '请填写邀请码',
|
||||
INVITE_CODE_INVALID: '邀请码错误,请重新输入',
|
||||
INVITE_CODE_REVOKED: '邀请码已被撤销,请联系管理员获取新的邀请码',
|
||||
INVITE_CODE_EXPIRED: '邀请码已过期,请联系管理员获取新的邀请码'
|
||||
};
|
||||
function invalidCredentialsReasonMessage(params) {
|
||||
const reason = params && params.reason;
|
||||
return reason && INVITE_CODE_REASON_TEXT_CN[reason] || '注册信息校验未通过,请检查后重试';
|
||||
}
|
||||
const CALL_RING_TIMEOUT_MS = 60000;
|
||||
class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component) {
|
||||
constructor(props) {
|
||||
@@ -18302,7 +18417,9 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
if (cred) {
|
||||
this.handleError(this.props.intl.formatMessage(messages.code_doesnot_match), 'warn');
|
||||
}
|
||||
TinodeWeb.navigateToCredentialsView(ctrl.params);
|
||||
if (!TinodeWeb.navigateToCredentialsView(ctrl.params) && !cred) {
|
||||
this.handleError(invalidCredentialsReasonMessage(ctrl.params), 'err');
|
||||
}
|
||||
} else {
|
||||
this.handleLoginSuccessful();
|
||||
}
|
||||
@@ -18326,12 +18443,16 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
});
|
||||
}
|
||||
static navigateToCredentialsView(params) {
|
||||
if (!Array.isArray(params.cred) || !params.cred.length) {
|
||||
return false;
|
||||
}
|
||||
const parsed = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].parseUrlHash(window.location.hash);
|
||||
parsed.path[0] = 'cred';
|
||||
parsed.params['method'] = params.cred[0];
|
||||
parsed.params['token'] = params.token;
|
||||
parsed.params['code'] = params.code;
|
||||
_lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].navigateTo(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].composeUrlHash(parsed.path, parsed.params));
|
||||
return true;
|
||||
}
|
||||
handleLoginSuccessful() {
|
||||
this.handleError();
|
||||
@@ -18663,7 +18784,9 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
});
|
||||
}).then(ctrl => {
|
||||
if (ctrl.code >= 300 && ctrl.text == 'validate credentials') {
|
||||
TinodeWeb.navigateToCredentialsView(ctrl.params);
|
||||
if (!TinodeWeb.navigateToCredentialsView(ctrl.params)) {
|
||||
this.handleError(invalidCredentialsReasonMessage(ctrl.params), 'err');
|
||||
}
|
||||
} else {
|
||||
this.handleLoginSuccessful(this);
|
||||
}
|
||||
@@ -19691,8 +19814,8 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
const chapterThreeActive = ['chat-inbound-request', 'chat-inbound-message', 'chat-outbound-request', 'chat-status', 'chat-friend', 'chat-media', 'chat-blocked', 'chat-deleted', 'chat-standard', 'chat-attachments', 'chat-mixed', 'chat-contact-card'].includes(activeProductView);
|
||||
const chapterFourActive = ['compose-keyboard', 'mentions-select', 'mentions-complete', 'mentions-message', 'emoji-panel', 'emoji-message', 'voice-ready', 'voice-hold', 'voice-recording', 'media-uploading', 'media-gallery', 'media-retry', 'upload-file', 'file-message', 'message-multiselect', 'favorite-success', 'forward-select', 'forward-multiple', 'forward-individual', 'forward-bundle'].includes(activeProductView);
|
||||
const chapterFiveActive = ['address-book', 'friend-requests', 'add-friend', 'my-friend-qr', 'friend-qr', 'friend-search-result', 'friend-verification', 'friend-profile', 'group-member-profile', 'friend-settings', 'friend-settings-blocked', 'friend-delete-confirm', 'block-list', 'block-confirm', 'clear-chat-confirm'].includes(activeProductView);
|
||||
const chapterSixActive = ['group-list', 'group-empty', 'group-invite', 'group-events', 'group-join-requests', 'group-new-request', 'group-announcement', 'group-summary', 'group-announcement-detail', 'group-settings', 'group-profile', 'group-avatar', 'group-nickname', 'group-description', 'group-my-nickname', 'group-role-message', 'group-qr', 'group-governance', 'group-admins', 'group-admin-add', 'group-admin-success', 'group-admin-partial', 'group-admin-removed', 'group-mute-add', 'group-muted', 'group-owner-select', 'group-owner-confirm', 'group-files', 'group-file-upload'].includes(activeProductView);
|
||||
const chapterSevenActive = ['favorites', 'favorites-mixed', 'favorites-files', 'favorites-text', 'favorites-voice', 'favorites-links', 'favorites-select', 'favorite-share', 'file-download', 'file-downloading', 'file-downloaded', 'history-search', 'history-files', 'history-links', 'history-images', 'history-videos'].includes(activeProductView);
|
||||
const chapterSixActive = ['group-list', 'group-empty', 'group-invite', 'group-events', 'group-join-requests', 'group-new-request', 'group-announcement', 'group-summary', 'group-announcement-detail', 'group-settings', 'group-profile', 'group-avatar', 'group-nickname', 'group-description', 'group-my-nickname', 'group-members', 'group-role-message', 'group-qr', 'group-governance', 'group-admins', 'group-admin-add', 'group-admin-success', 'group-admin-partial', 'group-admin-removed', 'group-mute-add', 'group-muted', 'group-owner-select', 'group-owner-confirm', 'group-files', 'group-file-upload'].includes(activeProductView);
|
||||
const chapterSevenActive = ['favorites', 'favorites-mixed', 'favorites-files', 'favorites-text', 'favorites-voice', 'favorites-links', 'favorites-image', 'favorites-video', 'favorites-select', 'favorite-share', 'file-download', 'file-downloading', 'file-downloaded', 'history-search', 'history-files', 'history-links', 'history-images', 'history-videos'].includes(activeProductView);
|
||||
const callExperienceActive = ['call-history', 'call-incoming', 'audio-call-ringing', 'audio-call-active', 'audio-call-muted', 'audio-call-speaker', 'video-call-ringing', 'video-call-camera-off', 'video-call-active', 'video-call-peer-camera-off', 'call-minimized'].includes(activeProductView);
|
||||
const workplaceCollaborationActive = ['workbench', 'organization-directory', 'meeting-organizer', 'meeting-attendee', 'meeting-create', 'meeting-detail', 'daily-report-editor', 'daily-report-mine', 'daily-report-team', 'daily-report-detail', 'monthly-report-editor', 'monthly-report-mine', 'monthly-report-team', 'monthly-report-detail', 'executive-mailbox', 'executive-mailbox-notice'].includes(activeProductView);
|
||||
const personalSettingsActive = ['personal-center', 'personal-profile', 'profile-nickname', 'profile-birth-date', 'profile-signature', 'profile-gender', 'profile-region', 'personal-qrcode', 'android-settings', 'cache-clear-confirm', 'clear-history-confirm', 'change-password', 'delete-account-confirm', 'app-version', 'privacy-settings', 'friend-discovery-settings', 'youth-mode-off', 'youth-mode-on', 'youth-mode-verify', 'notification-permission', 'permission-settings-reminder', 'camera-permission-info', 'microphone-permission-info'].includes(activeProductView);
|
||||
@@ -20575,7 +20698,7 @@ function DeptNode({
|
||||
if (children != null) return;
|
||||
setLoading(true);
|
||||
setLoadError(false);
|
||||
Promise.all([(0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_3__.getOrganizationDepartments)(dept.department_id).then(d => d.departments || d.items || []), dept.member_count ? (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_3__.getOrganizationDepartmentMembers)(dept.department_id).then(d => d.members || d.items || []) : Promise.resolve([])]).then(([depts, mems]) => {
|
||||
Promise.all([dept.child_count ? (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_3__.getOrganizationDepartments)(dept.department_id).then(d => d.departments || d.items || []) : Promise.resolve([]), dept.member_count ? (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_3__.getOrganizationDepartmentMembers)(dept.department_id).then(d => d.members || d.items || []) : Promise.resolve([])]).then(([depts, mems]) => {
|
||||
setChildren(depts);
|
||||
setMembers(mems);
|
||||
}).catch(() => setLoadError(true)).finally(() => setLoading(false));
|
||||
@@ -20993,6 +21116,10 @@ function MeetingCreate({
|
||||
}
|
||||
const startAt = new Date(`${date}T${startTime}:00`).toISOString();
|
||||
const endAt = new Date(`${date}T${endTime}:00`).toISOString();
|
||||
if (endAt <= startAt) {
|
||||
onToast('结束时间需晚于开始时间');
|
||||
return;
|
||||
}
|
||||
setSubmitting(true);
|
||||
(0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_3__.createMeeting)({
|
||||
title: title.trim(),
|
||||
@@ -21003,7 +21130,7 @@ function MeetingCreate({
|
||||
}).then(_ => {
|
||||
onToast('会议已发起');
|
||||
navigate('meeting-attendee');
|
||||
}).catch(err => onToast(err.message || '发起会议失败')).finally(() => setSubmitting(false));
|
||||
}).catch(err => onToast(err.details && err.details.field === 'end_at' ? '结束时间需晚于开始时间' : err.message || '发起会议失败')).finally(() => setSubmitting(false));
|
||||
};
|
||||
return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("div", {
|
||||
className: "workplace-page report-editor-page",
|
||||
@@ -21644,6 +21771,7 @@ function MonthlyReportEditor({
|
||||
};
|
||||
const [summary, setSummary] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(cached ? cached.summary : '');
|
||||
const [plan, setPlan] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(cached ? cached.plan : '');
|
||||
const [maxLen, setMaxLen] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(1000);
|
||||
const [hydrated, setHydrated] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(!cached);
|
||||
const [saved, setSaved] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(false);
|
||||
const [saveError, setSaveError] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(false);
|
||||
@@ -21681,6 +21809,7 @@ function MonthlyReportEditor({
|
||||
setVersionBoth(r.version);
|
||||
setSummary(nextSummary);
|
||||
setPlan(nextPlan);
|
||||
if (r.validation && r.validation.max_length) setMaxLen(r.validation.max_length);
|
||||
(0,_lib_use_cached_data_js__WEBPACK_IMPORTED_MODULE_4__.writeCachedData)(cacheKey, {
|
||||
reportId: r.report_id,
|
||||
version: r.version,
|
||||
@@ -21735,11 +21864,11 @@ function MonthlyReportEditor({
|
||||
}, void 0, false), "本月工作总结"]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("textarea", {
|
||||
value: summary,
|
||||
maxLength: "1000",
|
||||
maxLength: maxLen,
|
||||
placeholder: "请输入",
|
||||
onChange: e => setSummary(e.target.value)
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("small", {
|
||||
children: [summary.length, "/1000"]
|
||||
children: [summary.length, "/", maxLen]
|
||||
}, void 0, true)]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("label", {
|
||||
className: "report-field",
|
||||
@@ -21749,11 +21878,11 @@ function MonthlyReportEditor({
|
||||
}, void 0, false), "下月工作计划"]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("textarea", {
|
||||
value: plan,
|
||||
maxLength: "1000",
|
||||
maxLength: maxLen,
|
||||
placeholder: "请输入",
|
||||
onChange: e => setPlan(e.target.value)
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("small", {
|
||||
children: [plan.length, "/1000"]
|
||||
children: [plan.length, "/", maxLen]
|
||||
}, void 0, true)]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("p", {
|
||||
className: "report-draft-status",
|
||||
|
||||
Reference in New Issue
Block a user