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 : ( +
+ +
上传图谱
+
+ )} +
+