应付账单初始化

This commit is contained in:
caojia
2026-11-04 16:04:38 +08:00
committed by liuminghui
parent 04be15deab
commit 51a89b18e1
90 changed files with 15661 additions and 6 deletions
@@ -0,0 +1,94 @@
package com.bms.web.controller.data;
import java.util.List;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.bms.common.annotation.Log;
import com.bms.common.core.controller.BaseController;
import com.bms.common.core.domain.AjaxResult;
import com.bms.common.core.page.TableDataInfo;
import com.bms.common.enums.BusinessType;
import com.bms.common.exception.ServiceException;
import com.bms.price.domain.PayPostcodeGroup;
import com.bms.price.domain.PayPostcodeLine;
import com.bms.price.service.IPayPostcodeService;
/**
* 数据管理下的应付邮编配置。Excel 导入后按国家和附加费金额合并。
*/
@RestController
@RequestMapping("/data/payPostcode")
public class PayPostcodeController extends BaseController
{
@Autowired
private IPayPostcodeService payPostcodeService;
@PreAuthorize("@ss.hasPermi('data:payPostcode:list')")
@GetMapping("/list")
public TableDataInfo list(PayPostcodeGroup query)
{
startPage();
List<PayPostcodeGroup> list = payPostcodeService.selectGroupList(query);
return getDataTable(list);
}
@PreAuthorize("@ss.hasPermi('data:payPostcode:query')")
@GetMapping("/{groupId}")
public AjaxResult getInfo(@PathVariable Long groupId)
{
return success(payPostcodeService.selectGroupById(groupId));
}
@PreAuthorize("@ss.hasPermi('data:payPostcode:edit')")
@Log(title = "应付邮编配置", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody PayPostcodeGroup group)
{
return toAjax(payPostcodeService.updateGroup(group));
}
@PreAuthorize("@ss.hasPermi('data:payPostcode:query')")
@GetMapping("/line")
public TableDataInfo lines(PayPostcodeLine query)
{
startPage();
List<PayPostcodeLine> list = payPostcodeService.selectLineList(query);
return getDataTable(list);
}
@PreAuthorize("@ss.hasPermi('data:payPostcode:import')")
@Log(title = "应付邮编配置", businessType = BusinessType.IMPORT)
@PostMapping(value = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public AjaxResult importExcel(MultipartFile file) throws Exception
{
if (file == null || file.isEmpty())
{
throw new ServiceException("请选择 Excel 文件");
}
String name = file.getOriginalFilename() == null ? "" : file.getOriginalFilename().toLowerCase(Locale.ROOT);
if (!name.endsWith(".xlsx"))
{
throw new ServiceException("只支持 xlsx 文件");
}
return success(payPostcodeService.importExcel(file.getBytes(), file.getOriginalFilename(), getUsername()));
}
@PreAuthorize("@ss.hasPermi('data:payPostcode:remove')")
@Log(title = "应付邮编配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{groupIds}")
public AjaxResult remove(@PathVariable Long[] groupIds)
{
return toAjax(payPostcodeService.deleteByIds(groupIds));
}
}
@@ -0,0 +1,83 @@
package com.bms.web.controller.price;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.bms.common.core.controller.BaseController;
import com.bms.common.core.domain.AjaxResult;
import com.bms.common.core.page.TableDataInfo;
import com.bms.price.domain.PayBill;
import com.bms.price.domain.PayBillCommand;
import com.bms.price.service.IPayBillService;
/**
* 账单管理下的应付账单。
*/
@RestController
@RequestMapping("/price/payBill")
public class PayBillController extends BaseController
{
@Autowired
private IPayBillService payBillService;
@PreAuthorize("@ss.hasPermi('price:payBill:list')")
@GetMapping("/list")
public TableDataInfo list(PayBill query)
{
startPage();
List<PayBill> list = payBillService.selectPayBillList(query);
return getDataTable(list);
}
@PreAuthorize("@ss.hasPermi('price:payBill:query')")
@GetMapping("/{billId}")
public AjaxResult detail(@PathVariable Long billId)
{
return success(payBillService.selectPayBillDetail(billId));
}
@PreAuthorize("@ss.hasPermi('price:payBill:query')")
@PostMapping("/preview")
public AjaxResult preview(@RequestBody PayBillCommand command)
{
return success(payBillService.preview(command));
}
@PreAuthorize("@ss.hasPermi('price:payBill:add')")
@PostMapping
public AjaxResult generate(@RequestBody PayBillCommand command)
{
return success(payBillService.generate(command));
}
@PreAuthorize("@ss.hasPermi('price:payBill:confirm')")
@PutMapping("/confirm/{billId}")
public AjaxResult confirm(@PathVariable Long billId)
{
payBillService.confirm(billId);
return success();
}
@PreAuthorize("@ss.hasPermi('price:payBill:confirm')")
@PutMapping("/paid/{billId}")
public AjaxResult paid(@PathVariable Long billId)
{
payBillService.markPaid(billId);
return success();
}
@PreAuthorize("@ss.hasPermi('price:payBill:void')")
@PutMapping("/void")
public AjaxResult voidBill(@RequestBody PayBillCommand command)
{
payBillService.voidBill(command);
return success();
}
}
@@ -0,0 +1,227 @@
package com.bms.web.controller.price;
import java.util.List;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.bms.common.annotation.Log;
import com.bms.common.core.controller.BaseController;
import com.bms.common.core.domain.AjaxResult;
import com.bms.common.core.page.TableDataInfo;
import com.bms.common.enums.BusinessType;
import com.bms.common.exception.ServiceException;
import com.bms.common.utils.poi.ExcelUtil;
import com.bms.price.domain.ChannelProductMap;
import com.bms.price.domain.PayProduct;
import com.bms.price.domain.PayProductTerm;
import com.bms.price.domain.PaySaveCommand;
import com.bms.price.pay.PayDetailExporter;
import com.bms.price.service.IPayOrderCostService;
import com.bms.price.service.IPayProductService;
import jakarta.servlet.http.HttpServletResponse;
/**
* 价格基础下的应付配置。导入先预览,确认后才入库。
*/
@RestController
@RequestMapping("/price/pay")
public class PayProductController extends BaseController
{
@Autowired
private IPayProductService payProductService;
@Autowired
private IPayOrderCostService payOrderCostService;
@PreAuthorize("@ss.hasPermi('price:pay:list')")
@GetMapping("/list")
public TableDataInfo list(PayProduct query)
{
startPage();
List<PayProduct> list = payProductService.selectPayProductList(query);
return getDataTable(list);
}
/** 一个产品的价格版本和有效期 */
@PreAuthorize("@ss.hasAnyPermi('price:pay:query,price:pay:edit')")
@GetMapping("/term/list")
public AjaxResult termList(@RequestParam Long productId)
{
return success(payProductService.listTerms(productId));
}
@PreAuthorize("@ss.hasPermi('price:pay:edit')")
@Log(title = "应付有效期", businessType = BusinessType.UPDATE)
@PutMapping("/term")
public AjaxResult updateTerm(@RequestBody PayProductTerm term)
{
return toAjax(payProductService.updateTerm(term));
}
@PreAuthorize("@ss.hasPermi('price:pay:edit')")
@Log(title = "应付有效期", businessType = BusinessType.UPDATE)
@PutMapping("/term/status")
public AjaxResult changeTermStatus(@RequestBody PayProductTerm term)
{
return toAjax(payProductService.changeTermStatus(term));
}
/** 按订单的渠道服务商和应付产品生成应付账单 */
@PreAuthorize("@ss.hasAnyPermi('price:billing:bill,price:pay:edit')")
@Log(title = "应付账单", businessType = BusinessType.INSERT)
@PostMapping("/order/{billId}")
public AjaxResult generateOrderCost(@PathVariable String billId)
{
return success(payOrderCostService.generate(billId));
}
@PreAuthorize("@ss.hasPermi('price:pay:query')")
@GetMapping("/{productId}")
public AjaxResult getInfo(@PathVariable Long productId)
{
return success(payProductService.selectPayProductDetail(productId));
}
/** 下拉:已导入的公共模板,供渠道页选择。payType 为空时按应付 AP */
@PreAuthorize("@ss.hasAnyPermi('price:pay:query,data:serviceChannel:list,data:serviceChannel:edit')")
@GetMapping("/options")
public AjaxResult options(@RequestParam(value = "payType", required = false) String payType)
{
return success(payProductService.selectTemplateOptions(payType));
}
/** 渠道当前价格副本 */
@PreAuthorize("@ss.hasAnyPermi('price:pay:query,data:serviceChannel:query,data:serviceChannel:edit')")
@GetMapping("/channel/{channelId}")
public AjaxResult channelPrice(@PathVariable String channelId)
{
return success(payProductService.selectChannelPrice(channelId));
}
/** 渠道只绑定产品编号,以后按有效期取价 */
@PreAuthorize("@ss.hasAnyPermi('price:pay:edit,data:serviceChannel:edit')")
@Log(title = "渠道应付产品", businessType = BusinessType.UPDATE)
@PutMapping("/channel/{channelId}/bind")
public AjaxResult bindChannel(@PathVariable String channelId, @RequestBody ChannelProductMap link)
{
String payType = link == null ? null : link.getPayType();
if (link == null || link.getProductId() == null)
{
payProductService.unbindChannel(channelId, payType);
return success();
}
payProductService.bindChannel(channelId, link.getProductId(), link.getPriceSetId(), payType);
return success(payProductService.selectChannelPrice(channelId));
}
/** 对照两个价格版本 */
@PreAuthorize("@ss.hasPermi('price:pay:query')")
@GetMapping("/compare")
public AjaxResult compare(@RequestParam Long leftId, @RequestParam Long rightId)
{
return success(payProductService.compare(leftId, rightId));
}
/** 给已绑定的产品追加一版,产品编号不变 */
@PreAuthorize("@ss.hasAnyPermi('price:pay:import,data:serviceChannel:edit')")
@Log(title = "渠道应付价格", businessType = BusinessType.INSERT)
@PostMapping("/channel/{channelId}")
public AjaxResult saveChannel(@PathVariable String channelId, @RequestBody PayProduct product)
{
return success(payProductService.saveChannelVersion(channelId, product));
}
/** 重新导入渠道价格,生成新版本,不改模板 */
@PreAuthorize("@ss.hasAnyPermi('price:pay:import,data:serviceChannel:edit')")
@Log(title = "渠道应付价格", businessType = BusinessType.IMPORT)
@PostMapping(value = "/channel/{channelId}/reimport", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public AjaxResult reimportChannel(@PathVariable String channelId, MultipartFile file) throws Exception
{
assertWorkbook(file);
return success(payProductService.reimportChannel(channelId, file.getBytes(), file.getOriginalFilename()));
}
/** 按字典匹配工作表。dictValue 为空时读取文件里所有能对上的表 */
@PreAuthorize("@ss.hasPermi('price:pay:import')")
@Log(title = "应付配置", businessType = BusinessType.IMPORT)
@PostMapping(value = "/preview", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public AjaxResult preview(MultipartFile file, @RequestParam(value = "dictValue", required = false) String dictValue) throws Exception
{
assertWorkbook(file);
return success(payProductService.preview(file.getBytes(), file.getOriginalFilename(), dictValue));
}
/** 修改已导入的公共模板 */
@PreAuthorize("@ss.hasPermi('price:pay:import')")
@Log(title = "应付配置", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody PayProduct product)
{
return toAjax(payProductService.updateDetail(product));
}
/** 保存预览中勾选的产品 */
@PreAuthorize("@ss.hasPermi('price:pay:import')")
@Log(title = "应付配置", businessType = BusinessType.INSERT)
@PostMapping("/save")
public AjaxResult save(@RequestBody PaySaveCommand command)
{
return success(payProductService.save(command));
}
@PreAuthorize("@ss.hasPermi('price:pay:remove')")
@Log(title = "应付配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{productIds}")
public AjaxResult remove(@PathVariable Long[] productIds)
{
return toAjax(payProductService.deletePayProducts(productIds));
}
@PreAuthorize("@ss.hasPermi('price:pay:export')")
@Log(title = "应付配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, PayProduct query)
{
List<PayProduct> list = payProductService.selectPayProductList(query);
new ExcelUtil<>(PayProduct.class).exportExcel(response, list, "应付产品");
}
/** 按当前搜索条件导出产品、重量段、附加费和其他配置 */
@PreAuthorize("@ss.hasPermi('price:pay:export')")
@Log(title = "应付配置明细", businessType = BusinessType.EXPORT)
@PostMapping("/exportDetail")
public void exportDetail(HttpServletResponse response, PayProduct query) throws Exception
{
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
PayDetailExporter.write(response.getOutputStream(), payProductService.selectPayProductDetails(query));
}
private void assertWorkbook(MultipartFile file)
{
if (file == null || file.isEmpty())
{
throw new ServiceException("请选择价卡文件");
}
String filename = file.getOriginalFilename();
if (filename == null || !filename.toLowerCase(Locale.ROOT).endsWith(".xlsx"))
{
throw new ServiceException("请上传xlsx价卡");
}
if (file.getSize() > 30L * 1024 * 1024)
{
throw new ServiceException("价卡文件不能超过30MB");
}
}
}