فهرست منبع

Merge branch 'master' of http://192.168.0.115:3000/chenzhiguang/zhengzhou_university

xzw 4 سال پیش
والد
کامیت
9bc765e407
60فایلهای تغییر یافته به همراه1866 افزوده شده و 57908 حذف شده
  1. 25 0
      .gitignore
  2. 1 2
      backstage/package.json
  3. 1 1
      backstage/public/index.html
  4. 1 1
      backstage/src/assets/font/iconfont.json
  5. 404 0
      backstage/src/pages/content/Upload.vue
  6. 1 0
      backstage/src/pages/layout/aside.vue
  7. 1 1
      backstage/src/pages/layout/head.vue
  8. 1 1
      backstage/src/pages/login/index.vue
  9. 7 0
      backstage/src/router/index.js
  10. 4 4
      edit-backstage/css/main.css
  11. 0 57672
      edit-backstage/js/main_2020_show.js
  12. 1 1
      edit-backstage/js/manage.js
  13. 0 1
      web/public/static/js/CAD/bundle.js
  14. 0 162
      web/public/static/js/CAD/loadCAD.js
  15. 13 8
      web/public/static/js/main_2020_show.js
  16. 2 1
      web/public/static/js/myShow.js
  17. BIN
      web/src/assets/images/bg.jpg
  18. BIN
      web/src/assets/images/collection/1.png
  19. BIN
      web/src/assets/images/collection/10.png
  20. BIN
      web/src/assets/images/collection/11.png
  21. BIN
      web/src/assets/images/collection/12.png
  22. BIN
      web/src/assets/images/collection/13.png
  23. BIN
      web/src/assets/images/collection/14.png
  24. BIN
      web/src/assets/images/collection/15.png
  25. BIN
      web/src/assets/images/collection/16.png
  26. BIN
      web/src/assets/images/collection/17.png
  27. BIN
      web/src/assets/images/collection/18.png
  28. BIN
      web/src/assets/images/collection/19.png
  29. BIN
      web/src/assets/images/collection/2.png
  30. BIN
      web/src/assets/images/collection/20.png
  31. BIN
      web/src/assets/images/collection/3.png
  32. BIN
      web/src/assets/images/collection/4.png
  33. BIN
      web/src/assets/images/collection/5.png
  34. BIN
      web/src/assets/images/collection/6.png
  35. BIN
      web/src/assets/images/collection/7.png
  36. BIN
      web/src/assets/images/collection/8.png
  37. BIN
      web/src/assets/images/collection/9.png
  38. 22 0
      web/src/assets/images/icon/shoushi.svg
  39. BIN
      web/src/assets/images/upload_w.png
  40. BIN
      web/src/assets/images/uploadfile/close.png
  41. BIN
      web/src/assets/images/uploadfile/video.png
  42. BIN
      web/src/assets/images/uploadfile/zip.png
  43. BIN
      web/src/assets/images/uploadplus.png
  44. BIN
      web/src/assets/video/video.mp4
  45. BIN
      web/src/assets/video/welcome.mp4
  46. 1 1
      web/src/components/collection.vue
  47. 239 0
      web/src/components/longvideo/index.vue
  48. 111 0
      web/src/components/mapsvg.vue
  49. 1 0
      web/src/components/svg.vue
  50. 126 0
      web/src/components/uploader.vue
  51. 85 0
      web/src/components/welcome/index.vue
  52. 0 2
      web/src/main.js
  53. 15 1
      web/src/mixins/index.js
  54. 124 47
      web/src/pages/Home.vue
  55. 154 0
      web/src/utils/file.js
  56. 1 1
      web/src/utils/http.js
  57. 92 0
      web/src/utils/request.js
  58. 1 0
      web/src/views/collection/pc.vue
  59. 40 1
      web/src/views/gui/newguide.vue
  60. 392 0
      web/src/views/uploadflie/index.vue

+ 25 - 0
.gitignore

@@ -0,0 +1,25 @@
+.DS_Store
+node_modules
+/dist
+public/data
+
+
+
+# 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?

+ 1 - 2
backstage/package.json

@@ -13,8 +13,7 @@
     "element-ui": "^2.13.2",
     "js-base64": "^2.6.2",
     "vue": "^2.6.11",
-    "vue-router": "^3.1.6",
-    "vue2-editor": "^2.10.2"
+    "vue-router": "^3.1.6"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "~4.3.0",

+ 1 - 1
backstage/public/index.html

@@ -7,7 +7,7 @@
     <meta name="renderer" content="webkit">
     <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
-    <title>数字史馆管理系统</title>
+    <title>管理系统</title>
   </head>
   <body>
     <noscript>

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

@@ -3,7 +3,7 @@
   "name": "郑州信息工程大学",
   "font_family": "iconfont",
   "css_prefix_text": "icon",
-  "description": "展示界面和数字史馆管理系统",
+  "description": "展示界面和管理系统",
   "glyphs": [
     {
       "icon_id": "15079056",

+ 404 - 0
backstage/src/pages/content/Upload.vue

@@ -0,0 +1,404 @@
+<!--  -->
+<template>
+  <div>
+    <main-top :crumb="crumbData"></main-top>
+    <div class="table-interface">
+      <div class="top-body">
+        <div class="info-top">
+          <div class="info-left">
+            <el-input class="elInput" :maxlength="50"
+                show-word-limit v-model="inputKey" placeholder="请输入关键字"></el-input>
+            <el-button type="primary" @click="getInformation">查询</el-button>
+            <el-button @click="reset">重置</el-button>
+          </div>
+          <div class="info-right"></div>
+        </div>
+        <el-table :data="tableData" height="62vh" class="collection-con" style="width: 100%">
+          <el-table-column
+            v-for="(item, idx) in data"
+            :key="idx"
+            :prop="item.prop"
+            :label="item.label"
+          >
+            <template slot-scope="scope" >
+              <span v-html="scope.row[item.prop]||'-'"></span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作">
+            <template slot-scope="scope" >
+              <span class="o-span" @click="dowload(scope.row)">下载附件</span>
+              <span class="o-span" @click="del(scope.row)">删除</span>
+            </template>
+          </el-table-column>
+        </el-table>
+        <div class="e-pagination">
+          <el-pagination
+            @current-change="handleCurrentChange"
+            :current-page.sync="currentPage"
+            @size-change="handleSizeChange"
+            :page-size="size"
+            :page-sizes="PAGESIZES"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="total"
+          ></el-pagination>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+// 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
+// 例如:import 《组件名称》 from '《组件路径》';
+
+import MainTop from '@/components/main-top'
+const crumbData = [
+  {
+    name: '史料收件管理',
+    id: 4
+  }
+]
+
+
+let data = [
+      {
+        prop: "idx",
+        label: "编号"
+      },
+      {
+        prop: "description",
+        label: "史料说明"
+      },
+      {
+        prop: "phone",
+        label: "联系方式"
+      },
+      {
+        prop: "updateTime",
+        label: "提交时间"
+      }
+    ];
+export default {
+  // import引入的组件需要注入到对象中才能使用
+  components: {
+    MainTop,
+  },
+  data () {
+    return {
+      data,
+      crumbData,
+      tableData: [],
+      currentPage: 1,
+      size: 25,
+      total: 0,
+      loading: false,
+      inputKey:''
+    }
+  },
+  watch: {
+    currentPage () {
+      this.refresh()
+    },
+    size () {
+      this.refresh()
+    }
+  },
+  mounted () {
+    this.refresh()
+  },
+ 
+  methods: {
+    reset(){
+      this.inputKey=''
+      this.time=''
+      this.type=''
+      this.refresh()
+    },
+    del(item) {
+      this.$confirm("删除后,文件将无法恢复,是否继续?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.$http
+            .get(`/manage/material/remove/${item.id}`, {
+              headers: {
+                token: window.localStorage.getItem("token"),
+              },
+            })
+            .then((res) => {
+              if (res.code === 0) {
+                this.$alert("删除成功", "提示", {
+                  confirmButtonText: "确定",
+                  callback: () => {
+                    this.refresh();
+                  },
+                });
+              } else {
+                this.$notify.error({
+                  title: "错误",
+                  message: res.msg,
+                });
+              }
+            });
+        })
+        .catch(() => {
+          this.$message({
+            type: "info",
+            message: "已取消删除",
+          });
+        });
+    },
+    _browserDownload (url) {
+      let a = document.createElement('a')
+      let urlArr = url.split('/')
+      let fileName = urlArr[urlArr.length - 1]
+      a.href = url
+      a.download = fileName
+      a.style.display = 'none'
+      document.body.appendChild(a)
+      a.click()
+      document.body.removeChild(a)
+    },
+    async dowload(item){
+      let result = await this.$http({
+            method: 'get',
+            headers: {
+              token: window.localStorage.getItem('token')
+            },
+            url: `/manage/material/download/${item.id}`
+        })
+        if (result.code != 0) {
+          return this.$alert("获取下载链接失败", "提示", {
+            confirmButtonText: "确定",
+            callback: () => {
+              this.refresh();
+            },
+          });
+        }
+       this._browserDownload(result.data)
+    },
+    refresh () {
+      this.loading = true
+      this.getInformation()
+      this.loading = false
+    },
+    handleCurrentChange (val) {
+      this.currentPage = val
+    },
+    handleSizeChange(val){
+      this.size = val
+    },
+    async getInformation () {
+      let params = {
+          pageNum:this.currentPage,
+          pageSize: this.size,
+          searchKey: this.inputKey
+      }
+
+      let result = await this.$http({
+        method: 'post',
+        data: params,
+        headers: {
+          token: window.localStorage.getItem('token')
+        },
+        url: '/manage/material/list'
+      })
+
+      if (result.code !== 0) {
+        return
+      }
+      this.tableData = result.data.list
+      this.total = result.data.total
+      this.tableData.forEach((item, i) => {
+        item["idx"] = i + 1;
+      });
+    }
+  }
+}
+</script>
+
+
+<style lang="less" scoped>
+.top-body{
+  border-top: .0625rem solid #e6e6e6;
+  line-height: 1.5;
+  padding: 0 1.25rem 1.25rem;
+  align-items: center;
+  box-sizing: border-box;
+  background: #fff;
+  margin: 1rem 0;
+}
+
+.top-body .top-con{
+  font-weight: bold;
+}
+.table-title{
+  padding: 1rem 1rem 1rem 0 ;
+  font-size: 1rem;
+  color: #2d2d2d;
+  border-bottom: .0625rem solid #ccc;
+  display: flex;
+  justify-content: space-between;
+}
+
+.more{
+  color: #ec652d;
+  cursor: pointer;
+}
+
+.top-right{
+  background-color: #ec652d;
+  height: 3.5625rem;
+  line-height: 3.5625rem;
+  color: #fff;
+  padding: 0 1.875rem;
+  border-radius: .3125rem;
+  font-size: 1.125rem;
+  font-weight: bold;
+}
+
+.search-body{
+  background-color: #fff;
+  margin: 1.25rem 0;
+}
+
+.interface-table{
+  height: calc(100% - 17.1875rem);
+  overflow-x: hidden;
+  background-color: #fff;
+  padding: 0 1.125rem 2.375rem;
+  box-sizing: border-box;
+}
+
+.zan-con{
+  display: flex;
+  width: 100%;
+  justify-content: space-around;
+  margin-top: 1.5rem;
+  text-align: center;
+  font-size: 1.125rem;
+}
+
+.zan-con .line{
+  height: 8rem;
+  width: .0625rem;
+  background: #ccc;
+}
+
+.zan-con .zan-contain{
+  display: flex;
+  justify-content: space-between;
+  flex-direction: column;
+}
+
+.zan-con .zan-contain p{
+  font-size: 2.25rem;
+}
+
+.zan-con .zan-contain p:first-child{
+  font-size: .875rem;
+  line-height: 1.5;
+}
+
+.zan-sub{
+  text-align: right;
+  margin-top: 1.25rem;
+  color: #a5a5a5;
+  font-size: .875rem;
+}
+
+.table-interface{
+  height: calc(100% - 3rem);
+}
+
+
+.info-top{
+  padding: 1.25rem 0;
+  display: flex;
+  justify-content: space-between;
+  border-bottom: .0625rem #a5a5a5 solid;
+}
+
+.o-span{
+  cursor: pointer;
+  color: rgb(7, 152, 244);
+}
+
+.collection-con{
+  width: 100%;
+  overflow-x: hidden;
+  overflow-y: auto;
+  height: 68vh;
+}
+
+
+
+.collection-con ul{
+  display: flex;
+  flex-wrap: wrap;
+  margin-top: 1.25rem;
+}
+
+.collection-con ul li {
+  width: 24%;
+  margin-right: 1%;
+  cursor: pointer;
+  font-size: .8rem;
+  color: #2d2d2d;
+  margin-bottom: 1.25rem;
+}
+
+.collection-con ul .li-img {
+  position: relative;
+  
+}
+.collection-con ul .li-img div{
+  position: absolute;
+  left: .625rem;
+  bottom: .625rem;
+  color: #fff;
+}
+
+.collection-con ul .li-img div span{
+  margin-right: .625rem;
+}
+
+
+.collection-con ul img {
+  width: 100%;
+}
+
+.collection-con{
+  .li-txt,.li-name{
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+  .li-name{
+    margin-top: .5rem;
+    div{
+      font-size: 1rem;
+      font-weight: bold;
+      color: #532F1C;
+      &:last-of-type{
+        color: #707070;
+        font-size: .875rem;
+        font-weight: normal;
+        span{
+          margin-left: .30rem;
+          &:last-of-type{
+            &:hover{
+              color: #409EFF;
+            }
+          }
+          &:hover{
+            color: #c56351;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 1 - 0
backstage/src/pages/layout/aside.vue

@@ -6,6 +6,7 @@
       <div :class="{active:activeIdx>=2&&activeIdx<=6}"><i class="iconfont iconsys_nav_work"></i>内容管理</div>
       <div @click="go(2,'/dynamic')" :class="{activeFont:activeIdx === 2}">场景管理</div>
       <div @click="go(3,'/spirit')" :class="{activeFont:activeIdx === 3}">文物管理</div>
+      <div @click="go(4,'/upload')" :class="{activeFont:activeIdx === 4}">史料收件</div>
     </div>
     <div class="aside-item">
       <div :class="{active:activeIdx>=7&&activeIdx<=11}"><i class="iconfont iconsys_nav_system"></i>系统管理</div>

+ 1 - 1
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>数字史馆管理系统</span>
+    <span>管理系统</span>
   </div>
   <div class="header-user">
     <div class="avatars">

+ 1 - 1
backstage/src/pages/login/index.vue

@@ -9,7 +9,7 @@
     <img class="bg" :src="require('@/assets/img/bg.jpg')" alt="">
     <div class="middle">
       <div class="middle-left">
-        <div>数字史馆管理系统</div>
+        <div>管理系统</div>
       </div>
       <div class="middle-right">
         <el-form class="middle-form" :rules="ruleLogin" status-icon :model="formLogin" ref="formLogin">

+ 7 - 0
backstage/src/router/index.js

@@ -62,6 +62,13 @@ const routes = [
         component:  () => import( "../pages/system/Menu.vue"),
         meta: {index: 7,role:'sys_admin'}
       },
+
+      {
+        path:'/upload',
+        name: 'upload',
+        component:  () => import( "../pages/content/Upload.vue"),
+        meta: {index: 4,role:'sys_admin'}
+      },
       {
         path:'/parameter',
         name: 'parameter',

+ 4 - 4
edit-backstage/css/main.css

@@ -831,7 +831,7 @@ hr {
 
 .icon-fullscreen-exit:before {
     content: "";
-    background: url("https://super.4dage.com/images/narrow_off.png") center top no-repeat;
+    background: url("../images/narrow_off.png") center top no-repeat;
     background-size: 100%;
     display: inline-block;
     width: 24px;
@@ -840,7 +840,7 @@ hr {
 
 .icon-fullscreen:before {
     content: "";
-    background: url("https://super.4dage.com/images/enlarge_on.png")center top no-repeat;
+    background: url("../images/enlarge_on.png")center top no-repeat;
     background-size: 100%;
     display: inline-block;
     width: 24px;
@@ -3712,7 +3712,7 @@ a.hasHover:hover, a:active {
 .gui-floor-icon {
     width: 32px;
     height: 29px;
-    background: url("https://super.4dage.com/images/floor-icon.png") left top no-repeat;
+    background: url("../images/floor-icon.png") left top no-repeat;
     background-size: 98%;
 }
 
@@ -6345,7 +6345,7 @@ a.hasHover.tag-link:hover {
     display: block;
     width: 18px;
     height: 18px;
-    background: url("https://super.4dage.com/images/4dage-logo.png")left top no-repeat;
+    background: url("../images/4dage-logo.png")left top no-repeat;
     background-size: 100%;
 }
 

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 57672
edit-backstage/js/main_2020_show.js


+ 1 - 1
edit-backstage/js/manage.js

@@ -3,7 +3,7 @@ var Manage = function(){
     this.weixinURL = "https://res.wx.qq.com/open/js/jweixin-1.2.0.js",
     this.time = "?"+new Date().getTime();
     this.loadAudio();
-    this.loadWeixin();
+    // this.loadWeixin();
 }
 //动态加载js文件
 Manage.prototype.LoadJs = function(_files, succes){

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 1
web/public/static/js/CAD/bundle.js


+ 0 - 162
web/public/static/js/CAD/loadCAD.js

@@ -1,162 +0,0 @@
-{
-  let $layer = document.createElement('div')
-  let $cad = document.createElement('div')
-
-  $layer.className = 'cad'
-  $cad.id = 'cad'
-  $layer.appendChild($cad)
-
-  document.documentElement.appendChild($layer)
-
-  let style = document.createElement('style')
-  style.innerHTML = `
-    .cad {
-      position: absolute;
-      right: 80px;
-      top: 16px;
-      width: 200px;
-      height: 200px;
-      background: rgba(0, 0, 0, .3);
-      border-radius: 5px;
-      display: none;
-    }
-
-    .cad > div {
-      width: 100%;
-      height: 100%;
-    }
-
-    @media only screen and (max-width: 600px) { 
-      .cad {
-          position: absolute;
-          left: 16px;
-          top: 65px;
-          width: 100px;
-          height: 100px;
-          background: rgba(0, 0, 0, .3);
-          border-radius: 5px;
-      }
-    }
-  `
-
-  //解析查询字符串
-  function getQueryStringArgs() {
-    //取得查询字符串,并去掉开头'?'
-    var qs = location.search.length ? location.search.substring(1) : '';
-    //保存数据的对象
-    var args = {},
-      //以分割符'&'分割字符串,并以数组形式返回
-      items = qs.length ? qs.split('&') : [],
-      item = null,
-      name = null,
-      value = null,
-      i = 0,
-      len = items.length;
-    //逐个将每一项添加到args对象中
-    for (; i < len; i++) {
-      item = items[i].split('=');
-      //解码操作,因为查询字符串经过编码的
-      name = decodeURIComponent(item[0]);
-      value = decodeURIComponent(item[1]);
-      value = item[1];
-      if (name.length) {
-        args[name] = value;
-      }
-    }
-    return args;
-  }
-
-  function getData(url, cb) {
-    $.ajax({
-      method: 'GET',
-      url: url,
-      success(data) {
-        cb(null, data)
-      },
-      error(e) {
-        cb(e)
-      }
-    })
-  }
-
-  let code = getQueryStringArgs().m
-  let data, styleArg
-
-  getData('/CAD/static/data/'+ code +'/floor.json', (err, args) => {
-    if (!err) {
-      data = args
-      grentCAD()
-    }
-  })
-  getData('/CAD/static/data/'+ code +'/style.json', (err, args) => {
-    if (err) {
-      styleArg = {
-        line: {
-          color: '#fff',
-          width: 1
-        },
-        sign: {
-          color: 'rgb(0, 200, 175)'
-        }
-      }
-    } else {
-      styleArg = args
-    }
-    grentCAD()
-  })
-
-  
-  let point, dire
-
-  window.cad = {
-    setSign: function(p, d) {
-      point = p
-      dire = d
-    }
-  }
-  
-
-  function grentCAD() {
-    if (!(data && styleArg)) return;
-
-
-    $layer.style.display = 'none'
-    window.cad = structureCAD({
-      data: {
-          block: [],
-          column: [],
-          door: [],
-          hole: [],
-          segment: [],
-          "vertex-xy": [],
-          "vertex-z": [],
-      }, 
-      layer: $cad,
-      edit: false
-    });
-    
-    cad.setDefaultPointStyle({
-      fillColor: "rgba(0,0,0,0)",
-      storkeColor: "rgba(0,0,0,0)"
-    });
-
-    cad.setDefaultLineStyle({
-      width: styleArg.line.width,
-      color: styleArg.line.color
-    });
-
-    cad.setDefaultSignStyle({
-      color: styleArg.sign.color
-    })
-
-
-    cad.hideDire()
-    cad.hideGauge()
-
-    cad.loadData(data);
-    if (point && dire) {
-      window.cad.setSign(point, dire)
-    }
-    $layer.style.display = 'block'
-  }
-}

+ 13 - 8
web/public/static/js/main_2020_show.js

@@ -6541,6 +6541,10 @@ window.Modernizr = function(n, e, t) {
                     }),
                     t.changeMode(_e.PANORAMA);
                 }),
+                window.panoramafn=function(){
+                    // l(e),
+                    t.changeMode(_e.PANORAMA)
+                }
                 $("#gui-modes-outside").find("a").on("click", function(e) {
                     l(e),
                     J.track("showcase_gui", {
@@ -14677,6 +14681,7 @@ window.Modernizr = function(n, e, t) {
 							var e = N.calcFullLoadingTime();
 							de.warn("Total load time: " + e / 1e3),
 							H.loadComplete(e),
+                            window.dispatchEvent(window.evt);
 							de.warn("First render after model load finished.")
 						}),
 						S.on(le.MemoryUsageUpdated, n)
@@ -15865,10 +15870,7 @@ window.Modernizr = function(n, e, t) {
             options = options || {}
             
             if(this.sid == 'OJCzKg113653'){
-                
-                
-                
-                return;
+                return window.player.emit('loadLongVideo')
             }
             
             
@@ -17954,9 +17956,9 @@ window.Modernizr = function(n, e, t) {
                     li.appendChild(span);
                     docFragment.appendChild(li);
                 }
-                var ul = document.querySelector('#hotListContent ul');
-                ul.appendChild(docFragment);
-                console.log(docFragment);
+                // var ul = document.querySelector('#hotListContent ul');
+                // ul.appendChild(docFragment);
+                // console.log(docFragment);
             }
 				
 
@@ -18415,6 +18417,8 @@ window.Modernizr = function(n, e, t) {
             n.prototype.loadLabels = function() {//xzw
                 this.labels = new x(this);
                 var e = $.Deferred();
+                
+                return e.resolve();
                 //加载俯视图的标签  注释这个备注就会加载
                 //原先是labels, 改为showLabels,因为之前的somedata写的labels都是true
                 window.MP_PREFETCHED_MODELDATA.model.player_options.showLabels ? this.showingLabels = true : '';
@@ -26331,7 +26335,8 @@ window.Modernizr = function(n, e, t) {
                 transitionTime: 1e3
             },
             quickstart: {
-                enabled: 1 === r.valueFromHash("qust", 0) || 1 === r.valueFromHash("qs", 0),
+                // 1 === r.valueFromHash("qust", 0) || 1 === r.valueFromHash("qs", 0)
+                enabled: true,
                 animation: 1400,
                 showTextDelay: 500,
                 fadeOutDelay: 3e3,

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

@@ -1,5 +1,6 @@
 var g_ProjectName=window.location.pathname.substring(window.location.pathname.indexOf("/")+1,window.location.pathname.lastIndexOf("/"));
-// var g_Prefix="https://super.4dage.com/";
+// var g_Prefix="http://8.135.106.227:8009/";
+// https://super.4dage.com/
 var g_Prefix=window.location.origin+'/';
 
 var s = window.location.href.split('/');

BIN
web/src/assets/images/bg.jpg


BIN
web/src/assets/images/collection/1.png


BIN
web/src/assets/images/collection/10.png


BIN
web/src/assets/images/collection/11.png


BIN
web/src/assets/images/collection/12.png


BIN
web/src/assets/images/collection/13.png


BIN
web/src/assets/images/collection/14.png


BIN
web/src/assets/images/collection/15.png


BIN
web/src/assets/images/collection/16.png


BIN
web/src/assets/images/collection/17.png


BIN
web/src/assets/images/collection/18.png


BIN
web/src/assets/images/collection/19.png


BIN
web/src/assets/images/collection/2.png


BIN
web/src/assets/images/collection/20.png


BIN
web/src/assets/images/collection/3.png


BIN
web/src/assets/images/collection/4.png


BIN
web/src/assets/images/collection/5.png


BIN
web/src/assets/images/collection/6.png


BIN
web/src/assets/images/collection/7.png


BIN
web/src/assets/images/collection/8.png


BIN
web/src/assets/images/collection/9.png


+ 22 - 0
web/src/assets/images/icon/shoushi.svg

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg fill="#ffffff" version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve">
+<path d="M133.6,65.6c-3.3,0-6.3,1-8.9,2.8c-0.6-9.2-7.8-16.4-16.5-16.4c-3.5,0-6.8,1.2-9.5,3.2c-2-7.3-8.4-12.7-15.9-12.7
+	c-3.2,0-6.1,1-8.7,2.6V18.4c0-9.7-7.4-17.6-16.5-17.6c-9.1,0-16.5,7.9-16.5,17.6v103.1l-4.8-7.3c0,0,0,0,0,0
+	c-3.3-4.8-8.8-7.7-14.7-7.7c-3.5,0-6.9,1-9.8,2.9c-8.1,5.4-10.2,16.3-4.8,24.5L40.1,183c0.2,0.4,0.4,0.7,0.7,1
+	c0.1,0.2,0.3,0.4,0.4,0.5c0.3,0.5,0.7,1,1,1.5c0,0,0.1,0.1,0.1,0.1c5.7,9.2,10.5,11.1,15.7,13.2c0.5,0.2,1,0.3,1.5,0.3
+	c1.5,0,3-0.9,3.6-2.4c0.8-2-0.2-4.3-2.2-5.1c-4.5-1.8-7.5-3-11.9-9.9v0c-0.1-0.3-0.3-0.5-0.4-0.7c-0.3-0.3-0.6-0.8-0.9-1.3
+	c-0.2-0.3-0.4-0.5-0.5-0.8s-0.3-0.4-0.4-0.5c0-0.1-0.1-0.1-0.1-0.2l-33.1-49.2c-3-4.5-1.8-10.6,2.7-13.6c1.6-1.1,3.5-1.6,5.4-1.6
+	c3.3,0,6.3,1.6,8.2,4.3l12,18c0.7,1.1,2,1.7,3.3,1.7c0.4,0,0.8-0.1,1.1-0.2c1.6-0.5,2.8-2,2.8-3.7v-116c0-5.4,3.9-9.8,8.7-9.8
+	c4.8,0,8.7,4.4,8.7,9.8v40.1c0,0.5-0.1,1.1-0.1,1.6V86c0,2.1,1.8,3.9,3.9,3.9c1.8,0,3.3-1.3,3.8-2.9c0.1-0.4,0.2-0.8,0.2-1.2V58.9
+	c0.5-4.8,4.2-8.6,8.7-8.6c4.8,0,8.7,4.4,8.7,9.8v28.5c0,0.3,0,0.6,0.1,0.9v0.8c0,2.1,1.8,3.9,3.9,3.9s3.9-1.8,3.9-3.9V69.5
+	c0-5.4,3.9-9.8,8.7-9.8c4.8,0,8.7,4.4,8.7,9.8v24.5c0,0.3,0,0.6,0.1,0.9v9c0,2.1,1.8,3.9,3.9,3.9s3.9-1.8,3.9-3.9V83.2
+	c0-5.4,3.9-9.8,8.7-9.8c4.8,0,8.7,4.4,8.7,9.8v2.4c0,0.2-0.1,0.4-0.1,0.7v69.1c0,11.5-5.4,20.9-8.5,25.5
+	c-4.9,7.1-10.2,10.8-12.3,11.2s-3.6,2.4-3.2,4.5c0.3,1.9,2,3.3,3.8,3.3c0.2,0,0.4,0,0.7-0.1c5.1-0.9,11.9-6.5,17.4-14.4
+	c6.4-9.2,9.9-19.9,9.9-30v-46.9c0-0.2,0.1-0.4,0.1-0.7V83.2h0C150.1,73.5,142.7,65.6,133.6,65.6z"/>
+<path d="M196.9,18L180.7,1.9c-1.6-1.6-4.1-1.6-5.7,0c-1.6,1.6-1.6,4.1,0,5.7l9.6,9.6h-62.5l9.6-9.6c1.6-1.6,1.6-4.1,0-5.7
+	c-1.6-1.6-4.1-1.6-5.7,0l-16.2,16.2c-1.6,1.6-1.6,4.1,0,5.7l15.6,15.6c0.8,0.8,1.8,1.2,2.8,1.2s2-0.4,2.8-1.2c1.6-1.6,1.6-4.1,0-5.7
+	l-8.5-8.5h61.6l-8.5,8.5c-1.6,1.6-1.6,4.1,0,5.7c0.8,0.8,1.8,1.2,2.8,1.2s2-0.4,2.8-1.2l15.6-15.6c0.8-0.8,1.2-1.8,1.2-2.8
+	S197.6,18.8,196.9,18z"/>
+</svg>

BIN
web/src/assets/images/upload_w.png


BIN
web/src/assets/images/uploadfile/close.png


BIN
web/src/assets/images/uploadfile/video.png


BIN
web/src/assets/images/uploadfile/zip.png


BIN
web/src/assets/images/uploadplus.png


BIN
web/src/assets/video/video.mp4


BIN
web/src/assets/video/welcome.mp4


+ 1 - 1
web/src/components/collection.vue

@@ -62,7 +62,7 @@ export default {
   }
   .card-img {
     position: relative;
-    max-height: 190px;
+    height: 190px;
     overflow: hidden;
     background: linear-gradient(180deg, #AAAAAA 0%, #D1D1D1 100%);
     img {

+ 239 - 0
web/src/components/longvideo/index.vue

@@ -0,0 +1,239 @@
+<template>
+  <div class="longvideo">
+    <img class="close" @click="$bus.$emit('toggleLongVideo',false)" :src="require('@/assets/images/icon/close.png')" alt="">
+    <div class="longbody">
+      <video @click="autoplay" :style="{left:translate.x + 'px'}" ref="layout" autoplay loop :src="require('@/assets/video/video.mp4')"></video>
+    </div>
+    <div class="scorll-bar" :style="{width:barW+'px'}">
+      <span @click="autoplay" class="k" ref="scro" :style="{left: -translate.x * (((barW-100)/wLimit)) + 'px'}"></span>
+      <div>
+        <img :src="require('@/assets/images/icon/shoushi.svg')" alt="">
+        <span>可左右移动观看画面</span>
+      </div>
+    </div>
+
+    <div class="loading" v-if="loading">
+      <span>加载中...</span>
+    </div>
+  </div>
+</template>
+
+<script>
+const wh = {width: window.innerWidth, height: window.innerHeight}
+
+export default {
+  data(){
+    return {
+      loading:true,
+      translate: {
+        x: 0
+      },
+      barW:  (15084/2046) * 80 - 100
+    }
+  },
+  computed:{
+    wLimit () {
+      return  (15084/2046) * (wh.height - 180) - wh.width
+    },
+  },
+  methods:{
+    readyMove (ev) {
+      let startX
+      if (ev.screenX) {
+        startX = ev.screenX
+      } else {
+        startX = ev.touches[0].clientX
+      }
+
+      let x = this.translate.x
+
+      let moveHandle = ev => {
+        let moveX
+        if (ev.screenX) {
+          moveX = ev.screenX
+        } else {
+          moveX = ev.touches[0].clientX
+        }
+
+        // if (Math.abs(this.translate.y) >= 368) {
+        //   return
+        // }
+        // this.translate.x = x + moveX - startX
+        this.translate.x = Math.min(Math.max((x + moveX - startX), -this.wLimit), 0)
+        ev.preventDefault()
+        ev.stopPropagation()
+      }
+
+      let upHandle = ev => {
+        document.removeEventListener('touchmove', moveHandle, { passive: false })
+        document.removeEventListener('touchend', upHandle)
+        document.removeEventListener('mousemove', moveHandle, { passive: false })
+        document.removeEventListener('mouseup', upHandle)
+      }
+
+      document.addEventListener('touchmove', moveHandle, { passive: false })
+      document.addEventListener('touchend', upHandle)
+      document.addEventListener('mousemove', moveHandle, { passive: false })
+      document.addEventListener('mouseup', upHandle)
+    },
+
+    scrollreadyMove (ev) {
+      let startX
+
+      // console.log(startX);
+      if (ev.screenX) {
+        startX = ev.screenX
+      } else {
+        startX = ev.touches[0].clientX
+      }
+
+      let x = -this.translate.x * (this.barW / this.wLimit)
+
+      let moveHandle = ev => {
+        let moveX
+        if (ev.screenX) {
+          moveX = ev.screenX
+        } else {
+          moveX = ev.touches[0].clientX
+        }
+
+        let tmp = Math.max(Math.min((x + moveX - startX), this.barW), 0)
+        
+        this.translate.x = -tmp / (this.barW/this.wLimit)
+        ev.preventDefault()
+        ev.stopPropagation()
+      }
+
+      let upHandle = ev => {
+        document.removeEventListener('touchmove', moveHandle, { passive: false })
+        document.removeEventListener('touchend', upHandle)
+        document.removeEventListener('mousemove', moveHandle, { passive: false })
+        document.removeEventListener('mouseup', upHandle)
+      }
+
+      document.addEventListener('touchmove', moveHandle, { passive: false })
+      document.addEventListener('touchend', upHandle)
+      document.addEventListener('mousemove', moveHandle, { passive: false })
+      document.addEventListener('mouseup', upHandle)
+    },
+
+    autoplay(){
+      this.$nextTick(()=> {
+        this.$refs.layout.play();
+      })
+    }
+  },
+  mounted () {
+    this.readyMove = this.readyMove.bind(this)
+    this.$refs.layout.addEventListener('mousedown', this.readyMove)
+    this.$refs.layout.addEventListener('touchstart', this.readyMove)
+
+    this.scrollreadyMove = this.scrollreadyMove.bind(this)
+    this.$refs.scro.addEventListener('mousedown', this.scrollreadyMove)
+    this.$refs.scro.addEventListener('touchstart', this.scrollreadyMove)
+
+    this.autoplay()
+    this.$refs.layout.addEventListener('loadedmetadata',()=>{
+      this.loading = false
+    })
+  },
+  beforeDestroy () {
+    this.$refs.layout.removeEventListener('mousedown', this.readyMove)
+    this.$refs.layout.removeEventListener('touchstart', this.readyMove)
+
+    this.$refs.scro.removeEventListener('mousedown', this.scrollreadyMove)
+    this.$refs.scro.removeEventListener('touchstart', this.scrollreadyMove)
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.longvideo{
+  position: fixed;
+  top:0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 9999;
+  font-size: 0;
+  .close{
+    position: absolute;
+    right: 20px;
+    top: 20px;
+    width: 30px;
+    z-index: 99999;
+    cursor: pointer;
+  }
+  .longbody{
+    width: 100%;
+    height: 100%;
+    position: relative;
+    background: #000;
+    >video{
+        height: calc(100% - 180px);
+        position: absolute;
+        top: 90px;
+        left: 0;
+        cursor: pointer;
+    }
+  }
+  .scorll-bar{
+    width: 630px;
+    height: 80px;
+    background: rgba(0, 0, 0, 0.5);
+    position: fixed;
+    bottom: 140px;
+    left: 50%;
+    transform: translateX(-50%);
+    z-index: 9999;
+    .k{
+      height: 100%;
+      width: 100px;
+      border: 1px solid #85101C;
+      position: absolute;
+      left: 0;
+      top: 0;
+      display: inline-block;
+      cursor: pointer;
+      z-index: 9999;
+    }
+    >div{
+      position: absolute;
+      top: 0;
+      right: 0;
+      width: 50%;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background: rgba(0, 0, 0, 0.2);
+      >img{
+        width: 20px;
+        margin-right: 6px;
+      }
+      >span{
+        font-size: 16px;
+      }
+    }
+  }
+
+  .loading{
+    position: fixed;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    z-index: 10000;
+    background: #000;
+    >span{
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translateX(-50%,-50%);
+      color: #fff;
+      font-size: 16px;
+      display: inline-block;
+    }
+  }
+}
+</style>

+ 111 - 0
web/src/components/mapsvg.vue

@@ -109,6 +109,20 @@
           >
             <tspan x="0" y="0">2</tspan>
           </text>
+          <text
+            id="_2-2"
+            data-name="2"
+            transform="translate(-9.555 6.008)"
+            fill="#fcd67b"
+            font-size="8"
+            class="hovertext"
+            font-family="SourceHanSansCN-Medium, Source Han Sans CN"
+            font-weight="500"
+            opacity="0.8"
+          >
+            <tspan x="0" y="0">万水前山</tspan>
+            <tspan x="0" y="10">铁心向党</tspan>
+          </text>
         </g>
       </g>
       <g id="_3" @click="handleClick(3)" data-name="3">
@@ -141,7 +155,22 @@
           >
             <tspan x="0" y="0">3</tspan>
           </text>
+          <text
+            id="_3-2"
+            data-name="3"
+            class="hovertext"
+            transform="translate(-7.555 5.639)"
+            fill="#fcd67b"
+            font-size="7"
+            font-family="SourceHanSansCN-Medium, Source Han Sans CN"
+            font-weight="500"
+            opacity="0.8"
+          >
+            <tspan x="0" y="0">辗转办学</tspan>
+            <tspan x="0" y="10">奠定优秀</tspan>
+          </text>
         </g>
+        
       </g>
       <g id="_4"  @click="handleClick(4)" data-name="4">
         <path
@@ -176,6 +205,20 @@
           >
             <tspan x="0" y="0">4</tspan>
           </text>
+          <text
+            id="_4-3"
+            data-name="4"
+            class="hovertext"
+            transform="translate(-14.555 5.639)"
+            fill="#fcd67b"
+            font-size="7"
+            font-family="SourceHanSansCN-Medium, Source Han Sans CN"
+            font-weight="500"
+            opacity="0.8"
+          >
+            <tspan x="0" y="0">汇聚中原</tspan>
+            <tspan x="0" y="16">扬帆起航</tspan>
+          </text>
         </g>
       </g>
       <g id="_5-2"  @click="handleClick(5)" data-name="5">
@@ -211,6 +254,21 @@
           >
             <tspan x="0" y="0">5</tspan>
           </text>
+
+          <text
+            id="_5-3"
+            data-name="5"
+            class="hovertext"
+            transform="translate(-4.555 5.639)"
+            fill="#fcd67b"
+            font-size="7"
+            font-family="SourceHanSansCN-Medium, Source Han Sans CN"
+            font-weight="500"
+            opacity="0.8"
+          >
+            <tspan x="0" y="0">综合办学</tspan>
+            <tspan x="0" y="10">世纪跨越</tspan>
+          </text>
         </g>
       </g>
       <g id="_6"  @click="handleClick(6)" data-name="6">
@@ -246,6 +304,20 @@
           >
             <tspan x="0" y="0">6</tspan>
           </text>
+          <text
+            id="_6-2"
+            data-name="6"
+            class="hovertext"
+            transform="translate(-15.555 5.639)"
+            fill="#fcd67b"
+            font-size="7"
+            font-family="SourceHanSansCN-Medium, Source Han Sans CN"
+            font-weight="500"
+            opacity="0.8"
+          >
+            <tspan x="0" y="0">不忘初心</tspan>
+            <tspan x="0" y="10">时代重塑</tspan>
+          </text>
         </g>
       </g>
       <g id="_7-2"  @click="handleClick(7)" data-name="7">
@@ -281,6 +353,19 @@
           >
             <tspan x="0" y="0">7</tspan>
           </text>
+          <text
+            id="_7-3"
+            data-name="7"
+            class="hovertext"
+            transform="translate(-50.555 16.839)"
+            fill="#fcd67b"
+            font-size="7"
+            font-family="SourceHanSansCN-Medium, Source Han Sans CN"
+            font-weight="500"
+            opacity="0.8"
+          >
+            <tspan x="0" y="0">信息系统工程学院</tspan>
+          </text>
         </g>
       </g>
       <g id="_1-2"  @click="handleClick(1)" data-name="1" opacity="0.8">
@@ -316,6 +401,20 @@
         >
           <tspan x="0" y="0">1</tspan>
         </text>
+        <text
+          class="hovertext"
+          id="_1-6"
+          data-name="1"
+          transform="translate(5740 1626)"
+          fill="#fff"
+          font-size="8"
+          font-family="SourceHanSansCN-Medium, Source Han Sans CN"
+          opacity="1"
+          color
+          font-weight="500"
+        >
+          <tspan x="0" y="0">序厅</tspan>
+        </text>
       </g>
     </g>
   </svg>
@@ -379,15 +478,27 @@ export default {
         >g{
           >path{
             fill: #fcd67b;
+            display: none;
           }
         }
         ellipse{
+          display: none;
           fill: #fcd67b;
         }
         text{
           fill: #a01c26;
+          display: none;
+        }
+        .hovertext{
+          display: block;
+          fill: #fff;
+          letter-spacing: 1px;
         }
       }
+
+      .hovertext{
+        display: none;
+      }
     }
   }
 

+ 1 - 0
web/src/components/svg.vue

@@ -192,6 +192,7 @@ export default {
   },
   methods:{
     changeMode(type){
+      console.log(type);
       window[type+'fn']()
     },
     toggle(type){

+ 126 - 0
web/src/components/uploader.vue

@@ -0,0 +1,126 @@
+<template>
+  <input
+    ref="file"
+    type="file"
+    name="file"
+    id
+    style="display: none"
+    :accept="accept"
+  />
+</template>
+<script>
+import * as fileInfo from "@/utils/file";
+export default {
+  props: {
+    limit: Number,
+    mediaType: Array,
+    acceptType: String,
+    failString: String,
+    limitFailStr: String,
+  },
+  computed: {
+    accept() {
+      if (this.acceptType) {
+        return this.acceptType;
+      }
+      if (!this.mediaType) {
+        return '*'
+      }
+
+      let tmp = []
+      this.mediaType.forEach(item => {
+       tmp = tmp.concat(fileInfo.mediaMimes[item]
+        .map((ii) => item + "/" + ii))
+      });
+      return tmp.join(",");
+    },
+  },
+  mounted() {
+    this.$el.addEventListener("change", (e) => {
+      if (!window.FileReader) {
+        alert("无法上传");
+        e.target.value = "";
+        return;
+      }
+
+      if (e.target.files.length === 0) {
+        e.target.value = "";
+        return;
+      }
+
+      this.files = e.target.files;
+
+      this.files = Array.from(this.files).filter((item, i) => {
+
+
+        if (this.mediaType.length > 0 ) {
+          let pass = this.mediaType.find(jj=>{
+            return fileInfo.checkMediaMime(jj, item.name)
+          })
+
+          if (!pass) {
+            setTimeout(() => {
+            if (this.failString) {
+                alert(`“${item.name}”` + this.failString);
+              } else {
+                alert("不支持该文件格式");
+              }
+            }, i * 100);
+            return;
+          }
+        }
+        if (this.limit > 0) {
+          if (!fileInfo.checkSizeLimitFree(item.size, this.limit)) {
+            e.target.value = "";
+            setTimeout(() => {
+              if (this.limitFailStr) {
+                alert(`“${item.name}”` + this.limitFailStr);
+              }
+              else{
+                alert(`文件大小不能超过${this.limit}MB`);
+              }
+            }, i * 100);
+            return;
+          }
+        } else if (!fileInfo.checkSizeLimit(this.mediaType, item.size)) {
+          setTimeout(() => {
+            if (this.limitFailStr) {
+              alert(`“${item.name}”` + this.limitFailStr);
+            }
+            else{
+              alert(
+                `上传文件太大,不能超过${fileInfo.mediaMaxSize[this.mediaType]}MB`
+              );
+            }
+            
+          }, i * 100);
+          return;
+        }
+        return item
+      });
+
+      this.$emit("file-change", this);
+      e.target.value = "";
+    });
+  },
+  beforeDestroy() {
+    // this.clear();
+  },
+  methods: {
+    click() {
+      this.$el.click();
+    },
+    clear() {
+      this.dataURL && window.URL.revokeObjectURL(this.dataURL);
+      this.name = null;
+      this.type = null;
+      this.size = null;
+      this.files = null;
+      this.dataURL = null;
+      this.base64 = null;
+      this.poster = null;
+    },
+    upload() {},
+  },
+};
+</script>

+ 85 - 0
web/src/components/welcome/index.vue

@@ -0,0 +1,85 @@
+<template>
+  <div class="welcome">
+    <template v-show="!isVideo">
+      <img class="bg" :style="{'z-index': isVideo?-1:0}" :src="require('@/assets/images/bg.jpg')" alt="">
+      <div class="we_title">欢迎访问信息工程大学数字史馆</div>
+      <span class="btn" @click="showVideo">点击预览</span>
+    </template>
+    <video @click="autoplay" ref="welcome" preload loop :src="require('@/assets/video/welcome.mp4')"></video>
+    <span v-if="isVideo" class="btn" @click="$bus.$emit('toggleWelcome',false)">跳过</span>
+  </div>
+</template>
+
+<script>
+export default {
+  data(){
+    return {
+      isVideo: false
+    }
+  },
+  methods:{
+    autoplay(){
+      this.$nextTick(()=> {
+        setTimeout(() => {
+          this.$refs.welcome.play();
+        });
+      })
+    },
+    showVideo(){
+      this.isVideo=true
+      this.autoplay()
+    }
+  },
+  mounted(){
+    // this.autoplay()
+  }
+}
+</script>
+
+<style lang="less">
+.welcome{
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: #000;
+  z-index: 999;
+  .bg{
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%,-50%);
+    
+  }
+  .we_title{
+    background-color: none;
+    position: absolute;
+    top: 35%;
+    left: 50%;
+    transform: translate(-50%,-50%);
+    font-size: 34px;
+    color: #FCD67B;
+    letter-spacing: 2px;
+  }
+  >video{
+    width: 100%;
+  }
+  .btn{
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%,-50%);
+    z-index: 9999;
+    font-size: 16px;
+    color: #fff;
+    background-color: #A01C26;
+    border-radius: 44px;
+    display: inline-block;
+    cursor: pointer;
+    padding: 10px 40px;
+  }
+}
+</style>

+ 0 - 2
web/src/main.js

@@ -4,8 +4,6 @@ import '@/mixins'
 import router from './router'
 import {axios, serverLocation} from './utils/http'
 
-
-
 Vue.config.productionTip = false
 Vue.prototype.$http = axios
 Vue.prototype.$serverName = serverLocation

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

@@ -23,7 +23,21 @@ Vue.mixin({
       $showBroadcast,
       $hideBroadcast,
       $hideMap,
-      $showMap
+      $showMap,
+      $randomWord(randomFlag, min, max) {//随机字符串
+        var str = "",
+            range = min,
+            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++) {
+            var pos = Math.round(Math.random() * (arr.length - 1));
+            str += arr[pos];
+        }
+        return str;
+    },
     }
 })
 

+ 124 - 47
web/src/pages/Home.vue

@@ -20,7 +20,7 @@
             </div>
 
             <!-- 热点列表 -->
-            <hotspot-list/>
+            <!-- <hotspot-list/> -->
 
             <!-- 标题 -->
             <v-title/>
@@ -63,17 +63,29 @@
                 <mapsvg class="mapsvg" @click.stop/>
                 <!-- <img :src="require('@/assets/images/group.svg')" alt=""> -->
             </div>
-            <div class="search-con">
-                <input @keyup.enter="isShow=true" v-model="key" placeholder="搜索文物" type="text">
-                <img class="shugang" :src="require('@/assets/images/icon/shugeng.png')" alt="">
-                <img @click="isShow=true" :src="require('@/assets/images/search_w.png')" alt="">
+            <div class="rbtn">
+                <div class="search-con" @click="isShow=true">
+                <!-- <input  disabled="disabled" @keyup.enter="isShow=true" v-model="key" placeholder="搜索文物" type="text"> -->
+                    <div>搜索文物</div>
+                    <img class="shugang" :src="require('@/assets/images/icon/shugeng.png')" alt="">
+                    <img :src="require('@/assets/images/search_w.png')" alt="">
+                </div>
+                <div class="search-con" @click="handleShowFile">
+                    <!-- <input  disabled="disabled" @keyup.enter="isShow=true" v-model="key" placeholder="搜索文物" type="text"> -->
+                    <div>史料收件箱</div>
+                    <img class="shugang" :src="require('@/assets/images/icon/shugeng.png')" alt="">
+                    <img :src="require('@/assets/images/upload_w.png')" alt="">
+                </div>
             </div>
         </div>
 
         <!-- 文物搜索 -->
         <collection :seachKey="key" class="collect" :style="{opacity:!isFade?0:1}" v-if="isShow"/>
+
+        <uploadflie class="collect" :fileCode='fileCode' v-if="isShowFile"/>
     </div>
 
+    <longvideosvg v-if="showLoingVideo"/>
 
     <!-- 新菜单 -->
     <div class="n-menu" v-show="showMenu">
@@ -83,6 +95,7 @@
             <v-guide v-show="showPull"/>
         </transition>
     </div>
+    <welcome v-if="showWelcome"/>
   </div>
 </template>
 
@@ -104,26 +117,33 @@ import mapsvg from '@/components/mapsvg.vue';
 
 import vGuide from '@/views/gui/newguide';
 import collection from '@/views/collection'
+import uploadflie from '@/views/uploadflie'
+
+import longvideosvg from '@/components/longvideo';
+import welcome from '@/components/welcome';
 
 
 export default {
   name: 'Home',
   components: {
-      hot,
-      popup,
-      guiLoading,
-      hotspotList,
-      vTitle,
-      vMenu,
-      webVr,
-      guimsg,
-      vError,
-      vrCon,
-      vOther,
-      collection,
+    hot,
+    popup,
+    guiLoading,
+    hotspotList,
+    vTitle,
+    vMenu,
+    webVr,
+    guimsg,
+    vError,
+    vrCon,
+    vOther,
+    collection,
+    uploadflie,
     "m-svg":svg,
     vGuide,
-    mapsvg
+    mapsvg,
+    longvideosvg,
+    welcome
   },
 
   mounted(){
@@ -147,22 +167,72 @@ export default {
           this.isShow = data
         }
     })
+
+
+    this.$bus.$on('toggleWelcome',data=>{
+        if (typeof data == Object) {
+          this.showWelcome = data.toggle
+        }
+        else{
+          this.showWelcome = data
+        }
+    })
+    
+    this.$bus.$on('toggleLongVideo',data=>{
+        if (typeof data == Object) {
+          this.showLoingVideo = data.toggle
+        }
+        else{
+          this.showLoingVideo = data
+        }
+    })
+    
+
+    this.$bus.$on('toggleUploadFile',data=>{
+        if (typeof data == Object) {
+          this.isShowFile = data.toggle
+        }
+        else{
+          this.isShowFile = data
+        }
+        this.fileCode = ''
+    })
     window.addEventListener('loadfinish',  ()=> {
         this.showMenu = true
+        window.player.on("loadLongVideo", ()=> {
+            this.showLoingVideo = true
+        })
     })
+
+    
   },
   methods:{
       openMap(){
           this.$showMap({})
+      },
+      async handleShowFile(){
+        let result = await this.$http({
+            method: 'get',
+            url: '/api/web/material/getCode'
+        })
+        if (result.code != 0) {
+            return alert('获取展区列表失败')
+        }
+        this.isShowFile = true
+        this.fileCode = result.data
       }
   },
   data(){
       return {
-          key:'',
-          showPull:true,
-          showMenu:false,
-          isShow:false,
-          isFade:true
+        key:'',
+        showPull:true,
+        showMenu:false,
+        isShow:false,
+        isShowFile:false,
+        isFade:true,
+        showWelcome:true,
+        showLoingVideo: false,
+        fileCode:''
       }
   }
 }
@@ -213,37 +283,43 @@ export default {
             pointer-events: none!important;
         }
     }
-    .search-con{
-        padding: 10px;
-        background: rgba(0, 0, 0, 0.6);
-        position: relative;
-        text-align: center;
+    .rbtn{
         display: flex;
-        align-items: center;
         justify-content: space-between;
-        border-radius: 6px;
-        margin-top: 10px;
-        >input{
-            background:none;  
-            outline:none;  
-            border:none;
+        align-items: center;
+        .search-con{
+            width: 48%;
+            padding: 2px 10px;
+            background: rgba(0, 0, 0, 0.6);
+            position: relative;
             text-align: center;
-            width: calc(100% - 20px);
-            &::placeholder{
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            border-radius: 14px;
+            margin-top: 10px;
+            cursor: pointer;
+            font-size: 0;
+            border: 1px solid #85101C;
+            >div{
+                text-align: center;
+                width: calc(100% - 34px);
                 color: rgba(255, 255, 255, 0.55);
+                font-size: 12px;
+            }
+            .shugang{
+                width: 1px;
+                height: 100%;
+                cursor: auto;
+            }
+            >img{
+                width: 14px;
+                margin: 0 4px;
+                cursor: pointer;
             }
-        }
-        .shugang{
-          width: 1px;
-          height: 100%;
-          cursor: auto;
-        }
-        >img{
-            width: 20px;
-            margin-left: 10px;
-            cursor: pointer;
         }
     }
+
 }
 
 .collect{
@@ -253,5 +329,6 @@ export default {
     left: 0;
     width: 100%;
     height: 100%;
+    background: rgba(0, 0, 0, 0.6);
 }
 </style>

+ 154 - 0
web/src/utils/file.js

@@ -0,0 +1,154 @@
+// 媒体名称
+export const mediaTypes = {
+    "image": '图片',
+    "video": "视频",
+    "audio": "音频"
+}
+
+// 媒体扩展类型
+export const mediaMimes = {
+    "application":['x-tar','x-compressed','x-zip-compressed','zip','tar'], //压缩包
+    "image": ["jpg", "png", "jpeg", "bmp", "gif"],
+    "audio": ["mp3", "aac", "ogg", "wav" /* , "m4a" */],
+    "video": ["mp4", "mov", "quicktime" /* ,"webm", "rmvb", "wmv" */] //ios:mov
+}
+
+// 媒体大小显示(MB)
+export const mediaMaxSize = {
+    "image": 10,
+    "video": 20,
+    "audio": 5
+}
+
+/**
+ * 获取媒体扩展类型
+ * @param {Stirng} filename 文件名称
+ */
+export const getMime = filename => {
+    if (!filename || filename.indexOf('.') === -1) {
+        return ''
+    }
+
+    return filename.split('.').pop().toLowerCase()
+}
+
+/**
+ * 在路径中获取文件名
+ * @param {*} path 
+ */
+export const getFilename = path => {
+    const segment = (path || '').split('/')
+    return segment[segment.length - 1]
+}
+
+
+
+/**
+ * 检测媒体文件是否超过预设限制
+ * @param {String} type 媒体类型
+ * @param {Number} size 文件大小
+ */
+export const checkSizeLimit = (type, size) => {
+
+    size = size / 1024 / 1024
+
+    return size <= mediaMaxSize[type]
+}
+
+export const checkSizeLimitFree = (size, limit) => {
+
+    size = size / 1024 / 1024
+
+    return size <= limit
+}
+
+/**
+ * 检测媒体类型
+ * @param {String} type 媒体类型
+ * @param {String} filename 文件名称
+ */
+export const checkMediaMime = (type, filename) => {
+    let mime = getMime(filename)
+    const find = mediaMimes[type]
+    if (!find) {
+        return false
+    }
+    return find.indexOf(mime) !== -1
+}
+
+export const base64ToBlob = base64 => {
+    let arr = base64.split(','),
+        mime = arr[0].match(/:(.*?);/)[1],
+        bstr = atob(arr[1]),
+        n = bstr.length,
+        u8arr = new Uint8Array(n);
+    while (n--) {
+        u8arr[n] = bstr.charCodeAt(n);
+    }
+    return new Blob([u8arr], { type: mime });
+}
+
+export const base64ToDataURL = base64 => {
+    return window.URL.createObjectURL(base64ToBlob(base64));
+}
+
+export const blobToBase64 = function (blob) {
+    return new Promise(resolve => {
+        var reader = new FileReader();
+        reader.onload = function () {
+            resolve(reader.result);
+        };
+        reader.readAsDataURL(blob);
+    })
+};
+
+/**
+ * 获取图片文件尺寸
+ * @param {*} file 
+ */
+export const getImgWH = (data) => {
+    let file = data.file
+
+    return new Promise((resolve) => {
+        var reader = new FileReader();
+        //读取图片文件
+        reader.readAsDataURL(file);
+        reader.onload = function (e) {
+            //初始化JavaScript图片对象
+            var image = new Image();
+            //FileReader获得Base64字符串
+            image.src = e.target.result;
+            image.onload = function () {
+                //获得图片高宽
+                var height = this.height;
+                var width = this.width;
+                resolve({
+                    WH: {
+                        height,
+                        width
+                    },
+                    list:data.list,
+                    file
+                })
+            };
+        }
+    })
+
+
+}
+
+
+/**
+ * 转化字节单位
+ * @param {*} file 
+ */
+export const changeByteUnit = (x) => {
+    const units = ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+    let l = 0, n = parseInt(x, 10) || 0;
+
+    while (n >= 1024 && ++l) {
+        n = n / 1024;
+    }
+    return (n.toFixed(n < 10 && l > 0 ? 2 : 0) + units[l]);
+
+}

+ 1 - 1
web/src/utils/http.js

@@ -4,7 +4,7 @@ import axios from 'axios'
 var isProduction = process.env.NODE_ENV === 'production'
 // 配置请求域名
 
-const serverName = isProduction ? '' : 'http://8.135.106.227:8009'
+const serverName = isProduction ? '' : 'http://8.135.106.227:8009/'
 
 const serverLocation = isProduction ? '' : 'http://8.135.106.227:8009/'
 

+ 92 - 0
web/src/utils/request.js

@@ -0,0 +1,92 @@
+export const http = {
+  __request(xhr, method, url, data, done, fail) {
+    if (typeof done != "function") {
+      done = noop;
+    }
+    if (typeof fail != "function") {
+      fail = noop;
+    }
+
+    xhr.done((result) => {
+      done(result);
+    });
+
+    xhr.fail(fail);
+
+    xhr.always(() => (xhr = null));
+
+    return xhr;
+  },
+
+  /**
+   * Post 表单 支持文件上传
+   * @param {String} url 请求地址
+   * @param {FormData?} formData 请求参数
+   * @param {Function?} done 成功回调
+   * @param {Function?} fail 失败回调
+   */
+  postForm(url, formData, done, fail, onProgress) {
+    if (typeof onProgress === "function") {
+      return this.__request(
+        $.ajax({
+          type: "POST",
+          url: url,
+          processData: false,
+          contentType: false,
+          data: formData,
+          xhr: function() {
+            const xhr = new XMLHttpRequest();
+            xhr.upload.addEventListener("progress", function(e) {
+              onProgress((e.loaded / e.total) * 100 + "%");
+            });
+            return xhr;
+          },
+        }),
+        "postForm",
+        url,
+        formData,
+        done,
+        fail
+      );
+    } else {
+      return this.__request(
+        $.ajax({
+          type: "POST",
+          url: url,
+          processData: false,
+          contentType: false,
+          data: formData,
+        }),
+        "postForm",
+        url,
+        formData,
+        done,
+        fail
+      );
+    }
+  },
+
+  /**
+   * 上传文件
+   * @param {String} url 请求地址
+   * @param {Object?} data 请求参数
+   * @param {Function?} done 成功回调
+   * @param {Function?} fail 失败回调
+   */
+  uploadFile(url, data = {}, done, fail, onProgress) {
+    const form = new FormData();
+    // if (file.needTransfer) { //ie和苹果都不支持dataURLtoFile得传送,所以只能用blob
+    //     form.append("file", common.dataURLtoBlob(file.file), file.name || file.file.name);
+    // } else {
+    //     form.append("file", file.file, file.name || file.file.name);
+    // }
+    for (let key in data) {
+      if (key == "file") {
+        form.append("file", data[key], data.filename || data[key].name);
+      } else if (key != "filename") {
+        form.append(key, data[key]);
+      }
+    }
+    return this.postForm(url, form, done, fail, onProgress);
+  },
+};

+ 1 - 0
web/src/views/collection/pc.vue

@@ -234,6 +234,7 @@ export default {
     width: 100%;
     margin-top: 30px;
     max-height: 57vh;
+    height: 57vh;
     overflow-y: auto;
   }
   .paging{

+ 40 - 1
web/src/views/gui/newguide.vue

@@ -15,6 +15,7 @@
         >
           <div :class="{'slActive':guideActive === i,hoverCls:hoverIdx===i}">
             <img @click="gotoLight(item)" @mouseleave="hoverOutHandle(item,i)" @mouseenter="hoverHandle(item,i)" :src="item.thumbnail_signed_src" :alt="item.name" />
+            <span :title="item.name">{{item.name}}</span>
           </div>
         </swiper-slide>
       </swiper>
@@ -110,6 +111,7 @@ export default {
       guide: {
         list: [],
       },
+      inter:null,
       hoverIdx:'',
       guideActive:'',
       swiperOptions: {
@@ -125,6 +127,16 @@ export default {
     }
   },
   methods:{
+    clearIer(){
+      clearInterval(this.inter)
+      this.inter = null
+    },
+    setInter(){
+      this.clearIer()
+      this.inter=setInterval(() => {
+        this.swiper.slideNext()
+      }, 6000);
+    },
     slide(type){
       this.swiper[type]()
     },
@@ -227,13 +239,40 @@ export default {
             width: 100%;
             height: 100%;
           }
+          >span{
+            display: inline-block;
+            background-color: rgba(0, 0, 0, .7);
+            width: 100%;
+            position: absolute;
+            bottom: 0;
+            left: 0;
+            height: 30px;
+            padding: 0 4px;
+            font-size: 14px;
+            color: #fff;
+            text-align: center;
+            line-height: 30px;
+            white-space: nowrap;
+            text-overflow: ellipsis;
+            overflow: hidden;
+            word-break: break-all;
+          }
         }
         .slActive{
           border: 2px solid #fcd67b;
+          >span{
+            width: calc(100% - 4px);
+            margin-left: 2px;
+            margin-bottom: 2px;
+          }
         }
         .hoverCls{
           border: 2px solid #fff;
-          
+          >span{
+            width: calc(100% - 4px);
+            margin-left: 2px;
+            margin-bottom: 2px;
+          }
         }
       }
       

+ 392 - 0
web/src/views/uploadflie/index.vue

@@ -0,0 +1,392 @@
+<template>
+  <div>
+    <div class="collection" v-if="fileCode">
+      <img class="bg" :src="require('@/assets/images/collect_bg.png')">
+      <img class="close" @click="$bus.$emit('toggleUploadFile',false)" :src="require('@/assets/images/icon/close.png')">
+      <div class="con">
+        <div class="title">史料收件箱</div>
+        <div class="con-body">
+          <p>欢迎使用史料收件箱,您可在此分享史料信息,传递知识!感谢您对信息工程大学的支持!</p>
+          <div class="line"></div>
+          <div class="item">
+            <span>*史料说明</span>
+            <textarea maxlength="200" v-model="desc" placeholder="不超过200个字" cols="30" rows="5"></textarea>
+          </div>
+          <div class="line"></div>
+          <div class="item">
+            <span>上传史料</span>
+            <span class="desc">支持上传图片 /视频 /压缩包,上传文件数量不超过5个</span>
+          </div>
+          <div class="item uploaditem">
+            <span>上传内容</span>
+            <ul>
+              <li class="plus" @click="$refs.uploadFile.click()">
+                <img :src="require('@/assets/images/uploadplus.png')" alt="">
+                <upload
+                  ref="uploadFile"
+                  :limit="200"
+                  :mediaType="['application','image','video']"
+                  @file-change="onFileChange"
+                ></upload>
+              </li>
+
+              <li v-for="(item,i) in fileList" :key="i">
+                <img v-if="item.type=='application'" :src="require('@/assets/images/uploadfile/zip.png')" alt="">
+                <img v-else-if="item.type=='video'" :src="require('@/assets/images/uploadfile/video.png')" alt="">
+
+                <div v-else class="img">
+                  <img :src="item.img" alt="">
+                </div>
+
+                <div class="close" @click="del(item,i)">
+                  <img :src="require('@/assets/images/uploadfile/close.png')" alt="">
+                </div>
+                <span :title="item.name">{{item.name}}</span>
+              </li>
+            </ul>
+          </div>
+          <div class="line"></div>
+          <div class="item">
+            <span>联系方式</span>
+            <textarea v-model="contact" maxlength="50" placeholder="不超过50个字" cols="30" rows="2"></textarea>
+          </div>
+        </div>
+        <div class="submit">
+          <span @click="save">提交</span>
+        </div>
+      </div>
+    </div>
+
+    <div class="showloading" v-if="progress&&progress!='100%'">
+      <div class="loadingcon">
+        <div class="line">
+          <div class="progress" :style="{width:progress}"></div>
+        </div>
+        <span>文件上传中</span>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Upload from "@/components/uploader";
+import { http } from '@/utils/request'
+
+let TYPE = {
+
+}
+
+export default {
+  data(){
+    return {
+      hasLoad:false,
+      fileList:[],
+      progress:0,
+      desc:'',
+      contact:''
+    }
+  },
+  props:{
+    fileCode:String
+  },
+  components:{
+    Upload
+  },
+  computed:{
+    
+  },
+  watch:{
+    
+  },
+  methods:{
+    async save(){
+      if (!this.desc) {
+        return alert('请填写史料说明')
+      }
+      let params = {
+          "code": this.fileCode,
+          "description": this.desc,
+          "phone": this.contact
+      }
+
+      let result = await this.$http({
+        method: 'post',
+        data: params,
+        url: '/api/web/material/save'
+      })
+
+      if (result.code === 0) {
+        alert('提交成功')
+        this.$bus.$emit('toggleUploadFile',false)
+      }
+    },
+    async del(item,i){
+      let result = await this.$http({
+        method: 'post',
+        data: {path:item.path},
+        url: '/api/web/material/delete'
+      })
+      if (!result.code === 0) {
+        alert('删除失败,请稍后再试')
+        this.$bus.$emit('toggleUploadFile',false)
+      }
+      this.fileList.splice(i,1);
+
+// /api/web/material/delete
+    },
+    onFileChange(data) {
+      if (this.fileList.length>4) {
+        return alert('上传文件数量不超过5个')
+      }
+      
+      console.log(data);
+      let tmp = {
+        id:'_' + this.$randomWord(false,8,8),
+        file:data.files[0],
+        type:data.files[0].type.split('/')[0],
+        name:data.files[0].name,
+        img:window.URL.createObjectURL(data.files[0])
+      }
+      
+
+      http.uploadFile(`${this.$serverName}/api/web/material/upload/${this.fileCode}`, tmp, (res)=>{
+        tmp.path = res.data.path
+        this.fileList.push(tmp)
+        console.log(this.fileList,res);
+      }, err=>{
+        console.log(err);
+      },progress=>{
+        this.progress = progress
+      })
+
+    }
+    
+  },
+  mounted(){
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.collection{
+  margin: 0 auto;
+  width: 80%;
+  transform: translate(-50%,-50%);
+  top: 50%;
+  left: 50%;
+  min-height: 87vh;
+  padding: 0;
+  position: fixed;
+  .bg{
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: -1;
+  }
+  .close{
+    position: absolute;
+    bottom: 50px;
+    right: 50px;
+    width: 20px;
+    cursor: pointer;
+    z-index: 9999;
+  }
+ 
+  .con{
+    width: 100%;
+    margin-top: 45px;
+    overflow-y: auto;
+    .title{
+      text-align: center;
+      width: 100%;
+      text-shadow: 0px 3px 6px rgba(0, 0, 0, 0.59);
+      font-size: 18px;
+      font-weight: bold;
+      margin: 0 auto;
+      color: #FCD67B;
+      letter-spacing: 2px;
+    }
+    .con-body{
+      font-size: 16px;
+      letter-spacing: 1px;
+      width: 80%;
+      max-width: 900px;
+      margin: 44px auto 0;
+
+      .line{
+        width: 100%;
+        height: 1px;
+        background: #FFFFFF;
+        opacity: 0.3;
+        margin: 16px 0;
+      }
+
+      .item{
+        display: flex;
+        >span{
+          min-width: 100px;
+          display: inline-block;
+          margin-top: 20px;
+        }
+        >textarea{
+          width: 100%;
+          background: rgba(255, 255, 255, 0.8);
+          color: #000000;
+          padding: 10px 16px;
+          line-height: 1.5;
+          border-radius: 4px;
+          letter-spacing: 1px;
+        }
+        .desc{
+          font-size: 14px;
+          color: rgba(255, 255, 255, 0.59);
+        }
+      }
+
+      .uploaditem{
+        align-items: center;
+        margin-top: 60px;
+        margin-bottom: 40px;
+        >span{
+          margin-top: 0;
+        }
+        >ul{
+          display: flex;
+          >li{
+            background: rgba(255, 255, 255, 0.8);
+            width: 86px;
+            height: 80px;
+            position: relative;
+            border-radius: 4px;
+            margin-right: 15px;
+            >img{
+              width: 30px;
+              position: absolute;
+              top: 50%;
+              left: 50%;
+              transform: translate(-50%,-50%);
+            }
+            >span{
+              position: absolute;
+              width: 100%;
+              bottom: -25px;
+              left: 0;
+              text-align: center;
+              display: inline-block;
+              font-size: 14px;
+               white-space: nowrap;
+              text-overflow: ellipsis;
+              overflow: hidden;
+              word-break: break-all;
+            }
+            .img{
+              width: 100%;
+              height: 100%;
+              position: absolute;
+              top: 0;
+              left: 0;
+              img{
+                width: 100%;
+                height: 100%;
+              }
+            }
+            .close{
+              display: none;
+              position: absolute;
+              left: 0;
+              top: 0;
+              width: 100%;
+              height: 100%;
+              background: rgba(0, 0, 0, 0.6);
+              cursor: auto;
+              >img{
+                position: absolute;
+                top: 50%;
+                left: 50%;
+                transform: translate(-50%,-50%);
+                cursor: pointer;
+                width: 40px;
+              }
+            }
+            &:hover{
+              .close{
+                display: block;
+              }
+            }
+          }
+          .plus{
+            cursor: pointer;
+            >img{
+              width: 20px;
+              position: absolute;
+            }
+          }
+        }
+      }
+    }
+    .submit{
+      font-size: 18px;
+      font-weight: bold;
+      line-height: 20px;
+      color: #FFFFFF;
+      width: 100%;
+      text-align: center;
+      margin-top: 40px;
+      >span{
+        background: #A01C26;
+        margin: 0 auto;
+        display: inline-block;
+        line-height: 47px;
+        padding: 0 70px;
+        height: 47px;
+        border-radius: 46px;
+        cursor: pointer;
+      }
+    }
+  }
+  
+}
+
+.showloading{
+  position: fixed;
+  width: 100%;
+  height: 100%;
+  background: rgba(0, 0, 0, 0.6);
+  top: 0;
+  left: 0;
+  .loadingcon{
+    width: 47%;
+    height: 182px;
+    background: #FFFFFF;
+    border: 1px solid #707070;
+    border-radius: 4px;
+    position: absolute;
+    top: 50%;
+    transform: translate(-50%,-50%);
+    left: 50%;
+    .line{
+      width: 80%;
+      height: 25px;
+      background: #DCDCDC;
+      margin: 60px auto 0;
+      border-radius: 4px;
+      overflow: hidden;
+      .progress{
+        width: 100%;
+        height: 100%;
+        background: #A01C26;
+      }
+    }
+    >span{
+      color: #000;
+      display: inline-block;
+      width: 100%;
+      text-align: center;
+      margin-top: 14px;
+    }
+  }
+}
+
+</style>