chenlei 3 天之前
当前提交
7817b19de3
共有 100 个文件被更改,包括 2092141 次插入0 次删除
  1. 22 0
      .gitignore
  2. 2 0
      .npmrc
  3. 8 0
      .prettierignore
  4. 3 0
      .vscode/extensions.json
  5. 10 0
      .vscode/settings.json
  6. 1 0
      README.md
  7. 16 0
      package.json
  8. 二进制
      packages/base/model/ycq/31-01albedo.jpg
  9. 二进制
      packages/base/model/ycq/31-02albedo.jpg
  10. 二进制
      packages/base/model/ycq/31-03albedo.jpg
  11. 二进制
      packages/base/model/ycq/31-05albedo.jpg
  12. 二进制
      packages/base/model/ycq/31-06albedo.jpg
  13. 42 0
      packages/base/model/ycq/31-yangchunqiao.mtl
  14. 2075313 0
      packages/base/model/ycq/31-yangchunqiao.obj
  15. 14 0
      packages/base/package.json
  16. 22 0
      packages/base/src/index.js
  17. 30 0
      packages/mobile/.gitignore
  18. 13 0
      packages/mobile/index.html
  19. 8 0
      packages/mobile/jsconfig.json
  20. 30 0
      packages/mobile/package.json
  21. 22 0
      packages/mobile/postcss.config.js
  22. 6515 0
      packages/mobile/public/4dage.js
  23. 二进制
      packages/mobile/public/img/bg.jpg
  24. 51 0
      packages/mobile/public/model.html
  25. 16 0
      packages/mobile/src/App.vue
  26. 二进制
      packages/mobile/src/assets/fonts/SOURCEHANSERIFCN-BOLD.OTF
  27. 二进制
      packages/mobile/src/assets/fonts/SOURCEHANSERIFCN-REGULAR.OTF
  28. 二进制
      packages/mobile/src/assets/images/1.png
  29. 二进制
      packages/mobile/src/assets/images/2.png
  30. 二进制
      packages/mobile/src/assets/images/3-1.png
  31. 二进制
      packages/mobile/src/assets/images/3.png
  32. 二进制
      packages/mobile/src/assets/images/4.png
  33. 二进制
      packages/mobile/src/assets/images/Volume btn_off.png
  34. 二进制
      packages/mobile/src/assets/images/Volume btn_on.png
  35. 二进制
      packages/mobile/src/assets/images/auto-suspend 拷贝.png
  36. 二进制
      packages/mobile/src/assets/images/auto-suspend.png
  37. 二进制
      packages/mobile/src/assets/images/auto.png
  38. 二进制
      packages/mobile/src/assets/images/back.png
  39. 二进制
      packages/mobile/src/assets/images/back_2.png
  40. 二进制
      packages/mobile/src/assets/images/bg.png
  41. 二进制
      packages/mobile/src/assets/images/bg_2.png
  42. 二进制
      packages/mobile/src/assets/images/bg_3.png
  43. 二进制
      packages/mobile/src/assets/images/close.png
  44. 二进制
      packages/mobile/src/assets/images/dollhouse.png
  45. 二进制
      packages/mobile/src/assets/images/enlarge_on.png
  46. 二进制
      packages/mobile/src/assets/images/floor.png
  47. 二进制
      packages/mobile/src/assets/images/hotlist.png
  48. 二进制
      packages/mobile/src/assets/images/inside.png
  49. 二进制
      packages/mobile/src/assets/images/logo.png
  50. 二进制
      packages/mobile/src/assets/images/logo_2.png
  51. 二进制
      packages/mobile/src/assets/images/narrow_off.png
  52. 二进制
      packages/mobile/src/assets/images/pause.png
  53. 二进制
      packages/mobile/src/assets/images/pic_1.png
  54. 二进制
      packages/mobile/src/assets/images/pic_2.png
  55. 二进制
      packages/mobile/src/assets/images/pic_3.png
  56. 二进制
      packages/mobile/src/assets/images/pic_4.png
  57. 二进制
      packages/mobile/src/assets/images/pic_5.png
  58. 二进制
      packages/mobile/src/assets/images/play.png
  59. 二进制
      packages/mobile/src/assets/images/share.png
  60. 二进制
      packages/mobile/src/assets/images/view.png
  61. 二进制
      packages/mobile/src/assets/images/word_bg.png
  62. 112 0
      packages/mobile/src/assets/main.css
  63. 7 0
      packages/mobile/src/assets/utils.scss
  64. 16 0
      packages/mobile/src/main.js
  65. 14 0
      packages/mobile/src/router/index.js
  66. 12 0
      packages/mobile/src/stores/counter.js
  67. 0 0
      packages/mobile/src/views/Home/index.scss
  68. 7 0
      packages/mobile/src/views/Home/index.vue
  69. 29 0
      packages/mobile/vite.config.js
  70. 2 0
      packages/pc/.env
  71. 30 0
      packages/pc/.gitignore
  72. 14 0
      packages/pc/index.html
  73. 8 0
      packages/pc/jsconfig.json
  74. 36 0
      packages/pc/package.json
  75. 23 0
      packages/pc/postcss.config.js
  76. 6515 0
      packages/pc/public/4dage.js
  77. 2463 0
      packages/pc/public/hammer.js
  78. 二进制
      packages/pc/public/img/bg.jpg
  79. 49 0
      packages/pc/public/model.html
  80. 23 0
      packages/pc/src/App.vue
  81. 13 0
      packages/pc/src/api/index.js
  82. 7 0
      packages/pc/src/assets/elements.scss
  83. 二进制
      packages/pc/src/assets/fonts/SOURCEHANSERIFCN-BOLD.OTF
  84. 二进制
      packages/pc/src/assets/fonts/SOURCEHANSERIFCN-REGULAR.OTF
  85. 二进制
      packages/pc/src/assets/images/active.png
  86. 二进制
      packages/pc/src/assets/images/back.png
  87. 二进制
      packages/pc/src/assets/images/btn-bg.png
  88. 二进制
      packages/pc/src/assets/images/close.png
  89. 二进制
      packages/pc/src/assets/images/icon1.png
  90. 二进制
      packages/pc/src/assets/images/label-bg.png
  91. 二进制
      packages/pc/src/assets/images/left-icon.png
  92. 二进制
      packages/pc/src/assets/images/scene-btn-min.png
  93. 二进制
      packages/pc/src/assets/images/title-min.png
  94. 119 0
      packages/pc/src/assets/main.css
  95. 7 0
      packages/pc/src/assets/utils.scss
  96. 195 0
      packages/pc/src/components/Classification/index.scss
  97. 136 0
      packages/pc/src/components/Classification/index.vue
  98. 二进制
      packages/pc/src/components/Search/images/search-icon.png
  99. 166 0
      packages/pc/src/components/Search/index.scss
  100. 0 0
      packages/pc/src/components/Search/index.vue

+ 22 - 0
.gitignore

@@ -0,0 +1,22 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+node_modules
+npm-debug.log*
+yarn-error.log
+yarn.lock
+package-lock.json
+
+# production
+/es
+docs-dist
+
+# misc
+.DS_Store
+
+# ide
+/.idea
+
+dist
+dist-node
+build

+ 2 - 0
.npmrc

@@ -0,0 +1,2 @@
+registry=https://registry.npmmirror.com/
+@dage:registry=http://192.168.20.245:4873/

+ 8 - 0
.prettierignore

@@ -0,0 +1,8 @@
+build/
+public/
+**/*.png
+**/*.svg
+**/*.jpg
+.DS_Store
+.history
+package.json

+ 3 - 0
.vscode/extensions.json

@@ -0,0 +1,3 @@
+{
+  "recommendations": ["Vue.volar"]
+}

+ 10 - 0
.vscode/settings.json

@@ -0,0 +1,10 @@
+{
+  "explorer.fileNesting.enabled": true,
+  "explorer.fileNesting.patterns": {
+    "tsconfig.json": "tsconfig.*.json, env.d.ts",
+    "vite.config.*": "jsconfig*, vitest.config.*, cypress.config.*, playwright.config.*",
+    "package.json": "package-lock.json, pnpm*, .yarnrc*, yarn*, .eslint*, eslint*, .prettier*, prettier*, .editorconfig"
+  },
+  "editor.formatOnSave": true,
+  "editor.defaultFormatter": "esbenp.prettier-vscode"
+}

+ 1 - 0
README.md

@@ -0,0 +1 @@
+WHS2411062-1 贺龙纪念馆-红色基因库项目

+ 16 - 0
package.json

@@ -0,0 +1,16 @@
+{
+  "name": "bijiang-river-bridge",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [],
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "pinia": "^2.2.6",
+    "tslib": "^2.8.0"
+  }
+}

二进制
packages/base/model/ycq/31-01albedo.jpg


二进制
packages/base/model/ycq/31-02albedo.jpg


二进制
packages/base/model/ycq/31-03albedo.jpg


二进制
packages/base/model/ycq/31-05albedo.jpg


二进制
packages/base/model/ycq/31-06albedo.jpg


+ 42 - 0
packages/base/model/ycq/31-yangchunqiao.mtl

@@ -0,0 +1,42 @@
+newmtl qiaomen_1_01_31
+illum 4
+Kd 1.00 1.00 1.00
+Ka 1.00 1.00 1.00
+Tf 1.00 1.00 1.00
+map_Kd 31-01albedo.jpg
+Ni 1.50
+newmtl qiaomen_2_02_31
+illum 4
+Kd 1.00 1.00 1.00
+Ka 1.00 1.00 1.00
+Tf 1.00 1.00 1.00
+map_Kd 31-02albedo.jpg
+Ni 1.50
+newmtl qiaowu_1_03_31
+illum 4
+Kd 1.00 1.00 1.00
+Ka 1.00 1.00 1.00
+Tf 1.00 1.00 1.00
+map_Kd 31-03albedo.jpg
+Ni 1.50
+newmtl wuding_1_05_31
+illum 4
+Kd 1.00 1.00 1.00
+Ka 1.00 1.00 1.00
+Tf 1.00 1.00 1.00
+map_Kd 31-05albedo.jpg
+Ni 1.50
+newmtl wuding_1_06_31
+illum 4
+Kd 1.00 1.00 1.00
+Ka 1.00 1.00 1.00
+Tf 1.00 1.00 1.00
+map_Kd 31-06albedo.jpg
+Ni 1.50
+newmtl wuding_2_03_31
+illum 4
+Kd 1.00 1.00 1.00
+Ka 1.00 1.00 1.00
+Tf 1.00 1.00 1.00
+map_Kd 31-03albedo.jpg
+Ni 1.50

文件差异内容过多而无法显示
+ 2075313 - 0
packages/base/model/ycq/31-yangchunqiao.obj


+ 14 - 0
packages/base/package.json

@@ -0,0 +1,14 @@
+{
+  "name": "@bj/base",
+  "version": "1.0.0",
+  "description": "",
+  "sideEffects": false,
+  "module": "src/index.js",
+  "main": "src/index.js",
+  "files": [
+    "src"
+  ],
+  "keywords": [],
+  "author": "",
+  "license": "ISC"
+}

+ 22 - 0
packages/base/src/index.js

@@ -0,0 +1,22 @@
+export const NAV_TABS = [
+  {
+    id: 1,
+    label: "木梁桥",
+  },
+  {
+    id: 2,
+    label: "铁链吊桥",
+  },
+  {
+    id: 3,
+    label: "石拱桥",
+  },
+  {
+    id: 4,
+    label: "钢桁桥",
+  },
+  {
+    id: 5,
+    label: "藤桥",
+  },
+];

+ 30 - 0
packages/mobile/.gitignore

@@ -0,0 +1,30 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+.DS_Store
+dist
+dist-ssr
+coverage
+*.local
+
+/cypress/videos/
+/cypress/screenshots/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo

+ 13 - 0
packages/mobile/index.html

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" href="/favicon.ico" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>沘江古桥梁群</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
+  </body>
+</html>

+ 8 - 0
packages/mobile/jsconfig.json

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

+ 30 - 0
packages/mobile/package.json

@@ -0,0 +1,30 @@
+{
+  "name": "@bj/mobile",
+  "version": "0.0.0",
+  "private": true,
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "@bj/base": "workspace:*",
+    "pinia": "^2.2.6",
+    "swiper": "^11.1.15",
+    "vant": "^4.9.15",
+    "vue": "^3.5.13",
+    "vue-router": "^4.4.5"
+  },
+  "devDependencies": {
+    "@vant/auto-import-resolver": "^1.2.1",
+    "@vitejs/plugin-vue": "^5.2.1",
+    "autoprefixer": "^10.4.20",
+    "postcss-px-to-viewport": "^1.1.1",
+    "sass": "^1.82.0",
+    "unplugin-auto-import": "^0.18.6",
+    "unplugin-vue-components": "^0.27.5",
+    "vite": "^6.0.1",
+    "vite-plugin-vue-devtools": "^7.6.5"
+  }
+}

+ 22 - 0
packages/mobile/postcss.config.js

@@ -0,0 +1,22 @@
+export default {
+  plugins: {
+    autoprefixer: {},
+    "postcss-px-to-viewport": {
+      unitToConvert: "px", // 需要转换的单位,默认为"px"
+      viewportWidth: 750, // 设计稿的视口宽度
+      unitPrecision: 5, // 单位转换后保留的精度
+      propList: ["*"], // 能转化为vw的属性列表
+      viewportUnit: "vw", // 希望使用的视口单位
+      fontViewportUnit: "vw", // 字体使用的视口单位
+      selectorBlackList: [], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
+      minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
+      mediaQuery: true, // 媒体查询里的单位是否需要转换单位
+      replace: true, //  是否直接更换属性值,而不添加备用属性
+      exclude: /node_modules/i, // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
+      include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换
+      landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
+      landscapeUnit: "vw", // 横屏时使用的单位
+      landscapeWidth: 750, // 横屏时使用的视口宽度
+    },
+  },
+};

文件差异内容过多而无法显示
+ 6515 - 0
packages/mobile/public/4dage.js


二进制
packages/mobile/public/img/bg.jpg


+ 51 - 0
packages/mobile/public/model.html

@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <script src="./4dage.js"></script>
+  <title>Document</title>
+  <style>
+    html {
+      overflow: hidden;
+    }
+
+    .bacBox {
+      opacity: 1;
+      pointer-events: auto;
+      position: absolute;
+      z-index: 998;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      background-color: #cfcfd0;
+      transition: all 1s;
+    }
+  </style>
+</head>
+
+<body>
+  <div id="ui"></div>
+  <div class="outerImg">
+    <img src="./img/bg.jpg" alt="">
+  </div>
+  <script>
+    let number = getQueryVariable("m");
+
+    console.log('ppppppppp',number);
+
+    window.autoRotate = true; // 是否自动旋转
+    fdage.embed('https://4dscene.4dage.com/culturalrelics/HLJNG/4dage/' + number + '.4dage', {
+        width: 800,
+        height: 600,
+        autoStart: true,
+        fullFrame: true,
+        pagePreset: false
+    });
+  </script>
+</body>
+
+</html>

+ 16 - 0
packages/mobile/src/App.vue

@@ -0,0 +1,16 @@
+<script setup>
+import { RouterView } from "vue-router";
+</script>
+
+<template>
+  <RouterView />
+</template>
+
+<style>
+:root:root {
+  --van-primary-color: #981b23;
+  --van-base-font: "SourceHanSerifSC-Regular";
+  --design-width: 750;
+  --design-height: 1424;
+}
+</style>

二进制
packages/mobile/src/assets/fonts/SOURCEHANSERIFCN-BOLD.OTF


二进制
packages/mobile/src/assets/fonts/SOURCEHANSERIFCN-REGULAR.OTF


二进制
packages/mobile/src/assets/images/1.png


二进制
packages/mobile/src/assets/images/2.png


二进制
packages/mobile/src/assets/images/3-1.png


二进制
packages/mobile/src/assets/images/3.png


二进制
packages/mobile/src/assets/images/4.png


二进制
packages/mobile/src/assets/images/Volume btn_off.png


二进制
packages/mobile/src/assets/images/Volume btn_on.png


二进制
packages/mobile/src/assets/images/auto-suspend 拷贝.png


二进制
packages/mobile/src/assets/images/auto-suspend.png


二进制
packages/mobile/src/assets/images/auto.png


二进制
packages/mobile/src/assets/images/back.png


二进制
packages/mobile/src/assets/images/back_2.png


二进制
packages/mobile/src/assets/images/bg.png


二进制
packages/mobile/src/assets/images/bg_2.png


二进制
packages/mobile/src/assets/images/bg_3.png


二进制
packages/mobile/src/assets/images/close.png


二进制
packages/mobile/src/assets/images/dollhouse.png


二进制
packages/mobile/src/assets/images/enlarge_on.png


二进制
packages/mobile/src/assets/images/floor.png


二进制
packages/mobile/src/assets/images/hotlist.png


二进制
packages/mobile/src/assets/images/inside.png


二进制
packages/mobile/src/assets/images/logo.png


二进制
packages/mobile/src/assets/images/logo_2.png


二进制
packages/mobile/src/assets/images/narrow_off.png


二进制
packages/mobile/src/assets/images/pause.png


二进制
packages/mobile/src/assets/images/pic_1.png


二进制
packages/mobile/src/assets/images/pic_2.png


二进制
packages/mobile/src/assets/images/pic_3.png


二进制
packages/mobile/src/assets/images/pic_4.png


二进制
packages/mobile/src/assets/images/pic_5.png


二进制
packages/mobile/src/assets/images/play.png


二进制
packages/mobile/src/assets/images/share.png


二进制
packages/mobile/src/assets/images/view.png


二进制
packages/mobile/src/assets/images/word_bg.png


+ 112 - 0
packages/mobile/src/assets/main.css

@@ -0,0 +1,112 @@
+:root {
+  --z-index-normal: 1;
+  --z-index-top: 1000;
+  --z-index-popper: 2000;
+  --z-hot-popper: 3000;
+}
+
+body,
+ol,
+ul,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+th,
+td,
+dl,
+dd,
+form,
+fieldset,
+legend,
+input,
+textarea,
+select {
+  margin: 0;
+  padding: 0;
+}
+* {
+  box-sizing: border-box;
+  user-select: none;
+}
+body {
+  color: #333333;
+  text-align: justify;
+  font-family: "SourceHanSerifSC-Regular";
+  -webkit-tap-highlight-color: transparent;
+}
+a {
+  color: #fff;
+  cursor: pointer;
+  text-decoration: none;
+}
+em {
+  font-style: normal;
+}
+li {
+  list-style: none;
+}
+img {
+  border: 0;
+  vertical-align: middle;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+p {
+  word-wrap: break-word;
+}
+iframe {
+  border: none;
+}
+
+@font-face {
+  font-family: "SourceHanSerifSC-Bold";
+  src: url("./fonts/SOURCEHANSERIFCN-BOLD.otf");
+}
+@font-face {
+  font-family: "SourceHanSerifSC-Regular";
+  src: url("./fonts/SOURCEHANSERIFCN-REGULAR.otf");
+}
+
+.limit-line {
+  display: -webkit-box;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  -webkit-line-clamp: 1;
+  -webkit-box-orient: vertical;
+  word-break: break-all;
+  word-wrap: break-word;
+}
+
+.line-2 {
+  -webkit-line-clamp: 2;
+}
+
+.line-3 {
+  -webkit-line-clamp: 3;
+}
+
+.hidden {
+  display: none !important;
+  visibility: hidden !important;
+}
+
+.darkGlass {
+  background-color: rgba(0, 0, 0, 0.5);
+}
+
+.message-outer {
+  position: absolute;
+  display: table;
+  height: 100%;
+  width: 100%;
+
+  * {
+    transition: all 0.3s;
+  }
+}

+ 7 - 0
packages/mobile/src/assets/utils.scss

@@ -0,0 +1,7 @@
+@function vh-calc($num) {
+  @return calc(100vh * ($num / var(--design-height)));
+}
+
+@function vw-calc($num) {
+  @return calc(100vw * ($num / var(--design-width)));
+}

+ 16 - 0
packages/mobile/src/main.js

@@ -0,0 +1,16 @@
+import "./assets/main.css";
+
+import { createApp } from "vue";
+import { createPinia } from "pinia";
+import { Lazyload } from "vant";
+
+import App from "./App.vue";
+import router from "./router";
+
+const app = createApp(App);
+
+app.use(createPinia());
+app.use(router);
+app.use(Lazyload);
+
+app.mount("#app");

+ 14 - 0
packages/mobile/src/router/index.js

@@ -0,0 +1,14 @@
+import { createRouter, createWebHashHistory } from "vue-router";
+
+const router = createRouter({
+  history: createWebHashHistory(import.meta.env.BASE_URL),
+  routes: [
+    {
+      path: "/",
+      name: "home",
+      component: () => import("../views/Home/index.vue"),
+    },
+  ],
+});
+
+export default router;

+ 12 - 0
packages/mobile/src/stores/counter.js

@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+  const count = ref(0)
+  const doubleCount = computed(() => count.value * 2)
+  function increment() {
+    count.value++
+  }
+
+  return { count, doubleCount, increment }
+})

+ 0 - 0
packages/mobile/src/views/Home/index.scss


+ 7 - 0
packages/mobile/src/views/Home/index.vue

@@ -0,0 +1,7 @@
+<template>
+  <div class="home"></div>
+</template>
+
+<style lang="scss" scoped>
+@use "./index.scss";
+</style>

+ 29 - 0
packages/mobile/vite.config.js

@@ -0,0 +1,29 @@
+import { fileURLToPath, URL } from "node:url";
+
+import { defineConfig } from "vite";
+import vue from "@vitejs/plugin-vue";
+import AutoImport from "unplugin-auto-import/vite";
+import Components from "unplugin-vue-components/vite";
+import { VantResolver } from "@vant/auto-import-resolver";
+
+// https://vite.dev/config/
+export default defineConfig({
+  base: "./",
+  server: {
+    host: "0.0.0.0",
+  },
+  plugins: [
+    vue(),
+    AutoImport({
+      resolvers: [VantResolver()],
+    }),
+    Components({
+      resolvers: [VantResolver()],
+    }),
+  ],
+  resolve: {
+    alias: {
+      "@": fileURLToPath(new URL("./src", import.meta.url)),
+    },
+  },
+});

+ 2 - 0
packages/pc/.env

@@ -0,0 +1,2 @@
+VITE_BASE_URL=https://sit-yunnanguqiao.4dage.com
+VITE_PUBLIC_URL=https://houseoss.4dkankan.com/project/bijiang-bridge-public

+ 30 - 0
packages/pc/.gitignore

@@ -0,0 +1,30 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+.DS_Store
+dist
+dist-ssr
+coverage
+*.local
+
+/cypress/videos/
+/cypress/screenshots/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo

+ 14 - 0
packages/pc/index.html

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" href="/favicon.ico" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>沘江古桥梁群</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
+    <script src="./hammer.js"></script>
+  </body>
+</html>

+ 8 - 0
packages/pc/jsconfig.json

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

+ 36 - 0
packages/pc/package.json

@@ -0,0 +1,36 @@
+{
+  "name": "@bj/pc",
+  "version": "0.0.0",
+  "private": true,
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "preview": "vite preview"
+  },
+  "dependencies": {
+    "@bj/base": "workspace:*",
+    "@dage/service": "^1.0.6",
+    "@element-plus/icons-vue": "^2.3.1",
+    "@vueuse/core": "^12.0.0",
+    "animate.css": "^4.1.1",
+    "autoprefixer": "^10.4.20",
+    "element-plus": "^2.9.0",
+    "gsap": "^3.13.0",
+    "lodash": "^4.17.21",
+    "pinia": "^2.2.6",
+    "postcss-px-to-viewport": "^1.1.1",
+    "svg-pan-zoom": "^3.6.2",
+    "swiper": "^11.1.15",
+    "three": "^0.179.1",
+    "vue": "^3.5.13",
+    "vue-router": "^4.4.5"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^5.2.1",
+    "sass": "^1.82.0",
+    "unplugin-auto-import": "^0.18.6",
+    "unplugin-vue-components": "^0.27.5",
+    "vite": "^6.0.1"
+  }
+}

+ 23 - 0
packages/pc/postcss.config.js

@@ -0,0 +1,23 @@
+export default {
+  plugins: {
+    autoprefixer: {},
+    "postcss-px-to-viewport": {
+      unitToConvert: "px", // 需要转换的单位,默认为"px"
+      viewportWidth: 1920, // 设计稿的视口宽度
+      unitPrecision: 5, // 单位转换后保留的精度
+      propList: ["*"], // 能转化为vw的属性列表
+      viewportUnit: "vw", // 希望使用的视口单位
+      fontViewportUnit: "vw", // 字体使用的视口单位
+      selectorBlackList: [], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
+      minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
+      mediaQuery: true, // 媒体查询里的单位是否需要转换单位
+      replace: true, //  是否直接更换属性值,而不添加备用属性
+      exclude: undefined, // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
+      include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换
+      landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
+      landscapeUnit: "vw", // 横屏时使用的单位
+      landscapeWidth: 1920, // 横屏时使用的视口宽度
+      exclude: [/node_modules/],
+    },
+  },
+};

文件差异内容过多而无法显示
+ 6515 - 0
packages/pc/public/4dage.js


文件差异内容过多而无法显示
+ 2463 - 0
packages/pc/public/hammer.js


二进制
packages/pc/public/img/bg.jpg


+ 49 - 0
packages/pc/public/model.html

@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <script src="./4dage.js"></script>
+  <title>Document</title>
+  <style>
+    html {
+      overflow: hidden;
+    }
+
+    .bacBox {
+      opacity: 1;
+      pointer-events: auto;
+      position: absolute;
+      z-index: 998;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      background-color: #cfcfd0;
+      transition: all 1s;
+    }
+  </style>
+</head>
+
+<body>
+  <div id="ui"></div>
+  <div class="outerImg">
+    <img src="./img/bg.jpg" alt="">
+  </div>
+  <script>
+    let number = getQueryVariable("m");
+
+    window.autoRotate = true; // 是否自动旋转
+    fdage.embed('https://4dscene.4dage.com/culturalrelics/YNGQ/4dage/' + number + '.4dage', {
+        width: 800,
+        height: 600,
+        autoStart: true,
+        fullFrame: true,
+        pagePreset: false
+    });
+  </script>
+</body>
+
+</html>

+ 23 - 0
packages/pc/src/App.vue

@@ -0,0 +1,23 @@
+<script setup>
+import { RouterView } from "vue-router";
+</script>
+
+<template>
+  <RouterView />
+</template>
+
+<style>
+:root {
+  --design-width: 1920;
+  --design-height: 1014;
+}
+
+.el-image {
+  width: 100%;
+  height: 100%;
+}
+
+#app {
+  font-size: 18px;
+}
+</style>

+ 13 - 0
packages/pc/src/api/index.js

@@ -0,0 +1,13 @@
+import { requestByGet, requestByPost } from "@dage/service";
+
+export const getBridgeListApi = (params) => {
+  return requestByPost("/api/show/bridge/pageList", params);
+};
+
+export const getDictListApi = (params) => {
+  return requestByGet("/api/show/dict/getList", params);
+};
+
+export const getBridgeDetailApi = (id) => {
+  return requestByGet(`/api/show/bridge/detail/${id}`);
+};

+ 7 - 0
packages/pc/src/assets/elements.scss

@@ -0,0 +1,7 @@
+@forward "element-plus/theme-chalk/src/common/var.scss" with (
+  $colors: (
+    "primary": (
+      "base": #c90110,
+    ),
+  )
+);

二进制
packages/pc/src/assets/fonts/SOURCEHANSERIFCN-BOLD.OTF


二进制
packages/pc/src/assets/fonts/SOURCEHANSERIFCN-REGULAR.OTF


二进制
packages/pc/src/assets/images/active.png


二进制
packages/pc/src/assets/images/back.png


二进制
packages/pc/src/assets/images/btn-bg.png


二进制
packages/pc/src/assets/images/close.png


二进制
packages/pc/src/assets/images/icon1.png


二进制
packages/pc/src/assets/images/label-bg.png


二进制
packages/pc/src/assets/images/left-icon.png


二进制
packages/pc/src/assets/images/scene-btn-min.png


二进制
packages/pc/src/assets/images/title-min.png


+ 119 - 0
packages/pc/src/assets/main.css

@@ -0,0 +1,119 @@
+:root {
+  --z-index-normal: 1;
+  --z-index-top: 1000;
+  --z-index-popper: 2000;
+  --z-hot-popper: 3000;
+  --el-mask-color: rgba(255, 255, 255, 0) !important;
+}
+
+body,
+ol,
+ul,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+th,
+td,
+dl,
+dd,
+form,
+fieldset,
+legend,
+input,
+textarea,
+select {
+  margin: 0;
+  padding: 0;
+}
+* {
+  box-sizing: border-box;
+  user-select: none;
+}
+body {
+  color: #383838;
+  text-align: justify;
+  font-family: "SourceHanSerifSC-Regular";
+  -webkit-tap-highlight-color: transparent;
+}
+a {
+  color: #fff;
+  cursor: pointer;
+  text-decoration: none;
+}
+em {
+  font-style: normal;
+}
+li {
+  list-style: none;
+}
+img {
+  border: 0;
+  vertical-align: middle;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+p {
+  word-wrap: break-word;
+}
+iframe {
+  border: none;
+}
+
+@font-face {
+  font-family: "SourceHanSerifSC-Bold";
+  src: url("@/assets/fonts/SOURCEHANSERIFCN-BOLD.otf");
+}
+@font-face {
+  font-family: "SourceHanSerifSC-Regular";
+  src: url("@/assets/fonts/SOURCEHANSERIFCN-REGULAR.otf");
+}
+
+.limit-line {
+  display: -webkit-box;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  -webkit-line-clamp: 1;
+  -webkit-box-orient: vertical;
+  word-break: break-all;
+  word-wrap: break-word;
+}
+
+.line-2 {
+  -webkit-line-clamp: 2;
+}
+
+.line-3 {
+  -webkit-line-clamp: 3;
+}
+
+.hidden {
+  display: none !important;
+  visibility: hidden !important;
+}
+
+.darkGlass {
+  background-color: rgba(0, 0, 0, 0.5);
+}
+
+.message-outer {
+  position: absolute;
+  display: table;
+  height: 100%;
+  width: 100%;
+
+  * {
+    transition: all 0.3s;
+  }
+}
+
+.gradient-color {
+  color: transparent;
+  background: linear-gradient(180deg, #fffbc4 0%, #e5c05b 100%);
+  background-clip: text;
+}

+ 7 - 0
packages/pc/src/assets/utils.scss

@@ -0,0 +1,7 @@
+@function vh-calc($num) {
+  @return calc(100vh * ($num / var(--design-height)));
+}
+
+@function vw-calc($num) {
+  @return calc(100vw * ($num / var(--design-width)));
+}

+ 195 - 0
packages/pc/src/components/Classification/index.scss

@@ -0,0 +1,195 @@
+.classification {
+  margin: 0;
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  box-shadow: none;
+  background: none;
+  --el-dialog-padding-primary: 0;
+
+  &-modal {
+    backdrop-filter: blur(30px);
+    background: rgba(116, 78, 46, 0.5);
+  }
+  &-main {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  &::before {
+    content: "";
+    position: absolute;
+    top: 30px;
+    left: 30px;
+    width: 203px;
+    height: 76px;
+    background: url("@/assets/images/title-min.png") no-repeat center / contain;
+  }
+  .el-dialog__body {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 100%;
+  }
+  &__close {
+    position: absolute;
+    top: 50px;
+    right: 30px;
+    width: 50px;
+    height: 50px;
+    cursor: pointer;
+  }
+  &-tabs {
+    display: flex;
+    flex-direction: column;
+    gap: 30px;
+
+    li {
+      position: relative;
+      width: 130px;
+      height: 40px;
+      line-height: 38px;
+      text-align: center;
+      font-size: 16px;
+      border: 1px solid #744e2e;
+      border-radius: 50px;
+      background: rgba(44, 12, 0, 0.5);
+      cursor: pointer;
+
+      &.active,
+      &:hover {
+        p {
+          color: transparent;
+          background: linear-gradient(180deg, #fffbc4 0%, #e5c05b 100%);
+          background-clip: text;
+          font-family: "SourceHanSerifSC-Bold";
+        }
+      }
+      &.active {
+        border-color: #fffbc4;
+        background: rgba(116, 78, 46, 0.5);
+
+        &::after {
+          background: linear-gradient(180deg, #fffbc4 0%, #e5c05b 100%);
+        }
+      }
+      p {
+        color: #b18661;
+      }
+      &::after {
+        content: "";
+        position: absolute;
+        top: 50%;
+        left: -20px;
+        width: 8px;
+        height: 8px;
+        border-radius: 50%;
+        background: #b18661;
+        transform: translateY(-50%);
+      }
+    }
+  }
+
+  &-list {
+    --el-scrollbar-opacity: 1;
+
+    .el-scrollbar__thumb {
+      background: linear-gradient(180deg, #fffbc4 0%, #e5c05b 100%);
+    }
+    .el-scrollbar__bar.is-vertical {
+      width: 4px;
+    }
+    margin: 0 60px 0 40px;
+    padding-right: 20px;
+    height: 620px;
+
+    &-wrap {
+      display: flex;
+      flex-direction: column;
+      gap: 20px;
+    }
+  }
+  &-item {
+    position: relative;
+    flex-shrink: 0;
+    width: 220px;
+    height: 150px;
+    overflow: hidden;
+    border-radius: 10px;
+    cursor: pointer;
+
+    &.active {
+      padding: 1px;
+      font-family: "SourceHanSerifSC-Bold";
+      background: linear-gradient(180deg, #fffbc4 0%, #e5c05b 100%);
+
+      .classification-item-footer {
+        left: 1px;
+        right: 1px;
+        bottom: 1px;
+      }
+    }
+    img {
+      width: 100%;
+      height: 100%;
+      border-radius: 10px;
+      overflow: hidden;
+      object-fit: cover;
+    }
+    &-footer {
+      position: absolute;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0 10px;
+      border-bottom-left-radius: 10px;
+      border-bottom-right-radius: 10px;
+      background: rgba(116, 78, 46, 0.9);
+
+      p {
+        font-size: 16px;
+        color: #fffdde;
+      }
+      &::after {
+        content: "";
+        display: block;
+        width: 11px;
+        height: 16px;
+        background: url("@/assets/images/left-icon.png") no-repeat center /
+          contain;
+      }
+    }
+  }
+
+  &-container {
+    position: relative;
+    width: 1100px;
+    height: 620px;
+
+    video {
+      width: 100%;
+      height: 100%;
+    }
+  }
+  &-label {
+    position: absolute;
+    left: 50%;
+    bottom: -64px;
+    width: 230px;
+    height: 30px;
+    line-height: 30px;
+    text-align: center;
+    font-family: "SourceHanSerifSC-Bold";
+    transform: translateX(-50%);
+    background: url("@/assets/images/label-bg.png") no-repeat center / contain;
+
+    span {
+      color: transparent;
+      background: linear-gradient(180deg, #fffbc4 0%, #e5c05b 100%);
+      background-clip: text;
+    }
+  }
+}

+ 136 - 0
packages/pc/src/components/Classification/index.vue

@@ -0,0 +1,136 @@
+<template>
+  <ElDialog
+    v-model="show"
+    append-to-body
+    class="classification"
+    modal-class="classification-modal"
+    :show-close="false"
+  >
+    <img
+      class="classification__close"
+      src="@/assets/images/close.png"
+      @click="handleClose"
+    />
+
+    <div v-loading="loading" class="classification-main">
+      <ul class="classification-tabs">
+        <li
+          v-for="item in NAV_TABS"
+          :key="item.id"
+          :class="{ active: item.label === checkedClass }"
+          @click="checkedClass = item.label"
+        >
+          <p>{{ item.label }}</p>
+        </li>
+      </ul>
+
+      <ElScrollbar class="classification-list">
+        <div class="classification-list-wrap">
+          <div
+            v-for="(item, index) in list"
+            :key="item.id"
+            class="classification-item"
+            :class="{ active: activeIndex === index }"
+            @click="handleDetail(index)"
+          >
+            <img :src="`${baseUrl}${item.thumb}`" />
+            <div class="classification-item-footer">
+              <p>{{ item.name }}</p>
+            </div>
+          </div>
+        </div>
+      </ElScrollbar>
+
+      <div
+        v-if="list[activeIndex] && detail?.video.length"
+        class="classification-container"
+      >
+        <video autoplay controls :src="baseUrl + detail?.video[0].filePath" />
+
+        <p class="classification-label">
+          <span>{{ list[activeIndex].name }}</span>
+        </p>
+      </div>
+    </div>
+  </ElDialog>
+</template>
+
+<script setup>
+import { computed, watch, ref } from "vue";
+import { NAV_TABS } from "@bj/base";
+import { getBridgeListApi, getBridgeDetailApi } from "@/api";
+
+const baseUrl = import.meta.env.VITE_BASE_URL;
+const props = defineProps(["visible", "checked"]);
+const emits = defineEmits(["update:visible", "update:checked"]);
+const activeIndex = ref(0);
+const loading = ref(false);
+const list = ref([]);
+const detail = ref(null);
+
+const checkedClass = computed({
+  get() {
+    return props.checked;
+  },
+  set(v) {
+    emits("update:checked", v);
+  },
+});
+
+const show = computed({
+  get() {
+    return props.visible;
+  },
+  set(v) {
+    emits("update:visible", v);
+  },
+});
+
+const handleClose = () => {
+  show.value = false;
+  checkedClass.value = null;
+};
+
+const getBridgeList = async () => {
+  try {
+    loading.value = true;
+    const data = await getBridgeListApi({
+      pageNum: 1,
+      pageSize: 999,
+      type: checkedClass.value,
+    });
+    list.value = data.records;
+
+    if (list.value.length > 0) {
+      getBridgeDetail();
+    }
+  } finally {
+    loading.value = false;
+  }
+};
+
+const getBridgeDetail = async () => {
+  if (!list.value[activeIndex.value]) return;
+
+  try {
+    loading.value = true;
+    const data = await getBridgeDetailApi(list.value[activeIndex.value].id);
+    detail.value = data;
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleDetail = (index) => {
+  activeIndex.value = index;
+  getBridgeDetail();
+};
+
+watch(checkedClass, (v) => {
+  v && getBridgeList();
+});
+</script>
+
+<style lang="scss">
+@use "./index.scss";
+</style>

二进制
packages/pc/src/components/Search/images/search-icon.png


+ 166 - 0
packages/pc/src/components/Search/index.scss

@@ -0,0 +1,166 @@
+.map-search {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  position: absolute;
+  top: 30px;
+  right: 20px;
+  padding-left: 15px;
+  width: 300px;
+  height: 40px;
+  overflow: hidden;
+  border-radius: 25px;
+  background: rgba($color: #000000, $alpha: 0.5);
+  border: 1px solid #744e2e;
+  z-index: 9;
+
+  &__input {
+    flex: 1;
+    border: 0;
+    font-size: 16px;
+    color: #fffdde;
+    background: transparent;
+
+    &::placeholder {
+      color: inherit;
+      opacity: 0.8;
+    }
+    &:focus {
+      border: none;
+      outline: none;
+    }
+  }
+  &__btn {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 50px;
+    height: 100%;
+    background: #744e2e;
+    cursor: pointer;
+
+    &::after {
+      content: "";
+      width: 24px;
+      height: 22px;
+      background: url("./images/search-icon.png") no-repeat center / contain;
+    }
+  }
+
+  &-panel {
+    position: absolute;
+    top: 90px;
+    right: 20px;
+    bottom: 40px;
+    display: flex;
+    gap: 30px;
+    padding: 0 13px 10px 20px;
+    width: 300px;
+    overflow: hidden;
+    color: #fffdde;
+    font-size: 16px;
+    border-radius: 10px;
+    border: 1px solid #744e2e;
+    background: rgba(85, 47, 15, 0.6);
+    z-index: 9;
+
+    .swiper-slide {
+      display: flex;
+      align-items: center;
+      cursor: pointer;
+    }
+    &-left {
+      margin: 9px 0 72px;
+
+      .swiper-slide {
+        height: 60px;
+
+        &.active {
+          color: #e5c05b;
+          font-family: "SourceHanSerifSC-Bold";
+
+          .map-search-panel-left-wrap {
+            position: relative;
+
+            &::after {
+              content: "";
+              position: absolute;
+              left: 0;
+              right: 0;
+              bottom: -7px;
+              height: 2px;
+              background: #e5c05b;
+              border-radius: 2px;
+            }
+          }
+        }
+      }
+    }
+    &-right {
+      flex: 1;
+      margin: 19px 0 24px;
+
+      .swiper-slide {
+        padding-right: 30px;
+        height: 40px;
+
+        &.active,
+        &:hover {
+          color: #e5c05b;
+          font-family: "SourceHanSerifSC-Bold";
+
+          &::after {
+            content: "";
+            position: absolute;
+            top: 50%;
+            right: 0;
+            width: 24px;
+            height: 20px;
+            background: url("@/assets/images/active.png") no-repeat center /
+              contain;
+            transform: translateY(-50%);
+          }
+        }
+      }
+    }
+    .swiper-button-prev {
+      margin-top: 0;
+      top: 13px;
+      left: unset;
+      right: 33px;
+      width: 0;
+      height: 0;
+      border-left: 8px solid transparent;
+      border-right: 8px solid transparent;
+      border-bottom: 11px solid rgba(255, 253, 222, 0.5);
+
+      &::after {
+        display: none;
+      }
+    }
+    .swiper-button-next {
+      margin-top: 0;
+      top: unset;
+      left: unset;
+      right: 33px;
+      bottom: 16px;
+      width: 0;
+      height: 0;
+      border-left: 8px solid transparent;
+      border-right: 8px solid transparent;
+      border-top: 11px solid rgba(255, 253, 222, 0.5);
+
+      &::after {
+        display: none;
+      }
+    }
+    &__close {
+      position: absolute;
+      left: 18px;
+      bottom: 27px;
+      width: 36px;
+      height: 36px;
+      cursor: pointer;
+    }
+  }
+}

+ 0 - 0
packages/pc/src/components/Search/index.vue


部分文件因为文件数量过多而无法显示