| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- import { ProList } from "@ant-design/pro-components";
- import { EditOutlined, CheckOutlined } from "@ant-design/icons";
- import type {
- IApiResponseDictData,
- IPreferenceListResponse,
- IPreferenceRequest,
- IPreferenceResponse,
- } from "../../api/Dict";
- import { Button, Input, Space, Tag } from "antd";
- import { get, put } from "../../request";
- import type { IWbw } from "../template/Wbw/WbwWord";
- import WbwFactorsEditor from "../template/Wbw/WbwFactorsEditor";
- import { useEffect, useState } from "react";
- import WbwLookup from "../template/Wbw/WbwLookup";
- import Lookup from "./Lookup";
- import WbwParentEditor from "../template/Wbw/WbwParentEditor";
- import User from "../auth/User";
- import DictConfidence from "./DictConfidence";
- export const setValue = async (id: string, value: number) => {
- const url = `/v2/dict-preference/${id}`;
- const values: IPreferenceRequest = {
- confidence: value,
- };
- console.debug("api request", url, values);
- const result = await put<IPreferenceRequest, IPreferenceResponse>(
- url,
- values
- );
- return result;
- };
- interface IOkButton {
- data: IApiResponseDictData;
- onChange?: (data: IApiResponseDictData) => void;
- }
- const OkButton = ({ data, onChange }: IOkButton) => {
- const [loading, setLoading] = useState(false);
- return (
- <Button
- type="link"
- icon={<CheckOutlined />}
- loading={loading}
- onClick={async () => {
- setLoading(true);
- const result = await setValue(data.id, 100);
- setLoading(false);
- console.info("api response", result);
- if (result.ok) {
- onChange && onChange(result.data);
- }
- }}
- >
- 确认
- </Button>
- );
- };
- const toWbw = (data: IApiResponseDictData): IWbw => {
- return {
- book: 1,
- para: 1,
- sn: [1],
- word: { value: data.word, status: 5 },
- real: { value: data.word, status: 5 },
- factors: { value: data.factors ?? "", status: 5 },
- parent: { value: data.parent ?? "", status: 5 },
- confidence: data.confidence ?? 0,
- };
- };
- interface IFactorsEditorWidget {
- data: IApiResponseDictData;
- }
- const FactorsEditor = ({ data }: IFactorsEditorWidget) => {
- const [wbw, setWbw] = useState(toWbw(data));
- const [input, setInput] = useState(data.factors);
- const [type, setType] = useState(false);
- useEffect(() => setWbw(toWbw(data)), [data]);
- const upload = async (value: string) => {
- const url = `/v2/dict-preference/${data.id}`;
- const values: IPreferenceRequest = {
- factors: value,
- confidence: 100,
- };
- console.debug("api request", url, data);
- const result = await put<IPreferenceRequest, IPreferenceResponse>(
- url,
- values
- );
- console.info("api response", result);
- setWbw(toWbw(result.data));
- setInput(result.data.factors);
- return result;
- };
- return type ? (
- <div style={{ display: "flex" }}>
- <Input
- width={400}
- value={input ?? ""}
- placeholder="Title"
- onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
- setInput(event.target.value);
- }}
- />
- <Button
- type="text"
- icon={<CheckOutlined />}
- onClick={async () => {
- upload(input ?? "");
- setType(false);
- }}
- />
- </div>
- ) : (
- <Space>
- <WbwFactorsEditor
- key="factors"
- initValue={wbw}
- display={"block"}
- onChange={async (e: string): Promise<IPreferenceResponse> => {
- const result = upload(e ?? "");
- return result;
- }}
- />
- <Button
- type="text"
- icon={<EditOutlined />}
- onClick={() => setType(true)}
- />
- </Space>
- );
- };
- interface IParentEditorWidget {
- data: IApiResponseDictData;
- }
- const ParentEditor = ({ data }: IParentEditorWidget) => {
- const [wbw, setWbw] = useState(toWbw(data));
- const [input, setInput] = useState(data.factors);
- const [type, setType] = useState(false);
- useEffect(() => setWbw(toWbw(data)), [data]);
- const upload = async (value: string) => {
- const url = `/v2/dict-preference/${data.id}`;
- const values: IPreferenceRequest = {
- parent: value,
- confidence: 100,
- };
- console.debug("api request", url, data);
- const result = await put<IPreferenceRequest, IPreferenceResponse>(
- url,
- values
- );
- console.info("api response", result);
- setWbw(toWbw(result.data));
- setInput(result.data.factors);
- return result;
- };
- return type ? (
- <div style={{ display: "flex" }}>
- <Input
- width={400}
- value={input ?? ""}
- placeholder="Title"
- onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
- setInput(event.target.value);
- }}
- />
- <Button
- type="text"
- icon={<CheckOutlined />}
- onClick={async () => {
- upload(input ?? "");
- setType(false);
- }}
- />
- </div>
- ) : (
- <Space>
- <WbwParentEditor
- key="factors"
- initValue={wbw}
- display={"block"}
- onChange={async (e: string): Promise<IPreferenceResponse> => {
- const result = upload(e ?? "");
- return result;
- }}
- />
- <Button
- type="text"
- icon={<EditOutlined />}
- onClick={() => setType(true)}
- />
- </Space>
- );
- };
- export interface IDictPreferenceWidget {
- currPage?: number;
- pageSize?: number;
- }
- const DictPreference = ({
- currPage,
- pageSize = 100,
- }: IDictPreferenceWidget) => {
- const [lookupWords, setLookupWords] = useState<string[]>([]);
- const [lookupRun, setLookupRun] = useState(false);
- const [data, setData] = useState<IApiResponseDictData[]>([]);
- return (
- <>
- <WbwLookup words={lookupWords} run={lookupRun} />
- <ProList<IApiResponseDictData>
- search={{
- filterType: "light",
- }}
- rowKey="name"
- headerTitle="单词首选项"
- dataSource={data}
- onDataSourceChange={setData}
- request={async (params = {} as Record<string, any>) => {
- let url = `/v2/dict-preference`;
- const mPageSize = pageSize ?? params.pageSize ?? 100;
- const offset = ((currPage ?? params.current ?? 1) - 1) * mPageSize;
- url += `?limit=${mPageSize}&offset=${offset}`;
- url += params.keyword ? "&keyword=" + params.keyword : "";
- console.info("api request", url);
- const res = await get<IPreferenceListResponse>(url);
- console.info("api response", res);
- if (res.ok === false) {
- }
- return {
- data: res.data.rows.map((item, id) => {
- return { ...item, sn: id + offset + 1 };
- }),
- total: res.data.count,
- success: true,
- };
- }}
- pagination={
- currPage
- ? false
- : {
- showQuickJumper: !currPage,
- showSizeChanger: !currPage,
- showLessItems: !currPage,
- showPrevNextJumpers: !currPage,
- pageSize: 100,
- }
- }
- showActions="hover"
- onRow={(record) => {
- return {
- onMouseEnter: () => {
- console.info(`点击了行:${record.word}`);
- setLookupWords([record.word]);
- setLookupRun(true);
- },
- onMouseLeave: () => {
- setLookupRun(false);
- },
- };
- }}
- metas={{
- title: {
- dataIndex: "word",
- title: "用户",
- render(_dom, entity, _index, _action, _schema) {
- return (
- <Space>
- {`[${entity.sn}]`}
- <Lookup search={entity.word}>{entity.word}</Lookup>
- </Space>
- );
- },
- },
- avatar: {
- dataIndex: "sn",
- search: false,
- render(_dom, entity, _index, _action, _schema) {
- return (
- <User
- {...entity.editor}
- showName={false}
- showUserName={false}
- />
- );
- },
- },
- description: {
- dataIndex: "title",
- search: false,
- render(_dom, entity, _index, _action, _schema) {
- return (
- <Space>
- <FactorsEditor data={entity} />
- <span>|</span>
- <ParentEditor data={entity} />
- </Space>
- );
- },
- },
- subTitle: {
- dataIndex: "labels",
- render: (_, row) => {
- return (
- <Space>
- <Tag color="blue" key={row.count}>
- {row.count}
- </Tag>
- <DictConfidence
- value={row.confidence}
- onChange={async (value) => {
- const result = await setValue(row.id, value);
- setData((origin) => {
- origin.forEach((value, index, array) => {
- if (value.id === result.data.id) {
- array[index] = {
- ...value,
- confidence: result.data.confidence,
- };
- }
- });
- return origin;
- });
- }}
- />
- </Space>
- );
- },
- search: false,
- },
- actions: {
- render: (_text, row) => {
- return [
- <OkButton
- data={row}
- onChange={(data) => {
- setData((origin) => {
- origin.forEach((value, index, array) => {
- if (value.id === row.id) {
- array[index] = {
- ...value,
- confidence: data.confidence,
- };
- }
- });
- return origin;
- });
- }}
- />,
- ];
- },
- search: false,
- },
- status: {
- // 自己扩展的字段,主要用于筛选,不在列表中显示
- title: "状态",
- valueType: "select",
- valueEnum: {
- all: { text: "全部", status: "Default" },
- open: {
- text: "未解决",
- status: "Error",
- },
- closed: {
- text: "已解决",
- status: "Success",
- },
- processing: {
- text: "解决中",
- status: "Processing",
- },
- },
- },
- }}
- />
- </>
- );
- };
- export default DictPreference;
|