lrf402788946 5 years ago
commit
c735cb2438
100 changed files with 5957 additions and 0 deletions
  1. 2 0
      .browserslistrc
  2. 1 0
      .env
  3. 33 0
      .eslintrc.js
  4. 22 0
      .gitignore
  5. 19 0
      README.md
  6. 3 0
      babel.config.js
  7. 37 0
      package.json
  8. 5 0
      postcss.config.js
  9. BIN
      public/favicon.ico
  10. 17 0
      public/index.html
  11. 11 0
      src/App.vue
  12. BIN
      src/assets/1461290712106172.png
  13. BIN
      src/assets/1471336196-8812.jpg
  14. BIN
      src/assets/1471336564-3155.jpg
  15. BIN
      src/assets/1471336685-8591.gif
  16. BIN
      src/assets/1471336731-1731.jpg
  17. BIN
      src/assets/1471336777-9628.gif
  18. BIN
      src/assets/1471336823-7406.gif
  19. BIN
      src/assets/1471422360-3448.png
  20. BIN
      src/assets/1476839512-5798.jpg
  21. BIN
      src/assets/1478484593-1797.png
  22. BIN
      src/assets/1478484616-6180.png
  23. BIN
      src/assets/1478484640-8529.png
  24. BIN
      src/assets/1478484673-7487.png
  25. BIN
      src/assets/1480037104-2854.png
  26. BIN
      src/assets/1521460511-1688.png
  27. BIN
      src/assets/1521460555-1404.png
  28. BIN
      src/assets/1521460609-6852.jpg
  29. BIN
      src/assets/1552283620-9698.jpg
  30. BIN
      src/assets/a1.jpg
  31. BIN
      src/assets/a2.jpg
  32. BIN
      src/assets/a3.jpg
  33. BIN
      src/assets/a4.jpg
  34. BIN
      src/assets/a5.jpg
  35. BIN
      src/assets/bg-shade.png
  36. BIN
      src/assets/logo.png
  37. BIN
      src/assets/logo_beijing.png
  38. BIN
      src/assets/ncss_company.jpg
  39. BIN
      src/assets/ncss_student.jpg
  40. BIN
      src/assets/safity.png
  41. BIN
      src/assets/xinxi.png
  42. BIN
      src/assets/yxqqnn.png
  43. BIN
      src/assets/人物-团队.png
  44. BIN
      src/assets/右箭头 (1).png
  45. 54 0
      src/components/qrcode.vue
  46. 136 0
      src/components/to-login.vue
  47. 66 0
      src/layout/corpInfo.vue
  48. 116 0
      src/layout/detail-layout.vue
  49. 194 0
      src/layout/detail/jobfair/context.vue
  50. 85 0
      src/layout/detail/jobfair/head.vue
  51. 70 0
      src/layout/detail/jobinfo/context.vue
  52. 79 0
      src/layout/detail/jobs/context.vue
  53. 90 0
      src/layout/detail/jobs/head.vue
  54. 209 0
      src/layout/detail/talk/talk-context.vue
  55. 84 0
      src/layout/detail/talk/talk-head.vue
  56. 39 0
      src/layout/detail/user-defined.vue
  57. 49 0
      src/layout/detail/web-intro.vue
  58. 108 0
      src/layout/detail/web-jobs.vue
  59. 84 0
      src/layout/layout-part/foot.vue
  60. 57 0
      src/layout/layout-part/menus.vue
  61. 129 0
      src/layout/layout-part/top-menu.vue
  62. 176 0
      src/layout/recruitdetail-layout.vue
  63. 32 0
      src/layout/share.vue
  64. 22 0
      src/main.js
  65. 19 0
      src/plugins/axios.js
  66. 39 0
      src/plugins/check-res.js
  67. 5 0
      src/plugins/element.js
  68. 6 0
      src/plugins/filters.js
  69. 27 0
      src/plugins/loading.js
  70. 4 0
      src/plugins/meta.js
  71. 24 0
      src/plugins/methods.js
  72. 20 0
      src/plugins/setting.js
  73. 65 0
      src/plugins/stomp.js
  74. 10 0
      src/plugins/var.js
  75. 89 0
      src/router.js
  76. 264 0
      src/store.js
  77. 132 0
      src/util/axios-wrapper.js
  78. 10 0
      src/util/filters.js
  79. 30 0
      src/util/menus.js
  80. 50 0
      src/util/methods-util.js
  81. 47 0
      src/util/optionTitles.js
  82. 96 0
      src/util/qrcode.vue
  83. 69 0
      src/util/user-util.js
  84. 139 0
      src/views/corp/index.vue
  85. 1527 0
      src/views/index/index.vue
  86. 122 0
      src/views/info/detail.vue
  87. 47 0
      src/views/info/index.vue
  88. 66 0
      src/views/info/list.vue
  89. 144 0
      src/views/jobfair/detail.vue
  90. 35 0
      src/views/jobfair/index.vue
  91. 115 0
      src/views/jobfair/list.vue
  92. 88 0
      src/views/jobinfo/detail.vue
  93. 34 0
      src/views/jobinfo/index.vue
  94. 111 0
      src/views/jobinfo/list.vue
  95. 116 0
      src/views/jobs/detail.vue
  96. 34 0
      src/views/jobs/index.vue
  97. 127 0
      src/views/jobs/list.vue
  98. 136 0
      src/views/talk/detail.vue
  99. 81 0
      src/views/talk/index.vue
  100. 0 0
      src/views/talk/list.vue

+ 2 - 0
.browserslistrc

@@ -0,0 +1,2 @@
+> 1%
+last 2 versions

+ 1 - 0
.env

@@ -0,0 +1 @@
+VUE_APP_AXIOS_BASE_URL = ''

+ 33 - 0
.eslintrc.js

@@ -0,0 +1,33 @@
+// https://eslint.org/docs/user-guide/configuring
+
+module.exports = {
+  root: true,
+  env: {
+    node: true,
+  },
+  extends: ['plugin:vue/essential', '@vue/prettier'],
+  plugins: ['vue'],
+  rules: {
+    'max-len': [
+      'warn',
+      {
+        code: 250,
+      },
+    ],
+    'no-unused-vars': 'off',
+    'no-console': 'off',
+    'prettier/prettier': [
+      'warn',
+      {
+        singleQuote: true,
+        trailingComma: 'es5',
+        bracketSpacing: true,
+        jsxBracketSameLine: true,
+        printWidth: 160,
+      },
+    ],
+  },
+  parserOptions: {
+    parser: 'babel-eslint',
+  },
+};

+ 22 - 0
.gitignore

@@ -0,0 +1,22 @@
+.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*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 19 - 0
README.md

@@ -0,0 +1,19 @@
+# web-protal
+
+## Project setup
+```
+npm install
+```
+
+### Compiles and hot-reloads for development
+```
+npm run serve
+```
+
+### Compiles and minifies for production
+```
+npm run build
+```
+2/3级页面:
+  info:信息类列表,点击菜单切换列表数据刷新;
+      点击列表信息,进入详情路由

+ 3 - 0
babel.config.js

@@ -0,0 +1,3 @@
+module.exports = {
+  presets: ["@vue/app"]
+};

+ 37 - 0
package.json

@@ -0,0 +1,37 @@
+{
+  "name": "web-protal",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "@stomp/stompjs": "^5.4.2",
+    "axios": "^0.19.0",
+    "core-js": "^2.6.5",
+    "element-ui": "^2.11.1",
+    "jsonwebtoken": "^8.5.1",
+    "lodash": "^4.17.15",
+    "naf-core": "^0.1.2",
+    "qrcode": "^1.4.1",
+    "vshare": "^2.0.0",
+    "vue": "^2.6.10",
+    "vue-meta": "^2.1.1",
+    "vue-router": "^3.0.3",
+    "vuex": "^3.0.1"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "^3.9.0",
+    "@vue/cli-plugin-eslint": "^3.9.0",
+    "@vue/cli-service": "^3.9.0",
+    "@vue/eslint-config-prettier": "^4.0.1",
+    "babel-eslint": "^10.0.1",
+    "eslint": "^5.16.0",
+    "eslint-plugin-vue": "^5.0.0",
+    "less": "^3.0.4",
+    "less-loader": "^4.1.0",
+    "vue-template-compiler": "^2.6.10"
+  }
+}

+ 5 - 0
postcss.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  plugins: {
+    autoprefixer: {}
+  }
+};

BIN
public/favicon.ico


+ 17 - 0
public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+  <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>web-protal</title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but web-protal 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>

+ 11 - 0
src/App.vue

@@ -0,0 +1,11 @@
+<template>
+  <div id="app">
+    <router-view />
+  </div>
+</template>
+
+<style lang="less">
+body {
+  margin: 0;
+}
+</style>

BIN
src/assets/1461290712106172.png


BIN
src/assets/1471336196-8812.jpg


BIN
src/assets/1471336564-3155.jpg


BIN
src/assets/1471336685-8591.gif


BIN
src/assets/1471336731-1731.jpg


BIN
src/assets/1471336777-9628.gif


BIN
src/assets/1471336823-7406.gif


BIN
src/assets/1471422360-3448.png


BIN
src/assets/1476839512-5798.jpg


BIN
src/assets/1478484593-1797.png


BIN
src/assets/1478484616-6180.png


BIN
src/assets/1478484640-8529.png


BIN
src/assets/1478484673-7487.png


BIN
src/assets/1480037104-2854.png


BIN
src/assets/1521460511-1688.png


BIN
src/assets/1521460555-1404.png


BIN
src/assets/1521460609-6852.jpg


BIN
src/assets/1552283620-9698.jpg


BIN
src/assets/a1.jpg


BIN
src/assets/a2.jpg


BIN
src/assets/a3.jpg


BIN
src/assets/a4.jpg


BIN
src/assets/a5.jpg


BIN
src/assets/bg-shade.png


BIN
src/assets/logo.png


BIN
src/assets/logo_beijing.png


BIN
src/assets/ncss_company.jpg


BIN
src/assets/ncss_student.jpg


BIN
src/assets/safity.png


BIN
src/assets/xinxi.png


BIN
src/assets/yxqqnn.png


BIN
src/assets/人物-团队.png


BIN
src/assets/右箭头 (1).png


+ 54 - 0
src/components/qrcode.vue

@@ -0,0 +1,54 @@
+<template>
+  <div id="qrcode">
+    <img :src="dataUrl" />
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import QRCode from 'qrcode';
+export default {
+  name: 'qrcode',
+  props: {
+    qrcode: null,
+  },
+  components: {},
+  data: () => ({
+    dataUrl: null,
+    token: null,
+  }),
+  async mounted() {
+    await this.initQrcode();
+  },
+  created() {},
+  computed: {},
+  methods: {
+    async initQrcode() {
+      // 创建二维码
+      if (!this.qrcode) return;
+      let uri = `${Vue.config.weixin.baseUrl}/qrcode/${this.qrcode}/scan`;
+      if (uri.startsWith('/')) {
+        uri = `${location.protocol}//${location.host}${uri}`;
+      }
+      this.dataUrl = await QRCode.toDataURL(uri);
+      this.$stomp({
+        [`/exchange/qrcode.login/${this.qrcode}`]: this.onMessage,
+      });
+    },
+    onMessage(message) {
+      console.log('receive a message: ', message.body);
+      if (message.body == 'scaned') {
+        try {
+          this.$emit('toReturn', message);
+          console.log('扫码登录成功');
+        } catch (err) {
+          console.log('扫码登录失败');
+          console.error(err);
+        }
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 136 - 0
src/components/to-login.vue

@@ -0,0 +1,136 @@
+<template>
+  <div id="to-login">
+    <el-dialog
+      :title="title ? title : '提示'"
+      :visible.sync="display"
+      width="40%"
+      center
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      :show-close="false"
+      v-if="display"
+    >
+      <el-row>
+        <slot>
+          <el-col :span="12" class="el-icon-s-platform" style="text-align:center;padding-bottom:1rem;zoom:1.5;"> </el-col>
+          <el-col :span="12" class="el-icon-full-screen" style="text-align:center;padding-bottom:1rem;zoom:1.5;"> </el-col>
+        </slot>
+        <el-col :span="12">
+          <el-form :model="form" :rules="rules" ref="form">
+            <el-form-item prop="account">
+              <el-col>
+                <el-input placeholder="学号" prefix-icon="el-icon-user-solid" v-model="form.account"></el-input>
+              </el-col>
+            </el-form-item>
+            <el-form-item prop="passwd">
+              <el-col>
+                <el-input
+                  placeholder="密码(首次登陆密码为身份证密码后六位)"
+                  prefix-icon="el-icon-lock"
+                  v-model="form.passwd"
+                  show-password
+                  @keyup.enter.native="toSubmit"
+                >
+                </el-input>
+              </el-col>
+            </el-form-item>
+          </el-form>
+          <el-col :span="12" style="text-align:center;">
+            <el-button type="primary" @click="toSubmit">登&nbsp;&nbsp;&nbsp;&nbsp;录</el-button>
+          </el-col>
+          <el-col :span="12" style="text-align:center;">
+            <el-button @click="toClose">取&nbsp;&nbsp;&nbsp;&nbsp;消</el-button>
+          </el-col>
+        </el-col>
+        <el-col :span="12" style="text-align:center">
+          <qrcode :qrcode="qrcode" @toReturn="toReturn"></qrcode>
+        </el-col>
+        <slot name="footer"></slot>
+      </el-row>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+const jwt = require('jsonwebtoken');
+import { mapActions, mapState, mapMutations } from 'vuex';
+import qrcode from '@/components/qrcode.vue';
+export default {
+  name: 'to-login',
+  props: {
+    title: null,
+    display: { type: Boolean },
+  },
+  components: {
+    qrcode,
+  },
+  data: () => ({
+    form: {},
+    qrcode: '',
+    loginType: 0,
+    rules: {
+      account: [{ required: true, message: '请输入学号', trigger: 'blur' }],
+      passwd: [{ required: true, message: '请输入密码', trigger: 'blur' }],
+    },
+  }),
+  created() {
+    this.initQrcode();
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  methods: {
+    ...mapMutations(['setUser']),
+    ...mapActions(['createConnection', 'getWxtoken', 'userOperation']),
+    async initQrcode() {
+      let result = await this.createConnection();
+      this.$set(this, `qrcode`, result);
+    },
+    async toReturn(msg) {
+      let result = await this.getWxtoken(this.qrcode);
+      this.submit(result, 1);
+    },
+    toSubmit() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          this.submit(null, 0);
+        }
+        return false;
+      });
+    },
+    async submit(wxtoken, loginType) {
+      let data = JSON.parse(JSON.stringify(this.form));
+      if (loginType === 0) {
+        data.account = `${data.account}@999991`;
+      } else {
+        data = { wxtoken: wxtoken };
+      }
+      let result = await this.userOperation({ type: 'login', data: { loginType: loginType, info: data } });
+      console.log(result);
+      this.$message({
+        type: `${result.errcode}` === '0' ? 'success' : 'error',
+        message: `${result.errcode}` === '0' ? '登录成功' : 'result.errmsg',
+      });
+      if (`${result.errcode}` === '0') {
+        let info = jwt.decode(result.data);
+        sessionStorage.setItem('user', JSON.stringify(info));
+        window.location.href = `${window.location.href}`;
+      }
+    },
+    toClose() {
+      this.$emit('close');
+    },
+    // async wxLogin(wxtoken) {
+    //   let result = await this.userOperation({ type: 'login', data: { loginType: '1', info: { wxtoken: wxtoken } } });
+    //   if (`${result.errcode}` === '0') {
+    //     let info = jwt.decode(result.data);
+    //     sessionStorage.setItem('user', JSON.stringify(info));
+    //     this.setUser(info);
+    //     window.location.href = `${window.location.href}`;
+    //   }
+    // },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 66 - 0
src/layout/corpInfo.vue

@@ -0,0 +1,66 @@
+<template>
+  <div id="corpInfo">
+    <el-row v-if="corpInfo && corpInfo.id">
+      <el-col>
+        <el-image class="firmLogo" :src="corpInfo.logo_url"></el-image>
+      </el-col>
+      <el-col style="padding-bottom: 10px; border-bottom: 1px dashed #ddd;">
+        <el-link :underline="false" @click="$router.push({ path: '/corp/detail', query: { id: corpInfo.id } })">
+          <span style="font-size: 14px; color: #850000;">{{ corpInfo.corpname }}</span>
+        </el-link>
+      </el-col>
+      <el-col class="right_Detail" style="padding-top: 10px;">
+        <el-row>
+          <el-col>
+            <span>邮箱:{{ corpInfo.job_email }}</span>
+          </el-col>
+          <el-col>
+            <span>地址:{{ corpInfo.address }}</span>
+          </el-col>
+          <el-col>
+            <span>电话:{{ corpInfo.tel }}</span>
+          </el-col>
+        </el-row>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'corpInfo',
+  props: {
+    corpid: null,
+  },
+  components: {},
+  data: () => ({
+    corpInfo: {},
+  }),
+  created() {},
+  computed: {},
+  watch: {
+    corpid: {
+      handler(val) {
+        this.search();
+      },
+    },
+  },
+  methods: {
+    ...mapActions(['corpOperation']),
+    async search() {
+      if (!this.corpid) return;
+      let corpid = this.corpid;
+      let result = await this.corpOperation({ type: 'component', data: { corpid: corpid } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, 'corpInfo', result.data);
+        this.$set(this.corpInfo, `id`, this.corpid);
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 116 - 0
src/layout/detail-layout.vue

@@ -0,0 +1,116 @@
+<template>
+  <div id="detail">
+    <el-row>
+      <div class="w_0100">
+        <div class="w_1200">
+          <el-col :span="24" class="top">
+            <slot name="top">头部</slot>
+          </el-col>
+        </div>
+      </div>
+    </el-row>
+    <el-row>
+      <div class="w_0100 menu">
+        <div class="w_1200">
+          <el-col :span="24" class="menuTit">
+            <top-menu> </top-menu>
+          </el-col>
+        </div>
+      </div>
+    </el-row>
+    <el-row>
+      <div class="w_0100 main">
+        <div class="w_1200">
+          <el-col :span="24" class="mainInfo">
+            <el-col class="mainSide"><slot name="mainSide">主体左部导航</slot></el-col>
+            <el-col class="mainMain"><slot name="mainMain">主体右部信息</slot></el-col>
+          </el-col>
+        </div>
+      </div>
+    </el-row>
+    <el-row>
+      <div class="w_0100 footer">
+        <div class="w_1200">
+          <el-col :span="24" class="footerTit">
+            <foots></foots>
+          </el-col>
+        </div>
+      </div>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import topMenu from '@/layout/layout-part/top-menu.vue';
+import foots from '@/layout/layout-part/foot.vue';
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    topMenu,
+    foots,
+  },
+  data: () => ({}),
+  created() {},
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+.w_0100 {
+  float: left;
+  width: 100%;
+}
+.w_1200 {
+  margin: 0 auto;
+  width: 1200px;
+}
+.top {
+  float: left;
+  width: 100%;
+  height: 100px;
+  background: #fff;
+}
+.menu {
+  float: left;
+  width: 100%;
+  height: 40px;
+  background: #850000;
+}
+.main {
+  background: #f6f6f6;
+  min-height: 500px;
+}
+.mainInfo {
+  float: left;
+  width: 100%;
+  margin: 20px 0;
+}
+.mainSide {
+  float: left;
+  width: 280px;
+  min-height: 45px;
+  background: #fff;
+}
+.mainMain {
+  float: right;
+  width: 900px;
+  min-height: 500px;
+  padding: 20px 30px;
+  background: #fff;
+  color: #333;
+}
+.footer {
+  float: left;
+  width: 100%;
+  height: 64px;
+  background-color: #333;
+  padding: 0.8rem 0 3rem 0;
+}
+.footerTit {
+  float: left;
+  width: 100%;
+  height: 64px;
+}
+</style>

+ 194 - 0
src/layout/detail/jobfair/context.vue

@@ -0,0 +1,194 @@
+<template>
+  <div id="jobfair-context">
+    <el-row>
+      <el-col class="webMessage">
+        {{ title }}
+      </el-col>
+      <el-col style="padding: 50px 15px;">
+        <el-col class="comDetail">
+          <span v-html="info.content">{{ info && info.content ? info.content : '' }}</span>
+        </el-col>
+
+        <!-- <el-col class="comTitle">
+          <span style="font-weight: bold;">{{ info && info.title ? info.title : '' }} </span>
+        </el-col>
+        <el-col class="comDetail">
+          <span>{{ info && info.abs ? info.abs : '' }}</span>
+        </el-col>
+        <el-col><span class="comView">一、时间</span></el-col>
+        <el-col class="comDetail">
+          <span>
+            {{ info && info.dev ? info.dev : '' }}
+          </span>
+        </el-col>
+        <el-col><span class="comView">二、地点</span></el-col>
+        <el-col class="comDetail">
+          <span>
+            {{ info && info.glo ? info.glo : '' }}
+          </span>
+        </el-col>
+        <el-col><span class="comView">三、参会方式</span></el-col>
+        <el-col class="comDetail">
+          <span>
+            {{ info && info.ser ? info.ser : '' }}
+          </span>
+        </el-col>
+        <el-col><span class="comView">四、学校审核</span></el-col>
+        <el-col class="comDetail">
+          <span>
+            {{ detail && detail.cli ? detail.cli : '' }}
+          </span>
+        </el-col>
+        <el-col><span class="comView">五、其他</span></el-col>
+        <el-col class="comDetail">
+          <span>
+            {{ detail && detail.cli ? detail.cli : '' }}
+          </span>
+        </el-col>
+        <el-col><span class="comView">六、联系方式:</span></el-col>
+        <el-col class="comDetail">
+          <span style="text-indent: 0;">网址:</span>
+          <span style="font-family: 微软雅黑; text-indent: 0;">{{ detail && detail.inweb ? detail.inweb : '' }}</span>
+        </el-col>
+        <el-col class="comDetail">
+          <span style="text-indent: 0;">总部地址:</span>
+          <span style="text-indent: 0;">{{ detail && detail.inadd ? detail.inadd : '' }}</span>
+        </el-col>
+        <el-col class="comDetail">
+          <span style="text-indent: 0;">招聘负责人:</span>
+          <span style="text-indent: 0;">{{ detail && detail.inmail ? detail.inmail : '' }}</span>
+        </el-col>
+        <el-col style="text-align: center;margin: 20px 0px">
+          <a href="#" class="btnComplaint">
+            <el-image class="report" :src="pic"></el-image>
+            <span style="color: #fff;font-size: 14px;">校园招聘违规举报</span>
+          </a>
+        </el-col> -->
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'jobfair-context',
+  props: {
+    title: {
+      type: String,
+    },
+    info: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  components: {},
+  data: () => ({
+    // detail: {},
+    pic: require('@/assets/safity.png'),
+  }),
+  mounted() {
+    // this.$set(this, `detail`, this.info);
+  },
+  created() {},
+  computed: {},
+  methods: {
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (columnIndex === 0) {
+        if (rowIndex % 2 === 0) {
+          return {
+            rowspan: 2,
+            colspan: 1,
+          };
+        } else {
+          return {
+            rowspan: 0,
+            colspan: 0,
+          };
+        }
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.el-link:hover {
+  text-decoration: underline;
+  color: #850000;
+}
+.btnComplaint {
+  color: #fff !important;
+  display: inline-block;
+  background-color: #77b911;
+  height: 40px;
+  line-height: 40px;
+  padding: 0 20px;
+  border-radius: 3px;
+  font-size: 14px;
+}
+.report {
+  width: 24.68px;
+  height: 30px;
+  float: left;
+  margin: 5px 5px 0 0;
+}
+a {
+  text-decoration: none;
+}
+/deep/ .el-breadcrumb__inner {
+  color: #999;
+}
+.webMessage {
+  border-left: 3px solid #850000;
+  font-size: 16px;
+  line-height: 30px;
+  height: 30px;
+  padding: 0 15px;
+  margin: 0 0 0 -15px;
+}
+/deep/.el-button--mini {
+  padding: 10px 15px;
+}
+.firmLogo {
+  width: 100%;
+  height: 82px;
+  text-align: center;
+}
+.firmLogo .el-image__inner {
+  width: 82px;
+  border: 1px solid #f6f6f6;
+}
+/deep/.el-button--danger {
+  background-color: #850000;
+}
+/deep/.el-button--mini {
+  padding: 8px 5px;
+}
+
+.sizeA {
+  font-size: 14px;
+}
+.comTitle {
+  font-size: 21px;
+  font-weight: bold;
+  color: #000;
+  font-family: 宋体;
+  text-align: center;
+  margin-bottom: 2rem;
+}
+.comView {
+  font-size: 16px;
+  font-family: 宋体;
+  font-weight: bold;
+}
+
+.comDetail span {
+  display: inline-block;
+  font-size: 16px;
+  line-height: 24px;
+  height: 24px;
+  font-family: 宋体;
+  color: #333333;
+  text-indent: 30px;
+}
+</style>

+ 85 - 0
src/layout/detail/jobfair/head.vue

@@ -0,0 +1,85 @@
+<template>
+  <div id="jobfair-head">
+    <el-row>
+      <el-col :span="24" class="webMessage">
+        {{ title }}
+      </el-col>
+      <el-col :span="24" style="padding: 20px 15px;">
+        <el-col :span="18">
+          <span style="font-size: 16px;">{{ info && info.title ? info.title : '' }}</span>
+          <el-button type="danger" class="btn">参会单位</el-button>
+        </el-col>
+        <el-col :span="6" class="ticketBtn">
+          <el-button type="primary" @click="applyTicket()">领取门票</el-button>
+        </el-col>
+        <el-col :span="24">
+          <span class="sizeA">时&nbsp;&nbsp;&nbsp;间:{{ info && info.date ? info.date : '' }}</span>
+        </el-col>
+        <el-col :span="24">
+          <span class="sizeA">地&nbsp;&nbsp;&nbsp;点:{{ info && info.organizer ? info.organizer : '' }}</span>
+        </el-col>
+        <el-col :span="24">
+          <span class="sizeA">主办方:{{ info && info.address ? info.address : '' }}</span>
+        </el-col>
+        <!-- <el-col :span="24">
+          <span class="sizeA">点击量:{{ info && info.click ? info.click : '' }}</span>
+        </el-col> -->
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'jobfair-head',
+  props: {
+    title: {
+      type: String,
+    },
+    info: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  components: {},
+  data: () => ({
+    // detail: {},
+  }),
+  created() {},
+  mounted() {
+    // this.$set(this, `detail`, this.list);
+    // this.$set(this, `list`, this.info);
+  },
+  computed: {},
+  methods: {
+    applyTicket() {
+      this.$emit('getTicket');
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.btn {
+  margin-left: 1.5rem;
+  padding: 10px 5px;
+  background: #850000;
+}
+.webMessage {
+  border-left: 3px solid #850000;
+  font-size: 16px;
+  line-height: 30px;
+  height: 30px;
+  padding: 0 15px;
+  margin: 0 0 0 -15px;
+}
+.sizeA {
+  font-size: 14px;
+}
+.ticketBtn {
+  padding: 10px 0 0 0;
+}
+/deep/.ticketBtn .el-button {
+  padding: 8px;
+}
+</style>

File diff suppressed because it is too large
+ 70 - 0
src/layout/detail/jobinfo/context.vue


+ 79 - 0
src/layout/detail/jobs/context.vue

@@ -0,0 +1,79 @@
+<template>
+  <div id="context">
+    <el-row>
+      <el-col :span="24" class="webMessage">
+        {{ title }}
+      </el-col>
+      <!-- <el-col :span="24" style="padding: 20px 15px;">
+        <el-col>
+          <span class="sizeA">
+            {{ detail && detail.into ? detail.into : '' }}
+          </span>
+        </el-col>
+      </el-col> -->
+    </el-row>
+
+    <!-- <el-row class="info_row">
+      <el-col :span="24">岗位职责</el-col>
+      <el-col :span="24" v-for="(item, index) in 5" :key="index"> {{ index + 1 }}, {{ item && item.info ? detail.info : '理解需求' }} </el-col>
+    </el-row>
+    <el-row class="info_row">
+      <el-col :span="24">任职资格</el-col>
+      <el-col :span="24" v-for="(item, index) in 5" :key="index"> {{ index + 1 }}, {{ item && item.info ? detail.info : '任职资格' }} </el-col>
+    </el-row>
+    <el-row class="info_row">
+      <el-col :span="24">岗位职责</el-col>
+      <el-col :span="24" v-for="(item, index) in 5" :key="index"> {{ index + 1 }}, {{ item && item.info ? detail.info : '理解需求' }} </el-col>
+    </el-row> -->
+    <el-row class="info_row">
+      <!-- <el-col :span="24">任职资格</el-col> -->
+      <el-col :span="24"> {{ info && info.job_desc ? info.job_desc : '' }} </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'context',
+  props: {
+    title: {
+      type: String,
+    },
+    info: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  components: {},
+  data: () => ({
+    detail: {},
+  }),
+  created() {},
+  mounted() {
+    this.$set(this, `detail`, this.info);
+  },
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+.webMessage {
+  border-left: 3px solid #850000;
+  font-size: 16px;
+  line-height: 30px;
+  height: 30px;
+  padding: 0 15px;
+  margin: 0 0 0 -15px;
+}
+.sizeA {
+  font-size: 14px;
+}
+.info_row {
+  padding: 1.5rem;
+  font-size: 14px;
+  .el-col {
+    padding: 0.2rem;
+  }
+}
+</style>

+ 90 - 0
src/layout/detail/jobs/head.vue

@@ -0,0 +1,90 @@
+<template>
+  <div id="jobs-head">
+    <span v-if="info && info.id">
+      <el-card class="cards">
+        <!-- <span class="cards__place" style="font-size:14px;">
+        {{ info && info.city ? info.city : '' }}
+      </span>
+      <br /> -->
+        {{ info.job_name }}
+      </el-card>
+      <el-row style="margin-top;1rem;">
+        <el-col :span="22">
+          <span style="color:#f40;font-size:18px;">
+            <i class="el-icon-coin"></i>
+            {{ info.salary.text }}
+          </span>
+          <span class="row_icon">
+            <i class="el-icon-location"></i>
+            {{ info.city }}
+          </span>
+          <span class="row_icon">
+            <i class="el-icon-collection">{{ info.xl_req }}</i>
+          </span>
+        </el-col>
+        <el-col :span="2">
+          <el-button type="danger" size="mini" style="background:#850000;" @click="deliver()">投递简历</el-button>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col class="info" :span="24">
+          职位诱惑: {{ info && info.job_tag ? info.job_tag : '绩效奖金 岗前培训 节日礼物 扁平管理 年度旅游 岗位晋升 带薪年假 餐补 股票期权 ' }}
+        </el-col>
+        <el-col class="info" :span="24"> 薪酬福利: {{ info && info.welfare ? info.welfare : '五险一金 ' }} </el-col>
+        <el-col class="info" :span="24"> 截止时间: {{ info && info.end_date ? info.end_date : '2017年11月22日 ' }} </el-col>
+        <!-- <el-col class="info fade" style="margin-bottom:1rem;" :span="24"> 点击量: {{ info && info.views ? info.views : '3000' }} </el-col> -->
+      </el-row>
+    </span>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'jobs-head',
+  props: {
+    info: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  components: {},
+  data: () => ({
+    detail: {},
+  }),
+  created() {},
+  mounted() {
+    // this.$set(this, `detail`, this.info);
+  },
+  computed: {},
+  methods: {
+    deliver() {
+      this.$emit('toDeliver');
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.cards {
+  color: #fff;
+  font-size: 24px;
+  background: #850000;
+  padding: 0.5rem;
+  margin-bottom: 1rem;
+}
+.break {
+  word-break: keep-all;
+}
+.row_icon {
+  font-size: 18px;
+  margin-left: 1rem;
+}
+.info {
+  font-size: 16px;
+  margin-top: 0.5rem;
+}
+.fade {
+  font-size: 14px;
+  color: #cccccc;
+}
+</style>

+ 209 - 0
src/layout/detail/talk/talk-context.vue

@@ -0,0 +1,209 @@
+<template>
+  <div id="talk-context">
+    <el-row>
+      <el-col class="webMessage">
+        {{ title }}
+      </el-col>
+      <el-col style="padding: 3.125rem .9375rem;">
+        <el-col class="comDetail">
+          <span v-html="info.content">
+            {{ info && info.content ? info.content : '' }}
+          </span>
+        </el-col>
+
+        <!-- <el-col class="comTitle">
+          <span style="font-weight: bold;">{{ detail && detail.tit ? detail.tit : '' }} </span>
+        </el-col>
+        <el-col><span class="comView">公司简介:</span></el-col>
+        <el-col class="comDetail">
+          <span>{{ detail && detail.abs ? detail.abs : '' }}</span>
+        </el-col>
+        <el-col><span class="comView">发展历程:</span></el-col>
+        <el-col class="comDetail">
+          <span>
+            {{ detail && detail.dev ? detail.dev : '' }}
+          </span>
+        </el-col>
+        <el-col><span class="comView">全球布局:</span></el-col>
+        <el-col class="comDetail">
+          <span>
+            {{ detail && detail.glo ? detail.glo : '' }}
+          </span>
+        </el-col>
+        <el-col><span class="comView">产品系列:</span></el-col>
+        <el-col class="comDetail">
+          <span>
+            {{ detail && detail.ser ? detail.ser : '' }}
+          </span>
+        </el-col>
+        <el-col><span class="comView">全球客户:</span></el-col>
+        <el-col class="comDetail">
+          <span>
+            {{ detail && detail.cli ? detail.cli : '' }}
+          </span>
+        </el-col>
+        <el-col :span="24"><span>&nbsp;</span></el-col>
+        <el-col><span class="comView">岗位需求:</span></el-col>
+        <el-col :span="24"><span>&nbsp;</span></el-col>
+        <el-col>
+          <el-table :data="detail.tableData" :span-method="objectSpanMethod" border style="width: 80%; margin-top: 1.25rem;">
+            <el-table-column prop="id" label="岗位序列" width="180"> </el-table-column>
+            <el-table-column prop="name" label="岗位名称"> </el-table-column>
+            <el-table-column prop="major" label="需求专业"> </el-table-column>
+            <el-table-column prop="edu" label="学历"> </el-table-column>
+            <el-table-column prop="worspace" label="工作地点"> </el-table-column>
+            <el-table-column prop="require" label="语言要求"> </el-table-column>
+          </el-table>
+        </el-col>
+        <el-col style="margin-top: 2rem;"><span class="comView">宣讲时间地点:</span></el-col>
+        <el-col class="comDetail">
+          <span style="text-indent: 0;">
+            宣讲时间:{{ detail && detail.intime ? detail.intime : '' }} 宣讲地点:{{ detail && detail.inplace ? detail.inplace : '' }}
+          </span>
+        </el-col>
+        <el-col><span class="comView">联系方式:</span></el-col>
+        <el-col class="comDetail">
+          <span style="text-indent: 0;">网址:</span>
+          <span style="font-family: 微软雅黑; text-indent: 0;">{{ detail && detail.inweb ? detail.inweb : '' }}</span>
+        </el-col>
+        <el-col class="comDetail">
+          <span style="text-indent: 0;">总部地址:</span>
+          <span style="text-indent: 0;">{{ detail && detail.inadd ? detail.inadd : '' }}</span>
+        </el-col>
+        <el-col class="comDetail">
+          <span style="text-indent: 0;">招聘负责人:</span>
+          <span style="text-indent: 0;">{{ detail && detail.inmail ? detail.inmail : '' }}</span>
+        </el-col>
+        <el-col style="text-align: center;margin: 1.25rem 0rem">
+          <a href="#" class="btnComplaint">
+            <el-image class="report" :src="pic"></el-image>
+            <span style="color: #fff;font-size: .875rem;">校园招聘违规举报</span>
+          </a>
+        </el-col> -->
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'talk-context',
+  props: {
+    title: {
+      type: String,
+    },
+    info: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  components: {},
+  data: () => ({
+    detail: {},
+    pic: require('@/assets/safity.png'),
+  }),
+  mounted() {
+    // this.$set(this, `detail`, this.info);
+  },
+  created() {},
+  computed: {},
+  methods: {
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (columnIndex === 0) {
+        if (rowIndex % 2 === 0) {
+          return {
+            rowspan: 2,
+            colspan: 1,
+          };
+        } else {
+          return {
+            rowspan: 0,
+            colspan: 0,
+          };
+        }
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.el-link:hover {
+  text-decoration: underline;
+  color: #850000;
+}
+.btnComplaint {
+  color: #fff !important;
+  display: inline-block;
+  background-color: #77b911;
+  height: 2.5rem;
+  line-height: 2.5rem;
+  padding: 0 1.25rem;
+  border-radius: 0.1875rem;
+  font-size: 0.875rem;
+}
+.report {
+  width: 1.5425rem;
+  height: 1.875rem;
+  float: left;
+  margin: 0.3125rem 0.3125rem 0 0;
+}
+a {
+  text-decoration: none;
+}
+/deep/ .el-breadcrumb__inner {
+  color: #999;
+}
+.webMessage {
+  border-left: 0.1875rem solid #850000;
+  font-size: 1rem;
+  line-height: 1.875rem;
+  height: 1.875rem;
+  padding: 0 0.9375rem;
+  margin: 0 0 0 -0.9375rem;
+}
+/deep/.el-button--mini {
+  padding: 0.625rem 0.9375rem;
+}
+.firmLogo {
+  width: 100%;
+  height: 5.125rem;
+  text-align: center;
+}
+.firmLogo .el-image__inner {
+  width: 5.125rem;
+  border: 0.0625rem solid #f6f6f6;
+}
+/deep/.el-button--danger {
+  background-color: #850000;
+}
+/deep/.el-button--mini {
+  padding: 0.5rem 0.3125rem;
+}
+
+.sizeA {
+  font-size: 0.875rem;
+}
+.comTitle {
+  font-size: 1.3125rem;
+  font-weight: bold;
+  color: #000;
+  font-family: 宋体;
+  text-align: center;
+}
+.comView {
+  font-size: 1rem;
+  font-family: 宋体;
+  font-weight: bold;
+}
+
+.comDetail span {
+  display: inline-block;
+  font-size: 1rem;
+  line-height: 1.5rem;
+  height: 1.5rem;
+  font-family: 宋体;
+  color: #333333;
+  text-indent: 1.875rem;
+}
+</style>

+ 84 - 0
src/layout/detail/talk/talk-head.vue

@@ -0,0 +1,84 @@
+<template>
+  <div id="talk-head">
+    <el-row>
+      <el-col :span="24" class="webMessage">
+        {{ title }}
+      </el-col>
+      <el-col :span="24" style="padding: 1.25rem .9375rem;">
+        <el-col :span="18">
+          <span style="font-size: .875rem;">宣讲单位:{{ info && info.title ? info.title : '' }}</span>
+          <el-button type="danger" icon="el-icon-search" class="btn">工商查询</el-button>
+        </el-col>
+        <el-col :span="6" class="ticketBtn">
+          <el-button type="primary" @click="applyTicket()">领取门票</el-button>
+        </el-col>
+        <el-col :span="24">
+          <span class="sizeA">宣讲时间:{{ info && info.time ? info.time : '' }}</span>
+        </el-col>
+        <!-- <el-col :span="24">
+          <span class="sizeA">所在学校:{{ info && info.school ? info.school : '' }}</span>
+        </el-col> -->
+        <el-col :span="24">
+          <span class="sizeA">宣讲地点:{{ info && info.address ? info.address : '' }}</span>
+        </el-col>
+        <!-- <el-col :span="24">
+          <span class="sizeA">点击人次:{{ info && info.click ? info.click : '' }}</span>
+        </el-col> -->
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'talk-head',
+  props: {
+    title: {
+      type: String,
+    },
+    info: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  components: {},
+  data: () => ({
+    detail: {},
+  }),
+  created() {},
+  mounted() {
+    // this.$set(this, `detail`, this.info);
+  },
+  computed: {},
+  methods: {
+    applyTicket() {
+      this.$emit('getTicket');
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.btn {
+  margin-left: 1.5rem;
+  padding: 0.625rem 0.3125rem;
+  background: #850000;
+}
+.webMessage {
+  border-left: 0.1875rem solid #850000;
+  font-size: 1rem;
+  line-height: 1.875rem;
+  height: 1.875rem;
+  padding: 0 0.9375rem;
+  margin: 0 0 0 -0.9375rem;
+}
+.sizeA {
+  font-size: 0.875rem;
+}
+.ticketBtn {
+  padding: 0.625rem 0 0 0;
+}
+/deep/.ticketBtn .el-button {
+  padding: 0.5rem;
+}
+</style>

+ 39 - 0
src/layout/detail/user-defined.vue

@@ -0,0 +1,39 @@
+<template>
+  <div id="user-defined">
+    <el-row>
+      <el-col class="webMessage">
+        {{ title }}
+      </el-col>
+      <el-col style="padding: 3.125rem .9375rem;">
+        <slot></slot>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'user-defined',
+  props: {
+    title: {
+      type: String,
+    },
+  },
+  components: {},
+  data: () => ({}),
+  created() {},
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+.webMessage {
+  border-left: 0.1875rem solid #850000;
+  font-size: 1rem;
+  line-height: 1.875rem;
+  height: 1.875rem;
+  padding: 0 0.9375rem;
+  margin: 0 0 0 -0.9375rem;
+}
+</style>

+ 49 - 0
src/layout/detail/web-intro.vue

@@ -0,0 +1,49 @@
+<template>
+  <el-row>
+    <el-col class="webMessage">
+      {{ title }}
+    </el-col>
+    <el-col style="padding: 20px 15px;">
+      <el-col>
+        <span class="sizeA">
+          {{ info && info.intro ? info.intro : '' }}
+        </span>
+      </el-col>
+    </el-col>
+  </el-row>
+</template>
+
+<script>
+export default {
+  name: 'web-intro',
+  props: {
+    title: {
+      type: String,
+    },
+    info: {
+      type: Object,
+      default: () => {},
+    },
+  },
+  data: () => ({
+    detail: {},
+  }),
+  mounted() {
+    // this.$set(this, `detail`, this.info);
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.webMessage {
+  border-left: 3px solid #850000;
+  font-size: 16px;
+  line-height: 30px;
+  height: 30px;
+  padding: 0 15px;
+  margin: 0 0 0 -15px;
+}
+.sizeA {
+  font-size: 14px;
+}
+</style>

+ 108 - 0
src/layout/detail/web-jobs.vue

@@ -0,0 +1,108 @@
+<template>
+  <div id="web-jobs">
+    <el-row>
+      <el-col :span="24" class="webMessage" v-if="title">
+        {{ title }}
+      </el-col>
+    </el-row>
+    <span v-if="list.length > 0">
+      <el-row class="rowStyle" v-for="(item, index) in list" :key="index" :gutter="10">
+        <el-col :span="16">
+          <el-link class="job__name" :underline="false" @click="turnToJobs(item.id)">
+            <span title="查看职位">{{ item.job_name ? item.job_name : '广东省德庆县2019年引进高层次紧缺人才公告' }}</span>
+          </el-link>
+        </el-col>
+        <el-col class="money" :span="4">
+          {{ item.salary ? item.salary.text : '5K-10K/月' }}
+        </el-col>
+        <el-col :span="4">
+          {{ item.num ? item.num : '13人' }}
+        </el-col>
+        <el-col :span="16"> 招聘专业 : {{ item.subject ? item.subject : '法学,经济学,人文地理与城乡规划,环境科学,劳动与社会保障' }} </el-col>
+        <el-col :span="8"> {{ item.edu ? item.edu : '本科及以上' }} | {{ item.city ? item.city : '肇庆市' }} </el-col>
+      </el-row>
+      <el-row v-if="!type">
+        <el-col :span="24" style="text-align:center">
+          <el-pagination @current-change="search" :current-page="currentPage" :page-size="$limit" layout="total, prev, pager, next" :total="totalRow">
+          </el-pagination>
+        </el-col>
+      </el-row>
+    </span>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+export default {
+  name: 'web-jobs',
+  props: {
+    title: null,
+    info: null,
+    type: null,
+    origin: null,
+  },
+  data: () => ({
+    list: {},
+    currentPage: 1,
+    totalRow: 0,
+  }),
+  created() {
+    if (!this.type) this.search();
+  },
+  watch: {
+    info: {
+      handler(val) {
+        if (!this.type) this.dataPro();
+        else this.$set(this, `list`, this.info);
+      },
+    },
+  },
+  methods: {
+    turnToJobs(id) {
+      let query = {};
+      if (this.origin) query.origin = this.origin;
+      if (this.type) query.type = this.type;
+      query.id = id;
+      this.$router.push({ path: '/jobs/detail', query: query });
+    },
+    search(page) {
+      let skip = 0;
+      if (page) {
+        skip = (page - 1) * this.$limit;
+      }
+      let query = { skip: skip, limit: this.$limit };
+      this.$emit('search', query);
+    },
+    dataPro() {
+      this.$set(this, `totalRow`, this.info.total);
+      this.$set(this, `list`, this.info.data);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.webMessage {
+  border-left: 3px solid #850000;
+  font-size: 16px;
+  line-height: 30px;
+  height: 30px;
+  padding: 0 15px;
+  margin: 0 0 0 -15px;
+}
+.rowStyle {
+  border-bottom: 1px dashed #ddd;
+  padding: 1rem 1.5rem;
+  .el-col {
+    font-size: 0.9rem;
+    line-height: 2rem;
+  }
+  .job__name {
+    font-size: 1rem;
+    color: #850000;
+  }
+  .money {
+    color: #ff9900;
+  }
+}
+</style>

+ 84 - 0
src/layout/layout-part/foot.vue

@@ -0,0 +1,84 @@
+<template>
+  <div id="foot">
+    <el-row class="foot">
+      <el-col class="footLink">
+        <p>
+          <el-link :underline="false" href="" target="_blank">学校概括</el-link>
+          <el-link :underline="false" href="" target="_blank">创新创业</el-link>
+          <el-link :underline="false" href="" target="_blank">新闻公告</el-link>
+          <el-link :underline="false" href="" target="_blank">招聘信息</el-link>
+          <el-link :underline="false" href="" target="_blank">生源信息</el-link>
+          <el-link :underline="false" href="" target="_blank">政策法规</el-link>
+          <el-link :underline="false" href="" target="_blank">服务指南</el-link>
+          <el-link :underline="false" href="" target="_blank">就业学生团队</el-link>
+          <el-link :underline="false" href="" target="_blank">联系我们</el-link>
+        </p>
+      </el-col>
+      <el-col class="footTit">
+        <p>
+          <span class="text">长春工业大学版权所有</span>
+          <span class="line">|</span>
+          <span class="text">域名备案信息:吉ICP备05002091号</span>
+        </p>
+      </el-col>
+      <el-col class="footTxt">
+        <p>
+          <span class="text">可信网站验证</span>
+          <span class="text">诚信网站验证</span>
+          <span class="text">安全联盟</span>
+          <span class="text">行业验证</span>
+          <!-- <span class="text">浏览量:今日5823&nbsp;/&nbsp;共计6216772</span>
+          <el-link :underline="false" class="item" href="http://www.bibibi.net" target="_blank" style="color:#6d6d6d;">技术支持:云研科技</el-link> -->
+        </p>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'foot',
+  data: () => ({}),
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+p {
+  margin: 0;
+  padding: 0;
+}
+.foot {
+  width: 100%;
+  height: 95px;
+  padding: 15px 0;
+}
+.footLink {
+  height: 24px;
+  text-align: center;
+}
+.footLink .el-link {
+  margin: 0 10px 0 0;
+}
+.footTit {
+  height: 24px;
+  text-align: center;
+  color: #606266;
+  font-size: 14px;
+}
+.footTit span {
+  margin: 0 5px 0 5px;
+}
+.footTxt {
+  height: 24px;
+  text-align: center;
+  font-size: 14px;
+  color: #606266;
+}
+.footTxt span {
+  margin: 0 10px 0 0;
+}
+/deep/.el-link.el-link--default:hover {
+  color: #606266;
+}
+</style>

+ 57 - 0
src/layout/layout-part/menus.vue

@@ -0,0 +1,57 @@
+<template>
+  <div id="menus">
+    <el-menu :default-active="activeMenu" active-text-color="#850000" @select="changeMenu">
+      <el-menu-item
+        v-for="(item, index) in menuList"
+        :key="index"
+        :index="item.path"
+        :style="`${activeMenu === item.path ? 'border-left:2px solid #850000' : ''}`"
+      >
+        <span slot="title">{{ item.name }}</span>
+      </el-menu-item>
+    </el-menu>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+export default {
+  name: 'menus',
+  props: {
+    menuList: { type: Array, default: () => [] },
+  },
+  data: () => ({
+    activeMenu: '',
+  }),
+  created() {},
+  mounted() {
+    this.getPage();
+  },
+  watch: {
+    $route: {
+      handler(val) {
+        this.$set(this, `activeMenu`, val.path);
+      },
+      deep: true,
+    },
+  },
+  methods: {
+    changeMenu(val) {
+      this.$router.push({ path: val });
+      this.$set(this, `activeMenu`, val);
+    },
+    getPage() {
+      let path = this.$route.path;
+      this.$set(this, `activeMenu`, path);
+      return path;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.el-menu-item {
+  line-height: 32px;
+  height: 32px;
+}
+</style>

+ 129 - 0
src/layout/layout-part/top-menu.vue

@@ -0,0 +1,129 @@
+<template lang="html">
+  <div id="menus">
+    <el-col :span="24" class="menu">
+      <el-menu
+        :default-active="activeIndex"
+        class="el-menu-demo"
+        mode="horizontal"
+        background-color="#850000"
+        text-color="#fff"
+        active-text-color="#fff"
+        :router="true"
+      >
+        <el-menu-item index="1">首页</el-menu-item>
+        <el-submenu index="2">
+          <template slot="title">
+            学院概括
+          </template>
+          <el-menu-item index="2-1">学院简介</el-menu-item>
+          <el-menu-item index="2-2">部门概括</el-menu-item>
+        </el-submenu>
+        <el-submenu index="3">
+          <template slot="title">
+            创新创业
+          </template>
+          <el-menu-item index="3-1">创业法规</el-menu-item>
+          <el-menu-item index="3-2">创业培训</el-menu-item>
+          <el-menu-item index="3-3">创业案例</el-menu-item>
+        </el-submenu>
+        <el-submenu index="4">
+          <template slot="title">
+            新闻公告
+          </template>
+          <el-menu-item index="4-1">最新新闻</el-menu-item>
+          <el-menu-item index="4-2">就业新闻</el-menu-item>
+        </el-submenu>
+        <el-submenu index="5">
+          <template slot="title">
+            招聘信息
+          </template>
+          <el-menu-item index="/talk/list/in">校内宣讲会</el-menu-item>
+          <el-menu-item index="/talk/list/out">校外宣讲会</el-menu-item>
+          <el-menu-item index="/jobfair/list/in">校内双选会</el-menu-item>
+          <el-menu-item index="/jobfair/list/out">校外双选会</el-menu-item>
+          <el-menu-item index="/jobinfo/list">在线招聘</el-menu-item>
+          <el-menu-item index="/jobs/list/official">正式岗位</el-menu-item>
+          <el-menu-item index="/jobs/list/internship">实习岗位</el-menu-item>
+        </el-submenu>
+        <el-submenu index="6">
+          <template slot="title">
+            生源信息
+          </template>
+          <el-menu-item index="6-1">学院专业</el-menu-item>
+          <el-menu-item index="6-2">生源速览</el-menu-item>
+        </el-submenu>
+        <el-menu-item index="7">政策法规</el-menu-item>
+        <el-submenu index="8">
+          <template slot="title">
+            服务指南
+          </template>
+          <el-menu-item index="8-1">办事流程</el-menu-item>
+          <el-menu-item index="8-2">常用下载</el-menu-item>
+          <el-menu-item index="8-3">常见问题解答</el-menu-item>
+        </el-submenu>
+        <el-submenu index="9">
+          <template slot="title">
+            就业学生团队
+          </template>
+          <el-menu-item index="9-1">就业形象大使</el-menu-item>
+          <el-menu-item index="9-2">就业助理团队</el-menu-item>
+          <el-menu-item index="9-3">创新创业协会</el-menu-item>
+        </el-submenu>
+        <el-submenu index="10">
+          <template slot="title">
+            联系我们
+          </template>
+          <el-menu-item index="10-1">联系我们</el-menu-item>
+        </el-submenu>
+      </el-menu>
+    </el-col>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'menus',
+  data: () => ({
+    activeIndex: '1',
+  }),
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+.menu {
+  position: relative;
+  height: 40px;
+}
+/deep/.el-menu--horizontal > .el-menu-item {
+  height: 40px;
+  line-height: 40px;
+  width: 110px;
+  text-align: center;
+}
+.el-submenu {
+  width: 110px;
+  text-align: center;
+}
+/deep/.el-menu--horizontal > .el-submenu .el-submenu__icon-arrow {
+  display: none;
+}
+/deep/.el-menu--horizontal > .el-submenu .el-submenu__title {
+  height: 40px;
+  line-height: 40px;
+}
+/deep/.el-menu--popup {
+  min-width: 110px !important;
+}
+/deep/.el-menu--popup-bottom-start {
+  margin-top: 0px;
+}
+/deep/.menu .el-menu.el-menu--horizontal {
+  border-bottom: none;
+  background: #850000;
+}
+/deep/.el-menu--horizontal > .el-menu-item.is-active {
+  color: #fff;
+  border-bottom: none;
+}
+</style>

+ 176 - 0
src/layout/recruitdetail-layout.vue

@@ -0,0 +1,176 @@
+<template>
+  <div id="detail">
+    <el-row>
+      <div class="w_0100">
+        <div class="w_1200">
+          <el-col :span="24" class="top">
+            <slot name="top">头部</slot>
+          </el-col>
+        </div>
+      </div>
+    </el-row>
+    <el-row>
+      <div class="w_0100 menu">
+        <div class="w_1200">
+          <el-col :span="24" class="menuTit">
+            <top-menu> </top-menu>
+          </el-col>
+        </div>
+      </div>
+    </el-row>
+    <el-row>
+      <div class="w_0100 main">
+        <div class="w_1200">
+          <el-col :span="24" class="mainInfo">
+            <el-col :span="24" class="mainInfoTop">
+              <slot name="mainInfoTop">
+                主体头部导航
+              </slot>
+            </el-col>
+            <el-col :span="24" class="mainInfoMain">
+              <el-col :span="leftSpan" class="mainLeft">
+                <slot name="mainLeft">
+                  主体左边内容
+                </slot>
+              </el-col>
+              <el-col :span="rightSpan" class="mainRight" v-if="needRight">
+                <slot name="mainRight">
+                  主体右边内容
+                </slot>
+              </el-col>
+            </el-col>
+          </el-col>
+        </div>
+      </div>
+    </el-row>
+    <el-row>
+      <div class="w_0100 footer">
+        <div class="w_1200">
+          <el-col :span="24" class="footerTit">
+            <foots></foots>
+          </el-col>
+        </div>
+      </div>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import topMenu from '@/layout/layout-part/top-menu.vue';
+import foots from '@/layout/layout-part/foot.vue';
+import { mapActions, mapState, mapMutations } from 'vuex';
+const jwt = require('jsonwebtoken');
+export default {
+  name: 'detail',
+  props: {
+    needRight: { type: Boolean, default: true },
+  },
+  components: {
+    topMenu,
+    foots,
+  },
+  data: () => ({
+    leftSpan: 18,
+    rightSpan: 6,
+  }),
+  created() {
+    this.checkUrl();
+    this.setUser();
+  },
+  mounted() {
+    if (!this.needRight) {
+      this.$set(this, `leftSpan`, 24);
+      this.$set(this, `rightSpan`, 0);
+    }
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  methods: {
+    ...mapMutations(['setUser']),
+    ...mapActions(['userOperation']),
+    checkUrl() {
+      if (location.search.length > 0) {
+        let params = location.search.replace('?', '').split('&');
+        let paramToken = params.filter(item => item.includes(`token`));
+        if (paramToken.length > 0) {
+          let tokenArr = paramToken[0].split('=');
+          let token = tokenArr[1];
+          sessionStorage.setItem('code', token);
+          let info = jwt.decode(token);
+          this.setUser(info);
+          let pageParam = params.filter(item => !item.includes(`token`));
+          let turnTo = window.location.href.replace(window.location.search, `?${pageParam}`);
+          window.location.href = turnTo;
+        }
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.w_0100 {
+  float: left;
+  width: 100%;
+}
+.w_1200 {
+  margin: 0 auto;
+  width: 1200px;
+}
+.top {
+  float: left;
+  width: 100%;
+  height: 100px;
+  background: #fff;
+}
+.menu {
+  float: left;
+  width: 100%;
+  height: 40px;
+  background: #850000;
+}
+.main {
+  background: #f6f6f6;
+  min-height: 500px;
+}
+.mainInfo {
+  float: left;
+  width: 100%;
+  margin: 20px 0;
+}
+.mainInfoTop {
+  height: 50px;
+  margin: 20px 0 0 0;
+}
+.mainInfoMain {
+  width: 100%;
+  min-height: 1000px;
+  padding: 15px 0;
+  background: #fff;
+}
+.mainLeft {
+  // width: 900px;
+  min-height: 1000px;
+  padding: 0 15px;
+  border-right: 1px solid #f6f6f6;
+}
+.mainRight {
+  float: right;
+  // width: 299px;
+  min-height: 1000px;
+  padding: 0 30px;
+}
+.footer {
+  float: left;
+  width: 100%;
+  height: 64px;
+  background-color: #333;
+  padding: 0.8rem 0 3rem 0;
+}
+.footerTit {
+  float: left;
+  width: 100%;
+  height: 64px;
+}
+</style>

+ 32 - 0
src/layout/share.vue

@@ -0,0 +1,32 @@
+<template>
+  <div id="share">
+    <el-row>
+      <el-col :span="20">&nbsp;</el-col>
+      <el-col :span="4"><vshare :vshareConfig="config"></vshare></el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import vshare from 'vshare';
+export default {
+  name: 'share',
+  props: {},
+  components: {
+    vshare,
+  },
+  data: () => ({
+    config: {
+      common: {
+        bdDesc: '吉林省招聘信息网',
+        bdUrl: window.location.href,
+      },
+    },
+  }),
+  created() {},
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped></style>

+ 22 - 0
src/main.js

@@ -0,0 +1,22 @@
+import Vue from 'vue';
+import App from './App.vue';
+import router from './router';
+import store from './store';
+import '@/plugins/element.js';
+import '@/plugins/axios';
+import '@/plugins/check-res';
+import '@/plugins/meta';
+import '@/plugins/filters';
+import '@/plugins/loading';
+import '@/plugins/var';
+import '@/plugins/methods';
+import '@/plugins/setting';
+import InitStomp from '@/plugins/stomp';
+Vue.config.productionTip = false;
+
+new Vue({
+  router,
+  store,
+  render: h => h(App),
+}).$mount('#app');
+InitStomp();

+ 19 - 0
src/plugins/axios.js

@@ -0,0 +1,19 @@
+import Vue from 'vue';
+import AxiosWrapper from '@/util/axios-wrapper';
+
+const Plugin = {
+  install(vue, options) {
+    // 3. 注入组件
+    vue.mixin({
+      created() {
+        if (this.$store && !this.$store.$axios) {
+          this.$store.$axios = this.$axios;
+        }
+      },
+    });
+    // 4. 添加实例方法
+    vue.prototype.$axios = new AxiosWrapper(options);
+  },
+};
+
+Vue.use(Plugin, { baseUrl: process.env.VUE_APP_AXIOS_BASE_URL });

+ 39 - 0
src/plugins/check-res.js

@@ -0,0 +1,39 @@
+/* eslint-disable no-underscore-dangle */
+/* eslint-disable no-param-reassign */
+/* eslint-disable no-unused-vars */
+/* eslint-disable no-shadow */
+import Vue from 'vue';
+import _ from 'lodash';
+import { Message } from 'element-ui';
+
+const vm = new Vue({});
+const Plugin = {
+  install(Vue, options) {
+    // 4. 添加实例方法
+    Vue.prototype.$checkRes = (res, okText, errText) => {
+      let _okText = okText;
+      let _errText = errText;
+      if (!_.isFunction(okText) && _.isObject(okText) && okText != null) {
+        ({ okText: _okText, errText: _errText } = okText);
+      }
+      const { errcode = 0, errmsg } = res || {};
+      if (errcode === 0) {
+        if (_.isFunction(_okText)) {
+          return _okText();
+        }
+        if (_okText) {
+          Message.success(_okText);
+        }
+        return true;
+      }
+      if (_.isFunction(_errText)) {
+        return _errText();
+      }
+      Message.error(_errText || errmsg);
+      // Message({ message: _errText || errmsg, duration: 60000 });
+      return false;
+    };
+  },
+};
+
+Vue.use(Plugin);

+ 5 - 0
src/plugins/element.js

@@ -0,0 +1,5 @@
+import Vue from 'vue';
+import Element from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+
+Vue.use(Element);

+ 6 - 0
src/plugins/filters.js

@@ -0,0 +1,6 @@
+import Vue from 'vue';
+import filters from '@/util/filters';
+
+for (const method in filters) {
+  Vue.filter(method, filters[method]);
+}

+ 27 - 0
src/plugins/loading.js

@@ -0,0 +1,27 @@
+/* eslint-disable no-console */
+/* eslint-disable no-param-reassign */
+
+import Vue from 'vue';
+
+const Plugin = {
+  // eslint-disable-next-line no-unused-vars
+  install(vue, options) {
+    // 3. 注入组件
+    vue.mixin({
+      created() {
+        // eslint-disable-next-line no-underscore-dangle
+        const isRoot = this.constructor === Vue;
+        // console.log(`rootId:${rootVue_uid}; thisId:${this._uid}`);
+        // if (rootVue_uid !== 3) {
+        //   console.log(this);
+        // }
+        if (isRoot) {
+          const el = document.getElementById('loading');
+          if (el) el.style.display = 'none';
+        }
+      },
+    });
+  },
+};
+
+Vue.use(Plugin, { baseUrl: process.env.VUE_APP_AXIOS_BASE_URL });

+ 4 - 0
src/plugins/meta.js

@@ -0,0 +1,4 @@
+import Vue from 'vue';
+import Meta from 'vue-meta';
+
+Vue.use(Meta);

+ 24 - 0
src/plugins/methods.js

@@ -0,0 +1,24 @@
+import Vue from 'vue';
+import _ from 'lodash';
+const Plugin = {
+  install(Vue, options) {
+    // 3. 注入组件
+    Vue.mixin({
+      created() {
+        if (this.$store && !this.$store.$toUndefined) {
+          this.$store.$toUndefined = this.$toUndefined;
+        }
+      },
+    });
+    // 4. 添加实例方法
+    Vue.prototype.$toUndefined = object => {
+      let keys = Object.keys(object);
+      keys.map(item => {
+        object[item] = object[item] === '' ? (object[item] = undefined) : object[item];
+      });
+      return object;
+    };
+  },
+};
+
+Vue.use(Plugin);

+ 20 - 0
src/plugins/setting.js

@@ -0,0 +1,20 @@
+import Vue from 'vue';
+
+Vue.config.weixin = {
+  // baseUrl: process.env.BASE_URL + 'weixin',
+  baseUrl: 'http://smart.cc-lotus.info/weixin',
+};
+
+Vue.config.stomp = {
+  // brokerURL: 'ws://192.168.1.190:15674/ws',
+  brokerURL: '/ws', // ws://${location.host}/ws
+  connectHeaders: {
+    host: 'smart',
+    login: 'web',
+    passcode: 'web123',
+  },
+  // debug: true,
+  reconnectDelay: 5000,
+  heartbeatIncoming: 4000,
+  heartbeatOutgoing: 4000,
+};

+ 65 - 0
src/plugins/stomp.js

@@ -0,0 +1,65 @@
+/**
+ * 基于WebStomp的消息处理插件
+ */
+
+import Vue from 'vue';
+import _ from 'lodash';
+import assert from 'assert';
+import { Client } from '@stomp/stompjs/esm5/client';
+
+const Plugin = {
+  install(Vue, options) {
+    assert(_.isObject(options));
+    if (options.debug && !_.isFunction(options.debug)) {
+      options.debug = str => {
+        console.log(str);
+      };
+    }
+    assert(_.isString(options.brokerURL));
+    if (!options.brokerURL.startsWith('ws://')) {
+      options.brokerURL = `ws://${location.host}${options.brokerURL}`;
+    }
+
+    // 3. 注入组件
+    Vue.mixin({
+      beforeDestroy: function() {
+        if (this.$stompClient) {
+          this.$stompClient.deactivate();
+          delete this.$stompClient;
+        }
+      },
+    });
+
+    // 4. 添加实例方法
+    Vue.prototype.$stomp = function(subscribes = {}) {
+      // connect to mq
+      const client = new Client(options);
+      client.onConnect = frame => {
+        // Do something, all subscribes must be done is this callback
+        // This is needed because this will be executed after a (re)connect
+        console.log('[stomp] connected');
+        Object.keys(subscribes)
+          .filter(p => _.isFunction(subscribes[p]))
+          .forEach(key => {
+            client.subscribe(key, subscribes[key]);
+          });
+      };
+
+      client.onStompError = frame => {
+        // Will be invoked in case of error encountered at Broker
+        // Bad login/passcode typically will cause an error
+        // Complaint brokers will set `message` header with a brief message. Body may contain details.
+        // Compliant brokers will terminate the connection after any error
+        console.log('Broker reported error: ' + frame.headers['message']);
+        console.log('Additional details: ' + frame.body);
+      };
+
+      client.activate();
+
+      this.$stompClient = client;
+    };
+  },
+};
+export default () => {
+  Vue.use(Plugin, Vue.config.stomp);
+};

+ 10 - 0
src/plugins/var.js

@@ -0,0 +1,10 @@
+import Vue from 'vue';
+
+const Plugin = {
+  install(vue, options) {
+    // 4. 添加实例方法
+    vue.prototype.$limit = 5;
+  },
+};
+
+Vue.use(Plugin);

+ 89 - 0
src/router.js

@@ -0,0 +1,89 @@
+import Vue from 'vue';
+import Router from 'vue-router';
+
+Vue.use(Router);
+
+export default new Router({
+  mode: 'history',
+  base: process.env.VUE_APP_ROUTER,
+  routes: [
+    {
+      path: '/',
+      component: () => import('@/views/index/index.vue'),
+    },
+    {
+      path: '/info',
+      component: () => import('@/views/info/index.vue'),
+      children: [
+        {
+          path: 'list',
+          component: () => import('@/views/info/list.vue'),
+        },
+        {
+          path: 'detail',
+          component: () => import('@/views/info/detail.vue'),
+        },
+      ],
+    },
+    {
+      path: '/jobfair',
+      component: () => import('@/views/jobfair/index.vue'),
+      children: [
+        {
+          path: 'list/:type',
+          component: () => import('@/views/jobfair/list.vue'),
+        },
+      ],
+    },
+    {
+      path: '/jobfair/detail',
+      component: () => import('@/views/jobfair/detail.vue'),
+    },
+    {
+      path: '/talk',
+      component: () => import('@/views/talk/index.vue'),
+      children: [
+        {
+          path: 'list/:type',
+          component: () => import('@/views/talk/list.vue'),
+        },
+      ],
+    },
+    {
+      path: '/talk/detail',
+      component: () => import('@/views/talk/detail.vue'),
+    },
+    {
+      path: '/jobinfo',
+      component: () => import('@/views/jobinfo/index.vue'),
+      children: [
+        {
+          path: 'list',
+          component: () => import('@/views/jobinfo/list.vue'),
+        },
+      ],
+    },
+    {
+      path: '/jobinfo/detail',
+      component: () => import('@/views/jobinfo/detail.vue'),
+    },
+    {
+      path: '/jobs',
+      component: () => import('@/views/jobs/index.vue'),
+      children: [
+        {
+          path: 'list/:type',
+          component: () => import('@/views/jobs/list.vue'),
+        },
+      ],
+    },
+    {
+      path: '/jobs/detail',
+      component: () => import('@/views/jobs/detail.vue'),
+    },
+    {
+      path: '/corp/detail',
+      component: () => import('@/views/corp/index.vue'),
+    },
+  ],
+});

+ 264 - 0
src/store.js

@@ -0,0 +1,264 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+
+Vue.use(Vuex);
+const api = {
+  fairs: '/api/jobs/fairs',
+  fairsInfo: '/api/jobs/fairs/{id}',
+  fairsSimple: '/api/jobs/fairs/{id}/simple',
+  infos: '/api/jobs/infos',
+  infoss: '/api/jobs/infos/{id}',
+  talks: '/api/jobs/talks',
+  talksinfo: '/api/jobs/talks/{id}',
+  posts: '/api/jobs/posts',
+  postsinfo: '/api/jobs/posts/{id}',
+  corpBase: '/api/corp/corps/{corpid}',
+  corpInfo: '/api/corp/corps/{corpid}/info',
+  corpIdentity: '/api/corp/corps/{corpid}/identity',
+  userReg: '/api/stud/registers/{id}',
+  tickets: '/api/jobs/tickets',
+  ticketsinfo: '/api/jobs/tickets/{id}',
+  resumes: '/api/jobs/resumes',
+  resumesInfo: '/api/jobs/resumes/{id}',
+  letters: '/api/jobs/letters',
+  //微信部分
+  connection: '/weixin/qrcode/create',
+  wxtoken: '/weixin/qrcode/{qrcode}/token',
+  studLogin: '/api/stud/login',
+  //双选会企业信息
+  fairCorp: '/api/jobs/faircorps',
+  fairJobs: '/api/jobs/faircorps/{id}/jobs',
+};
+
+export default new Vuex.Store({
+  state: {
+    user: {},
+  },
+  mutations: {
+    setUser(state, payload) {
+      if (payload) {
+        state.user = payload;
+        sessionStorage.setItem('user', JSON.stringify(payload));
+      } else {
+        let user = sessionStorage.getItem('user');
+        if (user) state.user = JSON.parse(user);
+        else return false;
+      }
+    },
+  },
+  actions: {
+    //招聘会
+    async jobfairOperation({ state }, { type, data }) {
+      let result;
+      let { skip, limit } = data;
+      if (type === 'list') {
+        data = this.$toUndefined(data);
+        let { schid } = data;
+        result = await this.$axios.$get(api.fairs, {}, { schid: schid, skip: skip, limit: limit });
+      }
+      if (type === 'search') {
+        let { id } = data;
+        result = await this.$axios.$get(api.fairsInfo, { id: id });
+      }
+      return result;
+    },
+    //招聘会企业信息
+    async fairInfoOperation({ state }, { type, data }) {
+      let result;
+      let { skip, limit } = data;
+      if (type === 'searchCorp') {
+        let { schid, fairid, corpid, status } = data;
+        result = this.$axios.$get(api.fairCorp, {}, { schid: schid, fairid: fairid, corpid: corpid, status: status, skip: skip, limit: limit });
+      }
+      if (type === 'searchJobs') {
+        let { id } = data;
+        result = this.$axios.$get(api.fairJobs, { id: id }, { skip: skip, limit: limit });
+      }
+      return result;
+    },
+    //招聘会简要信息
+    async getfairsSimple({ state }, { type, data }) {
+      let result;
+      if (type === 'list') {
+        let { id } = data;
+        result = await this.$axios.$get(api.fairsSimple, { id: id });
+      }
+      return result;
+    },
+    //在线招聘
+    async jobinfoOperation({ state }, { type, data }) {
+      let { skip, limit } = data;
+      let result;
+      if (type === 'list') {
+        data = this.$toUndefined(data);
+        let { schid, corpname, is_practice } = data;
+        result = await this.$axios.$get(api.infos, {}, { corpname: corpname, schid: schid, is_practice: is_practice, skip: skip, limit: limit });
+      }
+      if (type === 'search') {
+        let { id } = data;
+        result = await this.$axios.$get(api.infoss, { id: id });
+      }
+      return result;
+    },
+    //宣讲会
+    async postTalksInfo({ state }, { type, data }) {
+      let result;
+      let { skip, limit } = data;
+      if (type === 'list') {
+        data = this.$toUndefined(data);
+        let { schid, corpname } = data;
+        result = await this.$axios.$get(api.talks, {}, { corpname: corpname, schid: schid, skip: skip, limit: limit });
+      }
+      if (type === 'search') {
+        let { id } = data;
+        result = await this.$axios.$get(api.talksinfo, { id: id });
+      }
+      return result;
+    },
+    //职位管理
+    async postOperation({ state }, { type, data }) {
+      let { skip, limit } = data;
+      let result;
+      if (type === 'list') {
+        data = this.$toUndefined(data);
+        let { schid, corpname, is_practice, corpid } = data;
+        result = await this.$axios.$get(
+          `${api.posts}`,
+          {},
+          { schid: schid, corpid: corpid, corpname: corpname, is_practice: is_practice, skip: skip, limit: limit }
+        );
+      }
+      if (type === 'search') {
+        let { id } = data;
+        result = await this.$axios.$get(api.postsinfo, { id: id });
+      }
+      return result;
+    },
+    //企业基本信息
+    async corpOperation({ state }, { type, data }) {
+      let result;
+      if (type === 'search') {
+        let { corpid } = data;
+        result = await this.$axios.$get(api.corpInfo, { corpid: corpid });
+      }
+      if (type === 'component') {
+        let { corpid } = data;
+        let base = await this.$axios.$get(api.corpBase, { corpid: corpid });
+        let info = await this.$axios.$get(api.corpInfo, { corpid: corpid });
+        let identity = await this.$axios.$get(api.corpIdentity, { corpid: corpid });
+        result = {
+          data: { ...info.data, ...identity.data, ...base.data },
+          errcode: `${info.errcode}` === '0' && `${identity.errcode}` === '0' && `${base.errcode}` === '0' ? '0' : '1',
+        };
+      }
+      return result;
+    },
+    // 入场券接口
+    async ticketsOperation({ state }, { type, data }) {
+      let result;
+      let { skip, limit } = data;
+      if (type === 'add') {
+        let { query, body } = data;
+        result = await this.$axios.$post(api.tickets, body, {}, query);
+      }
+      if (type === 'list') {
+        let { schid, fairid, studid } = data;
+        result = await this.$axios.$get(api.tickets, {}, { schid: schid, fairid: fairid, studid: studid, skip: skip, limit: limit });
+      }
+      if (type === 'search') {
+        let { id } = data;
+        result = await this.$axios.$get(api.ticketsinfo, { id: id });
+      }
+      if (type === 'update') {
+        let { info, id } = data;
+        result = await this.$axios.$post(api.ticketsinfo, info, { id: id });
+      }
+      if (type === 'delete') {
+        let { id } = data;
+        result = await this.$axios.$delete(api.ticketsinfo, {}, { id: id });
+      }
+      return result;
+    },
+    //用户
+    async userOperation({ stata }, { type, data }) {
+      let result;
+      if (type === 'search') {
+        let { studid } = data;
+        result = await this.$axios.$get(api.userReg, { id: studid });
+      }
+      if (type === 'login') {
+        let { loginType, info } = data;
+        result = this.$axios.$post(api.studLogin, info, {}, { type: loginType });
+      }
+      return result;
+    },
+    //求职信
+    async lettersOperation({ state }, { type, data }) {
+      let result;
+      let { skip, limit } = data;
+      if (type === 'list') {
+        let { resume_id, status, corpname, studname, post_id } = data;
+        result = await this.$axios.$get(
+          api.letters,
+          {},
+          { post_id: post_id, resume_id: resume_id, status: status, corpname: corpname, studname: studname, skip: skip, limit: limit }
+        );
+      }
+      if (type === 'apply') {
+        let { query, body } = data;
+        result = await this.$axios.$post(api.letters, body, {}, query);
+      }
+      return result;
+    },
+    // 简历管理
+    async resumesOperation({ state }, { type, data }) {
+      let result;
+      if (type === 'add') {
+        let { info, schid, studid } = data;
+        result = await this.$axios.$post(api.resumes, info, {}, { schid: schid, studid: studid });
+      }
+      if (type === 'search') {
+        let { id } = data;
+        result = await this.$axios.$get(api.resumesInfo, { id: id });
+      }
+      if (type === 'update') {
+        let { id, info } = data;
+        result = await this.$axios.$post(api.resumesInfo, info, { id: id });
+      }
+      return result;
+    },
+    //微信部分
+    async createConnection() {
+      let result = await this.$axios.$post(api.connection);
+      if (result.errcode != undefined && result.errcode === 0) {
+        console.log('create qrcode success', result.data);
+        return result.data;
+      }
+      console.error('create qrcode fail', result);
+    },
+    async getWxtoken({ state }, qrcode) {
+      let result = await this.$axios.$post(api.wxtoken, {}, { qrcode: qrcode });
+      if (result.errcode != undefined && result.errcode === 0) {
+        console.log('qrcode login success', result);
+        return result.token;
+      }
+      console.error('create qrcode fail', result);
+    },
+    //抓取信息
+    async getBugInfo({ state }, { data }) {
+      let { skip, limit } = data;
+      let result = await this.$axios.$get('/bugInfo/newsinfo', {}, { skip: skip, limit: limit });
+      return result;
+    },
+  },
+});
+
+const data = {
+  testItem: {
+    id: Math.random(),
+    name: 'name',
+    age: 'age',
+    tel: '13099876544',
+  },
+};

+ 132 - 0
src/util/axios-wrapper.js

@@ -0,0 +1,132 @@
+/* eslint-disable no-console */
+/* eslint-disable no-param-reassign */
+
+import _ from 'lodash';
+import Axios from 'axios';
+import { Util, Error } from 'naf-core';
+// import { Indicator } from 'mint-ui';
+import util from './user-util';
+
+const { trimData, isNullOrUndefined } = Util;
+const { ErrorCode } = Error;
+
+let currentRequests = 0;
+
+export default class AxiosWrapper {
+  constructor({ baseUrl = '', unwrap = true } = {}) {
+    this.baseUrl = baseUrl;
+    this.unwrap = unwrap;
+  }
+
+  // 替换uri中的参数变量
+  static merge(uri, query = {}) {
+    if (!uri.includes(':')) {
+      return uri;
+    }
+    const keys = [];
+    const regexp = /\/:([a-z0-9_]+)/gi;
+    let res;
+    // eslint-disable-next-line no-cond-assign
+    while ((res = regexp.exec(uri)) != null) {
+      keys.push(res[1]);
+    }
+    keys.forEach(key => {
+      if (!isNullOrUndefined(query[key])) {
+        uri = uri.replace(`:${key}`, query[key]);
+      }
+    });
+    return uri;
+  }
+  //替换路由方法
+  static routerChange(uri, router = {}) {
+    let keys = Object.keys(router);
+    keys.forEach(key => {
+      uri = _.replace(uri, `{${key}}`, router[key]);
+    });
+    return uri;
+  }
+
+  $get(uri, router, query, options) {
+    return this.$request(uri, null, query, options, router);
+  }
+
+  $post(uri, data = {}, router, query, options) {
+    return this.$request(uri, data, query, options, router);
+  }
+
+  $delete(uri, data = {}, router, query, options = {}) {
+    options = { ...options, method: 'delete' };
+    return this.$request(uri, data, query, options, router);
+  }
+
+  async $request(uri, data, query, options, router) {
+    // TODO: 合并query和options
+    if (_.isObject(query) && _.isObject(options)) {
+      options = { ...options, params: query, method: 'get' };
+    } else if (_.isObject(query) && !query.params) {
+      options = { params: query };
+    } else if (_.isObject(query) && query.params) {
+      options = query;
+    }
+    if (!options) options = {};
+    if (options.params) options.params = trimData(options.params);
+    let url = AxiosWrapper.merge(uri, options.params);
+    //处理url部分需要替换参数的情况
+    if (_.isObject(router)) {
+      url = AxiosWrapper.routerChange(url, router);
+    }
+    console.log(url);
+    currentRequests += 1;
+    // Indicator.open({
+    //   spinnerType: 'fading-circle',
+    // });
+
+    try {
+      const axios = Axios.create({
+        baseURL: this.baseUrl,
+      });
+      axios.defaults.headers.common.Authorization = util.token;
+      let res = await axios.request({
+        method: isNullOrUndefined(data) ? 'get' : 'post',
+        url,
+        data,
+        responseType: 'json',
+        ...options,
+      });
+      res = res.data;
+      const { errcode, errmsg, details } = res;
+      if (errcode) {
+        console.warn(`[${uri}] fail: ${errcode}-${errmsg} ${details}`);
+        return res;
+      }
+      // unwrap data
+      if (this.unwrap) {
+        res = _.omit(res, ['errmsg', 'details']);
+        const keys = Object.keys(res);
+        if (keys.length === 1 && keys.includes('data')) {
+          res = res.data;
+        }
+      }
+      return res;
+    } catch (err) {
+      let errmsg = '接口请求失败,请稍后重试';
+      if (err.response) {
+        const { status } = err.response;
+        if (status === 401) errmsg = '用户认证失败,请重新登录';
+        if (status === 403) errmsg = '当前用户不允许执行该操作';
+      }
+      console.error(
+        `[AxiosWrapper] 接口请求失败: ${err.config && err.config.url} - 
+        ${err.message}`
+      );
+      return { errcode: ErrorCode.SERVICE_FAULT, errmsg, details: err.message };
+    } finally {
+      /* eslint-disable */
+      currentRequests -= 1;
+      if (currentRequests <= 0) {
+        currentRequests = 0;
+        // Indicator.close();
+      }
+    }
+  }
+}

+ 10 - 0
src/util/filters.js

@@ -0,0 +1,10 @@
+import _ from 'lodash';
+
+const filters = {
+  getName(object) {
+    const { data, searchItem } = object;
+    return _.get(data, searchItem) === undefined ? '' : _.get(data, searchItem);
+  },
+};
+
+export default filters;

+ 30 - 0
src/util/menus.js

@@ -0,0 +1,30 @@
+export const coreMenu = [
+  {
+    path: '/talk/list/in',
+    name: '校内宣讲会',
+  },
+  {
+    path: '/talk/list/out',
+    name: '校外宣讲会',
+  },
+  {
+    path: '/jobfair/list/in',
+    name: '校内招聘会',
+  },
+  {
+    path: '/jobfair/list/out',
+    name: '校外招聘会',
+  },
+  {
+    path: '/jobinfo/list',
+    name: '在线招聘',
+  },
+  {
+    path: '/jobs/list/official',
+    name: '正式岗位',
+  },
+  {
+    path: '/jobs/list/internship',
+    name: '实习岗位',
+  },
+];

+ 50 - 0
src/util/methods-util.js

@@ -0,0 +1,50 @@
+import { Util } from 'naf-core';
+
+const { isNullOrUndefined } = Util;
+
+export default {
+  //判断信息是否过期
+  isDateOff(dataDate) {
+    const now = new Date(new Date().getTime() - 24 * 60 * 60 * 1000);
+    dataDate = new Date(dataDate);
+    return now.getTime() <= dataDate.getTime();
+  },
+  //判断企业是否可以执行此动作/显示
+  checkCorp(data) {
+    const { role, unit, selfUnit, status, displayType, userid } = data;
+    if (!isNullOrUndefined(selfUnit) && !isNullOrUndefined(status)) {
+      return role === 'corp' && selfUnit === unit && status === '0';
+    } else if (!isNullOrUndefined(displayType)) {
+      if (role === 'corp') {
+        return role === displayType;
+      } else {
+        return role === displayType && !isNullOrUndefined(userid);
+      }
+    }
+  },
+  //获取url的参数params
+  getParams() {
+    let str = location.href;
+    let num = str.indexOf('?');
+    const param = {};
+    str = str.substr(num + 1);
+    let num2 = str.indexOf('#');
+    let str2 = '';
+    if (num2 > 0) {
+      str2 = str.substr(0, num2);
+    } else {
+      num2 = str.indexOf('/');
+      str2 = str.substr(0, num2);
+    }
+    const arr = str2.split('&');
+    for (let i = 0; i < arr.length; i++) {
+      num = arr[i].indexOf('=');
+      if (num > 0) {
+        const name = arr[i].substring(0, num);
+        const value = arr[i].substr(num + 1);
+        param[name] = decodeURI(value);
+      }
+    }
+    return param;
+  },
+};

+ 47 - 0
src/util/optionTitles.js

@@ -0,0 +1,47 @@
+export const JOBFAIR_TITLE = [
+  { prop: 'subject', label: '' },
+  { prop: 'address', label: '举办地址' },
+  { prop: 'date', label: '举办日期' },
+  { prop: 'unit', label: '分站信息' },
+];
+
+export const CAMPUS_TITLE = [
+  { prop: 'subject', label: '' },
+  { prop: 'address', label: '举办地址' },
+  { prop: 'status', label: '审核状态' },
+  { prop: 'date', label: '举办日期' },
+  { prop: 'unit', label: '分站信息' },
+];
+
+export const JOBINFO_TITLE = [
+  { prop: 'title', label: '' },
+  { prop: 'count', label: '需求人数' },
+  { prop: 'nature.name', label: '工作性质' },
+  { prop: 'salary.name', label: '薪资待遇' },
+  { prop: 'xlreqs.name', label: '最低学历' },
+  { prop: 'city.name', label: '所在城市' },
+  // { prop: 'expired', label: '状态' },
+];
+
+export const RESUME_TITLE = [{ prop: 'title', label: '' }];
+
+export const LETTER_TITLE = [
+  { prop: 'title', label: '' },
+  { prop: 'corpname', label: '企业名称' },
+  { prop: 'type', label: '类型' },
+  { prop: 'status', label: '状态' },
+];
+
+export const TICKET_TITLE = [
+  { prop: 'subject', label: '' },
+  { prop: 'type', label: '门票类型' },
+  { prop: 'origin', label: '' },
+  { prop: 'date', label: '举办日期' },
+];
+
+export const CORP_JOBFAIR = [
+  { prop: 'subject', label: '' },
+  { prop: 'time', label: '举办时间' },
+  { prop: 'date', label: '举办日期' },
+  { prop: 'unit', label: '分站信息' },
+];

+ 96 - 0
src/util/qrcode.vue

@@ -0,0 +1,96 @@
+<template>
+  <div id="qrcodes" style="width:100%;">
+    <mt-header title="二维码">
+      <mt-button class="bgnone" slot="left" @click="$router.go(-1)">返回</mt-button>
+    </mt-header>
+    <span v-if="user.role === 'user'">
+      <li class="txtQr" style="padding-top:7vh;">学生姓名:{{ userInfo.xm || '' }}</li>
+      <li class="txtQr">门票类型:{{ ticketType }}</li>
+    </span>
+    <div id="qrcode" style="display:flex;justify-content:center;align-items:center;" :style="newHeight" ref="qrcode">
+      <canvas id="canvas" style="display:-webkit-inline-box;width: 4rem !important;height:4rem !important;margin-top: 200px;"></canvas>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapActions, mapState, mapMutations } from 'vuex';
+import QRCode from 'qrcode';
+export default {
+  name: 'qrcodes',
+  data() {
+    return {
+      id: this.$route.query.id || '',
+      ticketType: this.$route.query.type && this.$route.query.type === '0' ? '普通票' : '受限票' || '',
+      popupVisible: false,
+    };
+  },
+  computed: {
+    ...mapState({
+      user: state => state.publics.user,
+      userInfo: state => state.self.userInfo,
+    }),
+    newHeight: {
+      get() {
+        let height;
+        if (this.user.role === 'user') {
+          height = window.screen.availHeight * 0.3 + 'px';
+        } else {
+          height = window.screen.availHeight * 0.6 + 'px';
+        }
+        let style = { height: height };
+        return style;
+      },
+    },
+  },
+  created() {
+    this.$nextTick(() => {
+      this.initQrcode();
+    });
+  },
+  methods: {
+    async initQrcode() {
+      if (!this.booForQrcode) {
+        await QRCode.toCanvas(document.getElementById('canvas'), this.id, {
+          width: 300,
+          margin: 0,
+          color: { dark: this.$route.query.type === '0' ? '#00ff14' : '#FF9900' },
+        });
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.txtQr {
+  font-size: 14px;
+  text-align: center;
+  min-height: 30px;
+  margin-bottom: 1px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.mint-header {
+  -webkit-box-align: center;
+  -ms-flex-align: center;
+  align-items: center;
+  background-color: #26a2ff;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  color: #fff;
+  display: -webkit-box;
+  display: -ms-flexbox;
+  display: flex;
+  height: 50px;
+  line-height: 50px;
+  color: #fff;
+  font-size: 16px;
+  background: #2577e3;
+  padding: 0;
+  position: relative;
+  text-align: center;
+  white-space: nowrap;
+}
+</style>

+ 69 - 0
src/util/user-util.js

@@ -0,0 +1,69 @@
+/* eslint-disable no-console */
+export default {
+  get user() {
+    const val = sessionStorage.getItem('user');
+    try {
+      if (val) return JSON.parse(val);
+    } catch (err) {
+      console.error(err);
+    }
+    return null;
+  },
+  set user(userinfo) {
+    sessionStorage.setItem('user', JSON.stringify(userinfo));
+  },
+  get token() {
+    return sessionStorage.getItem('token');
+  },
+  set token(token) {
+    sessionStorage.setItem('token', token);
+  },
+  get openid() {
+    return sessionStorage.getItem('openid');
+  },
+  set openid(openid) {
+    sessionStorage.setItem('openid', openid);
+  },
+  get isGuest() {
+    return !this.user || this.user.role === 'guest';
+  },
+  save({ userinfo, token }) {
+    sessionStorage.setItem('user', JSON.stringify(userinfo));
+    sessionStorage.setItem('token', token);
+  },
+
+  get corpInfo() {
+    const val = sessionStorage.getItem('corpInfo');
+    if (val) return JSON.parse(val);
+    return null;
+  },
+  set corpInfo(corpInfo) {
+    sessionStorage.setItem('corpInfo', JSON.stringify(corpInfo));
+  },
+  saveCorpInfo(corpInfo) {
+    sessionStorage.setItem('corpInfo', JSON.stringify(corpInfo));
+  },
+
+  get unit() {
+    const val = sessionStorage.getItem('unit');
+    if (val) return JSON.parse(val);
+    return null;
+  },
+  set unit(unitList) {
+    sessionStorage.setItem('unit', JSON.stringify(unitList));
+  },
+  saveUnit(unitList) {
+    sessionStorage.setItem('unit', JSON.stringify(unitList));
+  },
+  get userInfo() {
+    const val = sessionStorage.getItem('userInfo');
+    if (val) return JSON.parse(val);
+    return null;
+  },
+  set userInfo(userInfo) {
+    sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
+  },
+  saveUserInfo(userInfo) {
+    sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
+  },
+};

+ 139 - 0
src/views/corp/index.vue

@@ -0,0 +1,139 @@
+<template>
+  <div id="index">
+    <recruitdetail-layout :needRight="false">
+      <template v-slot:mainInfoTop>
+        <el-row>
+          <el-col :span="24">
+            <el-breadcrumb separator-class="el-icon-arrow-right">
+              <el-breadcrumb-item :to="{ path: '/' }">
+                <i class="el-icon-s-home"></i>
+                <span>网站首页</span>
+              </el-breadcrumb-item>
+              <el-breadcrumb-item class="webDetail">企业详情</el-breadcrumb-item>
+            </el-breadcrumb>
+          </el-col>
+        </el-row>
+        <share></share>
+      </template>
+      <template v-slot:mainLeft>
+        <el-row class="webMessage" type="flex">
+          <el-col :span="24">企业信息</el-col>
+        </el-row>
+        <el-row type="flex" class="baseRow">
+          <el-col :span="3">
+            <el-image style="width:5.25rem;height:5.25rem;" :src="corpInfo.logo_url" fit="fill"></el-image>
+          </el-col>
+          <el-col :span="18">
+            <el-row id="corpname">
+              <el-col :span="24">{{ corpInfo.corpname }}</el-col>
+            </el-row>
+            <el-row id="industry">
+              <el-col :span="8">
+                行业:<span>{{ corpInfo.industry }}</span>
+              </el-col>
+              <el-col :span="12">
+                规模:<span>{{ corpInfo.scale }}</span>
+              </el-col>
+            </el-row>
+            <el-row id="address">
+              <el-col :span="8">
+                城市:<span>{{ corpInfo.province }}-{{ corpInfo.city }}</span>
+              </el-col>
+              <el-col :span="16">
+                地址:<span>{{ corpInfo.address }}</span>
+              </el-col>
+            </el-row>
+            <el-row id="content1">
+              <el-col :span="24">
+                联系电话:<span>{{ corpInfo.job_tel }}</span>
+              </el-col>
+            </el-row>
+            <el-row id="content2">
+              <el-col :span="24">
+                邮箱:<span>{{ corpInfo.job_email }}</span>
+              </el-col>
+            </el-row>
+            <el-row id="other">
+              <el-col :span="8">
+                注册资金:<span>{{ corpInfo.reg_capital }}</span>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="24">
+                企业标签:
+                <el-tag v-for="(item, index) in corpInfo.tags" :key="index">{{ item }}</el-tag>
+              </el-col>
+            </el-row>
+          </el-col>
+        </el-row>
+        <web-intro title="单位简介" :info="corpInfo"></web-intro>
+        <web-jobs title="招聘职位" :info="jobList" @search="searchJobs"> </web-jobs>
+      </template>
+    </recruitdetail-layout>
+  </div>
+</template>
+
+<script>
+import recruitdetailLayout from '@/layout/recruitdetail-layout.vue';
+import share from '@/layout/share.vue';
+import webIntro from '@/layout/detail/web-intro.vue';
+import webJobs from '@/layout/detail/web-jobs.vue';
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    recruitdetailLayout,
+    share,
+    webIntro,
+    webJobs,
+  },
+  data: () => ({
+    corpInfo: {},
+    jobList: [],
+  }),
+  created() {
+    this.search();
+  },
+  computed: {},
+  methods: {
+    ...mapActions(['corpOperation', 'postOperation']),
+    async search() {
+      if (!this.$route.query.id) return;
+      let result = await this.corpOperation({ type: 'component', data: { corpid: this.$route.query.id } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, 'corpInfo', result.data);
+        this.$set(this.corpInfo, `id`, this.$route.query.id);
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+    async searchJobs(query) {
+      console.log(query);
+      let result = await this.postOperation({ type: 'list', data: { corpid: this.$route.query.id, ...query } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `jobList`, result);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.webMessage {
+  border-left: 0.1875rem solid #850000;
+  font-size: 1rem;
+  line-height: 1.875rem;
+  height: 1.875rem;
+  padding: 0 0.9375rem;
+  margin: 0 0 0 -0.9375rem;
+}
+.baseRow {
+  padding: 1.25rem;
+  font-size: 0.875rem;
+  color: #333333;
+  span {
+    padding-left: 0.5rem;
+  }
+}
+</style>

File diff suppressed because it is too large
+ 1527 - 0
src/views/index/index.vue


+ 122 - 0
src/views/info/detail.vue

@@ -0,0 +1,122 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24">
+        <el-breadcrumb separator-class="el-icon-arrow-right">
+          <el-breadcrumb-item :to="{ path: '/' }"
+            ><i class="el-icon-s-home"></i>
+            <span style="font-size: 0.8rem;">网站首页</span>
+          </el-breadcrumb-item>
+          <el-breadcrumb-item><span style="font-size: 0.9rem;">学校概况</span></el-breadcrumb-item>
+          <el-breadcrumb-item><span style="font-zise: 0.8rem;">详情</span></el-breadcrumb-item>
+        </el-breadcrumb>
+      </el-col>
+      <el-col :span="24" align="right" style="font-size: 0.8rem;">插件</el-col>
+      <el-col :span="24" align="center" style="font-size: 1.5rem; padding-top: 1rem;">学校简介</el-col>
+      <el-col :span="24" align="center" class="date">2016年6月22日 点击人次:26125</el-col>
+      <el-col :span="24" style="padding-top: 1rem;">
+        <el-card class="box-card" shadow="never" style="padding-top: 1.5rem;">
+          <div slot="header" class="school_header">
+            <span align="left" class="schoolOverview">学校简介</span>
+          </div>
+          <el-card shadow="never">
+            <el-col
+              >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;长春工业大学是一所以工为主,工、管、文、理、经、法、教育、艺术等多学科相互支撑、协调发展的省属重点大学,是吉林省高层次人才培养、应用技术研发、高新技术产品研制、高水平社会服务的重要基地。
+              1992年被吉林省政府确定为首批三所省属重点高校之一,在2004年全国本科教学工作水平评估中获得优秀等级。2014年,学校作为全国首批、吉林省首家高校,顺利通过了教育部本科教学审核评估,赢得专家组高度评价。</el-col
+            >
+            <el-col>&nbsp;&nbsp;&nbsp;</el-col>
+            <el-col
+              >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;学校现有全日制在校学生20000余名,有教职员工1800余名。学校设有20个学院,2个教研部,1个工程训练中心;拥有2个省重中之重立项建设学科,8个省优势特色重点学科,3个一级学科博士点,17个一级学科硕士点,54个本科专业。
+              创建了以国家地方联合工程实验室、教育部工程研究中心和教育部重点实验室等为代表的25个国家和省部级科研机构,19个国家级和省级实验教学示范中心。</el-col
+            >
+            <el-col>&nbsp;&nbsp;&nbsp;</el-col>
+            <el-col
+              >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;长春工业大学是国务院学位委员会、教育部批准的首批具有学士学位授予权的高等学校之一,是教育部批准的举办国家示范性软件职业技术学院的35所院校之一。
+              形成了以本科教育为主体,积极发展研究生教育,适度发展高等职业技术教育和成人教育的人才培养体系和多层次、多渠道、多规格的办学格局。</el-col
+            >
+            <el-col>&nbsp;&nbsp;&nbsp;</el-col>
+            <el-col
+              >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;学校拥有一支整体结构合理、素质与水平较高的教师队伍。现有专任教师1119名,其中教授175名,博士生指导教师33名,硕士生指导教师500名;
+              教师中入选国家百千万人才工程1名,国家有突出贡献中青年专家2名,享受国务院政府特殊津贴33名,全国百名优秀留学回国先进个人1名,全国五一劳动奖章获得者1名,全国优秀教育工作者2名,全国模范教师1名,全国优秀教师3名,教育部新世纪优秀人才6人;
+              吉林省高级专家12名,吉林省拔尖创新人才28名,吉林省有突出贡献的中青年专业技术人才24名,长白山学者特聘教授3人、长白山学者讲座教授4人、长白山技能名师2人,
+              吉林省学科建设工程首席教授1名、主讲教授1名,优秀中青年骨干教师5名,吉林省高校优秀中青年骨干教师10名,吉林省跨世纪学术带头人后备人选30名,吉林英才奖章获得者13名,吉林省特等劳动模范1名,吉林省教学名师9名;享受长春市政府特殊津贴4名。</el-col
+            >
+            <el-col>&nbsp;&nbsp;&nbsp;</el-col>
+            <el-col
+              >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;学校多年来着力于教学改革、教学建设和教学管理,重视学生实践能力和创新精神的培养,形成了适应社会需求的人才培养模式,在就业市场中保持了很强的竞争力。
+              学校在国内较早地开展了创新教育和学习的革命,使学生的创新能力和学习能力普遍增强,深受用人单位的好评。
+              多年来,我校毕业生以综合素质高、实践能力强、适应性好、安心基层、踏实肯干、留得住、用得上、信得过等特点受到用人单位的普遍好评,毕业生就业率始终在省内高校中位于前列,曾荣获“全国普通高校毕业生就业工作先进集体”,并成为全国首批毕业生就业50所典型经验高校之一。</el-col
+            >
+            <el-col>&nbsp;&nbsp;&nbsp;</el-col>
+            <el-col
+              >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;学校建有39个研究所,32个省、部级以上科研基地。各类专业实验室设备仪器精良,实验条件先进。校图书馆藏书160余万册。学校还有一批设备先进、功能齐全的多媒体教室以及省内高校一流的体育场馆。
+              学校的计算机校园网通过光纤与国际互联网相连,学生在校园内随处可以享受宽带网络服务,阅读数字期刊和电子图书等。</el-col
+            >
+            <el-col>&nbsp;&nbsp;&nbsp;</el-col>
+            <el-col
+              >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;学校始终坚持为地方经济建设和社会发展服务的办学宗旨,依托一汽、吉化等大型重点企业和新兴高科技企业,开展人才培养、科技研发和社会服务。以服务求支持,以贡献求发展,形成了鲜明的办学特色。
+              近年来,学校紧紧抓住振兴老工业基地的机遇,积极发挥工科高校的学科优势和人才优势,全面整合提升科技创新能力和服务水平,主动承担起科技支撑的重要任务。我校的科研与产业结合紧密,成果转化率高,碳纤维、ABS树脂、铝合金搅拌摩擦焊、汽车安全气囊自动生产线、冶金节能等一批重大成果在我省实现了产业化。
+              五年来,学校承担各类科研项目1710项,全口径科研经费3.2亿元,其中国家及国务院各部门项目82项,获得省部级奖励101项,获得国家授权发明专利99项,SCI、EI、CSSCI和ISTP收录论文1215篇。</el-col
+            >
+            <el-col>&nbsp;&nbsp;&nbsp;</el-col>
+            <el-col
+              >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+              学校是教育部首批审定有条件接收外国留学生的高校之一,先后与英、美、日、韩、俄等国的高校、科研机构建立友好合作关系,互派留学生,互派专家、学者进行国际学术交流和科研协作,并与美国奥克兰大学和波特兰州立大学合作举办本科教育项目。</el-col
+            >
+            <el-col>&nbsp;&nbsp;&nbsp;</el-col>
+            <el-col
+              >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;学校在注重抓好教学和科研的同时,十分重视学生综合素质的培养和校园科技、文化氛围的营造,各种学生社团常年开展丰富多彩的科技、文艺、体育活动。
+              学校注重对学生思想政治素质和道德情操的培养,党建和思想政治工作连续两次被中组部、中宣部、教育部评为“全国党的建设和思想政治工作先进高等学校”。
+              连续多年被省委、省政府命名为“基层党组织标兵”、“精神文明建设标兵单位”和“普通高等教育先进学校”。学校于2009年荣获“全国精神文明建设工作先进单位”称号,2011年荣获“全国文明单位”称号。
+              2012年,学校党委荣获“全国创先争优先进基层党组织”称号。</el-col
+            >
+            <el-col>&nbsp;&nbsp;&nbsp;</el-col>
+            <el-col
+              >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;目前,学校紧紧抓住建设高教强省的良好机遇,全面深化内部综合管理体制改革,加快内涵发展,为把学校建成国内一流的地方工业大学而努力奋斗。</el-col
+            >
+            <el-col>&nbsp;&nbsp;&nbsp;</el-col>
+            <el-col>&nbsp;&nbsp;&nbsp;</el-col>
+          </el-card>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'index',
+  props: {},
+  components: {},
+  data: () => ({
+    menuList: [{ index: '1', name: '学校简介' }, { index: '2', name: '学校概括' }],
+  }),
+  created() {},
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+.date {
+  font-size: 0.8rem;
+  padding-top: 1rem;
+  border-bottom: 1px dashed #f6f6f6;
+  padding-bottom: 15px;
+}
+.schoolOverview {
+  font-size: 1rem;
+  width: 75px;
+  float: left;
+  height: 21px;
+  line-height: 21px;
+  text-align: center;
+  background: #8ec965;
+  color: #fff;
+}
+.school_header {
+  width: 100%;
+  height: 30px;
+  border-top: 2px solid #8ec965;
+}
+</style>

+ 47 - 0
src/views/info/index.vue

@@ -0,0 +1,47 @@
+<template>
+  <div id="index">
+    <detail-layout>
+      <template v-slot:mainSide>
+        <menus :menuList="menuList"></menus>
+      </template>
+      <template v-slot:mainMain>
+        <router-view />
+      </template>
+    </detail-layout>
+  </div>
+</template>
+
+<script>
+import menus from '@/layout/layout-part/menus.vue';
+import detailLayout from '@/layout/detail-layout.vue';
+export default {
+  methods: {
+    handleSizeChange(val) {
+      console.log(`每页 ${val} 条`);
+    },
+    handleCurrentChange(val) {
+      console.log(`当前页: ${val}`);
+    },
+    test(val) {
+      this.$set(this, `activeMenu`, val);
+    },
+  },
+  name: 'index',
+  props: {},
+
+  components: {
+    detailLayout,
+    menus,
+  },
+  data: () => ({
+    input3: '',
+    currentPage4: 1,
+    activeMenu: '1',
+    menuList: [{ index: '1', name: '创业法规' }, { index: '2', name: '创业培训' }, { index: '3', name: '创业案例' }],
+  }),
+  created() {},
+  computed: {},
+};
+</script>
+
+<style lang="less" scoped></style>

+ 66 - 0
src/views/info/list.vue

@@ -0,0 +1,66 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="1"><i class="el-icon-s-home"></i></el-col>
+      <el-col :span="23" style="margin-top:0.3rem">
+        <el-breadcrumb separator=">">
+          <el-breadcrumb-item :to="{ path: '/' }"><span style="color:#666666">网站首页</span></el-breadcrumb-item>
+          <el-breadcrumb-item>
+            <a href="/"><span style="color:#666666">创业案例</span></a>
+          </el-breadcrumb-item>
+          <el-breadcrumb-item><span style="color:#999999">文章列表</span></el-breadcrumb-item>
+        </el-breadcrumb>
+      </el-col>
+    </el-row>
+    <el-row>
+      <el-col :span="24" style="margin-top: 1rem; width:50%">
+        <el-input size="mini" placeholder="请输入文章标题" v-model="input3">
+          <el-button slot="append" icon="el-icon-search"></el-button>
+        </el-input>
+      </el-col>
+    </el-row>
+    <el-row
+      style="border-bottom-style:dashed; border-width:1px;border-color:#666666;font-size: small; padding: 0.5rem 0;"
+      v-for="(item, index) in 10"
+      :key="index"
+    >
+      <el-col style="padding-top: 0.5rem;" :span="21">
+        <el-link @click="$router.push({ path: '/info/detail', query: { id: 'none' } })">学有所成,扎根农村,做新时代的“现代农民”</el-link>
+      </el-col>
+      <el-col :span="3" style="color:#999999; padding-top: 0.7rem;"><span style="padding: 0.5rem 0;">2016-11-25</span></el-col>
+    </el-row>
+    <el-row style="margin-top:1rem;">
+      <el-pagination @current-change="handleCurrentChange" :current-page="currentPage4" :page-size="15" layout="total, prev, pager, next, jumper" :total="100">
+      </el-pagination>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  methods: {
+    handleSizeChange(val) {
+      console.log(`每页 ${val} 条`);
+    },
+    handleCurrentChange(val) {
+      console.log(`当前页: ${val}`);
+    },
+    test(val) {
+      this.$set(this, `activeMenu`, val);
+    },
+  },
+  name: 'index',
+  props: {},
+
+  components: {},
+  data: () => ({
+    input3: '',
+    currentPage4: 1,
+    activeMenu: '1',
+  }),
+  created() {},
+  computed: {},
+};
+</script>
+
+<style lang="less" scoped></style>

+ 144 - 0
src/views/jobfair/detail.vue

@@ -0,0 +1,144 @@
+<template>
+  <div id="detail">
+    <recruitdetail-layout :needRight="false">
+      <template v-slot:mainInfoTop>
+        <el-row>
+          <el-col :span="24">
+            <el-breadcrumb separator-class="el-icon-arrow-right">
+              <el-breadcrumb-item :to="{ path: '/' }">
+                <i class="el-icon-s-home"></i>
+                <span>网站首页</span>
+              </el-breadcrumb-item>
+              <el-breadcrumb-item><span>招聘会</span></el-breadcrumb-item>
+              <el-breadcrumb-item class="webDetail">详情</el-breadcrumb-item>
+            </el-breadcrumb>
+          </el-col>
+        </el-row>
+        <share></share>
+      </template>
+      <template v-slot:mainLeft>
+        <jobfair-head title="招聘会信息" :info="info" @getTicket="getTicket"></jobfair-head>
+        <jobfair-context title="招聘会说明" :info="info"></jobfair-context>
+        <user-defined title="招聘会相关">
+          <el-tabs v-model="tabs" type="card">
+            <el-tab-pane label="企业列表" name="corp">
+              <el-table :data="corpList" style="width: 100%" stripe :show-header="false">
+                <el-table-column label="企业" prop="corpname">
+                  <template v-slot="scoped">
+                    <el-link @click="$router.push({ path: '/corp/detail', query: { id: scoped.row.corpid } })">{{ scoped.row.corpname }}</el-link>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </el-tab-pane>
+            <el-tab-pane label="招聘职位" name="jobs">
+              <web-jobs :info="jobList" type="2" :origin="info.id" @search="searchJobs"> </web-jobs>
+            </el-tab-pane>
+          </el-tabs>
+        </user-defined>
+      </template>
+    </recruitdetail-layout>
+    <toLogin :display="loginDialog" @close="loginDialog = false" title="请登录"></toLogin>
+  </div>
+</template>
+
+<script>
+import userDefined from '@/layout/detail/user-defined.vue';
+import toLogin from '@/components/to-login.vue';
+import recruitdetailLayout from '@/layout/recruitdetail-layout.vue';
+import jobfairHead from '@/layout/detail/jobfair/head.vue';
+import jobfairContext from '@/layout/detail/jobfair/context.vue';
+import webJobs from '@/layout/detail/web-jobs.vue';
+import share from '@/layout/share.vue';
+import { mapActions, mapState } from 'vuex';
+
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    recruitdetailLayout,
+    jobfairHead,
+    jobfairContext,
+    webJobs,
+    share,
+    toLogin,
+    userDefined,
+  },
+  data: () => ({
+    url2: 'http://yun-campus-res.oss-cn-shenzhen.aliyuncs.com/company/1536028846-7488.jpg',
+    info: {},
+    jobList: [],
+    corpList: [],
+    tabs: 'corp',
+    loginDialog: false,
+  }),
+  created() {
+    this.search();
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  methods: {
+    ...mapActions(['jobfairOperation', 'userOperation', 'ticketsOperation', 'fairInfoOperation', 'postOperation']),
+    async search() {
+      //1直接拿着参数发送请求
+      let result = await this.jobfairOperation({ type: 'search', data: { id: this.$route.query.id } });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result.data的值
+        this.$set(this, `info`, result.data);
+        this.searchCorps();
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+    async searchCorps() {
+      let result = await this.fairInfoOperation({ type: 'searchCorp', data: { fairid: this.$route.query.id, skip: 0, limit: this.$limit } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `corpList`, result.data);
+        this.searchJobs();
+      }
+    },
+    async searchJobs() {
+      let jobsList = [];
+      if (this.corpList.length > 0) {
+        for (const item of this.corpList) {
+          let result = await this.fairInfoOperation({ type: `searchJobs`, data: { id: item.id } });
+          if (`${result.errcode}` === '0') {
+            result.data.map(item => jobsList.push(item));
+          }
+        }
+        this.$set(this, `jobList`, jobsList);
+      }
+    },
+    async getTicket() {
+      if (!this.user.id) {
+        this.loginDialog = true;
+        return false;
+      }
+      let query = {};
+      query.is_talk = `0`;
+      query.studid = this.user.id;
+      query.fairid = this.info.id;
+      query.schid = this.info.schid;
+      let result = await this.userOperation({ type: 'search', data: { studid: this.user.id } });
+      let info = result.data.info;
+      let body = {};
+      body.schid = info.schid;
+      body.year = info.year;
+      body.xm = info.xm;
+      body.xb = info.xb;
+      body.yx = info.yx;
+      body.zy = info.zy;
+      body.xl = info.xl;
+      body.syszd = info.syszd;
+      body.zzmm = info.zzmm;
+      result = await this.ticketsOperation({ type: 'add', data: { query: query, body: body } });
+      this.$message({
+        type: `${result.errcode}` === '0' ? 'success' : 'error',
+        message: `${result.errcode}` === '0' ? '成功领到门票' : result.errmsg === '数据已存在' ? '已领取过门票,不能重复领取' : result.errmsg,
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 35 - 0
src/views/jobfair/index.vue

@@ -0,0 +1,35 @@
+<template>
+  <div id="index">
+    <detail-layout>
+      <template v-slot:mainSide>
+        <menus :menuList="menuList"></menus>
+      </template>
+      <template v-slot:mainMain>
+        <router-view />
+      </template>
+    </detail-layout>
+  </div>
+</template>
+
+<script>
+import menus from '@/layout/layout-part/menus.vue';
+import detailLayout from '@/layout/detail-layout.vue';
+import { coreMenu } from '@/util/menus';
+export default {
+  name: 'JobfairIndex',
+  props: {},
+  components: {
+    detailLayout,
+    menus,
+  },
+  data: () => ({
+    menuList: coreMenu,
+  }),
+  created() {},
+  mounted() {},
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped></style>

+ 115 - 0
src/views/jobfair/list.vue

@@ -0,0 +1,115 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="1"><i class="el-icon-s-home"></i></el-col>
+      <el-col :span="23" style="margin-top:0.3rem">
+        <el-breadcrumb separator=">">
+          <el-breadcrumb-item :to="{ path: '/' }"><span style="color:#666666">网站首页</span></el-breadcrumb-item>
+          <el-breadcrumb-item>
+            <a href="/"><span style="color:#666666">招聘信息</span></a>
+          </el-breadcrumb-item>
+          <el-breadcrumb-item><span style="color:#999999">双选会</span></el-breadcrumb-item>
+        </el-breadcrumb>
+      </el-col>
+    </el-row>
+    <!-- 查询条件 -->
+    <!-- <el-row>
+      <el-col :span="24" style="margin-top: 1rem; width:50%">
+        <el-input size="mini" placeholder="请输入双选会名称" v-model="input3" @keyup.enter.native="search()">
+          <el-button slot="append" icon="el-icon-search" @click="search()"></el-button>
+        </el-input>
+      </el-col>
+    </el-row> -->
+    <el-row class="rowstyle" v-for="(item, index) in list" :key="index">
+      <!-- <el-col :span="3">
+        <div class="demo-basic--circle">
+          <div class="block"><el-avatar shape="square" :size="75" :src="squareUrl"></el-avatar></div>
+        </div>
+      </el-col> -->
+      <el-col :span="21">
+        <el-row>
+          <el-col :span="18">
+            <el-link style="color:#850000 " @click="$router.push({ path: '/jobfair/detail', query: { id: item.id } })">
+              {{ item.title }}
+            </el-link>
+          </el-col>
+          <el-col :span="6" style="text-align:center">
+            <span style="color:red;">{{ item.time }}</span>
+          </el-col>
+        </el-row>
+        <el-row>
+          <span style="color:#606266">{{ item.organizer }}</span>
+        </el-row>
+        <el-row>
+          <span style="color:#606266">{{ item.address }}</span>
+        </el-row>
+        <!-- <el-row style="color:#606266">
+          <el-col :span="20"><span>参与企业25家</span> </el-col>
+          <el-col :span="4"><i class="el-icon-view">2980 </i></el-col>
+        </el-row> -->
+      </el-col>
+    </el-row>
+    <el-row style="margin-top:1rem;" type="flex" justify="end">
+      <el-pagination @current-change="search" :current-page="currentPage" :page-size="$limit" layout="total, prev, pager, next, jumper" :total="totalRow">
+      </el-pagination>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapActions, mapState } from 'vuex';
+
+export default {
+  name: 'JobfairIndex',
+  props: {},
+  components: {},
+  data: () => ({
+    searchInfo: {},
+    squareUrl: '',
+    currentPage: 1,
+    list: [],
+    totalRow: 0,
+    type: '',
+  }),
+  created() {
+    this.$set(this, `type`, this.$route.params.type);
+    this.search();
+  },
+  mounted() {},
+  computed: {},
+  methods: {
+    ...mapActions(['jobfairOperation']),
+    async search(page) {
+      let skip = 0;
+      if (page) {
+        skip = (page - 1) * this.$limit;
+      }
+      let newData = { skip: skip, limit: this.$limit, ...this.searchInfo };
+      this.type === 'in' ? (newData['schid'] = 999991) : '';
+      let result = await this.jobfairOperation({ type: 'list', data: newData });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result。data的值
+        this.$set(this, 'list', result.data);
+        this.$set(this, `totalRow`, result.total);
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+  },
+  beforeRouteUpdate(to, from, next) {
+    this.$set(this, `type`, to.params.type);
+    this.search();
+    next();
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.rowstyle {
+  border-bottom-style: solid;
+  border-width: 1px;
+  border-color: #ebeef5;
+  font-size: small;
+  padding: 1rem 0;
+}
+</style>

+ 88 - 0
src/views/jobinfo/detail.vue

@@ -0,0 +1,88 @@
+<template>
+  <div id="detail">
+    <recruitdetail-layout>
+      <template v-slot:mainInfoTop>
+        <el-row>
+          <el-col :span="24">
+            <el-breadcrumb separator-class="el-icon-arrow-right">
+              <el-breadcrumb-item :to="{ path: '/' }"
+                ><i class="el-icon-s-home"></i>
+                <span>网站首页</span>
+              </el-breadcrumb-item>
+              <el-breadcrumb-item><span>在线招聘</span></el-breadcrumb-item>
+              <el-breadcrumb-item class="webDetail">详情</el-breadcrumb-item>
+            </el-breadcrumb>
+          </el-col>
+        </el-row>
+        <share></share>
+      </template>
+      <template v-slot:mainLeft>
+        <jobinfo-context :info="info"></jobinfo-context>
+        <!-- <web-jobs title="招聘职位" :info="info"> </web-jobs> -->
+        <web-jobs title="招聘职位" :info="jobList" type="2" :origin="info.id"> </web-jobs>
+      </template>
+      <template v-slot:mainRight>
+        <corpInfo :corpid="info.corpid"></corpInfo>
+      </template>
+    </recruitdetail-layout>
+  </div>
+</template>
+
+<script>
+import corpInfo from '@/layout/corpInfo.vue';
+import share from '@/layout/share.vue';
+import recruitdetailLayout from '@/layout/recruitdetail-layout.vue';
+import jobinfoContext from '@/layout/detail/jobinfo/context.vue';
+import webJobs from '@/layout/detail/web-jobs.vue';
+import { mapActions, mapState } from 'vuex';
+
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    recruitdetailLayout,
+    jobinfoContext,
+    webJobs,
+    corpInfo,
+    share,
+  },
+  data: () => ({
+    info: [],
+    corpInfo: {},
+    jobList: [],
+  }),
+  created() {
+    this.search();
+  },
+  computed: {},
+  methods: {
+    ...mapActions(['jobinfoOperation', 'postOperation']),
+    async search() {
+      //1直接拿着参数发送请求
+      let result = await this.jobinfoOperation({ type: 'search', data: { id: this.$route.query.id } });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result.data的值
+        this.$set(this, `info`, result.data);
+        // this.searchCorpInfo();
+        this.searchJobs();
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+    async searchJobs() {
+      let result;
+      let jobIds = this.info.jobs.length > 0 ? this.info.jobs : [];
+      let jobList = [];
+      for (const item of jobIds) {
+        result = await this.postOperation({ type: 'search', data: { id: item } });
+        if (`${result.errcode}` === '0') {
+          jobList.push(result.data);
+        }
+      }
+      this.$set(this, `jobList`, jobList);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 34 - 0
src/views/jobinfo/index.vue

@@ -0,0 +1,34 @@
+<template>
+  <div id="index">
+    <detail-layout>
+      <template v-slot:mainSide>
+        <menus :menuList="menuList"></menus>
+      </template>
+      <template v-slot:mainMain>
+        <router-view />
+      </template>
+    </detail-layout>
+  </div>
+</template>
+
+<script>
+import menus from '@/layout/layout-part/menus.vue';
+import detailLayout from '@/layout/detail-layout.vue';
+import { coreMenu } from '@/util/menus';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    detailLayout,
+    menus,
+  },
+  data: () => ({
+    menuList: coreMenu,
+  }),
+  created() {},
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped></style>

+ 111 - 0
src/views/jobinfo/list.vue

@@ -0,0 +1,111 @@
+<template>
+  <div id="list">
+    <el-row>
+      <el-col :span="1"><i class="el-icon-s-home"></i></el-col>
+      <el-col :span="23" style="margin-top:0.3rem">
+        <el-breadcrumb separator=">">
+          <el-breadcrumb-item :to="{ path: '/' }"><span style="color:#666666">网站首页</span></el-breadcrumb-item>
+          <el-breadcrumb-item>
+            <a href="/"><span style="color:#666666">招聘信息</span></a>
+          </el-breadcrumb-item>
+          <el-breadcrumb-item><span style="color:#999999">在线招聘</span></el-breadcrumb-item>
+        </el-breadcrumb>
+      </el-col>
+    </el-row>
+    <el-row>
+      <el-col :span="4" style="margin-top: 1rem;">
+        <el-select size="mini" v-model="searchInfo.is_practice" placeholder="选择招聘类型" @change="search()">
+          <el-option label="全部类型" :value="undefined"></el-option>
+          <el-option label="全职" :value="0"></el-option>
+          <el-option label="实习" :value="1"></el-option>
+        </el-select>
+      </el-col>
+      <el-col :span="10" style="margin-top: 1rem;">
+        <el-input size="mini" placeholder="请输入企业名称" v-model="searchInfo.corpname" @keyup.enter.native="search()">
+          <el-button slot="append" icon="el-icon-search" @click="search()"></el-button>
+        </el-input>
+      </el-col>
+    </el-row>
+    <el-row class="rowstyle" v-for="(item, index) in list" :key="index">
+      <!-- <el-col :span="3">
+        <div class="demo-basic--circle">
+          <div class="block"><el-avatar shape="square" :size="75" :src="squareUrl"></el-avatar></div>
+        </div>
+      </el-col> -->
+      <el-col :span="21" type="flex" justify="start">
+        <el-row>
+          <el-col :span="20">
+            <el-link style="color:#850000 " @click="$router.push({ path: '/jobinfo/detail', query: { id: item.id } })">
+              <!-- 学大教育集团(长春分公司)招聘简章 -->{{ item.title }}
+            </el-link>
+          </el-col>
+          <!-- <el-col :span="4" prop="">
+            <span style="color:#606266;">2019-06-17 09:30</span>
+          </el-col> -->
+        </el-row>
+        <el-row>
+          <!-- <span style="color:#606266">{{ item.content }}</span> -->
+        </el-row>
+        <el-row prop="title">
+          <span style="color:#606266">招聘类型:{{ `${item.is_practice}` === `0` ? '全职' : '实习' }}</span>
+        </el-row>
+        <!-- <el-row style="color:#606266">
+          <el-col :span="22" prop=""><span>参与企业25家</span></el-col>
+          <el-col :span="2" prop=""><i class="el-icon-view">2980 </i></el-col>
+        </el-row> -->
+      </el-col>
+    </el-row>
+    <el-row style="margin-top:1rem;" type="flex" justify="end">
+      <el-pagination @current-change="search" :current-page="currentPage" :page-size="$limit" layout="total, prev, pager, next, jumper" :total="totalRow">
+      </el-pagination>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'list',
+  props: {},
+  components: {},
+  data: () => ({
+    searchInfo: {},
+    squareUrl: '',
+    currentPage: 1,
+    totalRow: 0,
+    list: [],
+  }),
+  created() {
+    this.search();
+  },
+  computed: {},
+  methods: {
+    ...mapActions(['jobinfoOperation']),
+    async search(page) {
+      let skip = 0;
+      if (page) {
+        skip = (page - 1) * this.$limit;
+      }
+      let newData = { skip: skip, limit: this.$limit, ...this.searchInfo };
+      let result = await this.jobinfoOperation({ type: 'list', data: newData });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result。data的值
+        this.$set(this, 'list', result.data);
+        this.$set(this, `totalRow`, result.total);
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.rowstyle {
+  border-bottom-style: solid;
+  border-width: 1px;
+  border-color: #ebeef5;
+  font-size: small;
+  padding: 1rem 0;
+}
+</style>

+ 116 - 0
src/views/jobs/detail.vue

@@ -0,0 +1,116 @@
+<template>
+  <div id="detail">
+    <recruitdetail-layout>
+      <template v-slot:mainInfoTop>
+        <el-row>
+          <el-col :span="24">
+            <el-breadcrumb separator-class="el-icon-arrow-right">
+              <el-breadcrumb-item :to="{ path: '/' }"
+                ><i class="el-icon-s-home"></i>
+                <span>网站首页</span>
+              </el-breadcrumb-item>
+              <el-breadcrumb-item><span>职位</span></el-breadcrumb-item>
+              <el-breadcrumb-item class="webDetail">详情</el-breadcrumb-item>
+            </el-breadcrumb>
+          </el-col>
+        </el-row>
+        <share></share>
+      </template>
+      <template v-slot:mainLeft>
+        <jobs-head :info="info" @toDeliver="deliver"></jobs-head>
+        <jobs-context title="职位描述" :info="info"></jobs-context>
+        <web-intro title="单位简介" :info="corpInfo"></web-intro>
+      </template>
+      <template v-slot:mainRight>
+        <corpInfo :corpid="info.corpid"></corpInfo>
+      </template>
+    </recruitdetail-layout>
+    <toLogin :display="loginDialog" @close="loginDialog = false" title="请登录"></toLogin>
+  </div>
+</template>
+
+<script>
+import toLogin from '@/components/to-login.vue';
+import corpInfo from '@/layout/corpInfo.vue';
+import share from '@/layout/share.vue';
+import recruitdetailLayout from '@/layout/recruitdetail-layout.vue';
+import jobsHead from '@/layout/detail/jobs/head.vue';
+import jobsContext from '@/layout/detail/jobs/context.vue';
+import webIntro from '@/layout/detail/web-intro.vue';
+import { mapActions, mapState } from 'vuex';
+
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    recruitdetailLayout,
+    jobsHead,
+    webIntro,
+    jobsContext,
+    corpInfo,
+    share,
+    toLogin,
+  },
+  data: () => ({
+    info: {},
+    corpInfo: {},
+    loginDialog: false,
+  }),
+  created() {
+    this.search();
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  methods: {
+    ...mapActions(['postOperation', 'corpOperation', 'resumesOperation', 'userOperation', 'lettersOperation']),
+    async search() {
+      let result = await this.postOperation({ type: 'search', data: { id: this.$route.query.id } });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result.data的值
+        this.$set(this, `info`, result.data);
+        this.searchCorpInfo(this.info.corpid);
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+    async searchCorpInfo(corpid) {
+      let result = await this.corpOperation({ type: 'search', data: { corpid: corpid } });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result。data的值
+        this.$set(this, 'corpInfo', result.data);
+        this.$set(this.corpInfo, `id`, this.info.corpid);
+        this.$set(this.corpInfo, `corpname`, this.info.corpname);
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+    async deliver() {
+      if (!this.user.id) {
+        this.loginDialog = true;
+        return false;
+      }
+      let result = await this.userOperation({ type: 'search', data: { studid: this.user.id } });
+      let info = result.data.info;
+      result = await this.resumesOperation({ type: 'search', data: { id: this.user.id } });
+      let resume = result.data;
+      let query = {};
+      query.post_id = this.info.id;
+      query.resume_id = resume.id;
+      let body = {};
+      body.title = this.info.job_name;
+      body.corpname = this.info.corpname;
+      body.studname = this.user.xm;
+      this.$route.query.type ? (body.type = this.$route.query.type) : '';
+      this.$route.query.origin ? (body.origin = this.$route.query.origin) : '';
+      result = await this.lettersOperation({ type: 'apply', data: { query: query, body: body } });
+      this.$message({
+        type: `${result.errcode}` === '0' ? 'success' : 'error',
+        message: `${result.errcode}` === '0' ? '投递简历成功' : result.errmsg === '数据已存在' ? '已投递简历,不能重复投递' : result.errmsg,
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 34 - 0
src/views/jobs/index.vue

@@ -0,0 +1,34 @@
+<template>
+  <div id="index">
+    <detail-layout>
+      <template v-slot:mainSide>
+        <menus :menuList="menuList"></menus>
+      </template>
+      <template v-slot:mainMain>
+        <router-view />
+      </template>
+    </detail-layout>
+  </div>
+</template>
+
+<script>
+import menus from '@/layout/layout-part/menus.vue';
+import detailLayout from '@/layout/detail-layout.vue';
+import { coreMenu } from '@/util/menus';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    detailLayout,
+    menus,
+  },
+  data: () => ({
+    menuList: coreMenu,
+  }),
+  created() {},
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped></style>

+ 127 - 0
src/views/jobs/list.vue

@@ -0,0 +1,127 @@
+<template>
+  <div id="list">
+    <el-row>
+      <el-col :span="1"><i class="el-icon-s-home"></i></el-col>
+      <el-col :span="23" style="margin-top:0.3rem">
+        <el-breadcrumb separator=">">
+          <el-breadcrumb-item :to="{ path: '/' }"><span style="color:#666666">网站首页</span></el-breadcrumb-item>
+          <el-breadcrumb-item>
+            <a href="/"><span style="color:#666666">招聘信息</span></a>
+          </el-breadcrumb-item>
+          <el-breadcrumb-item><span style="color:#999999">岗位</span></el-breadcrumb-item>
+        </el-breadcrumb>
+      </el-col>
+    </el-row>
+    <el-row>
+      <el-col :span="10" style="margin-top: 1rem; width:50%">
+        <el-input size="mini" placeholder="请输入企业名称" v-model="searchInfo.corpname" @keyup.enter.native="search()">
+          <el-button slot="append" icon="el-icon-search" @click="search()"></el-button>
+        </el-input>
+      </el-col>
+    </el-row>
+    <el-row class="rowstyle" v-for="(item, index) in list" :key="index">
+      <el-col :span="3">
+        <div class="block"><el-avatar shape="square" :size="75" :src="squareUrl"></el-avatar></div>
+      </el-col>
+      <el-col :span="10" class="info">
+        <el-row>
+          <el-col :span="24">
+            <el-link class="title" @click="$router.push({ path: '/jobs/detail', query: { id: item.id } })">
+              {{ item.job_name }}
+            </el-link>
+          </el-col>
+          <el-col class="money" :span="24">{{ item.salary.text }}</el-col>
+          <el-col class="word" :span="24">
+            <span>{{ item.city }}/{{ item.xl_req }}/{{ item.job_number }}人</span>
+          </el-col>
+        </el-row>
+      </el-col>
+      <el-col :span="11" class="info">
+        <el-row>
+          <el-col class="word" :span="24">{{ item.corpname }}</el-col>
+          <el-col class="word" :span="24">{{ item.category }}</el-col>
+          <el-col class="word" :span="24">
+            {{ item.end_date }}
+          </el-col>
+        </el-row>
+      </el-col>
+    </el-row>
+    <el-row style="margin-top:1rem;" type="flex" justify="end">
+      <el-pagination @current-change="search" :current-page="currentPage" :page-size="$limit" layout="total, prev, pager, next, jumper" :total="totalRow">
+      </el-pagination>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapActions, mapState } from 'vuex';
+
+export default {
+  name: 'list',
+  props: {},
+  components: {},
+  data: () => ({
+    squareUrl: '',
+    searchInfo: {},
+    currentPage: 1,
+    totalRow: 0,
+    list: [],
+    type: '',
+  }),
+  created() {
+    this.search();
+  },
+  computed: {},
+  methods: {
+    ...mapActions(['postOperation']),
+    async search(page) {
+      let skip = 0;
+      if (page) {
+        skip = (page - 1) * this.$limit;
+      }
+      let newData = { skip: skip, limit: this.$limit, ...this.searchInfo }; //schid: 99991,
+      this.type === 'official' ? (newData['is_practice'] = 0) : (newData['is_practice'] = 1);
+      let result = await this.postOperation({ type: 'list', data: newData });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result.data的值
+        this.$set(this, `list`, result.data);
+        this.$set(this, `totalRow`, result.total);
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+  },
+  beforeRouteUpdate(to, from, next) {
+    this.$set(this, `type`, to.params.type);
+    this.search();
+    next();
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.rowstyle {
+  border-bottom-style: solid;
+  border-width: 1px;
+  border-color: #ebeef5;
+  font-size: small;
+  padding: 1rem 0;
+  .el-col {
+    margin-top: 0.5rem;
+  }
+  .info {
+    .title {
+      font-size: 1rem;
+      color: #850000;
+    }
+    .money {
+      font-size: 0.9rem;
+      color: #f40;
+    }
+    .word {
+      font-size: 0.85rem;
+      color: #666666;
+    }
+  }
+}
+</style>

+ 136 - 0
src/views/talk/detail.vue

@@ -0,0 +1,136 @@
+<template>
+  <div id="detail">
+    <recruitdetail-layout>
+      <template v-slot:mainInfoTop>
+        <el-row>
+          <el-col :span="24">
+            <el-breadcrumb separator-class="el-icon-arrow-right">
+              <el-breadcrumb-item :to="{ path: '/' }"
+                ><i class="el-icon-s-home"></i>
+                <span>网站首页</span>
+              </el-breadcrumb-item>
+              <el-breadcrumb-item><span>宣讲会</span></el-breadcrumb-item>
+              <el-breadcrumb-item class="webDetail">详情</el-breadcrumb-item>
+            </el-breadcrumb>
+          </el-col>
+        </el-row>
+        <share></share>
+      </template>
+      <template v-slot:mainLeft>
+        <talk-head title="宣讲会信息" :info="info" @getTicket="getTicket"></talk-head>
+        <web-intro title="单位简介" :info="corpInfo"></web-intro>
+        <talk-context title="招聘简章" :info="info"></talk-context>
+        <web-jobs title="招聘职位" :info="jobList" type="2" :origin="info.id"> </web-jobs>
+      </template>
+      <template v-slot:mainRight>
+        <corpInfo :corpid="info.corpid"></corpInfo>
+      </template>
+    </recruitdetail-layout>
+    <toLogin :display="loginDialog" @close="loginDialog = false" title="请登录"></toLogin>
+  </div>
+</template>
+
+<script>
+import toLogin from '@/components/to-login.vue';
+import corpInfo from '@/layout/corpInfo.vue';
+import share from '@/layout/share.vue';
+import webIntro from '@/layout/detail/web-intro.vue';
+import webJobs from '@/layout/detail/web-jobs.vue';
+import talkHead from '@/layout/detail/talk/talk-head.vue';
+import talkContext from '@/layout/detail/talk/talk-context.vue';
+import recruitdetailLayout from '@/layout/recruitdetail-layout.vue';
+import { mapActions, mapState } from 'vuex';
+
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    recruitdetailLayout,
+    talkHead,
+    talkContext,
+    webIntro,
+    webJobs,
+    corpInfo,
+    share,
+    toLogin,
+  },
+  data: () => ({
+    info: {},
+    corpInfo: {},
+    jobList: [],
+    loginDialog: false,
+  }),
+  created() {
+    this.search();
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  methods: {
+    ...mapActions(['postTalksInfo', 'corpOperation', 'userOperation', 'ticketsOperation', 'postOperation']),
+    async search() {
+      let result = await this.postTalksInfo({ type: 'search', data: { id: this.$route.query.id } });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result。data的值
+        this.$set(this, 'info', result.data);
+        this.searchCorpInfo(this.info.corpid);
+        this.searchJobs();
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+    async searchCorpInfo(corpid) {
+      let result = await this.corpOperation({ type: 'search', data: { corpid: corpid } });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result。data的值
+        this.$set(this, 'corpInfo', result.data);
+        this.$set(this.corpInfo, `id`, this.info.corpid);
+        this.$set(this.corpInfo, `corpname`, this.info.corpname);
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+    async searchJobs() {
+      let jobs = this.info.jobs;
+      if (jobs.length > 0) {
+        jobs.map(async item => {
+          let result = await this.postOperation({ type: 'search', data: { id: item } });
+          if (`${result.errcode}` === '0') {
+            result.data ? this.jobList.push(result.data) : '';
+          }
+        });
+      }
+    },
+    async getTicket() {
+      if (!this.user.id) {
+        this.loginDialog = true;
+        return false;
+      }
+      let query = {};
+      query.is_talk = `1`;
+      query.studid = this.user.id;
+      query.fairid = this.info.id;
+      query.schid = this.info.schid;
+      let result = await this.userOperation({ type: 'search', data: { studid: this.user.id } });
+      let info = result.data.info;
+      let body = {};
+      body.schid = info.schid;
+      body.year = info.year;
+      body.xm = info.xm;
+      body.xb = info.xb;
+      body.yx = info.yx;
+      body.zy = info.zy;
+      body.xl = info.xl;
+      body.syszd = info.syszd;
+      body.zzmm = info.zzmm;
+      result = await this.ticketsOperation({ type: 'add', data: { query: query, body: body } });
+      this.$message({
+        type: `${result.errcode}` === '0' ? 'success' : 'error',
+        message: `${result.errcode}` === '0' ? '成功领到门票' : result.errmsg === '数据已存在' ? '已领取过门票,不能重复领取' : result.errmsg,
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 81 - 0
src/views/talk/index.vue

@@ -0,0 +1,81 @@
+<template>
+  <div id="index">
+    <detail-layout>
+      <template v-slot:mainSide>
+        <el-calendar v-model="value" :first-day-of-week="7">
+          <template v-slot:dateCell="{ date, data }">
+            <span :class="data.isSelected ? 'is-selected' : ''" @click="toSearch(date)">
+              {{ date | getDay }}
+            </span>
+          </template>
+        </el-calendar>
+        <menus :menuList="menuList"></menus>
+      </template>
+      <template v-slot:mainMain>
+        <router-view />
+      </template>
+    </detail-layout>
+  </div>
+</template>
+
+<script>
+import menus from '@/layout/layout-part/menus.vue';
+import detailLayout from '@/layout/detail-layout.vue';
+import { coreMenu } from '@/util/menus';
+import { mapActions, mapState } from 'vuex';
+import _ from 'lodash';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    detailLayout,
+    menus,
+  },
+  data: () => ({
+    value: new Date(),
+    menuList: coreMenu,
+    list: [],
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    toSearch(date) {
+      let newDate = _.replace(date.toLocaleDateString(), '/', '-');
+      newDate = _.replace(newDate, '/', '-');
+      this.$router.push({ path: this.$router.path, query: { date: newDate } });
+    },
+  },
+  filters: {
+    getDay(date) {
+      let day = date.getDate();
+      return day;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/ .el-calendar-day {
+  height: 35px;
+}
+/deep/ .el-calendar__header {
+  padding: 12px 10px;
+}
+/deep/ .el-calendar-table thead th {
+  padding: 5px 0;
+}
+/deep/ .el-calendar__body {
+  padding: 1px 12px 2px;
+}
+/deep/ .el-button--mini,
+.el-button--mini.is-round {
+  padding: 6px 7px;
+}
+/deep/ .el-calendar__title {
+  color: #850000;
+}
+/deep/ .el-backtop,
+.el-calendar-table td.is-today {
+  color: #850000;
+}
+</style>

+ 0 - 0
src/views/talk/list.vue


Some files were not shown because too many files changed in this diff