import { Badge, Button, Card, Dropdown, type MenuProps, Popover, Skeleton, Space, Typography, } from "antd"; import { DownOutlined } from "@ant-design/icons"; import { useState, useEffect, useCallback } from "react"; import { useIntl } from "react-intl"; import { get } from "../../request"; import type { IApiResponseDictList } from "../../api/Dict"; import type { IUser } from "../auth/User"; import GrammarPop from "./GrammarPop"; import MdView from "../template/MdView"; import MyCreate from "./MyCreate"; const { Title, Link, Text } = Typography; interface IItem { value: R; score: number; } interface IWord { grammar: IItem[]; parent: IItem[]; note: IItem[]; meaning: IItem[]; factors: IItem[]; editor: IItem[]; } interface IWidget { word: string | undefined; } const CommunityWidget = ({ word }: IWidget) => { const intl = useIntl(); const [loaded, setLoaded] = useState(false); const [loading, setLoading] = useState(false); const [wordData, setWordData] = useState(); const [showCreate, setShowCreate] = useState(false); const [_myRefresh, setMyRefresh] = useState(false); const minScore = 100; //分数阈值。低于这个分数只显示在弹出菜单中 const dictLoad = useCallback(async (input: string) => { setLoading(true); const url = `/v2/userdict?view=community&word=${input}`; console.info("dict community url", url); get(url) .then((json) => { if (json.ok === false) { console.log("dict community", json.message); return; } console.debug("dict community", json.data); const meaning = new Map(); const grammar = new Map(); const parent = new Map(); const note = new Map(); const editorId = new Map(); const editor = new Map(); for (const it of json.data.rows) { let score: number | undefined; if (it.exp) { //分数计算 let conf = it.confidence / 100; if (it.confidence <= 1) { conf = 1; } const currScore = Math.floor((it.exp / 3600) * conf); if (it.mean) { score = meaning.get(it.mean); meaning.set(it.mean, score ? score + currScore : currScore); } if (it.type || it.grammar) { const strCase = it.type + "$" + it.grammar; score = grammar.get(strCase); grammar.set(strCase, score ? score + currScore : currScore); } if (it.parent) { score = parent.get(it.parent); parent.set(it.parent, score ? score + currScore : currScore); } if (it.note) { score = note.get(it.note); note.set(it.note, score ? score + currScore : currScore); } if (it.editor) { score = editorId.get(it.editor.id); editorId.set(it.editor.id, score ? score + currScore : currScore); editor.set(it.editor.id, it.editor); } } } const _data: IWord = { grammar: [], parent: [], note: [], meaning: [], factors: [], editor: [], }; meaning.forEach((value, key, _map) => { if (key && key.length > 0) { _data.meaning.push({ value: key, score: value }); } }); _data.meaning.sort((a, b) => b.score - a.score); grammar.forEach((value, key, _map) => { if (key && key.length > 0) { _data.grammar.push({ value: key, score: value }); } }); _data.grammar.sort((a, b) => b.score - a.score); parent.forEach((value, key, _map) => { if (key && key.length > 0) { _data.parent.push({ value: key, score: value }); } }); _data.parent.sort((a, b) => b.score - a.score); note.forEach((value, key, _map) => { if (key && key.length > 0) { _data.note.push({ value: key, score: value }); } }); _data.note.sort((a, b) => b.score - a.score); editorId.forEach((value, key, _map) => { const currEditor = editor.get(key); if (currEditor) { _data.editor.push({ value: currEditor, score: value }); } }); _data.editor.sort((a, b) => b.score - a.score); setWordData(_data); if (_data.editor.length > 0) { setLoaded(true); } else { setLoaded(false); } }) .finally(() => setLoading(false)) .catch((error) => { console.error(error); }); }, []); useEffect(() => { if (typeof word === "undefined") { return; } dictLoad(word); }, [word, setWordData, dictLoad]); const isShow = (score: number, index: number) => { const Ms = 500, Rd = 5, minScore = 15; const minOrder = Math.log(score) / Math.log(Math.pow(Ms, 1 / Rd)); if (index < minOrder && score > minScore) { return true; } else { return false; } }; const meaningLow = wordData?.meaning.filter( (value, index: number) => !isShow(value.score, index) ); const meaningExtra = meaningLow?.map((item, id) => { return {item.value}; }); const mainCollaboratorNum = 3; //默认显示的协作者数量,其余的在更多中显示 const collaboratorRender = (name: string, id: number, score: number) => { return ( {name} ); }; const items: MenuProps["items"] = wordData?.editor .filter((_value, index) => index >= mainCollaboratorNum) .map((item, id) => { return { key: id, label: collaboratorRender(item.value.nickName, id, item.score), }; }); const more = wordData ? ( wordData.editor.length > mainCollaboratorNum ? ( {intl.formatMessage({ id: `buttons.more`, })} ) : undefined ) : undefined; return ( {"社区字典"} {loading ? ( ) : loaded ? (
{"意思:"} {wordData?.meaning .filter((value, index: number) => isShow(value.score, index)) .map((item, id) => { return ( {item.value} ); })} {meaningLow && meaningLow.length > 0 ? ( {meaningExtra}} placement="bottom" > {intl.formatMessage({ id: `buttons.more`, })} ) : undefined}
{"语法:"} {wordData?.grammar .filter((value) => value.score >= minScore) .map((item, id) => { const grammar = item.value.split("$"); const grammarGuide = grammar.map((item, id) => { const strCase = item.replaceAll(".", ""); return strCase.length > 0 ? ( ) : undefined; }); return ( {grammarGuide} ); })}
{"词干:"} {wordData?.parent .filter((value) => value.score >= minScore) .map((item, id) => { return ( {item.value} ); })}
{"贡献者:"} {wordData?.editor .filter((_value, index) => index < mainCollaboratorNum) .map((item, id) => { return collaboratorRender( item.value.nickName, id, item.score ); })} {more}
{"注释:"}
{wordData?.note .filter((value) => value.score >= minScore) .slice(0, 1) .map((item, id) => { return ; })}
) : showCreate ? ( { setMyRefresh(true); if (word) { dictLoad(word); } }} /> ) : ( <> )}
); }; export default CommunityWidget;