# 金山文档中台内外网映射适配方案

2024年8月

# 需求

标准产品集成金山文档中台,要求客户端能连接金山中台服务,并且OA也要与金山中台互通,以上互通配置都通过SeeyonConfig应用配置器完成。

目前存在一个问题:如果使用金山在线编辑,目前只有一个SeeyonConfig参数用于配置金山中台服务器的地址。这样会导致一个问题:

如下图所示,如果地址配置的是金山域名http://wps.yonghu.com,则客户端能连接金山中台,但是内网OA服务器连不上金山中台(客户内网不给开金山域名访问策略);反之,如果配置的是金山内网IP,则客户端无法连接金山。

金山在线预览不存在此问题,在线预览有两个参数

1725264364449.png

修改方案如下图所示:SeeyonConfig配置金山地址的参数变成2个,一个配置外网客户端连接金山中台的地址,一个配置OA直连金山中台内网的地址。

1725264381297.png

# 方案原理

本次修改的原理是根据用户请求头信息中带入user-agent判断访问的终端类型,然后根据终端类型取获取对应配置中的外网地址,将金山中台返回的内网预览/编辑地址替换为外网地址,本次功能为金山文档中台在线编辑外网映射,在线预览目前产品已支持。

# 涉及工程

本次修改涉及到的工程ctp-common、apps-office-plugins

# 改动点

1.修改ctp-common中的systemProperties.xml配置,在ctp.offictTrans.wps中加入如下配置:

<m3EditDomain mark="{VE}" desc="M3应用的域名,该域名用于将金山编辑URL和M3保持同域"/>
<wechatEditDomain mark="{VE}" desc="微协同应用的域名,该域名用于将金山编辑URL和微协同保持同域"/>
<pcEditDomain mark="{VE}" desc="PC协同应用的域名,该域名用于将金山编辑URL和PC协同保持同域"/>

**2.修改apps-office-plugins中的WebOfficeUtil类,添加如下代码(此处代码主要是根据用户访问的终端信息获取配置的外网地址): **

	/**
     * 替换 url 中的主机和端口
     */
    public static String replaceAddress(String dest, String orig) throws BusinessException {
        try {
            if (Strings.isBlank(dest)||Strings.isBlank(orig)) {
                log.error("替换url host 失败.dest 或 orig为空");
                return orig;
            }
            URL destUrl = new URL(dest);
            URL origUrl = new URL(orig);
            URL newUrl = new URL(destUrl.getProtocol(), destUrl.getHost(), destUrl.getPort(), origUrl.getFile());
            log.info("替换weboffice地址,替换前{" + orig + "}\n替换后{" + newUrl + "}");
            return newUrl.toString();
        } catch (MalformedURLException e) {
            throw new BusinessException(e);
        }
    }
	/**
     * 获取外网地址
     */
    public static String publicAddress(HttpServletRequest request) {
        String agent = request.getHeader("User-Agent-Client");
        User currentUser = AppContext.getCurrentUser();
        //获取各端配置
        String wechatEditDomain = SystemProperties.getInstance().getProperty("officeTrans.wps.wechatEditDomain");
        String pcEditDomain = SystemProperties.getInstance().getProperty("officeTrans.wps.pcEditDomain");
        String m3EditDomain = SystemProperties.getInstance().getProperty("officeTrans.wps.m3EditDomain");
        return getPublicAddress(agent, currentUser, wechatEditDomain, pcEditDomain, m3EditDomain);
    }
    private static final List<String> M3_AGENT = Arrays.asList(
            Constants.login_useragent_from.mobile.name(),
            Constants.login_useragent_from.iphone.name(),
            Constants.login_useragent_from.ipad.name(),
            Constants.login_useragent_from.androidpad.name(),
            Constants.login_useragent_from.androidphone.name()
    );
    /**
     * 判断是否是M3访问金山中台预览
     * @param agent			各端agent
     * @param currentUser	当前登录用户
     * @return
     */
    protected static boolean isM3(String agent, User currentUser) {
        if(M3_AGENT.contains(agent)) {
            return true;
        }
        if(currentUser != null && currentUser.isFromM1()) {
            return true;
        }
        return false;
    }
    /**
     * 判断是否是微协同访问金山中台预览
     * @param agent			各端agent
     * @param currentUser	当前登录用户
     * @return
     */
    protected static boolean isWx(String agent, User currentUser) {
        if(Constants.login_useragent_from.wechat.name().equals(agent)) {
            return true;
        }
        if(currentUser != null && Constants.login_useragent_from.wechat.name().equals(currentUser.getUserAgentFrom())) {
            return true;
        }
        return false;
    }
	/**
     * 根据用户的agent信息获取配置的外网地址
     * @param agent			各端agent
     * @param currentUser	当前登录用户
     * @param wechatDomain	微协同地址
     * @param pcDomain	pc同地址
     * @param m3Domain	m3同地址
     * @return
     */
    protected static String getPublicAddress(String agent, User currentUser, String wechatDomain, String pcDomain, String m3Domain) {
        String publicAddress=null;
        if(isM3(agent, currentUser) && Strings.isNotEmpty(m3Domain)) {
            publicAddress=m3Domain;
        } else if(isWx(agent, currentUser) && Strings.isNotEmpty(wechatDomain)) {
            publicAddress=wechatDomain;
        } else if(Strings.isNotEmpty(pcDomain)) {
            publicAddress=pcDomain;
        }

        return publicAddress;
    }

3.修改apps-office-plugins中的WebOfficeResource类的createWebOffice方法,返回结果之前替换一下内网地址,代码如下:

UrlInfoVO result = WebOfficeHelper.fillCreateBackVO(woVo);
final String publicAddress = WebOfficeUtil.publicAddress(req);
if (publicAddress != null) {
	result.setWebOfficeDomin(WebOfficeUtil.replaceAddress(publicAddress, result.getWebOfficeDomin()));
	result.setWpsUrl(WebOfficeUtil.replaceAddress(publicAddress, result.getWpsUrl()));
}
return this.success(result);

修改前代码: 1725265978144.png

修改后代码: 1725266059058.png

# 修改配置

方法1:修改seeyonConfig配置,将需要开放外网访问端的中台外网地址配置上,如下图所示:

1725255793453.png

方法2:修改base/config/systemCtp.properties文件,添加如下配置:

在线预览配置:

officeTrans.wps.m3Domain=m3在线预览(金山文档中台)外网地址
officeTrans.wps.wechatDomain=微协同在线预览(金山文档中台)外网地址
officeTrans.wps.pcDomain=pc在线预览(金山文档中台)外网地址

在线编辑配置:

officeTrans.wps.m3EditDomain=m3在线编辑(金山文档中台)外网地址
officeTrans.wps.wechatEditDomain=微协同在线编辑(金山文档中台)外网地址
officeTrans.wps.pcEditDomain=pc在线编辑(金山文档中台)外网地址

备注:此处配置根据要开放的端进行选择配置,地址为金山文档中台外网访问地址,只需要到填写到端口。如:https://10.3.4.85:80

创建人:ranjf
修改人:ranjf、het