分销模块页面接口完成

This commit is contained in:
2025-11-20 10:26:25 +08:00
parent c6a1751e72
commit 1070049a9d
10 changed files with 1397 additions and 173 deletions

View File

@@ -0,0 +1,328 @@
<template>
<view class="box min-page">
<up-sticky>
<view class="bg-fff top">
<view class="u-flex u-row-between" style="gap: 58rpx">
<view
class="u-font-28 u-flex-1 filter-box u-flex u-row-between"
@click="showActions = true"
>
<template v-if="selType && selType.value">
<text class="u-font-28">{{ selType.name }}</text>
</template>
<template v-else>
<text class="color-999 u-m-r-10">全部</text>
</template>
<up-icon name="arrow-down" size="12"></up-icon>
</view>
<view class="u-flex-1 filter-box" style="border-radius: 100rpx">
<up-icon name="search" size="18"></up-icon>
<input
class="u-m-l-10 u-font-28"
type="text"
placeholder-class="color-999 u-font-28"
placeholder="搜索关键词"
v-model="keyWord"
@blur="keyWordBlur"
/>
</view>
<view
v-if="false"
class="u-flex-1 u-font-28 filter-box u-flex u-row-between"
@click="showTimeArea = true"
>
<template v-if="query.startTime && query.endTime">
<text class="u-font-20">
{{ query.startTime }} -
{{ query.endTime }}
</text>
</template>
<template v-else>
<text class="color-999">请选择日期</text>
<up-icon name="arrow-right" size="12"></up-icon>
</template>
</view>
</view>
<view class="u-flex u-p-l-32 u-p-r-32 u-m-t-32">
<view class="u-flex-1 u-text-center">
<view class="u-font-32 color-main font-bold">{{
state.totalRecharge
}}</view>
<view class="u-font-24 color-666 u-m-t-16">已充值金额</view>
</view>
<view class="u-flex-1 u-text-center">
<view class="u-font-32 color-main font-bold">{{
state.totalSub
}}</view>
<view class="u-font-24 color-666 u-m-t-16">已扣减金额</view>
</view>
</view>
</view>
</up-sticky>
<view class="recoders-list" v-if="state.records.length">
<view class="item" v-for="(item, index) in state.records" :key="index">
<view class="u-flex u-flex-between u-font-24">
<view class="color-666">
{{ returnState(item.type) }}
</view>
<text class="color-999">{{ item.createTime }}</text>
</view>
<view class="u-flex u-flex-between u-font-28 color-666 u-m-t-16">
<view>
<text>关联订单WX1987787224197300224</text>
<text></text>
</view>
<view>
<view class="price">
<text>{{ item.changeAmount }}</text>
</view>
<view class="u-m-t-4 u-font-24 color-999">变动后{{item.amount}}</view>
</view>
</view>
</view>
<up-loadmore :status="isEnd ? 'nomore' : 'loadmore'"></up-loadmore>
</view>
<view style="height: 60rpx"></view>
<dateAreaSel
:show="showTimeArea"
:minYear="2022"
@close="showTimeArea = false"
@confirm="confirmTimeArea"
></dateAreaSel>
<up-action-sheet
:show="showActions"
:actions="actions"
@select="handleSelect"
@close="showActions = false"
cancel-text="取消"
></up-action-sheet>
</view>
</template>
<script setup>
import * as distributionApi from "@/http/api/market/distribution.js";
import { onMounted, ref, reactive, watch } from "vue";
import { onLoad, onReachBottom } from "@dcloudio/uni-app";
import dateAreaSel from "@/components/date-range-picker/date-range-picker.vue";
import go from "@/commons/utils/go.js";
const showActions = ref(false);
const selType = ref(null);
const actions = [
{
name: "全部",
value: "",
},
{
name: "充值",
value: "manual_recharge",
},
{
name: "自助充值",
value: "self_recharge",
},
{
name: "退款",
value: "refund",
},
{
name: "手动扣减",
value: "manual_sub",
},
{
name: "系统扣减",
value: "sub",
},
];
function returnState(type) {
const item = actions.find((item) => item.value === type);
if (item) {
return item.name;
}
return "";
}
const keyWord = ref("");
function keyWordBlur() {
query.key = keyWord.value;
}
function handleSelect(item) {
console.log(item);
selType.value = item;
query.type = item.value;
}
const options = ref({});
function parseQueryString(queryString) {
const queryParams = queryString.split("&").map((param) => param.split("="));
const params = {};
for (const [key, value] of queryParams) {
params[key] = value;
}
return params;
}
onLoad((opt) => {
console.log(opt);
if (opt.q) {
const q = decodeURIComponent(opt.q);
const params = parseQueryString(q.split("?")[1]);
Object.assign(options.value, params);
} else {
Object.assign(options.value, opt);
}
console.log(options.value);
if (options.value.shopId) {
price.value = options.value.amount;
selChargeIndex.value = chargeList.value.findIndex(
(item) => item.price * 1 === options.value.amount * 1
);
init();
}
flow();
});
const showTimeArea = ref(false);
function confirmTimeArea(e) {
console.log(e);
query.startTime = e[0];
query.endTime = e[1];
}
function refresh() {
query.page = 1;
flow();
}
const query = reactive({
page: 1,
size: 10,
type: "",
key: "",
});
const state = reactive({
records: [],
totalRecharge: 0,
});
const listRes = ref({});
const isEnd = ref(false);
async function flow() {
console.log(selType.value);
const res = await distributionApi.moneyRecoders(query);
if (query.page == 1) {
Object.assign(state, res);
} else {
state.records = state.records.concat(res.records || []);
state.totalRecharge = res.totalRecharge || 0;
}
isEnd.value = query.page >= res.totalPage * 1;
}
onReachBottom(() => {
if (isEnd.value) {
return;
}
query.page++;
flow();
});
watch(
() => query.key,
(newval) => {
isEnd.value = false;
query.page = 1;
flow();
},
{
deep: true,
}
);
watch(
() => query.type,
(newval) => {
isEnd.value = false;
query.page = 1;
flow();
},
{
deep: true,
}
);
</script>
<style scoped lang="scss">
.min-page {
background: #f5f5f5;
}
.box {
position: relative;
}
.container {
padding: 32rpx 24rpx;
border-radius: 16rpx;
background-color: #fff;
}
.chrage-box {
border-radius: 74rpx;
background: #ffffff4d;
padding: 42rpx 28rpx;
}
.title-bg {
position: relative;
.image {
position: absolute;
height: 14rpx;
width: 94rpx;
right: -10rpx;
bottom: 0;
z-index: -1;
}
}
.xieyi {
color: #ecb592;
}
.u-text-nowrap {
white-space: nowrap;
}
.input-box {
padding: 24rpx 16rpx;
border-radius: 8rpx;
background: #f6f6f6;
}
.recoders-list {
margin-top: 40rpx;
.item {
margin-bottom: 36rpx;
background-color: #fff;
padding: 32rpx 28rpx;
border-radius: 16rpx;
.price {
font-weight: 700;
color: $my-main-color;
font-size: 32rpx;
.yuan {
font-weight: 400;
font-size: 28rpx;
}
}
}
}
.filter-box {
display: flex;
padding: 8rpx 24rpx;
align-items: center;
border-radius: 8rpx;
border: 2rpx solid #d9d9d9;
background: #f7f7f7;
min-height: 62rpx;
box-sizing: border-box;
}
.top {
padding: 32rpx 24rpx;
}
</style>