feat: 消费地图大屏功能, 新增。

This commit is contained in:
tianyongbao
2026-06-18 13:51:43 +08:00
parent 050c844508
commit 55d55f70a6
7 changed files with 370 additions and 1 deletions

View File

@@ -3,9 +3,12 @@ package com.intc.invest.controller;
import com.intc.common.core.web.controller.BaseController;
import com.intc.common.core.web.domain.AjaxResult;
import com.intc.common.core.web.page.TableDataInfo;
import com.intc.invest.domain.dto.AccountDealLocationDto;
import com.intc.invest.domain.dto.AccountsDto;
import com.intc.invest.domain.dto.AnalysisDto;
import com.intc.invest.domain.vo.AccountCalendarVo;
import com.intc.invest.domain.vo.AccountDealLocationVo;
import com.intc.invest.domain.vo.AccountsDealRecordVo;
import com.intc.invest.domain.vo.AccountsVo;
import com.intc.invest.domain.vo.BankCardStatisticsVo;
import com.intc.invest.domain.vo.OpenCardVo;
@@ -209,4 +212,36 @@ public class StatisticAnalysisController extends BaseController {
return AjaxResult.success(list);
}
/**
* 查询交易地点消费地图概览
*/
@ApiOperation(value="查询交易地点消费地图概览")
@GetMapping("/accountDealLocationOverview")
public AjaxResult getAccountDealLocationOverview(AccountDealLocationDto accountDealLocationDto)
{
return AjaxResult.success(iStatisticAnalysisService.getAccountDealLocationOverview(accountDealLocationDto));
}
/**
* 查询交易地点消费地图聚合点位
*/
@ApiOperation(value="查询交易地点消费地图聚合点位",response = AccountDealLocationVo.class)
@GetMapping("/accountDealLocationPoints")
public AjaxResult getAccountDealLocationPoints(AccountDealLocationDto accountDealLocationDto)
{
List<AccountDealLocationVo> list = iStatisticAnalysisService.getAccountDealLocationPoints(accountDealLocationDto);
return AjaxResult.success(list);
}
/**
* 查询交易地点消费明细
*/
@ApiOperation(value="查询交易地点消费明细",response = AccountsDealRecordVo.class)
@GetMapping("/accountDealLocationRecords")
public AjaxResult getAccountDealLocationRecords(AccountDealLocationDto accountDealLocationDto)
{
List<AccountsDealRecordVo> list = iStatisticAnalysisService.getAccountDealLocationRecords(accountDealLocationDto);
return AjaxResult.success(list);
}
}

View File

@@ -0,0 +1,60 @@
package com.intc.invest.domain.dto;
import com.intc.common.core.web.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* 交易地点消费地图查询对象
*
* @author tianyongbao
*/
@ApiModel("交易地点消费地图查询对象")
@Data
public class AccountDealLocationDto extends BaseEntity implements Serializable
{
private static final long serialVersionUID = 1L;
/** 开始日期 */
@ApiModelProperty(value="开始日期")
private String startTime;
/** 结束日期 */
@ApiModelProperty(value="结束日期")
private String endTime;
/** 账户 */
@ApiModelProperty(value="账户")
private Long accountId;
/** 交易类型 */
@ApiModelProperty(value="交易类型")
private String dealType;
/** 交易类别 */
@ApiModelProperty(value="交易类别")
private String dealCategory;
/** 交易子类别 */
@ApiModelProperty(value="交易子类别")
private String childCategory;
/** 地点名称 */
@ApiModelProperty(value="地点名称")
private String locationName;
/** 地点地址 */
@ApiModelProperty(value="地点地址")
private String locationAddress;
/** 经度 */
@ApiModelProperty(value="经度")
private Double longitude;
/** 纬度 */
@ApiModelProperty(value="纬度")
private Double latitude;
}

View File

@@ -0,0 +1,47 @@
package com.intc.invest.domain.vo;
import io.swagger.annotations.ApiModel;
import lombok.Data;
/**
* 交易地点消费地图聚合对象
*
* @author tianyongbao
*/
@ApiModel("交易地点消费地图聚合对象")
@Data
public class AccountDealLocationVo
{
/** 地点聚合键 */
private String locationKey;
/** 地点名称 */
private String locationName;
/** 地点地址 */
private String locationAddress;
/** 经度 */
private Double longitude;
/** 纬度 */
private Double latitude;
/** 消费金额 */
private Double totalAmount;
/** 交易笔数 */
private Long dealCount;
/** 最近交易时间 */
private String latestTime;
/** 关联账户 */
private String accountNames;
/** 交易类别 */
private String dealCategory;
/** 交易子类别 */
private String childCategory;
}

View File

@@ -1,6 +1,7 @@
package com.intc.invest.mapper;
import com.intc.common.datascope.annotation.DataScope;
import com.intc.invest.domain.dto.AccountDealLocationDto;
import com.intc.invest.domain.dto.AccountsDealRecordDto;
import com.intc.invest.domain.dto.AccountsDto;
import com.intc.invest.domain.dto.BankCardLendDto;
@@ -122,4 +123,22 @@ public interface StatisticAnalysisMapper {
@DataScope(businessAlias = "a")
public List<BankCardStatisticsVo> selectBankCardStatistics(AccountsDto accountsDto);
/**
* 查询交易地点消费地图聚合点位
*
* @param accountDealLocationDto 查询条件
* @return 地点聚合点位集合
*/
@DataScope(businessAlias = "a")
public List<AccountDealLocationVo> selectAccountDealLocationPoints(AccountDealLocationDto accountDealLocationDto);
/**
* 查询交易地点消费明细
*
* @param accountDealLocationDto 查询条件
* @return 交易明细集合
*/
@DataScope(businessAlias = "a")
public List<AccountsDealRecordVo> selectAccountDealLocationRecords(AccountDealLocationDto accountDealLocationDto);
}

View File

@@ -1,8 +1,11 @@
package com.intc.invest.service;
import com.intc.invest.domain.dto.AccountDealLocationDto;
import com.intc.invest.domain.dto.AccountsDto;
import com.intc.invest.domain.dto.AnalysisDto;
import com.intc.invest.domain.vo.AccountCalendarVo;
import com.intc.invest.domain.vo.AccountDealLocationVo;
import com.intc.invest.domain.vo.AccountsDealRecordVo;
import com.intc.invest.domain.vo.AccountsVo;
import com.intc.invest.domain.vo.BankCardStatisticsVo;
import com.intc.invest.domain.vo.CreditReportAnalysisVO;
@@ -78,4 +81,28 @@ public interface IStatisticAnalysisService {
*/
public List<BankCardStatisticsVo> getBankCardStatistics();
/**
* 查询交易地点消费地图概览
*
* @param accountDealLocationDto 查询条件
* @return 概览数据
*/
public Map<String, Object> getAccountDealLocationOverview(AccountDealLocationDto accountDealLocationDto);
/**
* 查询交易地点消费地图聚合点位
*
* @param accountDealLocationDto 查询条件
* @return 地点聚合点位集合
*/
public List<AccountDealLocationVo> getAccountDealLocationPoints(AccountDealLocationDto accountDealLocationDto);
/**
* 查询交易地点消费明细
*
* @param accountDealLocationDto 查询条件
* @return 交易明细集合
*/
public List<AccountsDealRecordVo> getAccountDealLocationRecords(AccountDealLocationDto accountDealLocationDto);
}

View File

@@ -3429,4 +3429,71 @@ public class StatisticAnalysisImpl implements IStatisticAnalysisService {
public List<BankCardStatisticsVo> getBankCardStatistics() {
return statisticAnalysisMapper.selectBankCardStatistics(new AccountsDto());
}
@Override
public Map<String, Object> getAccountDealLocationOverview(AccountDealLocationDto accountDealLocationDto) {
if (accountDealLocationDto == null) {
accountDealLocationDto = new AccountDealLocationDto();
}
List<AccountDealLocationVo> locationList = getAccountDealLocationPoints(accountDealLocationDto);
double totalAmount = 0;
long dealCount = 0;
double maxAmount = 0;
String latestTime = "";
for (AccountDealLocationVo vo : locationList) {
double amount = vo.getTotalAmount() == null ? 0 : vo.getTotalAmount();
totalAmount += amount;
dealCount += vo.getDealCount() == null ? 0 : vo.getDealCount();
if (amount > maxAmount) {
maxAmount = amount;
}
if (StringUtils.isNotEmpty(vo.getLatestTime()) && (StringUtils.isEmpty(latestTime) || vo.getLatestTime().compareTo(latestTime) > 0)) {
latestTime = vo.getLatestTime();
}
}
HashMap<String, Object> map = new HashMap<>();
map.put("totalAmount", totalAmount);
map.put("dealCount", dealCount);
map.put("locationCount", locationList.size());
map.put("maxAmount", maxAmount);
map.put("latestTime", latestTime);
map.put("topLocations", locationList.stream().limit(10).collect(Collectors.toList()));
return map;
}
@Override
public List<AccountDealLocationVo> getAccountDealLocationPoints(AccountDealLocationDto accountDealLocationDto) {
if (accountDealLocationDto == null) {
accountDealLocationDto = new AccountDealLocationDto();
}
initAccountDealLocationDefaultQuery(accountDealLocationDto);
return statisticAnalysisMapper.selectAccountDealLocationPoints(accountDealLocationDto);
}
@Override
public List<AccountsDealRecordVo> getAccountDealLocationRecords(AccountDealLocationDto accountDealLocationDto) {
if (accountDealLocationDto == null) {
accountDealLocationDto = new AccountDealLocationDto();
}
initAccountDealLocationDefaultQuery(accountDealLocationDto);
List<AccountsDealRecordVo> list = statisticAnalysisMapper.selectAccountDealLocationRecords(accountDealLocationDto);
for (AccountsDealRecordVo vo : list) {
if (StringUtils.isNotEmpty(vo.getDealCategory())) {
vo.setDealCategoryName(DictUtils.getDictLabel("deal_category", vo.getDealCategory()));
}
if (StringUtils.isNotEmpty(vo.getChildCategory()) && "1".equals(vo.getDealCategory())) {
vo.setChildCategoryName(DictUtils.getDictLabel("daily_expenses", vo.getChildCategory()));
}
}
return list;
}
private void initAccountDealLocationDefaultQuery(AccountDealLocationDto accountDealLocationDto) {
if (accountDealLocationDto != null && StringUtils.isEmpty(accountDealLocationDto.getDealType())) {
accountDealLocationDto.setDealType("2");
}
}
}

View File

@@ -68,6 +68,22 @@
<result property="transferRecordId" column="transfer_record_id" />
<result property="currentBalance" column="current_balance" />
<result property="childCategory" column="child_category" />
<result property="locationName" column="location_name" />
<result property="locationAddress" column="location_address" />
<result property="longitude" column="longitude" />
<result property="latitude" column="latitude" />
</resultMap>
<resultMap type="AccountDealLocationVo" id="AccountDealLocationResult">
<result property="locationKey" column="location_key" />
<result property="locationName" column="location_name" />
<result property="locationAddress" column="location_address" />
<result property="longitude" column="longitude" />
<result property="latitude" column="latitude" />
<result property="totalAmount" column="total_amount" />
<result property="dealCount" column="deal_count" />
<result property="latestTime" column="latest_time" />
<result property="accountNames" column="account_names" />
</resultMap>
<select id="selectAccountsOutInList" parameterType="AccountsDealRecordDto" resultMap="AccountsDealRecordResult">
@@ -1026,4 +1042,102 @@
b.bank_name
</select>
<sql id="accountDealLocationWhere">
a.del_flag = '0'
and a.longitude is not null
and a.latitude is not null
<if test="endTime != null and endTime != ''">
and #{endTime} &gt;= to_char(a.create_time, 'yyyy-MM-dd')
</if>
<if test="startTime != null and startTime != ''">
and to_char(a.create_time, 'yyyy-MM-dd') &gt;= #{startTime}
</if>
<if test="accountId != null">
and a.account_id = #{accountId}
</if>
<if test="dealType != null and dealType != ''">
and a.deal_type = #{dealType}
</if>
<if test="dealCategory != null and dealCategory != ''">
and a.deal_category = #{dealCategory}
</if>
<if test="childCategory != null and childCategory != ''">
and a.child_category = #{childCategory}
</if>
<if test="locationName != null and locationName != ''">
and a.location_name like '%' || #{locationName} || '%'
</if>
<if test="locationAddress != null and locationAddress != ''">
and a.location_address like '%' || #{locationAddress} || '%'
</if>
</sql>
<select id="selectAccountDealLocationPoints" parameterType="AccountDealLocationDto" resultMap="AccountDealLocationResult">
select
concat(round(a.longitude::numeric, 5), '_', round(a.latitude::numeric, 5)) as location_key,
COALESCE(NULLIF(max(a.location_name), ''), NULLIF(max(a.location_address), ''), concat(round(a.longitude::numeric, 5), ',', round(a.latitude::numeric, 5))) as location_name,
max(a.location_address) as location_address,
round(a.longitude::numeric, 5)::float8 as longitude,
round(a.latitude::numeric, 5)::float8 as latitude,
COALESCE(sum(a.amount), 0) as total_amount,
count(1) as deal_count,
to_char(max(a.create_time), 'yyyy-MM-dd HH24:mi:ss') as latest_time,
string_agg(distinct COALESCE(ac."name", ''), '、') as account_names
from
accounts_deal_record a
left join accounts ac on ac.id = a.account_id
<where>
<include refid="accountDealLocationWhere"/>
</where>
<!-- 数据范围过滤 -->
${params.dataScope}
group by
round(a.longitude::numeric, 5),
round(a.latitude::numeric, 5)
order by
sum(a.amount) desc
</select>
<select id="selectAccountDealLocationRecords" parameterType="AccountDealLocationDto" resultMap="AccountsDealRecordResult">
select
a.id,
a.name,
a.type,
a.account_id,
a.amount,
a.transfer_record_id,
a.deal_type,
a.create_by,
a.create_time,
a.update_by,
a.update_time,
a.del_flag,
a.remark,
a.deal_category,
a.current_balance,
a.child_category,
a.location_name,
a.location_address,
a.longitude,
a.latitude,
CONCAT(ac."name", '', right(ac.code, 4), '') as account_name
from
accounts_deal_record a
left join accounts ac on ac.id = a.account_id
<where>
<include refid="accountDealLocationWhere"/>
<if test="longitude != null">
and round(a.longitude::numeric, 5) = round(CAST(#{longitude} AS numeric), 5)
</if>
<if test="latitude != null">
and round(a.latitude::numeric, 5) = round(CAST(#{latitude} AS numeric), 5)
</if>
</where>
<!-- 数据范围过滤 -->
${params.dataScope}
order by
a.create_time desc
limit 100
</select>
</mapper>