Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product

pull/6/head
tangqian 2023-05-30 20:03:48 +08:00
commit e00d646c35
13 changed files with 253 additions and 35 deletions

View File

@ -110,6 +110,18 @@ public class RechargeOrderController {
return success(pageResult); return success(pageResult);
} }
@PostMapping("/findPromoterDrawPage")
@Operation(summary = "获得推广员抽佣统计")
@PreAuthorize("@ss.hasPermission('shop:recharge-order:query')")
@TenantIgnore
public CommonResult<PageResult<PromoterDrawVO>> getRechargeOrderPage(@RequestBody PromoterDrawReqVO pageVO) {
if(!TenantContextHolder.ID_SYSTEM.equals(SecurityFrameworkUtils.getLoginUser().getTenantId())){
pageVO.setTenantId(SecurityFrameworkUtils.getLoginUser().getTenantId());
}
PageResult<PromoterDrawVO> pageResult = rechargeOrderService.findPromoterDrawPage(pageVO);
return success(pageResult);
}
@GetMapping("/export-excel") @GetMapping("/export-excel")
@Operation(summary = "导出订单 Excel") @Operation(summary = "导出订单 Excel")

View File

@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.shop.controller.admin.recharge.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Data
public class PromoterDrawReqVO extends PageParam {
private Long tenantId;
@Schema(description = "商户名称")
private String deptName;
@Schema(description = "组织结构名称")
private String parentOrganizationName;
@Schema(description = "推广员名称")
private String nickname;
@Schema(description = "手机号")
private String mobile;
@Schema(description = "成为推广员时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.shop.controller.admin.recharge.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class PromoterDrawVO {
@Schema(description = "用户id")
private Long userId;
@Schema(description = "组织id")
private Long deptId;
@Schema(description = "商户id")
private Long tenantId;
@Schema(description = "组织名称")
private String deptName;
@Schema(description = "组织结构名称")
private String parentOrganizationName;
@Schema(description = "推广员名称")
private String nickname;
@Schema(description = "手机号")
private String mobile;
@Schema(description = "成为推广员时间")
private LocalDateTime createTime;
@Schema(description = "会员提成")
private Integer memberCommission;
@Schema(description = "商品提成")
private Integer goodsCommission;
@Schema(description = "成交定单数")
private BigDecimal orderCount;
@Schema(description = "可提现金额")
private BigDecimal drawAmount;
@Schema(description = "成交金额")
private BigDecimal dealAmount;
@Schema(description = "累计金额")
private BigDecimal totalAmount;
}

View File

@ -3,6 +3,9 @@ package cn.iocoder.yudao.module.shop.controller.admin.recharge.vo;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -31,5 +34,6 @@ public class RechargeOrderRespVO extends RechargeOrderBaseVO {
private String parentOrganizationName; private String parentOrganizationName;
@Schema(description = "推广员名称") @Schema(description = "推广员名称")
private String nickname; private String nickname;
@Schema(description = "提成金额", required = true, example = "3114")
private BigDecimal commissionPrice;
} }

View File

@ -60,6 +60,10 @@ public interface RechargeOrderMapper extends BaseMapperX<RechargeOrderDO> {
.orderByDesc(RechargeOrderDO::getId)); .orderByDesc(RechargeOrderDO::getId));
} }
IPage<RechargeOrderRespVO> findListPage(IPage<RechargeOrderRespVO> page, @Param("data") RechargeOrderPageReqVO data); IPage<RechargeOrderRespVO> findListPage(IPage<RechargeOrderRespVO> page, @Param("data") RechargeOrderPageReqVO data);
IPage<PromoterDrawVO> findPromoterDrawPage(IPage<PromoterDrawVO> page, @Param("data") PromoterDrawReqVO data);
List<PromoterDrawVO> findPromoterDrawCount(@Param("promoterIds") List<Long> promoterIds);
BigDecimal promoterOrderCount(@Param("startDate") LocalDateTime startDate, @Param("endDate")LocalDateTime endDate,@Param("promoterId") Long promoterId); BigDecimal promoterOrderCount(@Param("startDate") LocalDateTime startDate, @Param("endDate")LocalDateTime endDate,@Param("promoterId") Long promoterId);
List<RechargeOrderExcelVO> findListExcel(@Param("data") RechargeOrderExportReqVO data); List<RechargeOrderExcelVO> findListExcel(@Param("data") RechargeOrderExportReqVO data);

View File

@ -64,7 +64,7 @@ public interface RechargeOrderService {
* @return * @return
*/ */
PageResult<RechargeOrderRespVO> getRechargeOrderPage(RechargeOrderPageReqVO pageReqVO); PageResult<RechargeOrderRespVO> getRechargeOrderPage(RechargeOrderPageReqVO pageReqVO);
PageResult<PromoterDrawVO> findPromoterDrawPage(PromoterDrawReqVO pageReqVO);
/** /**
* , Excel * , Excel
* *

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.shop.service.recharge; package cn.iocoder.yudao.module.shop.service.recharge;
import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
@ -44,6 +45,7 @@ import cn.iocoder.yudao.module.shop.dal.mysql.recharge.RechargeOrderMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.shop.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.shop.enums.ErrorCodeConstants.*;
import static java.util.stream.Collectors.toMap;
/** /**
* Service * Service
@ -124,7 +126,36 @@ public class RechargeOrderServiceImpl implements RechargeOrderService {
rechargeOrderMapper.findListPage(page, pageReqVO); rechargeOrderMapper.findListPage(page, pageReqVO);
return new PageResult<>(page.getRecords(), page.getTotal()); return new PageResult<>(page.getRecords(), page.getTotal());
} }
@Override
public PageResult<PromoterDrawVO> findPromoterDrawPage(PromoterDrawReqVO pageReqVO) {
Page<PromoterDrawVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
rechargeOrderMapper.findPromoterDrawPage(page, pageReqVO);
List<PromoterDrawVO> list = page.getRecords();
if(list!=null && list.size() > 0){
List<Long> collect1 = list.stream().map(PromoterDrawVO::getUserId).collect(Collectors.toList());
List<PromoterDrawVO> promoterDrawVOList = rechargeOrderMapper.findPromoterDrawCount(collect1);
Map<Long,PromoterDrawVO> nameList = promoterDrawVOList.stream().collect(toMap(PromoterDrawVO::getUserId, value -> value,(value1,value2)->value1));
list.forEach(promoterDrawVO -> {
PromoterDrawVO promoterDrawNew = nameList.get(promoterDrawVO.getUserId());
if(promoterDrawNew!=null){
promoterDrawVO.setDealAmount(promoterDrawNew.getDealAmount());
promoterDrawVO.setTotalAmount(promoterDrawNew.getTotalAmount());
promoterDrawVO.setOrderCount(promoterDrawNew.getOrderCount());
if(promoterDrawVO.getMemberCommission()==null){
promoterDrawVO.setMemberCommission(0);
}
promoterDrawVO.setDrawAmount(NumberUtil.mul(promoterDrawNew.getDealAmount(),NumberUtil.div(promoterDrawVO.getMemberCommission().toString(),"100"),2));
}else {
promoterDrawVO.setDealAmount(new BigDecimal(0));
promoterDrawVO.setTotalAmount(new BigDecimal(0));
promoterDrawVO.setOrderCount(new BigDecimal(0));
promoterDrawVO.setMemberCommission(0);
promoterDrawVO.setDrawAmount(new BigDecimal(0));
}
});
}
return new PageResult<>(list, page.getTotal());
}
@Override @Override
public List<RechargeOrderDO> getRechargeOrderList(RechargeOrderExportReqVO exportReqVO) { public List<RechargeOrderDO> getRechargeOrderList(RechargeOrderExportReqVO exportReqVO) {
return rechargeOrderMapper.selectList(exportReqVO); return rechargeOrderMapper.selectList(exportReqVO);

View File

@ -10,6 +10,61 @@
--> -->
<select id="findPromoterDrawPage" resultType="cn.iocoder.yudao.module.shop.controller.admin.recharge.vo.PromoterDrawVO">
SELECT
a.user_id,
a.dept_id,
a.tenant_id,
c.`name`as dept_name,
c.parent_organization_name,
d.nickname,
d.mobile,
a.create_time,
b.member_commission,
b.goods_commission
FROM
member_promoter a
LEFT JOIN system_dept c on c.id= a.dept_id
LEFT JOIN member_user d on d.id=a.user_id
LEFT JOIN system_tenant b on b.id=a.tenant_id
<where>
<if test="data.tenantId!=null">
and a.tenant_id=#{data.tenantId}
</if>
<if test="data.tenantId!=null">
and c.parent_Organization_name=#{data.parentOrganizationName}
</if>
<if test="data.mobile!=null and data.mobile!=''">
and d.mobile=#{data.mobile}
</if>
<if test="data.nickname!=null and data.nickname!=''">
and d.nickname=#{data.nickname}
</if>
<if test="data.createTime !=null and data.createTime.length>=1">
and a.create_time &gt;=#{data.createTime[0]}
</if>
<if test="data.createTime !=null and data.createTime.length>=2">
and a.create_time &lt;=#{data.createTime[1]}
</if>
</where>
</select>
<select id="findPromoterDrawCount" resultType="cn.iocoder.yudao.module.shop.controller.admin.recharge.vo.PromoterDrawVO">
select b.promoter_id as user_id,count(case b.paid=1 when 1 then 0 end) as order_count,
sum(case b.paid =1 when 1 then 0 end) as deal_amount,
sum(case b.paid in (1,2) when 1 then 0 end) as total_amount
from cy_recharge_order b
<where>
<if test="promoterIds!=null and promoterIds.size()>0">
and b.promoter_id in
<foreach collection="promoterIds" separator="," open="(" close=")" item="id">
#{id}
</foreach>
</if>
</where>
GROUP BY b.promoter_id
</select>
<select id="findListPage" resultType="cn.iocoder.yudao.module.shop.controller.admin.recharge.vo.RechargeOrderRespVO"> <select id="findListPage" resultType="cn.iocoder.yudao.module.shop.controller.admin.recharge.vo.RechargeOrderRespVO">
select select
a.id, a.id,
@ -50,6 +105,8 @@
a.pay_type, a.pay_type,
a.total_price, a.total_price,
a.pay_price, a.pay_price,
a.pay_price,
CONVERT(a.pay_price*e.member_commission/100, DECIMAL(15,2)) as commissionPrice,
a.paid, a.paid,
d.parent_organization_name d.parent_organization_name
from cy_recharge_order a from cy_recharge_order a

View File

@ -52,6 +52,15 @@ export function getRechargeOrderPage(query) {
}) })
} }
// 获得抽佣明细-会员充值
export function getCommissionDetailsPage(query) {
return request({
url: '/shop/recharge-order/findPromoterDrawPage',
method: 'post',
data: query
})
}
// 导出订单 Excel // 导出订单 Excel
export function exportRechargeOrderExcel(query) { export function exportRechargeOrderExcel(query) {
return request({ return request({

View File

@ -3,21 +3,21 @@
<!-- 搜索工作栏 --> <!-- 搜索工作栏 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="98px"> <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="98px">
<el-form-item label="组织名称" prop="tenantName"> <el-form-item label="组织名称" prop="parentOrganizationName">
<el-input v-model="queryParams.tenantName" placeholder="请输入组织名称" clearable @keyup.enter.native="handleQuery"/> <el-input v-model="queryParams.parentOrganizationName" placeholder="请输入组织名称" clearable @keyup.enter.native="handleQuery"/>
</el-form-item> </el-form-item>
<el-form-item label="订单编号" prop="orderId"> <el-form-item label="商户名称" prop="deptName">
<el-input v-model="queryParams.orderId" placeholder="请输入订单编号" clearable @keyup.enter.native="handleQuery"/> <el-input v-model="queryParams.deptName" placeholder="请输入商户名称" clearable @keyup.enter.native="handleQuery"/>
</el-form-item> </el-form-item>
<el-form-item label="加入时间" prop="payTime"> <el-form-item label="加入时间" prop="createTime">
<el-date-picker v-model="queryParams.payTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange" <el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" clearable @keyup.enter.native="handleQuery"/> range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" clearable @keyup.enter.native="handleQuery"/>
</el-form-item> </el-form-item>
<el-form-item label="推广员" prop="nickname"> <el-form-item label="推广员" prop="nickname">
<el-input v-model="queryParams.nickname" placeholder="请输入推广员" clearable @keyup.enter.native="handleQuery"/> <el-input v-model="queryParams.nickname" placeholder="请输入推广员" clearable @keyup.enter.native="handleQuery"/>
</el-form-item> </el-form-item>
<el-form-item label="手机号" prop="nickname"> <el-form-item label="手机号" prop="mobile">
<el-input v-model="queryParams.nickname" placeholder="请输入手机号" clearable @keyup.enter.native="handleQuery"/> <el-input v-model="queryParams.mobile" placeholder="请输入手机号" clearable @keyup.enter.native="handleQuery"/>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery"></el-button> <el-button type="primary" icon="el-icon-search" @click="handleQuery"></el-button>
@ -31,32 +31,32 @@
<!-- <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"--> <!-- <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"-->
<!-- v-hasPermi="['shop:recharge-order:create']">新增</el-button>--> <!-- v-hasPermi="['shop:recharge-order:create']">新增</el-button>-->
<!-- </el-col>--> <!-- </el-col>-->
<el-col :span="1.5"> <!-- <el-col :span="1.5">-->
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading" <!-- <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"-->
v-hasPermi="['shop:recharge-order:export']">导出</el-button> <!-- v-hasPermi="['shop:recharge-order:export']">导出</el-button>-->
</el-col> <!-- </el-col>-->
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
<!-- 列表 --> <!-- 列表 -->
<el-table v-loading="loading" :data="list"> <el-table v-loading="loading" :data="list">
<el-table-column label="组织名称" align="center" prop="orderId" /> <el-table-column label="组织名称" align="center" prop="deptName" />
<el-table-column label="推广员" align="center" prop="parentOrganizationName" > <el-table-column label="推广员" align="center" prop="parentOrganizationName" >
<template v-slot="scope"> <template v-slot="scope">
<span>{{ scope.row.parentOrganizationName }}</span> <span>{{ scope.row.parentOrganizationName }}</span>
<span v-if="scope.row.nickname!=='' && scope.row.nickname!==null">-{{ scope.row.nickname }}</span> <span v-if="scope.row.nickname!=='' && scope.row.nickname!==null">-{{ scope.row.nickname }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="手机号" align="center" prop="orderId" /> <el-table-column label="手机号" align="center" prop="mobile" />
<el-table-column label="加入时间" align="center" prop="payTime" width="180"> <el-table-column label="加入时间" align="center" prop="createTime" width="180">
<template v-slot="scope"> <template v-slot="scope">
<span>{{ parseTime(scope.row.payTime) }}</span> <span>{{ parseTime(scope.row.createTime) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="成交定单数" align="center" prop="orderId" /> <el-table-column label="成交定单数" align="center" prop="orderCount" />
<el-table-column label="成交金额" align="center" prop="commissionPrice" /> <el-table-column label="成交金额" align="center" prop="dealAmount" />
<el-table-column label="累计金额" align="center" prop="tenantName" /> <el-table-column label="累计金额" align="center" prop="totalAmount" />
<el-table-column label="可提现金额" align="center" prop="tenantName" /> <el-table-column label="可提现金额" align="center" prop="drawAmount" />
</el-table> </el-table>
<!-- 分页组件 --> <!-- 分页组件 -->
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@ -68,7 +68,7 @@
<script> <script>
import { import {
getRechargeOrderPage, getCommissionDetailsPage,
exportRechargeOrderExcel exportRechargeOrderExcel
} from '@/api/shop/rechargeOrder'; } from '@/api/shop/rechargeOrder';
import {DICT_TYPE, getDictDatas} from "@/utils/dict"; import {DICT_TYPE, getDictDatas} from "@/utils/dict";
@ -104,10 +104,11 @@ export default {
queryParams: { queryParams: {
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
orderId: null, parentOrganizationName: '',
tenantName: null, deptName: '',
payTime: [], createTime: [],
nickname: null nickname: '',
mobile: ''
}, },
statusDictDatas: getDictDatas(DICT_TYPE.PAY_STATUS), statusDictDatas: getDictDatas(DICT_TYPE.PAY_STATUS),
}; };
@ -120,7 +121,7 @@ export default {
getList() { getList() {
this.loading = true; this.loading = true;
// //
getRechargeOrderPage(this.queryParams).then(response => { getCommissionDetailsPage(this.queryParams).then(response => {
this.list = response.data.list; this.list = response.data.list;
this.total = response.data.total; this.total = response.data.total;
this.loading = false; this.loading = false;

View File

@ -168,7 +168,7 @@ export default {
// //
open: false, open: false,
// //
title: '商户导入', title: '批量导入',
// //
isUploading: false, isUploading: false,
// //
@ -229,7 +229,7 @@ export default {
}, },
/** 导入按钮操作 */ /** 导入按钮操作 */
handleImport() { handleImport() {
this.upload.title = '推广员导入'; this.upload.title = '批量导入';
this.upload.open = true; this.upload.open = true;
}, },
// //

View File

@ -389,6 +389,7 @@ export default {
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {
this.reset(); this.reset();
this.form.status = 0
this.open = true; this.open = true;
this.isLook = false; this.isLook = false;
this.title = '添加店铺'; this.title = '添加店铺';

View File

@ -1,9 +1,9 @@
<template> <template>
<view class="box"> <view class="box">
<u-navbar autoBack title="发展会员业绩" bgColor="rgba(255,255,255,0)" :placeholder="true" leftIconSize="40" <u-navbar autoBack :title="performance[active].name" bgColor="rgba(255,255,255,0)" :placeholder="true" leftIconSize="40"
leftIconColor="#fff" titleStyle="font-size:35rpx;color:#fff"> leftIconColor="#fff" titleStyle="font-size:35rpx;color:#fff">
<!-- <view slot="right"> <!-- <view slot="right">
<u-icon name="more-dot-fill" color="#fff"></u-icon> <u-icon name="more-dot-fill" color="#fff" @click="show = true"></u-icon>
</view> --> </view> -->
</u-navbar> </u-navbar>
<u-sticky bgColor="#fff"> <u-sticky bgColor="#fff">
@ -48,7 +48,7 @@
</view> </view>
<view class="sale_turnover"> <view class="sale_turnover">
<view class="turnover_title"> <view class="turnover_title">
流水明细 {{performance[active].fund}}
</view> </view>
<view class="turnover_list"> <view class="turnover_list">
<u-list <u-list
@ -71,6 +71,7 @@
</view> </view>
</view> </view>
</view> </view>
<u-action-sheet :actions="performance" @close="show = false" :closeOnClickOverlay="true" :closeOnClickAction="true" @select="selectClick" :title="title" :show="show"></u-action-sheet>
</view> </view>
</template> </template>
@ -96,6 +97,23 @@
fontWeight: '400', fontWeight: '400',
color: '#fff' color: '#fff'
}, },
show:false,
title:'业绩',
active:0,
performance: [
{
fund:'流水明细',
name:'发展会员业绩',
fontSize:'30',
id:0
},
{
fund:'订单流水',
name: '商品订单业绩',
fontSize:'30',
id:1
},
],
list: [{ list: [{
name: '今日', name: '今日',
}, { }, {
@ -127,6 +145,10 @@
} }
}, },
methods: { methods: {
selectClick(value){
console.log(value)
this.active = value.id
},
async scrolltolower() { async scrolltolower() {
if(this.total>this.orderData.length){ if(this.total>this.orderData.length){
this.pageData.pageNo++ this.pageData.pageNo++