first commit

This commit is contained in:
sexygoat
2026-01-22 16:43:48 +08:00
parent 36590e3cc0
commit 777265209a
15 changed files with 16425 additions and 0 deletions

425
src/pages/H5.vue Normal file
View 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>