毛利分析的客户区域筛选。

This commit is contained in:
caojia
2026-11-05 14:26:36 +08:00
parent 218001e6ae
commit 1727386811
3 changed files with 59 additions and 7 deletions
@@ -24,6 +24,8 @@ public class PrcProfitReportQuery extends BaseEntity
private String customerCode; private String customerCode;
/** 客户代码拆分后的多值查询条件。 */ /** 客户代码拆分后的多值查询条件。 */
private List<String> customerCodes; private List<String> customerCodes;
/** 按客户当前区域筛选。 */
private String customerArea;
private String customerName; private String customerName;
/** 客户名称拆分后的多值查询条件。 */ /** 客户名称拆分后的多值查询条件。 */
private List<String> customerNames; private List<String> customerNames;
@@ -119,6 +119,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<sql id="profitReportFromAndWhere"> <sql id="profitReportFromAndWhere">
from prc_income_bill i from prc_income_bill i
inner join prc_order_bill p on p.bill_id = i.bill_id inner join prc_order_bill p on p.bill_id = i.bill_id
<if test="customerArea != null and customerArea != ''">
left join ctr_customer c on c.customer_id = p.customer_id and c.del_flag = '0'
</if>
<!-- 提成表关联暂停使用,毛利报表不再依赖提成配置。 <!-- 提成表关联暂停使用,毛利报表不再依赖提成配置。
left join prc_profit_commission_rate cr left join prc_profit_commission_rate cr
on cr.belong_saler_code = i.belong_saler_code and cr.status = '0' on cr.belong_saler_code = i.belong_saler_code and cr.status = '0'
@@ -126,6 +129,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<where> <where>
<!-- 不将未匹配产品、国家或重量段的计费失败订单纳入毛利报表;保留历史空值(按成功处理)。 --> <!-- 不将未匹配产品、国家或重量段的计费失败订单纳入毛利报表;保留历史空值(按成功处理)。 -->
and (p.billing_fail_status is null or p.billing_fail_status not in (1, 2, 3)) and (p.billing_fail_status is null or p.billing_fail_status not in (1, 2, 3))
<if test="customerArea != null and customerArea != ''">
and c.customer_area = #{customerArea}
</if>
<if test="beginBizDate != null"> <if test="beginBizDate != null">
and p.biz_date &gt;= #{beginBizDate} and p.biz_date &gt;= #{beginBizDate}
</if> </if>
+51 -7
View File
@@ -3,6 +3,13 @@
<el-card shadow="never" class="search-card"> <el-card shadow="never" class="search-card">
<el-form :model="query" label-width="88px" @submit.prevent> <el-form :model="query" label-width="88px" @submit.prevent>
<el-row :gutter="16"> <el-row :gutter="16">
<el-col :xs="24" :sm="12" :lg="8">
<el-form-item label="客户区域" class="filter-item">
<el-select v-model="query.customerArea" placeholder="请选择客户区域" class="filter-control" @change="handleSearch">
<el-option v-for="area in customer_area" :key="area.value" :label="area.label" :value="area.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :lg="8"> <el-col :xs="24" :sm="12" :lg="8">
<el-form-item label="计费日期" class="filter-item"> <el-form-item label="计费日期" class="filter-item">
<el-date-picker <el-date-picker
@@ -63,7 +70,7 @@
</el-col> </el-col>
<el-col :xs="24" :sm="12" :lg="8" class="filter-actions-col"> <el-col :xs="24" :sm="12" :lg="8" class="filter-actions-col">
<div class="filter-item filter-actions"> <div class="filter-item filter-actions">
<el-button type="primary" icon="Search" @click="handleSearch">搜索</el-button> <el-button type="primary" icon="Search" :disabled="!hasCustomerArea()" @click="handleSearch">搜索</el-button>
<el-button icon="Refresh" @click="handleReset">重置</el-button> <el-button icon="Refresh" @click="handleReset">重置</el-button>
</div> </div>
</el-col> </el-col>
@@ -132,6 +139,7 @@
icon="Download" icon="Download"
v-hasPermi="['report:profit:export']" v-hasPermi="['report:profit:export']"
:loading="exporting" :loading="exporting"
:disabled="!hasCustomerArea()"
@click="handleExport" @click="handleExport"
>导出当前维度</el-button> >导出当前维度</el-button>
</div> </div>
@@ -304,16 +312,19 @@ import { saveAs } from 'file-saver'
// 提成功能暂停使用:import { ElMessageBox } from 'element-plus' // 提成功能暂停使用:import { ElMessageBox } from 'element-plus'
const dimension = ref('product') const dimension = ref('product')
const { customer_area } = useDict('customer_area')
const multiValueFilterLimit = 2000 const multiValueFilterLimit = 2000
const dateRange = ref([formatLocalDate(-30), formatLocalDate(0)]) const dateRange = ref([formatLocalDate(-30), formatLocalDate(0)])
const arBillStatus = ref('') const arBillStatus = ref('')
const query = reactive({ const query = reactive({
customerArea: '',
orderNo: '', orderNo: '',
customerCode: '', customerCode: '',
belongSalerCode: '', belongSalerCode: '',
productCode: '' productCode: ''
}) })
const summaryList = ref([]) const summaryList = ref([])
let summaryRequestVersion = 0
const rows = ref([]) const rows = ref([])
let rowsRequestVersion = 0 let rowsRequestVersion = 0
const loading = ref(false) const loading = ref(false)
@@ -397,15 +408,21 @@ function validateMultiValueFilters(showMessage = true) {
return true return true
} }
function hasCustomerArea() {
return query.customerArea !== '' && query.customerArea !== null && query.customerArea !== undefined
}
function loadSummary() { function loadSummary() {
if (!validateMultiValueFilters(false)) return Promise.resolve() if (!hasCustomerArea() || !validateMultiValueFilters(false)) return Promise.resolve()
const requestVersion = ++summaryRequestVersion
return listProfitSummary(buildQuery(false)).then(res => { return listProfitSummary(buildQuery(false)).then(res => {
if (requestVersion !== summaryRequestVersion) return
summaryList.value = res.data || [] summaryList.value = res.data || []
}) })
} }
function loadRows() { function loadRows() {
if (!validateMultiValueFilters()) return Promise.resolve() if (!hasCustomerArea() || !validateMultiValueFilters()) return Promise.resolve()
const requestVersion = ++rowsRequestVersion const requestVersion = ++rowsRequestVersion
const requestDimension = dimension.value const requestDimension = dimension.value
loading.value = true loading.value = true
@@ -419,14 +436,31 @@ function loadRows() {
}) })
} }
function clearReportResults() {
summaryRequestVersion++
rowsRequestVersion++
orderListRequestVersion++
summaryList.value = []
rows.value = []
total.value = 0
loading.value = false
orderListDialogVisible.value = false
orderListLoading.value = false
orderListRows.value = []
orderListTotal.value = 0
orderListContext.value = null
}
function handleSearch() { function handleSearch() {
if (!validateMultiValueFilters()) return clearReportResults()
if (!hasCustomerArea() || !validateMultiValueFilters()) return
pageNum.value = 1 pageNum.value = 1
Promise.all([loadSummary(), loadRows()]) Promise.all([loadSummary(), loadRows()])
} }
function handleReset() { function handleReset() {
Object.keys(query).forEach(key => { query[key] = '' }) Object.keys(query).forEach(key => { query[key] = '' })
query.customerArea = customer_area.value[0]?.value ?? ''
arBillStatus.value = '' arBillStatus.value = ''
dateRange.value = [formatLocalDate(-30), formatLocalDate(0)] dateRange.value = [formatLocalDate(-30), formatLocalDate(0)]
handleSearch() handleSearch()
@@ -459,7 +493,7 @@ function openOrderList(row) {
function loadOrderList() { function loadOrderList() {
if (!orderListContext.value) return if (!orderListContext.value) return
if (!validateMultiValueFilters()) return if (!hasCustomerArea() || !validateMultiValueFilters()) return
const requestVersion = ++orderListRequestVersion const requestVersion = ++orderListRequestVersion
orderListLoading.value = true orderListLoading.value = true
const params = { const params = {
@@ -513,7 +547,7 @@ function arBillStatusLabel(value) {
} }
async function handleExport() { async function handleExport() {
if (!validateMultiValueFilters()) return if (!hasCustomerArea() || !validateMultiValueFilters()) return
exporting.value = true exporting.value = true
const exporter = dimension.value === 'product' ? exportProfitProducts : exportProfitOrders const exporter = dimension.value === 'product' ? exportProfitProducts : exportProfitOrders
try { try {
@@ -625,7 +659,17 @@ function handleDeleteRate(row) {
} }
*/ */
handleSearch() watch(customer_area, options => {
if (!options?.length) {
query.customerArea = ''
clearReportResults()
return
}
if (!options.some(area => area.value === query.customerArea)) {
query.customerArea = options[0].value
handleSearch()
}
}, { immediate: true })
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">