first commit
This commit is contained in:
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
5
babel.config.js
Normal file
5
babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
]
|
||||||
|
}
|
||||||
19
jsconfig.json
Normal file
19
jsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"module": "esnext",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"src/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"scripthost"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
14795
package-lock.json
generated
Normal file
14795
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
52
package.json
Normal file
52
package.json
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"name": "one-pipe-h5",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@vant/area-data": "^2.0.0",
|
||||||
|
"axios": "^1.9.0",
|
||||||
|
"core-js": "^3.8.3",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
|
"i": "^0.3.7",
|
||||||
|
"js-base64": "^3.7.7",
|
||||||
|
"npm": "^11.4.1",
|
||||||
|
"parallax-js": "^3.1.0",
|
||||||
|
"vant": "^2.13.8",
|
||||||
|
"vue": "^2.6.14",
|
||||||
|
"vue-router": "^3.6.5"
|
||||||
|
},
|
||||||
|
"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-service": "~5.0.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"eslint-plugin-vue": "^8.0.3",
|
||||||
|
"vue-template-compiler": "^2.6.14"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:vue/essential",
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"parser": "@babel/eslint-parser"
|
||||||
|
},
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not dead"
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
17
public/index.html
Normal file
17
public/index.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
36
src/App.vue
Normal file
36
src/App.vue
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<router-view />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "App"
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body{
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
box-shadow: border-box;
|
||||||
|
}
|
||||||
|
.h5-container {
|
||||||
|
overflow-y: scroll; /* 或 auto */
|
||||||
|
scrollbar-width: thin; /* Firefox:让它更细 */
|
||||||
|
scrollbar-color: transparent transparent; /* Firefox:轨道和滑块都透明 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Chrome / Safari / Edge */
|
||||||
|
.h5-container::-webkit-scrollbar {
|
||||||
|
width: 8px; /* 可以设置为 0,如果你想完全隐藏 */
|
||||||
|
background-color: transparent; /* 滚动条轨道背景 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.h5-container::-webkit-scrollbar-thumb {
|
||||||
|
background-color: transparent; /* 滚动条滑块 */
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
15
src/main.js
Normal file
15
src/main.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import Vue from "vue";
|
||||||
|
import App from "./App.vue";
|
||||||
|
import router from "./router";
|
||||||
|
|
||||||
|
Vue.config.productionTip = false;
|
||||||
|
import {Toast, Area, Popup} from "vant";
|
||||||
|
import "vant/lib/index.css";
|
||||||
|
|
||||||
|
Vue.use(Toast);
|
||||||
|
Vue.use(Area);
|
||||||
|
Vue.use(Popup);
|
||||||
|
new Vue({
|
||||||
|
router,
|
||||||
|
render: (h) => h(App),
|
||||||
|
}).$mount("#app");
|
||||||
666
src/pages/404.vue
Normal file
666
src/pages/404.vue
Normal file
@@ -0,0 +1,666 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-4">
|
||||||
|
<section class="wrapper">
|
||||||
|
<div class="container">
|
||||||
|
<div id="scene" class="scene" data-hover-only="false">
|
||||||
|
<div class="circle" data-depth="1.2" />
|
||||||
|
|
||||||
|
<div class="one" data-depth="0.9">
|
||||||
|
<div class="content">
|
||||||
|
<span class="piece" />
|
||||||
|
<span class="piece" />
|
||||||
|
<span class="piece" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="two" data-depth="0.60">
|
||||||
|
<div class="content">
|
||||||
|
<span class="piece" />
|
||||||
|
<span class="piece" />
|
||||||
|
<span class="piece" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="three" data-depth="0.40">
|
||||||
|
<div class="content">
|
||||||
|
<span class="piece" />
|
||||||
|
<span class="piece" />
|
||||||
|
<span class="piece" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="p404" data-depth="0.50">暂无此产品</p>
|
||||||
|
<p class="p404" data-depth="0.10">暂无此产品</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text">
|
||||||
|
<article>
|
||||||
|
<!-- <p>此产品不存在</p> -->
|
||||||
|
<!-- <p></p> -->
|
||||||
|
<!-- <p>请点击按钮返回首页!</p> -->
|
||||||
|
<!-- <button @click="enterHome">返回首页</button> -->
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import Parallax from 'parallax-js'
|
||||||
|
export default {
|
||||||
|
name: 'H5404Page',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
parallaxInstance: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
mounted() {
|
||||||
|
const scene = document.getElementById('scene')
|
||||||
|
if (scene) {
|
||||||
|
this.parallaxInstance = new Parallax(scene)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.parallaxInstance) {
|
||||||
|
this.parallaxInstance.destroy()
|
||||||
|
this.parallaxInstance = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
enterHome() {
|
||||||
|
this.$router.push({ name: 'H5' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.about {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 10;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: flex-end;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
.about .bg_links {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.about .social {
|
||||||
|
opacity: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
.about:hover {
|
||||||
|
width: 105px;
|
||||||
|
height: 105px;
|
||||||
|
transition: all 0.6s cubic-bezier(0.64, 0.01, 0.07, 1.65);
|
||||||
|
}
|
||||||
|
.about:hover .logo {
|
||||||
|
opacity: 1;
|
||||||
|
transition: all 0.6s ease;
|
||||||
|
}
|
||||||
|
.about:hover .social {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.about:hover .social .icon {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
.about:hover .social:hover {
|
||||||
|
background-size: 28px;
|
||||||
|
}
|
||||||
|
.about:hover .social:hover .icon {
|
||||||
|
background-size: 65%;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.about:hover .social.portfolio {
|
||||||
|
right: 0;
|
||||||
|
bottom: calc(100% - 40px);
|
||||||
|
transition: all 0.3s 0s cubic-bezier(0.64, 0.01, 0.07, 1.65);
|
||||||
|
}
|
||||||
|
.about:hover .social.portfolio .icon:hover {
|
||||||
|
background-color: #698fb7;
|
||||||
|
}
|
||||||
|
.about:hover .social.linkedin {
|
||||||
|
bottom: 0;
|
||||||
|
right: calc(100% - 40px);
|
||||||
|
transition: all 0.3s 0.25s cubic-bezier(0.64, 0.01, 0.07, 1.65);
|
||||||
|
}
|
||||||
|
.about:hover .social.linkedin .icon:hover {
|
||||||
|
background-color: #0077b5;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
li,
|
||||||
|
button,
|
||||||
|
a,
|
||||||
|
i,
|
||||||
|
input,
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
border: 0;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
h1:focus,
|
||||||
|
h2:focus,
|
||||||
|
h3:focus,
|
||||||
|
h4:focus,
|
||||||
|
h5:focus,
|
||||||
|
h6:focus,
|
||||||
|
p:focus,
|
||||||
|
ul:focus,
|
||||||
|
li:focus,
|
||||||
|
button:focus,
|
||||||
|
a:focus,
|
||||||
|
i:focus,
|
||||||
|
input:focus,
|
||||||
|
body:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
.c-4 {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #695681;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 5;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: rgba(0, 0, 0, 0.1);
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
}
|
||||||
|
.logo img {
|
||||||
|
width: 55%;
|
||||||
|
height: 55%;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav .menu {
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 5%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
nav .menu .website_name {
|
||||||
|
color: #695681;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 20px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
background: white;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 2px;
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
nav .menu .website_name:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
nav .menu .menu_links {
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
nav .menu .menu_links:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 799px) {
|
||||||
|
nav .menu .menu_links {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nav .menu .menu_links .link {
|
||||||
|
color: white;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-right: 50px;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
position: relative;
|
||||||
|
transition: all 0.3s 0.2s ease;
|
||||||
|
}
|
||||||
|
nav .menu .menu_links .link:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
nav .menu .menu_links .link:before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
height: 4px;
|
||||||
|
background: linear-gradient(90deg, #ffedc0 0%, #ff9d87 100%);
|
||||||
|
bottom: -10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.4s cubic-bezier(0.82, 0.02, 0.13, 1.26);
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
nav .menu .menu_links .link:hover {
|
||||||
|
opacity: 1;
|
||||||
|
color: #fb8a8a;
|
||||||
|
}
|
||||||
|
nav .menu .menu_links .link:hover:before {
|
||||||
|
width: 40px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
nav .menu .menu_icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
position: relative;
|
||||||
|
display: none;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 799px) {
|
||||||
|
nav .menu .menu_icon {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nav .menu .menu_icon .icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 2px;
|
||||||
|
background: white;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
nav .menu .menu_icon .icon:before,
|
||||||
|
nav .menu .menu_icon .icon:after {
|
||||||
|
content: '';
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: inherit;
|
||||||
|
position: absolute;
|
||||||
|
transition: all 0.3s cubic-bezier(0.49, 0.04, 0, 1.55);
|
||||||
|
}
|
||||||
|
nav .menu .menu_icon .icon:before {
|
||||||
|
transform: translateY(-8px);
|
||||||
|
}
|
||||||
|
nav .menu .menu_icon .icon:after {
|
||||||
|
transform: translateY(8px);
|
||||||
|
}
|
||||||
|
nav .menu .menu_icon:hover .icon {
|
||||||
|
background: #ffedc0;
|
||||||
|
}
|
||||||
|
nav .menu .menu_icon:hover .icon:before {
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
nav .menu .menu_icon:hover .icon:after {
|
||||||
|
transform: translateY(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
.wrapper .container {
|
||||||
|
margin: 0 auto;
|
||||||
|
transition: all 0.4s ease;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.wrapper .container .scene {
|
||||||
|
position: absolute;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
vertical-align: middle;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.wrapper .container .one,
|
||||||
|
.wrapper .container .two,
|
||||||
|
.wrapper .container .three,
|
||||||
|
.wrapper .container .circle,
|
||||||
|
.wrapper .container .p404 {
|
||||||
|
width: 60%;
|
||||||
|
height: 60%;
|
||||||
|
top: 20% !important;
|
||||||
|
left: 20% !important;
|
||||||
|
min-width: 400px;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
.wrapper .container .one .content,
|
||||||
|
.wrapper .container .two .content,
|
||||||
|
.wrapper .container .three .content,
|
||||||
|
.wrapper .container .circle .content,
|
||||||
|
.wrapper .container .p404 .content {
|
||||||
|
width: 600px;
|
||||||
|
height: 600px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
animation: content 0.8s cubic-bezier(1, 0.06, 0.25, 1) backwards;
|
||||||
|
}
|
||||||
|
@keyframes content {
|
||||||
|
0% {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.wrapper .container .one .content .piece,
|
||||||
|
.wrapper .container .two .content .piece,
|
||||||
|
.wrapper .container .three .content .piece,
|
||||||
|
.wrapper .container .circle .content .piece,
|
||||||
|
.wrapper .container .p404 .content .piece {
|
||||||
|
width: 200px;
|
||||||
|
height: 80px;
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 80px;
|
||||||
|
z-index: 1;
|
||||||
|
animation: pieceLeft 8s cubic-bezier(1, 0.06, 0.25, 1) infinite both;
|
||||||
|
}
|
||||||
|
@keyframes pieceLeft {
|
||||||
|
50% {
|
||||||
|
left: 80%;
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes pieceRight {
|
||||||
|
50% {
|
||||||
|
right: 80%;
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 799px) {
|
||||||
|
.wrapper .container .one,
|
||||||
|
.wrapper .container .two,
|
||||||
|
.wrapper .container .three,
|
||||||
|
.wrapper .container .circle,
|
||||||
|
.wrapper .container .p404 {
|
||||||
|
width: 90%;
|
||||||
|
height: 90%;
|
||||||
|
top: 5% !important;
|
||||||
|
left: 5% !important;
|
||||||
|
min-width: 280px;
|
||||||
|
min-height: 280px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-height: 660px) {
|
||||||
|
.wrapper .container .one,
|
||||||
|
.wrapper .container .two,
|
||||||
|
.wrapper .container .three,
|
||||||
|
.wrapper .container .circle,
|
||||||
|
.wrapper .container .p404 {
|
||||||
|
min-width: 280px;
|
||||||
|
min-height: 280px;
|
||||||
|
width: 60%;
|
||||||
|
height: 60%;
|
||||||
|
top: 20% !important;
|
||||||
|
left: 20% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.wrapper .container .text {
|
||||||
|
width: 60%;
|
||||||
|
height: 40%;
|
||||||
|
min-width: 400px;
|
||||||
|
min-height: 500px;
|
||||||
|
position: absolute;
|
||||||
|
margin: 40px 0;
|
||||||
|
animation: text 0.6s 1.8s ease backwards;
|
||||||
|
}
|
||||||
|
@keyframes text {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(40px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 799px) {
|
||||||
|
.wrapper .container .text {
|
||||||
|
min-height: 400px;
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.wrapper .container .text article {
|
||||||
|
width: 500px;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 80%;
|
||||||
|
z-index: 4;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 799px) {
|
||||||
|
.wrapper .container .text article {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.wrapper .container .text article p {
|
||||||
|
color: white;
|
||||||
|
font-size: 18px;
|
||||||
|
letter-spacing: 0.6px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-shadow: 6px 6px 10px #32243e;
|
||||||
|
}
|
||||||
|
.wrapper .container .text article button {
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 30px;
|
||||||
|
border-radius: 50px;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0px 15px 20px rgba(54, 24, 79, 0.5);
|
||||||
|
z-index: 3;
|
||||||
|
color: #695681;
|
||||||
|
background-color: white;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 12px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
.wrapper .container .text article button:hover {
|
||||||
|
box-shadow: 0px 10px 10px -10px rgba(54, 24, 79, 0.5);
|
||||||
|
transform: translateY(5px);
|
||||||
|
background: #fb8a8a;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.wrapper .container .p404 {
|
||||||
|
font-size: 100px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 4px;
|
||||||
|
color: white;
|
||||||
|
display: flex !important;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
animation: anime404 0.6s cubic-bezier(0.3, 0.8, 1, 1.05) both;
|
||||||
|
animation-delay: 1.2s;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 799px) {
|
||||||
|
.wrapper .container .p404 {
|
||||||
|
font-size: 50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes anime404 {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(10) skew(20deg, 20deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.wrapper .container .p404:nth-of-type(2) {
|
||||||
|
color: #36184f;
|
||||||
|
z-index: 1;
|
||||||
|
animation-delay: 1s;
|
||||||
|
filter: blur(10px);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.wrapper .container .circle {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.wrapper .container .circle:before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 800px;
|
||||||
|
height: 800px;
|
||||||
|
background-color: rgba(54, 24, 79, 0.2);
|
||||||
|
border-radius: 100%;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
box-shadow:
|
||||||
|
inset 5px 20px 40px rgba(54, 24, 79, 0.25),
|
||||||
|
inset 5px 0px 5px rgba(50, 36, 62, 0.3),
|
||||||
|
inset 5px 5px 20px rgba(50, 36, 62, 0.25),
|
||||||
|
2px 2px 5px rgba(255, 255, 255, 0.2);
|
||||||
|
animation: circle 0.8s cubic-bezier(1, 0.06, 0.25, 1) backwards;
|
||||||
|
}
|
||||||
|
@keyframes circle {
|
||||||
|
0% {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 799px) {
|
||||||
|
.wrapper .container .circle:before {
|
||||||
|
width: 400px;
|
||||||
|
height: 400px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.wrapper .container .one .content:before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 600px;
|
||||||
|
height: 600px;
|
||||||
|
background-color: rgba(54, 24, 79, 0.3);
|
||||||
|
border-radius: 100%;
|
||||||
|
box-shadow:
|
||||||
|
inset 5px 20px 40px rgba(54, 24, 79, 0.25),
|
||||||
|
inset 5px 0px 5px rgba(50, 36, 62, 0.3),
|
||||||
|
inset 5px 5px 20px rgba(50, 36, 62, 0.25),
|
||||||
|
2px 2px 5px rgba(255, 255, 255, 0.2);
|
||||||
|
animation: circle 0.8s 0.4s cubic-bezier(1, 0.06, 0.25, 1) backwards;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 799px) {
|
||||||
|
.wrapper .container .one .content:before {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.wrapper .container .one .content .piece {
|
||||||
|
background: linear-gradient(90deg, #8077ea 13.7%, #eb73ff 94.65%);
|
||||||
|
}
|
||||||
|
.wrapper .container .one .content .piece:nth-child(1) {
|
||||||
|
right: 15%;
|
||||||
|
top: 18%;
|
||||||
|
height: 30px;
|
||||||
|
width: 120px;
|
||||||
|
animation-delay: 0.5s;
|
||||||
|
animation-name: pieceRight;
|
||||||
|
}
|
||||||
|
.wrapper .container .one .content .piece:nth-child(2) {
|
||||||
|
left: 15%;
|
||||||
|
top: 45%;
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
animation-delay: 1s;
|
||||||
|
animation-name: pieceLeft;
|
||||||
|
}
|
||||||
|
.wrapper .container .one .content .piece:nth-child(3) {
|
||||||
|
left: 10%;
|
||||||
|
top: 75%;
|
||||||
|
height: 20px;
|
||||||
|
width: 70px;
|
||||||
|
animation-delay: 1.5s;
|
||||||
|
animation-name: pieceLeft;
|
||||||
|
}
|
||||||
|
.wrapper .container .two .content .piece {
|
||||||
|
background: linear-gradient(90deg, #ffedc0 0%, #ff9d87 100%);
|
||||||
|
}
|
||||||
|
.wrapper .container .two .content .piece:nth-child(1) {
|
||||||
|
left: 0%;
|
||||||
|
top: 25%;
|
||||||
|
height: 40px;
|
||||||
|
width: 120px;
|
||||||
|
animation-delay: 2s;
|
||||||
|
animation-name: pieceLeft;
|
||||||
|
}
|
||||||
|
.wrapper .container .two .content .piece:nth-child(2) {
|
||||||
|
right: 15%;
|
||||||
|
top: 35%;
|
||||||
|
width: 180px;
|
||||||
|
height: 50px;
|
||||||
|
animation-delay: 2.5s;
|
||||||
|
animation-name: pieceRight;
|
||||||
|
}
|
||||||
|
.wrapper .container .two .content .piece:nth-child(3) {
|
||||||
|
right: 10%;
|
||||||
|
top: 80%;
|
||||||
|
height: 20px;
|
||||||
|
width: 160px;
|
||||||
|
animation-delay: 3s;
|
||||||
|
animation-name: pieceRight;
|
||||||
|
}
|
||||||
|
.wrapper .container .three .content .piece {
|
||||||
|
background: #fb8a8a;
|
||||||
|
}
|
||||||
|
.wrapper .container .three .content .piece:nth-child(1) {
|
||||||
|
left: 25%;
|
||||||
|
top: 35%;
|
||||||
|
height: 20px;
|
||||||
|
width: 80px;
|
||||||
|
animation-name: pieceLeft;
|
||||||
|
animation-delay: 3.5s;
|
||||||
|
}
|
||||||
|
.wrapper .container .three .content .piece:nth-child(2) {
|
||||||
|
right: 10%;
|
||||||
|
top: 55%;
|
||||||
|
width: 140px;
|
||||||
|
height: 40px;
|
||||||
|
animation-name: pieceRight;
|
||||||
|
animation-delay: 4s;
|
||||||
|
}
|
||||||
|
.wrapper .container .three .content .piece:nth-child(3) {
|
||||||
|
left: 40%;
|
||||||
|
top: 68%;
|
||||||
|
height: 20px;
|
||||||
|
width: 80px;
|
||||||
|
animation-name: pieceLeft;
|
||||||
|
animation-delay: 4.5s;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
425
src/pages/H5.vue
Normal file
425
src/pages/H5.vue
Normal file
@@ -0,0 +1,425 @@
|
|||||||
|
<template>
|
||||||
|
<div class="h5-container">
|
||||||
|
<!-- topImg -->
|
||||||
|
<img
|
||||||
|
class="topImg"
|
||||||
|
:src="`https://h5.whjhft.com/static/${imgArr[0]}`"
|
||||||
|
v-show="imgArr[0]"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<!-- form表单 -->
|
||||||
|
<div class="form">
|
||||||
|
<div class="container">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="form-item">
|
||||||
|
<label class="label">*身份证姓名</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="form.cert_name"
|
||||||
|
placeholder="请输入身份证姓名(安全加密)"
|
||||||
|
@blur="validateName"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-item">
|
||||||
|
<label class="label">*联系电话</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="form.contact_num"
|
||||||
|
placeholder="请输入联系电话(安全加密)"
|
||||||
|
@blur="validatePhone"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-item" v-show="need_identity === 1">
|
||||||
|
<label class="label">*身份证号码</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="form.cert_no"
|
||||||
|
placeholder="未满18岁请勿领卡(安全加密)"
|
||||||
|
@blur="validateID"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-item">
|
||||||
|
<label class="label">*地区</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="form.address"
|
||||||
|
placeholder="选择地区(安全加密)"
|
||||||
|
@focus="selectArea"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="area">
|
||||||
|
<van-popup v-model="show" position="bottom">
|
||||||
|
<van-area title="选择地区" :area-list="areaList" @confirm="confirm" @cancel="cancel"/>
|
||||||
|
</van-popup>
|
||||||
|
</div>
|
||||||
|
<!--<van-area title="标题" :area-list="areaList" value="110101" />-->
|
||||||
|
<div class="form-item">
|
||||||
|
<label class="label">*详细地址</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="form.post_addr"
|
||||||
|
placeholder="街道/镇+村/小区/写字楼+门牌号"
|
||||||
|
@blur="validateAddress"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="tips">
|
||||||
|
*未满18周岁的,因政策原因不发货,请勿下单。请保持电话畅通,我们将随时可能与您联系。
|
||||||
|
</div>
|
||||||
|
<div class="btn">
|
||||||
|
<button @click="add">立即领取,包邮到家</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- details_img -->
|
||||||
|
<img
|
||||||
|
:src="`https://h5.whjhft.com/static/${imgArr[1]}`"
|
||||||
|
v-show="imgArr[1]"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<!-- copyright_img -->
|
||||||
|
<img
|
||||||
|
:src="`https://h5.whjhft.com/static/${imgArr[2]}`"
|
||||||
|
v-show="imgArr[2]"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from "axios";
|
||||||
|
import CryptoJS from "crypto-js";
|
||||||
|
import {areaList} from '@vant/area-data';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "H5Page",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show: false,
|
||||||
|
areaList,
|
||||||
|
encrypted: "erPY%2B%2BgxM2AhOlGj3B%2FyiTu3jbfg82vQ2vcXhcjzvEx%2BCBOQdn3%2BENusPylgeE5dg8ohlNHVohvkZdWejWOL1g%3D%3D",
|
||||||
|
cryptoConfig: {
|
||||||
|
key: "1234567890123456", // 16位密钥(AES-128)
|
||||||
|
iv: "6543210987654321", // 16位初始向量
|
||||||
|
},
|
||||||
|
parseObj: {
|
||||||
|
goods_id: null,
|
||||||
|
agent_id: null,
|
||||||
|
},
|
||||||
|
need_identity: null,
|
||||||
|
imgArr: [],
|
||||||
|
base64: null,
|
||||||
|
form: {
|
||||||
|
cert_name: "",
|
||||||
|
contact_num: "",
|
||||||
|
address: "",
|
||||||
|
post_addr: "",
|
||||||
|
goods: [],
|
||||||
|
agent_id: "",
|
||||||
|
cert_no: "",
|
||||||
|
post_province_name: "",
|
||||||
|
post_city_name: "",
|
||||||
|
post_district_name: "",
|
||||||
|
source: 7,
|
||||||
|
source_type: 1,
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
cert_name: '',
|
||||||
|
contact_num: '',
|
||||||
|
cert_no: '',
|
||||||
|
post_addr: ''
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
async created() {
|
||||||
|
await this.parseData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
validateName() {
|
||||||
|
const name = this.form.cert_name.trim();
|
||||||
|
if (!/^[\u4e00-\u9fa5]{2,}$/.test(name)) {
|
||||||
|
this.errors.cert_name = '请输入至少两个中文字符的姓名';
|
||||||
|
this.$toast.fail('请输入至少两个中文字符的姓名');
|
||||||
|
} else {
|
||||||
|
this.errors.cert_name = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validatePhone() {
|
||||||
|
const phone = this.form.contact_num.trim();
|
||||||
|
if (!/^1[3-9]\d{9}$/.test(phone)) {
|
||||||
|
this.errors.contact_num = '请输入正确的11位手机号';
|
||||||
|
this.$toast.fail('请输入正确的11位手机号');
|
||||||
|
} else {
|
||||||
|
this.errors.contact_num = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validateID() {
|
||||||
|
const id = this.form.cert_no.trim();
|
||||||
|
if (!/^\d{17}[\dXx]$/.test(id)) {
|
||||||
|
this.errors.cert_no = '请输入正确的身份证号码';
|
||||||
|
this.$toast.fail('请输入正确的身份证号码');
|
||||||
|
} else {
|
||||||
|
this.errors.cert_no = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validateAddress() {
|
||||||
|
const addr = this.form.post_addr.trim();
|
||||||
|
if (addr.length < 6) {
|
||||||
|
this.errors.post_addr = '详细地址不能少于6个字';
|
||||||
|
this.$toast.fail('详细地址不能少于6个字');
|
||||||
|
} else {
|
||||||
|
this.errors.post_addr = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async add() {
|
||||||
|
// 提交前统一校验一次
|
||||||
|
this.validateName();
|
||||||
|
this.validatePhone();
|
||||||
|
if (this.need_identity === 1) {
|
||||||
|
this.validateID();
|
||||||
|
}
|
||||||
|
this.validateAddress();
|
||||||
|
|
||||||
|
// 如果没有错误才提交
|
||||||
|
const firstError = Object.values(this.errors).find(err => err);
|
||||||
|
if (firstError) {
|
||||||
|
return this.$toast.fail(firstError);
|
||||||
|
}
|
||||||
|
// 发送下单请求
|
||||||
|
const res = await axios({
|
||||||
|
url: 'https://h5.whjhft.com/api/v1/h5/lot/save',
|
||||||
|
method: 'POST',
|
||||||
|
data: this.form
|
||||||
|
});
|
||||||
|
if (res.data.status === 1) {
|
||||||
|
this.$toast.success("下单成功");
|
||||||
|
this.form = {
|
||||||
|
cert_name: "",
|
||||||
|
contact_num: "",
|
||||||
|
address: "",
|
||||||
|
post_addr: "",
|
||||||
|
goods: [],
|
||||||
|
agent_id: "",
|
||||||
|
cert_no: "",
|
||||||
|
post_province_name: "",
|
||||||
|
post_city_name: "",
|
||||||
|
post_district_name: "",
|
||||||
|
source: 7,
|
||||||
|
source_type: 1,
|
||||||
|
}
|
||||||
|
} else if (res.data.status === 0) {
|
||||||
|
this.$toast.fail(res.data.msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 确定
|
||||||
|
confirm(value) {
|
||||||
|
this.form.address = value.map(item => item.name).join('/')
|
||||||
|
this.form.post_province_name = value[0].name
|
||||||
|
this.form.post_city_name = value[1].name
|
||||||
|
this.form.post_district_name = value[2].name
|
||||||
|
this.cancel()
|
||||||
|
},
|
||||||
|
// 取消
|
||||||
|
cancel() {
|
||||||
|
this.show = false
|
||||||
|
},
|
||||||
|
|
||||||
|
selectArea() {
|
||||||
|
this.show = true
|
||||||
|
},
|
||||||
|
// 解析URL参数
|
||||||
|
async parseData() {
|
||||||
|
// this.encrypted = window.location.href.split('=')[1]
|
||||||
|
const key = CryptoJS.enc.Utf8.parse(this.cryptoConfig.key);
|
||||||
|
const iv = CryptoJS.enc.Utf8.parse(this.cryptoConfig.iv);
|
||||||
|
|
||||||
|
const decrypted = CryptoJS.AES.decrypt(
|
||||||
|
decodeURIComponent(this.encrypted),
|
||||||
|
key,
|
||||||
|
{
|
||||||
|
iv: iv,
|
||||||
|
mode: CryptoJS.mode.CBC,
|
||||||
|
padding: CryptoJS.pad.Pkcs7,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.parseObj = JSON.parse(decrypted.toString(CryptoJS.enc.Utf8));
|
||||||
|
|
||||||
|
this.form.goods = [this.parseObj.goods_id]
|
||||||
|
this.form.agent_id = this.parseObj.agent_id
|
||||||
|
|
||||||
|
// 加密成base64 获取当前图片
|
||||||
|
const base64 = btoa(
|
||||||
|
this.parseObj.agent_id + "_" + this.parseObj.goods_id
|
||||||
|
);
|
||||||
|
|
||||||
|
const {data} = await axios.get(
|
||||||
|
`https://h5.whjhft.com/api/v1/h5/lot?key=${base64}`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (data.status === 0) {
|
||||||
|
await this.$router.push({name: "404"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.imgArr = [
|
||||||
|
data.data.good.top_img,
|
||||||
|
data.data.good.details_img,
|
||||||
|
data.data.good.copyright_img,
|
||||||
|
];
|
||||||
|
|
||||||
|
document.title = data.data.good.good_name;
|
||||||
|
|
||||||
|
this.need_identity = data.data.good.need_identity;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.h5-container {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.topImg {
|
||||||
|
width: 100%;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin: -1px;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
object-fit: cover;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #1b0b0c;
|
||||||
|
padding: 40px 20px;
|
||||||
|
/* height: 500px; */
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.container {
|
||||||
|
border: 1px solid #ffffff;
|
||||||
|
border-radius: 10px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.form-item {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
width: 90px;
|
||||||
|
/* border: 1px solid; */
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
flex: 1;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips{
|
||||||
|
color: white;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 20px;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 15px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #f46c6c;
|
||||||
|
color: white;
|
||||||
|
border-radius: 100px;
|
||||||
|
font-size: 15px;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: inset 0 3px 0 0 hsla(0, 0%, 100%, 0.15),
|
||||||
|
inset 0 -3px 2px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
display: block;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
/* 💥 动画部分 */
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
/* 💥 无限伸缩动画 */
|
||||||
|
animation: pulse 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.08);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.h5-container {
|
||||||
|
max-width: 410px;
|
||||||
|
|
||||||
|
.topImg {
|
||||||
|
width: 100%;
|
||||||
|
aspect-ratio: 1/1;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
margin: -1px;
|
||||||
|
object-fit: cover;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-slide-enter-active, .fade-slide-leave-active {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-slide-enter-from, .fade-slide-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-slide-enter-to, .fade-slide-leave-from {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
42
src/router/index.js
Normal file
42
src/router/index.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import Vue from "vue";
|
||||||
|
import Router from "vue-router";
|
||||||
|
|
||||||
|
Vue.use(Router);
|
||||||
|
|
||||||
|
import H5 from "@/pages/H5.vue";
|
||||||
|
import H5404Page from "@/pages/404.vue";
|
||||||
|
|
||||||
|
export const constantRoutes = [
|
||||||
|
{
|
||||||
|
path: "/h5",
|
||||||
|
name: "H5",
|
||||||
|
component: H5,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: "/404",
|
||||||
|
name: "404",
|
||||||
|
component: H5404Page,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: "/",
|
||||||
|
redirect: "/h5",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: "*",
|
||||||
|
redirect: "/404"
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const createRouter = () =>
|
||||||
|
new Router({
|
||||||
|
mode: "history", // require service support
|
||||||
|
scrollBehavior: () => ({ y: 0 }),
|
||||||
|
routes: constantRoutes,
|
||||||
|
});
|
||||||
|
|
||||||
|
const router = createRouter();
|
||||||
|
|
||||||
|
export default router;
|
||||||
326
test.vue
Normal file
326
test.vue
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<img class="imgs" :src="`https://h5.whjhft.com/static/${imgArr[0]}`" v-show="imgArr[0]">
|
||||||
|
<div class="content">
|
||||||
|
<van-cell-group>
|
||||||
|
<van-field :rules="[{ required: true, message: '请填写用户名' }]" v-model="formData.cert_name" label="收货人姓名" placeholder="请输入收货人姓名" />
|
||||||
|
</van-cell-group>
|
||||||
|
|
||||||
|
<van-cell-group>
|
||||||
|
<van-field v-model="formData.contact_num" label="收货人电话" placeholder="请输入收货人电话" />
|
||||||
|
</van-cell-group>
|
||||||
|
|
||||||
|
<van-cell-group>
|
||||||
|
<van-field v-model="formData.cert_no" label="身份证号" placeholder="请输入身份证号" v-show="need_identity===1"/>
|
||||||
|
</van-cell-group>
|
||||||
|
|
||||||
|
<van-cell-group>
|
||||||
|
<van-field readonly v-model="formData.post_province_name+formData.post_city_name+formData.post_district_name" label="地区" placeholder="请选择地区" @click="showPopup"/>
|
||||||
|
</van-cell-group>
|
||||||
|
|
||||||
|
<div class="popup">
|
||||||
|
<van-popup v-model="show" position="bottom" :style="{ height: '30%' }" >
|
||||||
|
<van-area title="选择地区" :area-list="areaList" @confirm="handleConfirm" @cancel="handleCancel"/>
|
||||||
|
</van-popup>
|
||||||
|
</div>
|
||||||
|
<van-cell-group>
|
||||||
|
<van-field v-model="formData.post_addr" label="详细地址" placeholder="请输入详细地址" />
|
||||||
|
</van-cell-group>
|
||||||
|
<button class="vbuttons" @click="submit">立即领取,包邮到家</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<img class="imgs" :src="`https://h5.whjhft.com/static/${imgArr[1]}`" v-show="imgArr[1]" >
|
||||||
|
|
||||||
|
|
||||||
|
<img class="imgs" :src="`https://h5.whjhft.com/static/${imgArr[2]}`" v-show="imgArr[2]">
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import areaData from 'china-area-data';
|
||||||
|
import { Base64 } from "js-base64";
|
||||||
|
import axios from "axios";
|
||||||
|
import { Toast } from 'vant';
|
||||||
|
import CryptoJS from 'crypto-js'; // 引入 CryptoJS
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
need_identity:null,
|
||||||
|
base64:null,
|
||||||
|
show: false,
|
||||||
|
urlos: null,
|
||||||
|
id_goods: null,
|
||||||
|
id_agent: null,
|
||||||
|
imgArr: [],
|
||||||
|
encrypted: 'https://example.com/product?data=DiW0XlB6rznMFVtUopdDj6CyL%2FGYjEubPEyOZRCjmtzZco97wHy9bLPo%2BnZdqureW%2BynJnIR%2Biktz5HNWrvLOg%3D%3D',
|
||||||
|
areaList: {},
|
||||||
|
value: '',
|
||||||
|
formData: {
|
||||||
|
cert_name: "",
|
||||||
|
contact_num: "",
|
||||||
|
address: "",
|
||||||
|
addressOption: [],
|
||||||
|
post_addr: "",
|
||||||
|
goods: [],
|
||||||
|
agent_id: "",
|
||||||
|
cert_no: "",
|
||||||
|
post_province_name: "",
|
||||||
|
post_city_name: "",
|
||||||
|
post_district_name: "",
|
||||||
|
source: 7,
|
||||||
|
source_type: 1
|
||||||
|
},
|
||||||
|
// CryptoJS 解密配置(需与加密端一致)
|
||||||
|
cryptoConfig: {
|
||||||
|
key: '1234567890123456', // 16位密钥(AES-128)
|
||||||
|
iv: '6543210987654321' // 16位初始向量
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
async created() {
|
||||||
|
console.log(window.location.href);
|
||||||
|
// await this.Parse(this.encrypted);
|
||||||
|
this.formatAreaData();
|
||||||
|
// const result = window.location.href.split('=')[1]
|
||||||
|
const result = 'ffMngb0kTzCgTwjPAt7KY0yAtF4784R3VRxzhlVEM5PMZn4xXT4XvuVLXFkQqZyXVS5Cnsd3WRpKaQIQh%2BLn0Q%3D%3D'
|
||||||
|
await this.getLink(result)
|
||||||
|
const {data} = await axios.get(`https://h5.whjhft.com/api/v1/h5/lot?key=${this.base64}`);
|
||||||
|
console.log(data)
|
||||||
|
this.imgArr=[
|
||||||
|
data.data.good.top_img,
|
||||||
|
data.data.good.details_img,
|
||||||
|
data.data.good.copyright_img,
|
||||||
|
data.data.good.customize_img,
|
||||||
|
]
|
||||||
|
this.need_identity=data.data.good.need_identity
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getLink(encrypted){
|
||||||
|
console.log(encrypted)
|
||||||
|
const key = CryptoJS.enc.Utf8.parse('1234567890123456');
|
||||||
|
const iv = CryptoJS.enc.Utf8.parse('6543210987654321');
|
||||||
|
|
||||||
|
const decrypted = CryptoJS.AES.decrypt(decodeURIComponent(encrypted), key, {
|
||||||
|
iv: iv,
|
||||||
|
mode: CryptoJS.mode.CBC,
|
||||||
|
padding: CryptoJS.pad.Pkcs7,
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = JSON.parse(decrypted.toString(CryptoJS.enc.Utf8));
|
||||||
|
this.formData.goods=[
|
||||||
|
result.goods_id
|
||||||
|
]
|
||||||
|
this.formData.agent_id=result.agent_id
|
||||||
|
// console.log(btoa(result.agent_id+'_'+result.goods_id))
|
||||||
|
// console.log(btoa(result.agent_id+'_'+))
|
||||||
|
console.log(result.goods_id)
|
||||||
|
result.goods_id=53
|
||||||
|
this.base64=btoa(result.agent_id+'_'+result.goods_id)
|
||||||
|
},
|
||||||
|
showPopup() {
|
||||||
|
this.show = true;
|
||||||
|
},
|
||||||
|
async submit() {
|
||||||
|
|
||||||
|
// 提交逻辑保持不变
|
||||||
|
const res = await axios({
|
||||||
|
url: 'https://h5.whjhft.com/api/v1/h5/lot/save',
|
||||||
|
method: 'POST',
|
||||||
|
data: this.formData
|
||||||
|
});
|
||||||
|
if (res.data.status === 1) {
|
||||||
|
Toast.success("提交成功");
|
||||||
|
} else if (res.data.status === 0) {
|
||||||
|
Toast.fail(res.data.msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formatAreaData() {
|
||||||
|
// 地区数据格式化逻辑保持不变
|
||||||
|
const result = {
|
||||||
|
province_list: {},
|
||||||
|
city_list: {},
|
||||||
|
county_list: {}
|
||||||
|
};
|
||||||
|
if (areaData['86']) {
|
||||||
|
result.province_list = areaData['86'];
|
||||||
|
}
|
||||||
|
Object.keys(result.province_list).forEach(provinceCode => {
|
||||||
|
const cities = areaData[provinceCode] || {};
|
||||||
|
Object.keys(cities).forEach(cityCode => {
|
||||||
|
if (typeof cities[cityCode] === 'object') {
|
||||||
|
result.city_list[cityCode] = cityCode;
|
||||||
|
} else {
|
||||||
|
result.city_list[cityCode] = cities[cityCode];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Object.keys(result.city_list).forEach(cityCode => {
|
||||||
|
const counties = areaData[cityCode] || {};
|
||||||
|
Object.keys(counties).forEach(countyCode => {
|
||||||
|
result.county_list[countyCode] = counties[countyCode];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.areaList = result;
|
||||||
|
console.log('格式化后的地区数据:', this.areaList);
|
||||||
|
},
|
||||||
|
handleConfirm(values) {
|
||||||
|
this.formData.post_province_name=values[0].name
|
||||||
|
this.formData.post_city_name=values[1].name
|
||||||
|
this.formData.post_district_name=values[2].name
|
||||||
|
this.formData.address=values[0].name+values[1].name+values[2].name
|
||||||
|
this.formData.addressOption=[
|
||||||
|
values[0].name,values[1].name,values[2].name
|
||||||
|
]
|
||||||
|
this.show = false;
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
handleCancel() {
|
||||||
|
this.show = false;
|
||||||
|
},
|
||||||
|
async Parse(urls) {
|
||||||
|
try {
|
||||||
|
console.log(urls);
|
||||||
|
const url = new URL(urls);
|
||||||
|
const dataParam = url.searchParams.get('data'); // 获取加密的data参数
|
||||||
|
console.log('原始加密参数:', dataParam);
|
||||||
|
|
||||||
|
// ====================== 核心修改:使用 CryptoJS 解密 ======================
|
||||||
|
// 1. Base64解码(如果参数是Base64编码的,需先解码)
|
||||||
|
const base64Decoded = Base64.decode(dataParam);
|
||||||
|
// 2. AES-CBC解密(需与加密端的密钥、IV、模式一致)
|
||||||
|
const decryptedBytes = CryptoJS.AES.decrypt(
|
||||||
|
base64Decoded,
|
||||||
|
CryptoJS.enc.Utf8.parse(this.cryptoConfig.key), // 密钥
|
||||||
|
{
|
||||||
|
iv: CryptoJS.enc.Utf8.parse(this.cryptoConfig.iv), // 初始向量
|
||||||
|
mode: CryptoJS.mode.CBC, // 加密模式
|
||||||
|
padding: CryptoJS.pad.Pkcs7 // 填充方式
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const decodedKey = decryptedBytes.toString(CryptoJS.enc.Utf8); // 转换为明文
|
||||||
|
// ====================== 修改结束 ======================
|
||||||
|
|
||||||
|
console.log('解密后数据:', decodedKey);
|
||||||
|
// 解析解密后的ID(假设格式为 "agentId_goodsId")
|
||||||
|
const [id_agent, id_goods] = decodedKey.split('_');
|
||||||
|
this.id_goods = Number(id_goods);
|
||||||
|
this.id_agent = id_agent;
|
||||||
|
console.log('商品ID:', this.id_goods, '代理商ID:', this.id_agent);
|
||||||
|
|
||||||
|
// 加载商品图片逻辑保持不变
|
||||||
|
const res = await axios.get(url.origin + '/api/v1/h5/lot?key=' + dataParam);
|
||||||
|
this.imgArr = [
|
||||||
|
res.data.data.good.top_img,
|
||||||
|
res.data.data.good.customize_img,
|
||||||
|
res.data.data.good.details_img
|
||||||
|
];
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解码/请求失败:', error);
|
||||||
|
Toast.fail('数据解析失败,请检查链接');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 新增自适应基础样式 */
|
||||||
|
html {
|
||||||
|
font-size: 50px; /* 375px宽度下的基准值(1rem=50px) */
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
*, *::before, *::after {
|
||||||
|
box-sizing: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 输入框相关自适应调整(优化原有样式) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 其他原有样式保持不变 */
|
||||||
|
.imgs{
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.imgs{
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
body{
|
||||||
|
max-width: 100vw;
|
||||||
|
overflow-x: hidden;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.content{
|
||||||
|
padding: 0.1rem;
|
||||||
|
margin: 5px;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
.vbuttons {
|
||||||
|
border-radius: 11115px;
|
||||||
|
background-color: #f46c6c;
|
||||||
|
color: white;
|
||||||
|
font-size: 15px;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: 0 2px 8px rgba(73, 147, 170, 0.2);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
animation: heart 1s infinite;
|
||||||
|
}
|
||||||
|
.vbuttons:active {
|
||||||
|
transform: scale(0.98);
|
||||||
|
box-shadow: 0 1px 4px rgba(73, 147, 170, 0.4);
|
||||||
|
}
|
||||||
|
@keyframes heart {
|
||||||
|
0%, 100% { transform: scale(1); }
|
||||||
|
50% { transform: scale(1.1); animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 1280px) {
|
||||||
|
/* 限制页面最大宽度并居中 */
|
||||||
|
body {
|
||||||
|
max-width: 1280px;
|
||||||
|
margin: 10px auto;
|
||||||
|
overflow-x: hidden; /* 隐藏可能出现的横向滚动条 */
|
||||||
|
.van-picker{
|
||||||
|
max-width: 1280px !important;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-picker__cancel{
|
||||||
|
|
||||||
|
}
|
||||||
|
.van-picker__confirm{
|
||||||
|
|
||||||
|
}
|
||||||
|
.van-picker__title{
|
||||||
|
|
||||||
|
}
|
||||||
|
*{
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
.vbuttons{
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 可选:调整大屏下的根字体大小(保持设计稿比例) */
|
||||||
|
html {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
4
vue.config.js
Normal file
4
vue.config.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
const { defineConfig } = require('@vue/cli-service')
|
||||||
|
module.exports = defineConfig({
|
||||||
|
transpileDependencies: true
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user