修复精准查找对拉黑关系显示"添加",跟实际能不能添加对不上(第5章复测发现)
/users/search 返回结果本身带 relationship 字段,服务端 imRelationshipAction() 对 blocked_by_me/blocked_by_peer 都明确映射成 action:"none"(不允许发起添加)——但 前端 actionLabel 只认 friend/pending_outbound/pending_inbound 三种,其余(含两种 拉黑关系)一律落到兜底的"添加"文案。点进去虽然会跳到资料页、由资料页自己的 cannotAddReason 挡住(不会真的误发出申请),但列表这一行本身的文案是误导的。 补上跟 Profile 组件里已有的 cannotAddReason 一致的两条文案(已拉黑/无法添加), 只是精简成适合一行列表项的长度。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7340b5e135
commit
d21d046443
@@ -265,8 +265,14 @@ function AddFriend({result = false, onToast, onOpenScanner}) {
|
||||
return undefined;
|
||||
}).catch(err => onToast(err.message || '生成邀请链接失败'));
|
||||
};
|
||||
// Real search results carry a relationship for blocked pairs too (blocked_by_me/blocked_by_peer),
|
||||
// which previously fell through to the same generic "添加" as an untouched stranger -- misleading
|
||||
// since tapping through leads to a profile page whose own cannotAddReason (see the Profile
|
||||
// component below) already refuses to let the request go anywhere. Matches that component's
|
||||
// wording, just condensed to fit this one-line list item.
|
||||
const actionLabel = item => item.relationship === 'friend' ? '已是好友' :
|
||||
item.relationship === 'pending_outbound' ? '已申请' : item.relationship === 'pending_inbound' ? '待通过' : '添加';
|
||||
item.relationship === 'pending_outbound' ? '已申请' : item.relationship === 'pending_inbound' ? '待通过' :
|
||||
item.relationship === 'blocked_by_me' ? '已拉黑' : item.relationship === 'blocked_by_peer' ? '无法添加' : '添加';
|
||||
return <div className="people-page"><Header title="添加好友" back="address-book" />
|
||||
<Search value={query} onChange={v => { setQuery(v); if (!v.trim()) { setSearched(false); setResults([]); } }} placeholder="查找账号" onSubmit={() => runSearch(query)} />
|
||||
<main>
|
||||
|
||||
+50
-14
@@ -4401,9 +4401,8 @@ const updateMonthlyDraft = (reportId, workSummary, nextPlan, version, attachment
|
||||
const submitMonthlyReport = (reportId, version) => imPost('/reports/monthly/' + encodeURIComponent(reportId) + '/submit', {
|
||||
version
|
||||
});
|
||||
const reopenMonthlyReport = (reportId, version, reason = '补充内容') => imPost('/reports/monthly/' + encodeURIComponent(reportId) + '/reopen', {
|
||||
version,
|
||||
reason
|
||||
const reopenMonthlyReport = (reportId, version) => imPost('/reports/monthly/' + encodeURIComponent(reportId) + '/reopen', {
|
||||
version
|
||||
});
|
||||
const getMonthlyStatistics = month => imGet('/reports/monthly/statistics' + qs({
|
||||
month
|
||||
@@ -7820,7 +7819,7 @@ function AddFriend({
|
||||
return undefined;
|
||||
}).catch(err => onToast(err.message || '生成邀请链接失败'));
|
||||
};
|
||||
const actionLabel = item => item.relationship === 'friend' ? '已是好友' : item.relationship === 'pending_outbound' ? '已申请' : item.relationship === 'pending_inbound' ? '待通过' : '添加';
|
||||
const actionLabel = item => item.relationship === 'friend' ? '已是好友' : item.relationship === 'pending_outbound' ? '已申请' : item.relationship === 'pending_inbound' ? '待通过' : item.relationship === 'blocked_by_me' ? '已拉黑' : item.relationship === 'blocked_by_peer' ? '无法添加' : '添加';
|
||||
return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("div", {
|
||||
className: "people-page",
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)(Header, {
|
||||
@@ -12961,7 +12960,7 @@ function normalizeConversations(chatList, myUserId) {
|
||||
icon: isGroup ? 'group' : 'person',
|
||||
online: isGroup ? undefined : !!item.online,
|
||||
muted: !!(item.acs && item.acs.isMuted && item.acs.isMuted()),
|
||||
pinned: !!item.pinned
|
||||
pinned: !!(item.private && item.private.pinned)
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -21109,18 +21108,24 @@ function DailyReportList({
|
||||
const cacheKey = 'daily-reports:' + (team ? 'managed' : 'mine');
|
||||
const statsCacheKey = 'daily-stats:' + toDateInputValue(new Date());
|
||||
const [reports, setReports] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(() => (0,_lib_use_cached_data_js__WEBPACK_IMPORTED_MODULE_4__.readCachedData)(cacheKey) || null);
|
||||
const [loadError, setLoadError] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(false);
|
||||
const [query, setQuery] = react__WEBPACK_IMPORTED_MODULE_0___default().useState('');
|
||||
const [stats, setStats] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(() => team && (0,_lib_use_cached_data_js__WEBPACK_IMPORTED_MODULE_4__.readCachedData)(statsCacheKey) || null);
|
||||
const ids = (reports || []).map(r => r.author_id);
|
||||
const names = useUserNames(ids, myUserId);
|
||||
const load = () => {
|
||||
setLoadError(false);
|
||||
(0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_3__.getDailyReports)({
|
||||
scope: team ? 'managed' : 'mine'
|
||||
}).then(d => {
|
||||
const list = d.reports || d.items || [];
|
||||
(0,_lib_use_cached_data_js__WEBPACK_IMPORTED_MODULE_4__.writeCachedData)(cacheKey, list);
|
||||
setReports(list);
|
||||
}).catch(() => setReports(prev => prev || []));
|
||||
}).catch(err => {
|
||||
onToast(err.message || '日报列表加载失败');
|
||||
setLoadError(true);
|
||||
setReports(prev => prev || []);
|
||||
});
|
||||
if (team) (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_3__.getDailyStatistics)(toDateInputValue(new Date())).then(s => {
|
||||
(0,_lib_use_cached_data_js__WEBPACK_IMPORTED_MODULE_4__.writeCachedData)(statsCacheKey, s);
|
||||
setStats(s);
|
||||
@@ -21211,7 +21216,7 @@ function DailyReportList({
|
||||
children: "加载中…"
|
||||
}, void 0, false) : filtered.length === 0 ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("p", {
|
||||
className: "organization-loading",
|
||||
children: "暂无日报"
|
||||
children: loadError ? '日报列表加载失败' : '暂无日报'
|
||||
}, void 0, false) : filtered.map(r => (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)(DailyReportCard, {
|
||||
report: r,
|
||||
names: names,
|
||||
@@ -21311,6 +21316,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 [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);
|
||||
const [submitting, setSubmitting] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(false);
|
||||
@@ -21353,17 +21359,18 @@ function MonthlyReportEditor({
|
||||
summary: nextSummary,
|
||||
plan: nextPlan
|
||||
});
|
||||
setHydrated(true);
|
||||
}).catch(err => onToast(err.message || '创建月报失败'));
|
||||
}, []);
|
||||
react__WEBPACK_IMPORTED_MODULE_0___default().useEffect(() => {
|
||||
if (!reportId) return undefined;
|
||||
if (!reportId || !hydrated) return undefined;
|
||||
setSaved(false);
|
||||
draftTimerRef.current = window.setTimeout(() => {
|
||||
draftTimerRef.current = null;
|
||||
saveDraft(summary, plan).catch(() => setSaveError(true));
|
||||
}, 600);
|
||||
return () => window.clearTimeout(draftTimerRef.current);
|
||||
}, [summary, plan, reportId, saveDraft]);
|
||||
}, [summary, plan, reportId, hydrated, saveDraft]);
|
||||
const submit = () => {
|
||||
if (!summary.trim() || !plan.trim()) {
|
||||
onToast('请完成必填内容');
|
||||
@@ -21514,6 +21521,7 @@ function MonthlyReportDetail({
|
||||
const reportId = hashParams && hashParams.report_id;
|
||||
const [report, setReport] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(() => reportId && (0,_lib_use_cached_data_js__WEBPACK_IMPORTED_MODULE_4__.readCachedData)('monthly-report:' + reportId) || null);
|
||||
const [loadError, setLoadError] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(false);
|
||||
const [reopening, setReopening] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(false);
|
||||
const names = useUserNames(report ? [report.author_id] : [], myUserId);
|
||||
react__WEBPACK_IMPORTED_MODULE_0___default().useEffect(() => {
|
||||
if (!reportId) return;
|
||||
@@ -21538,6 +21546,14 @@ function MonthlyReportDetail({
|
||||
}, void 0, false)
|
||||
}, void 0, false)]
|
||||
}, void 0, true);
|
||||
const canReopen = report.author_id === myUserId && report.status === 'submitted';
|
||||
const reopen = () => {
|
||||
setReopening(true);
|
||||
(0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_3__.reopenMonthlyReport)(report.report_id, report.version).then(() => {
|
||||
onToast('已重新打开,可继续编辑');
|
||||
navigate('monthly-report-editor');
|
||||
}).catch(err => onToast(err.message || '重新打开失败')).finally(() => setReopening(false));
|
||||
};
|
||||
return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("div", {
|
||||
className: "workplace-page",
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)(Header, {
|
||||
@@ -21576,7 +21592,15 @@ function MonthlyReportDetail({
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("p", {
|
||||
children: report.next_plan || '未填写'
|
||||
}, void 0, false)]
|
||||
}, void 0, true)]
|
||||
}, void 0, true), canReopen ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("section", {
|
||||
children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("button", {
|
||||
type: "button",
|
||||
className: "workplace-primary",
|
||||
disabled: reopening,
|
||||
onClick: reopen,
|
||||
children: reopening ? '处理中…' : '重新编辑'
|
||||
}, void 0, false)
|
||||
}, void 0, false) : null]
|
||||
}, void 0, true)]
|
||||
}, void 0, true);
|
||||
}
|
||||
@@ -21605,11 +21629,23 @@ function ExecutiveMailbox({
|
||||
enabled: false
|
||||
}));
|
||||
}, []);
|
||||
const pickFile = () => fileInputRef.current && fileInputRef.current.click();
|
||||
const attachmentPolicy = config && config.attachment_policy || {};
|
||||
const maxFiles = attachmentPolicy.max_files || attachmentPolicy.max_count || 5;
|
||||
const pickFile = () => {
|
||||
if (attachments.length >= maxFiles) {
|
||||
onToast(`最多上传 ${maxFiles} 个附件`);
|
||||
return;
|
||||
}
|
||||
fileInputRef.current && fileInputRef.current.click();
|
||||
};
|
||||
const handleFile = event => {
|
||||
const file = event.target.files && event.target.files[0];
|
||||
event.target.value = '';
|
||||
if (!file || !tinode) return;
|
||||
if (attachments.length >= maxFiles) {
|
||||
onToast(`最多上传 ${maxFiles} 个附件`);
|
||||
return;
|
||||
}
|
||||
setUploading(true);
|
||||
(0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_3__.uploadLargeFile)(tinode, file).then(({
|
||||
fileId
|
||||
@@ -21678,12 +21714,12 @@ function ExecutiveMailbox({
|
||||
children: [content.length, "/", config && config.max_length || 1000]
|
||||
}, void 0, true)]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("span", {
|
||||
children: "附件"
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("button", {
|
||||
children: ["附件(", attachments.length, "/", maxFiles, ")"]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("button", {
|
||||
type: "button",
|
||||
className: "mailbox-upload",
|
||||
onClick: pickFile,
|
||||
disabled: uploading,
|
||||
disabled: uploading || attachments.length >= maxFiles,
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)(Icon, {
|
||||
children: uploading ? 'hourglass_top' : 'upload_file'
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("span", {
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user