shaogen1995 пре 3 година
родитељ
комит
bee65cdb30
81 измењених фајлова са 40796 додато и 10 уклоњено
  1. 5 0
      houtai/.editorconfig
  2. 23 0
      houtai/.gitignore
  3. 24 0
      houtai/README.md
  4. 5 0
      houtai/babel.config.js
  5. 29916 0
      houtai/package-lock.json
  6. 68 0
      houtai/package.json
  7. BIN
      houtai/public/favicon.ico
  8. 17 0
      houtai/public/index.html
  9. 9 0
      houtai/src/App.vue
  10. 17 0
      houtai/src/apis/login.js
  11. 53 0
      houtai/src/apis/tab1.js
  12. 41 0
      houtai/src/apis/tab2.js
  13. 41 0
      houtai/src/apis/tab3.js
  14. 41 0
      houtai/src/apis/tab4.js
  15. 41 0
      houtai/src/apis/tab5.js
  16. 41 0
      houtai/src/apis/tab6.js
  17. 42 0
      houtai/src/apis/tab7.js
  18. 85 0
      houtai/src/apis/tab8.js
  19. 9 0
      houtai/src/apis/tab9.js
  20. 221 0
      houtai/src/assets/css/base.css
  21. BIN
      houtai/src/assets/img/IMGerror.png
  22. BIN
      houtai/src/assets/img/back.png
  23. BIN
      houtai/src/assets/img/banner.png
  24. BIN
      houtai/src/assets/img/demo.png
  25. BIN
      houtai/src/assets/img/forBac.png
  26. BIN
      houtai/src/assets/img/good.png
  27. BIN
      houtai/src/assets/img/goodAc.png
  28. BIN
      houtai/src/assets/img/goodNo.png
  29. BIN
      houtai/src/assets/img/logo.png
  30. BIN
      houtai/src/assets/img/lttx.png
  31. BIN
      houtai/src/assets/img/mesBac.png
  32. BIN
      houtai/src/assets/img/user.jpg
  33. BIN
      houtai/src/assets/imgAdd/comment.png
  34. BIN
      houtai/src/assets/imgAdd/like.png
  35. BIN
      houtai/src/assets/imgAdd/likeAc.png
  36. BIN
      houtai/src/assets/imgAdd/mesBac.png
  37. BIN
      houtai/src/assets/imgAdd/touxiang.png
  38. 28 0
      houtai/src/main.js
  39. 203 0
      houtai/src/router/index.js
  40. 106 0
      houtai/src/utils/pass.js
  41. 38 0
      houtai/src/utils/request.js
  42. 55 0
      houtai/src/views/forum/index.vue
  43. 597 0
      houtai/src/views/forum/list.vue
  44. 701 0
      houtai/src/views/forum/look.vue
  45. 63 0
      houtai/src/views/forumM/index.vue
  46. 511 0
      houtai/src/views/forumM/list.vue
  47. 465 0
      houtai/src/views/forumM/look.vue
  48. 356 0
      houtai/src/views/layout/index.vue
  49. 153 0
      houtai/src/views/login.vue
  50. 320 0
      houtai/src/views/message/index.vue
  51. 232 0
      houtai/src/views/messageM/index.vue
  52. 406 0
      houtai/src/views/tab1/index.vue
  53. 359 0
      houtai/src/views/tab1/tab1Add.vue
  54. 339 0
      houtai/src/views/tab1/tab1Add2.vue
  55. 203 0
      houtai/src/views/tab1/tab1Look.vue
  56. 354 0
      houtai/src/views/tab2/index.vue
  57. 417 0
      houtai/src/views/tab2/tab2Add.vue
  58. 130 0
      houtai/src/views/tab2/tab2Look.vue
  59. 354 0
      houtai/src/views/tab3/index.vue
  60. 425 0
      houtai/src/views/tab3/tab3Add.vue
  61. 133 0
      houtai/src/views/tab3/tab3Look.vue
  62. 349 0
      houtai/src/views/tab4/index.vue
  63. 298 0
      houtai/src/views/tab4/tab4Add.vue
  64. 119 0
      houtai/src/views/tab4/tab4Look.vue
  65. 349 0
      houtai/src/views/tab5/index.vue
  66. 219 0
      houtai/src/views/tab5/tab5Add.vue
  67. 116 0
      houtai/src/views/tab5/tab5Look.vue
  68. 349 0
      houtai/src/views/tab6/index.vue
  69. 325 0
      houtai/src/views/tab6/tab6Add.vue
  70. 125 0
      houtai/src/views/tab6/tab6Look.vue
  71. 287 0
      houtai/src/views/tab7/index.vue
  72. 326 0
      houtai/src/views/tab8/index.vue
  73. 105 0
      houtai/src/views/tab8/tab8Look.vue
  74. 161 0
      houtai/src/views/tab9/index.vue
  75. 3 0
      houtai/vue.config.js
  76. 1 1
      web/public/static/css/main.css
  77. 4 1
      web/public/static/js/main_2020_show.js
  78. 2 1
      web/public/static/js/manage.js
  79. 1 1
      web/src/App.vue
  80. 2 2
      web/src/utils/request.js
  81. 8 4
      web/src/views/gui/menu.vue

+ 5 - 0
houtai/.editorconfig

@@ -0,0 +1,5 @@
+[*.{js,jsx,ts,tsx,vue}]
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true

+ 23 - 0
houtai/.gitignore

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

+ 24 - 0
houtai/README.md

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

+ 5 - 0
houtai/babel.config.js

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

Разлика између датотеке није приказан због своје велике величине
+ 29916 - 0
houtai/package-lock.json


+ 68 - 0
houtai/package.json

@@ -0,0 +1,68 @@
+{
+  "name": "houtai",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "axios": "^0.24.0",
+    "Base64": "^1.1.0",
+    "core-js": "^3.6.5",
+    "element-ui": "^2.15.6",
+    "js-base64": "^3.7.2",
+    "moment": "^2.29.1",
+    "vant": "^2.12.45",
+    "vue": "^2.6.11",
+    "vue-router": "^3.2.0",
+    "wangeditor": "^4.7.11"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.0",
+    "@vue/cli-plugin-eslint": "~4.5.0",
+    "@vue/cli-plugin-router": "~4.5.0",
+    "@vue/cli-service": "~4.5.0",
+    "@vue/eslint-config-standard": "^5.1.2",
+    "babel-eslint": "^10.1.0",
+    "eslint": "^6.7.2",
+    "eslint-plugin-import": "^2.20.2",
+    "eslint-plugin-node": "^11.1.0",
+    "eslint-plugin-promise": "^4.2.1",
+    "eslint-plugin-standard": "^4.0.0",
+    "eslint-plugin-vue": "^6.2.2",
+    "less": "^3.0.4",
+    "less-loader": "^5.0.0",
+    "lint-staged": "^9.5.0",
+    "vue-template-compiler": "^2.6.11"
+  },
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "node": true
+    },
+    "extends": [
+      "plugin:vue/essential",
+      "@vue/standard"
+    ],
+    "parserOptions": {
+      "parser": "babel-eslint"
+    },
+    "rules": {}
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not dead"
+  ],
+  "gitHooks": {
+    "pre-commit": "lint-staged"
+  },
+  "lint-staged": {
+    "*.{js,jsx,vue}": [
+      "vue-cli-service lint",
+      "git add"
+    ]
+  }
+}

BIN
houtai/public/favicon.ico


+ 17 - 0
houtai/public/index.html

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

+ 9 - 0
houtai/src/App.vue

@@ -0,0 +1,9 @@
+<template>
+  <div id="app">
+    <Router-view/>
+  </div>
+</template>
+
+<style lang="less">
+
+</style>

+ 17 - 0
houtai/src/apis/login.js

@@ -0,0 +1,17 @@
+import axios from '../utils/request'
+// 用户登录接口
+export const userLogin = (data) => {
+  return axios({
+    method: 'post',
+    url: '/admin/login',
+    data
+  })
+}
+// 修改密码
+export const updatePwd = (data) => {
+  return axios({
+    method: 'post',
+    url: '/sys/user/updatePwd',
+    data
+  })
+}

+ 53 - 0
houtai/src/apis/tab1.js

@@ -0,0 +1,53 @@
+import axios from '../utils/request'
+// 获取列表
+export const goodsList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/goods/list',
+    data
+  })
+}
+// 点击删除
+export const goodsRemove = (id) => {
+  return axios({
+    url: `/cms/goods/remove/${id}`
+  })
+}
+// 新增、编辑
+export const goodsSave = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/goods/save',
+    data
+  })
+}
+// 是否显示
+export const goodsDisplay = (id, display) => {
+  return axios({
+    url: `/cms/goods/display/${id}/${display}`
+  })
+}
+// 排序
+export const goodsSort = (id, sort) => {
+  return axios({
+    url: `/cms/goods/sort/${id}/${sort}`
+  })
+}
+// 设为封面
+export const goodsImgIndex = (id, fileId) => {
+  return axios({
+    url: `/cms/goods/imgIndex/${id}/${fileId}`
+  })
+}
+// 通过id获取详情
+export const goodsDetail = (id) => {
+  return axios({
+    url: `/cms/goods/detail/${id}`
+  })
+}
+// 删除图片
+export const goodsimgRemove = (id) => {
+  return axios({
+    url: `/cms/goods/imgRemove/${id}`
+  })
+}

+ 41 - 0
houtai/src/apis/tab2.js

@@ -0,0 +1,41 @@
+import axios from '../utils/request'
+// 获取列表
+export const leaderList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/leader/list',
+    data
+  })
+}
+// 新增、编辑
+export const leaderSave = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/leader/save',
+    data
+  })
+}
+// 排序
+export const leaderSort = (id, sort) => {
+  return axios({
+    url: `/cms/leader/sort/${id}/${sort}`
+  })
+}
+// 是否显示
+export const leaderDisplay = (id, display) => {
+  return axios({
+    url: `/cms/leader/display/${id}/${display}`
+  })
+}
+// 通过id获取详情
+export const leaderDetail = (id) => {
+  return axios({
+    url: `/cms/leader/detail/${id}`
+  })
+}
+// 点击删除
+export const leaderRemove = (id) => {
+  return axios({
+    url: `/cms/leader/remove/${id}`
+  })
+}

+ 41 - 0
houtai/src/apis/tab3.js

@@ -0,0 +1,41 @@
+import axios from '../utils/request'
+// 获取列表
+export const studentList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/student/list',
+    data
+  })
+}
+// 排序
+export const studentSort = (id, sort) => {
+  return axios({
+    url: `/cms/student/sort/${id}/${sort}`
+  })
+}
+// 是否显示
+export const studentDisplay = (id, display) => {
+  return axios({
+    url: `/cms/student/display/${id}/${display}`
+  })
+}
+// 点击删除
+export const studentRemove = (id) => {
+  return axios({
+    url: `/cms/student/remove/${id}`
+  })
+}
+// 新增、编辑
+export const studentSave = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/student/save',
+    data
+  })
+}
+// 通过id获取详情
+export const studentDetail = (id) => {
+  return axios({
+    url: `/cms/student/detail/${id}`
+  })
+}

+ 41 - 0
houtai/src/apis/tab4.js

@@ -0,0 +1,41 @@
+import axios from '../utils/request'
+// 获取列表
+export const videoList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/video/list',
+    data
+  })
+}
+// 排序
+export const videoSort = (id, sort) => {
+  return axios({
+    url: `/cms/video/sort/${id}/${sort}`
+  })
+}
+// 是否显示
+export const videoDisplay = (id, display) => {
+  return axios({
+    url: `/cms/video/display/${id}/${display}`
+  })
+}
+// 点击删除
+export const videoRemove = (id) => {
+  return axios({
+    url: `/cms/video/remove/${id}`
+  })
+}
+// 新增、编辑
+export const videoSave = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/video/save',
+    data
+  })
+}
+// 通过id获取详情
+export const videoDetail = (id) => {
+  return axios({
+    url: `/cms/video/detail/${id}`
+  })
+}

+ 41 - 0
houtai/src/apis/tab5.js

@@ -0,0 +1,41 @@
+import axios from '../utils/request'
+// 获取列表
+export const imgList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/img/list',
+    data
+  })
+}
+// 排序
+export const imgSort = (id, sort) => {
+  return axios({
+    url: `/cms/img/sort/${id}/${sort}`
+  })
+}
+// 是否显示
+export const imgDisplay = (id, display) => {
+  return axios({
+    url: `/cms/img/display/${id}/${display}`
+  })
+}
+// 点击删除
+export const imgRemove = (id) => {
+  return axios({
+    url: `/cms/img/remove/${id}`
+  })
+}
+// 新增、编辑
+export const imgSave = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/img/save',
+    data
+  })
+}
+// 通过id获取详情
+export const imgDetail = (id) => {
+  return axios({
+    url: `/cms/img/detail/${id}`
+  })
+}

+ 41 - 0
houtai/src/apis/tab6.js

@@ -0,0 +1,41 @@
+import axios from '../utils/request'
+// 获取列表
+export const musicList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/music/list',
+    data
+  })
+}
+// 排序
+export const musicSort = (id, sort) => {
+  return axios({
+    url: `/cms/music/sort/${id}/${sort}`
+  })
+}
+// 是否显示
+export const musicDisplay = (id, display) => {
+  return axios({
+    url: `/cms/music/display/${id}/${display}`
+  })
+}
+// 点击删除
+export const musicRemove = (id) => {
+  return axios({
+    url: `/cms/music/remove/${id}`
+  })
+}
+// 新增、编辑
+export const musicSave = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/music/save',
+    data
+  })
+}
+// 通过id获取详情
+export const musicDetail = (id) => {
+  return axios({
+    url: `/cms/music/detail/${id}`
+  })
+}

+ 42 - 0
houtai/src/apis/tab7.js

@@ -0,0 +1,42 @@
+import axios from '../utils/request'
+// -----------------------web----------------------------
+// 提交留言
+export const commentSave = (data) => {
+  return axios({
+    method: 'post',
+    url: '/web/comment/save',
+    data
+  })
+}
+// 获取列表
+export const commentWebList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/web/comment/list',
+    data
+  })
+}
+
+// -----------------------后台----------------------------
+// 获取列表
+export const commentList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/comment/list',
+    data
+  })
+}
+// 留言的审核-通过2,不通过1
+export const commentAudit = (status, id) => {
+  return axios({
+    method: 'get',
+    url: `/cms/comment/audit/${id}/${status}`
+  })
+}
+// 删除留言
+export const commentRemove = (id) => {
+  return axios({
+    method: 'get',
+    url: `/cms/comment/remove/${id}`
+  })
+}

+ 85 - 0
houtai/src/apis/tab8.js

@@ -0,0 +1,85 @@
+import axios from '../utils/request'
+// -----------------------web----------------------------
+// 发帖--回帖
+export const webBbsSave = (data) => {
+  return axios({
+    method: 'post',
+    url: '/web/bbs/save',
+    data
+  })
+}
+// 获取列表
+export const webBbsList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/web/bbs/list',
+    data
+  })
+}
+// 获取帖子的评论(留言)
+export const webBbsMesList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/web/bbs/message/list',
+    data
+  })
+}
+// 点击回复给帖子评论
+// export const webBbsMesSave = (data) => {
+//   return axios({
+//     method: 'post',
+//     url: '/web/bbs/message/save',
+//     data
+//   })
+// }
+// 论坛-保存帖子浏览量
+export const webBbsVisit = (id) => {
+  return axios({
+    method: 'get',
+    url: `/web/bbs/visit/${id}`
+  })
+}
+// 点赞
+export const webBbsLike = (type, id) => {
+  return axios({
+    method: 'post',
+    url: `/web/bbs/like/${type}/${id}`
+  })
+}
+// 点踩
+// export const webBbsUnLike = (type, id) => {
+//   return axios({
+//     method: 'post',
+//     url: `/web/bbs/unLike/${type}/${id}`
+//   })
+// }
+// -----------------------后台----------------------------
+// 获取列表
+export const bbsListApi = (data) => {
+  return axios({
+    method: 'post',
+    url: '/cms/bbs/list',
+    data
+  })
+}
+// 发帖的审核-通过2,不通过1
+export const bbsAuditApi = (status, id) => {
+  return axios({
+    method: 'get',
+    url: `/cms/bbs/audit/${id}/${status}`
+  })
+}
+// 删除发帖
+export const bbsRemoveApi = (id) => {
+  return axios({
+    method: 'get',
+    url: `/cms/bbs/remove/${id}`
+  })
+}
+// 根据id获取帖子内容
+// export const bbsDetailApi = (id) => {
+//   return axios({
+//     method: 'get',
+//     url: `/cms/bbs/detail/${id}`
+//   })
+// }

+ 9 - 0
houtai/src/apis/tab9.js

@@ -0,0 +1,9 @@
+import axios from '../utils/request'
+// 列表
+export const logList = (data) => {
+  return axios({
+    method: 'post',
+    url: '/sys/log/list',
+    data
+  })
+}

+ 221 - 0
houtai/src/assets/css/base.css

@@ -0,0 +1,221 @@
+* {
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+}
+body {
+  background-color: transparent;
+}
+ul li {
+  list-style: none;
+}
+a {
+  text-decoration:none ;
+  color: #b9412e;
+}
+.insideTop {
+  position: relative;
+  padding-left: 30px;
+  font-weight: 700;
+  height: 40px;
+  margin-bottom: 12px;
+}
+.insideTop .add{
+  position: absolute;
+  top: -10px;
+  right: 30px;
+}
+.obstruct{
+  position: absolute;
+  left: 0px;
+  top: 60px;
+  width: 100%;
+  background-color: #f2f2f2;
+  height: 12px;
+}
+.biaoshi{
+  position: relative;
+  font-style:normal
+}
+.biaoshi::before{
+  position: absolute;
+  top: 0px;
+  left: -92px;
+  content: '*';
+  color: #F56C6C;
+}
+
+.el-button--primary{
+  background-color: #b9412e;
+  border-color: #b9412e;
+}
+.el-button--primary:focus, .el-button--primary:hover {
+  background: #a33e2f;
+  border-color: #a33e2f;
+}
+.el-input.is-active .el-input__inner, .el-input__inner:focus {
+  border-color: #b9412e;
+}
+.cell{
+  text-align: center !important;
+}
+.table .el-input__inner{
+  text-align: center;
+}
+.el-input__inner{
+  line-height: normal;
+}
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+-webkit-appearance: none;
+}
+input[type="number"] {
+-moz-appearance: textfield;
+}
+.el-dialog{
+  min-width: 652px;
+}
+.el-upload__tip{
+  font-size: 14px;
+}
+.el-range-editor.is-active, .el-range-editor.is-active:hover{
+  border-color: #b9412e;
+}
+.el-date-table td.today span{
+  color: #b9412e;
+}
+.el-date-table td.end-date span, .el-date-table td.start-date span{
+  background-color: #b9412e;
+}
+.el-date-table td.available:hover{
+  color: #b9412e;
+}
+.el-select .el-input__inner:focus{
+  border-color: #b9412e;
+}
+.el-select-dropdown__item.selected{
+  color: #b9412e;
+}
+.el-select .el-input.is-focus .el-input__inner{
+  border-color: #b9412e;
+}
+.el-table--fit{
+  border-top: 1px solid #EBEEF5;
+}
+.table_img{
+  width: 100px;
+  height: 80px;
+  object-fit: cover;
+  border: 3px solid #ccc;
+}
+.table_name{
+  cursor: pointer;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;    
+}
+.el-button--text{
+  color: #964134;
+}
+.el-button--text:focus, .el-button--text:hover{
+  color: #e06a58;
+}
+.upHint{
+  color: black;
+  height: 20px;
+}
+.el-radio__input.is-checked+.el-radio__label{
+  color: #964134;
+}
+.el-radio__input.is-checked .el-radio__inner{
+  border-color: #964134;
+  background: #964134;
+}
+.el-image__preview{
+  border: 5px solid #cccccc;
+  object-fit: cover;
+}
+.el-pager li{
+  border-radius: 5px;
+  margin: 0 5px;
+  min-width: 28px;
+  background-color: #f4f4f5;
+}
+.el-pagination .btn-next, .el-pagination .btn-prev{
+  background-color: #f4f4f5;
+  padding: 0;
+  min-width: 28px;
+}
+.el-pagination__sizes .el-input .el-input__inner:hover{
+  border-color: #b9412e;
+}
+.el-pager li:hover{
+  color: #b9412e;
+}
+.el-pager li.active{
+  color: #fff;
+  background-color: #b9412e;
+}
+.el-pagination button:hover{
+  color: #b9412e;
+}
+.el-upload--picture-card:hover, .el-upload:focus{
+  color: #b9412e;
+}
+.w-e-menu {
+	z-index: 2 !important;
+}
+.w-e-text-container {
+	z-index: 1 !important;
+}
+.w-e-toolbar {
+	z-index: 10 !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(18) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(19) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(13) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(14) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(16) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(20) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(21) {
+	display: none !important;
+}
+.w-e-toolbar .w-e-menu:nth-of-type(26) {
+	display: none !important;
+}
+.avatar-uploader .el-upload-list__item-name{
+  display: none;
+}
+.avatar-uploader .el-upload-list__item.is-success .el-upload-list__item-status-label{
+  display: none;
+}
+.el-upload-list__item .el-progress{
+  width: 500px;
+  position: static;
+  margin-bottom: 15px;
+}
+.el-upload-list__item{
+  width: 500px;
+}
+.el-month-table td.end-date .cell, .el-month-table td.start-date .cell{
+  background-color: #b9412e;
+}
+
+.el-month-table td.today .cell{
+  color: #b9412e;
+}
+.el-message-box__title{
+  color: #b9412e;
+}

BIN
houtai/src/assets/img/IMGerror.png


BIN
houtai/src/assets/img/back.png


BIN
houtai/src/assets/img/banner.png


BIN
houtai/src/assets/img/demo.png


BIN
houtai/src/assets/img/forBac.png


BIN
houtai/src/assets/img/good.png


BIN
houtai/src/assets/img/goodAc.png


BIN
houtai/src/assets/img/goodNo.png


BIN
houtai/src/assets/img/logo.png


BIN
houtai/src/assets/img/lttx.png


BIN
houtai/src/assets/img/mesBac.png


BIN
houtai/src/assets/img/user.jpg


BIN
houtai/src/assets/imgAdd/comment.png


BIN
houtai/src/assets/imgAdd/like.png


BIN
houtai/src/assets/imgAdd/likeAc.png


BIN
houtai/src/assets/imgAdd/mesBac.png


BIN
houtai/src/assets/imgAdd/touxiang.png


+ 28 - 0
houtai/src/main.js

@@ -0,0 +1,28 @@
+import Vue from 'vue'
+import ElementUI from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css'
+import App from './App.vue'
+import router from './router'
+import './assets/css/base.css'
+import Moment from 'moment'
+
+// 留言和论坛的下拉刷新
+import { List } from 'vant'
+import 'vant/lib/index.css'
+Vue.use(List)
+
+Vue.prototype.moment = Moment
+Vue.config.productionTip = false
+const imgErr = {
+  data () {
+    return {
+      defaultImg: 'this.src="' + require('./assets/img/IMGerror.png') + '"'
+    }
+  }
+}
+Vue.mixin(imgErr)
+Vue.use(ElementUI)
+new Vue({
+  router,
+  render: h => h(App)
+}).$mount('#app')

+ 203 - 0
houtai/src/router/index.js

@@ -0,0 +1,203 @@
+import Vue from 'vue'
+import VueRouter from 'vue-router'
+import { Message } from 'element-ui'
+Vue.use(VueRouter)
+
+const routes = [
+  // 留言板pc
+  {
+    path: '/message',
+    name: 'message',
+    component: () => import('../views/message/index.vue')
+  },
+  // 留言板M
+  {
+    path: '/messageM',
+    name: 'messageM',
+    component: () => import('../views/messageM/index.vue')
+  },
+  // 论坛pc
+  {
+    path: '/forum',
+    name: 'forum',
+    component: () => import('../views/forum/index.vue')
+  },
+  // 论坛M
+  {
+    path: '/forumM',
+    name: 'forumM',
+    component: () => import('../views/forumM/index.vue')
+  },
+  {
+    path: '/',
+    name: 'login',
+    component: () => import('../views/login.vue')
+  },
+  {
+    path: '/layout',
+    name: 'layout',
+    component: () => import('../views/layout/index.vue'),
+    children: [
+      {
+        path: 'tab1',
+        name: 'tab1',
+        meta: { myInd: 1 },
+        component: () => import('../views/tab1/index.vue')
+      },
+      {
+        path: 'tab1Add',
+        name: 'tab1Add',
+        meta: { myInd: 1 },
+        component: () => import('../views/tab1/tab1Add.vue')
+      },
+      {
+        path: 'tab1Add2',
+        name: 'tab1Add2',
+        meta: { myInd: 1 },
+        component: () => import('../views/tab1/tab1Add2.vue')
+      },
+      {
+        path: 'tab1Look',
+        name: 'tab1Look',
+        meta: { myInd: 1 },
+        component: () => import('../views/tab1/tab1Look.vue')
+      },
+      {
+        path: 'tab2',
+        name: 'tab2',
+        meta: { myInd: 2 },
+        component: () => import('../views/tab2/index.vue')
+      },
+      {
+        path: 'tab2Add',
+        name: 'tab2Add',
+        meta: { myInd: 2 },
+        component: () => import('../views/tab2/tab2Add.vue')
+      },
+      {
+        path: 'tab2Look',
+        name: 'tab2Look',
+        meta: { myInd: 2 },
+        component: () => import('../views/tab2/tab2Look.vue')
+      },
+      {
+        path: 'tab3',
+        name: 'tab3',
+        meta: { myInd: 3 },
+        component: () => import('../views/tab3/index.vue')
+      },
+      {
+        path: 'tab3Add',
+        name: 'tab3Add',
+        meta: { myInd: 3 },
+        component: () => import('../views/tab3/tab3Add.vue')
+      },
+      {
+        path: 'tab3Look',
+        name: 'tab3Look',
+        meta: { myInd: 3 },
+        component: () => import('../views/tab3/tab3Look.vue')
+      },
+      {
+        path: 'tab4',
+        name: 'tab4',
+        meta: { myInd: 4 },
+        component: () => import('../views/tab4/index.vue')
+      },
+      {
+        path: 'tab4Add',
+        name: 'tab4Add',
+        meta: { myInd: 4 },
+        component: () => import('../views/tab4/tab4Add.vue')
+      },
+      {
+        path: 'tab4Look',
+        name: 'tab4Look',
+        meta: { myInd: 4 },
+        component: () => import('../views/tab4/tab4Look.vue')
+      },
+      {
+        path: 'tab5',
+        name: 'tab5',
+        meta: { myInd: 5 },
+        component: () => import('../views/tab5/index.vue')
+      },
+      {
+        path: 'tab5Add',
+        name: 'tab5Add',
+        meta: { myInd: 5 },
+        component: () => import('../views/tab5/tab5Add.vue')
+      },
+      {
+        path: 'tab5Look',
+        name: 'tab5Look',
+        meta: { myInd: 5 },
+        component: () => import('../views/tab5/tab5Look.vue')
+      },
+      {
+        path: 'tab6',
+        name: 'tab6',
+        meta: { myInd: 6 },
+        component: () => import('../views/tab6/index.vue')
+      },
+      {
+        path: 'tab6Add',
+        name: 'tab6Add',
+        meta: { myInd: 6 },
+        component: () => import('../views/tab6/tab6Add.vue')
+      },
+      {
+        path: 'tab6Look',
+        name: 'tab6Look',
+        meta: { myInd: 6 },
+        component: () => import('../views/tab6/tab6Look.vue')
+      },
+      {
+        path: 'tab7',
+        name: 'tab7',
+        meta: { myInd: 7 },
+        component: () => import('../views/tab7/index.vue')
+      },
+      {
+        path: 'tab8',
+        name: 'tab8',
+        meta: { myInd: 8 },
+        component: () => import('../views/tab8/index.vue')
+      },
+      {
+        path: 'tab8Look',
+        name: 'tab8Look',
+        meta: { myInd: 8 },
+        component: () => import('../views/tab8/tab8Look.vue')
+      },
+      {
+        path: 'tab9',
+        name: 'tab9',
+        meta: { myInd: 9 },
+        component: () => import('../views/tab9/index.vue')
+      }
+    ]
+  }
+]
+
+const router = new VueRouter({
+  // mode: 'history',
+  base: process.env.BASE_URL,
+  routes
+})
+
+router.beforeEach((to, from, next) => {
+  // 如果是去登录页,不需要验证,直接下一步
+  if (to.name === 'login' || to.name === 'message' || to.name === 'messageM' || to.name === 'forum' || to.name === 'forumM') next()
+  // 否则要有token值才能下一步,不然就返回登录页
+  else {
+    const token = localStorage.getItem('CQLJXU_token')
+    if (token) next()
+    else {
+      Message.warning('登录失效,请重新登录')
+      next({ name: 'login' })
+    }
+  }
+})
+
+export default router

+ 106 - 0
houtai/src/utils/pass.js

@@ -0,0 +1,106 @@
+/* eslint-disable */
+function NoToChinese (num) {
+  num = String(num)
+  var chnNumChar = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
+  if (num == 0) {
+    return chnNumChar[0]
+  }
+  let tmp = ''
+  for (let i = 0; i < num.length; i++) {
+    const ele = num.charAt(i)
+    tmp += chnNumChar[ele]
+  }
+
+  return tmp
+}
+
+function randomWord (randomFlag, min, max) {
+  let str = ''
+  let range = min
+  const arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
+  // 随机产生
+  if (randomFlag) {
+    range = Math.round(Math.random() * (max - min)) + min
+  }
+  for (var i = 0; i < range; i++) {
+    const pos = Math.round(Math.random() * (arr.length - 1))
+    str += arr[pos]
+  }
+  return str
+}
+
+module.exports = {
+  formatDate: function (time) {
+    var weekArr = ['日', '一', '二', '三', '四', '五', '六']
+    var date = new Date(time)
+    var year = date.getFullYear()
+    var month = date.getMonth() + 1
+    var day = date.getDate()
+    var week = '星期' + weekArr[date.getDay()]
+    if (window.innerWidth < 1700) {
+      return (
+        year +
+        '年' +
+        (String(month).length > 1 ? month : '0' + month) +
+        '月' +
+        (String(day).length > 1 ? day : '0' + day) +
+        '日' +
+        '<br/>' +
+        week
+      )
+    }
+    return (
+      year +
+      '年' +
+      (String(month).length > 1 ? month : '0' + month) +
+      '月' +
+      (String(day).length > 1 ? day : '0' + day) +
+      '日' +
+      ' ' +
+      week
+    )
+  },
+  smoothscrollpos: function (domName) {
+    if (domName == '/') {
+      return window.scrollTo(0, 0)
+    }
+    const smoothscroll = () => {
+      const dom = document.getElementById(domName)
+      // window.scrollTo({
+      //   top:dom.offsetTop - 100,
+      //   left:0,
+      //   behavior: "smooth"
+      // })
+      dom && window.scrollTo(0, dom.offsetTop - 120)
+    }
+    smoothscroll()
+  },
+
+  formatTime: function (time, fan = false) {
+    let t1 = time.split(' ')[0].split('-')
+    if (fan) {
+      t1 = t1.map((item) => {
+        const t = NoToChinese(item)
+        return t
+      })
+    }
+    return t1
+  },
+  encodeStr: function (str, strv = '') {
+    const NUM = 2
+    const front = randomWord(false, 8)
+    const middle = randomWord(false, 8)
+    const end = randomWord(false, 8)
+
+    const str1 = str.substring(0, NUM)
+    const str2 = str.substring(NUM)
+
+    if (strv) {
+      const strv1 = strv.substring(0, NUM)
+      const strv2 = strv.substring(NUM)
+      return [front + str2 + middle + str1 + end, front + strv2 + middle + strv1 + end]
+    }
+
+    return front + str2 + middle + str1 + end
+  }
+}

+ 38 - 0
houtai/src/utils/request.js

@@ -0,0 +1,38 @@
+import axios from 'axios'
+const service = axios.create({
+  baseURL: 'http://192.168.0.135:8003/', // 本地调试
+  // baseURL: 'http://192.168.0.245:8005/', // 线上调试
+  // baseURL: '', // build
+  timeout: 5000
+})
+// 请求拦截器
+service.interceptors.request.use(function (config) {
+  // console.log('触发拦截器')
+  // 在发送请求之前做些什么:看看有没有token,如果有通过请求头的方式传递token
+  const token = localStorage.getItem('CQLJXU_token')
+  if (token) { // 判断是否有token,有,则
+    // config.headers['Authorization'] = token
+    config.headers.token = token
+  }
+
+  return config
+}, function (error) {
+  // 对请求错误做些什么
+  return Promise.reject(error)
+})
+
+// 添加响应拦截器
+service.interceptors.response.use(function (response) {
+  // console.log('触发相应拦截器', response)
+  // 对响应数据做点什么--response就是发送每个请求的返回值
+  if (response.data.code === 5001 || response.data.code === 5002) {
+    // Toast.fail('未登录,请先登录')
+    localStorage.removeItem('CQLJXU_token')
+  }
+  return response.data
+}, function (error) {
+  // 对响应错误做点什么
+  return Promise.reject(error)
+})
+
+export default service

+ 55 - 0
houtai/src/views/forum/index.vue

@@ -0,0 +1,55 @@
+<!--  -->
+<template>
+<div class='forum_index'>
+  <keep-alive>
+    <component :is='cutCom' @cutComFn='cutComFn' :lookInfo='lookInfo'></component>
+  </keep-alive>
+</div>
+</template>
+
+<script>
+import List from './list.vue'
+import Look from './look.vue'
+export default {
+  name: 'forum_index',
+  components: { List, Look },
+  data () {
+    // 这里存放数据
+    return {
+      cutCom: 'List',
+      lookInfo: {}
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 从List组件点击文章触发
+    cutComFn (item) {
+      // 改变is的值切换动态组件
+      if (item.id) this.cutCom = 'Look'
+      else this.cutCom = 'List'
+      this.lookInfo = item
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {
+
+  },
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+</style>

+ 597 - 0
houtai/src/views/forum/list.vue

@@ -0,0 +1,597 @@
+<template>
+  <div class="forum_list">
+    <div class="title">
+      <span>论 坛</span>
+    </div>
+    <div class="ulTitle" v-show="!fuTxtShow">
+      <ul>
+        <li
+          :class="{ active: item.id === tabInd }"
+          v-for="item in tab"
+          :key="item.id"
+          @click="cutTab(item)"
+        >
+          {{ item.name }}
+        </li>
+      </ul>
+      <!-- 发帖按钮 -->
+      <div class="ulTitleBtn" @click="fuTxtShow = true">发 帖</div>
+    </div>
+    <div class="conten" v-show="!fuTxtShow">
+      <div class="row rowFi">
+        <div class="row_one">公告/置顶</div>
+        <div class="row_tow">作 者</div>
+        <div class="row_three">回复数</div>
+        <div class="row_four">最后发表</div>
+      </div>
+      <div class="nullTit" v-if="dataArr.length === 0">暂无数据</div>
+      <div
+        class="row"
+        v-for="item in dataArr"
+        :key="item.id"
+        @click="skip(item)"
+        v-else
+      >
+        <div class="row_one">{{ item.title }}</div>
+        <div class="row_tow">{{ item.creatorName }}</div>
+        <div class="row_three">
+          {{ item.reply ? item.reply : 0 }}
+        </div>
+        <div class="row_four">
+          <!-- {{item.replyName}}/{{item.replyTime}} -->
+          {{item.replyName.length>5?item.replyName.substring(0, 5)+'...':item.replyName}} {{ item.replyTime.substring(0, 10) }}
+        </div>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging" v-show="!fuTxtShow">
+      <el-pagination
+        layout="prev, pager, next"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+    <!-- 底部 -->
+    <div class="bottom" v-show="fuTxtShow">
+      <!-- 后面加的关闭 -->
+      <div class="rickTextBack el-icon-arrow-left" @click="fuTxtShow = false">
+        返回
+        <div></div>
+      </div>
+      <div class="rickText">
+        <div class="inputR">
+          <el-select
+            v-model="selectType"
+            placeholder="请选择主题分类"
+            style="width: 400px"
+          >
+            <el-option label="数字史馆" value="scene"></el-option>
+            <el-option label="美丽校园" value="school"></el-option>
+            <el-option label="文物典藏" value="goods"></el-option>
+          </el-select>
+          <el-input
+            style="margin-left: 20px"
+            type="text"
+            placeholder="帖子标题字数不能超过30个字。"
+            v-model="title"
+            maxlength="30"
+            show-word-limit
+          >
+          </el-input>
+          <!-- 上传图片 -->
+          <el-upload
+            accept=".png,.jpg,.jpeg,.gif"
+            title="上传图片"
+            class="upload-demo imgUplod"
+            :action="baseURL + '/web/bbs/upload'"
+            multiple
+            :before-upload="beforethumbUploadImg"
+            :on-success="upload_thumb_successImg"
+          >
+            <i class="w-e-icon-image"></i>
+          </el-upload>
+        </div>
+        <!-- 富文本 -->
+        <div id="div1" style="z-index: 1"></div>
+        <!-- 按钮 -->
+        <div class="txtBtn">
+          <div
+            class="nameCut"
+            :class="{ active: !nameShow }"
+            @click="nameShow = false"
+          ></div>
+          <div class="noName">匿 名</div>
+          <div
+            class="nameCut"
+            :class="{ active: nameShow }"
+            @click="nameShow = true"
+          ></div>
+          <el-input
+            :disabled="!nameShow"
+            style="width: 300px"
+            type="text"
+            placeholder="请填写您的姓名"
+            v-model="creatorName"
+            maxlength="8"
+            show-word-limit
+          >
+          </el-input>
+          <el-button type="primary" style="width: 120px" @click="publish"
+            >发 贴</el-button
+          >
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from '@/utils/request'
+import { webBbsSave, webBbsList, webBbsVisit } from '@/apis/tab8'
+import E from 'wangeditor'
+export default {
+  name: 'forum_list',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      // 选择匿名
+      nameShow: true,
+      // 控制富文本显示和隐藏
+      fuTxtShow: false,
+      // 列表数据
+      dataArr: [],
+      total: 0,
+      // 服务器前缀地址
+      baseURL: '',
+      tabInd: 1,
+      tab: [
+        { id: 1, name: '数字史馆', type: 'scene' },
+        { id: 2, name: '美丽校园', type: 'school' },
+        { id: 3, name: '文物典藏', type: 'goods' }
+      ],
+      formData: {
+        endTime: '',
+        searchKey: '',
+        startTime: '',
+        status: 2,
+        type: 'scene',
+        pageNum: 1,
+        pageSize: 10,
+        bbsType: 'topic'
+      },
+      selectType: 'scene',
+      title: '',
+      creatorName: '',
+      content: ''
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 上传图片
+    beforethumbUploadImg (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 5
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('图片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('图片大小超过5M!')
+          reject(file)
+        } else if (file.name.length > 32) {
+          this.$message.error('图片名字不能超过32个字!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_successImg (data) {
+      this.$message.success('上传成功')
+      this.editor.txt.append(
+        `<img src="${this.baseURL}${data.data.urlPath}"  style="max-width:100%;display: block;margin: 10px auto;"/><p><br/></p>`
+      )
+    }, // 点击发表文章
+    async publish () {
+      if (this.creatorName.trim() === '' && this.nameShow) {
+        return this.$message.warning('名字不能为空!')
+      }
+      if (this.title.trim() === '') {
+        return this.$message.warning('标题不能为空!')
+      }
+      if (this.editor.txt.html() === '') {
+        return this.$message.warning('内容不能为空')
+      }
+      const res = await webBbsSave({
+        bbsType: 'topic',
+        content: this.editor.txt.html(),
+        creatorName: this.creatorName,
+        title: this.title,
+        type: this.selectType
+      })
+      if (res.code === 0) {
+        this.title = this.creatorName = ''
+        this.editor.txt.html('')
+        this.$message.success('发帖成功,等待审核.')
+        this.fuTxtShow = false
+      } else this.$message.warning(res.msg)
+    },
+    // 点击通知父组件切换 动态组件is的值,并且把数据传过去
+    async skip (item) {
+      await webBbsVisit(item.id)
+      this.$emit('cutComFn', item)
+    },
+    cutTab (item) {
+      this.tabInd = item.id
+      this.formData.type = item.type
+      this.formData.pageNum = 1
+      this.webBbsList(this.formData)
+      // 让下面的下拉框同步
+      this.selectType = item.type
+    },
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.webBbsList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.webBbsList(this.formData)
+    },
+    // 封装获取列表的方法
+    async webBbsList (data) {
+      const res = await webBbsList(data)
+      this.total = res.data.total
+      this.dataArr = res.data.records
+      this.dataArr.forEach(v => {
+        if (!v.replyName) v.replyName = v.creatorName
+        if (!v.replyTime) v.replyTime = v.createTime
+      })
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {
+    // 初始化富文本
+    // 富文本
+    this.editor = new E('#div1')
+    // 配置字体
+    this.editor.config.fontNames = [
+      '黑体',
+      '仿宋',
+      '楷体',
+      '标楷体',
+      '华文仿宋',
+      '华文楷体',
+      '宋体',
+      '微软雅黑',
+      'Arial',
+      'Tahoma',
+      'Verdana',
+      'Times New Roman'
+    ]
+    this.editor.config.showLinkVideo = false
+    this.editor.create()
+  },
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  // 如果页面有keep-alive缓存功能,这个函数会触发
+  activated () {
+    // 调用获取列表方法
+    this.webBbsList(this.formData)
+  }
+}
+</script>
+<style lang='less' scoped>
+/* 分页 */
+/deep/.el-pagination {
+  display: flex;
+  align-items: center;
+}
+
+.conten::-webkit-scrollbar {
+  /*滚动条整体样式*/
+  width: 3px; /*高宽分别对应横竖滚动条的尺寸*/
+  height: 1px;
+}
+.conten::-webkit-scrollbar-thumb {
+  /*滚动条里面小方块*/
+  border-radius: 10px;
+  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+  background: rgba(185, 46, 46, 0.3);
+}
+.conten::-webkit-scrollbar-track {
+  /*滚动条里面轨道*/
+  // box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+  border-radius: 10px;
+  background: transparent;
+}
+.forum_list {
+  border-top: 8px solid #be1220;
+  border-bottom: 8px solid #be1220;
+  padding: 0 12px;
+  background: url("../../assets/img/forBac.png") #f0dbbf center center no-repeat;
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  width: 1200px;
+  height: 650px;
+  .title {
+    color: #fff;
+    display: flex;
+    align-items: center;
+    height: 60px;
+    & > span {
+      font-weight: 700;
+      padding-left: 40px;
+      font-size: 26px;
+      margin-right: 100px;
+    }
+  }
+  .ulTitle {
+    position: relative;
+    border-radius: 5px 5px 0 0;
+    background-color: rgba(255, 255, 255, 0.3);
+    height: 60px;
+    padding: 10px;
+    & > ul {
+      padding-left: 10px;
+      border-bottom: 1px solid #b92e2e;
+      height: 50px;
+      display: flex;
+      & > li {
+        margin-right: 30px;
+        cursor: pointer;
+        letter-spacing: 2px;
+        font-weight: 600;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        height: 40px;
+        width: 120px;
+        font-size: 18px;
+        text-align: center;
+      }
+      .active {
+        background-color: #b92e2e;
+        color: #fff;
+        border-radius: 20px;
+      }
+    }
+    .ulTitleBtn {
+      font-size: 18px;
+      color: #fff;
+      cursor: pointer;
+      position: absolute;
+      top: 10px;
+      right: 50px;
+      width: 100px;
+      height: 40px;
+      line-height: 40px;
+      text-align: center;
+      background-color: #f2cd83;
+      border-radius: 5px;
+    }
+  }
+
+  .conten {
+    height: 410px;
+    overflow-y: auto;
+    background-color: rgba(255, 255, 255, 0.3);
+    padding-bottom: 20px;
+    color: #5f5f5f;
+    .row {
+      padding: 0 10px;
+      cursor: pointer;
+      margin: 0 40px;
+      border-bottom: 1px dashed #d5a6a6;
+      font-size: 16px;
+      display: flex;
+      & > div {
+        height: 60px;
+        line-height: 60px;
+        margin: 0 40px;
+        text-align: center;
+      }
+      .row_one {
+        text-align: left;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        margin-left: 0;
+        flex: 1;
+      }
+      .row_tow {
+        width: 135px;
+      }
+      .row_three {
+        width: 100px;
+      }
+      .row_four {
+        text-align: left;
+        margin-right: 0;
+        width: 190px;
+      }
+    }
+    .rowFi {
+      font-weight: 600;
+      border-bottom: none;
+      font-size: 22px;
+      .row_one {
+        color: #b9412e;
+      }
+    }
+    .nullTit {
+      height: 100px;
+      line-height: 100px;
+      font-size: 30px;
+      color: #b9412e;
+      text-align: center;
+    }
+  }
+  .paging {
+    /deep/.el-pager li {
+      background-color: transparent;
+      color: #333333;
+    }
+    /deep/.el-pager li.active {
+      color: #b92e2e;
+    }
+    /deep/.el-pagination button {
+      background-color: transparent;
+    }
+    /deep/.el-pagination button:disabled {
+      background-color: transparent;
+    }
+    border-radius: 0 0 5px 5px;
+    background-color: rgba(255, 255, 255, 0.3);
+    height: 80px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  .bottom {
+    padding: 12px;
+    width: 100%;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    .rickTextBack {
+      position: relative;
+      padding-left: 20px;
+      width: 100%;
+      height: 50px;
+      line-height: 50px;
+      color: #cb444e;
+      background-color: rgba(255, 255, 255, 0.3);
+      cursor: pointer;
+      & > div {
+        background-color: #b92e2e;
+        position: absolute;
+        bottom: 0;
+        left: 10px;
+        width: 1156px;
+        height: 1px;
+      }
+    }
+    .rickText {
+      width: 100%;
+      background-color: rgba(255, 255, 255, 0.3);
+      padding: 20px;
+      .inputR {
+        display: flex;
+        margin-bottom: 20px;
+        position: relative;
+        .imgUplod {
+          /deep/.w-e-icon-image {
+            color: #999;
+            display: inline-block;
+            width: 40px;
+            height: 40px;
+            line-height: 40px;
+          }
+          /deep/.el-upload-list {
+            display: none !important;
+          }
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          cursor: pointer;
+          position: absolute;
+          z-index: 9999;
+          top: 61px;
+          right: 1px;
+          width: 40px;
+          height: 40px;
+          &:hover {
+            background-color: #f6f6f6;
+            /deep/.w-e-icon-image {
+              color: black;
+            }
+          }
+        }
+      }
+      .txtBtn {
+        display: flex;
+        align-items: center;
+        position: relative;
+        margin-top: 20px;
+        /deep/.el-button {
+          width: 120px;
+          height: 40px;
+          position: absolute;
+          right: 20px;
+          bottom: 0;
+          color: #d8b380;
+          font-size: 18px;
+        }
+        .nameCut {
+          cursor: pointer;
+          position: relative;
+          margin-right: 10px;
+          width: 20px;
+          height: 20px;
+          border-radius: 50%;
+          border: 1px solid #b9412e;
+        }
+        .noName {
+          margin-right: 30px;
+        }
+        .active {
+          &::after {
+            content: "";
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            transform: translate(-50%, -50%);
+            width: 15px;
+            height: 15px;
+            border-radius: 50%;
+            background-color: #b9412e;
+          }
+        }
+        /deep/.el-input.is-disabled .el-input__inner {
+          background-color: #e9ebec;
+        }
+      }
+    }
+    /deep/.el-input__inner {
+      background-color: rgba(255, 255, 255, 0.5);
+    }
+    /deep/.el-input__count-inner {
+      background-color: transparent;
+    }
+    // /deep/.w-e-toolbar {
+    //   background-color: rgba(255, 255, 255, 0.5) !important;
+    // }
+    // /deep/.w-e-text-container {
+    //   background-color: rgba(255, 255, 255, 0.5) !important;
+    // }
+  }
+}
+</style>

+ 701 - 0
houtai/src/views/forum/look.vue

@@ -0,0 +1,701 @@
+<template>
+  <div class="forum_look">
+    <!-- 回帖按钮 -->
+    <div class="ulTitleBtn" @click="fuTxtShow = true">回 帖</div>
+    <div class="title">
+      <div class="rowBack el-icon-arrow-left" @click='backList' v-show="!fuTxtShow">
+        返回
+      </div>
+      <span>论 坛</span>
+      <!-- <ul>
+        <li
+          :class="{ active: item.type === lookInfo.type }"
+          v-for="item in tab"
+          :key="item.id"
+        >
+          {{ item.name }}
+        </li>
+      </ul>
+      <img
+        src="../../assets/img/back.png"
+        alt=""
+        @click="$emit('cutComFn', {})"
+      /> -->
+    </div>
+    <div class="conten" v-show="!fuTxtShow">
+      <div class="row rowOne">
+        <div class="xian"></div>
+        <!-- 头像 -->
+        <div class="buddha">
+          <i class="el-icon-user-solid"></i>
+        </div>
+        <span>{{ lookInfo.creatorName }}</span>
+        <h3>{{ lookInfo.title }}</h3>
+        <p v-html="lookInfo.content"></p>
+        <div class="row_bott">
+          <span>发表于:{{ lookInfo.createTime }}</span>
+          <div class="inco">
+            <div title="赞" @click="clickLikeOne('upVote', lookInfo.id)">
+              <img :src="require(`@/assets/img/${lookInfo.flag?'goodAc':'good'}.png`)" alt="" />&nbsp;点赞&nbsp;({{
+                lookInfo.upVote ? lookInfo.upVote : 0
+              }})
+            </div>
+            <!-- <div title="踩" @click="clickUnlikeOne('unVote', lookInfo.id)">
+              <img src="../../assets/img/goodNo.png" alt="" />({{
+                lookInfo.unVote ? lookInfo.unVote : 0
+              }})
+            </div> -->
+          </div>
+        </div>
+      </div>
+      <!-- 留言列表为空的时候 -->
+      <div class="rowNull" v-if="dataArr.length === 0">暂无数据</div>
+      <div class="row" v-for="item in dataArr" :key="item.id" v-else>
+        <!-- 头像 -->
+        <div class="buddha">
+          <i class="el-icon-user-solid"></i>
+        </div>
+        <span>{{ item.creatorName }}</span>
+        <h3>&emsp;</h3>
+        <p v-html="item.content"></p>
+        <div class="row_bott">
+          <span>发表于:{{ item.createTime }}</span>
+          <div class="inco">
+            <div title="赞" @click="clickLike('upVote', item.id)">
+              <img :src="require(`@/assets/img/${item.flag?'goodAc':'good'}.png`)" alt="" />&nbsp;点赞&nbsp;({{
+                item.upVote ? item.upVote : 0
+              }})
+            </div>
+            <!-- <div title="踩" @click="clickUnlike('unVote', item.id)">
+              <img src="../../assets/img/goodNo.png" alt="" />({{
+                item.unVote ? item.unVote : 0
+              }})
+            </div> -->
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging" v-show="!fuTxtShow">
+      <el-pagination
+        layout="prev, pager, next"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+    <!-- 底部 -->
+    <div class="bottom" v-show="fuTxtShow">
+      <!-- 后面加的关闭 -->
+      <div class="rickTextBack el-icon-arrow-left" @click="fuTxtShow = false">
+        返回
+        <div></div>
+      </div>
+      <div class="rickText">
+        <div class="inputR">
+          <!-- 上传图片 -->
+          <el-upload
+            accept=".png,.jpg,.jpeg,.gif"
+            title="上传图片"
+            class="upload-demo imgUplod"
+            :action="baseURL + '/web/bbs/upload'"
+            multiple
+            :before-upload="beforethumbUploadImg"
+            :on-success="upload_thumb_successImg"
+          >
+            <i class="w-e-icon-image"></i>
+          </el-upload>
+        </div>
+        <!-- 富文本 -->
+        <div id="div1" style="z-index: 1"></div>
+        <!-- 按钮 -->
+
+        <!-- 按钮 -->
+        <div class="txtBtn">
+          <div
+            class="nameCut"
+            :class="{ active: !nameShow }"
+            @click="nameShow = false"
+          ></div>
+          <div class="noName">匿 名</div>
+          <div
+            class="nameCut"
+            :class="{ active: nameShow }"
+            @click="nameShow = true"
+          ></div>
+          <el-input
+            :disabled="!nameShow"
+            style="width: 300px"
+            type="text"
+            placeholder="请填写您的姓名"
+            v-model="name2"
+            maxlength="8"
+            show-word-limit
+          >
+          </el-input>
+          <el-button type="primary" style="width: 120px" @click="reply"
+            >提 交</el-button
+          >
+        </div>
+
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from '@/utils/request'
+import { webBbsMesList, webBbsSave, webBbsLike } from '@/apis/tab8'
+import E from 'wangeditor'
+export default {
+  name: 'forum_look',
+  components: {},
+  props: {
+    lookInfo: {
+      type: Object,
+      default: () => {}
+    }
+  },
+  data () {
+    // 这里存放数据
+    return {
+      // 选择匿名
+      nameShow: true,
+      // 控制富文本显示和隐藏
+      fuTxtShow: false,
+      // 点赞-帖子的开关
+      likeFlagOne: [],
+      // unLikeFlagOne: [],
+      // 点赞-评论的开关
+      likeFlag: [],
+      // unLikeFlag: [],
+      baseURL: '',
+      // 评论列表数据
+      total: 0,
+      dataArr: [],
+      tab: [
+        { id: 1, name: '数字史馆', type: 'scene' },
+        { id: 2, name: '美丽校园', type: 'school' },
+        { id: 3, name: '文物典藏', type: 'goods' }
+      ],
+      formData: {
+        parentId: null,
+        pageNum: 1,
+        pageSize: 10
+      },
+      name2: ''
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 点击返回
+    backList () {
+      this.fuTxtShow = false
+      this.$emit('cutComFn', {})
+    },
+    // 点赞-帖子
+    async clickLikeOne (type, id) {
+      if (!this.likeFlagOne.includes(id)) {
+        const res = await webBbsLike(type, id)
+        if (res.code === 0) {
+          this.$message.success('点赞成功.')
+          this.likeFlagOne.push(id)
+          this.lookInfo.upVote++
+          this.lookInfo.flag = true
+        } else this.$message.warning(res.msg)
+      } else this.$message.warning('您已经赞过了.')
+    },
+    // 点踩-帖子
+    // async clickUnlikeOne (type, id) {
+    //   if (!this.unLikeFlagOne.includes(id)) {
+    //     const res = await webBbsLike(type, id)
+    //     if (res.code === 0) {
+    //       this.$message.success('点踩成功.')
+    //       this.unLikeFlagOne.push(id)
+    //       this.lookInfo.unVote++
+    //     } else this.$message.warning(res.msg)
+    //   } else this.$message.warning('您已经踩过了.')
+    // },
+    // 点赞-评论
+    async clickLike (type, id) {
+      if (!this.likeFlag.includes(id)) {
+        const res = await webBbsLike(type, id)
+        if (res.code === 0) {
+          this.$message.success('点赞成功.')
+          this.likeFlag.push(id)
+          this.webBbsMesList(this.formData)
+        } else this.$message.warning(res.msg)
+      } else this.$message.warning('您已经赞过了.')
+    },
+    // 点踩-评论
+    // async clickUnlike (type, id) {
+    //   if (!this.unLikeFlag.includes(id)) {
+    //     const res = await webBbsLike(type, id)
+    //     if (res.code === 0) {
+    //       this.$message.success('点踩成功.')
+    //       this.unLikeFlag.push(id)
+    //       this.webBbsMesList(this.formData)
+    //     } else this.$message.warning(res.msg)
+    //   } else this.$message.warning('您已经踩过了.')
+    // },
+    // 点击回复
+    async reply () {
+      if (this.name2.trim() === '' && this.nameShow) {
+        return this.$message.warning('名字不能为空!')
+      }
+      if (this.editor.txt.html() === '') {
+        return this.$message.warning('内容不能为空')
+      }
+      const res = await webBbsSave({
+        bbsType: 'reply',
+        parentId: this.formData.parentId,
+        content: this.editor.txt.html(),
+        creatorName: this.name2,
+        type: this.lookInfo.type,
+        title: this.lookInfo.title
+      })
+      if (res.code === 0) {
+        this.name2 = ''
+        this.editor.txt.html('')
+        this.$message.success('回帖成功,等待审核.')
+        this.webBbsMesList(this.formData)
+        this.fuTxtShow = false
+      } else this.$message.warning(res.msg)
+    },
+    // 上传图片
+    beforethumbUploadImg (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 5
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('图片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('图片大小超过5M!')
+          reject(file)
+        } else if (file.name.length > 32) {
+          this.$message.error('图片名字不能超过32个字!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_successImg (data) {
+      this.$message.success('上传成功')
+      this.editor.txt.append(
+        `<img src="${this.baseURL}${data.data.urlPath}"  style="max-width:100%;display: block;margin: 10px auto;"/><p><br/></p>`
+      )
+    },
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.webBbsMesList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.webBbsMesList(this.formData)
+    },
+    // 封装获取评论列表的方法
+    async webBbsMesList (data) {
+      const res = await webBbsMesList(data)
+      this.total = res.data.total
+      this.dataArr = res.data.records
+      // 点赞高亮的判断
+      this.dataArr.forEach(v => {
+        this.likeFlag.forEach(p => {
+          if (p === v.id) v.flag = true
+        })
+      })
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {
+    // 初始化富文本
+    // 富文本
+    this.editor = new E('#div1')
+    // 配置字体
+    this.editor.config.fontNames = [
+      '黑体',
+      '仿宋',
+      '楷体',
+      '标楷体',
+      '华文仿宋',
+      '华文楷体',
+      '宋体',
+      '微软雅黑',
+      'Arial',
+      'Tahoma',
+      'Verdana',
+      'Times New Roman'
+    ]
+    this.editor.config.showLinkVideo = false
+    this.editor.create()
+  },
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {
+    this.formData.pageNum = 1
+    this.formData.parentId = this.lookInfo.id
+    this.webBbsMesList(this.formData)
+    // 看看有没有点赞
+    this.likeFlagOne.forEach(v => {
+      if (v === this.lookInfo.id) this.lookInfo.flag = true
+    })
+  } // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+::-webkit-scrollbar {
+  /*滚动条整体样式*/
+  width: 3px; /*高宽分别对应横竖滚动条的尺寸*/
+  height: 0px;
+}
+::-webkit-scrollbar-thumb {
+  /*滚动条里面小方块*/
+  border-radius: 10px;
+  box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+  background: rgba(185, 46, 46, 0.3);
+}
+::-webkit-scrollbar-track {
+  /*滚动条里面轨道*/
+  // box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+  border-radius: 10px;
+  background: #fff9ec;
+}
+.forum_look {
+  border-top: 8px solid #be1220;
+  border-bottom: 8px solid #be1220;
+  padding: 0 12px;
+  background: url("../../assets/img/forBac.png") #f0dbbf center center no-repeat;
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  width: 1200px;
+  height: 650px;
+  .ulTitleBtn {
+    font-size: 18px;
+    color: #fff;
+    cursor: pointer;
+    position: absolute;
+    top: 10px;
+    right: 50px;
+    width: 100px;
+    height: 40px;
+    line-height: 40px;
+    text-align: center;
+    background-color: #f2cd83;
+    border-radius: 5px;
+  }
+  .rowBack {
+    z-index: 100;
+    position: absolute;
+    top: 65px;
+    left: 15px;
+    height: 50px;
+    line-height: 50px;
+    color: #cb444e;
+    cursor: pointer;
+    & > div {
+      background-color: #b92e2e;
+      position: absolute;
+      bottom: 0;
+      left: 10px;
+      width: 1156px;
+      height: 1px;
+    }
+  }
+  .title {
+    color: #fff;
+    display: flex;
+    align-items: center;
+    height: 60px;
+    & > span {
+      font-weight: 700;
+      padding-left: 40px;
+      font-size: 26px;
+    }
+  }
+  .conten {
+    border-radius: 5px 5px 0 0;
+    position: relative;
+    height: 480px;
+    overflow-y: auto;
+    color: #5f5f5f;
+    background-color: rgba(255, 255, 255, 0.3);
+    padding: 10px 50px 20px 30px;
+    .row {
+      padding-top: 10px;
+      position: relative;
+      border-bottom: 1px dashed #d5a6a6;
+      .buddha {
+        margin-left: 30px;
+        text-align: center;
+        position: absolute;
+        width: 130px;
+        height: 50px;
+        overflow: hidden;
+        left: 0px;
+        top: 31px;
+        & > i {
+          width: 50px;
+          height: 50px;
+          line-height: 50px;
+          background-color: #fff;
+          border-radius: 50%;
+          font-size: 30px;
+          color: #e7cfcf;
+        }
+      }
+      & > span {
+        margin-left: 30px;
+        width: 130px;
+        text-align: center;
+        position: absolute;
+        left: 0px;
+        top: 91px;
+      }
+
+      & > h3 {
+        text-align: center;
+      }
+      & > p {
+        width: 80%;
+        margin: 0 0 0 180px;
+        line-height: 26px;
+      }
+      .row_bott {
+        width: 80%;
+        margin: 0 0 0 180px;
+        margin-top: 30px;
+        margin-bottom: 15px;
+        display: flex;
+        justify-content: space-between;
+        & > span {
+          color: #a8a8a8;
+        }
+        .inco {
+          position: absolute;
+          right: 0;
+          bottom: 15px;
+          & > div {
+            cursor: pointer;
+            display: flex;
+            align-items: center;
+          }
+        }
+      }
+    }
+    .rowOne {
+      .row_bott .inco{
+        bottom: 0;
+      }
+      border-bottom: none;
+      &>h3{
+        margin-bottom: 10px;
+      }
+      .buddha {
+        top: 41px;
+      }
+      & > span {
+        top: 101px;
+      }
+      .xian {
+        width: 1136px;
+        position: absolute;
+        bottom: -14px;
+        left: -20px;
+        height: 1px;
+        background-color: #be1220;
+      }
+    }
+    .rowNull {
+      height: 100px;
+      line-height: 100px;
+      font-size: 30px;
+      color: #b9412e;
+      text-align: center;
+    }
+  }
+  .paging {
+    /deep/.el-pager li {
+      background-color: transparent;
+      color: #333333;
+    }
+    /deep/.el-pager li.active {
+      color: #b92e2e;
+    }
+    /deep/.el-pagination button {
+      background-color: transparent;
+    }
+    /deep/.el-pagination button:disabled {
+      background-color: transparent;
+    }
+    border-radius: 0 0 5px 5px;
+    background-color: rgba(255, 255, 255, 0.3);
+    height: 80px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  .bottom {
+    padding: 12px;
+    width: 100%;
+    position: absolute;
+    bottom: 40px;
+    left: 0;
+    .rickTextBack {
+      position: relative;
+      padding-left: 20px;
+      width: 100%;
+      height: 50px;
+      line-height: 50px;
+      color: #cb444e;
+      background-color: rgba(255, 255, 255, 0.3);
+      cursor: pointer;
+      & > div {
+        background-color: #b92e2e;
+        position: absolute;
+        bottom: 0;
+        left: 10px;
+        width: 1156px;
+        height: 1px;
+      }
+    }
+     .rickTextBack {
+      position: relative;
+      padding-left: 20px;
+      width: 100%;
+      height: 50px;
+      line-height: 50px;
+      color: #cb444e;
+      background-color: rgba(255, 255, 255, 0.3);
+      cursor: pointer;
+      & > div {
+        background-color: #b92e2e;
+        position: absolute;
+        bottom: 0;
+        left: 10px;
+        width: 1156px;
+        height: 1px;
+      }
+    }
+    .rickText {
+      width: 100%;
+      background-color: rgba(255, 255, 255, 0.3);
+      padding: 20px;
+      .inputR {
+        position: relative;
+        .imgUplod {
+          /deep/.w-e-icon-image {
+            color: #999;
+            display: inline-block;
+            width: 40px;
+            height: 40px;
+            line-height: 40px;
+          }
+          /deep/.el-upload-list {
+            display: none !important;
+          }
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          cursor: pointer;
+          position: absolute;
+          z-index: 9999;
+          top: 1px;
+          right: 1px;
+          width: 40px;
+          height: 40px;
+          &:hover {
+            background-color: #f6f6f6;
+            /deep/.w-e-icon-image {
+              color: black;
+            }
+          }
+        }
+      }
+      .txtBtn {
+        display: flex;
+        align-items: center;
+        position: relative;
+        margin-top: 20px;
+        /deep/.el-button {
+          width: 120px;
+          height: 40px;
+          position: absolute;
+          right: 20px;
+          bottom: 0;
+          color: #d8b380;
+          font-size: 18px;
+        }
+        .nameCut {
+          cursor: pointer;
+          position: relative;
+          margin-right: 10px;
+          width: 20px;
+          height: 20px;
+          border-radius: 50%;
+          border: 1px solid #b9412e;
+        }
+        .noName{
+          margin-right: 30px;
+        }
+        .active {
+          &::after {
+            content: "";
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            transform: translate(-50%, -50%);
+            width: 15px;
+            height: 15px;
+            border-radius: 50%;
+            background-color: #b9412e;
+          }
+        }
+        /deep/.el-input.is-disabled .el-input__inner{
+          background-color: #e9ebec;
+        }
+      }
+    }
+    /deep/.el-input__inner {
+      background-color: rgba(255, 255, 255, 0.5);
+    }
+    /deep/.el-input__count-inner {
+      background-color: transparent;
+    }
+    // /deep/.w-e-toolbar {
+    //   background-color: rgba(231,218,203) !important;
+    // }
+    // /deep/.w-e-text-container {
+    //   background-color: rgba(231,218,203) !important;
+    // }
+  }
+}
+</style>

+ 63 - 0
houtai/src/views/forumM/index.vue

@@ -0,0 +1,63 @@
+<template>
+  <div class="forumM_index">
+      <keep-alive>
+    <component :is='cutCom' @cutComFn='cutComFn' :lookInfo='lookInfo'></component>
+    <!-- <component :is='cutCom' @cutComFn='cutComFn'></component> -->
+  </keep-alive>
+  </div>
+</template>
+
+<script>
+import List from './list.vue'
+import Look from './look.vue'
+export default {
+  name: 'forumM_index',
+  components: { List, Look },
+  data () {
+    // 这里存放数据
+    return {
+      cutCom: 'List',
+      lookInfo: {}
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 从List组件点击文章触发
+    cutComFn (item, flag) {
+      // 改变is的值切换动态组件
+      if (flag) this.cutCom = 'Look'
+      else this.cutCom = 'List'
+      this.lookInfo = item
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {},
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.forumM_index {
+  background: url("../../assets/imgAdd/mesBac.png");
+  padding: 20px 10px;
+  width: 100vw;
+  height: 100vh;
+  overflow: hidden;
+  /deep/::-webkit-scrollbar {
+    width: 0;
+    height: 0;
+    color: transparent;
+  }
+}
+</style>

+ 511 - 0
houtai/src/views/forumM/list.vue

@@ -0,0 +1,511 @@
+<template>
+  <div class="forumM_list">
+    <h3>论坛</h3>
+    <ul class="topTab">
+      <li
+        :class="{ active: item.id === tabInd }"
+        v-for="item in tab"
+        :key="item.id"
+        @click="cutTab(item)"
+      >
+        {{ item.name }}
+      </li>
+    </ul>
+    <!-- 内容 -->
+
+    <van-list
+      class="conten"
+      v-model="loading"
+      :finished="finished"
+      finished-text="没有更多了"
+      @load="onLoad"
+      :immediate-check="false"
+    >
+      <div
+        class="row"
+        v-for="item in dataArr"
+        :key="item.id"
+        @click="skip(item)"
+      >
+        <div class="row_top">
+          <div class="left">
+            <img src="../../assets/imgAdd/touxiang.png" alt="" />
+            <span>{{ item.creatorName }}</span>
+          </div>
+          <div class="right">{{ item.createTime }}</div>
+        </div>
+        <div class="rowCon">
+          <div class="title">{{ item.title }}</div>
+          <div v-html="item.content" class="txt"></div>
+        </div>
+        <div class="rowFloo">
+          <div class="one">{{ item.reply }}</div>
+          <div
+            class="tow"
+            :class="{ active: item.flag }"
+            @click.stop="likeClick(item)"
+          >
+            {{ item.upVote }}
+          </div>
+        </div>
+      </div>
+    </van-list>
+
+    <!-- 底部的回帖按钮 -->
+    <div class="postMes" @click="postMesShow = true">我 要 发 贴</div>
+
+    <!-- 点击我要发贴出来的发帖页面 -->
+    <div class="postMesShow" v-show="postMesShow">
+      <div class="postMesBack" @click="postMesShow = false">
+        <i class="el-icon-arrow-left"></i>
+        <span>我 要 发 贴</span>
+      </div>
+      <!-- 标题输入框 -->
+      <el-input
+        style="margin: 20px 0 10px"
+        type="text"
+        placeholder="帖子标题字数不能超过30个字。"
+        v-model="title"
+        maxlength="30"
+        show-word-limit
+      >
+      </el-input>
+      <el-select
+        v-model="selectType"
+        placeholder="请选择主题分类"
+        style="width: 100%"
+      >
+        <el-option label="数字史馆" value="scene"></el-option>
+        <el-option label="美丽校园" value="school"></el-option>
+        <el-option label="文物典藏" value="goods"></el-option>
+      </el-select>
+        <!-- 上传图片 -->
+        <el-upload
+          accept=".png,.jpg,.jpeg,.gif"
+          title="上传图片"
+          class="upload-demo imgUplod"
+          :action="baseURL + '/web/bbs/upload'"
+          multiple
+          :before-upload="beforethumbUploadImg"
+          :on-success="upload_thumb_successImg"
+        >
+          <i class="w-e-icon-image"></i>
+        </el-upload>
+      <!-- 富文本 -->
+      <div id="div1" style="z-index: 1">
+      </div>
+      <!-- 底部姓名和按钮 -->
+      <div class="postMesFloo">
+        <el-input
+          style="margin-right: 20px"
+          type="text"
+          placeholder="请填写您的姓名"
+          v-model="creatorName"
+          maxlength="8"
+          show-word-limit
+        >
+        </el-input>
+        <div class="submit" @click="publish">提 交</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from '@/utils/request'
+import E from 'wangeditor'
+import { webBbsList, webBbsVisit, webBbsLike, webBbsSave } from '@/apis/tab8'
+export default {
+  neme: 'forumM_list',
+  components: {},
+  props: {
+    lookInfo: {
+      type: Object,
+      default: () => {}
+    }
+  },
+  data () {
+    // 这里存放数据
+    return {
+      // 服务器前缀地址
+      baseURL: '',
+
+      // vant下拉刷新的数据----------
+      loading: false,
+      finished: false,
+      // vant下拉刷新的数据----------
+      tabInd: 1,
+      tab: [
+        { id: 1, name: '数字史馆', type: 'scene' },
+        { id: 2, name: '美丽校园', type: 'school' },
+        { id: 3, name: '文物典藏', type: 'goods' }
+      ],
+      dataArr: [],
+      formData: {
+        endTime: '',
+        searchKey: '',
+        startTime: '',
+        status: 2,
+        type: 'scene',
+        pageNum: 1,
+        pageSize: 5,
+        bbsType: 'topic'
+      },
+      selectType: 'scene',
+      title: '',
+      creatorName: '',
+      content: '',
+      // 点赞-帖子的开关
+      likeFlagOne: [],
+      // 控制富文本的显示和隐藏
+      postMesShow: false
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 点击发表文章
+    async publish () {
+      if (this.creatorName.trim() === '') {
+        return this.$message.warning('名字不能为空!')
+      }
+      if (this.title.trim() === '') {
+        return this.$message.warning('标题不能为空!')
+      }
+      if (this.editor.txt.html() === '') {
+        return this.$message.warning('内容不能为空')
+      }
+      const res = await webBbsSave({
+        bbsType: 'topic',
+        content: this.editor.txt.html(),
+        creatorName: this.creatorName,
+        title: this.title,
+        type: this.selectType
+      })
+      if (res.code === 0) {
+        this.title = this.creatorName = ''
+        this.editor.txt.html('')
+        this.$message.success('发帖成功,等待审核.')
+        this.fuTxtShow = false
+      } else this.$message.warning(res.msg)
+    },
+    // 上传图片
+    beforethumbUploadImg (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 5
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('图片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('图片大小超过5M!')
+          reject(file)
+        } else if (file.name.length > 32) {
+          this.$message.error('图片名字不能超过32个字!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_successImg (data) {
+      this.$message.success('上传成功')
+      this.editor.txt.append(
+        `<img src="${this.baseURL}${data.data.urlPath}"  style="max-width:100%;display: block;margin: 10px auto;"/><p><br/></p>`
+      )
+    },
+    // vant下拉刷新触发的函数
+    onLoad () {
+      this.formData.pageNum++
+      this.webBbsList(this.formData)
+    },
+    // 封装消息提示函数
+    notify (message, type) {
+      this.$notify({
+        message,
+        position: 'bottom-right',
+        type,
+        duration: 1000
+      })
+    },
+    // 点击点赞
+    async likeClick (item) {
+      if (!this.likeFlagOne.includes(item.id)) {
+        const res = await webBbsLike('upVote', item.id)
+        if (res.code === 0) {
+          this.notify('点赞成功', 'success')
+          this.likeFlagOne.push(item.id)
+          item.upVote++
+          item.flag = true
+        } else this.notify(res.msg, 'warning')
+      } else this.notify('您已经赞过了', 'warning')
+    },
+    // 点击通知父组件切换 动态组件is的值,并且把数据传过去
+    async skip (item) {
+      await webBbsVisit(item.id)
+      const temp = document.querySelector('.conten')
+      this.$emit('cutComFn', { ...item, scrollTop: temp.scrollTop }, true)
+    },
+    cutTab (item) {
+      this.dataArr = []
+      this.tabInd = item.id
+      this.formData.type = item.type
+      this.formData.pageNum = 1
+      this.webBbsList(this.formData)
+      this.finished = false
+      // 让下面的下拉框同步
+      this.selectType = item.type
+      // 回到屏幕顶点
+      // const temp = document.querySelector('.conten')
+      // temp.scrollTo({ top: 0 })
+      // console.log('-----------')
+      // window.scrollTo({ top: 0 })
+    },
+    // 封装获取列表的方法
+    async webBbsList (data) {
+      const res = await webBbsList(data)
+      res.data.records.forEach((v) => {
+        this.dataArr.push(v)
+      })
+      this.loading = false
+      if (res.data.records.length < 5 || this.dataArr.length >= res.data.total) this.finished = true
+      this.likeFlagOne.forEach((p) => {
+        this.dataArr.forEach((v) => {
+          if (p === v.id) v.flag = true
+        })
+      })
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 调用获取列表方法
+    this.webBbsList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {
+    // 初始化富文本
+    // 富文本
+    this.editor = new E('#div1')
+    // 配置字体
+    this.editor.config.fontNames = [
+      '黑体',
+      '仿宋',
+      '楷体',
+      '标楷体',
+      '华文仿宋',
+      '华文楷体',
+      '宋体',
+      '微软雅黑',
+      'Arial',
+      'Tahoma',
+      'Verdana',
+      'Times New Roman'
+    ]
+    this.editor.config.showLinkVideo = false
+    this.editor.create()
+  },
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {
+    if (this.lookInfo.scrollTop) {
+      const temp = document.querySelector('.conten')
+      temp.scrollTo({ top: this.lookInfo.scrollTop })
+    }
+  } // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.forumM_list {
+  width: 100%;
+  height: 100%;
+  & > h3 {
+    font-size: 20px;
+    margin-left: 10px;
+  }
+  .topTab {
+    margin: 10px;
+    display: flex;
+    & > li {
+      margin-right: 15px;
+      height: 26px;
+      line-height: 26px;
+      width: 100px;
+      color: #a19d97;
+      text-align: center;
+    }
+    .active {
+      border-radius: 13px;
+      background-color: #b92e2e;
+      color: #fff;
+    }
+  }
+  .conten {
+    width: 100%;
+    height: calc(100vh - 162px);
+    overflow-y: auto;
+    .row {
+      margin-bottom: 10px;
+      padding: 8px;
+      padding-bottom: 0;
+      background-color: rgba(255, 255, 255, 0.3);
+      .row_top {
+        display: flex;
+        justify-content: space-between;
+        .left {
+          & > img {
+            margin-right: 10px;
+            width: 36px;
+            height: 36px;
+          }
+          & > span {
+            font-size: 14px;
+            vertical-align: top;
+          }
+        }
+        .right {
+          font-size: 12px;
+          color: #a19d97;
+        }
+      }
+      .rowCon {
+        .title {
+          font-weight: 700;
+          margin: 10px 0;
+        }
+        .txt {
+          font-size: 14px;
+          padding-bottom: 10px;
+          border-bottom: 1px solid #c0b19c;
+        }
+      }
+      .rowFloo {
+        padding: 0 10px;
+        display: flex;
+        justify-content: space-between;
+        & > div {
+          padding-left: 30px;
+          height: 40px;
+          line-height: 40px;
+        }
+        .one {
+          background: url("../../assets/imgAdd/comment.png") no-repeat left
+            center;
+        }
+        .tow {
+          background: url("../../assets/imgAdd/like.png") no-repeat left center;
+        }
+        .active {
+          background: url("../../assets/imgAdd/likeAc.png") no-repeat left
+            center;
+        }
+      }
+    }
+  }
+  .postMes {
+    margin-top: 10px;
+    background-color: #b92e2e;
+    text-align: center;
+    width: 100%;
+    height: 50px;
+    line-height: 50px;
+    color: #fff;
+  }
+  .postMesShow {
+    padding: 20px;
+    background: url("../../assets/imgAdd/mesBac.png") #f3e9d9;
+    z-index: 999;
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100vw;
+    height: 100vh;
+    .postMesBack {
+      display: flex;
+      align-items: center;
+      font-size: 30px;
+      font-weight: 700;
+      & > span {
+        font-size: 20px;
+      }
+    }
+    /deep/.el-input__inner {
+      background-color: rgba(255, 255, 255, 0.5);
+    }
+    /deep/.el-input__count-inner {
+      background-color: transparent;
+    }
+    // /deep/.w-e-toolbar {
+    //   background-color: rgba(255, 255, 255, 0.5) !important;
+    // }
+    // /deep/.w-e-text-container {
+    //   background-color: rgba(255, 255, 255, 0.5) !important;
+    // }
+    /deep/.w-e-toolbar .w-e-menu {
+      display: none !important;
+    }
+    /deep/.w-e-toolbar .w-e-menu:nth-of-type(17) {
+      display: flex !important;
+    }
+
+      .imgUplod {
+        /deep/.w-e-icon-image {
+          color: #999;
+          display: inline-block;
+          width: 40px;
+          height: 40px;
+          line-height: 40px;
+        }
+        /deep/.el-upload-list {
+          display: none !important;
+        }
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        cursor: pointer;
+        position: absolute;
+        z-index: 9999;
+        top: 170px;
+        left: 70px;
+        width: 40px;
+        height: 40px;
+      }
+    #div1 {
+      height: calc(100vh - 240px);
+      margin-top: 10px;
+      /deep/.w-e-text-container{
+        height: calc(100% - 45px) !important;
+      }
+    }
+    .postMesFloo {
+      margin-top: 10px;
+      display: flex;
+      justify-content: space-between;
+      .submit {
+        margin-top: 2px;
+        width: 60px;
+        height: 36px;
+        line-height: 36px;
+        text-align: center;
+        color: #fff;
+        background-color: #b92e2e;
+        border-radius: 5px;
+      }
+    }
+  }
+}
+</style>

+ 465 - 0
houtai/src/views/forumM/look.vue

@@ -0,0 +1,465 @@
+<template>
+  <div class="forumM_look">
+    <!-- 返回按钮和标题 -->
+    <div class="postMesBackTop" @click="$emit('cutComFn', lookInfo, false)">
+      <i class="el-icon-arrow-left"></i>
+      <span>{{ lookInfo.title }}</span>
+    </div>
+    <!-- 内容 -->
+    <!-- 没有数据的时候 -->
+    <div class="conten null" :class="{offsetHeight:offsetHeight}" v-if="dataArr.length === 0">暂无回帖</div>
+    <van-list
+      v-else
+      :class="{offsetHeight:offsetHeight}"
+      class="conten"
+      v-model="loading"
+      :finished="finished"
+      finished-text="没有更多了"
+      @load="onLoad"
+      :immediate-check="false"
+    >
+      <div class="row" v-for="item in dataArr" :key="item.id">
+        <div class="row_top">
+          <div class="left">
+            <img src="../../assets/imgAdd/touxiang.png" alt="" />
+            <div>
+              <p>{{ item.creatorName }}</p>
+              <p class="right">{{ item.createTime }}</p>
+            </div>
+          </div>
+          <div class="rowFloo" @click="clickLike(item)">
+            <div class="tow" :class="{ active: item.flag }">
+              {{ item.upVote }}
+            </div>
+          </div>
+        </div>
+        <div class="rowCon">
+          <div class="title">{{ item.title }}</div>
+          <div v-html="item.content" class="txt"></div>
+        </div>
+      </div>
+    </van-list>
+
+    <!-- 底部的回帖按钮 -->
+    <div class="postMes" @click="postMesShow = true">我 要 回 贴</div>
+
+    <!-- 点击我要发贴出来的发帖页面 -->
+    <div class="postMesShow" v-show="postMesShow">
+      <div class="postMesBack" @click="postMesShow = false">
+        <i class="el-icon-arrow-left"></i>
+        <span>我 要 回 贴</span>
+      </div>
+      <!-- 上传图片 -->
+      <el-upload
+        accept=".png,.jpg,.jpeg,.gif"
+        title="上传图片"
+        class="upload-demo imgUplod"
+        :action="baseURL + '/web/bbs/upload'"
+        multiple
+        :before-upload="beforethumbUploadImg"
+        :on-success="upload_thumb_successImg"
+      >
+        <i class="w-e-icon-image"></i>
+      </el-upload>
+      <!-- 富文本 -->
+      <div id="div2" style="z-index: 1"></div>
+      <!-- 底部姓名和按钮 -->
+      <div class="postMesFloo">
+        <el-input
+          style="margin-right: 20px"
+          type="text"
+          placeholder="请填写您的姓名"
+          v-model="name2"
+          maxlength="8"
+          show-word-limit
+        >
+        </el-input>
+        <div class="submit" @click="publish">提 交</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from '@/utils/request'
+import E from 'wangeditor'
+import { webBbsMesList, webBbsLike, webBbsSave } from '@/apis/tab8'
+export default {
+  name: 'forumM_look',
+  // import引入的组件需要注入到对象中才能使用
+  components: {},
+  props: {
+    lookInfo: {
+      type: Object,
+      default: () => {}
+    }
+  },
+  data () {
+    // 这里存放数据
+    return {
+      // 头部高度的变化
+      offsetHeight: false,
+      // 控制富文本的显示和隐藏
+      postMesShow: false,
+      name2: '',
+      content: '',
+      // 服务器前缀地址
+      baseURL: '',
+      // 点赞-帖子的开关
+      likeFlag: [],
+
+      formData: {
+        parentId: null,
+        pageNum: 1,
+        pageSize: 5
+      },
+      // vant下拉刷新的数据----------
+      loading: false,
+      finished: false,
+      // vant下拉刷新的数据----------
+      dataArr: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 点击发表文章
+    async publish () {
+      if (this.name2.trim() === '') {
+        return this.$message.warning('名字不能为空!')
+      }
+      if (this.editor.txt.html() === '') {
+        return this.$message.warning('内容不能为空')
+      }
+      const res = await webBbsSave({
+        bbsType: 'reply',
+        parentId: this.formData.parentId,
+        content: this.editor.txt.html(),
+        creatorName: this.name2,
+        type: this.lookInfo.type,
+        title: this.lookInfo.title
+      })
+      if (res.code === 0) {
+        this.name2 = ''
+        this.editor.txt.html('')
+        this.$message.success('回帖成功,等待审核.')
+        this.webBbsMesList(this.formData)
+        this.fuTxtShow = false
+      } else this.$message.warning(res.msg)
+    },
+    // 上传图片
+    beforethumbUploadImg (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 5
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('图片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('图片大小超过5M!')
+          reject(file)
+        } else if (file.name.length > 32) {
+          this.$message.error('图片名字不能超过32个字!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_successImg (data) {
+      this.$message.success('上传成功')
+      this.editor.txt.append(
+        `<img src="${this.baseURL}${data.data.urlPath}"  style="max-width:100%;display: block;margin: 10px auto;"/><p><br/></p>`
+      )
+    },
+
+    // 封装消息提示函数
+    notify (message, type) {
+      this.$notify({
+        message,
+        position: 'bottom-right',
+        type,
+        duration: 1000
+      })
+    },
+    // 点击点赞
+    async clickLike (item) {
+      console.log('--------')
+      if (!this.likeFlag.includes(item.id)) {
+        const res = await webBbsLike('upVote', item.id)
+        if (res.code === 0) {
+          this.notify('点赞成功', 'success')
+          this.likeFlag.push(item.id)
+          item.upVote++
+          item.flag = true
+        } else this.notify(res.msg, 'warning')
+      } else this.notify('您已经赞过了', 'warning')
+    },
+    onLoad () {
+      this.formData.pageNum++
+      this.webBbsMesList(this.formData)
+    },
+    // 封装获取评论列表的方法
+    async webBbsMesList (data) {
+      const res = await webBbsMesList(data)
+      res.data.records.forEach((v) => {
+        this.dataArr.push(v)
+      })
+      this.loading = false
+      if (
+        res.data.records.length < 5 ||
+        this.dataArr.length >= res.data.total
+      ) {
+        this.finished = true
+      }
+      // 点赞高亮的判断
+      this.dataArr.forEach((v) => {
+        this.likeFlag.forEach((p) => {
+          if (p === v.id) v.flag = true
+        })
+      })
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {
+    // 初始化富文本
+    // 富文本
+    this.editor = new E('#div2')
+    // 配置字体
+    this.editor.config.fontNames = [
+      '黑体',
+      '仿宋',
+      '楷体',
+      '标楷体',
+      '华文仿宋',
+      '华文楷体',
+      '宋体',
+      '微软雅黑',
+      'Arial',
+      'Tahoma',
+      'Verdana',
+      'Times New Roman'
+    ]
+    this.editor.config.showLinkVideo = false
+    this.editor.create()
+  },
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {
+    this.dataArr = []
+    this.finished = false
+    this.formData.pageNum = 1
+    this.formData.parentId = this.lookInfo.id
+    this.webBbsMesList(this.formData)
+    // 获取头部的高度
+    const temp = document.querySelector('.postMesBackTop')
+    if (temp.offsetHeight > 40) this.offsetHeight = true
+    else this.offsetHeight = false
+  } // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.forumM_look {
+  width: 100%;
+  height: 100%;
+  .postMesBackTop {
+    margin-bottom: 20px;
+    padding-right: 80px;
+    display: flex;
+    align-items: center;
+    font-size: 30px;
+    font-weight: 700;
+    & > span {
+      font-size: 20px;
+      display: -webkit-box;
+      overflow: hidden;
+      white-space: normal !important;
+      text-overflow: ellipsis;
+      word-wrap: break-word;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical;
+    }
+  }
+  .conten {
+    width: 100%;
+    height: calc(100vh - 140px);
+    overflow-y: auto;
+    .row {
+      margin-bottom: 10px;
+      padding: 8px;
+      padding-bottom: 0;
+      border-bottom: 1px dashed #fff;
+      .row_top {
+        display: flex;
+        justify-content: space-between;
+        .left {
+          max-width: 200px;
+          display: flex;
+          & > img {
+            margin-right: 10px;
+            width: 36px;
+            height: 36px;
+          }
+          & > div {
+            & > p {
+              font-size: 14px;
+              vertical-align: top;
+            }
+            .right {
+              margin-top: 5px;
+              font-size: 12px;
+              color: #a19d97;
+            }
+          }
+        }
+        .rowFloo {
+          padding: 0 10px;
+          display: flex;
+          justify-content: space-between;
+          & > div {
+            padding-left: 30px;
+            height: 40px;
+            line-height: 40px;
+          }
+          .tow {
+            background: url("../../assets/imgAdd/like.png") no-repeat left
+              center;
+          }
+          .active {
+            background: url("../../assets/imgAdd/likeAc.png") no-repeat left
+              center;
+          }
+        }
+      }
+      .rowCon {
+        .title {
+          font-weight: 700;
+          margin: 10px 0;
+        }
+        .txt {
+          font-size: 14px;
+          padding-bottom: 10px;
+        }
+      }
+    }
+  }
+  .null {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 30px;
+  }
+  .offsetHeight{
+    height: calc(100vh - 162px);
+  }
+  .postMes {
+    margin-top: 10px;
+    background-color: #b92e2e;
+    text-align: center;
+    width: 100%;
+    height: 50px;
+    line-height: 50px;
+    color: #fff;
+  }
+  .postMesShow {
+    padding: 20px;
+    background: url("../../assets/imgAdd/mesBac.png") #f3e9d9;
+    z-index: 999;
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100vw;
+    height: 100vh;
+    .postMesBack {
+      display: flex;
+      align-items: center;
+      font-size: 30px;
+      font-weight: 700;
+      & > span {
+        font-size: 20px;
+      }
+    }
+    /deep/.el-input__inner {
+      background-color: rgba(255, 255, 255, 0.5);
+    }
+    /deep/.el-input__count-inner {
+      background-color: transparent;
+    }
+    // /deep/.w-e-toolbar {
+    //   background-color: rgba(255, 255, 255, 0.5) !important;
+    // }
+    // /deep/.w-e-text-container {
+    //   background-color: rgba(255, 255, 255, 0.5) !important;
+    // }
+    /deep/.w-e-toolbar .w-e-menu {
+      display: none !important;
+    }
+    /deep/.w-e-toolbar .w-e-menu:nth-of-type(17) {
+      display: flex !important;
+    }
+
+    .imgUplod {
+      /deep/.w-e-icon-image {
+        color: #999;
+        display: inline-block;
+        width: 40px;
+        height: 40px;
+        line-height: 40px;
+      }
+      /deep/.el-upload-list {
+        display: none !important;
+      }
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      cursor: pointer;
+      position: absolute;
+      z-index: 9999;
+      top: 60px;
+      left: 70px;
+      width: 40px;
+      height: 40px;
+    }
+    #div2 {
+      height: calc(100vh - 124px);
+      margin-top: 10px;
+      /deep/.w-e-text-container {
+        height: calc(100% - 45px) !important;
+      }
+    }
+    .postMesFloo {
+      margin-top: 10px;
+      display: flex;
+      justify-content: space-between;
+      .submit {
+        margin-top: 2px;
+        width: 60px;
+        height: 36px;
+        line-height: 36px;
+        text-align: center;
+        color: #fff;
+        background-color: #b92e2e;
+        border-radius: 5px;
+      }
+    }
+  }
+}
+</style>

+ 356 - 0
houtai/src/views/layout/index.vue

@@ -0,0 +1,356 @@
+<template>
+  <div class="layout">
+    <div class="top">
+      <img src="@/assets/img/logo.png" alt="" />
+      <p>中国人民解放军陆军勤务学院</p>
+      <div class="top_right">
+        <div class="user" @click="cut = !cut">
+          <img src="@/assets/img/user.jpg" alt="" />
+          <span>{{ userName }}</span>
+          <!-- 下箭头 -->
+          <div class="pull_down" v-if="cut"></div>
+          <div class="pull_up" v-else></div>
+        </div>
+        <!-- 点击箭头出来的ul -->
+        <ul class="user_handle" v-show="cut">
+          <li @click="isShow = true">修改密码</li>
+          <li @click="outLogin">退出登录</li>
+        </ul>
+      </div>
+    </div>
+    <div class="con">
+      <div class="left">
+        <div class="biaoji">内容管理</div>
+        <ul>
+          <li
+            v-for="item in tab1"
+            :key="item.id"
+            :class="{ active: $route.meta.myInd === item.id }"
+            @click="push(item.url)"
+          >
+            {{ item.name }}
+          </li>
+        </ul>
+        <div class="biaoji">审核管理</div>
+        <ul>
+          <li
+            v-for="item in tab3"
+            :key="item.id"
+            :class="{ active: $route.meta.myInd === item.id }"
+            @click="push(item.url)"
+          >
+            {{ item.name }}
+          </li>
+        </ul>
+        <div class="biaoji">系统管理</div>
+        <ul>
+          <li
+            v-for="item in tab2"
+            :key="item.id"
+            :class="{ active: $route.meta.myInd === item.id }"
+            @click="push(item.url)"
+          >
+            {{ item.name }}
+          </li>
+        </ul>
+      </div>
+      <!-- 右侧内容 -->
+      <div class="right" @click="cut = false">
+        <Router-view />
+      </div>
+    </div>
+    <!-- 点击修改密码出现弹窗 -->
+    <el-dialog title="修改密码" :visible.sync="isShow" @close="btnX()">
+      <el-form :model="form" label-width="100px" :rules="rules" ref="ruleForm">
+        <el-form-item label="旧密码:" prop="oldPassword">
+          <el-input
+            v-model="form.oldPassword"
+            placeholder="请输入"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="新密码:" prop="newPassword">
+          <el-input
+            v-model="form.newPassword"
+            placeholder="请输入"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="确定新密码:" prop="checkPass">
+          <el-input
+            v-model="form.checkPass"
+            placeholder="请输入"
+            show-password
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="btnX">取 消</el-button>
+        <el-button type="primary" @click="btnOk">确 定</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { encodeStr } from '../../utils/pass'
+import { Base64 } from 'js-base64'
+import { updatePwd } from '@/apis/login'
+export default {
+  name: 'layout',
+  components: {},
+  data () {
+    // 这里存放数据
+    const validatePass2 = (rule, value, callback) => {
+      if (value !== this.form.newPassword) {
+        callback(new Error('两次输入密码不一致!'))
+      } else {
+        callback()
+      }
+    }
+    return {
+      // 修改密码
+      form: {
+        oldPassword: '',
+        newPassword: '',
+        checkPass: ''
+      },
+      rules: {
+        checkPass: [{ validator: validatePass2, trigger: 'blur' }],
+        oldPassword: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        newPassword: [
+          { required: true, message: '不能为空', trigger: 'blur' },
+          { max: 15, message: '不能超过15个字', trigger: 'blur' }
+        ]
+      },
+      userName: '',
+      cut: false,
+      isShow: false,
+      tab1: [
+        { name: '文物典藏管理', id: 1, url: '/layout/tab1' },
+        { name: '学院领导管理', id: 2, url: '/layout/tab2' },
+        { name: '学籍管理', id: 3, url: '/layout/tab3' },
+        { name: '学院宣传片管理', id: 4, url: '/layout/tab4' },
+        { name: '校园图片管理', id: 5, url: '/layout/tab5' },
+        { name: '校歌管理', id: 6, url: '/layout/tab6' }
+      ],
+      tab2: [{ name: '操作日志', id: 9, url: '/layout/tab9' }],
+      tab3: [
+        { name: '留言审核', id: 7, url: '/layout/tab7' },
+        { name: '发帖审核', id: 8, url: '/layout/tab8' }
+      ]
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 修改密码点击取消
+    btnX () {
+      this.$refs.ruleForm.resetFields()
+      this.cut = false
+      this.isShow = false
+      this.form = {
+        oldPassword: '',
+        newPassword: '',
+        checkPass: ''
+      }
+    },
+    // 修改密码点击确定
+    async btnOk () {
+      await this.$refs.ruleForm.validate()
+      try {
+        const data = {
+          oldPassword: encodeStr(Base64.encode(this.form.oldPassword)),
+          newPassword: encodeStr(Base64.encode(this.form.newPassword))
+        }
+        const res = await updatePwd(data)
+        if (res.code === 0) {
+          this.$message.success('修改成功')
+          localStorage.clear('SWKK_token')
+          localStorage.clear('SWKK_userInfo')
+          this.$router.push('/')
+        } else this.$message.warning(res.msg)
+      } catch (error) {
+        this.$message.error('旧密码错误')
+      }
+    },
+    push (url) {
+      this.$router.push(url).catch(() => {})
+    },
+    // 点击退出登录
+    outLogin () {
+      this.cut = false
+      this.$confirm('确定退出吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(() => {
+          localStorage.clear('CQLJXU_token')
+          localStorage.clear('CQLJXU_userName')
+          this.$router.push('/')
+          this.$message.success('退出成功!')
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取用户名
+    const res = localStorage.getItem('CQLJXU_userName')
+    this.userName = res
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.layout {
+  .top {
+    position: relative;
+    width: 100%;
+    min-width: 1800px;
+    box-shadow: 1px 3px 3px 3px rgb(196, 177, 177);
+    height: 70px;
+    background-color: #b9412e;
+    display: flex;
+    align-items: center;
+    & > img {
+      width: 50px;
+      // height: 60px;
+      border-radius: 50%;
+      overflow: hidden;
+      margin: 0 10px 0 30px;
+    }
+    & > P {
+      color: #fff;
+      font-size: 24px;
+      font-weight: 700;
+    }
+    .top_right {
+      width: 150px;
+      position: absolute;
+      right: 30px;
+      top: 0;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      .user {
+        color: #fff;
+        cursor: pointer;
+        position: relative;
+        display: flex;
+        align-items: center;
+        img {
+          margin-right: 15px;
+          width: 34px;
+          height: 34px;
+          border-radius: 50%;
+          overflow: hidden;
+        }
+        .pull_down {
+          position: absolute;
+          right: -25px;
+          bottom: 10px;
+          display: inline-block;
+          width: 0;
+          height: 0;
+          border-left: 8px solid transparent;
+          border-right: 8px solid transparent;
+          border-bottom: 8px solid #fff;
+        }
+        .pull_up {
+          cursor: pointer;
+          position: absolute;
+          right: -25px;
+          bottom: 10px;
+          display: inline-block;
+          width: 0;
+          height: 0;
+          border-left: 8px solid transparent;
+          border-right: 8px solid transparent;
+          border-top: 8px solid #fff;
+        }
+      }
+      .user_handle {
+        z-index: 999;
+        padding: 10px 40px;
+        position: absolute;
+        right: 0;
+        bottom: -90px;
+        background-color: #b9412e;
+        li {
+          color: #fff;
+          cursor: pointer;
+          margin: 10px 0;
+        }
+        li:hover {
+          color: orange;
+        }
+      }
+    }
+  }
+  .con {
+    background-color: #f2f2f2;
+    display: flex;
+    width: 100%;
+    padding: 30px 30px 0;
+    height: calc(100vh - 70px);
+  }
+  .left {
+    min-width: 220px;
+    width: 220px;
+    height: 100%;
+    min-height: 800px;
+    background-color: #fff;
+    padding-top: 15px;
+    .biaoji {
+      height: 40px;
+      background-color: #b9412e;
+      width: 90%;
+      border-radius: 0 40px 40px 0;
+      color: #fff;
+      font-weight: 700;
+      font-size: 20px;
+      line-height: 40px;
+      padding-left: 50px;
+    }
+    ul {
+      li {
+        cursor: pointer;
+        padding-left: 50px;
+        margin: 30px 0;
+        &:hover {
+          color: #b9412e;
+        }
+      }
+      .active {
+        color: #b9412e;
+      }
+    }
+  }
+  .right {
+    position: relative;
+    padding: 20px 0;
+    min-width: 1500px;
+    flex: 1;
+    margin-left: 30px;
+    background-color: #fff;
+    height: 100%;
+    min-height: 800px;
+  }
+}
+</style>

+ 153 - 0
houtai/src/views/login.vue

@@ -0,0 +1,153 @@
+<!--  -->
+<template>
+<div class='login'>
+  <div class="top">
+    <img src="../assets/img/logo.png" alt="">
+    <p>中国人民解放军陆军勤务学院</p>
+  </div>
+  <div class="con">
+    <div class="left">
+      <p>中国人民解放军陆军勤务学院</p>
+      <p>管理后台</p>
+    </div>
+    <div class="right">
+      <p>欢迎登录</p>
+      <div class="row">
+        <el-input v-model="from.userName" placeholder="账号"></el-input>
+      </div>
+      <div class="row">
+        <el-input v-model="from.passWord" placeholder="密码" show-password></el-input>
+      </div>
+      <div class="btn" @click="login">登 录</div>
+    </div>
+  </div>
+</div>
+</template>
+
+<script>
+import { encodeStr } from '../utils/pass'
+import { Base64 } from 'js-base64'
+import { userLogin } from '@/apis/login'
+export default {
+  name: 'login',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      from: {
+        userName: '',
+        passWord: ''
+      }
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    async login () {
+      if (this.from.userName.trim() === '') return this.$message.warning('账号不能为空!')
+      if (this.from.passWord.trim() === '') return this.$message.warning('密码不能为空!')
+      const data = {
+        userName: this.from.userName,
+        passWord: encodeStr(Base64.encode(this.from.passWord))
+      }
+      const res = await userLogin(data)
+      if (res.code === 0) {
+        localStorage.setItem('CQLJXU_token', res.data.token)
+        localStorage.setItem('CQLJXU_userName', res.data.user.userName)
+        this.$router.push('/layout/tab1')
+        this.$message.success('登录成功')
+      } else this.$message.warning(res.msg)
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {
+
+  },
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.login{
+  .top{
+    box-shadow: 1px 3px 3px 3px rgb(196, 177, 177);
+    height: 70px;
+    background-color: #b9412e;
+    display: flex;
+    align-items: center;
+    &>img {
+      width: 50px;
+      // height: 60px;
+      border-radius: 50%;
+      overflow: hidden;
+      margin: 0 10px 0 30px;
+    }
+    &>P {
+      color: #fff;
+      font-size: 24px;
+      font-weight: 700;
+    }
+  }
+  .con{
+    display: flex;
+    margin: 180px auto 0;
+    width: 700px;
+    height: 500px;
+    border: 1px solid #ccc;
+    .left{
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      width: 350px;
+      height: 100%;
+      background-color: #b9412e;
+      &>p{
+        width: 80%;
+        margin: 0 auto;
+        margin-bottom: 30px;
+        color: #fff;
+        font-weight: 700;
+        text-align: center;
+        font-size: 30px;
+      }
+    }
+    .right{
+      width: 350px;
+      &>p {
+        font-size: 24px;
+        text-align: center;
+        margin-top: 100px;
+      }
+      .row{
+        width: 90%;
+        margin: 50px auto;
+      }
+      .btn {
+        cursor: pointer;
+        width: 90%;
+        height: 40px;
+        line-height: 40px;
+        text-align: center;
+        margin: 50px auto 0;
+        background-color: #b9412e;
+        border-radius: 8px;
+        color: #fff;
+
+      }
+    }
+  }
+}
+
+</style>

+ 320 - 0
houtai/src/views/message/index.vue

@@ -0,0 +1,320 @@
+<template>
+  <div class="message">
+    <div class="conten">
+      <h2 class="title">留 言 板</h2>
+      <ul class="liuyan" v-if="data.length > 0">
+        <li v-for="item in data" :key="item.id">
+          <div class="name">{{ item.creatorName }}</div>
+          <div class="con">{{ item.content }}</div>
+          <div class="time">{{ item.createTime }}</div>
+        </li>
+      </ul>
+      <!-- 没有数据的时候提示 -->
+      <div class="liuyan noneTxt" v-else>暂无数据</div>
+      <!-- 分页器 -->
+      <div class="pagination">
+        <el-pagination
+          layout="prev, pager, next"
+          :total="total"
+          @current-change="currentChange"
+        >
+        </el-pagination>
+      </div>
+      <!-- 文本域和按钮 -->
+      <div class="bottmInp">
+        <div class="texe">
+          <el-input
+            maxlength="100"
+            show-word-limit
+            resize="none"
+            type="textarea"
+            :rows="3"
+            placeholder="欢迎提交您的珍贵留言,100字以内~"
+            v-model="textarea"
+          >
+          </el-input>
+        </div>
+        <div class="button">
+          <div class="button_left">
+            <div class="biaoji"></div>
+            <el-input
+              style="width: 270px"
+              type="text"
+              placeholder="请填写您的姓名"
+              v-model="name"
+              maxlength="8"
+              show-word-limit
+            >
+            </el-input>
+          </div>
+          <el-button
+            style="width: 120px; color: #d7b07e"
+            type="primary"
+            @click="commentSave"
+            >提 交</el-button
+          >
+        </div>
+      </div>
+    </div>
+    <ul>
+      <li>
+        <span></span>
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script>
+import { commentSave, commentWebList } from '@/apis/tab7'
+export default {
+  name: 'message',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      textarea: '',
+      name: '',
+      data: [],
+      total: 0,
+      formData: {
+        startTime: '',
+        endTime: '',
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: '',
+        status: 2
+      }
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.commentWebList(this.formData)
+    },
+    // 点击提交留言
+    async commentSave () {
+      if (this.textarea.trim() === '') { return this.$message.warning('内容不能为空!') }
+      if (this.name.trim() === '') { return this.$message.warning('名字不能为空!') }
+      const res = await commentSave({
+        content: this.textarea,
+        creatorName: this.name
+      })
+      if (res.code === 0) {
+        this.textarea = this.name = ''
+        this.$message.success('提交成功,等待审核.')
+      } else this.$message.warning(res.msg)
+    },
+    // 封装获取列表的方法
+    async commentWebList (data) {
+      const res = await commentWebList(data)
+      this.total = res.data.total
+      res.data.records.forEach((v) => {
+        v.createTime = v.createTime.substring(0, v.createTime.length - 3)
+      })
+      this.data = res.data.records
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    this.commentWebList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+/deep/.el-input__inner::-webkit-input-placeholder {
+  color: #878787 !important;
+}
+/deep/.el-input__inner:-moz-placeholder {
+  color: #878787 !important;
+}
+/deep/.el-input__inner::-moz-placeholder {
+  color: #878787 !important;
+}
+/deep/.el-input__inner:-ms-input-placeholder {
+  /* Internet Explorer 10+ */
+  color: #878787 !important;
+}
+/deep/.el-textarea__inner::-webkit-input-placeholder {
+  color: #878787 !important;
+}
+/deep/.el-textarea__inner:-moz-placeholder {
+  color: #878787 !important;
+}
+/deep/.el-textarea__inner::-moz-placeholder {
+  color: #878787 !important;
+}
+/deep/.el-textarea__inner:-ms-input-placeholder {
+  /* Internet Explorer 10+ */
+  color: #878787 !important;
+}
+.message {
+  position: relative;
+  margin: 0 auto;
+  width: 1000px;
+  height: 100vh;
+  min-height: 650px;
+  .conten {
+    background: url("../../assets/img/mesBac.png");
+    background-size: 100% 100%;
+    border-top: 8px solid #be1220;
+    border-bottom: 8px solid #be1220;
+    /deep/.el-button--primary {
+      background-color: #b92e2e;
+      width: 100%;
+      height: 40px;
+    }
+    /deep/.el-pager li {
+      background-color: transparent;
+      color: #333333;
+    }
+    /deep/.el-pager li.active {
+      color: #b92e2e;
+    }
+    /deep/.el-pagination button {
+      background-color: transparent;
+    }
+    /deep/.el-pagination button:disabled {
+      background-color: transparent;
+    }
+
+    position: absolute;
+    top: 50%;
+    left: 0;
+    transform: translateY(-50%);
+    width: 100%;
+    height: 650px;
+    background-color: #fff;
+    padding: 20px;
+    .title {
+      padding-left: 20px;
+      color: #fff;
+    }
+    .liuyan::-webkit-scrollbar {
+      /*滚动条整体样式*/
+      width: 3px; /*高宽分别对应横竖滚动条的尺寸*/
+      height: 1px;
+    }
+    .liuyan::-webkit-scrollbar-thumb {
+      /*滚动条里面小方块*/
+      border-radius: 10px;
+      box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+      background: rgba(185, 46, 46, 0.3);
+    }
+    .liuyan::-webkit-scrollbar-track {
+      /*滚动条里面轨道*/
+      // box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+      border-radius: 10px;
+      background: transparent;
+    }
+    .liuyan {
+      background-color: rgba(255, 255, 255, 0.3);
+      padding-right: 20px;
+      margin: 20px 20px 0;
+      padding: 15px;
+      height: 320px;
+      overflow-y: auto;
+      li {
+        border-bottom: 1px dashed #b92e2e;
+        color: #878787;
+        font-size: 16px;
+        display: flex;
+        & > div {
+          padding: 12px 0;
+        }
+        .name {
+          width: 140px;
+        }
+        .con {
+          flex: 1;
+          margin-right: 20px;
+        }
+        .time {
+          width: 140px;
+        }
+      }
+    }
+    .noneTxt {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      font-size: 26px;
+    }
+    .pagination {
+      padding: 20px;
+      margin: 0 auto;
+      width: 920px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      background-color: rgba(255, 255, 255, 0.3);
+    }
+    .bottmInp {
+      /deep/.el-textarea__inner:focus {
+        border-color: #b9412e;
+      }
+      /deep/.el-textarea__inner {
+        background-color: rgba(255, 255, 255, 0.3);
+      }
+      /deep/.el-input__inner {
+        background-color: rgba(255, 255, 255, 0.3);
+      }
+      /deep/.el-textarea .el-input__count {
+        background-color: transparent;
+        color: #878787;
+      }
+      /deep/.el-input__count-inner {
+        background-color: transparent;
+        color: #878787;
+      }
+      margin-top: 15px;
+      width: 100%;
+      padding: 0 20px;
+    }
+    .button {
+      margin-top: 15px;
+      display: flex;
+      justify-content: space-between;
+      .button_left {
+        width: 300px;
+        display: flex;
+        align-items: center;
+        .biaoji {
+          position: relative;
+          margin-right: 10px;
+          width: 20px;
+          height: 20px;
+          border-radius: 50%;
+          border: 1px solid #b9412e;
+          &::after {
+            content: "";
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            transform: translate(-50%, -50%);
+            width: 15px;
+            height: 15px;
+            border-radius: 50%;
+            background-color: #b9412e;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 232 - 0
houtai/src/views/messageM/index.vue

@@ -0,0 +1,232 @@
+<!--  -->
+<template>
+  <div class="messageM">
+    <div class="top">
+      <h3>留言板</h3>
+      <p>已有 {{ total }} 条留言</p>
+    </div>
+    <!-- 内容 -->
+    <van-list
+      class="conten"
+      v-model="loading"
+      :finished="finished"
+      finished-text="没有更多了"
+      @load="onLoad"
+      :immediate-check="false"
+    >
+      <div class="row" v-for="item in data" :key="item.id">
+        <div class="left">
+          <img src="../../assets/imgAdd/touxiang.png" alt="" />
+        </div>
+        <div class="right">
+          <p>
+            {{ item.creatorName }} <span>{{ item.createTime }}</span>
+          </p>
+          <div class="txt">{{ item.content }}</div>
+        </div>
+      </div>
+    </van-list>
+    <!-- 文本域和按钮 -->
+    <div class="bottmInp">
+      <div class="texe">
+        <el-input
+          maxlength="100"
+          show-word-limit
+          resize="none"
+          type="textarea"
+          :rows="3"
+          placeholder="请输入留言..."
+          v-model="textarea"
+        >
+        </el-input>
+      </div>
+      <div class="button">
+        <div class="button_left">
+          <el-input
+            type="text"
+            placeholder="请填写您的姓名"
+            v-model="name"
+            maxlength="8"
+            show-word-limit
+          >
+          </el-input>
+        </div>
+        <div class="button_right">
+        <el-button
+          type="primary"
+          @click="commentSave"
+          >提 交</el-button
+        >
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { commentSave, commentWebList } from '@/apis/tab7'
+export default {
+  name: 'messageM',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      // vant下拉刷新的数据----------
+      loading: false,
+      finished: false,
+      // vant下拉刷新的数据----------
+
+      textarea: '',
+      name: '',
+      data: [],
+      total: 0,
+      formData: {
+        startTime: '',
+        endTime: '',
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: '',
+        status: 2
+      }
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // vant下拉刷新触发的函数
+    onLoad () {
+      this.formData.pageNum++
+      this.commentWebList(this.formData)
+    },
+    // 点击提交留言
+    async  commentSave () {
+      if (this.textarea.trim() === '') return this.$message.warning('内容不能为空!')
+      if (this.name.trim() === '') return this.$message.warning('名字不能为空!')
+      const res = await commentSave({ content: this.textarea, creatorName: this.name })
+      if (res.code === 0) {
+        this.textarea = this.name = ''
+        this.$message.success('提交成功,等待审核.')
+      } else this.$message.warning(res.msg)
+    },
+    // 封装获取列表的方法
+    async commentWebList (data) {
+      const res = await commentWebList(data)
+      this.total = res.data.total
+      res.data.records.forEach(v => {
+        this.data.push(v)
+      })
+      this.loading = false
+      if (res.data.records.length < 10) this.finished = true
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    this.commentWebList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.messageM {
+  background: url("../../assets/imgAdd/mesBac.png");
+  padding: 24px;
+  width: 100vw;
+  height: 100vh;
+  overflow: hidden;
+  /deep/::-webkit-scrollbar {
+    width: 0;
+    height: 0;
+    color: transparent;
+  }
+  .top {
+    & > h3 {
+      font-size: 20px;
+    }
+    & > p {
+      margin-top: 5px;
+      font-size: 12px;
+      color: #a19d97;
+    }
+  }
+  .conten {
+    height: calc(100vh - 230px);
+    overflow-y: auto;
+    .row {
+      border-bottom: 2px dashed #fff;
+      padding: 15px 0;
+      display: flex;
+      .left {
+        width: 46px;
+        height: 46px;
+        margin-right: 15px;
+        & > img {
+          width: 100%;
+          height: 100%;
+        }
+      }
+      .right {
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+        & > p {
+          display: flex;
+          justify-content: space-between;
+          font-size: 16px;
+          align-items: center;
+          & > span {
+            font-size: 12px;
+            color: #a19d97;
+          }
+        }
+        .txt {
+          margin-top: 10px;
+          font-size: 14px;
+        }
+      }
+    }
+  }
+  .bottmInp {
+    padding: 10px 0;
+    /deep/.el-textarea__inner:focus {
+      border-color: #b9412e;
+    }
+    /deep/.el-textarea__inner {
+      background-color: rgba(255, 255, 255, 0.3);
+    }
+    /deep/.el-input__inner {
+      background-color: rgba(255, 255, 255, 0.3);
+    }
+    /deep/.el-textarea .el-input__count {
+      background-color: transparent;
+      color: #878787;
+    }
+    /deep/.el-input__count-inner {
+      background-color: transparent;
+      color: #878787;
+    }
+    .button {
+      margin-top: 10px;
+      display: flex;
+      justify-content: space-between;
+      .button_left{
+        width: 75vh;
+        margin-right: 5vh;
+      }
+      .button_right{
+        width: 20vh;
+      }
+    }
+  }
+}
+</style>

+ 406 - 0
houtai/src/views/tab1/index.vue

@@ -0,0 +1,406 @@
+<template>
+  <div class="tab1">
+    <div class="insideTop">
+      文物典藏管理
+      <div class="add">
+        <el-button type="primary" @click="addGood">新增文物典藏</el-button>
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <div class="conten">
+      <div class="con_left">
+        <div class="cutJT">
+          <i class="el-icon-arrow-down"></i>
+          文物典藏
+        </div>
+        <ul>
+          <li
+            v-for="item in conLeftArr"
+            :key="item.id"
+            :class="{ active: formData.type === item.type }"
+            @click="cutLeft(item.type)"
+          >
+            {{ item.name }}
+          </li>
+        </ul>
+      </div>
+      <!-- 右侧主要内容 -->
+      <div class="con_right">
+        <div class="classify">全部</div>
+        <div class="search">
+          <span>发布时间:</span>
+          <el-date-picker
+            style="width: 240px"
+            v-model="time"
+            type="daterange"
+            range-separator="-"
+            start-placeholder="开始时间"
+            end-placeholder="结束时间"
+          >
+          </el-date-picker>
+          <span class="search_k">标题关键字:</span>
+          <el-input
+            v-model="formData.searchKey"
+            placeholder="请输入"
+            style="width: 240px"
+          ></el-input>
+          <span class="search_k">排序:</span>
+          <el-select
+            v-model="formData.sortType"
+            placeholder="请选择"
+            style="width: 240px"
+          >
+            <el-option label="发布时间" :value="0"></el-option>
+            <el-option label="排序编号" :value="1"></el-option>
+          </el-select>
+          <!-- 右侧按钮 -->
+          <div class="search_btn">
+            <el-button type="primary" @click="searchBtn">查 询</el-button>
+            <el-button @click="resetBtn">重 置</el-button>
+          </div>
+        </div>
+        <!-- 表格 -->
+        <div class="table">
+          <el-table :data="tableData" style="width: 100%">
+            <el-table-column label="序号" width="80">
+              <template slot-scope="scope">
+                {{
+                  scope.$index + (formData.pageNum - 1) * formData.pageSize + 1
+                }}
+              </template>
+            </el-table-column>
+            <el-table-column label="标题" width="250">
+              <template #default="{ row }">
+                <span class="table_name" :title="row.name">{{
+                  row.name
+                }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="封面图片" width="120">
+              <template #default='{row}'>
+                <img class="table_img" :src="baseURL+row.thumb" alt="" :onerror="defaultImg"/>
+              </template>
+            </el-table-column>
+            <el-table-column prop="visit" label="阅读" width="100"> </el-table-column>
+            <el-table-column prop="creatorName" label="发布人"> </el-table-column>
+            <el-table-column prop="createTime" label="发布时间" width="200">
+            </el-table-column>
+            <el-table-column  label="排序" width="80">
+              <template #default="{ row }">
+                <el-input type="text" v-model="row.sort" @blur="changeSort(row.sort,row.id)"></el-input>
+              </template>
+            </el-table-column>
+            <el-table-column label="是否显示">
+              <template #default="{ row }">
+                <el-switch v-model="row.display" active-color="#b9412e" :active-value='1' :inactive-value='0' @change='changeSwit($event,row.id)'>
+                </el-switch>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作">
+              <template #default="{ row }">
+                <el-button
+                  type="text"
+                  @click="lookGood(row.id)"
+                  >查看</el-button
+                >
+                <el-button type="text" v-if="!row.display" @click="editGood(row.id)">编辑</el-button>
+                <el-button type="text" v-if="!row.display" @click="delGoods(row.id)">删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging">
+      <el-pagination
+        layout="sizes,prev, pager, next,jumper"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from '@/utils/request'
+import { goodsList, goodsRemove, goodsDisplay, goodsSort } from '@/apis/tab1'
+export default {
+  name: 'tab1',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      baseURL: '',
+      total: 0,
+      time: '',
+      conLeftArr: [
+        { name: '实物模型', type: 'model' },
+        { name: '专题图库', type: 'img' },
+        { name: '视频档案', type: 'video' }
+      ],
+      formData: {
+        startTime: '',
+        endTime: '',
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: '',
+        sortType: 0,
+        type: 'model'
+      },
+      tableData: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {
+    time (val) {
+      this.handleSelect(val)
+    }
+  },
+  // 方法集合
+  methods: {
+    // 点击重置
+    resetBtn () {
+      this.formData.searchKey = ''
+      this.formData.sortType = 0
+      this.time = ''
+      this.formData.pageNum = 1
+      this.formData.startTime = this.formData.endTime = ''
+      this.goodsList(this.formData)
+    },
+    // 点击查询
+    searchBtn () {
+      this.formData.pageNum = 1
+      this.goodsList(this.formData)
+    },
+    // 排序
+    async changeSort (val, id) {
+      // console.log(998, val, id)
+      if (Number(val) < 1) return this.$message.warning('不能小于1')
+      const res = await goodsSort(id, Number(val))
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.goodsList(this.formData)
+      } else this.$message.warning(res.msg)
+    },
+    // 点击开关
+    async changeSwit (val, id) {
+      const res = await goodsDisplay(id, val)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.goodsList(this.formData)
+      } else this.$message.warning(res.msg)
+      console.log(998, val, id)
+    },
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.goodsList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.goodsList(this.formData)
+    },
+    // 点击删除
+    delGoods (id) {
+      this.$confirm('删除后,信息无法恢复,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          const res = await goodsRemove(id)
+          if (res.code === 0) {
+            this.$message.success('删除成功')
+            this.goodsList(this.formData)
+          } else this.$message.warning(res.msg)
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    },
+    // 点击查看
+    lookGood (id) {
+      this.$router.push({
+        path: '/layout/tab1Look',
+        query: { conLeftId: this.formData.type, id }
+      })
+    },
+    // 点击编辑文物
+    editGood (id) {
+      if (this.formData.type === 'img') {
+        this.$router.push({
+          path: '/layout/tab1Add2',
+          query: { id }
+        })
+      } else {
+        this.$router.push({
+          path: '/layout/tab1Add',
+          query: { conLeftId: this.formData.type, id }
+        })
+      }
+    },
+    // 点击新增文物
+    addGood () {
+      if (this.formData.type === 'img') this.$router.push('/layout/tab1Add2')
+      else {
+        this.$router.push({
+          path: '/layout/tab1Add',
+          query: { conLeftId: this.formData.type }
+        })
+      }
+    },
+    // 点击左侧的tab栏
+    cutLeft (type) {
+      if (type === this.formData.type) return
+      this.formData.type = type
+      this.goodsList(this.formData)
+    },
+    // 时间处理----------------
+    handleSelect (e) {
+      const date = []
+      for (const i in e) {
+        date.push(this.gettime(e[i]))
+      }
+      this.formData.startTime = date[0]
+      if (date[1]) {
+        this.formData.endTime = date[1].replace('00:00:00', '23:59:59')
+      }
+      if (e === null) this.formData.endTime = ''
+    },
+    gettime (data) {
+      const value =
+        data.getFullYear() +
+        '-' +
+        this.checkTime(data.getMonth() + 1) +
+        '-' +
+        this.checkTime(data.getDate()) +
+        ' ' +
+        this.checkTime(data.getHours()) +
+        ':' +
+        this.checkTime(data.getMinutes()) +
+        ':' +
+        this.checkTime(data.getSeconds())
+      return value
+    },
+    checkTime (i) {
+      if (i < 10) {
+        i = '0' + i
+      }
+      return i
+    },
+    // 封装获取列表的函数
+    async goodsList (data) {
+      const res = await goodsList(data)
+      this.total = res.data.total
+      this.tableData = res.data.records
+      // console.log(998, res)
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 判断是第一次进来还是修改或者新增或者查看后返回
+    // 拿到路由跳转传过来的数据
+    if (this.$route.query.conLeftId) {
+      this.formData.type = this.$route.query.conLeftId
+    }
+    this.goodsList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab1 {
+  height: 100%;
+  .conten {
+    display: flex;
+    height: calc(100% - 32px);
+    .con_left {
+      padding: 20px 0 0 15px;
+      width: 180px;
+      height: 100%;
+      border: 1px solid #ccc;
+      .cutJT {
+        margin-bottom: 10px;
+      }
+      ul {
+        li {
+          cursor: pointer;
+          margin-left: 20px;
+          width: 100px;
+          text-align: center;
+          line-height: 30px;
+          height: 30px;
+          &:hover {
+            color: #b9412e;
+            background-color: #e6f7ff;
+          }
+        }
+        .active {
+          color: #b9412e;
+          background-color: #e6f7ff;
+        }
+      }
+    }
+    .con_right {
+      padding: 15px 30px 0;
+      flex: 1;
+      .classify {
+        text-align: center;
+        width: 40px;
+        padding-bottom: 10px;
+        color: #b9412e;
+        border-bottom: 2px solid #b9412e;
+      }
+      .search {
+        margin-bottom: 20px;
+        position: relative;
+        margin-top: 12px;
+        height: 40px;
+        .search_k {
+          margin-left: 30px;
+        }
+        .search_btn {
+          display: flex;
+          justify-content: space-between;
+          width: 200px;
+          position: absolute;
+          right: 0px;
+          top: 0;
+        }
+      }
+    }
+  }
+  .table{
+    max-width: 1370px;
+  }
+  /deep/.el-table__body-wrapper{
+    max-height: 485px;
+    overflow-y: auto;
+  }
+      .paging {
+      position: absolute;
+      bottom: 15px;
+      right: 50px;
+    }
+
+}
+</style>

+ 359 - 0
houtai/src/views/tab1/tab1Add.vue

@@ -0,0 +1,359 @@
+<template>
+  <div class="tab1Add">
+    <div class="insideTop">
+      文物典藏管理 > {{ruleForm.id?'编辑':'新增'}}文物典藏
+      <div class="add">
+        <el-button type="primary" @click="goBack">返 回</el-button>
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <!-- 表单 -->
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="140px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="标题:" prop="name">
+          <el-input
+            v-model="ruleForm.name"
+            maxlength="25"
+            show-word-limit
+            style="width: 500px"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="精品类型:">
+          <i class="biaoshi biaoshi2"></i>
+          <el-radio
+            v-model="conLeftId"
+            label="model"
+            :disabled="conLeftId !== 'model'"
+            >实物模型</el-radio
+          >
+          <el-radio v-model="conLeftId" label="img" disabled>专题图库</el-radio>
+          <el-radio
+            v-model="conLeftId"
+            label="video"
+            :disabled="conLeftId !== 'video'"
+            >视频档案</el-radio
+          >
+        </el-form-item>
+        <!-- 图片和附件 -->
+        <el-form-item
+          :label="conLeftId === 'model' ? '模型封面图片:' : '封面图片:'"
+        >
+          <i class="biaoshi" :class="{ biaoshi1: conLeftId === 'model' }"></i>
+          <el-upload
+            class="avatar-uploader"
+            :action="baseURL + '/cms/goods/upload'"
+            :headers="{
+              token,
+            }"
+            :show-file-list="true"
+            :before-upload="beforethumbUpload"
+            :on-success="upload_thumb_success"
+          >
+            <div v-if="ruleForm.thumb" class="imgdiv">
+              <img
+                style="max-width: 200px; max-height: 200px;display: block;"
+                :src="baseURL + ruleForm.thumb"
+              />
+              <i
+                class="el-icon-circle-close"
+                @click.stop="ruleForm.thumb = ''"
+              ></i>
+            </div>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+          <p class="upHint">格式要求:</p>
+          <p class="upHint">
+            1、支持png、jpg、gif和jpeg的图片格式;最大支持20MB。
+          </p>
+          <p class="upHint">
+            2、用于{{
+              conLeftId === "model" ? "实物模型" : "视频档案"
+            }}列表中进行展示。
+          </p>
+        </el-form-item>
+        <!-- 上传附件 -->
+        <el-form-item
+          :label="conLeftId === 'model' ? '模型文件:' : '视频文件:'"
+        >
+          <i class="biaoshi"></i>
+          <el-upload
+            multiple
+            class="upload-demo"
+            :file-list="fileList"
+            :action="baseURL + '/cms/goods/video/upload'"
+            :headers="{ token }"
+            :before-upload="beforeFujian"
+            :on-success="successFujian"
+            :before-remove="beforeRemove"
+            :on-remove="handleRemove"
+            :limit="1"
+            :on-exceed="handleExceed"
+            :show-file-list="true"
+          >
+            <el-button size="small" type="primary">点击上传</el-button>
+          </el-upload>
+          <div class="el-upload__tip" v-if="conLeftId === 'model'">
+            <p class="upHint">格式要求:</p>
+            <p class="upHint">1、仅支持.4dage格式的模型文件。</p>
+            <p class="upHint">2、最大支持500MB。</p>
+          </div>
+          <div class="el-upload__tip" v-else>
+            <p class="upHint">格式要求:</p>
+            <p class="upHint">
+              1、仅支持mp4视频格式文件。
+            </p>
+            <p class="upHint">2、最大支持2G的视频文件。</p>
+          </div>
+        </el-form-item>
+      </el-form>
+      <!-- 底部按钮 -->
+      <div class="con_btn">
+        <el-button type="primary" @click="saveGood">保 存</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { goodsSave, goodsDetail } from '@/apis/tab1'
+import axios from '@/utils/request'
+export default {
+  name: 'tab1Add',
+  components: {},
+  data () {
+    return {
+      conLeftId: '',
+      fileList: [],
+      // 服务器前缀地址
+      baseURL: '',
+      token: '',
+      ruleForm: {
+        name: '', // 标题
+        type: '', // 类型, model:模型, img:图片, video:视频
+        thumb: '', // 封面图
+        fileName: '', // 文件名称
+        filePath: '' // 文件地址
+      },
+      rules: {
+        name: [{ required: true, message: '不能为空', trigger: 'blur' }]
+      }
+    }
+  },
+  computed: {},
+  methods: {
+    // 点击保存
+    async saveGood () {
+      if (this.ruleForm.name.trim() === '') { return this.$message.warning('标题不能为空') }
+      if (this.ruleForm.thumb === '') { return this.$message.warning('图片不能为空') }
+      if (this.ruleForm.filePath === '') { return this.$message.warning('文件不能为空') }
+      const obj = { ...this.ruleForm, type: this.conLeftId }
+      const res = await goodsSave(obj)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.$router.push({
+          path: '/layout/tab1',
+          query: { conLeftId: this.conLeftId }
+        })
+      } else this.$message.warning(res.msg)
+    },
+    // 点击返回
+    goBack () {
+      this.$confirm('点击返回后,编辑的信息将无法保存,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          this.$router.push({
+            path: '/layout/tab1',
+            query: { conLeftId: this.conLeftId }
+          })
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    },
+    // 上传图片
+    beforethumbUpload (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 20
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('照片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('照片大小超过20M!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_success (data) {
+      this.$message.success('上传成功')
+      // console.log('图片上传成功', data.data.filePath)
+      this.ruleForm.thumb = data.data.filePath
+    },
+    // 上传附件
+    beforeFujian (file) {
+      console.log('附件上传前', file)
+      if (this.conLeftId === 'model') {
+        const sizeOk = file.size / 1024 / 1024 < 500
+        const typeOk = file.type === '' && file.name.includes('.4dage')
+        return new Promise((resolve, reject) => {
+          if (file.name.length > 32) {
+            this.$message.error('文件名字不能超过32个字')
+            reject(file)
+          } else if (!sizeOk) {
+            this.$message.error('模型大小超过500M!')
+            reject(file)
+          } else if (!typeOk) {
+            this.$message.error('模型格式有误!')
+            reject(file)
+          } else {
+            resolve(file)
+          }
+        })
+      } else if (this.conLeftId === 'video') {
+        const sizeOk = file.size / 1024 / 1024 < 2048
+        const typeOk = file.type === 'video/mp4'
+        return new Promise((resolve, reject) => {
+          if (file.name.length > 32) {
+            this.$message.error('视频名字不能超过32个字')
+            reject(file)
+          } else if (!sizeOk) {
+            this.$message.error('视频大小超过2GB!')
+            reject(file)
+          } else if (!typeOk) {
+            this.$message.error('视频格式有误!')
+            reject(file)
+          } else {
+            resolve(file)
+          }
+        })
+      }
+    },
+    successFujian (file) {
+      console.log('上传附件成功', file)
+      if (file.code === 0) {
+        this.ruleForm.filePath = file.data.urlPath
+        this.ruleForm.fileName = file.data.fileName
+        this.$message.success('上传成功')
+      } else if (file.code === -1) {
+        this.$message.warning('上传失败,不支持的文件格式')
+      }
+    },
+    beforeRemove (file, fileList) {
+      if (file && file.status === 'success') {
+        return this.$confirm(`确定移除 ${file.name}?`)
+      }
+    },
+    handleRemove (file, fileList) {
+      this.ruleForm.filePath = ''
+      this.ruleForm.fileName = ''
+    },
+    handleExceed (files, fileList) {
+      this.$message.warning('只能上传一个文件,请删除原文件后操作')
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('CQLJXU_token')
+    // 拿到路由跳转传过来的数据
+    this.conLeftId = this.$route.query.conLeftId
+    // 通过父亲传过来的id获取详情
+    if (this.$route.query.id) {
+      const res = await goodsDetail(Number(this.$route.query.id))
+      this.ruleForm = res.data.entity
+      // 附件回显
+      this.fileList = [{ name: res.data.entity.fileName }]
+      // console.log(998, res)
+    }
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab1Add {
+  height: 100%;
+  .conten {
+    overflow-y: auto;
+    position: relative;
+    /deep/.el-icon-plus {
+      border: 1px dashed #ccc;
+    }
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .biaoshi1::before {
+      left: -120px;
+    }
+    .biaoshi2::before {
+      top: -10px;
+    }
+    .avatar-uploader .el-upload {
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+    }
+    .avatar-uploader .el-upload:hover {
+      border-color: #3e5eb3;
+    }
+    .avatar-uploader-icon {
+      font-size: 28px;
+      color: #8c939d;
+      width: 178px;
+      height: 178px;
+      line-height: 178px;
+      text-align: center;
+    }
+    .con_btn {
+      position: absolute;
+      left: 50%;
+      transform: translateX(-50%);
+      bottom: 15px;
+    }
+    .imgdiv {
+      max-width: 200px;
+      max-height: 200px;
+      &>img{
+        border: 5px solid #ccc;
+      }
+    }
+    .el-icon-circle-close {
+      font-size: 24px;
+    }
+  }
+}
+</style>

+ 339 - 0
houtai/src/views/tab1/tab1Add2.vue

@@ -0,0 +1,339 @@
+<template>
+  <div class="tab1Add2">
+    <div class="insideTop">
+      文物典藏管理 > 新增文物典藏
+      <div class="add">
+        <el-button type="primary" @click="goBack">返 回</el-button>
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <!-- 表单 -->
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="120px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="标题:" prop="name">
+          <el-input
+            v-model="ruleForm.name"
+            maxlength="25"
+            show-word-limit
+            style="width: 500px"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="精品类型:">
+          <i class="biaoshi biaoshi2"></i>
+          <el-radio v-model="conLeftId" label="model" disabled>实物模型</el-radio>
+          <el-radio v-model="conLeftId" label="img">专题图库</el-radio>
+          <el-radio v-model="conLeftId" label="video:视频" disabled>视频档案</el-radio>
+        </el-form-item>
+        <!-- 图片 -->
+        <el-form-item label="图片:" style="height:480px">
+          <i class="biaoshi biaoshi1"></i>
+          <div class="imgBox">
+            <div
+              class="imgdiv"
+              v-for="(item, index) in imgList"
+              :key="item.id"
+            >
+              <el-image
+                style="width: 200px; height: 200px"
+                :src="baseURL+item.filePath"
+                :preview-src-list="imgListLook"
+              >
+              </el-image>
+              <!-- 封面显示 -->
+              <div class="cover" v-if="imgActive === index">封面图片</div>
+              <!-- 下面的按钮 -->
+              <div class="handle">
+                <el-button size="mini" type="primary" round @click="goodsImgIndex(index)" v-if="imgActive !== index">设为封面</el-button>
+              </div>
+              <!-- 删除 -->
+              <div class="delImg el-icon-delete" @click="delGoodsImg(index,item.id)" v-if="imgActive !== index"></div>
+            </div>
+            <el-upload
+              v-if="this.imgList.length<18"
+              ref="upload"
+              class="avatar-uploader"
+              :action="baseURL + '/cms/goods/upload'"
+              :headers="{ token }"
+              :show-file-list="true"
+              :before-upload="beforethumbUpload"
+              :on-success="upload_thumb_success"
+            >
+              <div class="upImg">
+                <i slot="default" class="el-icon-plus"></i>
+              </div>
+            </el-upload>
+          </div>
+          <p class="upHint upHint1">格式要求:</p>
+          <p class="upHint">
+            1、支持png、jpg、gif和jpeg的图片格式;单张最大支持20MB。
+          </p>
+          <p class="upHint">2、最多可上传18张图片。</p>
+        </el-form-item>
+      </el-form>
+      <!-- 底部按钮 -->
+      <div class="con_btn">
+        <el-button type="primary" @click="goodsSave">保 存</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { goodsSave, goodsDetail, goodsimgRemove } from '@/apis/tab1'
+import axios from '@/utils/request'
+export default {
+  name: 'tab1Add2',
+  components: {},
+  data () {
+    return {
+      // 重新上传的数据
+      imgActive: 0,
+      // 上传成功后的图片数组
+      imgList: [],
+      imgListLook: [],
+      conLeftId: 'img',
+      fileList: [],
+      // 服务器前缀地址
+      baseURL: '',
+      token: '',
+      ruleForm: {
+        code: new Date().valueOf(),
+        name: '',
+        type: 'img',
+        thumb: ''
+      },
+      rules: {
+        name: [{ required: true, message: '不能为空', trigger: 'blur' }]
+      }
+    }
+  },
+  computed: {},
+  methods: {
+    // 点击保存
+    async goodsSave () {
+      if (this.ruleForm.name.trim() === '') { return this.$message.warning('标题不能为空') }
+      if (this.imgList.length === 0) { return this.$message.warning('图片不能为空') }
+      // if (this.imgList.length > 18) { return this.$message.warning('图片不能超过18张') }
+      const temp = []
+      this.imgList.forEach(v => {
+        temp.push(v.id)
+      })
+      const obj = { ...this.ruleForm, fileIds: temp.join(','), thumb: this.imgList[this.imgActive].filePath, indexId: this.imgList[this.imgActive].id }
+      const res = await goodsSave(obj)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.$router.push({
+          path: '/layout/tab1',
+          query: { conLeftId: 'img' }
+        })
+      } else this.$message.warning(res.msg)
+      // console.log(998, res)
+    },
+    // 点击删除
+    delGoodsImg (index, id) {
+      this.$confirm('删除后,信息无法恢复,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          await goodsimgRemove(id)
+          this.imgList.splice(index, 1)
+          this.imgListLook.splice(index, 1)
+          if (index < this.imgActive) this.imgActive--
+          this.$message.success('删除成功')
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    },
+    // 点击设为封面
+    async goodsImgIndex (index) {
+      this.imgActive = index
+      // this.ruleForm.thumb = this.imgList[index].filePath
+      this.$message.success('操作成功')
+    },
+    // 点击返回
+    goBack () {
+      this.$confirm('点击返回后,编辑的信息将无法保存,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          this.$router.push({
+            path: '/layout/tab1',
+            query: { conLeftId: 'img' }
+          })
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    },
+    // 上传图片
+    beforethumbUpload (file) {
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 20
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('照片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('照片大小超过20M!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    async upload_thumb_success (data) {
+      this.$message.success('上传成功')
+      // console.log('图片上传成功', data)
+      this.imgList.push({ name: data.data.name, id: data.data.id, filePath: data.data.filePath })
+      this.imgListLook.push(this.baseURL + data.data.filePath)
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('CQLJXU_token')
+    // 通过父亲传过来的id获取详情
+    if (this.$route.query.id) {
+      const res = await goodsDetail(Number(this.$route.query.id))
+      this.ruleForm = res.data.entity
+      this.imgList = res.data.file
+      this.imgList.forEach((v, i) => {
+        this.imgListLook.push(this.baseURL + v.filePath)
+        // 修改封面显示
+        if (v.isIndex === 1) this.imgActive = i
+      })
+      // console.log(998, res)
+    }
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab1Add2 {
+  height: 100%;
+  .conten {
+    /deep/.el-form-item{
+      max-height: 480px;
+      overflow-y: auto;
+    }
+    position: relative;
+    /deep/.el-icon-plus {
+      font-size: 60px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      border: 1px dashed #ccc;
+      width: 200px;
+      height: 200px;
+    }
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .biaoshi1::before {
+      left: -63px;
+    }
+    .biaoshi2::before {
+      top: -10px;
+    }
+    .avatar-uploader .el-upload {
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+    }
+    .avatar-uploader .el-upload:hover {
+      border-color: #3e5eb3;
+    }
+    .avatar-uploader-icon {
+      font-size: 28px;
+      color: #8c939d;
+      width: 178px;
+      height: 178px;
+      line-height: 178px;
+      text-align: center;
+    }
+    .con_btn {
+      position: absolute;
+      left: 50%;
+      transform: translateX(-50%);
+      bottom: 15px;
+    }
+    .imgBox{
+      display: flex;
+      flex-wrap: wrap;
+      .imgdiv{
+        position: relative;
+        margin-right: 30px;
+        margin-bottom: 10px;
+        .handle{
+          display: flex;
+          justify-content: center;
+          margin-top: 5px;
+        }
+        .delImg{
+          cursor: pointer;
+          border-radius: 10px;
+          color: #fff;
+          background-color: #b9412e;
+          padding: 3px;
+          font-size: 26px;
+          position: absolute;
+          top: 5px;
+          right: 5px;
+        }
+        .cover{
+          pointer-events: none;
+          font-size: 16px;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          width: 100%;
+          z-index: 999;
+          position: absolute;
+          top: 44%;
+          left: 0;
+          transform: translateY(-50%);
+          height: 40px;
+          background-color: rgba(255,255,255,.4);
+        }
+      }
+    }
+    .upHint1{
+      margin-top: 15px;
+    }
+  }
+}
+</style>

+ 203 - 0
houtai/src/views/tab1/tab1Look.vue

@@ -0,0 +1,203 @@
+<!--  -->
+<template>
+  <div class="tab1Look">
+    <div class="insideTop">
+      文物典藏管理 > 查看文物典藏
+      <div class="add">
+        <el-button type="primary" @click="goBack">返 回</el-button>
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容2 -->
+    <div class="conten" v-if="conLeftId === 'img'">
+      <div class="con_top">基本信息</div>
+      <div class="row">
+        <div>标题:</div>
+        <span>{{ myObj.name }}</span>
+      </div>
+      <div class="row">
+        <div>精品类型:</div>
+        <span>专题图库</span>
+      </div>
+      <div class="row">
+        <div>显示设置:</div>
+        <el-switch
+          disabled
+          v-model="myObj.display"
+          active-color="#b9412e"
+          :active-value="1"
+          :inactive-value="0"
+        >
+        </el-switch>
+      </div>
+      <div class="row">
+        <div>图片:</div>
+        <div class="imgList">
+          <div class="imgParcel" v-for="(item, index) in srcList2" :key="index">
+            <el-image
+              style="width: 200px; height: 200px"
+              :src="item"
+              :preview-src-list="srcList2"
+            >
+            </el-image>
+            <!-- 封面显示 -->
+            <div class="cover" v-if="imgActive === index">封面图片</div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 主要内容1-3 -->
+    <div class="conten" v-else>
+      <div class="con_top">基本信息</div>
+      <div class="row">
+        <div>标题:</div>
+        <span>{{ myObj.name }}</span>
+      </div>
+      <div class="row">
+        <div>精品类型:</div>
+        <span>{{ myObj.type === "model" ? "实物模型" : "视频档案" }}</span>
+      </div>
+      <div class="row">
+        <div>{{ conLeftId === "model" ? "实物图片" : "封面图片" }}:</div>
+        <el-image
+          v-if="srcList.length !== 0"
+          style="width: 200px; height: 200px"
+          :src="srcList[0]"
+          :preview-src-list="srcList"
+        >
+        </el-image>
+      </div>
+      <div class="row">
+        <div>{{ conLeftId === "model" ? "模型文件" : "视频文件" }}:</div>
+        <a :href="baseURL + myObj.filePath" download>{{ myObj.fileName }}</a>
+      </div>
+      <div class="row">
+        <div>显示设置:</div>
+        <el-switch
+          disabled
+          v-model="myObj.display"
+          active-color="#b9412e"
+          :active-value="1"
+          :inactive-value="0"
+        >
+        </el-switch>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from '@/utils/request'
+import { goodsDetail } from '@/apis/tab1'
+export default {
+  name: 'tab1Look',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      imgActive: null,
+      myArr: [],
+      // 服务器前缀地址
+      baseURL: '',
+      myObj: {},
+      conLeftId: '',
+      srcList: [],
+      srcList2: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 点击返回
+    goBack () {
+      this.$router.push({
+        path: '/layout/tab1',
+        query: { conLeftId: this.conLeftId }
+      })
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 拿到路由跳转传过来的数据
+    this.conLeftId = this.$route.query.conLeftId
+    // 通过父亲传过来的id获取详情
+    if (this.$route.query.id) {
+      const res = await goodsDetail(Number(this.$route.query.id))
+      this.myObj = res.data.entity
+      this.srcList = [this.baseURL + this.myObj.thumb]
+      console.log(998, this.myObj)
+      this.myArr = res.data.file
+      this.myArr.forEach((v, i) => {
+        this.srcList2.push(this.baseURL + v.filePath)
+        if (v.isIndex === 1) this.imgActive = i
+      })
+    }
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab1Look {
+  height: 100%;
+  .conten {
+    overflow-y: auto;
+    position: relative;
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .row {
+      display: flex;
+      margin: 25px 0;
+      & > div {
+        width: 120px;
+        text-align: right;
+      }
+      .imgList {
+        width: 1500px;
+        display: flex;
+        flex-wrap: wrap;
+      }
+      .imgParcel {
+        position: relative;
+        width: 200px;
+        height: 200px;
+        margin-right: 30px;
+        margin-bottom: 30px;
+      }
+      .cover {
+        pointer-events: none;
+        font-size: 16px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        width: 100%;
+        z-index: 999;
+        position: absolute;
+        top: 50%;
+        left: 0;
+        transform: translateY(-50%);
+        height: 40px;
+        background-color: rgba(255, 255, 255, 0.4);
+      }
+    }
+  }
+}
+</style>

+ 354 - 0
houtai/src/views/tab2/index.vue

@@ -0,0 +1,354 @@
+<template>
+  <div class="tab2">
+    <div class="insideTop">
+      学院领导管理
+      <div class="add">
+        <el-button type="primary" @click="$router.push('/layout/tab2Add')"
+          >新增领导信息</el-button
+        >
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="classify">全部</div>
+      <div class="search">
+        <span>发布时间:</span>
+        <el-date-picker
+          style="width: 240px"
+          v-model="time"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+        >
+        </el-date-picker>
+        <span class="search_k">姓名关键字:</span>
+        <el-input
+          v-model="formData.searchKey"
+          placeholder="请输入"
+          style="width: 240px"
+        ></el-input>
+        <span class="search_k">排序:</span>
+        <el-select
+          v-model="formData.sortType"
+          placeholder="请选择"
+          style="width: 240px"
+        >
+          <el-option label="发布时间" :value="0"></el-option>
+          <el-option label="排序编号" :value="1"></el-option>
+        </el-select>
+        <!-- 右侧按钮 -->
+        <div class="search_btn">
+          <el-button type="primary" @click="searchBtn">查 询</el-button>
+          <el-button @click="resetBtn">重 置</el-button>
+        </div>
+      </div>
+      <!-- 表格 -->
+      <div class="table">
+        <el-table :data="tableData" style="width: 100%">
+          <el-table-column label="序号" width="80">
+            <template slot-scope="scope">
+              {{
+                scope.$index + (formData.pageNum - 1) * formData.pageSize + 1
+              }}
+            </template>
+          </el-table-column>
+          <el-table-column label="姓名" width="250">
+            <template #default="{ row }">
+              <span class="table_name" :title="row.name">{{ row.name }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="任职职位" width="200">
+            <template #default="{ row }">
+              <span class="table_name" :title="row.job">{{ row.job }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="封面图片" width="120">
+            <template #default="{ row }">
+              <img
+                class="table_img"
+                :src="baseURL + row.thumb"
+                alt=""
+                :onerror="defaultImg"
+              />
+            </template>
+          </el-table-column>
+          <el-table-column prop="visit" label="阅读" width="100"> </el-table-column>
+          <el-table-column prop="creatorName" label="发布人"> </el-table-column>
+          <el-table-column prop="createTime" label="发布时间" width="200">
+          </el-table-column>
+          <el-table-column prop="address" label="排序" width="80">
+            <template #default="{ row }">
+              <el-input
+                type="text"
+                v-model="row.sort"
+                @blur="changeSort(row.sort, row.id)"
+              ></el-input>
+            </template>
+          </el-table-column>
+          <el-table-column label="是否显示" width="100">
+            <template #default="{ row }">
+              <el-switch
+                v-model="row.display"
+                active-color="#b9412e"
+                :active-value="1"
+                :inactive-value="0"
+                @change="changeSwit($event, row.id)"
+              >
+              </el-switch>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作">
+            <template #default="{ row }">
+              <el-button type="text" @click="lookGood(row.id)">查看</el-button>
+              <el-button
+                type="text"
+                v-if="!row.display"
+                @click="editLeader(row.id)"
+                >编辑</el-button
+              >
+              <el-button
+                type="text"
+                v-if="!row.display"
+                @click="delLeader(row.id)"
+                >删除</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging">
+      <el-pagination
+        layout="sizes,prev, pager, next,jumper"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from '@/utils/request'
+import {
+  leaderList,
+  leaderSort,
+  leaderDisplay,
+  leaderRemove
+} from '@/apis/tab2'
+export default {
+  name: 'tab2',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      total: 0,
+      time: '',
+      formData: {
+        startTime: '',
+        endTime: '',
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: '',
+        sortType: 0
+      },
+      tableData: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {
+    time (val) {
+      this.handleSelect(val)
+    }
+  },
+  // 方法集合
+  methods: {
+    // 点击查看
+    lookGood (id) {
+      this.$router.push({
+        path: '/layout/tab2Look',
+        query: { id }
+      })
+    },
+    // 点击删除
+    delLeader (id) {
+      this.$confirm('删除后,信息无法恢复,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          const res = await leaderRemove(id)
+          if (res.code === 0) {
+            this.$message.success('删除成功')
+            this.leaderList(this.formData)
+          } else this.$message.warning(res.msg)
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    },
+    // 点击编辑
+    editLeader (id) {
+      this.$router.push({
+        path: '/layout/tab2Add',
+        query: { id }
+      })
+    },
+    // 点击重置
+    resetBtn () {
+      this.formData.searchKey = ''
+      this.formData.sortType = 0
+      this.time = ''
+      this.formData.pageNum = 1
+      this.formData.startTime = this.formData.endTime = ''
+      this.leaderList(this.formData)
+    },
+    // 点击查询
+    searchBtn () {
+      this.formData.pageNum = 1
+      this.leaderList(this.formData)
+    },
+    // 点击开关
+    async changeSwit (val, id) {
+      const res = await leaderDisplay(id, val)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.leaderList(this.formData)
+      } else this.$message.warning(res.msg)
+      // console.log(998, val, id)
+    },
+    // 排序
+    async changeSort (val, id) {
+      // console.log(998, val, id)
+      if (Number(val) < 1) return this.$message.warning('不能小于1')
+      const res = await leaderSort(id, Number(val))
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.leaderList(this.formData)
+      } else this.$message.warning(res.msg)
+    },
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.leaderList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.leaderList(this.formData)
+    },
+    // 时间处理----------------
+    handleSelect (e) {
+      const date = []
+      for (const i in e) {
+        date.push(this.gettime(e[i]))
+      }
+      this.formData.startTime = date[0]
+      if (date[1]) {
+        this.formData.endTime = date[1].replace('00:00:00', '23:59:59')
+      }
+      if (e === null) this.formData.endTime = ''
+    },
+    gettime (data) {
+      const value =
+        data.getFullYear() +
+        '-' +
+        this.checkTime(data.getMonth() + 1) +
+        '-' +
+        this.checkTime(data.getDate()) +
+        ' ' +
+        this.checkTime(data.getHours()) +
+        ':' +
+        this.checkTime(data.getMinutes()) +
+        ':' +
+        this.checkTime(data.getSeconds())
+      return value
+    },
+    checkTime (i) {
+      if (i < 10) {
+        i = '0' + i
+      }
+      return i
+    },
+    // 封装获取列表函数
+    async leaderList (data) {
+      const res = await leaderList(data)
+      this.total = res.data.total
+      this.tableData = res.data.records
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    this.leaderList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab2 {
+  height: 100%;
+  .insideTop .add {
+    right: 55px;
+  }
+  .conten {
+    padding: 15px 30px 0;
+    height: calc(100% - 32px);
+    .classify {
+      text-align: center;
+      width: 40px;
+      padding-bottom: 10px;
+      color: #b9412e;
+      border-bottom: 2px solid #b9412e;
+    }
+    .search {
+      margin-bottom: 20px;
+      position: relative;
+      margin-top: 12px;
+      height: 40px;
+      .search_k {
+        margin-left: 30px;
+      }
+      .search_btn {
+        display: flex;
+        justify-content: space-between;
+        width: 200px;
+        position: absolute;
+        right: 22px;
+        top: 0;
+      }
+    }
+    .table {
+      max-width: 1533px;
+    }
+    /deep/.el-table__body-wrapper {
+      max-height: 485px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    bottom: 15px;
+    right: 50px;
+  }
+}
+</style>

+ 417 - 0
houtai/src/views/tab2/tab2Add.vue

@@ -0,0 +1,417 @@
+<template>
+  <div class="tab2Add">
+    <div class="insideTop">
+      学院领导管理 > {{ ruleForm.id ? "编辑" : "新增" }}领导信息
+      <div class="add">
+        <el-button type="primary" @click="goBack">返 回</el-button>
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <!-- 表单 -->
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="120px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="姓名:" prop="name">
+          <el-input
+            v-model="ruleForm.name"
+            maxlength="25"
+            show-word-limit
+            style="width: 500px"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="性别:" prop="sex">
+          <el-radio v-model="ruleForm.sex" label="M">男</el-radio>
+          <el-radio v-model="ruleForm.sex" label="F">女</el-radio>
+        </el-form-item>
+        <el-form-item label="政治面貌:" prop="politics">
+          <el-select
+            v-model="ruleForm.politics"
+            placeholder="请选择"
+            style="width: 500px"
+          >
+            <el-option label="中共党员" value="中共党员"></el-option>
+            <el-option label="中共预备党员" value="中共预备党员"></el-option>
+            <el-option label="共青团员" value="共青团员"></el-option>
+            <el-option label="民革党员" value="民革党员"></el-option>
+            <el-option label="民盟盟员" value="民盟盟员"></el-option>
+            <el-option label="民建会员" value="民建会员"></el-option>
+            <el-option label="民进会员" value="民进会员"></el-option>
+            <el-option label="农工党党员" value="农工党党员"></el-option>
+            <el-option label="致公党党员" value="致公党党员"></el-option>
+            <el-option label="九三学社社员" value="九三学社社员"></el-option>
+            <el-option label="台盟盟员" value="台盟盟员"></el-option>
+            <el-option label="无党派人士" value="无党派人士"></el-option>
+            <el-option label="群众" value="群众"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="任期职位:" prop="job">
+          <el-input
+            v-model="ruleForm.job"
+            maxlength="50"
+            show-word-limit
+            style="width: 500px"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="任期:">
+          <i class="biaoshi biaoshi1"></i>
+          <el-date-picker
+            style="width: 500px"
+            v-model="time"
+            type="monthrange"
+            range-separator="-"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+          >
+          </el-date-picker>
+        </el-form-item>
+        <!-- 图片和附件 -->
+        <el-form-item label="领导照片">
+          <i class="biaoshi biaoshi2"></i>
+          <el-upload
+            class="avatar-uploader"
+            :action="baseURL + '/cms/leader/upload'"
+            :headers="{
+              token,
+            }"
+            :show-file-list="true"
+            :before-upload="beforethumbUpload"
+            :on-success="upload_thumb_success"
+          >
+            <div v-if="ruleForm.thumb" class="imgdiv">
+              <img
+                style="max-width: 200px; max-height: 200px; display: block"
+                :src="baseURL + ruleForm.thumb"
+              />
+              <i
+                class="el-icon-circle-close"
+                @click.stop="ruleForm.thumb = ''"
+              ></i>
+            </div>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+          <p class="upHint">
+            格式要求:支持png、jpg、gif和jpeg的图片格式;最大支持20MB。
+          </p>
+        </el-form-item>
+      </el-form>
+      <!-- 富文本 -->
+      <div class="con_top">
+        领导简介
+        <!-- 富文本上传图片 -->
+        <el-upload
+          :headers="{
+            token,
+          }"
+          accept=".png,.jpg,.jpeg,.gif"
+          title="上传图片"
+          class="upload-demo imgUplod"
+          :action="baseURL + '/cms/leader/upload'"
+          multiple
+          :before-upload="beforethumbUploadImg"
+          :on-success="upload_thumb_successImg"
+        >
+          <i class="w-e-icon-image"></i>
+        </el-upload>
+      </div>
+      <div id="div1" style="z-index: 1"></div>
+      <!-- 底部按钮 -->
+      <div class="con_btn">
+        <el-button type="primary" @click="saveLeader">保 存</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { leaderSave, leaderDetail } from '@/apis/tab2'
+import axios from '@/utils/request'
+import E from 'wangeditor'
+export default {
+  name: 'tab2Add',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      time: '',
+      // 服务器前缀地址
+      baseURL: '',
+      token: '',
+      ruleForm: {
+        name: '',
+        sex: 'M',
+        politics: '',
+        job: '',
+        thumb: ''
+      },
+      rules: {
+        name: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        sex: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        politics: [{ required: true, message: '不能为空', trigger: 'change' }],
+        job: [{ required: true, message: '不能为空', trigger: 'blur' }]
+      }
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 富文本上传图片
+    beforethumbUploadImg (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 5
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('图片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('图片大小超过5M!')
+          reject(file)
+        } else if (file.name.length > 32) {
+          this.$message.error('图片名字不能超过32个字!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_successImg (data) {
+      this.$message.success('上传成功')
+      this.editor.txt.append(
+        `<img src="${this.baseURL}${data.data.urlPath}"  style="max-width:100%;display: block;margin: 10px auto;"/><p>&emsp;&emsp;</p>`
+      )
+    },
+    // 点击保存
+    async saveLeader () {
+      // console.log(998, this.startTime, this.endTime)
+      if (this.ruleForm.thumb === '') {
+        return this.$message.warning('图片不能为空')
+      }
+      if (!this.time) {
+        return this.$message.warning('任期不能为空')
+      }
+      if (this.editor.txt.html() === '') {
+        return this.$message.warning('领导简介不能为空')
+      }
+      try {
+        await this.$refs.ruleForm.validate()
+        const obj = {
+          ...this.ruleForm,
+          description: this.editor.txt.html(),
+          tenure: this.time[0] + ',' + this.time[1]
+        }
+        const res = await leaderSave(obj)
+        if (res.code === 0) {
+          this.$message.success('操作成功')
+          this.$router.push('/layout/tab2')
+        } else this.$message.warning(res.msg)
+        // console.log(998, obj)
+      } catch (error) {
+        console.log(error)
+        this.$message.warning('有字段不符合要求')
+      }
+    },
+    // 上传图片
+    beforethumbUpload (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 20
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('照片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('照片大小超过20M!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_success (data) {
+      this.$message.success('上传成功')
+      // console.log('图片上传成功', data.data.urlPath)
+      this.ruleForm.thumb = data.data.urlPath
+    },
+    // 点击返回
+    goBack () {
+      this.$confirm('点击返回后,编辑的信息将无法保存,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          this.$router.push('/layout/tab2')
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {},
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  async mounted () {
+    // 初始化富文本
+    // 富文本
+    this.editor = new E('#div1')
+    // 配置字体
+    this.editor.config.fontNames = [
+      '黑体',
+      '仿宋',
+      '楷体',
+      '标楷体',
+      '华文仿宋',
+      '华文楷体',
+      '宋体',
+      '微软雅黑',
+      'Arial',
+      'Tahoma',
+      'Verdana',
+      'Times New Roman'
+    ]
+    this.editor.config.showLinkVideo = false
+    this.editor.create()
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('CQLJXU_token')
+    // 如果是编辑
+    if (this.$route.query.id) {
+      const res = await leaderDetail(Number(this.$route.query.id))
+      this.ruleForm = res.data
+      console.log(998, res)
+      // 富文本回显
+      this.editor.txt.html(res.data.description)
+      // 日期回显
+      this.time = res.data.tenure.split(',')
+    }
+
+    // this.editor.txt.html('')
+  },
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab2Add {
+  height: 100%;
+  .conten {
+    padding-bottom: 10px;
+    overflow-y: auto;
+    height: calc(100% - 32px);
+    .con_top {
+      position: relative;
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+      &::after{
+        content: '*';
+        position: absolute;
+        top: -1px;
+        left: 10px;
+        color: #F56C6C;
+      }
+      .imgUplod {
+        /deep/.w-e-icon-image {
+          color: #999;
+          display: inline-block;
+          width: 40px;
+          height: 40px;
+          line-height: 40px;
+        }
+        /deep/.el-upload-list {
+          display: none !important;
+        }
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        cursor: pointer;
+        position: absolute;
+        z-index: 9999;
+        top: 53px;
+        right: 121px;
+        width: 40px;
+        height: 40px;
+        &:hover {
+          background-color: #f6f6f6;
+          /deep/.w-e-icon-image {
+            color: black;
+          }
+        }
+      }
+    }
+    .biaoshi1::before {
+      left: -64px;
+      top: -10px;
+    }
+    .biaoshi2::before {
+      left: -78px;
+    }
+    /deep/.el-icon-plus {
+      border: 1px dashed #ccc;
+    }
+    .avatar-uploader .el-upload {
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+    }
+    .avatar-uploader .el-upload:hover {
+      border-color: #3e5eb3;
+    }
+    .avatar-uploader-icon {
+      font-size: 28px;
+      color: #8c939d;
+      width: 178px;
+      height: 178px;
+      line-height: 178px;
+      text-align: center;
+    }
+    #div1 {
+      width: 85%;
+      margin: 0 auto;
+    }
+    .con_btn {
+      width: 80px;
+      margin: 15px auto 0;
+    }
+    .imgdiv {
+      max-width: 200px;
+      max-height: 200px;
+      & > img {
+        border: 5px solid #ccc;
+      }
+    }
+    .el-icon-circle-close {
+      font-size: 24px;
+    }
+  }
+}
+</style>

+ 130 - 0
houtai/src/views/tab2/tab2Look.vue

@@ -0,0 +1,130 @@
+<template>
+  <div class="tab2Look">
+    <div class="insideTop">
+      学院领导管理 > 查看领导信息
+      <div class="add">
+        <el-button type="primary" @click="$router.push('/layout/tab2')"
+          >返 回</el-button
+        >
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <div class="row">
+        <div>姓名:</div>
+        <span>{{myObj.name}}</span>
+      </div>
+      <div class="row">
+        <div>性别:</div>
+        <span>{{myObj.sex==='M'?'男':'女'}}</span>
+      </div>
+      <div class="row">
+        <div>政治面貌:</div>
+        <span>{{myObj.politics}}</span>
+      </div>
+      <div class="row">
+        <div>任期职位:</div>
+        <span>{{myObj.job}}</span>
+      </div>
+      <div class="row">
+        <div>任期:</div>
+        <span>{{time}}</span>
+      </div>
+      <div class="row">
+        <div>领导照片:</div>
+        <el-image
+          v-if="srcList.length!==0"
+          style="width: 200px; height: 200px"
+          :src="srcList[0]"
+          :preview-src-list="srcList"
+        >
+        </el-image>
+      </div>
+      <div class="row">
+        <div>显示设置:</div>
+        <el-switch disabled v-model="myObj.display" active-color="#b9412e" :active-value='1' :inactive-value='0'> </el-switch>
+      </div>
+      <div class="con_top">领导简介</div>
+      <div id="div1" v-html="myObj.description"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+import moment from 'moment'
+import { leaderDetail } from '@/apis/tab2'
+import axios from '@/utils/request'
+export default {
+  name: 'tab2Look',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      baseURL: '',
+      myObj: {},
+      time: '',
+      srcList: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {},
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 通过父亲传过来的id获取详情
+    if (this.$route.query.id) {
+      const res = await leaderDetail(Number(this.$route.query.id))
+      this.myObj = res.data
+      this.srcList = [this.baseURL + res.data.thumb]
+      // 处理日期
+      this.time = moment((res.data.tenure.split(','))[0]).format('YYYY年MM月') + '-' + moment((res.data.tenure.split(','))[1]).format('YYYY年MM月')
+    }
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab2Look {
+  height: 100%;
+  .conten {
+    padding-bottom: 20px;
+    overflow-y: auto;
+    position: relative;
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .row {
+      display: flex;
+      margin: 25px 0;
+      & > div {
+        width: 120px;
+        text-align: right;
+      }
+    }
+    #div1{
+      width: 85%;
+      margin: 0 auto;
+    }
+  }
+}
+</style>

+ 354 - 0
houtai/src/views/tab3/index.vue

@@ -0,0 +1,354 @@
+<template>
+  <div class="tab3">
+    <div class="insideTop">
+      学籍管理
+      <div class="add">
+        <el-button type="primary" @click="$router.push('/layout/tab3Add')"
+          >新增学籍信息</el-button
+        >
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="classify">全部</div>
+      <div class="search">
+        <span>发布时间:</span>
+        <el-date-picker
+          style="width: 240px"
+          v-model="time"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+        >
+        </el-date-picker>
+        <span class="search_k">关键字:</span>
+        <el-input
+          v-model="formData.searchKey"
+          placeholder="请输入姓名或学籍号"
+          style="width: 240px"
+        ></el-input>
+        <span class="search_k">排序:</span>
+        <el-select
+          v-model="formData.sortType"
+          placeholder="请选择"
+          style="width: 240px"
+        >
+          <el-option label="发布时间" :value="0"></el-option>
+          <el-option label="排序编号" :value="1"></el-option>
+        </el-select>
+        <!-- 右侧按钮 -->
+        <div class="search_btn">
+          <el-button type="primary" @click="searchBtn">查 询</el-button>
+          <el-button @click="resetBtn">重 置</el-button>
+        </div>
+      </div>
+      <!-- 表格 -->
+      <div class="table">
+        <el-table :data="tableData" style="width: 100%">
+          <el-table-column label="序号" width="80">
+            <template slot-scope="scope">
+              {{
+                scope.$index + (formData.pageNum - 1) * formData.pageSize + 1
+              }}
+            </template>
+          </el-table-column>
+          <el-table-column label="姓名" width="250">
+            <template #default="{ row }">
+              <span class="table_name" :title="row.name">{{ row.name }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="学籍号" width="200">
+            <template #default="{ row }">
+              <span class="table_name" :title="row.num">{{ row.num }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="封面图片" width="120">
+            <template #default="{ row }">
+              <img
+                class="table_img"
+                :src="baseURL + row.thumb"
+                alt=""
+                :onerror="defaultImg"
+              />
+            </template>
+          </el-table-column>
+          <el-table-column prop="visit" label="阅读" width="100"> </el-table-column>
+          <el-table-column prop="creatorName" label="发布人"> </el-table-column>
+          <el-table-column prop="createTime" label="发布时间" width="200">
+          </el-table-column>
+          <el-table-column prop="address" label="排序" width="80">
+            <template #default="{ row }">
+              <el-input
+                type="text"
+                v-model="row.sort"
+                @blur="changeSort(row.sort, row.id)"
+              ></el-input>
+            </template>
+          </el-table-column>
+          <el-table-column label="是否显示">
+            <template #default="{ row }">
+              <el-switch
+                v-model="row.display"
+                active-color="#b9412e"
+                :active-value="1"
+                :inactive-value="0"
+                @change="changeSwit($event, row.id)"
+              >
+              </el-switch>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作">
+            <template #default="{ row }">
+              <el-button type="text" @click="lookGood(row.id)">查看</el-button>
+              <el-button
+                type="text"
+                v-if="!row.display"
+                @click="editLeader(row.id)"
+                >编辑</el-button
+              >
+              <el-button
+                type="text"
+                v-if="!row.display"
+                @click="delLeader(row.id)"
+                >删除</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging">
+      <el-pagination
+        layout="sizes,prev, pager, next,jumper"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  studentList,
+  studentSort,
+  studentDisplay,
+  studentRemove
+} from '@/apis/tab3'
+import axios from '@/utils/request'
+export default {
+  name: 'tab3',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      total: 0,
+      time: '',
+      formData: {
+        startTime: '',
+        endTime: '',
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: '',
+        sortType: 0
+      },
+      tableData: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {
+    time (val) {
+      this.handleSelect(val)
+    }
+  },
+  // 方法集合
+  methods: {
+    // 点击编辑
+    editLeader (id) {
+      this.$router.push({
+        path: '/layout/tab3Add',
+        query: { id }
+      })
+    },
+    // 点击删除
+    delLeader (id) {
+      this.$confirm('删除后,信息无法恢复,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          const res = await studentRemove(id)
+          if (res.code === 0) {
+            this.$message.success('删除成功')
+            this.studentList(this.formData)
+          } else this.$message.warning(res.msg)
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    }, // 点击开关
+    async changeSwit (val, id) {
+      const res = await studentDisplay(id, val)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.studentList(this.formData)
+      } else this.$message.warning(res.msg)
+      // console.log(998, val, id)
+    },
+    // 排序
+    async changeSort (val, id) {
+      // console.log(998, val, id)
+      if (Number(val) < 1) return this.$message.warning('不能小于1')
+      const res = await studentSort(id, Number(val))
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.studentList(this.formData)
+      } else this.$message.warning(res.msg)
+    },
+    // 点击重置
+    resetBtn () {
+      this.formData.searchKey = ''
+      this.formData.sortType = 0
+      this.time = ''
+      this.formData.pageNum = 1
+      this.formData.startTime = this.formData.endTime = ''
+      this.studentList(this.formData)
+    },
+    // 点击查询
+    searchBtn () {
+      this.formData.pageNum = 1
+      this.studentList(this.formData)
+    },
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.studentList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.studentList(this.formData)
+    },
+    // 点击查看
+    lookGood (id) {
+      this.$router.push({
+        path: '/layout/tab3Look',
+        query: { id }
+      })
+    },
+    // 时间处理----------------
+    handleSelect (e) {
+      const date = []
+      for (const i in e) {
+        date.push(this.gettime(e[i]))
+      }
+      this.formData.startTime = date[0]
+      if (date[1]) {
+        this.formData.endTime = date[1].replace('00:00:00', '23:59:59')
+      }
+      if (e === null) this.formData.endTime = ''
+    },
+    gettime (data) {
+      const value =
+        data.getFullYear() +
+        '-' +
+        this.checkTime(data.getMonth() + 1) +
+        '-' +
+        this.checkTime(data.getDate()) +
+        ' ' +
+        this.checkTime(data.getHours()) +
+        ':' +
+        this.checkTime(data.getMinutes()) +
+        ':' +
+        this.checkTime(data.getSeconds())
+      return value
+    },
+    checkTime (i) {
+      if (i < 10) {
+        i = '0' + i
+      }
+      return i
+    },
+    // 封装获取列表函数
+    async studentList (data) {
+      const res = await studentList(data)
+      // console.log(998, res)
+      this.total = res.data.total
+      this.tableData = res.data.records
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    this.studentList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab3 {
+  height: 100%;
+  .insideTop .add {
+    right: 55px;
+  }
+  .conten {
+    padding: 15px 30px 0;
+    height: calc(100% - 32px);
+    .classify {
+      text-align: center;
+      width: 40px;
+      padding-bottom: 10px;
+      color: #b9412e;
+      border-bottom: 2px solid #b9412e;
+    }
+    .search {
+      margin-bottom: 20px;
+      position: relative;
+      margin-top: 12px;
+      height: 40px;
+      .search_k {
+        margin-left: 30px;
+      }
+      .search_btn {
+        display: flex;
+        justify-content: space-between;
+        width: 200px;
+        position: absolute;
+        right: 22px;
+        top: 0;
+      }
+    }
+    .table {
+      max-width: 1533px;
+    }
+    /deep/.el-table__body-wrapper {
+      max-height: 485px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    bottom: 15px;
+    right: 50px;
+  }
+}
+</style>

+ 425 - 0
houtai/src/views/tab3/tab3Add.vue

@@ -0,0 +1,425 @@
+<template>
+  <div class="tab3Add">
+    <div class="insideTop">
+      学籍管理 > {{ ruleForm.id ? "编辑" : "新增" }}学籍信息
+      <div class="add">
+        <el-button type="primary" @click="goBack">返 回</el-button>
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <!-- 表单 -->
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="120px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="姓名:" prop="name">
+          <el-input
+            v-model="ruleForm.name"
+            maxlength="25"
+            show-word-limit
+            style="width: 500px"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="性别:" prop="sex">
+          <el-radio v-model="ruleForm.sex" label="M">男</el-radio>
+          <el-radio v-model="ruleForm.sex" label="F">女</el-radio>
+        </el-form-item>
+        <el-form-item label="政治面貌:" prop="politics">
+          <el-select
+            v-model="ruleForm.politics"
+            placeholder="请选择"
+            style="width: 500px"
+          >
+            <el-option label="中共党员" value="中共党员"></el-option>
+            <el-option label="中共预备党员" value="中共预备党员"></el-option>
+            <el-option label="共青团员" value="共青团员"></el-option>
+            <el-option label="民革党员" value="民革党员"></el-option>
+            <el-option label="民盟盟员" value="民盟盟员"></el-option>
+            <el-option label="民建会员" value="民建会员"></el-option>
+            <el-option label="民进会员" value="民进会员"></el-option>
+            <el-option label="农工党党员" value="农工党党员"></el-option>
+            <el-option label="致公党党员" value="致公党党员"></el-option>
+            <el-option label="九三学社社员" value="九三学社社员"></el-option>
+            <el-option label="台盟盟员" value="台盟盟员"></el-option>
+            <el-option label="无党派人士" value="无党派人士"></el-option>
+            <el-option label="群众" value="群众"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="学籍号:" prop="num">
+          <el-input
+            v-model="ruleForm.num"
+            maxlength="25"
+            show-word-limit
+            style="width: 500px"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="专业:" prop="job">
+          <el-input
+            v-model="ruleForm.job"
+            maxlength="25"
+            show-word-limit
+            style="width: 500px"
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="学年:">
+          <i class="biaoshi biaoshi1"></i>
+          <el-date-picker
+            style="width: 500px"
+            v-model="time"
+            type="monthrange"
+            range-separator="-"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+          >
+          </el-date-picker>
+        </el-form-item>
+        <!-- 图片和附件 -->
+        <el-form-item label="学生照片">
+          <i class="biaoshi biaoshi2"></i>
+          <el-upload
+            class="avatar-uploader"
+            :action="baseURL + '/cms/student/upload'"
+            :headers="{
+              token,
+            }"
+            :show-file-list="true"
+            :before-upload="beforethumbUpload"
+            :on-success="upload_thumb_success"
+          >
+            <div v-if="ruleForm.thumb" class="imgdiv">
+              <img
+                style="max-width: 200px; max-height: 200px; display: block"
+                :src="baseURL + ruleForm.thumb"
+              />
+              <i
+                class="el-icon-circle-close"
+                @click.stop="ruleForm.thumb = ''"
+              ></i>
+            </div>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+          <p class="upHint">
+            格式要求:支持png、jpg、gif和jpeg的图片格式;最大支持20MB。
+          </p>
+        </el-form-item>
+      </el-form>
+      <!-- 富文本 -->
+      <div class="con_top">
+        校园动态
+        <!-- 富文本上传图片 -->
+        <el-upload
+          :headers="{
+            token,
+          }"
+          accept=".png,.jpg,.jpeg,.gif"
+          title="上传图片"
+          class="upload-demo imgUplod"
+          :action="baseURL + '/cms/student/upload'"
+          multiple
+          :before-upload="beforethumbUploadImg"
+          :on-success="upload_thumb_successImg"
+        >
+          <i class="w-e-icon-image"></i>
+        </el-upload>
+      </div>
+      <div id="div1" style="z-index: 1"></div>
+      <!-- 底部按钮 -->
+      <div class="con_btn">
+        <el-button type="primary" @click="saveLeader">保 存</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { studentSave, studentDetail } from '@/apis/tab3'
+import axios from '@/utils/request'
+import E from 'wangeditor'
+export default {
+  name: 'tab3Add',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      time: '',
+      // 服务器前缀地址
+      baseURL: '',
+      token: '',
+      ruleForm: {
+        name: '',
+        sex: 'M',
+        politics: '',
+        num: '',
+        job: '',
+        thumb: ''
+      },
+      rules: {
+        name: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        sex: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        politics: [{ required: true, message: '不能为空', trigger: 'change' }],
+        num: [{ required: true, message: '不能为空', trigger: 'blur' }],
+        job: [{ required: true, message: '不能为空', trigger: 'blur' }]
+      }
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+    // 富文本上传图片
+    beforethumbUploadImg (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 5
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('图片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('图片大小超过5M!')
+          reject(file)
+        } else if (file.name.length > 32) {
+          this.$message.error('图片名字不能超过32个字!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_successImg (data) {
+      this.$message.success('上传成功')
+      this.editor.txt.append(
+        `<img src="${this.baseURL}${data.data.urlPath}"  style="max-width:100%;display: block;margin: 10px auto;"/><p>&emsp;&emsp;</p>`
+      )
+    },
+    // 点击保存
+    async saveLeader () {
+      if (this.ruleForm.thumb === '') {
+        return this.$message.warning('图片不能为空')
+      }
+      if (!this.time) {
+        return this.$message.warning('学年不能为空')
+      }
+      if (this.editor.txt.html() === '') {
+        return this.$message.warning('校园动态不能为空')
+      }
+      try {
+        await this.$refs.ruleForm.validate()
+        const obj = {
+          ...this.ruleForm,
+          description: this.editor.txt.html(),
+          tenure: this.time[0] + ',' + this.time[1]
+        }
+        const res = await studentSave(obj)
+        if (res.code === 0) {
+          this.$message.success('操作成功')
+          this.$router.push('/layout/tab3')
+        } else this.$message.warning(res.msg)
+        // console.log(998, obj)
+      } catch (error) {
+        console.log(error)
+        this.$message.warning('有字段不符合要求')
+      }
+    },
+    // 上传图片
+    beforethumbUpload (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 20
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('照片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('照片大小超过20M!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_success (data) {
+      this.$message.success('上传成功')
+      // console.log('图片上传成功', data.data.urlPath)
+      this.ruleForm.thumb = data.data.urlPath
+    },
+    // 点击返回
+    goBack () {
+      this.$confirm('点击返回后,编辑的信息将无法保存,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          this.$router.push('/layout/tab3')
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('CQLJXU_token')
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  async mounted () {
+    // 初始化富文本
+    // 富文本
+    this.editor = new E('#div1')
+    // 配置字体
+    this.editor.config.fontNames = [
+      '黑体',
+      '仿宋',
+      '楷体',
+      '标楷体',
+      '华文仿宋',
+      '华文楷体',
+      '宋体',
+      '微软雅黑',
+      'Arial',
+      'Tahoma',
+      'Verdana',
+      'Times New Roman'
+    ]
+    this.editor.config.showLinkVideo = false
+    this.editor.create()
+    // 如果是编辑
+    if (this.$route.query.id) {
+      const res = await studentDetail(Number(this.$route.query.id))
+      this.ruleForm = res.data
+      console.log(998, res)
+      // 富文本回显
+      this.editor.txt.html(res.data.description)
+      // 日期回显
+      this.time = res.data.tenure.split(',')
+    }
+  },
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab3Add {
+  height: 100%;
+  .conten {
+    padding-bottom: 10px;
+    overflow-y: auto;
+    height: calc(100% - 32px);
+    .con_top {
+      position: relative;
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+      &::after {
+        content: "*";
+        position: absolute;
+        top: -1px;
+        left: 10px;
+        color: #f56c6c;
+      }
+      .imgUplod {
+        /deep/.w-e-icon-image {
+          color: #999;
+          display: inline-block;
+          width: 40px;
+          height: 40px;
+          line-height: 40px;
+        }
+        /deep/.el-upload-list {
+          display: none !important;
+        }
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        cursor: pointer;
+        position: absolute;
+        z-index: 9999;
+        top: 53px;
+        right: 121px;
+        width: 40px;
+        height: 40px;
+        &:hover {
+          background-color: #f6f6f6;
+          /deep/.w-e-icon-image {
+            color: black;
+          }
+        }
+      }
+    }
+    .biaoshi1::before {
+      left: -64px;
+      top: -10px;
+    }
+    .biaoshi2::before {
+      left: -78px;
+    }
+    /deep/.el-icon-plus {
+      border: 1px dashed #ccc;
+    }
+    .avatar-uploader .el-upload {
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+    }
+    .avatar-uploader .el-upload:hover {
+      border-color: #3e5eb3;
+    }
+    .avatar-uploader-icon {
+      font-size: 28px;
+      color: #8c939d;
+      width: 178px;
+      height: 178px;
+      line-height: 178px;
+      text-align: center;
+    }
+    #div1 {
+      width: 85%;
+      margin: 0 auto;
+    }
+    .con_btn {
+      width: 80px;
+      margin: 15px auto 0;
+    }
+    .imgdiv {
+      max-width: 200px;
+      max-height: 200px;
+      & > img {
+        border: 5px solid #ccc;
+      }
+    }
+    .el-icon-circle-close {
+      font-size: 24px;
+    }
+  }
+}
+</style>

+ 133 - 0
houtai/src/views/tab3/tab3Look.vue

@@ -0,0 +1,133 @@
+<template>
+  <div class="tab3Look">
+    <div class="insideTop">
+      学籍管理 > 查看学籍信息
+      <div class="add">
+        <el-button type="primary" @click="$router.push('/layout/tab3')"
+          >返 回</el-button
+        >
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <div class="row">
+        <div>姓名:</div>
+        <span>{{myObj.name}}</span>
+      </div>
+      <div class="row">
+        <div>性别:</div>
+        <span>{{myObj.sex==='M'?'男':'女'}}</span>
+      </div>
+      <div class="row">
+        <div>政治面貌:</div>
+        <span>{{myObj.politics}}</span>
+      </div>
+      <div class="row">
+        <div>学籍号:</div>
+        <span>{{myObj.num}}</span>
+      </div>
+      <div class="row">
+        <div>专业:</div>
+        <span>{{myObj.job}}</span>
+      </div>
+      <div class="row">
+        <div>学年:</div>
+        <span>{{time}}</span>
+      </div>
+      <div class="row">
+        <div>学生照片:</div>
+        <el-image
+          v-if="srcList.length!==0"
+          style="width: 200px; height: 200px"
+          :src="srcList[0]"
+          :preview-src-list="srcList"
+        >
+        </el-image>
+      </div>
+      <div class="row">
+        <div>显示设置:</div>
+        <el-switch disabled v-model="myObj.display" active-color="#b9412e" :active-value='1' :inactive-value='0'> </el-switch>
+      </div>
+      <div class="con_top">校园动态</div>
+      <div id="div1" v-html="myObj.description"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+import moment from 'moment'
+import { studentDetail } from '@/apis/tab3'
+import axios from '@/utils/request'
+export default {
+  name: 'tab3Look',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      baseURL: '',
+      myObj: {},
+      time: '',
+      srcList: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {},
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 通过父亲传过来的id获取详情
+    if (this.$route.query.id) {
+      const res = await studentDetail(Number(this.$route.query.id))
+      this.myObj = res.data
+      this.srcList = [this.baseURL + res.data.thumb]
+      // 处理日期
+      this.time = moment((res.data.tenure.split(','))[0]).format('YYYY年MM月') + '-' + moment((res.data.tenure.split(','))[1]).format('YYYY年MM月')
+    }
+  }, // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab3Look {
+  height: 100%;
+  .conten {
+    padding-bottom: 20px;
+    overflow-y: auto;
+    position: relative;
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .row {
+      display: flex;
+      margin: 25px 0;
+      & > div {
+        width: 120px;
+        text-align: right;
+      }
+    }
+    #div1{
+      width: 85%;
+      margin: 0 auto;
+    }
+  }
+}
+</style>

+ 349 - 0
houtai/src/views/tab4/index.vue

@@ -0,0 +1,349 @@
+<template>
+  <div class="tab4">
+    <div class="insideTop">
+      学院宣传片管理
+      <div class="add">
+        <el-button type="primary" @click="$router.push('/layout/tab4Add')"
+          >新增宣传片</el-button
+        >
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="classify">全部</div>
+      <div class="search">
+        <span>发布时间:</span>
+        <el-date-picker
+          style="width: 240px"
+          v-model="time"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+        >
+        </el-date-picker>
+        <span class="search_k">标题关键字:</span>
+        <el-input
+          v-model="formData.searchKey"
+          placeholder="请输入"
+          style="width: 240px"
+        ></el-input>
+        <span class="search_k">排序:</span>
+        <el-select
+          v-model="formData.sortType"
+          placeholder="请选择"
+          style="width: 240px"
+        >
+          <el-option label="发布时间" :value="0"></el-option>
+          <el-option label="排序编号" :value="1"></el-option>
+        </el-select>
+        <!-- 右侧按钮 -->
+        <div class="search_btn">
+          <el-button type="primary" @click="searchBtn">查 询</el-button>
+          <el-button @click="resetBtn">重 置</el-button>
+        </div>
+      </div>
+      <!-- 表格 -->
+      <div class="table">
+        <el-table :data="tableData" style="width: 100%">
+          <el-table-column label="序号" width="80">
+            <template slot-scope="scope">
+              {{
+                scope.$index + (formData.pageNum - 1) * formData.pageSize + 1
+              }}
+            </template>
+          </el-table-column>
+          <el-table-column label="标题" width="250">
+            <template #default="{ row }">
+              <span class="table_name" :title="row.name">{{ row.name }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="封面图片" width="120">
+            <template #default="{ row }">
+              <img
+                class="table_img"
+                :src="baseURL + row.thumb"
+                alt=""
+                :onerror="defaultImg"
+              />
+            </template>
+          </el-table-column>
+          <el-table-column prop="visit" label="阅读"> </el-table-column>
+          <el-table-column prop="creatorName" label="发布人"> </el-table-column>
+          <el-table-column prop="createTime" label="发布时间" width="200">
+          </el-table-column>
+          <el-table-column prop="address" label="排序" width="80">
+            <template #default="{ row }">
+              <el-input
+                type="text"
+                v-model="row.sort"
+                @blur="changeSort(row.sort, row.id)"
+              ></el-input>
+            </template>
+          </el-table-column>
+          <el-table-column label="是否显示">
+            <template #default="{ row }">
+              <el-switch
+                v-model="row.display"
+                active-color="#b9412e"
+                :active-value="1"
+                :inactive-value="0"
+                @change="changeSwit($event, row.id)"
+              >
+              </el-switch>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作">
+            <template #default="{ row }">
+              <el-button type="text" @click="lookGood(row.id)">查看</el-button>
+              <el-button
+                type="text"
+                v-if="!row.display"
+                @click="editLeader(row.id)"
+                >编辑</el-button
+              >
+              <el-button
+                type="text"
+                v-if="!row.display"
+                @click="delLeader(row.id)"
+                >删除</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging">
+      <el-pagination
+        layout="sizes,prev, pager, next,jumper"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  videoList,
+  videoSort,
+  videoDisplay,
+  videoRemove
+} from '@/apis/tab4'
+import axios from '@/utils/request'
+export default {
+  name: 'tab4',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      total: 0,
+      time: '',
+      formData: {
+        startTime: '',
+        endTime: '',
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: '',
+        sortType: 0
+      },
+      tableData: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {
+    time (val) {
+      this.handleSelect(val)
+    }
+  },
+  // 方法集合
+  methods: {
+    // 点击编辑
+    editLeader (id) {
+      this.$router.push({
+        path: '/layout/tab4Add',
+        query: { id }
+      })
+    },
+    // 点击删除
+    delLeader (id) {
+      this.$confirm('删除后,信息无法恢复,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          const res = await videoRemove(id)
+          if (res.code === 0) {
+            this.$message.success('删除成功')
+            this.videoList(this.formData)
+          } else this.$message.warning(res.msg)
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    }, // 点击开关
+    async changeSwit (val, id) {
+      const res = await videoDisplay(id, val)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.videoList(this.formData)
+      } else this.$message.warning(res.msg)
+      // console.log(998, val, id)
+    },
+    // 排序
+    async changeSort (val, id) {
+      // console.log(998, val, id)
+      if (Number(val) < 1) return this.$message.warning('不能小于1')
+      const res = await videoSort(id, Number(val))
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.videoList(this.formData)
+      } else this.$message.warning(res.msg)
+    },
+    // 点击重置
+    resetBtn () {
+      this.formData.searchKey = ''
+      this.formData.sortType = 0
+      this.time = ''
+      this.formData.pageNum = 1
+      this.formData.startTime = this.formData.endTime = ''
+      this.videoList(this.formData)
+    },
+    // 点击查询
+    searchBtn () {
+      this.formData.pageNum = 1
+      this.videoList(this.formData)
+    },
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.videoList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.videoList(this.formData)
+    },
+    // 点击查看
+    lookGood (id) {
+      this.$router.push({
+        path: '/layout/tab4Look',
+        query: { id }
+      })
+    },
+    // 时间处理----------------
+    handleSelect (e) {
+      const date = []
+      for (const i in e) {
+        date.push(this.gettime(e[i]))
+      }
+      this.formData.startTime = date[0]
+      if (date[1]) {
+        this.formData.endTime = date[1].replace('00:00:00', '23:59:59')
+      }
+      if (e === null) this.formData.endTime = ''
+    },
+    gettime (data) {
+      const value =
+        data.getFullYear() +
+        '-' +
+        this.checkTime(data.getMonth() + 1) +
+        '-' +
+        this.checkTime(data.getDate()) +
+        ' ' +
+        this.checkTime(data.getHours()) +
+        ':' +
+        this.checkTime(data.getMinutes()) +
+        ':' +
+        this.checkTime(data.getSeconds())
+      return value
+    },
+    checkTime (i) {
+      if (i < 10) {
+        i = '0' + i
+      }
+      return i
+    },
+    // 封装获取列表函数
+    async videoList (data) {
+      const res = await videoList(data)
+      // console.log(998, res)
+      this.total = res.data.total
+      this.tableData = res.data.records
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    this.videoList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab4 {
+  height: 100%;
+  .insideTop .add {
+    right: 55px;
+  }
+  .conten {
+    padding: 15px 30px 0;
+    height: calc(100% - 32px);
+    .classify {
+      text-align: center;
+      width: 40px;
+      padding-bottom: 10px;
+      color: #b9412e;
+      border-bottom: 2px solid #b9412e;
+    }
+    .search {
+      margin-bottom: 20px;
+      position: relative;
+      margin-top: 12px;
+      height: 40px;
+      .search_k {
+        margin-left: 30px;
+      }
+      .search_btn {
+        display: flex;
+        justify-content: space-between;
+        width: 200px;
+        position: absolute;
+        right: 22px;
+        top: 0;
+      }
+    }
+    .table {
+      max-width: 1533px;
+    }
+    /deep/.el-table__body-wrapper {
+      max-height: 485px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    bottom: 15px;
+    right: 50px;
+  }
+}
+</style>

+ 298 - 0
houtai/src/views/tab4/tab4Add.vue

@@ -0,0 +1,298 @@
+<template>
+  <div class="tab4Add">
+    <div class="insideTop">
+      学院宣传片管理 > {{ruleForm.id?'编辑':'新增'}}宣传片
+      <div class="add">
+        <el-button type="primary" @click="goBack">返 回</el-button>
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <!-- 表单 -->
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="140px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="标题:" prop="name">
+          <el-input
+            v-model="ruleForm.name"
+            maxlength="25"
+            show-word-limit
+            style="width: 500px"
+          ></el-input>
+        </el-form-item>
+        <!-- 图片和附件 -->
+        <el-form-item label="封面图片:">
+          <i class="biaoshi"></i>
+          <el-upload
+            class="avatar-uploader"
+            :action="baseURL + '/cms/video/upload'"
+            :headers="{
+              token,
+            }"
+            :show-file-list="true"
+            :before-upload="beforethumbUpload"
+            :on-success="upload_thumb_success"
+          >
+            <div v-if="ruleForm.thumb" class="imgdiv">
+              <img
+                style="width: 100%; height: 100%"
+                :src="baseURL + ruleForm.thumb"
+              />
+              <i
+                class="el-icon-circle-close"
+                @click.stop="ruleForm.thumb = ''"
+              ></i>
+            </div>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+          <p class="upHint">
+            格式要求:支持png、jpg、gif和jpeg的图片格式;最大支持20MB。
+          </p>
+        </el-form-item>
+        <!-- 上传附件 -->
+        <el-form-item label="视频文件:">
+          <i class="biaoshi"></i>
+          <el-upload
+            multiple
+            class="upload-demo"
+            :file-list="fileList"
+            :action="baseURL + '/cms/video/video/upload'"
+            :headers="{ token }"
+            :before-upload="beforeFujian"
+            :on-success="successFujian"
+            :before-remove="beforeRemove"
+            :on-remove="handleRemove"
+            :limit="1"
+            :on-exceed="handleExceed"
+            :show-file-list="true"
+          >
+            <el-button size="small" type="primary">点击上传</el-button>
+            <div class="el-upload__tip" slot="tip">
+              <p class="upHint">格式要求:</p>
+              <p class="upHint">
+                1、仅支持mp4视频格式文件。
+              </p>
+              <p class="upHint">2、最大支持2G的视频文件。</p>
+            </div>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+      <!-- 底部按钮 -->
+      <div class="con_btn">
+        <el-button type="primary" @click="saveGood">保 存</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { videoSave, videoDetail } from '@/apis/tab4'
+import axios from '@/utils/request'
+export default {
+  name: 'tab4Add',
+  components: {},
+  data () {
+    return {
+      fileList: [],
+      // 服务器前缀地址
+      baseURL: '',
+      token: '',
+      ruleForm: {
+        name: '',
+        thumb: '',
+        filePath: '',
+        fileName: ''
+      },
+      rules: {
+        name: [{ required: true, message: '不能为空', trigger: 'blur' }]
+      }
+    }
+  },
+  computed: {},
+  methods: {
+    // 点击保存
+    async saveGood () {
+      if (this.ruleForm.name.trim() === '') { return this.$message.warning('标题不能为空') }
+      if (this.ruleForm.thumb === '') { return this.$message.warning('图片不能为空') }
+      if (this.ruleForm.filePath === '') { return this.$message.warning('文件不能为空') }
+      const obj = { ...this.ruleForm }
+      const res = await videoSave(obj)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.$router.push('/layout/tab4')
+      } else this.$message.warning(res.msg)
+    },
+    // 点击返回
+    goBack () {
+      this.$confirm('点击返回后,编辑的信息将无法保存,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          this.$router.push('/layout/tab4')
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    },
+    // 上传图片
+    beforethumbUpload (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 20
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('照片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('照片大小超过20M!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_success (data) {
+      this.$message.success('上传成功')
+      // console.log('图片上传成功', data.data.urlPath)
+      this.ruleForm.thumb = data.data.urlPath
+    },
+    // 上传附件
+    beforeFujian (file) {
+      console.log('附件上传前', file)
+      const sizeOk = file.size / 1024 / 1024 < 2048
+      const typeOk = file.type === 'video/mp4'
+      return new Promise((resolve, reject) => {
+        if (file.name.length > 32) {
+          this.$message.error('视频名字不能超过32个字')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('视频大小超过2GB!')
+          reject(file)
+        } else if (!typeOk) {
+          this.$message.error('视频格式有误!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    successFujian (file) {
+      console.log('上传附件成功', file)
+      if (file.code === 0) {
+        this.ruleForm.filePath = file.data.urlPath
+        this.ruleForm.fileName = file.data.fileName
+        this.$message.success('上传成功')
+      } else if (file.code === -1) {
+        this.$message.warning('上传失败,不支持的文件格式')
+      }
+    },
+    beforeRemove (file, fileList) {
+      if (file && file.status === 'success') {
+        return this.$confirm(`确定移除 ${file.name}?`)
+      }
+    },
+    handleRemove (file, fileList) {
+      this.ruleForm.filePath = ''
+      this.ruleForm.fileName = ''
+    },
+    handleExceed (files, fileList) {
+      this.$message.warning('只能上传一个视频,请删除原视频后操作')
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('CQLJXU_token')
+    // 通过父亲传过来的id获取详情
+    if (this.$route.query.id) {
+      const res = await videoDetail(Number(this.$route.query.id))
+      this.ruleForm = res.data
+      // 附件回显
+      this.fileList = [{ name: res.data.fileName }]
+      // console.log(998, res)
+    }
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab4Add {
+  height: 100%;
+  .conten {
+    position: relative;
+    /deep/.el-icon-plus {
+      border: 1px dashed #ccc;
+    }
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .biaoshi1::before {
+      left: -120px;
+    }
+    .biaoshi2::before {
+      top: -10px;
+    }
+    .avatar-uploader .el-upload {
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+    }
+    .avatar-uploader .el-upload:hover {
+      border-color: #3e5eb3;
+    }
+    .avatar-uploader-icon {
+      font-size: 28px;
+      color: #8c939d;
+      width: 178px;
+      height: 178px;
+      line-height: 178px;
+      text-align: center;
+    }
+    .con_btn {
+      position: absolute;
+      left: 50%;
+      transform: translateX(-50%);
+      bottom: 15px;
+    }
+    .imgdiv {
+      max-width: 200px;
+      max-height: 200px;
+      & > img {
+        border: 5px solid #ccc;
+      }
+    }
+    .el-icon-circle-close {
+      font-size: 24px;
+    }
+  }
+}
+</style>

+ 119 - 0
houtai/src/views/tab4/tab4Look.vue

@@ -0,0 +1,119 @@
+<!--  -->
+<template>
+  <div class="tab4Look">
+    <div class="insideTop">
+      学院宣传片管理 > 查看宣传片
+      <div class="add">
+        <el-button type="primary" @click="$router.push('/layout/tab4')"
+          >返 回</el-button
+        >
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <div class="row">
+        <div>标题:</div>
+        <span>{{myObj.name}}</span>
+      </div>
+      <div class="row">
+        <div>封面图片:</div>
+        <el-image
+          v-if="srcList.length!==0"
+          style="width: 200px; height: 200px"
+          :src="srcList[0]"
+          :preview-src-list="srcList"
+        >
+        </el-image>
+      </div>
+      <div class="row">
+        <div>视频文件:</div>
+        <a :href="baseURL+myObj.filePath" download>{{myObj.fileName}}</a>
+      </div>
+      <div class="row">
+        <div>显示设置:</div>
+        <el-switch disabled v-model="myObj.display" active-color="#b9412e" :active-value='1' :inactive-value='0'> </el-switch>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { videoDetail } from '@/apis/tab4'
+import axios from '@/utils/request'
+export default {
+  name: 'tab4Look',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      baseURL: '',
+      myObj: {},
+      srcList: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 通过父亲传过来的id获取详情
+    if (this.$route.query.id) {
+      const res = await videoDetail(Number(this.$route.query.id))
+      this.myObj = res.data
+      this.srcList = [this.baseURL + res.data.thumb]
+    }
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab4Look {
+  height: 100%;
+  .conten {
+    overflow-y: auto;
+    position: relative;
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .row {
+      display: flex;
+      margin: 25px 0;
+      & > div {
+        width: 120px;
+        text-align: right;
+      }
+    .imgList{
+      width: 1500px;
+      display: flex;
+      flex-wrap: wrap;
+      /deep/.el-image{
+        margin-right: 30px;
+        margin-bottom: 30px;
+      }
+    }
+    }
+  }
+}
+</style>

+ 349 - 0
houtai/src/views/tab5/index.vue

@@ -0,0 +1,349 @@
+<template>
+  <div class="tab5">
+    <div class="insideTop">
+      校园图片管理
+      <div class="add">
+        <el-button type="primary" @click="$router.push('/layout/tab5Add')"
+          >新增校园图片</el-button
+        >
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="classify">全部</div>
+      <div class="search">
+        <span>发布时间:</span>
+        <el-date-picker
+          style="width: 240px"
+          v-model="time"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+        >
+        </el-date-picker>
+        <span class="search_k">标题关键字:</span>
+        <el-input
+          v-model="formData.searchKey"
+          placeholder="请输入"
+          style="width: 240px"
+        ></el-input>
+        <span class="search_k">排序:</span>
+        <el-select
+          v-model="formData.sortType"
+          placeholder="请选择"
+          style="width: 240px"
+        >
+          <el-option label="发布时间" :value="0"></el-option>
+          <el-option label="排序编号" :value="1"></el-option>
+        </el-select>
+        <!-- 右侧按钮 -->
+        <div class="search_btn">
+          <el-button type="primary" @click="searchBtn">查 询</el-button>
+          <el-button @click="resetBtn">重 置</el-button>
+        </div>
+      </div>
+      <!-- 表格 -->
+      <div class="table">
+        <el-table :data="tableData" style="width: 100%">
+          <el-table-column label="序号" width="80">
+            <template slot-scope="scope">
+              {{
+                scope.$index + (formData.pageNum - 1) * formData.pageSize + 1
+              }}
+            </template>
+          </el-table-column>
+          <el-table-column label="标题" width="250">
+            <template #default="{ row }">
+              <span class="table_name" :title="row.name">{{ row.name }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="封面图片" width="120">
+            <template #default="{ row }">
+              <img
+                class="table_img"
+                :src="baseURL + row.thumb"
+                alt=""
+                :onerror="defaultImg"
+              />
+            </template>
+          </el-table-column>
+          <el-table-column prop="visit" label="阅读"> </el-table-column>
+          <el-table-column prop="creatorName" label="发布人"> </el-table-column>
+          <el-table-column prop="createTime" label="发布时间" width="200">
+          </el-table-column>
+          <el-table-column prop="address" label="排序" width="80">
+            <template #default="{ row }">
+              <el-input
+                type="text"
+                v-model="row.sort"
+                @blur="changeSort(row.sort, row.id)"
+              ></el-input>
+            </template>
+          </el-table-column>
+          <el-table-column label="是否显示">
+            <template #default="{ row }">
+              <el-switch
+                v-model="row.display"
+                active-color="#b9412e"
+                :active-value="1"
+                :inactive-value="0"
+                @change="changeSwit($event, row.id)"
+              >
+              </el-switch>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作">
+            <template #default="{ row }">
+              <el-button type="text" @click="lookGood(row.id)">查看</el-button>
+              <el-button
+                type="text"
+                v-if="!row.display"
+                @click="editLeader(row.id)"
+                >编辑</el-button
+              >
+              <el-button
+                type="text"
+                v-if="!row.display"
+                @click="delLeader(row.id)"
+                >删除</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging">
+      <el-pagination
+        layout="sizes,prev, pager, next,jumper"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  imgList,
+  imgSort,
+  imgDisplay,
+  imgRemove
+} from '@/apis/tab5'
+import axios from '@/utils/request'
+export default {
+  name: 'tab5',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      total: 0,
+      time: '',
+      formData: {
+        startTime: '',
+        endTime: '',
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: '',
+        sortType: 0
+      },
+      tableData: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {
+    time (val) {
+      this.handleSelect(val)
+    }
+  },
+  // 方法集合
+  methods: {
+    // 点击编辑
+    editLeader (id) {
+      this.$router.push({
+        path: '/layout/tab5Add',
+        query: { id }
+      })
+    },
+    // 点击删除
+    delLeader (id) {
+      this.$confirm('删除后,信息无法恢复,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          const res = await imgRemove(id)
+          if (res.code === 0) {
+            this.$message.success('删除成功')
+            this.imgList(this.formData)
+          } else this.$message.warning(res.msg)
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    }, // 点击开关
+    async changeSwit (val, id) {
+      const res = await imgDisplay(id, val)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.imgList(this.formData)
+      } else this.$message.warning(res.msg)
+      // console.log(998, val, id)
+    },
+    // 排序
+    async changeSort (val, id) {
+      // console.log(998, val, id)
+      if (Number(val) < 1) return this.$message.warning('不能小于1')
+      const res = await imgSort(id, Number(val))
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.imgList(this.formData)
+      } else this.$message.warning(res.msg)
+    },
+    // 点击重置
+    resetBtn () {
+      this.formData.searchKey = ''
+      this.formData.sortType = 0
+      this.time = ''
+      this.formData.pageNum = 1
+      this.formData.startTime = this.formData.endTime = ''
+      this.imgList(this.formData)
+    },
+    // 点击查询
+    searchBtn () {
+      this.formData.pageNum = 1
+      this.imgList(this.formData)
+    },
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.imgList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.imgList(this.formData)
+    },
+    // 点击查看
+    lookGood (id) {
+      this.$router.push({
+        path: '/layout/tab5Look',
+        query: { id }
+      })
+    },
+    // 时间处理----------------
+    handleSelect (e) {
+      const date = []
+      for (const i in e) {
+        date.push(this.gettime(e[i]))
+      }
+      this.formData.startTime = date[0]
+      if (date[1]) {
+        this.formData.endTime = date[1].replace('00:00:00', '23:59:59')
+      }
+      if (e === null) this.formData.endTime = ''
+    },
+    gettime (data) {
+      const value =
+        data.getFullYear() +
+        '-' +
+        this.checkTime(data.getMonth() + 1) +
+        '-' +
+        this.checkTime(data.getDate()) +
+        ' ' +
+        this.checkTime(data.getHours()) +
+        ':' +
+        this.checkTime(data.getMinutes()) +
+        ':' +
+        this.checkTime(data.getSeconds())
+      return value
+    },
+    checkTime (i) {
+      if (i < 10) {
+        i = '0' + i
+      }
+      return i
+    },
+    // 封装获取列表函数
+    async imgList (data) {
+      const res = await imgList(data)
+      // console.log(998, res)
+      this.total = res.data.total
+      this.tableData = res.data.records
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    this.imgList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab5 {
+  height: 100%;
+  .insideTop .add {
+    right: 55px;
+  }
+  .conten {
+    padding: 15px 30px 0;
+    height: calc(100% - 32px);
+    .classify {
+      text-align: center;
+      width: 40px;
+      padding-bottom: 10px;
+      color: #b9412e;
+      border-bottom: 2px solid #b9412e;
+    }
+    .search {
+      margin-bottom: 20px;
+      position: relative;
+      margin-top: 12px;
+      height: 40px;
+      .search_k {
+        margin-left: 30px;
+      }
+      .search_btn {
+        display: flex;
+        justify-content: space-between;
+        width: 200px;
+        position: absolute;
+        right: 22px;
+        top: 0;
+      }
+    }
+    .table {
+      max-width: 1533px;
+    }
+    /deep/.el-table__body-wrapper {
+      max-height: 485px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    bottom: 15px;
+    right: 50px;
+  }
+}
+</style>

+ 219 - 0
houtai/src/views/tab5/tab5Add.vue

@@ -0,0 +1,219 @@
+<template>
+  <div class="tab5Add">
+    <div class="insideTop">
+      校园图片管理 > {{ruleForm.id?'编辑':'新增'}}图片
+      <div class="add">
+        <el-button type="primary" @click="goBack">返 回</el-button>
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <!-- 表单 -->
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="100px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="标题:" prop="name">
+          <el-input
+            v-model="ruleForm.name"
+            maxlength="25"
+            show-word-limit
+            style="width: 500px"
+          ></el-input>
+        </el-form-item>
+        <!-- 图片和附件 -->
+        <el-form-item label="图片:">
+          <i class="biaoshi biaoshi1"></i>
+          <el-upload
+            class="avatar-uploader"
+            :action="baseURL + '/cms/img/upload'"
+            :headers="{
+              token,
+            }"
+            :show-file-list="true"
+            :before-upload="beforethumbUpload"
+            :on-success="upload_thumb_success"
+          >
+            <div v-if="ruleForm.thumb" class="imgdiv">
+              <img
+                style="width: 100%; height: 100%"
+                :src="baseURL + ruleForm.thumb"
+              />
+              <i
+                class="el-icon-circle-close"
+                @click.stop="ruleForm.thumb = ''"
+              ></i>
+            </div>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+          <p class="upHint">格式要求:支持png、jpg、gif和jpeg的图片格式;最大支持20MB。</p>
+        </el-form-item>
+      </el-form>
+      <!-- 底部按钮 -->
+      <div class="con_btn">
+        <el-button type="primary" @click="saveGood">保 存</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { imgSave, imgDetail } from '@/apis/tab5'
+import axios from '@/utils/request'
+export default {
+  name: 'tab5Add',
+  components: {},
+  data () {
+    return {
+      // 服务器前缀地址
+      baseURL: '',
+      token: '',
+      ruleForm: {
+        name: '',
+        thumb: ''
+      },
+      rules: {
+        name: [{ required: true, message: '不能为空', trigger: 'blur' }]
+      }
+    }
+  },
+  computed: {},
+  methods: {
+    // 点击保存
+    async saveGood () {
+      if (this.ruleForm.name.trim() === '') { return this.$message.warning('标题不能为空') }
+      if (this.ruleForm.thumb === '') { return this.$message.warning('图片不能为空') }
+      const obj = { ...this.ruleForm }
+      // console.log(998, obj)
+      const res = await imgSave(obj)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.$router.push('/layout/tab5')
+      } else this.$message.warning(res.msg)
+    },
+    // 点击返回
+    goBack () {
+      this.$confirm('点击返回后,编辑的信息将无法保存,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          this.$router.push('/layout/tab5')
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    },
+    // 上传图片
+    beforethumbUpload (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 20
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('照片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('照片大小超过20M!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_success (data) {
+      this.$message.success('上传成功')
+      // console.log('图片上传成功', data.data.urlPath)
+      this.ruleForm.thumb = data.data.urlPath
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('CQLJXU_token')
+    // 通过父亲传过来的id获取详情
+    if (this.$route.query.id) {
+      const res = await imgDetail(Number(this.$route.query.id))
+      this.ruleForm = res.data
+      // console.log(998, res)
+    }
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab5Add {
+  height: 100%;
+  .conten {
+    position: relative;
+    /deep/.el-icon-plus {
+      border: 1px dashed #ccc;
+    }
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .biaoshi1::before {
+      left: -64px;
+    }
+    .avatar-uploader .el-upload {
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+    }
+    .avatar-uploader .el-upload:hover {
+      border-color: #3e5eb3;
+    }
+    .avatar-uploader-icon {
+      font-size: 28px;
+      color: #8c939d;
+      width: 178px;
+      height: 178px;
+      line-height: 178px;
+      text-align: center;
+    }
+    .con_btn {
+      position: absolute;
+      left: 50%;
+      transform: translateX(-50%);
+      bottom: 15px;
+    }
+    .imgdiv {
+      max-width: 200px;
+      max-height: 200px;
+      & > img {
+        border: 5px solid #ccc;
+      }
+    }
+    .el-icon-circle-close {
+      font-size: 24px;
+    }
+  }
+}
+</style>

+ 116 - 0
houtai/src/views/tab5/tab5Look.vue

@@ -0,0 +1,116 @@
+<!--  -->
+<template>
+  <div class="tab5Look">
+    <div class="insideTop">
+      校园图片管理 > 查看图片
+      <div class="add">
+        <el-button type="primary" @click="$router.push('/layout/tab5')"
+          >返 回</el-button
+        >
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <div class="row">
+        <div>标题:</div>
+        <span>{{myObj.name}}</span>
+      </div>
+      <div class="row">
+        <div>图片:</div>
+        <el-image
+          v-if="srcList.length!==0"
+          style="width: 200px; height: 200px"
+          :src="srcList[0]"
+          :preview-src-list="srcList"
+        >
+        </el-image>
+      </div>
+      <div class="row">
+        <div>显示设置:</div>
+        <el-switch disabled v-model="myObj.display" active-color="#b9412e" :active-value='1' :inactive-value='0'> </el-switch>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { imgDetail } from '@/apis/tab5'
+import axios from '@/utils/request'
+
+export default {
+  name: 'tab5Look',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      baseURL: '',
+      myObj: {},
+      srcList: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 通过父亲传过来的id获取详情
+    if (this.$route.query.id) {
+      const res = await imgDetail(Number(this.$route.query.id))
+      this.myObj = res.data
+      this.srcList = [this.baseURL + res.data.thumb]
+    }
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab5Look {
+  height: 100%;
+  .conten {
+    overflow-y: auto;
+    position: relative;
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .row {
+      display: flex;
+      margin: 25px 0;
+      & > div {
+        width: 120px;
+        text-align: right;
+      }
+    .imgList{
+      width: 1500px;
+      display: flex;
+      flex-wrap: wrap;
+      /deep/.el-image{
+        margin-right: 30px;
+        margin-bottom: 30px;
+      }
+    }
+    }
+  }
+}
+</style>

+ 349 - 0
houtai/src/views/tab6/index.vue

@@ -0,0 +1,349 @@
+<template>
+  <div class="tab6">
+    <div class="insideTop">
+      校歌管理
+      <div class="add">
+        <el-button type="primary" @click="$router.push('/layout/tab6Add')"
+          >新增音频</el-button
+        >
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="classify">全部</div>
+      <div class="search">
+        <span>发布时间:</span>
+        <el-date-picker
+          style="width: 240px"
+          v-model="time"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+        >
+        </el-date-picker>
+        <span class="search_k">标题关键字:</span>
+        <el-input
+          v-model="formData.searchKey"
+          placeholder="请输入"
+          style="width: 240px"
+        ></el-input>
+        <span class="search_k">排序:</span>
+        <el-select
+          v-model="formData.sortType"
+          placeholder="请选择"
+          style="width: 240px"
+        >
+          <el-option label="发布时间" :value="0"></el-option>
+          <el-option label="排序编号" :value="1"></el-option>
+        </el-select>
+        <!-- 右侧按钮 -->
+        <div class="search_btn">
+          <el-button type="primary" @click="searchBtn">查 询</el-button>
+          <el-button @click="resetBtn">重 置</el-button>
+        </div>
+      </div>
+      <!-- 表格 -->
+      <div class="table">
+        <el-table :data="tableData" style="width: 100%">
+          <el-table-column label="序号" width="80">
+            <template slot-scope="scope">
+              {{
+                scope.$index + (formData.pageNum - 1) * formData.pageSize + 1
+              }}
+            </template>
+          </el-table-column>
+          <el-table-column label="标题" width="250">
+            <template #default="{ row }">
+              <span class="table_name" :title="row.name">{{ row.name }}</span>
+            </template>
+          </el-table-column>
+          <!-- <el-table-column label="封面图片" width="120">
+            <template #default="{ row }">
+              <img
+                class="table_img"
+                :src="baseURL + row.thumb"
+                alt=""
+                :onerror="defaultImg"
+              />
+            </template>
+          </el-table-column> -->
+          <el-table-column prop="visit" label="阅读"> </el-table-column>
+          <el-table-column prop="creatorName" label="发布人"> </el-table-column>
+          <el-table-column prop="createTime" label="发布时间" width="200">
+          </el-table-column>
+          <el-table-column prop="address" label="排序" width="80">
+            <template #default="{ row }">
+              <el-input
+                type="text"
+                v-model="row.sort"
+                @blur="changeSort(row.sort, row.id)"
+              ></el-input>
+            </template>
+          </el-table-column>
+          <el-table-column label="是否显示">
+            <template #default="{ row }">
+              <el-switch
+                v-model="row.display"
+                active-color="#b9412e"
+                :active-value="1"
+                :inactive-value="0"
+                @change="changeSwit($event, row.id)"
+              >
+              </el-switch>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作">
+            <template #default="{ row }">
+              <el-button type="text" @click="lookGood(row.id)">查看</el-button>
+              <el-button
+                type="text"
+                v-if="!row.display"
+                @click="editLeader(row.id)"
+                >编辑</el-button
+              >
+              <el-button
+                type="text"
+                v-if="!row.display"
+                @click="delLeader(row.id)"
+                >删除</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging">
+      <el-pagination
+        layout="sizes,prev, pager, next,jumper"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  musicList,
+  musicSort,
+  musicDisplay,
+  musicRemove
+} from '@/apis/tab6'
+import axios from '@/utils/request'
+export default {
+  name: 'tab6',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      total: 0,
+      time: '',
+      formData: {
+        startTime: '',
+        endTime: '',
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: '',
+        sortType: 0
+      },
+      tableData: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {
+    time (val) {
+      this.handleSelect(val)
+    }
+  },
+  // 方法集合
+  methods: {
+    // 点击编辑
+    editLeader (id) {
+      this.$router.push({
+        path: '/layout/tab6Add',
+        query: { id }
+      })
+    },
+    // 点击删除
+    delLeader (id) {
+      this.$confirm('删除后,信息无法恢复,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          const res = await musicRemove(id)
+          if (res.code === 0) {
+            this.$message.success('删除成功')
+            this.musicList(this.formData)
+          } else this.$message.warning(res.msg)
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    }, // 点击开关
+    async changeSwit (val, id) {
+      const res = await musicDisplay(id, val)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.musicList(this.formData)
+      } else this.$message.warning(res.msg)
+      // console.log(998, val, id)
+    },
+    // 排序
+    async changeSort (val, id) {
+      // console.log(998, val, id)
+      if (Number(val) < 1) return this.$message.warning('不能小于1')
+      const res = await musicSort(id, Number(val))
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.musicList(this.formData)
+      } else this.$message.warning(res.msg)
+    },
+    // 点击重置
+    resetBtn () {
+      this.formData.searchKey = ''
+      this.formData.sortType = 0
+      this.time = ''
+      this.formData.pageNum = 1
+      this.formData.startTime = this.formData.endTime = ''
+      this.musicList(this.formData)
+    },
+    // 点击查询
+    searchBtn () {
+      this.formData.pageNum = 1
+      this.musicList(this.formData)
+    },
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.musicList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.musicList(this.formData)
+    },
+    // 点击查看
+    lookGood (id) {
+      this.$router.push({
+        path: '/layout/tab6Look',
+        query: { id }
+      })
+    },
+    // 时间处理----------------
+    handleSelect (e) {
+      const date = []
+      for (const i in e) {
+        date.push(this.gettime(e[i]))
+      }
+      this.formData.startTime = date[0]
+      if (date[1]) {
+        this.formData.endTime = date[1].replace('00:00:00', '23:59:59')
+      }
+      if (e === null) this.formData.endTime = ''
+    },
+    gettime (data) {
+      const value =
+        data.getFullYear() +
+        '-' +
+        this.checkTime(data.getMonth() + 1) +
+        '-' +
+        this.checkTime(data.getDate()) +
+        ' ' +
+        this.checkTime(data.getHours()) +
+        ':' +
+        this.checkTime(data.getMinutes()) +
+        ':' +
+        this.checkTime(data.getSeconds())
+      return value
+    },
+    checkTime (i) {
+      if (i < 10) {
+        i = '0' + i
+      }
+      return i
+    },
+    // 封装获取列表函数
+    async musicList (data) {
+      const res = await musicList(data)
+      // console.log(998, res)
+      this.total = res.data.total
+      this.tableData = res.data.records
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    this.musicList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab6 {
+  height: 100%;
+  .insideTop .add {
+    right: 55px;
+  }
+  .conten {
+    padding: 15px 30px 0;
+    height: calc(100% - 32px);
+    .classify {
+      text-align: center;
+      width: 40px;
+      padding-bottom: 10px;
+      color: #b9412e;
+      border-bottom: 2px solid #b9412e;
+    }
+    .search {
+      margin-bottom: 20px;
+      position: relative;
+      margin-top: 12px;
+      height: 40px;
+      .search_k {
+        margin-left: 30px;
+      }
+      .search_btn {
+        display: flex;
+        justify-content: space-between;
+        width: 200px;
+        position: absolute;
+        right: 22px;
+        top: 0;
+      }
+    }
+    .table {
+      max-width: 1533px;
+    }
+    /deep/.el-table__body-wrapper {
+      max-height: 485px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    bottom: 15px;
+    right: 50px;
+  }
+}
+</style>

+ 325 - 0
houtai/src/views/tab6/tab6Add.vue

@@ -0,0 +1,325 @@
+<template>
+  <div class="tab6Add">
+    <div class="insideTop">
+      校歌管理 > {{ruleForm.id?'编辑':'新增'}}音频
+      <div class="add">
+        <el-button type="primary" @click="goBack">返 回</el-button>
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <!-- 表单 -->
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="120px"
+        class="demo-ruleForm"
+      >
+        <el-form-item label="标题:" prop="name">
+          <el-input
+            v-model="ruleForm.name"
+            maxlength="25"
+            show-word-limit
+            style="width: 500px"
+          ></el-input>
+        </el-form-item>
+        <!-- 图片和附件 -->
+        <!-- <el-form-item label="图片:">
+          <i class="biaoshi biaoshi1"></i>
+          <el-upload
+            class="avatar-uploader"
+            :action="baseURL + '/cms/music/upload'"
+            :headers="{
+              token,
+            }"
+            :show-file-list="true"
+            :before-upload="beforethumbUpload"
+            :on-success="upload_thumb_success"
+          >
+            <div v-if="ruleForm.thumb" class="imgdiv">
+              <img
+                style="width: 100%; height: 100%"
+                :src="baseURL + ruleForm.thumb"
+              />
+              <i
+                class="el-icon-circle-close"
+                @click.stop="ruleForm.thumb = ''"
+              ></i>
+            </div>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </el-upload>
+          <p class="upHint">格式要求:支持png、jpg、gif和jpeg的图片格式;最大支持20M。</p>
+        </el-form-item> -->
+        <!-- 上传附件 -->
+        <el-form-item label="音频文件:">
+          <i class="biaoshi"></i>
+          <el-upload
+            multiple
+            class="upload-demo"
+            :file-list="fileList"
+            :action="baseURL + '/cms/music/video/upload'"
+            :headers="{ token }"
+            :before-upload="beforeFujian"
+            :on-success="successFujian"
+            :before-remove="beforeRemove"
+            :on-remove="handleRemove"
+            :limit="1"
+            :on-exceed="handleExceed"
+            :show-file-list="true"
+          >
+            <el-button size="small" type="primary">点击上传</el-button>
+            <div class="el-upload__tip" slot="tip">
+              <p class="upHint">格式要求:</p>
+              <p class="upHint">1、支持音频格式文件(例如:mp3、wav)。</p>
+              <p class="upHint">2、最大支持10MB的音频文件。</p>
+            </div>
+          </el-upload>
+        </el-form-item>
+        <el-form-item label="歌词:">
+          <i class="biaoshi biaoshi1"></i>
+          <div id="div1" style="z-index: 1"></div>
+        </el-form-item>
+      </el-form>
+      <!-- 底部按钮 -->
+      <div class="con_btn">
+        <el-button type="primary" @click="saveGood">保 存</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { musicSave, musicDetail } from '@/apis/tab6'
+import axios from '@/utils/request'
+import E from 'wangeditor'
+export default {
+  name: 'tab6Add',
+  components: {},
+  data () {
+    return {
+      fileList: [],
+      // 服务器前缀地址
+      baseURL: '',
+      token: '',
+      ruleForm: {
+        name: '',
+        filePath: '',
+        fileName: '',
+        thumb: ''
+      },
+      rules: {
+        name: [{ required: true, message: '不能为空', trigger: 'blur' }]
+      }
+    }
+  },
+  computed: {},
+  methods: {
+    // 点击保存
+    async saveGood () {
+      if (this.ruleForm.name.trim() === '') { return this.$message.warning('标题不能为空') }
+      // if (this.ruleForm.thumb === '') { return this.$message.warning('图片不能为空') }
+      if (this.ruleForm.filePath === '') { return this.$message.warning('音频不能为空') }
+      if (this.editor.txt.html() === '') { return this.$message.warning('歌词不能为空') }
+      const obj = { ...this.ruleForm, description: this.editor.txt.html() }
+      const res = await musicSave(obj)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.$router.push('/layout/tab6')
+      } else this.$message.warning(res.msg)
+    },
+    // 点击返回
+    goBack () {
+      this.$confirm('点击返回后,编辑的信息将无法保存,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          this.$router.push('/layout/tab6')
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    },
+    // 上传图片
+    beforethumbUpload (file) {
+      // console.log(998, file)
+      // 限制图片大小和格式
+      const sizeOk = file.size / 1024 / 1024 < 20
+      const typeOk =
+        file.type === 'image/png' ||
+        (file.type === 'image/jpeg' && !file.name.includes('.jfif')) ||
+        file.type === 'image/gif'
+
+      return new Promise((resolve, reject) => {
+        if (!typeOk) {
+          this.$message.error('照片格式有误!')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('照片大小超过20M!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    upload_thumb_success (data) {
+      this.$message.success('上传成功')
+      // console.log('图片上传成功', data.data.urlPath)
+      this.ruleForm.thumb = data.data.urlPath
+    },
+    // 上传附件
+    beforeFujian (file) {
+      console.log('附件上传前', file)
+      const sizeOk = file.size / 1024 / 1024 < 10
+      const typeOk =
+        file.type === 'audio/mpeg' ||
+        file.type === 'audio/wav'
+      return new Promise((resolve, reject) => {
+        if (file.name.length > 32) {
+          this.$message.error('音频名字不能超过32个字')
+          reject(file)
+        } else if (!sizeOk) {
+          this.$message.error('音频大小超过10M!')
+          reject(file)
+        } else if (!typeOk) {
+          this.$message.error('音频格式有误!')
+          reject(file)
+        } else {
+          resolve(file)
+        }
+      })
+    },
+    successFujian (file) {
+      console.log('上传附件成功', file)
+      if (file.code === 0) {
+        this.ruleForm.filePath = file.data.urlPath
+        this.ruleForm.fileName = file.data.fileName
+        this.$message.success('上传成功')
+      } else if (file.code === -1) {
+        this.$message.warning('上传失败,不支持的文件格式')
+      }
+    },
+    beforeRemove (file, fileList) {
+      if (file && file.status === 'success') {
+        return this.$confirm(`确定移除 ${file.name}?`)
+      }
+    },
+    handleRemove (file, fileList) {
+      this.ruleForm.filePath = ''
+      this.ruleForm.fileName = ''
+    },
+    handleExceed (files, fileList) {
+      this.$message.warning('只能上传一个音频,请删除原音频后操作')
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 获取用户token
+    this.token = localStorage.getItem('CQLJXU_token')
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  async mounted () {
+    // 初始化富文本
+    // 富文本
+    this.editor = new E('#div1')
+    // 配置字体
+    this.editor.config.fontNames = [
+      '黑体',
+      '仿宋',
+      '楷体',
+      '标楷体',
+      '华文仿宋',
+      '华文楷体',
+      '宋体',
+      '微软雅黑',
+      'Arial',
+      'Tahoma',
+      'Verdana',
+      'Times New Roman'
+    ]
+    this.editor.config.showLinkVideo = false
+    this.editor.create()
+    // 如果是编辑
+    if (this.$route.query.id) {
+      const res = await musicDetail(Number(this.$route.query.id))
+      this.ruleForm = res.data
+      console.log(998, res)
+      // 富文本回显
+      this.editor.txt.html(res.data.description)
+      // 附件回显
+      this.fileList = [{ name: res.data.fileName }]
+    }
+  },
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab6Add {
+  height: 100%;
+  .conten {
+    overflow-y: auto;
+    position: relative;
+    /deep/.el-icon-plus {
+      border: 1px dashed #ccc;
+    }
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .biaoshi1::before {
+      left: -64px;
+    }
+    .avatar-uploader .el-upload {
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+    }
+    .avatar-uploader .el-upload:hover {
+      border-color: #3e5eb3;
+    }
+    .avatar-uploader-icon {
+      font-size: 28px;
+      color: #8c939d;
+      width: 178px;
+      height: 178px;
+      line-height: 178px;
+      text-align: center;
+    }
+    .con_btn {
+      width: 80px;
+      margin: 0 auto;
+      margin-bottom: 20px;
+    }
+    #div1{
+      width: 1200px;
+    }
+    .imgdiv {
+      max-width: 200px;
+      max-height: 200px;
+      & > img {
+        border: 5px solid #ccc;
+      }
+    }
+    .el-icon-circle-close {
+      font-size: 24px;
+    }
+  }
+}
+</style>

+ 125 - 0
houtai/src/views/tab6/tab6Look.vue

@@ -0,0 +1,125 @@
+<!--  -->
+<template>
+  <div class="tab6Look">
+    <div class="insideTop">
+      校歌管理 > 查看音频
+      <div class="add">
+        <el-button type="primary" @click="$router.push('/layout/tab6')"
+          >返 回</el-button
+        >
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <div class="row">
+        <div>标题:</div>
+        <span>{{myObj.name}}</span>
+      </div>
+      <!-- <div class="row">
+        <div>封面:</div>
+        <el-image
+          v-if="srcList.length!==0"
+          style="width: 200px; height: 200px"
+          :src="srcList[0]"
+          :preview-src-list="srcList"
+        >
+        </el-image>
+      </div> -->
+      <div class="row">
+        <div>音频文件:</div>
+        <a :href="baseURL+myObj.filePath" download>{{myObj.fileName}}</a>
+      </div>
+      <div class="row">
+        <div>歌词:</div>
+        <div class="lyric" v-html="myObj.description">
+        </div>
+      </div>
+      <div class="row">
+        <div>显示设置:</div>
+        <el-switch disabled v-model="myObj.display" active-color="#b9412e" :active-value='1' :inactive-value='0'> </el-switch>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from '@/utils/request'
+import { musicDetail } from '@/apis/tab6'
+export default {
+  name: 'tab6Look',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      baseURL: '',
+      myObj: {},
+      srcList: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {
+
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    // 通过父亲传过来的id获取详情
+    if (this.$route.query.id) {
+      const res = await musicDetail(Number(this.$route.query.id))
+      this.myObj = res.data
+      this.srcList = [this.baseURL + res.data.thumb]
+    }
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab6Look {
+  height: 100%;
+  .conten {
+    overflow-y: auto;
+    position: relative;
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .row {
+      display: flex;
+      margin: 25px 0;
+      & > div {
+        width: 120px;
+        text-align: right;
+      }
+      .lyric{
+        padding: 5px;
+        text-align: left;
+        width: auto;
+        min-width: 600px;
+        border: 1px solid #ccc;
+        &>p{
+          margin: 5px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 287 - 0
houtai/src/views/tab7/index.vue

@@ -0,0 +1,287 @@
+<template>
+  <div class="tab7">
+    <div class="insideTop">留言审核</div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="classify">全部</div>
+      <div class="search">
+        <span>提交时间:</span>
+        <el-date-picker
+          style="width: 240px"
+          v-model="time"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+        >
+        </el-date-picker>
+        <span class="search_k">留言内容:</span>
+        <el-input
+          v-model="formData.searchKey"
+          placeholder="关键字"
+          style="width: 240px"
+        ></el-input>
+        <span class="search_k">状态:</span>
+        <el-select
+          v-model="formData.status"
+          placeholder="请选择"
+          style="width: 240px"
+        >
+          <el-option label="全部" value=""></el-option>
+          <el-option label="待审核" :value="0"></el-option>
+          <el-option label="审核通过" :value="2"></el-option>
+          <el-option label="审核不通过" :value="1"></el-option>
+        </el-select>
+        <!-- 右侧按钮 -->
+        <div class="search_btn">
+          <el-button type="primary" @click="searchBtn">查 询</el-button>
+          <el-button @click="resetBtn">重 置</el-button>
+        </div>
+      </div>
+      <!-- 表格 -->
+      <div class="table">
+        <el-table :data="tableData" style="width: 100%">
+          <el-table-column label="序号" width="80">
+            <template slot-scope="scope">
+              {{
+                scope.$index + (formData.pageNum - 1) * formData.pageSize + 1
+              }}
+            </template>
+          </el-table-column>
+          <el-table-column label="留言内容" prop="content"></el-table-column>
+          <el-table-column prop="creatorName" label="发布人" width="200">
+          </el-table-column>
+          <el-table-column prop="createTime" label="发布时间" width="200">
+          </el-table-column>
+          <el-table-column prop="status" label="审核状态" width="150">
+          </el-table-column>
+          <el-table-column label="操作" width="200">
+            <template #default="{ row }">
+              <el-button
+                v-if="row.status !== '通过'"
+                type="text"
+                style="color: #254e91"
+                @click="passMes(2, row.id)"
+                >通过</el-button
+              >
+              <el-button type="text" @click="passMes(1, row.id)" v-if="row.status !== '不通过'"
+                >不通过</el-button
+              >
+              <el-button
+                type="text"
+                @click="delMes(row.id)"
+                v-if="row.status !== '通过'"
+                >删除</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging">
+      <el-pagination
+        layout="sizes,prev, pager, next,jumper"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import { commentList, commentAudit, commentRemove } from '@/apis/tab7'
+export default {
+  name: 'tab7',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      total: 0,
+      time: '',
+      formData: {
+        startTime: '',
+        endTime: '',
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: '',
+        status: ''
+      },
+      tableData: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {
+    time (val) {
+      this.handleSelect(val)
+    }
+  },
+  // 方法集合
+  methods: {
+    // 点击通过和不通过
+    async passMes (status, id) {
+      const res = await commentAudit(status, id)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.commentList(this.formData)
+      } else this.$message.warning(res.msg)
+    },
+    // 点击删除
+    delMes (id) {
+      this.$confirm('删除后,信息无法恢复,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          const res = await commentRemove(id)
+          if (res.code === 0) {
+            this.$message.success('删除成功')
+            this.commentList(this.formData)
+          } else this.$message.warning(res.msg)
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    },
+    // 点击重置
+    resetBtn () {
+      this.formData.searchKey = ''
+      this.formData.status = ''
+      this.time = ''
+      this.formData.pageNum = 1
+      this.formData.startTime = this.formData.endTime = ''
+      this.commentList(this.formData)
+    },
+    // 点击查询
+    searchBtn () {
+      this.formData.pageNum = 1
+      this.commentList(this.formData)
+    },
+    // 封装获取留言列表的方法
+    async commentList (data) {
+      const res = await commentList(data)
+      this.total = res.data.total
+      res.data.records.forEach((v) => {
+        if (v.status === 0) v.status = '待审核'
+        else if (v.status === 1) v.status = '不通过'
+        else if (v.status === 2) v.status = '通过'
+      })
+      this.tableData = res.data.records
+    },
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.commentList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.commentList(this.formData)
+    },
+    // 时间处理----------------
+    handleSelect (e) {
+      const date = []
+      for (const i in e) {
+        date.push(this.gettime(e[i]))
+      }
+      this.formData.startTime = date[0]
+      if (date[1]) {
+        this.formData.endTime = date[1].replace('00:00:00', '23:59:59')
+      }
+      if (e === null) this.formData.endTime = ''
+    },
+    gettime (data) {
+      const value =
+        data.getFullYear() +
+        '-' +
+        this.checkTime(data.getMonth() + 1) +
+        '-' +
+        this.checkTime(data.getDate()) +
+        ' ' +
+        this.checkTime(data.getHours()) +
+        ':' +
+        this.checkTime(data.getMinutes()) +
+        ':' +
+        this.checkTime(data.getSeconds())
+      return value
+    },
+    checkTime (i) {
+      if (i < 10) {
+        i = '0' + i
+      }
+      return i
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    // 调用获取列表方法
+    this.commentList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab7 {
+  height: 100%;
+  .insideTop .add {
+    right: 55px;
+  }
+  .conten {
+    padding: 15px 30px 0;
+    height: calc(100% - 32px);
+    .classify {
+      text-align: center;
+      width: 40px;
+      padding-bottom: 10px;
+      color: #b9412e;
+      border-bottom: 2px solid #b9412e;
+    }
+    .search {
+      margin-bottom: 20px;
+      position: relative;
+      margin-top: 12px;
+      height: 40px;
+      .search_k {
+        margin-left: 30px;
+      }
+      .search_btn {
+        display: flex;
+        justify-content: space-between;
+        width: 200px;
+        position: absolute;
+        right: 22px;
+        top: 0;
+      }
+    }
+    .table {
+      max-width: 1533px;
+    }
+    /deep/.el-table__body-wrapper {
+      max-height: 485px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    bottom: 15px;
+    right: 50px;
+  }
+}
+</style>

+ 326 - 0
houtai/src/views/tab8/index.vue

@@ -0,0 +1,326 @@
+<template>
+  <div class="tab8">
+    <div class="insideTop">发帖审核</div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="classify">全部</div>
+      <div class="search">
+        <span>提交时间:</span>
+        <el-date-picker
+          style="width: 240px"
+          v-model="time"
+          type="daterange"
+          range-separator="-"
+          start-placeholder="开始时间"
+          end-placeholder="结束时间"
+        >
+        </el-date-picker>
+        <span class="search_k">发帖内容:</span>
+        <el-input
+          v-model="formData.searchKey"
+          placeholder="关键字"
+          style="width: 200px"
+        ></el-input>
+        <span class="search_k">状态:</span>
+        <el-select
+          v-model="formData.status"
+          placeholder="请选择"
+          style="width: 120px"
+        >
+          <el-option label="全部" value=""></el-option>
+          <el-option label="待审核" :value="0"></el-option>
+          <el-option label="审核通过" :value="2"></el-option>
+          <el-option label="审核不通过" :value="1"></el-option>
+        </el-select>
+        <span class="search_k">板块:</span>
+        <el-select
+          v-model="formData.type"
+          placeholder="请选择"
+          style="width: 120px"
+        >
+          <el-option label="全部" value=""></el-option>
+          <el-option label="数字史馆" value="scene"></el-option>
+          <el-option label="美丽校园" value="school"></el-option>
+          <el-option label="文物典藏" value="goods"></el-option>
+        </el-select>
+        <span class="search_k">类型:</span>
+        <el-select
+          v-model="formData.bbsType"
+          placeholder="请选择"
+          style="width: 120px"
+        >
+          <el-option label="全部" value=""></el-option>
+          <el-option label="主题" value="topic"></el-option>
+          <el-option label="回帖" value="reply"></el-option>
+        </el-select>
+        <!-- 右侧按钮 -->
+        <div class="search_btn">
+          <el-button type="primary" @click="searchBtn">查 询</el-button>
+          <el-button @click="resetBtn">重 置</el-button>
+        </div>
+      </div>
+      <!-- 表格 -->
+      <div class="table">
+        <el-table :data="tableData" style="width: 100%">
+          <el-table-column label="序号" width="80">
+            <template slot-scope="scope">
+              {{
+                scope.$index + (formData.pageNum - 1) * formData.pageSize + 1
+              }}
+            </template>
+          </el-table-column>
+          <el-table-column label="标题" prop="title"> </el-table-column>
+          <el-table-column prop="type" label="板块"> </el-table-column>
+          <el-table-column prop="bbsType" label="类型"> </el-table-column>
+          <el-table-column prop="creatorName" label="发布人"> </el-table-column>
+          <el-table-column prop="createTime" label="发布时间">
+          </el-table-column>
+          <el-table-column prop="status" label="审核状态"> </el-table-column>
+          <el-table-column label="操作">
+            <template #default="{ row }">
+              <el-button
+                type="text"
+                style="color: #254e91"
+                @click="lookGood(row)"
+                >查看</el-button
+              >
+              <el-button
+                type="text"
+                style="color: #254e91"
+                v-if="row.status !== '通过'"
+                @click="passPost(2,row.id)"
+                >通过</el-button
+              >
+              <el-button type="text" v-if="row.status !== '不通过'" @click="passPost(1,row.id)"
+                >不通过</el-button
+              >
+              <el-button type="text" v-if="row.status !== '通过'" @click="bbsRemoveApi(row.id)"
+                >删除</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging">
+      <el-pagination
+        layout="sizes,prev, pager, next,jumper"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import { bbsListApi, bbsAuditApi, bbsRemoveApi } from '@/apis/tab8'
+export default {
+  name: 'tab8',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      total: 0,
+      time: '',
+      formData: {
+        startTime: '',
+        endTime: '',
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: '',
+        status: '',
+        type: '',
+        bbsType: ''
+      },
+      tableData: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {
+    time (val) {
+      this.handleSelect(val)
+    }
+  },
+  // 方法集合
+  methods: {
+    // 点击删除
+    bbsRemoveApi (id) {
+      this.$confirm('删除后,信息无法恢复,是否继续?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async () => {
+          const res = await bbsRemoveApi(id)
+          if (res.code === 0) {
+            this.$message.success('删除成功')
+            this.getBbsList(this.formData)
+          } else this.$message.warning(res.msg)
+        })
+        .catch(() => {
+          this.$message.info('已取消')
+        })
+    },
+    // 点击通过和不通过
+    async passPost (status, id) {
+      const res = await bbsAuditApi(status, id)
+      if (res.code === 0) {
+        this.$message.success('操作成功')
+        this.getBbsList(this.formData)
+      } else this.$message.warning(res.msg)
+    },
+    // 点击重置
+    resetBtn () {
+      this.formData.searchKey = ''
+      this.formData.status = ''
+      this.formData.bbsType = ''
+      this.formData.type = ''
+      this.time = ''
+      this.formData.pageNum = 1
+      this.formData.startTime = this.formData.endTime = ''
+      this.getBbsList(this.formData)
+    },
+    // 点击查询
+    searchBtn () {
+      this.formData.pageNum = 1
+      this.getBbsList(this.formData)
+    },
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.getBbsList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.getBbsList(this.formData)
+    },
+    // 点击查看
+    lookGood (val) {
+      this.$router.push({
+        path: '/layout/tab8Look',
+        query: val
+      })
+    },
+    // 封装获取列表的方法
+    async getBbsList (data) {
+      const res = await bbsListApi(data)
+      this.total = res.data.total
+      res.data.records.forEach((v) => {
+        if (v.bbsType === 'topic') v.bbsType = '主题'
+        else if (v.bbsType === 'reply') v.bbsType = '回帖'
+        if (v.status === 0) v.status = '待审核'
+        else if (v.status === 1) v.status = '不通过'
+        else if (v.status === 2) v.status = '通过'
+        if (v.type === 'scene') v.type = '数字史馆'
+        else if (v.type === 'school') v.type = '美丽校园'
+        else if (v.type === 'goods') v.type = '文物典藏'
+      })
+      this.tableData = res.data.records
+    },
+    // 时间处理----------------
+    handleSelect (e) {
+      const date = []
+      for (const i in e) {
+        date.push(this.gettime(e[i]))
+      }
+      this.formData.startTime = date[0]
+      if (date[1]) {
+        this.formData.endTime = date[1].replace('00:00:00', '23:59:59')
+      }
+      if (e === null) this.formData.endTime = ''
+    },
+    gettime (data) {
+      const value =
+        data.getFullYear() +
+        '-' +
+        this.checkTime(data.getMonth() + 1) +
+        '-' +
+        this.checkTime(data.getDate()) +
+        ' ' +
+        this.checkTime(data.getHours()) +
+        ':' +
+        this.checkTime(data.getMinutes()) +
+        ':' +
+        this.checkTime(data.getSeconds())
+      return value
+    },
+    checkTime (i) {
+      if (i < 10) {
+        i = '0' + i
+      }
+      return i
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    this.getBbsList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab8 {
+  height: 100%;
+  .insideTop .add {
+    right: 55px;
+  }
+  .conten {
+    padding: 15px 30px 0;
+    height: calc(100% - 32px);
+    .classify {
+      text-align: center;
+      width: 40px;
+      padding-bottom: 10px;
+      color: #b9412e;
+      border-bottom: 2px solid #b9412e;
+    }
+    .search {
+      margin-bottom: 20px;
+      position: relative;
+      margin-top: 12px;
+      height: 40px;
+      .search_k {
+        margin-left: 20px;
+      }
+      .search_btn {
+        display: flex;
+        justify-content: space-between;
+        width: 200px;
+        position: absolute;
+        right: 22px;
+        top: 0;
+      }
+    }
+    .table {
+      max-width: 1533px;
+    }
+    /deep/.el-table__body-wrapper {
+      max-height: 485px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    bottom: 15px;
+    right: 50px;
+  }
+}
+</style>

+ 105 - 0
houtai/src/views/tab8/tab8Look.vue

@@ -0,0 +1,105 @@
+<template>
+  <div class="tab8Look">
+    <div class="insideTop">
+      发帖审核 > 查看发帖信息
+      <div class="add">
+        <el-button type="primary" @click="$router.push('/layout/tab8')"
+          >返 回</el-button
+        >
+      </div>
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="con_top">基本信息</div>
+      <div class="row">
+        <div>板块:</div>
+        <span>{{data.type}}</span>
+      </div>
+      <div class="row">
+        <div>类型:</div>
+        <span>{{data.bbsType}}</span>
+      </div>
+      <div class="row">
+        <div>标题:</div>
+        <span>{{data.title}}</span>
+      </div>
+      <div class="row">
+        <div>发布人:</div>
+        <span>{{data.creatorName}}</span>
+      </div>
+      <div class="row">
+        <div>发布时间:</div>
+        <span>{{data.createTime}}</span>
+      </div>
+      <div class="con_top">{{data.bbsType}}内容</div>
+      <div id="div1" v-html="data.content"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+import axios from '@/utils/request'
+export default {
+  name: 'tab8Look',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      data: {},
+      baseURL: ''
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {},
+  // 方法集合
+  methods: {},
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  async created () {
+    // 获取服务器前缀地址
+    this.baseURL = axios.defaults.baseURL
+    this.data = this.$route.query
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab8Look {
+  height: 100%;
+  .conten {
+    padding-bottom: 20px;
+    overflow-y: auto;
+    position: relative;
+    height: calc(100% - 32px);
+    .con_top {
+      margin-bottom: 12px;
+      height: 40px;
+      line-height: 40px;
+      padding-left: 20px;
+      background-color: #fbfbfb;
+    }
+    .row {
+      display: flex;
+      margin: 25px 0;
+      & > div {
+        width: 120px;
+        text-align: right;
+      }
+    }
+    #div1{
+      width: 85%;
+      margin: 0 auto;
+    }
+  }
+}
+</style>

+ 161 - 0
houtai/src/views/tab9/index.vue

@@ -0,0 +1,161 @@
+<template>
+  <div class="tab6">
+    <div class="insideTop">
+      操作日志
+    </div>
+    <div class="obstruct"></div>
+    <!-- 主要内容 -->
+    <div class="conten">
+      <div class="search">
+        <el-input
+          v-model="formData.searchKey"
+          placeholder="请输入关键字"
+          style="width: 240px"
+        ></el-input>
+        <!-- 右侧按钮 -->
+        <div class="search_btn">
+          <el-button type="primary" @click="searchBtn">查 询</el-button>
+        </div>
+      </div>
+      <!-- 表格 -->
+      <div class="table">
+        <el-table :data="tableData" style="width: 100%">
+          <el-table-column label="序号" width="80">
+            <template slot-scope="scope">
+              {{
+                scope.$index + (formData.pageNum - 1) * formData.pageSize + 1
+              }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="userName" label="账号"> </el-table-column>
+          <el-table-column prop="type" label="操作模块"> </el-table-column>
+          <el-table-column prop="description" label="操作事件"></el-table-column>
+          <el-table-column prop="createTime" label="操作时间"></el-table-column>
+        </el-table>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="paging">
+      <el-pagination
+        layout="sizes,prev, pager, next,jumper"
+        :total="total"
+        :current-page="formData.pageNum"
+        @current-change="currentChange"
+        @size-change="sizeChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import { logList } from '@/apis/tab9'
+export default {
+  name: 'tab6',
+  components: {},
+  data () {
+    // 这里存放数据
+    return {
+      total: 0,
+      formData: {
+        pageNum: 1,
+        pageSize: 10,
+        searchKey: ''
+      },
+      tableData: []
+    }
+  },
+  // 监听属性 类似于data概念
+  computed: {},
+  // 监控data中的数据变化
+  watch: {
+  },
+  // 方法集合
+  methods: {
+    // 点击查询
+    searchBtn () {
+      this.formData.pageNum = 1
+      this.logList(this.formData)
+    },
+    // 封装获取列表的函数
+    async logList (data) {
+      const res = await logList(data)
+      this.total = res.data.total
+      this.tableData = res.data.records
+      // console.log(998, res)
+    },
+    // 分页器方法
+    currentChange (val) {
+      // console.log('当前页改变了', val)
+      this.formData.pageNum = val
+      this.logList(this.formData)
+    },
+    sizeChange (val) {
+      // console.log('条数改变了', val)
+      this.formData.pageNum = 1
+      this.formData.pageSize = val
+      this.logList(this.formData)
+    }
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created () {
+    this.logList(this.formData)
+  },
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted () {},
+  beforeCreate () {}, // 生命周期 - 创建之前
+  beforeMount () {}, // 生命周期 - 挂载之前
+  beforeUpdate () {}, // 生命周期 - 更新之前
+  updated () {}, // 生命周期 - 更新之后
+  beforeDestroy () {}, // 生命周期 - 销毁之前
+  destroyed () {}, // 生命周期 - 销毁完成
+  activated () {} // 如果页面有keep-alive缓存功能,这个函数会触发
+}
+</script>
+<style lang='less' scoped>
+.tab6 {
+  height: 100%;
+  .insideTop .add{
+    right: 55px;
+  }
+  .conten {
+    padding: 15px 30px 0;
+    height: calc(100% - 32px);
+    .classify {
+      text-align: center;
+      width: 40px;
+      padding-bottom: 10px;
+      color: #b9412e;
+      border-bottom: 2px solid #b9412e;
+    }
+    .search {
+      display: flex;
+      margin-bottom: 20px;
+      position: relative;
+      margin-top: 12px;
+      height: 40px;
+      .search_k {
+        margin-left: 30px;
+      }
+      .search_btn {
+        margin-left: 30px;
+        display: flex;
+        justify-content: space-between;
+        width: 100px;
+      }
+    }
+    .table {
+      max-width: 1533px;
+    }
+    /deep/.el-table__body-wrapper {
+      max-height: 528px;
+      overflow-y: auto;
+    }
+  }
+  .paging {
+    position: absolute;
+    bottom: 15px;
+    right: 50px;
+  }
+}
+</style>

+ 3 - 0
houtai/vue.config.js

@@ -0,0 +1,3 @@
+module.exports = {
+  publicPath: './'
+}

+ 1 - 1
web/public/static/css/main.css

@@ -7056,5 +7056,5 @@ a.hasHover.tag-link:hover {
 
 
 #model-title{
-    display: none!important;
+    color: #fff;
 }

+ 4 - 1
web/public/static/js/main_2020_show.js

@@ -6719,7 +6719,7 @@ window.Modernizr = function(n, e, t) {
                     } 
                     h.attr("data-index", s)
                     
-                    je.highlight.visible && h.find("img").attr("src", 'https://super.4dage.com/'+thumbUrl)
+                    je.highlight.visible && h.find("img").attr("src", thumbUrl)
                     
                     
                     if (c.name) {
@@ -15002,12 +15002,15 @@ window.Modernizr = function(n, e, t) {
                 //czj 判断someData 有没有backgroundMusic 添加音乐
                 if (window.DATA.backgroundMusic) {
                     if(window.isLocal){
+                        console.log('1111111',manage.dealURL(window.DATA.backgroundMusic));
                         SoundManager.setSrc('bgm', manage.dealURL(window.DATA.backgroundMusic))
                     }else{
+                        console.log('22222222',window.DATA.backgroundMusic);
                         SoundManager.setSrc('bgm', window.DATA.backgroundMusic )
                     }  
                     $("#volume").show();
                 }else if (g_version === "one"){
+                    console.log('333333333',manage.dealURL( g_Prefix+"/audio/"+"audio"+window.number + "/background.mp3"));
                     SoundManager.setSrc('bgm', manage.dealURL( g_Prefix+"/audio/"+"audio"+window.number + "/background.mp3"))
                     
                     

+ 2 - 1
web/public/static/js/manage.js

@@ -3,7 +3,8 @@ var g_ProjectName=window.location.pathname.substring(window.location.pathname.in
 var g_Prefix="https://super.4dage.com/";
 
 // var g_Prefix=window.location.origin+'/';
-window.isLocal = true
+// 打开下面就是切换本地模式
+// window.isLocal = true
 
 var g_index=null;
 var g_modeldata=null;

+ 1 - 1
web/src/App.vue

@@ -20,7 +20,7 @@ export default {
 <style lang="less">
 .vvvv{
     width: 100%;
-    height: 100%;
+    height: 100vh;
     min-width: 1918px;
     min-height: 900px;
 }

+ 2 - 2
web/src/utils/request.js

@@ -1,8 +1,8 @@
 import axios from 'axios'
 const service = axios.create({
   // baseURL: 'http://192.168.0.135:8005/', // 本地调试
-  baseURL: 'http://192.168.0.245:8005/', // 线上调试
-  // baseURL: '', // build
+  // baseURL: 'http://192.168.0.245:8005/', // 线上调试
+  baseURL: '', // build
   timeout: 5000
 })
 // 请求拦截器

+ 8 - 4
web/src/views/gui/menu.vue

@@ -148,7 +148,7 @@
             >
               <img
                 class="icon icon-inside"
-                :src="require('@/assets/images/icon/musicoff.png')"
+                :src="require(`@/assets/images/icon/${bgmPlay?'musicon':'musicoff'}.png`)"
                 title="关闭音乐"
               />
             </div>
@@ -212,7 +212,7 @@
 
         <div id="volume" @click="switchBGM" class="ui-icon bgandshare wide">
           <div>
-            <img :src="require('@/assets/images/icon/musicon.png')" />
+            <img :src="require(`@/assets/images/icon/${bgmPlay?'musicon':'musicoff'}.png`)" />
           </div>
         </div>
         <div id="vr" class="ui-icon wide hidden" style="display: none">
@@ -322,18 +322,22 @@ export default {
       // 玫瑰
       isShowGood2: false,
       likeNum2: 0,
+      bgmPlay:false
     };
   },
   computed: {},
   mounted() {},
   methods: {
     switchBGM() {
-      if ($("#volume img")[0].src.indexOf("on.png") > -1) {
+      if (this.bgmPlay) {
         window.manage.switchBgmState(true);
-      } else if ($("#volume img")[0].src.indexOf("off.png") > -1) {
+        this.bgmPlay=false
+      } else  {
         window.manage.switchBgmState(false);
+        this.bgmPlay=true
       }
     },
+
     // 点击点赞
     handleLike() {
       if (this.isShowGood) return;