Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class DatasetFile {
private Long fileSize; // bytes
private String checkSum;
private String tags;
private LocalDateTime tagsUpdatedAt;
private String metadata;
private String status; // UPLOADED, PROCESSING, COMPLETED, ERROR
private LocalDateTime uploadTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public class DatasetFileResponse {
private String description;
/** 文件路径 */
private String filePath;
/** 文件标签(JSON 字符串) */
private String tags;
/** 标签更新时间 */
private LocalDateTime tagsUpdatedAt;
/** 上传时间 */
private LocalDateTime uploadTime;
/** 最后更新时间 */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,98 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.datamate.datamanagement.infrastructure.persistence.mapper.DatasetFileMapper">
<sql id="Base_Column_List">
id, dataset_id, file_name, file_path, file_type, file_size, check_sum, tags, metadata, status,
upload_time, last_access_time, created_at, updated_at
</sql>

<select id="findById" parameterType="string"
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE id = #{id}
</select>

<select id="findByDatasetId" parameterType="string"
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId}
ORDER BY upload_time DESC
</select>

<select id="findByDatasetIdAndStatus" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId}
AND status = #{status}
ORDER BY upload_time DESC
</select>

<select id="findByDatasetIdAndFileType" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId}
AND file_type = #{fileType}
ORDER BY upload_time DESC
</select>

<select id="countByDatasetId" parameterType="string" resultType="long">
SELECT COUNT(*) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId}
</select>

<select id="countCompletedByDatasetId" parameterType="string" resultType="long">
SELECT COUNT(*) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId} AND status = 'COMPLETED'
</select>

<select id="sumSizeByDatasetId" parameterType="string" resultType="long">
SELECT COALESCE(SUM(file_size), 0) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId}
</select>

<select id="findByDatasetIdAndFileName" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId} AND file_name = #{fileName}
LIMIT 1
</select>

<select id="findAllByDatasetId" parameterType="string"
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId}
ORDER BY upload_time DESC
</select>

<select id="findByCriteria" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId}
<!-- Replace invalid XML '&&' with 'and' for MyBatis OGNL -->
<if test="fileType != null and fileType != ''">
AND file_type = #{fileType}
</if>
<if test="status != null and status != ''">
AND status = #{status}
</if>
ORDER BY upload_time DESC
</select>


<update id="update" parameterType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
UPDATE t_dm_dataset_files
SET file_name = #{fileName},
file_path = #{filePath},
file_type = #{fileType},
file_size = #{fileSize},
upload_time = #{uploadTime},
last_access_time = #{lastAccessTime},
status = #{status}
WHERE id = #{id}
</update>

<delete id="deleteById" parameterType="string">
DELETE FROM t_dm_dataset_files WHERE id = #{id}
</delete>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.datamate.datamanagement.infrastructure.persistence.mapper.DatasetFileMapper">
<sql id="Base_Column_List">
id, dataset_id, file_name, file_path, file_type, file_size, check_sum, tags, tags_updated_at, metadata, status,
upload_time, last_access_time, created_at, updated_at
</sql>
<select id="findById" parameterType="string"
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE id = #{id}
</select>
<select id="findByDatasetId" parameterType="string"
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId}
ORDER BY upload_time DESC
</select>
<select id="findByDatasetIdAndStatus" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId}
AND status = #{status}
ORDER BY upload_time DESC
</select>
<select id="findByDatasetIdAndFileType" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId}
AND file_type = #{fileType}
ORDER BY upload_time DESC
</select>
<select id="countByDatasetId" parameterType="string" resultType="long">
SELECT COUNT(*) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId}
</select>
<select id="countCompletedByDatasetId" parameterType="string" resultType="long">
SELECT COUNT(*) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId} AND status = 'COMPLETED'
</select>
<select id="sumSizeByDatasetId" parameterType="string" resultType="long">
SELECT COALESCE(SUM(file_size), 0) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId}
</select>
<select id="findByDatasetIdAndFileName" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId} AND file_name = #{fileName}
LIMIT 1
</select>
<select id="findAllByDatasetId" parameterType="string"
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId}
ORDER BY upload_time DESC
</select>
<select id="findByCriteria" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
SELECT <include refid="Base_Column_List"/>
FROM t_dm_dataset_files
WHERE dataset_id = #{datasetId}
<!-- Replace invalid XML '&&' with 'and' for MyBatis OGNL -->
<if test="fileType != null and fileType != ''">
AND file_type = #{fileType}
</if>
<if test="status != null and status != ''">
AND status = #{status}
</if>
ORDER BY upload_time DESC
</select>
<update id="update" parameterType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
UPDATE t_dm_dataset_files
SET file_name = #{fileName},
file_path = #{filePath},
file_type = #{fileType},
file_size = #{fileSize},
upload_time = #{uploadTime},
last_access_time = #{lastAccessTime},
status = #{status}
WHERE id = #{id}
</update>
<delete id="deleteById" parameterType="string">
DELETE FROM t_dm_dataset_files WHERE id = #{id}
</delete>
</mapper>
105 changes: 105 additions & 0 deletions frontend/src/pages/DataManagement/Detail/components/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,64 @@ export default function Overview({ dataset, filesOperation, fetchDataset }) {
width: 200,
render: (text) => formatDateTime(text),
},
{
title: "标签",
dataIndex: "tags",
key: "tags",
width: 220,
render: (value: any, record: any) => {
const isDirectory = typeof record.id === "string" && record.id.startsWith("directory-");
if (isDirectory) return "-";

let raw = value;
if (!raw) return "-";

// 后端目前将 tags 作为 JSON 字符串存储在 t_dm_dataset_files.tags 中
// 这里尝试解析为 FileTag 数组结构 [{ type, from_name, values: { [type]: [...] } }]
if (typeof raw === "string") {
try {
raw = JSON.parse(raw);
} catch {
// 解析失败则直接展示原始字符串
return raw;
}
}

if (!Array.isArray(raw) || raw.length === 0) return "-";

const labels: string[] = [];
raw.forEach((tag: any) => {
const type = tag?.type;
const valuesObj = tag?.values || {};
const tagValues = (type && valuesObj[type]) || [];

if (Array.isArray(tagValues)) {
tagValues.forEach((item) => {
if (typeof item === "string" && !labels.includes(item)) {
labels.push(item);
}
});
} else if (typeof tagValues === "string" && !labels.includes(tagValues)) {
labels.push(tagValues);
}
});

if (!labels.length) return "-";
return labels.join(", ");
},
},
{
title: "标签更新时间",
dataIndex: "tagsUpdatedAt",
key: "tagsUpdatedAt",
width: 200,
render: (text: any, record: any) => {
const isDirectory = typeof record.id === "string" && record.id.startsWith("directory-");
if (isDirectory) return "-";
if (!text) return "-";
return formatDateTime(text);
},
},
{
title: "操作",
key: "action",
Expand Down Expand Up @@ -528,6 +586,53 @@ export default function Overview({ dataset, filesOperation, fetchDataset }) {
<span>{previewFileDetail.status}</span>
</div>
)}
{previewFileDetail?.tags && (
<div>
<span className="text-gray-500">标签:</span>
<span>
{(() => {
let raw = previewFileDetail.tags as any;
if (!raw) return "-";

if (typeof raw === "string") {
try {
raw = JSON.parse(raw);
} catch {
return raw;
}
}

if (!Array.isArray(raw) || raw.length === 0) return "-";

const labels: string[] = [];
raw.forEach((tag: any) => {
const type = tag?.type;
const valuesObj = tag?.values || {};
const tagValues = (type && valuesObj[type]) || [];

if (Array.isArray(tagValues)) {
tagValues.forEach((item) => {
if (typeof item === "string" && !labels.includes(item)) {
labels.push(item);
}
});
} else if (typeof tagValues === "string" && !labels.includes(tagValues)) {
labels.push(tagValues);
}
});

if (!labels.length) return "-";
return labels.join(", ");
})()}
</span>
</div>
)}
{previewFileDetail?.tagsUpdatedAt && (
<div>
<span className="text-gray-500">标签更新时间:</span>
<span>{formatDateTime(previewFileDetail.tagsUpdatedAt)}</span>
</div>
)}
{previewFileDetail?.uploadTime && (
<div>
<span className="text-gray-500">上传时间:</span>
Expand Down
Loading
Loading