完成携程机票修改视频聊天逻辑

This commit is contained in:
tangxinyue 2026-02-12 18:43:48 +08:00
parent cf60f79906
commit c6dcc7ab4d
15 changed files with 2196 additions and 2067 deletions

View File

@ -1,9 +1,11 @@
<template>
<view style="width: 100%;" :style="{ height: `calc(${data.statusBarHeight}px + 88rpx)` }">
<slot name="statusBar"></slot>
<!-- <slot name="statusBar"></slot> -->
</view>
<view class="nav-bar-container" :style="{ backgroundColor: bgColor, zIndex: zIndex }">
<view class="status-placeholder" :style="{ height: `${data.statusBarHeight}px` }"></view>
<view class="status-placeholder" :style="{ height: `${data.statusBarHeight}px` }">
<slot name="statusBar"></slot>
</view>
<view style="width: 100%;height: 88rpx;" @click="openPopup">
<slot>
<uni-nav-bar backgroundColor="#00000000" class="nav-bar" :border="false" :title="title" v-bind="$attrs"

View File

@ -6,14 +6,15 @@
<image v-if="dark=='light'" class="colse" src="/static/image/watermarkColseLight.png" mode=""></image>
<image v-else class="colse" src="/static/image/watermarkColseDark.png" mode=""></image> -->
<image class="watermarkImg" src="/static/image/watermark.png" mode=""></image>
<image class="colse" src="/static/image/watermarkColse.png" mode="" @click="$goRechargePage('watermark_close')"></image>
<image class="colse" src="/static/image/watermarkColse.png" mode=""
@click="$goRechargePage('watermark_close')"></image>
</view>
</view>
</template>
<script>
export default {
export default {
props: {
dark: {
type: String,
@ -37,11 +38,11 @@
console.log('状态栏高度:', this.statusBarHeight + 'px')
}
},
}
}
</script>
<style lang="scss">
.watermark {
.watermark {
pointer-events: none;
width: 100vw;
position: fixed;
@ -56,6 +57,7 @@
z-index: 99 !important;
background-image: url('/static/image/watermarkBG.png');
background-size: 125px 125px;
.watermarkBox {
width: 200px;
height: 255px;
@ -77,5 +79,5 @@
height: 55px;
pointer-events: none;
}
}
}
</style>

View File

@ -27,7 +27,7 @@ export function createApp() {
const systemInfo = uni.getStorageSync('systemInfo') || {}
app.config.globalProperties.$system = systemInfo.platform == 'ios' ? 'iOS' : 'Android'
app.config.globalProperties.$systemInfo = systemInfo
uni.setStorageSync('version', '1.0.1.sp5')
uni.setStorageSync('version', '1.0.2.sp4')
app.config.globalProperties.$version = uni.getStorageSync('version')
app.use(globalMethods);

View File

@ -260,20 +260,20 @@
<script setup>
import customTab from "@/components/custom-tab/custom-tab.vue"
import countUp from "@/components/countUp/countUp.vue"
import {
import customTab from "@/components/custom-tab/custom-tab.vue"
import countUp from "@/components/countUp/countUp.vue"
import {
postJson
} from "@/utils/requests.js"
import {
} from "@/utils/requests.js"
import {
ref,
reactive,
getCurrentInstance,
watch,
nextTick,
toRefs
} from "vue";
import {
} from "vue";
import {
onLoad,
onShow,
onReady,
@ -281,55 +281,55 @@
onReachBottom,
onBackPress,
onUnload
} from "@dcloudio/uni-app";
const {
} from "@dcloudio/uni-app";
const {
appContext,
proxy
} = getCurrentInstance();
const popup = ref();
const coupon = ref();
const couponBox = ref();
const myCoupon = ref();
const dialogVipBenefits = [{
} = getCurrentInstance();
const popup = ref();
const coupon = ref();
const couponBox = ref();
const myCoupon = ref();
const dialogVipBenefits = [{
name: "模拟微信",
url: "/static/image/recharge/moniweixinDialog.png"
},
{
},
{
name: "无广告",
url: "/static/image/recharge/wuguanggaoDialog.png"
},
{
},
{
name: "无水印",
url: "/static/image/recharge/wushuiyinDialog.png"
},
{
},
{
name: "专属客服",
url: "/static/image/recharge/zhuanshukefuDialog.png"
}
]
}
]
//
const packageList = [{
//
const packageList = [{
name: "连续包月",
delPrice: "89",
price: "29",
lifespan: "一月"
},
{
},
{
name: "连续包季",
delPrice: "189",
price: "98",
lifespan: "一季"
},
{
},
{
name: "连续包年",
delPrice: "365",
price: "198",
lifespan: "一年"
}
]
}
]
const data = reactive({
const data = reactive({
scrollLeft: 0,
active_id: 0,
active_ids: 0,
@ -433,29 +433,29 @@
//
isProcessingClick: false,
banner: '/static/image/recharge/banner1.png',
})
})
let {
let {
buttonText,
selected,
benefitList,
noticeList,
commentList,
paymentMethod
} = toRefs(data)
} = toRefs(data)
/**
/**
* 返回监听
*/
onBackPress((e) => {
onBackPress((e) => {
if (e.from == 'backbutton' && data.appUser.vip == 1) {
open()
return true; //
}
})
})
onLoad(async () => {
onLoad(async () => {
const config = uni.getStorageSync('config').config
const themeConfig = config?.['client.uniapp.theme']
if (themeConfig?.enable) {
@ -595,15 +595,15 @@
})
}
})
})
onShow(async () => {
onShow(async () => {
})
onUnload(() => {
})
onUnload(() => {
// uni.offNativeEventReceive()
})
onReady(() => {
})
onReady(() => {
try {
if (plus.os.name === 'Android') {
let color = plus.android.newObject("android.graphics.Color");
@ -618,7 +618,7 @@
}
})
console.log("状态栏设置完毕!");
setTimeout(function() {
setTimeout(function () {
uni.setNavigationBarColor({
backgroundColor: '#fff',
animation: { //
@ -627,18 +627,18 @@
}
})
}, 200);
setTimeout(function() {
setTimeout(function () {
plus.navigator.setStatusBarStyle("light");
}, 200);
}
} catch (error) {
//TODO handle the exception
}
})
})
function isToday(inputTime) {
function isToday(inputTime) {
//
const today = new Date();
today.setHours(0, 0, 0, 0);
@ -651,9 +651,9 @@
//
return inputTimestamp === todayTimestamp;
}
}
function calculateTimeRemaining(targetTime) {
function calculateTimeRemaining(targetTime) {
//
const target = new Date(targetTime).getTime();
const now = new Date().getTime();
@ -688,9 +688,9 @@
minutes: minutes,
seconds: seconds
};
}
}
function activeClick(status) {
function activeClick(status) {
myCoupon.value.close()
if (status && data.active_ids > 0) {
let item = data.activeitems
@ -707,14 +707,14 @@
setPrice(true)
}, 1000);
}
}
}
function setActiveId(item) {
function setActiveId(item) {
data.active_ids = item.id
data.activeitems = item
}
}
function setPrice(status) {
function setPrice(status) {
console.log("setPrice")
if (data.incrementTimer) {
clearInterval(data.incrementTimer);
@ -796,9 +796,9 @@
console.log("最后", data.price)
}
/* 获取我的优惠券 */
async function getActivity() {
}
/* 获取我的优惠券 */
async function getActivity() {
let activity = await proxy.$requestPromise({
url: 'api/activity/coupon',
method: "GET",
@ -830,9 +830,9 @@
]
data.myActivity = deduplicateKeepLast(data.myActivity)
}
}
}
function deduplicateKeepLast(arr, idKey = 'id') {
function deduplicateKeepLast(arr, idKey = 'id') {
const map = new Map();
arr.forEach(item => {
@ -841,10 +841,10 @@
});
return Array.from(map.values());
}
}
/* 领取优惠券 */
async function submitActivity() {
/* 领取优惠券 */
async function submitActivity() {
console.log("activity_id");
let activity_id = ''
data.activity.forEach(item => {
@ -879,24 +879,24 @@
})
}
}
/**
}
/**
* @param {Object} item
* @param {Object} index
* 选择购买套餐
*/
/*
防抖
*/
const debouncedOnSelect = debounce((items, index) => {
/*
防抖
*/
const debouncedOnSelect = debounce((items, index) => {
onSelect(items, index);
}, 200, false);
}, 200, false);
function debounce(func, wait, immediate = true) {
function debounce(func, wait, immediate = true) {
let timeout;
return function(...args) {
return function (...args) {
const later = () => {
timeout = null;
if (!immediate) func(...args);
@ -908,8 +908,8 @@
if (callNow) func(...args);
};
}
async function onSelect(items, index) {
}
async function onSelect(items, index) {
data.active_id = 0
data.activeCoupon = {}
data.active_ids = 0
@ -1016,22 +1016,22 @@
]
}
paymentMethod.value = data.payList[0].type
setTimeout(function() {
setTimeout(function () {
data.countdown = true
}, 100);
await setPrice(true)
await getActivity()
}
/**
}
/**
* @param {Object} value
* 选择支付方式
*/
function onSelectPayment(value) {
function onSelectPayment(value) {
paymentMethod.value = value
}
}
function open() {
function open() {
uni.setStorageSync('back_number', data.back_number + 1);
// refuni-popup , type ['top','left','bottom','right','center']
@ -1061,12 +1061,12 @@
coupon.value.open()
}
}
}
/**
/**
* 随机生成通知列表
*/
function generateNoticeList() {
function generateNoticeList() {
noticeList.value = []
for (let i = 0; i <= 10; i++) {
noticeList.value.push({
@ -1075,11 +1075,11 @@
package: getRandomItem()
})
}
}
/**
}
/**
* 下单拉取支付
*/
async function activateVip(type = '') {
async function activateVip(type = '') {
if (type == 'back') {
proxy.$apiUserEvent('all', {
type: "click",
@ -1154,13 +1154,13 @@
uni.requestPayment({
provider: paymentMethod.value,
orderInfo: payData, //
success: function(resss) {
success: function (resss) {
setTimeout(() => {
uni.hideLoading();
}, 30000);
paymentResult(paymentRes.data.orderId, paymentMethod.value)
},
fail: function(err) {
fail: function (err) {
proxy.$apiUserEvent('all', {
type: "event",
key: "pay_fail",
@ -1201,11 +1201,11 @@
setTimeout(() => {
uni.hideLoading();
}, 10000);
}
}
//
async function paymentResult(orderId, paytype) {
//
async function paymentResult(orderId, paytype) {
uni.hideLoading();
uni.showLoading({
title: '会员发放排队中,正在实时向服务器索要,请耐心等待。',
@ -1311,19 +1311,19 @@
//
poll();
}
}
//
function getRandomItem() {
//
function getRandomItem() {
const list = ['月度会员', '季度会员', '年度会员'];
const randomIndex = Math.floor(Math.random() * list.length);
return list[randomIndex];
}
}
/**
/**
* 随机生成时间提示语
*/
function generateNaturalTimeAgo() {
function generateNaturalTimeAgo() {
const weights = [{
range: [1, 30],
weight: 30,
@ -1390,12 +1390,12 @@
const amount = Math.floor(Math.random() * (max - min + 1)) + min;
return `${amount}${selected.unit}`;
}
}
/**
/**
* 随机生成电话号码
*/
function generateMaskedPhoneNumber() {
function generateMaskedPhoneNumber() {
//
const prefixes = [
'130', '131', '132', '133', '134', '135', '136', '137', '138', '139',
@ -1418,13 +1418,13 @@
// 43 + **** + 4
return fullNumber.replace(/(\d{3})(\d{4})(\d{4})/, '$1****$3');
}
}
/**
/**
* 返回
*/
function back() {
function back() {
proxy.$apiUserEvent('all', {
type: "click",
key: "recharge_dialog_cancel",
@ -1440,14 +1440,14 @@
}
})
uni.navigateBack();
}
}
function Complete() {
function Complete() {
data.coupon = false
console.log("播放完成");
}
}
function shouldBeTrue(obj) {
function shouldBeTrue(obj) {
// 1: features true
if (!('features' in obj)) {
return false;
@ -1465,15 +1465,15 @@
// 4: features alipay false
return true;
}
}
</script>
<style lang="scss" scoped>
* {
* {
box-sizing: content-box;
}
}
.couponBox {
.couponBox {
width: 375px;
height: 450px;
position: relative;
@ -1584,18 +1584,18 @@
top: -145px;
z-index: 3;
}
}
}
.couponButton {
.couponButton {
position: relative;
margin-top: 37px;
width: 305px;
height: 86px;
margin-left: calc(50% - 152.5px);
z-index: 4 !important;
}
}
.page-container {
.page-container {
background-color: #F7F7F7;
padding-bottom: 240rpx;
padding-bottom: calc(240rpx + constant(safe-area-inset-bottom)) !important;
@ -1758,9 +1758,9 @@
}
}
@keyframes vertical-scroll {
@keyframes vertical-scroll {
from {
transform: translateY(100%);
}
@ -1768,9 +1768,9 @@
to {
transform: translateY(-100%);
}
}
}
.footer-container {
.footer-container {
position: fixed;
left: 0;
right: 0;
@ -1870,13 +1870,13 @@
flex-shrink: 0;
opacity: 0;
text-align: center;
height: 100%;
height: 104rpx;
width: 32%;
}
}
}
}
.dialog-container {
.dialog-container {
display: flex;
flex-direction: column;
width: 80vw;
@ -2001,16 +2001,16 @@
}
}
}
}
.back {
.back {
position: fixed;
top: 100rpx;
left: 36rpx;
z-index: 1;
}
}
.uni-margin-wrap::after {
.uni-margin-wrap::after {
// position: absolute;
// content: '';
// left: 0;
@ -2019,9 +2019,9 @@
// height: 18px;
// background-color: #f7f7f7;
// border-radius: 16px 16px 0px 0px;
}
}
.uni-margin-wrap {
.uni-margin-wrap {
// position: relative;
height: auto;
width: 100%;
@ -2075,11 +2075,11 @@
padding: 0 100rpx;
}
}
}
.placeholder {
.placeholder {
// display: none;
// position: relative;
// background-color: #f7f7f7;
@ -2087,20 +2087,20 @@
// border-radius: 1rem 1rem 0 0;
// left: 0;
// bottom: 30rpx;
}
}
/* 由小到大缩放动画 */
.animated-box {
/* 由小到大缩放动画 */
.animated-box {
animation: scaleIn 1s ease-out forwards;
}
}
/* 延迟动画 */
.scale-in-delay {
/* 延迟动画 */
.scale-in-delay {
animation: scaleIn 0.5s ease-out 0.2s forwards;
}
}
/* 动画关键帧定义 */
@keyframes scaleIn {
/* 动画关键帧定义 */
@keyframes scaleIn {
0% {
transform: scale(0);
opacity: 0;
@ -2114,17 +2114,17 @@
transform: scale(1);
opacity: 1;
}
}
}
.iosQuestion {
.iosQuestion {
.titleBox {
.image {
margin-top: 3px !important;
}
}
}
}
.question {
.question {
margin: 24rpx 32rpx;
padding: 17px 13px;
background-color: #FFFFFF;
@ -2161,9 +2161,9 @@
color: #AAAAAA;
}
}
}
}
.myCouponList {
.myCouponList {
margin: 24rpx 32rpx;
padding: 17px 13px;
@ -2231,9 +2231,9 @@
}
}
}
}
}
.myCouponContainer {
.myCouponContainer {
width: calc(100% - 52px);
height: 400px;
background-image: url('/static/image/recharge/myCouponContainerBg.png');
@ -2371,16 +2371,16 @@
color: #fff;
font-size: 20px;
}
}
}
.white-flow {
.white-flow {
background: linear-gradient(-45deg, transparent, transparent, transparent, transparent, transparent, transparent, transparent, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2), transparent, transparent, transparent, transparent, transparent, transparent, transparent);
background-repeat: no-repeat;
background-size: 60% 100%;
animation: flow 2s infinite linear;
}
}
@keyframes flow {
@keyframes flow {
0% {
background-position: -100% 0;
}
@ -2388,25 +2388,25 @@
100% {
background-position: 200% 0;
}
}
}
::v-deep .uni-countdown-day {
::v-deep .uni-countdown-day {
width: auto !important;
color: #2A2617 !important;
/* 例如,将文字颜色改为红色 */
background-color: transparent !important;
margin-right: 0 !important;
padding-right: 0 !important;
}
}
::v-deep .uni-countdown-splitor-day {
::v-deep .uni-countdown-splitor-day {
margin-left: 0 !important;
}
}
.yanhua {
.yanhua {
position: fixed;
top: 170px;
left: 15px;
z-index: 999999;
}
}
</style>

View File

@ -1,5 +1,12 @@
<template>
<view class="codefun-flex-col page">
<!-- 水印 -->
<view v-if="$isVip()">
<watermark dark="light" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button>
</view>
<view class="codefun-flex-col page" :style="{ '--font-weight-bold': $system == 'iOS' ? 500 : 700 }">
<view class="codefun-flex-col group">
@ -8,7 +15,7 @@
<NavBar title="订单详情" textColor="#fff" :bgColor="data.navBar.bgColor" :buttonGroup="buttonGroup"
@button-click="util.clickTitlePopupButton" tipLayerType="ctrip-air-tickets-tip" isTipLayer
tipLayerText="修改机票信息">
<template v-slot:statusBar>
<template v-if="$system == 'iOS'" v-slot:statusBar>
<view class="status-bar">
<image class="top-logo" style="width: 160rpx"
src="/static/image/other/air-tickets/ctrip-air/top-logo.png" mode="widthFix">
@ -20,7 +27,8 @@
<view class="text">订单详情</view>
<view class="level">
<image style="width: 100%"
:src="`/static/image/other/air-tickets/ctrip-air/level-1.png`" mode="widthFix">
:src="`/static/image/other/air-tickets/ctrip-air/level-${airTicketsInfo.ctripOrderInfo.level}.png`"
mode="widthFix">
</image>
</view>
</view>
@ -110,7 +118,8 @@
<view class="codefun-flex-row codefun-justify-between codefun-items-center">
<view class="codefun-flex-row codefun-items-center">
<text class="font_6 text_56">总计</text>
<text class="font_7 text_21 codefun-ml-8">¥{{ airTicketsInfo.orderInfo.price }}</text>
<text class="font_7 text_21 codefun-ml-8" @click="goEdit">¥{{ airTicketsInfo.orderInfo.price
}}</text>
<uni-icons class="codefun-shrink-0 codefun-ml-4" type="help" size="18"
color="#006FEF"></uni-icons>
</view>
@ -136,7 +145,7 @@
</view>
<view class="codefun-flex-col group_9">
<view class="codefun-flex-row codefun-justify-between codefun-items-center codefun-self-stretch">
<view class="codefun-flex-row">
<view class="codefun-flex-row" @click="goEdit">
<image class="codefun-shrink-0 image_13"
src="/static/image/other/air-tickets/ctrip-air/airplant.png" />
<text class="codefun-self-center font_6 text_64 codefun-ml-6">{{
@ -157,7 +166,7 @@
<text class="codefun-self-start font_8 text_30">{{ flightInfo.year }} {{ flightInfo.date }} {{
flightInfo.week
}}</text>
<view class="codefun-flex-row codefun-items-center codefun-self-stretch group_10">
<view class="codefun-flex-row codefun-items-center codefun-self-stretch group_10" @click="goEdit">
<image class="codefun-shrink-0 image_15"
src="/static/image/other/air-tickets/ctrip-air/image1.png" />
<view class="codefun-flex-col codefun-flex-1 codefun-ml-12">
@ -180,20 +189,30 @@
style="flex-wrap: wrap; flex: 1; width: 100%;">
<image class="codefun-shrink-0 image_8"
:src="`/static/image/other/air-tickets/air-line/${airlineInfo.icon}.png`" />
<text class="font_11">{{ airlineInfo.name }}
{{ airTicketsInfo.flightInfo.flightNumber }}</text>
<view class="font_11 codefun-flex-row codefun-items-center">{{
airlineInfo.name }}
{{ airTicketsInfo.flightInfo.flightNumber }}
<view class="codefun-shrink-0 section_8"></view>
<text class="font_11">{{ airTicketsInfo.flightInfo.seatCategory }}</text>
<view class="codefun-shrink-0 section_8"></view>
<text class="font_11">{{ airTicketsInfo.flightInfo.aircraftType }}</text>
<view class="codefun-shrink-0 section_8"></view>
<text class="font_11" style="color: #EC6103;">{{
</view>
<view class="font_11 codefun-flex-row codefun-items-center">{{
airTicketsInfo.flightInfo.seatCategory }}<view
class="codefun-shrink-0 section_8">
</view>
</view>
<view class="font_11 codefun-flex-row codefun-items-center">{{
airTicketsInfo.flightInfo.aircraftType }}<view
class="codefun-shrink-0 section_8">
</view>
</view>
<view class="font_11 codefun-flex-row codefun-items-center"
style="color: #EC6103;">{{
airTicketsInfo.flightInfo.meal
}}</text>
<view class="codefun-shrink-0 section_8"></view>
<text class="font_11" style="color: #EC6103;">{{
}}<view class="codefun-shrink-0 section_8"></view>
</view>
<view class="font_11 codefun-flex-row codefun-items-center"
style="color: #EC6103;">{{
airTicketsInfo.flightInfo.luggageCheckInQuota
}}</text>
}}</view>
</view>
</view>
<uni-icons class="codefun-shrink-0 codefun-ml-12" type="right" size="12"
@ -219,7 +238,7 @@
<text class="codefun-self-start font_6 text_41">已购 / 赠送服务</text>
<view class="codefun-self-stretch grid mt-13">
<view class="codefun-flex-row codefun-justify-between codefun-items-center grid-item_1">
<view class="codefun-flex-row codefun-items-center">
<view style="flex: 1;" class="codefun-flex-row codefun-items-center">
<text class="font_8 text_42">优惠券</text>
<image class="codefun-shrink-0 image_18 codefun-ml-2"
src="/static/image/other/air-tickets/ctrip-air/give.png" />
@ -228,12 +247,12 @@
color="#C7C8CC"></uni-icons>
</view>
<view class="codefun-flex-row codefun-justify-between codefun-items-center grid-item_2">
<text class="font_8 text_43">旅游专享券</text>
<text style="flex: 1;" class="font_8 text_43">旅游专享券</text>
<uni-icons class="codefun-shrink-0 codefun-ml-4" type="right" size="13"
color="#C7C8CC"></uni-icons>
</view>
<view class="codefun-flex-row codefun-justify-between codefun-items-center grid-item">
<view class="codefun-flex-row codefun-items-center">
<view style="flex: 1;" class="codefun-flex-row codefun-items-center">
<text class="font_8">机场美食券</text>
<image class="codefun-shrink-0 image_18 codefun-ml-2"
src="/static/image/other/air-tickets/ctrip-air/give.png" />
@ -250,8 +269,8 @@
<view class="codefun-flex-row codefun-self-stretch group_17">
<text class="codefun-shrink-0 codefun-self-start font_13 text_47">出行人</text>
<view class="codefun-flex-col codefun-flex-1 codefun-relative group_16 ml-41">
<text class="codefun-self-start text_23"><text style="margin-right: 6px;"
v-for="value in airTicketsInfo.passengersInfo">{{
<text class="codefun-self-start text_23" @click="goEdit"><text
style="margin-right: 6px;" v-for="value in airTicketsInfo.passengersInfo">{{
value.name }}</text></text>
<view class="codefun-flex-row codefun-items-center codefun-self-stretch codefun-mt-8">
<text class="font_14 text_49">查看证件航司预订号修改姓名/证件</text>
@ -264,7 +283,8 @@
<view
class="codefun-flex-row codefun-justify-between codefun-items-center codefun-self-start group_18">
<text class="font_13 text_50">联系手机</text>
<text class="text_23">+86 {{ airTicketsInfo.ticketNumber.replace(/(\d{3})\d{4}(\d{4})/,
<text class="text_23" @click="goEdit">+86 {{
airTicketsInfo.ticketNumber.replace(/(\d{3})\d{4}(\d{4})/,
'$1****$2')
}}</text>
</view>
@ -355,10 +375,14 @@ import airlineJson from '@/static/json/air-line.json';
const buttonGroup = [{
name: "编辑机票信息",
click: () => {
util.goPage(`/pages/other/air-tickets/edit/edit?ticketsApp=ctrip&storageKey=${data.STORAGE_KEY}`)
goEdit()
}
}]
function goEdit() {
util.goPage(`/pages/other/air-tickets/edit/edit?ticketsApp=ctrip&storageKey=${data.STORAGE_KEY}`)
}
const data = reactive({
navBar: {
bgColor: 'transparent'
@ -496,6 +520,8 @@ onPageScroll((e) => {
display: flex;
align-items: center;
justify-content: center;
padding-top: 16rpx;
padding-bottom: 32rpx;
}
::v-deep .uni-navbar__header-btns-right {
@ -599,7 +625,7 @@ onPageScroll((e) => {
.text_5 {
color: #ffffff;
font-size: 44rpx;
font-weight: 700;
font-weight: var(--font-weight-bold);
line-height: 40.48rpx;
letter-spacing: 2.2rpx;
}
@ -689,7 +715,7 @@ onPageScroll((e) => {
.text_13 {
color: #f2740d;
font-size: 20rpx;
font-weight: 700;
font-weight: var(--font-weight-bold);
line-height: 18.38rpx;
}
}
@ -762,7 +788,7 @@ onPageScroll((e) => {
.font_4 {
font-size: 28rpx;
line-height: 24.72rpx;
font-weight: 700;
font-weight: var(--font-weight-bold);
color: #1a1a1a;
}
}
@ -770,7 +796,7 @@ onPageScroll((e) => {
.font_3 {
font-size: 24rpx;
line-height: 22.24rpx;
font-weight: 700;
font-weight: var(--font-weight-bold);
color: #ffffff;
}
}
@ -894,7 +920,6 @@ onPageScroll((e) => {
background-color: #ffffff;
border-radius: 16rpx 16rpx 0 0;
margin-top: -16rpx;
z-index: 99;
.group_8 {
border-radius: 24rpx 24rpx 0 0;
@ -1050,7 +1075,7 @@ onPageScroll((e) => {
.font_10 {
font-size: 32rpx;
line-height: 36rpx;
font-weight: 700;
font-weight: var(--font-weight-bold);
color: #1a1a1a;
}
@ -1070,7 +1095,7 @@ onPageScroll((e) => {
border: solid 2rpx #0177d4;
.text_40 {
font-weight: 700;
font-weight: var(--font-weight-bold);
line-height: 22.36rpx;
}
}
@ -1079,7 +1104,7 @@ onPageScroll((e) => {
.font_7 {
font-size: 36rpx;
line-height: 24.72rpx;
font-weight: 700;
font-weight: var(--font-weight-bold);
color: #1a1a1a;
}
}
@ -1384,7 +1409,7 @@ onPageScroll((e) => {
.font_6 {
font-size: 36rpx;
line-height: 33.26rpx;
font-weight: 700;
font-weight: var(--font-weight-bold);
color: #1a1a1a;
}
@ -1399,7 +1424,7 @@ onPageScroll((e) => {
bottom: 0;
left: 0;
right: 0;
z-index: 999;
z-index: 9;
}
@ -1474,7 +1499,7 @@ onPageScroll((e) => {
.font {
font-size: 28rpx;
line-height: 24.72rpx;
font-weight: 700;
font-weight: var(--font-weight-bold);
color: #ffffff;
}
}

View File

@ -455,7 +455,7 @@ onLoad((options) => {
Object.assign(data.ticketsInfo, mergedData)
// tips stored defaultData - defaultData
if (data.storageKey === 'fligggyAirTicketsInfo' && !data.ticketsInfo.fligggyOrderInfo.tips) {
if (data.storageKey === 'fliggyAirTicketsInfo' && !data.ticketsInfo.fligggyOrderInfo.tips) {
data.ticketsInfo.fligggyOrderInfo.tips = []
}
if (data.storageKey === 'ctripAirTicketsInfo' && !data.ticketsInfo.ctripOrderInfo.tips) {
@ -486,7 +486,7 @@ const handleRightButtonClick = () => {
}
if (data.storageKey === 'ctripAirTicketsInfo') {
delete data.ticketsInfo.fligggyOrderInfo
} else if (data.storageKey === 'fligggyAirTicketsInfo') {
} else if (data.storageKey === 'fliggyAirTicketsInfo') {
delete data.ticketsInfo.ctripOrderInfo
} else {
delete data.ticketsInfo.fligggyOrderInfo

View File

@ -112,7 +112,7 @@
<view class="fc-price">
<text class="label">总价</text>
<view class="symbol">¥</view>
<text class="value">{{ airTickrtInfo.orderInfo.price }}</text>
<text class="value" @click="goEdit">{{ airTickrtInfo.orderInfo.price }}</text>
<uni-icons type="right" size="10" color="#1A1A1A"></uni-icons>
</view>
<view class="fc-rules">
@ -140,7 +140,7 @@
</view>
</view>
<view class="flight-route">
<view class="flight-route" @click="goEdit">
<!-- Departure -->
<view class="route-left">
<text class="time">{{ airTickrtInfo.flightInfo.startTime }}</text>
@ -202,13 +202,16 @@
:class="{ 'last-passenger': index === airTickrtInfo.passengersInfo.length - 1 }"
v-for="(item, index) in airTickrtInfo.passengersInfo" :key="index">
<text class="label" :class="{ 'empty': index !== 0 }">乘机人</text>
<view class="info">
<view class="info" @click="goEdit">
<text class="name">{{ item.name }}</text>
<text class="id-card">{{ item.idType }}{{ item.idNumber }}</text>
<text class="id-card">{{ item.idType }}{{ item.idType === '身份证' ?
stringUtil.maskIdCard(item.idNumber) : (item.idType === '护照' ?
stringUtil.maskPassport(item.idNumber) : item.idNumber) }}</text>
<view class="ticket-row">
<text class="ticket-no">票号{{ item.ticketNo }}</text>
<image src="/static/image/other/air-tickets/fliggy-air/copy-blue.png"
mode="widthFix" class="copy-icon-sm"></image>
<image style="width: 10px;"
src="/static/image/other/air-tickets/fliggy-air/copy-blue.png" mode="widthFix"
class="copy-icon-sm"></image>
<text class="action-text">复制</text>
<text class="sub-text">({{ airTickrtInfo.flightInfo.startCity }}-{{
airTickrtInfo.flightInfo.endCity }})</text>
@ -299,15 +302,20 @@ import { ref, onMounted, reactive, toRefs, computed } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import defualtData from '@/pages/other/air-tickets/commom/defualt.json';
import airlineJson from '@/static/json/air-line.json';
import { util, numberUtil } from '@/utils/common.js';
import { util, numberUtil, stringUtil } from '@/utils/common.js';
const buttonGroup = [{
name: "编辑机票信息",
click: () => {
util.goPage(`/pages/other/air-tickets/edit/edit?ticketsApp=fliggy&storageKey=${data.STORAGE_KEY}`)
goEdit()
}
}]
function goEdit() {
util.goPage(`/pages/other/air-tickets/edit/edit?ticketsApp=fliggy&storageKey=${data.STORAGE_KEY}`)
}
const data = reactive({
STORAGE_KEY: 'fliggyAirTicketsInfo',
navBar: {
@ -988,28 +996,31 @@ const onBack = () => {
.ticket-row {
display: flex;
align-items: center;
gap: 8rpx;
font-size: 24rpx;
line-height: 24rpx;
color: #1A1A1A;
margin-bottom: 50rpx;
.action-text {
flex-shrink: 0;
color: #6F66D9;
font-weight: 500;
margin-left: 8rpx;
}
.copy-icon-sm {
width: 20rpx;
height: 20rpx;
flex-shrink: 0;
margin-left: 8rpx;
}
.sub-text {
flex-shrink: 0;
color: #999;
margin-left: 8rpx;
}
.ticket-no {
flex-shrink: 0;
color: #333;
}
}

View File

@ -83,8 +83,11 @@
<text class="time-big alipay-font">{{ ticketData.flightInfo.startTime }}</text>
<text class="airport-text">{{ ticketData.flightInfo.startAirport }} </text>
</view>
<image src="/static/image/other/air-tickets/qunar/location.png"
style="width: 16rpx; height: 16rpx;flex-shrink: 0;margin-bottom: 4rpx;"></image>
<view style="width: 16rpx; height: 16rpx;flex-shrink: 0;margin-bottom: 4rpx;">
<image class="location-icon"
src="/static/image/other/air-tickets/qunar/location.png"
style="width: 8px; display: block;" mode="widthFix"></image>
</view>
</view>
<view class="arrow-col">
@ -111,8 +114,11 @@
<text class="time-big alipay-font">{{ ticketData.flightInfo.endTime }}</text>
<text class="airport-text">{{ ticketData.flightInfo.endAirport }}</text>
</view>
<image src="/static/image/other/air-tickets/qunar/location.png"
style="width: 16rpx; height: 16rpx;flex-shrink: 0;margin-bottom: 4rpx;"></image>
<view style="width: 16rpx; height: 16rpx;flex-shrink: 0;margin-bottom: 4rpx;">
<image class="location-icon"
src="/static/image/other/air-tickets/qunar/location.png"
style="width: 8px; display: block;" mode="widthFix"></image>
</view>
</view>
@ -120,19 +126,19 @@
<view class="flight-detail-row">
<image class="item" src="/static/image/other/air-tickets/qunar/flight-number.png"
mode="widthFix" style="width: 24rpx; height: 24rpx;margin-right: 4rpx;"></image>
mode="widthFix" style="width: 12px;margin-right: 4rpx;flex-shrink: 0;"></image>
<text class="detail-item item">{{ ticketData.flightInfo.aircraftType }}</text>
<text class="detail-divider item">|</text>
<image class="item" src="/static/image/other/air-tickets/qunar/seat-category.png"
mode="widthFix" style="width: 24rpx; height: 24rpx;margin-right: 4rpx;"></image>
mode="widthFix" style="width: 12px;margin-right: 4rpx;flex-shrink: 0;"></image>
<text class="detail-item item">{{ ticketData.flightInfo.seatCategory }}</text>
<text class="detail-divider item">|</text>
<image class="item" src="/static/image/other/air-tickets/qunar/on-time.png"
mode="widthFix" style="width: 24rpx; height: 24rpx;margin-right: 4rpx;"></image>
mode="widthFix" style="width: 12px;margin-right: 4rpx; flex-shrink: 0;"></image>
<text class="detail-item item">准点率{{ ticketData.flightInfo.onTimeRate }}</text>
<text class="detail-divider item">|</text>
<image class="item" src="/static/image/other/air-tickets/qunar/meal.png" mode="widthFix"
style="width: 24rpx; height: 24rpx;margin-right: 4rpx;"></image>
style="width: 12px;margin-right: 4rpx;flex-shrink: 0;"></image>
<text class="detail-item item">{{ ticketData.flightInfo.meal }}</text>
</view>
<view class="tips-box">
@ -192,7 +198,9 @@
<view class="row-content"
@click="util.goPage('/pages/other/air-tickets/edit/edit')">
<view class="p-name">{{ p.name }}</view>
<view class="p-sub">{{ p.idType }}: {{ p.idNumber }}</view>
<view class="p-sub">{{ p.idType }}: {{ p.idType === '身份证' ?
stringUtil.maskIdCard(p.idNumber) : (p.idType === '护照' ?
stringUtil.maskPassport(p.idNumber) : p.idNumber) }}</view>
<view class="p-sub">
<text>票号:{{ p.ticketNo }}</text>
<image src="/static/image/other/air-tickets/qunar/copy-black.png"
@ -345,7 +353,7 @@ import NavBar from '@/components/nav-bar/nav-bar.vue';
import { ref, onMounted, reactive, toRefs, computed } from 'vue';
import { onShow } from '@dcloudio/uni-app';
import defualtData from '@/pages/other/air-tickets/commom/defualt.json';
import { util } from '@/utils/common.js';
import { util, stringUtil } from '@/utils/common.js';
import airlineJson from '@/static/json/air-line.json';
const buttonGroup = [{

View File

@ -15,7 +15,7 @@
<image class="icon" src="/static/image/other/video-call/float.png"></image>
</view>
<view class="center">
<text class="time">{{ videoData.timeText }}</text>
<text class="time">{{ data.timing }}</text>
</view>
<view v-if="data.isEdit" class="right" @click.stop>
<view class="button" @click="confirmEdit">完成</view>
@ -169,7 +169,7 @@ const data = reactive({
videoData: {
micOn: true,
speakerOn: true,
cameraOn: false,
cameraOn: true,
mainVideoIndex: 0,
timeText: '125:22',
videoList: [
@ -178,9 +178,10 @@ const data = reactive({
{ preview: '/static/image/other/video-call/defualt/voice_chat_3.jpg', videoUrl: '', savedVideoUrl: '', iconType: 0 },
{ preview: '/static/image/other/video-call/defualt/voice_chat_4.jpg', videoUrl: '', savedVideoUrl: '', iconType: 0 },
{ preview: '/static/image/other/video-call/defualt/voice_chat_5.jpg', videoUrl: '', savedVideoUrl: '', iconType: 0 },
{ preview: '/static/image/other/video-call/defualt/voice_chat_me.jpg', videoUrl: '', savedVideoUrl: '', iconType: 1 }
{ preview: '/static/image/other/video-call/defualt/voice_chat_me.jpg', videoUrl: '', savedVideoUrl: '', iconType: 0 }
]
},
timing: 0,
videoDataBackup: null, //
isEdit: false,
statusBarHeight: 0,
@ -205,6 +206,7 @@ const data = reactive({
//
let statusBarTimer = null
let timingTimer = null //
let { videoData, statusBarHeight } = toRefs(data)
@ -261,11 +263,13 @@ onLoad(() => {
console.log('videoData1', videoData)
const videoDataNew = {
...videoData,
iconType: videoData.onMic ? videoData.iconType : 1,
videoList: videoData.videoList.map((item) => {
item.videoUrl = plus.io.convertLocalFileSystemURL(item.savedVideoUrl)
return item
})
}
data.timing = videoData.timeText
data.videoData = videoDataNew
console.log('videoData2', data.videoData)
@ -279,6 +283,13 @@ onLoad(() => {
})
onShow(() => {
//
const videoData = uni.getStorageSync('videoData')
if (videoData && videoData.timeText) {
data.timing = videoData.timeText
}
startTimer()
// #ifdef APP-PLUS
util.setAndroidSystemBarColor('#232323')
// 便
@ -306,6 +317,13 @@ onHide(() => {
data.dragState.isDragging = false
data.dragState.draggingIndex = -1
//
if (data.timing) {
data.videoData.timeText = data.timing
uni.setStorageSync('videoData', data.videoData)
}
stopTimer() //
console.log('🚪 页面隐藏,已清理定时器和状态')
})
@ -317,6 +335,14 @@ onUnmounted(() => {
statusBarTimer = null
}
//
if (data.timing) {
data.videoData.timeText = data.timing
uni.setStorageSync('videoData', data.videoData)
}
stopTimer() //
//
if (data.dragState.longPressTimer) {
clearTimeout(data.dragState.longPressTimer)
@ -329,7 +355,7 @@ onUnmounted(() => {
//
const openTimeEditPopup = () => {
// (: "125:22")
const parts = data.videoData.timeText.split(':')
const parts = data.timing.split(':')
data.tempMinutes = parts[0] || '0'
data.tempSeconds = parts[1] || '00'
data.showTimeEditPopup = true
@ -353,6 +379,10 @@ const saveTimeEdit = () => {
// storage
uni.setStorageSync('videoData', data.videoData)
//
data.timing = data.videoData.timeText
startTimer()
//
data.showTimeEditPopup = false
}
@ -448,11 +478,10 @@ const saveImage = async () => {
const changeIconType = (item, index) => {
if (index == data.videoData.videoList.length - 1) {
item.iconType = item.iconType == 2 ? 0 : item.iconType + 1
} else {
item.iconType = item.iconType == 2 ? 0 : 2
if (index == data.videoData.videoList.length - 1 && !data.videoData.micOn) {
return
}
item.iconType = item.iconType == 2 ? 0 : 2
uni.setStorageSync('videoData', data.videoData)
}
@ -610,6 +639,13 @@ const chooseImage = () => {
//
const changeInfo = (key) => {
data.videoData[key] = !data.videoData[key]
if (key == 'micOn') {
if (!data.videoData[key]) {
data.videoData.videoList[data.videoData.videoList.length - 1].iconType = 1
} else {
data.videoData.videoList[data.videoData.videoList.length - 1].iconType = 0
}
}
uni.setStorageSync('videoData', data.videoData)
}
@ -772,6 +808,36 @@ const handleTouchEnd = (event, index) => {
const hangup = () => {
uni.navigateBack()
}
//
const startTimer = () => {
stopTimer()
timingTimer = setInterval(() => {
if (!data.timing) return
let timeStr = String(data.timing)
if (timeStr.indexOf(':') === -1) return
let parts = timeStr.split(':')
let minutes = parseInt(parts[0]) || 0
let seconds = parseInt(parts[1]) || 0
seconds++
if (seconds >= 60) {
seconds = 0
minutes++
}
data.timing = `${minutes}:${seconds.toString().padStart(2, '0')}`
}, 1000)
}
//
const stopTimer = () => {
if (timingTimer) {
clearInterval(timingTimer)
timingTimer = null
}
}
</script>
<style lang="less" scoped>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -229,6 +229,20 @@ export const stringUtil = {
if (length < 8) return idCard;
return idCard.substring(0, 4) + '*'.repeat(length - 8) + idCard.substring(length - 4);
},
/**
* 护照号脱敏
* @param {string} passport - 护照号
* @returns {string} 脱敏后的护照号
*/
maskPassport(passport) {
if (!passport) return passport;
const length = passport.length;
if (length <= 4) return passport;
return passport.substring(0, 2) + '*'.repeat(length - 4) + passport.substring(length - 2);
}
};

View File

@ -213,6 +213,7 @@ export default {
console.log("模拟请求:", JSON.stringify(user))
if (user.code == 0) {
uni.setStorageSync('AppUser', user.data)
uni.setStorageSync('userInfo', user.data)
// uni.showModal({
// title: '提示',
// content: JSON.stringify(user.data),