chore: replace all cn comments of fe to en version by volc api (#320)
This commit is contained in:
@@ -20,7 +20,7 @@ import { KnowledgeApi } from '@coze-arch/bot-api';
|
||||
import { type ViewOnlinePageDetailProps } from '@/types';
|
||||
|
||||
/**
|
||||
* 将API返回的网页信息转换为视图数据
|
||||
* Convert the web page information returned by the API into view data
|
||||
*/
|
||||
const transformWebInfoToViewData = (webInfo: {
|
||||
id?: string;
|
||||
@@ -47,7 +47,7 @@ export const useGetWebInfo = (): {
|
||||
include_content: true,
|
||||
});
|
||||
|
||||
// 如果没有数据,返回空数组
|
||||
// If there is no data, return an empty array
|
||||
if (!responseData?.[webID]?.web_info) {
|
||||
return [] as ViewOnlinePageDetailProps[];
|
||||
}
|
||||
@@ -56,7 +56,7 @@ export const useGetWebInfo = (): {
|
||||
const mainPageData = transformWebInfoToViewData(webInfo);
|
||||
const result = [mainPageData];
|
||||
|
||||
// 处理子页面数据
|
||||
// Processing subpage data
|
||||
if (webInfo?.subpages?.length) {
|
||||
const subpagesData = webInfo.subpages.map(transformWebInfoToViewData);
|
||||
result.push(...subpagesData);
|
||||
|
||||
@@ -28,7 +28,7 @@ export type CardRadioGroupProps<T = unknown> = PropsWithChildren<
|
||||
};
|
||||
|
||||
/**
|
||||
* 始终使用卡片风格,并符合 UI 设计样式的 {@link RadioGroup}
|
||||
* Always use the card style and conform to the UI design style {@link RadioGroup}
|
||||
*/
|
||||
export function CardRadioGroup<T = unknown>({
|
||||
value,
|
||||
|
||||
@@ -26,7 +26,7 @@ export interface CollapsePanelProps extends PropsWithChildren {
|
||||
}
|
||||
|
||||
/**
|
||||
* 用 Collapsible 封装的更符合 UI 设计的折叠面板
|
||||
* A collapsible panel with Collapsible for better UI design
|
||||
*/
|
||||
export function CollapsePanel({
|
||||
header,
|
||||
|
||||
@@ -30,10 +30,10 @@ interface FilterPageConfig {
|
||||
}
|
||||
|
||||
interface Document {
|
||||
// TODO: 扩充
|
||||
// TODO: Expansion
|
||||
id: string;
|
||||
title: string;
|
||||
/** 是否存在过滤内容 */
|
||||
/** Is there filtered content? */
|
||||
filterPageConfigList: FilterPageConfig[];
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
padding: 9px 16px !important;
|
||||
}
|
||||
|
||||
/** 去掉hover行样式 */
|
||||
/** Remove hover line style */
|
||||
.semi-table-tbody .semi-table-row:hover>.semi-table-row-cell {
|
||||
background-color: transparent !important;
|
||||
background-image: none !important;
|
||||
|
||||
@@ -54,17 +54,17 @@ export const TablePreview: React.FC<TablePreviewProps> = ({
|
||||
}) => {
|
||||
const { sheet_list = [], table_meta = {}, preview_data = {} } = data;
|
||||
const startRow = Number(settings[TableSettingFormFields.DATA_START_ROW]) || 0;
|
||||
// 选中的表id
|
||||
// Selected table id
|
||||
const sheetId = useMemo(
|
||||
() => settings[TableSettingFormFields.SHEET] || 0,
|
||||
[settings],
|
||||
);
|
||||
// 选中的表名
|
||||
// Selected table name
|
||||
const sheetName = useMemo(
|
||||
() => (sheet_list || []).find(sheet => sheet?.id === sheetId)?.sheet_name,
|
||||
[sheet_list, sheetId],
|
||||
);
|
||||
// 选中的表的数据量
|
||||
// The amount of data for the selected table
|
||||
const total = useMemo(
|
||||
() =>
|
||||
Number(
|
||||
|
||||
@@ -90,7 +90,7 @@ export const TableSettingBar: React.FC<TableSettingBarProps> = ({
|
||||
e2e: KnowledgeE2e.TableLocalTableConfigurationStarRow,
|
||||
field: TableSettingFormFields.DATA_START_ROW,
|
||||
label: I18n.t('datasets_createFileModel_tab_dataStarRow'),
|
||||
// 数据起始行需大于表头行
|
||||
// The starting row of the data must be larger than the header row
|
||||
options: options.slice(
|
||||
Number(tableSettings[TableSettingFormFields.KEY_START_ROW]) + 1,
|
||||
),
|
||||
@@ -112,7 +112,7 @@ export const TableSettingBar: React.FC<TableSettingBarProps> = ({
|
||||
TableSettingFormFields.KEY_START_ROW,
|
||||
);
|
||||
if (isNumber(curSheet) && formApi.current) {
|
||||
// 修改sheet,初始化表头行和数据行
|
||||
// Modify the sheet, initialize the header and data rows
|
||||
formApi.current.setValue(TableSettingFormFields.KEY_START_ROW, 0);
|
||||
formApi.current.setValue(TableSettingFormFields.DATA_START_ROW, 1);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
/** 暂时注释,后续还要用,待讨论 */
|
||||
/** Temporary comment, to be used later, to be discussed */
|
||||
// &:hover {
|
||||
// background: var(--coz-mg-secondary-hovered) !important;
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
/** table去掉背景色 */
|
||||
/** Table remove background color */
|
||||
.semi-table-thead>.semi-table-row>.semi-table-row-head, .semi-table-tbody>.semi-table-row, .semi-table-tbody>.semi-table-row>.semi-table-cell-fixed-left,.semi-table-thead>.semi-table-row>.semi-table-row-head.semi-table-cell-fixed-left::before {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ const InputRender = ({
|
||||
);
|
||||
};
|
||||
|
||||
// TODO 待解
|
||||
// TODO to be solved
|
||||
// eslint-disable-next-line @coze-arch/max-line-per-function
|
||||
export const TableStructure: React.FC<TableStructureProps> = ({
|
||||
data = [],
|
||||
@@ -487,7 +487,7 @@ export const TableStructure: React.FC<TableStructureProps> = ({
|
||||
},
|
||||
];
|
||||
|
||||
// 预览场景下,不需要操作列
|
||||
// In the preview scenario, no operation column is required
|
||||
if (isPreview) {
|
||||
columns.pop();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// 组件相关
|
||||
// component related
|
||||
export {
|
||||
TableSettingBar,
|
||||
type TableSettingBarProps,
|
||||
|
||||
@@ -79,7 +79,7 @@ const renderSubText = (
|
||||
}
|
||||
let subDesc = '';
|
||||
if (hasURLImport) {
|
||||
// 更新频率
|
||||
// update frequency
|
||||
const updateInterval = hoursToDays(item?.update_interval || 0);
|
||||
subDesc = getFrequencyMap(updateInterval);
|
||||
} else {
|
||||
|
||||
@@ -30,7 +30,7 @@ interface UploadFooterProps {
|
||||
controls: FooterControlsProps;
|
||||
}
|
||||
|
||||
/** 类型断言 入参是不是 按钮数组 */
|
||||
/** Type assertion imported parameter yes no, button array */
|
||||
function isBtnArray(controls: unknown): controls is FooterBtnProps[] {
|
||||
return !!controls && isArray(controls);
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ interface UploadActionNavbarProps {
|
||||
title: string;
|
||||
}
|
||||
|
||||
// 上传页面导航栏
|
||||
// Upload page navigation bar
|
||||
export const UploadActionNavbar = ({ title }: UploadActionNavbarProps) => {
|
||||
const params = useKnowledgeParams();
|
||||
const resourceNavigate = useDataNavigate();
|
||||
|
||||
// TODO: hzf biz的分化在Scene层维护
|
||||
// TODO: Scene layer maintenance of hzf biz differentiation
|
||||
const fromProject = params.biz === 'project';
|
||||
const handleBack = () => {
|
||||
const query = getKnowledgeIDEQuery() as Record<string, string>;
|
||||
|
||||
@@ -29,8 +29,8 @@ export const getBeforeUpload: (params: {
|
||||
}) => UploadProps['beforeUpload'] =
|
||||
({ maxSizeMB }) =>
|
||||
async fileInfo => {
|
||||
// 不通过 maxSize 属性来限制的原因是
|
||||
// 只有 beforeUpload 钩子能改 validateMessage
|
||||
// The reason for not limiting by the maxSize property is
|
||||
// Only the beforeUpload hook can change validateMessage
|
||||
const res = {
|
||||
fileInstance: fileInfo.file.fileInstance,
|
||||
status: fileInfo.file.status,
|
||||
@@ -73,7 +73,7 @@ export const getBeforeUpload: (params: {
|
||||
|
||||
if (getFileExtension(fileInstance.name).toLowerCase() === 'pdf') {
|
||||
try {
|
||||
// TODO: 后续其他位置的 pdfjs 调用也都应该改成异步加载
|
||||
// TODO: Subsequent pdfjs calls from other locations should also be changed to asynchronous loading
|
||||
const pdfjs = await import('@coze-arch/pdfjs-shadow');
|
||||
const { getDocument, initPdfJsWorker } = pdfjs;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ export const customRequest: UploadProps['customRequest'] = async options => {
|
||||
const { onSuccess, onError, onProgress, file } = options;
|
||||
|
||||
try {
|
||||
// 业务
|
||||
// business
|
||||
const { name, fileInstance } = file;
|
||||
|
||||
if (fileInstance) {
|
||||
@@ -47,7 +47,7 @@ export const customRequest: UploadProps['customRequest'] = async options => {
|
||||
onUploadProgress: e => {
|
||||
const status = file?.status;
|
||||
const response = file?.response;
|
||||
// 成功或失败、检验失败后,或者有返回接口数据,不再更新进度条
|
||||
// Success or failure, after the inspection fails, or if the interface data is returned, the progress bar will not be updated.
|
||||
if (
|
||||
status === UploadStatus.SUCCESS ||
|
||||
status === UploadStatus.UPLOAD_FAIL ||
|
||||
|
||||
@@ -38,7 +38,7 @@ const getFileListMap = (fileList: FileItem[]): GetFileListMapRes =>
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
/** 过滤 fileList,仅保留在 unitList 中的文件,即上传成功的文件 */
|
||||
/** Filter the fileList to keep only the files in the unitList, that is, the files that were uploaded successfully. */
|
||||
export const filterFileListByUnitList = (
|
||||
fileList: FileItem[],
|
||||
unitList: UnitItem[],
|
||||
|
||||
@@ -34,7 +34,7 @@ export const UnitName: React.FC<UnitNameProps> = ({
|
||||
formatType,
|
||||
}) => {
|
||||
const { type, name, validateMessage } = record;
|
||||
const [value, setValue] = useState(name); // 需要用自身state,否则出现无法输入中文的bug
|
||||
const [value, setValue] = useState(name); // You need to use your own state, otherwise there will be a bug that cannot enter Chinese.
|
||||
const getValidateMessage = (val: string) =>
|
||||
!val ? I18n.t('datasets_unit_exception_name_empty') : validateMessage;
|
||||
useEffect(() => {
|
||||
|
||||
@@ -39,7 +39,7 @@ export const UnitName: FC<UnitNameProps> = ({
|
||||
inModal = false,
|
||||
}) => {
|
||||
const { type, name, validateMessage, dynamicErrorMessage } = record;
|
||||
const [value, setValue] = useState(name); // 需要用自身state,否则出现无法输入中文的bug
|
||||
const [value, setValue] = useState(name); // You need to use your own state, otherwise there will be a bug that cannot enter Chinese.
|
||||
const [validData, setValidData] = useState({ valid: true, errorMsg: '' });
|
||||
|
||||
const getValidateMessage = (val: string) =>
|
||||
|
||||
@@ -30,7 +30,7 @@ export interface UploadStateProps {
|
||||
needLoading?: boolean;
|
||||
overlayClassName?: string;
|
||||
disableRetry?: boolean;
|
||||
// 不显示重试文案
|
||||
// Do not show retry copy
|
||||
noRetry?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ export const UploadUnitTable: FC<UploadUnitTableProps> = props => {
|
||||
const curStatus = getProcessStatus(item?.status);
|
||||
const statusDescript = item?.statusDescript || '';
|
||||
|
||||
// 使用getColumns获取每个项目的信息
|
||||
// Use getColumns to obtain information for each item
|
||||
const columnInfo: ColumnInfo = getColumns
|
||||
? getColumns(item, index)
|
||||
: {};
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 更新频率 */
|
||||
/** update frequency */
|
||||
export enum FrequencyDay {
|
||||
ZERO = 0,
|
||||
ONE = 1,
|
||||
@@ -28,7 +28,7 @@ export enum TableSettingFormFields {
|
||||
DATA_START_ROW = 'start_line_idx',
|
||||
}
|
||||
|
||||
/** 知识库上传文件最大 size 100MB */
|
||||
/** Knowledge base upload file maximum size 100MB */
|
||||
export const UNIT_MAX_MB = 100;
|
||||
|
||||
export const PDF_MAX_PAGES = 500;
|
||||
|
||||
@@ -49,7 +49,7 @@ function getCreateDocumentParams(
|
||||
return {
|
||||
document_bases: [
|
||||
{
|
||||
name: '', // table custom传控
|
||||
name: '', // Table custom control
|
||||
source_info: {
|
||||
document_source: DocumentSource.Custom,
|
||||
},
|
||||
@@ -102,7 +102,7 @@ export const TableCustomCreate = <
|
||||
|
||||
useEffect(() => {
|
||||
if (footerStatus !== FooterBtnStatus.LOADING) {
|
||||
setFooterStatus(getCustomStatus(metaData, 'toBeDelete')); // toBeDelete 待删
|
||||
setFooterStatus(getCustomStatus(metaData, 'toBeDelete')); // toBeDelete to be deleted
|
||||
}
|
||||
}, [metaData]);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
import { type TableLocalContentProps } from '../../types';
|
||||
import { TableCustomCreate as TableCustomCreateV2 } from './create-v2';
|
||||
|
||||
/** 到时候要删掉 TableCustomCreateV1*/
|
||||
/** Delete TableCustomCreateV1 at that time.*/
|
||||
export const TableCustomCreate = (props: TableLocalContentProps) => (
|
||||
<TableCustomCreateV2 {...props} />
|
||||
);
|
||||
|
||||
@@ -175,7 +175,7 @@ export function tableDataCleaning({
|
||||
},
|
||||
}));
|
||||
|
||||
// 增加操作列
|
||||
// Add action column
|
||||
tableColumns.push({
|
||||
title: <></>,
|
||||
width: 100,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* service定义:包含业务处理 & 事件
|
||||
* Service definition: contains business processes & events
|
||||
*/
|
||||
import { useMemo } from 'react';
|
||||
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
type UploadTableState,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
|
||||
/** table-local upload 时要用tos_uri 去取table_info */
|
||||
/** Use tos_uri to get table_info when uploading table-local */
|
||||
export const useUploadFetchTableParams = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
@@ -84,7 +84,7 @@ export const useRetry = <
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO 加上报
|
||||
// TODO plus report
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -66,7 +66,7 @@ export const TableUpload = <
|
||||
const fetchTableInfo = useFetchTableSchemaInfo<T>(useStore);
|
||||
|
||||
useEffect(() => {
|
||||
// 删除上传文件时,同步删除表格源数据
|
||||
// When deleting an uploaded file, delete the table source data synchronously
|
||||
if (!unitList.length) {
|
||||
setOriginTableData({});
|
||||
setTableData({});
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* service定义:包含业务处理 & 事件
|
||||
* Service definition: contains business processes & events
|
||||
*/
|
||||
import { useMemo } from 'react';
|
||||
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
type UploadTableState,
|
||||
} from '@/features/knowledge-type/table/interface';
|
||||
|
||||
/** table-local upload 时要用tos_uri 去取table_info */
|
||||
/** Use tos_uri to get table_info when uploading table-local */
|
||||
export const useUploadFetchTableParams = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
>(
|
||||
@@ -84,7 +84,7 @@ export const useRetry = <
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO 加上报
|
||||
// TODO plus report
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -71,7 +71,7 @@ export const TableUpload = <
|
||||
const fetchTableInfo = useFetchTableSchemaInfo<T>(useStore);
|
||||
|
||||
useEffect(() => {
|
||||
// 删除上传文件时,同步删除表格源数据
|
||||
// When deleting an uploaded file, delete the table source data synchronously
|
||||
if (!unitList.length) {
|
||||
setOriginTableData({});
|
||||
setTableData({});
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/**
|
||||
* pure network request & common services
|
||||
*/
|
||||
// TODO 待解
|
||||
// TODO to be solved
|
||||
|
||||
import { type StoreApi, type UseBoundStore } from 'zustand';
|
||||
import { debounce, get } from 'lodash-es';
|
||||
@@ -163,8 +163,8 @@ export const useFetchTableSchemaInfoReq = (
|
||||
};
|
||||
|
||||
/**
|
||||
* 这个方法 所有的table链路都会用到
|
||||
* impure,会改store,因为所有table链路类似,所以放到这里
|
||||
* This method is used by all table links
|
||||
* Impure, will change the store, because all table links are similar, so put it here
|
||||
*/
|
||||
export const useFetchTableSchemaInfo = <
|
||||
T extends UploadTableState<number> & UploadTableAction<number>,
|
||||
@@ -187,7 +187,7 @@ export const useFetchTableSchemaInfo = <
|
||||
}
|
||||
: res;
|
||||
if (!isOnlyPreview) {
|
||||
// 为什么有这个if,因为第一次请求全量,第二次请求isOnlyPreview
|
||||
// Why is there this if, because the first request is full, and the second request is OnlyPreview.
|
||||
setOriginTableData(newData);
|
||||
}
|
||||
const validateRes = semanticValidator(newData);
|
||||
@@ -202,8 +202,8 @@ export const useFetchTableSchemaInfo = <
|
||||
);
|
||||
};
|
||||
|
||||
// TODO 待优化,这个函数包含了太多逻辑,非常乱
|
||||
// events action nl2ql链路
|
||||
// TODO needs to be optimized. This function contains too much logic and is very messy.
|
||||
// Events action nl2ql link
|
||||
export const useChangeTableSettingsNl2ql = <
|
||||
T extends UploadTableState<number> &
|
||||
UploadTableAction<number> &
|
||||
@@ -224,7 +224,7 @@ export const useChangeTableSettingsNl2ql = <
|
||||
const AWAIT = 500;
|
||||
const params = useUploadFetchTableParams(useStore);
|
||||
|
||||
const isThirdResegment = isThirdResegmentFunc(opt ?? OptType.ADD, type); // 判断是否为三方的resegment
|
||||
const isThirdResegment = isThirdResegmentFunc(opt ?? OptType.ADD, type); // Determine whether it is a tripartite resegment
|
||||
const isIncremental = isIncrementalFunc(opt ?? OptType.ADD);
|
||||
|
||||
const onChangeTableSettings = debounce((v: TableSettings) => {
|
||||
@@ -233,7 +233,7 @@ export const useChangeTableSettingsNl2ql = <
|
||||
type &&
|
||||
[UnitType.TABLE_GOOGLE_DRIVE, UnitType.TABLE_FEISHU].includes(type)
|
||||
? {
|
||||
// 飞书需要传 tos_uri
|
||||
// Feishu needs to pass tos_uri
|
||||
tos_uri: type === UnitType.TABLE_FEISHU ? tosUrlRef : undefined,
|
||||
source_file_id: sourceFileId ?? undefined,
|
||||
document_source:
|
||||
@@ -243,7 +243,7 @@ export const useChangeTableSettingsNl2ql = <
|
||||
}
|
||||
: params;
|
||||
fetchTableInfo({
|
||||
// 如果为三方的resegment就不传 source_file
|
||||
// If it is a resegment of three parties, it will not be transmitted source_file
|
||||
source_file: isThirdResegment ? undefined : sourceFile,
|
||||
table_sheet:
|
||||
!isIncremental &&
|
||||
@@ -254,7 +254,7 @@ export const useChangeTableSettingsNl2ql = <
|
||||
header_line_idx: String(v.header_line_idx),
|
||||
start_line_idx: String(v.start_line_idx),
|
||||
},
|
||||
// 如果为三方的resegment和增量导入,就传 document_id 其他情况不传
|
||||
// If it is a three-party resegment and incremental import, it will pass document_id other cases will not pass
|
||||
document_id: isThirdResegment || isIncremental ? docID : undefined,
|
||||
table_data_type: TableDataType.AllData,
|
||||
});
|
||||
@@ -315,7 +315,7 @@ export const useUpdateDocument = <
|
||||
|
||||
/**
|
||||
* table custom createDocument
|
||||
* TODO 即将废弃,切到新的knowledge信息架构后要删掉
|
||||
* TODO will be abandoned soon, and will be deleted after cutting to the new knowledge information architecture
|
||||
* @deprecated
|
||||
* @param setStatus
|
||||
* @param formApi
|
||||
@@ -368,8 +368,8 @@ export const useCreateDocument = (
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* table unit name校验
|
||||
* TODO 待删,新链路已经不用,只直接用新的,因为产品功能是新的
|
||||
* Table unit name verification
|
||||
* TODO to be deleted, the new link is no longer used, only the new one is used directly, because the product function is new.
|
||||
*/
|
||||
export const useValidateUnitName = () => {
|
||||
const { docID: docIdFromQuery, spaceID, datasetID } = useKnowledgeParams();
|
||||
|
||||
@@ -60,7 +60,7 @@ import {
|
||||
} from '@/constants';
|
||||
|
||||
/**
|
||||
* 校验key是否能作为语义匹配项
|
||||
* Verify whether the key can be used as a semantic match
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
@@ -83,7 +83,7 @@ export const semanticValidator = (
|
||||
return {};
|
||||
}
|
||||
|
||||
// TODO 下面forEach写的不好,待优化
|
||||
// The forEach below TODO is not well written and needs to be optimized.
|
||||
const res: SemanticValidate = {};
|
||||
Object.keys(table_meta).forEach(sheetId => {
|
||||
res[sheetId] = {};
|
||||
@@ -260,7 +260,7 @@ export function getConfigurationNextStatus(
|
||||
const hasDuplicateColumnName = meta.some(
|
||||
v => meta.filter(i => i.column_name === v.column_name).length >= 2,
|
||||
);
|
||||
// 没有表结构数据禁止下一步
|
||||
// No table structure data prohibits next step
|
||||
if (
|
||||
!Object.keys(meta).length ||
|
||||
hasEmptyMeta ||
|
||||
@@ -282,13 +282,13 @@ export function getDocIdFromProgressList(progressList: ProgressItem[]) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取footer状态,不包括loading状态,仅判断启/禁用
|
||||
* 满足以下任一情况时,禁用footer按钮
|
||||
* 1.存在列名为空
|
||||
* 2.unitName为空
|
||||
* 3.没有选择语义匹配项
|
||||
* Get footer status, excluding loading status, only judge start/disable
|
||||
* Disable the footer button when any of the following conditions are met
|
||||
* 1. There is an empty column name
|
||||
* 2. unitName is empty
|
||||
* 3. No semantic match selected
|
||||
* @param metaData
|
||||
* @param unitName // TODO unitName的判断待删
|
||||
* @param unitName//TODO unitName judgment to be deletede deleted
|
||||
* @returns
|
||||
*/
|
||||
export const getCustomStatus = (
|
||||
@@ -297,13 +297,13 @@ export const getCustomStatus = (
|
||||
): FooterBtnStatus => {
|
||||
const isDisabled =
|
||||
metaData.some(meta => !meta.column_type) ||
|
||||
!validateField(unitName)?.valid || // TODO 这一行待删
|
||||
!validateField(unitName)?.valid || // TODO line to be deleted
|
||||
!metaData.some(meta => meta.is_semantic === true) ||
|
||||
metaData.some(v => validateField(v.column_name ?? '')?.valid === false);
|
||||
return isDisabled ? FooterBtnStatus.DISABLE : FooterBtnStatus.ENABLE;
|
||||
};
|
||||
|
||||
// table上传第一步footer状态判断
|
||||
// Table upload first step footer status judgment
|
||||
export function getButtonStatus(unitList: UnitItem[]) {
|
||||
const valid = unitList.some(v => validateField(v.name)?.valid === false);
|
||||
if (
|
||||
@@ -331,8 +331,8 @@ export function getAddSegmentParams({
|
||||
documentInfo: DocumentBase[];
|
||||
}) {
|
||||
const payload = {
|
||||
space_id: spaceId, // 兼容旧接口
|
||||
document_id: docId, // 兼容旧接口
|
||||
space_id: spaceId, // Compatible with outdated interfaces
|
||||
document_id: docId, // Compatible with outdated interfaces
|
||||
dataset_id: datasetId,
|
||||
format_type: FormatType.Table,
|
||||
document_bases: documentInfo,
|
||||
@@ -393,7 +393,7 @@ export function getCreateDocumentParams({
|
||||
update_rule: getUpdateRule(),
|
||||
table_sheet: tableSettingsToString(tableSettings),
|
||||
table_meta: metaData.map(meta => ({
|
||||
id: isAppend ? meta.id : '0', // 不是追加,默认是新建(为'0')
|
||||
id: isAppend ? meta.id : '0', // Not append, default is new ('0')
|
||||
column_name: meta.column_name,
|
||||
is_semantic: meta.is_semantic,
|
||||
column_type: meta.column_type,
|
||||
@@ -403,6 +403,6 @@ export function getCreateDocumentParams({
|
||||
})),
|
||||
|
||||
is_append: isAppend,
|
||||
// document_id: useDocIdFromQuery() ?? undefined, // TODO 待删除,这里是为了兼容原来的MemoryApi.ProcessDocumentsTask更新逻辑
|
||||
// document_id: useDocIdFromQuery ()?? undefined,//TODO to be deleted, here is to be compatible with the original MemoryApi. ProcessDocumentsTask update logic
|
||||
};
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ export const TextProcessing: FC<
|
||||
},
|
||||
},
|
||||
],
|
||||
// 非首次添加时,不需要传分段规则
|
||||
// When not added for the first time, no segmentation rules are required
|
||||
chunk_strategy: getCustomValues(segmentMode, segmentRule),
|
||||
storage_strategy:
|
||||
IS_CN_REGION && enableStorageStrategy
|
||||
|
||||
@@ -69,7 +69,7 @@ export const SegmentPreviewStep: FC<
|
||||
[docReviewList, unitList],
|
||||
);
|
||||
|
||||
/** 创建 doc review */
|
||||
/** Create doc review */
|
||||
useEffect(() => {
|
||||
const createDocReview = async () => {
|
||||
const { unitList: inputUnitList } = useStore.getState();
|
||||
@@ -95,7 +95,7 @@ export const SegmentPreviewStep: FC<
|
||||
if (!docReviewCreated) {
|
||||
createDocReview();
|
||||
}
|
||||
// TODO: segmentMode 切换时需要重新创建 doc review
|
||||
// TODO: segmentMode needs to be recreated when switching doc review
|
||||
}, [
|
||||
docReviewCreated,
|
||||
parsingStrategy,
|
||||
@@ -104,7 +104,7 @@ export const SegmentPreviewStep: FC<
|
||||
levelChunkStrategy,
|
||||
]);
|
||||
|
||||
/** 轮询 doc review 状态 */
|
||||
/** Poll doc review status */
|
||||
const { run: pollDocReviewStatus, cancel: cancelPollDocReviewStatus } =
|
||||
useRequest(
|
||||
async () => {
|
||||
@@ -131,12 +131,12 @@ export const SegmentPreviewStep: FC<
|
||||
};
|
||||
}, [docReviewCreated]);
|
||||
|
||||
/** 结束轮询 */
|
||||
/** end polling */
|
||||
const docReviewProcessFinished =
|
||||
docReviewList.length > 0 &&
|
||||
docReviewList.every(
|
||||
item =>
|
||||
// docReview 刚创建时没有 status, 其他情况下校验 status 是否为 Processing
|
||||
// DocReview has no status when it is first created. In other cases, check whether the status is Processing.
|
||||
typeof item.status !== 'undefined' &&
|
||||
item.status !== ReviewStatus.Processing,
|
||||
);
|
||||
|
||||
@@ -88,7 +88,7 @@ export function getCreateDocumentParams({
|
||||
levelChunkStrategy,
|
||||
),
|
||||
};
|
||||
// 火山[云搜索服务]只在国内环境上线
|
||||
// Volcano [Cloud Search Service] is only available in the domestic environment
|
||||
if (IS_CN_REGION && enableStorageStrategy) {
|
||||
req.storage_strategy = {
|
||||
storage_location: storageLocation,
|
||||
|
||||
@@ -38,7 +38,7 @@ import { type PDFDocumentFilterValue } from '@/features/knowledge-type/text';
|
||||
import type { UploadTextLocalAddUpdateStore } from '../../store';
|
||||
import { TextLocalAddUpdateStep } from '../../constants';
|
||||
|
||||
// ! 本地文档上传
|
||||
// ! Local file upload
|
||||
export const TextSegment: FC<
|
||||
ContentProps<UploadTextLocalAddUpdateStore>
|
||||
> = props => {
|
||||
|
||||
@@ -19,32 +19,32 @@ import { type Review } from '@coze-arch/idl/knowledge';
|
||||
|
||||
export interface IDocReviewState {
|
||||
/**
|
||||
* 当前 active 的 doc review 的 id
|
||||
* The id of the currently active doc review
|
||||
*/
|
||||
currentReviewID?: string;
|
||||
/**
|
||||
* 当前选中的分段的 id
|
||||
* The ID of the currently selected segment
|
||||
*/
|
||||
selectionIDs?: string[];
|
||||
/**
|
||||
* docReview 的列表
|
||||
* List of docReview
|
||||
*/
|
||||
docReviewList: Review[];
|
||||
}
|
||||
|
||||
export interface IDocReviewAction {
|
||||
/**
|
||||
* 设置当前 active 的 doc review 的 id
|
||||
* Set the id of the currently active doc review
|
||||
* @param id
|
||||
*/
|
||||
setCurrentReviewID: (id: string) => void;
|
||||
/**
|
||||
* 设置当前选中的分段的 id
|
||||
* Sets the ID of the currently selected segment.
|
||||
* @param ids
|
||||
*/
|
||||
setSelectionIDs: (ids: string[]) => void;
|
||||
/**
|
||||
* 设置 docReview 的列表
|
||||
* Set up a list of docReviews
|
||||
* @param list
|
||||
*/
|
||||
setDocReviewList: (list: Review[]) => void;
|
||||
|
||||
@@ -67,7 +67,7 @@ export const SegmentPreviewStep: FC<
|
||||
[docReviewList, documentInfo],
|
||||
);
|
||||
|
||||
/** 创建 doc review */
|
||||
/** Create doc review */
|
||||
useEffect(() => {
|
||||
const createDocReview = async () => {
|
||||
const res = await KnowledgeApi.CreateDocumentReview({
|
||||
@@ -88,7 +88,7 @@ export const SegmentPreviewStep: FC<
|
||||
if (!docReviewCreated) {
|
||||
createDocReview();
|
||||
}
|
||||
// TODO: segmentMode 切换时需要重新创建 doc review
|
||||
// TODO: segmentMode needs to be recreated when switching doc review
|
||||
}, [
|
||||
docReviewCreated,
|
||||
parsingStrategy,
|
||||
@@ -98,7 +98,7 @@ export const SegmentPreviewStep: FC<
|
||||
documentInfo,
|
||||
]);
|
||||
|
||||
/** 轮询 doc review 状态 */
|
||||
/** Poll doc review status */
|
||||
const { run: pollDocReviewStatus, cancel: cancelPollDocReviewStatus } =
|
||||
useRequest(
|
||||
async () => {
|
||||
@@ -125,12 +125,12 @@ export const SegmentPreviewStep: FC<
|
||||
};
|
||||
}, [docReviewCreated]);
|
||||
|
||||
/** 结束轮询 */
|
||||
/** end polling */
|
||||
const docReviewProcessFinished =
|
||||
docReviewList.length > 0 &&
|
||||
docReviewList.every(
|
||||
item =>
|
||||
// docReview 刚创建时没有 status, 其他情况下校验 status 是否为 Processing
|
||||
// DocReview has no status when it is first created. In other cases, check whether the status is Processing.
|
||||
typeof item.status !== 'undefined' &&
|
||||
item.status !== ReviewStatus.Processing,
|
||||
);
|
||||
@@ -167,7 +167,7 @@ export const SegmentPreviewStep: FC<
|
||||
<>
|
||||
<SegmentPreview
|
||||
docReviewList={docReviewList}
|
||||
// 重分段的时候只有一个文档,所以不需要刷新 docReviewList
|
||||
// There is only one document when re-segmenting, so there is no need to refresh the docReviewList.
|
||||
segmentMode={segmentMode}
|
||||
currentReviewID={currentReviewID}
|
||||
setCurrentReviewID={setCurrentReviewID}
|
||||
|
||||
@@ -51,7 +51,7 @@ export const useResegment = <T extends UploadTextLocalResegmentStore>(
|
||||
const pollingTaskProgress = usePollingTaskProgress();
|
||||
const docId = params.docID ?? '';
|
||||
|
||||
// TODO: 分层相关
|
||||
// TODO: Hierarchical correlation
|
||||
const { run: handleProcessText } = useRequest(
|
||||
async () => {
|
||||
if (!params.datasetID) {
|
||||
|
||||
@@ -37,7 +37,7 @@ import {
|
||||
import type { UploadTextLocalResegmentStore } from '../../store';
|
||||
import { TextLocalResegmentStep } from '../../constants';
|
||||
|
||||
// ! 本地文档上传
|
||||
// ! Local file upload
|
||||
export const TextSegment: FC<
|
||||
ContentProps<UploadTextLocalResegmentStore>
|
||||
> = props => {
|
||||
@@ -89,7 +89,7 @@ export const TextSegment: FC<
|
||||
setDocumentInfo(resDocumentInfo);
|
||||
});
|
||||
|
||||
// TODO: 切回来
|
||||
// TODO: Cut back
|
||||
useEffect(() => {
|
||||
if (docID) {
|
||||
listDocumentReq({
|
||||
|
||||
@@ -32,7 +32,7 @@ export const getButtonNextStatus = (
|
||||
return FooterBtnStatus.DISABLE;
|
||||
}
|
||||
}
|
||||
// TODO: 分层相关
|
||||
// TODO: Hierarchical correlation
|
||||
|
||||
return FooterBtnStatus.ENABLE;
|
||||
};
|
||||
|
||||
@@ -19,32 +19,32 @@ import { type Review } from '@coze-arch/idl/knowledge';
|
||||
|
||||
export interface IDocReviewState {
|
||||
/**
|
||||
* 当前 active 的 doc review 的 id
|
||||
* The id of the currently active doc review
|
||||
*/
|
||||
currentReviewID?: string;
|
||||
/**
|
||||
* 当前选中的分段的 id
|
||||
* The ID of the currently selected segment
|
||||
*/
|
||||
selectionIDs?: string[];
|
||||
/**
|
||||
* docReview 的列表
|
||||
* List of docReview
|
||||
*/
|
||||
docReviewList: Review[];
|
||||
}
|
||||
|
||||
export interface IDocReviewAction {
|
||||
/**
|
||||
* 设置当前 active 的 doc review 的 id
|
||||
* Set the id of the currently active doc review
|
||||
* @param id
|
||||
*/
|
||||
setCurrentReviewID: (id: string) => void;
|
||||
/**
|
||||
* 设置当前选中的分段的 id
|
||||
* Sets the ID of the currently selected segment.
|
||||
* @param ids
|
||||
*/
|
||||
setSelectionIDs: (ids: string[]) => void;
|
||||
/**
|
||||
* 设置 docReview 的列表
|
||||
* Set up a list of docReviews
|
||||
* @param list
|
||||
*/
|
||||
setDocReviewList: (list: Review[]) => void;
|
||||
|
||||
@@ -51,14 +51,14 @@ export type UploadTextStore<T extends number> = UploadTextState<T> &
|
||||
UploadTextAction<T>;
|
||||
|
||||
export interface FilterPageConfig {
|
||||
// 注意页码从 1 开始
|
||||
// Note that page numbers start at 1
|
||||
pageIndex: number;
|
||||
isFilter: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务含义是 crop 框距离四个边缘距离占整个 pdf 尺寸的百分比
|
||||
* 取值 [0, 1] 粒度 0.01
|
||||
* The business implication is the distance between the crop box and the four edges as a percentage of the entire pdf size
|
||||
* Value [0,1] particle size 0.01
|
||||
*/
|
||||
export interface CropperSizePercent {
|
||||
topPercent: number;
|
||||
|
||||
@@ -84,12 +84,12 @@ export const SegmentPreview = (props: ISegmentPreviewProps) => {
|
||||
review => review.review_id === currentReviewID,
|
||||
);
|
||||
const fileType = currentReview?.document_type;
|
||||
// 前端不好展示 docx,需要用后端转换过的 pdf 格式的 url
|
||||
// The front end is not good to display docx, so you need to use the URL in pdf format converted by the back end.
|
||||
const fileUrl = ['docx', 'doc'].includes(fileType ?? '')
|
||||
? (currentReview?.preview_tos_url ?? '')
|
||||
: (currentReview?.tos_url ?? '');
|
||||
const segmentTosUrl = currentReview?.doc_tree_tos_url ?? '';
|
||||
// 切换文档时进行保存 review
|
||||
// Save review when switching documents
|
||||
const { loading: saveLoading, runAsync: saveDocumentReview } = useRequest(
|
||||
async () => {
|
||||
const res = await KnowledgeApi.SaveDocumentReview({
|
||||
|
||||
@@ -46,7 +46,7 @@ export const ImageLocalTaskList: FC<
|
||||
return null;
|
||||
}
|
||||
|
||||
// 实现自己的getImageFileInfo方法
|
||||
// Implement your own getImageFileInfo method
|
||||
const getImageFileInfo = (data: RenderColumnsProps) => {
|
||||
const { record } = data;
|
||||
const curStatus = getProcessStatus(record?.status);
|
||||
|
||||
@@ -45,7 +45,7 @@ export const TableLocalTaskList: FC<
|
||||
return null;
|
||||
}
|
||||
|
||||
// 实现自己的getTableLocalInfo方法
|
||||
// Implement your own getTableLocalInfo method
|
||||
const getTableLocalInfo = (data: RenderColumnsProps) => {
|
||||
const { record } = data;
|
||||
const curStatus = getProcessStatus(record?.status);
|
||||
|
||||
@@ -46,7 +46,7 @@ export const TextLocalTaskList: FC<
|
||||
return null;
|
||||
}
|
||||
|
||||
// 实现自己的getTextLocalInfo方法
|
||||
// Implement your own getTextLocalInfo method
|
||||
const getTextLocalInfo = (data: RenderColumnsProps) => {
|
||||
const { record } = data;
|
||||
const curStatus = getProcessStatus(record?.status);
|
||||
|
||||
@@ -124,7 +124,7 @@ export const useCreateDocument = <
|
||||
}
|
||||
options?.onSuccess && options.onSuccess(res);
|
||||
} catch (e) {
|
||||
// 创建失败,默认渲染处理的数据
|
||||
// Failed to create, default rendering of processed data
|
||||
const error = e as Error;
|
||||
const fakeProgressList = reqParams?.document_bases?.map(item => ({
|
||||
...item,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// !Notice 禁止直接导出 getUploadConfig,各种第三方依赖如 pdf.js 等会被加载到大部分页面的首屏
|
||||
// ! Notice prohibits the direct export of getUploadConfig, various third-party dependencies such as pdf.js will be loaded on the first screen of most pages
|
||||
// export { getUploadConfig } from './config';
|
||||
export {
|
||||
BOT_DATA_REFACTOR_CLASS_NAME,
|
||||
|
||||
@@ -59,7 +59,7 @@ export const KnowledgeResourceProcessorLayout = ({
|
||||
|
||||
const { datasetID, opt, docID, biz } = useKnowledgeParams();
|
||||
|
||||
// 获取知识库详情
|
||||
// Get Knowledge Base Details
|
||||
const { data: dataSetInfo, loading } = useGetKnowledgeListInfo({
|
||||
datasetID: datasetID || '',
|
||||
});
|
||||
@@ -90,7 +90,7 @@ export const KnowledgeResourceProcessorLayout = ({
|
||||
onStatusChange?.('normal');
|
||||
}, [headerTiTle]);
|
||||
|
||||
// TODO:hzf 分化拆分到scenes
|
||||
// TODO: hzf differentiation split into scenes
|
||||
const fromProject = biz === 'project';
|
||||
|
||||
return (
|
||||
|
||||
@@ -33,7 +33,7 @@ export enum UploadMode {
|
||||
Error = 'error',
|
||||
}
|
||||
|
||||
// Select时保存的数据结构
|
||||
// Data Structure Saved When Selecting
|
||||
export interface FileInfo {
|
||||
id: FileId;
|
||||
name?: string;
|
||||
@@ -41,7 +41,7 @@ export interface FileInfo {
|
||||
hasChildren?: boolean;
|
||||
file_type?: string;
|
||||
file_url?: string;
|
||||
// 飞书 Wiki 空间需要使用
|
||||
// Feishu Wiki space is required
|
||||
space_id?: string;
|
||||
obj_token?: string;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* types由于多个位置都会使用,避免循环依赖,故提到最上层
|
||||
* Types Since multiple locations are used to avoid circular dependencies, the top layer is mentioned
|
||||
*/
|
||||
export type {
|
||||
SemanticValidate,
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
export enum ProcessStatus {
|
||||
Processing, // 处理中
|
||||
Complete, // 处理完成
|
||||
Failed, // 处理失败
|
||||
Processing, // Processing
|
||||
Complete, // Processing complete
|
||||
Failed, // Processing failed
|
||||
}
|
||||
export interface ProcessProgressItemProps {
|
||||
className?: string | undefined;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* 本文件放的是 steps/table 下组件相关的 types
|
||||
* This file contains the types related to the components under steps/table
|
||||
*/
|
||||
import type {
|
||||
DocTableColumn,
|
||||
|
||||
@@ -46,6 +46,6 @@ export interface CustomSegmentRule {
|
||||
separator: Seperator;
|
||||
maxTokens: number;
|
||||
preProcessRules: PreProcessRule[];
|
||||
/** 分段重叠度 */
|
||||
/** segmented overlap */
|
||||
overlap: number;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ export const transformUnitList = ({
|
||||
}
|
||||
return unit;
|
||||
});
|
||||
// TODO as 待解
|
||||
// TODO as to be solved
|
||||
return filteredList as UnitItem[];
|
||||
};
|
||||
|
||||
@@ -111,8 +111,8 @@ export function useOptFromQuery(): OptType {
|
||||
return opt;
|
||||
}
|
||||
|
||||
/** 为什么返回undefined? 不一定需要空字符串,如果取不到就返回undefined */
|
||||
/**现在还有 docID 这个入口吗??? */
|
||||
/** Why return undefined? You don't necessarily need an empty string. If you can't get it, return undefined. */
|
||||
/**Is there still an entrance for docID??? */
|
||||
export function useDocIdFromQuery(): string | undefined {
|
||||
const query = useKnowledgeParams();
|
||||
return get(query, 'docID', undefined);
|
||||
|
||||
@@ -18,9 +18,9 @@ import { type Dataset, StorageLocation } from '@coze-arch/idl/knowledge';
|
||||
|
||||
export function getStorageStrategyEnabled(dataset?: Dataset) {
|
||||
return (
|
||||
// 云搜索只在国内环境上线
|
||||
// Cloud search is only available in the domestic environment
|
||||
IS_CN_REGION &&
|
||||
// 只有知识库首次上传,才可以配置云搜索
|
||||
// Cloud search can only be configured if the knowledge base is uploaded for the first time.
|
||||
dataset?.doc_count === 0 &&
|
||||
dataset?.storage_location === StorageLocation.Default
|
||||
);
|
||||
|
||||
@@ -30,9 +30,9 @@ export const getSortedFilterPages = (filterPagesConfig: FilterPageConfig[]) =>
|
||||
export const getFilterPagesString = (pages: number[]) => pages.join(' / ');
|
||||
|
||||
/**
|
||||
* 渲染为形如下方例子的内容:
|
||||
* 论文 1:过滤第 2 / 4 / 6 页;设置了页面局部过滤
|
||||
* 论文 2:过滤第 1 页...
|
||||
* Render as the following example:
|
||||
* Paper 1: Filter page 2/4/6; set page local filtering
|
||||
* Paper 2: Filtering Page 1...
|
||||
*/
|
||||
export const renderDocumentFilterValue = ({
|
||||
filterValue,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** 此文件放的是 table 通用 utils */
|
||||
/** This file contains table utils */
|
||||
import { get } from 'lodash-es';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
@@ -44,7 +44,7 @@ export interface IValidateRes {
|
||||
valid: boolean;
|
||||
errorMsg: string;
|
||||
}
|
||||
// 校验tableStructure列名及表明是否包含特殊字符
|
||||
// Verify tableStructure column names and indicate whether they contain special characters
|
||||
export const validateField = (
|
||||
fieldName: string,
|
||||
emptyMsg = '',
|
||||
@@ -52,7 +52,7 @@ export const validateField = (
|
||||
let valid = true;
|
||||
let errorMsg = '';
|
||||
|
||||
// 是否包含特殊字符-->单引号,双引号,转义符,反引号
|
||||
// Whether it contains special characters -- > single quotes, double quotes, escape characters, backquotes
|
||||
const notationReg = /["'`\\]+/g;
|
||||
|
||||
if (!fieldName) {
|
||||
@@ -66,7 +66,7 @@ export const validateField = (
|
||||
valid = false;
|
||||
errorMsg = I18n.t('knowledge_tableStructure_field_errLegally');
|
||||
}
|
||||
// 不能包含_knowledge_slice_id关键字
|
||||
// Cannot contain _knowledge_slice_id keywords
|
||||
if (['_knowledge_slice_id'].includes(fieldName)) {
|
||||
valid = false;
|
||||
errorMsg = I18n.t('knowledge_tableStructure_errSystemField');
|
||||
@@ -81,10 +81,10 @@ export const getSrcFromImg = (str: string): string[] => {
|
||||
return [];
|
||||
}
|
||||
const imgRegx = /<img[^>]+src\s*=\s*['"]([^'"]+)['"][^>]*>/g;
|
||||
// 使用正则表达式进行匹配
|
||||
// Matching using regular expressions
|
||||
const matches = str.match(imgRegx);
|
||||
|
||||
// 提取匹配结果中的src属性值
|
||||
// Extract the value of the src attribute from the matching result
|
||||
const srcList: string[] = [];
|
||||
if (matches) {
|
||||
for (let i = 0; i < matches.length; i++) {
|
||||
|
||||
Reference in New Issue
Block a user