john 2 лет назад
Родитель
Сommit
0b977567c1

+ 1 - 0
ClientPlatform/.eslintrc.js

@@ -18,5 +18,6 @@ module.exports = {
     "eol-last": 0,
     "no-unused-vars": 0,
     "no-unreachable": 0,
+    "no-trailing-spaces": 0
   },
 };

+ 1 - 0
ClientPlatform/.yarnrc

@@ -0,0 +1 @@
+registry "https://registry.npmmirror.com/"

+ 1 - 1
ClientPlatform/config/webpack.common.js

@@ -116,7 +116,7 @@ module.exports = (isProduction) => {
         BASE_URL: '"./"',
       }),
       new HtmlWebpackPlugin({
-        title: "博客",
+        title: "DeepBIO",
         template: "public/index.html",
       }),
       new VueLoaderPlugin(),

+ 1 - 1
ClientPlatform/mockData/api-mock/login.js

@@ -4,7 +4,7 @@ module.exports = {
     code: 200,
     message: "ok",
     data: {
-      name: "blog",
+      name: "hello",
       id: "is",
       avatar:
         "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F2b22236d-a6e4-4437-b9f6-4ca9a01bac3a%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1682339675&t=c57d5ab4523574bb34138908789a11ad",

+ 8 - 3
ClientPlatform/package.json

@@ -10,11 +10,13 @@
   "dependencies": {
     "axios": "^1.3.4",
     "core-js": "^3.6.5",
-    "element-ui": "^2.15.13",
+    "element-ui": "^2.7.2",
     "vue": "^2.6.11",
     "vue-demi": "^0.13.11",
     "vue-router": "^3.6.5",
-    "vue2-tinymce-editor": "0.0.1"
+    "vue2-tinymce-editor": "0.0.1",
+    "vxe-table": "^3.6.11",
+    "xe-utils": "^3.5.7"
   },
   "devDependencies": {
     "@babel/core": "^7.21.3",
@@ -72,5 +74,8 @@
     "> 1%",
     "last 2 versions",
     "not dead"
-  ]
+  ],
+  "volta": {
+    "node": "14.21.3"
+  }
 }

+ 0 - 4
ClientPlatform/public/index.html

@@ -15,10 +15,6 @@
         continue.</strong
       >
     </noscript>
-    <link rel="stylesheet" href="https://chorer.github.io/css/style.css">
-    <link rel="stylesheet" href="https://chorer.github.io/css/third%20party/prism.css">
-    <link rel="stylesheet" href="https://chorer.github.io/css/third%20party/jquery.fancybox.css">
-    <link rel="stylesheet" href="https://chorer.github.io/css/third%20party/pace-theme-flash.css">
     <div id="app"></div>
     <!-- built files will be auto injected -->
   </body>

+ 5 - 11
ClientPlatform/src/App.vue

@@ -1,7 +1,7 @@
 <template>
   <div id="app">
     <userHeader></userHeader>
-    <main class="main" :class="isAdmin && 'admin'">
+    <main class="main">
       <!-- route outlet -->
       <router-view></router-view>
     </main>
@@ -15,11 +15,6 @@ import userHeader from "./components/user-header.vue";
 
 export default {
   name: "App",
-  data() {
-    return {
-      isAdmin: false,
-    };
-  },
   components: {
     HelloWorld,
     userHeader,
@@ -32,8 +27,6 @@ export default {
     },
   },
   async mounted() {
-    const res = await getBlogs();
-    console.log(res);
     this.$nextTick(() => {
       this.isAdmin = this.$route.path.indexOf("/admin") > -1;
     });
@@ -46,11 +39,12 @@ export default {
   font-family: Avenir, Helvetica, Arial, sans-serif;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
-  text-align: center;
+  /*text-align: center;*/
   color: #2c3e50;
   /*margin-top: 60px;*/
 }
-.main.admin {
-  max-width: 100%;
+.main {
+    margin-top: 66.5px;
+    /*margin-top: 200px;*/
 }
 </style>

BIN
ClientPlatform/src/assets/home_0.png


BIN
ClientPlatform/src/assets/home_1.png


BIN
ClientPlatform/src/assets/home_2.png


+ 11 - 2
ClientPlatform/src/components/login.vue

@@ -16,7 +16,8 @@
 
     <span slot="footer" class="dialog-footer">
       <el-button @click="dialogVisible = false">取 消</el-button>
-      <el-button type="primary" @click="toLogin">登陆|注册</el-button>
+      <el-button type="primary" @click="toLogin">注册</el-button>
+      <el-button type="primary" @click="toLogin">登陆</el-button>
     </span>
   </el-dialog>
 </template>
@@ -40,7 +41,15 @@ export default {
     },
     handleClose() {},
     async toLogin() {
-      const res = await loginOrRegister();
+      if (!this.form.name) {
+        this.$message.error("请输入用户名称!");
+        return
+      }
+      if (!this.form.password) {
+        this.$message.error("请输入用户密码!");
+        return
+      }
+      const res = await loginOrRegister(this.form);
       console.log("loginOrRegister", res);
       window.localStorage.setItem("userInfo", JSON.stringify(res.data));
       window.localStorage.setItem("token", res.data.token);

+ 92 - 77
ClientPlatform/src/components/user-header.vue

@@ -1,116 +1,131 @@
 <template>
-  <header class="header" :class="active !== 'admin' ? 'home' : 'admin'">
-    <div class="header_top">
-      <span class="theme"
-        ><a @click="toLogin" href="#/">colin's blog</a
-        ><el-avatar
-          style="margin-left: 5px"
-          v-if="avatar"
-          size="small"
-          :src="avatar"
-        ></el-avatar>
-      </span>
-      <nav class="navbar">
-        <ul class="menu">
-          <li class="menu-item">
-            <i class="fa fa-home"></i>
-            <a
-              href="#/"
-              :class="active === 'home' ? 'menu-item-link2' : 'menu-item-link'"
-              >首页</a
-            ><span class="circle"></span>
-          </li>
-          <li class="menu-item">
-            <i class="fa fa-home"></i>
-            <a
-              href="#/admin"
-              :class="active === 'admin' ? 'menu-item-link2' : 'menu-item-link'"
-              >个人管理</a
-            ><span class="circle"></span>
-          </li>
-        </ul>
-      </nav>
-    </div>
-    <i id="homelink" data-link="https://chorer.github.io/"></i>
-    <div class="header_bottom" v-if="active !== 'admin' && false">
-      <div class="blog-title">
-        <a
-          target="_blank"
-          rel="noopener"
-          href="https://github.com/Chorer/hexo-theme-PureBlue"
-          class="logo"
-          >Focus on FE learning</a
-        >
-        <div class="descrs">
-          <div class="descr">个人博客</div>
-          <div class="descr">" Do what you love,Love what you do "</div>
-        </div>
-        <div class="blog-down">
-          <a href="javascript:void(0);"
-            ><i class="fa fa-angle-double-down fa-2x"></i
-          ></a>
-        </div>
-      </div>
-      <div @click="print">4040</div>
+    <div>
+        <header class="header-box">
+            <div class="logo">DeepBIO</div>
+            <div class="nav-box">
+                <div @click="toNewPage('home')" :class="[active === 'home' &&'active', 'item']"><i class="el-icon-s-home"></i>Home</div>
+<!--                <div @click="toNewPage('server')" :class="[active === 'server' &&'active', 'item']"><i class="el-icon-s-operation"></i>Server</div>-->
+                <div @click="toNewPage('order')" :class="[active === 'order' &&'active', 'item']"><i class="el-icon-s-claim"></i>Order</div>
+                <div @click="toNewPage('task')" :class="[active === 'task' &&'active', 'item']"><i class="el-icon-s-order"></i>Task</div>
+            </div>
+            <div class="user-box">
+                <div class="login" v-if="userInfo && userInfo.name">{{ userInfo.name }}</div>
+                <div class="login" v-else @click="$refs.loginCom.show()">login</div>
+            </div>
+
+        </header>
+        <loginCom ref="loginCom"></loginCom>
     </div>
-  </header>
 </template>
 
 <script>
+
+import loginCom from './login.vue'
+
 export default {
   name: "userHeader",
   data() {
     return {
+      userInfo: {},
       active: "",
       avatar:
         "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F2b22236d-a6e4-4437-b9f6-4ca9a01bac3a%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1682345978&t=f6e3b830ea09df2467363b2681ee65c0",
     };
   },
+  components: { loginCom },
   mounted() {
     setTimeout(() => {
-      if (this.$route.path.indexOf("admin") > -1) {
-        this.active = "admin";
-      } else if (this.$route.name === "home") {
-        this.active = "home";
-      } else {
-        this.active = this.$route.name;
+      this.active = this.$route.name;
+      const userInfoStr = localStorage.getItem('userInfo')
+      if (userInfoStr) {
+        this.userInfo = JSON.parse(userInfoStr)
       }
     }, 300);
   },
   watch: {
     $route(to, from) {
       setTimeout(() => {
-        if (this.$route.path.indexOf("admin") > -1) {
-          this.active = "admin";
-        } else if (this.$route.name === "home") {
-          this.active = "home";
-        } else {
-          this.active = this.$route.name;
-        }
+        this.active = this.$route.name;
       }, 300);
     },
   },
   methods: {
-    print() {
-      console.log(this.$route);
-    },
     toLogin() {
       console.log(61);
     },
+    toNewPage(name) {
+      // 判断是否登录
+      if (!this.userInfo?.id && name !== 'home') {
+        this.$refs.loginCom.show()
+        return
+      }
+      this.$router.push({
+        path: `/${name}`
+      })
+    }
   },
 };
 </script>
 <style lang="less" scoped>
-.header {
-  margin-bottom: -350px;
-  .theme {
+.header-box {
+  color: #ffffff;
+  background-color: rgb(16, 126, 100);;
+  font-size: 34px;
+  display: flex;
+  padding: 10px 40px;
+  flex-direction: row;
+  transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
+  box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 4px -1px, rgba(0, 0, 0, 0.14) 0px 4px 5px 0px, rgba(0, 0, 0, 0.12) 0px 1px 10px 0px;
+  position: fixed;
+  z-index: 100;
+  right: 0;
+  left: 0;
+  top: 0;
+  .logo {
+    margin-right: 40px;
+  }
+
+  .nav-box {
+    font-size: 20px;
     display: flex;
+    margin-right: 30px;
     align-items: center;
+    font-weight: bold;
+
+    .item {
+      margin-right: 24px;
+      cursor: pointer;
+      transition: all ease 50ms;
+
+      &.active {
+        color: #f6903d;
+        position: relative;
+
+        &:after {
+          content: "";
+          position: absolute;
+          width: 100%;
+          height: 2px;
+          background-color: #f6903d;
+          bottom: -20px;
+          left: 0;
+          right: 0;
+        }
+      }
+    }
   }
-  &.home {
-  }
-  &.admin {
-    height: 65px;
+
+  .user-box {
+    color: #ffffff;
+    font-size: 24px;
+    line-height: 46.5px;
+    align-items: center;
+
+    .login {
+        cursor: pointer;
+    }
+
+    //font-size: ;
   }
 }
 </style>

+ 3 - 1
ClientPlatform/src/main.js

@@ -2,13 +2,15 @@ import Vue from "vue";
 import VueRouter from "vue-router";
 import ElementUI from "element-ui";
 import "element-ui/lib/theme-chalk/index.css";
+import VXETable from 'vxe-table'
+import 'vxe-table/lib/style.css'
 import App from "./App.vue";
 import router from "./router";
 import "./style.less";
 Vue.config.productionTip = false;
 Vue.use(VueRouter);
 Vue.use(ElementUI);
-
+Vue.use(VXETable)
 new Vue({
   router,
   render: (h) => h(App),

+ 122 - 324
ClientPlatform/src/pages/home/home.vue

@@ -1,137 +1,65 @@
 <template>
-  <div class="home-box">
-    <el-row type="flex" justify="space-between" class="event-box">
-      <el-col :span="18" class="sort-box">
-        <el-row type="flex">
-          <el-col :span="4" :class="active === 'views' && 'active'"
-            ><span @click="getList('views')">浏览量排序</span></el-col
-          >
-          <el-col :span="4" :class="active === 'likes' && 'active'"
-            ><span @click="getList('likes')">点赞量排序</span></el-col
-          >
-          <el-col :span="4" :class="active === 'comments' && 'active'"
-            ><span @click="getList('comments')">评论数排序</span></el-col
-          >
-          <el-col :span="5" :class="active === 'time' && 'active'"
-            ><span @click="getList('time')">发布时间排序</span></el-col
-          >
-        </el-row>
-      </el-col>
-      <el-col :span="6">
-        <el-input
-          placeholder="请输入内容"
-          v-model="searchText"
-          @keyup.enter="search()"
-        >
-          <el-button slot="append" @click="search()">搜索</el-button>
-        </el-input>
-      </el-col>
-    </el-row>
-    <div class="body-box" v-if="blogsList.length">
-      <div class="bolg-box">
-        <div class="list-box">
-          <div
-            @click="showDetail(item.id)"
-            class="item"
-            v-for="(item, index) in blogsList"
-            :key="index"
-          >
-            <img :src="item.image" alt="" />
-            <div>{{ item.name }}</div>
-          </div>
-        </div>
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="size"
-          :total="total"
-          @current-change="sizeChange"
-          :pager-count="this.pageSize"
-        >
-        </el-pagination>
-      </div>
-      <div class="other-box">
-        <div class="tag-box">
-          <div class="title">热门标签</div>
-          <div class="tags">
-            <span
-              class="tag"
-              :style="{
-                backgroundColor: item.color,
-              }"
-              v-for="item in tags"
-              :key="item.name"
-              @click="searchTag(item.name)"
-            >
-              {{ item.name }}
-            </span>
-          </div>
-        </div>
-        <div class="click-box" v-if="clickList.length">
-          <div class="title">点击排行</div>
-          <div class="list-box">
-            <div
-              class="item"
-              v-for="(item, index) in clickList"
-              :key="index"
-              @click="showDetail(item.id)"
-            >
-              <div v-if="index === 0" class="index">
-                <img :src="item.image" alt="" />
-                <div class="name">{{ item.name }}</div>
-              </div>
-              <div v-else class="other">
-                <img :src="item.image" alt="" />
-                <div class="content">
-                  <div>{{ item.name }}</div>
-                  <div>{{ item.createTime }}</div>
+    <div class="page-box">
+        <div class="swiper-box">
+            <div class="base">
+                <div class="img">
+                    <img src="../../assets/home_0.png" alt="">
+                </div>
+                <div class="text-box">
+                    <div class="title">What is DeepBIO?</div>
+                    <div class="content">DeepBIO is a user-friendly interpretable deep-learning platform for biological sequence functional analysis, such as sequence-level functional prediction and base-wise functional annotation. As for the sequence-level functional prediction, DeepBIO integrates a total of 42 state-of-the-art deep-learning approaches, and enables a one-stop-shop web service for researchers to develop a new deep learning architecture to answer any biological question. To be specific, given any biological sequence data, DeepBIO allows to train and evaluate deep-learning models, conduct model comparison and optimization, and provide a series of visualization analyses. As for the base-wise functional site annotation, DeepBIO offers well-pretrained deep-learning
+                        architectures
+                        for over 20 functional site annotation tasks, supports comprehensive interpretations and graphical visualizations of identified sites, and validates the reliability of the identified sites by conservation motif analysis.
+                    </div>
+                </div>
+            </div>
+            <div class="base">
+
+                <div class="text-box">
+                    <div class="title">What is DeepBIO?</div>
+                    <div class="content">DeepBIO is a user-friendly interpretable deep-learning platform for biological sequence functional analysis, such as sequence-level functional prediction and base-wise functional annotation. As for the sequence-level functional prediction, DeepBIO integrates a total of 42 state-of-the-art deep-learning approaches, and enables a one-stop-shop web service for researchers to develop a new deep learning architecture to answer any biological question. To be specific, given any biological sequence data, DeepBIO allows to train and evaluate deep-learning models, conduct model comparison and optimization, and provide a series of visualization analyses. As for the base-wise functional site annotation, DeepBIO offers well-pretrained deep-learning
+                        architectures
+                        for over 20 functional site annotation tasks, supports comprehensive interpretations and graphical visualizations of identified sites, and validates the reliability of the identified sites by conservation motif analysis.
+                    </div>
+                </div>
+                <div class="img">
+                    <img src="../../assets/home_1.png" alt="">
+                </div>
+            </div>
+            <div class="base">
+                <div class="img">
+                    <img src="../../assets/home_2.png" alt="">
+                </div>
+                <div class="text-box">
+                    <div class="title">What is DeepBIO?</div>
+                    <div class="content">DeepBIO is a user-friendly interpretable deep-learning platform for biological sequence functional analysis, such as sequence-level functional prediction and base-wise functional annotation. As for the sequence-level functional prediction, DeepBIO integrates a total of 42 state-of-the-art deep-learning approaches, and enables a one-stop-shop web service for researchers to develop a new deep learning architecture to answer any biological question. To be specific, given any biological sequence data, DeepBIO allows to train and evaluate deep-learning models, conduct model comparison and optimization, and provide a series of visualization analyses. As for the base-wise functional site annotation, DeepBIO offers well-pretrained deep-learning
+                        architectures
+                        for over 20 functional site annotation tasks, supports comprehensive interpretations and graphical visualizations of identified sites, and validates the reliability of the identified sites by conservation motif analysis.
+                    </div>
                 </div>
-              </div>
             </div>
-          </div>
         </div>
-      </div>
     </div>
-  </div>
 </template>
 <script>
-import axios from "axios";
-import { hotTags, getClicks, getBlogs } from "@/api";
 
 export default {
   name: "home",
+  components: {
+  },
   data() {
     return {
-      /*
-       * active
-       *    浏览量排序: views
-       *    点赞量排序: likes
-       *    评论数排序: comments
-       *    发布时间排序: time
-       * */
-      active: "views",
-      tag: "",
-      searchText: "",
-      tags: [],
-      blogsList: [],
-      clickList: [],
-      color: [
-        "#2B6363",
-        "#DB704D",
-        "#63B4AE",
-        "#EA5368",
-        "#EFA19D",
-        "#E7CA65",
-        "#C7C7AB",
-        "#EA5368",
-        "#EFA19D",
-        "#2B6363",
-        "#DB704D",
-      ],
-      total: 0,
-      pageSize: 15,
-      size: 1,
-    };
+      // modules: [Pagination],
+      swiperOption: {
+        slidesPerView: 1,
+        spaceBetween: 30,
+        direction: "vertical",
+        pagination: {
+          el: '.swiper-pagination',
+          clickable: true
+        }
+      }
+    }
   },
   watch: {
     tags() {
@@ -139,226 +67,96 @@ export default {
     },
   },
   mounted() {
-    setTimeout(() => {
-      if (this.$route.query && this.$route.query.search) {
-        this.searchText = this.$route.query.search;
-      }
-      this.getList("views");
-      this.getTagsFn();
-      this.getClickListFn();
-    }, 200);
   },
   methods: {
-    async getList(type) {
-      if (this.active !== type) {
-        this.active = type;
-      }
-      const params = {
-        sort: this.active,
-        tag: this.tag,
-        searchText: this.searchText,
-        size: this.size,
-        pageSize: this.pageSize,
-      };
-      const res = await getBlogs(params);
-      this.total = res.data.total;
-      this.blogsList = res.data.list;
-    },
-    async getClickListFn() {
-      const res = await getClicks();
-      this.clickList = res.data;
-    },
-    async getTagsFn() {
-      const res = await hotTags();
-      console.log("8080", res);
-      this.tags = res.data.map((item) => {
-        return {
-          name: item,
-          color: this.color[Math.floor(Math.random() * 9)],
-        };
-      });
-    },
-    showDetail(id) {
-      this.$router.push({
-        path: "/blogDetails",
-        query: {
-          id,
-        },
-      });
-    },
-    search() {
-      this.tag = "";
-      this.total = 0;
-      this.pageSize = 15;
-      this.size = 1;
-      this.getList();
-    },
-    searchTag(tag) {
-      this.tag = tag;
-      this.searchText = "";
-      this.total = 0;
-      this.pageSize = 15;
-      this.size = 1;
-      this.getList();
-    },
-    sizeChange(size) {
-      this.size = size;
-      this.getList();
+    onSlideChange() {
+      console.log('111');
     },
+    scroll() {
+      // 获取当前 swiper-wrapper 元素的 left 值,即偏移量
+      const wrapperLeft = this.$refs.mySwiper.wrapperEl.style.left;
+      // 将 left 值转换为数值
+      const left = parseInt(wrapperLeft);
+      // 计算当前滚动位置对应的 slide 的索引值
+      const currentIndex = -left / this.$refs.mySwiper.slidesGrid[0];
+      // 切换到下一个或上一个 slide
+      if (this.$refs.mySwiper.progress > 0.5) {
+        this.$refs.mySwiper.slideNext();
+      } else {
+        this.$refs.mySwiper.slidePrev();
+      }
+    }
   },
 };
 </script>
 
 <style lang="less" scoped>
-.home-box {
-  //background-color: #ffffff;
-  .event-box {
-    padding: 15px 20px;
-    margin-bottom: 20px;
-    background-color: #ffffff;
-    border-radius: 4px;
-    .sort-box {
-      //font-size: 14px;
-      span {
-        &:hover {
-          cursor: pointer;
-        }
-      }
-    }
-    .active {
-      color: #409eff;
-    }
-  }
-  .body-box {
-    display: flex;
-    .bolg-box {
-      flex: 1;
-      .list-box {
+.page-box {
+  .swiper-box {
+    height: calc(100vh - 67px);
+    //overflow: hidden;
+    //position: relative;
+
+    .base {
+      width: 100%;
+      //height: 100%;
+      height: calc(80vh - 67px);
+      padding: 20px 50px;
+      box-sizing: border-box;
+      display: flex;
+      //flex-direction: row;
+      //align-items: center;
+
+      .img {
+        box-sizing: border-box;
         display: flex;
-        flex-wrap: wrap;
-        .item {
-          //width: 300px;
-          background-color: #ffffff;
-          flex: 1 1 260px;
-          margin-right: 15px;
-          margin-bottom: 15px;
-          img {
-            cursor: pointer;
-          }
-        }
+        align-items: center;
+        justify-content: center;
+        width: 35%;
+
         img {
+          width: 100%;
+          display: block;
         }
       }
-    }
-    .other-box {
-      .tag-box {
-        border-radius: 4px;
-        width: 280px;
-        background-color: #f8f9fb;
-        margin-bottom: 24px;
-        .title {
-          text-align: left;
-          padding-left: 5px;
 
-          &:before {
-            content: "";
-            display: block;
-            position: relative;
-            top: 35px;
-            width: 85px;
-            height: 2px;
-            border-radius: 4px;
-            background: #2c3e50;
-          }
+      .text-box {
+        box-sizing: border-box;
+        flex: 1;
+        padding: 40px;
+        text-align: left;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+
+        .title {
+          box-sizing: border-box;
+          margin: 20px 0;
+          //margin: 0px;
+          font-family: Roboto, Helvetica, Arial, sans-serif;
+          font-size: 2.125rem;
+          line-height: 1.235;
+          letter-spacing: 0.00735em;
+          font-weight: 700;
         }
-        .tags {
-          padding: 0 5px;
-          text-align: left;
-          min-height: 150px;
-          .tag {
-            font-size: 14px;
-            color: #ffffff;
-            cursor: pointer;
-            padding: 1px 5px;
-            border-radius: 4px;
-            margin-right: 5px;
-            margin-bottom: 5px;
-            display: inline-block;
-            transition: all 0.3ms;
-            &:hover {
-              color: #409eff;
-            }
-          }
+
+        .content {
+          box-sizing: border-box;
+          width: 100%;
         }
+
       }
-      .click-box {
-        border-radius: 4px;
-        width: 280px;
-        background-color: #f8f9fb;
-        .title {
-          text-align: left;
-          padding-left: 5px;
 
-          &:before {
-            content: "";
-            display: block;
-            position: relative;
-            top: 35px;
-            width: 85px;
-            height: 2px;
-            border-radius: 4px;
-            background: #2c3e50;
-          }
-        }
-        .list-box {
-          //height: 250px;
-          min-height: 250px;
-          max-height: 470px;
-          //max-height: 50vh;
-          padding: 5px;
-          overflow: scroll;
-          background-color: #f8f9fb;
-          .item {
-            cursor: pointer;
-            .index {
-              margin-bottom: 5px;
-              img {
-                cursor: pointer;
-              }
-              .name {
-                transition: color ease-in-out 0.3s;
-                background-color: #000000;
-                color: #ffffff;
-              }
-              &:hover {
-                .name {
-                  color: #409eff;
-                }
-              }
-            }
-            .other {
-              display: flex;
-              margin-bottom: 10px;
-              img {
-                cursor: pointer;
-                width: 70px;
-                height: 70px;
-              }
-              .content {
-                text-align: left;
-                color: #333;
-                padding-left: 10px;
-                font-size: 18px;
-              }
-              &:hover {
-                .content {
-                  color: #409eff;
-                }
-              }
-            }
-          }
-        }
+      .text {
+        flex: 1;
+        display: flex;
+        align-items: center;
       }
+
+    }
+
+    .other-box {
+      margin-top: 1px;
     }
   }
 }

+ 274 - 0
ClientPlatform/src/pages/order/order.vue

@@ -0,0 +1,274 @@
+<template>
+  <div class="page-box">
+      order
+  </div>
+</template>
+<script>
+import axios from "axios";
+import { hotTags, getClicks, getBlogs } from "@/api";
+
+export default {
+  name: "home",
+  data() {
+    return {
+      /*
+       * active
+       *    浏览量排序: views
+       *    点赞量排序: likes
+       *    评论数排序: comments
+       *    发布时间排序: time
+       * */
+      active: "views",
+      tag: "",
+      searchText: "",
+      tags: [],
+      blogsList: [],
+      clickList: [],
+      color: [
+        "#2B6363",
+        "#DB704D",
+        "#63B4AE",
+        "#EA5368",
+        "#EFA19D",
+        "#E7CA65",
+        "#C7C7AB",
+        "#EA5368",
+        "#EFA19D",
+        "#2B6363",
+        "#DB704D",
+      ],
+      total: 0,
+      pageSize: 15,
+      size: 1,
+    };
+  },
+  watch: {
+    tags() {
+      console.log(119);
+    },
+  },
+  mounted() {
+    setTimeout(() => {
+      if (this.$route.query && this.$route.query.search) {
+        this.searchText = this.$route.query.search;
+      }
+      this.getList("views");
+      this.getTagsFn();
+      this.getClickListFn();
+    }, 200);
+  },
+  methods: {
+    async getList(type) {
+      if (this.active !== type) {
+        this.active = type;
+      }
+      const params = {
+        sort: this.active,
+        tag: this.tag,
+        searchText: this.searchText,
+        size: this.size,
+        pageSize: this.pageSize,
+      };
+      const res = await getBlogs(params);
+      this.total = res.data.total;
+      this.blogsList = res.data.list;
+    },
+    async getClickListFn() {
+      const res = await getClicks();
+      this.clickList = res.data;
+    },
+    async getTagsFn() {
+      const res = await hotTags();
+      console.log("8080", res);
+      this.tags = res.data.map((item) => {
+        return {
+          name: item,
+          color: this.color[Math.floor(Math.random() * 9)],
+        };
+      });
+    },
+    showDetail(id) {
+      this.$router.push({
+        path: "/blogDetails",
+        query: {
+          id,
+        },
+      });
+    },
+    search() {
+      this.tag = "";
+      this.total = 0;
+      this.pageSize = 15;
+      this.size = 1;
+      this.getList();
+    },
+    searchTag(tag) {
+      this.tag = tag;
+      this.searchText = "";
+      this.total = 0;
+      this.pageSize = 15;
+      this.size = 1;
+      this.getList();
+    },
+    sizeChange(size) {
+      this.size = size;
+      this.getList();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.home-box {
+  //background-color: #ffffff;
+  .event-box {
+    padding: 15px 20px;
+    margin-bottom: 20px;
+    background-color: #ffffff;
+    border-radius: 4px;
+    .sort-box {
+      //font-size: 14px;
+      span {
+        &:hover {
+          cursor: pointer;
+        }
+      }
+    }
+    .active {
+      color: #409eff;
+    }
+  }
+  .body-box {
+    display: flex;
+    .bolg-box {
+      flex: 1;
+      .list-box {
+        display: flex;
+        flex-wrap: wrap;
+        .item {
+          //width: 300px;
+          background-color: #ffffff;
+          flex: 1 1 260px;
+          margin-right: 15px;
+          margin-bottom: 15px;
+          img {
+            cursor: pointer;
+          }
+        }
+        img {
+        }
+      }
+    }
+    .other-box {
+      .tag-box {
+        border-radius: 4px;
+        width: 280px;
+        background-color: #f8f9fb;
+        margin-bottom: 24px;
+        .title {
+          text-align: left;
+          padding-left: 5px;
+
+          &:before {
+            content: "";
+            display: block;
+            position: relative;
+            top: 35px;
+            width: 85px;
+            height: 2px;
+            border-radius: 4px;
+            background: #2c3e50;
+          }
+        }
+        .tags {
+          padding: 0 5px;
+          text-align: left;
+          min-height: 150px;
+          .tag {
+            font-size: 14px;
+            color: #ffffff;
+            cursor: pointer;
+            padding: 1px 5px;
+            border-radius: 4px;
+            margin-right: 5px;
+            margin-bottom: 5px;
+            display: inline-block;
+            transition: all 0.3ms;
+            &:hover {
+              color: #409eff;
+            }
+          }
+        }
+      }
+      .click-box {
+        border-radius: 4px;
+        width: 280px;
+        background-color: #f8f9fb;
+        .title {
+          text-align: left;
+          padding-left: 5px;
+
+          &:before {
+            content: "";
+            display: block;
+            position: relative;
+            top: 35px;
+            width: 85px;
+            height: 2px;
+            border-radius: 4px;
+            background: #2c3e50;
+          }
+        }
+        .list-box {
+          //height: 250px;
+          min-height: 250px;
+          max-height: 470px;
+          //max-height: 50vh;
+          padding: 5px;
+          overflow: scroll;
+          background-color: #f8f9fb;
+          .item {
+            cursor: pointer;
+            .index {
+              margin-bottom: 5px;
+              img {
+                cursor: pointer;
+              }
+              .name {
+                transition: color ease-in-out 0.3s;
+                background-color: #000000;
+                color: #ffffff;
+              }
+              &:hover {
+                .name {
+                  color: #409eff;
+                }
+              }
+            }
+            .other {
+              display: flex;
+              margin-bottom: 10px;
+              img {
+                cursor: pointer;
+                width: 70px;
+                height: 70px;
+              }
+              .content {
+                text-align: left;
+                color: #333;
+                padding-left: 10px;
+                font-size: 18px;
+              }
+              &:hover {
+                .content {
+                  color: #409eff;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 274 - 0
ClientPlatform/src/pages/server/server.vue

@@ -0,0 +1,274 @@
+<template>
+  <div class="page-box">
+      server
+  </div>
+</template>
+<script>
+import axios from "axios";
+import { hotTags, getClicks, getBlogs } from "@/api";
+
+export default {
+  name: "home",
+  data() {
+    return {
+      /*
+       * active
+       *    浏览量排序: views
+       *    点赞量排序: likes
+       *    评论数排序: comments
+       *    发布时间排序: time
+       * */
+      active: "views",
+      tag: "",
+      searchText: "",
+      tags: [],
+      blogsList: [],
+      clickList: [],
+      color: [
+        "#2B6363",
+        "#DB704D",
+        "#63B4AE",
+        "#EA5368",
+        "#EFA19D",
+        "#E7CA65",
+        "#C7C7AB",
+        "#EA5368",
+        "#EFA19D",
+        "#2B6363",
+        "#DB704D",
+      ],
+      total: 0,
+      pageSize: 15,
+      size: 1,
+    };
+  },
+  watch: {
+    tags() {
+      console.log(119);
+    },
+  },
+  mounted() {
+    setTimeout(() => {
+      if (this.$route.query && this.$route.query.search) {
+        this.searchText = this.$route.query.search;
+      }
+      this.getList("views");
+      this.getTagsFn();
+      this.getClickListFn();
+    }, 200);
+  },
+  methods: {
+    async getList(type) {
+      if (this.active !== type) {
+        this.active = type;
+      }
+      const params = {
+        sort: this.active,
+        tag: this.tag,
+        searchText: this.searchText,
+        size: this.size,
+        pageSize: this.pageSize,
+      };
+      const res = await getBlogs(params);
+      this.total = res.data.total;
+      this.blogsList = res.data.list;
+    },
+    async getClickListFn() {
+      const res = await getClicks();
+      this.clickList = res.data;
+    },
+    async getTagsFn() {
+      const res = await hotTags();
+      console.log("8080", res);
+      this.tags = res.data.map((item) => {
+        return {
+          name: item,
+          color: this.color[Math.floor(Math.random() * 9)],
+        };
+      });
+    },
+    showDetail(id) {
+      this.$router.push({
+        path: "/blogDetails",
+        query: {
+          id,
+        },
+      });
+    },
+    search() {
+      this.tag = "";
+      this.total = 0;
+      this.pageSize = 15;
+      this.size = 1;
+      this.getList();
+    },
+    searchTag(tag) {
+      this.tag = tag;
+      this.searchText = "";
+      this.total = 0;
+      this.pageSize = 15;
+      this.size = 1;
+      this.getList();
+    },
+    sizeChange(size) {
+      this.size = size;
+      this.getList();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.home-box {
+  //background-color: #ffffff;
+  .event-box {
+    padding: 15px 20px;
+    margin-bottom: 20px;
+    background-color: #ffffff;
+    border-radius: 4px;
+    .sort-box {
+      //font-size: 14px;
+      span {
+        &:hover {
+          cursor: pointer;
+        }
+      }
+    }
+    .active {
+      color: #409eff;
+    }
+  }
+  .body-box {
+    display: flex;
+    .bolg-box {
+      flex: 1;
+      .list-box {
+        display: flex;
+        flex-wrap: wrap;
+        .item {
+          //width: 300px;
+          background-color: #ffffff;
+          flex: 1 1 260px;
+          margin-right: 15px;
+          margin-bottom: 15px;
+          img {
+            cursor: pointer;
+          }
+        }
+        img {
+        }
+      }
+    }
+    .other-box {
+      .tag-box {
+        border-radius: 4px;
+        width: 280px;
+        background-color: #f8f9fb;
+        margin-bottom: 24px;
+        .title {
+          text-align: left;
+          padding-left: 5px;
+
+          &:before {
+            content: "";
+            display: block;
+            position: relative;
+            top: 35px;
+            width: 85px;
+            height: 2px;
+            border-radius: 4px;
+            background: #2c3e50;
+          }
+        }
+        .tags {
+          padding: 0 5px;
+          text-align: left;
+          min-height: 150px;
+          .tag {
+            font-size: 14px;
+            color: #ffffff;
+            cursor: pointer;
+            padding: 1px 5px;
+            border-radius: 4px;
+            margin-right: 5px;
+            margin-bottom: 5px;
+            display: inline-block;
+            transition: all 0.3ms;
+            &:hover {
+              color: #409eff;
+            }
+          }
+        }
+      }
+      .click-box {
+        border-radius: 4px;
+        width: 280px;
+        background-color: #f8f9fb;
+        .title {
+          text-align: left;
+          padding-left: 5px;
+
+          &:before {
+            content: "";
+            display: block;
+            position: relative;
+            top: 35px;
+            width: 85px;
+            height: 2px;
+            border-radius: 4px;
+            background: #2c3e50;
+          }
+        }
+        .list-box {
+          //height: 250px;
+          min-height: 250px;
+          max-height: 470px;
+          //max-height: 50vh;
+          padding: 5px;
+          overflow: scroll;
+          background-color: #f8f9fb;
+          .item {
+            cursor: pointer;
+            .index {
+              margin-bottom: 5px;
+              img {
+                cursor: pointer;
+              }
+              .name {
+                transition: color ease-in-out 0.3s;
+                background-color: #000000;
+                color: #ffffff;
+              }
+              &:hover {
+                .name {
+                  color: #409eff;
+                }
+              }
+            }
+            .other {
+              display: flex;
+              margin-bottom: 10px;
+              img {
+                cursor: pointer;
+                width: 70px;
+                height: 70px;
+              }
+              .content {
+                text-align: left;
+                color: #333;
+                padding-left: 10px;
+                font-size: 18px;
+              }
+              &:hover {
+                .content {
+                  color: #409eff;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 113 - 0
ClientPlatform/src/pages/task/task.vue

@@ -0,0 +1,113 @@
+<template>
+    <div class="page-box">
+        <div class="search-box">
+            <el-input placeholder="任务Id"></el-input>&nbsp;&nbsp;
+            <el-button type="primary" icon="el-icon-search">搜索</el-button>
+        </div>
+        <div>
+            <vxe-table
+                    show-overflow
+                    height="200"
+                    row-id="id"
+                    :loading="loading1"
+                    :data="tableData1">
+                <vxe-column type="checkbox" width="60"></vxe-column>
+                <vxe-column type="seq" title="序号" width="60"></vxe-column>
+                <vxe-column field="name" title="Name" sortable></vxe-column>
+                <vxe-column field="sex" title="Sex"></vxe-column>
+                <vxe-column field="age" title="Age"></vxe-column>
+                <vxe-column field="rate" title="Rate"></vxe-column>
+            </vxe-table>
+
+            <vxe-pager
+                    :loading="loading1"
+                    :current-page="tablePage1.currentPage"
+                    :page-size="tablePage1.pageSize"
+                    :total="tablePage1.totalResult"
+                    :layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
+                    @page-change="handlePageChange1">
+            </vxe-pager>
+        </div>
+
+    </div>
+
+</template>
+<script>
+import axios from "axios";
+import { hotTags, getClicks, getBlogs } from "@/api";
+import "element-ui/lib/theme-chalk/index.css";
+
+export default {
+  name: 'task',
+  data() {
+    return {
+      loading1: false,
+      tableData1: [],
+      tablePage1: {
+        currentPage: 1,
+        pageSize: 10,
+        totalResult: 0
+      }
+    }
+  },
+  created() {
+    this.findList1()
+  },
+  methods: {
+    findList1() {
+      this.loading1 = true
+      setTimeout(() => {
+        const list = [
+          { id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: '1', age: 28, address: 'Shenzhen' },
+          { id: 10002, name: 'Test2', nickname: 'T2', role: 'Test', sex: '0', age: 22, address: 'Guangzhou' },
+          { id: 10003, name: 'Test3', nickname: 'T3', role: 'PM', sex: '1', age: 32, address: 'Shanghai' },
+          { id: 10004, name: 'Test4', nickname: 'T4', role: 'Designer', sex: '0', age: 23, address: 'Shenzhen' },
+          { id: 10005, name: 'Test5', nickname: 'T5', role: 'Develop', sex: '0', age: 30, address: 'Shanghai' },
+          { id: 10006, name: 'Test6', nickname: 'T6', role: 'Develop', sex: '0', age: 27, address: 'Shanghai' },
+          { id: 10007, name: 'Test7', nickname: 'T1', role: 'Develop', sex: '1', age: 28, address: 'Shenzhen' },
+          { id: 10008, name: 'Test8', nickname: 'T2', role: 'Test', sex: '0', age: 22, address: 'Guangzhou' },
+          { id: 10009, name: 'Test9', nickname: 'T3', role: 'PM', sex: '1', age: 32, address: 'Shanghai' },
+          { id: 100010, name: 'Test10', nickname: 'T4', role: 'Designer', sex: '0', age: 23, address: 'Shenzhen' },
+          { id: 100011, name: 'Test11', nickname: 'T5', role: 'PM', sex: '0', age: 35, address: 'Shenzhen' },
+          { id: 100012, name: 'Test12', nickname: 'T6', role: 'Designer', sex: '1', age: 25, address: 'Shanghai' },
+          { id: 100013, name: 'Test13', nickname: 'T9', role: 'Develop', sex: '1', age: 33, address: 'Shenzhen' },
+          { id: 100014, name: 'Test14', nickname: 'T6', role: 'Develop', sex: '0', age: 21, address: 'Shanghai' },
+          { id: 100015, name: 'Test15', nickname: 'T6', role: 'Develop', sex: '0', age: 19, address: 'Shanghai' },
+          { id: 100016, name: 'Test16', nickname: 'T8', role: 'Develop', sex: '1', age: 29, address: 'Shenzhen' }
+        ]
+        this.loading1 = false
+        this.tablePage1.totalResult = list.length
+        this.tableData1 = list.slice((this.tablePage1.currentPage - 1) * this.tablePage1.pageSize, this.tablePage1.currentPage * this.tablePage1.pageSize)
+        console.log(this.tableData1)
+      }, 300)
+    },
+    handlePageChange1({ currentPage, pageSize }) {
+      this.tablePage1.currentPage = currentPage
+      this.tablePage1.pageSize = pageSize
+      this.findList1()
+    }
+  }
+};
+</script>
+
+<style lang="less" scoped>
+.page-box {
+  padding: 0 24px;
+  margin-top: 67px;
+  height: calc(100vh - 68px);
+
+  .search-box {
+    display: flex;
+      margin-top: 24px;
+      padding-top: 24px;
+      margin-bottom: 24px;
+  }
+
+  .list-box {
+    //margin-top: 24px;
+    //  box-sizing: border-box;
+    //  height: 300px;
+    //  width: 100%;
+  }
+}
+</style>

+ 15 - 0
ClientPlatform/src/router.js

@@ -7,6 +7,21 @@ const routes = [
     name: "home",
     component: () => import("./pages/home/home.vue"),
   },
+  {
+    path: "/server",
+    name: "server",
+    component: () => import("./pages/server/server.vue"),
+  },
+  {
+    path: "/order",
+    name: "order",
+    component: () => import("./pages/order/order.vue"),
+  },
+  {
+    path: "/task",
+    name: "task",
+    component: () => import("./pages/task/task.vue"),
+  },
   {
     path: "/blogDetails",
     name: "blogDetails",

+ 5 - 2
ClientPlatform/src/style.less

@@ -1,5 +1,8 @@
-@bg-color: #f8f9fb;
+@bg-color: rgb(16, 126, 100);
 
 body {
-  background-color: @bg-color;
+  //background-color: @bg-color;
+  padding: 0;
+  margin: 0;
+  
 }

+ 12 - 2
ClientPlatform/yarn.lock

@@ -3365,9 +3365,9 @@ electron-to-chromium@^1.4.284:
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.348.tgz#f49379dc212d79f39112dd026f53e371279e433d"
   integrity sha512-gM7TdwuG3amns/1rlgxMbeeyNoBFPa+4Uu0c7FeROWh4qWmvSOnvcslKmWy51ggLKZ2n/F/4i2HJ+PVNxH9uCQ==
 
-element-ui@^2.15.13:
+element-ui@^2.7.2:
   version "2.15.13"
-  resolved "https://registry.yarnpkg.com/element-ui/-/element-ui-2.15.13.tgz#380f019ee7d15b181105587b41fd5914c308a143"
+  resolved "https://registry.npmmirror.com/element-ui/-/element-ui-2.15.13.tgz#380f019ee7d15b181105587b41fd5914c308a143"
   integrity sha512-LJoatEYX6WV74FqXBss8Xfho9fh9rjDSzrDrTyREdGb1h1R3uRvmLh5jqp2JU137aj4/BgqA3K06RQpQBX33Bg==
   dependencies:
     async-validator "~1.8.1"
@@ -8418,6 +8418,11 @@ vue@^2.6.11:
     "@vue/compiler-sfc" "2.7.14"
     csstype "^3.1.0"
 
+vxe-table@^3.6.11:
+  version "3.6.11"
+  resolved "https://registry.npmmirror.com/vxe-table/-/vxe-table-3.6.11.tgz#e95da0507b37082e6d4881d274e5fee2760ad7f0"
+  integrity sha512-0qkxmbV0RkciRn4YL7eQVQ1YODmw1RP2WUg2wfk6Y3XGdQGBBpKCuWrv/GfCFrTtfWoHKo9Hs6I2MZsZ5LkAUA==
+
 watchpack-chokidar2@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957"
@@ -8690,6 +8695,11 @@ ws@^8.13.0:
   resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0"
   integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==
 
+xe-utils@^3.5.7:
+  version "3.5.7"
+  resolved "https://registry.npmmirror.com/xe-utils/-/xe-utils-3.5.7.tgz#2c885852dfadd5c8beeffdc1f884f8ceb962c669"
+  integrity sha512-3H+fDBKBR2wLJgyA7k9C/w1Xljx6Maml5ukV0WDY06HjYyGs2FEz6XhcwRCLIDXX4pBP3Gu0nX9DbCeuuRA2Ew==
+
 xtend@^4.0.0, xtend@~4.0.1:
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"

+ 2 - 0
README.md

@@ -2,6 +2,8 @@
 
 https://docs.djangoproject.com/zh-hans/4.0/intro/tutorial01/
 
+https://inner.wei-group.net/DeepBIO/#/
+
 ## 项目说明
 
 ### 安装 django