Kaynağa Gözat

文物列表页

任一存 2 yıl önce
işleme
2b4881b75a

+ 4 - 0
.browserslistrc

@@ -0,0 +1,4 @@
+> 1%
+last 2 versions
+not dead
+not ie 11

+ 0 - 0
.env


+ 3 - 0
.env.dev

@@ -0,0 +1,3 @@
+CLI_MODE=dev
+NODE_ENV=development
+PUBLIC_PATH=./

+ 3 - 0
.env.prod

@@ -0,0 +1,3 @@
+CLI_MODE=test
+NODE_ENV=production
+PUBLIC_PATH=./

+ 2 - 0
.env.test

@@ -0,0 +1,2 @@
+NODE_ENV=production
+PUBLIC_PATH=./

+ 3 - 0
.eslintignore

@@ -0,0 +1,3 @@
+*/libs
+/node_modules
+/.vscode

+ 55 - 0
.eslintrc.js

@@ -0,0 +1,55 @@
+module.exports = {
+  root: true,
+  env: {
+    browser: true,
+    commonjs: true,
+    es6: true,
+    jest: true,
+    jquery: true,
+    node: true,
+  },
+  'extends': [
+    'plugin:vue/vue3-recommended',
+    'eslint:recommended'
+  ],
+  parserOptions: {
+    parser: '@babel/eslint-parser'
+  },
+  rules: {
+    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
+    'semi': ['error', 'never'],
+    "no-unused-vars": ["warn", {
+      "vars": "all",
+      "args": "after-used",
+      "ignoreRestSiblings": false
+    }],
+    "keyword-spacing": ["error", { "before": true, "after": true }],
+    "object-curly-spacing": ["error", "always"],
+    "space-infix-ops": ["error"],
+    'key-spacing': ["error", {
+      "mode": "strict"
+    }],
+    "comma-spacing": ["error", { "before": false, "after": true }],
+    "func-call-spacing": ["error", "never"],
+    "semi-spacing": ["error", { "before": false, "after": true }],
+    "space-before-blocks": ["error", "always"],
+    'no-trailing-spaces': 'error',
+    'no-multi-spaces': 'error',
+    "indent": ["error", 2],
+    'no-empty': 'off',
+    // 默认不启用:为了避免细微的 bug,最好直接从 Object.prototype 调用挂载于prototype上的方法方法。例如,foo.hasOwnProperty("bar") 应该替换为 Object.prototype.hasOwnProperty.call(foo, "bar")。
+    'no-prototype-builtins': "off",
+  },
+  globals: {
+    api: true,
+    config: true,
+    mapState: true,
+    mapGetters: true,
+    mapMutations: true,
+    store: true,
+    utils: true,
+    gConfigInfo: true,
+    gConfigTxt: true,
+  }
+}

+ 24 - 0
.gitignore

@@ -0,0 +1,24 @@
+.DS_Store
+node_modules
+/dist
+
+*.zip
+
+# 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?

+ 4 - 0
README.md

@@ -0,0 +1,4 @@
+## 部署测试环境
+文件存放位置:
+
+访问url:

+ 9 - 0
babel.config.js

@@ -0,0 +1,9 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset',
+  ],
+  // plugins: [
+  //   "transform-object-rest-spread",
+  //   "@babel/plugin-proposal-optional-chaining",
+  // ],
+}

+ 20 - 0
jsconfig.json

@@ -0,0 +1,20 @@
+{
+  "compilerOptions": {
+    "target": "es5",
+    "module": "esnext",
+    "baseUrl": "./",
+    "moduleResolution": "node",
+    "paths": {
+      "@/*": [
+        "src/*"
+      ]
+    },
+    "lib": [
+      "esnext",
+      "dom",
+      "dom.iterable",
+      "scripthost"
+    ]
+  },
+  "exclude": ["libs", "node_modules"]
+}

+ 34 - 0
package.json

@@ -0,0 +1,34 @@
+{
+  "name": "my-app",
+  "version": "0.0.1",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve --mode dev",
+    "build-test": "vue-cli-service build --mode test",
+    "build-prod": "vue-cli-service build --mode prod",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "axios": "^1.1.3",
+    "core-js": "^3.8.3",
+    "dayjs": "^1.11.7",
+    "element-plus": "^2.3.5",
+    "mitt": "^3.0.0",
+    "vue": "^3.2.13",
+    "vue-router": "^4.0.3",
+    "vuex": "^4.0.0"
+  },
+  "devDependencies": {
+    "@babel/core": "^7.12.16",
+    "@babel/eslint-parser": "^7.12.16",
+    "@vue/cli-plugin-babel": "~5.0.0",
+    "@vue/cli-plugin-eslint": "~5.0.0",
+    "@vue/cli-plugin-router": "~5.0.0",
+    "@vue/cli-plugin-vuex": "~5.0.0",
+    "@vue/cli-service": "~5.0.0",
+    "eslint": "^7.32.0",
+    "eslint-plugin-vue": "^8.0.3",
+    "less": "^4.0.0",
+    "less-loader": "^8.0.0"
+  }
+}

+ 29 - 0
public/index.html

@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+    <link rel="icon" href="<%= BASE_URL %>logo.png">
+    <title></title>
+  </head>
+  <body>
+    <!-- <script src="https://cdn.bootcss.com/vConsole/3.2.0/vconsole.min.js"></script>
+    <script>
+      new VConsole()
+    </script> -->
+    
+    <script src="./user-config/info.js"></script>
+    <script src="./user-config/txt.js"></script>
+    
+    <script>
+      document.title = gConfigInfo.title
+    </script>
+    
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

BIN
public/logo.png


BIN
public/user-config/4dage/cs01.4dage


BIN
public/user-config/4dage/cs02.4dage


BIN
public/user-config/images/cs01.jpg


BIN
public/user-config/images/cs02.jpg


+ 153 - 0
public/user-config/info.js

@@ -0,0 +1,153 @@
+// **注意不要手打任何符号,请全部使用 复制 粘贴,以免格式错误,程序无法运行!**
+//(所有标点符号都不要删除,你只需要修改文字和编号)
+
+var gConfigInfo = {
+  // 定义网址的 标题
+  title: '常熟博物馆',
+
+  // 是否开启模型自动旋转功能  开启:true  关闭:false
+  spinInfo: false,
+
+  //配置  模型文件名字
+  // 左边的是编号
+  // 右边的是 模型名称
+  // 这里举一个模型例子(这里的书写顺序就是网址的排列顺序)
+  // (所有标点符号都不要删除,你只需要修改文字和编号,添加的时候复制粘贴即可)
+
+  // 复制模板    '':``,
+
+  objInfo: {
+    'cs01': `北宋 “淳化元宝”背刻佛像金币`,
+    'cs02': `宋 石雕高僧禅定造像`,
+    'cs03': `新石器时代 良渚文化有段石锛`,
+    'cs04': `清 黄杨木雕苦行僧罗汉像`,
+    'cs05': `清 张希黄留青刻竹臂搁`,
+    'cs06': `清 “乾隆乙丑年造,仙传杜士元”款橄榄核舟`,
+    'cs08': `清 象牙雕西游记人物鸟食缸`,
+    'cs09': `清 孙原湘铭蕉叶纹端砚`,
+    'cs10': `太平天国 “苏福省水师主将楫天义正典乐”木印`,
+    'cs11': `元 剔犀如意云纹漆盒`,
+    'cs12': `西晋 青釉猪圈`,
+    'cs13': `西晋 青釉菱形纹三丁罐`,
+    'cs14': `西晋 青釉提梁香熏`,
+    'cs15': `明 德化窑瓷观音像`,
+    'cs16': `明永乐 甜白釉暗刻缠枝花卉纹墩式碗`,
+    'cs17': `明永乐 青花一束莲纹盘`,
+    'cs18': `明正德 青花缠枝茶花纹宫碗`,
+    'cs19': `明正德 “大明正德年制”款青花阿拉伯纹折枝莲瓶`,
+    'cs20': `清 御题“碧峰馆”诗山子`,
+    'cs21': `清 翠雕七弦琴`,
+    'cs22': `清顺治 酱色釉暗刻云龙纹盘`,
+    'cs23': `清康熙 “大清康熙年制”款青花饮中八仙图八角碗`,
+    'cs24': `清康熙 淡描青花人物笔海`,
+    'cs25': `清雍正 “大清雍正年制”款斗彩云龙纹杯`,
+    'cs26': `清雍正 “大清雍正年制”款珐琅彩过枝月季花纹盘`,
+    'cs27': `清乾隆 “竹庵氏制”款绞胎云龙纹砚`,
+    'cs28': `元 白玉子母龙琵琶形带钩`,
+    'cs29': `清 白玉雕子母龙带钩`,
+    'cs30': `清乾隆 珐琅彩过枝芙蓉花纹盘`,
+    'cs31': `清道光 “陈国治作”款蓝釉雕瓷柳下双马象耳瓶`,
+    'cs32': `清道光 “陈国治作”款蓝釉雕瓷柳下双马象耳瓶 `,
+    'cs33': `明 黄道周小楷《赵用贤文集序》卷`,
+    'cs34': `清 唐俊溪山归牧图卷`,
+    'cs35': `清 杨晋四季花卉图卷`,
+    'cs36': `明 邹元标小楷《赵用贤传》卷`,
+    'cs37': `唐 “左鹰扬卫温阳府之印”铜官印`,
+    'cs38': `清 白玉雕子冈款“马上封侯”搬指`,
+    'cs39': `明 白玉雕子冈款“二乔观书”牌`,
+    'cs40': `清 玻璃翠雕鹊梅牌`,
+    'cs41': `明 白玉透雕花鸟纹圆饰件一对`,
+    'cs42': `清 王翚芳洲图轴`,
+    'cs43': `宋 “刘三郎铺己酉”铭文金臂钏`,
+    'cs44': `明 白玉镶金如意发簪`,
+    'cs45': `明 梵文花蕊嵌宝金饰件`,
+    'cs46': `新石器时代 良渚文化玉琮`,
+    'cs47': `新石器时代 良渚文化玉璧`,
+    'cs48': `新石器时代 良渚文化玉双龙连体环形佩`,
+    'cs49': `五代 越窑系青釉葵口盏、托`,
+    'cs50': `清 林鹤田两面刻“闲多反笑野云忙、身似野僧犹有发”石章`,
+    'cs2-01': `清乾隆 粉彩八仙纹方酒斗`,
+    'cs2-02': `元 玉溪窑青花人物纹玉壶春瓶`,
+    'cs2-03': `清光绪 秋葵绿釉仿周亚敦`,
+    'cs2-04': `清光绪 黄釉仿太公作宝簠`,
+    'cs2-05': `明 碧玉冠饰`,
+    'cs2-06': `清 青玉痕都斯坦玉刀柄`,
+    'cs2-07': `清 象牙雕荷叶形摆件`,
+    'cs2-08': `明 金镶银金蜂采蜜发簪`,
+    'cs2-10': `西晋 青釉狗圈`,
+    'cs2-11': `五代 越窑青釉瓜楞执壶`,
+    'cs2-12': `宋 越窑刻花鸳鸯戏荷纹盒`,
+    'cs2-13': `宋 越窑划花盏托`,
+    'cs2-14': `明万历 青花锦鸡牡丹纹六角形罐`,
+    'cs2-15': `明万历 青花双龙戏珠纹铺首双耳炉`,
+    'cs2-16': `明万历 五彩双龙戏珠纹扇盒`,
+    'cs2-17': `清雍正 青花缠枝莲纹石榴尊`,
+    'cs2-18': `清雍正 淡描青花百子图印盒`,
+    'cs2-19': `清雍正 淡描青花陶渊明爱菊图茶杯`,
+    'cs2-20': `清雍正仿成化款 斗彩灵芝花纹盘`,
+    'cs2-21': `清乾隆 斗彩团花撇口碗`,
+    'cs2-22': `清乾隆 青花釉里红八仙过海纹盘`,
+    'cs2-23': `清乾隆 斗彩暗八宝纹双腹碗`,
+    'cs2-24': `清乾隆 青花矾红龙生九子纹盘`,
+    'cs2-25': `清咸丰 仿哥釉八卦纹琮式瓶`,
+    'cs2-26': `清咸丰 蓝釉象耳方瓶`,
+    'cs2-27': `清 青花花鸟纹瓶 “王步”款`,
+    'cs2-28': `西晋 青釉鐎斗、鐎炉`,
+    'cs2-29': `西晋 青釉辟邪烛台`,
+    'cs2-30': `明 德化窑回纹暗花三足炉`,
+    'cs2-31': `明 德化窑白釉寿星像`,
+    'cs2-32': `明 蓝釉堆贴鱼藻纹盖罐`,
+    'cs2-33': `正德 青花缠枝莲纹盖罐`,
+    'cs2-34': `清顺治 青花枯树飞鸟纹花觚`,
+    'cs2-35': `清康熙 素三彩马`,
+    'cs2-36': `清康熙 青花松竹梅纹盘`,
+    'cs2-37': `清乾隆 白釉荷塘戏鸭纹雕瓷水盂`,
+    'cs2-39': `清乾隆 墨绿釉堆花象耳长方瓶`,
+    'cs2-40': `宋 钧窑系天青釉钟式碗`,
+    'cs2-41': `清 绿釉雕瓷山水纹三角形笔架`,
+    'cs2-42': `清光绪 黄釉雕瓷山水纹印盒`,
+    'cs2-43': `清光绪 黄釉八骏图雕瓷笔筒`,
+    'cs2-44': `清光绪 白釉山水雕瓷纹帽筒`,
+    'cs2-45': `元 梅花双耳方形金杯`,
+    'cs2-46': `明 赵忠毅公鋄银铁如意`,
+    'cs2-47': `明 青玉乳丁纹匜`,
+    'cs2-48': `明 松树纹白玉笔筒`,
+    'cs2-49': `明 白玉铺首纹碗`,
+    'cs2-50': `汉 青玉豚`,
+    'cs2-51': `民国 “陆氏所作“款乌铜嵌银丝墨盒`,
+    'cs2-52': `民国 “铁琴铜剑楼审定印”田黄石章(赵古泥刻)`,
+    'cs2-53': `北宋 “归远第二指挥第二都朱记”铜官印`,
+    'cs2-54': `清 紫檀雕花笔筒`,
+    'cs2-55': `清 翁伴石刻竹笔筒`,
+    'cs2-56': `明 "黄道周铭"山水诗文木雕笔海`,
+    'cs2-57': `清 象牙雕“乐山”款山水人物笔筒`,
+    'cs2-58': `清 沈石友款雕玉花骢端砚`,
+    'cs2-59': `清 夏翬竹刻山水臂搁`,
+    'cs2-60': `新石器 良渚文化玉璧`,
+    'cs2-61': `新石器 良渚文化玉璧`,
+    'cs2-62': `新石器 良渚文化玉璧`,
+    'cs2-63': `新石器 良渚文化琮形玉管`,
+    'cs2-64': `新石器 良渚文化冠状玉饰`,
+    'cs2-66': `清 “太平天国昭文县后营中师中旅帅”木印`,
+    'cs2-67': `明 云鸟纹金饰`,
+    'cs2-68': `明 如意形镶宝金发簪`,
+    'cs2-69': `明 金镶白玉葫芦耳环`,
+    'cs2-70': `明 金葫芦形耳环`,
+    'cs2-71': `明 金瓜楞形戒指`,
+    'cs2-72': `明 金掩鬓簪`,
+    'cs2-73': `明 金木梳背`,
+    'cs2-74': `明 金镶白玉发簪`,
+    'cs2-75': `元 八思巴文铜官印`,
+    'cs2-76': `清 林鹤田两面刻“身居城市意在山林、佛少风流一种神多堀强三分”石章`,
+    'cs2-79': `宋 漆盏托`,
+    'cs2-80': `元 铜鎛钟`,
+    'cs2-81': `汉 “本始四年款”五铢大陶范`,
+    'cs2-83': `新莽 一刀平五千(嵌金)`,
+    'cs2-84': `秦 “半两”大钱铜母范`,
+    'cs2-85': `宋 建窑黑釉兔毫斗笠碗`,
+    'cs2-86': `明 法华弥勒佛像`,
+    'cs2-87': `新石器 崧泽文化兽首形玉饰`,
+    'cs2-88': `清 “昭文沈氏师米斋金石”石印`,
+    'cs2-89': `清光绪 粉紫釉仿汉元康鋗`,
+  }
+}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 396 - 0
public/user-config/txt.js


+ 86 - 0
src/App.vue

@@ -0,0 +1,86 @@
+<template>
+  <router-view />
+</template>
+
+<script>
+export default {
+  mounted() {
+    this.$mitt.on('test', e => {
+      console.log('test', e)
+    })
+  }
+}
+</script>
+
+<style lang="less">
+html, body {
+  // overscroll-behavior: none;
+  // overflow: hidden;
+  height: 100%;
+}
+
+#app {
+  height: 100%;
+}
+
+// * {
+//   user-select: none;
+//   -webkit-touch-callout: none;
+// }
+
+// // 360浏览器不支持not()
+// input, textarea {
+//   user-select: initial;
+// }
+
+// 字体
+// @font-face {
+//   font-family: 'Source Han Serif CN';
+//   src: url('@/assets/style/SourceHanSerifCN-Regular.otf');
+// }
+// @font-face {
+//   font-family: 'Source Han Serif CN-Bold';
+//   src: url('@/assets/style/SourceHanSerifCN-Bold.otf');
+// }
+// i {
+//   font-style: italic;
+// }
+
+// 滚动条
+// ::-webkit-scrollbar { background: #dddecc; width: 0.3rem; height: 0.3rem; } /*宽度是对垂直滚动条而言,高度是对水平滚动条而言*/
+// ::-webkit-scrollbar-thumb { background: #828a5b; border-radius: 0.15rem; }
+// ::-webkit-scrollbar-corner { background: #dddecc; }
+
+// // vue组件过渡效果
+// .fade-out-leave-active {
+//   transition: opacity 1s;
+// }
+// .fade-out-leave-to {
+//   opacity: 0;
+// }
+
+// // 不断渐变显隐 animation
+// .animation-show-hide {
+//   animation: show-hide 1.8s infinite;
+// }
+// @keyframes show-hide {
+//   0% {
+//     opacity: 0;
+//   }
+//   50% {
+//     opacity: 1;
+//   }
+//   100% {
+//     opacity: 0;
+//   }
+// }
+
+// // vue-viewer
+// .viewer-container {
+//   background-color: rgba(0, 0, 0, 80%) !important;
+// }
+// 或者
+// .viewer-backdrop {
+//   background-color: rgba(0, 0, 0, 90%) !important;
+// }
+</style>

+ 17 - 0
src/api.js

@@ -0,0 +1,17 @@
+// import axios from "axios"
+
+// axios({
+//   method: 'post',
+//   url: `${config.backendDir}visit/saveType`,
+//   headers: {
+//     appId: "CA02F83A5FA162B930AA2F962D202F43B0F6DE0B51AD79FEDB03FA8202BB4909330105B3B347510D87C97060C4288280D4A744E00565A4EC",
+//     "Content-Type": "application/json",
+//   },
+//   data: {
+//     moduleType,
+//     type: 'visit',
+//   },
+// })
+
+export default {
+}

BIN
src/assets/images/back.png


BIN
src/assets/images/bg.jpg


BIN
src/assets/images/bigBac.png


BIN
src/assets/images/close.png


BIN
src/assets/images/divBac.png


BIN
src/assets/images/favicon.ico


BIN
src/assets/images/logo.png


BIN
src/assets/images/play.png


BIN
src/assets/images/titleBac.png


+ 59 - 0
src/assets/style/my-reset.css

@@ -0,0 +1,59 @@
+* {
+  /* 阻止safari在用户交互设置一些元素的背景色 */
+  -webkit-tap-highlight-color: transparent;
+  box-sizing: border-box;
+}
+
+html {
+  overflow: hidden;
+  touch-action: none;
+  scroll-behavior: smooth; /* MDN: When this property is specified on the root element, it applies to the viewport instead. This property specified on the body element will not propagate to the viewport.(???) */
+  height: 100%;
+}
+
+body {
+  text-align: justify;
+  height: 100%;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+a {
+  color: initial;
+  text-decoration: initial;
+  outline: none;
+}
+
+button {
+  padding: 0;
+  cursor: pointer;
+  background-color: initial;
+  border: initial;
+  outline: none;
+  white-space: pre;
+}
+
+img {
+  user-select: none;
+}
+
+menu {
+  list-style-type: initial;
+}
+
+li {
+  display: initial;
+}
+
+input {
+  outline: initial;
+  background: initial;
+  border: initial;
+  border-radius: initial;
+  width: initial;
+  height: initial;
+}
+
+td {
+  vertical-align: inherit;
+}

+ 48 - 0
src/assets/style/reset.css

@@ -0,0 +1,48 @@
+/* http://meyerweb.com/eric/tools/css/reset/ 
+   v2.0 | 20110126
+   License: none (public domain)
+*/
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed, 
+figure, figcaption, footer, header, hgroup, 
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	font-size: 100%;
+	font: inherit;
+	vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure, 
+footer, header, hgroup, menu, nav, section {
+	display: block;
+}
+body {
+	line-height: 1;
+}
+ol, ul {
+	list-style: none;
+}
+blockquote, q {
+	quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+	content: '';
+	content: none;
+}
+table {
+	border-collapse: collapse;
+	border-spacing: 0;
+}

+ 2 - 0
src/config.js

@@ -0,0 +1,2 @@
+export default {
+}

+ 44 - 0
src/directives/v-click-outside.js

@@ -0,0 +1,44 @@
+export default {
+  install(Vue) {
+    Vue.directive('click-outside', {
+      bind(el, binding) {
+        function documentHandler(e) {
+          if (el.contains(e.target)) {
+            return false
+          }
+          if (binding.expression) {
+            binding.value(e)
+          }
+        }
+        el.__vueClickOutside__ = documentHandler
+        if (binding.modifiers.click) {
+          document.addEventListener('click', documentHandler, {
+            capture: binding.modifiers.capture
+          })
+        }
+        if (binding.modifiers.mousedown) {
+          document.addEventListener('mousedown', documentHandler, {
+            capture: binding.modifiers.capture
+          })
+        }
+        if (binding.modifiers.touchstart) {
+          document.addEventListener('touchstart', documentHandler, {
+            capture: binding.modifiers.capture
+          })
+        }
+      },
+      unbind(el, binding) {
+        document.removeEventListener('click', el.__vueClickOutside__, {
+          capture: binding.modifiers.capture
+        })
+        document.removeEventListener('mousedown', el.__vueClickOutside__, {
+          capture: binding.modifiers.capture
+        })
+        document.removeEventListener('tarchstart', el.__vueClickOutside__, {
+          capture: binding.modifiers.capture
+        })
+        delete el.__vueClickOutside__
+      }
+    })
+  }
+}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 4 - 0
src/libs/ua-parser.min.js


+ 78 - 0
src/main.js

@@ -0,0 +1,78 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+import store from './store'
+import "@/assets/style/reset.css"
+import "@/assets/style/my-reset.css"
+import UAParser from "@/libs/ua-parser.min.js"
+import clickOutside from "@/directives/v-click-outside.js"
+import mitt from "mitt"
+import ElementPlus from 'element-plus'
+import 'element-plus/dist/index.css'
+// import 'viewerjs/dist/viewer.css'
+// import VueViewer from 'v-viewer'
+
+console.log(`version: ${process.env.VUE_APP_VERSION}`)
+console.log(`Build time: ${process.env.VUE_APP_UPDATE_TIME}`)
+
+const app = createApp(App)
+
+// 挂载配置信息
+app.config.globalProperties.$config = config
+app.config.globalProperties.$gConfigInfo = gConfigInfo
+app.config.globalProperties.$gConfigTxt = gConfigTxt
+app.config.globalProperties.$env = process.env
+
+// 挂载消息发布订阅中心
+app.config.globalProperties.$mitt = mitt()
+
+// 解析、挂载浏览器信息
+const uaParser = new UAParser()
+const uaInfo = uaParser.getResult()
+console.log(uaInfo)
+app.config.globalProperties.$uaInfo = uaInfo
+if (uaInfo.browser && uaInfo.browser.name === 'WeChat') {
+  app.config.globalProperties.$isWeChat = true
+}
+if (uaInfo.browser && uaInfo.browser.name === 'Safari') {
+  app.config.globalProperties.$isSafari = true
+}
+if (uaInfo.device.type === 'mobile') {
+  app.config.globalProperties.$isMobile = true
+}
+
+// // 处理resize事件
+// let windowWidthLast = window.innerWidth
+// let windowHeightLast = window.innerHeight
+// function onResize() {
+//   windowWidthLast = window.innerWidth
+//   windowHeightLast = window.innerHeight
+// }
+// window.addEventListener('resize', () => {
+//   onResize()
+// })
+
+// // 禁用上下文菜单
+// document.oncontextmenu = function(e) {
+//   e.preventDefault()
+// }
+
+// // safari里只能在交互行为的回调中成功地首次调用audio的play方法,所以需要一个全局的audio元素来播放随时可能需要自发播放的音频。
+// const audioNode = document.createElement("audio")
+// audioNode.id = 'global-audio'
+// audioNode.style.display = 'none'
+// audioNode.loop = true
+// document.body.appendChild(audioNode)
+
+app.use(store)
+  .use(router)
+  .use(clickOutside)
+  .use(ElementPlus)
+  // .use(VueViewer)
+  // .component('HotSpot', HotSpot)
+  .mount('#app')
+
+// 必须在vue根组件挂载之后执行
+if (app.config.globalProperties.$isMobile) {
+  document.getElementById('app').classList.add('mobile')
+}

+ 18 - 0
src/router/index.js

@@ -0,0 +1,18 @@
+import { createRouter, createWebHashHistory } from 'vue-router'
+import HomeView from '../views/Home.vue'
+// import store from '@/store/index.js'
+
+const routes = [
+  {
+    path: '/',
+    name: 'home-view',
+    component: HomeView,
+  },
+]
+
+const router = createRouter({
+  history: createWebHashHistory(),
+  routes
+})
+
+export default router

+ 18 - 0
src/store/index.js

@@ -0,0 +1,18 @@
+import { createStore } from 'vuex'
+
+export default createStore({
+  state: {
+    usingChinese: true,
+  },
+  getters: {
+  },
+  mutations: {
+    setUsingChinese(state, value) {
+      state.usingChinese = value
+    },
+  },
+  actions: {
+  },
+  modules: {
+  }
+})

+ 70 - 0
src/utils.js

@@ -0,0 +1,70 @@
+export default {
+  /**
+   * 返回一个自带消抖效果的函数,用res表示。
+   *
+   * fn: 需要被消抖的函数
+   * delay: 消抖时长
+   * isImmediateCall: 是否在一组操作中的第一次调用时立即执行fn
+   * isRememberLastCall:是否在一组中最后一次调用后等delay时长再执行fn
+   */
+  debounce(fn, delay = 250, isImmediateCall = true, isRememberLastCall = true) {
+    console.assert(isImmediateCall || isRememberLastCall, 'isImmediateCall 和 isRememberLastCall 至少应有一个是true,否则没有意义!')
+    let timer = null
+    // 上次调用的时刻
+    let lastCallTime = 0
+
+    if (isImmediateCall && !isRememberLastCall) {
+      return function (...args) {
+        const currentTime = Date.now()
+        if (currentTime - lastCallTime >= delay) {
+          fn.apply(this, args)
+        }
+        lastCallTime = currentTime
+      }
+    } else if (!isImmediateCall && isRememberLastCall) {
+      return function (...args) {
+        if (timer) {
+          clearTimeout(timer)
+        }
+        timer = setTimeout(() => {
+          fn.apply(this, args)
+        }, delay)
+      }
+    } else if (isImmediateCall && isRememberLastCall) {
+      return function (...args) {
+        const currentTime = Date.now()
+        if (currentTime - lastCallTime >= delay) { // 一组操作中的第一次
+          fn.apply(this, args)
+          lastCallTime = currentTime
+          return
+        } else { // 一组中的后续调用
+          if (timer) { // 在此之前存在中间调用
+            lastCallTime = currentTime
+            clearTimeout(timer)
+          }
+          timer = setTimeout(() => {
+            fn.apply(this, args)
+            lastCallTime = 0
+            timer = null
+          }, delay)
+        }
+      }
+    } else {
+      console.error('不应该执行到这里!')
+    }
+  },
+  throttle(fn, interval = 250) {
+    let lastRunTime = 0
+
+    return function (...args) {
+      let elapsedTime = Date.now() - lastRunTime
+      if (elapsedTime < interval) {
+        return null
+      }
+
+      let context = this
+      lastRunTime = Date.now()
+      return fn.apply(context, args)
+    }
+  },
+}

+ 138 - 0
src/views/Home.vue

@@ -0,0 +1,138 @@
+<template>
+  <div
+    class="home"
+  >
+    <div class="containers">
+      <h1 class="title">
+        {{ $gConfigInfo.title }}
+      </h1>
+
+      <ul>
+        <li
+          v-for="item in Object.entries($gConfigInfo.objInfo).slice(pageSize * (currentPage - 1), pageSize * currentPage)"
+          :key="item[0]"
+        >
+          <img
+            class=""
+            :src="`${$env.BASE_URL}user-config/images/${item[0]}.jpg`"
+            alt=""
+            draggable="false"
+          >
+          <div class="title">
+            {{ item[1] }}
+          </div>
+        </li>
+      </ul>
+
+      <el-pagination
+        v-model:current-page="currentPage"
+        v-model:page-size="pageSize"
+        class="pagination"
+        :page-sizes="[10, 20, 50, 100]"
+        background
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="Object.keys($gConfigInfo.objInfo).length"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'HomeView',
+  data() {
+    return {
+      currentPage: 1,
+      pageSize: 10,
+    }
+  },
+  computed: {
+    ...mapState([
+    ]),
+  },
+  mounted() {
+    console.log(process.env)
+    this.$mitt.emit('test', { msg: 'home mounted' })
+  },
+  unmounted() {
+  },
+  methods: {
+    ...mapMutations([
+    ]),
+  },
+}
+</script>
+
+<style lang="less" scoped>
+.home {
+  width: 100%;
+  height: 100%;
+  .containers {
+    padding-top: 40px;
+    width: 100vw;
+    max-width: 1080px;
+    /* height: 100vh; */
+    background-color: #285b5e;
+    /* overflow: hidden; */
+    height: 100%;
+    margin: 0 auto;
+    padding-bottom: 50px;
+    position: relative;
+    > .title {
+      letter-spacing: 4px;
+      margin: 0 auto;
+      color: #fff;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      width: 270px;
+      height: 50px;
+      background: url('@/assets/images/titleBac.png') no-repeat center;
+      background-size: 100% 100%;
+      margin-bottom: 20px;
+    }
+    > ul {
+      width: 100%;
+      height: calc(100% - 70px);
+      padding-left: 20px;
+      display: flex;
+      flex-wrap: wrap;
+      overflow: auto;
+      > li {
+        display: inline-block;
+        width: calc((100% - 20px * 4) / 3 - 1px);
+        margin-right: 20px;
+        margin-bottom: 20px;
+        > img {
+          width: 100%;
+          padding: 10px;
+          background: url(@/assets/images/divBac.png);
+          background-size: 100% 100%;
+          box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.4);
+          transition: all 0.3s;
+          cursor: pointer;
+          &:hover {
+            transform: translateY(-10px);
+          }
+        }
+        > .title {
+          color: #fff;
+          margin-top: 10px;
+          font-size: 16px;
+          font-weight: 100;
+          text-align: center;
+        }
+      }
+    }
+    .pagination {
+      position: absolute;
+      left: 50%;
+      bottom: 10px;
+      transform: translateX(-50%);
+    }
+  }
+}
+
+@media screen and (max-width: 600px) {
+}
+</style>

+ 37 - 0
vue.config.js

@@ -0,0 +1,37 @@
+const webpack = require('webpack')
+const { defineConfig } = require('@vue/cli-service')
+
+process.env.VUE_APP_VERSION = require('./package.json').version
+
+const dayjs = require('dayjs')
+const time = dayjs().format('YYYY-M-D HH:mm:ss')
+process.env.VUE_APP_UPDATE_TIME = time
+
+module.exports = defineConfig({
+  publicPath: process.env.PUBLIC_PATH,
+  productionSourceMap: process.env.CLI_MODE === 'prod' ? false : true,
+  // transpileDependencies: true, // 默认false,表示babel-loader 会忽略所有 node_modules 中的文件
+  configureWebpack: {
+    module: {
+      rules: [
+        // {
+        //   test: /\.cur$/,
+        //   use: {
+        //     loader: 'file-loader'
+        //   }
+        // }
+      ]
+    },
+    plugins: [
+      new webpack.ProvidePlugin({
+        utils: ['/src/utils.js', 'default'],
+        store: ['/src/store/index.js', 'default'],
+        api: ['/src/api.js', 'default'],
+        config: ['/src/config.js', 'default'],
+        mapState: ['vuex', 'mapState'],
+        mapGetters: ['vuex', 'mapGetters'],
+        mapMutations: ['vuex', 'mapMutations'],
+      }),
+    ],
+  },
+})

Dosya farkı çok büyük olduğundan ihmal edildi
+ 6383 - 0
yarn.lock