feat: 质惠游 H5 一期 —— 门票模块全链路(微信公众号版)

从 xghmall(云闪付版湘工游)迁移民票模块,改造为微信公众号 H5:

- 技术栈沿用 uni-app + Vue2 + uView(含定制版日历组件)
- 登录/支付独立成层(common/auth.js、common/pay.js):
  一期假登录(测试手机号)+ 模拟支付,后端微信接口就绪后只换这两处
- 登录页重写:短信验证码 + 公众号网页授权(code 换用户信息)预留
- 门票列表页为入口页(进页必须登录),加订单悬浮按钮
- 支付成功页接通:查看订单/继续逛逛 + 订单状态轮询
- 详情页定位导航改用 uni.openLocation + 高德网页兜底
- 出行人页:身份证 18 位格式校验,删除死的删除按钮,修正证件类型回显笔误
- 清理云闪付 SDK、支付宝授权、死页面引用等残留

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
xuchao
2026-07-21 00:43:59 +08:00
co-authored by Claude Opus 4.8
commit 4190565eb7
192 changed files with 35664 additions and 0 deletions
@@ -0,0 +1,189 @@
<template name="gmy-float-touch">
<view>
<view @touchmove.stop.prevent = "doNothing" >
<view class="box" style="z-index: 999;" @click="show" :style="{top:top+'px',left:left + 'px'}" @touchmove="touchmove" @touchend="touchend">
<image :src="mainImg" mode="aspectFill" :animation="animationData" ></image>
<!-- <text style="font-size: 20rpx;color: #fff;">订单</text> -->
</view>
<!-- <view class="menu " :class="{menu0:!isShow&&isleft,menu1:isShow&&isleft ,menu1R:isShow&& !isleft ,menu0R:!isShow&& !isleft}" :style="{top:(top-75) +'px'}" @tap="menuClick(1)" >
<image :src="imgLists[0]" mode=""></image>
</view> -->
<!-- xuchao: 质惠游一期只有门票模块,仅保留"门票订单"菜单项 -->
<view class="menu " :class="{menu0:!isShow&&isleft,menu4:isShow&&isleft ,menu4R:isShow&& !isleft ,menu0R:!isShow&& !isleft}" :style="{top:top+'px'}" @tap="menuClick(4)">
<image :src="imgLists[3]" mode="aspectFill"></image>
</view>
</view>
</view>
</template>
<script>
export default{
name:"gmy-float-touch",
data(){
return {
isShow:false,
top:500,
left:3,
right:3,
isleft:true,
animationData:''
}
},
props:{
imgLists:{
type:Array
},
mainImg:{
type:String,
default:"../../static/main.png"
}
},
methods:{
doNothing:function(){},
show:function(){
this.isShow = !this.isShow;
this.spred();
},
touchmove:function(e){
if(this.isShow){
return
}
var position = e.touches[0];
var wHeight = this.getSystemInfo('H');
if(position.pageY>50 && position.pageY+50 < wHeight){
this.top = position.pageY-20;
}
this.left = position.pageX;
},
touchend:function(e){
var wWidth = this.getSystemInfo('W');
const pageX = e.changedTouches[0].clientX;
if(pageX > wWidth*0.5){
this.isleft = false;
this.left = wWidth-50;
}
else{
this.isleft = true;
this.left = 3;
}
},
menuClick:function(index){
this.$emit("menuClick",index);
},
getSystemInfo:function(type){
var result;
const screen = uni.getSystemInfoSync();
const wHeight = screen.windowHeight;
const wWidth = screen.windowWidth;
switch(type){
case 'H':result = wHeight;break;
case 'W':result = wWidth;break;
default: result = 'Err';
}
return result;
},
spred:function(e){
var animation = uni.createAnimation({
duration: 200,
timingFunction: 'ease',
});
this.animationData = animation.export();
if(this.isShow){
animation.rotate(135).step();
}
else{
animation.rotate(0).step();
}
this.animationData = animation.export();
},
}
}
</script>
<style lang="scss">
image{
width: 80upx;
height: 80upx;
z-index: 99;
// margin:10upx 20upx 10upx 20upx;
}
.box{
position: fixed;
left: 5upx;
top: 70%;
width: 80upx;
height: 80upx;
// border-radius: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
// background-color: rgba($color: #777, $alpha: 0.4);
}
.menu{
color:white;
position: fixed;
width: 80upx;
height: 80upx;
// border-radius: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
// background-color: rgba($color: #777, $alpha: 0.4);
}
.menu0{
left: 5upx;
opacity: 0;
transition: top 0.2s, left 0.2s, opacity 0.2s;
}
.menu1{
left: 20upx;
transition: top 0.2s, left 0.2s, opacity 0.2s;
}
.menu2{
left: 10upx;
transition: top 0.2s, left 0.2s, opacity 0.2s;
}
.menu3{
left: 205upx;
transition: top 0.2s, left 0.2s, opacity 0.2s;
}
.menu4{
left: 106upx;
transition: top 0.2s, left 0.2s, opacity 0.2s;
}
.menu5{
left: 5upx;
transition: top 0.2s, left 0.2s, opacity 0.2s;
}
.menu0R{
right: 10upx;
opacity: 0;
transition: top 0.2s, right 0.2s, opacity 0.2s;
}
.menu1R{
right: 20upx;
transition: top 0.2s, right 0.2s, opacity 0.2s;
}
.menu2R{
right: 20upx;
transition: top 0.2s, right 0.2s, opacity 0.2s;
}
.menu3R{
right: 210upx;
transition: top 0.2s, right 0.2s, opacity 0.2s;
}
.menu4R{
right: 106upx;
transition: top 0.2s, right 0.2s, opacity 0.2s;
}
.menu5R{
right: 20upx;
transition: top 0.2s, right 0.2s, opacity 0.2s;
}
</style>
+14
View File
@@ -0,0 +1,14 @@
# 仿苹果悬浮按钮
## 只需再页面中调用插件,在监听menuClick事件即可,该事件返回五个小按钮的索引从上往下索引一次是1,2,3,4,5。具体事件由用户根据索引自定义
## 如果需要使用图标请在使用时传入,数据说明
* mainImg:主图标,不可隐藏,图片单独设置。
* imgLists:弹出菜单图标,共5个菜单,故需5个图标,以数组形式设置
### 使用
* import gmyFloatTouch from "../../../components/gmy-float-touch/gmy-float-touch.vue" //引用
* <gmy-float-touch :imgLists="imgLists" :mainImg="mainImg" @menuClick="floatTouchClick"></gmy-float-touch> //页面使用
* floatTouchClick:function(e){ //事件
console.log(e);
},
* mainImg:"../../static/main.png", //数据格式
imgLists:["../../static/home.png","../../static/approve.png","../../static/match.png","../../static/send.png","../../static/return.png"],