4个文件已添加
19个文件已修改
1021 ■■■■ 已修改文件
WebRoot/WEB-INF/web.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/js/index/funcLink.js 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/js/panel.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/api/schedule/AppVersion.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/base/action/CrmController.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/base/entity/T482104Entity.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/base/service/CrmServiceIfc.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/base/service/CrmServiceImpl.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/clues/action/CluesController.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/clues/entity/AssignCluesEntity.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/clues/entity/ContactEntity.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/clues/entity/T481101Entity.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/clues/service/CluesServiceIfc.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/clues/service/CluesServiceImpl.java 124 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/mail/action/MailController.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/mail/listener/EmailImageFilter.java 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/mail/service/MailFileIfc.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/mail/service/MailFileImpl.java 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/mail/service/MailIfc.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/mail/service/MailImpl.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/mail/service/MailServiceIfc.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/crm/mail/service/MailServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/entity/ImageUrlParametersEntity.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/WEB-INF/web.xml
@@ -196,6 +196,16 @@
</filter-mapping>
<filter>
    <filter-name>mailImageFilter</filter-name>
    <filter-class>com.yc.crm.mail.listener.EmailImageFilter</filter-class>
    <async-supported>true</async-supported>
</filter>
<filter-mapping>
    <filter-name>mailImageFilter</filter-name>
    <url-pattern>/uploads/email/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>formidFilter</filter-name>
    <filter-class>com.yc.action.build.FormidFilter</filter-class>
    <async-supported>true</async-supported>
WebRoot/js/index/funcLink.js
@@ -1585,16 +1585,16 @@
    var wp = $.trim(strPam).length > 0 ? ("wherePan=" + strPam) : "";
    let wp = $.trim(strPam).length > 0 ? (strPam) : "";
    if (ef != undefined && ef != null && ef != "")
        wp = (wp == "") ? "wherePan=" + encodeURI(encodeURI(ef)) : wp + " and "
        wp = (wp == "") ?  encodeURI(encodeURI(ef)) : wp + " and "
            + encodeURI(encodeURI(ef));
    try {
        closeLoading();
        parent.addTab("", f, t, wp);
        parent.addTab("", f, t, "wherePan=" +encodeURIComponent(wp));
    } catch (e) {
        closeLoading();
        showWindow("/app" + spellPath + f + "/" + t + "/index.jsp?" + wp, "");
        showWindow("/app" + spellPath + f + "/" + t + "/index.jsp?" + "wherePan=" +wp, "");
    }
}
WebRoot/js/panel.js
@@ -2574,7 +2574,8 @@
                    if(ben10.length==bwai10.length){
                        for(j = 0; j < ben10.length; j++){
                            if(xinxi[0] == bwai10[j] && xinxi[1] != ""){
                                setDoc(ben10[j], ".value= '" + xinxi[1] + "'");
                                //这里要把id转成小写,不然赋值会出问题 xin 2024-9-19 13:55:51
                                setDoc(ben10[j].toLowerCase(), ".value= '" + xinxi[1] + "'");
                            }
                        }
                    }else{//抛出提示
src/com/yc/api/schedule/AppVersion.java
@@ -6,4 +6,5 @@
public class AppVersion {
    String android;
    String ios;
    String hmos;//dev
}
src/com/yc/crm/base/action/CrmController.java
@@ -45,7 +45,7 @@
        CallBackMessage callBackMessage = new CallBackMessage();
        try {
            SpObserver.setDBtoInstance("_" + request.getSession().getAttribute(SessionKey.DATA_BASE_ID));
            callBackMessage.setInfo(crmServiceIfc.getBaseInfo(request.getSession().getAttribute(SessionKey.USERCODE) + ""));
            callBackMessage.setInfo(crmServiceIfc.getBaseInfo(request.getSession()));
            callBackMessage.sendSuccessMessageByDefault();
            return callBackMessage.toJSONObject();
        } catch (Exception e) {
@@ -55,7 +55,27 @@
            SpObserver.setDBtoInstance();
        }
    }
    /**
     * 获取系统的邮箱及姓名(用户,客户,线索)
     *
     * @param request
     * @return
     */
    @RequestMapping("/emailList.do")
    public @ResponseBody Object mailUserInfo(@RequestBody @Nullable Page page, HttpServletRequest request) {
        CallBackMessage callBackMessage = new CallBackMessage();
        try {
            SpObserver.setDBtoInstance("_" + request.getSession().getAttribute(SessionKey.DATA_BASE_ID));
            callBackMessage.setInfo(crmServiceIfc.getMailUserInfo(page.getKey()));
            callBackMessage.sendSuccessMessageByDefault();
            return callBackMessage.toJSONObject();
        } catch (Exception e) {
            callBackMessage.sendErrorMessage(this.getErrorMsg(e));
            return callBackMessage.toJSONObject();
        } finally {
            SpObserver.setDBtoInstance();
        }
    }
    /**
     * 获取用户,以部门分组树形结构显示
     *
src/com/yc/crm/base/entity/T482104Entity.java
@@ -12,6 +12,7 @@
    private Integer id;
    private String comment;
    private String attachList;
    private String imageList;
    private String createTime;
    private String senders;//通知人员
    private String updateTime;
@@ -19,4 +20,5 @@
    private Integer pageCount;
    private Integer enableFlag;//是否可编辑和删除
    private List<FileEntity> files;
    private List<FileEntity> imageFiles;
}
src/com/yc/crm/base/service/CrmServiceIfc.java
@@ -8,7 +8,7 @@
public interface CrmServiceIfc {
    Map getBaseInfo(String userCode);
    Map getBaseInfo(HttpSession session);
    Object getUserInfo(HttpSession session, Page page);
@@ -41,4 +41,6 @@
    void commentDel(Integer id);
    List<T482112Entity> listByMonth(String date,String dbi,String formid);
    Object getMailUserInfo(String key);
}
src/com/yc/crm/base/service/CrmServiceImpl.java
@@ -8,6 +8,7 @@
import com.yc.exception.ApplicationException;
import com.yc.service.BaseService;
import com.yc.utils.DateUtil;
import com.yc.utils.SessionKey;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
@@ -27,8 +28,10 @@
@Service
public class CrmServiceImpl extends BaseService implements CrmServiceIfc {
    @Override
    public Map getBaseInfo(String userCode) {
    public Map getBaseInfo(HttpSession session) {
        String userCode=session.getAttribute(SessionKey.USERCODE).toString();
        HashMap map = new HashMap();
        map.put("isAdmin", ("SuperUser".equalsIgnoreCase(session.getAttribute(SessionKey.USERTYPE) + "") || "DeveloperUser".equalsIgnoreCase(session.getAttribute(SessionKey.USERTYPE) + "")) ? 1 : 0);
        //----系统参数
        List<SysdictEntity> list = this.jdbcTemplate.query("select dictid,interValue as id,dictvalue as name from _sysdict where dictid in(-48013000,-48013001,-48013002,-48013003,-48013004,-48013005,-48013006,-48013007,-48013008,-48013009,-48013010,-48013011,-48013012,-48013013,-48013014,-48013015)\n" +
                "order by dictid desc,sequence\n ", new BeanPropertyRowMapper<>(SysdictEntity.class));
@@ -101,12 +104,24 @@
    }
    @Override
    public Object getMailUserInfo(String key) {
            //--取用户
          String  sql = " select ccCode,ccName,userCode,userName,email from _sysuser  where email like '%" + key + "%' or userName like '%" + key + "%' \n" +
                    "union all\n" +
                    //--取联系人(线索,客户)
                    " select '' as ccCode,'' as ccName,'' as userCode,name as userName,email from t482103 where email like '%" + key + "%' or name like '%" + key + "%'\n";
        List<UserEntity> query = this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(UserEntity.class));
        return query;
    }
    @Override
    public Object getUserInfo(HttpSession session, Page page) {
        // String ccCode = (String) session.getAttribute(SessionKey.CCCODE);
        String where = "";
        if (page != null && StringUtils.isNotBlank(page.getKey())) {
            where = " where email like '%" + page.getKey() + "%' or userName like '%" + page.getKey() + "%'";
            where = " where ccCode='"+page.getKey()+"' or email like '%" + page.getKey() + "%' or userName like '%" + page.getKey() + "%'";
        }
        String sql = " select ccCode,ccName,userCode,userName,email from _sysuser " + where + "order by ccCode asc";
        List<UserEntity> query = this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(UserEntity.class));
@@ -426,6 +441,7 @@
                ",@id int     \n" +
                ",@comment varchar(3000)  \n" +
                ",@attachList varchar(300)  \n" +
                ",@imageList varchar(300)  \n" +
                ",@senders varchar(300)  \n" +
                ",@createTime datetime\n" +
                ",@updateTime datetime\n" +
@@ -436,6 +452,7 @@
                "@id=" + entity.getId() + ",   \n" +
                "@comment=" + GridUtils.prossSqlParm(entity.getComment()) + "      ,\n" +
                "@attachList=" + GridUtils.prossSqlParm(entity.getAttachList()) + "      ,\n" +
                "@imageList=" + GridUtils.prossSqlParm(entity.getImageList()) + "      ,\n" +
                "@senders=" + GridUtils.prossSqlParm(entity.getSenders()) + "      ,\n" +
                "@createTime=getdate(),\n" +
                "@updateTime=getdate()\n" +
@@ -447,6 +464,7 @@
                ",refId  \n" +
                ",comment \n" +
                ",attachList\n" +
                ",imageList\n" +
                ",senders\n" +
                ",createTime\n" +
                ",updateTime)values(" +
@@ -455,6 +473,7 @@
                ",@refId  \n" +
                ",@comment\n" +
                ",@attachList\n" +
                ",@imageList\n" +
                ",@senders\n" +
                ",@createTime\n" +
                ",@updateTime)" +
@@ -467,6 +486,7 @@
                ",refId=@refId  \n" +
                ",comment=@comment \n" +
                ",attachList=@attachList\n" +
                ",imageList=@imageList\n" +
                ",senders=@senders\n" +
                ",updateTime=@updateTime where id=@id\n" +
                "end\n";
@@ -936,6 +956,8 @@
                ",id,refCode,refName       \n" +
                ",title         \n" +
                ",color         \n" +
                ",userCode         \n" +
                ",userName         \n" +
                ",participant_id\n" +
                ",start_time    \n" +
                ",end_time      \n" +
@@ -950,6 +972,8 @@
                ",num        " +
                ",create_time   \n" +
                ",update_time   \n" +
                ",pinFlag   \n" +
                ",completeFlag   \n" +
                ",@TotalRowCount as totalRowCount ,@pageCount as pageCount       ";
        String sql = "set nocount on ; \n" +
@@ -1000,6 +1024,7 @@
                " id,       \n" +
                "comment,   \n" +
                "attachList,\n" +
                "imageList,\n" +
                "convert(varchar(19), createTime,120) as createTime,senders,\n" +
                "convert(varchar(19), updateTime,120)  as updateTime" +
                ",case when usercode=@usercode then 1 else 0 end as enableFlag,@TotalRowCount as totalRowCount ,@pageCount as pageCount       ";
@@ -1026,6 +1051,13 @@
                fileStructEntity.setFileStr(x.getAttachList());
                x.setFiles(Utils.getFileEntities(fileStructEntity));
            }
            if (StringUtils.isNotBlank(x.getImageList())) {
                FileStructEntity fileStructEntity = new FileStructEntity();
                fileStructEntity.setDbid(request.getDbid());
                fileStructEntity.setFormid(request.getFormId() + "");
                fileStructEntity.setFileStr(x.getImageList());
                x.setImageFiles(Utils.getFileEntities(fileStructEntity));
            }
        });
        Response response = new Response();
        response.setTotalCount((list != null && list.size() > 0) ? list.get(0).getTotalRowCount() : 0);
src/com/yc/crm/clues/action/CluesController.java
@@ -32,7 +32,27 @@
        CallBackMessage callBackMessage = new CallBackMessage();
        try {
            SpObserver.setDBtoInstance("_" + request.getSession().getAttribute(SessionKey.DATA_BASE_ID));
           cluesServiceIfc.assign(assignClues);
           cluesServiceIfc.assign(assignClues,request.getSession().getAttribute(SessionKey.USERNAME)+"");
            callBackMessage.sendSuccessMessageByDefault();
            return callBackMessage.toJSONObject();
        }catch (Exception e){
            callBackMessage.sendErrorMessage(this.getErrorMsg(e));
            return callBackMessage.toJSONObject();
        }finally {
            SpObserver.setDBtoInstance();
        }
    }
    /**
     * 新分配线索
     * @param request
     * @return
     */
    @RequestMapping("/newAssign.do")
    public @ResponseBody Object newAssign(@RequestBody AssignCluesEntity assignClues, HttpServletRequest request){
        CallBackMessage callBackMessage = new CallBackMessage();
        try {
            SpObserver.setDBtoInstance("_" + request.getSession().getAttribute(SessionKey.DATA_BASE_ID));
            cluesServiceIfc.newAssign(assignClues);
            callBackMessage.sendSuccessMessageByDefault();
            return callBackMessage.toJSONObject();
        }catch (Exception e){
@@ -128,6 +148,74 @@
        }
    }
    /**
     * 删除线索
     *
     * @param request
     * @return
     */
    @RequestMapping("/del.do")
    public @ResponseBody Object cluesDel(String docCode, HttpServletRequest request) {
        CallBackMessage callBackMessage = new CallBackMessage();
        try {
            SpObserver.setDBtoInstance("_" + request.getSession().getAttribute(SessionKey.DATA_BASE_ID));
            cluesServiceIfc.cluesDel(docCode);
            callBackMessage.sendSuccessMessageByDefault();
            return callBackMessage.toJSONObject();
        } catch (Exception e) {
            callBackMessage.sendErrorMessage(this.getErrorMsg(e));
            return callBackMessage.toJSONObject();
        } finally {
            SpObserver.setDBtoInstance();
        }
    }
    /**
     * 无效线索
     *
     * @param request
     * @return
     */
    @RequestMapping("/fail.do")
    public @ResponseBody Object cluesFail(@RequestBody T481104Entity entity, HttpServletRequest request) {
        CallBackMessage callBackMessage = new CallBackMessage();
        try {
            SpObserver.setDBtoInstance("_" + request.getSession().getAttribute(SessionKey.DATA_BASE_ID));
            cluesServiceIfc.cluesFail(entity);
            callBackMessage.sendSuccessMessageByDefault();
            return callBackMessage.toJSONObject();
        } catch (Exception e) {
            callBackMessage.sendErrorMessage(this.getErrorMsg(e));
            return callBackMessage.toJSONObject();
        } finally {
            SpObserver.setDBtoInstance();
        }
    }
    /**
     * 线索联系人列表
     * @param request
     * @return
     */
    @RequestMapping("/contactList.do")
    public @ResponseBody Object contactList(@RequestBody CluesRequestEntity cluesRequest, HttpServletRequest request){
        CallBackMessage callBackMessage = new CallBackMessage();
        try {
            SpObserver.setDBtoInstance("_" + request.getSession().getAttribute(SessionKey.DATA_BASE_ID));
            cluesRequest.setDbid(request.getSession().getAttribute(SessionKey.DATA_BASE_ID)+"");
            //当前用户
            cluesRequest.setCreateUsercode(request.getSession().getAttribute(SessionKey.USERCODE)+"");
            //所属部门
            cluesRequest.setCccode(request.getSession().getAttribute(SessionKey.CCCODE)+"");
            cluesRequest.setFormId(481101);
            callBackMessage.setInfo(cluesServiceIfc.contactList(cluesRequest));
            callBackMessage.sendSuccessMessageByDefault();
            return callBackMessage.toJSONObject();
        }catch (Exception e){
            callBackMessage.sendErrorMessage(this.getErrorMsg(e));
            return callBackMessage.toJSONObject();
        }finally {
            SpObserver.setDBtoInstance();
        }
    }
    /**
     * 线索列表
     * @param request
     * @return
@@ -138,6 +226,10 @@
        try {
            SpObserver.setDBtoInstance("_" + request.getSession().getAttribute(SessionKey.DATA_BASE_ID));
            cluesRequest.setDbid(request.getSession().getAttribute(SessionKey.DATA_BASE_ID)+"");
            //当前用户
            cluesRequest.setCreateUsercode(request.getSession().getAttribute(SessionKey.USERCODE)+"");
            //所属部门
            cluesRequest.setCccode(request.getSession().getAttribute(SessionKey.CCCODE)+"");
            cluesRequest.setFormId(481101);
            callBackMessage.setInfo(cluesServiceIfc.getAllClues(cluesRequest));
            callBackMessage.sendSuccessMessageByDefault();
@@ -165,6 +257,8 @@
            clues.setCompanyname(request.getSession().getAttribute(SessionKey.COMPANY_NAME)+"");
            clues.setCreateUsercode(request.getSession().getAttribute(SessionKey.USERCODE)+"");
            clues.setCreateUserName(request.getSession().getAttribute(SessionKey.USERNAME)+"");
            clues.setCcCode(request.getSession().getAttribute(SessionKey.CCCODE)+"");
            clues.setCcName(request.getSession().getAttribute(SessionKey.CCNAME)+"");
            clues.setFormId(481101);
                cluesServiceIfc.save(clues);
            callBackMessage.sendSuccessMessageByDefault();
src/com/yc/crm/clues/entity/AssignCluesEntity.java
@@ -10,4 +10,6 @@
    private String docCode;//线索编号
    private String ownerCode;//分配给谁
    private String ownerName;//分配给谁
    private String ownerCcCode;//分配给谁
    private String ownerCcName;//分配给谁
}
src/com/yc/crm/clues/entity/ContactEntity.java
New file
@@ -0,0 +1,9 @@
package com.yc.crm.clues.entity;
import lombok.Data;
@Data
public class ContactEntity {
    private String docCode,cluesName,name,email;
    private  int totalRowCount,pageCount;
}
src/com/yc/crm/clues/entity/T481101Entity.java
@@ -34,7 +34,6 @@
    private Integer lastprintnum;
    private Integer lastprintformid;
    private Integer lastprintdocstatus;
    private String cccode;
    private String cltCode;
    private String cltName;
    private String honorific;
src/com/yc/crm/clues/service/CluesServiceIfc.java
@@ -11,7 +11,7 @@
    Response getAllClues(CluesRequestEntity request);
    void assign(AssignCluesEntity assignClues);
    void assign(AssignCluesEntity assignClues,String userName);
    void attention(CluesRequestEntity cluesRequest);
@@ -20,4 +20,12 @@
    void contactDel(Integer id);
    T481101Entity get(CluesRequestEntity cluesRequest);
    void cluesDel(String docCode);
    void cluesFail(T481104Entity entity);
    Response contactList(CluesRequestEntity cluesRequest);
    void newAssign(AssignCluesEntity assignClues);
}
src/com/yc/crm/clues/service/CluesServiceImpl.java
@@ -36,6 +36,8 @@
                "    @DocStatusName            varchar(50),\n" +
                "    @companyid                nvarchar(20),\n" +
                "    @companyname              varchar(50),\n" +
                "    @ccCode                varchar(20),\n" +
                "    @ccName                varchar(50),\n" +
                "    @EnterCode                varchar(20),\n" +
                "    @EnterName                varchar(50),\n" +
                "    @EnterDate                datetime,\n" +
@@ -117,6 +119,8 @@
                "@DocCode=" + GridUtils.prossSqlParm(t481101Entity.getDocCode()) + ",         \n" +
                "@companyid=" + GridUtils.prossSqlParm(t481101Entity.getCompanyid()) + ",         \n" +
                "@companyname= " + GridUtils.prossSqlParm(t481101Entity.getCompanyname()) + ",         \n" +
                "@ccCode=" + GridUtils.prossSqlParm(t481101Entity.getCcCode()) + ",         \n" +
                "@ccName= " + GridUtils.prossSqlParm(t481101Entity.getCcName()) + ",         \n" +
                "@periodid= dbo.GetPeriodID(@FormID,@CompanyID,getdate()),          \n" +
                "@EnterCode=" + GridUtils.prossSqlParm(t481101Entity.getCreateUsercode()) + ",         \n" +
                "@EnterName=" + GridUtils.prossSqlParm(t481101Entity.getCreateUserName()) + " ,        \n" +
@@ -168,6 +172,8 @@
                ",DocCode" +
                ",companyid" +
                ",companyname" +
                ",ccCode" +
                ",ccName" +
                ",periodid" +
                ",EnterCode" +
                ",EnterName" +
@@ -215,6 +221,8 @@
                ",@DocCode" +
                ",@companyid" +
                ",@companyname" +
                ",@ccCode" +
                ",@ccName" +
                ",@periodid" +
                ",@EnterCode" +
                ",@EnterName" +
@@ -258,7 +266,7 @@
                ",@pin_flag,'起草' " +
                ")\n" +
                //----处理联系人信息
                contactAddSql(t481101Entity.getContactsList()) +
                contactAddSql(t481101Entity.getContactsList(),"线索") +
                "end\n" +
                "else \n" +//-------修改
                "begin\n" +
@@ -292,7 +300,7 @@
                ",category_ids=@category_ids" +
                ",inquiry_country=@inquiry_country,pin_flag=@pin_flag from t481101H where doccode=@doccode\n" +
                //----处理联系人信息
                contactUpdateSql(t481101Entity.getContactsList()) +
                contactUpdateSql(t481101Entity.getContactsList(),"线索") +
                "end\n" +
                //--处理审计功能
                auditAddSql(t481101Entity);
@@ -312,6 +320,46 @@
        return sql;
    }
    @Override
    public Response contactList(CluesRequestEntity request) {
        String fileds = " " +
                "c.refCode,c.id,a.docCode,a.clues_name           \n" +
                ",c.name              \n" +
                ",c.email             \n" +
                ",@TotalRowCount as totalRowCount ,@pageCount as pageCount              \n";
        String where = " contactType='线索' ";
        if (request.getSearchTxt() != null && request.getSearchTxt().size() > 0) {
            //拼接查询条件
            where += getSearchInfo(request);
        }
        String sql = "set nocount on ; \n" +
//                "                 declare @key varchar(300)  \n" +
//                "                 select @key ="+1+" \n" +
                "                 declare @Limit int , @Page int ,@StartRowNo int ,@EndRowNo int ; \n" +
                "                 select @Limit  = " + request.getPageSize() + " , @Page  = " + request.getPageNo() + "  ; \n" +
                "                 declare @TotalRowCount int ,@pageCount int; \n" +
                " select @StartRowNo = (isnull(@Page,0) - 1) * isnull(@Limit,0) + 1 ; \n" +
                " select @EndRowNo = isnull(@Page,0) * isnull(@Limit,0) ; \n" +
                " select @TotalRowCount =count(1),@pageCount=CEILING((COUNT(1)+0.0)/" + request.getPageSize() + ")  from t482103 c \n" +
                " left join t481101h a on a.docCode=c.refCode\n" +
                " left join t481104h b on a.docCode=b.refCode" +
                " where " + where + " \n" +
                " SELECT * FROM ( \n" +
                " select top 100 percent ROW_NUMBER() OVER (ORDER BY  a.docCode) AS NO,\n" +
                fileds + "  from t482103 c \n" +
                " left join t481101h a on a.docCode=c.refCode\n" +
                " left join t481104h b on a.docCode=b.refCode" +
                " where " + where +
                " order by  a.docCode asc \n" +
                " ) t WHERE t.NO  BETWEEN @StartRowNo AND @EndRowNo";
        List<ContactEntity> list = this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ContactEntity.class));
        //增加联系人输出
        Response response = new Response();
        response.setTotalCount((list != null && list.size() > 0) ? list.get(0).getTotalRowCount() : 0);
        response.setPageCount((list != null && list.size() > 0) ? list.get(0).getPageCount() : 0);
        response.setData(list);
        return response;
    }
    @Override
    public Response getAllClues(CluesRequestEntity request) {
@@ -409,7 +457,7 @@
                " select @EndRowNo = isnull(@Page,0) * isnull(@Limit,0) ; \n" +
                " select @TotalRowCount =count(1),@pageCount=CEILING((COUNT(1)+0.0)/" + request.getPageSize() + ")  from t481101h a left join t481104h b on a.docCode=b.refCode where " + where + " \n" +
                " SELECT * FROM ( \n" +
                " select top 100 percent ROW_NUMBER() OVER (ORDER BY  docCode) AS NO,\n" +
                " select top 100 percent ROW_NUMBER() OVER (ORDER BY  a.docCode) AS NO,\n" +
                fileds + "  from t481101h a left join t481104h b on a.docCode=b.refCode\n" +
                " where " + where +
                " order by  a.docCode asc \n" +
@@ -463,6 +511,24 @@
        response.setPageCount((list != null && list.size() > 0) ? list.get(0).getPageCount() : 0);
        response.setData(list);
        return response;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cluesDel(String docCode) {
        //删除线索,需要把相关的联系人,跟进,日程,评论也删除
        String sql="declare @docCode varchar(50)="+ GridUtils.prossSqlParm(docCode)+"\n" +
                " exec p481101Del @docCode";
        this.doBaseExecute(sql);
    }
    @Override
    public void cluesFail(T481104Entity entity) {
        String sql="declare @docCode varchar(50)="+ GridUtils.prossSqlParm(entity.getDocCode())+",\n" +
                "@failStatus int=" +entity.getFailStatus()+",\n"+
                "@failStatusName varchar(50)="+ GridUtils.prossSqlParm(entity.getFailStatusName())+",\n" +
                "@failReason varchar(250)="+ GridUtils.prossSqlParm(entity.getFailReason())+"\n" +
                "update t481101h set fail_Status=@failStatus,fail_Status_Name=@failStatusName,fail_Reason=@failReason where docCode=@docCode\n";
        this.doBaseExecute(sql);
    }
    @Override
@@ -601,12 +667,35 @@
        String sql = "update a set a.pinFlag=" + cluesRequest.getPinFlag() + " from t481104h a where id=" + cluesRequest.getId();
        this.doBaseExecute(sql);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void newAssign(AssignCluesEntity assignClues) {
        if(StringUtils.isBlank(assignClues.getOwnerCode())&&StringUtils.isBlank(assignClues.getOwnerCcCode())){
            throw new ApplicationException("部门和用户不能都为空");
        }
        String sql = " declare @refCode varchar(20),@ownerCode varchar(20),@ownerName varchar(20)\n" +
                " ,@ownerCcCode varchar(20),@ownerCcName varchar(20),@ownerType int=0" +
                "select @refCode=" + GridUtils.prossSqlParm(assignClues.getDocCode()) + ",@ownerCode=" + GridUtils.prossSqlParm(assignClues.getOwnerCode()) + ",@ownerName=" + GridUtils.prossSqlParm(assignClues.getOwnerName()) + ",@ownerCcCode=" + GridUtils.prossSqlParm(assignClues.getOwnerCcCode()) + ",@ownerCcName=" + GridUtils.prossSqlParm(assignClues.getOwnerCcName()) + "\n";
        if(StringUtils.isNotBlank(assignClues.getOwnerCcCode())) {
            sql+=" select @ownerType=1 \n";//表示当前线索是分配到个人,而不是部门
        }
                sql+=" insert into t481104h(refCode          \n" +
                ",ownerCode        \n" +
                ",ownerName        \n" +
                ",ownerCcCode        \n" +
                ",ownerCcName        \n" +
                ",ownerType       \n" +
                ",enterTime       \n)values(@refCode,@ownerCode,@ownerName,@ownerType,getdate())";
        this.doBaseExecute(sql);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void assign(AssignCluesEntity assignClues) {
        String sql = " declare @refCode varchar(20),@ownerCode varchar(20),@ownerName varchar(20)\n" +
                "select @refCode=" + GridUtils.prossSqlParm(assignClues.getDocCode()) + ",@ownerCode=" + GridUtils.prossSqlParm(assignClues.getOwnerCode()) + ",@ownerName=" + GridUtils.prossSqlParm(assignClues.getOwnerName()) + "\n" +
    public void assign(AssignCluesEntity assignClues,String userName) {
        String sql = " declare @id int,@reasonForRollback nvarchar(300),@refCode varchar(20),@ownerCode varchar(20),@ownerName varchar(20)\n" +
                "select @refCode=" + GridUtils.prossSqlParm(assignClues.getDocCode()) + ",@ownerCode=" + GridUtils.prossSqlParm(assignClues.getOwnerCode()) + ",@ownerName=" + GridUtils.prossSqlParm(assignClues.getOwnerName()) + ",@reasonForRollback='线索已移出,原因:"+userName+"重新分配给"+assignClues.getOwnerName()+"'\n" +
                " select @id=id from t481104h where refCode=@refCode\n" +
                " update t481104h set exitTime=getDate(),reasonForRollback=@reasonForRollback where id=@id\n" +
                " insert into t481104h(refCode          \n" +
                ",ownerCode        \n" +
                ",ownerName        \n" +
@@ -627,7 +716,8 @@
     * @return
     */
    private String getSearchInfo(CluesRequestEntity request) {
        String where = " and(1=1  ";
        //自已创建或已发布给指定人员或属于当前部门
        String where = " and((((a.CreateUsercode="+GridUtils.prossSqlParm(request.getCreateUsercode())+" or (isnull(a.isPush,0)=1 and b.ownerCode="+GridUtils.prossSqlParm(request.getCreateUsercode())+")) and isnull(b.reasonForRollback,'')='') or b.ownerCcCode="+GridUtils.prossSqlParm(request.getCccode())+") \n";
        Set<Map.Entry<String, String>> entries = request.getSearchTxt().entrySet();
        for (Map.Entry<String, String> entry : entries) {
            if (entry.getKey().equalsIgnoreCase("cluesName")) {
@@ -640,7 +730,7 @@
                where += " and isnull(b.pinFlag,0)=" + entry.getValue();
            }
            if (entry.getKey().equalsIgnoreCase("ownerCode")) {
                where += " and b.ownerCode  like '%" + entry.getValue() + "%'";
                where += " and b.ownerCode  in (select list from getinstr( '" + entry.getValue() + "'))";
            }
            if (entry.getKey().equalsIgnoreCase("systemFlag")) {
                where += " and isnull(b.systemFlag,0) = " + entry.getValue() + "";
@@ -661,7 +751,7 @@
                where += " and a.originList like '%" + entry.getValue() + "%'";
            }
            if (entry.getKey().equalsIgnoreCase("createUsercode")) {
                where += " and a.createUsercode like '%" + entry.getValue() + "%'";
                where += " and a.createUsercode in (select list from getinstr( '" + entry.getValue() + "'))";
            }
            if (entry.getKey().equalsIgnoreCase("country")) {
                where += " and a.country = '" + entry.getValue() + "'";
@@ -669,13 +759,19 @@
            if (entry.getKey().equalsIgnoreCase("lastModifyTime")) {
                String[] value = entry.getValue().split(";");
                where += " and (b.lastModifyTime >= DATEADD(day, -" + value[0] + ", CAST(GETDATE() AS date))  )";//TODO 后期增加处理联系,未联系功能
                where += " and (b.lastModifyTime >= DATEADD(day, -" + value[0] + ", CAST(GETDATE() AS date))  )";
            }
            //TODO 后期增加处理联系,未联系功能
            //处理是查询我的线索还是所有线索
            //481101是公海线索,481104是私海线索
        }
        return where + " )";
    }
    private String contactUpdateSql(List<T482103Entity> contactsList) {
    public String contactUpdateSql(List<T482103Entity> contactsList,String contactType) {
        if (contactsList == null || contactsList.size() == 0) {
            return "";
        }
@@ -684,7 +780,7 @@
            if (StringUtils.isNotBlank(contact.getRefCode()) && contact.getId() == null) {
                List<T482103Entity> temp = new ArrayList<T482103Entity>();
                temp.add(contact);
                sql += contactAddSql(temp);
                sql += contactAddSql(temp,contactType);
                continue;
            }
            sql += "\nselect\n" +
@@ -740,7 +836,7 @@
     * @param contactsList
     * @return
     */
    private String contactAddSql(List<T482103Entity> contactsList) {
    public String contactAddSql(List<T482103Entity> contactsList,String contactType) {
        if (contactsList == null || contactsList.size() == 0) {
            return "";
        }
@@ -769,6 +865,7 @@
                    ",remark             \n" +
                    ",image_list \n" +
                    ",birth              \n" +
                    ",contactType        \n" +
                    ",post_grade         \n" +
                    ",create_time        \n" +
                    ",update_time        " +
@@ -782,6 +879,7 @@
                    ",@remark             \n" +
                    ",@contact_image_list \n" +
                    ",@birth              \n" +
                    ",'"+contactType+"'   \n" +
                    ",@post_grade         \n" +
                    ",@create_time        \n" +
                    ",@update_time        " +
src/com/yc/crm/mail/action/MailController.java
@@ -2,6 +2,7 @@
import com.yc.crm.mail.entity.*;
import com.yc.crm.mail.service.MailAccountIfc;
import com.yc.crm.mail.service.MailFileIfc;
import com.yc.crm.mail.service.MailIfc;
import com.yc.crm.mail.service.MailServiceIfc;
import com.yc.crm.mail.util.AllBackMsg;
@@ -47,6 +48,8 @@
    MailIfc emailIfc;
    @Autowired
    MailServiceIfc mailServiceIfc;
    @Autowired
    MailFileIfc mailFileIfc;
    private static final Pattern EMAIL_PATTERN =
            Pattern.compile("^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$");
@@ -85,7 +88,8 @@
     * @return
     */
    @GetMapping("/getMailList.do")
    public AllBackMsg getMailList(String mail, @RequestParam(defaultValue = "1") Integer mailType, boolean isNoRead, HttpServletRequest request, HttpServletResponse response) throws Exception {
    public AllBackMsg getMailList(String mail, @RequestParam(defaultValue = "1") Integer mailType,
                                  @RequestParam(defaultValue = "1") Integer page,@RequestParam(defaultValue = "20") Integer limit, boolean isNoRead, HttpServletRequest request, HttpServletResponse response) throws Exception {
        AllBackMsg msg = new AllBackMsg();
        try {
            if (StringUtils.isNotBlank(mail)) {
@@ -102,7 +106,7 @@
            }
            DataSourceEntity dataSourceEntity = MultiDataSource.getDataSourceMap(request);//获取数据源信息
            SpObserver.setDBtoInstance("_" + dataSourceEntity.getDbId());//切换数据源
            List<t482101HList> t482101HEntityList = emailIfc.getReceivingMailList(mail, mailType, isNoRead, userCode);
            List<t482101HList> t482101HEntityList = emailIfc.getReceivingMailList(mail, mailType, isNoRead, userCode,page,limit);
            if (t482101HEntityList.size() > 0) {
                msg.setSuccess("执行完成", t482101HEntityList);
            }
@@ -120,7 +124,8 @@
     * @return
     */
    @GetMapping("/getHandleMailList.do")
    public AllBackMsg getHandleMailList(String mail, HttpServletRequest request, HttpServletResponse response) throws Exception {
    public AllBackMsg getHandleMailList(String mail,@RequestParam(defaultValue = "1") Integer page,@RequestParam(defaultValue = "20") Integer limit,
                                        HttpServletRequest request, HttpServletResponse response) throws Exception {
        AllBackMsg msg = new AllBackMsg();
        try {
            if (StringUtils.isNotBlank(mail)) {
@@ -137,7 +142,7 @@
            }
            DataSourceEntity dataSourceEntity = MultiDataSource.getDataSourceMap(request);//获取数据源信息
            SpObserver.setDBtoInstance("_" + dataSourceEntity.getDbId());//切换数据源
            List<t482101HList> t482101HEntityList = emailIfc.getHandleMailList(mail, userCode);
            List<t482101HList> t482101HEntityList = emailIfc.getHandleMailList(mail, userCode,page,limit);
            if (t482101HEntityList.size() > 0) {
                msg.setSuccess("执行完成", t482101HEntityList);
            }
@@ -168,11 +173,11 @@
            if (t482101HEntity != null) {
                if (StringUtils.isNotBlank(t482101HEntity.getAttachmentList())) {//附件的处理
                    //获取到附件内容
                    List<AttachmentEntity> attachmentEntities = emailIfc.getAttachmentEntityList(t482101HEntity.getAttachmentList());
                    List<AttachmentEntity> attachmentEntities = mailFileIfc.getAttachmentEntityList(t482101HEntity.getAttachmentList());
                    List<String> list = new ArrayList<>();
                    if (attachmentEntities.size() > 0) {
                        for (AttachmentEntity a : attachmentEntities) {
                            list.add(shoppingImageServer + "/uploads/attachment/" + dataSourceEntity.getDbId() + "/482101/" + a.getUnid() + "@p@" + a.getPhysicalFile());
                            list.add(shoppingImageServer + "/uploads/email/" + dataSourceEntity.getDbId() + "/482101/" + a.getUnid() + "@p@" + a.getPhysicalFile());
                        }
                        t482101HEntity.setAttachmentPath(list);
                    }
src/com/yc/crm/mail/listener/EmailImageFilter.java
New file
@@ -0,0 +1,187 @@
package com.yc.crm.mail.listener;
import com.yc.crm.mail.service.MailFileIfc;
import com.yc.factory.FactoryBean;
import com.yc.sdk.shopping.entity.ImageEntity;
import com.yc.sdk.shopping.entity.ImageUrlParametersEntity;
import com.yc.sdk.shopping.util.SettingKey;
import org.apache.catalina.connector.ClientAbortException;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
/**
 * @BelongsProject: eCoWorksV3
 * @BelongsPackage: com.yc.crm.mail.listener
 * @author: xinyb
 * @CreateTime: 2024-09-14  17:10
 * @Description:
 */
@Component
public class EmailImageFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String reqUri = request.getRequestURI();
        String hostUrl = SettingKey.getHostUrl(request);
        String queryString = request.getQueryString();
        HttpSession session = request.getSession();
        String rootPath = session.getServletContext().getRealPath("/");
        ImageUrlParametersEntity imageUrlParametersEntity = getImageUrlParameters(reqUri);
        File file = new File(rootPath.substring(0, rootPath.length() - 1) + reqUri);
        try {
            if (file != null && file.exists()) {
                filterChain.doFilter(request, response);
                return;
            }
            MailFileIfc mailFileIfc= (MailFileIfc) FactoryBean.getBean("MailFileImpl");
            ImageEntity image = mailFileIfc.getImageFile(
                    imageUrlParametersEntity.getUnids(),
                    imageUrlParametersEntity.getWidth(),
                    imageUrlParametersEntity.getHeight(),
                    (imageUrlParametersEntity.getWidth() == null
                            && imageUrlParametersEntity.getHeight() == null ? true : false),
                    request, imageUrlParametersEntity.getAttachmentPath(), imageUrlParametersEntity.getFormidPath());
            if (image == null) {
                System.out.println("输出缩略图时出错,出错文件reqUri:" + hostUrl + reqUri + (queryString != null && !"".equals(queryString) ? "?" + queryString : ""));
                return;
            }
            if (image != null && image.getOriginalFileName() != null && (
                    image.getOriginalFileName().toLowerCase().endsWith(".pdf")
                            || image.getOriginalFileName().toLowerCase().endsWith(".doc")
                            || image.getOriginalFileName().toLowerCase().endsWith(".xls")
                            || image.getOriginalFileName().toLowerCase().endsWith(".ppt")
                            || image.getOriginalFileName().toLowerCase().endsWith(".docx")
                            || image.getOriginalFileName().toLowerCase().endsWith(".xlsx")
                            || image.getOriginalFileName().toLowerCase().endsWith(".pptx")
            )) {
                //不是图片格式,附件打开预览会自动下载,在这里处理直接跳过下面的生成输出流 by danaus 2023-07-10 09:49
                filterChain.doFilter(request, response);
                return;
            } else {
                //图片格式,直接显示
                response.setStatus(HttpServletResponse.SC_OK);
                InputStream is = null;
                try {
                    is = new FileInputStream(image.getFile());
                    //设置页面另存为时的文件名
                    response.setHeader("Content-Disposition", "inline; filename="
                            + (image != null && image.getOriginalFileName() != null ? new String(image.getOriginalFileName().getBytes("utf-8"), "ISO_8859_1") : ""));
                    String type = "image/";
                    //输出流
                    response.setContentType(type + image.getFileType());
                    OutputStream output = response.getOutputStream();
                    try {
                        FileCopyUtils.copy(is, output);
                    } catch (ClientAbortException | IllegalStateException e) {
                        System.out.println(getClass() + " reqUri:" + reqUri + ", Error:" + e.getMessage());
                    }
                    return;
                    // 这里不能再执行   chain.doFilter(request, response) , 因为是新生成的文件,如果用  chain.doFilter 输出,则浏览器收到 404 文件不存的错误 ,
                    // 为了解决这个问题,使用  response 流 Stream 输出解决
                    //chain.doFilter(request, response);
                } catch (Exception e) {
                    System.out.println("输出缩略图时出错,出错文件reqUri:" + hostUrl + reqUri + (queryString != null && !"".equals(queryString) ? "?" + queryString : "") + ",错误原因:" + (e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
                    e.printStackTrace();
                } finally {
                    try {
                        if (is != null) is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            servletResponse.setContentType("text/html;charset=utf-8");
            PrintWriter out = servletResponse.getWriter();
            out.print(e.getCause() != null ? e.getCause().getMessage() : e.getMessage());
            out.flush();
            out.close();
        }
    }
    /**
     * 获取图片宽度和高度参数
     *
     * @param fileName
     * @return
     */
    private ImageUrlParametersEntity getImageUrlParameters(String reqUri) {
        ImageUrlParametersEntity imageUrlParametersEntity = new ImageUrlParametersEntity();
        String str[] = reqUri.split("/");
        if (str.length >= 5) {
            String attachmentPath = str[2];  //imageUrlParametersEntity
            String dbId = str[3];  //数据库连接 ID
            String formidPath = str[4];  //功能号,如果是 shopping ,则对应的是 images 值
            String fileName = str[5];   //文件名
            int pos = fileName.indexOf(".");   //去掉扩展名
            String unids = "";       //获取 unid 名字
            String fileType = "";  //文件扩展名
            if (pos < 0) {
                unids = fileName;
            }
            if (pos >= 0) {
                unids = fileName.substring(0, pos);
                fileType = fileName.substring(pos + 1, fileName.length());
            }
            pos = unids.indexOf("_");   //从 size 处截断
            Integer width = null;
            Integer height = null;
            if (pos > 0) {
                String size = unids.substring(pos + 1, unids.length());   //取下划线后面的 size
                String w[] = size.split("x");
                if (w != null && w.length > 0) {
                    width = Integer.parseInt(w[0]);
                    height = Integer.parseInt(w[1]);
                }
                unids = unids.substring(0, pos);   //再次取 unid( 去掉 size )
            }
            imageUrlParametersEntity.setDbId(dbId);
            imageUrlParametersEntity.setFileName(fileName);
            imageUrlParametersEntity.setUnids(unids);
            imageUrlParametersEntity.setFileType(fileType);
            imageUrlParametersEntity.setWidth(width);
            imageUrlParametersEntity.setHeight(height);
            imageUrlParametersEntity.setAttachmentPath(attachmentPath);
            imageUrlParametersEntity.setFormidPath(formidPath);
            String unid = "", seq = "";
            String unidStr[] = unids.split(SettingKey.NAVSPLIT);   //
            unid = unidStr[0];
            imageUrlParametersEntity.setUnid(unid);
            if (unidStr.length > 1) {
                String seqs[] = unidStr[1].split(";");
                seq = seqs[seqs.length - 1];   //只取最后一个 seq , 因为有时候传过来的值是:  7394;7382 ,如果不处理会导致语法错误
                imageUrlParametersEntity.setMailSeq(seq);
            }
        }
        return imageUrlParametersEntity;
    }
    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
src/com/yc/crm/mail/service/MailFileIfc.java
New file
@@ -0,0 +1,45 @@
package com.yc.crm.mail.service;
import com.yc.crm.mail.entity.MailFileEntity;
import com.yc.entity.attachment.AttachmentEntity;
import com.yc.sdk.shopping.entity.ImageEntity;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
public interface MailFileIfc {
    /**
     * 附件保存
     *
     * @param unIdFile
     */
    abstract void saveAttachment(List<MailFileEntity> mailFile);
    /**
     * 邮件附件的调用处理
     *
     * @param unid
     * @return
     */
    abstract List<AttachmentEntity> getAttachmentEntityList(String unIdSeq);
    /**
     * 删除附件
     *
     * @param unId
     * @return
     */
    abstract Integer deleteAttachment(List<String> unId);
    /**
     * 获取图片实体对象 File
     * @param unid
     * @param rootPath
     * @param dbId
     * @return
     */
    public ImageEntity getImageFile(String unid, Integer width, Integer height, boolean isShowOrgImage, HttpServletRequest request, String attachmentPath, String formidPath ) throws Exception;
}
src/com/yc/crm/mail/service/MailFileImpl.java
New file
@@ -0,0 +1,304 @@
package com.yc.crm.mail.service;
import com.yc.action.grid.GridUtils;
import com.yc.crm.mail.entity.MailFileEntity;
import com.yc.entity.DataSourceEntity;
import com.yc.entity.attachment.AttachmentEntity;
import com.yc.multiData.MultiDataSource;
import com.yc.sdk.shopping.entity.ImageEntity;
import com.yc.sdk.shopping.entity.ShoppingImageEntity;
import com.yc.sdk.shopping.util.BlobToFile;
import com.yc.sdk.shopping.util.SettingKey;
import com.yc.service.BaseService;
import com.yc.utils.ImageUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.LobRetrievalFailureException;
import org.springframework.jdbc.core.support.AbstractLobStreamingResultSetExtractor;
import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @BelongsProject: eCoWorksV3
 * @BelongsPackage: com.yc.crm.mail.service
 * @author: xinyb
 * @CreateTime: 2024-09-19  10:19
 * @Description:邮件附件或图片处理
 */
@Service("MailFileImpl")
public class MailFileImpl extends BaseService implements MailFileIfc {
    private final ShoppingImageEntity shoppingImage =  new ShoppingImageEntity() ;
    @Autowired
    private DefaultLobHandler defaultLobHandler;
    @Override
    public void saveAttachment(List<MailFileEntity> mailFile) {
        try {
        } catch (Exception e) {
            throw e;
        }
    }
    @Override
    public List<AttachmentEntity> getAttachmentEntityList(String unIdSeq) {
        String unId = null;
        if (StringUtils.isBlank(unIdSeq)) {
            return null;
        }
        String[] array = unIdSeq.split(";");
        unId = array[0];//在有值时候第一个必定是unId
        ArrayList<String> fieldId = new ArrayList<>(Arrays.asList(array));
        fieldId.remove(0);//去掉第一个元素(UNID)
        String sql = " set nocount on \n"
                + " declare @unid varchar(50) = " + GridUtils.prossSqlParm(unId) +
                ",@fieldid varchar(1000) = " + GridUtils.prossSqlParm(StringUtils.join(fieldId, ",")) + " \n";
        sql += " select UNID,seq,DocCode,RowId,FieldId,FormId, \n"
                + " PhysicalPath,PhysicalFile,OriginalFileName,FileSize,FileType, \n"
                + " AuthorCode,AuthorName,SmallPicPath,UploadTime,OriginalPicture \n"
                + " from _sys_Attachment \n"
                + " where unid = @unid ";
        if (fieldId.size() > 0) {
            if (isNumeric(fieldId.get(0))) {
                sql += " and seq in(select list from GetInStr(@fieldid)) \n";
            } else {
                sql += " and fieldid in(select list from GetInStr(@fieldid)) \n";
            }
        }
        List<Map<String, Object>> list = this.jdbcTemplate.queryForList(sql);
        List<AttachmentEntity> attachmentList = new ArrayList<AttachmentEntity>();
        for (int i = 0; list != null && i < list.size(); i++) {
            AttachmentEntity attachment = new AttachmentEntity();
            attachment.setUnid(unId);
            attachment.setPhysicalFile(list.get(i).get("PhysicalFile") == null ? null : (String) list.get(i).get("PhysicalFile"));
            attachment.setOriginalFileName(list.get(i).get("OriginalFileName") == null ? null : (String) list.get(i).get("OriginalFileName"));
            attachment.setOriginalPicture(list.get(i).get("OriginalPicture") == null ? null : (byte[]) list.get(i).get("OriginalPicture"));  //附件处理
            attachmentList.add(attachment);
        }
        return attachmentList;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer deleteAttachment(List<String> unId) {
        try {
            if (unId == null || unId.size() == 0) {
                return 0;
            }
            String sql = " set nocount on \n"
                    + " declare @unid varchar(4000) = '" + StringUtils.join(unId, ",") + "'  \n";
            sql += "delete _sys_Attachment where unid in (select list from GetInStr(@unid)) \n";
            sql += "select @@ROWCOUNT";
            return jdbcTemplate.queryForObject(sql, Integer.class);
        } catch (Exception e) {
            throw e;
        }
    }
    @Override
    public ImageEntity getImageFile(String unid, Integer width, Integer height, boolean isShowOrgImage, HttpServletRequest request, String attachmentPath, String formidPath) throws Exception {
        HttpSession session = request.getSession();
        if (unid == null || "".equals(unid)) {
            // this.print(response, "获取图片时,必须传递参数 " + SettingKey.UNID);
            return null;
        }
        if (isShowOrgImage) {
            width = null;
            height = null;
        }
        ShoppingImageEntity shoppingImageEntity = null ;
        DataSourceEntity dataSourceEntity = null;
        try {
            dataSourceEntity = MultiDataSource.getDataSourceMap( request) ;
            if (dataSourceEntity == null) {
                throw new Exception("没有找到数据源,获取图片文件失败!" ) ;
            }
            String rootPath = session.getServletContext().getRealPath("/");
            //String uuid = UUID.randomUUID().toString().toUpperCase();
            shoppingImageEntity = getImage( unid,rootPath ,dataSourceEntity.getDbId(),attachmentPath,formidPath);
            if (shoppingImageEntity == null || shoppingImageEntity.getImage() == null) {
                return null;
            }
            //取原图路径
            String shoppingImageFileName = SettingKey.getShoppingImageFileName(rootPath,unid, width,height, isShowOrgImage, dataSourceEntity.getDbId()+"", shoppingImageEntity.getFileType(),attachmentPath,formidPath);
            File file = shoppingImageEntity.getImage();
            if (file != null) {
                if (width != null && height != null && shoppingImageEntity.getFileType()!=null
                        //图片文件才缩放,否则会报错
                        && StringUtils.containsAny(shoppingImageEntity.getFileType().toLowerCase(),"jpg","png","gif","jpeg","tiff","bmp","raw","tga","fpx","webp")) {
                    // 缩放图片
                    ImageUtils.scale(file.getPath(), shoppingImageFileName, width, height);
                } else {
                    shoppingImageFileName = file.getPath(); // 不缩放
                }
                ImageEntity image = new ImageEntity();
                image.setFile(new File(shoppingImageFileName));
                image.setFileType(shoppingImageEntity.getFileType());
                image.setOriginalFileName(shoppingImageEntity.getOriginalFileName());
                return image;
            }
        } catch (IOException e) {
            System.out.println("输出缩略图时出错,出错文件名:" + (shoppingImageEntity!=null?shoppingImageEntity.getPhysicalFile():"") +  (dataSourceEntity!=null?"dbid:["+dataSourceEntity.getDbId() + "],系统名称:["+ dataSourceEntity.getSystemDescribe()+"]":"") );
            throw e;
        }catch (Exception e) {
            throw e ;
        } finally {
            //if (width != null && height != null && file != null && file.exists())
            //    file.delete();
        }
        return null;
    }
    private ShoppingImageEntity getImage(String unids, String rootPath, int dbId, String attachmentPath, String formidPath) {
        if  (unids == null || "".equals(unids))  return null ;
        String unid = "" ,mailSeq = "" ;
        String unidStr[] = unids.split(SettingKey.NAVSPLIT) ;   //
        unid = unidStr[0] ;
        if (unidStr.length > 1 ) {
            String seqs[] = unidStr[1].split(";") ;
            mailSeq = seqs[seqs.length-1];   //只取最后一个 seq , 因为有时候传过来的值是:  7394;7382 ,如果不处理会导致语法错误
        }
        String sql = " set nocount on ; \n"
                + " declare @myrowcount int,@myerror int \n"
                + " declare @unid varchar(50) = "+ GridUtils.prossSqlParm(unid)+" \n"
                + " declare @FormId int,@DocCode varchar(50),@FieldId varchar(50),@RowId varchar(50) \n"
                + " declare @OriginalFileName varchar(200),@PhysicalFile varchar(50),@FileType varchar(50),@FileSize bigint \n"
                + " declare @AuthorCode varchar(50),@AuthorName varchar(50),@OriginalPicture varbinary(max) \n"
                + " select top 1 @FormId = a.FormId,@DocCode = a.DocCode,@FieldId = a.FieldId,@RowId = a.RowId, \n"
                + "    @OriginalFileName = a.OriginalFileName ,@PhysicalFile = a.PhysicalFile,@FileType = a.FileType,\n"
                + "    @FileSize = isnull(a.FileSize,0),@AuthorCode = a.AuthorCode,@AuthorName = a.AuthorName,\n"
                + "    @OriginalPicture = a.OriginalPicture \n"
                + " from " + (formidPath!=null&&"9747".equals(formidPath)?"_sys_AttachmentLog":"_sys_Attachment9") + " a \n"
                + " where a.UNID = @unid  \n"
                + (mailSeq !=null && !"".equals(mailSeq)?" and a.fieldid = '" + mailSeq + "' \n":"")
                + " select @myrowcount  = @@rowcount,@myerror = @@error \n"
                + " if isnull(@myrowcount,0) = 0 \n"
                + " begin \n"
                + "    select top 1 @FormId = a.FormId,@DocCode = a.DocCode,@FieldId = a.FieldId,@RowId = a.RowId, \n"
                + "       @OriginalFileName = a.OriginalFileName ,@PhysicalFile = a.PhysicalFile,@FileType = a.FileType,\n"
                + "       @FileSize = isnull(a.FileSize,0),@AuthorCode = a.AuthorCode,@AuthorName = a.AuthorName,\n"
                + "       @OriginalPicture = a.OriginalPicture \n"
                + "    from "+ (formidPath!=null&&"9747".equals(formidPath)?"_sys_AttachmentLog":"_sys_Attachment") +" a \n"
                + "    where a.UNID = @unid  \n"
                + (mailSeq !=null && !"".equals(mailSeq)?"    and a.fieldid = '" + mailSeq + "' \n":"")
                + " end \n "
                + " select @FormId as FormId,@DocCode as DocCode,@FieldId as FieldId,@RowId as RowId, \n" +
                "       @OriginalFileName as OriginalFileName ,@PhysicalFile as PhysicalFile,@FileType as FileType,\n" +
                "       isnull(@FileSize,0) as FileSize,@AuthorCode as AuthorCode,@AuthorName as AuthorName,\n" +
                "       @OriginalPicture as OriginalPicture \n";
        try {
            this.jdbcTemplate.query(sql,new AbstractLobStreamingResultSetExtractor(){
                protected void handleNoRowFound() throws LobRetrievalFailureException {
                    System.out.println("在数据库id为:" + dbId + "中,导购管理  ShoppingImageImpl 未找到 unid=" + unids + " 的图片文件(或附件)!");
                    shoppingImage.setFormId(-1);
                    shoppingImage.setDocCode("");
                    shoppingImage.setFieldId("");
                    shoppingImage.setRowId("");
                    shoppingImage.setOriginalFileName("");
                    shoppingImage.setPhysicalFile(null);
                    shoppingImage.setFileType("");
                    shoppingImage.setFileSize(0L);
                    shoppingImage.setAuthorCode("");
                    shoppingImage.setAuthorName("");
                    shoppingImage.setImage(null) ;
                }
                @Override
                protected void streamData(ResultSet rs) throws SQLException, IOException, DataAccessException {
                    shoppingImage.setFormId(rs.getString("FormId") == null?0:rs.getInt("FormId"));
                    shoppingImage.setDocCode(rs.getString("DocCode") == null?"":rs.getString("DocCode"));
                    shoppingImage.setFieldId(rs.getString("FieldId") == null?"":rs.getString("FieldId"));
                    shoppingImage.setRowId(rs.getString("RowId") == null?"":rs.getString("RowId"));
                    shoppingImage.setOriginalFileName(rs.getString("OriginalFileName") == null?null:rs.getString("OriginalFileName"));
                    shoppingImage.setPhysicalFile(rs.getString("PhysicalFile") == null?null:rs.getString("PhysicalFile"));
                    shoppingImage.setFileType(rs.getString("FileType") == null?null:rs.getString("FileType"));
                    shoppingImage.setFileSize(rs.getLong("FileSize"));
                    shoppingImage.setAuthorCode(rs.getString("AuthorCode") == null?null:rs.getString("AuthorName"));
                    shoppingImage.setAuthorName(rs.getString("AuthorName") == null?null:rs.getString("AuthorName"));
                    //取原图路径
                    String shoppingImageFileName = SettingKey.getShoppingImageFileName(rootPath,unids, null, null, true, dbId+"", shoppingImage.getFileType(),attachmentPath,formidPath);
                    InputStream is = null ;
                    byte[] bytes = null ;
                    try {
                        is = defaultLobHandler.getBlobAsBinaryStream(rs, "OriginalPicture");
                        if (is != null) {
                            bytes = ShoppingImageEntity.InputStreamToByte( is); //取二进制图片
                            File file = BlobToFile.writeBytesToFile(bytes,shoppingImageFileName);  //
                            if (file != null) {
                                shoppingImage.setImage(file);
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        throw e ;
                    } finally {
                        bytes = null ;
                        if (is != null) is.close();
                    }
                }   // end function
            });
            return shoppingImage ;
        }catch(DataAccessException e ) {
            if (e instanceof EmptyResultDataAccessException){
                return null ;
            }else {
                System.out.println("dbid:" + dbId + ",error:" + (e.getCause() != null ?e.getCause().getMessage():e.getMessage())) ;
                e.printStackTrace();
                throw e;
            }
        }catch(Exception e){
            System.out.println("dbid:" + dbId + ",error:" + (e.getCause() != null ?e.getCause().getMessage():e.getMessage())) ;
            e.printStackTrace();
            throw e;
        }
    }
    /**
     * 判断是否为数字
     *
     * @param str
     * @return
     */
    private static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }
}
src/com/yc/crm/mail/service/MailIfc.java
@@ -1,10 +1,8 @@
package com.yc.crm.mail.service;
import com.yc.crm.mail.entity.MailFileEntity;
import com.yc.crm.mail.entity.MailModuleEntity;
import com.yc.crm.mail.entity.t482101HEntity;
import com.yc.crm.mail.entity.t482101HList;
import com.yc.entity.attachment.AttachmentEntity;
import java.util.List;
@@ -81,14 +79,14 @@
     * @param isRead   是否已读
     * @return
     */
    List<t482101HList> getReceivingMailList(String email, Integer mailType, boolean isNoRead, String userCode);
    List<t482101HList> getReceivingMailList(String email, Integer mailType, boolean isNoRead, String userCode,Integer page,Integer limit);
    /**
     * 获取待处理邮件列表
     * @param email
     * @return
     */
    List<t482101HList> getHandleMailList(String email,String userCode);
    List<t482101HList> getHandleMailList(String email,String userCode,Integer page,Integer limit);
    /**
     * 获取用户的全部邮件
@@ -112,29 +110,6 @@
     * @return
     */
//    Integer deleteMailDrafts(String userCode,String docCode);
    /**
     * 附件保存
     *
     * @param unIdFile
     */
    abstract void saveAttachment(List<MailFileEntity> mailFile);
    /**
     * 邮件附件的调用处理
     *
     * @param unid
     * @return
     */
    abstract List<AttachmentEntity> getAttachmentEntityList(String unIdSeq);
    /**
     * 删除附件
     *
     * @param unId
     * @return
     */
    abstract Integer deleteAttachment(List<String> unId);
    /**
     * 获取收件邮箱已经存在的MessageId集合
src/com/yc/crm/mail/service/MailImpl.java
@@ -3,7 +3,6 @@
import com.yc.action.grid.GridUtils;
import com.yc.crm.mail.entity.*;
import com.yc.entity.AttachmentConfig;
import com.yc.entity.attachment.AttachmentEntity;
import com.yc.sdk.shopping.service.imagedata.ShoppingImageDataIfc;
import com.yc.sdk.weixincp.util.UploadFiles;
import com.yc.service.BaseService;
@@ -14,11 +13,7 @@
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.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
@@ -210,7 +205,7 @@
    }
    @Override
    public List<t482101HList> getReceivingMailList(String email, Integer mailType, boolean isNoRead, String userCode) {
    public List<t482101HList> getReceivingMailList(String email, Integer mailType, boolean isNoRead, String userCode, Integer page, Integer limit) {
        String sql = "set nocount on\n";
        try {
            sql += "select companyId,companyName,mailType,DocCode,senderName,sender,receiver,subject,plain_text," +
@@ -229,6 +224,8 @@
            if (isNoRead) {//0表示未读,1表示已读
                sql += " and isnull(read_flag,0) = 0";
            }
            sql += " order by docCode asc \n";
            sql += " OFFSET (" + page + " - 1) * " + limit + " ROWS FETCH NEXT " + limit + " ROWS ONLY";
            return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(t482101HList.class));
        } catch (Exception e) {
            throw e;
@@ -236,7 +233,7 @@
    }
    @Override
    public List<t482101HList> getHandleMailList(String email, String userCode) {
    public List<t482101HList> getHandleMailList(String email, String userCode, Integer page, Integer limit) {
        String sql = "set nocount on\n";
        try {
            sql += "select companyId,companyName,mailType,DocCode,senderName,sender,receiver,subject,plain_text," +
@@ -245,6 +242,8 @@
                    "handle_time from t482101H ";
            sql += " where isnull(handle_time,'') <> '' and isnull(handle_time,'') < getdate()";
            sql += " and userCode=" + GridUtils.prossSqlParm(userCode) + " and receiver like '%" + email + "%'";
            sql += " order by docCode asc \n";
            sql += " OFFSET (" + page + " - 1) * " + limit + " ROWS FETCH NEXT " + limit + " ROWS ONLY";
            return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(t482101HList.class));
        } catch (Exception e) {
            throw e;
@@ -276,84 +275,6 @@
                    "update_time=getdate() \n";
            sql += " where docCode=" + GridUtils.prossSqlParm(mail.getDocCode());
            sql += " select @@ROWCOUNT";
            return jdbcTemplate.queryForObject(sql, Integer.class);
        } catch (Exception e) {
            throw e;
        }
    }
    @Override
    public void saveAttachment(List<MailFileEntity> mailFile) {
        try {
        } catch (Exception e) {
            throw e;
        }
    }
    @Override
    public List<AttachmentEntity> getAttachmentEntityList(String unIdSeq) {
        String unId = null;
        if (StringUtils.isBlank(unIdSeq)) {
            return null;
        }
        String[] array = unIdSeq.split(";");
        unId = array[0];//在有值时候第一个必定是unId
        ArrayList<String> fieldId = new ArrayList<>(Arrays.asList(array));
        fieldId.remove(0);//去掉第一个元素(UNID)
        String sql = " set nocount on \n"
                + " declare @unid varchar(50) = " + GridUtils.prossSqlParm(unId) +
                ",@fieldid varchar(1000) = " + GridUtils.prossSqlParm(StringUtils.join(fieldId, ",")) + " \n";
        sql += " select UNID,seq,DocCode,RowId,FieldId,FormId, \n"
                + " PhysicalPath,PhysicalFile,OriginalFileName,FileSize,FileType, \n"
                + " AuthorCode,AuthorName,SmallPicPath,UploadTime,OriginalPicture \n"
                + " from _sys_Attachment \n"
                + " where unid = @unid ";
        if (fieldId.size() > 0) {
            if (isNumeric(fieldId.get(0))) {
                sql += " and seq in(select list from GetInStr(@fieldid)) \n";
            } else {
                sql += " and fieldid in(select list from GetInStr(@fieldid)) \n";
            }
        }
        List<Map<String, Object>> list = this.jdbcTemplate.queryForList(sql);
        List<AttachmentEntity> attachmentList = new ArrayList<AttachmentEntity>();
        for (int i = 0; list != null && i < list.size(); i++) {
            AttachmentEntity attachment = new AttachmentEntity();
            attachment.setUnid(unId);
            attachment.setPhysicalFile(list.get(i).get("PhysicalFile") == null ? null : (String) list.get(i).get("PhysicalFile"));
            attachment.setOriginalFileName(list.get(i).get("OriginalFileName") == null ? null : (String) list.get(i).get("OriginalFileName"));
            attachment.setOriginalPicture(list.get(i).get("OriginalPicture") == null ? null : (byte[]) list.get(i).get("OriginalPicture"));  //附件处理
            attachmentList.add(attachment);
        }
        return attachmentList;
    }
    /**
     * 判断是否为数字
     *
     * @param str
     * @return
     */
    private static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer deleteAttachment(List<String> unId) {
        try {
            if (unId == null || unId.size() == 0) {
                return 0;
            }
            String sql = " set nocount on \n"
                    + " declare @unid varchar(4000) = '" + StringUtils.join(unId, ",") + "'  \n";
            sql += "delete _sys_Attachment where unid in (select list from GetInStr(@unid)) \n";
            sql += "select @@ROWCOUNT";
            return jdbcTemplate.queryForObject(sql, Integer.class);
        } catch (Exception e) {
            throw e;
src/com/yc/crm/mail/service/MailServiceIfc.java
@@ -41,4 +41,5 @@
     * @return
     */
    Integer setQuickReply(String docCode,String content) throws MessagingException;
}
src/com/yc/crm/mail/service/MailServiceImpl.java
@@ -33,11 +33,12 @@
 */
@Service
public class MailServiceImpl extends BaseService implements MailServiceIfc {
    @Autowired
    MailIfc mailIfc;
    @Autowired
    MailAccountIfc mailAccountIfc;
    @Autowired
    MailFileIfc mailFileIfc;
    @Override
    public void receivingEmails(T482102Entity emailEntity, FoundationEntity foundation) throws MessagingException {
@@ -179,7 +180,7 @@
            //下面附件内容
            if (StringUtils.isNotBlank(t482101H.getAttachmentList())) {//有附件内容
                //获取到附件内容
                List<AttachmentEntity> attachmentEntities = mailIfc.getAttachmentEntityList(t482101H.getAttachmentList());
                List<AttachmentEntity> attachmentEntities = mailFileIfc.getAttachmentEntityList(t482101H.getAttachmentList());
                if (attachmentEntities != null && attachmentEntities.size() > 0) {
                    for (AttachmentEntity a : attachmentEntities) {
                        InputStream inputStream = new ByteArrayInputStream(a.getOriginalPicture());
@@ -437,7 +438,7 @@
                    String nextResult = result.toString();
                    if (nextResult.contains(cId)) {//有嵌套内容
                        //替换
                        nextResult = nextResult.replace("cid:" + cId + "", shoppingImageServer + "/mail/attachment/82/482101/" + unId + "@p@" + p.getPhysicalFile());
                        nextResult = nextResult.replace("cid:" + cId + "", shoppingImageServer + "/uploads/email/82/482101/" + unId + "@p@" + p.getPhysicalFile());
                        result.setLength(0);//清空先
                        result.append(nextResult);
                    }
src/com/yc/sdk/shopping/entity/ImageUrlParametersEntity.java
@@ -13,6 +13,7 @@
    private String formidPath = null ; //功能号,如果是 shopping ,则对应的是 images 值
    private String unid = null ;
    private Integer seq = null ;
    private String mailSeq=null;//CRM的邮件附件需要到 xin 2024-9-19 11:22:27
    public String getUnid() {
        return unid;
@@ -26,6 +27,15 @@
    public void setSeq(Integer seq) {
        this.seq = seq;
    }
    public String getMailSeq() {
        return mailSeq;
    }
    public void setMailSeq(String mailSeq) {
        this.mailSeq = mailSeq;
    }
    public String getAttachmentPath() {
        return attachmentPath;
    }