shish 4 days ago
parent
commit
7cd168ba8f

+ 35 - 16
ghsApp/src/admin/billing/forwardResult.vue

@@ -4,7 +4,7 @@
   海报图直接展示在本页(不弹框),可长按转发或保存;其它 fundType 仅展示简单成功信息。
   海报图直接展示在本页(不弹框),可长按转发或保存;其它 fundType 仅展示简单成功信息。
 -->
 -->
 <template>
 <template>
-	<appResult title="冲销成功">
+	<appResult :title="pageTitle">
 		<!-- 返余额:金额/单号/余额已在海报图内展示,页面上不再重复 -->
 		<!-- 返余额:金额/单号/余额已在海报图内展示,页面上不再重复 -->
 		<view class="forward-info" v-if="Number(fundType) !== 2">
 		<view class="forward-info" v-if="Number(fundType) !== 2">
 			<text class="forward-info__amount">冲销成功 ¥{{ formatMoney(actPrice) }}</text>
 			<text class="forward-info__amount">冲销成功 ¥{{ formatMoney(actPrice) }}</text>
@@ -39,12 +39,7 @@
 				class="admin-button-com big blue btn-item"
 				class="admin-button-com big blue btn-item"
 				@click="generatePoster"
 				@click="generatePoster"
 			>重新生成凭证</button>
 			>重新生成凭证</button>
-			<button
-				v-if="orderId"
-				class="admin-button-com big blue btn-item"
-				@click="goOrder"
-			>查看原单</button>
-			<button class="admin-button-com big btn-item" @click="goHome">返回首页</button>
+			<button class="admin-button-com big btn-item" @click="goBack">{{ isRepost ? '返回' : '返回首页' }}</button>
 		</view>
 		</view>
 
 
 		<canvas
 		<canvas
@@ -82,7 +77,9 @@ export default {
 			posterUrl: '',
 			posterUrl: '',
 			drawing: false,
 			drawing: false,
 			canvasW: 360,
 			canvasW: 360,
-			canvasH: 640
+			canvasH: 640,
+			// repost:从冲销列表/详情补发凭证,非首次冲销成功
+			mode: ''
 		}
 		}
 	},
 	},
 	computed: {
 	computed: {
@@ -92,9 +89,16 @@ export default {
 		},
 		},
 		hasBalance() {
 		hasBalance() {
 			return this.customBalance !== null && this.customBalance !== '' && !isNaN(Number(this.customBalance))
 			return this.customBalance !== null && this.customBalance !== '' && !isNaN(Number(this.customBalance))
+		},
+		isRepost() {
+			return this.mode === 'repost'
+		},
+		pageTitle() {
+			return this.isRepost ? '退款凭证' : '冲销成功'
 		}
 		}
 	},
 	},
 	onLoad(option) {
 	onLoad(option) {
+		this.mode = option.mode || ''
 		this.fundType = Number(option.fundType || 0)
 		this.fundType = Number(option.fundType || 0)
 		this.actPrice = parseFloat(option.amount || option.actPrice || 0)
 		this.actPrice = parseFloat(option.amount || option.actPrice || 0)
 		this.customId = Number(option.customId || 0)
 		this.customId = Number(option.customId || 0)
@@ -127,6 +131,7 @@ export default {
 			}
 			}
 			return n.toFixed(2)
 			return n.toFixed(2)
 		},
 		},
+		init(){},
 		/**
 		/**
 		 * 读取冲销成功跳转前写入的缓存,补全余额/单号等关键字段
 		 * 读取冲销成功跳转前写入的缓存,补全余额/单号等关键字段
 		 */
 		 */
@@ -200,6 +205,10 @@ export default {
 			Promise.all([codeReq, detailReq]).then(([res, detRes]) => {
 			Promise.all([codeReq, detailReq]).then(([res, detRes]) => {
 				if (detRes && detRes.code == 1 && detRes.data) {
 				if (detRes && detRes.code == 1 && detRes.data) {
 					that.applyBalanceFromApi(detRes.data.balance)
 					that.applyBalanceFromApi(detRes.data.balance)
+					// 补发场景列表可能没带客户名,用详情接口补全海报抬头
+					if (!that.customName && detRes.data.name) {
+						that.customName = detRes.data.name
+					}
 				}
 				}
 				if (res.code == 1 && res.data && res.data.imgUrl) {
 				if (res.code == 1 && res.data && res.data.imgUrl) {
 					that.applyBalanceFromApi(res.data.balance)
 					that.applyBalanceFromApi(res.data.balance)
@@ -234,7 +243,8 @@ export default {
 		 * 按可用宽度缩小单号字号,保证与「冲销单号」标签同一行且不重叠
 		 * 按可用宽度缩小单号字号,保证与「冲销单号」标签同一行且不重叠
 		 */
 		 */
 		fitSnFontSize(ctx, sn, maxWidth) {
 		fitSnFontSize(ctx, sn, maxWidth) {
-			let size = 16
+			// 与明细行字号对齐,起始略小于标签,便于长单号一行放下
+			let size = 14
 			while (size > 10) {
 			while (size > 10) {
 				ctx.setFontSize(size)
 				ctx.setFontSize(size)
 				const measured = ctx.measureText ? ctx.measureText(sn) : null
 				const measured = ctx.measureText ? ctx.measureText(sn) : null
@@ -298,9 +308,12 @@ export default {
 			ctx.lineTo(width - padX, 258)
 			ctx.lineTo(width - padX, 258)
 			ctx.stroke()
 			ctx.stroke()
 
 
+			// 明细三行字号整体小 4(相对原 24/20),避免信息区过抢眼
+			const rowLabelSize = 20
+			const rowValueSize = 16
 			// 最新余额(有值才画金额,无值画 --)
 			// 最新余额(有值才画金额,无值画 --)
 			const balanceText = this.hasBalance ? ('¥' + this.formatMoney(this.customBalance)) : '--'
 			const balanceText = this.hasBalance ? ('¥' + this.formatMoney(this.customBalance)) : '--'
-			ctx.setFontSize(24)
+			ctx.setFontSize(rowLabelSize)
 			ctx.setFillStyle('#333333')
 			ctx.setFillStyle('#333333')
 			ctx.setTextAlign('left')
 			ctx.setTextAlign('left')
 			ctx.fillText('最新余额', padX, 298)
 			ctx.fillText('最新余额', padX, 298)
@@ -311,12 +324,11 @@ export default {
 			// 冲销单号同一行:左侧标签,右侧按宽度缩小字号,保证不换行、不重叠
 			// 冲销单号同一行:左侧标签,右侧按宽度缩小字号,保证不换行、不重叠
 			const snLabel = '冲销单号'
 			const snLabel = '冲销单号'
 			const snText = this.forwardSn || '--'
 			const snText = this.forwardSn || '--'
-			const snLabelSize = 24
-			ctx.setFontSize(snLabelSize)
+			ctx.setFontSize(rowLabelSize)
 			ctx.setFillStyle('#333333')
 			ctx.setFillStyle('#333333')
 			ctx.setTextAlign('left')
 			ctx.setTextAlign('left')
 			ctx.fillText(snLabel, padX, 333)
 			ctx.fillText(snLabel, padX, 333)
-			const snLabelW = (ctx.measureText ? ctx.measureText(snLabel).width : snLabelSize * 4) || snLabelSize * 4
+			const snLabelW = (ctx.measureText ? ctx.measureText(snLabel).width : rowLabelSize * 4) || rowLabelSize * 4
 			const snMaxW = width - padX * 2 - snLabelW - 16
 			const snMaxW = width - padX * 2 - snLabelW - 16
 			const snSize = this.fitSnFontSize(ctx, snText, snMaxW)
 			const snSize = this.fitSnFontSize(ctx, snText, snMaxW)
 			ctx.setTextAlign('right')
 			ctx.setTextAlign('right')
@@ -324,12 +336,12 @@ export default {
 			ctx.setFillStyle('#666666')
 			ctx.setFillStyle('#666666')
 			ctx.fillText(snText, width - padX, 333)
 			ctx.fillText(snText, width - padX, 333)
 
 
-			ctx.setFontSize(24)
+			ctx.setFontSize(rowLabelSize)
 			ctx.setFillStyle('#333333')
 			ctx.setFillStyle('#333333')
 			ctx.setTextAlign('left')
 			ctx.setTextAlign('left')
 			ctx.fillText('日期', padX, 368)
 			ctx.fillText('日期', padX, 368)
 			ctx.setTextAlign('right')
 			ctx.setTextAlign('right')
-			ctx.setFontSize(20)
+			ctx.setFontSize(rowValueSize)
 			ctx.setFillStyle('#666666')
 			ctx.setFillStyle('#666666')
 			ctx.fillText(dayjs().format('YYYY-MM-DD HH:mm'), width - padX, 368)
 			ctx.fillText(dayjs().format('YYYY-MM-DD HH:mm'), width - padX, 368)
 
 
@@ -393,7 +405,14 @@ export default {
 			}
 			}
 			this.$util.pageTo({ url: '/pagesOrder/detail', type: 2, query: { id: this.orderId } })
 			this.$util.pageTo({ url: '/pagesOrder/detail', type: 2, query: { id: this.orderId } })
 		},
 		},
-		goHome() {
+		/**
+		 * 首次成功回首页;列表/详情补发则返回上一页
+		 */
+		goBack() {
+			if (this.isRepost) {
+				uni.navigateBack({ delta: 1 })
+				return
+			}
 			this.$util.pageTo({ url: '/admin/home/workbench', type: 2 })
 			this.$util.pageTo({ url: '/admin/home/workbench', type: 2 })
 		}
 		}
 	}
 	}

+ 14 - 0
ghsApp/src/admin/home/components/OrderItem.vue

@@ -7,6 +7,8 @@
         <image class="avatar" mode="aspectFit" :src="item.customAvatarUrl"></image>
         <image class="avatar" mode="aspectFit" :src="item.customAvatarUrl"></image>
         <view class="tit"> {{ item.customName || '' }}</view>
         <view class="tit"> {{ item.customName || '' }}</view>
         <view class="other-refund" v-if="item.refund == 2">有售后</view>
         <view class="other-refund" v-if="item.refund == 2">有售后</view>
+        <!-- 方案A:有成功冲销凭证时展示,与「有售后」同级提示 -->
+        <view class="other-forward" v-if="item.hasForward == 1">有冲销</view>
         <view class="other-status" v-if="item.debt == 1">挂账</view>
         <view class="other-status" v-if="item.debt == 1">挂账</view>
         <text class="other-book" v-if="item.book == 1">预订单</text>
         <text class="other-book" v-if="item.book == 1">预订单</text>
         <text class="other-presell" v-if="item.presell == 1">预售单</text>
         <text class="other-presell" v-if="item.presell == 1">预售单</text>
@@ -725,6 +727,18 @@ export default {
     margin-right: 20upx;
     margin-right: 20upx;
     width: auto;
     width: auto;
   }
   }
+  /* 冲销角标:与有售后同风格,略偏橙便于区分 */
+  & > .other-forward {
+    text-align: center;
+    color: white;
+    background-color: #e67e22;
+    border: 2upx solid #e67e22;
+    border-radius: 30upx;
+    padding: 5upx 12upx;
+    font-size: 20upx;
+    margin-right: 20upx;
+    width: auto;
+  }
   & > .other-status {
   & > .other-status {
     text-align: center;
     text-align: center;
     color: white;
     color: white;

+ 56 - 1
ghsApp/src/pagesOrder/forwardDetail.vue

@@ -1,6 +1,6 @@
 <!--
 <!--
   冲销凭证详情(方案A)
   冲销凭证详情(方案A)
-  用途:展示凭证主信息与花材明细;供列表页跳转查看,不可编辑
+  用途:展示凭证主信息与花材明细;返余额时可重新生成退款凭证海报补发
 -->
 -->
 <template>
 <template>
 	<view class="forward-detail">
 	<view class="forward-detail">
@@ -50,6 +50,11 @@
 				</text>
 				</text>
 			</view>
 			</view>
 		</view>
 		</view>
+
+		<!-- 返余额:成功页漏转发时可在此补发凭证海报 -->
+		<view class="footer" v-if="Number(info.fundType) === 2">
+			<button class="admin-button-com big blue" @click="goPoster">重新生成凭证</button>
+		</view>
 	</view>
 	</view>
 </template>
 </template>
 
 
@@ -89,6 +94,39 @@ export default {
 			}).catch(() => {
 			}).catch(() => {
 				uni.hideLoading()
 				uni.hideLoading()
 			})
 			})
+		},
+		/**
+		 * 跳转凭证页重新绘制海报,供成功页漏转发后补发
+		 */
+		goPoster() {
+			const info = this.info || {}
+			if (!info.id || Number(info.fundType) !== 2) {
+				return
+			}
+			uni.setStorageSync('forwardResultPayload', {
+				fundType: info.fundType,
+				amount: info.amount,
+				customId: info.customId || 0,
+				customBalance: info.customBalance != null ? info.customBalance : '',
+				customName: info.customName || '',
+				forwardSn: info.forwardSn || '',
+				forwardId: info.id,
+				orderId: info.orderId || 0
+			})
+			this.$util.pageTo({
+				url: '/admin/billing/forwardResult',
+				query: {
+					mode: 'repost',
+					fundType: info.fundType,
+					amount: info.amount,
+					customId: info.customId || 0,
+					customBalance: info.customBalance != null ? info.customBalance : '',
+					customName: encodeURIComponent(info.customName || ''),
+					forwardSn: info.forwardSn || '',
+					forwardId: info.id,
+					orderId: info.orderId || 0
+				}
+			})
 		}
 		}
 	}
 	}
 }
 }
@@ -98,10 +136,27 @@ export default {
 .forward-detail {
 .forward-detail {
 	min-height: 100vh;
 	min-height: 100vh;
 	padding: 24upx;
 	padding: 24upx;
+	padding-bottom: 160upx;
 	background: #f5f7fa;
 	background: #f5f7fa;
 	box-sizing: border-box;
 	box-sizing: border-box;
 }
 }
 
 
+.footer {
+	position: fixed;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	padding: 20upx 30upx;
+	padding-bottom: calc(20upx + env(safe-area-inset-bottom));
+	background: #fff;
+	box-shadow: 0 -4upx 16upx rgba(0, 0, 0, 0.06);
+	box-sizing: border-box;
+
+	button {
+		width: 100%;
+	}
+}
+
 .card {
 .card {
 	background: #fff;
 	background: #fff;
 	border-radius: 16upx;
 	border-radius: 16upx;

+ 64 - 11
ghsApp/src/pagesOrder/forwardList.vue

@@ -1,6 +1,7 @@
 <!--
 <!--
   冲销凭证列表(方案A)
   冲销凭证列表(方案A)
-  用途:按原销售单 orderId 展示累计冲销凭证,点击进详情;与售后记录分开展示。
+  用途:按原销售单 orderId 展示累计冲销凭证,点击进详情;
+  返余额凭证可在此补发「退款凭证」海报(成功页忘记转发时)。
 -->
 -->
 <template>
 <template>
 	<view class="app-content">
 	<view class="app-content">
@@ -9,17 +10,23 @@
 			<text class="sum-bar__price">¥{{ parseFloat(forwardPrice) }}</text>
 			<text class="sum-bar__price">¥{{ parseFloat(forwardPrice) }}</text>
 		</view>
 		</view>
 		<block v-if="!$util.isEmpty(list.data)">
 		<block v-if="!$util.isEmpty(list.data)">
-			<view class="flex-space list" v-for="(item, index) in list.data" :key="index" @click="goDetail(item)">
-				<view class="label">
-					<text>日期:{{ item.addTime ? item.addTime.substr(5, 11) : '' }}</text>
-					<text>单号:{{ item.forwardSn }}</text>
-					<text>资金:{{ fundTypeText(item.fundType) }}</text>
-					<text>库存:{{ item.forwardStock == 0 ? '已回库' : '未回库' }}</text>
-					<text v-if="!$util.isEmpty(item.remark)">备注:{{ item.remark }}</text>
+			<view class="list" v-for="(item, index) in list.data" :key="index" @click="goDetail(item)">
+				<view class="flex-space list__main">
+					<view class="label">
+						<text>日期:{{ item.addTime ? item.addTime.substr(5, 11) : '' }}</text>
+						<text>单号:{{ item.forwardSn }}</text>
+						<text>资金:{{ fundTypeText(item.fundType) }}</text>
+						<text>库存:{{ item.forwardStock == 0 ? '已回库' : '未回库' }}</text>
+						<text v-if="!$util.isEmpty(item.remark)">备注:{{ item.remark }}</text>
+					</view>
+					<view class="flex val">
+						-¥{{ parseFloat(item.amount) }}
+						<view class="iconfont iconxiangyou"></view>
+					</view>
 				</view>
 				</view>
-				<view class="flex val">
-					-¥{{ parseFloat(item.amount) }}
-					<view class="iconfont iconxiangyou"></view>
+				<!-- 仅返余额有退款凭证海报,可补发生成 -->
+				<view v-if="Number(item.fundType) === 2" class="list__actions" @click.stop>
+					<button class="admin-button-com middel blue" @click.stop="goPoster(item)">重新生成凭证</button>
 				</view>
 				</view>
 			</view>
 			</view>
 		</block>
 		</block>
@@ -56,12 +63,45 @@ export default {
 			const map = { 1: '原路退', 2: '返余额', 3: '仅记账' }
 			const map = { 1: '原路退', 2: '返余额', 3: '仅记账' }
 			return map[Number(type)] || '--'
 			return map[Number(type)] || '--'
 		},
 		},
+		init(){},
 		goDetail(item) {
 		goDetail(item) {
 			if (!item.id) {
 			if (!item.id) {
 				return
 				return
 			}
 			}
 			this.$util.pageTo({ url: '/pagesOrder/forwardDetail', query: { id: item.id } })
 			this.$util.pageTo({ url: '/pagesOrder/forwardDetail', query: { id: item.id } })
 		},
 		},
+		/**
+		 * 跳转凭证页重新绘制海报,供成功页漏转发后补发
+		 */
+		goPoster(item) {
+			if (!item || !item.id || Number(item.fundType) !== 2) {
+				return
+			}
+			uni.setStorageSync('forwardResultPayload', {
+				fundType: item.fundType,
+				amount: item.amount,
+				customId: item.customId || 0,
+				customBalance: item.customBalance != null ? item.customBalance : '',
+				customName: item.customName || '',
+				forwardSn: item.forwardSn || '',
+				forwardId: item.id,
+				orderId: item.orderId || 0
+			})
+			this.$util.pageTo({
+				url: '/admin/billing/forwardResult',
+				query: {
+					mode: 'repost',
+					fundType: item.fundType,
+					amount: item.amount,
+					customId: item.customId || 0,
+					customBalance: item.customBalance != null ? item.customBalance : '',
+					customName: encodeURIComponent(item.customName || ''),
+					forwardSn: item.forwardSn || '',
+					forwardId: item.id,
+					orderId: item.orderId || 0
+				}
+			})
+		},
 		/** 冲销列表不分页,一次拉完后标记 finished */
 		/** 冲销列表不分页,一次拉完后标记 finished */
 		_list() {
 		_list() {
 			return listByOrder({
 			return listByOrder({
@@ -109,6 +149,10 @@ export default {
 		margin-bottom: 20upx;
 		margin-bottom: 20upx;
 		background: #ffffff;
 		background: #ffffff;
 
 
+		&__main {
+			width: 100%;
+		}
+
 		.label {
 		.label {
 			position: relative;
 			position: relative;
 			line-height: 50upx;
 			line-height: 50upx;
@@ -128,6 +172,15 @@ export default {
 				color: #999999;
 				color: #999999;
 			}
 			}
 		}
 		}
+
+		&__actions {
+			display: flex;
+			flex-direction: row;
+			justify-content: flex-end;
+			margin-top: 16upx;
+			padding-top: 16upx;
+			border-top: 1upx solid #f0f2f5;
+		}
 	}
 	}
 }
 }
 </style>
 </style>

+ 2 - 0
hdApp/src/pagesPurchase/orderItem.vue

@@ -9,6 +9,8 @@
         </text>
         </text>
       </view>
       </view>
       <view v-if="info.refund == 2" class="status" style="color:red;border:1px solid red;border-radius:20upx;font-size:20upx;padding:5upx 12upx;margin-right:40upx;">有退款</view>
       <view v-if="info.refund == 2" class="status" style="color:red;border:1px solid red;border-radius:20upx;font-size:20upx;padding:5upx 12upx;margin-right:40upx;">有退款</view>
+      <!-- 方案A:采购单有冲销凭证时展示,与有退款同级提示 -->
+      <view v-if="info.hasForward == 1" class="status" style="color:#e67e22;border:1px solid #e67e22;border-radius:20upx;font-size:20upx;padding:5upx 12upx;margin-right:40upx;">有冲销</view>
       <view v-if="info.debt == 1" class="status" style="color:red;border:1px solid red;border-radius:20upx;font-size:20upx;padding:5upx 12upx;margin-right:40upx;">挂账</view>
       <view v-if="info.debt == 1" class="status" style="color:red;border:1px solid red;border-radius:20upx;font-size:20upx;padding:5upx 12upx;margin-right:40upx;">挂账</view>
       <text v-if="info.book == 1" class="status"  style="color:white;border:1px solid #657cac;border-radius:20upx;font-size:20upx;padding:5upx 12upx;margin-right:40upx;background:#657cac;">预订单</text>
       <text v-if="info.book == 1" class="status"  style="color:white;border:1px solid #657cac;border-radius:20upx;font-size:20upx;padding:5upx 12upx;margin-right:40upx;background:#657cac;">预订单</text>
       <view class="status" v-if="info.status == 3" style="color:green;font-weight:bold;">{{ getStatusName }} </view>
       <view class="status" v-if="info.status == 3" style="color:green;font-weight:bold;">{{ getStatusName }} </view>