Parcourir la source

发票清单下载、发票明细

zuypeng il y a 2 ans
Parent
commit
0d8078c7ad

+ 142 - 92
admin-web/src/views/admin/invoice/dialog.vue

@@ -6,7 +6,7 @@
     <el-dialog
         :title="state.dialog.title"
         v-model="state.dialog.isShowDialog"
-        width="820px"
+        width="920px"
         draggable
         destroy-on-close
         :close-on-click-modal="false"
@@ -20,14 +20,14 @@
           size="default"
           label-width="125px"
           class="mt5">
-        <el-form-item label="微信发票申请id" prop="applyId">
+<!--        <el-form-item label="微信发票申请id" prop="applyId">
           <el-input
               v-model.trim="state.ruleForm.applyId"
               placeholder="微信发票申请号"
               readonly
               class="wd200">
           </el-input>
-        </el-form-item>
+        </el-form-item>-->
         <el-form-item label="开票日期" prop="fapiaoTime">
           <el-input
               v-model.trim="state.ruleForm.fapiaoTime"
@@ -35,6 +35,17 @@
               class="wd200">
           </el-input>
         </el-form-item>
+        <el-form-item label="发票状态" prop="status">
+          <ext-d-label    class="wd200" type="Invoice.status" :model-value="state.ruleForm.status"> </ext-d-label>
+        </el-form-item>
+        <el-form-item label="开票人" prop="biller">
+          <el-input
+              v-model.trim="state.ruleForm.sellerInformation.name"
+              placeholder="开票人"
+              readonly
+              class="wd200">
+          </el-input>
+        </el-form-item>
 <!--        <el-form-item label="用户id" prop="userId">
           <el-input
               v-model.trim="state.ruleForm.userId"
@@ -53,7 +64,7 @@
         </el-form-item>
         <el-form-item label="累积总金额(元)" prop="totalMoney">
           <el-input
-              :model-value="u.fmt.fmtMoney(state.detail.totalMoney)"
+              :model-value="u.fmt.fmtMoney(state.ruleForm.totalMoney)"
               placeholder="累积总金额(元)"
               readonly
               class="wd200">
@@ -83,92 +94,131 @@
               class="wd200">
           </el-input>
         </el-form-item>
-        <el-form-item label="接收发票邮箱" prop="email">
-          <el-input
-              v-model.trim="state.ruleForm.email"
-              placeholder="接收发票邮箱"
-              readonly
-              class="wd200">
-          </el-input>
-        </el-form-item>
-        <el-form-item label="电话" prop="phone">
-          <el-input
-              v-model.trim="state.ruleForm.phone"
-              placeholder="电话"
-              readonly
-              class="wd200">
-          </el-input>
-        </el-form-item>
-        <el-form-item label="发票类型" prop="invoiceType">
-          <ext-d-label   class="wd200"  type="Invoice.type" :model-value="state.ruleForm.buyerInformation.type"></ext-d-label>
-        </el-form-item>
-        <el-form-item label="发票抬头名称" prop="invoiceTitle">
-          <el-input
-              v-model.trim="state.ruleForm.buyerInformation.name"
-              placeholder="发票抬头名称"
-              readonly
-              class="wd200">
-          </el-input>
-        </el-form-item>
-        <el-form-item label="公司税号" prop="taxId">
-          <el-input
-              v-model.trim="state.ruleForm.buyerInformation.taxpayer_id"
-              placeholder="公司税号"
-              readonly
-              class="wd200">
-          </el-input>
-        </el-form-item>
-        <el-form-item label="公司地址" prop="address">
-          <el-input
-              v-model.trim="state.ruleForm.buyerInformation.address"
-              placeholder="公司地址"
-              readonly
-              class="wd200">
-          </el-input>
-        </el-form-item>
-        <el-form-item label="开户银行" prop="bankName">
-          <el-input
-              v-model.trim="state.ruleForm.buyerInformation.bank_name"
-              placeholder="开户银行"
-              readonly
-              class="wd200">
-          </el-input>
-        </el-form-item>
-        <el-form-item label="银行账户" prop="bankAccount">
-          <el-input
-              v-model.trim="state.ruleForm.buyerInformation.bank_account"
-              placeholder="银行账户"
-              readonly
-              class="wd200">
-          </el-input>
-        </el-form-item>
-        <el-form-item label="发票金额(单位:分)" prop="invoiceAmount">
-          <el-input
-              :model-value="u.fmt.fmtMoney(state.ruleForm.totalAmount)"
-              placeholder="发票金额(单位:分)"
-              readonly
-              class="wd200">
-          </el-input>
-        </el-form-item>
-        <el-form-item label="税额" prop="taxInfo">
-          <el-input
-              :model-value="u.fmt.fmtMoney(state.ruleForm.taxAmount)"
-              placeholder="税额"
-              readonly
-              class="wd200">
-          </el-input>
-        </el-form-item>
-        <el-form-item label="开票人" prop="biller">
-          <el-input
-              v-model.trim="state.ruleForm.sellerInformation.name"
-              placeholder="开票人"
-              readonly
-              class="wd200">
-          </el-input>
-        </el-form-item>
-        <el-form-item label="发票状态" prop="status">
-          <ext-d-label    class="wd200" type="Invoice.status" :model-value="state.ruleForm.status"> </ext-d-label>
-        </el-form-item>
+
+        <el-card header="开票人" shadow="hover" class="mt20">
+          <el-form-item label="开票企业名称" prop="invoiceTitle">
+            <el-input
+                v-model.trim="state.ruleForm.sellerInformation.name"
+                placeholder="开票企业名称"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="公司税号" prop="taxId">
+            <el-input
+                v-model.trim="state.ruleForm.sellerInformation.taxpayer_id"
+                placeholder="公司税号"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="公司地址" prop="address">
+            <el-input
+                v-model.trim="state.ruleForm.sellerInformation.address"
+                placeholder="公司地址"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="开户银行" prop="bankName">
+            <el-input
+                v-model.trim="state.ruleForm.sellerInformation.bank_name"
+                placeholder="开户银行"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="联系电话" prop="bankAccount">
+            <el-input
+                v-model.trim="state.ruleForm.sellerInformation.telephone"
+                placeholder="联系电话"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+        </el-card>
+
+        <el-card header="发票信息" shadow="hover" class="mt20">
+          <el-form-item label="发票类型" prop="invoiceType">
+            <ext-d-label   class="wd200"  type="Invoice.type" :model-value="state.ruleForm.buyerInformation.type"></ext-d-label>
+          </el-form-item>
+          <el-form-item label="发票抬头名称" prop="invoiceTitle">
+            <el-input
+                v-model.trim="state.ruleForm.buyerInformation.name"
+                placeholder="发票抬头名称"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="公司税号" prop="taxId">
+            <el-input
+                v-model.trim="state.ruleForm.buyerInformation.taxpayer_id"
+                placeholder="公司税号"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="公司地址" prop="address">
+            <el-input
+                v-model.trim="state.ruleForm.buyerInformation.address"
+                placeholder="公司地址"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="开户银行" prop="bankName">
+            <el-input
+                v-model.trim="state.ruleForm.buyerInformation.bank_name"
+                placeholder="开户银行"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="银行账户" prop="bankAccount">
+            <el-input
+                v-model.trim="state.ruleForm.buyerInformation.bank_account"
+                placeholder="银行账户"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="发票金额(单位:分)" prop="invoiceAmount">
+            <el-input
+                :model-value="u.fmt.fmtMoney(state.ruleForm.totalAmount)"
+                placeholder="发票金额(单位:分)"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="税额" prop="taxInfo">
+            <el-input
+                :model-value="u.fmt.fmtMoney(state.ruleForm.taxAmount)"
+                placeholder="税额"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+
+          <el-form-item label="接收发票邮箱" prop="email">
+            <el-input
+                v-model.trim="state.ruleForm.email"
+                placeholder="接收发票邮箱"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="电话" prop="phone">
+            <el-input
+                v-model.trim="state.ruleForm.phone"
+                placeholder="电话"
+                readonly
+                class="wd200">
+            </el-input>
+          </el-form-item>
+        </el-card>
+
+
+
 <!--        <el-form-item label="备注" prop="remark">
           <el-input
               v-model.trim="state.ruleForm.remark"
@@ -229,8 +279,8 @@ const state = reactive(initState());
 
 // 打开弹窗
 const open = (action: string = 'add', row: any) => {
-  state.dialog.title = u.dialog.actions[action].title + "『发票记录表』"
-  state.dialog.submitTxt = u.dialog.actions[action].btn + "『发票记录表』"
+  state.dialog.title = u.dialog.actions[action].title + "『发票』"
+  state.dialog.submitTxt = u.dialog.actions[action].btn
   state.dialog.isShowDialog = true;
   state.detail = row;
   if (action !== 'add') {

+ 8 - 1
admin-web/src/views/admin/invoice/index.vue

@@ -196,7 +196,7 @@
 
 <script setup lang="ts" name="InvoiceList">
 import {defineAsyncComponent, reactive, onMounted, onBeforeMount, ref, getCurrentInstance, nextTick, onBeforeUnmount} from 'vue';
-import {$body, $get} from "/@/utils/request";
+import {$body, $get, $post} from "/@/utils/request";
 import {Msg} from "/@/utils/message";
 import u from "/@/utils/u"
 
@@ -331,7 +331,14 @@ const handleInvice = (row: any) => {
 }
 
 const handleDownloadExcel = () => {
+  let url = import.meta.env.VITE_API_URL;
+  if (!url) {
+    url = `${location.origin}/admin/`;
+  }
+  // $get(`/finance/export/invoiceList`,{...state.formQuery, ...state.pageQuery})
+  let params =   Object.keys(state.formQuery).map(key=>`${key}=${state.formQuery[key]}`).join("&")
 
+  window.open(`${url}/finance/export/invoiceList?t=${new Date().getTime()}&${params}`, "_blank")
 }
 
 const handleInfo = (row:any) => {

+ 1 - 0
admin/src/main/java/com/kym/admin/config/SaTokenConfigure.java

@@ -22,6 +22,7 @@ public class SaTokenConfigure implements WebMvcConfigurer {
                 // login接口不鉴权
                 .excludePathPatterns(
                         "/wx/*",
+                        "/finance/export/*",
                         "/**/login",
                         "/**/error",
                         "/**/pullEnStations",

+ 16 - 31
admin/src/main/java/com/kym/admin/controller/FinanceController.java

@@ -1,5 +1,6 @@
 package com.kym.admin.controller;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.io.IoUtil;
 import cn.hutool.poi.excel.ExcelUtil;
 import cn.hutool.poi.excel.ExcelWriter;
@@ -17,6 +18,8 @@ import com.kym.service.wechat.WxPayService;
 import jakarta.servlet.ServletOutputStream;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.ModelAttribute;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -27,7 +30,10 @@ import org.springframework.web.bind.annotation.RestController;
 
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 
 /**
@@ -39,6 +45,8 @@ import java.util.List;
 @RequestMapping("/finance")
 public class FinanceController {
 
+    private final Logger logger = LoggerFactory.getLogger(FinanceController.class);
+
     private final WxPayService wxPayService;
 
     private final RefundLogService refundLogService;
@@ -130,43 +138,18 @@ public class FinanceController {
      * @param params
      * @return 导出发票列表
      */
-    @PostMapping("/export/invoiceList")
-    void exportInvoiceList(@RequestBody InvoiceQueryParam params, HttpServletRequest request, HttpServletResponse response) {
-        params.setPageSize(Integer.MAX_VALUE);
-        PageBean<InvoiceVo> pageBean = invoiceService.listInvoice(params);
-        List<InvoiceVo> list = pageBean.getList();
-        ExcelWriter writer = ExcelUtil.getWriter();
-//设置要导出到的sheet
-        writer.setSheet("列表");
-//自定义excel标题和列名
-        writer.addHeaderAlias("mobilePhone", "用户手机号");
-        writer.addHeaderAlias("invoiceTitle", "发票抬头");
-        writer.addHeaderAlias("taxId", "公司税号");
-        writer.addHeaderAlias("email", "接收发票邮箱");
-        writer.addHeaderAlias("invoiceType", "发票类型");
-        writer.addHeaderAlias("address", "公司地址");
-        writer.addHeaderAlias("telephone", "购买方电话");
-        writer.addHeaderAlias("bankName", "开户银行");
-        writer.addHeaderAlias("bankAccount", "银行账户");
-        writer.addHeaderAlias("biller", "开票人");
-        writer.addHeaderAlias("invoiceAmount", "发票金额");
-        writer.addHeaderAlias("totalPower", "累积充电量");
-        writer.addHeaderAlias("totalMoney", "累积总金额");
-        writer.addHeaderAlias("elecMoney", "累积电费");
-        writer.addHeaderAlias("serviceMoney", "累积服务费");
-        writer.addHeaderAlias("serviceMoneyDiscount", "服务费优惠金额");
-        writer.addHeaderAlias("status", "发票状态");
-//一次性写出内容,使用默认样式,强制输出标题
-        writer.write(list, true);
+    @GetMapping("/export/invoiceList")
+    void exportInvoiceList(@ModelAttribute InvoiceQueryParam params, HttpServletRequest request, HttpServletResponse response) {
+       ExcelWriter writer = invoiceService.exportInvoiceList(params);
+//        response.setContentType("application/octet-stream;charset=utf-8");
         response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
-        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("发票列表", StandardCharsets.UTF_8) + ".xlsx");
-        //将excel文件信息写入输出流,返回给调用者
+        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("发票列表", StandardCharsets.UTF_8) + ".xlsx");
         ServletOutputStream excelOut = null;
         try {
             excelOut = response.getOutputStream();
             writer.flush(excelOut, true);
         } catch (Exception e) {
-            e.printStackTrace();
+         logger.error("exportInvoiceList error",e);
         } finally {
             writer.close();
         }
@@ -174,3 +157,5 @@ public class FinanceController {
     }
 
 }
+
+

+ 4 - 0
service/src/main/java/com/kym/service/miniapp/InvoiceService.java

@@ -1,5 +1,6 @@
 package com.kym.service.miniapp;
 
+import cn.hutool.poi.excel.ExcelWriter;
 import com.github.yulichang.base.MPJBaseService;
 import com.kym.entity.admin.queryParams.InvoiceQueryParam;
 import com.kym.entity.common.PageBean;
@@ -27,4 +28,7 @@ public interface InvoiceService extends MPJBaseService<Invoice> {
     List<Invoice> listInvoiceForApp(Integer status);
 
     void cancelApplyInvoice(String invoiceId);
+
+
+    ExcelWriter exportInvoiceList(InvoiceQueryParam param);
 }

+ 70 - 2
service/src/main/java/com/kym/service/miniapp/impl/InvoiceServiceImpl.java

@@ -1,6 +1,8 @@
 package com.kym.service.miniapp.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.NumberUtil;
 import cn.hutool.poi.excel.ExcelUtil;
 import cn.hutool.poi.excel.ExcelWriter;
 import com.baomidou.dynamic.datasource.annotation.DS;
@@ -8,12 +10,14 @@ import com.github.pagehelper.PageHelper;
 import com.github.yulichang.base.MPJBaseServiceImpl;
 import com.github.yulichang.toolkit.JoinWrappers;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.kym.common.IQuery;
 import com.kym.common.exception.BusinessException;
 import com.kym.common.utils.CommUtil;
 import com.kym.common.utils.OrderUtils;
 import com.kym.entity.admin.queryParams.InvoiceQueryParam;
 import com.kym.entity.common.PageBean;
 import com.kym.entity.miniapp.ChargeOrder;
+import com.kym.entity.miniapp.DataDict;
 import com.kym.entity.miniapp.Invoice;
 import com.kym.entity.miniapp.User;
 import com.kym.entity.miniapp.queryParams.ApplyInvoiceParams;
@@ -22,6 +26,7 @@ import com.kym.entity.wechat.InvoiceOrderDetail;
 import com.kym.entity.wechat.TitleUrl;
 import com.kym.mapper.miniapp.InvoiceMapper;
 import com.kym.service.miniapp.ChargeOrderService;
+import com.kym.service.miniapp.DataDictService;
 import com.kym.service.miniapp.InvoiceService;
 import com.kym.service.wechat.WxPayService;
 import lombok.extern.slf4j.Slf4j;
@@ -29,8 +34,11 @@ import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -47,8 +55,10 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic
 
     private final ChargeOrderService chargeOrderService;
     private final WxPayService wxPayService;
+    private final DataDictService dataDictService;
 
-    public InvoiceServiceImpl(ChargeOrderService chargeOrderService, @Lazy WxPayService wxPayService) {
+    public InvoiceServiceImpl(ChargeOrderService chargeOrderService, @Lazy WxPayService wxPayService,@Lazy DataDictService dataDictService) {
+        this.dataDictService =dataDictService;
         this.chargeOrderService = chargeOrderService;
         this.wxPayService = wxPayService;
     }
@@ -146,7 +156,7 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic
         return new PageBean<>(list);
     }
 
-    void invoiceExport(InvoiceQueryParam params){
+    void invoiceExport(InvoiceQueryParam params) {
         MPJLambdaWrapper<Invoice> wrapper = JoinWrappers.lambda(Invoice.class)
                 .selectAsClass(Invoice.class, InvoiceVo.class)
                 .selectAll(Invoice.class)
@@ -196,4 +206,62 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic
         }
     }
 
+    @Override
+    public ExcelWriter exportInvoiceList(InvoiceQueryParam params) {
+        MPJLambdaWrapper<Invoice> wrapper = JoinWrappers.lambda(Invoice.class)
+                .selectAsClass(Invoice.class, InvoiceVo.class)
+                .selectAll(Invoice.class)
+                .select(User::getMobilePhone)
+                .leftJoin(User.class, User::getId, Invoice::getUserId)
+                .like(CommUtil.isNotEmptyAndNull(params.getPhone()), User::getMobilePhone, params.getPhone())
+                .like(CommUtil.isNotEmptyAndNull(params.getInvoiceTitle()), Invoice::getInvoiceTitle, params.getInvoiceTitle())
+                .like(CommUtil.isNotEmptyAndNull(params.getBiller()), Invoice::getBiller, params.getBiller())
+                .like(CommUtil.isNotEmptyAndNull(params.getTaxId()), Invoice::getTaxId, params.getTaxId())
+                .like(CommUtil.isNotEmptyAndNull(params.getInvoiceType()), Invoice::getInvoiceType, params.getInvoiceType())
+                .like(CommUtil.isNotEmptyAndNull(params.getEmail()), Invoice::getEmail, params.getEmail())
+                .eq(params.getStatus() != null, Invoice::getStatus, params.getStatus())
+                .orderByDesc(Invoice::getId);
+        var list = selectJoinList(InvoiceVo.class, wrapper);
+        ExcelWriter writer = ExcelUtil.getWriter();
+//设置要导出到的sheet
+//自定义excel标题和列名
+        writer.addHeaderAlias("status", "发票状态");
+        writer.addHeaderAlias("mobilePhone", "用户手机号");
+        writer.addHeaderAlias("invoiceTitle", "发票抬头");
+        writer.addHeaderAlias("taxId", "公司税号");
+        writer.addHeaderAlias("email", "接收发票邮箱");
+        writer.addHeaderAlias("invoiceType", "发票类型");
+        writer.addHeaderAlias("address", "公司地址");
+        writer.addHeaderAlias("telephone", "购买方电话");
+        writer.addHeaderAlias("bankName", "开户银行");
+        writer.addHeaderAlias("bankAccount", "银行账户");
+        writer.addHeaderAlias("biller", "开票人");
+        writer.addHeaderAlias("invoiceAmount", "发票金额(元)");
+        writer.addHeaderAlias("totalPower", "累积充电量(度)");
+        writer.addHeaderAlias("totalMoney", "累积总金额(元)");
+        writer.addHeaderAlias("elecMoney", "累积电费(元)");
+        writer.addHeaderAlias("serviceMoney", "累积服务费(元)");
+        writer.addHeaderAlias("serviceMoneyDiscount", "服务费优惠金额(元)");
+
+        List<DataDict> dataDicts = dataDictService.lambdaQuery().list();
+        Map<String, String> dictMap = dataDicts.stream().collect(Collectors.toMap(k -> k.getCode() + ":" + k.getValue(), DataDict::getName));
+//一次性写出内容,使用默认样式,强制输出标题
+        List<Map<String, Object>> rows = new ArrayList<>();
+        list.forEach(k -> {
+            Map<String, Object> m = BeanUtil.beanToMap(k,"mobilePhone","invoiceTitle","taxId","email",
+                    "address","telephone","bankName","bankAccount","biller","totalPower");
+            m.put("invoiceType", dictMap.getOrDefault("Invoice.type:"+k.getInvoiceType(),""));
+            m.put("invoiceAmount", NumberUtil.decimalFormat("#.##",k.getInvoiceAmount()/100f));
+            m.put("totalMoney",NumberUtil.decimalFormat("#.##",k.getTotalMoney()/100f));
+            m.put("elecMoney", NumberUtil.decimalFormat("#.##",k.getElecMoney()/100f));
+            m.put("serviceMoney", NumberUtil.decimalFormat("#.##",k.getServiceMoney()/100f));
+            m.put("serviceMoneyDiscount",NumberUtil.decimalFormat("#.##",k.getServiceMoneyDiscount()/100f));
+            m.put("status", dictMap.getOrDefault("Invoice.status:"+k.getStatus(),""));
+            rows.add(m);
+        });
+        writer.write(rows, true);
+
+        return writer;
+    }
+
 }