guhongwei %!s(int64=5) %!d(string=hai) anos
achega
3e8fa2ce8f
Modificáronse 63 ficheiros con 5747 adicións e 0 borrados
  1. 1 0
      .env
  2. 33 0
      .eslintrc.js
  3. 22 0
      .gitignore
  4. 29 0
      README.md
  5. 11 0
      babel.config.js
  6. 63 0
      package.json
  7. BIN=BIN
      public/favicon.ico
  8. 17 0
      public/index.html
  9. BIN=BIN
      src/assets/logo.png
  10. 24 0
      src/pages/corp/App.vue
  11. 21 0
      src/pages/corp/main.js
  12. 13 0
      src/pages/corp/plugins/nuts.js
  13. 115 0
      src/pages/corp/router.js
  14. 29 0
      src/pages/corp/store/index.js
  15. 234 0
      src/pages/corp/views/enterprise/index.vue
  16. 202 0
      src/pages/corp/views/enterprise/internship.vue
  17. 139 0
      src/pages/corp/views/enterprise/lecture.vue
  18. 201 0
      src/pages/corp/views/enterprise/position.vue
  19. 86 0
      src/pages/corp/views/hr/detail.vue
  20. 81 0
      src/pages/corp/views/hr/index.vue
  21. 54 0
      src/pages/corp/views/hr/update.vue
  22. 44 0
      src/pages/corp/views/index.vue
  23. 442 0
      src/pages/corp/views/jobfair/detailAdd.vue
  24. 156 0
      src/pages/corp/views/jobfair/index.vue
  25. 117 0
      src/pages/corp/views/jobfair/list.vue
  26. 288 0
      src/pages/corp/views/jobinfo/detail.vue
  27. 83 0
      src/pages/corp/views/jobinfo/index.vue
  28. 68 0
      src/pages/corp/views/jobinfo/list.vue
  29. 409 0
      src/pages/corp/views/jobs/detail.vue
  30. 78 0
      src/pages/corp/views/jobs/index.vue
  31. 76 0
      src/pages/corp/views/jobs/list.vue
  32. 46 0
      src/pages/corp/views/login/index.vue
  33. 57 0
      src/pages/corp/views/login/message.vue
  34. 163 0
      src/pages/corp/views/login/nomal.vue
  35. 78 0
      src/pages/corp/views/profile/detail.vue
  36. 99 0
      src/pages/corp/views/profile/index.vue
  37. 100 0
      src/pages/corp/views/resume/detail.vue
  38. 131 0
      src/pages/corp/views/resume/index.vue
  39. 136 0
      src/pages/corp/views/resume/list-index.vue
  40. 101 0
      src/pages/corp/views/resume/list.vue
  41. 274 0
      src/pages/corp/views/resume/management.vue
  42. 127 0
      src/pages/corp/views/source/index.vue
  43. 94 0
      src/pages/corp/views/source/list.vue
  44. 429 0
      src/pages/corp/views/talk/detail.vue
  45. 103 0
      src/pages/corp/views/talk/index.vue
  46. 19 0
      src/plugins/axios.js
  47. 39 0
      src/plugins/check-res.js
  48. 6 0
      src/plugins/element.js
  49. 6 0
      src/plugins/filters.js
  50. 27 0
      src/plugins/loading.js
  51. 4 0
      src/plugins/meta.js
  52. 29 0
      src/plugins/methods.js
  53. 65 0
      src/plugins/stomp.js
  54. 10 0
      src/plugins/var.js
  55. 3 0
      src/style/element.css
  56. 7 0
      src/style/nutui.css
  57. 133 0
      src/util/axios-wrapper.js
  58. 10 0
      src/util/filters.js
  59. 50 0
      src/util/methods-util.js
  60. 47 0
      src/util/optionTitles.js
  61. 96 0
      src/util/qrcode.vue
  62. 69 0
      src/util/user-util.js
  63. 53 0
      vue.config.js

+ 1 - 0
.env

@@ -0,0 +1 @@
+VUE_APP_AXIOS_BASE_URL = /api

+ 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?

+ 29 - 0
README.md

@@ -0,0 +1,29 @@
+# weixin-corp
+
+## Project setup
+```
+npm install
+```
+
+### Compiles and hot-reloads for development
+```
+npm run serve
+```
+
+### Compiles and minifies for production
+```
+npm run build
+```
+
+### Run your tests
+```
+npm run test
+```
+
+### Lints and fixes files
+```
+npm run lint
+```
+
+### Customize configuration
+See [Configuration Reference](https://cli.vuejs.org/config/).

+ 11 - 0
babel.config.js

@@ -0,0 +1,11 @@
+module.exports = {
+  presets: ['@vue/app'],
+  plugins: [
+    [
+      '@nutui/babel-plugin-separate-import',
+      {
+        style: 'css',
+      },
+    ],
+  ],
+};

+ 63 - 0
package.json

@@ -0,0 +1,63 @@
+{
+  "name": "weixin-corp",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "@nutui/babel-plugin-separate-import": "^1.2.0",
+    "@nutui/nutui": "^2.1.5",
+    "axios": "^0.19.0",
+    "core-js": "^2.6.5",
+    "element-ui": "^2.12.0",
+    "jsonwebtoken": "^8.5.1",
+    "lodash": "^4.17.15",
+    "naf-core": "^0.1.2",
+    "qrcode": "^1.4.1",
+    "vue": "^2.6.10",
+    "vue-meta": "^2.2.2",
+    "vue-router": "^3.0.3",
+    "vuex": "^3.0.1",
+    "wangeditor": "^3.1.1"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "^3.11.0",
+    "@vue/cli-plugin-eslint": "^3.11.0",
+    "@vue/cli-service": "^3.11.0",
+    "@vue/eslint-config-prettier": "^5.0.0",
+    "babel-eslint": "^10.0.1",
+    "eslint": "^5.16.0",
+    "eslint-plugin-prettier": "^3.1.0",
+    "eslint-plugin-vue": "^5.0.0",
+    "less": "^3.0.4",
+    "less-loader": "^5.0.0",
+    "prettier": "^1.18.2",
+    "vue-template-compiler": "^2.6.10"
+  },
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "node": true
+    },
+    "extends": [
+      "plugin:vue/essential",
+      "@vue/prettier"
+    ],
+    "rules": {},
+    "parserOptions": {
+      "parser": "babel-eslint"
+    }
+  },
+  "postcss": {
+    "plugins": {
+      "autoprefixer": {}
+    }
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions"
+  ]
+}

BIN=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>weixin-corp</title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but weixin-corp 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>

BIN=BIN
src/assets/logo.png


+ 24 - 0
src/pages/corp/App.vue

@@ -0,0 +1,24 @@
+<template>
+  <div>
+    <login></login>
+    <router-view />
+  </div>
+</template>
+
+<script>
+import login from '@m/layout/login.vue';
+export default {
+  name: 'app',
+  components: {
+    login,
+  },
+};
+</script>
+
+<style lang="less">
+body {
+  margin: 0;
+  padding: 0;
+  background: #eeeeee;
+}
+</style>

+ 21 - 0
src/pages/corp/main.js

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

+ 13 - 0
src/pages/corp/plugins/nuts.js

@@ -0,0 +1,13 @@
+import Vue from 'vue';
+import { NavBar, Tabbar, cell, Textinput, button, BackTop, ActionSheet, DatePicker, imagepicker, InfiniteLoading, Scroller } from '@nutui/nutui';
+NavBar.install(Vue);
+Tabbar.install(Vue);
+cell.install(Vue);
+Textinput.install(Vue);
+button.install(Vue);
+BackTop.install(Vue);
+ActionSheet.install(Vue);
+DatePicker.install(Vue);
+imagepicker.install(Vue);
+InfiniteLoading.install(Vue);
+Scroller.install(Vue);

+ 115 - 0
src/pages/corp/router.js

@@ -0,0 +1,115 @@
+import Vue from 'vue';
+import Router from 'vue-router';
+
+Vue.use(Router);
+
+const router = new Router({
+  routes: [
+    {
+      path: '/',
+      component: () => import('./views/index.vue'),
+    },
+    {
+      path: '/hr/update',
+      component: () => import('./views/hr/update.vue'),
+    },
+    {
+      path: '/hr/index',
+      component: () => import('./views/hr/index.vue'),
+    },
+    {
+      path: '/hr/detail',
+      component: () => import('./views/hr/detail.vue'),
+    },
+    {
+      path: '/jobfair/index',
+      component: () => import('./views/jobfair/index.vue'),
+    },
+    {
+      path: '/jobfair/detail',
+      component: () => import('./views/jobfair/detailAdd.vue'),
+    },
+    {
+      path: '/jobfair/list',
+      component: () => import('./views/jobfair/list.vue'),
+    },
+    {
+      path: '/talk/index',
+      component: () => import('./views/talk/index.vue'),
+    },
+    {
+      path: '/talk/detail',
+      component: () => import('./views/talk/detail.vue'),
+    },
+    {
+      path: '/source/index',
+      component: () => import('./views/source/index.vue'),
+    },
+    {
+      path: '/resume/index',
+      component: () => import('./views/resume/index.vue'),
+    },
+    {
+      path: '/resume/detail',
+      component: () => import('./views/resume/detail.vue'),
+    },
+    {
+      path: '/resume/management',
+      component: () => import('./views/resume/management.vue'),
+    },
+    {
+      path: '/login/index',
+      component: () => import('./views/login/index.vue'),
+    },
+    {
+      path: '/login/message',
+      component: () => import('./views/login/message.vue'),
+    },
+    {
+      path: '/login/nomal',
+      component: () => import('./views/login/nomal.vue'),
+    },
+    {
+      path: '/enterprise/index',
+      component: () => import('./views/enterprise/index.vue'),
+    },
+    {
+      path: '/enterprise/internship',
+      component: () => import('./views/enterprise/internship.vue'),
+    },
+    {
+      path: '/enterprise/lecture',
+      component: () => import('./views/enterprise/lecture.vue'),
+    },
+    {
+      path: '/enterprise/position',
+      component: () => import('./views/enterprise/position.vue'),
+    },
+    {
+      path: '/profile/index',
+      component: () => import('./views/profile/index.vue'),
+    },
+    {
+      path: '/profile/detail',
+      component: () => import('./views/profile/detail.vue'),
+    },
+    {
+      path: '/jobs/index',
+      component: () => import('./views/jobs/index.vue'),
+    },
+    {
+      path: '/jobs/detail',
+      component: () => import('./views/jobs/detail.vue'),
+    },
+    {
+      path: '/jobinfo/index',
+      component: () => import('./views/jobinfo/index.vue'),
+    },
+    {
+      path: '/jobinfo/detail',
+      component: () => import('./views/jobinfo/detail.vue'),
+    },
+  ],
+});
+
+export default router;

+ 29 - 0
src/pages/corp/store/index.js

@@ -0,0 +1,29 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import * as profiles from '@m/store/profiles';
+import * as jobs from '@m/store/jobs';
+import * as hr from '@m/store/hr';
+import * as jobinfo from '@m/store/jobinfo';
+import * as talks from '@m/store/talks';
+import * as resumes from '@m/store/resumes';
+import * as letters from '@m/store/letters';
+import * as jobfair from '@m/store/jobfair';
+import * as school from '@m/store/schoolList';
+import * as user from '@m/store/user';
+
+Vue.use(Vuex);
+
+export default new Vuex.Store({
+  modules: {
+    profiles: profiles,
+    jobs: jobs,
+    hr: hr,
+    jobinfo: jobinfo,
+    talks: talks,
+    resumes: resumes,
+    letters: letters,
+    jobfair: jobfair,
+    school: school,
+    user: user,
+  },
+});

+ 234 - 0
src/pages/corp/views/enterprise/index.vue

@@ -0,0 +1,234 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="top">
+        <el-col :span="5" class="topIMg">
+          <el-image style="width:60px; height: 60px;" :src="url"></el-image>
+        </el-col>
+        <el-col :span="19" class="topTit">长春市福瑞科技有限公司</el-col>
+      </el-col>
+      <el-col :span="24" class="talkMainTop">
+        <el-col :span="8">
+          <div class="talkMainTopCol active">
+            <i class="el-icon-s-promotion el-icon--top"></i>
+            <p>所在位置</p>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div class="talkMainTopCol">
+            <i class="el-icon-video-camera-solid el-icon--top"></i>
+            <p>宣传视频</p>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div class="talkMainTopCol">
+            <i class="el-icon-picture el-icon--top"></i>
+            <p>宣传相册</p>
+          </div>
+        </el-col>
+      </el-col>
+      <el-col :span="24" class="jobsBrief">
+        <el-collapse v-model="activeNames" @change="handleChange">
+          <el-collapse-item title="">
+            <h4 style="padding:0 10px;">公司简介</h4>
+            <div class="jobsBriefTit">
+              暂无数据
+            </div>
+          </el-collapse-item>
+        </el-collapse>
+      </el-col>
+      <el-col :span="24" class="lecture">
+        <el-col :span="24" class="lectureTit">宣讲会</el-col>
+        <el-col :span="24" class="lectureTxt">
+          <el-button class="lectureBtn" icon="el-icon-plus" @click="$router.push('/views/enterprise/lecture')">新增宣讲会</el-button>
+          <el-col :span="24" class="text" v-for="(tag, index) in tags" :key="index" :type="tag.type">
+            <el-col :span="14">
+              <el-col :span="24">{{ tag.company }}</el-col>
+              <el-col :span="24" class="textCom">
+                <i data-v-7f91b2e0="" class="el-icon-location el-icon--left"></i>
+                {{ tag.school }}
+              </el-col>
+              <el-col :span="24" class="textCom">
+                <i data-v-7f91b2e0="" class="el-icon-office-building el-icon--left"></i>
+                {{ tag.place }}
+              </el-col>
+            </el-col>
+            <el-col :span="9" class="textCom">
+              <el-col :span="24">&nbsp;</el-col>
+              <el-col :span="24">&nbsp;</el-col>
+              <el-col :span="24">{{ tag.time }}</el-col>
+            </el-col>
+            <el-col :span="1">
+              <el-col :span="24">&nbsp;</el-col>
+              <el-col :span="24"><i data-v-7f91b2e0="" class="el-icon-arrow-right"></i></el-col>
+              <el-col :span="24">&nbsp;</el-col>
+            </el-col>
+          </el-col>
+        </el-col>
+      </el-col>
+      <el-col :span="24" class="lecture">
+        <el-col :span="24" class="lectureTit">实习</el-col>
+        <el-col :span="24" class="lectureTxt">
+          <el-button class="lectureBtn" icon="el-icon-plus" @click="$router.push('/views/enterprise/internship')">新增实习职位</el-button>
+          <el-col :span="24" class="text" v-for="(tag, index) in tags1" :key="index" :type="tag.type">
+            <el-col :span="17">
+              <el-col :span="24">{{ tag.position }}</el-col>
+              <el-col :span="24" class="textCom">
+                <span>{{ tag.place }}</span>
+                <span>{{ tag.edu }}</span>
+              </el-col>
+            </el-col>
+            <el-col :span="6" class="textCom">
+              <el-col :span="24">{{ tag.time }}</el-col>
+              <el-col :span="24" style="color:red;text-align:right;padding: 0 12px 0 0;">{{ tag.wages }}</el-col>
+            </el-col>
+            <el-col :span="1" style="padding: 10px 0;">
+              <i data-v-7f91b2e0="" class="el-icon-arrow-right"></i>
+            </el-col>
+          </el-col>
+        </el-col>
+      </el-col>
+      <el-col :span="24" class="lecture">
+        <el-col :span="24" class="lectureTit">职位</el-col>
+        <el-col :span="24" class="lectureTxt">
+          <el-button class="lectureBtn" icon="el-icon-plus" @click="$router.push('/views/enterprise/position')">新增正式职位</el-button>
+          <el-col :span="24" class="text" v-for="(tag, index) in tags2" :key="index" :type="tag.type">
+            <el-col :span="17">
+              <el-col :span="24">{{ tag.position }}</el-col>
+              <el-col :span="24" class="textCom">
+                <span>{{ tag.place }}</span>
+                <span>{{ tag.edu }}</span>
+              </el-col>
+            </el-col>
+            <el-col :span="6" class="textCom">
+              <el-col :span="24">{{ tag.time }}</el-col>
+              <el-col :span="24" style="color:red;text-align:right;padding: 0 12px 0 0;">{{ tag.wages }}</el-col>
+            </el-col>
+            <el-col :span="1" style="padding: 10px 0;">
+              <i data-v-7f91b2e0="" class="el-icon-arrow-right"></i>
+            </el-col>
+          </el-col>
+        </el-col>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'index',
+  props: {},
+  components: {},
+  data: () => ({
+    url: '',
+    activeNames: [null],
+    tags: [{ company: '辽宁鸿文教育科技有限公司', school: '长春大学', place: '综合楼C区502室', time: '2019-09-05 13:00' }],
+    tags1: [{ position: 'java工程师', place: '长春', edu: '博士及以上', time: '2019-09-05', wages: '3k' }],
+    tags2: [{ position: 'java工程师', place: '长春', edu: '博士及以上', time: '2019-09-05', wages: '3k' }],
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    handleChange(val) {
+      console.log(val);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+h4 {
+  margin: 0;
+  padding: 0;
+}
+.top {
+  height: 4.375rem;
+  padding: 5px;
+}
+.topImg {
+  text-align: center;
+}
+.topTit {
+  height: 3.75rem;
+  line-height: 1.875rem;
+}
+.talkMainTop {
+  width: 100%;
+  background: #fff;
+  border-bottom: 0.0625rem solid #f6f6f6;
+  border-top: 0.0625rem solid #f6f6f6;
+}
+.talkMainTopCol {
+  width: 100%;
+  text-align: center;
+  padding: 0.0625rem 0;
+  color: #333;
+  font-size: 0.875rem;
+  border-right: 0.0625rem solid #f6f6f6;
+}
+.active i {
+  color: #25b6ed;
+}
+.active p {
+  color: #25b6ed;
+}
+.talkMainTop .el-col:last-child .talkMainTopCol:last-child {
+  border-right: none;
+}
+.talkMainTopCol i {
+  font-size: 1.25rem;
+  padding: 0.3125rem 0;
+}
+.talkMainTopCol p {
+  margin: 0 0;
+  padding: 0.3125rem 0;
+}
+/deep/.jobsBrief .el-collapse-item__header {
+  width: 100%;
+  padding: 0 50%;
+  height: 1.875rem;
+  line-height: 1.875rem;
+}
+/deep/.el-collapse-item__arrow {
+  margin: 0;
+  font-size: 1.25rem;
+  transform: rotate(90deg);
+}
+/deep/.el-collapse-item__arrow.is-active {
+  transform: rotate(270deg);
+}
+.jobsBriefTit {
+  position: relative;
+  background: #fff;
+  z-index: 999;
+  top: 0;
+  padding: 0.625rem 0.9375rem 0;
+}
+.lectureTit {
+  height: 1.875rem;
+  line-height: 1.875rem;
+  font-size: 0.875rem;
+  padding: 0 10px;
+  background: #f6f6f6;
+}
+.lectureBtn {
+  text-align: center;
+  width: 100%;
+  border: none;
+  color: #25b6ed;
+  font-size: 1rem;
+}
+.text {
+  padding: 0.3125rem 0.625rem;
+  font-size: 1rem;
+  border-bottom: 0.0625rem solid #ccc;
+}
+.textCom {
+  font-size: 0.875rem;
+  color: #666;
+}
+.textSchTit {
+  color: #666;
+  padding: 0.1875rem 0;
+}
+</style>

+ 202 - 0
src/pages/corp/views/enterprise/internship.vue

@@ -0,0 +1,202 @@
+<template>
+  <div id="internship">
+    <el-row style="background:#ccc;height:100vh;">
+      <el-form ref="form" :model="form" label-width="80px">
+        <el-form-item label="职位名称">
+          <el-input v-model="form.name" placeholder="必填"></el-input>
+        </el-form-item>
+        <el-form-item label="工作性质" class="natureBtn">
+          <nut-cell v-model="form.nature" :desc="info.char ? info.char : '必填'" :showIcon="true" @click.native="isVisible = true"> </nut-cell>
+          <nut-actionsheet :is-visible="isVisible" :isClickCloseMask="true" @close="switchActionSheet('isVisible')" cancelTxt="取消">
+            <template v-slot:custom>
+              <el-row v-for="(item, index) in tags" :key="index" @click.native="charChoose(item.name, 'isVisible')">
+                <el-col :span="24" class="tagsBtn">{{ item.name }}</el-col>
+              </el-row>
+            </template>
+          </nut-actionsheet>
+        </el-form-item>
+        <el-form-item label="招聘人数">
+          <el-input v-model="form.num" placeholder="必填"></el-input>
+        </el-form-item>
+        <el-form-item label="工作城市">
+          <el-input v-model="form.city" placeholder="必填"></el-input>
+        </el-form-item>
+        <el-form-item label="截止时间">
+          <nut-cell v-model="form.time" :desc="this.date1 ? this.date1 : '请选择'" :showIcon="true" @click.native="isVisible1 = true"> </nut-cell>
+          <nut-datepicker
+            :is-visible="isVisible1"
+            type="date"
+            startDate="2019-01-01"
+            endDate="2030-01-01"
+            @close="switchPicker('isVisible1')"
+            @choose="setChooseValue1"
+          >
+          </nut-datepicker>
+        </el-form-item>
+        <el-form-item label="职位薪资">
+          <el-input v-model="form.salary" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="学历要求">
+          <!-- <el-input v-model="form.edu" placeholder="下拉"></el-input> -->
+          <nut-cell v-model="form.edu" :desc="info1.char1 ? info1.char1 : '必填'" :showIcon="true" @click.native="isVisible3 = true"> </nut-cell>
+          <nut-actionsheet :is-visible="isVisible3" :isClickCloseMask="true" @close="switchActionSheet3('isVisible3')" cancelTxt="取消">
+            <template v-slot:custom>
+              <el-row v-for="(item, index) in tags1" :key="index" @click.native="charChoose3(item.name, 'isVisible3')">
+                <el-col :span="24" class="tagsBtn">{{ item.name }}</el-col>
+              </el-row>
+            </template>
+          </nut-actionsheet>
+        </el-form-item>
+        <el-form-item label="相关专业">
+          <el-input v-model="form.major" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="职位诱惑">
+          <el-input v-model="form.temp" placeholder="请用空格分开"></el-input>
+        </el-form-item>
+        <el-form-item label="岗位职责">
+          <el-input type="textarea" v-model="form.duty" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="岗位要求">
+          <el-input type="textarea" v-model="form.requ" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="其他描述">
+          <el-input type="textarea" v-model="form.desc" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="投递说明">
+          <el-input type="textarea" v-model="form.expla" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="" class="onBtn">
+          <el-button type="primary" @click="onSubmit" round>暂存</el-button>
+          <el-button type="primary" @click="onSubmit" round>发布</el-button>
+        </el-form-item>
+      </el-form>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'internship',
+  props: {},
+  components: {},
+  data: () => ({
+    form: {
+      name: '',
+      nature: '',
+      num: '',
+      city: '',
+      time: '',
+      salary: '',
+      edu: '',
+      major: '',
+      temp: '',
+      duty: '',
+      requ: '',
+      desc: '',
+      expla: '',
+    },
+    tags: [{ name: '正式岗位' }, { name: '实习岗位' }],
+    tags1: [{ name: '博士及以上' }, { name: '硕士及以上' }, { name: '本科及以上' }, { name: '大专及以上' }, { name: '不限' }],
+    isVisible: false,
+    isVisible1: false,
+    isVisible3: false,
+    info: {
+      char: '',
+    },
+    info1: {
+      char1: '',
+    },
+    date1: null,
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    onSubmit() {
+      console.log('submit!');
+    },
+    switchActionSheet(param) {
+      this[`${param}`] = !this[`${param}`];
+    },
+    switchPicker(param) {
+      this[`${param}`] = !this[`${param}`];
+    },
+    charChoose(item, sheet) {
+      this.$set(this.info, `char`, item);
+      this.switchActionSheet(sheet);
+    },
+    setChooseValue1(param) {
+      this.date1 = param[3];
+    },
+    switchActionSheet3(param) {
+      this[`${param}`] = !this[`${param}`];
+    },
+    switchPicker3(param) {
+      this[`${param}`] = !this[`${param}`];
+    },
+    charChoose3(item, sheet) {
+      this.$set(this.info1, `char1`, item);
+      this.switchActionSheet3(sheet);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-form-item {
+  margin-bottom: 0;
+  border-bottom: 0.0625rem solid #ccc;
+  background: #fff;
+}
+/deep/.el-input__inner {
+  border: none;
+}
+.onBtn {
+  background: #ccc;
+  margin: 0.625rem 0 0 0;
+}
+/deep/.onBtn .el-form-item__content {
+  margin-left: 0rem !important;
+  text-align: center;
+}
+/deep/.onBtn .el-form-item__content .el-button {
+  width: 90%;
+  margin: 0.3125rem 0;
+}
+/deep/.el-button + .el-button {
+  margin-left: 0rem;
+}
+.el-textarea {
+  height: 2.5rem;
+}
+/deep/.el-textarea__inner {
+  border: none;
+  padding: 0.625rem 0.625rem 0 0.625rem;
+  height: 2.5rem;
+  line-height: 1.25rem;
+}
+/deep/.nut-cell-box {
+  min-height: 2.5rem;
+}
+/deep/.nut-cell-left {
+  display: none;
+}
+/deep/.nut-cell-right {
+  width: 100%;
+}
+/deep/.nut-cell-desc {
+  width: 95%;
+  font-size: 14px;
+  color: #000;
+  padding: 0 5px;
+}
+/deep/.nut-actionsheet-cancel {
+  margin-top: 0;
+}
+.tagsBtn {
+  text-align: center;
+  height: 2.5rem;
+  line-height: 2.5rem;
+  border-bottom: 0.0625rem solid #ccc;
+  background: #fff;
+}
+</style>

+ 139 - 0
src/pages/corp/views/enterprise/lecture.vue

@@ -0,0 +1,139 @@
+<template>
+  <div id="lecture">
+    <el-row>
+      <el-col :span="24" class="main">
+        <el-form ref="form" :model="form" label-width="80px">
+          <el-form-item label="宣讲学校">
+            <el-input v-model="form.name" placeholder="必填" @click.native="drawer = true"></el-input>
+            <el-drawer title="宣讲学校" :visible.sync="drawer" :direction="direction">
+              <span>长春大学!</span>
+            </el-drawer>
+          </el-form-item>
+          <el-form-item label="宣讲地点">
+            <el-input v-model="form.place" placeholder="必填"></el-input>
+          </el-form-item>
+          <el-form-item label="截止时间">
+            <nut-cell v-model="form.time" :desc="this.datetime ? this.datetime : '请选择'" :showIcon="true" @click.native="isVisible2 = true"> </nut-cell>
+            <nut-datepicker
+              :is-visible="isVisible2"
+              title="请选择日期时间"
+              type="datetime"
+              startDate="2018-01-01"
+              endDate="2019-10-05"
+              @close="switchPicker('isVisible2')"
+              @choose="setChooseValue2"
+            >
+            </nut-datepicker>
+          </el-form-item>
+          <el-form-item label="" class="onBtn">
+            <el-alert title="提示:最終宣讲时间和场地,请以学校审批结果为准" type="info" center :closable="false"> </el-alert>
+            <el-button type="primary" @click="onSubmit" round>暂存</el-button>
+            <el-button type="primary" @click="onSubmit" round>提交</el-button>
+          </el-form-item>
+        </el-form>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'lecture',
+  props: {},
+  components: {},
+  data: () => ({
+    form: {
+      name: '',
+      place: '',
+      time: '',
+    },
+    drawer: false,
+    direction: 'rtl',
+    isVisible: false,
+    isVisible2: false,
+    datetime: null,
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    onSubmit() {
+      console.log('submit!');
+    },
+    switchPicker(param) {
+      this[`${param}`] = !this[`${param}`];
+    },
+    setChooseValue2(param) {
+      this.datetime = param[5];
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  padding: 0.625rem;
+}
+/deep/.el-form-item {
+  margin-bottom: 0;
+}
+/deep/.el-form-item {
+  margin-bottom: 0;
+  border-bottom: 0.0625rem solid #ccc;
+  background: #fff;
+}
+/deep/.el-input__inner {
+  border: none;
+}
+/deep/.onBtn {
+  border-bottom: none;
+}
+/deep/.onBtn .el-alert {
+  background: transparent;
+  padding: 0;
+}
+/deep/.onBtn .el-form-item__content {
+  margin-left: 0rem !important;
+  text-align: center;
+}
+/deep/.onBtn .el-form-item__content .el-button {
+  width: 90%;
+  margin: 0.3125rem 0;
+}
+/deep/.el-button + .el-button {
+  margin-left: 0rem;
+}
+.el-textarea {
+  height: 2.5rem;
+}
+/deep/.el-textarea__inner {
+  border: none;
+  padding: 0.625rem 0.625rem 0 0.625rem;
+  height: 2.5rem;
+  line-height: 1.25rem;
+}
+/deep/.nut-cell-box {
+  min-height: 2.5rem;
+}
+/deep/.nut-cell-left {
+  display: none;
+}
+/deep/.nut-cell-right {
+  width: 100%;
+}
+/deep/.nut-cell-desc {
+  width: 95%;
+  font-size: 14px;
+  color: #000;
+  padding: 0 5px;
+}
+/deep/.nut-actionsheet-cancel {
+  margin-top: 0;
+}
+.tagsBtn {
+  text-align: center;
+  height: 2.5rem;
+  line-height: 2.5rem;
+  border-bottom: 0.0625rem solid #ccc;
+  background: #fff;
+}
+</style>

+ 201 - 0
src/pages/corp/views/enterprise/position.vue

@@ -0,0 +1,201 @@
+<template>
+  <div id="position">
+    <el-row style="background:#ccc;height:100vh;">
+      <el-form ref="form" :model="form" label-width="80px">
+        <el-form-item label="职位名称">
+          <el-input v-model="form.name" placeholder="必填"></el-input>
+        </el-form-item>
+        <el-form-item label="工作性质" class="natureBtn">
+          <nut-cell v-model="form.nature" :desc="info.char ? info.char : '必填'" :showIcon="true" @click.native="isVisible = true"> </nut-cell>
+          <nut-actionsheet :is-visible="isVisible" :isClickCloseMask="true" @close="switchActionSheet('isVisible')" cancelTxt="取消">
+            <template v-slot:custom>
+              <el-row v-for="(item, index) in tags" :key="index" @click.native="charChoose(item.name, 'isVisible')">
+                <el-col :span="24" class="tagsBtn">{{ item.name }}</el-col>
+              </el-row>
+            </template>
+          </nut-actionsheet>
+        </el-form-item>
+        <el-form-item label="招聘人数">
+          <el-input v-model="form.num" placeholder="必填"></el-input>
+        </el-form-item>
+        <el-form-item label="工作城市">
+          <el-input v-model="form.city" placeholder="必填"></el-input>
+        </el-form-item>
+        <el-form-item label="截止时间">
+          <nut-cell v-model="form.time" :desc="this.date1 ? this.date1 : '请选择'" :showIcon="true" @click.native="isVisible1 = true"> </nut-cell>
+          <nut-datepicker
+            :is-visible="isVisible1"
+            type="date"
+            startDate="2019-01-01"
+            endDate="2030-01-01"
+            @close="switchPicker('isVisible1')"
+            @choose="setChooseValue1"
+          >
+          </nut-datepicker>
+        </el-form-item>
+        <el-form-item label="职位薪资">
+          <el-input v-model="form.salary" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="学历要求">
+          <!-- <el-input v-model="form.edu" placeholder="下拉"></el-input> -->
+          <nut-cell v-model="form.edu" :desc="info1.char1 ? info1.char1 : '必填'" :showIcon="true" @click.native="isVisible3 = true"> </nut-cell>
+          <nut-actionsheet :is-visible="isVisible3" :isClickCloseMask="true" @close="switchActionSheet3('isVisible3')" cancelTxt="取消">
+            <template v-slot:custom>
+              <el-row v-for="(item, index) in tags1" :key="index" @click.native="charChoose3(item.name, 'isVisible3')">
+                <el-col :span="24" class="tagsBtn">{{ item.name }}</el-col>
+              </el-row>
+            </template>
+          </nut-actionsheet>
+        </el-form-item>
+        <el-form-item label="相关专业">
+          <el-input v-model="form.major" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="职位诱惑">
+          <el-input v-model="form.temp" placeholder="请用空格分开"></el-input>
+        </el-form-item>
+        <el-form-item label="岗位职责">
+          <el-input type="textarea" v-model="form.duty" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="岗位要求">
+          <el-input type="textarea" v-model="form.requ" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="其他描述">
+          <el-input type="textarea" v-model="form.desc" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="投递说明">
+          <el-input type="textarea" v-model="form.expla" placeholder="请输入..."></el-input>
+        </el-form-item>
+        <el-form-item label="" class="onBtn">
+          <el-button type="primary" @click="onSubmit" round>暂存</el-button>
+          <el-button type="primary" @click="onSubmit" round>发布</el-button>
+        </el-form-item>
+      </el-form>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'position',
+  props: {},
+  components: {},
+  data: () => ({
+    form: {
+      name: '',
+      nature: '',
+      num: '',
+      city: '',
+      time: '',
+      salary: '',
+      edu: '',
+      major: '',
+      temp: '',
+      duty: '',
+      requ: '',
+      desc: '',
+      expla: '',
+    },
+    tags: [{ name: '正式岗位' }, { name: '实习岗位' }],
+    tags1: [{ name: '博士及以上' }, { name: '硕士及以上' }, { name: '本科及以上' }, { name: '大专及以上' }, { name: '不限' }],
+    isVisible: false,
+    isVisible1: false,
+    isVisible3: false,
+    info: {
+      char: '',
+    },
+    info1: {
+      char1: '',
+    },
+    date1: null,
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    onSubmit() {
+      console.log('submit!');
+    },
+    switchActionSheet(param) {
+      this[`${param}`] = !this[`${param}`];
+    },
+    switchPicker(param) {
+      this[`${param}`] = !this[`${param}`];
+    },
+    charChoose(item, sheet) {
+      this.$set(this.info, `char`, item);
+      this.switchActionSheet(sheet);
+    },
+    setChooseValue1(param) {
+      this.date1 = param[3];
+    },
+    switchActionSheet3(param) {
+      this[`${param}`] = !this[`${param}`];
+    },
+    switchPicker3(param) {
+      this[`${param}`] = !this[`${param}`];
+    },
+    charChoose3(item, sheet) {
+      this.$set(this.info1, `char1`, item);
+      this.switchActionSheet3(sheet);
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+/deep/.el-form-item {
+  margin-bottom: 0;
+  border-bottom: 0.0625rem solid #ccc;
+  background: #fff;
+}
+/deep/.el-input__inner {
+  border: none;
+}
+.onBtn {
+  background: #ccc;
+  margin: 0.625rem 0 0 0;
+}
+/deep/.onBtn .el-form-item__content {
+  margin-left: 0rem !important;
+  text-align: center;
+}
+/deep/.onBtn .el-form-item__content .el-button {
+  width: 90%;
+  margin: 0.3125rem 0;
+}
+/deep/.el-button + .el-button {
+  margin-left: 0rem;
+}
+.el-textarea {
+  height: 2.5rem;
+}
+/deep/.el-textarea__inner {
+  border: none;
+  padding: 0.625rem 0.625rem 0 0.625rem;
+  height: 2.5rem;
+  line-height: 1.25rem;
+}
+/deep/.nut-cell-box {
+  min-height: 2.5rem;
+}
+/deep/.nut-cell-left {
+  display: none;
+}
+/deep/.nut-cell-right {
+  width: 100%;
+}
+/deep/.nut-cell-desc {
+  width: 95%;
+  font-size: 14px;
+  color: #000;
+  padding: 0 5px;
+}
+/deep/.nut-actionsheet-cancel {
+  margin-top: 0;
+}
+.tagsBtn {
+  text-align: center;
+  height: 2.5rem;
+  line-height: 2.5rem;
+  border-bottom: 0.0625rem solid #ccc;
+  background: #fff;
+}
+</style>

+ 86 - 0
src/pages/corp/views/hr/detail.vue

@@ -0,0 +1,86 @@
+<template>
+  <div id="detail">
+    <el-row style="padding:10px;">
+      <el-form :model="form" label-width="auto" label-position="right">
+        <el-col :span="24">
+          <form-item label="HR姓名" porp="name">
+            <el-input v-model="form.name" style="width: 100%"></el-input>
+          </form-item>
+        </el-col>
+        <el-col :span="24">
+          <form-item label="手机" porp="mobile">
+            <el-input v-model="form.mobile" style="width: 100%"></el-input>
+          </form-item>
+        </el-col>
+        <el-col :span="24">
+          <form-item label="密码" porp="passwd">
+            <el-input v-model="form.passwd" type="password" style="width: 100%"></el-input>
+          </form-item>
+        </el-col>
+        <!-- <el-col :span="24">
+          <form-item label="图形码" porp="pic">
+            <el-input v-model="noUse.pic" style="width: 100%"></el-input>
+          </form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-col :span="4" style="padding:0.4rem 0 0 0">验证码</el-col>
+          <el-col :span="13" style="text-align:right">
+            <el-form-item label="" porp="data">
+              <el-input v-model="noUse.data" style="width: 100%"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="7" class="huoBtn">
+            <el-button type="success" :offset="1">获取验证码</el-button>
+          </el-col>
+        </el-col> -->
+      </el-form>
+      <el-col :span="24" style="text-align:center">
+        <el-button @click="dialog = false">取 消</el-button>
+        <el-button type="primary" @click="toSubmit()">确 定</el-button>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import formItem from '@m/components/form-item.vue';
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    formItem,
+  },
+  data: () => ({
+    circleUrl: '',
+    form: {},
+    noUse: {},
+  }),
+  created() {},
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['hrOperation']),
+    async toSubmit() {
+      let result;
+      result = await this.hrOperation({ type: 'add', data: { info: this.form, corpid: this.user.corpid } });
+      if (`${result.errcode}` === '0') {
+        this.$message.success('操作成功');
+        this.$router.push('/hr/index');
+      } else {
+        this.$message.error(result.errmsg);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.huoBtn .el-button {
+  padding: 0.625rem;
+  margin: 0 0 0 0.625rem;
+}
+</style>

+ 81 - 0
src/pages/corp/views/hr/index.vue

@@ -0,0 +1,81 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="dataList" v-for="(item, index) in dataList" :key="index">
+        <el-col :span="10" @click.native="$router.push({ path: '/hr/update', query: { id: item._id } })">{{ item.name }}</el-col>
+        <el-col :span="10">{{ item.mobile }}</el-col>
+        <el-col :span="2">
+          <deleteDig :id="item._id" @delete="toDelete"></deleteDig>
+        </el-col>
+      </el-col>
+    </el-row>
+    <el-row class="addBtn" type="flex" justify="end">
+      <el-button circle type="primary" icon="el-icon-plus" @click="$router.push({ path: '/hr/detail' })" style="margin:10rem 0 0 0"></el-button>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import deleteDig from '@m/components/delete-dig.vue';
+import _ from 'lodash';
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    deleteDig,
+  },
+  data: () => ({
+    dataList: [],
+    input: '',
+  }),
+  created() {
+    this.search();
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['hrOperation']),
+    async search() {
+      let result;
+      if (this.input.length > 0) {
+        result = await this.hrOperation({ type: 'search', data: { tel: this.input } });
+        this.$set(this, `dataList`, [result.data]);
+      } else {
+        result = await this.hrOperation({ type: 'list', data: this.user.corpid });
+        this.$set(this, `dataList`, result.data);
+      }
+    },
+    async toDelete(id) {
+      let result = await this.hrOperation({ type: 'delete', data: { id: id } });
+      if (`${result.errcode}` === '0') {
+        this.$message.success('删除成功');
+        this.search();
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : '删除失败');
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.dataList {
+  padding: 0.625rem 0 0.625rem 1.25rem;
+  background-color: white;
+  line-height: 1.875rem;
+  border-bottom: 0.0625rem solid #ccc;
+}
+.addBtn {
+  position: fixed;
+  z-index: 999;
+  bottom: 20%;
+  right: 5%;
+}
+/deep/.el-message-box {
+  width: 100% !important;
+}
+</style>

+ 54 - 0
src/pages/corp/views/hr/update.vue

@@ -0,0 +1,54 @@
+<template>
+  <div id="update">
+    <el-form :model="form" label-width="auto" label-position="right" style="padding-top:2rem;">
+      <el-col :span="24">
+        <el-form-item label="密码" porp="passwd">
+          <el-input v-model="form.passwd" type="password" style="width: 100%"></el-input>
+        </el-form-item>
+      </el-col>
+      <!-- <el-col :span="24" style="margin:1rem 0">绑定微信:</el-col> -->
+    </el-form>
+    <el-col :span="24" style="text-align:center">
+      <el-button @click="dialog = false">取 消</el-button>
+      <el-button type="primary" @click="toSubmit()">确 定</el-button>
+    </el-col>
+  </div>
+</template>
+
+<script>
+import formItem from '@m/components/form-item.vue';
+import { mapActions } from 'vuex';
+export default {
+  name: 'update',
+  props: {},
+  components: {
+    // formItem,
+  },
+  data: () => ({
+    dataList: [],
+    select: '',
+    circleUrl: '',
+    input: '',
+    dialog: false,
+    info: {},
+    form: {},
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    ...mapActions(['hrOperation']),
+    async toSubmit() {
+      let result;
+      result = await this.hrOperation({ type: 'update', data: { info: { passwd: this.form.passwd, id: this.$route.query.id } } });
+      if (`${result.errcode}` === '0') {
+        this.$message.success('操作成功');
+        this.$router.push('/hr/index');
+      } else {
+        this.$message.error(result.errmsg);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 44 - 0
src/pages/corp/views/index.vue

@@ -0,0 +1,44 @@
+<template>
+  <div id="index">
+    <nut-cell title="校园招聘会" :showIcon="true" @click.native="$router.push({ path: '/jobfair/index' })"> </nut-cell>
+    <nut-cell title="校园宣讲会" :showIcon="true" @click.native="$router.push({ path: '/talk/index' })"> </nut-cell>
+    <nut-cell title="招聘信息管理" :showIcon="true" @click.native="$router.push({ path: '/jobinfo/index' })"> </nut-cell>
+    <nut-cell title="职位管理" :showIcon="true" @click.native="$router.push({ path: '/jobs/index' })"> </nut-cell>
+    <nut-cell title="招聘简章管理" :showIcon="true" @click.native="$router.push({ path: '/profile/index' })"> </nut-cell>
+    <nut-cell title="生源查看" :showIcon="true" @click.native="$router.push({ path: '/source/index' })"> </nut-cell>
+    <nut-cell title="HR信息" :showIcon="true" @click.native="$router.push({ path: '/hr/index' })"> </nut-cell>
+    <el-row class="btn__row">
+      <el-col :span="23">
+        <el-button type="info" @click="back">返回首页 </el-button>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'index',
+  props: {},
+  components: {},
+  data: () => ({}),
+  created() {},
+  computed: {},
+  methods: {
+    back() {
+      window.location.href = '/';
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.btn__row {
+  .el-col {
+    margin-top: 1rem;
+  }
+  .el-button {
+    width: 100%;
+    border-radius: 30px;
+  }
+}
+</style>

+ 442 - 0
src/pages/corp/views/jobfair/detailAdd.vue

@@ -0,0 +1,442 @@
+<template>
+  <div id="detailAdd">
+    <el-row style="background:#fff; padding:0 0.5rem;">
+      <el-col :span="24">
+        <el-form ref="form" :model="info" label-width="auto" label-position="left">
+          <el-form-item label="招聘简章" prop="info">
+            <drawer :data="profileList" type="profile_id" need="value" :selected="info.profile_id" placeholder="请选择招聘简章" @select="getProfile"></drawer>
+          </el-form-item>
+          <el-form-item label="申请说明" prop="apply_desc">
+            <el-input v-model="info.apply_desc" placeholder="请填写申请说明" style=""></el-input>
+          </el-form-item>
+          <el-form-item label="招聘需求" type="info">
+            <el-button type="text" @click="dialogTableVisible = true" class="xinBtn" style="">点击查看职位</el-button>
+          </el-form-item>
+          <el-form-item label="参会人员" type="info">
+            <el-button type="text" @click="dialogTableVisibles = true" class="xinBtn" style="">点击查看参会人员</el-button>
+          </el-form-item>
+        </el-form>
+        <el-row type="flex" justify="center" :gutter="20" style="padding:1rem 0;">
+          <el-col :span="10" style="text-align:center;">
+            <el-button type="success" @click="submit()">申&nbsp;&nbsp;&nbsp;&nbsp;请</el-button>
+          </el-col>
+        </el-row>
+      </el-col>
+    </el-row>
+    <el-dialog :visible.sync="dialogTableVisible" :fullscreen="true" :show-close="false">
+      <template #title>
+        <el-row type="flex" align="middle" justify="center">
+          <el-col :span="8"><i @click="dialogTableVisible = false" class="el-icon-back" style="zoom:1.5"></i></el-col>
+          <el-col :span="8" style="font-size:1.25rem;text-align: center;">职&nbsp;&nbsp;&nbsp;&nbsp;位</el-col>
+          <el-col :span="8" style="text-align: right;"><i @click="addJob = true" class="el-icon-plus" style="zoom:1.5"></i></el-col>
+        </el-row>
+      </template>
+      <el-table :data="gridData" style="width: 100%" border>
+        <el-table-column align="center" type="expand">
+          <template v-slot="scoped">
+            <el-row>
+              <el-col :span="6">岗位名称:</el-col>
+              <el-col :span="18">{{ scoped.row.job_name }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">工作性质:</el-col>
+              <el-col :span="18">{{ `${scoped.row.is_practice}` === '0' ? '全职' : '实习' }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">学历要求:</el-col>
+              <el-col :span="18">{{ scoped.row.xl_req }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">专业要求:</el-col>
+              <el-col :span="18">{{ scoped.row.zy_req }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">薪资:</el-col>
+              <el-col :span="18">{{ scoped.row.salary.text }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">招聘人数:</el-col>
+              <el-col :span="18">{{ scoped.row.job_number }}人</el-col>
+            </el-row>
+          </template>
+        </el-table-column>
+        <el-table-column align="center" label="岗位名称" prop="job_name"> </el-table-column>
+        <el-table-column align="center" label="操作">
+          <template slot-scope="scope">
+            <el-button size="mini" type="danger" @click="handleDelete(scope.$index, 'gridData')">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+    <el-dialog :visible.sync="addJob" append-to-body :fullscreen="true" :show-close="false">
+      <template #title>
+        <el-row type="flex" align="middle" justify="start">
+          <el-col :span="8"><i @click="addJob = false" class="el-icon-back" style="zoom:1.5"></i></el-col>
+          <el-col :span="8" style="font-size:1.25rem;">选择职位</el-col>
+          <el-col :span="8"></el-col>
+        </el-row>
+      </template>
+      <el-row v-for="(item, index) in jobList" :key="index" type="flex" justify="center" align="middle" class="jobs">
+        <el-col :span="18">
+          <el-col :span="18">{{ item.job_name }}</el-col>
+          <el-col :span="6">{{ `${item.is_practice}` === '0' ? '全职' : '实习' }}</el-col>
+          <el-col :span="24">{{ item.xl_req }}</el-col>
+          <el-col :span="24">{{ item.zy_req }}</el-col>
+          <el-col :span="18">{{ item.salary && item.salary.text }}</el-col>
+          <el-col :span="6">招聘{{ item.job_number }}人</el-col>
+        </el-col>
+        <el-col :span="6" style="text-align:center;">
+          <el-button type="primary" size="mini" icon="el-icon-plus" circle @click="addjobs(item)"></el-button>
+        </el-col>
+      </el-row>
+    </el-dialog>
+    <el-dialog :visible.sync="dialogTableVisibles" :fullscreen="true" :show-close="false">
+      <template #title>
+        <el-row type="flex" align="middle" justify="center">
+          <el-col :span="8"><i @click="dialogTableVisibles = false" class="el-icon-back" style="zoom:1.5"></i></el-col>
+          <el-col :span="8" style="font-size:1.25rem;text-align: center;">参会人员</el-col>
+          <el-col :span="8" style="text-align: right;"><i @click="addPer = true" class="el-icon-plus" style="zoom:1.5"></i></el-col>
+        </el-row>
+      </template>
+      <el-table :data="attendList" border style="width: 100%">
+        <el-table-column align="center" type="expand">
+          <template v-slot="scoped">
+            <el-row>
+              <el-col :span="6">姓名:</el-col>
+              <el-col :span="18">{{ scoped.row.name }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">性别:</el-col>
+              <el-col :span="18">{{ scoped.row.gender }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">民族:</el-col>
+              <el-col :span="18">{{ scoped.row.nation }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">职务职称:</el-col>
+              <el-col :span="18">{{ scoped.row.position }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">手机号码:</el-col>
+              <el-col :span="18">{{ scoped.row.mobile }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">邮箱:</el-col>
+              <el-col :span="18">{{ scoped.row.email }}</el-col>
+            </el-row>
+          </template>
+        </el-table-column>
+        <el-table-column prop="name" label="姓名" type="text" align="center"> </el-table-column>
+        <el-table-column label="操作">
+          <template #header>
+            操作
+          </template>
+          <template v-slot="scoped">
+            <el-button type="text" @click="delAttend(scoped.$index, scoped.row)" size="small">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+    <el-dialog :visible.sync="addPer" append-to-body :fullscreen="true" :show-close="false">
+      <template #title>
+        <el-row type="flex" align="middle" justify="center">
+          <el-col :span="8"><i @click="addPer = false" class="el-icon-back" style="zoom:1.5"></i></el-col>
+          <el-col :span="16" style="font-size:1.25rem;">参会人员信息</el-col>
+        </el-row>
+      </template>
+      <el-form :model="perForm" label-width="auto" label-position="left" style="padding:0.5rem 1rem;" :rules="rules">
+        <el-form-item label="姓名" prop="name">
+          <el-input v-model="perForm.name" placeholder="请输入姓名"></el-input>
+        </el-form-item>
+        <el-form-item label="性别" prop="gender">
+          <drawer :data="genderList" type="perForm.gender" need="label" :selected="perForm.gender" placeholder="请选择性别" @select="getProfile"></drawer>
+        </el-form-item>
+        <el-form-item label="民族" prop="nation">
+          <drawer :data="nation_list" type="perForm.nation" :selected="perForm.nation" need="label" placeholder="请选择民族" @select="getProfile"></drawer>
+        </el-form-item>
+        <el-form-item label="职务" prop="position">
+          <el-input v-model="perForm.position" placeholder="请输入职务"></el-input>
+        </el-form-item>
+        <el-form-item label="手机" prop="mobile">
+          <el-input v-model="perForm.mobile" placeholder="请输入手机"></el-input>
+        </el-form-item>
+        <el-form-item label="邮箱" prop="email">
+          <el-input v-model="perForm.email" placeholder="请输入邮箱"></el-input>
+        </el-form-item>
+      </el-form>
+      <el-row type="flex" align="middle" justify="center">
+        <el-col :span="8">
+          <el-button type="success" @click="addAttend()">保&nbsp;&nbsp;&nbsp;&nbsp;存</el-button>
+        </el-col>
+      </el-row>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import drawer from '@m/components/drawer.vue';
+import WangEditor from '@m/components/wang-editor.vue';
+import { mapActions, mapState } from 'vuex';
+import _ from 'lodash';
+export default {
+  name: 'detailAdd',
+  props: {},
+  components: { drawer },
+  data: () => ({
+    info: {},
+    jobfairInfo: {},
+    profileList: [],
+    jobList: [],
+    OrJobList: [],
+    perForm: {},
+    query: {},
+    genderList: [{ label: '男' }, { label: '女' }],
+    dialogTableVisible: false,
+    dialogTableVisibles: false,
+    dialogVisible: false,
+    addJob: false,
+    addPer: false,
+    loading: true,
+    gridData: [],
+    attendList: [],
+    rules: {
+      name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
+      mobile: [{ required: true, message: '请输入手机号', trigger: 'blur' }, { min: 11, max: 11, message: '请输入11位手机号码', trigger: 'blur' }],
+    },
+    nation_list: [
+      { label: '汉族' },
+      { label: '回族' },
+      { label: '蒙古族' },
+      { label: '藏族' },
+      { label: '维吾尔族' },
+      { label: '苗族' },
+      { label: '彝族' },
+      { label: '壮族' },
+      { label: '布依族' },
+      { label: '朝鲜族' },
+      { label: '满族' },
+      { label: '侗族' },
+      { label: '瑶族' },
+      { label: '白族' },
+      { label: '土家族' },
+      { label: '哈尼族' },
+      { label: '哈萨克族' },
+      { label: '傣族' },
+      { label: '黎族' },
+      { label: '傈僳族' },
+      { label: '佤族' },
+      { label: '畲族' },
+      { label: '高山族' },
+      { label: '拉祜族' },
+      { label: '水族' },
+      { label: '东乡族' },
+      { label: '纳西族' },
+      { label: '景颇族' },
+      { label: '柯尔克孜族' },
+      { label: '土族' },
+      { label: '达斡尔族' },
+      { label: '仫佬族' },
+      { label: '羌族' },
+      { label: '布朗族' },
+      { label: '撒拉族' },
+      { label: '毛南族' },
+      { label: '仡佬族' },
+      { label: '锡伯族' },
+      { label: '阿昌族' },
+      { label: '普米族' },
+      { label: '塔吉克族' },
+      { label: '怒族' },
+      { label: '乌孜别克族' },
+      { label: '俄罗斯族' },
+      { label: '鄂温克族' },
+      { label: '德昂族' },
+      { label: '保安族' },
+      { label: '裕固族' },
+      { label: '京族' },
+      { label: '塔塔尔族' },
+      { label: '独龙族' },
+      { label: '鄂伦春族' },
+      { label: '赫哲族' },
+      { label: '门巴族' },
+      { label: '珞巴族' },
+      { label: '基诺族' },
+      { label: '其他' },
+    ],
+  }),
+  created() {
+    this.getProfileList();
+    this.getJobsList();
+    if (this.$route.query.id) {
+      this.search();
+    } else {
+      this.getJobfair();
+    }
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['profilesOperation', 'fairsOperation', 'fairsOperation', 'postsOperation']),
+    async search() {
+      this.$set(this, `loading`, false);
+      let result = await this.fairsOperation({ type: 'searchCorps', data: { id: this.$route.query.id } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `info`, result.data);
+        this.$set(this, `attendList`, result.data.attendee);
+        this.$set(this, `gridData`, result.data.jobs);
+        this.$set(this, `loading`, true);
+      }
+    },
+    async submit() {
+      let jobs = this.gridData.map(item => item.id);
+      let attendee = this.attendList.map(item => item);
+      let info = JSON.parse(JSON.stringify(this.info));
+      info.jobs = jobs;
+      info.attendee = attendee;
+      let result;
+      if (info.id) {
+        result = await this.fairsOperation({ type: 'applyUpdate', data: { id: this.$route.query.id, info: info } });
+      } else {
+        result = await this.fairsOperation({
+          type: 'apply',
+          data: { ...this.query, info: info },
+        });
+      }
+      if (`${result.errcode}` === '0') {
+        this.$message.success('操作成功');
+        this.$router.push({ path: '/jobfair/index' });
+      } else {
+        this.$message.error(result.errmsg || 'error');
+      }
+    },
+    addjobs(item) {
+      let data = JSON.parse(JSON.stringify(item));
+      this.gridData.push(data);
+      this.resetJobList();
+      // this.$message('已添加');
+      this.$notify({
+        message: '已添加',
+        type: 'success',
+        duration: 1000,
+        showClose: false,
+      });
+    },
+    handleDelete(index, type) {
+      let arr = _.get(this, `${type}`);
+      arr.splice(index, 1);
+      this.resetJobList();
+    },
+    //职位列表
+    async getJobsList() {
+      let result = await this.postsOperation({ type: 'list', data: { corpid: this.user.corpid } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `jobList`, result.data);
+        this.$set(this, `OrJobList`, result.data);
+        this.resetJobList();
+      }
+    },
+    //重置职位列表
+    async resetJobList() {
+      let data = JSON.parse(JSON.stringify(this.OrJobList));
+      let selectList = [];
+      let chooseList = [];
+      if (this.gridData.length > 0) {
+        this.gridData.map(item => {
+          let val = typeof item === 'object' ? item.id : item;
+          if (val !== undefined) {
+            let selected = _.find(data, select => select.id === val);
+            selectList.push(selected);
+          }
+        });
+        chooseList = _.differenceBy(data, selectList, 'id');
+      } else {
+        chooseList = data;
+      }
+      this.$set(this, `gridData`, selectList);
+      this.$set(this, `jobList`, chooseList);
+    },
+    // 招聘简章
+    async getProfileList() {
+      let result = await this.profilesOperation({ type: 'list', data: { corpid: this.user.corpid } });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result。data的值
+        let arr = result.data.map(item => {
+          let object = { label: item.title, value: item.id };
+          return object;
+        });
+        this.$set(this, `profileList`, arr); //result.data
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+    async getProfile({ type, value }) {
+      let checkType = type.split('.');
+      if (checkType.length < 2) {
+        this.$set(this.info, type, value);
+        let result = await this.profilesOperation({ type: 'search', data: { id: this.info.profile_id } });
+        if (`${result.errcode}` === `0`) {
+          this.info.content = result.data.content;
+        }
+      } else {
+        this.$set(_.get(this, checkType[0]), `${checkType[1]}`, value);
+      }
+    },
+    async getJobfair() {
+      let result = await this.fairsOperation({ type: 'search', data: { id: this.$route.query.fair_id } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `jobfairInfo`, result.data);
+        let { schid, schname, corpid, corpname } = result.data;
+        let query = { schid: schid, schname: schname, fairid: this.$route.query.fair_id, corpid: this.user.corpid, corpname: this.user.corpname };
+        this.$set(this, `query`, query);
+      }
+    },
+    // 增加参会人员
+    addAttend() {
+      let data = JSON.parse(JSON.stringify(this.perForm));
+      this.attendList.push(data);
+      this.perForm = {};
+      this.addPer = false;
+    },
+    // 删除参会人员
+    delAttend(index, val) {
+      this.attendList.splice(index, 1);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.xinBtn {
+  border: 0.0625rem solid #ccc;
+  border-radius: 0.25rem;
+  text-align: center;
+  color: #606266;
+  width: 100%;
+}
+/deep/.el-upload-dragger {
+  width: 19.375rem;
+}
+/deep/.el-dialog {
+  margin: 0;
+  width: 100%;
+}
+/deep/.el-date-editor.el-input {
+  width: 11.5rem;
+}
+/deep/.el-select {
+  width: 7.875rem;
+}
+/deep/.el-drawer.btt {
+  bottom: 19.1875rem !important;
+}
+/deep/.w-e-toolbar .w-e-menu {
+  padding: 0.3125rem 0.125rem;
+}
+.jobs {
+  padding: 0.5rem 1rem;
+  border-bottom: 0.0625rem solid #cccccc;
+}
+</style>

+ 156 - 0
src/pages/corp/views/jobfair/index.vue

@@ -0,0 +1,156 @@
+<template>
+  <div id="index">
+    <el-row style="padding-top:0.5rem;">
+      <el-col :span="24" class="search">
+        <el-col :span="20" class="searchInput"> <el-input placeholder="请输入招聘会名称" prefix-icon="el-icon-search" v-model="input"> </el-input></el-col>
+        <el-col :span="4" class="searchBtn"><el-button>搜索</el-button></el-col>
+      </el-col>
+    </el-row>
+    <scroll :hasMore="hasMore" @loadMore="search" v-if="list.length > 0">
+      <el-row v-for="(item, index) in list" :key="index" type="flex" align="middle" justify="center" class="row">
+        <el-col :span="18">
+          <el-col :span="24">{{ item.fairInfo && item.fairInfo.title }}</el-col>
+          <el-col :span="24">主办方:{{ item.fairInfo && item.fairInfo.organizer }}</el-col>
+          <el-col :span="24">城市:{{ item.fairInfo && item.fairInfo.city }}</el-col>
+          <el-col :span="24">时间:{{ item.fairInfo && item.fairInfo.time }}</el-col>
+          <el-col :span="24">
+            状态:
+            <span :style="`color:${item.status === '0' ? '#666' : item.status === '1' ? '#67C23A' : '#F56C6C'}`">
+              {{ `${item.status}` === '0' ? '未审核' : `${item.status}` === '1' ? '审核通过' : '审核失败' }}
+            </span>
+          </el-col>
+        </el-col>
+        <el-col :span="3" class="editBtn"
+          ><el-button @click="$router.push({ path: '/jobfair/detail', query: { id: item.id } })"><i class="el-icon-edit"></i></el-button
+        ></el-col>
+        <el-col :span="2"><delete-dig :id="item.id" @delete="toDelete"></delete-dig></el-col>
+      </el-row>
+    </scroll>
+    <el-row class="addBtn" type="flex" justify="end">
+      <el-button circle type="primary" icon="el-icon-plus" @click="$router.push({ path: '/jobfair/list' })"></el-button>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import yun from '@m/layout/yun-layout.vue';
+import scroll from '@m/layout/scroll.vue';
+import deleteDig from '@m/components/delete-dig.vue';
+import _ from 'lodash';
+import { mapActions, mapState, mapMutations } from 'vuex';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    scroll,
+    deleteDig,
+  },
+  data: () => ({
+    input: '',
+    list: [],
+    totalRow: 10,
+    hasMore: true,
+    currentPage: 1,
+    loading: false,
+  }),
+  created() {
+    this.search();
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['fairsOperation']),
+    async search(type) {
+      try {
+        let skip = 0;
+        //判断下type,如果type存在.当前页加一
+        if (type && type === 'nextPage') {
+          this.currentPage++; //当前页加一
+          skip = (this.currentPage - 1) * this.$limit; //重新计算skip:即计算数据库开始查询的位置
+        }
+        if (this.list.length >= this.totalRow) return false; //判断的是:如果我列表的数据条数大于等于数据库返回给我的总数时=>我就不查了.没数据了
+        this.$set(this, `hasMore`, false); //控制无限加载瞬间加载N次的情况
+        let result = await this.fairsOperation({
+          type: 'mylist',
+          data: { corpid: this.user.corpid },
+        });
+        if (`${result.errcode}` === '0') {
+          if (result.data.length > 0) {
+            let arr = [];
+            for (const item of result.data) {
+              let object = await this.searchJobfair(item);
+              arr.push(object);
+            }
+            this.$set(this, `list`, skip === 0 ? arr : this.list.concat(arr));
+          }
+          this.$set(this, `totalRow`, result.total);
+          this.$set(this, `hasMore`, this.list.length < this.totalRow); //此处是根据数据库总数的结果和当前列表的总条数比较,看看是否可以继续请求数据
+        }
+      } finally {
+        this.$set(this, `loading`, true);
+      }
+    },
+    async searchJobfair(object) {
+      let result = await this.fairsOperation({ type: 'search', data: { id: object.fairid } });
+      if (`${result.errcode}` === '0') {
+        object.fairInfo = result.data;
+      }
+      return object;
+    },
+    async toDelete(id) {
+      let result = await this.fairsOperation({ type: 'deleteCorps', data: { id: id } });
+      if (`${result.errcode}` === '0') {
+        this.$message.success('删除成功');
+        this.search();
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : '删除失败');
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+p {
+  margin: 0;
+  padding: 0;
+}
+.text-ovel {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.search {
+  border-bottom: 0.0625rem solid #ccc;
+}
+.searchInput {
+  padding: 0.3125rem 0.625rem;
+}
+.searchBtn {
+  padding: 0.3125rem 0;
+}
+.searchBtn .el-button {
+  border: none;
+}
+.addBtn {
+  position: fixed;
+  bottom: 8rem;
+  right: 1rem;
+}
+.row {
+  padding: 5px 10px;
+  border-bottom: 1px solid #ccc;
+  background: #fff;
+}
+/deep/.editBtn .el-button {
+  padding: 0;
+  width: 32px;
+  height: 32px;
+  border-radius: 90px;
+  color: #fff;
+  background: #409eff;
+}
+</style>

+ 117 - 0
src/pages/corp/views/jobfair/list.vue

@@ -0,0 +1,117 @@
+<template>
+  <div id="index">
+    <el-row style="padding-top:0.5rem;">
+      <el-col :span="24" class="search">
+        <el-col :span="20" class="searchInput"> <el-input placeholder="请输入招聘会名称" prefix-icon="el-icon-search" v-model="input"> </el-input></el-col>
+        <el-col :span="4" class="searchBtn"><el-button>搜索</el-button></el-col>
+      </el-col>
+    </el-row>
+    <scroll :hasMore="hasMore" @loadMore="search" v-if="list.length > 0">
+      <el-row v-for="(item, index) in list" :key="index" type="flex" align="middle" justify="center" class="row">
+        <el-col :span="18">
+          <el-col :span="24">{{ item.title }}</el-col>
+          <el-col :span="24">主办方:{{ item.organizer }}</el-col>
+          <el-col :span="24">城市{{ item.city }}</el-col>
+          <el-col :span="24">时间{{ item.time }}</el-col>
+        </el-col>
+        <el-col :span="3">
+          <el-button type="primary" @click="$router.push({ path: '/jobfair/detail', query: { fair_id: item.id } })">申请</el-button>
+        </el-col>
+        <!-- <el-col :span="2"><delete-dig :id="item.id" @delete="toDelete"></delete-dig></el-col> -->
+      </el-row>
+    </scroll>
+  </div>
+</template>
+
+<script>
+import yun from '@m/layout/yun-layout.vue';
+import scroll from '@m/layout/scroll.vue';
+import deleteDig from '@m/components/delete-dig.vue';
+import _ from 'lodash';
+import { mapActions, mapState, mapMutations } from 'vuex';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    scroll,
+    // deleteDig,
+  },
+  data: () => ({
+    input: '',
+    list: [],
+    totalRow: 10,
+    hasMore: true,
+    currentPage: 1,
+  }),
+  created() {
+    this.search();
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['fairsOperation']),
+    async search(type) {
+      let skip = 0;
+      //判断下type,如果type存在.当前页加一
+      if (type && type === 'nextPage') {
+        this.currentPage++; //当前页加一
+        skip = (this.currentPage - 1) * this.$limit; //重新计算skip:即计算数据库开始查询的位置
+      }
+      if (this.list.length >= this.totalRow) return false; //判断的是:如果我列表的数据条数大于等于数据库返回给我的总数时=>我就不查了.没数据了
+      this.$set(this, `hasMore`, false); //控制无限加载瞬间加载N次的情况
+      let result = await this.fairsOperation({ type: 'list', data: { skip: skip, limit: this.$limit } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `list`, this.list.concat(result.data));
+        this.$set(this, `totalRow`, result.total);
+        this.$set(this, `hasMore`, this.list.length < this.totalRow); //此处是根据数据库总数的结果和当前列表的总条数比较,看看是否可以继续请求数据
+      }
+    },
+    async toDelete(id) {
+      let result = await this.fairsOperation({ type: 'deleteCorps', data: { id: id } });
+      if (`${result.errcode}` === '0') {
+        this.$message.success('删除成功');
+        this.search();
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : '删除失败');
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+p {
+  margin: 0;
+  padding: 0;
+}
+.text-ovel {
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+}
+.search {
+  border-bottom: 0.0625rem solid #ccc;
+}
+.searchInput {
+  padding: 0.3125rem 0.625rem;
+}
+.searchBtn {
+  padding: 0.3125rem 0;
+}
+.searchBtn .el-button {
+  border: none;
+}
+.addBtn {
+  position: fixed;
+  bottom: 8rem;
+  right: 1rem;
+}
+.row {
+  padding: 5px 10px;
+  border-bottom: 1px solid #ccc;
+  background: #fff;
+}
+</style>

+ 288 - 0
src/pages/corp/views/jobinfo/detail.vue

@@ -0,0 +1,288 @@
+<template>
+  <div id="detail" style="background:#fff;">
+    <el-form :model="info" label-position="right" label-width="0" style="padding:0.4rem;" ref="form" :rules="rules" v-if="loading">
+      <form-item label="招聘简章" prop="profile_id">
+        <drawer :data="profileList" type="profile_id" need="value" :selected="info.profile_id" placeholder="请选择招聘简章" @select="getProfile"></drawer>
+      </form-item>
+      <!-- <form-item label="招聘标题" prop="title">
+        <el-input v-model="info.title" readonly placeholder="请输入招聘标题"></el-input>
+      </form-item> -->
+      <form-item label="工作性质" prop="is_practice">
+        <drawer
+          :data="praList"
+          type="is_practice"
+          :selected="info.is_practice"
+          need="value"
+          placeholder="点击选择工作性质"
+          @select="changeSelect"
+          style="margin:5px 0px"
+        >
+        </drawer>
+      </form-item>
+      <form-item label="招聘职位" type="info">
+        <el-button type="text" @click="dialogTableVisible = true" class="xinBtn">点击新增职位</el-button>
+      </form-item>
+    </el-form>
+    <el-row type="flex" justify="center" class="detailBtn">
+      <el-col :span="12">
+        <el-button style="width:60%" @click="toSubmit(0)">保存为草稿</el-button>
+      </el-col>
+      <el-col :span="12">
+        <el-button type="success" style="width:60%" @click="toSubmit(1)">提交</el-button>
+      </el-col>
+    </el-row>
+    <el-dialog :visible.sync="dialogTableVisible" :fullscreen="true" :show-close="false">
+      <template #title>
+        <el-row type="flex" align="middle" justify="center">
+          <el-col :span="8"><i @click="dialogTableVisible = false" class="el-icon-back" style="zoom:1.5"></i></el-col>
+          <el-col :span="8" style="font-size:1.25rem;text-align: center;">职&nbsp;&nbsp;&nbsp;&nbsp;位</el-col>
+          <el-col :span="8" style="text-align: right;"><i @click="addJob = true" class="el-icon-plus" style="zoom:1.5"></i></el-col>
+        </el-row>
+      </template>
+      <el-table :data="gridData" style="width: 100%" border>
+        <el-table-column align="center" type="expand">
+          <template v-slot="scoped">
+            <el-row>
+              <el-col :span="6">岗位名称:</el-col>
+              <el-col :span="18">{{ scoped.row.job_name }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">工作性质:</el-col>
+              <el-col :span="18">{{ `${scoped.row.is_practice}` === '0' ? '全职' : '实习' }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">学历要求:</el-col>
+              <el-col :span="18">{{ scoped.row.xl_req }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">专业要求:</el-col>
+              <el-col :span="18">{{ scoped.row.zy_req }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">薪资:</el-col>
+              <el-col :span="18">{{ scoped.row.salary.text }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">招聘人数:</el-col>
+              <el-col :span="18">{{ scoped.row.job_number }}人</el-col>
+            </el-row>
+          </template>
+        </el-table-column>
+        <el-table-column align="center" label="岗位名称" prop="job_name"> </el-table-column>
+        <el-table-column align="center" label="操作">
+          <template slot-scope="scope">
+            <el-button size="mini" type="danger" @click="handleDelete(scope.$index, 'gridData')">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+    <el-dialog :visible.sync="addJob" append-to-body :fullscreen="true" :show-close="false">
+      <template #title>
+        <el-row type="flex" align="middle" justify="start">
+          <el-col :span="8"><i @click="addJob = false" class="el-icon-back" style="zoom:1.5"></i></el-col>
+          <el-col :span="8" style="font-size:1.25rem;">选择职位</el-col>
+          <el-col :span="8"></el-col>
+        </el-row>
+      </template>
+      <el-row v-for="(item, index) in jobList" :key="index" type="flex" justify="center" align="middle" class="jobs">
+        <el-col :span="18">
+          <el-col :span="18">{{ item.job_name }}</el-col>
+          <el-col :span="6">{{ `${item.is_practice}` === '0' ? '全职' : '实习' }}</el-col>
+          <el-col :span="24">{{ item.xl_req }}</el-col>
+          <el-col :span="24">{{ item.zy_req }}</el-col>
+          <el-col :span="18">{{ item.salary && item.salary.text }}</el-col>
+          <el-col :span="6">招聘{{ item.job_number }}人</el-col>
+        </el-col>
+        <el-col :span="6" style="text-align:center;">
+          <el-button type="primary" size="mini" icon="el-icon-plus" circle @click="addjobs(item)"></el-button>
+        </el-col>
+      </el-row>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import formItem from '@m/components/form-item.vue';
+import drawer from '@m/components/drawer.vue';
+import _ from 'lodash';
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    drawer,
+    formItem,
+  },
+  data: () => ({
+    info: {},
+    jobList: [],
+    OrJobList: [],
+    dialogTableVisible: false,
+    addJob: false,
+    gridData: [],
+    profileList: [],
+    loading: false,
+    praList: [{ value: 0, label: '全职' }, { value: 1, label: '实习' }],
+    rules: {
+      profile_id: [{ required: true, message: '请选择招聘简章', trigger: 'blur' }],
+      is_practice: [{ required: true, message: '请选择工作性质', trigger: 'blur' }],
+      info: [{ required: true, message: '请选择工作城市', trigger: 'blur' }],
+    },
+  }),
+  created() {
+    this.getProfileList();
+    this.getJobsList();
+    this.search();
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['profilesOperation', 'jobinfoOperation', 'postsOperation']),
+    async search() {
+      if (this.$route.query.id) {
+        this.$set(this, `loading`, false);
+        let result = await this.jobinfoOperation({ type: 'search', data: { id: this.$route.query.id } });
+        this.$set(this, `info`, result.data);
+        this.$set(this, `gridData`, result.data.jobs);
+        this.resetJobList();
+      }
+      this.$set(this, `loading`, true);
+    },
+    // 招聘简章
+    async getProfileList() {
+      let result = await this.profilesOperation({ type: 'list', data: { corpid: this.user.corpid } });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result。data的值
+        let arr = result.data.map(item => {
+          let object = { label: item.title, value: item.id };
+          return object;
+        });
+        this.$set(this, `profileList`, arr); //result.data
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+    async getProfile({ type, value }) {
+      let checkType = type.split('.');
+      if (checkType.length < 2) {
+        this.$set(this.info, type, value);
+        let result = await this.profilesOperation({ type: 'search', data: { id: this.info.profile_id } });
+        if (`${result.errcode}` === `0`) {
+          this.info.content = result.data.content;
+          this.info.title = result.data.title;
+        }
+      } else {
+        this.$set(_.get(this, checkType[0]), `${checkType[1]}`, value);
+      }
+    },
+    //职位列表
+    async getJobsList() {
+      let result = await this.postsOperation({ type: 'list', data: { corpid: this.user.corpid } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `jobList`, result.data);
+        this.$set(this, `OrJobList`, result.data);
+        this.resetJobList();
+      }
+    },
+    //重置职位列表
+    async resetJobList() {
+      let data = JSON.parse(JSON.stringify(this.OrJobList));
+      let selectList = [];
+      let chooseList = [];
+      if (this.gridData.length > 0) {
+        this.gridData.map(item => {
+          let val = typeof item === 'object' ? item.id : item;
+          if (val !== undefined) {
+            let selected = _.find(data, select => select.id === val);
+            selectList.push(selected);
+          }
+        });
+        chooseList = _.differenceBy(data, selectList, 'id');
+      } else {
+        chooseList = data;
+      }
+      this.$set(this, `gridData`, selectList);
+      this.$set(this, `jobList`, chooseList);
+    },
+    addjobs(item) {
+      let data = JSON.parse(JSON.stringify(item));
+      this.gridData.push(data);
+      this.resetJobList();
+      // this.$message('已添加');
+      this.$notify({
+        message: '已添加',
+        type: 'success',
+        duration: 1000,
+        showClose: false,
+      });
+    },
+    handleDelete(index, type) {
+      let arr = _.get(this, `${type}`);
+      arr.splice(index, 1);
+      this.resetJobList();
+    },
+    async toSubmit(state) {
+      let data = JSON.parse(JSON.stringify(this.info));
+      data.is_submit = state;
+      let jobsIdList = this.gridData.map(item => item.id);
+      data.jobs = jobsIdList;
+      let result;
+      if (this.info.id) {
+        result = await this.jobinfoOperation({ type: 'update', data: { info: data, id: this.$route.query.id } });
+      } else {
+        result = await this.jobinfoOperation({
+          type: 'add',
+          data: { info: data, schid: 999991, corpid: this.user.corpid, corpname: this.user.corpname, schname: '测试学校1' },
+        });
+      }
+      if (`${result.errcode}` === '0') {
+        this.$message.success('操作成功');
+        this.$router.push('/jobinfo/index');
+      } else {
+        this.$message.error(result.errmsg);
+      }
+    },
+    changeSelect({ type, value }) {
+      if (type === 'is_practice') {
+        this.$set(this.info, `${type}`, value);
+      } else {
+        this.$set(this.info, `${type}`, value.label);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.el-form-item {
+  border-bottom: 0.0625rem solid #bbb;
+}
+/deep/.w-e-toolbar .w-e-menu {
+  padding: 0.3125rem 0.125rem;
+}
+.detailBtn {
+  text-align: center;
+  padding: 1.25rem 0;
+}
+
+/deep/.el-drawer.btt {
+  height: 0 !important;
+}
+/deep/.el-dialog {
+  width: 100%;
+}
+/deep/.xinBtn {
+  border: 1px solid #ccc;
+  border-radius: 4px;
+  text-align: center;
+  color: #606266;
+  width: 100%;
+}
+.jobs {
+  padding: 0.5rem 1rem;
+  border-bottom: 0.0625rem solid #cccccc;
+}
+</style>

+ 83 - 0
src/pages/corp/views/jobinfo/index.vue

@@ -0,0 +1,83 @@
+<template>
+  <div id="index">
+    <el-tabs v-model="activeName" :stretch="true" style="background:#fff;">
+      <el-tab-pane label="招聘岗位" name="work">
+        <list :data="workList" :hasMore="workHasMore" @delete="toDelete" @loadMore="search" type="work"></list>
+      </el-tab-pane>
+      <el-tab-pane label="实习岗位" name="practice">
+        <list :data="practiceList" :hasMore="practiceHasMore" @delete="toDelete" @loadMore="search" type="practice"></list>
+      </el-tab-pane>
+    </el-tabs>
+    <el-row class="addBtn" type="flex" justify="end">
+      <el-button circle type="primary" icon="el-icon-plus" @click="$router.push({ path: '/jobinfo/detail' })"></el-button>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import list from './list.vue';
+import deleteDig from '@m/components/delete-dig.vue';
+import { mapActions, mapState } from 'vuex';
+import _ from 'lodash';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    list,
+  },
+  data: () => ({
+    activeName: 'work',
+    workList: [],
+    workTotalRow: 0,
+    workHasMore: true,
+    practiceList: [],
+    practiceTotalRow: 0,
+    practiceHasMore: true,
+  }),
+  created() {
+    this.search({ type: 'work' });
+    this.search({ type: 'practice' });
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+    // ...mapState(['user']),
+  },
+  methods: {
+    ...mapActions(['jobinfoOperation']),
+    async search({ type, page }) {
+      let skip = 0;
+      if (page) {
+        skip = (page - 1) * this.$limit;
+      }
+      let result = await this.jobinfoOperation({
+        type: 'list',
+        data: { skip: skip, limit: this.$limit, is_practice: type === 'work' ? 0 : 1, corpid: this.user.corpid },
+      });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `${type}List`, _.get(this, `${type}List`).concat(result.data));
+        this.$set(this, `${type}TotalRow`, result.total);
+        this.$set(this, `${type}HasMore`, _.get(this, `${type}List`).length < _.get(this, `${type}TotalRow`));
+      }
+    },
+    async toDelete(id) {
+      let result = await this.jobinfoOperation({ type: 'delete', data: { id: id } });
+      if (`${result.errcode}` === '0') {
+        this.$message.success('删除成功');
+        this.search();
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : '删除失败');
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.addBtn {
+  position: fixed;
+  bottom: 8rem;
+  right: 1rem;
+}
+</style>

+ 68 - 0
src/pages/corp/views/jobinfo/list.vue

@@ -0,0 +1,68 @@
+<template>
+  <div id="list">
+    <scroll :hasMore="hasMore" @loadMore="loadMore" v-if="data.length > 0">
+      <el-row v-for="(item, index) in data" :key="index" type="flex" align="middle" class="row">
+        <el-col :span="21" class="main">
+          <el-row class="mainTit" @click.native="$router.push({ path: '/jobinfo/detail', query: { id: item.id } })">
+            <el-col :span="24" style="padding: 0.2rem; 0"><span>标题:</span>{{ item.title }}</el-col>
+          </el-row>
+        </el-col>
+        <el-col :span="2">
+          <deleteDig :id="item.id" @delete="toDelete"></deleteDig>
+        </el-col>
+      </el-row>
+    </scroll>
+    <nodata v-else></nodata>
+  </div>
+</template>
+
+<script>
+import nodata from '@m/components/nodata.vue';
+import deleteDig from '@m/components/delete-dig.vue';
+import scroll from '@m/layout/scroll.vue';
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'list',
+  props: {
+    data: { type: Array, default: () => [] },
+    hasMore: { type: Boolean, default: true },
+    type: { type: String },
+  },
+  components: { scroll, deleteDig, nodata },
+  data: () => ({
+    currentPage: 1,
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    loadMore() {
+      this.currentPage++;
+      this.$emit('loadMore', { type: this.type, page: this.currentPage });
+    },
+    toDelete(id) {
+      this.$emit('delete', id);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  background: #ccc;
+}
+.mainTit {
+  background-color: #fff;
+  span {
+    color: #999;
+  }
+}
+.addBtn {
+  position: fixed;
+  bottom: 8rem;
+  right: 1rem;
+}
+.row {
+  border-bottom: 0.0625rem solid #ccc;
+  padding: 0.625rem;
+}
+</style>

+ 409 - 0
src/pages/corp/views/jobs/detail.vue

@@ -0,0 +1,409 @@
+<template>
+  <div id="detail" style="background:#fff;">
+    <el-form ref="form" :model="info" label-position="right" label-width="auto" :rules="rules" style="padding:0.4rem;">
+      <el-form-item label="职位名称" prop="job_name">
+        <el-input v-model="info.job_name" placeholder="请填写职位名称" style="margin:5px 0px"></el-input>
+      </el-form-item>
+      <el-form-item label="工作性质" prop="is_practice">
+        <drawer
+          :data="praList"
+          type="is_practice"
+          :selected="info.is_practice"
+          placeholder="点击选择工作性质"
+          need="value"
+          @select="selectChange"
+          style="margin:5px 0px"
+        >
+        </drawer>
+      </el-form-item>
+      <el-form-item label="职位分类" prop="category">
+        <drawer
+          :data="jobTypeList"
+          type="category"
+          :selected="info.category"
+          placeholder="点击选择职位"
+          need="label"
+          @select="selectChange"
+          style="margin:5px 0px"
+        ></drawer>
+      </el-form-item>
+      <el-form-item label="截止时间" prop="end_date">
+        <el-input v-model="info.end_date" placeholder="请选择日期" @click.native="dateVis = true" style="margin:5px 0px"></el-input>
+        <nut-datepicker
+          :is-visible="dateVis"
+          :defaultValue="new Date().toLocaleString()"
+          :endDate="endDate"
+          type="date"
+          title="请选择日期"
+          :is-show-chinese="false"
+          @close="dateVis = false"
+          @choose="selectDate"
+        ></nut-datepicker>
+      </el-form-item>
+      <el-form-item label="工作城市" prop="city">
+        <tag-all-select
+          placeholder="点击选择城市"
+          :firstList="provinceList"
+          :secondList="cityList"
+          @selectChange="selectChange"
+          @listChange="listChange"
+          :selected="info.city"
+          type="city"
+        ></tag-all-select>
+      </el-form-item>
+      <el-form-item label="学历要求" prop="xl_req">
+        <drawer
+          :data="edu_list"
+          type="xl_req"
+          :selected="info.xl_req"
+          placeholder="点击选择工作性质"
+          need="label"
+          @select="selectChange"
+          style="margin:5px 0px"
+        >
+        </drawer>
+      </el-form-item>
+      <el-form-item label="专业要求" prop="zy_req">
+        <tagSecSelect
+          placeholder="点击选择相关专业"
+          :selected="info.zy_req"
+          :firstList="subjectList"
+          :secondList="subjectSubList"
+          @selectChange="selectChange"
+          @listChange="listChange"
+          type="zy_req"
+        ></tagSecSelect>
+      </el-form-item>
+      <el-form-item label="薪资待遇" prop="salary">
+        <el-col :span="10">
+          <el-input type="number" v-model="info.salary.min">
+            <template #append>
+              <strong>K</strong>
+            </template>
+          </el-input>
+        </el-col>
+        <el-col :span="4" style="text-align:center;">
+          至
+        </el-col>
+        <el-col :span="10">
+          <el-input type="number" v-model="info.salary.max">
+            <template #append>
+              <strong>K</strong>
+            </template>
+          </el-input>
+        </el-col>
+      </el-form-item>
+      <el-form-item label="职位诱惑" prop="job_tag">
+        <tagCheckbox
+          placeholder="点击选择职位诱惑"
+          :firstList="entice_list"
+          @selectChange="selectChange"
+          @listChange="listChange"
+          :selected="info.job_tag"
+          type="job_tag"
+        ></tagCheckbox>
+      </el-form-item>
+      <el-form-item label="招聘人数" prop="job_number">
+        <el-input-number v-model="info.job_number" :min="1" placeholder="添加需要招聘的人数" style="width:100%;margin:5px 0px"></el-input-number>
+      </el-form-item>
+      <el-form-item label="职位描述" prop="job_desc">
+        <el-input type="textarea" :rows="5" placeholder="请输入职位描述" v-model="info.job_desc" style="margin:5px 0px"> </el-input>
+      </el-form-item>
+      <el-form-item label="简历投递说明" prop="apply_intro">
+        <el-input type="textarea" :rows="5" placeholder="请输入简历投递说明" v-model="info.apply_intro" style="margin:5px 0px"> </el-input>
+      </el-form-item>
+      <el-form-item label="岗位要求" prop="welfare">
+        <el-input type="textarea" :rows="5" placeholder="请输入岗位要求" v-model="info.welfare" style="margin:5px 0px"> </el-input>
+      </el-form-item>
+      <el-form-item label="其他说明" prop="job_req">
+        <el-input type="textarea" :rows="5" placeholder="请输入其他描述" v-model="info.other" style="margin:5px 0px"> </el-input>
+      </el-form-item>
+    </el-form>
+    <el-row>
+      <el-col :span="24" style="padding-top:1rem;">
+        <el-button style="width:100%;border-radius: 30px" type="success" @click="toSubmit()">保存</el-button>
+      </el-col>
+      <el-col :span="24" style="padding-top:1rem;">
+        <el-button style="width:100%;border-radius: 30px" type="info" @click="$router.push({ path: '/jobs/index' })">返回</el-button>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import drawer from '@m/components/drawer.vue';
+import tagAllSelect from '@m/components/tag-all-select.vue';
+import tagSecSelect from '@m/components/tag-sec-select.vue';
+import tagCheckbox from '@m/components/tag-checkbox.vue';
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    drawer,
+    tagAllSelect,
+    tagSecSelect,
+    tagCheckbox,
+  },
+  data() {
+    return {
+      info: {
+        salary: {},
+      },
+      dateVis: false,
+      endDate: `${new Date().getFullYear() + 1}-${new Date().getMonth() + 1}-${new Date().getDate()}`,
+      jobTypeList: [
+        {
+          label: 'IT',
+          value: '1',
+        },
+        {
+          label: 'test2',
+          value: '2',
+        },
+        {
+          label: 'test3',
+          value: '3',
+        },
+        {
+          label: 'test4',
+          value: '4',
+        },
+      ],
+      praList: [{ value: 0, label: '校招' }, { value: 1, label: '实习' }, { value: 2, label: '社招' }],
+      edu_list: [
+        { value: '不限', label: '不限' },
+        { value: '中专及以上', label: '中专及以上' },
+        { value: '大专及以上', label: '大专及以上' },
+        { value: '本科及以上', label: '本科及以上' },
+        { value: '硕士及以上', label: '硕士及以上' },
+        { value: '博士及以上', label: '博士及以上' },
+      ],
+      cityList: [],
+      provinceList: [{ label: '北京市', value: '110000' }, { label: '吉林省', value: '220000' }, { label: '沈阳省', value: '210000' }],
+      secondList: [{ label: '长春市', value: '220100' }, { label: '吉林市', value: '220200' }],
+      secondList1: [{ label: '沈阳市', value: '210100' }, { label: '大连市', value: '210200' }],
+      subjectList: [
+        { label: '不限专业', value: '0' },
+        { label: '哲学', value: '1' },
+        { label: '经济学', value: '2' },
+        { label: '法学', value: '3' },
+        { label: '教育学', value: '4' },
+        { label: '文学', value: '5' },
+        { label: '历史学', value: '6' },
+        { label: '理学', value: '7' },
+        { label: '工学', value: '8' },
+        { label: '农学', value: '9' },
+        { label: '医学', value: '10' },
+      ],
+      subjectSubList: [],
+      subjectSub: [
+        { label: '哲学类', value: '11' },
+        { label: '哲学', value: '12' },
+        { label: '逻辑类', value: '13' },
+        { label: '宗教类', value: '14' },
+        { label: '伦理类', value: '15' },
+      ],
+      subjectSub2: [{ label: '社会经济学', value: '16' }, { label: '国际经济学', value: '17' }, { label: '资本主义经济学', value: '18' }],
+      entice_list: [
+        { value: '1', label: '年底双薪' },
+        { value: '2', label: '绩效奖金' },
+        { value: '3', label: '岗前培训' },
+        { value: '4', label: '节日礼物' },
+        { value: '5', label: '扁平管理' },
+        { value: '6', label: '年度旅游' },
+        { value: '7', label: '岗位晋升' },
+        { value: '8', label: '股票期权' },
+        { value: '9', label: '弹性工作' },
+        { value: '10', label: '带薪年假' },
+        { value: '11', label: '交通补助' },
+        { value: '12', label: '餐补' },
+        { value: '13', label: '房补' },
+        { value: '14', label: '免费班车' },
+        { value: '15', label: '员工旅游' },
+        { value: '16', label: '包吃包住' },
+        { value: '17', label: '健康体检' },
+        { value: '18', label: '留人基金' },
+        { value: '19', label: '学费返还' },
+      ],
+      rules: {
+        job_name: [{ required: true, message: '请输入职位名称', trigger: 'blur' }],
+        is_practice: [{ required: true, message: '请选择工作性质', trigger: 'blur' }],
+        category: [{ required: true, message: '请选择职位分类', trigger: 'blur' }],
+        end_date: [{ required: true, message: '请选择截止时间', trigger: 'change' }],
+        city: [{ required: true, message: '请选择工作城市', trigger: 'blur' }],
+        xl_req: [{ required: true, message: '请选择学历要求', trigger: 'blur' }],
+        zy_req: [{ required: true, message: '请选择专业要求', trigger: 'blur' }],
+        salary: {
+          type: 'object',
+          fields: {
+            max: { required: true, message: '请输入完整的薪资待遇', type: 'string' },
+            min: { required: true, message: '请输入完整的薪资待遇', type: 'string' },
+          },
+        },
+        job_tag: [{ required: true, message: '请选择职位诱惑', trigger: 'blur' }],
+        job_number: [{ required: true, message: '请输入招聘人数', trigger: 'blur' }],
+        job_desc: [{ required: true, message: '请输入职位描述', trigger: 'blur' }],
+        apply_intro: [{ required: true, message: '请输入简历投递说明', trigger: 'blur' }],
+        welfare: [{ required: true, message: '请输入岗位要求', trigger: 'blur' }],
+      },
+    };
+  },
+  created() {
+    this.search();
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['postsOperation']),
+    async search() {
+      if (this.$route.query.id) {
+        let result = await this.postsOperation({ type: 'search', data: { id: this.$route.query.id } });
+        let infos = JSON.parse(JSON.stringify(result.data));
+        infos.salary.max = `${infos.salary.max}`;
+        infos.salary.min = `${infos.salary.min}`;
+        this.$set(this, `info`, infos);
+        this.returnData(this.info);
+      }
+    },
+    selectChange({ type, value }) {
+      console.log(type, value);
+      this.$set(this.info, `${type}`, value);
+    },
+    selectDate(date) {
+      this.$set(this.info, `end_date`, date[3]);
+      this.dateVis = false;
+    },
+    listChange({ value, type }) {
+      //此方法是更换子列表的
+      if (value.value === '220000') {
+        this.$set(this, `cityList`, this.secondList);
+      } else if (value.value === '210000') {
+        this.$set(this, `cityList`, this.secondList1);
+      } else if (type === 'zy_req') {
+        //专业查询模拟
+        this.$set(this, `subjectSubList`, value === '1' ? this.subjectSub : this.subjectSub2);
+      }
+    },
+    toSubmit() {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          this.submit();
+        }
+      });
+    },
+    async submit() {
+      let result;
+      let infos = JSON.parse(JSON.stringify(this.info));
+      let mid = '';
+      infos.salary.text = infos.salary.min + 'k-' + infos.salary.max + 'k/月';
+      if (typeof infos.city === 'object') {
+        infos.city.map(item => {
+          mid === '' ? (mid = item.label) : (mid += `,${item.label}`);
+        });
+        infos.city = mid;
+        mid = '';
+      }
+      if (typeof infos.job_tag === 'object') {
+        infos.job_tag.map(item => {
+          mid === '' ? (mid = item.label) : (mid += `,${item.label}`);
+        });
+        infos.job_tag = mid;
+        mid = '';
+      }
+      if (typeof infos.zy_req === 'object') {
+        infos.zy_req.map(item => {
+          mid === '' ? (mid = item.label) : (mid += `,${item.label}`);
+        });
+        infos.zy_req = mid;
+      }
+      if (this.info.id) {
+        result = await this.postsOperation({ type: 'update', data: { info: infos, id: this.$route.query.id } });
+      } else {
+        result = await this.postsOperation({ type: 'add', data: { info: infos, corpname: '福瑞', corpid: this.user.corpid } });
+      }
+      if (`${result.errcode}` === '0') {
+        this.$message.success('操作成功');
+        this.$router.push('/jobs/index');
+      } else {
+        this.$message.error(result.errmsg);
+      }
+    },
+    returnData(data) {
+      if (data.city) {
+        let mid = data.city.split(',');
+        let selected = [];
+        for (const select of mid) {
+          let res = this.provinceList.filter(item => item.label === select);
+          if (res.length > 0) {
+            selected = [...selected, ...res];
+          } else {
+            let res = this.secondList.filter(item => item.label === select);
+            if (res.length > 0) {
+              selected = [...selected, ...res];
+            } else {
+              let res = this.secondList1.filter(item => item.label === select);
+              if (res.length > 0) {
+                selected = [...selected, ...res];
+              }
+            }
+          }
+        }
+        this.$set(this.info, `city`, selected);
+      }
+      if (data.zy_req) {
+        let mid = data.zy_req.split(',');
+        let selected = [];
+        for (const select of mid) {
+          let res = this.subjectList.filter(item => item.label === select && item.value === '0');
+          if (res.length <= 0) {
+            res = this.subjectSub.filter(item => item.label === select);
+            selected = [...selected, ...res];
+            res = this.subjectSub2.filter(item => item.label === select);
+            selected = [...selected, ...res];
+            this.$set(this.info, `zy_req`, selected);
+          } else {
+            this.$set(this.info, `zy_req`, res);
+          }
+        }
+      }
+      if (data.job_tag) {
+        let mid = data.job_tag.split(',');
+        let selected = [];
+        for (const select of mid) {
+          let res = this.entice_list.filter(item => item.label === select);
+          selected = [...selected, ...res];
+        }
+        this.$set(this.info, `job_tag`, selected);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-input__inner {
+  border: none;
+}
+.el-form-item {
+  border-bottom: 0.0625rem solid #bbb;
+}
+.el-form-item {
+  margin: 0;
+}
+/deep/.el-form-item__label {
+  line-height: 51px;
+}
+/deep/.el-form-item__error {
+  color: #f56c6c;
+  font-size: 12px;
+  line-height: 1;
+  padding-top: 4px;
+  position: absolute;
+  top: 2rem;
+  left: -6.5rem;
+}
+</style>

+ 78 - 0
src/pages/corp/views/jobs/index.vue

@@ -0,0 +1,78 @@
+<template>
+  <div id="index">
+    <el-tabs v-model="activeName" :stretch="true" style="background:#fff;">
+      <el-tab-pane label="招聘岗位" name="work">
+        <list :data="workList" :hasMore="workHasMore" @delete="toDelete" @loadMore="search" type="work"></list>
+      </el-tab-pane>
+      <el-tab-pane label="实习岗位" name="practice">
+        <list :data="practiceList" :hasMore="practiceHasMore" @delete="toDelete" @loadMore="search" type="practice"></list>
+      </el-tab-pane>
+    </el-tabs>
+    <el-row class="addBtn" type="flex" justify="end">
+      <el-button circle type="primary" icon="el-icon-plus" @click="$router.push({ path: '/jobs/detail' })"></el-button>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import list from './list.vue';
+import { mapActions, mapState } from 'vuex';
+import _ from 'lodash';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    list,
+  },
+  data: () => ({
+    activeName: 'work',
+    workList: [],
+    workTotalRow: 0,
+    workHasMore: true,
+    practiceList: [],
+    practiceTotalRow: 0,
+    practiceHasMore: true,
+  }),
+  created() {
+    this.search({ type: 'work' });
+    this.search({ type: 'practice' });
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['postsOperation']),
+    async search({ type, page }) {
+      let skip = 0;
+      if (page) {
+        skip = (page - 1) * this.$limit;
+      }
+      let result = await this.postsOperation({ type: 'list', data: { is_practice: type === 'work' ? 0 : 1, corpid: this.user.corpid } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `${type}List`, _.get(this, `${type}List`).concat(result.data));
+        this.$set(this, `${type}TotalRow`, result.total);
+        this.$set(this, `${type}HasMore`, _.get(this, `${type}List`).length < _.get(this, `${type}TotalRow`));
+      }
+    },
+    async toDelete(id) {
+      let result = await this.postsOperation({ type: 'delete', data: { id: id } });
+      if (`${result.errcode}` === '0') {
+        this.$message.success('删除成功');
+        this.search();
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : '删除失败');
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.addBtn {
+  position: fixed;
+  bottom: 8rem;
+  right: 1rem;
+}
+</style>

+ 76 - 0
src/pages/corp/views/jobs/list.vue

@@ -0,0 +1,76 @@
+<template>
+  <div id="list">
+    <scroll :hasMore="hasMore" @loadMore="loadMore" v-if="data.length > 0">
+      <el-row :gutter="20" v-for="(item, index) in data" :key="index" type="flex" align="middle" class="row">
+        <el-col :span="17" class="main" style="background:#fff;">
+          <el-row class="mainTit" @click.native="$router.push({ path: '/resume/index', query: { id: item.id } })">
+            <el-col :span="20" style="padding: 0.2rem; 0">
+              {{ item.job_name }}
+            </el-col>
+            <el-col :span="20" style="padding: 0.2rem; 0"> <span class="el-icon-location">工作地点:</span>{{ item.city }} </el-col>
+            <el-col :span="20" style="padding: 0.2rem; 0"> <span class="el-icon-user-solid">招聘人数:</span>{{ item.job_number }} </el-col>
+            <el-col :span="20" style="padding: 0.2rem; 0"> <span class="el-icon-trophy">专业要求:</span>{{ item.zy_req }} </el-col>
+            <el-col :span="20" style="padding: 0.2rem; 0"> <span class="el-icon-collection">学历要求:</span>{{ item.xl_req }} </el-col>
+          </el-row>
+        </el-col>
+        <el-col :span="3">
+          <el-button type="primary" circle size="small" icon="el-icon-edit" @click="$router.push({ path: '/jobs/detail', query: { id: item.id } })"></el-button>
+        </el-col>
+        <el-col :span="3">
+          <deleteDig :id="item.id" @delete="toDelete"></deleteDig>
+        </el-col>
+      </el-row>
+    </scroll>
+    <nodata v-else></nodata>
+  </div>
+</template>
+
+<script>
+import nodata from '@m/components/nodata.vue';
+import deleteDig from '@m/components/delete-dig.vue';
+import scroll from '@m/layout/scroll.vue';
+export default {
+  name: 'list',
+  props: {
+    data: { type: Array, default: () => [] },
+    hasMore: { type: Boolean, default: true },
+    type: { type: String },
+  },
+  components: { scroll, deleteDig, nodata },
+  data: () => ({
+    currentPage: 1,
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    loadMore() {
+      this.currentPage++;
+      this.$emit('loadMore', { type: this.type, page: this.currentPage });
+    },
+    toDelete(id) {
+      this.$emit('delete', id);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  background: #ccc;
+}
+.mainTit {
+  background-color: #fff;
+  padding: 0 0.625rem 0;
+  span {
+    color: #999;
+  }
+}
+.addBtn {
+  position: fixed;
+  bottom: 8rem;
+  right: 1rem;
+}
+.row {
+  border-bottom: 0.0625rem solid #ccc;
+}
+</style>

+ 46 - 0
src/pages/corp/views/login/index.vue

@@ -0,0 +1,46 @@
+<template>
+  <div id="index">
+    <el-row class="login">
+      <el-col :span="3" class="ZH"><span>账号</span></el-col>
+      <el-col :span="21"><nut-textinput v-model="val" placeholder="请输入..." :clearBtn="true" :hasBorder="false"/></el-col>
+    </el-row>
+    <el-row style="border-bottom:1px solid #E4E7ED;">
+      <el-col :span="3" class="ZH"><span>密码 </span></el-col>
+      <el-col :span="21"><nut-textinput v-model="val" placeholder="请输入..." :clearBtn="true" :hasBorder="false"/></el-col>
+    </el-row>
+    <el-row style="border-bottom:1px solid #E4E7ED">
+      <el-col :span="3" style="padding-left:340px"><el-button type="text">忘记密码</el-button></el-col>
+    </el-row>
+    <el-row style="margin-top:1rem"><nut-button block shape="circle" style="background:#409EFF">登录</nut-button></el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'index',
+  props: {},
+  components: {},
+  data: () => ({
+    val: '',
+  }),
+  created() {},
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+.login {
+  margin-top: 1rem;
+  border-bottom: 1px solid #e4e7ed;
+  border-top: 1px solid #e4e7ed;
+}
+.ZH {
+  margin-top: 11px;
+  padding-left: 10px;
+  font-size: 13px;
+}
+/deep/.nut-textinput input {
+  padding: 0;
+}
+</style>

+ 57 - 0
src/pages/corp/views/login/message.vue

@@ -0,0 +1,57 @@
+<template>
+  <div id="message">
+    <el-row class="top">
+      <el-col :span="6">
+        <div class="demo-basic--circle">
+          <div class="block"><el-avatar :size="70" :src="circleUrl"></el-avatar></div>
+        </div>
+      </el-col>
+      <el-col :span="14" style="margin-top:26px"><span style="color:#008b8b">长春市福瑞科技有限公司</span></el-col>
+      <el-col :span="4" style="margin-top:26px"><span style="color:#32CD32">已认证</span></el-col>
+    </el-row>
+    <el-row>
+      <nut-cell :isLink="true" title="基本资料" :showIcon="true"> </nut-cell>
+    </el-row>
+    <el-row>
+      <nut-cell :isLink="true" title="认证信息" :showIcon="true"> </nut-cell>
+    </el-row>
+    <el-row>
+      <nut-cell :isLink="true" title="入驻学校" :showIcon="true"> </nut-cell>
+    </el-row>
+    <el-row>
+      <nut-cell :isLink="true" title="企业HR成员" :showIcon="true"> </nut-cell>
+    </el-row>
+    <el-row>
+      <nut-cell :isLink="true" title="人才邀约" :showIcon="true"> </nut-cell>
+    </el-row>
+    <el-row>
+      <nut-cell :isLink="true" title="同城招聘" :showIcon="true"> </nut-cell>
+    </el-row>
+    <el-row>
+      <nut-cell :isLink="true" title="企业问卷" :showIcon="true"> </nut-cell>
+    </el-row>
+    <el-row style="padding-left:10px;padding-top:5px;"><span style="color:darkorange">PC端操作请访问hr.bysjy.com.cn</span></el-row>
+    <el-row style="margin-top:2rem"><nut-button block shape="circle">退出登录</nut-button></el-row>
+    <el-row style="margin-top:1rem"><nut-button block shape="circle" style="background:#C0C4CC">注销账户</nut-button></el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'message',
+  props: {},
+  components: {},
+  data: () => ({
+    circleUrl: '',
+  }),
+  created() {},
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+.top {
+  padding: 10px 10px;
+}
+</style>

+ 163 - 0
src/pages/corp/views/login/nomal.vue

@@ -0,0 +1,163 @@
+<template>
+  <div id="nomal" style="background:#ebeef5; height:140vh">
+    <el-row>
+      <el-row class="top">
+        <el-col :span="5" style="line-height: 30px;"> <span>企业名称</span></el-col>
+        <el-col :span="15" style="line-height: 30px;"><span>长春市福瑞科技有限公司</span></el-col>
+        <el-col :span="3"> <el-tag effect="dark">已认证 </el-tag></el-col>
+      </el-row>
+      <el-row class="HR">
+        <el-col :span="5"> <span>HR管理员</span></el-col>
+        <el-col :span="15"><span>杨帆</span></el-col>
+      </el-row>
+      <el-row style="background: #fff;">
+        <el-col :span="5" class="ZH"><span>所在省份 </span></el-col>
+        <el-col :span="19"><nut-cell title="吉林" :showIcon="true"> </nut-cell></el-col>
+      </el-row>
+      <el-row style="background: #fff;">
+        <el-col :span="5" class="ZH"><span>所在城市 </span></el-col>
+        <el-col :span="19"><nut-cell title="长春" :showIcon="true"> </nut-cell></el-col>
+      </el-row>
+      <el-row style="background: #fff;">
+        <el-col :span="5" class="ZH"><span>单位地址 </span></el-col>
+        <el-col :span="19"><nut-cell title="长春市前进大街996号力旺广场B座16楼"> </nut-cell></el-col>
+      </el-row>
+      <el-row style="background: #fff;">
+        <el-col :span="5" class="ZH"><span>单位规模 </span></el-col>
+        <el-col :span="19"><nut-cell title="少于50人" :showIcon="true"> </nut-cell></el-col>
+      </el-row>
+      <el-row style="background: #fff;">
+        <el-col :span="5" class="ZH"><span>固定电话 </span></el-col>
+        <el-col :span="19"><nut-cell title="0431-84887775"> </nut-cell></el-col>
+      </el-row>
+      <el-row style="background: #fff;">
+        <el-col :span="5" class="ZH"><span>招聘电话 </span></el-col>
+        <el-col :span="19"><nut-cell title="13943018186"> </nut-cell></el-col>
+      </el-row>
+      <el-row style="background: #fff;">
+        <el-col :span="5" class="ZH"><span>招聘邮箱 </span></el-col>
+        <el-col :span="19"><nut-cell title="myhope1977@163.com"> </nut-cell></el-col>
+      </el-row>
+      <el-row style="background: #fff;">
+        <el-col :span="5" class="ZH"><span>企业邮箱 </span></el-col>
+        <el-col :span="19"><nut-cell title="myhope1977@163.com"> </nut-cell></el-col>
+      </el-row>
+      <el-row class="SR" style="margin-top: 1rem;">
+        <el-col :span="5"><span>企业愿景 </span></el-col>
+        <el-col :span="19" style="margin-top:5px"><nut-textinput v-model="val1" placeholder="请输入..." :clearBtn="true" :hasBorder="false"/></el-col>
+      </el-row>
+      <el-row class="SR">
+        <el-col :span="5"><span>网申网址 </span></el-col>
+        <el-col :span="19" style="margin-top:5px"><nut-textinput v-model="val2" placeholder="请输入..." :clearBtn="true" :hasBorder="false"/></el-col>
+      </el-row>
+      <el-row class="SR">
+        <el-col :span="5"><span>视频网址 </span></el-col>
+        <el-col :span="19" style="margin-top:5px"><nut-textinput v-model="val3" placeholder="请输入..." :clearBtn="true" :hasBorder="false"/></el-col>
+      </el-row>
+      <el-row class="SR">
+        <el-col :span="5"><span>H5宣传页</span></el-col>
+        <el-col :span="19" style="margin-top:5px"><nut-textinput v-model="val4" placeholder="请输入..." :clearBtn="true" :hasBorder="false"/></el-col>
+      </el-row>
+      <el-row class="SR">
+        <el-col :span="5"><span>企业网址 </span></el-col>
+        <el-col :span="19" style="margin-top:5px"><nut-textinput v-model="val5" placeholder="www." :clearBtn="true" :hasBorder="false"/></el-col>
+      </el-row>
+      <el-row class="ZP">
+        <el-col :span="5"><span>企业相册</span></el-col>
+        <el-col :span="19"><span style="color:#909399">(最多5张,点击删除图片)</span></el-col>
+      </el-row>
+      <el-row class="SC">
+        <nut-imagepicker @imgMsg="imgMsg" :imgList="imgList1" class="element.style" :width="70" :height="70"> </nut-imagepicker>
+      </el-row>
+
+      <el-row style=" margin-top: 1rem; background: #fff;">
+        <el-col :span="5" class="ZH" style=" margin-top: 24px;"><span>企业介绍 </span></el-col>
+        <el-col :span="19"><nut-cell title="本公司是一家软件开发公司,以开发吉林省计算中心平台为主要业务" :showIcon="true"> </nut-cell></el-col>
+      </el-row>
+      <el-row class="end">请上传办公环境,以便招聘者更全面的了解</el-row>
+      <el-row style="margin-top:2rem;">
+        <nut-button block shape="circle" style="background:#409EFF"> 保存</nut-button>
+      </el-row>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'nomal',
+  props: {},
+  components: {},
+  data: () => ({
+    val1: '',
+    val2: '',
+    val3: '',
+    val4: '',
+    val5: '',
+    imgList1: [],
+    imgMsg: '',
+  }),
+  created() {},
+  computed: {},
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+.top {
+  padding: 5px 10px;
+  border-top: 1px solid #e4e7ed;
+  border-bottom: 1px solid #dcdfe6;
+  margin-top: 1rem;
+}
+.HR {
+  border-bottom: 1px solid #e4e7ed;
+  height: 44px;
+  line-height: 44px;
+  padding: 0px 10px;
+}
+.ZH {
+  margin-top: 14px;
+  padding-left: 10px;
+  font-size: 16px;
+}
+/deep/.nut-cell .nut-cell-title {
+  font-size: 16px;
+}
+.SR {
+  background: #fff;
+  padding-left: 10px;
+  height: 48px;
+  line-height: 48px;
+  border-bottom: 1px solid #e4e7ed;
+}
+.ZP {
+  background: #fff;
+  padding-left: 10px;
+  height: 48px;
+  line-height: 48px;
+  margin-top: 1rem;
+}
+.element.style {
+  width: 70px;
+  height: 70px;
+}
+.SC {
+  background: #fff;
+  border-bottom: 1px solid #e4e7ed;
+}
+/deep/.nut-imagepicker .img-list .add-icon {
+  border: 1px solid #e4e7ed;
+}
+/deep/.nut-imagepicker .img-list .add-icon i {
+  color: #909399;
+}
+/deep/.nut-cell .nut-cell-title {
+  padding: 10px 0px;
+}
+.end {
+  margin-top: 8px;
+  padding-left: 10px;
+  font-size: 16px;
+  color: #606266;
+}
+</style>

+ 78 - 0
src/pages/corp/views/profile/detail.vue

@@ -0,0 +1,78 @@
+<template>
+  <div id="index">
+    <el-row style="padding:10px 5px;overflow: hidden;background:#fff;">
+      <el-form :model="info" :rules="rules">
+        <form-item label="标   题" prop="title">
+          <el-input placeholder="必填" v-model="info.title"></el-input>
+        </form-item>
+        <form-item label="内   容" prop="content">
+          <wang-editor v-if="loading" v-model="info.content" :rows="5"></wang-editor>
+        </form-item>
+        <el-row type="flex" align="middle" justify="center">
+          <el-col :span="6">
+            <el-button type="success" style="width:100%; margin: 1rem 0;" @click="toSubmit()">保存</el-button>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import formItem from '@m/components/form-item.vue';
+import WangEditor from '@m/components/wang-editor.vue';
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    formItem,
+    WangEditor,
+  },
+  data: () => ({
+    info: {},
+    loading: true,
+    rules: {
+      title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
+      content: [{ required: true, message: '请输入内容', trigger: 'blur' }],
+    },
+  }),
+  created() {
+    if (this.$route.query.id) this.search();
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['profilesOperation']),
+    async search() {
+      this.$set(this, `loading`, false);
+      let result = await this.profilesOperation({ type: 'search', data: { id: this.$route.query.id } });
+      this.$set(this, `info`, result.data);
+      this.$set(this, `loading`, true);
+    },
+    async toSubmit() {
+      let result;
+      if (this.info.id) {
+        result = await this.profilesOperation({ type: 'update', data: { info: this.info, id: this.$route.query.id } });
+      } else {
+        result = await this.profilesOperation({ type: 'add', data: { info: this.info, corpid: this.user.corpid, corpname: '福瑞test' } });
+      }
+      if (`${result.errcode}` === '0') {
+        this.$message.success('操作成功');
+        this.$router.push('/profile/index');
+      } else {
+        this.$message.error(result.errmsg);
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.w-e-toolbar .w-e-menu {
+  padding: 5px 2px;
+}
+</style>

+ 99 - 0
src/pages/corp/views/profile/index.vue

@@ -0,0 +1,99 @@
+<template>
+  <div id="index">
+    <scroll :hasMore="hasMore" @loadMore="search" v-if="list.length > 0">
+      <el-row class="mainTit" v-for="(item, index) in list" :key="index">
+        <el-col :span="24" class="recruitTxt">
+          <el-col
+            :span="20"
+            class="recruitTxt_txt"
+            style="padding: 0.5rem; 0"
+            @click.native="$router.push({ path: '/profile/detail', query: { id: item.id } })"
+          >
+            {{ item.title }}
+          </el-col>
+          <el-col :span="2">
+            <deleteDig :id="item.id" @delete="toDelete"></deleteDig>
+          </el-col>
+        </el-col>
+      </el-row>
+    </scroll>
+    <nodata v-else></nodata>
+    <el-row class="addBtn" type="flex" justify="end">
+      <el-button circle type="primary" icon="el-icon-plus" @click="$router.push({ path: '/profile/detail' })"></el-button>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import nodata from '@m/components/nodata.vue';
+import deleteDig from '@m/components/delete-dig.vue';
+import scroll from '@m/layout/scroll.vue';
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'index',
+  props: {},
+  components: { deleteDig, scroll, nodata },
+  data: () => ({
+    list: [],
+    hasMore: true,
+    totalRow: 10,
+    searchInfo: '',
+    currentPage: 1,
+  }),
+  created() {
+    this.search();
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['profilesOperation']),
+    async search(type) {
+      let skip = 0;
+      //判断下type,如果type存在.当前页加一
+      if (type && type === 'nextPage') {
+        this.currentPage++; //当前页加一
+        skip = (this.currentPage - 1) * this.$limit; //重新计算skip:即计算数据库开始查询的位置
+      }
+      if (this.list.length >= this.totalRow) return false; //判断的是:如果我列表的数据条数大于等于数据库返回给我的总数时=>我就不查了.没数据了
+      this.$set(this, `hasMore`, false); //控制无限加载瞬间加载N次的情况
+      let result = await this.profilesOperation({ type: 'list', data: { skip: skip, limit: this.$limit, corpid: this.user.corpid } }); //查询,添加skip和limit参数
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result。data的值
+        this.$set(this, `list`, this.list.concat(result.data)); //将现有的列表和请求来的数据列表合并到一起,自动追加在下面import '@/plugins/var';
+        this.$set(this, `totalRow`, result.total); //将数据库返回的总数放到页面的totalRow变量中,用来判断
+        this.$set(this, `hasMore`, this.list.length < this.totalRow); //此处是根据数据库总数的结果和当前列表的总条数比较,看看是否可以继续请求数据
+      }
+    },
+    async toDelete(id) {
+      let result = await this.profilesOperation({ type: 'delete', data: { id: id } });
+      if (`${result.errcode}` === '0') {
+        this.$message.success('删除成功');
+        this.search();
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : '删除失败');
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  background: #ccc;
+}
+.mainTit {
+  background-color: #fff;
+  padding: 0.625rem 0 0.625rem 0.625rem;
+}
+.recruitTxt {
+  margin: 0.3125rem 0 0 0;
+}
+.addBtn {
+  position: fixed;
+  bottom: 8rem;
+  right: 1rem;
+}
+</style>

+ 100 - 0
src/pages/corp/views/resume/detail.vue

@@ -0,0 +1,100 @@
+<template>
+  <div id="detail">
+    <el-row>
+      <el-form :model="info" label-position="right" label-width="0" style="padding:10px 5px;" ref="form" :rules="rules">
+        <form-item label="学生姓名" prop="name">
+          <el-input v-model="info.name" placeholder="请输入姓名"></el-input>
+        </form-item>
+        <form-item label="教育经历" prop="educations">
+          <el-input v-model="info.educations" readonly placeholder="请输入教育经历"></el-input>
+        </form-item>
+        <form-item label="个人介绍" prop="content">
+          <wang-editor v-if="loading" v-model="info.content" :rows="5"></wang-editor>
+        </form-item>
+        <form-item label="专业技能" prop="skill">
+          <wang-editor v-if="loading" v-model="info.skill" :rows="5" placeholder="请用空格隔开"></wang-editor>
+        </form-item>
+        <form-item label="工作经历" prop="works">
+          <wang-editor v-if="loading" v-model="info.works" :rows="5" placeholder="请用空格隔开"></wang-editor>
+        </form-item>
+        <form-item label="个人风采" prop="shows">
+          <wang-editor v-if="loading" v-model="info.shows" :rows="5" placeholder="个人风采"></wang-editor>
+        </form-item>
+        <form-item label="一句话描述" prop="profile">
+          <wang-editor v-if="loading" v-model="info.profile" :rows="5" placeholder="描述"></wang-editor>
+        </form-item>
+        <el-row>
+          <el-col :span="6" class="button"><el-button type="success">纳入考虑</el-button></el-col>
+          <el-col :span="6" class="button"><el-button type="success">暂不考虑</el-button></el-col>
+          <el-col :span="6" class="button"><el-button type="success" @click="dialogVisible = true">查看消息</el-button></el-col>
+          <el-col :span="6" class="button"><el-button type="success" @click="dialogVisibles = true">回复</el-button></el-col>
+        </el-row>
+      </el-form>
+    </el-row>
+    <el-dialog title="查看消息" class="chakan" :visible.sync="dialogVisible" width="30%">
+      <span>查看消息</span>
+    </el-dialog>
+    <el-dialog title="回复" class="chakan" :visible.sync="dialogVisibles" width="30%">
+      <span>回复</span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import formItem from '@m/components/form-item.vue';
+import WangEditor from '@m/components/wang-editor.vue';
+import { mapActions } from 'vuex';
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    formItem,
+    WangEditor,
+  },
+  data: () => ({
+    input: '',
+    info: {},
+    loading: true,
+    rules: {
+      name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
+    },
+    dialogVisible: false,
+    dialogVisibles: false,
+  }),
+  created() {
+    if (this.$route.query.id) this.search();
+  },
+  computed: {},
+  methods: {
+    // 无数据,无法显示id
+    ...mapActions(['resumesOperation']),
+    async search() {
+      this.$set(this, `loading`, false);
+      let result = await this.resumesOperation({ type: 'search', data: { id: this.$route.query.id } });
+      this.$set(this, `info`, result.data);
+      this.$set(this, `loading`, true);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-dialog {
+  width: 100% !important;
+  margin: 0% !important;
+  position: absolute;
+}
+/deep/.chakan .el-dialog {
+  bottom: 20%;
+}
+.button {
+  text-align: center;
+}
+/deep/.button .el-button {
+  padding: 0.5rem 0;
+  width: 4.375rem;
+}
+/deep/.w-e-toolbar .w-e-menu {
+  padding: 0.3125rem 0.125rem;
+}
+</style>

+ 131 - 0
src/pages/corp/views/resume/index.vue

@@ -0,0 +1,131 @@
+<template>
+  <div id="management" style="background:#fff;">
+    <el-row>
+      <el-tabs v-model="activeName" class="tabs" stretch>
+        <el-tab-pane label="简历夹" name="first">
+          <list-index :dataList="firstList" :hasMore="firstHasMore" @changeStatus="changeStatus" @search="search" type="0"></list-index>
+        </el-tab-pane>
+        <!-- <el-tab-pane label="面试夹" name="second">
+          <el-col :span="24" class="search">
+            <el-input placeholder="请输入候选人姓名或手机" prefix-icon="el-icon-search" v-model="input"> </el-input>
+          </el-col>
+          <el-col :span="24" class="tabs1">
+            <el-tabs v-model="activeName1" @tab-click="handleClick1">
+              <el-tab-pane label="全部" name="first">
+                全部
+              </el-tab-pane>
+              <el-tab-pane label="1轮" name="second">
+                未查看
+              </el-tab-pane>
+              <el-tab-pane label="2轮" name="third">
+                已查看
+              </el-tab-pane>
+              <el-tab-pane label="3轮及以上" name="fourth">
+                不合格
+              </el-tab-pane>
+            </el-tabs>
+          </el-col>
+          <el-col :span="24" class="down">
+            <el-col :span="10" class="downLeft">
+              <el-col :span="8"><el-button class="downBtn">全选</el-button></el-col>
+              <el-col :span="16">
+                <p class="text">合计0人</p>
+                <p class="text">合计0人</p>
+              </el-col>
+            </el-col>
+            <el-col :span="9" class="downCenter">
+              <el-col :span="12"><el-button class="downBtn" style="background: cornflowerblue;">复试</el-button></el-col>
+              <el-col :span="12"><el-button class="downBtn">录用</el-button></el-col>
+            </el-col>
+            <el-col :span="5" class="downRight">
+              <el-button class="downBtn">通知</el-button>
+            </el-col>
+          </el-col>
+        </el-tab-pane> -->
+        <el-tab-pane label="录用夹" name="third">
+          <list-index :dataList="secondList" :hasMore="secondHasMore" @changeStatus="changeStatus" @search="search" type="1"></list-index>
+        </el-tab-pane>
+      </el-tabs>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import listIndex from './list-index.vue';
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'management',
+  props: {},
+  components: {
+    listIndex,
+  },
+  data: () => ({
+    activeName: 'first',
+    firstList: [],
+    firstTotalRow: 0,
+    firstHasMore: true,
+    secondList: [],
+    secondTotalRow: 0,
+    secondHasMore: true,
+  }),
+  created() {
+    this.search({ type: '0', studname: undefined });
+    this.search({ type: '1', studname: undefined });
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['lettersOperation']),
+    async search({ type, studname }) {
+      let listName = type === '0' ? 'first' : 'seconde';
+      let result = this.lettersOperation({
+        type: 'list',
+        data: { post_id: this.$route.query.id, status: type, studname: studname === '' ? undefined : studname },
+      });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `${listName}List`, result.data);
+        this.$set(this, `${listName}TotalRow`, result.total);
+        this.$set(this, `${listName}HasMore`, false);
+      }
+    },
+    async changeStatus({ id, status }) {
+      let result;
+      if (typeof id === 'string') {
+        result = await this.lettersOperation({ type: 'update', data: { id: this.user.corpid, status: status } });
+      } else {
+        id.map(async item => {
+          result = await this.lettersOperation({ type: 'update', data: { id: item, status: status } });
+          if (`${result.errcode}` !== '0') {
+            this.$message.error(result.errmsg || 'error');
+          }
+        });
+      }
+      if (`${result.errcode}` === '0') {
+        this.$message.success('操作完成');
+      } else {
+        this.$message.error(result.errmsg || 'error');
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.tabs .el-tabs__header {
+  margin: 0;
+}
+/deep/.tabs .el-tabs__nav {
+  width: 100%;
+}
+/deep/.tabs .el-tabs__item {
+  width: 33%;
+  text-align: center;
+}
+/deep/.tabs1 .el-tabs__item {
+  width: 25%;
+  text-align: center;
+}
+</style>

+ 136 - 0
src/pages/corp/views/resume/list-index.vue

@@ -0,0 +1,136 @@
+<template>
+  <div id="list-index">
+    <el-row style="background:#ccc;" type="flex" align="middle" justify="center">
+      <el-col :span="20" class="search">
+        <el-input placeholder="请输入候选人姓名或手机" prefix-icon="el-icon-search" v-model="input"> </el-input>
+      </el-col>
+      <el-col :span="4" class="search" style="height:3.125rem;">
+        <el-button type="text" style="padding-top: 1.125rem;padding-left: 0.625rem;font-size: 1rem;" @click="toSearch()">搜索</el-button>
+      </el-col>
+    </el-row>
+    <el-col :span="24" class="tabs1">
+      <el-tabs v-model="activeName1">
+        <el-tab-pane label="学生简历" name="first">
+          <list ref="childList" :dataList="dataList" :hasMore="hasMore" :type="type" v-on="$listeners" @selected="selected"></list>
+        </el-tab-pane>
+      </el-tabs>
+    </el-col>
+    <el-col :span="24" class="down">
+      <el-col :span="10" class="downLeft">
+        <el-col :span="8">
+          <el-button class="downBtn" @click="toAllSelect()">全选</el-button>
+        </el-col>
+        <el-col :span="16">
+          <p class="text">合计{{ checked.length }}人</p>
+          <p class="text">总计{{ dataList.length }}人</p>
+        </el-col>
+      </el-col>
+      <el-col :span="9" class="downCenter">
+        <el-button class="downBtn" @click="changeStatus('1')">合格</el-button>
+      </el-col>
+      <el-col :span="5" class="downRight">
+        <el-button class="downBtn">通知</el-button>
+      </el-col>
+    </el-col>
+  </div>
+</template>
+
+<script>
+import deleteDig from '@m/components/delete-dig.vue';
+import list from './list.vue';
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'list-index',
+  props: {
+    dataList: { type: Array, default: () => [] },
+    hasMore: { type: Boolean, default: true },
+    type: { type: String, default: '' },
+  },
+  components: {
+    list,
+  },
+  data: () => ({
+    loading: false,
+    activeName1: 'first',
+    input: '',
+    checked: [],
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    toAllSelect() {
+      this.$refs.childList.allSelect();
+    },
+    selected(ids) {
+      this.$set(this, `checked`, ids);
+    },
+    toSearch() {
+      this.$emit('search', { type: this.type, studname: this.input === '' ? undefined : this.input });
+    },
+    changeStatus(status) {
+      this.$emit('changeStatus', { id: this.checked, status: status });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.tabs .el-tabs__header {
+  margin: 0;
+}
+/deep/.tabs .el-tabs__nav {
+  width: 100%;
+}
+/deep/.tabs .el-tabs__item {
+  width: 33%;
+  text-align: center;
+}
+/deep/.tabs1 .el-tabs__item {
+  width: 25%;
+  text-align: center;
+}
+.search {
+  background: #ccc;
+}
+.search .el-input {
+  width: 95%;
+  padding: 0.625rem;
+}
+/deep/.search .el-input__inner {
+  height: 1.875rem;
+}
+.down {
+  height: 2.5rem;
+  background: #fff;
+  position: fixed;
+  bottom: 0;
+  text-align: center;
+  line-height: 2.5rem;
+  color: #fff;
+}
+.downLeft {
+  height: 2.5rem;
+  background: #666;
+}
+.downCenter {
+  height: 2.5rem;
+  background: royalblue;
+}
+.downRight {
+  height: 2.5rem;
+  background: springgreen;
+}
+.text {
+  height: 1.25rem;
+  line-height: 1.25rem;
+  font-size: 0.875rem;
+  margin: 0;
+  padding: 0;
+}
+.downBtn {
+  background: transparent;
+  border: transparent;
+  color: #fff;
+  font-size: 1.125rem;
+}
+</style>

+ 101 - 0
src/pages/corp/views/resume/list.vue

@@ -0,0 +1,101 @@
+<template>
+  <div id="list">
+    <span v-if="!dataList.length > 0">
+      <el-row class="main" v-for="(item, index) in tags" :key="index">
+        <el-col :span="2" class="mainChe">
+          <el-checkbox-group v-model="checked" @change="toSelect">
+            <el-checkbox :label="item.id">&nbsp;</el-checkbox>
+          </el-checkbox-group>
+        </el-col>
+        <el-col :span="5" class="mainImg">
+          <el-image style="width: 3.75rem; height: 3.75rem" :src="item.url"></el-image>
+        </el-col>
+        <el-col :span="17" class="mainTit">
+          <p>{{ item.name }}</p>
+          <p style="font-size:.875rem;color:#666;">投递时间{{ item.time }}</p>
+          <p style="font-size:.875rem;color:#666;">最近通知 {{ item.tongzhi }}</p>
+        </el-col>
+      </el-row>
+    </span>
+    <el-row v-else>
+      <el-col :span="24" class="main" style="font-size:1.5rem; line-height:1.5rem;color:#999;text-align:center;">
+        暂无数据
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'list',
+  props: {
+    dataList: { type: Array, default: () => [] },
+    hasMore: { type: Boolean, default: true },
+    type: { type: String, default: '' },
+  },
+  components: {},
+  data: () => ({
+    currentPage: 1,
+    checked: [],
+    tags: [
+      {
+        id: 1,
+        url: '',
+        name: '刘琪',
+        time: '7月8日7:26',
+        tongzhi: '无',
+      },
+    ],
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    loadMore() {
+      console.log('is all');
+    },
+    allSelect() {
+      if (this.dataList.length !== this.checked.length) {
+        let selected = this.dataList.map(item => item.id);
+        this.$set(this, `checked`, selected);
+      } else {
+        this.$set(this, `checked`, []);
+      }
+      this.toSelect();
+    },
+    toSelect() {
+      this.$emit('selected', this.checked);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+p {
+  margin: 0;
+  padding: 0;
+}
+.main {
+  height: 5.625rem;
+  border-bottom: 0.0625rem solid #ccc;
+}
+.mainChe {
+  text-align: center;
+  line-height: 5.625rem;
+}
+.mainChe .el-checkbox {
+  height: 0.9375rem;
+  line-height: 0.9375rem;
+}
+.mainImg {
+  height: 5.625rem;
+  text-align: center;
+  padding: 0.9375rem 0;
+}
+.mainTit {
+  height: 5.625rem;
+  text-align: left;
+}
+.mainTit p {
+  padding: 0.3125rem 0 0.1875rem 0;
+}
+</style>

+ 274 - 0
src/pages/corp/views/resume/management.vue

@@ -0,0 +1,274 @@
+<template>
+  <div id="management">
+    <el-row>
+      <el-tabs v-model="activeName" @tab-click="handleClick" class="tabs" stretch>
+        <el-tab-pane label="简历夹" name="first">
+          <el-col :span="24" class="search">
+            <el-input placeholder="请输入候选人姓名或手机" prefix-icon="el-icon-search" v-model="input"> </el-input>
+          </el-col>
+          <el-col :span="24" class="tabs1">
+            <el-tabs v-model="activeName1" @tab-click="handleClick1">
+              <el-tab-pane label="全部" name="first">
+                <el-row class="main" v-for="(tag, index) in tags" :key="index" :type="tag.type">
+                  <el-col :span="2" class="mainChe">
+                    <el-checkbox v-model="checked"></el-checkbox>
+                  </el-col>
+                  <el-col :span="5" class="mainImg">
+                    <el-image style="width: 3.75rem; height: 3.75rem" :src="tag.url"></el-image>
+                  </el-col>
+                  <el-col :span="17" class="mainTit">
+                    <p>{{ tag.name }}</p>
+                    <p style="font-size:14px;color:#666;">投递时间{{ tag.time }}</p>
+                    <p style="font-size:14px;color:#666;">最近通知 {{ tag.tongzhi }}</p>
+                  </el-col>
+                </el-row>
+              </el-tab-pane>
+              <el-tab-pane label="未查看" name="second">
+                未查看
+              </el-tab-pane>
+              <el-tab-pane label="已查看" name="third">
+                已查看
+              </el-tab-pane>
+              <el-tab-pane label="不合格" name="fourth">
+                不合格
+              </el-tab-pane>
+            </el-tabs>
+          </el-col>
+          <el-col :span="24" class="down">
+            <el-col :span="10" class="downLeft">
+              <el-col :span="8"><el-button class="downBtn">全选</el-button></el-col>
+              <el-col :span="16">
+                <p class="text">合计0人</p>
+                <p class="text">合计0人</p>
+              </el-col>
+            </el-col>
+            <el-col :span="9" class="downCenter">
+              <el-button class="downBtn">合格</el-button>
+            </el-col>
+            <el-col :span="5" class="downRight">
+              <el-button class="downBtn">通知</el-button>
+            </el-col>
+          </el-col>
+        </el-tab-pane>
+        <!-- <el-tab-pane label="面试夹" name="second">
+          <el-col :span="24" class="search">
+            <el-input placeholder="请输入候选人姓名或手机" prefix-icon="el-icon-search" v-model="input"> </el-input>
+          </el-col>
+          <el-col :span="24" class="tabs1">
+            <el-tabs v-model="activeName1" @tab-click="handleClick1">
+              <el-tab-pane label="全部" name="first">
+                全部
+              </el-tab-pane>
+              <el-tab-pane label="1轮" name="second">
+                未查看
+              </el-tab-pane>
+              <el-tab-pane label="2轮" name="third">
+                已查看
+              </el-tab-pane>
+              <el-tab-pane label="3轮及以上" name="fourth">
+                不合格
+              </el-tab-pane>
+            </el-tabs>
+          </el-col>
+          <el-col :span="24" class="down">
+            <el-col :span="10" class="downLeft">
+              <el-col :span="8"><el-button class="downBtn">全选</el-button></el-col>
+              <el-col :span="16">
+                <p class="text">合计0人</p>
+                <p class="text">合计0人</p>
+              </el-col>
+            </el-col>
+            <el-col :span="9" class="downCenter">
+              <el-col :span="12"><el-button class="downBtn" style="background: cornflowerblue;">复试</el-button></el-col>
+              <el-col :span="12"><el-button class="downBtn">录用</el-button></el-col>
+            </el-col>
+            <el-col :span="5" class="downRight">
+              <el-button class="downBtn">通知</el-button>
+            </el-col>
+          </el-col>
+        </el-tab-pane> -->
+        <el-tab-pane label="录用夹" name="third">
+          <el-col :span="24" class="search">
+            <el-input placeholder="请输入候选人姓名或手机" prefix-icon="el-icon-search" v-model="input"> </el-input>
+          </el-col>
+          <el-col :span="24" class="tabs1">
+            <el-tabs v-model="activeName1" @tab-click="handleClick1">
+              <el-tab-pane label="全部" name="first">
+                全部
+              </el-tab-pane>
+              <el-tab-pane label="未明确" name="second">
+                未明确
+              </el-tab-pane>
+              <el-tab-pane label="明确录用" name="third">
+                明确录用
+              </el-tab-pane>
+            </el-tabs>
+          </el-col>
+          <el-col :span="24" class="down">
+            <el-col :span="10" class="downLeft">
+              <el-col :span="8"><el-button class="downBtn">全选</el-button></el-col>
+              <el-col :span="16">
+                <p class="text">合计0人</p>
+                <p class="text">合计0人</p>
+              </el-col>
+            </el-col>
+            <el-col :span="9" class="downCenter">
+              <el-button class="downBtn">确定录用</el-button>
+            </el-col>
+            <el-col :span="5" class="downRight">
+              <el-button class="downBtn">通知</el-button>
+            </el-col>
+          </el-col>
+        </el-tab-pane>
+      </el-tabs>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'management',
+  props: {},
+  components: {},
+  data: () => ({
+    activeName: 'first',
+    activeName1: 'first',
+    input: '',
+    checked: '',
+    checked1: '',
+    checked2: '',
+    checked3: '',
+    tags: [
+      {
+        url: '',
+        name: '刘琪',
+        time: '7月8日7:26',
+        tongzhi: '无',
+      },
+    ],
+    tags1: [
+      {
+        url: '',
+        name: '你好',
+        time: '7月8日7:26',
+        tongzhi: '无',
+      },
+    ],
+    tags2: [
+      {
+        url: '',
+        name: '你好好',
+        time: '7月8日7:26',
+        tongzhi: '无',
+      },
+    ],
+    tags3: [
+      {
+        url: '',
+        name: '你好好好',
+        time: '7月8日7:26',
+        tongzhi: '无',
+      },
+    ],
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    handleClick(tab, event) {
+      console.log(tab, event);
+    },
+    handleClick1(tab, event) {
+      console.log(tab, event);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+p {
+  margin: 0;
+  padding: 0;
+}
+/deep/.tabs .el-tabs__header {
+  margin: 0;
+}
+/deep/.tabs .el-tabs__nav {
+  width: 100%;
+}
+/deep/.tabs .el-tabs__item {
+  width: 33%;
+  text-align: center;
+}
+/deep/.tabs1 .el-tabs__item {
+  width: 25%;
+  text-align: center;
+}
+.search {
+  background: #ccc;
+}
+.search .el-input {
+  width: 95%;
+  padding: 0.625rem;
+}
+/deep/.search .el-input__inner {
+  height: 1.875rem;
+}
+.main {
+  height: 5.625rem;
+  border-bottom: 0.0625rem solid #ccc;
+}
+.mainChe {
+  text-align: center;
+  line-height: 5.625rem;
+}
+.mainChe .el-checkbox {
+  height: 0.9375rem;
+  line-height: 0.9375rem;
+}
+.mainImg {
+  height: 5.625rem;
+  text-align: center;
+  padding: 0.9375rem 0;
+}
+.mainTit {
+  height: 5.625rem;
+  text-align: left;
+}
+.mainTit p {
+  padding: 0.3125rem 0 0.1875rem 0;
+}
+.down {
+  height: 2.5rem;
+  background: #fff;
+  position: fixed;
+  bottom: 0;
+  text-align: center;
+  line-height: 2.5rem;
+  color: #fff;
+}
+.downLeft {
+  height: 2.5rem;
+  background: #666;
+}
+.downCenter {
+  height: 2.5rem;
+  background: royalblue;
+}
+.downRight {
+  height: 2.5rem;
+  background: springgreen;
+}
+.text {
+  height: 1.25rem;
+  line-height: 20px;
+  font-size: 14px;
+  margin: 0;
+  padding: 0;
+}
+.downBtn {
+  background: transparent;
+  border: transparent;
+  color: #fff;
+  font-size: 18px;
+}
+</style>

+ 127 - 0
src/pages/corp/views/source/index.vue

@@ -0,0 +1,127 @@
+<template>
+  <div id="index" style="background:#fff;">
+    <el-row>
+      <el-col :span="24" class="search">
+        <el-col :span="20" class="searchInput"> <el-input placeholder="请输入你要搜索的内容" prefix-icon="el-icon-search" v-model="input"> </el-input></el-col>
+        <el-col :span="4" class="searchBtn"><el-button>搜索</el-button></el-col>
+      </el-col>
+      <el-col :span="24" style="position: relative;top:3.125rem;">
+        <el-tabs v-model="active" @tab-click="handleClick">
+          <el-tab-pane name="fir">
+            <span slot="label">华中<br />114008</span>
+            <list :data="list" :hasMore="listHasMore" @search="search"></list>
+          </el-tab-pane>
+          <el-tab-pane name="sec">
+            <span slot="label">华南<br />114008</span>
+            <list :data="list" :hasMore="listHasMore" @search="search"></list>
+          </el-tab-pane>
+          <el-tab-pane name="thr">
+            <span slot="label">华东<br />114008</span>
+            <list :data="list" :hasMore="listHasMore" @search="search"></list>
+          </el-tab-pane>
+          <el-tab-pane name="for">
+            <span slot="label">华北<br />114008</span>
+            <list :data="list" :hasMore="listHasMore" @search="search"></list>
+          </el-tab-pane>
+          <el-tab-pane name="fiv">
+            <span slot="label">西南<br />114008</span>
+            <list :data="list" :hasMore="listHasMore" @search="search"></list>
+          </el-tab-pane>
+          <el-tab-pane name="six">
+            <span slot="label">西北<br />114008</span>
+            <list :data="list" :hasMore="listHasMore" @search="search"></list>
+          </el-tab-pane>
+          <el-tab-pane name="sev">
+            <span slot="label">东北<br />114008</span>
+            <list :data="list" :hasMore="listHasMore" @search="search"></list>
+          </el-tab-pane>
+        </el-tabs>
+      </el-col>
+    </el-row>
+    <nut-backtop :distance="200" @click="onClick" :bottom="20" :right="0" :zIndex="10" :duration="1000">
+      <i class="el-icon-upload2" style="font-size:40px;color:#666;"></i>
+    </nut-backtop>
+  </div>
+</template>
+
+<script>
+import list from './list.vue';
+import _ from 'lodash';
+import { mapActions, mapState } from 'vuex';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    list,
+  },
+  data: () => ({
+    input: '',
+    active: 'fir',
+    list: [],
+    listTotalRow: 0,
+    listHasMore: true,
+  }),
+  created() {
+    this.search();
+  },
+  computed: {},
+  methods: {
+    ...mapActions(['getList']),
+    async search() {
+      if (this.list.length === 0) {
+        this.getDataList('fir');
+      } else {
+        this.getDataList(this.active);
+      }
+    },
+    async getDataList(type) {
+      let { result, totalRow } = await this.getList('school');
+      let data = _.get(this, `list`).concat(result);
+      this.$set(this, `list`, data);
+      this.$set(this, `listTotalRow`, totalRow);
+      if (_.get(this, `list`).length >= _.get(this, `listTotalRow`)) {
+        this.$set(this, `listHasMore`, false);
+      }
+    },
+    handleClick(tab, event) {
+      console.log(tab, event);
+    },
+    changeStatus() {
+      this.btnStatus = this.btnStatus === 0 ? 1 : 0;
+    },
+    onClick() {
+      console.log('触发回到顶部按钮');
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+p {
+  margin: 0;
+  padding: 0;
+}
+.search {
+  border-bottom: 0.0625rem solid #ccc;
+  position: fixed;
+  top: 0;
+  background: #fff;
+  z-index: 999;
+}
+.searchInput {
+  padding: 0.3125rem 0.625rem;
+}
+.searchBtn {
+  padding: 0.3125rem 0;
+}
+.searchBtn .el-button {
+  border: none;
+}
+/deep/.el-tabs__item {
+  line-height: 1.25rem;
+  text-align: center;
+}
+/deep/.el-tabs__header {
+  margin: 0;
+}
+</style>

+ 94 - 0
src/pages/corp/views/source/list.vue

@@ -0,0 +1,94 @@
+<template>
+  <div id="list">
+    <nut-scroller
+      :is-un-more="!hasMore"
+      :is-loading="loading"
+      :type="'vertical'"
+      @loadMore="loadMore"
+      :threshold="200"
+      pulldownTxt="向下滚动查看更多信息"
+      unloadMoreTxt="没有更多信息啦"
+      style="height:100vh;"
+    >
+      <template v-slot:list>
+        <el-row class="main" v-for="(item, index) in data" :key="index" type="flex">
+          <el-col :span="3" class="img"><el-image :src="item.url"></el-image></el-col>
+          <el-col :span="17" class="txt">
+            <p class="txtName">{{ item.name }}</p>
+            <p class="txtTit">
+              <span class="addres">{{ item.addres }}</span>
+              <span class="num">{{ item.num }}</span>
+            </p>
+          </el-col>
+          <el-col :span="4" class="btn">
+            <el-button type="primary" round @click="changeStatus(item.id)" v-show="item.btnStatus == 0">关注</el-button>
+            <el-button type="info" round @click="changeStatus(item.id)" v-show="item.btnStatus == 1">已关注</el-button>
+          </el-col>
+        </el-row>
+      </template>
+    </nut-scroller>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'list',
+  props: {
+    data: { type: Array, default: () => [] },
+    type: { type: String, default: 'jobs' },
+    hasMore: { type: Boolean, default: true },
+    height: { type: String },
+  },
+  components: {},
+  data: () => ({
+    loading: false,
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    loadMore() {
+      this.loading = true;
+      this.$emit('search');
+      this.loading = false;
+    },
+    changeStatus(item) {
+      //点击关注
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  padding: 0.625rem;
+  border-bottom: 0.0625rem solid #f6f6f6;
+}
+.img {
+  width: 2.5rem;
+  height: 2.5rem;
+}
+.txt {
+  padding: 0 0.625rem;
+  font-size: 0.875rem;
+  color: #333;
+}
+.txt .txtName {
+  font-size: 1rem;
+}
+.txt .txtTit {
+  color: #ccc;
+}
+.btn {
+  text-align: right;
+  padding: 0.625rem 0;
+}
+/deep/.btn .el-button {
+  width: 3.125rem;
+  height: 1.5rem;
+  padding: 0;
+}
+p {
+  margin: 0;
+  padding: 0;
+}
+</style>

+ 429 - 0
src/pages/corp/views/talk/detail.vue

@@ -0,0 +1,429 @@
+<template>
+  <div id="detail">
+    <el-form ref="form" :model="info" label-width="0" label-position="left" style="padding:0 0.5rem;" :rules="rules">
+      <form-item label="发布学校" prop="schid">
+        <el-col :span="24">
+          <drawer :data="schList" type="schid" need="value" :selected="query.schid" placeholder="请选择发布学校" @select="selectSch"></drawer>
+        </el-col>
+      </form-item>
+      <form-item label="招聘简章" prop="profile_id">
+        <el-col :span="24">
+          <drawer :data="profileList" type="profile_id" need="value" :selected="info.profile_id" placeholder="请选择招聘简章" @select="getProfile"></drawer>
+        </el-col>
+      </form-item>
+      <form-item label="宣讲标题" prop="title">
+        <el-input v-model="info.title" placeholder="请输入宣讲标题"></el-input>
+      </form-item>
+      <form-item label="招聘需求" type="info">
+        <el-button type="text" @click="dialogTableVisible = true" class="xinBtn" style="background:#fff">点击查看职位</el-button>
+      </form-item>
+
+      <form-item label="预定时间">
+        <el-button type="text" @click="datePick = true" class="xinBtn" style="background:#fff">{{ info.time ? info.time : '请选择时间' }}</el-button>
+        <nut-datepicker
+          :is-visible="datePick"
+          title="请选择预定时间"
+          :minute-step="30"
+          startHour="8"
+          endHour="21"
+          type="datetime"
+          :defaultValue="new Date().toLocaleString()"
+          :endDate="endDate"
+          @close="datePick = false"
+          @choose="dateChoose"
+        >
+        </nut-datepicker>
+        <!-- <el-date-picker v-model="info.date" type="date" placeholder="选择日期" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd"> </el-date-picker>
+        <el-select v-model="info.time" placeholder="请选择" format="yyyy-MM-dd HH:mm">
+          <el-option v-for="item in career_time_list" :key="item.career_time" :label="item.career_time" :value="item.career_time"> </el-option>
+        </el-select> -->
+      </form-item>
+
+      <form-item label="申请说明" prop="apply_desc">
+        <el-input v-model="info.apply_desc" placeholder="请填写申请说明"></el-input>
+      </form-item>
+      <form-item label="来访人数" prop="team_size">
+        <el-input v-model="info.team_size" placeholder="请填写来访人数"></el-input>
+      </form-item>
+      <form-item label="带队领导" prop="team_leader">
+        <el-input v-model="info.team_leader" placeholder="请填写带队领导"></el-input>
+      </form-item>
+      <form-item label="带队领导职务" prop="leader_position">
+        <el-input v-model="info.leader_position" placeholder="请填写带队领导职务"></el-input>
+      </form-item>
+      <form-item label="对接联系人" prop="contact_person">
+        <el-input v-model="info.contact_person" placeholder="请填写招聘对接联系人"></el-input>
+      </form-item>
+      <form-item label="对接联系人电话" prop="contact_mobile">
+        <el-input v-model="info.contact_mobile" placeholder="请填写对接联系人电话"></el-input>
+      </form-item>
+      <form-item label="地址" prop="address">
+        <el-input v-model="info.address" placeholder="请填写地址"></el-input>
+      </form-item>
+      <form-item label="招聘公函模板">
+        <el-link href="http://yun-campus-res.oss-cn-shenzhen.aliyuncs.com/yxqqnn0100000011/setting/1521077641-1574.doc" type="success">
+          关于赴高校开展招聘及相关工作函
+        </el-link>
+      </form-item>
+      <upload-file
+        :url="`/files/jobs/talk_official/upload`"
+        desc="点击上传公函,公函不能超过2MB"
+        :limit="1"
+        @upload="uploadSuccess"
+        @changeName="changeName"
+        @toRemove="toRemove"
+        type="official_letter"
+        :data="uploads.official_letter"
+      ></upload-file>
+    </el-form>
+    <el-row type="flex" justify="center">
+      <el-col :span="10" style="text-align:center;">
+        <el-button type="success" style="width:60%" @click="toSubmit()">申&nbsp;&nbsp;&nbsp;&nbsp;请</el-button>
+      </el-col>
+    </el-row>
+    <el-dialog :visible.sync="dialogTableVisible" :fullscreen="true" :show-close="false">
+      <template #title>
+        <el-row type="flex" align="middle" justify="center">
+          <el-col :span="8"><i @click="dialogTableVisible = false" class="el-icon-back" style="zoom:1.5"></i></el-col>
+          <el-col :span="8" style="font-size:1.25rem;text-align: center;">职&nbsp;&nbsp;&nbsp;&nbsp;位</el-col>
+          <el-col :span="8" style="text-align: right;"><i @click="addJob = true" class="el-icon-plus" style="zoom:1.5"></i></el-col>
+        </el-row>
+      </template>
+      <el-table :data="gridData" style="width: 100%" border>
+        <el-table-column align="center" type="expand">
+          <template v-slot="scoped">
+            <el-row>
+              <el-col :span="6">岗位名称:</el-col>
+              <el-col :span="18">{{ scoped.row.job_name }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">工作性质:</el-col>
+              <el-col :span="18">{{ `${scoped.row.is_practice}` === '0' ? '全职' : '实习' }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">学历要求:</el-col>
+              <el-col :span="18">{{ scoped.row.xl_req }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">专业要求:</el-col>
+              <el-col :span="18">{{ scoped.row.zy_req }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">薪资:</el-col>
+              <el-col :span="18">{{ scoped.row.salary.text }}</el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="6">招聘人数:</el-col>
+              <el-col :span="18">{{ scoped.row.job_number }}人</el-col>
+            </el-row>
+          </template>
+        </el-table-column>
+        <el-table-column align="center" label="岗位名称" prop="job_name"> </el-table-column>
+        <el-table-column align="center" label="操作">
+          <template slot-scope="scope">
+            <el-button size="mini" type="danger" @click="handleDelete(scope.$index, 'gridData')">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+    <el-dialog :visible.sync="addJob" append-to-body :fullscreen="true" :show-close="false">
+      <template #title>
+        <el-row type="flex" align="middle" justify="start">
+          <el-col :span="8"><i @click="addJob = false" class="el-icon-back" style="zoom:1.5"></i></el-col>
+          <el-col :span="8" style="font-size:1.25rem;">选择职位</el-col>
+          <el-col :span="8"></el-col>
+        </el-row>
+      </template>
+      <el-row v-for="(item, index) in jobList" :key="index" type="flex" justify="center" align="middle" class="jobs">
+        <el-col :span="18">
+          <el-col :span="18">{{ item.job_name }}</el-col>
+          <el-col :span="6">{{ `${item.is_practice}` === '0' ? '全职' : '实习' }}</el-col>
+          <el-col :span="24">{{ item.xl_req }}</el-col>
+          <el-col :span="24">{{ item.zy_req }}</el-col>
+          <el-col :span="18">{{ item.salary && item.salary.text }}</el-col>
+          <el-col :span="6">招聘{{ item.job_number }}人</el-col>
+        </el-col>
+        <el-col :span="6" style="text-align:center;">
+          <el-button type="primary" size="mini" icon="el-icon-plus" circle @click="addjobs(item)"></el-button>
+        </el-col>
+      </el-row>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import formItem from '@m/components/form-item.vue';
+import drawer from '@m/components/drawer.vue';
+import uploadFile from '@m/components/upload-file.vue';
+import { mapActions, mapState } from 'vuex';
+import _ from 'lodash';
+export default {
+  name: 'detail',
+  props: {},
+  components: {
+    drawer,
+    formItem,
+    uploadFile,
+  },
+  data: () => ({
+    info: {},
+    uploads: {},
+    profileList: [],
+    jobList: [],
+    OrJobList: [],
+    schList: [],
+    query: {},
+    datePick: false,
+    endDate: `${new Date().getFullYear() + 1}-${new Date().getMonth() + 1}-${new Date().getDate()}`,
+    rules: {
+      apply_desc: [{ required: true, message: '请填写申请说明', trigger: 'blur' }],
+      mobile: [{ required: true, message: '请输入手机号', trigger: 'blur' }, { min: 11, max: 11, message: '请输入11位手机号码', trigger: 'blur' }],
+    },
+    school_list: [
+      { school_id: '1251', school_name: '长春工业大学1' },
+      { school_id: '1252', school_name: '长春工业大学2' },
+      { school_id: '1253', school_name: '长春工业大学3' },
+    ],
+    career_time_list: [
+      { career_time: '08:30-10:00' },
+      { career_time: '10:30-12:00' },
+      { career_time: '13:00-14:30' },
+      { career_time: '15:00-16:30' },
+      { career_time: '18:00-20:30' },
+    ],
+    dialogTableVisible: false,
+    addJob: false,
+    gridData: [],
+    loading: true,
+  }),
+  created() {
+    this.$set(this.info, `title`, JSON.parse(JSON.stringify(this.user.corpname)));
+    this.getProfileList();
+    this.getJobsList();
+    this.getSchList();
+    this.search();
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['profilesOperation', 'talksOperation', 'postsOperation', 'corpSchInfo']),
+    async search() {
+      if (this.$route.query.id) {
+        this.$set(this, `loading`, false);
+        let result = await this.talksOperation({ type: 'search', data: { id: this.$route.query.id } });
+        this.$set(this, `info`, result.data);
+        this.$set(this.uploads, `official_letter`, this.info.official_letter);
+        this.$set(this, `gridData`, result.data.jobs);
+        this.$set(this, `loading`, true);
+        this.resetJobList();
+      }
+    },
+    async toSubmit() {
+      let result;
+      let data = JSON.parse(JSON.stringify(this.info));
+      let letter = JSON.parse(JSON.stringify(this.uploads));
+      let jobsIdList = this.gridData.map(item => item.id);
+      data.jobs = jobsIdList;
+      data.official_letter = letter.official_letter;
+      if (this.info.id) {
+        result = await this.talksOperation({ type: 'update', data: { info: data, id: this.$route.query.id } });
+      } else {
+        result = await this.talksOperation({
+          type: 'add',
+          data: { info: data, corpid: this.user.corpid, corpname: this.user.corpname, ...this.query },
+        });
+      }
+      if (`${result.errcode}` === '0') {
+        this.$message.success('操作成功');
+        this.$router.push('/talk/index');
+      } else {
+        this.$message.error(result.errmsg);
+      }
+    },
+    addjobs(item) {
+      let data = JSON.parse(JSON.stringify(item));
+      this.gridData.push(data);
+      this.resetJobList();
+      // this.$message('已添加');
+      this.$notify({
+        message: '已添加',
+        type: 'success',
+        duration: 1000,
+        showClose: false,
+      });
+    },
+    handleDelete(index, type) {
+      let arr = _.get(this, `${type}`);
+      arr.splice(index, 1);
+      this.resetJobList();
+    },
+    //职位列表
+    async getJobsList() {
+      let result = await this.postsOperation({ type: 'list', data: { corpid: this.user.corpid } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `jobList`, result.data);
+        this.$set(this, `OrJobList`, result.data);
+        this.resetJobList();
+      }
+    },
+    //重置职位列表
+    async resetJobList() {
+      let data = JSON.parse(JSON.stringify(this.OrJobList));
+      let selectList = [];
+      let chooseList = [];
+      if (this.gridData.length > 0) {
+        this.gridData.map(item => {
+          let val = typeof item === 'object' ? item.id : item;
+          let selected = _.find(data, select => select.id === val);
+          selectList.push(selected);
+        });
+        // chooseList = _.differenceBy(data, selectList, 'id');
+        chooseList = _.differenceWith(data, selectList, (item, value) => {
+          return item.id === value.id;
+        });
+      } else {
+        chooseList = data;
+      }
+
+      this.$set(this, `jobList`, chooseList);
+    },
+    // 招聘简章
+    async getProfileList() {
+      let result = await this.profilesOperation({ type: 'list', data: { corpid: this.user.corpid } });
+      if (`${result.errcode}` === '0') {
+        //给this=>vue的实例下在中的list属性,赋予result。data的值
+        let arr = result.data.map(item => {
+          let object = { label: item.title, value: item.id };
+          return object;
+        });
+        this.$set(this, `profileList`, arr); //result.data
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+    async getProfile({ type, value }) {
+      let checkType = type.split('.');
+      if (checkType.length < 2) {
+        this.$set(this.info, type, value);
+        let result = await this.profilesOperation({ type: 'search', data: { id: this.info.profile_id } });
+        if (`${result.errcode}` === `0`) {
+          this.$set(this.info, `content`, result.data.content);
+        }
+      } else {
+        this.$set(_.get(this, checkType[0]), `${checkType[1]}`, value);
+      }
+    },
+    async getSchList() {
+      let result = await await this.corpSchInfo({ type: 'list', data: { corpid: this.user.corpid } });
+      if (`${result.errcode}` === '0') {
+        let arr = result.data.map(item => {
+          let object = {};
+          object.label = item.schname;
+          object.value = item.schid;
+          return object;
+        });
+        this.$set(this, `schList`, arr);
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : 'error');
+      }
+    },
+    selectSch({ type, value }) {
+      let res = this.schList.filter(item => {
+        return `${item.value}` === `${value}`;
+      });
+      if (res.length > 0) {
+        this.$set(this.query, `schid`, value);
+        this.$set(this.query, `schname`, res[0].label);
+      }
+    },
+    dateChoose(date) {
+      this.$set(this.info, `date`, `${date[0]}-${date[1]}-${date[2]}`);
+      this.$set(this.info, `time`, date[5]);
+    },
+    uploadSuccess({ type, data }) {
+      if (type !== 'avatar_url') {
+        let arr = _.get(this.uploads, type);
+        if (arr !== undefined) {
+          if (type === 'official_letter') {
+            this.$set(this.uploads, `${type}`, { name: data.name, uri: data.uri });
+          } else {
+            this.uploads[type].push({ name: data.name, uri: data.uri });
+          }
+        } else {
+          if (type === 'official_letter') {
+            this.$set(this.uploads, `${type}`, { name: data.name, uri: data.uri });
+          } else {
+            let newArr = [{ name: data.name, uri: data.uri }];
+            this.$set(this.uploads, `${type}`, newArr);
+          }
+        }
+      } else {
+        this.$set(this.info, `${type}`, data.uri);
+      }
+      if (this.info.id) {
+        this.toSubmit();
+      }
+    },
+    changeName({ type, data }) {
+      let newObject = { name: data.name, uri: `${data.url}` };
+      this.$set(this.uploads, `official_letter`, newObject);
+      if (this.info.id) {
+        this.toSubmit();
+      }
+    },
+    toRemove({ type, data }) {
+      if (type !== 'avatar_url') {
+        let arr = _.get(this.uploads, type);
+        if (arr !== undefined && typeof arr === 'object' && arr.length > 0) {
+          let newArr = arr.filter(item => item.uri !== data.url);
+          this.$set(this.uploads, `${type}`, newArr);
+        }
+        if (this.info.id) {
+          this.toSubmit();
+        }
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.style {
+  font-size: 14px;
+  padding: 0 10px;
+  border-top: 1px solid #e4e7ed;
+}
+/deep/.xinBtn {
+  border: 1px solid #ccc;
+  border-radius: 4px;
+  text-align: center;
+  color: #606266;
+  width: 100%;
+}
+/deep/.el-upload-dragger {
+  width: 310px;
+}
+/deep/.el-dialog {
+  margin: 0;
+  width: 100%;
+}
+/deep/.el-date-editor.el-input {
+  width: 11.5rem;
+}
+/deep/.el-select {
+  width: 7.875rem;
+}
+/deep/.el-drawer.btt {
+  bottom: 19.1875rem !important;
+}
+/deep/.w-e-toolbar .w-e-menu {
+  padding: 0.3125rem 0.125rem;
+}
+.jobs {
+  padding: 0.5rem 1rem;
+  border-bottom: 0.0625rem solid #cccccc;
+}
+</style>

+ 103 - 0
src/pages/corp/views/talk/index.vue

@@ -0,0 +1,103 @@
+<template>
+  <div id="index" style="background:#fff;">
+    <scroll :hasMore="hasMore" @loadMore="search" v-if="list.length > 0">
+      <el-row v-for="(item, index) in list" :key="index" type="flex" align="middle" justify="center" class="row">
+        <el-col :span="21" @click.native="$router.push({ path: '/talk/detail', query: { id: item.id } })">
+          <el-col :span="24">{{ item.title }}</el-col>
+          <el-col :span="24">地址:{{ item.address }}</el-col>
+          <el-col :span="24">时间:{{ item.time }}</el-col>
+          <el-col :span="24">
+            状态:
+            <span :style="`color:${item.status === '0' ? '#666' : item.status === '1' ? '#67C23A' : '#F56C6C'}`">
+              {{ `${item.status}` === '0' ? '未审核' : `${item.status}` === '1' ? '审核通过' : '审核失败' }}
+            </span>
+          </el-col>
+        </el-col>
+        <el-col :span="2"><delete-dig :id="item.id" @delete="toDelete"></delete-dig></el-col>
+      </el-row>
+    </scroll>
+    <nodata v-else></nodata>
+    <el-row class="addBtn" type="flex" justify="end">
+      <el-button circle type="primary" icon="el-icon-plus" @click="$router.push({ path: '/talk/detail' })"></el-button>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import scroll from '@m/layout/scroll.vue';
+import nodata from '@m/components/nodata.vue';
+import deleteDig from '@m/components/delete-dig.vue';
+import _ from 'lodash';
+import { mapActions, mapState, mapMutations } from 'vuex';
+export default {
+  name: 'index',
+  props: {},
+  components: {
+    scroll,
+    deleteDig,
+    nodata,
+  },
+  data: () => ({
+    list: [],
+    totalRow: 10,
+    hasMore: true,
+    currentPage: 1,
+  }),
+  created() {
+    this.search();
+  },
+  computed: {
+    ...mapState({
+      user: state => state.user.user,
+    }),
+  },
+  methods: {
+    ...mapActions(['talksOperation']),
+    async search(type) {
+      let skip = 0;
+      //判断下type,如果type存在.当前页加一
+      if (type && type === 'nextPage') {
+        this.currentPage++; //当前页加一
+        skip = (this.currentPage - 1) * this.$limit; //重新计算skip:即计算数据库开始查询的位置
+      }
+      if (!this.hasMore) return false; //判断的是:如果我列表的数据条数大于等于数据库返回给我的总数时=>我就不查了.没数据了
+      this.$set(this, `hasMore`, false); //控制无限加载瞬间加载N次的情况
+      let result = await this.talksOperation({ type: 'list', data: { is_practice: this.activeName === 'submit' ? 0 : 1, corpid: this.user.corpid } });
+      if (`${result.errcode}` === '0') {
+        this.$set(this, `list`, skip === 0 ? result.data : this.list.concat(result.data));
+        this.$set(this, `totalRow`, result.total);
+        this.$set(this, `hasMore`, this.list.length < this.totalRow); //此处是根据数据库总数的结果和当前列表的总条数比较,看看是否可以继续请求数据
+      }
+    },
+    async toDelete(id) {
+      let result = await this.talksOperation({ type: 'delete', data: { id: id } });
+      if (`${result.errcode}` === '0') {
+        this.$message.success('删除成功');
+        this.$set(this, `hasMore`, true);
+        this.search();
+      } else {
+        this.$message.error(result.errmsg ? result.errmsg : '删除失败');
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.addBtn {
+  position: fixed;
+  bottom: 8rem;
+  right: 1rem;
+}
+.row {
+  border-bottom: 0.0625rem solid #999;
+  .el-col {
+    .el-col:first-child {
+      padding-top: 0.125rem;
+    }
+    .el-col {
+      padding-bottom: 0.625rem;
+    }
+  }
+}
+</style>

+ 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);

+ 6 - 0
src/plugins/element.js

@@ -0,0 +1,6 @@
+import Vue from 'vue';
+import Element from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+import '@/style/element.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);

+ 29 - 0
src/plugins/methods.js

@@ -0,0 +1,29 @@
+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.prototype.$checkUser = () => {
+      let user = JSON.parse(sessionStorage.getItem('user'));
+      return typeof user === 'object';
+    };
+  },
+};
+
+Vue.use(Plugin);

+ 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 = 15;
+  },
+};
+
+Vue.use(Plugin);

+ 3 - 0
src/style/element.css

@@ -0,0 +1,3 @@
+.el-dialog__body {
+  padding: 0;
+}

+ 7 - 0
src/style/nutui.css

@@ -0,0 +1,7 @@
+.load-more{
+  background: #ccc;
+}
+.tips-txt {
+  font-size: 1rem;
+  color: #1e1e21;
+}

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

@@ -0,0 +1,133 @@
+/* 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);
+    }
+    currentRequests += 1;
+    // Indicator.open({
+    //   spinnerType: 'fading-circle',
+    // });
+
+    try {
+      const axios = Axios.create({
+        baseURL: this.baseUrl,
+      });
+      if (sessionStorage.getItem('token')) {
+        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;

+ 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));
+  },
+};

+ 53 - 0
vue.config.js

@@ -0,0 +1,53 @@
+const path = require('path');
+const mobileSrc = path.resolve(__dirname, '../web-mobile/src');
+
+module.exports = {
+  publicPath: './',
+  pages: {
+    index: 'src/pages/corp/main.js',
+  },
+  configureWebpack: config => {
+    Object.assign(config, {
+      // 开发生产共同配置
+      resolve: {
+        alias: {
+          '@': path.resolve(__dirname, './src'),
+          '@c': path.resolve(__dirname, './src/components'),
+          '@a': path.resolve(__dirname, './src/assets'),
+          '@m': mobileSrc,
+        },
+      },
+    });
+  },
+  // css: {
+  //   loaderOptions: {
+  //     css: {
+  //       data: `@import "./src/style/nutui.css";@import "@nutui/nutui/dist/styles/index.css";`,
+  //     },
+  //   },
+  // },
+  devServer: {
+    port: '8006',
+    //api地址前缀
+    proxy: {
+      '/api': {
+        target: 'http://smart.cc-lotus.info',
+        changeOrigin: true,
+        ws: true,
+      },
+      '/wxtoken': {
+        target: 'http://smart.cc-lotus.info/weixin',
+        changeOrigin: true,
+        ws: true,
+        pathRewrite: {
+          '^/wxtoken': 'http://localhost:8005',
+        },
+      },
+      '/files': {
+        target: 'http://smart.cc-lotus.info',
+        changeOrigin: true,
+        ws: true,
+      },
+    },
+  },
+};