Просмотр исходного кода

:construction: create all router of wikipali

visuddhinanda 3 лет назад
Родитель
Сommit
3b30a66a11
49 измененных файлов с 1344 добавлено и 106 удалено
  1. 91 20
      dashboard/src/Router.tsx
  2. 33 0
      dashboard/src/components/blog/HeadBar.tsx
  3. 26 0
      dashboard/src/components/library/Footer.tsx
  4. 36 0
      dashboard/src/components/library/HeadBar.tsx
  5. 0 5
      dashboard/src/components/nut/library/Footer.tsx
  6. 0 5
      dashboard/src/components/nut/library/HeadBar.tsx
  7. 0 5
      dashboard/src/components/nut/studio/HeadBar.tsx
  8. 0 5
      dashboard/src/components/nut/studio/LeftSider.tsx
  9. 0 0
      dashboard/src/components/studio/Footer.tsx
  10. 15 0
      dashboard/src/components/studio/HeadBar.tsx
  11. 56 0
      dashboard/src/components/studio/LeftSider.tsx
  12. 3 3
      dashboard/src/locales/zh-Hans/channel/index.ts
  13. 16 0
      dashboard/src/locales/zh-Hans/dict/index.ts
  14. 19 1
      dashboard/src/locales/zh-Hans/index.ts
  15. 0 22
      dashboard/src/pages/community/index.tsx
  16. 23 0
      dashboard/src/pages/library/anthology/article.tsx
  17. 24 0
      dashboard/src/pages/library/anthology/index.tsx
  18. 22 0
      dashboard/src/pages/library/anthology/show.tsx
  19. 23 0
      dashboard/src/pages/library/blog/anthology.tsx
  20. 22 0
      dashboard/src/pages/library/blog/course.tsx
  21. 23 0
      dashboard/src/pages/library/blog/index.tsx
  22. 22 0
      dashboard/src/pages/library/blog/term.tsx
  23. 23 0
      dashboard/src/pages/library/blog/translation.tsx
  24. 19 0
      dashboard/src/pages/library/community/index.tsx
  25. 0 0
      dashboard/src/pages/library/community/recent.tsx
  26. 23 0
      dashboard/src/pages/library/course/course.tsx
  27. 23 0
      dashboard/src/pages/library/course/index.tsx
  28. 22 0
      dashboard/src/pages/library/course/lesson.tsx
  29. 19 0
      dashboard/src/pages/library/dict/index.tsx
  30. 22 0
      dashboard/src/pages/library/dict/show.tsx
  31. 19 0
      dashboard/src/pages/library/palicanon/index.tsx
  32. 22 0
      dashboard/src/pages/library/term/show.tsx
  33. 11 1
      dashboard/src/pages/nut/index.tsx
  34. 26 0
      dashboard/src/pages/studio/analysis/index.tsx
  35. 23 0
      dashboard/src/pages/studio/anthology/edit.tsx
  36. 27 0
      dashboard/src/pages/studio/anthology/index.tsx
  37. 23 0
      dashboard/src/pages/studio/article/edit.tsx
  38. 27 0
      dashboard/src/pages/studio/article/index.tsx
  39. 3 3
      dashboard/src/pages/studio/channel/create.tsx
  40. 10 11
      dashboard/src/pages/studio/channel/edit.tsx
  41. 13 12
      dashboard/src/pages/studio/channel/index.tsx
  42. 166 0
      dashboard/src/pages/studio/dict/index.tsx
  43. 83 0
      dashboard/src/pages/studio/group/edit.tsx
  44. 29 0
      dashboard/src/pages/studio/group/index.tsx
  45. 25 0
      dashboard/src/pages/studio/group/show.tsx
  46. 13 13
      dashboard/src/pages/studio/index.tsx
  47. 26 0
      dashboard/src/pages/studio/palicanon/index.tsx
  48. 26 0
      dashboard/src/pages/studio/recent/index.tsx
  49. 167 0
      dashboard/src/pages/studio/term/index.tsx

+ 91 - 20
dashboard/src/Router.tsx

@@ -16,12 +16,49 @@ import NutForbidden from "./pages/nut/forbidden";
 import NutNotFound from "./pages/nut/not-found";
 import NutSwitchLanguage from "./pages/nut/switch-languages";
 import NutHome from "./pages/nut";
-import NutCommunity from "./pages/community";
-import NutCommunityRecent from "./pages/community/recent";
-//import NutStudio from "./pages/studio";
-import NutStudioChannel from "./pages/studio/channel";
-import NutStudioChannelCreate from "./pages/studio/channel/create";
-import NutStudioChannelEdit from "./pages/studio/channel/edit";
+
+import LibraryCommunity from "./pages/library/community";
+import LibraryCommunityRecent from "./pages/library/community/recent";
+import LibraryPalicanon from "./pages/library/palicanon";
+import LibraryCourse from "./pages/library/course";
+import LibraryCourseShow from "./pages/library/course/course";
+import LibraryLessonShow from "./pages/library/course/lesson";
+import LibraryTerm from "./pages/library/term/show";
+import LibraryDict from "./pages/library/dict";
+import LibraryDictShow from "./pages/library/dict/show";
+import LibraryAnthology from "./pages/library/anthology";
+import LibraryAnthologyShow from "./pages/library/anthology/show";
+import LibraryArticle from "./pages/library/anthology/article";
+
+import LibraryBlog from "./pages/library/blog";
+import LibraryBlogTranslation from "./pages/library/blog/translation";
+import LibraryBlogCourse from "./pages/library/blog/course";
+import LibraryBlogAnthology from "./pages/library/blog/anthology";
+import LibraryBlogTerm from "./pages/library/blog/term";
+
+import StudioHome from "./pages/studio";
+
+import StudioPalicanon from "./pages/studio/palicanon";
+import StudioRecent from "./pages/studio/recent";
+
+import StudioChannel from "./pages/studio/channel";
+import StudioChannelCreate from "./pages/studio/channel/create";
+import StudioChannelEdit from "./pages/studio/channel/edit";
+
+import StudioGroup from "./pages/studio/group";
+import StudioGroupEdit from "./pages/studio/group/edit";
+import StudioGroupShow from "./pages/studio/group/show";
+
+import StudioDict from "./pages/studio/dict";
+import StudioTerm from "./pages/studio/term";
+
+import StudioArticle from "./pages/studio/article";
+import StudioArticleEdit from "./pages/studio/article/edit";
+
+import StudioAnthology from "./pages/studio/anthology";
+import StudioAnthologyEdit from "./pages/studio/anthology/edit";
+
+import StudioAnalysis from "./pages/studio/analysis";
 
 const Widget = () => {
   return (
@@ -35,10 +72,7 @@ const Widget = () => {
             <Route path="new" element={<NutUsersUnlockNew />} />
             <Route path="verify/:token" element={<NutUsersUnlockVerify />} />
           </Route>
-          <Route
-            path="reset-password/:token"
-            element={<NutUsersResetPassword />}
-          />
+          <Route path="reset-password/:token" element={<NutUsersResetPassword />} />
           <Route path="forgot-password" element={<NutUsersForgotPassword />} />
         </Route>
       </Route>
@@ -54,16 +88,53 @@ const Widget = () => {
       <Route path="forbidden" element={<NutForbidden />} />
       <Route path="" element={<NutHome />} />
       <Route path="*" element={<NutNotFound />} />
-	  <Route path="community" element={<NutCommunity />}>
-		<Route path="myread" element={<NutCommunityRecent />}></Route>
-	  </Route>
-	  <Route path="studio/:studioid" >
-	  	<Route path="channel" element={<NutStudioChannel />}>
-			
-	  	</Route>
-	  </Route>
-	  <Route path="studio/:studioid/channel/create" element={<NutStudioChannelCreate />}> </Route>
-	  <Route path="studio/:studioid/channel/edit" element={<NutStudioChannelEdit />}> </Route>
+
+	  <Route path="community" element={<LibraryCommunity />}></Route>
+	  <Route path="recent" element={<LibraryCommunityRecent />} />
+	  <Route path="palicanon" element={<LibraryPalicanon />} />
+
+	  <Route path="course" element={<LibraryCourse />}></Route>
+      <Route path="course/show/:id" element={<LibraryCourseShow />}></Route>
+      <Route path="course/lesson/:id" element={<LibraryLessonShow />}></Route>
+
+	  <Route path="term/:word" element={<LibraryTerm />} />
+
+	  <Route path="dict" element={<LibraryDict />} />
+	  <Route path="dict/:word" element={<LibraryDictShow />} />
+
+	  <Route path="anthology" element={<LibraryAnthology />} />
+	  <Route path="anthology/show/:id" element={<LibraryAnthologyShow />} />
+	  <Route path="article/show/:id" element={<LibraryArticle />} />
+
+	  <Route path="blog/:studioname" element={<LibraryBlog />} />
+	  <Route path="blog/:studioname/translation" element={<LibraryBlogTranslation />} />
+	  <Route path="blog/:studioname/course" element={<LibraryBlogCourse />} />
+	  <Route path="blog/:studioname/anthology" element={<LibraryBlogAnthology />} />
+	  <Route path="blog/:studioname/term" element={<LibraryBlogTerm />} />
+
+	  <Route path="studio/:studioname" element={<StudioHome />}></Route>
+	  <Route path="studio/:studioname/palicanon" element={<StudioPalicanon />}></Route>
+	  <Route path="studio/:studioname/recent" element={<StudioRecent />}></Route>
+
+	  <Route path="studio/:studioname/channel" element={<StudioChannel />}></Route>
+	  <Route path="studio/:studioname/channel/create" element={<StudioChannelCreate />} />
+	  <Route path="studio/:studioname/channel/edit/:channelid" element={<StudioChannelEdit />} />
+
+	  <Route path="studio/:studioname/group" element={<StudioGroup />}></Route>
+	  <Route path="studio/:studioname/group/:groupid" element={<StudioGroupShow />} />
+	  <Route path="studio/:studioname/group/edit/:groupid" element={<StudioGroupEdit />} />
+
+	  <Route path="studio/:studioname/dict" element={<StudioDict />}> </Route>
+	  <Route path="studio/:studioname/term" element={<StudioTerm />}> </Route>
+
+	  <Route path="studio/:studioname/article" element={<StudioArticle />}></Route>
+	  <Route path="studio/:studioname/article/edit/:articleid" element={<StudioArticleEdit />} />
+	  
+	  <Route path="studio/:studioname/anthology" element={<StudioAnthology />}></Route>
+	  <Route path="studio/:studioname/anthology/edit/:anthology_id" element={<StudioAnthologyEdit />} />
+
+	  <Route path="studio/:studioname/analysis" element={<StudioAnalysis />}></Route>
+
     </Routes>
   );
 };

+ 33 - 0
dashboard/src/components/blog/HeadBar.tsx

@@ -0,0 +1,33 @@
+import { Link } from "react-router-dom";
+import { Space } from "antd";
+import { useIntl } from "react-intl";
+
+const Widget = () => {
+	//Library head bar
+	const intl = useIntl();//i18n
+	// TODO
+  return (
+	<Space>
+		<Link to="/community">
+			{intl.formatMessage({ id: "columns.library.community.title" })}
+		</Link>
+		<Link to="/palicanon">
+			{intl.formatMessage({ id: "columns.library.palicanon.title" })}
+		</Link>
+		<Link to="/course">
+			{intl.formatMessage({ id: "columns.library.course.title" })}
+		</Link>
+		<Link to="/term">
+			{intl.formatMessage({ id: "columns.library.term.title" })}
+		</Link>
+		<Link to="/dict">
+			{intl.formatMessage({ id: "columns.library.dict.title" })}
+		</Link>
+		<Link to="/anthology">
+			{intl.formatMessage({ id: "columns.library.anthology.title" })}
+		</Link>
+	</Space>
+  );
+};
+
+export default Widget;

+ 26 - 0
dashboard/src/components/library/Footer.tsx

@@ -0,0 +1,26 @@
+import { Link } from "react-router-dom";
+import { Space } from "antd";
+import { useIntl } from "react-intl";
+
+const Widget = () => {
+	//Library foot bar
+	const intl = useIntl();//i18n
+	// TODO
+  return (
+	<div>
+		<p>底部区域</p>
+		<Space>
+
+			<Link to="/">
+				联系方式
+			</Link>
+			<Link to="/">
+				{intl.formatMessage({ id: "columns.library.palicanon.title" })}
+			</Link>
+		</Space>		
+	</div>
+
+  );
+};
+
+export default Widget;

+ 36 - 0
dashboard/src/components/library/HeadBar.tsx

@@ -0,0 +1,36 @@
+import { Link } from "react-router-dom";
+import { Space } from "antd";
+import { useIntl } from "react-intl";
+
+const Widget = () => {
+	//Library head bar
+	const intl = useIntl();//i18n
+	// TODO
+  return (
+	<Space>
+		<Link to="/community">
+			{intl.formatMessage({ id: "columns.library.community.title" })}
+		</Link>
+		<Link to="/palicanon">
+			{intl.formatMessage({ id: "columns.library.palicanon.title" })}
+		</Link>
+		<Link to="/course">
+			{intl.formatMessage({ id: "columns.library.course.title" })}
+		</Link>
+		<Link to="/term">
+			{intl.formatMessage({ id: "columns.library.term.title" })}
+		</Link>
+		<Link to="/dict">
+			{intl.formatMessage({ id: "columns.library.dict.title" })}
+		</Link>
+		<Link to="/anthology">
+			{intl.formatMessage({ id: "columns.library.anthology.title" })}
+		</Link>
+
+		<Link to="/studio/kosalla">译经楼首页</Link>
+
+	</Space>
+  );
+};
+
+export default Widget;

+ 0 - 5
dashboard/src/components/nut/library/Footer.tsx

@@ -1,5 +0,0 @@
-const Widget = () => {
-  return <div>Library Footer</div>;
-};
-
-export default Widget;

+ 0 - 5
dashboard/src/components/nut/library/HeadBar.tsx

@@ -1,5 +0,0 @@
-const Widget = () => {
-  return <div>Library head bar</div>;
-};
-
-export default Widget;

+ 0 - 5
dashboard/src/components/nut/studio/HeadBar.tsx

@@ -1,5 +0,0 @@
-const Widget = () => {
-  return <div>studio head bar</div>;
-};
-
-export default Widget;

+ 0 - 5
dashboard/src/components/nut/studio/LeftSider.tsx

@@ -1,5 +0,0 @@
-const Widget = () => {
-  return <div>left sider</div>;
-};
-
-export default Widget;

+ 0 - 0
dashboard/src/components/nut/studio/Footer.tsx → dashboard/src/components/studio/Footer.tsx


+ 15 - 0
dashboard/src/components/studio/HeadBar.tsx

@@ -0,0 +1,15 @@
+import { Link } from "react-router-dom";
+import { Space } from "antd";
+
+const Widget = () => {
+  return (
+  	<div>
+		studio head bar
+		<Space>
+			<Link to="/">首页</Link>
+		</Space>
+	</div>
+  );
+};
+
+export default Widget;

+ 56 - 0
dashboard/src/components/studio/LeftSider.tsx

@@ -0,0 +1,56 @@
+import { Link } from "react-router-dom";
+import { Space } from "antd";
+import { useIntl } from "react-intl";
+import { useParams } from "react-router-dom";
+
+const Widget = () => {
+	//Library head bar
+	const intl = useIntl();//i18n
+	const { studioname } = useParams();
+	// TODO
+	const linkPalicanon = "/studio/"+studioname+"/palicanon";
+	const linkRecent = "/studio/"+studioname+"/recent";
+	const linkChannel = "/studio/"+studioname+"/channel";
+	const linkGroup = "/studio/"+studioname+"/group";
+	const linkUserdict = "/studio/"+studioname+"/dict";
+	const linkTerm = "/studio/"+studioname+"/term";
+	const linkArticle = "/studio/"+studioname+"/article";
+	const linkAnthology = "/studio/"+studioname+"/anthology";
+	const linkAnalysis = "/studio/"+studioname+"/analysis";
+  return (
+  <div>
+	<Space>
+		<Link to={linkPalicanon}>
+			{intl.formatMessage({ id: "columns.studio.palicanon.title" })}
+		</Link>
+		<Link to={linkRecent}>
+			{intl.formatMessage({ id: "columns.studio.recent.title" })}
+		</Link>
+		<Link to={linkChannel}>
+			{intl.formatMessage({ id: "columns.studio.channel.title" })}
+		</Link>
+		<Link to={linkGroup}>
+			{intl.formatMessage({ id: "columns.studio.group.title" })}
+		</Link>
+		<Link to={linkUserdict}>
+			{intl.formatMessage({ id: "columns.studio.userdict.title" })}
+		</Link>
+		<Link to={linkTerm}>
+			{intl.formatMessage({ id: "columns.studio.term.title" })}
+		</Link>
+		<Link to={linkArticle}>
+			{intl.formatMessage({ id: "columns.studio.article.title" })}
+		</Link>
+		<Link to={linkAnthology}>
+			{intl.formatMessage({ id: "columns.studio.anthology.title" })}
+		</Link>
+		<Link to={linkAnalysis}>
+			{intl.formatMessage({ id: "columns.studio.analysis.title" })}
+		</Link>
+	</Space>
+
+  </div>
+  );
+};
+
+export default Widget;

+ 3 - 3
dashboard/src/locales/zh-Hans/channel/index.ts

@@ -1,11 +1,11 @@
 const items = {
   "channel.title": "版本风格",
-  "channel.type": "版本类型",
-  "channel.name": "版本名称",
+  "channel.type": "类型",
+  "channel.name": "名称",
   "channel.create.message.noname": "请输入版本名称",
   "channel.type.nissaya.title": "逐词解析",
   "channel.type.translation.title": "译文",
-  "channel.lang": "版本语言",
+  "channel.lang": "语言",
 };
 
 export default items;

+ 16 - 0
dashboard/src/locales/zh-Hans/dict/index.ts

@@ -0,0 +1,16 @@
+const items = {
+  "dict": "字典",
+  "dict.fields.sn.label": "序号",
+  "dict.fields.word.label": "词头",
+  "dict.fields.type.label": "类型",
+  "dict.fields.grammar.label": "语法信息",
+  "dict.fields.parent.label": "词干",
+  "dict.fields.meaning.label": "意思",
+  "dict.fields.factors.label": "组份",
+  "dict.fields.factormeaning.label": "组份意思",
+  "dict.fields.note.label": "注释",
+  "dict.fields.confidence.label": "信心指数",
+  "dict.fields.dictname.label": "字典名称",
+};
+
+export default items;

+ 19 - 1
dashboard/src/locales/zh-Hans/index.ts

@@ -3,15 +3,33 @@ import buttons from "./buttons";
 import tables from "./tables";
 import nut from "./nut";
 import channel from "./channel";
+import dict from "./dict";
 
 const items = {
   "flashes.success": "操作成功",
-  "title.channel": "版本风格",
+  "columns.library.title": "藏经阁",
+  "columns.library.community.title": "社区",
+  "columns.library.palicanon.title": "圣典",
+  "columns.library.course.title": "课程",
+  "columns.library.term.title": "术语百科",
+  "columns.library.dict.title": "字典",
+  "columns.library.anthology.title": "文集",
+  "columns.studio.title": "译经楼",
+  "columns.studio.palicanon.title": "圣典",
+  "columns.studio.recent.title": "最近编辑",
+  "columns.studio.channel.title": "版本风格",
+  "columns.studio.group.title": "群组",
+  "columns.studio.userdict.title": "用户字典",
+  "columns.studio.term.title": "术语",
+  "columns.studio.article.title": "文章",
+  "columns.studio.anthology.title": "文集",
+  "columns.studio.analysis.title": "分析",
   ...buttons,
   ...forms,
   ...tables,
   ...nut,
   ...channel,
+  ...dict,
 };
 
 export default items;

+ 0 - 22
dashboard/src/pages/community/index.tsx

@@ -1,22 +0,0 @@
-import { Outlet, Link } from "react-router-dom";
-import { Space } from "antd";
-
-const Widget = () => {
-  return (
-    <div>
-      <div>最新译文</div>
-      <div>
-        <Outlet />
-        <div>
-          <Space>
-            <Link to="/">Home</Link>
-            <Link to="/community/myread">我的阅读</Link>
-          </Space>
-        </div>
-      </div>
-      <div>底部区域</div>
-    </div>
-  );
-};
-
-export default Widget;

+ 23 - 0
dashboard/src/pages/library/anthology/article.tsx

@@ -0,0 +1,23 @@
+import { Space } from "antd";
+import { useParams } from "react-router-dom";
+
+import HeadBar from "../../../components/library/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+	const { article_id } = useParams();//url 参数
+
+  return (
+    <div>
+		<HeadBar />
+      <div>文章阅读器{article_id}</div>
+      <div>
+		<Space>主显示区</Space>
+      </div>
+		<Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 24 - 0
dashboard/src/pages/library/anthology/index.tsx

@@ -0,0 +1,24 @@
+import { Space } from "antd";
+import { Link } from "react-router-dom";
+
+import HeadBar from "../../../components/library/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+  return (
+    <div>
+		<HeadBar />
+      <div>文集首页</div>
+	  <div>
+	  	<Space>
+			<Link to="/anthology/show/12345">文集1</Link>
+			<Link to="/article/show/23456">文章1</Link>
+		</Space>
+	  </div>
+		<Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 22 - 0
dashboard/src/pages/library/anthology/show.tsx

@@ -0,0 +1,22 @@
+import { Space } from "antd";
+import { useParams } from "react-router-dom";
+
+import HeadBar from "../../../components/library/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+	const { anthology_id } = useParams();//url 参数
+  return (
+    <div>
+		<HeadBar />
+      <div>文集{anthology_id}详情</div>
+      <div>
+		<Space>主显示区</Space>
+      </div>
+		<Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 23 - 0
dashboard/src/pages/library/blog/anthology.tsx

@@ -0,0 +1,23 @@
+import { Space } from "antd";
+import { useParams, Link } from "react-router-dom";
+import HeadBar from "../../../components/blog/HeadBar";
+import Footer from "../../../components/library/Footer";
+const Widget = () => {
+	// TODO
+	const { courseid } = useParams();//url 参数
+  return (
+    <div>
+	<HeadBar />
+      <div>课程{courseid} 详情</div>
+	  <div>
+	  	<Space>
+			<Link to="/course/lesson/12345">lesson 1</Link>
+			<Link to="/course/lesson/23456">lesson 2</Link>
+		</Space>
+	  </div>
+	  <Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 22 - 0
dashboard/src/pages/library/blog/course.tsx

@@ -0,0 +1,22 @@
+import { Space } from "antd";
+import { useParams } from "react-router-dom";
+import HeadBar from "../../../components/blog/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+	const { lessonid } = useParams();//url 参数
+
+  return (
+    <div>
+		<HeadBar />
+      <div>课 {lessonid} 详情</div>
+      <div>
+		<Space>主显示区</Space>
+      </div>
+	  <Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 23 - 0
dashboard/src/pages/library/blog/index.tsx

@@ -0,0 +1,23 @@
+import { Space } from "antd";
+import { Link } from "react-router-dom";
+import HeadBar from "../../../components/blog/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+  return (
+    <div>
+		<HeadBar />
+      <div>课程首页</div>
+	  <div>
+	  	<Space>
+			<Link to="/course/show/12345">课程1</Link>
+			<Link to="/course/show/23456">课程2</Link>
+		</Space>
+	  </div>
+		<Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 22 - 0
dashboard/src/pages/library/blog/term.tsx

@@ -0,0 +1,22 @@
+import { Space } from "antd";
+import { useParams } from "react-router-dom";
+import HeadBar from "../../../components/blog/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+	const { lessonid } = useParams();//url 参数
+
+  return (
+    <div>
+		<HeadBar />
+      <div>课 {lessonid} 详情</div>
+      <div>
+		<Space>主显示区</Space>
+      </div>
+	  <Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 23 - 0
dashboard/src/pages/library/blog/translation.tsx

@@ -0,0 +1,23 @@
+import { Space } from "antd";
+import { useParams, Link } from "react-router-dom";
+import HeadBar from "../../../components/blog/HeadBar";
+import Footer from "../../../components/library/Footer";
+const Widget = () => {
+	// TODO
+	const { courseid } = useParams();//url 参数
+  return (
+    <div>
+	<HeadBar />
+      <div>课程{courseid} 详情</div>
+	  <div>
+	  	<Space>
+			<Link to="/course/lesson/12345">lesson 1</Link>
+			<Link to="/course/lesson/23456">lesson 2</Link>
+		</Space>
+	  </div>
+	  <Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 19 - 0
dashboard/src/pages/library/community/index.tsx

@@ -0,0 +1,19 @@
+import { Space } from "antd";
+import HeadBar from "../../../components/library/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+  return (
+    <div>
+		<HeadBar />
+      <div>最新译文</div>
+      <div>
+		<Space>主显示区</Space>
+      </div>
+		<Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 0 - 0
dashboard/src/pages/community/recent.tsx → dashboard/src/pages/library/community/recent.tsx


+ 23 - 0
dashboard/src/pages/library/course/course.tsx

@@ -0,0 +1,23 @@
+import { Space } from "antd";
+import { useParams, Link } from "react-router-dom";
+import HeadBar from "../../../components/library/HeadBar";
+import Footer from "../../../components/library/Footer";
+const Widget = () => {
+	// TODO
+	const { courseid } = useParams();//url 参数
+  return (
+    <div>
+	<HeadBar />
+      <div>课程{courseid} 详情</div>
+	  <div>
+	  	<Space>
+			<Link to="/course/lesson/12345">lesson 1</Link>
+			<Link to="/course/lesson/23456">lesson 2</Link>
+		</Space>
+	  </div>
+	  <Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 23 - 0
dashboard/src/pages/library/course/index.tsx

@@ -0,0 +1,23 @@
+import { Space } from "antd";
+import { Link } from "react-router-dom";
+import HeadBar from "../../../components/library/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+  return (
+    <div>
+		<HeadBar />
+      <div>课程首页</div>
+	  <div>
+	  	<Space>
+			<Link to="/course/show/12345">课程1</Link>
+			<Link to="/course/show/23456">课程2</Link>
+		</Space>
+	  </div>
+		<Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 22 - 0
dashboard/src/pages/library/course/lesson.tsx

@@ -0,0 +1,22 @@
+import { Space } from "antd";
+import { useParams } from "react-router-dom";
+import HeadBar from "../../../components/library/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+	const { lessonid } = useParams();//url 参数
+
+  return (
+    <div>
+		<HeadBar />
+      <div>课 {lessonid} 详情</div>
+      <div>
+		<Space>主显示区</Space>
+      </div>
+	  <Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 19 - 0
dashboard/src/pages/library/dict/index.tsx

@@ -0,0 +1,19 @@
+import { Space } from "antd";
+import HeadBar from "../../../components/library/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+  return (
+    <div>
+		<HeadBar />
+      <div>字典首页</div>
+      <div>
+		<Space>主显示区</Space>
+      </div>
+		<Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 22 - 0
dashboard/src/pages/library/dict/show.tsx

@@ -0,0 +1,22 @@
+import { Space } from "antd";
+import { useParams } from "react-router-dom";
+
+import HeadBar from "../../../components/library/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+	const { word } = useParams();//url 参数
+  return (
+    <div>
+		<HeadBar />
+      <div>字典-单词-{word}</div>
+      <div>
+		<Space>主显示区</Space>
+      </div>
+		<Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 19 - 0
dashboard/src/pages/library/palicanon/index.tsx

@@ -0,0 +1,19 @@
+import { Space } from "antd";
+import HeadBar from "../../../components/library/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+  return (
+    <div>
+		<HeadBar />
+      <div>圣典分类</div>
+      <div>
+		<Space>主显示区</Space>
+      </div>
+		<Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 22 - 0
dashboard/src/pages/library/term/show.tsx

@@ -0,0 +1,22 @@
+import { Space } from "antd";
+import { useParams } from "react-router-dom";
+
+import HeadBar from "../../../components/library/HeadBar";
+import Footer from "../../../components/library/Footer";
+
+const Widget = () => {
+	// TODO
+	const { word } = useParams();//url 参数
+  return (
+    <div>
+		<HeadBar />
+      <div>术语百科 单词-{word}</div>
+      <div>
+		<Space>主显示区</Space>
+      </div>
+		<Footer />
+    </div>
+  );
+};
+
+export default Widget;

+ 11 - 1
dashboard/src/pages/nut/index.tsx

@@ -1,5 +1,15 @@
+import HeadBar from "../../components/library/HeadBar";
+import Footer from "../../components/library/Footer";
+
 const Widget = () => {
-  return <div>Home Page</div>;
+  return (
+	<div>
+		<HeadBar />
+		<div>Home Page</div>
+		<Footer />
+	</div>
+  	
+  );
 };
 
 export default Widget;

+ 26 - 0
dashboard/src/pages/studio/analysis/index.tsx

@@ -0,0 +1,26 @@
+import { useParams ,Link} from "react-router-dom";
+import { useIntl } from "react-intl";
+import { Space } from "antd";
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+const Widget = () => {
+	const intl = useIntl();//i18n
+	const { studioname } = useParams();//url 参数
+  return (
+    <div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.analysis.title" })}/行为分析首页</h2>
+      <div>
+		<Space>
+			<Link to=""> </Link>
+		</Space>
+      </div>
+      <Footer/>
+    </div>
+  );
+};
+
+export default Widget;

+ 23 - 0
dashboard/src/pages/studio/anthology/edit.tsx

@@ -0,0 +1,23 @@
+import { useParams } from "react-router-dom";
+import { useIntl } from "react-intl";
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+const Widget = () => {
+	const intl = useIntl();
+	const { studioname,anthology_id } = useParams();//url 参数
+  return (
+    <div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.anthology.title" })}/anthology/{anthology_id}</h2>
+      <div>
+		
+      </div>
+      <Footer/>
+    </div>
+  );
+};
+
+export default Widget;

+ 27 - 0
dashboard/src/pages/studio/anthology/index.tsx

@@ -0,0 +1,27 @@
+import { useParams ,Link} from "react-router-dom";
+import { useIntl } from "react-intl";
+import { Space } from "antd";
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+const Widget = () => {
+	const intl = useIntl();//i18n
+	const { studioname } = useParams();//url 参数
+	const linkEdit = `/studio/${studioname}/anthology/edit/12345`;
+  return (
+    <div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.article.title" })}/文集列表</h2>
+      <div>
+		<Space>
+			<Link to={linkEdit}> anthology edit </Link>
+		</Space>
+      </div>
+      <Footer/>
+    </div>
+  );
+};
+
+export default Widget;

+ 23 - 0
dashboard/src/pages/studio/article/edit.tsx

@@ -0,0 +1,23 @@
+import { useParams } from "react-router-dom";
+import { useIntl } from "react-intl";
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+const Widget = () => {
+	const intl = useIntl();
+	const { studioname,articleid } = useParams();//url 参数
+  return (
+    <div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.article.title" })}/edit/{articleid}</h2>
+      <div>
+		
+      </div>
+      <Footer/>
+    </div>
+  );
+};
+
+export default Widget;

+ 27 - 0
dashboard/src/pages/studio/article/index.tsx

@@ -0,0 +1,27 @@
+import { useParams ,Link} from "react-router-dom";
+import { useIntl } from "react-intl";
+import { Space } from "antd";
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+const Widget = () => {
+	const intl = useIntl();//i18n
+	const { studioname } = useParams();//url 参数
+	const linkEdit = `/studio/${studioname}/article/edit/12345`;
+  return (
+    <div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.article.title" })}/文章列表</h2>
+      <div>
+		<Space>
+			<Link to={linkEdit}> article edit </Link>
+		</Space>
+      </div>
+      <Footer/>
+    </div>
+  );
+};
+
+export default Widget;

+ 3 - 3
dashboard/src/pages/studio/channel/create.tsx

@@ -9,15 +9,15 @@ interface IFormData {
   }
 const Widget = () => {
 	const intl = useIntl();
-	const { studioid } = useParams();
+	const { studioname } = useParams();
   return (
     <div>
-      <div>studio/{studioid}/{intl.formatMessage({ id: "title.channel" })}/create</div>
+      <div>studio/{studioname}/{intl.formatMessage({ id: "title.channel" })}/create</div>
       <div>
         <div>
           <Space>
             <Link to="/">Home</Link>
-            <Link to="/community/myread">{studioid}</Link>
+            <Link to="/community/myread">{studioname}</Link>
           </Space>
         </div>
 		

+ 10 - 11
dashboard/src/pages/studio/channel/edit.tsx

@@ -1,8 +1,11 @@
 import { useParams } from "react-router-dom";
 import { ProForm, ProFormText , ProFormSelect,ProFormTextArea } from "@ant-design/pro-components";
 import { useIntl } from "react-intl";
-import { Link } from "react-router-dom";
-import { Space,message } from "antd";
+import { message } from "antd";
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
 interface IFormData {
 	name: string;
 	type: string;
@@ -12,17 +15,13 @@ interface IFormData {
   }
 const Widget = () => {
 	const intl = useIntl();
-	const { studioid } = useParams();
+	const { studioname,channelid } = useParams();//url 参数
   return (
     <div>
-      <div>studio/{studioid}/{intl.formatMessage({ id: "title.channel" })}/create</div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.channel.title" })}/edit/{channelid}</h2>
       <div>
-        <div>
-          <Space>
-            <Link to="/">Home</Link>
-            <Link to="/community/myread">{studioid}</Link>
-          </Space>
-        </div>
 		
 		<div>
 		<ProForm<IFormData>
@@ -76,7 +75,7 @@ const Widget = () => {
 		</ProForm>
 		</div>
       </div>
-      <div>底部区域</div>
+      <Footer/>
     </div>
   );
 };

+ 13 - 12
dashboard/src/pages/studio/channel/index.tsx

@@ -1,24 +1,25 @@
-import { useParams } from "react-router-dom";
+import { useParams ,Link} from "react-router-dom";
 import { useIntl } from "react-intl";
-import { Link } from "react-router-dom";
 import { Space } from "antd";
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
 
 const Widget = () => {
 	const intl = useIntl();//i18n
-	const { studioid } = useParams();//url 参数
-
+	const { studioname } = useParams();//url 参数
+	const linkEdit = `/studio/${studioname}/channel/edit/12345`;
   return (
     <div>
-      <div>studio/{studioid}/{intl.formatMessage({ id: "title.channel" })}</div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.channel.title" })}/版本列表</h2>
       <div>
-        <div>
-          <Space>
-            <Link to="/">Home</Link>
-            <Link to="/community/myread">{studioid}</Link>
-          </Space>
-        </div>
+		<Space>
+			<Link to={linkEdit}> channel1 edit </Link>
+		</Space>
       </div>
-      <div>底部区域</div>
+      <Footer/>
     </div>
   );
 };

+ 166 - 0
dashboard/src/pages/studio/dict/index.tsx

@@ -0,0 +1,166 @@
+import { useParams } from "react-router-dom";
+import { ProTable } from "@ant-design/pro-components";
+import { useIntl } from "react-intl";
+import { Link } from "react-router-dom";
+import { Button,Layout } from "antd";
+import {  PlusOutlined } from '@ant-design/icons';
+
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+interface IItem {
+  id: number;
+  word: string;
+  type: string;
+  grammar: string;
+  parent: string;
+  meaning: string;  
+  note: string;
+  factors: string;
+  createdAt: number;
+}
+
+const valueEnum = {
+	0: 'n',
+	1: 'ti',
+	2: 'v',
+	3: 'ind',
+  };
+
+const Widget = () => {
+  const intl = useIntl();
+  const { studioname } = useParams();
+  return (
+	<Layout>
+		<HeadBar/>
+		<LeftSider/>
+		<Layout>{studioname}</Layout>
+    <ProTable<IItem>
+      columns={[
+        {
+          title: intl.formatMessage({ id: "dict.fields.sn.label" }),
+          dataIndex: "id",
+          key: "id",
+          width: 80,
+          search: false,
+        },
+        {
+          title: intl.formatMessage({ id: "dict.fields.word.label" }),
+          dataIndex: "word",
+          key: "word",
+		  render: (_) => <Link to="">{_}</Link>,
+		  tip: '单词过长会自动收缩',
+		  ellipsis: true,
+		  formItemProps: {
+			rules: [
+			  {
+				required: true,
+				message: '此项为必填项',
+			  },
+			],
+		  },
+        },
+		{
+			title: intl.formatMessage({ id: "dict.fields.type.label" }),
+			dataIndex: "type",
+			key: "type",
+			search: false,
+			filters: true,
+			onFilter: true,
+			valueEnum: {
+			  all: { text: '全部', status: 'Default' },
+			  n: { text: '名词', status: 'Default' },
+			  ti: { text: '三性', status: 'Processing' },
+			  v: { text: '动词', status: 'Success' },
+			  ind: { text: '不变词', status: 'Success' },
+			},
+		},
+		{
+			title: intl.formatMessage({ id: "dict.fields.grammar.label" }),
+			dataIndex: "grammar",
+			key: "grammar",
+			search: false,
+		},
+		{
+			title: intl.formatMessage({ id: "dict.fields.parent.label" }),
+			dataIndex: "parent",
+			key: "parent",
+		},
+		{
+			title: intl.formatMessage({ id: "dict.fields.meaning.label" }),
+			dataIndex: "meaning",
+			key: "meaning",
+			tip: '意思过长会自动收缩',
+			ellipsis: true,
+		},
+		{
+			title: intl.formatMessage({ id: "dict.fields.note.label" }),
+			dataIndex: "note",
+			key: "note",
+			search: false,
+			tip: '注释过长会自动收缩',
+			ellipsis: true,
+		},
+		{
+			title: intl.formatMessage({ id: "dict.fields.factors.label" }),
+			dataIndex: "factors",
+			key: "factors",
+			search: false,
+		},
+        {
+          title: intl.formatMessage({ id: "forms.fields.created-at.label" }),
+          key: "created-at",
+          width: 200,
+
+          search: false,
+		  dataIndex: 'createdAt',
+		  valueType: 'date',
+    	sorter: (a, b) => a.createdAt - b.createdAt,
+        },
+      ]}
+      request={async (params = {}, sorter, filter) => {
+        // TODO
+        console.log(params, sorter, filter);
+
+        const size = params.pageSize || 20;
+        return {
+          total: 1 << 12,
+          success: true,
+          data: Array.from(Array(size).keys()).map((x) => {
+            const id = ((params.current || 1) - 1) * size + x + 1;
+			
+            var it: IItem = {
+              id,
+              word: `word ${id}`,
+			  type: valueEnum[2],
+			  grammar: "阳-单-属",
+			  parent: `parent ${id}`,
+			  meaning: `meaning ${id}`,
+			  note: `note ${id}`,
+			  factors: `factors ${id}`,
+              createdAt: Date.now() - Math.floor(Math.random() * 200000),
+            };
+            return it;
+          }),
+        };
+      }}
+      rowKey="id"
+      bordered
+      pagination={{
+        showQuickJumper: true,
+        showSizeChanger: true,
+      }}
+      headerTitle={intl.formatMessage({ id: "dict" })}
+	  toolBarRender={() => [
+        <Button key="button" icon={<PlusOutlined />} type="primary">
+          新建
+        </Button>,
+      ]}
+    />
+	<Footer/>
+	</Layout>
+  );
+};
+
+export default Widget;

+ 83 - 0
dashboard/src/pages/studio/group/edit.tsx

@@ -0,0 +1,83 @@
+import { useParams } from "react-router-dom";
+import { ProForm, ProFormText , ProFormSelect,ProFormTextArea } from "@ant-design/pro-components";
+import { useIntl } from "react-intl";
+import { message } from "antd";
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+interface IFormData {
+	name: string;
+	type: string;
+	lang: string;
+	summary: string;
+	studio: string;
+  }
+const Widget = () => {
+	const intl = useIntl();
+	const { studioname,groupid } = useParams();//url 参数
+  return (
+    <div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.group.title" })}/edit/{groupid}</h2>
+      <div>
+		
+		<div>
+		<ProForm<IFormData>
+		onFinish={async (values: IFormData) => {
+			// TODO
+			values.studio = "aaaa";
+			console.log(values);
+			message.success(intl.formatMessage({ id: "flashes.success" }));
+		}}
+		>
+		<ProForm.Group>
+			<ProFormText
+			width="md"
+			name="name"
+			required
+			label={intl.formatMessage({ id: "channel.name" })}
+			rules={[{ required: true, message: intl.formatMessage({ id: "channel.create.message.noname" }) }]}
+			/>
+		</ProForm.Group>
+		
+		<ProForm.Group>
+			<ProFormSelect
+				options={[
+					{value: 'translation', label: intl.formatMessage({ id: "channel.type.translation.title" }), },
+					{value: 'nissaya', label: intl.formatMessage({ id: "channel.type.nissaya.title" }), },
+				]}
+				width="md"
+				name="type"
+				rules={[{ required: true, message: intl.formatMessage({ id: "channel.create.message.noname" }) }]}
+				label={intl.formatMessage({ id: "channel.type" })}
+				/>
+		</ProForm.Group>
+		<ProForm.Group>
+			<ProFormSelect
+				options={[
+					{value: 'zh-Hans', label: "简体中文", },
+					{value: 'zh-Hant', label: "繁体中文", },
+					{value: 'en-US', label: "English", },
+				]}
+				width="md"
+				name="lang"
+				rules={[{ required: true, message: intl.formatMessage({ id: "channel.create.message.noname" }) }]}
+				label={intl.formatMessage({ id: "channel.lang" })}
+				/>
+		</ProForm.Group>
+
+		<ProForm.Group>
+			<ProFormTextArea  name="summary" label="简介" />
+		</ProForm.Group>
+
+		</ProForm>
+		</div>
+      </div>
+      <Footer/>
+    </div>
+  );
+};
+
+export default Widget;

+ 29 - 0
dashboard/src/pages/studio/group/index.tsx

@@ -0,0 +1,29 @@
+import { useParams ,Link} from "react-router-dom";
+import { useIntl } from "react-intl";
+import { Space } from "antd";
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+const Widget = () => {
+	const intl = useIntl();//i18n
+	const { studioname } = useParams();//url 参数
+	const linkEdit = `/studio/${studioname}/group/edit/12345`;
+	const linkShow = `/studio/${studioname}/group/12345`;
+  return (
+    <div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.channel.title" })}/版本列表</h2>
+      <div>
+		<Space>
+			<Link to={linkEdit}> group1 edit </Link>
+			<Link to={linkShow}> group1 show </Link>
+		</Space>
+      </div>
+      <Footer/>
+    </div>
+  );
+};
+
+export default Widget;

+ 25 - 0
dashboard/src/pages/studio/group/show.tsx

@@ -0,0 +1,25 @@
+import { useParams } from "react-router-dom";
+import { useIntl } from "react-intl";
+
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+
+const Widget = () => {
+	const intl = useIntl();
+	const { studioname,groupid } = useParams();//url 参数
+  return (
+    <div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.channel.title" })}/show/{groupid}</h2>
+      <div>
+		群组详情
+      </div>
+      <Footer/>
+    </div>
+  );
+};
+
+export default Widget;

+ 13 - 13
dashboard/src/pages/studio/index.tsx

@@ -1,24 +1,24 @@
-import { useParams } from "react-router-dom";
+import { useParams ,Link} from "react-router-dom";
 import { useIntl } from "react-intl";
-import { Link } from "react-router-dom";
 import { Space } from "antd";
+import HeadBar from "../../components/studio/HeadBar";
+import LeftSider from "../../components/studio/LeftSider";
+import Footer from "../../components/studio/Footer";
 
 const Widget = () => {
-	const intl = useIntl();
-	const { studioid } = useParams();
-
+	const intl = useIntl();//i18n
+	const { studioname } = useParams();//url 参数
   return (
     <div>
-      <div>studio index{intl.formatMessage({ id: "title.channel" })}</div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/首页</h2>
       <div>
-        <div>
-          <Space>
-            <Link to="/">Home</Link>
-            <Link to="/community/myread">{studioid}</Link>
-          </Space>
-        </div>
+		<Space>
+			<Link to=""> </Link>
+		</Space>
       </div>
-      <div>底部区域</div>
+      <Footer/>
     </div>
   );
 };

+ 26 - 0
dashboard/src/pages/studio/palicanon/index.tsx

@@ -0,0 +1,26 @@
+import { useParams ,Link} from "react-router-dom";
+import { useIntl } from "react-intl";
+import { Space } from "antd";
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+const Widget = () => {
+	const intl = useIntl();//i18n
+	const { studioname } = useParams();//url 参数
+  return (
+    <div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.palicanon.title" })}</h2>
+      <div>
+		<Space>
+			<Link to=""> </Link>
+		</Space>
+      </div>
+      <Footer/>
+    </div>
+  );
+};
+
+export default Widget;

+ 26 - 0
dashboard/src/pages/studio/recent/index.tsx

@@ -0,0 +1,26 @@
+import { useParams ,Link} from "react-router-dom";
+import { useIntl } from "react-intl";
+import { Space } from "antd";
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+const Widget = () => {
+	const intl = useIntl();//i18n
+	const { studioname } = useParams();//url 参数
+  return (
+    <div>
+		<HeadBar/>
+		<LeftSider/>
+      <h2>studio/{studioname}/{intl.formatMessage({ id: "columns.studio.recent.title" })}</h2>
+      <div>
+		<Space>
+			<Link to=""> </Link>
+		</Space>
+      </div>
+      <Footer/>
+    </div>
+  );
+};
+
+export default Widget;

+ 167 - 0
dashboard/src/pages/studio/term/index.tsx

@@ -0,0 +1,167 @@
+import { useParams } from "react-router-dom";
+import { ProTable } from "@ant-design/pro-components";
+import { useIntl } from "react-intl";
+import { Link } from "react-router-dom";
+import { Button,Layout } from "antd";
+import {  PlusOutlined } from '@ant-design/icons';
+
+import HeadBar from "../../../components/studio/HeadBar";
+import LeftSider from "../../../components/studio/LeftSider";
+import Footer from "../../../components/studio/Footer";
+
+interface IItem {
+  id: number;
+  word: string;
+  type: string;
+  grammar: string;
+  parent: string;
+  meaning: string;  
+  note: string;
+  factors: string;
+  createdAt: number;
+}
+
+const valueEnum = {
+	0: 'n',
+	1: 'ti',
+	2: 'v',
+	3: 'ind',
+  };
+
+const Widget = () => {
+  const intl = useIntl();
+  const { studioname } = useParams();
+  return (
+	<Layout>
+		<HeadBar/>
+		<LeftSider/>
+		<Layout>{studioname}</Layout>
+    <ProTable<IItem>
+      columns={[
+        {
+          title: intl.formatMessage({ id: "dict.fields.sn.label" }),
+          dataIndex: "id",
+          key: "id",
+          width: 80,
+          search: false,
+        },
+        {
+          title: intl.formatMessage({ id: "dict.fields.word.label" }),
+          dataIndex: "word",
+          key: "word",
+		  render: (_) => <Link to="">{_}</Link>,
+		  tip: '单词过长会自动收缩',
+		  ellipsis: true,
+		  formItemProps: {
+			rules: [
+			  {
+				required: true,
+				message: '此项为必填项',
+			  },
+			],
+		  },
+        },
+		{
+			title: intl.formatMessage({ id: "dict.fields.type.label" }),
+			dataIndex: "type",
+			key: "type",
+			search: false,
+			filters: true,
+			onFilter: true,
+			valueEnum: {
+			  all: { text: '全部', status: 'Default' },
+			  n: { text: '名词', status: 'Default' },
+			  ti: { text: '三性', status: 'Processing' },
+			  v: { text: '动词', status: 'Success' },
+			  ind: { text: '不变词', status: 'Success' },
+			},
+		},
+		{
+			title: intl.formatMessage({ id: "dict.fields.grammar.label" }),
+			dataIndex: "grammar",
+			key: "grammar",
+			search: false,
+		},
+		{
+			title: intl.formatMessage({ id: "dict.fields.parent.label" }),
+			dataIndex: "parent",
+			key: "parent",
+		},
+		{
+			title: intl.formatMessage({ id: "dict.fields.meaning.label" }),
+			dataIndex: "meaning",
+			key: "meaning",
+			tip: '意思过长会自动收缩',
+			ellipsis: true,
+		},
+		{
+			title: intl.formatMessage({ id: "dict.fields.note.label" }),
+			dataIndex: "note",
+			key: "note",
+			search: false,
+			tip: '注释过长会自动收缩',
+			ellipsis: true,
+		},
+		{
+			title: intl.formatMessage({ id: "dict.fields.factors.label" }),
+			dataIndex: "factors",
+			key: "factors",
+			search: false,
+		},
+        {
+          title: intl.formatMessage({ id: "forms.fields.created-at.label" }),
+          key: "created-at",
+          width: 200,
+
+          search: false,
+		  dataIndex: 'createdAt',
+		  valueType: 'date',
+    	sorter: (a, b) => a.createdAt - b.createdAt,
+        },
+      ]}
+      request={async (params = {}, sorter, filter) => {
+        // TODO
+        console.log(params, sorter, filter);
+
+        const size = params.pageSize || 20;
+        return {
+          total: 1 << 12,
+          success: true,
+          data: Array.from(Array(size).keys()).map((x) => {
+            const id = ((params.current || 1) - 1) * size + x + 1;
+			
+            var it: IItem = {
+              id,
+              word: `word ${id}`,
+			  type: valueEnum[2],
+			  grammar: "阳-单-属",
+			  parent: `parent ${id}`,
+			  meaning: `meaning ${id}`,
+			  note: `note ${id}`,
+			  factors: `factors ${id}`,
+              createdAt: Date.now() - Math.floor(Math.random() * 200000),
+            };
+            return it;
+          }),
+        };
+      }}
+      rowKey="id"
+      bordered
+      pagination={{
+        showQuickJumper: true,
+        showSizeChanger: true,
+      }}
+      headerTitle={intl.formatMessage({ id: "dict" })}
+	  toolBarRender={() => [
+        <Button key="button" icon={<PlusOutlined />} type="primary">
+          新建
+        </Button>,
+      ]}
+    />
+	<Footer/>
+
+	</Layout>
+  );
+};
+
+export default Widget;