Skip to content

Commit c0ddc15

Browse files
authored
feat(auto-annotation): sync tags and timestamps to datasets and optimize visibility (#271)
- Sync auto-annotation tag and tag_created_time to both dataset and annotation result dataset - Add automatic annotation indicators for annotated data - Hide auto-annotation related fields for non-annotated data
1 parent cf8d12b commit c0ddc15

File tree

5 files changed

+314
-103
lines changed

5 files changed

+314
-103
lines changed

backend/services/data-management-service/src/main/java/com/datamate/datamanagement/domain/model/dataset/DatasetFile.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class DatasetFile {
3232
private Long fileSize; // bytes
3333
private String checkSum;
3434
private String tags;
35+
private LocalDateTime tagsUpdatedAt;
3536
private String metadata;
3637
private String status; // UPLOADED, PROCESSING, COMPLETED, ERROR
3738
private LocalDateTime uploadTime;

backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/DatasetFileResponse.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ public class DatasetFileResponse {
2727
private String description;
2828
/** 文件路径 */
2929
private String filePath;
30+
/** 文件标签(JSON 字符串) */
31+
private String tags;
32+
/** 标签更新时间 */
33+
private LocalDateTime tagsUpdatedAt;
3034
/** 上传时间 */
3135
private LocalDateTime uploadTime;
3236
/** 最后更新时间 */
Lines changed: 98 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,98 @@
1-
<?xml version="1.0" encoding="UTF-8"?>
2-
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
3-
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
4-
<mapper namespace="com.datamate.datamanagement.infrastructure.persistence.mapper.DatasetFileMapper">
5-
<sql id="Base_Column_List">
6-
id, dataset_id, file_name, file_path, file_type, file_size, check_sum, tags, metadata, status,
7-
upload_time, last_access_time, created_at, updated_at
8-
</sql>
9-
10-
<select id="findById" parameterType="string"
11-
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
12-
SELECT <include refid="Base_Column_List"/>
13-
FROM t_dm_dataset_files
14-
WHERE id = #{id}
15-
</select>
16-
17-
<select id="findByDatasetId" parameterType="string"
18-
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
19-
SELECT <include refid="Base_Column_List"/>
20-
FROM t_dm_dataset_files
21-
WHERE dataset_id = #{datasetId}
22-
ORDER BY upload_time DESC
23-
</select>
24-
25-
<select id="findByDatasetIdAndStatus" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
26-
SELECT <include refid="Base_Column_List"/>
27-
FROM t_dm_dataset_files
28-
WHERE dataset_id = #{datasetId}
29-
AND status = #{status}
30-
ORDER BY upload_time DESC
31-
</select>
32-
33-
<select id="findByDatasetIdAndFileType" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
34-
SELECT <include refid="Base_Column_List"/>
35-
FROM t_dm_dataset_files
36-
WHERE dataset_id = #{datasetId}
37-
AND file_type = #{fileType}
38-
ORDER BY upload_time DESC
39-
</select>
40-
41-
<select id="countByDatasetId" parameterType="string" resultType="long">
42-
SELECT COUNT(*) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId}
43-
</select>
44-
45-
<select id="countCompletedByDatasetId" parameterType="string" resultType="long">
46-
SELECT COUNT(*) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId} AND status = 'COMPLETED'
47-
</select>
48-
49-
<select id="sumSizeByDatasetId" parameterType="string" resultType="long">
50-
SELECT COALESCE(SUM(file_size), 0) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId}
51-
</select>
52-
53-
<select id="findByDatasetIdAndFileName" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
54-
SELECT <include refid="Base_Column_List"/>
55-
FROM t_dm_dataset_files
56-
WHERE dataset_id = #{datasetId} AND file_name = #{fileName}
57-
LIMIT 1
58-
</select>
59-
60-
<select id="findAllByDatasetId" parameterType="string"
61-
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
62-
SELECT <include refid="Base_Column_List"/>
63-
FROM t_dm_dataset_files
64-
WHERE dataset_id = #{datasetId}
65-
ORDER BY upload_time DESC
66-
</select>
67-
68-
<select id="findByCriteria" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
69-
SELECT <include refid="Base_Column_List"/>
70-
FROM t_dm_dataset_files
71-
WHERE dataset_id = #{datasetId}
72-
<!-- Replace invalid XML '&&' with 'and' for MyBatis OGNL -->
73-
<if test="fileType != null and fileType != ''">
74-
AND file_type = #{fileType}
75-
</if>
76-
<if test="status != null and status != ''">
77-
AND status = #{status}
78-
</if>
79-
ORDER BY upload_time DESC
80-
</select>
81-
82-
83-
<update id="update" parameterType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
84-
UPDATE t_dm_dataset_files
85-
SET file_name = #{fileName},
86-
file_path = #{filePath},
87-
file_type = #{fileType},
88-
file_size = #{fileSize},
89-
upload_time = #{uploadTime},
90-
last_access_time = #{lastAccessTime},
91-
status = #{status}
92-
WHERE id = #{id}
93-
</update>
94-
95-
<delete id="deleteById" parameterType="string">
96-
DELETE FROM t_dm_dataset_files WHERE id = #{id}
97-
</delete>
98-
</mapper>
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
3+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
4+
<mapper namespace="com.datamate.datamanagement.infrastructure.persistence.mapper.DatasetFileMapper">
5+
<sql id="Base_Column_List">
6+
id, dataset_id, file_name, file_path, file_type, file_size, check_sum, tags, tags_updated_at, metadata, status,
7+
upload_time, last_access_time, created_at, updated_at
8+
</sql>
9+
10+
<select id="findById" parameterType="string"
11+
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
12+
SELECT <include refid="Base_Column_List"/>
13+
FROM t_dm_dataset_files
14+
WHERE id = #{id}
15+
</select>
16+
17+
<select id="findByDatasetId" parameterType="string"
18+
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
19+
SELECT <include refid="Base_Column_List"/>
20+
FROM t_dm_dataset_files
21+
WHERE dataset_id = #{datasetId}
22+
ORDER BY upload_time DESC
23+
</select>
24+
25+
<select id="findByDatasetIdAndStatus" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
26+
SELECT <include refid="Base_Column_List"/>
27+
FROM t_dm_dataset_files
28+
WHERE dataset_id = #{datasetId}
29+
AND status = #{status}
30+
ORDER BY upload_time DESC
31+
</select>
32+
33+
<select id="findByDatasetIdAndFileType" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
34+
SELECT <include refid="Base_Column_List"/>
35+
FROM t_dm_dataset_files
36+
WHERE dataset_id = #{datasetId}
37+
AND file_type = #{fileType}
38+
ORDER BY upload_time DESC
39+
</select>
40+
41+
<select id="countByDatasetId" parameterType="string" resultType="long">
42+
SELECT COUNT(*) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId}
43+
</select>
44+
45+
<select id="countCompletedByDatasetId" parameterType="string" resultType="long">
46+
SELECT COUNT(*) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId} AND status = 'COMPLETED'
47+
</select>
48+
49+
<select id="sumSizeByDatasetId" parameterType="string" resultType="long">
50+
SELECT COALESCE(SUM(file_size), 0) FROM t_dm_dataset_files WHERE dataset_id = #{datasetId}
51+
</select>
52+
53+
<select id="findByDatasetIdAndFileName" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
54+
SELECT <include refid="Base_Column_List"/>
55+
FROM t_dm_dataset_files
56+
WHERE dataset_id = #{datasetId} AND file_name = #{fileName}
57+
LIMIT 1
58+
</select>
59+
60+
<select id="findAllByDatasetId" parameterType="string"
61+
resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
62+
SELECT <include refid="Base_Column_List"/>
63+
FROM t_dm_dataset_files
64+
WHERE dataset_id = #{datasetId}
65+
ORDER BY upload_time DESC
66+
</select>
67+
68+
<select id="findByCriteria" resultType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
69+
SELECT <include refid="Base_Column_List"/>
70+
FROM t_dm_dataset_files
71+
WHERE dataset_id = #{datasetId}
72+
<!-- Replace invalid XML '&&' with 'and' for MyBatis OGNL -->
73+
<if test="fileType != null and fileType != ''">
74+
AND file_type = #{fileType}
75+
</if>
76+
<if test="status != null and status != ''">
77+
AND status = #{status}
78+
</if>
79+
ORDER BY upload_time DESC
80+
</select>
81+
82+
83+
<update id="update" parameterType="com.datamate.datamanagement.domain.model.dataset.DatasetFile">
84+
UPDATE t_dm_dataset_files
85+
SET file_name = #{fileName},
86+
file_path = #{filePath},
87+
file_type = #{fileType},
88+
file_size = #{fileSize},
89+
upload_time = #{uploadTime},
90+
last_access_time = #{lastAccessTime},
91+
status = #{status}
92+
WHERE id = #{id}
93+
</update>
94+
95+
<delete id="deleteById" parameterType="string">
96+
DELETE FROM t_dm_dataset_files WHERE id = #{id}
97+
</delete>
98+
</mapper>

frontend/src/pages/DataManagement/Detail/components/Overview.tsx

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,64 @@ export default function Overview({ dataset, filesOperation, fetchDataset }) {
189189
width: 200,
190190
render: (text) => formatDateTime(text),
191191
},
192+
{
193+
title: "标签",
194+
dataIndex: "tags",
195+
key: "tags",
196+
width: 220,
197+
render: (value: any, record: any) => {
198+
const isDirectory = typeof record.id === "string" && record.id.startsWith("directory-");
199+
if (isDirectory) return "-";
200+
201+
let raw = value;
202+
if (!raw) return "-";
203+
204+
// 后端目前将 tags 作为 JSON 字符串存储在 t_dm_dataset_files.tags 中
205+
// 这里尝试解析为 FileTag 数组结构 [{ type, from_name, values: { [type]: [...] } }]
206+
if (typeof raw === "string") {
207+
try {
208+
raw = JSON.parse(raw);
209+
} catch {
210+
// 解析失败则直接展示原始字符串
211+
return raw;
212+
}
213+
}
214+
215+
if (!Array.isArray(raw) || raw.length === 0) return "-";
216+
217+
const labels: string[] = [];
218+
raw.forEach((tag: any) => {
219+
const type = tag?.type;
220+
const valuesObj = tag?.values || {};
221+
const tagValues = (type && valuesObj[type]) || [];
222+
223+
if (Array.isArray(tagValues)) {
224+
tagValues.forEach((item) => {
225+
if (typeof item === "string" && !labels.includes(item)) {
226+
labels.push(item);
227+
}
228+
});
229+
} else if (typeof tagValues === "string" && !labels.includes(tagValues)) {
230+
labels.push(tagValues);
231+
}
232+
});
233+
234+
if (!labels.length) return "-";
235+
return labels.join(", ");
236+
},
237+
},
238+
{
239+
title: "标签更新时间",
240+
dataIndex: "tagsUpdatedAt",
241+
key: "tagsUpdatedAt",
242+
width: 200,
243+
render: (text: any, record: any) => {
244+
const isDirectory = typeof record.id === "string" && record.id.startsWith("directory-");
245+
if (isDirectory) return "-";
246+
if (!text) return "-";
247+
return formatDateTime(text);
248+
},
249+
},
192250
{
193251
title: "操作",
194252
key: "action",
@@ -528,6 +586,53 @@ export default function Overview({ dataset, filesOperation, fetchDataset }) {
528586
<span>{previewFileDetail.status}</span>
529587
</div>
530588
)}
589+
{previewFileDetail?.tags && (
590+
<div>
591+
<span className="text-gray-500">标签:</span>
592+
<span>
593+
{(() => {
594+
let raw = previewFileDetail.tags as any;
595+
if (!raw) return "-";
596+
597+
if (typeof raw === "string") {
598+
try {
599+
raw = JSON.parse(raw);
600+
} catch {
601+
return raw;
602+
}
603+
}
604+
605+
if (!Array.isArray(raw) || raw.length === 0) return "-";
606+
607+
const labels: string[] = [];
608+
raw.forEach((tag: any) => {
609+
const type = tag?.type;
610+
const valuesObj = tag?.values || {};
611+
const tagValues = (type && valuesObj[type]) || [];
612+
613+
if (Array.isArray(tagValues)) {
614+
tagValues.forEach((item) => {
615+
if (typeof item === "string" && !labels.includes(item)) {
616+
labels.push(item);
617+
}
618+
});
619+
} else if (typeof tagValues === "string" && !labels.includes(tagValues)) {
620+
labels.push(tagValues);
621+
}
622+
});
623+
624+
if (!labels.length) return "-";
625+
return labels.join(", ");
626+
})()}
627+
</span>
628+
</div>
629+
)}
630+
{previewFileDetail?.tagsUpdatedAt && (
631+
<div>
632+
<span className="text-gray-500">标签更新时间:</span>
633+
<span>{formatDateTime(previewFileDetail.tagsUpdatedAt)}</span>
634+
</div>
635+
)}
531636
{previewFileDetail?.uploadTime && (
532637
<div>
533638
<span className="text-gray-500">上传时间:</span>

0 commit comments

Comments
 (0)