sinake
3 天以前 e0bbd21f56757c35dc067eaa8bc67057b65fead4
新增发票管理
已修改1个文件
已添加5个文件
591 ■■■■■ 文件已修改
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceInvoiceController.java 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-project/src/main/java/com/ruoyi/project/domain/ServiceInvoice.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-project/src/main/java/com/ruoyi/project/mapper/ServiceInvoiceMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-project/src/main/java/com/ruoyi/project/service/IServiceInvoiceService.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceInvoiceServiceImpl.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
@@ -51,8 +51,6 @@
    @Autowired
    private ServerConfig serverConfig;
    @Value("${appcode}")
    private String  appcode;
    /**
     * é€šç”¨ä¸‹è½½è¯·æ±‚
@@ -131,120 +129,6 @@
        }
    }
    public String aliOCR(String base64) {
        String host = "https://mixedmulti.market.alicloudapi.com";
        String path = "/ocrservice/mixedMultiInvoice";
        String method = "POST";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        //根据API的要求,定义相对应的Content-Type
        headers.put("Content-Type", "application/json; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        String bodys = "{\"img\":\""+base64+"\"}";
        try {
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            System.out.println(response.toString());
            //获取response的body
            String content=EntityUtils.toString(response.getEntity());
            JSONObject jsonContent=JSONObject.parseObject(content);
            JSONArray subMsgs=jsonContent.getJSONArray("subMsgs");
            List<Map<String,Object>> lists=new ArrayList<>();
            for(Object row: subMsgs){
                Map<String,Object> tempList=new HashMap<>();
                JSONObject rowObject=(JSONObject)row;
                tempList.put("发票分类",rowObject.getString("type"));
                JSONObject result=((JSONObject)rowObject.get("result")).getJSONObject("data");
                for(Map.Entry<String, Object> entry : result.entrySet()){
                    tempList.put(entry.getKey(),entry.getValue());
                }
                if(rowObject.getString("type").equals("银行承兑汇票")){
                    BigDecimal totalAmount= ChineseUtils.chineseToNumber(result.getString("票据金额大写"));
                    tempList.put("发票金额",totalAmount);
                }
                if(rowObject.getString("type").equals("火车票")){
                    tempList.put("发票金额",result.getString("票价"));
                }
                lists.add(tempList);
            }
            System.out.println(content);
            return JSON.toJSONString(lists);
        } catch (Exception e) {
            e.printStackTrace();
            return "{}";
        }
    }
    /**
     * é€šç”¨ä¸Šä¼ è¯·æ±‚
     */
    @ApiOperation("testOCR")
    @PostMapping("/common/testOCR")
    public AjaxResult testOCR(@RequestBody String fileName) throws Exception {
        Path filePath= Paths.get(fileName);
        String base64= Base64.getEncoder().encodeToString( Files.readAllBytes(filePath));
        AjaxResult ajax = AjaxResult.success();
        ajax.put("OCRList", aliOCR(base64));
        return ajax;
    }
    /**
     * é€šç”¨ä¸Šä¼ è¯·æ±‚
     */
    @PostMapping("/common/uploadOCR")
    public AjaxResult uploadOCR(MultipartFile file) throws Exception {
        try {
            // ä¸Šä¼ æ–‡ä»¶è·¯å¾„
            String filePath = RuoYiConfig.getUploadPath();
            //判断文件是否存在
            String filename = file.getOriginalFilename().trim();
            String felinamePath = FileUploadUtils.extractFilename(file);
//            String pathFileName = FileUploadUtils.getPathFileName(filePath, s);
            for (int i=1;i<500;i++) {
                File file1 = new File(filePath + "/" + felinamePath);
                boolean exists = file1.exists();
                if (exists) {
                    int index = filename.lastIndexOf(".");
                    String startStr = filename.substring(0, index);
                    String endStr = filename.substring(index, filename.length());
                    String newFilename = startStr + "-" + i + endStr; // your new filename
                    felinamePath = DateUtils.datePath() + "/" + newFilename;
                    String contentType = file.getContentType();
                    byte[] bytes = file.getBytes();
                    file = new MockMultipartFile(newFilename, newFilename, contentType, bytes);
                }else{
                    break;
                }
            }
            // ä¸Šä¼ å¹¶è¿”回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);
            String url1 = serverConfig.getUrl();
            log.info("url1的值old :{}", url1);
            if (url1.contains("8032")) {
                //这里的8032不是tomcat的,所以要转成tomcat的
                url1 = url1.replace("8032", "8032/prod-api");
            }
            String base64= Base64.getEncoder().encodeToString(file.getBytes());
            log.info("url1的值new :{}", url1);
            String url = url1 + fileName;
            AjaxResult ajax = AjaxResult.success();
            ajax.put("fileName", fileName);
            ajax.put("url", url);
            ajax.put("OCRList", aliOCR(base64));
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }
//    private static void parseUTF(int[] bits) {
//        int index = 0;//这个指针指向每一行循环时列下标的位置,下一行开始时重新置位0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceInvoiceController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,239 @@
package com.ruoyi.web.controller.project;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ChineseUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.project.domain.ServiceInvoice;
import com.ruoyi.project.service.IServiceInvoiceService;
import com.ruoyi.web.controller.tool.HttpUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
/**
 * å‘票管理Controller
 *
 * @author ruoyi
 * @date 2026-10-21
 */
@Api("发票管理")
@RestController
@RequestMapping("/project/invoice")
public class ServiceInvoiceController extends BaseController {
    @Autowired
    private IServiceInvoiceService serviceInvoiceService;
    @Autowired
    private ServerConfig serverConfig;
    @Value("${appcode}")
    private String  appcode;
    /**
     * æŸ¥è¯¢å‘票管理列表
     */
    @ApiOperation("查询发票管理列表")
    @GetMapping("/list")
    public TableDataInfo list(ServiceInvoice serviceInvoice) {
        startPage();
        List<ServiceInvoice> list = serviceInvoiceService.queryList(serviceInvoice);
        return getDataTable(list);
    }
    /**
     * å¯¼å‡ºå‘票管理列表
     */
    @ApiOperation("导出发票管理列表")
    @Log(title = "发票管理", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(ServiceInvoice serviceInvoice) {
        List<ServiceInvoice> list = serviceInvoiceService.queryList(serviceInvoice);
        ExcelUtil<ServiceInvoice> util = new ExcelUtil<ServiceInvoice>(ServiceInvoice.class);
        return util.exportExcel(list, "发票管理数据");
    }
    /**
     * èŽ·å–å‘ç¥¨ç®¡ç†è¯¦ç»†ä¿¡æ¯
     */
    @ApiOperation("获取发票管理详细信息")
    @GetMapping(value = "/getInfo/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(serviceInvoiceService.getById(id));
    }
    /**
     * æ–°å¢žå‘票管理
     */
    @ApiOperation("新增发票管理")
    @Log(title = "发票管理", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @RepeatSubmit
    public AjaxResult add(@RequestBody ServiceInvoice serviceInvoice) {
        return toAjax(serviceInvoiceService.save(serviceInvoice));
    }
    /**
     * ä¿®æ”¹å‘票管理
     */
    @ApiOperation("修改发票管理")
    @Log(title = "发票管理", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @RepeatSubmit
    public AjaxResult edit(@RequestBody ServiceInvoice serviceInvoice) {
        return toAjax(serviceInvoiceService.updateById(serviceInvoice));
    }
    /**
     * åˆ é™¤å‘票管理
     */
    @ApiOperation("删除发票管理")
    @Log(title = "发票管理", businessType = BusinessType.DELETE)
    @GetMapping("/remove/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(serviceInvoiceService.removeByIds(Arrays.asList(ids)));
    }
    /**
     * é€šç”¨ä¸Šä¼ è¯·æ±‚
     */
    @ApiOperation("testOCR")
    @PostMapping("/testOCR")
    public AjaxResult testOCR(@RequestBody String fileName) throws Exception {
        Path filePath= Paths.get(fileName);
        String base64= Base64.getEncoder().encodeToString( Files.readAllBytes(filePath));
        AjaxResult ajax = AjaxResult.success();
        ajax.put("OCRList", aliOCR(base64,0,0));
        return ajax;
    }
    /**
     * é€šç”¨ä¸Šä¼ è¯·æ±‚
     */
    @PostMapping("/uploadOCR")
    public AjaxResult uploadOCR(@RequestParam("file") MultipartFile file, @RequestParam("userId") long userId, @RequestParam("caseId") long caseId) throws Exception {
        try {
            // ä¸Šä¼ æ–‡ä»¶è·¯å¾„
            String filePath = RuoYiConfig.getUploadPath();
            //判断文件是否存在
            String filename = file.getOriginalFilename().trim();
            String felinamePath = FileUploadUtils.extractFilename(file);
            String newFilename="";
//            String pathFileName = FileUploadUtils.getPathFileName(filePath, s);
            for (int i=1;i<500;i++) {
                File file1 = new File(filePath + "/" + felinamePath);
                boolean exists = file1.exists();
                if (exists) {
                    int index = filename.lastIndexOf(".");
                    String startStr = filename.substring(0, index);
                    String endStr = filename.substring(index, filename.length());
                    newFilename = startStr + "-" + i + endStr; // your new filename
                    felinamePath = DateUtils.datePath() + "/" + newFilename;
                    String contentType = file.getContentType();
                    byte[] bytes = file.getBytes();
                    file = new MockMultipartFile(newFilename, newFilename, contentType, bytes);
                }else{
                    break;
                }
            }
            // ä¸Šä¼ å¹¶è¿”回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);
            String url1 = serverConfig.getUrl();
            String url = url1 + fileName;
            String base64= Base64.getEncoder().encodeToString(file.getBytes());
            List<Map<String,Object>> lists=aliOCR(base64,userId,caseId);
            for(Map<String,Object> row : lists){
                ServiceInvoice invoice=new ServiceInvoice();
                invoice.setUserId(userId);
                invoice.setCaseId(caseId);
                invoice.setInvoiceType(row.get("type")+"");
                invoice.setInvoiceNo(row.get("发票号码")+"");
                invoice.setOccurDate(row.get("开票日期")+"");
                invoice.setInvoiceAmount(row.get("发票金额")+"");
                invoice.setSellerName(row.get("受票方名称")+"");
                invoice.setInvoiceUrl(url);
                invoice.setInvoiceName(newFilename);
                invoice.setExtContent(JSON.toJSONString(row));
                serviceInvoiceService.save(invoice);
            }
            AjaxResult ajax = AjaxResult.success();
            ajax.put("fileName", fileName);
            ajax.put("url", url);
            ajax.put("OCRList", lists);
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }
    public List<Map<String,Object>> aliOCR(String base64,long userId,long caseId) {
        String host = "https://mixedmulti.market.alicloudapi.com";
        String path = "/ocrservice/mixedMultiInvoice";
        String method = "POST";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        //根据API的要求,定义相对应的Content-Type
        headers.put("Content-Type", "application/json; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        String bodys = "{\"img\":\""+base64+"\"}";
        List<Map<String,Object>> lists=new ArrayList<>();
        try {
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            //获取response的body
            String content= EntityUtils.toString(response.getEntity());
            JSONObject jsonContent=JSONObject.parseObject(content);
            JSONArray subMsgs=jsonContent.getJSONArray("subMsgs");
            for(Object row: subMsgs){
                Map<String,Object> tempList=new HashMap<>();
                JSONObject rowObject=(JSONObject)row;
                tempList.put("发票分类",rowObject.getString("type"));
                JSONObject result=((JSONObject)rowObject.get("result")).getJSONObject("data");
                for(Map.Entry<String, Object> entry : result.entrySet()){
                    tempList.put(entry.getKey(),entry.getValue());
                }
                if(rowObject.getString("type").equals("银行承兑汇票")){
                    BigDecimal totalAmount= ChineseUtils.chineseToNumber(result.getString("票据金额大写"));
                    tempList.put("发票金额",totalAmount);
                }
                if(rowObject.getString("type").equals("火车票")){
                    tempList.put("发票金额",result.getString("票价"));
                }
                lists.add(tempList);
            }
            return lists;
        } catch (Exception e) {
            return lists;
        }
    }
}
ruoyi-project/src/main/java/com/ruoyi/project/domain/ServiceInvoice.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,127 @@
package com.ruoyi.project.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.util.Date;
/**
 * å‘票管理对象 service_invoice
 *
 * @author ruoyi
 * @date 2026-10-21
 */
@Data
@ApiModel("发票管理")
@TableName("service_invoice")
public class ServiceInvoice extends BaseEntity {
    private static final long serialVersionUID = 1L;
    /**
     * ä¸»é”®ID
     */
    @ApiModelProperty("主键ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * ç”¨æˆ·ID
     */
    @ApiModelProperty("用户ID")
    @Excel(name = "用户ID")
    private Long userId;
    /**
     * æ¡ˆä¾‹ID
     */
    @ApiModelProperty("案例ID")
    @Excel(name = "案例ID")
    private Long caseId;
    /**
     * å‘票类型
     */
    @ApiModelProperty("发票类型")
    @Excel(name = "发票类型")
    private String invoiceType;
    /**
     * å‘票名称
     */
    @ApiModelProperty("发票名称")
    @Excel(name = "发票名称")
    private String invoiceName;
    /**
     * å‘票号码
     */
    @ApiModelProperty("发票号码")
    @Excel(name = "发票号码")
    private String invoiceNo;
    /**
     * å‘生日期
     */
    @ApiModelProperty("发生日期")
    @Excel(name = "发生日期", width = 30, dateFormat = "yyyy-MM-dd")
    private String occurDate;
    /**
     * å‘票开始日期
     */
    @ApiModelProperty("发票开始日期")
    @Excel(name = "发票开始日期", width = 30, dateFormat = "yyyy-MM-dd")
    private String invoiceStartDate;
    /**
     * å‘票结束日期
     */
    @ApiModelProperty("发票结束日期")
    @Excel(name = "发票结束日期", width = 30, dateFormat = "yyyy-MM-dd")
    private String invoiceEndDate;
    /**
     * å‘票金额
     */
    @ApiModelProperty("发票金额")
    @Excel(name = "发票金额")
    private String invoiceAmount;
    /**
     * é”€å”®æ–¹åç§°
     */
    @ApiModelProperty("销售方名称")
    @Excel(name = "销售方名称")
    private String sellerName;
    /**
     * å‘票URL
     */
    @ApiModelProperty("发票URL")
    @Excel(name = "发票URL")
    private String invoiceUrl;
    /**
     * æ‰©å±•内容(json存)
     */
    @ApiModelProperty("扩展内容(json存)")
    private String extContent;
    /**
     * å¤‡æ³¨
     */
    @ApiModelProperty("备注")
    @Excel(name = "备注")
    @TableField("remark")
    private String remark;
}
ruoyi-project/src/main/java/com/ruoyi/project/mapper/ServiceInvoiceMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ruoyi.project.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.project.domain.ServiceInvoice;
import org.apache.ibatis.annotations.Mapper;
/**
 * å‘票管理Mapper接口
 *
 * @author ruoyi
 * @date 2026-10-21
 */
@Mapper
public interface ServiceInvoiceMapper extends BaseMapper<ServiceInvoice> {
}
ruoyi-project/src/main/java/com/ruoyi/project/service/IServiceInvoiceService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.project.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.project.domain.ServiceInvoice;
import java.util.List;
/**
 * å‘票管理Service接口
 *
 * @author ruoyi
 * @date 2026-10-21
 */
public interface IServiceInvoiceService extends IService<ServiceInvoice> {
    /**
     * æŸ¥è¯¢å‘票管理列表
     *
     * @param serviceInvoice å‘票管理
     * @return å‘票管理集合
     */
    List<ServiceInvoice> queryList(ServiceInvoice serviceInvoice);
}
ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceInvoiceServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,71 @@
package com.ruoyi.project.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.domain.ServiceInvoice;
import com.ruoyi.project.mapper.ServiceInvoiceMapper;
import com.ruoyi.project.service.IServiceInvoiceService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * å‘票管理Service业务层处理
 *
 * @author ruoyi
 * @date 2026-10-21
 */
@Service
public class ServiceInvoiceServiceImpl extends ServiceImpl<ServiceInvoiceMapper, ServiceInvoice> implements IServiceInvoiceService {
    /**
     * æŸ¥è¯¢å‘票管理列表
     *
     * @param serviceInvoice å‘票管理
     * @return å‘票管理
     */
    @Override
    public List<ServiceInvoice> queryList(ServiceInvoice serviceInvoice) {
        LambdaQueryWrapper<ServiceInvoice> wrappers = Wrappers.lambdaQuery();
        if (serviceInvoice.getId() != null) {
            wrappers.eq(ServiceInvoice::getId, serviceInvoice.getId());
        }
        if (serviceInvoice.getUserId() != null) {
            wrappers.eq(ServiceInvoice::getUserId, serviceInvoice.getUserId());
        }
        if (serviceInvoice.getCaseId() != null) {
            wrappers.eq(ServiceInvoice::getCaseId, serviceInvoice.getCaseId());
        }
        if (StringUtils.isNotBlank(serviceInvoice.getInvoiceType())) {
            wrappers.eq(ServiceInvoice::getInvoiceType, serviceInvoice.getInvoiceType());
        }
        if (StringUtils.isNotBlank(serviceInvoice.getInvoiceName())) {
            wrappers.like(ServiceInvoice::getInvoiceName, serviceInvoice.getInvoiceName());
        }
        if (StringUtils.isNotBlank(serviceInvoice.getInvoiceNo())) {
            wrappers.eq(ServiceInvoice::getInvoiceNo, serviceInvoice.getInvoiceNo());
        }
        if (serviceInvoice.getOccurDate() != null) {
            wrappers.eq(ServiceInvoice::getOccurDate, serviceInvoice.getOccurDate());
        }
        if (serviceInvoice.getInvoiceStartDate() != null) {
            wrappers.ge(ServiceInvoice::getInvoiceStartDate, serviceInvoice.getInvoiceStartDate());
        }
        if (serviceInvoice.getInvoiceEndDate() != null) {
            wrappers.le(ServiceInvoice::getInvoiceEndDate, serviceInvoice.getInvoiceEndDate());
        }
        if (serviceInvoice.getInvoiceAmount() != null) {
            wrappers.eq(ServiceInvoice::getInvoiceAmount, serviceInvoice.getInvoiceAmount());
        }
        if (StringUtils.isNotBlank(serviceInvoice.getSellerName())) {
            wrappers.like(ServiceInvoice::getSellerName, serviceInvoice.getSellerName());
        }
        if (StringUtils.isNotBlank(serviceInvoice.getRemark())) {
            wrappers.like(ServiceInvoice::getRemark, serviceInvoice.getRemark());
        }
        wrappers.orderByDesc(ServiceInvoice::getCreateTime).orderByDesc(ServiceInvoice::getId);
        return this.list(wrappers);
    }
}