11 致远OA开发插件部署文档

一:背景

A8 是单体应用程序,并且功能众多。我们希望A8功能模块化,且模块具有自己发版版本。同时希望客开功能,插件化(以“可插拔”的形式,依托A8 运行)。

二:技术方案

我们采用A8 插件(A8 Plugin) 进行模块化开发,它在不增加额外的知识成本下,满足客开插件:自定义配置,国际化等功能。

1.A8 插件开发文档: 

如图:

 

请各位开发:严格按照上述文档开发插件

2.文件部署规范

为了方便维护标准代码和客开代码,我们对这二者的部署做如下规范:

2.1 标准产品部署:沿用原始A8 部署规范

2.1.1 配置文档,文件存放路径:*\webapps\seeyon\WEB-INF\cfgHome\plugin\自定义文件夹*

如图:

2.1.2 jar 包发布位置:webapps\seeyon\WEB-INF\lib

如图:

 

2.2 客开插件:

2.2.1 jar 包部署位置: \webapps\seeyon\WEB-INF\lib\customer\xxx.jar

如图:

 

注意:框架代码:将自动扫描该插件包:所有jar 文件,并加载到jvm中

2.2.2 前端资源文件的部署: 如js,css,图片等: 部署目录是:\webapps\seeyon\customer\客户名称\,访问方式:seeyon\customer\客户名称\xx

如图:

 

2.2.3 jsp 页面:部署目录是:\webapps\seeyon\WEB-INF\jsp\customer\客户名称\,访问方式:customer\客户名称\xx

如下图:

 

后端代码:

public class AController extends BaseController { @Override public ModelAndView index(HttpServletRequest request, HttpServletResponse response) throws Exception { //jsp路径是:customer/demo/front/jsp/capRunningLog ModelAndView mav = new ModelAndView("customer/demo/capRunningLog"); //添加一个测试属性 mav.addObject("a", "123"); return mav; } }

2.2.4 spring 配置;

a.插件开发配置:

b. spring 配置部署:部署位置:\webapps\seeyon\WEB-INF\cfgHome\plugin\customer\客户名称\xxx

 

案例:我们以访问后台jsp页面,并且在jsp显示客开图片为例进行说明:

a.假设我们的客开插件名称为:demo 。jsp 文件保存在:\webapps\seeyon\WEB-INF\jsp\customer\demo\capRunningLog.jsp

b.需求: 我们希望能正确请求到上述jsp 页面,同时在jsp 页面上显示该插件下:\webapps\seeyon\customer\demo\img\img\123.png 文件

c.操作过程:

后端代码: 访问jsp 页面,请以:customer/客开插件名称/开头,如上述jsp 页面:customer/demo/capRunningLog

public class AController extends BaseController { @Override public ModelAndView index(HttpServletRequest request, HttpServletResponse response) throws Exception { //jsp路径是:customer/demo/capRunningLog ModelAndView mav = new ModelAndView("customer/demo/capRunningLog"); //添加一个测试属性 mav.addObject("a", "123"); return mav; } }

前端代码:

<%@ page contentType="text/html; charset=utf-8" isELIgnored="false" %>
<%@ include file="/WEB-INF/jsp/common/common.jsp" %>
<!DOCTYPE html>
<html lang="en">
​
<head>
    <meta charset="UTF-8">
    <title>${ctp:i18n('system.menuname.BusinessOrderPlatform')}|${ctp:i18n('system.menuname.BusinessMonitorCenter')}</title>
    <!--引用标准产品文件 -->
    <link href="${staticPath}/portal/icons/default/fonts/plane/iconfont.css${staticSuffix}" rel="stylesheet" type="text/css">
    <link rel="stylesheet" href="${staticPath}/common/cap4/bizconfig/css/monitor/capRunningLog.css${staticSuffix}" />
    <script src="${staticPath}/common/cap4/common/underscore.js${staticSuffix}"></script>
    <link rel="stylesheet" href="${staticPath}/common/cap4/bizconfig/jqSelect/jquery.searchableSelect.css${staticSuffix}" />
    <script src="${staticPath}/common/cap4/bizconfig/jqSelect/jquery.searchableSelect.js${staticSuffix}"></script>
</head>
​
<body style="background-color:#F9F9F9;">
    <div id="runningLog" class="table-wrap" style="display: none">
        <div id="view"  class="view_menu">
            <div class="tab tab_biz  div_active ready-cli" id="tab_biz">${ctp:i18n('cap.monitor.application')}</div>
            <div class="tab tab_form" id="tab_form">${ctp:i18n('common.form.label')}</div>
        </div>
        <div class="panel-header">
            <div style="min-width:1024px;">
                <div class="cap-search cap-search-time">
                    <label for="">${ctp:i18n('common.option.time.label')}</label>
                    <span>
                        <input readonly="readonly" unselectable="on" id="beginoperatime" type="text" />
                        <i class="iconfont cap-icon-riqishijian start-time-operator"></i>
                    </span>
                    <p>-</p>
                    <span>
                        <input readonly="readonly" unselectable="on" id="endoperatime" type="text" />
                        <i class="iconfont cap-icon-riqishijian end-time-operator"></i>
                    </span>
                </div>
                <div class="cap-search cap-search-text">
                    <label for="">${ctp:i18n('common.opinion.member.label')}</label>
                    <input readonly="readonly" unselectable="on" id="operationName" type="text">
                    <input class="display_none" id="operationNameId" type="text">
                    <i class="iconfont cap-icon-xuanren j-xuanren-operator"></i>
                </div>
​
                <div class="cap-search cap-search-text">
                    <label for="">${ctp:i18n('common.opinion.describe.label')}</label>
                    <input id="description" type="text">
                </div>
​
                <div class="cap-search cap-search-text j-business">
                    <label for="">${ctp:i18n('cap.monitor.application')}</label>
                    <input id="bizName" type="text">
                </div>
                <br>
                <div class="cap-search cap-search-time">
                    <label for="">${ctp:i18n('common.date.create.label')}</label>
                    <span>
                        <input readonly="readonly" unselectable="on" id="begincreatetime" type="text" />
                        <i class="iconfont cap-icon-riqishijian start-time-creator"></i>
                    </span>
                    <p>-</p>
                    <span>
                        <input readonly="readonly" unselectable="on" id="endcreatetime" type="text" />
                        <i class="iconfont cap-icon-riqishijian end-time-creator"></i>
                    </span>
                </div>
​
​
                <div class="cap-search cap-search-text">
                    <label for="">${ctp:i18n('common.creater.label')}</label>
                    <input readonly="readonly" unselectable="on" id="creatorName" type="text">
                    <input class="display_none" id="creatorNameId" type="text">
                    <i class="iconfont cap-icon-xuanren j-xuanren-createor"></i>
                </div>
​
                <div class="cap-search cap-search-select j-opType">
                    <label for="">${ctp:i18n('common.option.type.label')}</label>
                    <select class="j-select-value" id="operateType"></select>
                </div>
​
                <div class="cap-search cap-search-text j-formName" style="display: none;">
                    <label for="">${ctp:i18n('common.form.label')}</label>
                    <input id="formName" type="text">
                </div>
                <button id="doReset" class="cap-button" style="display: none"><i class=""></i><span>${ctp:i18n('form.reset.button.label')}</span></button>
                <button id="doSearch" class="cap-button"  style="display: none"><i class=""></i><span>${ctp:i18n('common.button.condition.search.label')}</span></button>
            </div>
        </div>
        <div class="table-content" id="runningLogParent">
            <table class="j-runnerTabel"></table>
        </div>
    </div>
    <!--客开后端测试属性-->
    hhaah: <label for="">${a}</label>
    <!-- 客开静态资源引用-->
    <img src="${staticPath}/customer/demo/front/img/123.png" />
</body>
​
</html>

如上述代码:引用后端变量和静态资源

hhaah: <label for="">${a}</label>

<img src="${staticPath}/customer/demo/front/img/123.png" />

请注意:A8 原来提供的属性,现在均可用,如上述的:${staticPath} 表示/seeyon

d.效果

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
曾经有过四年的致远A6 2.83 维护经历。这中间,致远方面肯定不会提供相关信息,市场上任何ERP的维护、二开都是价格不菲,这个就是IT,跟所有智力行业一样,靠知识寻求价值!要不花钱,就自己专研!而你自己形成的成果,本身就可以转换为经济价值!当然,在很多外行看来,IT从业者都是服务员,呼之来使之去........并不是每件事都是愉快的,并不是每个地方都有发展的!在四川,除了成都,其它市县的IT从业并不乐观! 一晃几年过去了,偶然翻开自己存放在QQ群里的笔记,颇有感触,于是想着不如把它发出来吧! 回到正题,致远A6 2.83 系统中很多东西都是自己打开疑似文件进行分析,于是便总结了许多维护中的经验。这款OA比较老,大约是2005年的设计思想,JSP+MySQL组合。其中数据库在安装时使用了固定密码,这个文件中有!我是使用Navicat for MySQL链接数据库进行代码执行,或者日常数据修改。 为什么要分离呢?因为A6是一款小企业用的OA,而这家公司有2000个用户,工作日活跃用户350人左右,在没有与其他ERP数据对接的情况下,每天都会产生大量数据,其中最大的流程表在很短时间就突破6千万条数据,而每个用户,点开每条协同都会单独在这个张表中查询自己的数据,很快数据库就会进入查询排队,直到超时丢弃。查询缓慢,数据丢失就会发生。所以需要定期对数据库进行分离,部署成历史数据库和在用数据库,在用数据库清空了所有协同数据,就相当于重新安装的OA,运行数据当然会很快。这就为什么要做数据库分离操作的原因! 下载的压缩包中有两个文件,一个比较全,是自由部署A6时一些需要修改的文件或者你想修改来达到特定目的的文件,如安装路径修改、OA附件上传大小修改、端口修改等,并包含数据库分离代码。另一个文件是专门对分离代码进行解说,分离代码是对数据库分析后,对影响数据库性能的表单进行清除,保留有用信息,主要是清除了协同信息,保留了用户的表单模板、表单查询等有用信息。 作为DBA,分离数据库前做好备份是必须的,在测试服务器演练也是必须的!备份数据的难点在于附件文件的备份,即/upload文件夹........慢慢等吧!根据服务器配置,整个工程时间至少需要两天,其中大部分时间用于数据备份,数据库分离代码执行时间预计12个小时(我这个数据很大,所以.....)。分离之后的数据库,用来部署为在用服务器。分离前的数据库用来部署历史数据库,所以建议使用两台服务器分别部署,也就是要安装两套OA服务器,各自访问各自的数据,由于所有历史数据将会部署到一个服务器,也就是该服务器将安装多套AO,所以需要修改数据库端口和Web端口来避免冲突!部署时,某些图片文件需要复制到对应文件夹! 根据各自公司的情况来定分离时间吧,我这个是2年分离一次(时间选择年底是最佳哦)!通过对my.ini、xxsStartTomcat.bat、server.xml文件的优化,这个软件可以一直用到企业破产......A6其它版本或许略有差别,可以自己测试!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr_GGI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值