| @@ -47,13 +47,15 @@ | |||
| <version>5.2.4</version> | |||
| </dependency> | |||
| <!-- https://mvnrepository.com/artifact/net.sourceforge.tess4j/tess4j --> | |||
| <!-- ocr --> | |||
| <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> | |||
| </dependencies> | |||
| <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> | |||
| <artifactId>mallinkService</artifactId> | |||
| <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> | |||
| </dependencies> | |||
| <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> | |||
| </dependencies> | |||
| </project> | |||
| @@ -80,6 +80,7 @@ public class FormallTess4jTrain { | |||
| System.out.println(trainCmdstr); | |||
| //executeLocalCmd(trainCmdstr, null); | |||
| //此处可以批量开始 | |||
| String extractorCmdstr = "unicharset_extractor "+prefix+".box"; | |||
| System.out.println(extractorCmdstr); | |||
| //executeLocalCmd(extractorCmdstr, null); | |||
| @@ -95,6 +96,7 @@ public class FormallTess4jTrain { | |||
| String cntrainCmdstr = "cntraining "+prefix+".tr"; | |||
| System.out.println(cntrainCmdstr); | |||
| //executeLocalCmd(cntrainCmdstr, null); | |||
| //批量结束 | |||
| //System.out.println("DONE createTrainFiles !"); | |||
| } | |||
| @@ -35,14 +35,6 @@ | |||
| <artifactId>mybatis-multi-tenancy</artifactId> | |||
| <version>1.0</version> | |||
| </dependency> | |||
| <!-- ocr --> | |||
| <dependency> | |||
| <groupId>com.iformall</groupId> | |||
| <artifactId>mallinkOcr</artifactId> | |||
| <version>1.0</version> | |||
| </dependency> | |||
| </dependencies> | |||
| </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> | |||