Prechádzať zdrojové kódy

Merge branch 'master'

tremble 3 rokov pred
rodič
commit
d7e38b0447
72 zmenil súbory, kde vykonal 1156 pridanie a 275 odobranie
  1. 9 0
      new_backstage/jsconfig.json
  2. 427 52
      new_backstage/package-lock.json
  3. 1 1
      new_backstage/public/index.html
  4. 1 1
      new_backstage/src/assets/font/iconfont.json
  5. 3 1
      new_backstage/src/configue/http.js
  6. 19 2
      new_backstage/src/configue/menu.js
  7. 1 0
      new_backstage/src/main.js
  8. 3 0
      new_backstage/src/mixins/index.js
  9. 1 1
      new_backstage/src/pages/content/collection/index.vue
  10. 1 1
      new_backstage/src/pages/content/sweep/index.vue
  11. 20 12
      new_backstage/src/pages/layout/aside.vue
  12. 1 1
      new_backstage/src/pages/layout/head.vue
  13. 1 0
      new_backstage/src/pages/layout/index.vue
  14. 3 2
      new_backstage/src/pages/login/index.vue
  15. 4 0
      new_backstage/src/router/base.js
  16. 12 13
      new_backstage/src/router/index.js
  17. 8 1
      new_backstage/src/util/listener.js
  18. 3 0
      web/README.md
  19. 9 0
      web/jsconfig.json
  20. 254 31
      web/package-lock.json
  21. 4 3
      web/package.json
  22. 1 1
      web/public/index.html
  23. 1 1
      web/public/scene.html
  24. 7 28
      web/public/static/css/main.css
  25. BIN
      web/public/static/images/Volume btn_off.png
  26. BIN
      web/public/static/images/Volume btn_on.png
  27. 0 0
      web/public/static/images/bgm_off_ganlanlv.png
  28. 0 0
      web/public/static/images/bgm_off_huyangjin.png
  29. 0 0
      web/public/static/images/bgm_off_jiyinhong.png
  30. 0 0
      web/public/static/images/bgm_on.png
  31. 29 9
      web/public/static/js/manage.js
  32. BIN
      web/src/assets/images/Volume btn_off.png
  33. BIN
      web/src/assets/images/Volume btn_on.png
  34. BIN
      web/src/assets/images/btnlist/Volume btn_off.png
  35. BIN
      web/src/assets/images/btnlist/Volume btn_on.png
  36. BIN
      web/src/assets/images/btnlist/bgm_off_ganlanlv.png
  37. BIN
      web/src/assets/images/btnlist/bgm_off_huyangjin.png
  38. BIN
      web/src/assets/images/btnlist/bgm_off_jiyinhong.png
  39. BIN
      web/src/assets/images/btnlist/bgm_on.png
  40. BIN
      web/src/assets/images/btnlist/大场景-展开.png
  41. BIN
      web/src/assets/images/btnlist/大场景-缩小.png
  42. BIN
      web/src/assets/images/btnlist/解说-关闭.png
  43. BIN
      web/src/assets/images/btnlist/解说-打开.png
  44. BIN
      web/src/assets/images/xinjiang/content_ganlanlv.png
  45. BIN
      web/src/assets/images/xinjiang/content_huyangjin.png
  46. BIN
      web/src/assets/images/xinjiang/content_jiyinhong.png
  47. BIN
      web/src/assets/images/返回顶部.png
  48. 1 0
      web/src/assets/style/globalVars.less
  49. 11 5
      web/src/assets/theme/theme.less
  50. 106 0
      web/src/components/BackTop.vue
  51. 12 13
      web/src/components/Danmaku.vue
  52. 24 1
      web/src/components/lrLayout/index.vue
  53. 6 2
      web/src/components/sTitle.vue
  54. 1 1
      web/src/config/api.js
  55. 3 3
      web/src/config/route.js
  56. 33 0
      web/src/config/utils.js
  57. 1 0
      web/src/mixins/index.js
  58. 3 3
      web/src/views/collection/Collection.vue
  59. 1 1
      web/src/views/collection/detail.vue
  60. 1 1
      web/src/views/layout/footer.vue
  61. 5 4
      web/src/views/layout/header.vue
  62. 38 15
      web/src/views/layout/index.vue
  63. 1 1
      web/src/views/martyr/index.vue
  64. 21 13
      web/src/views/message/Message.vue
  65. 5 1
      web/src/views/message/index.vue
  66. 1 1
      web/src/views/sacrifice/index.vue
  67. 2 2
      web/src/views/sacrifice/liuyan.vue
  68. 24 20
      web/src/views/scene/gui/menu.vue
  69. 2 2
      web/src/views/spirit/index.vue
  70. 14 16
      web/src/views/user/forget.vue
  71. 9 4
      web/src/views/user/register.vue
  72. 8 5
      web/src/views/user/userinfo.vue

+ 9 - 0
new_backstage/jsconfig.json

@@ -0,0 +1,9 @@
+{
+  "compilerOptions": {
+    "baseUrl": ".",
+    "paths": {
+      "@/*": ["./src/*"]
+    }
+  },
+  "exclude": ["node_modules", "dist"]
+}

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 427 - 52
new_backstage/package-lock.json


+ 1 - 1
new_backstage/public/index.html

@@ -5,7 +5,7 @@
     <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.png">
-    <title>92403部队</title>
+    <title>福州基地数字史馆</title>
   </head>
   <body>
     <noscript>

+ 1 - 1
new_backstage/src/assets/font/iconfont.json

@@ -1,6 +1,6 @@
 {
   "id": "1855608",
-  "name": "92403部队",
+  "name": "福州基地数字史馆",
   "font_family": "iconfont",
   "css_prefix_text": "icon",
   "description": "展示界面和管理后台",

+ 3 - 1
new_backstage/src/configue/http.js

@@ -8,8 +8,10 @@ const vue = new Vue();
 var isProduction = process.env.NODE_ENV === "production";
 let loading = "";
 
-const serverName = isProduction ? "/" : "http://192.168.0.245:8006/";
+// 后端的baseUrl
+const serverName = isProduction ? "/" : "http://192.168.0.135:8004/";
 
+// 前端域名或IP,没用到。
 const serverLocation = window.location.hostname;
 
 axios.defaults.baseURL = serverName;

+ 19 - 2
new_backstage/src/configue/menu.js

@@ -1,3 +1,14 @@
+/**
+ * name => 路由项的meta.name
+ * id => 路由项的meta.belong,对应主菜单的id
+ * key => 路由项的name, 路由项的path中的第一层路径,路由项的meta.index,被渲染的组件在src/pages/systemOrType中的子路径名
+ * noEdit => 有无对应的编辑页面
+ * type => 路由项的meta.type, main中的key,分为system和content两类。
+ * param[n].key => 路由项的path中的param形式的第二、三、四…层路径,
+ * param[n].default => 没用到
+ * editParam[n].key => 对应的编辑页面的路由项的path中的【param形式的】第二、三、四…层路径,
+ * editParam[n].default => 没用到
+ */
 let routes = [
   {
     name: "史馆场景管理",
@@ -7,7 +18,7 @@ let routes = [
     type:'content'
   },
   {
-    name: "精品典藏管理",
+    name: "馆藏数据库管理",
     id: "2",
     key: "collection",
     param: [
@@ -33,7 +44,7 @@ let routes = [
     type:'content'
   },
   {
-    name: "纪念祭扫管理",
+    name: "网上祭英烈管理",
     id: "3",
     key: "sweep",
     param: [
@@ -163,6 +174,9 @@ let routes = [
   },
 ];
 
+/**
+ * 一级菜单。key与routes中的type相对应。也决定了被渲染的组件在pages下所在子路径。
+ */
 let main = [
   {
     name: "内容管理",
@@ -178,6 +192,9 @@ let main = [
   },
 ];
 
+/**
+ * main分为内容管理和系统管理两类,每一类会被加上routes字段,包含routes中类别相同的条目。此变量用于配置前端路由。
+ */
 let menu = main.map(item=>{
   let route = []
   routes.forEach((sub)=>{

+ 1 - 0
new_backstage/src/main.js

@@ -3,6 +3,7 @@ import App from './App.vue'
 import router from './router'
 
 import ElementUI from 'element-ui';
+// 会被下面的导入文件覆盖吧?
 import 'element-ui/lib/theme-chalk/index.css';
 import '../theme/index.css'
 import './mixins'

+ 3 - 0
new_backstage/src/mixins/index.js

@@ -169,6 +169,7 @@ Vue.mixin({
         })
         .catch(() => {});
     },
+    // 刷新列表页
     backList() {
       let name = this.$route.meta.index;
       let { type } = this.$route.params;
@@ -179,6 +180,7 @@ Vue.mixin({
         },
       });
     },
+    // 前往相应的编辑页
     goto(item) {
       let { type } = this.$route.params;
       this.$router.push({
@@ -210,6 +212,7 @@ Vue.mixin({
         );
       });
     },
+    // 前往相应编辑,,audit模式。
     audit(item) {
       let { type } = this.$route.params;
       this.$router.push({

+ 1 - 1
new_backstage/src/pages/content/collection/index.vue

@@ -12,7 +12,7 @@
         @select="handleMenu"
         :menu="menu"
         :default="subMenu"
-        title="精品典藏"
+        title="馆藏数据库"
       />
       <div class="tablebody">
         <status :status="status" @select="selectStatus"></status>

+ 1 - 1
new_backstage/src/pages/content/sweep/index.vue

@@ -6,7 +6,7 @@
       </div>
     </main-top>
     <div class="tablecon flexcon" >
-      <accordion @select="handleMenu" :menu="menu" :default="subMenu" title="纪念祭扫"/>
+      <accordion @select="handleMenu" :menu="menu" :default="subMenu" title="网上祭英烈"/>
       <div class="tablebody">
         <status :status="status" v-if="$route.params.type=='martyr'" @select="selectStatus"></status>
         <search>

+ 20 - 12
new_backstage/src/pages/layout/aside.vue

@@ -17,10 +17,10 @@ export default {
   components: {},
   data () {
     return {
-      routes,
-      main,
-      menu:[],
-      tmpRoute:[]
+      routes, // 可否不挂到组件上?
+      main, // 可否不挂到组件上?
+      menu:[], // 适用于此用户的菜单
+      tmpRoute:[] //适用于此用户的所有子菜单项的集合。和menu有冗余。
     }
   },
   computed: {
@@ -31,6 +31,7 @@ export default {
       set: function () {
       }
     },
+    // 当前url所属的主菜单
     belong: {
       get: function () {
         return this.$route.meta.belong
@@ -40,6 +41,7 @@ export default {
     }
   },
   watch: {
+    // 前端路由变化后,把active的子菜单项保存到store。
     'activeIdx':{
       immediate:true,
       handler: function (newVal) {
@@ -57,12 +59,15 @@ export default {
       let path = {path:`/${item.key}${item.param?`/${item.param.map(tt=>tt.default).join('/')}`:''}`}
       this.$router.push(path)
     },
+    // mounted时执行。根据后端给的菜单和配置文件里的菜单和用户身份,得到最终菜单保存到本组件,并保存active菜单项到store。
     async getResource(){
+      // 从后端拿到该用户有权限的菜单列表。
       let result = await this.$http({
         method: 'GET',
         url: '/sys/resource/getTreePermissions'
       })
-
+      // menu.js里配置的routes列表里的每一项,如果在后端给的列表里也有对应项,则二者合并保存到此变量。
+      // 或者那一项是系统管理类型的,且用户是管理员,也保存到此变量。
       this.tmpRoute = routes.filter(item => {
         let tmp = ''
         result.data.forEach(sub=>{
@@ -73,24 +78,27 @@ export default {
           }
         })
 
-          if (item.type == "system") {
-            if (window.localStorage.getItem("role") == 'sys_admin') {
-                tmp = item
-            }
-            else{
-              tmp = ''
-            }
+        if (item.type == "system") {
+          if (window.localStorage.getItem("role") == 'sys_admin') {
+              tmp = item
           }
+          else{
+            tmp = ''
+          }
+        }
+
         return tmp ? Object.assign(item,tmp) : tmp
       });
 
       console.log(this.tmpRoute);
 
+      // 找出active的那一项并保存到store
       let temp = this.tmpRoute.filter(item=>{
           return item.key == this.activeIdx
         })
       this.$store.commit("SetActiveMenu", temp[0]);
 
+      // menu.js里main加上子菜单数据,去掉没有子菜单的主菜单项,保存到本组件。
       this.menu = main.filter(item=>{
         let route = []
         this.tmpRoute.forEach((sub)=>{

+ 1 - 1
new_backstage/src/pages/layout/head.vue

@@ -3,7 +3,7 @@
 <div class='header card'>
   <div class="header-title">
     <img src="@/assets/img/logo.png" alt="">
-    <span>92403部队</span>
+    <span>福州基地数字史馆</span>
   </div>
   <div class="header-user">
     <div class="avatars" @click="handleAvatar">

+ 1 - 0
new_backstage/src/pages/layout/index.vue

@@ -13,6 +13,7 @@ import Head from './head'
 import Aside from './aside'
 
 export default {
+  name: 'Layout',
   components: {
     Head,
     Aside

+ 3 - 2
new_backstage/src/pages/login/index.vue

@@ -4,13 +4,13 @@
   <div class="layout-con">
     <div class="logo">
       <img :src="require('@/assets/img/logo.png')" alt="">
-      <span>92403部队</span>
+      <span>福州基地数字史馆</span>
     </div>
     <img class="bg" :src="require('@/assets/img/bg.jpg')" alt="">
     <div class="mask"></div>
     <div class="middle">
       <div class="middle-left">
-        <div>92403部队<br/>管理后台</div>
+        <div>福州基地数字史馆<br/>管理后台</div>
       </div>
       <div class="middle-right">
         <el-form class="middle-form" :rules="ruleLogin" status-icon :model="formLogin" ref="formLogin">
@@ -36,6 +36,7 @@ import { encodeStr } from '@/util'
 import { Base64 } from 'js-base64'
 
 export default {
+  name: 'Login',
   components: {},
   data () {
     var checkUsername = (rule, value, callback) => {

+ 4 - 0
new_backstage/src/router/base.js

@@ -1,3 +1,7 @@
+/**
+ * 没用到
+ */
+
 const Menu = [
   { text: '首页', belong: 1, link: '/', name: 'home' },
   { text: '三维场景', belong: 2, link: '/digital', name: 'digital' },

+ 12 - 13
new_backstage/src/router/index.js

@@ -29,23 +29,22 @@ let routes = [
   {
     path: '/login',
     name: 'login',
-    component: () => import( "../pages/login/")
-  }
+    component: () => import( "../pages/login/index.vue")
+  },  
 ]
 
 menu.forEach(item => {
   item.routes.forEach(sub=>{
     routes[0].children.push({
-        name: sub.key,
-        path: `/${sub.key}${sub.param?`/:${sub.param.map(tt=>tt.key).join('/:')}`:''}`,
-        meta: {
-          index: sub.key,
-          belong: item.id,
-          name:sub.name,
-          type:sub.type
-
-        },
-        component: () => import(`../pages/${item.key}/${sub.key}/index.vue`)
+      name: sub.key,
+      path: `/${sub.key}${sub.param?`/:${sub.param.map(tt=>tt.key).join('/:')}`:''}`,
+      meta: {
+        index: sub.key,
+        belong: item.id,
+        name:sub.name,
+        type:sub.type
+      },
+      component: () => import(`../pages/${item.key}/${sub.key}/index.vue`)
     })
 
     //编辑页路由
@@ -60,7 +59,7 @@ menu.forEach(item => {
           type:sub.type
         },
         component: () => import(`../pages/${item.key}/${sub.key}/edit.vue`)
-    })
+      })
     }
   })
 })

+ 8 - 1
new_backstage/src/util/listener.js

@@ -5,11 +5,16 @@
  * @LastEditTime: 2020-04-03 12:02:39
  * @Description: 启动器
  */
-
+/**
+ * 用处是什么?
+ * _promise: 外界调用register,从而把本对象作为参数执行了callback,应该得到一个Promise对象,存起来。
+ * _resolve: 外界通过resolve方法传入的,应该是Promise的resolve方法。
+ */
 class Detector {
   constructor() {
       this._resolve = null
   }
+  // 把本对象作为参数执行了callback,应该得到一个Promise对象,存起来。
   register(callback) {
       this._promise = callback(this)
   }
@@ -19,9 +24,11 @@ class Detector {
       }
       return this._promise
   }
+  // 把保存的Promise对象resolve掉。
   valid() {
       this._resolve && this._resolve()
   }
+  // 存入resolve。外界调用register时传入的参数函数会new一个Promise对象并调用此方法,从而本对象内部就保存了Promise对象和它的resolve方法。
   resolve(resolve) {
       this._resolve = resolve
   }

+ 3 - 0
web/README.md

@@ -22,3 +22,6 @@ npm run lint
 
 ### Customize configuration
 See [Configuration Reference](https://cli.vuejs.org/config/).
+
+## 测试环境
+192.168.0.245:22 /data/army_fuzhou_data/web

+ 9 - 0
web/jsconfig.json

@@ -0,0 +1,9 @@
+{
+  "compilerOptions": {
+    "baseUrl": ".",
+    "paths": {
+      "@/*": ["./src/*"]
+    }
+  },
+  "exclude": ["node_modules", "dist"]
+}

+ 254 - 31
web/package-lock.json

@@ -8,6 +8,7 @@
       "name": "web",
       "version": "0.1.0",
       "dependencies": {
+        "@tweenjs/tween.js": "^18.6.4",
         "axios": "^0.19.2",
         "core-js": "^3.6.5",
         "js-base64": "^3.6.1",
@@ -77,6 +78,10 @@
       },
       "engines": {
         "node": ">=6.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/babel"
       }
     },
     "node_modules/@babel/generator": {
@@ -1439,6 +1444,11 @@
       "integrity": "sha1-pTUV2yXYA4N0OBtzryC7Ty5QjYc=",
       "dev": true
     },
+    "node_modules/@tweenjs/tween.js": {
+      "version": "18.6.4",
+      "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz",
+      "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ=="
+    },
     "node_modules/@types/color-name": {
       "version": "1.1.1",
       "resolved": "https://registry.npm.taobao.org/@types/color-name/download/@types/color-name-1.1.1.tgz?cache=0&sync_timestamp=1588200011932&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcolor-name%2Fdownload%2F%40types%2Fcolor-name-1.1.1.tgz",
@@ -1826,6 +1836,9 @@
       },
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
       }
     },
     "node_modules/@vue/cli-service/node_modules/find-up": {
@@ -1863,6 +1876,9 @@
       },
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/@vue/cli-service/node_modules/p-locate": {
@@ -1948,6 +1964,10 @@
       "engines": {
         "node": ">= 8.9.0"
       },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
       "peerDependencies": {
         "webpack": "^4.0.0 || ^5.0.0"
       }
@@ -2312,6 +2332,10 @@
         "fast-json-stable-stringify": "^2.0.0",
         "json-schema-traverse": "^0.4.1",
         "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
       }
     },
     "node_modules/ajv-errors": {
@@ -2357,6 +2381,9 @@
       },
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/ansi-escapes/node_modules/type-fest": {
@@ -2366,6 +2393,9 @@
       "dev": true,
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/ansi-html": {
@@ -2431,7 +2461,21 @@
       "version": "2.1.2",
       "resolved": "https://registry.npm.taobao.org/arch/download/arch-2.1.2.tgz",
       "integrity": "sha1-DFK75zRLtPomDEQ9LLrZwA/y8L8=",
-      "dev": true
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
     },
     "node_modules/argparse": {
       "version": "1.0.10",
@@ -2645,6 +2689,10 @@
       },
       "bin": {
         "autoprefixer": "bin/autoprefixer"
+      },
+      "funding": {
+        "type": "tidelift",
+        "url": "https://tidelift.com/funding/github/npm/autoprefixer"
       }
     },
     "node_modules/aws-sign2": {
@@ -3104,7 +3152,21 @@
       "version": "5.2.1",
       "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.1.tgz",
       "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY=",
-      "dev": true
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
     },
     "node_modules/browserify-zlib": {
       "version": "0.2.0",
@@ -3131,6 +3193,10 @@
       },
       "engines": {
         "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      },
+      "funding": {
+        "type": "tidelift",
+        "url": "https://tidelift.com/funding/github/npm/browserslist"
       }
     },
     "node_modules/buffer": {
@@ -3258,6 +3324,9 @@
       },
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
       }
     },
     "node_modules/cache-loader/node_modules/find-up": {
@@ -3295,6 +3364,9 @@
       },
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/cache-loader/node_modules/p-locate": {
@@ -3662,6 +3734,9 @@
       },
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
     "node_modules/cli-highlight/node_modules/chalk": {
@@ -4076,6 +4151,10 @@
       "engines": {
         "node": ">= 6.9.0"
       },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
       "peerDependencies": {
         "webpack": "^4.0.0 || ^5.0.0"
       }
@@ -4167,7 +4246,11 @@
       "version": "3.6.5",
       "resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.6.5.tgz?cache=0&sync_timestamp=1586450269267&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.6.5.tgz",
       "integrity": "sha1-c5XcJzrzf7LlDpvT2f6EEoUjHRo=",
-      "hasInstallScript": true
+      "hasInstallScript": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
     },
     "node_modules/core-js-compat": {
       "version": "3.6.5",
@@ -4177,6 +4260,10 @@
       "dependencies": {
         "browserslist": "^4.8.5",
         "semver": "7.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
       }
     },
     "node_modules/core-js-compat/node_modules/semver": {
@@ -4193,7 +4280,11 @@
       "resolved": "https://registry.npm.taobao.org/core-js-pure/download/core-js-pure-3.6.5.tgz",
       "integrity": "sha1-x5519eONvIWmYtke6lK4JW1TuBM=",
       "dev": true,
-      "hasInstallScript": true
+      "hasInstallScript": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
     },
     "node_modules/core-util-is": {
       "version": "1.0.2",
@@ -4355,6 +4446,10 @@
       "engines": {
         "node": ">= 8.9.0"
       },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
       "peerDependencies": {
         "webpack": "^4.0.0 || ^5.0.0"
       }
@@ -4631,6 +4726,9 @@
         "object-is": "^1.0.1",
         "object-keys": "^1.1.1",
         "regexp.prototype.flags": "^1.2.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/deep-is": {
@@ -5060,7 +5158,7 @@
     },
     "node_modules/dom7": {
       "version": "2.1.5",
-      "resolved": "https://registry.npmmirror.com/dom7/-/dom7-2.1.5.tgz",
+      "resolved": "https://registry.npmjs.org/dom7/-/dom7-2.1.5.tgz",
       "integrity": "sha512-xnhwVgyOh3eD++/XGtH+5qBwYTgCm0aW91GFgPJ3XG+jlsRLyJivnbP0QmUBFhI+Oaz9FV0s7cxgXHezwOEBYA==",
       "dependencies": {
         "ssr-window": "^2.0.0"
@@ -5324,6 +5422,9 @@
       },
       "engines": {
         "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/es-to-primitive": {
@@ -5338,6 +5439,9 @@
       },
       "engines": {
         "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/escalade": {
@@ -5413,6 +5517,9 @@
       },
       "engines": {
         "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/eslint-loader": {
@@ -5507,6 +5614,9 @@
       },
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/eslint/node_modules/import-fresh": {
@@ -6066,6 +6176,9 @@
       },
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/file-entry-cache": {
@@ -6245,6 +6358,12 @@
       "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.12.1.tgz?cache=0&sync_timestamp=1592520660197&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.12.1.tgz",
       "integrity": "sha1-3lSmIFMRuT1gOY68Ac9wFWgjErY=",
       "dev": true,
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
       "engines": {
         "node": ">=4.0"
       }
@@ -6455,6 +6574,9 @@
       },
       "engines": {
         "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
     "node_modules/glob-parent": {
@@ -6600,6 +6722,9 @@
       "dev": true,
       "engines": {
         "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/has-value": {
@@ -6673,7 +6798,21 @@
       "version": "5.2.1",
       "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.1.tgz",
       "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY=",
-      "dev": true
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
     },
     "node_modules/hash-sum": {
       "version": "2.0.0",
@@ -7198,6 +7337,9 @@
       },
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
     "node_modules/inquirer/node_modules/chalk": {
@@ -7211,6 +7353,9 @@
       },
       "engines": {
         "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
     "node_modules/inquirer/node_modules/cli-cursor": {
@@ -7431,6 +7576,9 @@
       "dev": true,
       "engines": {
         "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/is-ci": {
@@ -7490,6 +7638,9 @@
       "dev": true,
       "engines": {
         "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/is-descriptor": {
@@ -7669,6 +7820,9 @@
       },
       "engines": {
         "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/is-resolvable": {
@@ -7708,6 +7862,9 @@
       },
       "engines": {
         "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/is-typedarray": {
@@ -7803,7 +7960,7 @@
     },
     "node_modules/js-base64": {
       "version": "3.7.2",
-      "resolved": "https://registry.npmmirror.com/js-base64/-/js-base64-3.7.2.tgz",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz",
       "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ=="
     },
     "node_modules/js-message": {
@@ -8268,6 +8425,10 @@
       "dev": true,
       "engines": {
         "node": ">= 0.6.0"
+      },
+      "funding": {
+        "type": "tidelift",
+        "url": "https://tidelift.com/subscription/pkg/npm-loglevel?utm_medium=referral&utm_source=npm_fund"
       }
     },
     "node_modules/loose-envify": {
@@ -9011,7 +9172,10 @@
       "version": "1.8.0",
       "resolved": "https://registry.npm.taobao.org/object-inspect/download/object-inspect-1.8.0.tgz?cache=0&sync_timestamp=1592545231350&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject-inspect%2Fdownload%2Fobject-inspect-1.8.0.tgz",
       "integrity": "sha1-34B+Xs9TpgnMa/6T6sPMe+WzqdA=",
-      "dev": true
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
     "node_modules/object-is": {
       "version": "1.1.2",
@@ -9024,6 +9188,9 @@
       },
       "engines": {
         "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/object-keys": {
@@ -9073,6 +9240,9 @@
       },
       "engines": {
         "node": ">= 0.8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/object.pick": {
@@ -9100,6 +9270,9 @@
       },
       "engines": {
         "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/obuf": {
@@ -9272,6 +9445,9 @@
       },
       "engines": {
         "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/p-locate": {
@@ -9536,6 +9712,9 @@
       "optional": true,
       "engines": {
         "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
     "node_modules/pify": {
@@ -9637,6 +9816,10 @@
       },
       "engines": {
         "node": ">=6.0.0"
+      },
+      "funding": {
+        "type": "tidelift",
+        "url": "https://tidelift.com/funding/github/npm/postcss"
       }
     },
     "node_modules/postcss-calc": {
@@ -10653,6 +10836,9 @@
       },
       "engines": {
         "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/regexpp": {
@@ -10866,6 +11052,9 @@
       "dev": true,
       "dependencies": {
         "path-parse": "^1.0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/resolve-cwd": {
@@ -11030,6 +11219,10 @@
       },
       "engines": {
         "node": ">= 8.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
       }
     },
     "node_modules/select-hose": {
@@ -11559,7 +11752,6 @@
       "version": "0.5.3",
       "resolved": "https://registry.npm.taobao.org/source-map-resolve/download/source-map-resolve-0.5.3.tgz?cache=0&sync_timestamp=1584829515586&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsource-map-resolve%2Fdownload%2Fsource-map-resolve-0.5.3.tgz",
       "integrity": "sha1-GQhmvs51U+H48mei7oLGBrVQmho=",
-      "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
       "dev": true,
       "dependencies": {
         "atob": "^2.1.2",
@@ -11592,7 +11784,6 @@
       "version": "0.4.0",
       "resolved": "http://registry.npm.taobao.org/source-map-url/download/source-map-url-0.4.0.tgz",
       "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
-      "deprecated": "See https://github.com/lydell/source-map-url#deprecated",
       "dev": true
     },
     "node_modules/spdx-correct": {
@@ -11716,7 +11907,7 @@
     },
     "node_modules/ssr-window": {
       "version": "2.0.0",
-      "resolved": "https://registry.npmmirror.com/ssr-window/-/ssr-window-2.0.0.tgz",
+      "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-2.0.0.tgz",
       "integrity": "sha512-NXzN+/HPObKAx191H3zKlYomE5WrVIkoCB5IaSdvKokxTpjBdWfr0RaP+1Z5KOfDT0ZVz+2tdtiBkhsEQ9p+0A=="
     },
     "node_modules/ssri": {
@@ -11853,6 +12044,9 @@
       "dependencies": {
         "define-properties": "^1.1.3",
         "es-abstract": "^1.17.5"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/string.prototype.trimstart": {
@@ -11863,6 +12057,9 @@
       "dependencies": {
         "define-properties": "^1.1.3",
         "es-abstract": "^1.17.5"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/strip-ansi": {
@@ -11998,7 +12195,7 @@
     },
     "node_modules/swiper": {
       "version": "5.4.5",
-      "resolved": "https://registry.npmmirror.com/swiper/-/swiper-5.4.5.tgz",
+      "resolved": "https://registry.npmjs.org/swiper/-/swiper-5.4.5.tgz",
       "integrity": "sha512-7QjA0XpdOmiMoClfaZ2lYN6ICHcMm72LXiY+NF4fQLFidigameaofvpjEEiTQuw3xm5eksG5hzkaRsjQX57vtA==",
       "hasInstallScript": true,
       "dependencies": {
@@ -12007,6 +12204,10 @@
       },
       "engines": {
         "node": ">= 4.7.0"
+      },
+      "funding": {
+        "type": "patreon",
+        "url": "https://www.patreon.com/vladimirkharlampidi"
       }
     },
     "node_modules/table": {
@@ -12192,7 +12393,7 @@
     },
     "node_modules/throttle-debounce": {
       "version": "2.3.0",
-      "resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz",
+      "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz",
       "integrity": "sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==",
       "engines": {
         "node": ">=8"
@@ -12738,6 +12939,9 @@
         "es-abstract": "^1.17.2",
         "has-symbols": "^1.0.1",
         "object.getownpropertydescriptors": "^2.1.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/util/node_modules/inherits": {
@@ -12773,7 +12977,7 @@
     },
     "node_modules/v-viewer": {
       "version": "1.6.4",
-      "resolved": "https://registry.npmmirror.com/v-viewer/-/v-viewer-1.6.4.tgz",
+      "resolved": "https://registry.npmjs.org/v-viewer/-/v-viewer-1.6.4.tgz",
       "integrity": "sha512-LVkiUHpmsbsZXebeNXnu8krRCi5i2n07FeLFxoIVGhw8lVvTBO0ffpbDC6mLEuacCjrIh09HjIqpciwUtWE8lQ==",
       "dependencies": {
         "throttle-debounce": "^2.0.1",
@@ -12813,7 +13017,11 @@
       "version": "1.0.4",
       "resolved": "https://registry.npm.taobao.org/vendors/download/vendors-1.0.4.tgz?cache=0&sync_timestamp=1579857147055&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvendors%2Fdownload%2Fvendors-1.0.4.tgz",
       "integrity": "sha1-4rgApT56Kbk1BsPPQRANFsTErY4=",
-      "dev": true
+      "dev": true,
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
     },
     "node_modules/verror": {
       "version": "1.10.0",
@@ -12830,9 +13038,9 @@
       }
     },
     "node_modules/viewerjs": {
-      "version": "1.10.3",
-      "resolved": "https://registry.npmmirror.com/viewerjs/-/viewerjs-1.10.3.tgz",
-      "integrity": "sha512-X6dSO8aa6+Majmhx2GQcDSOzLClmj9zjsa89lGyG3cKGM2ca8rpGwL+iSRaAtRZalL5+VQ9osg+zfYVcAUyH8g=="
+      "version": "1.10.2",
+      "resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.10.2.tgz",
+      "integrity": "sha512-v/4+OUF/71JthlvYuqfse+WGkMJO0LxvWiOLsAoxWw+RWjMdEBWn0ZQ5Mc+OhNIFd9uLhG62GzfFIplvix8odg=="
     },
     "node_modules/vm-browserify": {
       "version": "1.1.2",
@@ -12859,7 +13067,7 @@
     },
     "node_modules/vue-chat-scroll": {
       "version": "1.4.0",
-      "resolved": "https://registry.npmmirror.com/vue-chat-scroll/-/vue-chat-scroll-1.4.0.tgz",
+      "resolved": "https://registry.npmjs.org/vue-chat-scroll/-/vue-chat-scroll-1.4.0.tgz",
       "integrity": "sha512-taHcwJJadZwJR4C4t/fv+R9ZXXSrwrpQKP17La/ep5q7IyH5i3BvscgSpXwu7s8TPP9T9n5n3JDnO+vRsZ/mBQ==",
       "peerDependencies": {
         "vue": "^2.4.4"
@@ -12881,6 +13089,9 @@
       "engines": {
         "node": ">=8.10"
       },
+      "funding": {
+        "url": "https://github.com/sponsors/mysticatea"
+      },
       "peerDependencies": {
         "eslint": ">=5.0.0"
       }
@@ -13045,7 +13256,7 @@
       "version": "2.1.8",
       "resolved": "https://registry.npm.taobao.org/chokidar/download/chokidar-2.1.8.tgz",
       "integrity": "sha1-gEs6e2qZNYw8XGHnHYco8EHP+Rc=",
-      "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies",
+      "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.",
       "dev": true,
       "optional": true,
       "dependencies": {
@@ -13189,6 +13400,10 @@
       },
       "engines": {
         "node": ">=6.11.5"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
       }
     },
     "node_modules/webpack-bundle-analyzer": {
@@ -13361,7 +13576,7 @@
       "version": "2.1.8",
       "resolved": "https://registry.npm.taobao.org/chokidar/download/chokidar-2.1.8.tgz",
       "integrity": "sha1-gEs6e2qZNYw8XGHnHYco8EHP+Rc=",
-      "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies",
+      "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.",
       "dev": true,
       "dependencies": {
         "anymatch": "^2.0.0",
@@ -13794,6 +14009,9 @@
       },
       "engines": {
         "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
     "node_modules/wrap-ansi/node_modules/color-convert": {
@@ -15211,6 +15429,11 @@
       "integrity": "sha1-pTUV2yXYA4N0OBtzryC7Ty5QjYc=",
       "dev": true
     },
+    "@tweenjs/tween.js": {
+      "version": "18.6.4",
+      "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz",
+      "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ=="
+    },
     "@types/color-name": {
       "version": "1.1.1",
       "resolved": "https://registry.npm.taobao.org/@types/color-name/download/@types/color-name-1.1.1.tgz?cache=0&sync_timestamp=1588200011932&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fcolor-name%2Fdownload%2F%40types%2Fcolor-name-1.1.1.tgz",
@@ -18265,7 +18488,7 @@
     },
     "dom7": {
       "version": "2.1.5",
-      "resolved": "https://registry.npmmirror.com/dom7/-/dom7-2.1.5.tgz",
+      "resolved": "https://registry.npmjs.org/dom7/-/dom7-2.1.5.tgz",
       "integrity": "sha512-xnhwVgyOh3eD++/XGtH+5qBwYTgCm0aW91GFgPJ3XG+jlsRLyJivnbP0QmUBFhI+Oaz9FV0s7cxgXHezwOEBYA==",
       "requires": {
         "ssr-window": "^2.0.0"
@@ -20498,7 +20721,7 @@
     },
     "js-base64": {
       "version": "3.7.2",
-      "resolved": "https://registry.npmmirror.com/js-base64/-/js-base64-3.7.2.tgz",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz",
       "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ=="
     },
     "js-message": {
@@ -23815,7 +24038,7 @@
     },
     "ssr-window": {
       "version": "2.0.0",
-      "resolved": "https://registry.npmmirror.com/ssr-window/-/ssr-window-2.0.0.tgz",
+      "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-2.0.0.tgz",
       "integrity": "sha512-NXzN+/HPObKAx191H3zKlYomE5WrVIkoCB5IaSdvKokxTpjBdWfr0RaP+1Z5KOfDT0ZVz+2tdtiBkhsEQ9p+0A=="
     },
     "ssri": {
@@ -24054,7 +24277,7 @@
     },
     "swiper": {
       "version": "5.4.5",
-      "resolved": "https://registry.npmmirror.com/swiper/-/swiper-5.4.5.tgz",
+      "resolved": "https://registry.npmjs.org/swiper/-/swiper-5.4.5.tgz",
       "integrity": "sha512-7QjA0XpdOmiMoClfaZ2lYN6ICHcMm72LXiY+NF4fQLFidigameaofvpjEEiTQuw3xm5eksG5hzkaRsjQX57vtA==",
       "requires": {
         "dom7": "^2.1.5",
@@ -24205,7 +24428,7 @@
     },
     "throttle-debounce": {
       "version": "2.3.0",
-      "resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz",
+      "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz",
       "integrity": "sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ=="
     },
     "through": {
@@ -24679,7 +24902,7 @@
     },
     "v-viewer": {
       "version": "1.6.4",
-      "resolved": "https://registry.npmmirror.com/v-viewer/-/v-viewer-1.6.4.tgz",
+      "resolved": "https://registry.npmjs.org/v-viewer/-/v-viewer-1.6.4.tgz",
       "integrity": "sha512-LVkiUHpmsbsZXebeNXnu8krRCi5i2n07FeLFxoIVGhw8lVvTBO0ffpbDC6mLEuacCjrIh09HjIqpciwUtWE8lQ==",
       "requires": {
         "throttle-debounce": "^2.0.1",
@@ -24726,9 +24949,9 @@
       }
     },
     "viewerjs": {
-      "version": "1.10.3",
-      "resolved": "https://registry.npmmirror.com/viewerjs/-/viewerjs-1.10.3.tgz",
-      "integrity": "sha512-X6dSO8aa6+Majmhx2GQcDSOzLClmj9zjsa89lGyG3cKGM2ca8rpGwL+iSRaAtRZalL5+VQ9osg+zfYVcAUyH8g=="
+      "version": "1.10.2",
+      "resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.10.2.tgz",
+      "integrity": "sha512-v/4+OUF/71JthlvYuqfse+WGkMJO0LxvWiOLsAoxWw+RWjMdEBWn0ZQ5Mc+OhNIFd9uLhG62GzfFIplvix8odg=="
     },
     "vm-browserify": {
       "version": "1.1.2",
@@ -24749,7 +24972,7 @@
     },
     "vue-chat-scroll": {
       "version": "1.4.0",
-      "resolved": "https://registry.npmmirror.com/vue-chat-scroll/-/vue-chat-scroll-1.4.0.tgz",
+      "resolved": "https://registry.npmjs.org/vue-chat-scroll/-/vue-chat-scroll-1.4.0.tgz",
       "integrity": "sha512-taHcwJJadZwJR4C4t/fv+R9ZXXSrwrpQKP17La/ep5q7IyH5i3BvscgSpXwu7s8TPP9T9n5n3JDnO+vRsZ/mBQ==",
       "requires": {}
     },

+ 4 - 3
web/package.json

@@ -8,15 +8,16 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@tweenjs/tween.js": "^18.6.4",
     "axios": "^0.19.2",
     "core-js": "^3.6.5",
     "js-base64": "^3.6.1",
-    "vue": "^2.6.11",
-    "vue-chat-scroll": "^1.4.0",
-    "vue-router": "^3.2.0",
     "swiper": "^5.3.8",
     "v-viewer": "^1.6.4",
+    "vue": "^2.6.11",
     "vue-awesome-swiper": "^4.1.1",
+    "vue-chat-scroll": "^1.4.0",
+    "vue-router": "^3.2.0",
     "vuex": "^3.5.1"
   },
   "devDependencies": {

+ 1 - 1
web/public/index.html

@@ -8,7 +8,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
     <meta name="format-detection" content="telephone=no">
     <link rel="icon" href="<%= BASE_URL %>favicon.png">
-    <title>92403部队史馆门户网站</title>
+    <title>福州基地数字史馆门户网站</title>
   </head>
   <body>
     <div id="app"></div>

+ 1 - 1
web/public/scene.html

@@ -19,7 +19,7 @@
             window.navigationStart = Date.now() + 300;
         };
     </script>
-    <title>92403部队史馆门户网站</title>
+    <title>福州基地数字史馆门户网站</title>
   </head>
   <body>
     <script src="<%= VUE_APP_STATIC_DIR %>/js/lib/jquery-2.1.1.min.js" class="build keep"></script>

+ 7 - 28
web/public/static/css/main.css

@@ -791,24 +791,6 @@ hr {
     content: "\e602"
 }
 
-.icon-fullscreen-exit:before {
-    content: "";
-    background: url("https://super.4dage.com/images/narrow_off.png") center top no-repeat;
-    background-size: 100%;
-    display: inline-block;
-    width: 24px;
-    height: 24px;
-}
-
-.icon-fullscreen:before {
-    content: "";
-    background: url("https://super.4dage.com/images/enlarge_on.png")center top no-repeat;
-    background-size: 100%;
-    display: inline-block;
-    width: 24px;
-    height: 24px;
-}
-
 .icon-help:before {
     content: "\e605"
 }
@@ -3296,10 +3278,6 @@ a.hasHover:hover, a:active {
     padding-right: 30px
 }
 
-.right .ui-icon.wide {
-    padding-left: 30px
-}
-
 .mobile-only {
     display: none
 }
@@ -3751,12 +3729,13 @@ a.hasHover:hover, a:active {
 }
 
 .pinBottom.right .ui-icon {
-    padding: 0;
-    margin-right: 0px;
-    float: left;
-    background: rgba(0, 0, 0, 0.2);
-    border-radius: 10px;
-    margin-right: 10px;
+  margin-right: 23px;
+  margin-bottom: 17px;
+}
+
+.pinBottom.right .ui-icon img {
+  width: 50px;
+  height: 50px;
 }
 
 #volume>a, #gui-fullscreen>a, #gui-fullscreen-exit>a {

BIN
web/public/static/images/Volume btn_off.png


BIN
web/public/static/images/Volume btn_on.png


web/src/assets/images/btnlist/bgm_ganlanlv.png → web/public/static/images/bgm_off_ganlanlv.png


web/src/assets/images/btnlist/bgm_huyangjin.png → web/public/static/images/bgm_off_huyangjin.png


web/src/assets/images/btnlist/bgm_jiyinhong.png → web/public/static/images/bgm_off_jiyinhong.png


web/src/assets/images/btnlist/bgm.png → web/public/static/images/bgm_on.png


+ 29 - 9
web/public/static/js/manage.js

@@ -125,12 +125,25 @@ Manage.prototype.loadAudio = function() {
     this.switchBgmState(true);
   });
 
-  $("#volume")
-    .find("a")
+  window.addEventListener('themechange', (e) => {
+    if ($("#bg-music-btn")[0].src.indexOf(`bgm_off_`) > -1) {
+      setTimeout(() => {
+        let theme = ''
+        if($('#app')[0]) {
+          theme = $('#app')[0].className.substring(5)
+        } else {
+          theme = 'huyangjin'
+        }
+        $("#bg-music-btn").attr("src", `../static/images/bgm_off_${theme}.png`);
+      }, 0);
+    }
+  })
+  
+  $("#bg-music-btn")
     .on("click", () => {
-      if ($("#volume img")[0].src.indexOf("btn_on.png") > -1) {
+      if ($("#bg-music-btn")[0].src.indexOf("bgm_on.png") > -1) {
         this.switchBgmState(true);
-      } else if ($("#volume img")[0].src.indexOf("btn_off.png") > -1) {
+      } else if ($("#bg-music-btn")[0].src.indexOf(`bgm_off_`) > -1) {
         this.switchBgmState(false);
       }
     });
@@ -140,18 +153,25 @@ Manage.prototype.switchBgmState = function(state) {
   if (!g_bgAudio || !g_bgAudio.src) return;
 
   var played = function() {
-    console.log("begin play bgm");
     g_play = 1;
     g_playAudio = g_bgAudio;
-    $("#volume a img").attr("src", "./images/Volume btn_off.png");
-    $("#volume").attr("title", "关闭声音");
+    
+    let theme = ''
+    if($('#app')[0]) {
+      theme = $('#app')[0].className.substring(5)
+    } else {
+      theme = 'huyangjin'
+    }
+
+    $("#bg-music-btn").attr("src", `../static/images/bgm_off_${theme}.png`);
+    $("#bg-music-btn").attr("title", "关闭声音");
     g_tourAudio && g_tourAudio.pause();
   };
   var paused = function() {
     g_play = 0;
     g_playAudio == g_bgAudio && (g_playAudio = null);
-    $("#volume a img").attr("src", "./images/Volume btn_on.png");
-    $("#volume").attr("title", "打开声音");
+    $("#bg-music-btn").attr("src", "../static/images/bgm_on.png");
+    $("#bg-music-btn").attr("title", "打开声音");
   };
 
   if (state) {

BIN
web/src/assets/images/Volume btn_off.png


BIN
web/src/assets/images/Volume btn_on.png


BIN
web/src/assets/images/btnlist/Volume btn_off.png


BIN
web/src/assets/images/btnlist/Volume btn_on.png


BIN
web/src/assets/images/btnlist/bgm_off_ganlanlv.png


BIN
web/src/assets/images/btnlist/bgm_off_huyangjin.png


BIN
web/src/assets/images/btnlist/bgm_off_jiyinhong.png


BIN
web/src/assets/images/btnlist/bgm_on.png


BIN
web/src/assets/images/btnlist/大场景-展开.png


BIN
web/src/assets/images/btnlist/大场景-缩小.png


BIN
web/src/assets/images/btnlist/解说-关闭.png


BIN
web/src/assets/images/btnlist/解说-打开.png


BIN
web/src/assets/images/xinjiang/content_ganlanlv.png


BIN
web/src/assets/images/xinjiang/content_huyangjin.png


BIN
web/src/assets/images/xinjiang/content_jiyinhong.png


BIN
web/src/assets/images/返回顶部.png


+ 1 - 0
web/src/assets/style/globalVars.less

@@ -1,3 +1,4 @@
+// 没用到?
 @cdn:'https://shlmuseum.oss-cn-shanghai.aliyuncs.com/shls_museum/images/';
 @inputH:30px;
 @theme:#9D362F;

+ 11 - 5
web/src/assets/theme/theme.less

@@ -394,8 +394,7 @@
     }
     &:hover,
     &.active {
-      &::before,
-      &::after {
+      &::before {
         content: "";
         display: inline-block;
         position: absolute;
@@ -404,15 +403,22 @@
         transform: translateY(-50%);
         width: @wh;
         height: @wh;
-        border: 1px solid @color!important;
+        border: 1px solid @backcolor !important;
         border-radius: 50%;
-        background: @color;
+        background: @backcolor;
       }
       &::after {
+        content: "";
+        display: inline-block;
+        position: absolute;
+        top: 50%;
+        transform: translateY(-50%);
+        border: 1px solid @backcolor !important;
+        border-radius: 50%;
         width: @wh*0.5;
         height: @wh*0.5;
         left: @wh * 0.25;
-        background: @backcolor;
+        background: #fff;
       }
     }
   }

+ 106 - 0
web/src/components/BackTop.vue

@@ -0,0 +1,106 @@
+<template>
+  <div class="back-top-wrapper" @click="onClickBackTop" v-show="isShowBackTopBtn">
+    <slot>
+      <div class="back-top__default">回到顶部</div>
+    </slot>
+  </div>
+</template>
+
+<script>
+const { debounce } = require('@/config/utils.js')
+const TWEEN = require('@tweenjs/tween.js')
+
+export default({
+  props: {
+    targetId: {
+      type: String,
+      required: true,
+    },
+    triggerDistance: {
+      type: Number,
+      default: 200,
+    }
+  },
+   data() {
+    return {
+      target: null,
+      isShowBackTopBtn: false,
+      isBackingTop: false,
+    }
+  },
+  methods: {
+    onClickBackTop() {
+      if (this.isBackingTop) {
+        return
+      }
+      this.isBackingTop = true
+
+      const tweenTarget = {
+        scrollTop: this.target.scrollTop
+      }
+      new TWEEN.Tween(tweenTarget)
+        .to({scrollTop: 0}, 800)
+        .easing(TWEEN.Easing.Quartic.Out)
+        .onUpdate(() => {
+          this.target.scrollTop = tweenTarget.scrollTop
+        })
+        .onComplete(() => {
+          this.isBackingTop = false
+        })
+        .start()
+      
+      const animate = (time) => {
+        if (this.isBackingTop) {
+          requestAnimationFrame(animate)
+          TWEEN.update(time)
+        }
+      }
+      requestAnimationFrame(animate)
+
+      // 不想引入tween.js的话,可以用这段简单的匀速滚动代码
+      // const startTime = Date.now()
+      // const totalScroll = this.target.scrollTop
+      // const fn = () => {
+      //   if (this.target.scrollTop === 0) {
+      //     this.isBackingTop = false
+      //     return
+      //   } 
+
+      //   const nowTime = Date.now()
+      //   const assumeScrollTop = totalScroll - (nowTime - startTime) * totalScroll / 500
+      //   this.target.scrollTop = assumeScrollTop > 0 ? assumeScrollTop : 0
+      //   requestAnimationFrame(fn)
+      // }
+      // requestAnimationFrame(fn)
+    },
+    onTargetScroll: debounce(function(e) {
+     if (e.target.scrollTop >= this.triggerDistance) {
+        this.isShowBackTopBtn = true
+      } else {
+        this.isShowBackTopBtn = false
+      }
+    }, 100),
+  },
+  mounted() {
+    this.target = document.getElementById(this.targetId)
+    if (this.target) {
+      this.target.addEventListener('scroll', this.onTargetScroll, {
+        passive: true,
+      })
+    }
+  },
+  unmounted() {
+    if (this.target) {
+      this.target.removeEventListener('scroll', this.onTargetScroll, {
+        passive: true,
+      })
+    }
+  }
+})
+</script>
+
+<style scoped lang="less">
+.back-top__default {
+  cursor: pointer;
+}
+</style>

+ 12 - 13
web/src/components/Danmaku.vue

@@ -17,7 +17,7 @@
       </transition-group>
     </div>
     <div class="input-container" v-if="!isMobile">
-        <input @click.stop="toggleSelectMenu" v-model="danmu" type="text" placeholder="请选择弹幕内发送吧~" class="send-choices">
+        <input @click.stop="toggleSelectMenu" v-model="danmu" type="text" placeholder="请选择弹幕内发送吧~" class="send-choices">
       <div class="send-btn-container">
         <img
           @click="hideList"
@@ -45,7 +45,7 @@
       </ul>
     </div>
     <div class="input-mobile" v-else>
-      <span class="send-choices" @click.stop="toggleSelectMenu">请选择弹幕内发送吧~</span>
+      <span class="send-choices" @click.stop="toggleSelectMenu">请选择弹幕内发送吧~</span>
       <div class="send-btn-container">
         <img
           @click="hideList"
@@ -199,13 +199,13 @@ export default {
 }
 .danmaku-container {
   max-width: 340px;
-  max-height: 288px;
-  overflow-x: hidden;
-  overflow-y: scroll;
-
-  &::-webkit-scrollbar{
-    width: 2px;
-  }
+  max-height: 300px;
+  overflow: hidden;
+  // overflow-x: hidden;
+  // overflow-y: scroll;
+  // &::-webkit-scrollbar{
+  //   width: 2px;
+  // }
 }
 
 /* .hidedanmu{
@@ -239,8 +239,7 @@ export default {
   margin: 0;
   color: #fff;
   border-radius: 20px;
-  background: rgba(0, 0, 0, 0.6);
-  border: 1px solid hsla(0, 0%, 100%, 0.53);
+  background: rgba(0, 0, 0, 0.39);
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
@@ -249,7 +248,7 @@ export default {
 }
 .danmaku-list li.danmaku-list-item:nth-last-child(6) {
   /* visibility: hidden; */
-  animation: fadeout 0.3s linear;
+  animation: fadeout 0.3s linear forwards;
 }
 
 .input-container {
@@ -436,7 +435,7 @@ export default {
     transform: translateY(3px);
   }
   100% {
-    opacity: 0.2;
+    opacity: 0.3;
     transform: translateY(0px);
   }
 }

+ 24 - 1
web/src/components/lrLayout/index.vue

@@ -1,14 +1,27 @@
 <template>
   <div class="lr_layout">
+    <BackTop class="back-top" :targetId="'collection-list'">
+      <img :src="require('@/assets/images/返回顶部.png')" />
+    </BackTop>
     <div class="lcon">
       <slot name="lcon"></slot>
     </div>
-    <div class="rcon">
+    <div id="collection-list" class="rcon">
       <slot name="rcon"></slot>
     </div>
   </div>
 </template>
 
+<script>
+import BackTop from "@/components/BackTop.vue";
+
+export default {
+  components: {
+    BackTop
+  },
+}
+</script>
+
 <style lang="less" scoped>
 .lr_layout {
   position: relative;
@@ -36,4 +49,14 @@
     }
   }
 }
+
+.back-top {
+  position: absolute;
+  right: -230px;
+  bottom: 247px;
+  width: 60px;
+  height: 60px;
+  border-radius: 30px;
+  cursor: pointer;
+}
 </style>

+ 6 - 2
web/src/components/sTitle.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="name">
-    <img :src="require(`@/assets/images/xinjiang/xing_${theme}.png`)" alt="">
+    <img v-if="ifShowStar" :src="require(`@/assets/images/xinjiang/xing_${theme}.png`)" alt="">
     <p class="primaryColor">{{name}}</p>
   </div>
 </template>
@@ -8,7 +8,11 @@
 <script>
 export default {
   props:{
-    name:String
+    name: String,
+    ifShowStar: {
+      type: Boolean,
+      default: true,
+    }
   }
 }
 </script>

+ 1 - 1
web/src/config/api.js

@@ -134,7 +134,7 @@ export function getDetailById(type,data, cb) {
   });
 }
 
-//
+//祭
 export function mournVisit(data, cb=()=>{}) {
   axios({
     method: "get",

+ 3 - 3
web/src/config/route.js

@@ -1,9 +1,9 @@
 const Menu = [
     { text: '数字史馆', belong: 1, link: '/', name: 'home' },
-    { text: '精品典藏', belong: 2, link: '/collection', name: 'collection' },
-    { text: '纪念祭扫', belong: 3, link: '/spirit', name: 'spirit' },
+    { text: '馆藏数据库', belong: 2, link: '/collection', name: 'collection' },
+    { text: '网上祭英烈', belong: 3, link: '/spirit', name: 'spirit' },
     // { text: '学习园地', belong: 4, link: '/dynamic/:key/:type/:id', name: 'dynamic' },
-    { text: '我要留言', belong: 5, link: '/message', name: 'message' },
+    { text: '强军寄语', belong: 5, link: '/message', name: 'message' },
 ]
 
 const Detail = [

+ 33 - 0
web/src/config/utils.js

@@ -101,5 +101,38 @@ module.exports = {
     }
 
     return front + str2 + middle + str1 + end
+  },
+  /**
+   * 返回一个自带消抖效果的函数,用res表示。
+   * 
+   * fn: 需要被消抖的函数
+   * delay: 消抖时长
+   * isImmediateCall: 是在第一次调用时立即执行fn,还是在最后一次调用后等delay时长再调用fn
+   */
+  debounce: function(fn, delay, isImmediateCall = false) {
+    let timer = null
+    // 上次调用的时刻
+    let lastCallTime = 0
+
+    if (isImmediateCall) {
+      return function (...args) {
+        const context = this
+        const currentTime = Date.now()
+        if (currentTime - lastCallTime >= delay) {
+          fn.apply(context, args)
+        }
+        lastCallTime = currentTime
+      }
+    } else {
+      return function (...args) {
+        if (timer) {
+          clearTimeout(timer)
+        }
+        const context = this
+        timer = setTimeout(() => {
+          fn.apply(context, args)
+        }, delay)
+      }
+    }
   }
 };

+ 1 - 0
web/src/mixins/index.js

@@ -41,6 +41,7 @@ Vue.mixin({
       userInfo: (state) => state.common.userInfo,
       theme: (state) => state.common.theme
     }),
+    // 响应性有吗?
     token(){
       let token = (window.localStorage.getItem('webtoken')&&window.localStorage.getItem('webtoken')) || ''
       return token

+ 3 - 3
web/src/views/collection/Collection.vue

@@ -66,7 +66,7 @@ export default {
     width: 100%;
     text-align: center;
     position: relative;
-    padding-bottom: 30px;
+    padding-bottom: 104px;
     >ul{
       width: 100%;
       min-height: 70vh;
@@ -77,7 +77,7 @@ export default {
         width: 310px;
         margin-right: 18px;
         text-align: center;
-        margin-bottom: 18px;
+        margin-bottom: 37px;
         cursor: pointer;
         &:nth-child(3n){
           margin-right: 0;
@@ -134,7 +134,7 @@ export default {
       }
     }
     .paging{
-      margin-top: 40px;
+      margin-top: 27px;
       font-weight: normal;
     }
   }

+ 1 - 1
web/src/views/collection/detail.vue

@@ -3,7 +3,7 @@
     <div class="aside">
       <mSidebar :activeId="String(activeId)" :list="list" @handleItem="handleItem" class="m-sidebar"/>
       <div slot="bottom" class="search-cls">
-        <input type="text" placeholder="搜索精品典藏" @keyup.enter="getCollection" v-model="keyword" />
+        <input type="text" placeholder="搜索馆藏数据库" @keyup.enter="getCollection" v-model="keyword" />
         <div @click="getCollection" class="search-btn primary">
           <img :src="require('@/assets/images/search.png')" alt />
         </div>

+ 1 - 1
web/src/views/layout/footer.vue

@@ -10,7 +10,7 @@
         <p>友情链接:<a href="http://25.21.144.120/" target="_blank">新疆生产建设兵总队网</a></p>
       </li>
       <li>
-        <p>版权所有:92403部队史馆</p>
+        <p>版权所有:福州基地数字史馆</p>
         <p>CopyRights 2016, All Rights Reserved.</p>
       </li>
       <li>

+ 5 - 4
web/src/views/layout/header.vue

@@ -14,7 +14,7 @@
           alt=""
         />
       </div>
-      <span @click="gotoHome">92403部队</span>
+      <span @click="gotoHome">福州基地数字史馆</span>
     </div>
 
     <div class="nav-right">
@@ -104,12 +104,12 @@ const navs = [
     id: 1,
   },
   {
-    name: "精品典藏",
+    name: "馆藏数据库",
     link: "/collection",
     id: 2,
   },
   {
-    name: "纪念祭扫",
+    name: "网上祭英烈",
     link: "/spirit",
     id: 3,
   },
@@ -119,7 +119,7 @@ const navs = [
   //   id: 4,
   // },
   {
-    name: "我要留言",
+    name: "强军寄语",
     link: "/message",
     id: 5,
   },
@@ -205,6 +205,7 @@ export default {
     changeColor(id) {
       this.$store.dispatch("changeTheme", id);
       document.getElementById("app").className = "theme" + id;
+      document.getElementsByTagName('iframe')[0].contentWindow.dispatchEvent(new Event('themechange'))
     },
     navigateTo(item) {
       this.activeIdx = item.id;

+ 38 - 15
web/src/views/layout/index.vue

@@ -12,8 +12,8 @@
           <input type="password" @keyup.enter="login" v-model="password" placeholder="密码" />
         </div>
         <p class="sub">
-          <span @click="$router.push({ path: '/register' })">注册账号</span>
-          <span @click="$router.push({ path: '/forget' })">忘记密码</span>
+          <span class="register-account" @click="onClickRegisterAccount">注册账号</span>
+          <span class="forget-passcode" @click="onClickForgetPasscode">忘记密码</span>
         </p>
         <div class="button primarybtn" @click="login">登录</div>
       </div>
@@ -49,6 +49,20 @@ export default {
     },
   },
   methods: {
+    onClickRegisterAccount() {
+      if (this.$route.name === 'register') {
+        this.closeLogin()
+      } else {
+        this.$router.push({ name: 'register' })
+      }
+    },
+    onClickForgetPasscode() {
+      if (this.$route.name === 'forget') {
+        this.closeLogin()
+      } else {
+        this.$router.push({ name: 'forget' })
+      }
+    },
     handleKD(e){
       if(this.$route.name!='scene'){
         e.stopPropagation()
@@ -110,36 +124,45 @@ export default {
   top: 0;
   width: 310px;
   background-color: rgba(255, 255, 255, 0.9);
-  padding: 30px 20px;
+  padding: 28px 15px 25px;
   .title {
-    font-size: 20px;
+    font-size: 24px;
+    font-weight: bold;
+    color: #333333;
+    margin-bottom: -9px;
   }
   .linput {
-    height: 42px;
+    height: 50px;
+    border-radius: 5px;
+    margin-top: 30px;
+    padding-left: 11px;
     background-color: #fff;
-    border-radius: 4px;
-    margin-top: 40px;
-    width: 100%;
-    padding-left: 20px;
+    background: rgba(255, 255, 255, 0.8);
+    border: 1px solid #999999;
     > input {
       border: none;
       background: none;
-      line-height: 42px;
-      height: 42px;
+      height: 100%;
       width: 100%;
     }
   }
   .sub {
     text-align: right;
-    font-size: 14px;
-    margin-top: 10px;
+    margin-top: 9px;
     > span {
-      margin-left: 30px;
+      font-size: 14px;
+      color: #999999;
       cursor: pointer;
     }
+    .register-account {
+      margin-right: 18px;
+    }
+    .forget-passcode {
+      margin-right: 6px;
+    }
   }
   .button {
-    margin-top: 30px;
+    margin-top: 39px;
     width: 100%;
   }
 }

+ 1 - 1
web/src/views/martyr/index.vue

@@ -10,7 +10,7 @@
         <div class="img borderColor">
           <img :src="data.thumb||g_defaultAvatar" alt="" />
         </div>
-        <sbutton :name="'网上祭拜'" @click.native="gotosacrifice" />
+        <sbutton :name="'网上缅怀'" @click.native="gotosacrifice" />
       </div>
       <div class="right">
         <div>

+ 21 - 13
web/src/views/message/Message.vue

@@ -39,8 +39,9 @@
           <ul class="content">
             <li v-for="(item,i) in message" :key="i">
               <div class="info">
-                <span class="primaryColor">{{(item.isRealName?item.realName:item.nickName)||'匿名用户'}}</span>
-                <span>{{item.createTime}}</span>
+                <span class="primaryColor user-name">{{(item.isRealName?item.realName:item.nickName)||'匿名用户'}}</span>
+                <img class="user-level" :src="require(`@/assets/images/xinjiang/junxian/${item.level+1}.png`)" alt="">
+                <span class="comment-time"><pre>{{item.createTime.split(' ').join('   ').split(':').join(':  ')}}</pre></span>
               </div>
               <div class="body">
                 <span>{{item.content}}</span>
@@ -53,7 +54,7 @@
               <ul class="response-text" v-if="item.children">
                 <li v-for="(sub,idx) in item.children" :key="idx">
                   <div>{{sub.content}}</div>
-                  <div>来自:{{sub.isRealName?sub.realName:sub.nickName}} 的评论 {{sub.createTime}}</div>
+                  <div><pre>来自:{{sub.isRealName?sub.realName:sub.nickName}} 的评论    {{item.createTime.split(' ').join('   ').split(':').join(':  ')}}</pre></div>
                 </li>
               </ul>
               <template v-if="item.showComment">
@@ -250,7 +251,8 @@ export default {
       }
     }
     .leaving{
-      margin-top: 40px;
+      margin-top: 62px;
+      padding: 0 165px;
       .title{
         text-align: left;
         font-size: 30px;
@@ -273,14 +275,20 @@ export default {
         >li{
           margin-bottom: 10px;
           .info{
-            >span{
-              display: inline-block;
+            display: flex;
+            align-items: flex-end;
+            .user-name {
               font-size: 20px;
-              margin-right: 10px;
-              &:not(:first-of-type){
-                color: rgba(153, 153, 153, 1);
-                font-size: 14px;
-              }
+              margin-right: 13px;
+            }
+            .user-level {
+              width: 60px;
+              height: 20px;
+            }
+            .comment-time {
+              color: rgba(153, 153, 153, 1);
+              font-size: 14px;
+              margin-left: auto;
             }
           }
           .body{
@@ -295,11 +303,11 @@ export default {
             }
             .txtSameHover{
               color: rgba(153, 153, 153, 1);
-              img{
+              img {
                 margin-right: 10px;
                 width: 16px;
                 position: relative;
-                top: -1px;
+                top: 2px;
               }
             }
           }

+ 5 - 1
web/src/views/message/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="msg-con">
     <div class="msg" :style="{backgroundImage:`url(${require('@/assets/images/xinjiang/msg_bg.jpg')})`}">
-      <h1 class="primaryColor">我要留言</h1>
+      <h1 class="primaryColor">强军寄语</h1>
       <Message/>
     </div>
   </div>
@@ -11,6 +11,7 @@
 import Message from "./Message";
 
 export default {
+  name: 'MsgCon-强军寄语',
   components:{
     Message
   }
@@ -21,6 +22,9 @@ export default {
 .msg-con{
   overflow-y: auto;
   overflow-x: hidden;
+  margin-top: 100px;
+  padding-top: 0;
+  height: calc(100% - 100px);
 .msg{
   background-color: #ece1db;
   background-size: 100% auto;

+ 1 - 1
web/src/views/sacrifice/index.vue

@@ -26,7 +26,7 @@
         class="sbtn"
         v-else
         @click.native="baijifn"
-        :name="'点击进行祭'"
+        :name="'点击进行祭'"
       />
     </div>
     <liuyan class="right"> </liuyan>

+ 2 - 2
web/src/views/sacrifice/liuyan.vue

@@ -16,7 +16,7 @@
       <div class="content">
         <textarea
           placeholder="请输入缅怀致敬"
-          maxlength="250"
+          maxlength="25"
           v-model="msg"
           rows="6"
           cols="80"
@@ -24,7 +24,7 @@
         </textarea>
       </div>
       <div class="bottom">
-        <span>{{ msg.length }} / 250</span>
+        <span>{{ msg.length }} / 25</span>
         <span class="sbtn " :class="{primary:token}" @click="leaveMsg">发表</span>
       </div>
     </div>

+ 24 - 20
web/src/views/scene/gui/menu.vue

@@ -90,7 +90,7 @@
                 title="导览"
               />
             </div>
-            <div
+            <!-- <div
               data-original-title="热点列表"
               id="hotList"
               rel="tooltip"
@@ -102,7 +102,7 @@
                 :src="require('@/assets/images/btnlist/hotlist.png')"
                 title="热点列表"
               />
-            </div>
+            </div> -->
             <div
               data-original-title="全景漫游"
               id="gui-modes-inside"
@@ -188,10 +188,10 @@
               :src="require(`@/assets/images/btnlist/${item.id}${btnlistActive==item.id?`_${theme}`:''}.png`)"
             />
           </li>
-          <li @click="isBgm=!isBgm">
+          <li>
             <img
-              title="音乐"
-              :src="require(`@/assets/images/btnlist/bgm${isBgm?`_${theme}`:''}.png`)"
+              id="bg-music-btn"
+              :src="require(`@/assets/images/btnlist/bgm_on.png`)"
             />
           </li>
         </ul>
@@ -225,7 +225,7 @@
         <div id="volume" class="ui-icon wide">
           <a>
             <img
-              :src="require('@/assets/images/btnlist/Volume btn_on.png')"
+              :src="require('@/assets/images/btnlist/解说-打开.png')"
               width="24"
               height="24"
             />
@@ -257,7 +257,7 @@
           title="{[{ VIEW_FULLSCREEN }]}"
         >
           <a title="全屏">
-            <i class="icon icon-fullscreen"></i>
+            <img class="icon icon-fullscreen" :src="require('@/assets/images/btnlist/大场景-展开.png')"/>
           </a>
         </div>
         <div
@@ -269,7 +269,7 @@
           style="display: none"
         >
           <a title="退出全屏">
-            <i class="icon icon-fullscreen-exit"></i>
+            <img class="icon-fullscreen-exit" :src="require('@/assets/images/btnlist/大场景-缩小.png')"/>
           </a>
         </div>
         <div class="pull-right terms terms2">
@@ -281,7 +281,7 @@
 </template>
 
 <script>
-
+import { checkLogin } from "@/config/api";
 import { getStar,dianzan  } from "@/config/api";
 
 let menuli = [
@@ -384,7 +384,6 @@ export default {
       conLi,
       showAutoList: false,
       btnlistActive:this.itemctive,
-      isBgm:false,
       isShowGood:false,
       likeNum:0
     };
@@ -401,21 +400,26 @@ export default {
       this.$emit('btnactive',item.id)
     },
     handleLike(){
-       if (this.isShowGood) return
-        this.isShowGood = true
-        dianzan(()=>{
-          this.isShowGood = true
-          setTimeout(() => {
-            this.isShowGood = false
-            this.likeNum++
-          }, 2500);
-        })
+      if (this.isShowGood) return
+      checkLogin(res => {
+        if (res.data) {
+          dianzan(()=>{
+            this.isShowGood = true
+            setTimeout(() => {
+              this.isShowGood = false
+              this.likeNum++
+            }, 2500);
+          })
+        } else {
+          alert('请登录后操作')
+        }
+      })
     },
     getStar(){
       getStar(res=>{
         this.likeNum = res.data
       })
-    }
+    },
   },
   mounted(){
     this.$bus.$on('resetbtnactive',()=>{

+ 2 - 2
web/src/views/spirit/index.vue

@@ -143,7 +143,7 @@ export default {
           }
         }
         > ul {
-          @gap: 32px;
+          @gap: 30px;
           width: 96%;
           padding: 0 3%;
           height: calc(100% - 90px);
@@ -153,7 +153,7 @@ export default {
           > li {
             width: calc((100% - @gap * 7) / 8);
             margin-right: @gap;
-            margin-bottom: @gap / 2;
+            margin-bottom: @gap;
             position: relative;
             display: inline-block;
             cursor: pointer;

+ 14 - 16
web/src/views/user/forget.vue

@@ -19,9 +19,9 @@
                   type="text"
                 />
               </div>
-              <span class="requiretxt primaryColor">
-                <!-- {{ sub.showValidate && sub.required ? sub.validate : "" }} -->
-              </span>
+              <!-- <span class="requiretxt primaryColor">
+                {{ sub.showValidate && sub.required ? sub.validate : "" }}
+              </span> -->
             </li>
           </ul>
         </div>
@@ -236,7 +236,6 @@ export default {
     .form {
       margin-top: 30px;
       ul {
-        padding: 0 100px;
         border-bottom: 1px solid #ebebeb;
         margin-bottom: 20px;
         &:last-of-type {
@@ -244,21 +243,20 @@ export default {
         }
         > li {
           display: flex;
-          justify-content: space-between;
+          justify-content: center;
           align-items: center;
-          margin-bottom: 20px;
-          .input {
-            border: #ebebeb 1px solid;
-            width: 320px;
-          }
+          margin-bottom: 25px;
           > span {
+            width: 140px;
+            flex: 0 0 auto;
+            color: #333;
             display: inline-block;
-            flex: 1;
-            text-align: left;
-            margin: 0 20px;
-            &:first-of-type {
-              text-align: right;
-            }
+            margin-right: 12px;
+            text-align: right;
+          }
+          .input {
+            border: #ebebeb 1px solid;
+            width: 310px;
           }
           .require {
             &::before {

+ 9 - 4
web/src/views/user/register.vue

@@ -6,9 +6,9 @@
     }"
   >
     <div class="register">
-      <p class="title primaryColor">欢迎申请92403部队账号</p>
+      <p class="title primaryColor">欢迎申请福州基地数字史馆账号</p>
       <p class="sub">
-        92403部队管理系统实行实名制注册,请如实填写已下信息,我们将对用户资料实行实名制验证,信息不实的将被锁定。
+        福州基地数字史馆管理系统实行实名制注册,请如实填写以下信息,我们将对用户资料实行实名制验证,信息不实的将被锁定。
       </p>
       <div class="form">
         <ul
@@ -17,7 +17,7 @@
           :key="index"
         >
           <li v-for="(sub, i) in item.arr" :key="i">
-            <span :class="{ require: sub.required }">{{ sub.label }}:</span>
+            <span class="form-item-name" :class="{ require: sub.required }">{{ sub.label }}:</span>
             <div class="normalradio" v-if="sub.type === 'radio'">
               <input id="man" type="radio" value="0" v-model="sub.val" />
               <label for="man">男</label>
@@ -87,7 +87,7 @@ export default {
               val: "",
               showValidate: true,
               required: true,
-              validate: "请填写真实军人证件或身份证件号码。",
+              validate: "请填写真实军人证件号码。",
             },
             {
               label: "单位名称",
@@ -224,8 +224,13 @@ export default {
           justify-content: space-between;
           align-items: center;
           margin-bottom: 20px;
+          .form-item-name {
+            width: 100px;
+            flex: 0 0 auto;
+          }
           .input {
             border: #ebebeb 1px solid;
+            width: 310px;
           }
           .normalradio {
             min-width: 207px;

+ 8 - 5
web/src/views/user/userinfo.vue

@@ -4,7 +4,7 @@
     <p class="title primaryColor">个人设置</p>
     <div class="form">
       <ul class="borderColor" v-for="(item,index) in registerInfo" :key="index">
-        <stitle :name="item.name" class="stitle"/>
+        <stitle :ifShowStar="false" :name="item.name" class="stitle"/>
         <br/>
         <li v-for="(sub,i) in item.arr" :key="i">
           <span :class="{'require':sub.required}">{{sub.label}}:</span>
@@ -41,7 +41,7 @@ const registerInfo = [
         showValidate: true,
         required: true,
         disable:true,
-        validate: "请填写真实军人证件或身份证件号码。",
+        validate: "请填写真实军人证件号码。",
       },
       {
         label: "真实姓名",
@@ -181,12 +181,15 @@ export default {
   .form {
     margin-top: 30px;
     ul {
-      padding: 0 100px;
-      border-bottom: 1px solid #ebebeb;
+      margin: 0 100px;
       margin-bottom: 20px;
       text-align: left;
+      &:first-of-type {
+        border-bottom: 1px solid #ebebeb;
+        padding-bottom: 40px;
+        margin-bottom: 55px;
+      }
       &:last-of-type {
-        border-bottom: none;
       }
       .stitle{
         margin: 30px 0 40px;