diff --git a/miniapp/src/api/knowledge.ts b/miniapp/src/api/knowledge.ts
index 4994b84..ec06440 100644
--- a/miniapp/src/api/knowledge.ts
+++ b/miniapp/src/api/knowledge.ts
@@ -16,6 +16,7 @@ export interface Disease {
recurrence?: string;
detection?: string;
prevention?: string;
+ imageUrl?: string;
sortOrder?: number;
}
diff --git a/miniapp/src/pages/knowledge/detail/index.module.scss b/miniapp/src/pages/knowledge/detail/index.module.scss
index 1614ee4..0ce213a 100644
--- a/miniapp/src/pages/knowledge/detail/index.module.scss
+++ b/miniapp/src/pages/knowledge/detail/index.module.scss
@@ -39,6 +39,19 @@
padding: $spacing-lg;
}
+.imageCard {
+ margin: $spacing-lg $spacing-lg 0;
+ background: $color-bg-card;
+ border-radius: $radius-md;
+ padding: $spacing-md;
+ box-shadow: $shadow-card;
+}
+
+.symptomImage {
+ width: 100%;
+ border-radius: $radius-sm;
+}
+
.sectionCard {
background: $color-bg-card;
border-radius: $radius-md;
diff --git a/miniapp/src/pages/knowledge/detail/index.tsx b/miniapp/src/pages/knowledge/detail/index.tsx
index a32317a..008f889 100644
--- a/miniapp/src/pages/knowledge/detail/index.tsx
+++ b/miniapp/src/pages/knowledge/detail/index.tsx
@@ -1,5 +1,5 @@
import React, { useCallback, useEffect, useState } from 'react';
-import { ScrollView, Text, View } from '@tarojs/components';
+import { Image, ScrollView, Text, View } from '@tarojs/components';
import Taro, { useRouter } from '@tarojs/taro';
import styles from './index.module.scss';
import {
@@ -86,6 +86,11 @@ const DetailPage: React.FC = () => {
{disease.name}
{CATEGORY_LABELS[disease.category] || disease.category}
+ {disease.imageUrl ? (
+
+
+
+ ) : null}
{sections.map((s) => (
diff --git a/miniapp/src/types/index.ts b/miniapp/src/types/index.ts
index 5ffc0b3..f580ab8 100644
--- a/miniapp/src/types/index.ts
+++ b/miniapp/src/types/index.ts
@@ -196,6 +196,7 @@ export interface Disease {
recurrence?: string;
detection?: string;
prevention?: string;
+ imageUrl?: string;
sortOrder?: number;
}
diff --git a/web/src/dal/knowledge.ts b/web/src/dal/knowledge.ts
index 9a589df..f690d5a 100644
--- a/web/src/dal/knowledge.ts
+++ b/web/src/dal/knowledge.ts
@@ -45,3 +45,9 @@ export const listArticles = (params?: any) => get('/knowledg
export const createArticle = (data: Partial) => post('/knowledge/articles', data);
export const updateArticle = (id: string, data: Partial) => patch(`/knowledge/articles/${id}`, data);
export const deleteArticle = (id: string) => del(`/knowledge/articles/${id}`);
+
+export const uploadKnowledgeImage = (file: File) => {
+ const fd = new FormData();
+ fd.append('file', file);
+ return post<{ url: string; name: string; size: number }>('/knowledge/images', fd);
+};
diff --git a/web/src/pages/Knowledge.tsx b/web/src/pages/Knowledge.tsx
index ca9f16d..b49b03a 100644
--- a/web/src/pages/Knowledge.tsx
+++ b/web/src/pages/Knowledge.tsx
@@ -1,5 +1,6 @@
import { useRef, useState } from 'react';
-import { Button, Form, Input, InputNumber, Modal, Popconfirm, Select, Switch, Tabs, Tag, message } from 'antd';
+import { Button, Form, Input, InputNumber, Modal, Popconfirm, Select, Switch, Tabs, Tag, Upload, message } from 'antd';
+import type { UploadFile } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { ProTable, type ActionType, type ProColumns } from '@ant-design/pro-components';
import {
@@ -11,6 +12,7 @@ import {
createArticle,
updateArticle,
deleteArticle,
+ uploadKnowledgeImage,
type Disease,
type KnowledgeArticle,
} from '../dal/knowledge';
@@ -38,6 +40,7 @@ function DiseaseTab() {
const [modalOpen, setModalOpen] = useState(false);
const [form] = Form.useForm>();
const [editing, setEditing] = useState(null);
+ const [imageList, setImageList] = useState([]);
const columns: ProColumns[] = [
{ title: '序号', valueType: 'indexBorder', search: false, width: 60 },
@@ -69,6 +72,9 @@ function DiseaseTab() {
onClick={() => {
setEditing(r);
form.setFieldsValue(r);
+ setImageList(
+ r.imageUrl ? [{ uid: '-1', name: '症状图谱', status: 'done', url: r.imageUrl }] : [],
+ );
setModalOpen(true);
}}
>
@@ -97,6 +103,7 @@ function DiseaseTab() {
setEditing(null);
form.resetFields();
form.setFieldsValue({ category: 'viral', enabled: true, sortOrder: 0 });
+ setImageList([]);
setModalOpen(true);
};
@@ -147,6 +154,35 @@ function DiseaseTab() {
options={Object.entries(CATEGORY_LABELS).map(([value, label]) => ({ value, label }))}
/>
+
+ {
+ try {
+ const res = await uploadKnowledgeImage(file as File);
+ form.setFieldValue('imageUrl', res.url);
+ setImageList([{ uid: '-1', name: res.name, status: 'done', url: res.url }]);
+ onSuccess?.(res);
+ } catch (e) {
+ onError?.(e as Error);
+ }
+ }}
+ onRemove={() => {
+ setImageList([]);
+ form.setFieldValue('imageUrl', undefined);
+ }}
+ >
+ {imageList.length >= 1 ? null : (
+
+ )}
+
+