daisy 5 år sedan
förälder
incheckning
b3dcb73cf7

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+.DS_Store
+node_modules
+/dist
+package-lock.json
+
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 32 - 1
README.md

@@ -1 +1,32 @@
-# seec-bok-frontend
+# seek-bok-frontend
+
+## Project setup
+```
+npm install --registry=https://registry.npm.taobao.org
+```
+
+### Compiles and hot-reloads for development
+```
+npm run serve
+```
+
+### Compiles and minifies for production
+```
+npm run build
+```
+
+### Run your unit tests
+```
+npm run test:unit
+```
+
+### Customize configuration
+See [Configuration Reference](https://cli.vuejs.org/config/).
+
+
+### 可能出现的报错
+
+#### node-sass错误 
+``` 
+npm install node-sass@4.x --registry=https://registry.npm.taobao.org
+```

+ 5 - 0
babel.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ]
+}

+ 34 - 0
package.json

@@ -0,0 +1,34 @@
+{
+  "name": "seek-bok-frontend",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "test:unit": "vue-cli-service test:unit"
+  },
+  "dependencies": {
+    "core-js": "^3.6.5",
+    "element-plus": "^1.0.2-beta.70",
+    "node-sass": "^4.14.1",
+    "vue": "^3.0.0",
+    "vue-router": "^4.0.0-0",
+    "vuex": "^4.0.0-0"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.0",
+    "@vue/cli-plugin-router": "~4.5.0",
+    "@vue/cli-plugin-unit-mocha": "~4.5.0",
+    "@vue/cli-plugin-vuex": "~4.5.0",
+    "@vue/cli-service": "~4.5.0",
+    "@vue/compiler-sfc": "^3.0.0",
+    "@vue/test-utils": "^2.0.0-0",
+    "chai": "^4.1.2",
+    "sass-loader": "^8.0.2"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not dead"
+  ]
+}

BIN
public/favicon.ico


+ 17 - 0
public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title><%= htmlWebpackPlugin.options.title %></title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 44 - 0
src/App.vue

@@ -0,0 +1,44 @@
+<template>
+  <!--  <div id="nav">-->
+  <!--    <router-link to="/home">Home</router-link> |-->
+  <!--    <router-link to="/about">About</router-link>-->
+  <!--  </div>-->
+  <router-view/>
+</template>
+
+
+<style>
+  #app {
+    font-family: Avenir, Helvetica, Arial, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+    text-align: center;
+    color: #2c3e50;
+  }
+
+  #nav {
+    padding: 30px;
+  }
+
+  #nav a {
+    font-weight: bold;
+    color: #2c3e50;
+  }
+
+  #nav a.router-link-exact-active {
+    color: #42b983;
+  }
+
+  html{
+    height: 100%;
+  }
+
+  body{
+    margin: 0px;
+    height: 100%;
+  }
+
+  #app{
+    height: 100%;
+  }
+</style>

BIN
src/assets/logo.png


BIN
src/assets/seec-logo--full.png


+ 60 - 0
src/components/HelloWorld.vue

@@ -0,0 +1,60 @@
+<template>
+  <div class="hello">
+    <h1>{{ msg }}</h1>
+    <p>
+      For a guide and recipes on how to configure / customize this project,<br>
+      check out the
+      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
+    </p>
+    <h3>Installed CLI Plugins</h3>
+    <ul>
+      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
+      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
+      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
+      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-mocha" target="_blank" rel="noopener">unit-mocha</a></li>
+    </ul>
+    <h3>Essential Links</h3>
+    <ul>
+      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
+      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
+      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
+      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
+      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
+    </ul>
+    <h3>Ecosystem</h3>
+    <ul>
+      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
+      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
+      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
+      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
+      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
+    </ul>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'HelloWorld',
+  props: {
+    msg: String
+  }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+h3 {
+  margin: 40px 0 0;
+}
+ul {
+  list-style-type: none;
+  padding: 0;
+}
+li {
+  display: inline-block;
+  margin: 0 10px;
+}
+a {
+  color: #42b983;
+}
+</style>

+ 13 - 0
src/components/bok/BokMain.vue

@@ -0,0 +1,13 @@
+<template>
+  <router-view :key="$route.path"/>
+</template>
+
+<script>
+export default {
+  name: "BokMain",
+}
+</script>
+
+<style scoped>
+
+</style>

+ 72 - 0
src/components/bok/NavBar.vue

@@ -0,0 +1,72 @@
+<template>
+  <div class="navbar-wrapper">
+    <el-breadcrumb separator-class="el-icon-arrow-right">
+      <el-breadcrumb-item v-for="(p, i) in path" :key="'p-' + i" :to="toBreadcrumbLink(p)">{{ p }}</el-breadcrumb-item>
+    </el-breadcrumb>
+    <el-dropdown trigger="click" style="position: absolute;top: 0px;right: 0px">
+      <el-avatar shape="square" :size="30" :src="squareUrl"></el-avatar>
+      <template #dropdown>
+        <el-dropdown-menu>
+          <el-dropdown-item>选项1</el-dropdown-item>
+          <el-dropdown-item>选项2</el-dropdown-item>
+          <el-dropdown-item>选项3</el-dropdown-item>
+          <el-dropdown-item>选项4</el-dropdown-item>
+        </el-dropdown-menu>
+      </template>
+    </el-dropdown>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "NavBar",
+  data() {
+    return {
+      systemName: "bok",
+      squareUrl: "https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png",
+    }
+  },
+  computed:{
+    path(){
+      const _this = this
+      let res = _this.$store.getters['bok/getPath'].split("/")
+      res[0] = _this.systemName
+      return res
+    }
+  },
+  mounted() {
+    const _this = this;
+
+    _this.path = _this.$route.path.split("/");
+    _this.path[0] = _this.systemName;
+  },
+  methods: {
+    toBreadcrumbLink(p) {
+      const _this = this;
+      return ""
+    },
+  },
+}
+</script>
+
+<style scoped>
+.navbar-wrapper {
+  height: 50px;
+  box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+  position: relative;
+}
+
+.el-breadcrumb {
+  height: calc(100% - 30px);
+  padding: 15px;
+  font-size: 20px;
+}
+
+.el-avatar {
+  margin: 10px;
+}
+
+.el-avatar:hover{
+  cursor: pointer;
+}
+</style>

+ 92 - 0
src/components/bok/SideBar.vue

@@ -0,0 +1,92 @@
+<template>
+  <div class="sidebar-wrapper">
+    <a href="https://p.seec.seecoder.cn/" target="view_window">
+      <img alt="Seecoder logo" src="../../assets/seec-logo--full.png" class="logo">
+    </a>
+    <el-menu
+        default-active="completion"
+        class="el-menu-vertical-demo"
+        @select="handleSelect"
+        @open="handleOpen"
+        @close="handleClose">
+      <el-menu-item index="questionSearch">
+        <i class="el-icon-search"></i>
+        <template #title>搜索</template>
+      </el-menu-item>
+      <el-menu-item index="questionRepository">
+        <i class="el-icon-menu"></i>
+        <template #title>题库</template>
+      </el-menu-item>
+      <el-menu-item index="completion">
+        <i class="el-icon-notebook-1"></i>
+        <template #title>已做</template>
+      </el-menu-item>
+      <el-menu-item index="collection">
+        <i class="el-icon-collection"></i>
+        <template #title>收藏</template>
+      </el-menu-item>
+      <el-menu-item index="setting">
+        <i class="el-icon-setting"></i>
+        <template #title>设置</template>
+      </el-menu-item>
+    </el-menu>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "SideBar",
+  methods: {
+    handleOpen(key, keyPath) {
+      console.log(key, keyPath);
+    },
+    handleClose(key, keyPath) {
+      console.log(key, keyPath);
+    },
+
+    // bok主页,侧边栏选择
+    handleSelect(index){
+      this.$router.push('/' + index)
+    },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import "../../style/variables";
+
+.sidebar-wrapper {
+  position: relative;
+  width: $sideBarWidth;
+  height: 100%;
+  /*margin: 0px;*/
+  float: left;
+  background-color: #ecf5ff;
+}
+
+.el-menu {
+  --el-menu-background-color: #ecf5ff;
+  --el-menu-item-hover-fill: #ffffff;
+}
+
+.el-menu-vertical-demo {
+  border-right: unset;
+}
+
+.el-menu-item {
+  font-size: 16px;
+}
+
+li.el-menu-item.is-active {
+  background-color: #ffffff;
+}
+
+.logo {
+  margin-top: 9px;
+  margin-bottom: 9px;
+  height: 30px;
+  //position: absolute;
+  //top: 10px;
+  //right: 10px;
+}
+</style>

+ 15 - 0
src/components/bok/bokMain/Collection.vue

@@ -0,0 +1,15 @@
+<template>
+<div>
+  <h1>Collection</h1>
+</div>
+</template>
+
+<script>
+export default {
+  name: "Collection"
+}
+</script>
+
+<style scoped>
+
+</style>

+ 15 - 0
src/components/bok/bokMain/Completion.vue

@@ -0,0 +1,15 @@
+<template>
+<div>
+  <h1>Completion</h1>
+</div>
+</template>
+
+<script>
+export default {
+  name: "Completion"
+}
+</script>
+
+<style scoped>
+
+</style>

+ 13 - 0
src/components/bok/bokMain/Example.vue

@@ -0,0 +1,13 @@
+<template>
+  <div><h1>Example</h1></div>
+</template>
+
+<script>
+export default {
+  name: "example"
+}
+</script>
+
+<style scoped>
+
+</style>

+ 69 - 0
src/components/bok/bokMain/QuestionRepository.vue

@@ -0,0 +1,69 @@
+<template>
+  <div class="question-repository">
+    <h1>Question Repository</h1>
+    <ul>
+      <li v-for="(item, index) in packages">
+        <question-package :name="item.name" :description="item.description"
+        :logo="item.logo" :user="item.user"/>
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script>
+import QuestionPackage from '@/components/bok/bokMain/qR/QuestionPackage'
+
+export default {
+  name: "QuestionRepository",
+  components:{
+    "question-package":QuestionPackage,
+  },
+  data(){
+    return {
+      packages:[
+        {
+          name: 'java',
+          description: 'thinking in java',
+          logo: 'https://mjh1.oss-cn-hangzhou.aliyuncs.com/seecoder/good.png',
+          user: "user1",
+        },
+        {
+          name: 'c',
+          description: 'c primer plus',
+          logo: 'https://mjh1.oss-cn-hangzhou.aliyuncs.com/seecoder/good.png',
+          user: 'user2',
+        },
+        {
+          name: 'python',
+          description: 'mooctest.net',
+          logo: 'https://mjh1.oss-cn-hangzhou.aliyuncs.com/seecoder/good.png',
+          user: 'user3',
+        },
+        {
+          name: 'lol',
+          description: 'league of legends',
+          logo: 'https://mjh1.oss-cn-hangzhou.aliyuncs.com/seecoder/good.png',
+          user: 'gamer',
+        }
+      ]
+    }
+  },
+  methods:{
+  }
+}
+</script>
+
+<style scoped>
+.question-repository{
+  padding: 20px;
+}
+
+ol, ul{
+  list-style: none;
+}
+
+li {
+  display: inline-block;
+  text-align: -webkit-match-parent;
+}
+</style>

+ 15 - 0
src/components/bok/bokMain/QuestionSearch.vue

@@ -0,0 +1,15 @@
+<template>
+  <div>
+    <h1>Question Search</h1>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "QuestionSearch"
+}
+</script>
+
+<style scoped>
+
+</style>

+ 15 - 0
src/components/bok/bokMain/Setting.vue

@@ -0,0 +1,15 @@
+<template>
+<div>
+  <h1>Setting</h1>
+</div>
+</template>
+
+<script>
+export default {
+  name: "Setting"
+}
+</script>
+
+<style scoped>
+
+</style>

+ 58 - 0
src/components/bok/bokMain/qR/QuestionPackage.vue

@@ -0,0 +1,58 @@
+<template>
+  <div class="question-package" @click="clickQuestionPackage">
+    <div style="height: 70%">
+      <h2 style="margin-top: 0px;padding-top:10px">{{ name }}</h2>
+      <h3>{{ description }}</h3>
+      <img alt="Package Logo" :src="logo"/>
+    </div>
+    <div style="height:calc(30% - 30px  );background-color: #f6f6f6;padding:15px;">
+      <span>适合:</span>
+      <span>{{ user }}</span>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "QuestionPackage",
+  data() {
+    return {}
+  },
+  props: {
+    name: String,
+    description: String,
+    logo: String,
+    user: String,
+  },
+  methods:{
+    clickQuestionPackage(){
+      const _this = this
+
+      alert(_this.description)
+    }
+  },
+}
+</script>
+
+<style scoped>
+.question-package {
+  display: block;
+  width: 215px;
+  height: 260px;
+  /*padding: 15px;*/
+  margin: 15px;
+  position: relative;
+  border: 1px solid #ebebeb;
+  border-radius: 3px;
+  background: #fff;
+}
+
+.question-package:hover {
+  border: 1px solid #AFAFAF;
+  cursor: pointer;
+}
+
+.question-package img {
+  height: 75px;
+}
+</style>

+ 9 - 0
src/main.js

@@ -0,0 +1,9 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+import store from './store'
+
+import ElementPlus from 'element-plus';
+import 'element-plus/lib/theme-chalk/index.css';
+
+createApp(App).use(store).use(router).use(ElementPlus).mount('#app')

+ 74 - 0
src/router/index.js

@@ -0,0 +1,74 @@
+import {createRouter, createWebHistory} from 'vue-router'
+import Home from '../views/Home.vue'
+import store from '../store/index'
+
+const routes = [
+  {
+    path: '/home',
+    name: 'Home',
+    component: Home
+  },
+  {
+    path: '/about',
+    name: 'About',
+    // route level code-splitting
+    // this generates a separate chunk (about.[hash].js) for this route
+    // which is lazy-loaded when the route is visited.
+    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
+  },
+  {
+    path: '/',
+    name: 'BokFrontEnd',
+    component: () => import('../views/Bok'),
+    redirect: '/questionRepository',
+    children: [
+      {
+        path: 'example',
+        name: 'Example',
+        component: () => import('../components/bok/bokMain/Example'),
+      },
+      {
+        path: 'questionSearch',
+        name: 'QuestionSearch',
+        component: () => import('../components/bok/bokMain/QuestionSearch'),
+      },
+      {
+        path: 'questionRepository',
+        name: "QuestionRepository",
+        component: () => import("../components/bok/bokMain/QuestionRepository"),
+      },
+      {
+        path: "collection",
+        name: "Collection",
+        component: () => import("../components/bok/bokMain/Collection"),
+      },
+      {
+        path: "completion",
+        name: "Completion",
+        component: () => import("../components/bok/bokMain/Completion"),
+      },
+      {
+        path: "setting",
+        name: "Setting",
+        component: () => import("../components/bok/bokMain/Setting"),
+      },
+    ]
+  },
+  {
+    path: "/question/:questionId",
+    name: 'Question',
+    component: () => import('../views/Question')
+  }
+]
+
+const router = createRouter({
+  history: createWebHistory(process.env.BASE_URL),
+  routes
+})
+
+router.afterEach((to, from) => {
+  // ...
+  store.commit('bok/setPath', to.path)
+})
+
+export default router

+ 19 - 0
src/store/bok.js

@@ -0,0 +1,19 @@
+const bok = {
+  namespaced: true,
+  state: {
+    navBarPath: "",
+  },
+  mutations: {
+    setPath(state, path) {
+      state.navBarPath = path
+    },
+  },
+  actions: {},
+  getters: {
+    getPath: (state) => {
+      return state.navBarPath;
+    },
+  },
+}
+
+export default bok

+ 14 - 0
src/store/index.js

@@ -0,0 +1,14 @@
+import { createStore } from 'vuex'
+import bok from '@/store/bok'
+
+export default createStore({
+  state: {
+  },
+  mutations: {
+  },
+  actions: {
+  },
+  modules: {
+    bok
+  }
+})

+ 3 - 0
src/style/variables.scss

@@ -0,0 +1,3 @@
+//layout
+
+$sideBarWidth: 230px

+ 5 - 0
src/views/About.vue

@@ -0,0 +1,5 @@
+<template>
+  <div class="about">
+    <h1>This is an about page</h1>
+  </div>
+</template>

+ 36 - 0
src/views/Bok.vue

@@ -0,0 +1,36 @@
+<template>
+  <div class="layout-wrapper">
+    <side-bar></side-bar>
+    <div class="main-container">
+      <nav-bar></nav-bar>
+      <bok-main></bok-main>
+    </div>
+  </div>
+</template>
+
+<script>
+import SideBar from "../components/bok/SideBar";
+import NavBar from "../components/bok/NavBar";
+import BokMain from "../components/bok/BokMain"
+
+export default {
+  name: "Bok",
+  components: {
+    "nav-bar": NavBar,
+    "side-bar": SideBar,
+    "bok-main": BokMain,
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import "src/style/variables";
+
+.layout-wrapper{
+  height: 100%;
+}
+
+.main-container{
+  margin-left: $sideBarWidth;
+}
+</style>

+ 18 - 0
src/views/Home.vue

@@ -0,0 +1,18 @@
+<template>
+  <div class="home">
+    <img alt="Vue logo" src="../assets/logo.png">
+    <HelloWorld msg="Welcome to Your Vue.js App"/>
+  </div>
+</template>
+
+<script>
+// @ is an alias to /src
+import HelloWorld from '@/components/HelloWorld.vue'
+
+export default {
+  name: 'Home',
+  components: {
+    HelloWorld
+  }
+}
+</script>

+ 23 - 0
src/views/Question.vue

@@ -0,0 +1,23 @@
+<template>
+  <div>Question{{questionId}}</div>
+</template>
+
+<script>
+export default {
+  name: "Question",
+  data(){
+    return {
+      questionId: null,
+    }
+  },
+  mounted() {
+    const _this = this
+    let path = _this.$route.path.split("/")
+    _this.questionId = Number(path[path.length-1])
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 13 - 0
tests/unit/example.spec.js

@@ -0,0 +1,13 @@
+import { expect } from 'chai'
+import { shallowMount } from '@vue/test-utils'
+import HelloWorld from '@/components/HelloWorld.vue'
+
+describe('HelloWorld.vue', () => {
+  it('renders props.msg when passed', () => {
+    const msg = 'new message'
+    const wrapper = shallowMount(HelloWorld, {
+      props: { msg }
+    })
+    expect(wrapper.text()).to.include(msg)
+  })
+})

+ 8 - 0
vue.config.js

@@ -0,0 +1,8 @@
+// vue.config.js
+
+/**
+ * @type {import('@vue/cli-service').ProjectOptions}
+ */
+module.exports = {
+  // 选项...
+}