前端开发 #12

Merged
pfqxe4nai merged 1 commits from xiaofan_branch into master 2 years ago

@ -17,6 +17,12 @@
"navigationBarTitleText": "Mini-12306"
}
},
{
"path": "pages/index/passenge-list",
"style": {
"navigationBarTitleText": "Mini-12306"
}
},
{
"path": "pages/index/ticket",
"style": {
@ -69,6 +75,12 @@
"style": {
"navigationBarTitleText": "Mini-12306"
}
},
{
"path": "pages/index/newpassenger",
"style": {
"navigationBarTitleText": "Mini-12306"
}
}
],
"globalStyle": {

@ -69,7 +69,8 @@ export default {
};
// POSTformDataJSON
uni.request({
url: 'http://192.168.251.7:8000/search_train/', //
// url: 'http://192.168.251.7:8000/search_train/', //
url: 'http://localhost:8000/search_train/',
method: 'POST',
data: JSON.stringify(formData), // formDataJSON
header: {

@ -47,7 +47,8 @@ export default {
// POSTformDataJSON
uni.request({
url: 'http://192.168.251.7:8000/login_view/', //
// url: 'http://192.168.251.7:8000/login_view/', //
url: 'http://localhost:8000/login_view/',
method: 'POST',
data: JSON.stringify(formData), // formDataJSON
header: {

@ -1,36 +1,30 @@
<template>
<view class="order-page">
<view class="order-details">
<!-- 订单详情 -->
<view class="order-info">
<text class="order-label">订单编号</text>
<text class="order-value">{{ orderNumber }}</text>
</view>
<view class="order-info">
<text class="order-label">乘车人</text>
<text class="order-value">{{ passengerName }}</text>
</view>
<view class="order-info">
<text class="order-label">车次</text>
<text class="order-value">{{ trainNumber }}</text>
<view class="container">
<!-- 选项卡 -->
<view class="tab-bar">
<view class="tab-item" :class="{ 'active': activeTab === 'unpaid' }" @click="switchTab('unpaid')"></view>
<view class="tab-item" :class="{ 'active': activeTab === 'paid' }" @click="switchTab('paid')"></view>
<view class="tab-item" :class="{ 'active': activeTab === 'myTicket' }" @click="switchTab('myTicket')"></view>
</view>
<!-- 订单列表 -->
<view class="order-list">
<view v-if="activeTab === 'unpaid'" class="order-item unpaid" v-for="(order, index) in unpaidOrders" :key="index">
<text>订单号{{ order.orderNumber }}</text>
<text>金额{{ order.amount }}</text>
<text>状态待支付</text>
</view>
<view class="order-info">
<text class="order-label">座位</text>
<text class="order-value">{{ seat }}</text>
<view v-if="activeTab === 'paid'" class="order-item paid" v-for="(order, index) in paidOrders" :key="index">
<text>订单号{{ order.orderNumber }}</text>
<text>金额{{ order.amount }}</text>
<text>状态已支付</text>
</view>
<!-- 其他订单信息如车票信息金额等 -->
</view>
<view class="payment-info">
<!-- 支付信息 -->
<view class="payment-item">
<text class="payment-label">订单总额</text>
<text class="payment-value">{{ totalAmount }} </text>
<view v-if="activeTab === 'myTicket'" class="order-item my-ticket" v-for="(order, index) in myTickets" :key="index">
<text>订单号{{ order.orderNumber }}</text>
<text>车次{{ order.trainNumber }}</text>
<text>座位号{{ order.seatNumber }}</text>
</view>
<!-- 其他支付信息如优惠券支付方式等 -->
</view>
<button class="pay-btn" @click="payOrder"></button>
<button class="pay-btn" @click="refund">退</button>
<button class="pay-btn" @click="refund"></button>
</view>
</template>
@ -38,85 +32,75 @@
export default {
data() {
return {
orderNumber: '20240418001',
passengerName: '张三',
trainNumber: 'G1234',
seat: '商务座',
totalAmount: 500
activeTab: 'unpaid', //
unpaidOrders: [
{ orderNumber: '123456789', amount: 100 },
{ orderNumber: '987654321', amount: 200 },
], //
paidOrders: [
{ orderNumber: '543216789', amount: 150 },
{ orderNumber: '987654312', amount: 250 },
], //
myTickets: [
{ orderNumber: '123456789', trainNumber: 'G1234', seatNumber: 'A12' },
{ orderNumber: '987654321', trainNumber: 'D5678', seatNumber: 'B34' },
], //
};
},
methods: {
payOrder() {
//
uni.navigateTo({
url: '/pages/index/Payment'
});
//
},
change(){
uni.navigateTo({
url: '/pages/index/Change'
});
},
refund(){
uni.navigateTo({
url: '/pages/index/refund'
});
}
switchTab(tab) {
this.activeTab = tab;
}
}
};
</script>
<style>
.order-page {
<style scoped>
.container {
padding: 20px;
}
.order-details {
.tab-bar {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
.order-info {
margin-bottom: 10px;
.tab-item {
flex: 1;
text-align: center;
padding: 10px;
background-color: #f5f5f5;
}
.order-label {
font-size: 16px;
color: #333;
}
.order-value {
font-size: 16px;
color: #666;
.tab-item.active {
background-color: #007aff;
color: #ffffff;
}
.payment-info {
border-top: 1px solid #ccc;
padding-top: 20px;
.order-list {
display: flex;
flex-direction: column;
}
.payment-item {
.order-item {
padding: 10px;
margin-bottom: 10px;
border-radius: 5px;
}
.payment-label {
font-size: 16px;
color: #333;
.unpaid {
background-color: #ff3b30;
color: #ffffff;
}
.payment-value {
font-size: 16px;
color: #666;
.paid {
background-color: #34c759;
color: #ffffff;
}
.pay-btn {
width: 100%;
height: 40px;
.my-ticket {
background-color: #007aff;
color: #fff;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
color: #ffffff;
}
</style>

@ -24,6 +24,7 @@ export default {
buyReturn() {
//
console.log("购买返程");
alert('改签功能暂未开放,敬请期待!');
},
payNow() {
const paymentSuccess = Math.random() < 0.8; // 80%

@ -109,7 +109,7 @@ export default {
//
if (this.Bankcard.length < 16 || this.Bankcard.length > 19) {
uni.showToast({
title: '银行卡号应为16-1911位',
title: '银行卡号应为16-19位',
icon: 'none'
});
return;
@ -125,7 +125,8 @@ export default {
// POSTformDataJSON
uni.request({
url: 'http://192.168.251.7:8000/save_passenger/',
// url: 'http://192.168.251.7:8000/save_passenger/',
url: 'http://localhost:8000/save_passenger/',
method: 'POST',
data: JSON.stringify(formData), // formDataJSON
header: {

@ -1,67 +1,180 @@
<template>
<div>
<h1>确认订单</h1>
<div v-if="ticket">
<div v-for="(ticket, index) in selectedTicketInfo" :key="index" class="ticket-box">
<div class="departure-info">
<p class="time">{{ ticket.departure_time }}</p>
<p class="station">{{ ticket.departure_station }}</p>
</div>
<div class="train-info">
<h2 class="train-no">{{ ticket.trainno }}</h2>
<p class="date">{{ ticket.date }}</p>
</div>
<div class="arrival-info">
<p class="time">{{ ticket.arrival_time }}</p>
<p class="station">{{ ticket.arrival_station }}</p>
</div>
<div class="ticket-info">
<div class="departure-info">
<p class="time">{{ departure_time }}</p>
<p class="station">{{ departure }}</p>
</div>
<div class="train-info">
<h2 class="train-no">{{ ticketno }}</h2>
<p class="date">{{ date }}</p>
</div>
<div class="arrival-info">
<p class="time">{{ arrival_time }}</p>
<p class="station"> {{ arrival }}</p>
</div>
</div>
<div id="app">
<div class="seat-selection">
<div class="seat-options">
<label class="seat-option" :class="{ active: selectedSeat === 'business' }">
<input type="radio" v-model="selectedSeat" value="business">
</label>
<label class="seat-option" :class="{ active: selectedSeat === 'firstClass' }">
<input type="radio" v-model="selectedSeat" value="firstClass">
</label>
<label class="seat-option" :class="{ active: selectedSeat === 'secondClass' }">
<input type="radio" v-model="selectedSeat" value="secondClass">
</label>
<label class="seat-option" :class="{ active: selectedSeat === 'noSeat' }">
<input type="radio" v-model="selectedSeat" value="noSeat">
</label>
</div>
</div>
</div>
<div class="passenger-selection">
<h2>乘车人选择</h2>
<button class="add-btn" @click="addPassenge"></button>
</div>
<view v-if="ticketData">
<div class="container">
<!-- 二等座 -->
<div
class="seat-box Second"
@click="selectSeat('Second')"
:class="{ selected: selectedSeat === 'Second' }"
>
<p>二等座</p>
<p class="price">¥{{ ticketData.secondseatprice }}</p>
<p class="num">{{ ticketData.secondseatnum }}</p>
</div>
<!-- 一等座 -->
<div
class="seat-box First"
@click="selectSeat('First')"
:class="{ selected: selectedSeat === 'First' }"
>
<p>一等座</p>
<p class="price">¥{{ ticketData.firstseatprice }}</p>
<p class="num">{{ ticketData.firstseatnum }}</p>
</div>
<!-- 商务座 -->
<div
class="seat-box Business"
@click="selectSeat('Business')"
:class="{ selected: selectedSeat === 'Business' }"
>
<p>商务座</p>
<p class="price">¥{{ ticketData.businessseatprice }}</p>
<p class="num">{{ ticketData.businessseatnum }}</p>
</div>
<!-- 无座 -->
<div
class="seat-box NO"
@click="selectSeat('NO')"
:class="{ selected: selectedSeat === 'NO' }"
>
<p>无座</p>
<p class="price">¥{{ ticketData.noseatprice }}</p>
<p class="num">{{ ticketData.noseatnum }}</p>
</div>
</div>
</view>
<div>
<button class="add-btn" @click="addPassenge"></button>
<view>
<block v-for="(passenger, index) in selectedPassengers" :key="index">
<view>
<text>{{ passenger.name }} - {{ passenger.passengerstate }} - {{ passenger.idcardno }} - {{ passenger.mobileno }}</text>
</view>
</block>
</view>
</div>
<button class="submit-btn" @click="submitOrder"></button>
</div>
</template>
<script>
export default {
data() {
return {
ticket: {} //
};
},
mounted() {
//
if (this.$route.query.data) {
this.selectedData = JSON.parse(this.$route.query.data);
}
export default {
data() {
return {
selectedSeat: null,
ticketno: '',
date: '',
departure: '',
arrival: '',
departure_time:'',
arrival_time:'',
ticketData: null,
selectedPassengers: []
};
},
onLoad(query) {
//
this.ticketno = query.ticketno || '';
this.date = query.date || '';
this.departure = query.departure || '';
this.arrival = query.arrival || '';
this.departure_time = query.departure_time || '';
this.arrival_time = query.arrival_time || '';
},
onshow(){
this.fetchTicketInfo();
this.loadSelectedPassengers();
},
mounted() {
this.fetchTicketInfo();
this.loadSelectedPassengers();
},
methods: {
selectSeat(seatType) {
this.selectedSeat = seatType; //
},
loadSelectedPassengers(){
const passengers = localStorage.getItem('selectedPassenger');
if (passengers) {
this.selectedPassengers = JSON.parse(passengers);
} else {
console.error('No passengers found in local storage.');
}
},
submitOrder() {
uni.navigateTo({
url: '/pages/index/Payment'
});
}
},
addPassenge(){
uni.navigateTo({
url: '/pages/index/passenge-list'
});
},
fetchTicketInfo() {
const formData = {
date:this.date,
trainno:this.ticketno,
};
// POSTformDataJSON
uni.request({
url: 'http://localhost:8000/book_ticket/',
method: 'POST',
data: JSON.stringify(formData), // formDataJSON
header: {
'content-type': 'application/json' // JSON
},
success: (res) => {
//
if (res.statusCode === 200) { // 200
const data = res.data;
if (data.message === '选座成功') {
console.log('请求成功',data);
this.ticketData = data.tickets;
uni.showToast({
title: '查询成功',
icon: 'success'
});
} else {
//
const data = res.data;
console.log('请求成功', data);
uni.showToast({
title: data.message + (data.reason ? ': ' + data.reason : ''),
icon: 'none'
});
}
}
},
fail: (err) => {
//
console.error('请求失败', err);
uni.showToast({
title: '请求失败,请重试',
icon: 'none'
});
}
});
},
}
};
</script>
@ -73,7 +186,8 @@ h1 {
margin-bottom: 20px;
}
.ticket-box {
.ticket-info {
display: flex;
justify-content: space-between;
align-items: center;
@ -90,15 +204,15 @@ h1 {
text-align: center;
}
.time {
font-size: 8px; /* 设置时间的字体大小 */
.time .num,.price {
font-size: 12px; /* 设置时间的字体大小 */
}
.station {
font-size: 16px; /* 设置车站名称的字体大小 */
}
.train-no {
.train-no,{
font-size: 20px; /* 设置车次的字体大小 */
}
@ -106,36 +220,44 @@ h1 {
font-size: 10px; /* 设置日期的字体大小 */
}
.seat-selection {
.container {
display: flex;
justify-content: center;
margin-top: 20px;
justify-content: space-between; /* 均匀分布每个子元素 */
}
.seat-options {
.container > div { /* 选择 container 中的每一个直接子元素 */
flex: 1; /* 每个子元素平分父容器的宽度 */
border: 1px solid #ccc;
padding: 10px;
margin-right: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.seat-option {
border: 1px solid #ccc;
padding: 10px 20px;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.3s, border-color 0.3s;
margin-right: 10px;
.container > div:last-child {
margin-right: 0; /* 移除最后一个子元素的右边距 */
}
.seat-option:last-child {
margin-right: 0;
.container {
display: flex;
flex-wrap: wrap;
}
.seat-option input[type="radio"] {
display: none;
.seat-box {
width: 100px;
padding: 10px;
margin: 10px;
border: 1px solid #ccc;
text-align: center;
cursor: pointer;
}
.seat-option.active {
border-color: #007bff;
background-color: #d0e6ff;
.seat-box.selected {
background-color: #4cd964;; /* 选中的座位框变绿 */
color: white;
}
.submit-btn {

@ -11,14 +11,6 @@
<script>
export default {
// data() {
// return {
// title: 'Mini-12306'
// };
// },
// onLoad() {
// },
methods: {
button1(){
uni.navigateTo({

@ -0,0 +1,169 @@
<template>
<view class="container">
<view class="add-header">
<text class="title">添加用户</text>
</view>
<form>
<view class="input-group">
<input v-model="name" type="text" placeholder="请输入姓名" />
</view>
<view class="input-group">
<input v-model="passengerstate" type="text" placeholder="请输入乘客类型" />
</view>
<view class="input-group">
<input v-model="idCard" type="text" placeholder="请输入身份证号码" />
</view>
<view class="input-group">
<input v-model="PhoneNo" type="text" placeholder="请输入电话号码" />
</view>
<view class="add-btn">
<button @click="addpassenger"></button>
</view>
</form>
</view>
</template>
<script>
export default {
data() {
return {
name: '',
passengerstate:'',
idCard: '',
PhoneNo:''
};
},
methods: {
addpassenger() {
// nameidCard
if (!this.name ) {
uni.showToast({
title: '请输入姓名',
icon: 'none'
});
return;
}
if ( !this.idCard) {
uni.showToast({
title: '请输入身份证号',
icon: 'none'
});
return;
}
if ( !this.PhoneNo) {
uni.showToast({
title: '请输入电话号码',
icon: 'none'
});
return;
}
//
if (this.idCard.length != 18) {
uni.showToast({
title: '身份证号码应为18位',
icon: 'none'
});
return;
}
//
if (this.PhoneNo.length != 11) {
uni.showToast({
title: '手机号码应为11位',
icon: 'none'
});
return;
}
const formData = {
name: this.name,
idCard: this.idCard,
PhoneNO:this.PhoneNo,
passengerstate:this.passengerstate,
};
// POSTformDataJSON
uni.request({
// url: 'http://192.168.251.7:8000/save_passenger/',
url: 'http://localhost:8000/addpassenger/',
method: 'POST',
data: JSON.stringify(formData), // formDataJSON
header: {
'content-type': 'application/json' // JSON
},
success: (res) => {
//
if (res.statusCode === 200) { // 200
const data = res.data;
if (data.message === '添加成功') {
console.log('请求成功', data);
uni.showToast({
title: '添加成功',
icon: 'success'
});
uni.navigateBack({
url: '/pages/index/passenge-list'
});
} else {
//
const data = res.data;
console.log('请求成功', data);
uni.showToast({
title: data.message + (data.reason ? ': ' + data.reason : ''),
icon: 'none'
});
}
}
},
fail: (err) => {
//
console.error('请求失败', err);
uni.showToast({
title: '请求失败,请重试',
icon: 'none'
});
}
});
}
}
};
</script>
<style scoped>
.container {
padding: 20px;
}
.input-group {
margin-bottom: 20px;
}
.input-group input {
background-color: #ffffff;
opacity: 0.65;
width: 95%;
height: 40px;
padding: 0 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
.add-header {
margin-bottom: 20px;
}
.add-btn button {
width: 100%;
height: 40px;
line-height: 40px;
border: none;
border-radius: 5px;
background-color: #007aff;
color: #000000;
outline: none;
}
</style>

@ -0,0 +1,92 @@
<template>
<view class="container">
<view class="title">选择乘客</view>
<view v-for="(passenger, index) in passengers" :key="index" class="passenger-card">
<checkbox-group @change="onSelectPassenger(index)">
<checkbox :value="index.toString()" :checked="passenger.selected"></checkbox>
</checkbox-group>
<view class="passenger-info">
<text>姓名{{ passenger.name }}</text>
<text>乘客类型{{ passenger.passengerstate }}</text>
<text>身份证号{{ passenger.idcardno }}</text>
<text>电话号码{{ passenger.mobileno }}</text>
</view>
</view>
<button @click="confirmSelection"></button>
<button @click="addPassenger"></button>
</view>
</template>
<script>
export default {
data() {
return {
passengers: []
};
},
onShow() { // Uni-app
this.fetchPassengerInfo();
},
mounted() {
this.fetchPassengerInfo();
},
methods: {
onSelectPassenger(index) {
this.$set(this.passengers, index, {
...this.passengers[index],
selected: !this.passengers[index].selected
});
},
confirmSelection() {
const selectedPassengers = this.passengers.filter(passenger => passenger.selected);
localStorage.setItem('selectedPassenger', JSON.stringify(selectedPassengers));
uni.navigateBack({
url: '/pages/index/confirm-order'
});
},
fetchPassengerInfo() {
fetch('http://localhost:8000/get_passengers/')
.then(response => response.json())
.then(data => {
this.passengers = data.passenger.map(p => ({
...p,
selected: false //
}));
})
.catch(error => {
console.error('Error fetching passengers:', error);
//
});
},
addPassenger() {
uni.navigateTo({
url: '/pages/index/newpassenger'
});
}
}
};
</script>
<style scoped>
.container {
padding: 16px;
}
.title {
font-size: 24px;
font-weight: bold;
margin-bottom: 16px;
}
.passenger-card {
margin-bottom: 12px;
padding: 12px;
border: 1px solid #ddd;
border-radius: 8px;
}
.passenger-info text {
display: block;
margin-top: 4px;
}
</style>

@ -41,8 +41,8 @@ export default {
methods: {
handleBookClick(ticket) {
uni.navigateTo({
url: '/pages/index/confirm-order'
});
url: `/pages/index/confirm-order?ticketno=${ticket.trainno}&date=${ticket.date}&departure=${ticket.departure_station}&arrival=${ticket.arrival_station}&departure_time=${ticket.departure_time}&arrival_time=${ticket.arrival_time}`
});
}
}
};
@ -73,7 +73,7 @@ h1 {
}
.time {
font-size: 10px; /* 设置时间的字体大小 */
font-size: 12px; /* 设置时间的字体大小 */
}
.station {

@ -46,11 +46,15 @@ export default {
},
rescheduleTicket() {
//
alert('改签功能暂未开放,敬请期待!');
uni.navigateTo({
url: '/pages/index/refund'
});
},
refundTicket() {
// 退
alert('退票功能暂未开放,敬请期待!');
uni.navigateTo({
url: '/pages/index/Change'
});
}
},
mounted() {

@ -1,88 +1,89 @@
<template>
<div class="user-center-page">
<div class="header">
<h1 class="title">用户中心</h1>
</div>
<div class="user-info">
<p class="info">用户名: {{ userInfo.username }}</p>
<p class="info">手机号: {{ userInfo.phone }}</p>
<p class="info">邮箱: {{ userInfo.email }}</p>
</div>
<div class="order-list">
<div v-for="(order, index) in orderList" :key="index" class="order-item" @click="viewOrderDetail(order)">
<p class="order-info">订单号: {{ order.orderId }}</p>
<p class="order-info">出发地: {{ order.departure }}</p>
<p class="order-info">目的地: {{ order.destination }}</p>
<p class="order-info">出发时间: {{ order.departureTime }}</p>
<p class="order-info">到达时间: {{ order.arrivalTime }}</p>
<p class="order-info">价格: {{ order.price }} </p>
</div>
</div>
</div>
<view class="container">
<!-- 顶部用户信息部分 -->
<view class="user-info">
<text class="user-name">{{ userName }}</text>
</view>
<!-- 功能按钮部分 -->
<view class="button-list">
<button class="list-button" @click="navigateToPassenger"></button>
<button class="list-button" @click="navigateToOrders"></button>
<button class="list-button" @click="navigateToChangePassword"></button>
<button class="list-button logout-button" @click="logout">退</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
userInfo: {
username: '肖帆',
phone: '18879439530',
email: '2023210156@qq.com'
},
orderList: [
{ orderId: '202401010001', departure: '北京', destination: '上海', departureTime: '08:00', arrivalTime: '10:30', price: '500' },
{ orderId: '202401010002', departure: '上海', destination: '北京', departureTime: '09:00', arrivalTime: '11:30', price: '500' },
{ orderId: '202401010003', departure: '北京', destination: '广州', departureTime: '10:00', arrivalTime: '12:30', price: '600' },
{ orderId: '202401010004', departure: '广州', destination: '北京', departureTime: '11:00', arrivalTime: '13:30', price: '600' },
{ orderId: '202401010005', departure: '北京', destination: '深圳', departureTime: '12:00', arrivalTime: '14:30', price: '700' },
{ orderId: '202401010006', departure: '深圳', destination: '北京', departureTime: '13:00', arrivalTime: '15:30', price: '700' },
]
userName: '张三' //
};
},
methods: {
viewOrderDetail(order) {
//
//
navigateToPassenger() {
uni.navigateTo({
url: '/pages/index/passenge-list'
});
},
navigateToOrders() {
uni.navigateTo({
url: '/pages/index/Orders'
});
},
navigateToChangePassword() {
uni.navigateTo({
url: '/pages/change-password/index'
});
},
logout() {
// token
uni.clearStorageSync();
//
uni.reLaunch({
url: '/pages/index/Login'
});
}
}
};
</script>
<style scoped>
.user-center-page {
.container {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
.header {
text-align: center;
.user-info {
margin-bottom: 20px;
text-align: center;
}
.title {
.user-name {
font-size: 24px;
font-weight: bold;
}
.user-info {
margin-bottom: 20px;
}
.info {
font-size: 16px;
margin-bottom: 10px;
.button-list {
width: 100%;
}
.order-item {
border: 1px solid #ddd;
.list-button {
width: 100%;
padding: 15px;
margin-top: 10px;
background-color: #007aff;
color: #ffffff;
text-align: center;
border-radius: 5px;
padding: 10px;
margin-bottom: 10px;
cursor: pointer;
font-size: 18px;
}
.order-info {
font-size: 14px;
margin-bottom: 5px;
.logout-button {
background-color: #ff3b30;
}
</style>

Loading…
Cancel
Save