Merge branch 'test'
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package com.bms.web.controller.ar;
|
package com.bms.web.controller.ar;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@ import com.bms.ar.domain.ArBillLog;
|
|||||||
import com.bms.ar.domain.vo.ArBillActionRequest;
|
import com.bms.ar.domain.vo.ArBillActionRequest;
|
||||||
import com.bms.ar.domain.vo.ArBillGenerateQuery;
|
import com.bms.ar.domain.vo.ArBillGenerateQuery;
|
||||||
import com.bms.ar.domain.vo.ArBillGenerateRequest;
|
import com.bms.ar.domain.vo.ArBillGenerateRequest;
|
||||||
|
import com.bms.ar.domain.vo.ArBillListExportRow;
|
||||||
import com.bms.ar.domain.vo.ArBillQuery;
|
import com.bms.ar.domain.vo.ArBillQuery;
|
||||||
import com.bms.ar.service.IArBillService;
|
import com.bms.ar.service.IArBillService;
|
||||||
import com.bms.common.annotation.Log;
|
import com.bms.common.annotation.Log;
|
||||||
@@ -40,6 +42,7 @@ import com.bms.common.core.page.TableDataInfo;
|
|||||||
import com.bms.common.exception.ServiceException;
|
import com.bms.common.exception.ServiceException;
|
||||||
import com.bms.common.enums.BusinessType;
|
import com.bms.common.enums.BusinessType;
|
||||||
import com.bms.common.utils.StringUtils;
|
import com.bms.common.utils.StringUtils;
|
||||||
|
import com.bms.common.utils.poi.ExcelUtil;
|
||||||
import com.bms.common.utils.uuid.IdUtils;
|
import com.bms.common.utils.uuid.IdUtils;
|
||||||
import com.bms.price.domain.PrcOrderBill;
|
import com.bms.price.domain.PrcOrderBill;
|
||||||
|
|
||||||
@@ -78,6 +81,23 @@ public class ArBillController extends BaseController {
|
|||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按当前筛选条件导出全部应收账单,不受列表分页参数影响。
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('ar:bill:export')")
|
||||||
|
@Log(title = "应收账单", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/export")
|
||||||
|
public void export(HttpServletResponse response, ArBillQuery query, HttpServletRequest request) {
|
||||||
|
rejectMultiValueParameter(request, "customerId");
|
||||||
|
List<ArBill> bills = billService.selectArBillList(query == null ? new ArBillQuery() : query);
|
||||||
|
List<ArBillListExportRow> rows = new ArrayList<>(bills.size());
|
||||||
|
for (ArBill bill : bills) {
|
||||||
|
rows.add(ArBillListExportRow.from(bill));
|
||||||
|
}
|
||||||
|
ExcelUtil<ArBillListExportRow> util = new ExcelUtil<>(ArBillListExportRow.class);
|
||||||
|
util.exportExcel(response, rows, "应收账单");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询账单头信息;账单明细通过独立分页接口按需加载。
|
* 查询账单头信息;账单明细通过独立分页接口按需加载。
|
||||||
*/
|
*/
|
||||||
|
|||||||
+41
-3
@@ -1,7 +1,9 @@
|
|||||||
package com.bms.web.controller.customer.customermoney;
|
package com.bms.web.controller.customer.customermoney;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@@ -13,7 +15,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.bms.ar.domain.ArBill;
|
import com.bms.ar.domain.ArBill;
|
||||||
import com.bms.ar.domain.ArBalanceWriteoff;
|
import com.bms.ar.domain.ArBalanceWriteoff;
|
||||||
|
import com.bms.ar.domain.vo.ArBillListExportRow;
|
||||||
import com.bms.ar.domain.vo.ArBillQuery;
|
import com.bms.ar.domain.vo.ArBillQuery;
|
||||||
|
import com.bms.ar.domain.vo.ArBillSummary;
|
||||||
import com.bms.ar.service.IArBalanceWriteoffService;
|
import com.bms.ar.service.IArBalanceWriteoffService;
|
||||||
import com.bms.ar.service.IArBillService;
|
import com.bms.ar.service.IArBillService;
|
||||||
import com.bms.common.annotation.Log;
|
import com.bms.common.annotation.Log;
|
||||||
@@ -21,6 +25,7 @@ import com.bms.common.core.controller.BaseController;
|
|||||||
import com.bms.common.core.domain.AjaxResult;
|
import com.bms.common.core.domain.AjaxResult;
|
||||||
import com.bms.common.core.page.TableDataInfo;
|
import com.bms.common.core.page.TableDataInfo;
|
||||||
import com.bms.common.enums.BusinessType;
|
import com.bms.common.enums.BusinessType;
|
||||||
|
import com.bms.common.utils.poi.ExcelUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 客户余额账单查询与核销 Controller
|
* 客户余额账单查询与核销 Controller
|
||||||
@@ -43,17 +48,50 @@ public class CustomerBillController extends BaseController
|
|||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:list')")
|
||||||
@GetMapping("/list/{customerId}")
|
@GetMapping("/list/{customerId}")
|
||||||
public TableDataInfo billList(@PathVariable("customerId") Long customerId, ArBillQuery query)
|
public AjaxResult billList(@PathVariable("customerId") Long customerId, ArBillQuery query)
|
||||||
{
|
{
|
||||||
if (customerId == null || customerId <= 0L)
|
if (customerId == null || customerId <= 0L)
|
||||||
{
|
{
|
||||||
return getDataTable(Collections.emptyList());
|
AjaxResult result = success();
|
||||||
|
result.put("rows", Collections.emptyList());
|
||||||
|
result.put("total", 0L);
|
||||||
|
result.put("summary", new ArBillSummary());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
ArBillQuery billQuery = query == null ? new ArBillQuery() : query;
|
ArBillQuery billQuery = query == null ? new ArBillQuery() : query;
|
||||||
billQuery.setCustomerId(customerId);
|
billQuery.setCustomerId(customerId);
|
||||||
startPage();
|
startPage();
|
||||||
List<ArBill> list = billService.selectArBillList(billQuery);
|
List<ArBill> list = billService.selectArBillList(billQuery);
|
||||||
return getDataTable(list);
|
TableDataInfo pageData = getDataTable(list);
|
||||||
|
AjaxResult result = success();
|
||||||
|
result.put("rows", pageData.getRows());
|
||||||
|
result.put("total", pageData.getTotal());
|
||||||
|
result.put("summary", billService.selectArBillSummary(billQuery));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按当前筛选条件导出指定客户的全部应收账单,不受列表分页参数影响。
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('customersupplier:customerinfo:export')")
|
||||||
|
@Log(title = "客户账单", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/export/{customerId}")
|
||||||
|
public void export(HttpServletResponse response, @PathVariable("customerId") Long customerId, ArBillQuery query)
|
||||||
|
{
|
||||||
|
List<ArBillListExportRow> rows = new ArrayList<>();
|
||||||
|
if (customerId != null && customerId > 0L)
|
||||||
|
{
|
||||||
|
ArBillQuery billQuery = query == null ? new ArBillQuery() : query;
|
||||||
|
// 客户ID固定取自路径,忽略请求参数中可能出现的 customerId。
|
||||||
|
billQuery.setCustomerId(customerId);
|
||||||
|
List<ArBill> bills = billService.selectArBillList(billQuery);
|
||||||
|
for (ArBill bill : bills)
|
||||||
|
{
|
||||||
|
rows.add(ArBillListExportRow.from(bill));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExcelUtil<ArBillListExportRow> util = new ExcelUtil<>(ArBillListExportRow.class);
|
||||||
|
util.exportExcel(response, rows, "客户账单");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package com.bms.ar.domain.vo;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import com.bms.ar.domain.ArBill;
|
||||||
|
import com.bms.ar.enums.ArBillStatus;
|
||||||
|
import com.bms.common.annotation.Excel;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/** 应收账单列表 Excel 导出行。 */
|
||||||
|
@Data
|
||||||
|
public class ArBillListExportRow implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Excel(name = "账单号", sort = 0, width = 22)
|
||||||
|
private String billNo;
|
||||||
|
|
||||||
|
@Excel(name = "账单名称", sort = 1, width = 24)
|
||||||
|
private String billName;
|
||||||
|
|
||||||
|
@Excel(name = "客户名称", sort = 2, width = 24)
|
||||||
|
private String customerName;
|
||||||
|
|
||||||
|
@Excel(name = "客户编码", sort = 3, width = 16)
|
||||||
|
private String customerCode;
|
||||||
|
|
||||||
|
@Excel(name = "账单截止日", sort = 4, dateFormat = "yyyy-MM-dd", width = 16)
|
||||||
|
private Date billPeriodEnd;
|
||||||
|
|
||||||
|
@Excel(name = "订单数", sort = 5, width = 12)
|
||||||
|
private Integer orderCount;
|
||||||
|
|
||||||
|
@Excel(name = "应收总额", sort = 6, scale = 2, width = 16)
|
||||||
|
private BigDecimal totalAmount;
|
||||||
|
|
||||||
|
@Excel(name = "已核销", sort = 7, scale = 2, width = 16)
|
||||||
|
private BigDecimal writtenOffAmount;
|
||||||
|
|
||||||
|
@Excel(name = "未核销", sort = 8, scale = 2, width = 16)
|
||||||
|
private BigDecimal unwrittenAmount;
|
||||||
|
|
||||||
|
@Excel(name = "状态", sort = 9, width = 14)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Excel(name = "账单日期", sort = 10, dateFormat = "yyyy-MM-dd", width = 16)
|
||||||
|
private Date billDate;
|
||||||
|
|
||||||
|
public static ArBillListExportRow from(ArBill bill) {
|
||||||
|
ArBillListExportRow row = new ArBillListExportRow();
|
||||||
|
row.setBillNo(bill.getBillNo());
|
||||||
|
row.setBillName(bill.getBillName());
|
||||||
|
row.setCustomerName(bill.getCustomerName());
|
||||||
|
row.setCustomerCode(bill.getCustomerCode());
|
||||||
|
row.setBillPeriodEnd(bill.getBillPeriodEnd());
|
||||||
|
row.setOrderCount(bill.getOrderCount());
|
||||||
|
row.setTotalAmount(bill.getTotalAmount());
|
||||||
|
row.setWrittenOffAmount(bill.getWrittenOffAmount());
|
||||||
|
row.setUnwrittenAmount(bill.getUnwrittenAmount());
|
||||||
|
ArBillStatus billStatus = ArBillStatus.of(bill.getStatus());
|
||||||
|
row.setStatus(billStatus == null ? bill.getStatus() : billStatus.getLabel());
|
||||||
|
row.setBillDate(bill.getBillDate());
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.bms.ar.domain.vo;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/** 应收账单列表按筛选条件汇总的金额。 */
|
||||||
|
@Data
|
||||||
|
public class ArBillSummary implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private BigDecimal totalAmount = BigDecimal.ZERO;
|
||||||
|
private BigDecimal writtenOffAmount = BigDecimal.ZERO;
|
||||||
|
private BigDecimal unwrittenAmount = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
@@ -7,10 +7,13 @@ import java.util.List;
|
|||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import com.bms.ar.domain.ArBill;
|
import com.bms.ar.domain.ArBill;
|
||||||
import com.bms.ar.domain.vo.ArBillQuery;
|
import com.bms.ar.domain.vo.ArBillQuery;
|
||||||
|
import com.bms.ar.domain.vo.ArBillSummary;
|
||||||
|
|
||||||
public interface ArBillMapper {
|
public interface ArBillMapper {
|
||||||
List<ArBill> selectArBillList(ArBillQuery query);
|
List<ArBill> selectArBillList(ArBillQuery query);
|
||||||
|
|
||||||
|
ArBillSummary selectArBillSummary(ArBillQuery query);
|
||||||
|
|
||||||
ArBill selectArBillById(Long arBillId);
|
ArBill selectArBillById(Long arBillId);
|
||||||
|
|
||||||
ArBill selectArBillByBillNo(String billNo);
|
ArBill selectArBillByBillNo(String billNo);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import com.bms.ar.domain.vo.ArBillGenerateRequest;
|
|||||||
import com.bms.ar.domain.vo.ArBillGenerateQuery;
|
import com.bms.ar.domain.vo.ArBillGenerateQuery;
|
||||||
import com.bms.ar.domain.vo.ArBillActionRequest;
|
import com.bms.ar.domain.vo.ArBillActionRequest;
|
||||||
import com.bms.ar.domain.vo.ArBillQuery;
|
import com.bms.ar.domain.vo.ArBillQuery;
|
||||||
|
import com.bms.ar.domain.vo.ArBillSummary;
|
||||||
import com.bms.price.domain.PrcOrderBill;
|
import com.bms.price.domain.PrcOrderBill;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,6 +26,8 @@ public interface IArBillService
|
|||||||
{
|
{
|
||||||
List<ArBill> selectArBillList(ArBillQuery query);
|
List<ArBill> selectArBillList(ArBillQuery query);
|
||||||
|
|
||||||
|
ArBillSummary selectArBillSummary(ArBillQuery query);
|
||||||
|
|
||||||
ArBill selectArBillById(Long arBillId);
|
ArBill selectArBillById(Long arBillId);
|
||||||
|
|
||||||
List<ArBillDetail> selectArBillDetails(Long arBillId);
|
List<ArBillDetail> selectArBillDetails(Long arBillId);
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ import com.bms.ar.domain.vo.ArBillActionRequest;
|
|||||||
import com.bms.ar.domain.vo.ArBillGenerateQuery;
|
import com.bms.ar.domain.vo.ArBillGenerateQuery;
|
||||||
import com.bms.ar.domain.vo.ArBillGenerateRequest;
|
import com.bms.ar.domain.vo.ArBillGenerateRequest;
|
||||||
import com.bms.ar.domain.vo.ArBillQuery;
|
import com.bms.ar.domain.vo.ArBillQuery;
|
||||||
|
import com.bms.ar.domain.vo.ArBillSummary;
|
||||||
import com.bms.common.config.BmsConfig;
|
import com.bms.common.config.BmsConfig;
|
||||||
import com.bms.common.exception.ServiceException;
|
import com.bms.common.exception.ServiceException;
|
||||||
import com.bms.common.utils.DateUtils;
|
import com.bms.common.utils.DateUtils;
|
||||||
@@ -223,6 +224,14 @@ public class ArBillServiceImpl implements IArBillService {
|
|||||||
return bills;
|
return bills;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 汇总当前筛选条件下的全部账单金额,不受列表分页影响。
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ArBillSummary selectArBillSummary(ArBillQuery query) {
|
||||||
|
return billMapper.selectArBillSummary(query);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询账单头信息;导出记录随账单头返回,明细由独立分页接口查询。
|
* 查询账单头信息;导出记录随账单头返回,明细由独立分页接口查询。
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -35,6 +35,12 @@
|
|||||||
<result property="updateTime" column="update_time"/>
|
<result property="updateTime" column="update_time"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
|
<resultMap id="ArBillSummaryResult" type="com.bms.ar.domain.vo.ArBillSummary">
|
||||||
|
<result property="totalAmount" column="total_amount"/>
|
||||||
|
<result property="writtenOffAmount" column="written_off_amount"/>
|
||||||
|
<result property="unwrittenAmount" column="unwritten_amount"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectArBillColumns">
|
<sql id="selectArBillColumns">
|
||||||
select ar_bill_id,
|
select ar_bill_id,
|
||||||
bill_no,
|
bill_no,
|
||||||
@@ -67,8 +73,7 @@
|
|||||||
from ar_bill
|
from ar_bill
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectArBillList" parameterType="com.bms.ar.domain.vo.ArBillQuery" resultMap="ArBillResult">
|
<sql id="arBillListFilter">
|
||||||
<include refid="selectArBillColumns"/>
|
|
||||||
<where>
|
<where>
|
||||||
and (generation_status is null or generation_status = 'READY')
|
and (generation_status is null or generation_status = 'READY')
|
||||||
<if test="billNo != null and billNo != ''">and bill_no like concat('%', #{billNo}, '%')</if>
|
<if test="billNo != null and billNo != ''">and bill_no like concat('%', #{billNo}, '%')</if>
|
||||||
@@ -86,9 +91,22 @@
|
|||||||
<if test="billDateEnd != null">and bill_date <= #{billDateEnd}</if>
|
<if test="billDateEnd != null">and bill_date <= #{billDateEnd}</if>
|
||||||
<if test="billPeriodEnd != null">and bill_period_end = #{billPeriodEnd}</if>
|
<if test="billPeriodEnd != null">and bill_period_end = #{billPeriodEnd}</if>
|
||||||
</where>
|
</where>
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectArBillList" parameterType="com.bms.ar.domain.vo.ArBillQuery" resultMap="ArBillResult">
|
||||||
|
<include refid="selectArBillColumns"/>
|
||||||
|
<include refid="arBillListFilter"/>
|
||||||
order by create_time desc, ar_bill_id desc
|
order by create_time desc, ar_bill_id desc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectArBillSummary" parameterType="com.bms.ar.domain.vo.ArBillQuery" resultMap="ArBillSummaryResult">
|
||||||
|
select coalesce(sum(total_amount), 0) as total_amount,
|
||||||
|
coalesce(sum(written_off_amount), 0) as written_off_amount,
|
||||||
|
coalesce(sum(unwritten_amount), 0) as unwritten_amount
|
||||||
|
from ar_bill
|
||||||
|
<include refid="arBillListFilter"/>
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="selectArBillById" parameterType="long" resultMap="ArBillResult">
|
<select id="selectArBillById" parameterType="long" resultMap="ArBillResult">
|
||||||
<include refid="selectArBillColumns"/>
|
<include refid="selectArBillColumns"/>
|
||||||
where ar_bill_id = #{arBillId}
|
where ar_bill_id = #{arBillId}
|
||||||
|
|||||||
@@ -126,7 +126,9 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页;可选的分页前置内容用于展示汇总等信息。 -->
|
||||||
|
<div class="basic-table-pagination" :class="{ 'basic-table-pagination--with-extra': $slots['pagination-extra'] }">
|
||||||
|
<slot name="pagination-extra" />
|
||||||
<pagination
|
<pagination
|
||||||
v-show="total > 0"
|
v-show="total > 0"
|
||||||
:total="total"
|
:total="total"
|
||||||
@@ -136,6 +138,7 @@
|
|||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -727,6 +730,16 @@ onBeforeUnmount(() => {
|
|||||||
.basic-table {
|
.basic-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
.basic-table-pagination--with-extra {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.basic-table-pagination--with-extra :deep(.pagination-container) {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
.basic-table-virtual {
|
.basic-table-virtual {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 240px;
|
min-height: 240px;
|
||||||
|
|||||||
@@ -32,6 +32,9 @@
|
|||||||
<el-col :span="1.5"><el-button type="primary" plain icon="Plus" v-hasPermi="['ar:bill:generate']" @click="generateOpen = true">生成账单</el-button></el-col>
|
<el-col :span="1.5"><el-button type="primary" plain icon="Plus" v-hasPermi="['ar:bill:generate']" @click="generateOpen = true">生成账单</el-button></el-col>
|
||||||
<el-col v-if="customerScoped" :span="1.5"><el-button type="info" plain icon="Close" @click="clearCustomerFilter">清除客户条件</el-button></el-col>
|
<el-col v-if="customerScoped" :span="1.5"><el-button type="info" plain icon="Close" @click="clearCustomerFilter">清除客户条件</el-button></el-col>
|
||||||
</template>
|
</template>
|
||||||
|
<template #search-extra>
|
||||||
|
<el-button type="warning" plain icon="Download" v-hasPermi="['ar:bill:export']" @click="handleExport">导出</el-button>
|
||||||
|
</template>
|
||||||
<template #search-customerId="{ model }">
|
<template #search-customerId="{ model }">
|
||||||
<customer-select v-model="model.customerId" placeholder="请输入客户名称或代码搜索" :remote-search="true" :page-size="20" />
|
<customer-select v-model="model.customerId" placeholder="请输入客户名称或代码搜索" :remote-search="true" :page-size="20" />
|
||||||
</template>
|
</template>
|
||||||
@@ -45,6 +48,7 @@
|
|||||||
<el-button v-if="row.status === AR_BILL_STATUS.DRAFT || row.status === AR_BILL_STATUS.CONFIRMED" link type="warning" v-hasPermi="['ar:bill:void']" @click="voidBill(row)">作废</el-button>
|
<el-button v-if="row.status === AR_BILL_STATUS.DRAFT || row.status === AR_BILL_STATUS.CONFIRMED" link type="warning" v-hasPermi="['ar:bill:void']" @click="voidBill(row)">作废</el-button>
|
||||||
<el-button v-if="row.status !== AR_BILL_STATUS.DRAFT && row.status !== AR_BILL_STATUS.VOID" link type="primary" v-hasPermi="['ar:bill:export']" @click="exportBill(row)">导出明细</el-button>
|
<el-button v-if="row.status !== AR_BILL_STATUS.DRAFT && row.status !== AR_BILL_STATUS.VOID" link type="primary" v-hasPermi="['ar:bill:export']" @click="exportBill(row)">导出明细</el-button>
|
||||||
<el-button v-if="canGoWriteoff(row)" link type="primary" v-hasPermi="['customer:bill:writeoff']" @click="goWriteoff(row)">去核销</el-button>
|
<el-button v-if="canGoWriteoff(row)" link type="primary" v-hasPermi="['customer:bill:writeoff']" @click="goWriteoff(row)">去核销</el-button>
|
||||||
|
<el-button v-if="canGoReverseWriteoff(row)" link type="warning" v-hasPermi="['customer:bill:writeoff:cancel']" @click="goReverseWriteoff(row)">反核销</el-button>
|
||||||
</template>
|
</template>
|
||||||
</basic-table>
|
</basic-table>
|
||||||
|
|
||||||
@@ -150,7 +154,7 @@ const columns = [
|
|||||||
{ label: '账单截止日', prop: 'billPeriodEnd', minWidth: 120, formatter: row => `截至 ${date(row.billPeriodEnd)}` }, { label: '订单数', prop: 'orderCount', width: 80 },
|
{ label: '账单截止日', prop: 'billPeriodEnd', minWidth: 120, formatter: row => `截至 ${date(row.billPeriodEnd)}` }, { label: '订单数', prop: 'orderCount', width: 80 },
|
||||||
{ label: '应收总额', prop: 'totalAmount', width: 120, align: 'right', slot: 'totalAmount' }, { label: '已核销', prop: 'writtenOffAmount', width: 110, align: 'right', slot: 'writtenOffAmount' },
|
{ label: '应收总额', prop: 'totalAmount', width: 120, align: 'right', slot: 'totalAmount' }, { label: '已核销', prop: 'writtenOffAmount', width: 110, align: 'right', slot: 'writtenOffAmount' },
|
||||||
{ label: '未核销', prop: 'unwrittenAmount', width: 110, align: 'right', slot: 'unwrittenAmount' }, { label: '状态', prop: 'status', width: 110, slot: 'status' },
|
{ label: '未核销', prop: 'unwrittenAmount', width: 110, align: 'right', slot: 'unwrittenAmount' }, { label: '状态', prop: 'status', width: 110, slot: 'status' },
|
||||||
{ label: '账单日期', prop: 'billDate', width: 120, formatter: row => date(row.billDate) }, { label: '操作', prop: 'action', width: 330, fixed: 'right', slot: 'action', showInToolbar: false }
|
{ label: '账单日期', prop: 'billDate', width: 120, formatter: row => date(row.billDate) }, { label: '操作', prop: 'action', width: 380, fixed: 'right', slot: 'action', showInToolbar: false }
|
||||||
]
|
]
|
||||||
const searchColumns = [
|
const searchColumns = [
|
||||||
{ label: '账单号', prop: 'billNo', component: 'input', placeholder: '账单号', width: '180px' }, { label: '账单名称', prop: 'billName', component: 'input', placeholder: '账单名称', width: '180px' }, { label: '客户名称', prop: 'customerId', component: 'input', placeholder: '请选择客户', width: '220px' },
|
{ label: '账单号', prop: 'billNo', component: 'input', placeholder: '账单号', width: '180px' }, { label: '账单名称', prop: 'billName', component: 'input', placeholder: '账单名称', width: '180px' }, { label: '客户名称', prop: 'customerId', component: 'input', placeholder: '请选择客户', width: '220px' },
|
||||||
@@ -158,7 +162,22 @@ const searchColumns = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
// 将页面日期范围转换为后端查询字段,其他筛选条件原样透传。
|
// 将页面日期范围转换为后端查询字段,其他筛选条件原样透传。
|
||||||
function queryList(params) { const query = { ...params }; if (query.billDateRange?.length === 2) { query.billDateStart = query.billDateRange[0]; query.billDateEnd = query.billDateRange[1] }; delete query.billDateRange; return listArBill(query) }
|
function normalizeBillQuery(params) {
|
||||||
|
const query = { ...params }
|
||||||
|
if (query.billDateRange?.length === 2) {
|
||||||
|
query.billDateStart = query.billDateRange[0]
|
||||||
|
query.billDateEnd = query.billDateRange[1]
|
||||||
|
}
|
||||||
|
delete query.billDateRange
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
function queryList(params) { return listArBill(normalizeBillQuery(params)) }
|
||||||
|
function handleExport() {
|
||||||
|
const query = normalizeBillQuery(tableRef.value?.getQueryParams() || defaultSearchParams.value)
|
||||||
|
delete query.pageNum
|
||||||
|
delete query.pageSize
|
||||||
|
proxy.download('/ar/bill/export', query, `ar_bill_${Date.now()}.xlsx`)
|
||||||
|
}
|
||||||
// 生成弹窗只提交任务,账单明细由后台异步批量写入;这里负责刷新列表并开始轮询。
|
// 生成弹窗只提交任务,账单明细由后台异步批量写入;这里负责刷新列表并开始轮询。
|
||||||
function handleGenerateSuccess(task) {
|
function handleGenerateSuccess(task) {
|
||||||
tableRef.value?.refresh()
|
tableRef.value?.refresh()
|
||||||
@@ -392,8 +411,20 @@ function canGoWriteoff(row) {
|
|||||||
|| row.status === AR_BILL_STATUS.PARTIAL_WRITTEN_OFF
|
|| row.status === AR_BILL_STATUS.PARTIAL_WRITTEN_OFF
|
||||||
return canWriteoffStatus && Number(row.unwrittenAmount) > 0
|
return canWriteoffStatus && Number(row.unwrittenAmount) > 0
|
||||||
}
|
}
|
||||||
|
function canGoReverseWriteoff(row) {
|
||||||
|
if (!row?.customerId || !(Number(row.writtenOffAmount) > 0)) return false
|
||||||
|
return row.status === AR_BILL_STATUS.PARTIAL_WRITTEN_OFF
|
||||||
|
|| row.status === AR_BILL_STATUS.WRITTEN_OFF
|
||||||
|
}
|
||||||
function goWriteoff(row) {
|
function goWriteoff(row) {
|
||||||
if (!canGoWriteoff(row)) return
|
if (!canGoWriteoff(row)) return
|
||||||
|
goCustomerBillWriteoff(row)
|
||||||
|
}
|
||||||
|
function goReverseWriteoff(row) {
|
||||||
|
if (!canGoReverseWriteoff(row)) return
|
||||||
|
goCustomerBillWriteoff(row)
|
||||||
|
}
|
||||||
|
function goCustomerBillWriteoff(row) {
|
||||||
router.push({
|
router.push({
|
||||||
path: '/customersupplier/customer-money/index',
|
path: '/customersupplier/customer-money/index',
|
||||||
query: {
|
query: {
|
||||||
|
|||||||
+52
-2
@@ -16,8 +16,24 @@
|
|||||||
:border="true"
|
:border="true"
|
||||||
:max-height="560"
|
:max-height="560"
|
||||||
:page-size="10"
|
:page-size="10"
|
||||||
|
ref="tableRef"
|
||||||
row-key="arBillId"
|
row-key="arBillId"
|
||||||
>
|
>
|
||||||
|
<template #search-extra>
|
||||||
|
<el-button
|
||||||
|
type="warning"
|
||||||
|
icon="Download"
|
||||||
|
@click="handleExport"
|
||||||
|
v-hasPermi="['customersupplier:customerinfo:export']"
|
||||||
|
>导出</el-button>
|
||||||
|
</template>
|
||||||
|
<template #pagination-extra>
|
||||||
|
<div class="bill-summary">
|
||||||
|
<span>应收总额:<b class="amount">{{ money(billSummary.totalAmount) }}</b></span>
|
||||||
|
<span>已核销:<b class="written">{{ money(billSummary.writtenOffAmount) }}</b></span>
|
||||||
|
<span>未核销:<b class="unwritten">{{ money(billSummary.unwrittenAmount) }}</b></span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template #col-status="{ row }">
|
<template #col-status="{ row }">
|
||||||
<el-tag :type="statusType(row.status)">{{ statusText(row.status) }}</el-tag>
|
<el-tag :type="statusType(row.status)">{{ statusText(row.status) }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
@@ -38,7 +54,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from 'vue'
|
import { computed, getCurrentInstance, ref } from 'vue'
|
||||||
import { listCustomerBills } from '@/api/customersuppliermanagement/customermoney/customerbill'
|
import { listCustomerBills } from '@/api/customersuppliermanagement/customermoney/customerbill'
|
||||||
import { AR_BILL_STATUS_OPTIONS, AR_BILL_STATUS_TYPES } from '@/constants/ar/bill'
|
import { AR_BILL_STATUS_OPTIONS, AR_BILL_STATUS_TYPES } from '@/constants/ar/bill'
|
||||||
import { arEnumLabel } from '@/constants/ar/enums'
|
import { arEnumLabel } from '@/constants/ar/enums'
|
||||||
@@ -48,6 +64,7 @@ const props = defineProps({
|
|||||||
customerId: { type: [String, Number], required: true },
|
customerId: { type: [String, Number], required: true },
|
||||||
customerName: { type: String, default: '' }
|
customerName: { type: String, default: '' }
|
||||||
})
|
})
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const visible = computed({
|
const visible = computed({
|
||||||
@@ -58,6 +75,9 @@ const dialogTitle = computed(() => props.customerName ? `客户账单 - ${props.
|
|||||||
|
|
||||||
// BasicTable merges these fixed parameters after search and pagination state.
|
// BasicTable merges these fixed parameters after search and pagination state.
|
||||||
const fixedParams = computed(() => ({ customerId: Number(props.customerId) }))
|
const fixedParams = computed(() => ({ customerId: Number(props.customerId) }))
|
||||||
|
const tableRef = ref()
|
||||||
|
const billSummary = ref({ totalAmount: 0, writtenOffAmount: 0, unwrittenAmount: 0 })
|
||||||
|
let querySerial = 0
|
||||||
const statusOptions = AR_BILL_STATUS_OPTIONS
|
const statusOptions = AR_BILL_STATUS_OPTIONS
|
||||||
const columns = [
|
const columns = [
|
||||||
{ label: '账单号', prop: 'billNo', minWidth: 180, showOverflowTooltip: true },
|
{ label: '账单号', prop: 'billNo', minWidth: 180, showOverflowTooltip: true },
|
||||||
@@ -81,6 +101,28 @@ const searchColumns = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
function queryBills(params) {
|
function queryBills(params) {
|
||||||
|
const query = normalizeBillQuery(params)
|
||||||
|
const serial = ++querySerial
|
||||||
|
return listCustomerBills(props.customerId, query).then(response => {
|
||||||
|
if (serial === querySerial) {
|
||||||
|
billSummary.value = response.summary || { totalAmount: 0, writtenOffAmount: 0, unwrittenAmount: 0 }
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleExport() {
|
||||||
|
const query = normalizeBillQuery(tableRef.value?.getQueryParams() || {})
|
||||||
|
delete query.pageNum
|
||||||
|
delete query.pageSize
|
||||||
|
proxy.download(
|
||||||
|
`/customersupplier/customerbill/export/${props.customerId}`,
|
||||||
|
query,
|
||||||
|
`客户账单_${props.customerId}_${Date.now()}.xlsx`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeBillQuery(params) {
|
||||||
const query = { ...params }
|
const query = { ...params }
|
||||||
const range = query.billDateRange
|
const range = query.billDateRange
|
||||||
if (Array.isArray(range) && range.length === 2) {
|
if (Array.isArray(range) && range.length === 2) {
|
||||||
@@ -90,7 +132,7 @@ function queryBills(params) {
|
|||||||
delete query.billDateRange
|
delete query.billDateRange
|
||||||
// The route parameter is authoritative; the customer ID cannot be changed by search/reset.
|
// The route parameter is authoritative; the customer ID cannot be changed by search/reset.
|
||||||
delete query.customerId
|
delete query.customerId
|
||||||
return listCustomerBills(props.customerId, query)
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
function date(value) { return value ? String(value).slice(0, 10) : '-' }
|
function date(value) { return value ? String(value).slice(0, 10) : '-' }
|
||||||
@@ -103,6 +145,14 @@ function statusType(value) { return AR_BILL_STATUS_TYPES[value] || 'info' }
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.bill-summary {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px 20px;
|
||||||
|
color: var(--el-text-color-regular);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.bill-summary b { font-weight: 600; }
|
||||||
.amount { color: #f56c6c; font-weight: 600; }
|
.amount { color: #f56c6c; font-weight: 600; }
|
||||||
.written { color: var(--el-color-success); }
|
.written { color: var(--el-color-success); }
|
||||||
.unwritten { color: var(--el-color-warning); }
|
.unwritten { color: var(--el-color-warning); }
|
||||||
|
|||||||
Reference in New Issue
Block a user