Răsfoiți Sursa

批发端、零售店余额明细列表新增筛选字段:收支类型、事件类型

ouyang 3 săptămâni în urmă
părinte
comite
e55737c95c

+ 286 - 4
ghsApp/src/admin/shopYeChange/list.vue

@@ -1,7 +1,18 @@
 <template>
 	<view class="app-content">
-		<view style="text-align:center;padding-top:20upx;margin-bottom:20upx;">
-			<DateSelect class="bar" top="0" @selectDateFn="selectDateFn" />
+		<!-- 日期与筛选栏:筛选样式对齐 pagesPurchase/supplier -->
+		<view class="toolbar-wrap">
+			<!-- 左侧占位,与右侧筛选同宽,保证日期视觉居中 -->
+			<view class="toolbar-side"></view>
+			<view class="date-wrap">
+				<DateSelect class="bar" top="0" @selectDateFn="selectDateFn" />
+			</view>
+			<view class="toolbar-side toolbar-side--right">
+				<view class="filter-btn-wrap">
+					<button class="admin-button-com middle" @click="openFilterPanel">筛选</button>
+					<view v-if="hasActiveFilters" class="filter-dot"></view>
+				</view>
+			</view>
 		</view>
 		<view class="main-view">
 			<block v-if="!$util.isEmpty(list.data)">
@@ -43,6 +54,47 @@
 				<AppWrapperEmpty title="暂无数据" :is-empty="$util.isEmpty(list.data)" />
 			</block>
 		</view>
+
+		<!-- 筛选面板:增减余额 io、事项 capitalType -->
+		<view v-if="showFilterPanel" class="filter-overlay" @click="closeFilterPanel">
+			<view class="filter-panel" @click.stop>
+				<view class="filter-header">筛选变动明细</view>
+				<scroll-view class="filter-body" scroll-y>
+					<view class="filter-section">
+						<view class="filter-title">增减余额</view>
+						<view class="filter-options">
+							<view
+								v-for="(item, index) in ioOptions"
+								:key="'io-' + index"
+								class="filter-option"
+								:class="{ active: filterIo === item.value }"
+								@click="onSelectIo(index)"
+							>
+								{{ item.label }}
+							</view>
+						</view>
+					</view>
+					<view class="filter-section">
+						<view class="filter-title">事项</view>
+						<view class="filter-options">
+							<view
+								v-for="(item, index) in capitalTypeOptions"
+								:key="'capital-' + index"
+								class="filter-option"
+								:class="{ active: filterCapitalType === item.value }"
+								@click="onSelectCapitalType(index)"
+							>
+								{{ item.label }}
+							</view>
+						</view>
+					</view>
+				</scroll-view>
+				<view class="filter-actions">
+					<button class="filter-action-btn clear-btn" @click="clearFilters">重置</button>
+					<button class="filter-action-btn confirm-btn" @click="confirmFilters">确定</button>
+				</view>
+			</view>
+		</view>
 	</view>
 </template>
 <script>
@@ -50,6 +102,8 @@ import DateSelect from "@/components/module/dateSelect";
 import AppWrapperEmpty from "@/components/app-wrapper-empty";
 import { changeList } from '@/api/shop-ye-change'
 import list from '@/mixins/list'
+
+// 余额变动明细列表:日期 + 筛选(io、capitalType)查询 shop-ye-change/list
 export default {
 	name: "list",
 	components: {
@@ -63,17 +117,90 @@ export default {
 				searchTime:'',
 				startTime: "",
 				endTime: "",
-			}
+			},
+			showFilterPanel: false,
+			// -1 表示全部,请求时不传对应字段
+			filterIo: -1,
+			filterCapitalType: -1,
+			ioOptions: [
+				{ label: '全部', value: -1 },
+				{ label: '增加余额', value: 1 },
+				{ label: '减少余额', value: 0 },
+			],
+			capitalTypeOptions: [
+				{ label: '全部', value: -1 },
+				{ label: '采购退款', value: 1 },
+				{ label: '充值', value: 4 },
+				{ label: '提现', value: 6 },
+				{ label: '下单', value: 10 },
+				{ label: '采购', value: 11 },
+				{ label: '结算', value: 20 },
+				{ label: '退款', value: 38 },
+				{ label: '充值', value: 66 },
+				{ label: '扫码付款', value: 79 },
+				{ label: '扫码退款', value: 80 },
+			],
 		};
 	},
+	computed: {
+		// 任一筛选项非「全部」时显示角标
+		hasActiveFilters() {
+			return this.filterIo !== -1 || this.filterCapitalType !== -1
+		}
+	},
 	methods: {
 		selectDateFn(val) {
 			this.params = {...this.params,...val}
 			this.resetList()
 			this.init()
 		},
+		openFilterPanel() {
+			this.showFilterPanel = true
+		},
+		closeFilterPanel() {
+			this.showFilterPanel = false
+		},
+		onSelectIo(index) {
+			const item = this.ioOptions[index]
+			if (item) {
+				this.filterIo = item.value
+			}
+		},
+		onSelectCapitalType(index) {
+			const item = this.capitalTypeOptions[index]
+			if (item) {
+				this.filterCapitalType = item.value
+			}
+		},
+		clearFilters() {
+			this.filterIo = -1
+			this.filterCapitalType = -1
+			this.closeFilterPanel()
+			this.resetList()
+			this.init()
+		},
+		confirmFilters() {
+			this.closeFilterPanel()
+			this.resetList()
+			this.init()
+		},
+		/** 组装列表请求参数:仅在有筛选值时传 io、capitalType */
+		buildListParams() {
+			const params = {
+				page: this.list.page,
+				tx: 0,
+				...this.params
+			}
+			if (this.filterIo !== -1) {
+				params.io = this.filterIo
+			}
+			if (this.filterCapitalType !== -1) {
+				params.capitalType = this.filterCapitalType
+			}
+			return params
+		},
 		async init(){
-			const res = await changeList({ page:this.list.page,tx:0,...this.params })
+			const res = await changeList(this.buildListParams())
 			if (this.$util.isEmpty(res.data.list)){
 				this.completes(res)
 				return
@@ -110,6 +237,49 @@ export default {
 	min-height: 100vh;
 }
 
+.toolbar-wrap {
+	display: flex;
+	align-items: center;
+	padding: 20upx 24upx;
+	margin-bottom: 20upx;
+	background-color: #fff;
+	border-bottom: 1upx solid #eef1f6;
+}
+
+.toolbar-side {
+	flex: 0 0 120upx;
+	display: flex;
+	align-items: center;
+}
+
+.toolbar-side--right {
+	justify-content: flex-end;
+}
+
+.date-wrap {
+	flex: 1;
+	min-width: 0;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+}
+
+.filter-btn-wrap {
+	position: relative;
+	display: flex;
+	align-items: center;
+}
+
+.filter-dot {
+	position: absolute;
+	top: 6upx;
+	right: 6upx;
+	width: 14upx;
+	height: 14upx;
+	border-radius: 50%;
+	background-color: #3385ff;
+}
+
 .main-view {
 	padding: 0;
 }
@@ -222,4 +392,116 @@ export default {
 	text-align: right;
 	width: 100%;
 }
+
+.filter-overlay {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	z-index: 9999999;
+	display: flex;
+	align-items: flex-start;
+	justify-content: center;
+	background-color: rgba(0, 0, 0, 0.5);
+}
+
+.filter-panel {
+	display: flex;
+	flex-direction: column;
+	width: 100%;
+	height: 90vh;
+	max-height: 90vh;
+	overflow: hidden;
+	border-radius: 0 0 24upx 24upx;
+	background: #fff;
+}
+
+.filter-header {
+	flex-shrink: 0;
+	padding: 24upx 0;
+	text-align: center;
+	color: #333;
+	font-size: 32upx;
+	font-weight: 700;
+	border-bottom: 1upx solid #f0f0f0;
+}
+
+.filter-body {
+	flex: 1;
+	min-height: 0;
+	height: 0;
+	width: 100%;
+	box-sizing: border-box;
+}
+
+.filter-section {
+	padding: 30upx 40upx;
+	border-bottom: 1upx solid #f0f0f0;
+}
+
+.filter-title {
+	margin-bottom: 20upx;
+	color: #333;
+	font-size: 28upx;
+	font-weight: 700;
+}
+
+.filter-options {
+	display: flex;
+	flex-wrap: wrap;
+}
+
+.filter-option {
+	min-width: 120upx;
+	padding: 15upx 28upx;
+	margin-right: 18upx;
+	margin-top: 18upx;
+	border: 1upx solid #dce2e0;
+	border-radius: 28upx;
+	color: #60666d;
+	background: #fff;
+	font-size: 26upx;
+	text-align: center;
+}
+
+.filter-option.active {
+	color: #3385ff;
+	border-color: #3385ff;
+	background: #eef5ff;
+	font-weight: 700;
+}
+
+.filter-actions {
+	flex-shrink: 0;
+	display: flex;
+	padding: 30upx 40upx 40upx;
+	padding-bottom: calc(40upx + constant(safe-area-inset-bottom));
+	padding-bottom: calc(40upx + env(safe-area-inset-bottom));
+	border-top: 1upx solid #f0f0f0;
+	background: #fff;
+}
+
+.filter-action-btn {
+	flex: 1;
+	height: 80upx;
+	line-height: 80upx;
+	font-size: 28upx;
+	border-radius: 40upx;
+}
+
+.filter-action-btn::after {
+	border: none;
+}
+
+.clear-btn {
+	margin-right: 20upx;
+	color: #666;
+	background: #f5f7f9;
+}
+
+.confirm-btn {
+	color: #fff;
+	background: #3385ff;
+}
 </style>

+ 287 - 5
hdApp/src/pagesStore/me/shopYeChange.vue

@@ -1,7 +1,18 @@
 <template>
 	<view class="app-content">
-		<view style="text-align:center;padding-top:20upx;margin-bottom:20upx;">
-			<DateSelect class="bar" top="0" @selectDateFn="selectDateFn" />
+		<!-- 日期与筛选栏:筛选样式对齐 pagesPurchase/supplier -->
+		<view class="toolbar-wrap">
+			<!-- 左侧占位,与右侧筛选同宽,保证日期视觉居中 -->
+			<view class="toolbar-side"></view>
+			<view class="date-wrap">
+				<DateSelect class="bar" top="0" @selectDateFn="selectDateFn" />
+			</view>
+			<view class="toolbar-side toolbar-side--right">
+				<view class="filter-btn-wrap">
+					<button class="admin-button-com middle" @click="openFilterPanel">筛选</button>
+					<view v-if="hasActiveFilters" class="filter-dot"></view>
+				</view>
+			</view>
 		</view>
 		<view class="main-view">
 			<block v-if="!$util.isEmpty(list.data)">
@@ -43,6 +54,47 @@
 				<AppWrapperEmpty title="暂无数据" :is-empty="$util.isEmpty(list.data)" />
 			</block>
 		</view>
+
+		<!-- 筛选面板:增减余额 io、事项 capitalType -->
+		<view v-if="showFilterPanel" class="filter-overlay" @click="closeFilterPanel">
+			<view class="filter-panel" @click.stop>
+				<view class="filter-header">筛选变动明细</view>
+				<scroll-view class="filter-body" scroll-y>
+					<view class="filter-section">
+						<view class="filter-title">增减余额</view>
+						<view class="filter-options">
+							<view
+								v-for="(item, index) in ioOptions"
+								:key="'io-' + index"
+								class="filter-option"
+								:class="{ active: filterIo === item.value }"
+								@click="onSelectIo(index)"
+							>
+								{{ item.label }}
+							</view>
+						</view>
+					</view>
+					<view class="filter-section">
+						<view class="filter-title">事项</view>
+						<view class="filter-options">
+							<view
+								v-for="(item, index) in capitalTypeOptions"
+								:key="'capital-' + index"
+								class="filter-option"
+								:class="{ active: filterCapitalType === item.value }"
+								@click="onSelectCapitalType(index)"
+							>
+								{{ item.label }}
+							</view>
+						</view>
+					</view>
+				</scroll-view>
+				<view class="filter-actions">
+					<button class="filter-action-btn clear-btn" @click="clearFilters">重置</button>
+					<button class="filter-action-btn confirm-btn" @click="confirmFilters">确定</button>
+				</view>
+			</view>
+		</view>
 	</view>
 </template>
 <script>
@@ -50,6 +102,8 @@ import DateSelect from "@/components/module/dateSelect";
 import AppWrapperEmpty from "@/components/app-wrapper-empty";
 import { changeList } from '@/api/shop-ye-change'
 import list from '@/mixins/list'
+
+// 花店余额变动明细:日期 + 筛选(io、capitalType)查询 shop-ye-change/list
 export default {
 	name: "shopYeChange",
 	components: {
@@ -63,17 +117,90 @@ export default {
 				searchTime:'',
 				startTime: "",
 				endTime: "",
-			}
+			},
+			showFilterPanel: false,
+			// -1 表示全部,请求时不传对应字段
+			filterIo: -1,
+			filterCapitalType: -1,
+			ioOptions: [
+				{ label: '全部', value: -1 },
+				{ label: '增加余额', value: 1 },
+				{ label: '减少余额', value: 0 },
+			],
+			capitalTypeOptions: [
+				{ label: '全部', value: -1 },
+				{ label: '下单', value: 0 },
+				{ label: '采购退款', value: 1 },
+				{ label: '充值', value: 4 },
+				{ label: '提现', value: 6 },
+				{ label: '采购', value: 11 },
+				{ label: '结算', value: 20 },
+				{ label: '退款', value: 38 },
+				{ label: '充值', value: 66 },
+				{ label: '扫码付款', value: 79 },
+				{ label: '扫码退款', value: 80 },
+			],
 		};
 	},
+	computed: {
+		// 任一筛选项非「全部」时显示角标
+		hasActiveFilters() {
+			return this.filterIo !== -1 || this.filterCapitalType !== -1
+		}
+	},
 	methods: {
 		selectDateFn(val) {
 			this.params = {...this.params,...val}
 			this.resetList()
 			this.init()
 		},
+		openFilterPanel() {
+			this.showFilterPanel = true
+		},
+		closeFilterPanel() {
+			this.showFilterPanel = false
+		},
+		onSelectIo(index) {
+			const item = this.ioOptions[index]
+			if (item) {
+				this.filterIo = item.value
+			}
+		},
+		onSelectCapitalType(index) {
+			const item = this.capitalTypeOptions[index]
+			if (item) {
+				this.filterCapitalType = item.value
+			}
+		},
+		clearFilters() {
+			this.filterIo = -1
+			this.filterCapitalType = -1
+			this.closeFilterPanel()
+			this.resetList()
+			this.init()
+		},
+		confirmFilters() {
+			this.closeFilterPanel()
+			this.resetList()
+			this.init()
+		},
+		/** 组装列表请求参数:仅在有筛选值时传 io、capitalType */
+		buildListParams() {
+			const params = {
+				page: this.list.page,
+				tx: 0,
+				...this.params
+			}
+			if (this.filterIo !== -1) {
+				params.io = this.filterIo
+			}
+			if (this.filterCapitalType !== -1) {
+				params.capitalType = this.filterCapitalType
+			}
+			return params
+		},
 		async init(){
-			const res = await changeList({ page:this.list.page,tx:0,...this.params })
+			const res = await changeList(this.buildListParams())
 			if (this.$util.isEmpty(res.data.list)){
 				this.completes(res)
 				return
@@ -113,6 +240,49 @@ export default {
 	min-height: 100vh;
 }
 
+.toolbar-wrap {
+	display: flex;
+	align-items: center;
+	padding: 20upx 24upx;
+	margin-bottom: 20upx;
+	background-color: #fff;
+	border-bottom: 1upx solid #eef1f6;
+}
+
+.toolbar-side {
+	flex: 0 0 120upx;
+	display: flex;
+	align-items: center;
+}
+
+.toolbar-side--right {
+	justify-content: flex-end;
+}
+
+.date-wrap {
+	flex: 1;
+	min-width: 0;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+}
+
+.filter-btn-wrap {
+	position: relative;
+	display: flex;
+	align-items: center;
+}
+
+.filter-dot {
+	position: absolute;
+	top: 6upx;
+	right: 6upx;
+	width: 14upx;
+	height: 14upx;
+	border-radius: 50%;
+	background-color: #3385ff;
+}
+
 .main-view {
 	padding: 0;
 }
@@ -225,4 +395,116 @@ export default {
 	text-align: right;
 	width: 100%;
 }
-</style>
+
+.filter-overlay {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	z-index: 9999999;
+	display: flex;
+	align-items: flex-start;
+	justify-content: center;
+	background-color: rgba(0, 0, 0, 0.5);
+}
+
+.filter-panel {
+	display: flex;
+	flex-direction: column;
+	width: 100%;
+	height: 90vh;
+	max-height: 90vh;
+	overflow: hidden;
+	border-radius: 0 0 24upx 24upx;
+	background: #fff;
+}
+
+.filter-header {
+	flex-shrink: 0;
+	padding: 24upx 0;
+	text-align: center;
+	color: #333;
+	font-size: 32upx;
+	font-weight: 700;
+	border-bottom: 1upx solid #f0f0f0;
+}
+
+.filter-body {
+	flex: 1;
+	min-height: 0;
+	height: 0;
+	width: 100%;
+	box-sizing: border-box;
+}
+
+.filter-section {
+	padding: 30upx 40upx;
+	border-bottom: 1upx solid #f0f0f0;
+}
+
+.filter-title {
+	margin-bottom: 20upx;
+	color: #333;
+	font-size: 28upx;
+	font-weight: 700;
+}
+
+.filter-options {
+	display: flex;
+	flex-wrap: wrap;
+}
+
+.filter-option {
+	min-width: 120upx;
+	padding: 15upx 28upx;
+	margin-right: 18upx;
+	margin-top: 18upx;
+	border: 1upx solid #dce2e0;
+	border-radius: 28upx;
+	color: #60666d;
+	background: #fff;
+	font-size: 26upx;
+	text-align: center;
+}
+
+.filter-option.active {
+	color: #3385ff;
+	border-color: #3385ff;
+	background: #eef5ff;
+	font-weight: 700;
+}
+
+.filter-actions {
+	flex-shrink: 0;
+	display: flex;
+	padding: 30upx 40upx 40upx;
+	padding-bottom: calc(40upx + constant(safe-area-inset-bottom));
+	padding-bottom: calc(40upx + env(safe-area-inset-bottom));
+	border-top: 1upx solid #f0f0f0;
+	background: #fff;
+}
+
+.filter-action-btn {
+	flex: 1;
+	height: 80upx;
+	line-height: 80upx;
+	font-size: 28upx;
+	border-radius: 40upx;
+}
+
+.filter-action-btn::after {
+	border: none;
+}
+
+.clear-btn {
+	margin-right: 20upx;
+	color: #666;
+	background: #f5f7f9;
+}
+
+.confirm-btn {
+	color: #fff;
+	background: #3385ff;
+}
+</style>