Przeglądaj źródła

车费设置页面;

郭鹏飞 8 miesięcy temu
rodzic
commit
93541272e0

+ 1 - 1
src/pages.json

@@ -7,7 +7,7 @@
 	},
 	"pages": [
 		{
-			"path": "pages/demo/coupon",
+			"path": "pages/settings/fare",
 			"style": {
 				"navigationBarTitleText": "广誉源"
 			}

+ 199 - 180
src/pages/address/virtual.vue

@@ -1,77 +1,111 @@
 <template>
 	<view class="page-container">
-		<view class="location-bar">
-			<view class="location-content">
-				<u-icon name="map" color="#666" size="20"></u-icon>
-				<text class="location-text">信达国际金融中心</text>
-			</view>
-			<u-icon name="arrow-right" color="#999" size="14"></u-icon>
-		</view>
-
-		<view class="main-card">
-			<view class="card-header">
-				<text class="header-title">虚拟地址</text>
-				<view class="add-btn" @click="addAddress">
-					<u-icon name="plus" color="#19be6b" size="14"></u-icon>
+		<view class="location-card" @click="chooseLocation">
+			<view class="left-content">
+				<u-icon name="map-fill" color="#1ecbc3" size="24"></u-icon>
+				<view class="info">
+					<text class="label">我的位置</text>
+					<text class="value">{{ currentLocation }}</text>
 				</view>
 			</view>
+			<u-icon name="arrow-right" color="#999" size="16"></u-icon>
+		</view>
 
-			<u-line color="#f0f0f0"></u-line>
-
-			<view class="address-list">
-				<u-radio-group v-model="selectedValue" placement="column" iconPlacement="left">
-					<view class="list-item" v-for="(item, index) in addressList" :key="item.id">
-						<view class="item-left" @click="selectItem(item.id)">
-							<u-radio :name="item.id" activeColor="#2b9b86" />
-							<text class="item-text">{{ item.name }}</text>
-						</view>
+		<view class="list-title">
+			<text>虚拟地址</text>
+			<text class="more" @click="goToAdd">新增虚拟地址</text>
+		</view>
+		
+		<view class="address-list">
+			<u-radio-group v-model="selected" placement="column" activeColor="#0879FF" @change="onChange">
+				<view 
+					class="address-item" 
+					v-for="(item, index) in addressList" 
+					:key="item.id"
+				>
+					<view class="check-icon">
+						<u-radio :name="item.id" />
+					</view>
 
-						<view class="item-right" @click.stop="deleteItem(index)">
-							<u-icon name="trash" color="#dd524d" size="22"></u-icon>
-						</view>
+					<view class="address-info">
+						<view class="name">{{ item.name }}</view>
+						<view class="detail">{{ item.address }}</view>
 					</view>
-				</u-radio-group>
 
-				<view v-if="addressList.length === 0" class="empty-tip">
-					暂无地址,请添加
+					<view class="delete-btn" @click.stop="onDelete(item)">
+						<u-icon name="trash" color="#999" size="22"></u-icon>
+					</view>
 				</view>
-			</view>
+			</u-radio-group>
+		</view>
 
-			<view class="btn-group">
-				<button class="custom-btn btn-back" @click="goBack">返回</button>
-				<button class="custom-btn btn-save" @click="saveData">保存</button>
-			</view>
+		<u-gap height="100"></u-gap>
+
+		<view class="footer-bar">
+			<u-button 
+				text="保存" 
+				color="#1ecbc3" 
+				shape="circle" 
+				size="large"
+				customStyle="height: 48px; font-size: 16px;"
+				@click="onSave"
+			></u-button>
 		</view>
+
+		<u-modal 
+			:show="isShow" 
+			title="" 
+			content="确定要删除该地址吗?" 
+			showCancelButton
+			confirmColor="#1ecbc3"
+			@confirm="onDelete"
+			@cancel="isShow = false"
+		></u-modal>
 	</view>
 </template>
 
 <script>
 import {
-	getInfo
+	getInfo,
+	getJsLocation,
 } from '@/api/index';
 import {
 	netVirtualAddrAdd,
+	netVirtualAddrDel,
 	getVirtualAddrByPhone
 } from '@/api/address';
 export default {
 	data() {
 		return {
 			query: {},
-			// 选中的值
-			selectedValue: 1,
-			// 模拟数据列表
+			selected: '',
+			currentLocation: '信达国际金融中心',
+			isShow: false,
+			// 数据
 			addressList: [
-				{ id: 1, name: '太原市小店区xxx' },
-				{ id: 2, name: '晋中市榆次区xxx' }
+				{
+					id: 1,
+					name: '信达国际金融中心',
+					address: '山西省太原市万柏林区迎泽西大街86号',
+				},
+				{
+					id: 2,
+					name: '信达国际金融中心',
+					address: '山西省太原市万柏林区迎泽西大街86号',
+				},
+				{
+					id: 3,
+					name: '信达国际金融中心',
+					address: '山西省太原市万柏林区迎泽西大街86号',
+				}
 			]
-		};
+		}
 	},
 	onLoad(query) {
 		this.query = query;
 	},
 	onShow() {
 		// this.getData();
-		this.getUData();
 	},
 	methods: {
 		getData() {
@@ -79,23 +113,63 @@ export default {
 				// console.log(1, res)
 			});
 		},
-		getUData() {
-			getInfo().then(res => {
-				if (res.data.code == 200) {
-					this.userInfo = res.data.data;
+		// 选择地址(单选逻辑)
+		onChange(e) {
+			console.log(e)
+		},
+		// 点击我的位置
+		chooseLocation() {
+			console.log('点击我的位置');
+		},			
+		// 删除确认
+		onDelete(item) {
+			uni.showModal({
+				title: '提示',
+				content: '确定要删除该地址吗?',
+				success: (res) => {
+					if (res.confirm) {
+						netVirtualAddrDel({ id: item.id }).then(res => {
+							uni.$u.toast(res.data.msg);
+							if (res.data.code === 200) {
+								this.getData();
+							}
+						});
+					}
 				}
 			});
+			// this.isShow = true;
 		},
-		// 点击文字也能选中
-		selectItem(id) {
-			this.selectedValue = id;
+		// 点击保存
+		onSave() {
+			const selected = this.addressList.find(item => item.id === this.selected);
+			if(selected) {
+				console.log('保存选中的地址:', selected);
+				// let params = {
+				// 	name: selected.name,
+				// 	address: selected.address,
+				// 	latitude: selected.latitude,
+				// 	longitude: selected.longitude,
+				// 	cOpenId: uni.getStorageSync('wx_copenid')
+				// }
+				// // 更新商户的位置
+				// getJsLocation(params).then(res => {
+				// 	uni.navigateBack();
+				// });
+			} else {
+				uni.$u.toast('请选择一个地址');
+			}
 		},
-		// 添加地址
-		addAddress() {
+		// 跳转新增
+		goToAdd() {
 			uni.chooseLocation({
 				success: res => {
 					console.log(res)
-					return;
+					// address: "融创长风壹号东门北120米"
+					// distance: 57
+					// errMsg: "chooseLocation:ok"
+					// latitude: 37.826281
+					// longitude: 112.516064
+					// name: "中国电信融创长风壹号营业厅"
 					let params = {
 						name: res.name,
 						address: res.address,
@@ -115,159 +189,104 @@ export default {
 					});
 				}
 			});
-		},
-		// 删除条目
-		deleteItem(index) {
-			uni.showModal({
-				title: '提示',
-				content: '确定要删除该地址吗?',
-				success: (res) => {
-					if (res.confirm) {
-						this.addressList.splice(index, 1);
-					}
-				}
-			});
-		},
-		// 返回
-		goBack() {
-			uni.navigateBack();
-		},
-		// 保存
-		saveData() {
-			console.log('当前选中ID:', this.selectedValue);
-			uni.showToast({ title: '保存成功', icon: 'success' });
 		}
 	}
-};
+}
 </script>
 
 <style lang="scss" scoped>
-$theme-color: #2b9b86;
-$bg-color: #e6fafa;
-
 .page-container {
 	min-height: 100vh;
-	padding: 24rpx;
-	background-color: $bg-color;
-}
+	padding: 20rpx;
+	padding-bottom: 120rpx; 
+	background-color: #F6F7F9;
 
-.location-bar {
-	padding: 20rpx 24rpx;
-	margin-bottom: 20rpx;
-	border-radius: 12rpx;
-	background-color: #fff;
-	display: flex;
-	align-items: center;
-	justify-content: space-between;
-
-	.location-content {
+	.location-card {
+		background-color: #fff;
+		border-radius: 16rpx;
+		padding: 30rpx;
 		display: flex;
+		justify-content: space-between;
 		align-items: center;
+		margin-bottom: 30rpx;
+		box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.02);
 
-		.location-text {
-			margin-left: 10rpx;
-			font-size: 28rpx;
-			color: #333;
+		.left-content {
+			display: flex;
+			align-items: center;
+			
+			.info {
+				margin-left: 20rpx;
+				display: flex;
+				flex-direction: column;
+				
+				.label {
+					font-size: 24rpx;
+					color: #999;
+					margin-bottom: 8rpx;
+				}
+				.value {
+					font-size: 30rpx;
+					font-weight: bold;
+					color: #333;
+				}
+			}
 		}
 	}
-}
-
-.main-card {
-	min-height: 500rpx;
-	border-radius: 12rpx;
-	padding: 20rpx 24rpx;
-	background-color: #fff;
-	display: flex;
-	flex-direction: column;
-	position: relative;
-	box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
-}
 
-.card-header {
-	display: flex;
-	justify-content: space-between;
-	align-items: center;
-	margin-bottom: 20rpx;
-
-	.header-title {
-		font-size: 32rpx;
-		font-weight: bold;
-		color: #333;
-	}
-
-	.add-btn {
-		width: 44rpx;
-		height: 44rpx;
-		border: 2rpx solid $theme-color;
-		border-radius: 8rpx;
+	.list-title {
+		font-size: 26rpx;
+		color: #999;
+		padding: 0 10rpx;
+		margin-bottom: 20rpx;
 		display: flex;
-		justify-content: center;
 		align-items: center;
-	}
-}
-
-.address-list {
-	flex: 1;
-	margin-top: 10rpx;
-}
+		justify-content: space-between;
 
-.list-item {
-	display: flex;
-	justify-content: space-between;
-	align-items: center;
-	padding: 24rpx 0;
-	border-bottom: 1rpx solid #f5f5f5;
+		.more {
+			color: #1ecbc3;
+		}
+	}
 
-	.item-left {
+	.address-item {
+		background-color: #fff;
+		border-radius: 16rpx;
+		padding: 30rpx;
+		margin-bottom: 20rpx;
 		display: flex;
 		align-items: center;
-		flex: 1;
-	}
-
-	.item-text {
-		font-size: 30rpx;
-		color: #333;
-	}
+		box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.02);
+		transition: opacity 0.2s;
 
-	.item-right {
-		padding-left: 20rpx;
-	}
-}
-
-.empty-tip {
-	text-align: center;
-	color: #999;
-	padding-top: 50rpx;
-}
+		.check-icon {
+			margin-right: 20rpx;
+		}
 
-.btn-group {
-	display: flex;
-	justify-content: space-between;
-	margin-top: 40rpx;
-	padding-bottom: 10rpx;
-}
+		.address-info {
+			flex: 1;
+			display: flex;
+			flex-direction: column;
+			margin-right: 20rpx;
 
-.custom-btn {
-	width: 45%;
-	height: 80rpx;
-	line-height: 80rpx;
-	font-size: 30rpx;
-	border-radius: 10rpx;
-	border: none;
+			.name {
+				font-size: 32rpx;
+				font-weight: bold;
+				color: #333;
+				margin-bottom: 10rpx;
+			}
+			
+			.detail {
+				font-size: 26rpx;
+				color: #666;
+				line-height: 1.4;
+			}
+		}
 
-	&::after {
-		border: none;
+		.delete-btn {
+			padding: 10rpx;
+			display: flex;
+			align-items: center;
+		}
 	}
 }
-
-.btn-back {
-	background-color: #fff;
-	color: $theme-color;
-	border: 2rpx solid $theme-color;
-}
-
-.btn-save {
-	background-color: $theme-color;
-	color: #fff;
-}
 </style>

+ 289 - 0
src/pages/settings/fare.vue

@@ -0,0 +1,289 @@
+<template>
+	<view class="page-container">
+		<view class="card switch-card">
+			<view class="label">
+				免车费({{ isFree ? '生效中' : '未开启' }})
+			</view>
+			<u-switch  
+				size="24"
+				v-model="isFree" 
+				activeColor="#1ecbc3"
+				@change="switchChange"
+			></u-switch>
+		</view>
+
+		<view class="card form-card" v-if="isFree">
+			<u-cell-group :border="false">
+				<u-cell 
+					title="服务项目" 
+					:value="formData.projectName || '请选择'" 
+					isLink 
+					:border="true"
+					@click="showProjectPicker = true"
+				></u-cell>
+
+				<u-cell 
+					title="服务时间1" 
+					:value="formData.timeRange1 || '请选择'" 
+					isLink 
+					:border="true"
+					@click="openTimePicker('timeRange1')"
+				></u-cell>
+
+				<u-cell 
+					title="服务时间2" 
+					:value="formData.timeRange2 || '请选择'" 
+					isLink 
+					:border="true"
+					@click="openTimePicker('timeRange2')"
+				></u-cell>
+
+				<u-cell title="订单距离" :border="false">
+					<view slot="value" class="input-slot">
+						<u-input
+							v-model="formData.distance"
+							placeholder="请输入最高免除距离"
+							border="none"
+							inputAlign="right"
+							type="number"
+							fontSize="15px"
+							placeholderStyle="font-size: 14px; color: #c0c4cc;"
+						>
+							<template slot="suffix">
+								<text class="unit-text" v-if="formData.distance">km</text>
+							</template>
+						</u-input>
+					</view>
+				</u-cell>
+			</u-cell-group>
+		</view>
+
+		<view class="tips-card" v-if="isFree">
+			<view class="tips-title">温馨提示:</view>
+			<view class="tips-content">
+				1.此处设置的免车费订单距离是客户距离你的直线距离,直线距离的车行距离在地理位置特殊性上可能有一定误差,望大家设置距离时知晓。
+			</view>
+			<view class="tips-content">
+				2.超出距离xxkm后,公司固定收取车费比例的10%管理费。
+			</view>
+		</view>
+
+		<u-gap height="100"></u-gap>
+
+		<view class="footer-bar">
+			<u-button 
+				text="保存" 
+				color="#1ecbc3" 
+				shape="circle" 
+				customStyle="height: 48px; font-size: 16px;"
+				@click="onSave"
+			></u-button>
+		</view>
+
+		<u-picker 
+			:show="showProjectPicker" 
+			:columns="projectList" 
+			confirmColor="#1ecbc3"
+			@confirm="confirmProject"
+			@cancel="showProjectPicker = false"
+		></u-picker>
+
+		<u-picker
+			:show="showTimePicker"
+			:columns="timeColumns"
+			confirmColor="#1ecbc3"
+			@confirm="confirmTime"
+			@cancel="showTimePicker = false"
+		></u-picker>
+
+	</view>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            isFree: false, // 开关状态
+            
+            // 表单数据
+            formData: {
+                projectName: '',
+                timeRange1: '',
+                timeRange2: '',
+                distance: ''
+            },
+            
+            // 弹窗控制
+            showProjectPicker: false,
+            showTimePicker: false,
+            activeTimeField: '', // 当前正在编辑的时间字段名
+            
+            // 数据源模拟
+            projectList: [['泰式唤醒', '精油SPA', '中医推拿']],
+            // 复杂时间选择器数据列
+            timeColumns: [],
+        }
+    },
+    onLoad() {
+        // 初始化时间选择器的数据
+        this.initTimePickerData();
+    },
+    methods: {
+        // 初始化 5 列时间数据
+        initTimePickerData() {
+            // 1. 生成小时 (00时 - 23时)
+            const hours = [];
+            for (let i = 0; i < 24; i++) {
+                hours.push((i < 10 ? '0' + i : i) + '时');
+            }
+            
+            // 2. 生成分钟 (00分 - 59分)
+            const minutes = [];
+            for (let i = 0; i < 60; i++) {
+                minutes.push((i < 10 ? '0' + i : i) + '分');
+            }
+            
+            // 3. 组装5列:[开始时, 开始分, '至', 结束时, 结束分]
+            this.timeColumns = [
+                hours,
+                minutes,
+                ['至'], // 中间分隔符列
+                hours,
+                minutes
+            ];
+        },
+        // 开关切换
+        switchChange(val) {
+            if(!val) {
+                // 关闭时清空或保持数据根据业务需求
+                console.log('功能已关闭');
+            }
+        },
+        // 确认服务项目
+        confirmProject(e) {
+            this.formData.projectName = e.value[0];
+            this.showProjectPicker = false;
+        },
+
+        // 打开时间选择
+        openTimePicker(field) {
+            this.activeTimeField = field;
+            this.showTimePicker = true;
+            // TODO: 这里可以根据 this.formData[field] 的值去设置 defaultIndex (回显选中位置)
+            // 如果需要回显,需要解析字符串 "09:00-21:00" 并计算索引
+        },
+        // 确认时间
+        confirmTime(e) {
+            const values = e.value; // 拿到选中的数组,如 ["09时", "00分", "至", "21时", "30分"]
+				
+            // 提取数字部分
+            const startHour = values[0].replace('时', '');
+            const startMin = values[1].replace('分', '');
+            const endHour = values[3].replace('时', '');
+            const endMin = values[4].replace('分', '');
+            
+            // 拼接格式
+            const timeString = `${startHour}:${startMin}-${endHour}:${endMin}`;
+            
+            // 赋值给当前激活的字段
+            if(this.activeTimeField) {
+                this.formData[this.activeTimeField] = timeString;
+            }
+            
+            this.showTimePicker = false;
+        },
+
+        // 保存
+        onSave() {
+            if(this.isFree) {
+                // 简单校验
+                if(!this.formData.projectName || !this.formData.distance) {
+                    uni.showToast({
+                        title: '请完善配置信息',
+                        icon: 'none'
+                    });
+                    return;
+                }
+            }
+            
+            console.log('保存数据:', {
+                isFree: this.isFree,
+                ...this.formData
+            });
+            
+            uni.showToast({
+                title: '保存成功',
+                icon: 'success'
+            });
+            
+            setTimeout(() => {
+                uni.navigateBack();
+            }, 1500);
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.page-container {
+    min-height: 100vh;
+    padding: 20rpx;
+    padding-bottom: 120rpx; 
+    background-color: #F6F7F9;
+
+	.card {
+		background-color: #fff;
+		border-radius: 16rpx;
+		margin-bottom: 20rpx;
+		overflow: hidden; 
+	}
+
+	.switch-card {
+		padding: 30rpx;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		
+		.label {
+			font-size: 30rpx;
+			color: #333;
+		}
+	}
+
+    .form-card {
+        .input-slot {
+            width: 300rpx;
+            display: flex;
+            justify-content: flex-end;
+            align-items: center;
+        }
+        
+        .unit-text {
+            color: #333;
+            margin-left: 4rpx;
+            font-size: 30rpx;
+        }
+    }
+	
+	.tips-card {
+		background-color: #fff;
+		border-radius: 16rpx;
+		padding: 30rpx;
+		
+		.tips-title {
+			font-size: 28rpx;
+			font-weight: bold;
+			color: #333;
+			margin-bottom: 16rpx;
+		}
+		
+		.tips-content {
+			font-size: 26rpx;
+			color: #666;
+			line-height: 1.6;
+			margin-bottom: 10rpx;
+			text-align: justify;
+		}
+	}
+}
+</style>

+ 0 - 0
src/pages/demo/settings.vue → src/pages/settings/settings.vue