| @@ -47,13 +47,15 @@ | |||||
| <version>5.2.4</version> | <version>5.2.4</version> | ||||
| </dependency> | </dependency> | ||||
| <!-- https://mvnrepository.com/artifact/net.sourceforge.tess4j/tess4j --> | |||||
| <!-- ocr --> | |||||
| <dependency> | <dependency> | ||||
| <groupId>net.sourceforge.tess4j</groupId> | |||||
| <artifactId>tess4j</artifactId> | |||||
| <version>4.5.2</version> | |||||
| <groupId>com.iformall</groupId> | |||||
| <artifactId>mallinkOcr</artifactId> | |||||
| <version>1.0</version> | |||||
| </dependency> | </dependency> | ||||
| </dependencies> | </dependencies> | ||||
| <build> | <build> | ||||
| @@ -0,0 +1,24 @@ | |||||
| CREATE TABLE `wx_merchant_ocr_model` ( | |||||
| `id` bigint(20) NOT NULL, | |||||
| `merchant_id` bigint(20) NOT NULL COMMENT '商户编号', | |||||
| `ocr_model_id` bigint(20) NOT NULL COMMENT 'ocr模板编号', | |||||
| `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | |||||
| `tenant_id` varchar(5) DEFAULT NULL COMMENT '租户id', | |||||
| `parent_tenant_id` varchar(5) DEFAULT NULL, | |||||
| `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, | |||||
| PRIMARY KEY (`id`), | |||||
| UNIQUE KEY `UNIQUE` (`merchant_id`) | |||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; | |||||
| CREATE TABLE `wx_ocr_model` ( | |||||
| `id` bigint(20) NOT NULL, | |||||
| `lang_code` varchar(20) NOT NULL DEFAULT 'iformallLang' COMMENT '语言定义', | |||||
| `font_name` varchar(20) NOT NULL COMMENT '字库名称', | |||||
| `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||||
| `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |||||
| `remark` text COMMENT '说明', | |||||
| `status` tinyint(1) DEFAULT '0' COMMENT '0-有效 1-无效', | |||||
| PRIMARY KEY (`id`), | |||||
| UNIQUE KEY `UNIQUE` (`font_name`) | |||||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; | |||||
| @@ -16,6 +16,17 @@ | |||||
| <groupId>com.iformall</groupId> | <groupId>com.iformall</groupId> | ||||
| <artifactId>mallinkService</artifactId> | <artifactId>mallinkService</artifactId> | ||||
| <version>1.0</version> | <version>1.0</version> | ||||
| </dependency> <!-- ocr --> | |||||
| <dependency> | |||||
| <groupId>com.iformall</groupId> | |||||
| <artifactId>mallinkOcr</artifactId> | |||||
| <version>1.0</version> | |||||
| </dependency> | |||||
| <!-- ocr --> | |||||
| <dependency> | |||||
| <groupId>com.iformall</groupId> | |||||
| <artifactId>mallinkOcr</artifactId> | |||||
| <version>1.0</version> | |||||
| </dependency> | </dependency> | ||||
| </dependencies> | </dependencies> | ||||
| <build> | <build> | ||||
| @@ -0,0 +1,57 @@ | |||||
| package com.iformall.controller; | |||||
| import com.iformall.common.ErrorCode; | |||||
| import com.iformall.common.ResultData; | |||||
| import com.iformall.domain.po.WxMerchantOcrModel; | |||||
| import com.iformall.domain.po.base.TenantEntity; | |||||
| import com.iformall.ocr.FormallTess4j; | |||||
| import com.iformall.service.WxOcrService; | |||||
| import io.swagger.annotations.Api; | |||||
| import io.swagger.annotations.ApiImplicitParam; | |||||
| import io.swagger.annotations.ApiImplicitParams; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.web.bind.annotation.GetMapping; | |||||
| import org.springframework.web.bind.annotation.RequestMapping; | |||||
| import org.springframework.web.bind.annotation.RestController; | |||||
| /** | |||||
| * @author gongbiao | |||||
| */ | |||||
| @RestController | |||||
| @RequestMapping("/api/wxOcr") | |||||
| @Api(description = "ocr") | |||||
| public class WxOcrController extends BaseController { | |||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
| @Autowired | |||||
| private WxOcrService ocrService; | |||||
| @ApiOperation("分析图片信息") | |||||
| @GetMapping("/analyImage") | |||||
| @ApiImplicitParams({ | |||||
| @ApiImplicitParam(name = "merchantId", value = "商户编号", dataType = "Long", paramType = "query", required = true), | |||||
| @ApiImplicitParam(name = "imageUrl", value = "小票图片url", dataType = "String", paramType = "query", required = true), | |||||
| }) | |||||
| public ResultData analyImage(Long merchantId,String imageUrl) { | |||||
| TenantEntity tenantEntity = getTenantInfo(); | |||||
| WxMerchantOcrModel model = ocrService.getMerchantOcrModel(merchantId, tenantEntity.getTenantId(), tenantEntity.getParentTenantId()); | |||||
| if (null == model) { | |||||
| return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(), "当前商户没有配置OCR模板"); | |||||
| } | |||||
| String result; | |||||
| try { | |||||
| result = FormallTess4j.ocrNetImgFile(imageUrl); | |||||
| return new ResultData(result); | |||||
| } catch (Exception e) { | |||||
| logger.error("ocr识别失败。",e); | |||||
| return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(), "ocr识别失败。"+e.getMessage()); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -38,5 +38,4 @@ | |||||
| </dependency> | </dependency> | ||||
| </dependencies> | </dependencies> | ||||
| </project> | </project> | ||||
| @@ -80,6 +80,7 @@ public class FormallTess4jTrain { | |||||
| System.out.println(trainCmdstr); | System.out.println(trainCmdstr); | ||||
| //executeLocalCmd(trainCmdstr, null); | //executeLocalCmd(trainCmdstr, null); | ||||
| //此处可以批量开始 | |||||
| String extractorCmdstr = "unicharset_extractor "+prefix+".box"; | String extractorCmdstr = "unicharset_extractor "+prefix+".box"; | ||||
| System.out.println(extractorCmdstr); | System.out.println(extractorCmdstr); | ||||
| //executeLocalCmd(extractorCmdstr, null); | //executeLocalCmd(extractorCmdstr, null); | ||||
| @@ -95,6 +96,7 @@ public class FormallTess4jTrain { | |||||
| String cntrainCmdstr = "cntraining "+prefix+".tr"; | String cntrainCmdstr = "cntraining "+prefix+".tr"; | ||||
| System.out.println(cntrainCmdstr); | System.out.println(cntrainCmdstr); | ||||
| //executeLocalCmd(cntrainCmdstr, null); | //executeLocalCmd(cntrainCmdstr, null); | ||||
| //批量结束 | |||||
| //System.out.println("DONE createTrainFiles !"); | //System.out.println("DONE createTrainFiles !"); | ||||
| } | } | ||||
| @@ -35,14 +35,6 @@ | |||||
| <artifactId>mybatis-multi-tenancy</artifactId> | <artifactId>mybatis-multi-tenancy</artifactId> | ||||
| <version>1.0</version> | <version>1.0</version> | ||||
| </dependency> | </dependency> | ||||
| <!-- ocr --> | |||||
| <dependency> | |||||
| <groupId>com.iformall</groupId> | |||||
| <artifactId>mallinkOcr</artifactId> | |||||
| <version>1.0</version> | |||||
| </dependency> | |||||
| </dependencies> | </dependencies> | ||||
| </project> | </project> | ||||
| @@ -0,0 +1,25 @@ | |||||
| package com.iformall.domain.po; | |||||
| import com.baomidou.mybatisplus.annotation.TableName; | |||||
| import com.iformall.domain.po.base.TenantEntity; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| import java.util.Date; | |||||
| @TableName(value = "wx_merchant_ocr_model") | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| public class WxMerchantOcrModel extends TenantEntity { | |||||
| private static final long serialVersionUID = 1L; | |||||
| protected Long id; | |||||
| @io.swagger.annotations.ApiModelProperty(value="商户编号",name="merchantId") | |||||
| private Long merchantId; | |||||
| @io.swagger.annotations.ApiModelProperty(value="ocr模板编号",name="ocrModelId") | |||||
| private Long ocrModelId; | |||||
| @io.swagger.annotations.ApiModelProperty(value="创建时间",name="createTime") | |||||
| private Date createTime; | |||||
| @io.swagger.annotations.ApiModelProperty(value="创建时间",name="updateTime") | |||||
| private Date updateTime; | |||||
| } | |||||
| @@ -0,0 +1,28 @@ | |||||
| package com.iformall.domain.po; | |||||
| import com.baomidou.mybatisplus.annotation.TableName; | |||||
| import com.iformall.domain.po.base.BaseEntity; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| import java.util.Date; | |||||
| @TableName(value = "wx_ocr_model") | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| public class WxOcrModel extends BaseEntity { | |||||
| private static final long serialVersionUID = 1L; | |||||
| protected Long id; | |||||
| @io.swagger.annotations.ApiModelProperty(value="语言定义,默认iformallLang",name="langCode") | |||||
| private String langCode; | |||||
| @io.swagger.annotations.ApiModelProperty(value="字库名称",name="fontName") | |||||
| private String fontName; | |||||
| @io.swagger.annotations.ApiModelProperty(value="创建时间",name="createTime") | |||||
| private Date createTime; | |||||
| @io.swagger.annotations.ApiModelProperty(value="更新时间",name="updateTime") | |||||
| private Date updateTime; | |||||
| @io.swagger.annotations.ApiModelProperty(value="备注",name="remark") | |||||
| private String remark; | |||||
| @io.swagger.annotations.ApiModelProperty(value="0-有效 1-无效",name="status") | |||||
| private Integer status; | |||||
| } | |||||
| @@ -0,0 +1,14 @@ | |||||
| package com.iformall.mapper; | |||||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||||
| import com.iformall.domain.po.WxMerchantOcrModel; | |||||
| import java.util.List; | |||||
| import org.apache.ibatis.annotations.Mapper; | |||||
| @Mapper | |||||
| public interface WxMerchantOcrModelMapper extends BaseMapper<WxMerchantOcrModel> { | |||||
| List<WxMerchantOcrModel> findList(WxMerchantOcrModel merchantOcrModel); | |||||
| } | |||||
| @@ -0,0 +1,14 @@ | |||||
| package com.iformall.mapper; | |||||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||||
| import com.iformall.domain.po.WxOcrModel; | |||||
| import java.util.List; | |||||
| import org.apache.ibatis.annotations.Mapper; | |||||
| @Mapper | |||||
| public interface WxOcrModelMapper extends BaseMapper<WxOcrModel> { | |||||
| List<WxOcrModel> findList(WxOcrModel ocrModel); | |||||
| } | |||||
| @@ -0,0 +1,30 @@ | |||||
| package com.iformall.service; | |||||
| import com.github.pagehelper.PageInfo; | |||||
| import com.iformall.common.ResultData; | |||||
| import com.iformall.domain.po.WxActivity; | |||||
| import com.iformall.domain.po.WxMerchantOcrModel; | |||||
| import com.iformall.domain.po.WxOcrModel; | |||||
| import com.iformall.enums.EnumPayWay; | |||||
| import java.util.List; | |||||
| import javax.servlet.http.HttpServletResponse; | |||||
| /** | |||||
| * @author gongbiao | |||||
| */ | |||||
| public interface WxOcrService { | |||||
| PageInfo<WxOcrModel> listOcrModelAsPage(WxOcrModel record, Integer pageIndex, Integer pageSize); | |||||
| WxOcrModel getOcrModelById(Long id); | |||||
| ResultData saveOrUpdateOcrModel(WxOcrModel record); | |||||
| WxMerchantOcrModel getMerchantOcrModel(Long merchantId,String tenantId,String parentTenantId); | |||||
| ResultData saveOrUpdateMerchantOcrModel(WxMerchantOcrModel record); | |||||
| ResultData deleteMerchantOcrModel(Long id); | |||||
| } | |||||
| @@ -0,0 +1,89 @@ | |||||
| package com.iformall.service.impl; | |||||
| import com.github.pagehelper.PageHelper; | |||||
| import com.github.pagehelper.PageInfo; | |||||
| import com.iformall.common.IdWorker; | |||||
| import com.iformall.common.Result; | |||||
| import com.iformall.common.ResultData; | |||||
| import com.iformall.domain.po.WxMerchantOcrModel; | |||||
| import com.iformall.domain.po.WxOcrModel; | |||||
| import com.iformall.mapper.WxMerchantOcrModelMapper; | |||||
| import com.iformall.mapper.WxOcrModelMapper; | |||||
| import com.iformall.service.WxOcrService; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Service; | |||||
| import java.util.Date; | |||||
| import java.util.List; | |||||
| @Service | |||||
| public class WxOcrServiceImpl implements WxOcrService { | |||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
| @Autowired | |||||
| WxMerchantOcrModelMapper merchantOcrModelMapper; | |||||
| @Autowired | |||||
| WxOcrModelMapper ocrModelMapper; | |||||
| @Override | |||||
| public PageInfo<WxOcrModel> listOcrModelAsPage(WxOcrModel record, Integer pageIndex, Integer pageSize) { | |||||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> ocrModelMapper.findList(record)); | |||||
| } | |||||
| @Override | |||||
| public WxOcrModel getOcrModelById(Long id) { | |||||
| return ocrModelMapper.selectById(id); | |||||
| } | |||||
| @Override | |||||
| public ResultData saveOrUpdateOcrModel(WxOcrModel record) { | |||||
| Date date = new Date(); | |||||
| if (record.getId() == null) { | |||||
| final IdWorker idWorker = IdWorker.get(); | |||||
| record.setId(idWorker.nextId()); | |||||
| record.setCreateTime(date); | |||||
| ocrModelMapper.insert(record); | |||||
| } else { | |||||
| record.setUpdateTime(date); | |||||
| ocrModelMapper.updateById(record); | |||||
| } | |||||
| return new ResultData(Result.SUCCESS, "操作成功"); | |||||
| } | |||||
| @Override | |||||
| public WxMerchantOcrModel getMerchantOcrModel(Long merchantId,String tenantId,String parentTenantId) { | |||||
| WxMerchantOcrModel query = new WxMerchantOcrModel(); | |||||
| query.setMerchantId(merchantId); | |||||
| query.setTenantId(tenantId); | |||||
| query.setParentTenantId(parentTenantId); | |||||
| List<WxMerchantOcrModel> models = merchantOcrModelMapper.findList(query); | |||||
| if (null == models || models.size() <= 0) { | |||||
| return null; | |||||
| } | |||||
| return models.get(0); | |||||
| } | |||||
| @Override | |||||
| public ResultData saveOrUpdateMerchantOcrModel(WxMerchantOcrModel record) { | |||||
| Date date = new Date(); | |||||
| if (record.getId() == null) { | |||||
| final IdWorker idWorker = IdWorker.get(); | |||||
| record.setId(idWorker.nextId()); | |||||
| record.setCreateTime(date); | |||||
| merchantOcrModelMapper.insert(record); | |||||
| } else { | |||||
| record.setUpdateTime(date); | |||||
| merchantOcrModelMapper.updateById(record); | |||||
| } | |||||
| return new ResultData(Result.SUCCESS, "操作成功"); | |||||
| } | |||||
| @Override | |||||
| public ResultData deleteMerchantOcrModel(Long id) { | |||||
| merchantOcrModelMapper.deleteById(id); | |||||
| return new ResultData(Result.SUCCESS, "操作成功"); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,57 @@ | |||||
| <?xml version="1.0" encoding="UTF-8"?> | |||||
| <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
| <mapper namespace="com.iformall.mapper.WxMerchantOcrModelMapper"> | |||||
| <resultMap type="com.iformall.domain.po.WxMerchantOcrModel" id="BaseResultMap"> | |||||
| <result property="id" column="id"/> | |||||
| <result property="tenantId" column="tenant_id" jdbcType="VARCHAR"/> | |||||
| <result property="parentTenantId" column="parent_tenant_id" jdbcType="VARCHAR"/> | |||||
| <result property="merchantId" column="merchant_id" jdbcType="BIGINT"/> | |||||
| <result property="ocrModelId" column="ocr_model_id" jdbcType="BIGINT"/> | |||||
| <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/> | |||||
| <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/> | |||||
| </resultMap> | |||||
| <sql id="allColumns"> | |||||
| id,tenant_id,parent_tenant_id,merchant_id,ocr_model_id,create_time,update_time | |||||
| </sql> | |||||
| <sql id="dynamicWhereConditions"> | |||||
| where 1 = 1 | |||||
| <if test=" null != id "> | |||||
| and `id` = #{id} | |||||
| </if> | |||||
| <if test=" null != tenantId and '' != tenantId"> | |||||
| and `tenant_id` = #{tenantId} | |||||
| </if> | |||||
| <if test=" null != parentTenantId and '' != parentTenantId"> | |||||
| and `parent_tenant_id` = #{parentTenantId} | |||||
| </if> | |||||
| <if test=" null != merchantId "> | |||||
| and `merchant_id` = #{merchantId} | |||||
| </if> | |||||
| <if test=" null != ocrModelId "> | |||||
| and `ocr_model_id` = #{ocrModelId} | |||||
| </if> | |||||
| <if test=" null != ids "> | |||||
| and id in | |||||
| <foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | |||||
| #{idItem} | |||||
| </foreach> | |||||
| </if> | |||||
| <if test=" null != sortColumns">order by ${sortColumns}</if> | |||||
| </sql> | |||||
| <select id="findList" parameterType="com.iformall.domain.po.WxMerchantOcrModel" resultMap="BaseResultMap"> | |||||
| select | |||||
| <include refid="allColumns"/> | |||||
| from wx_merchant_ocr_model | |||||
| <include refid="dynamicWhereConditions"/> | |||||
| </select> | |||||
| </mapper> | |||||
| @@ -0,0 +1,54 @@ | |||||
| <?xml version="1.0" encoding="UTF-8"?> | |||||
| <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
| <mapper namespace="com.iformall.mapper.WxOcrModelMapper"> | |||||
| <resultMap type="com.iformall.domain.po.WxOcrModel" id="BaseResultMap"> | |||||
| <result property="id" column="id"/> | |||||
| <result property="langCode" column="lang_code" jdbcType="VARCHAR"/> | |||||
| <result property="fontName" column="font_name" jdbcType="VARCHAR"/> | |||||
| <result property="remark" column="remark" jdbcType="VARCHAR"/> | |||||
| <result property="status" column="status" jdbcType="INTEGER"/> | |||||
| <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/> | |||||
| <result property="update_time" column="updateTime" jdbcType="TIMESTAMP"/> | |||||
| </resultMap> | |||||
| <sql id="allColumns"> | |||||
| id,lang_code,font_name,remark,status,create_time,updateTime | |||||
| </sql> | |||||
| <sql id="dynamicWhereConditions"> | |||||
| where 1 = 1 | |||||
| <if test=" null != id "> | |||||
| and `id` = #{id} | |||||
| </if> | |||||
| <if test=" null != langCode and '' != langCode"> | |||||
| and `lang_code` = #{langCode} | |||||
| </if> | |||||
| <if test=" null != fontName and '' != fontName"> | |||||
| and `font_name` = #{fontName} | |||||
| </if> | |||||
| <if test=" null != status "> | |||||
| and `status` = #{status} | |||||
| </if> | |||||
| <if test=" null != ids "> | |||||
| and id in | |||||
| <foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | |||||
| #{idItem} | |||||
| </foreach> | |||||
| </if> | |||||
| <if test=" null != sortColumns">order by ${sortColumns}</if> | |||||
| </sql> | |||||
| <select id="findList" parameterType="com.iformall.domain.po.WxOcrModel" resultMap="BaseResultMap"> | |||||
| select | |||||
| <include refid="allColumns"/> | |||||
| from wx_ocr_model | |||||
| <include refid="dynamicWhereConditions"/> | |||||
| </select> | |||||
| </mapper> | |||||