2025-08-20 19:14:59 +08:00

1329 lines
42 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="main">
<view class="meng" v-if="showNotice" @click="handleShowNotice"></view>
<!-- 筛选卡片 -->
<view class="filterCard">
<view class="filterHeader">
<view class="filterTitle">查询筛选</view>
<view class="filterBtn" @click="handleSelect">
<image class="filterIcon" src="/static/images/recons/select_icon.svg" />
<text>筛选</text>
</view>
</view>
<!-- 时间选择器 -->
<view class="dateSelector">
<view class="dateRange">
<picker mode="date" @change="bindDateChange($event, 0)" :value="pageData.searchTime[0]"
:end="pageData.endDate" start="2018-12-01" class="datePicker">
<view class="dateInput">
<text>{{ pageData.searchTime[0] }}</text>
<text class="uni-icon uni-icon-arrowdown"></text>
</view>
</picker>
<view class="dateSeparator"></view>
<picker mode="date" @change="bindDateChange($event, 1)" :value="pageData.searchTime[1]"
:end="pageData.endDate" start="2018-12-01" class="datePicker">
<view class="dateInput">
<text>{{ pageData.searchTime[1] }}</text>
<text class="uni-icon uni-icon-arrowdown"></text>
</view>
</picker>
</view>
</view>
</view>
<!-- BusinessType经营模式 SettlementMode结算模式 -->
<!-- <view class="searchBox">-->
<!-- <view class="searchItem">-->
<!-- <span class="searchLabel">经营模式</span>-->
<!-- <picker mode="selector" :range="BusinessTypeList" :value="BusinessTypeIndex" range-key="label">-->
<!-- {{BusinessTypeList[BusinessTypeIndex].label}}-->
<!-- </picker>-->
<!-- </view>-->
<!-- <view class="searchItem">-->
<!-- <span class="searchLabel">结算模式</span>-->
<!-- <picker mode="selector" :range="SettlementModeList" :value="SettlementModeIndex" range-key="label">-->
<!-- {{SettlementModeList[SettlementModeIndex].label}}-->
<!-- </picker>-->
<!-- </view>-->
<!-- </view>-->
</div>
<template v-if="!pageData.isLoading && pageData.msg && pageData.msg.Total_Revenue">
<!-- 实收总额卡片 -->
<view class="revenueCard">
<view class="revenueHeader">
<view class="revenueTitle">实收总额</view>
<view class="revenueAmount">¥{{ $util.fmoney(pageData.msg.Total_Revenue, 2) }}</view>
</view>
<view class="revenueDetails">
<view class="detailGrid">
<view class="detailItem">
<view class="itemValue">{{ $util.fmoney(pageData.msg.Different_Price_More, 2) }}</view>
<view class="itemLabel">长款金额<text class="unit">/</text></view>
</view>
<view class="detailItem">
<view class="itemValue">{{ $util.fmoney(pageData.msg.Different_Price_Less, 2) }}</view>
<view class="itemLabel">短款金额<text class="unit">/</text></view>
</view>
<view class="detailItem">
<view class="itemValue">{{ $util.fmoney(pageData.msg.TotalOffAmount, 2) }}</view>
<view class="itemLabel">优惠金额<text class="unit">/</text></view>
</view>
<view class="detailItem">
<view class="itemValue">{{ $util.noDecimal(pageData.msg.TicketCount) }}</view>
<view class="itemLabel">客单数量<text class="unit">/</text></view>
</view>
<view class="detailItem">
<view class="itemValue">{{ $util.fmoney(pageData.msg.TotalCount, 2) }}</view>
<view class="itemLabel">商品出售<text class="unit">/</text></view>
</view>
<view class="detailItem">
<view class="itemValue">{{ $util.fmoney(pageData.msg.countave, 2) }}</view>
<view class="itemLabel">商品均价<text class="unit">/</text></view>
</view>
</view>
</view>
</view>
<!-- 经营报表标题 -->
<view class="reportHeader">
<view class="reportTitle">
<image class="reportIcon" src="https://eshangtech.com/ShopICO/ahyd-BID/revenue/yestoday-region.png" />
<text>经营报表</text>
</view>
<view class="reportInfo"
v-if="pageData.msg && (pageData.msg.SearchResult || BusinessTypeValue !== 0 || SettlementModeValue !== 0)">
<view v-if="showModal" class="reportText">
<text v-if="copySearchText && (BusinessTypeValue || SettlementModeValue)" class="warningText">
温馨提示模糊查询不支持选择经营方法/结算方式
</text>
<text v-if="pageData.msg.SearchResult && pageData.msg.SearchResult[0]" class="searchResult">{{
pageData.msg.SearchResult[0] }}</text>
<text v-if="BusinessTypeValue !== 0" class="filterMode">
经营模式: {{ getBusinessTypeLabel(BusinessTypeValue) }}
</text>
<text v-if="SettlementModeValue !== 0" class="filterMode">
结算模式: {{ getSettlementModeLabel(SettlementModeValue) }}
</text>
</view>
<view v-else class="reportText">
<text v-if="copySearchText && (BusinessTypeValue || SettlementModeValue)" class="warningText">
温馨提示模糊查询不支持选择经营方法/结算方式
</text>
<view v-for="(item, index) in pageData.msg.SearchResult" :key="index" class="searchResultItem">
<text v-for="(subItem, subIndex) in item" :key="subIndex" class="searchResultText">
<text class="highlightText" v-if="item.length > 1 && subItem.indexOf('') === -1">
{{ copySearchText }}
</text>
{{ subItem }}
</text>
</view>
</view>
</view>
</view>
<!-- 区域数据卡片 -->
<view class="regionCard" v-if="ServerpartList.length > 0">
<!-- 省内区域 -->
<view class="regionSection">
<view class="regionTitle" :class="{ 'active': pageData.insideShow }"
@click="pageData.insideShow = !pageData.insideShow">
<view class="titleText">全部片区</view>
<view class="expandIcon" :class="{ 'expanded': pageData.insideShow }">
<text class="uni-icon uni-icon-arrowdown"></text>
</view>
</view>
<view v-show="pageData.insideShow" class="regionList">
<view v-for="(item, i) in ServerpartList" :key="i" class="regionItem">
<view class="regionHeader" @click="toggleRegion(item)">
<view class="regionInfo">
<view class="regionName">{{ item.Region_Name }}</view>
<view class="regionRevenue">¥{{ $util.fmoney(item.Total_Revenue, 2) }}</view>
</view>
<view class="regionStats">
<view class="statLabel">营收占比</view>
<view class="statValue">{{ item.Revenue_Proportion }}</view>
</view>
<view class="expandBtn" :class="{ 'active': item.show }">
<text class="uni-icon uni-icon-arrowright"></text>
</view>
</view>
<view class="serverList" v-show="item.show">
<view v-for="(child, index) in item.revenueServerModels" :key="index" class="serverItem"
:class="{ 'visited': child.visited }" @tap="toDetail(child)">
<view class="serverInfo">
<view class="serverName">{{ child.Serverpart_Name }}</view>
<view class="serverStats">
<text class="serverProportion">{{ child.Revenue_Proportion }}</text>
<text class="serverRevenue">¥{{ $util.fmoney(child.Total_Revenue, 2) }}</text>
</view>
</view>
<view class="serverArrow">
<text class="uni-icon uni-icon-arrowright"></text>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 省外区域 -->
<template v-if="insideRegionList.length > 0">
<view class="regionSection">
<view class="regionTitle" :class="{ 'active': pageData.exsideShow }"
@click="pageData.exsideShow = !pageData.exsideShow">
<view class="titleText">省外区域</view>
<view class="expandIcon" :class="{ 'expanded': pageData.exsideShow }">
<text class="uni-icon uni-icon-arrowdown"></text>
</view>
</view>
<view v-show="pageData.exsideShow" class="regionList">
<view v-for="(item, i) in insideRegionList" :key="i" class="regionItem">
<view class="regionHeader" @click="toggleRegion(item)">
<view class="regionInfo">
<view class="regionName">{{ item.Region_Name }}</view>
<view class="regionRevenue">¥{{ $util.fmoney(item.Total_Revenue, 2) }}</view>
</view>
<view class="regionStats">
<view class="statLabel">营收占比</view>
<view class="statValue">{{ item.Revenue_Proportion }}</view>
</view>
<view class="expandBtn" :class="{ 'active': item.show }">
<text class="uni-icon uni-icon-arrowright"></text>
</view>
</view>
<view class="serverList" v-show="item.show">
<view v-for="(child, index) in item.revenueServerModels" :key="index" class="serverItem"
:class="{ 'visited': child.visited }" @click="toDetail(child)">
<view class="serverDot"></view>
<view class="serverInfo">
<view class="serverName">{{ child.Serverpart_Name }}</view>
<view class="serverStats">
<text class="serverProportion">{{ child.Revenue_Proportion }}</text>
<text class="serverRevenue">¥{{ $util.fmoney(child.Total_Revenue, 2) }}</text>
</view>
</view>
<view class="serverArrow">
<text class="uni-icon uni-icon-arrowright"></text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
</view>
</template>
<view class="" v-else-if="!pageData.isLoading && !pageData.msg">
<noFound nodata=" true" :text="noDataText" />
</view>
<uni-popup ref="popup" type="bottom" background-color="#fff" :safe-area="false">
<div class="popupBox">
<!-- <div style="display: flex;align-items: center;justify-content: space-between">-->
<!-- <text class="title">查询配置</text>-->
<!-- <img src="/static/images/recons/delete.svg" alt="" class="delete" @click="handleClosePopup">-->
<!-- </div>-->
<div class="popupContent">
<div class="search_box">
<img src="/static/images/recons/search_icon.svg" alt="" class="search_icon">
<input v-model="searchText" confirm-type="search" @confirm="getList" placeholder="可以查询门店/服务区/品牌/商家等信息"
class="select_input" clear />
<img src="/static/images/recons/delete.svg" alt="" class="delete" @click="handleDelete">
</div>
<view class="scrollContent">
<view class="popupTitle">日期选择</view>
<view class="timeList">
<view :class="selectTime === item.value ? 'timeItem timeSelectItem' : 'timeItem'"
v-for="(item, index) in timeTypeList" :key="index" @click="handleChangeTime(item.value)">{{ item.label
}}
</view>
</view>
<view class="timeList">
<view :class="selectTimeOther ? 'timeItem timeSelectItem' : 'timeItem'" @click="handleTimeOther">自定义
</view>
</view>
<view class="popupTitle">业态类型</view>
<view class="timeList">
<view :class="BusinessTrade === item.value ? 'timeItem timeSelectItem' : 'timeItem'"
v-for="(item, index) in tradeList" :key="index" @click="handleChangeTrade(item.value, index)">
{{ item.label }}
</view>
</view>
<view class="timeList"
v-if="bigTradeIndex >= 0 && tradeList[bigTradeIndex] && tradeList[bigTradeIndex].children && tradeList[bigTradeIndex].children.length > 0">
<view :class="BusinessSmallTrade.indexOf(item.value) !== -1 ? 'timeItem timeSelectItem' : 'timeItem'"
v-for="(item, index) in tradeList[bigTradeIndex].children" :key="index"
@click="handleChangeSmallTrade(item.value)">{{ item.label }}</view>
</view>
<view class="popupTitle">经营模式</view>
<view class="timeList">
<view :class="BusinessTypeValue === item.value ? 'timeItem timeSelectItem' : 'timeItem'"
v-for="(item, index) in BusinessTypeList" :key="index" @click="handleChangeBusiness(item.value)">
{{ item.label }}</view>
</view>
<view class="popupTitle" style="display: flex;position: relative;align-items: center">
<span class="title">结算模式</span>
<view class="notice" @click="handleShowNotice">?
<view class="noticeBox" v-if="showNotice" :style="{ left: '10%', top: '20px' }">
<span class="noticeText">营收回款经营模式为商家收款商家按月/季度/半年/年度模式返款给驿达</span>
<span class="noticeText">资金返款经营模式为驿达收款驿达按月/季度/半年/年度模式打款给商家</span>
<span class="noticeText">营收分润经营模式为单个业态使用移动支付分账模式移动支付交易按照七三分成的模式营收达到保底后按照合同约定的提成比例进行分成</span>
<span class="noticeText">组合分润经营模式为多个业态使用移动支付分账模式移动支付交易按照七三分成的模式营收达到保底后按照合同约定的提成比例进行分成</span>
<span class="noticeText">阶段提成经营模式为合作分成根据营业额的高低提成比例会进行阶段性的变化</span>
</view>
</view>
</view>
<view class="timeList">
<view :class="SettlementModeValue === item.value ? 'timeItem timeSelectItem' : 'timeItem'"
v-for="(item, index) in SettlementModeList" :key="index" @click="handleChangeSettlement(item.value)">
{{ item.label }}</view>
</view>
</view>
</div>
<div class="btn" @click="handleConfirmCheckChange">确认</div>
</div>
</uni-popup>
<uni-popup ref="timePopup" type="center" style="background: #fff">
<div class="timePopup">
<div style="display: flex;margin-left: 10%">
<picker mode="date" @change="handleChangeTimePopup($event, 0)" :value="searchTimePopup[0]"
:end="pageData.endDate" start="2018-12-01" class="screen-unit">
<text style="font-size: 32rpx">{{ searchTimePopup[0] }}</text>
<text class="uni-icon uni-icon-arrowdown"></text>
</picker>
<text class="mr20"></text>
<picker mode="date" @change="handleChangeTimePopup($event, 0)" :value="searchTimePopup[1]"
:end="pageData.endDate" start="2018-12-01" class="screen-unit">
<text style="font-size: 32rpx">{{ searchTimePopup[1] }}</text>
<text class="uni-icon uni-icon-arrowdown"></text>
</picker>
</div>
<div class="btn" @click="handleTimePopup">确认</div>
</div>
</uni-popup>
</view>
</template>
<script>
import { mapState } from 'vuex'
import request from '@/util/index.js'
import { wrapTreeNode } from "../../util/dateTime";
import moment from "moment";
export default {
data() {
let now = new Date()
let nowTime = this.$util.cutDate(now, 'YYYY-MM-DD', -1)
let sTime = this.$util.cutDate(now, 'YYYY-MM-DD', -1)
return {
pageData: {
endDate: nowTime,
searchTime: [sTime, nowTime],
msg: {},
isLoading: true,
exsideShow: true,
insideShow: true,
},
noDataText: '抱歉,没有数据,请稍后重试',
regionType: 0, // 0 东南 1 西北
ServerpartList: [],
insideRegionList: [], // 省外
queryTime: '',// 传入的时间
lastDay: '',// 首页的实际时间
searchText: '',// 搜索框内容
copySearchText: '',// 搜索框内容复制
requestText: '',// 已经请求过接口的查询框内容
isScreen: false,// 显示popup里面的内容
checkBoxValue: ['MerchantName', 'Brand', 'Shop', 'Serverpart'],// 查询的字段放接口里的
checkChange: ['MerchantName', 'Brand', 'Shop', 'Serverpart'],// checkBox里面选择了 但是没点确定的
BusinessTypeList: [],// 经营模式列表
BusinessTypeValue: 0,// 经营模式的选择项
BusinessTrade: 0,//选择的业态类型
BusinessSmallTrade: [],// 小类业态
bigTradeIndex: null,// 大类的第几项
tradeList: [],//业态类型数据
SettlementModeList: [],// 结算模式列表
SettlementModeValue: 0,// 结算模式的选择项
timeTypeList: [{ label: '近1周', value: 1 }, { label: '近1月', value: 2 }, { label: '近3月', value: 3 }, { label: '近半年', value: 4 }],
selectTime: 0,
selectTimeOther: false,
timePopup: false,
searchTimePopup: [null, null],
showNotice: false,
showModal: false,// 显示模式
selectTradeId: '',//选择的业态
}
},
computed: {
...mapState({ 'ProvinceCode': (state) => { return state.userData.ProvinceCode } }),
},
methods: {
// 获取经营模式标签
getBusinessTypeLabel(value) {
const item = this.BusinessTypeList.find(item => item.value === value)
return item ? item.label : ''
},
// 获取结算模式标签
getSettlementModeLabel(value) {
const item = this.SettlementModeList.find(item => item.value === value)
return item ? item.label : ''
},
// 是否显示结算模式的悬浮框
handleShowNotice() {
this.showNotice = !this.showNotice
},
// 自定义时间选框里面的选择 改变悬浮框的自定义时间 外面页面上的时间也要跟着改变 强刷
handleChangeTimePopup(e, index) {
this.searchTimePopup[index] = e.detail.value
this.$forceUpdate()
},
// 自定义时间选框的确定 赋值给页面上的时间
handleTimePopup() {
this.pageData.searchTime = this.searchTimePopup
this.$refs.timePopup.close()
},
// 经营模式和结算模式只能二选一 选了一个另一个就取消
// 选择了结算模式
handleChangeSettlement(value) {
if (this.BusinessTypeValue !== 0) {
this.BusinessTypeValue = 0
}
this.SettlementModeValue = value
},
// 选择了经营模式
handleChangeBusiness(value) {
if (this.SettlementModeValue !== 0) {
this.SettlementModeValue = 0
}
this.BusinessTypeValue = value
},
// 改变小类业态
handleChangeSmallTrade(value) {
if (this.BusinessSmallTrade.indexOf(Number(value)) === -1) {
this.BusinessSmallTrade.push(Number(value))
} else {
let list = []
this.BusinessSmallTrade.forEach(item => {
if (Number(value) === item) {
} else {
list.push(item)
}
})
this.BusinessSmallTrade = list
}
},
// 选择业态类型
handleChangeTrade(value, index) {
if (this.BusinessTrade === value) {
this.BusinessTrade = 0
this.BusinessSmallTrade = []
this.bigTradeIndex = null
} else {
this.BusinessTrade = value
this.BusinessSmallTrade = []
this.bigTradeIndex = index
}
},
// 给悬浮框的自定义时间赋初始值
// 选择了自定义时间
handleTimeOther() {
this.searchTimePopup = JSON.parse(JSON.stringify(this.pageData.searchTime))
this.$refs.timePopup.open()
this.selectTimeOther = true
this.selectTime = 0
},
// 改变选择的时间
// 选择的时间类型 moment 拿到时间
handleChangeTime(value) {
this.selectTimeOther = false
this.selectTime = value
let endTime
let startTime
let searchTime
if (this.selectTime === 1) {
endTime = moment().subtract(1, 'day').format('YYYY-MM-DD')
startTime = moment().subtract(7, 'day').format('YYYY-MM-DD')
searchTime = [startTime, endTime]
} else if (this.selectTime === 2) {
endTime = moment().subtract(1, 'day').format('YYYY-MM-DD')
startTime = moment().subtract(30, 'day').format('YYYY-MM-DD')
searchTime = [startTime, endTime]
} else if (this.selectTime === 3) {
endTime = moment().subtract(1, 'day').format('YYYY-MM-DD')
startTime = moment().subtract(90, 'day').format('YYYY-MM-DD')
searchTime = [startTime, endTime]
} else if (this.selectTime === 4) {
endTime = moment().subtract(1, 'day').format('YYYY-MM-DD')
startTime = moment().subtract(180, 'day').format('YYYY-MM-DD')
searchTime = [startTime, endTime]
}
this.pageData.searchTime = searchTime
},
// 拿到枚举的方法
async handleEnumeration(text) {
const req = {
FieldExplainField: text,
sessionName: text,
FieldEnumStatus: true
}
const data = await request.$webGet('EShangApiMain/FrameWork/GetFieldEnumTree', req)
// 变成label、value的数据格式
let list = wrapTreeNode(data.Result_Data.List)
return list
},
handleConfirmCheckChange() {
// 老的选类型的方法 暂时不让他改 已经写死
this.checkBoxValue = this.checkChange
// 关闭悬浮框
this.$refs.popup.close()
// 没用的东西
this.isScreen = false
// 请求数据的方法
this.getList()
},
// 查询配置的关闭方法 暂时隐藏不用
handleClosePopup() {
this.checkChange = this.checkBoxValue
this.$refs.popup.close()
this.isScreen = false
this.BusinessTypeValue = 0
this.SettlementModeValue = 0
this.selectTime = 0
// this.getList()
},
// 删除查询字段
handleDelete() {
this.searchText = ''
},
// 更多筛选的点击打开悬浮框
handleSelect() {
this.$refs.popup.open()
this.isScreen = true
},
// 老的一个跳转方法 暂时用不到
toTrend() {
this.$util.toNextRoute('navigateTo', '/pages/operatingStatements/operatingTrend?time=' + this.pageData.searchTime[1])
},
// 改变时间的方法
bindDateChange(e, index) {
let nowDate = this.pageData.searchTime[index]
if (e.detail.value != nowDate) {
this.pageData.searchTime[index] = e.detail.value
this.$forceUpdate()
this.searchList()
}
},
// 套一层方法 可以进行其他操作 只有有其他操作的 业务更改之后就没了 暂时保留
searchList() {
this.getList()
},
// 老方法 显示具体条目
toggleRegion(item) {
item.show = !item.show ? true : false
this.$forceUpdate()
},
// 跳转详情带上参数
toDetail(item) {
this.$util.toNextRoute('navigateTo', '/pages/operatingStatements/detail?pcode=' + item.Province_Code + '&id=' +
item.Serverpart_Id + '&st=' + this.pageData.searchTime[0] + '&et=' + this.pageData.searchTime[1] +
'&searchKey=' + JSON.parse(JSON.stringify(this.checkBoxValue)) + '&searchValue=' + this.requestText +
'&BusinessTypeValue=' + this.BusinessTypeValue + '&SettlementModeValue=' + this.SettlementModeValue + '&BusinessTrade=' + this.selectTradeId
)
item.visited = true
this.$forceUpdate()
},
// 页面请求的主要方法
getList() {
console.log('this.BusinessSmallTrade', this.BusinessSmallTrade)
// copySearchText 是要显示在经营报表下方的红色字 每次请求前要清空 不能和searchText同源 不然清空搜索框 显示的文字也会消失
this.copySearchText = ''
uni.showLoading({
title: '正在加载',
mask: true
})
let _this = this
let searchTime = this.pageData.searchTime
// 接口要的查询字段类型 之前是可选的 用这样的方法写 暂时可以保留 不影响
let searchName = ''
this.checkBoxValue.forEach(item => {
if (searchName) {
searchName += `,${item}`
} else {
searchName = item
}
})
let req;
console.log('BusinessSmallTrade', this.BusinessSmallTrade)
console.log('BusinessTrade', this.BusinessTrade)
console.log('tradeList', this.tradeList)
let tradeId = ''
if (this.BusinessSmallTrade && this.BusinessSmallTrade.length > 0) {
tradeId = this.BusinessSmallTrade.toString()
} else if (this.BusinessTrade) {
let list = []
this.tradeList.forEach(item => {
if (Number(item.value) === Number(this.BusinessTrade)) {
if (item.children && item.children.length > 0) {
item.children.forEach(subItem => {
list.push(Number(subItem.value))
})
}
}
})
if (list && list.length > 0) {
tradeId = list.toString()
}
}
console.log('tradeId', tradeId)
this.selectTradeId = tradeId
req = {
startTime: searchTime[0],
endTime: searchTime[1],
SearchKeyName: searchName,
SearchKeyValue: this.searchText,
BusinessTrade: tradeId,
BusinessType: this.searchText ? '' : this.BusinessTypeValue ? this.BusinessTypeValue : '',
SettlementMode: this.searchText ? '' : this.SettlementModeValue ? this.SettlementModeValue : '',
}
// _this.$request.$webGet('WeChat/GetRevenueReport',{
request.$webGet('CommercialApi/Revenue/GetRevenueReport', req).then(res => {
// 拿到数据之后的一些处理方法 看看就明白了
if (res.Result_Code == 100) {
_this.pageData.msg = res.Result_Data
_this.pageData.msg.countave = (Number(_this.pageData.msg.Province_InsideAmount) / Number(_this.pageData.msg.TotalCount)).toFixed(2)
res.Result_Data.revenueRegionModels.map(n => {
n.show = false
})
if (res.Result_Data.revenueInsideRegionModels) {
res.Result_Data.revenueInsideRegionModels.map(n => {
n.show = false
})
_this.insideRegionList = res.Result_Data.revenueInsideRegionModels
}
// _this.pageData.msg.SearchResult
// 判断一下 如果是有搜索框的值 就按照搜索框有的值显示
// 没有就出现结算模式 或者经营模式
if (this.searchText) {
this.showModal = false
if (res.Result_Data.SearchResult) {
let newList = []
res.Result_Data.SearchResult.forEach(item => {
newList.push(item.split(this.searchText))
_this.pageData.msg.SearchResult = newList
_this.copySearchText = JSON.parse(JSON.stringify(this.searchText))
})
}
} else {
if (this.BusinessTypeValue || this.SettlementModeValue) {
this.showModal = true
}
}
_this.ServerpartList = res.Result_Data.revenueRegionModels
} else if (res.Result_Code == 200 || res.Result_Code == 999) {
_this.noDataText = '暂无数据'
_this.insideRegionList = []
_this.pageData.msg = null
} else {
_this.pageData.msg = null
_this.noDataText = res.Result_Desc
_this.insideRegionList = []
}
_this.requestText = _this.searchText
uni.hideLoading()
_this.pageData.isLoading = false
_this.$forceUpdate()
})
},
// 拿业态枚举
async handleGetTradeList() {
const data = await request.$webGet('EShangApiMain/BaseInfo/GetBusinessTradeTree', {})
const treeTable = wrapTreeNode(data.Result_Data.List);
console.log('treeTable', treeTable)
let list = []
if (treeTable && treeTable.length > 0) {
treeTable.forEach(item => {
let children = []
if (item.children && item.children.length > 0) {
item.children.forEach(subItem => {
children.push({
label: subItem.AUTOSTATISTICS_NAME,
value: subItem.AUTOSTATISTICS_ID
})
})
}
list.push({
label: item.AUTOSTATISTICS_NAME,
value: item.AUTOSTATISTICS_ID,
children: children
})
})
}
this.tradeList = list
}
},
async onLoad(query) {
console.log('queryqueryquery', query);
// 拿时间和拿传入的数据
this.lastDay = uni.getStorageSync('lastDay')
if (query.time) {
this.queryTime = query.time
const date = new Date(this.queryTime)
let y = date.getFullYear()
let m = date.getMonth() + 1
const realDate = new Date(this.lastDay)
let realMonth = realDate.getMonth() + 1
if (m < realMonth) {
if (m < 10) {
m = '0' + m
}
let day = this.$util.getThisMonthDay(`${y}-${m}`)
let time = [`${y}-${m}-01`, `${y}-${m}-${day}`]
this.pageData.searchTime = time
} else {
if (m < 10) {
m = '0' + m
}
let d = realDate.getDate()
if (d < 10) {
d = '0' + d
}
let time = [`${y}-${m}-01`, `${y}-${m}-${d}`]
this.pageData.searchTime = time
}
}
// 用枚举方法拿到枚举数组
this.BusinessTypeList = await this.handleEnumeration('BUSINESS_TYPE')
this.SettlementModeList = await this.handleEnumeration('SETTLEMENT_MODES')
await this.handleGetTradeList()
// 调用接口拿到页面数据的方法
this.getList()
}
}
</script>
<style lang="scss" scoped>
// 使用项目全局颜色变量
$bg: #f8f9fa;
$muted: #666;
$card: #fff;
$shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
$primary: #27B25F;
$primary2: #4CCC7F;
$success: #2ed573;
$warning: #ff9f43;
$danger: #ff4757;
$info: #3742fa;
.main {
width: 100vw;
min-height: 100vh;
background-color: $bg;
padding: 32rpx;
padding-bottom: env(safe-area-inset-bottom);
box-sizing: border-box;
}
// 遮罩层
.meng {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 101;
background: rgba(0, 0, 0, 0.5);
}
// 筛选卡片
.filterCard {
background: $card;
border-radius: 16rpx;
padding: 24rpx;
margin-bottom: 32rpx;
box-shadow: $shadow;
.filterHeader {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 24rpx;
.filterTitle {
font-size: 28rpx;
font-weight: 600;
color: #160002;
}
.filterBtn {
display: flex;
align-items: center;
padding: 12rpx 24rpx;
background: transparent;
border: 1rpx solid $primary;
border-radius: 24rpx;
.filterIcon {
width: 24rpx;
height: 24rpx;
margin-right: 8rpx;
filter: brightness(0) saturate(100%) invert(45%) sepia(67%) saturate(1055%) hue-rotate(113deg) brightness(96%) contrast(86%);
}
text {
font-size: 24rpx;
font-weight: 400;
color: $primary;
}
}
}
.dateSelector {
.dateRange {
display: flex;
align-items: center;
justify-content: space-between;
.datePicker {
flex: 1;
.dateInput {
display: flex;
align-items: center;
justify-content: center;
padding: 16rpx 24rpx;
background: #f8f8f8;
border-radius: 12rpx;
text:first-child {
font-size: 24rpx;
font-weight: 400;
color: #160002;
}
.uni-icon-arrowdown {
font-size: 20rpx;
color: $muted;
margin-left: 8rpx;
}
}
}
.dateSeparator {
margin: 0 24rpx;
font-size: 24rpx;
font-weight: 400;
color: $muted;
}
}
}
}
// 实收总额卡片
.revenueCard {
background: linear-gradient(to left, #93a4ec 0%, #4b76e9 100%);
border-radius: 16rpx;
padding: 32rpx;
margin-bottom: 32rpx;
box-shadow: $shadow;
.revenueHeader {
text-align: center;
margin-bottom: 24rpx;
.revenueTitle {
font-size: 24rpx;
font-weight: 400;
color: rgba(255, 255, 255, 0.9);
margin-bottom: 12rpx;
}
.revenueAmount {
font-size: 36rpx;
font-weight: 600;
color: #fff;
font-family: 'DIN Alternate', 'Arial', sans-serif;
}
}
.revenueDetails {
.detailGrid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24rpx;
.detailItem {
text-align: center;
.itemValue {
font-size: 28rpx;
font-weight: 600;
color: #fff;
margin-bottom: 8rpx;
font-family: 'DIN Alternate', 'Arial', sans-serif;
}
.itemLabel {
font-size: 24rpx;
font-weight: 400;
color: rgba(255, 255, 255, 0.8);
.unit {
font-size: 20rpx;
}
}
}
}
}
}
// 经营报表标题
.reportHeader {
margin-bottom: 32rpx;
.reportTitle {
display: flex;
align-items: center;
margin-bottom: 16rpx;
.reportIcon {
width: 32rpx;
height: 32rpx;
margin-right: 12rpx;
}
text {
font-size: 28rpx;
font-weight: 600;
color: #160002;
}
}
.reportInfo {
padding-left: 44rpx;
.reportText {
.warningText {
display: block;
font-size: 22rpx;
font-weight: 400;
color: $danger;
margin-bottom: 8rpx;
}
.searchResult {
font-size: 24rpx;
font-weight: 400;
color: $muted;
line-height: 1.5;
}
.filterMode {
display: block;
font-size: 22rpx;
font-weight: 400;
color: $muted;
margin-top: 4rpx;
}
.searchResultItem {
margin-bottom: 8rpx;
.searchResultText {
font-size: 24rpx;
font-weight: 400;
color: $muted;
.highlightText {
color: $danger;
font-weight: 600;
}
}
}
}
}
}
// 区域数据卡片
.regionCard {
background: $card;
border-radius: 16rpx;
box-shadow: $shadow;
overflow: hidden;
.regionSection {
.regionTitle {
display: flex;
align-items: center;
justify-content: space-between;
padding: 32rpx;
background: #fafafa;
border-bottom: 1rpx solid #f0f0f0;
.titleText {
font-size: 26rpx;
font-weight: 600;
color: #160002;
}
.expandIcon {
transition: transform 0.3s ease;
&.expanded {
transform: rotate(180deg);
}
.uni-icon-arrowdown {
font-size: 24rpx;
color: $muted;
}
}
}
.regionList {
.regionItem {
border-bottom: 1rpx solid #f8f8f8;
&:last-child {
border-bottom: none;
}
.regionHeader {
display: flex;
align-items: center;
padding: 24rpx;
background: $card;
.regionInfo {
flex: 2;
.regionName {
font-size: 24rpx;
font-weight: 600;
color: #160002;
margin-bottom: 8rpx;
}
.regionRevenue {
font-size: 28rpx;
font-weight: 600;
color: $primary;
font-family: 'DIN Alternate', 'Arial', sans-serif;
}
}
.regionStats {
flex: 1;
text-align: center;
.statLabel {
font-size: 22rpx;
font-weight: 400;
color: $muted;
margin-bottom: 8rpx;
}
.statValue {
font-size: 24rpx;
font-weight: 600;
color: #160002;
}
}
.expandBtn {
flex: 0 0 64rpx;
display: flex;
justify-content: center;
align-items: center;
transition: transform 0.3s ease;
&.active {
transform: rotate(90deg);
}
.uni-icon-arrowright {
font-size: 24rpx;
color: $muted;
}
}
}
.serverList {
background: #fafafa;
.serverItem {
display: flex;
align-items: center;
padding: 24rpx 32rpx;
border-bottom: 1rpx solid #f0f0f0;
transition: background-color 0.2s ease;
&:last-child {
border-bottom: none;
}
&.visited {
.serverName {
color: $primary;
}
}
.serverDot {
width: 8rpx;
height: 8rpx;
border-radius: 50%;
background: $primary;
margin-right: 16rpx;
flex-shrink: 0;
}
.serverInfo {
flex: 1;
.serverName {
font-size: 24rpx;
font-weight: 400;
color: #160002;
margin-bottom: 8rpx;
}
.serverStats {
display: flex;
align-items: center;
.serverProportion {
font-size: 22rpx;
font-weight: 400;
color: $muted;
margin-right: 16rpx;
}
.serverRevenue {
font-size: 24rpx;
font-weight: 600;
color: $primary;
font-family: 'DIN Alternate', 'Arial', sans-serif;
}
}
}
.serverArrow {
.uni-icon-arrowright {
font-size: 20rpx;
color: $muted;
}
}
}
}
}
}
}
}
// 搜索框样式(弹窗内使用)
.search_box {
position: relative;
width: 100%;
height: 72rpx;
background: #F2F4F5;
display: flex;
align-items: center;
border-radius: 36rpx;
padding: 0 24rpx;
box-sizing: border-box;
img {
width: 32rpx;
height: 32rpx;
margin-right: 16rpx;
flex-shrink: 0;
}
.select_input {
flex: 1;
border: none;
height: 40rpx;
font-size: 24rpx;
font-weight: 400;
color: #160002;
background: transparent;
}
.delete {
width: 32rpx;
height: 32rpx;
flex-shrink: 0;
}
}
// 已在 filterCard 中重新定义
// 弹窗样式
.popupBox {
width: 100%;
height: 70vh;
background: $card;
box-sizing: border-box;
padding: 32rpx;
position: relative;
border-radius: 24rpx 24rpx 0 0;
display: flex;
flex-direction: column;
.popupContent {
flex: 1;
margin-top: 24rpx;
overflow: hidden;
.scrollContent {
height: calc(100% - 72rpx);
overflow-y: auto;
padding-bottom: 24rpx;
}
.popupTitle {
font-size: 28rpx;
font-weight: 600;
color: #160002;
margin: 32rpx 0 16rpx;
.title {
font-size: 28rpx;
font-weight: 600;
color: #160002;
}
.notice {
margin-left: 12rpx;
width: 24rpx;
height: 24rpx;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx solid $muted;
border-radius: 50%;
color: $muted;
font-size: 20rpx;
font-weight: 500;
.noticeBox {
max-width: 500rpx;
position: absolute;
top: 40rpx;
left: 0;
display: inline-block;
padding: 16rpx 20rpx;
background: $card;
border-radius: 12rpx;
box-shadow: $shadow;
z-index: 100;
.noticeText {
display: block;
font-size: 22rpx;
font-weight: 400;
color: #160002;
line-height: 1.5;
margin-bottom: 8rpx;
&:last-child {
margin-bottom: 0;
}
}
}
}
}
.timeList {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
margin-bottom: 24rpx;
.timeItem {
flex: 0 0 calc(25% - 12rpx);
padding: 16rpx 8rpx;
text-align: center;
background: #f8f8f8;
border-radius: 12rpx;
font-size: 22rpx;
font-weight: 400;
color: #160002;
transition: all 0.2s ease;
}
.timeSelectItem {
background: rgba($primary, 0.1);
color: $primary;
border: 1rpx solid $primary;
}
}
}
.btn {
width: 100%;
padding: 24rpx 0;
text-align: center;
border-radius: 16rpx;
color: #fff;
background: $primary;
font-size: 28rpx;
font-weight: 600;
margin-top: 24rpx;
flex-shrink: 0;
}
}
// 时间选择弹窗
.timePopup {
width: 80vw;
background: $card;
border-radius: 16rpx;
padding: 32rpx;
box-shadow: $shadow;
.btn {
width: 100%;
padding: 24rpx 0;
text-align: center;
border-radius: 16rpx;
color: #fff;
background: $primary;
font-size: 28rpx;
font-weight: 600;
margin-top: 32rpx;
}
}
// 覆盖uni-popup的默认样式移除底部间隙
::v-deep .uni-popup__wrapper-box {
padding-bottom: 0 !important;
}
::v-deep .uni-popup--bottom {
padding-bottom: 0 !important;
}
</style>