shish 1 tahun lalu
induk
melakukan
3803f7f692
2 mengubah file dengan 453 tambahan dan 168 penghapusan
  1. 451 168
      hdApp/src/admin/order/refund.vue
  2. 2 0
      hdApp/src/admin/order/refundList.vue

+ 451 - 168
hdApp/src/admin/order/refund.vue

@@ -1,92 +1,149 @@
 <template>
-	<view class="app-content">
-		<view class="flex refund-item">
-			<view class="refund-label">退款方式:</view>
-			<view class="flex list">
-				<button 
-					class="admin-button-com big" 
-					:class="refundType==1?'blue':'default'" 
-					@tap="refundType=1">
-					退货并退款
-				</button>
-				<button 
-					class="admin-button-com big" 
-					:class="refundType==2?'blue':'default'" 
-					@tap="refundType=2"
-					style="margin-left: 30upx;">
-					只退款
-				</button>
+	<view class="refund-page">
+		<!-- 商品选择卡片 -->
+		<view class="card-section">
+			<view class="section-title">
+				<text class="title-text">退货商品</text>
 			</view>
-		</view>
-		<view class="refund-item-list" v-if="refundType==1">
-			<view class="refund-label"><text></text>选择商品:</view>
-			<view>
+			<view class="product-list-compact">
 				<template v-if="!$util.isEmpty(goodsInfoList)">
-					<view class="list" v-for="(res,i) in goodsInfoList" :key="i">
-						<view class="flex list-title" >
-							<text class="product-name">{{res.name}}</text>
-							<text class="product-num">{{ `${parseFloat(res.num)}` }}份</text>
-							<text class="product-price">{{`${parseFloat(res.unitPrice)}`}}元/份</text>
+					<view class="product-row" v-for="(res,i) in goodsInfoList" :key="i">
+						<view class="product-basic-info">
+							<text class="product-name-compact">{{res.name}}</text>
+							<view class="product-meta">
+								<text class="stock-info">数量: {{parseFloat(res.num)}}份</text>
+								<text class="price-info">¥{{parseFloat(res.unitPrice)}}/份</text>
+								<text class="available-info">可退: {{Number(res.num)-Number(res.refundNum)}}份</text>
+							</view>
 						</view>
-						<view class="flex list-val" style="font-size:26upx;font-weight:bold;">
-							<input type="number" placeholder="退货数" v-model="res.refundCount" placeholder-style="color:#CCCCCC" />
-							<text style="margin-left:10upx;">份</text>
-							<text style="color:green;margin-left:20upx;">可退{{Number(res.num)-Number(res.refundNum)}}份</text>
+						<view class="refund-control">
+							<input 
+								class="refund-input-compact" 
+								type="number" 
+								placeholder="0" 
+								v-model="res.refundCount" 
+								placeholder-style="color:#ccc" />
+							<text class="unit-label">份</text>
 						</view>
 					</view>
 				</template>
 				<template v-if="!$util.isEmpty(itemInfoList)">
-					<view class="list" v-for="(res,i) in itemInfoList" :key="i">
-						<view class="flex list-title" >
-							<text class="product-name">{{res.name}}</text>
-							<text class="product-num">{{ `${parseFloat(res.num)}` }}{{res.unitName}}</text>
-							<text class="product-price">{{`${parseFloat(res.unitPrice)}`}}元/{{res.unitName}}</text>
+					<view class="product-row" v-for="(res,i) in itemInfoList" :key="i">
+						<view class="product-basic-info">
+							<text class="product-name-compact">{{res.name}}</text>
+							<view class="product-meta">
+								<text class="stock-info">数量: {{parseFloat(res.num)}}{{res.unitName}}</text>
+								<text class="price-info">¥{{parseFloat(res.unitPrice)}}/{{res.unitName}}</text>
+								<text class="available-info">可退: {{Number(res.num)-Number(res.refundNum)}}{{res.unitName}}</text>
+							</view>
 						</view>
-						<view class="flex list-val" style="font-size:26upx;font-weight:bold;">
-							<input type="number" placeholder="退货数" v-model="res.refundCount" placeholder-style="color:#CCCCCC" style="height:60upx;width:160upx;" />
-							<text style="margin-left:10upx;">{{res.unitName}}</text>
-							<text style="color:green;margin-left:20upx;">可退{{Number(res.num)-Number(res.refundNum)}}{{res.unitName}}</text>
+						<view class="refund-control">
+							<input 
+								class="refund-input-compact" 
+								type="number" 
+								placeholder="0" 
+								v-model="res.refundCount" 
+								placeholder-style="color:#ccc" />
+							<text class="unit-label">{{res.unitName}}</text>
 						</view>
 					</view>
 				</template>
 			</view>
 		</view>
-		<view class="flex refund-item">
-			<view class="refund-label">订单金额:</view>
-			<view class="list">
-				¥{{parseFloat(orderInfo.orderPrice)||0}}
-				<text style="margin-left:25upx;font-size:25upx;color:green;" v-if="Number(orderInfo.tkPrice)>0">已退¥{{orderInfo.tkPrice ? parseFloat(orderInfo.tkPrice) : 0}}</text>
+
+		<!-- 金额信息卡片 -->
+		<view class="card-section">
+			<view class="section-title">
+				<text class="title-text">金额信息</text>
+			</view>
+			<view class="amount-info">
+				<view class="amount-row">
+					<text class="amount-label">订单金额</text>
+					<view class="amount-value">
+						<text class="price-text">¥{{parseFloat(orderInfo.orderPrice)||0}}</text>
+						<text class="refunded-text" v-if="Number(orderInfo.tkPrice)>0">
+							已退 ¥{{orderInfo.tkPrice ? parseFloat(orderInfo.tkPrice) : 0}}
+						</text>
+					</view>
+				</view>
+				<view class="amount-row">
+					<text class="amount-label">可退金额</text>
+					<text class="amount-value available-amount">¥{{coundRefundPrice}}</text>
+				</view>
+				<view class="amount-row input-row">
+					<text class="amount-label required">退款金额</text>
+					<view class="amount-input-wrapper">
+						<text class="currency-symbol">¥</text>
+						<input 
+							class="amount-input" 
+							type="digit" 
+							v-model="refundMoney" 
+							placeholder="请输入退款金额"
+							placeholder-style="color:#999"
+							@focus="refundMoney=''">
+					</view>
+				</view>
 			</view>
 		</view>
-		<view class="flex refund-item">
-			<view class="refund-label">可退金额:</view>
-			<view class="list">¥{{coundRefundPrice}}</view>
+
+		<!-- 退款方式选择卡片 -->
+		<view class="card-section">
+			<view class="section-title">
+				<text class="title-text">库存变化</text>
+			</view>
+			<view class="refund-type-buttons">
+				<button 
+					class="admin-button-com big" 
+					:class="refundType==1?'blue':'default'" 
+					@tap="refundType=1">
+					库存退回来
+				</button>
+				<button 
+					class="admin-button-com big" 
+					:class="refundType==2?'blue':'default'" 
+					@tap="refundType=2">
+					库存不退回
+				</button>
+			</view>
 		</view>
-		<view class="flex refund-item">
-			<view class="refund-label"><text></text>退款金额:</view>
-			<input type="digit" v-model="refundMoney" @focus="refundMoney=''">
+
+		<!-- 备注卡片 -->
+		<view class="card-section">
+			<view class="section-title">
+				<text class="title-text">备注</text>
+			</view>
+			<view class="remark-container">
+				<textarea 
+					class="remark-textarea" 
+					v-model="remark" 
+					placeholder="选填"
+					placeholder-style="color:#999" />
+			</view>
 		</view>
-		<view class="refund-item">
-			<view class="refund-label">备注:</view>
-			<textarea v-model="remark" />
+
+		<!-- 重要提示 -->
+		<view class="warning-notice" v-if="orderInfo.onlinePay == 1">
+			<view class="warning-icon">⚠️</view>
+			<view class="warning-text">
+				<view class="warning-title">重要提示</view>
+				<view class="warning-content">此单为线下付款,退款后钱不会原路退回,还需要线下给客户退钱。</view>
+			</view>
 		</view>
-		<view v-if="orderInfo.onlinePay == 1" style="color:red;margin:15upx 0 15upx 0;font-weight:bold;">请注意:此单线下付款,退货钱不会原路退回,只回滚库存,操作后请线下给客户退款。</view>
-		<view class="flex-center btn-box" style="margin-bottom:50upx;margin-top:20upx;">
-			<view class="flex-center btn" @tap="cancelRefund">取消</view>
-			<view class="flex-center btn active" @tap="confirmRefund" style="margin-left: 80upx">确定</view>
+
+		<!-- 底部操作按钮 -->
+		<view class="bottom-actions">
+			<button class="action-btn cancel-btn" @tap="cancelRefund">取消</button>
+			<button class="action-btn confirm-btn" @tap="confirmRefund">确认退款</button>
 		</view>
 	</view>
 </template>
 <script>
 import { getDetail,refund } from "@/api/order/index";
-import { allRefund } from "@/api/refund"
-import { changeHalf } from "@/api/item"
 export default {
 	name: "orderDetail",
 	components: {},
 	data() {
 		return {
-			product:[],
 			goodsInfoList:[],
 			itemInfoList:[],
 			refundMoney:0,
@@ -96,9 +153,7 @@ export default {
 			coundRefundPrice:0
 		};
 	},
-	onShow(){
 
-	},
 	computed:{
 		refundPrice(){
 			let price = 0
@@ -128,37 +183,11 @@ export default {
 			return price
 		}
 	},
-	watch:{
-	},
+
 	methods: {
-		addHalf(item){
-			let that = this
-			let orderSn = this.orderInfo.orderSn
-			let remark = "零售订单"+orderSn+"售后,退回半扎"
-			that.$util.confirmModal({content:'确认退回半扎?'},() => {
-				uni.showLoading()
-				changeHalf({productId:item.itemId,add:1,remark:remark}).then((res) => {
-					uni.hideLoading()
-					let stock = res.data.stock ? res.data.stock : 0
-					uni.showToast({title: '成功,剩 '+stock,duration:2600,icon:'success'})
-				})
-			})
-		},
 		cancelRefund(){
 			uni.navigateBack({delta: 1});
 		},
-		allRefundFn(){
-			let that = this
-			that.$util.confirmModal({content:'确认全部退货退款?'},() => {
-				uni.showLoading({mask:true})
-				allRefund({id:that.orderInfo.id}).then(res => {
-					uni.hideLoading()
-					if(res.code == 1){
-						that.$util.pageTo({url:'/common/success',query:{titleType:1},type:2})
-					}
-				})
-			})
-		},
 		confirmRefund(){
 			let hasError = false
 			let selectProduct = []
@@ -206,7 +235,7 @@ export default {
 				uni.showToast({title:'请选择商品',icon:'none'})
 				return;
 			}
-			let refundParams = {product:JSON.stringify(selectProduct),id: this.option.id,price:this.refundMoney,remark:this.remark,refundType:this.refundType,getOriginalItem:1}
+			let refundParams = {product:JSON.stringify(selectProduct),id: this.option.id,price:this.refundMoney,remark:this.remark,refundType:this.refundType,getOriginalItem:1,version:2}
 			that.$util.confirmModal({content:'确认退款?'},() => {
 				uni.showLoading({mask:true})
 				refund(refundParams).then(res => {
@@ -236,94 +265,348 @@ export default {
 };
 </script>
 <style lang="scss" scoped>
-.app-content{
-	height: calc(100vh - 30upx * 2);
-	padding: 30upx;
-	background: #FFFFFF;
-	font-size: 30upx;
+.refund-page {
+	min-height: 100vh;
+	background: #f5f6f8;
+	padding: 20upx 0 200upx;
+}
+
+
 
-	.refund-item-list{
+// 卡片样式
+.card-section {
+	background: #fff;
+	margin: 0 20upx 20upx;
+	border-radius: 16upx;
+	box-shadow: 0 2upx 12upx rgba(0, 0, 0, 0.08);
+	overflow: hidden;
+}
+
+// 节标题
+.section-title {
+	padding: 30upx 30upx 20upx;
+	border-bottom: 1upx solid #f0f0f0;
+	display: flex;
+	align-items: center;
+	
+	.title-text {
+		font-size: 32upx;
+		font-weight: 600;
+		color: #333;
+	}
+	
+	.required-mark {
+		color: #ff4757;
+		font-size: 32upx;
+		margin-left: 8upx;
+	}
+}
+
+// 退款方式按钮
+.refund-type-buttons {
+	padding: 30upx 30upx 20upx;
+	display: flex;
+	gap: 30upx;
+	
+	.admin-button-com {
+		flex: 1;
+		border-radius: 12upx;
+		font-weight: 500;
+		transition: all 0.3s ease;
+	}
+}
+
+// 紧凑商品列表
+.product-list-compact {
+	margin-top:15upx;
+	padding: 0 20upx 20upx;
+	max-height: 60vh;
+	overflow-y: auto;
+}
+
+.product-row {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 20upx;
+	margin-bottom: 8upx;
+	background: #fafbfc;
+	border-radius: 8upx;
+	border: 1upx solid #eef0f2;
+	
+	&:last-child {
+		margin-bottom: 0;
+	}
+	
+	&:active {
+		background: #f0f8ff;
+	}
+}
+
+.product-basic-info {
+	flex: 1;
+	margin-right: 20upx;
+	
+	.product-name-compact {
+		font-size: 28upx;
+		font-weight: 600;
+		color: #333;
+		line-height: 1.3;
+		display: block;
+		margin-bottom: 8upx;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+	
+	.product-meta {
 		display: flex;
-		padding-bottom: 30upx;
-		padding-top: 30upx;
-		border-top: 1upx solid #e6e4e4;
-		border-bottom: 1upx solid #e6e4e4;
-		.refund-label{
-			width: 200upx;
-			color:#666666;
-			font-size:26upx;
-			text{color: red;}
+		gap: 12upx;
+		flex-wrap: wrap;
+		
+		.stock-info {
+			font-size: 22upx;
+			color: #666;
+			background: #f5f5f5;
+			padding: 4upx 8upx;
+			border-radius: 4upx;
 		}
-		.list{
-			margin-bottom: 10upx;
-			.list-title{
-				height: 60upx;
-				padding-bottom: 20upx;
-				font-size:26upx;
-				font-weight:bold;
-				.product-name{
-					overflow: hidden;
-					text-overflow:ellipsis;
-					white-space: nowrap;
-					width:190upx;
-				}
-				.product-price{
-					overflow: hidden;
-					text-overflow:ellipsis;
-					white-space: nowrap;
-					width:130upx;
-					margin-left:10upx;
-				}
-				.product-num{
-					width:90upx;
-					overflow: hidden;
-					text-overflow:ellipsis;
-					white-space: nowrap;
-					margin-left:10upx;
-				}
-			}
-			.list-val{
-				input{
-					width: 200upx;
-					border: 1upx solid #ddd;
-					text-align: center;
-					font-weight: normal;
-				}
-			}
+		
+		.price-info {
+			font-size: 22upx;
+			color: #09c567;
+			background: rgba(9, 197, 103, 0.1);
+			padding: 4upx 8upx;
+			border-radius: 4upx;
+			font-weight: 500;
+		}
+		
+		.available-info {
+			font-size: 22upx;
+			color: #ff6b35;
+			background: rgba(255, 107, 53, 0.1);
+			padding: 4upx 8upx;
+			border-radius: 4upx;
+		}
+	}
+}
+
+.refund-control {
+	display: flex;
+	align-items: center;
+	gap: 8upx;
+	
+	.refund-input-compact {
+		width: 100upx;
+		height: 60upx;
+		background: #fff;
+		border: 1upx solid #ddd;
+		border-radius: 6upx;
+		text-align: center;
+		font-size: 26upx;
+		color: #333;
+		font-weight: 500;
+		
+		&:focus {
+			border-color: #09c567;
+			box-shadow: 0 0 0 2upx rgba(9, 197, 103, 0.2);
+		}
+	}
+	
+	.unit-label {
+		font-size: 24upx;
+		color: #666;
+		min-width: 40upx;
+	}
+}
+
+// 金额信息
+.amount-info {
+	padding: 30upx;
+}
+
+.amount-row {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding: 20upx 0;
+	border-bottom: 1upx solid #f0f0f0;
+	
+	&:last-child {
+		border-bottom: none;
+	}
+	
+	&.input-row {
+		align-items: flex-start;
+		padding-top: 30upx;
+	}
+	
+	.amount-label {
+		font-size: 28upx;
+		color: #666;
+		
+		&.required::after {
+			content: "*";
+			color: #ff4757;
+			margin-left: 5upx;
 		}
 	}
-	.refund-item{
+	
+	.amount-value {
 		display: flex;
-		padding: 18upx 0;
-		.refund-label{
-			width: 200upx;
-			color:#666666;
-			font-size:26upx;
-			text{
-				color: red;
-			}
+		align-items: center;
+		
+		.price-text {
+			font-size: 32upx;
+			font-weight: 600;
+			color: #333;
 		}
-		input{
-			border: 1upx solid #ddd;
+		
+		.refunded-text {
+			margin-left: 20upx;
+			font-size: 24upx;
+			color: #09c567;
+			background: rgba(9, 197, 103, 0.1);
+			padding: 6upx 12upx;
+			border-radius: 16upx;
 		}
-		textarea{
-			width: calc(100% - 210upx);
-			height:150upx;
-			border: 1upx solid #ddd;
+		
+		&.available-amount {
+			font-size: 32upx;
+			font-weight: 600;
+			color: #09c567;
 		}
 	}
-	.btn-box{
-		.btn{
-			width: 220upx;
-			height: 90upx;
-			border: 1upx solid #666666;
-			border-radius: 10upx;
-			color:#666666;
-			&.active{
-				background: #3385ff;
-				color: #fff;
-				border: 1upx solid #3385ff;
-			}
+}
+
+.amount-input-wrapper {
+	display: flex;
+	align-items: center;
+	background: #fafbfc;
+	border: 1upx solid #ddd;
+	border-radius: 8upx;
+	padding: 0 20upx;
+	min-width: 300upx;
+	
+	&:focus-within {
+		border-color: #09c567;
+	}
+	
+	.currency-symbol {
+		font-size: 28upx;
+		color: #666;
+		margin-right: 10upx;
+	}
+	
+	.amount-input {
+		flex: 1;
+		height: 80upx;
+		font-size: 28upx;
+		color: #333;
+		font-weight: 500;
+		border: none;
+		background: transparent;
+	}
+}
+
+// 备注输入框
+.remark-container {
+	padding: 20upx 30upx 30upx;
+}
+
+.remark-textarea {
+	width: 100%;
+	height: 120upx;
+	background: #fafbfc;
+	border: 1upx solid #ddd;
+	border-radius: 8upx;
+	padding: 15upx;
+	font-size: 28upx;
+	color: #333;
+	line-height: 1.2;
+	box-sizing: border-box;
+	resize: none;
+	
+	&:focus {
+		border-color: #09c567;
+	}
+}
+
+// 警告提示
+.warning-notice {
+	background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
+	margin: 0 20upx 20upx;
+	border-radius: 16upx;
+	border-left: 6upx solid #f39c12;
+	padding: 30upx;
+	display: flex;
+	align-items: flex-start;
+	
+	.warning-icon {
+		font-size: 40upx;
+		margin-right: 20upx;
+		margin-top: 5upx;
+	}
+	
+	.warning-text {
+		flex: 1;
+		
+		.warning-title {
+			font-size: 28upx;
+			font-weight: 600;
+			color: #d68910;
+			margin-bottom: 12upx;
+		}
+		
+		.warning-content {
+			font-size: 26upx;
+			color: #85751a;
+			line-height: 1.5;
+		}
+	}
+}
+
+// 底部操作按钮
+.bottom-actions {
+	position: fixed;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	background: #fff;
+	padding: 30upx;
+	border-top: 1upx solid #eee;
+	display: flex;
+	gap: 30upx;
+	box-shadow: 0 -4upx 12upx rgba(0, 0, 0, 0.1);
+}
+
+.action-btn {
+	flex: 1;
+	height: 88upx;
+	border-radius: 12upx;
+	font-size: 32upx;
+	font-weight: 600;
+	border: none;
+	transition: all 0.3s ease;
+	
+	&.cancel-btn {
+		background: #f8f9fa;
+		color: #666;
+		border: 1upx solid #ddd;
+		
+		&:active {
+			background: #e9ecef;
+		}
+	}
+	
+	&.confirm-btn {
+		background: linear-gradient(135deg, #09c567 0%, #00b894 100%);
+		color: #fff;
+		box-shadow: 0 4upx 12upx rgba(9, 197, 103, 0.3);
+		
+		&:active {
+			transform: translateY(2upx);
+			box-shadow: 0 2upx 8upx rgba(9, 197, 103, 0.3);
 		}
 	}
 }

+ 2 - 0
hdApp/src/admin/order/refundList.vue

@@ -56,6 +56,8 @@ export default {
     this._list();
   },
   methods: {
+    init(){
+    },
     goDetail(item){
       this.$util.pageTo({url: '/admin/order/refundDetail',query: {id: item.id}})
     },