全网泛微ecology二次开发最详细教程(后端+ecode前端,纯二开,不使用建模)

1.后端环境搭建

一、IDEA环境配置

  1.1 打开idea,创建一个新的Java项目File->New->Project

1.2 选择Java项目

1.3 下一步:编辑好项目名称,点击Finish

1.4 项目创建文件完成之后需要进行项目配置File-Project Structure,点击project,分别选择Project SDK为1.8、、Project language level为SDK default 8

1.5 因为创建项目后会自带一个src的文件夹,我们后续的代码开发在src文件下,src文件夹下的目录结构最好与泛微e9的目录结构一致;如:src.com.api.xxx; src.com.engine.xxx等;如果不存在src,可以在当前界面新加一个src文件夹,并指定为Sources;

1.6 指定代码编辑后的输出目录,注意这里的Output path:应该是为小伙伴你们自己下载下来,或者已有的ecology代码文件夹下,并且要指定输出到classbean文件下,那么后续我们代码编译后会自动输出到对应的ecology项目下。

1.7 引入依赖,我们这里需要引入三个特定的依赖,(我这里原有的泛微项目在D盘的Weaver文件夹下)分别是你原有的的泛微项目下的classbean文件夹,这里我们需要做一个操作,就是需要把这个classbean文件夹压缩成一个压缩包,然后将压缩包的后缀改成.jar,然后将这个classbean.jar直接引入即可;第二个依赖是小伙伴自己项目里面Resin文件夹下的lib文件夹进行引入;第三个依赖是小伙伴自己项目下ecology里面的WEB-INF/lib的文件夹进行引入即可。

1.8 设置项目的sdks,必须使用jdk1.8版本,最好用泛微提供的jdk1.8的版本,自己项目文件夹下一般都会有泛微提供的jdk包。

1.9 最后点击apply按钮即可完成我们环境的配置。

二、Resin的配置

 注意:如果小伙伴们想在idea中想配置Resin进行项目的启动,那目前只能使用2019版本及以下的idea,2020以上版本不支持Resin。

添加之后,配置项目自己所带的端口即可。然后就能正常启动啦!包括你dubug或者是run都是没问题的。

以上就是泛微后端环境的搭建的全部流程,希望能帮助到小伙伴们!

2.前端ecode的基本使用

      一、创建页面组件

      因为博主已经含有了泛微的项目,所以没有下载具体的ecode到本地,而是直接使用ecode进行代码编写;而且本地和线上也有一些差异,所以直接就在项目的ecode平台上进行 编码了。所以这里都是讲的在线上的ecode平台进行编码,线上和本地只是一些组件引入的差异,其他并无差异,可放心查阅。另外就是前端是需要申请许可的,这个大家自行找泛微的人申请即可。

2.1 进入ecode平台,后端将项目启动之后,http://localhost:8081/ecode,在你的ip:端口后面拼接/ecode即可进入。

2.2 进入页面之后,我们二开的话一般都是建立新的文件夹,然后进行开发,那么第一步就是新建一个根目录的文件夹,然后在我们新建好的分类下面新建一个文件夹即可。

文件夹创建成功后,就会自动出现一些配置文件夹,小伙伴们可按需引入。

后续就是新建页面、新建store、新建主页面等等。博主这里新建coms文件夹来存放页面组件,新建store文件夹来存放页面操作方法等;最重要的就是建立注册文件和主入口组件,分别建立register.js文件和index.js文件。这里注册组件写法基本一致,可查看泛微的ecode开发文档。

//注册文件 registe.js

//注册和绑定新页面前端实现接口
ecodeSDK.rewriteRouteQueue.push({
  fn:(params)=>{
    const {Com,Route,nextState} = params;
    const cpParams = {
      path:'main/cs/app', //路由地址
      appId:'${appId}',
      name:'testBank', //具体页面应用id
      node:'app', //渲染的路由节点,这里渲染的是app这个节点
      Route,
      nextState
    }
    if(ecodeSDK.checkPath(cpParams)) {
      const acParams = {
        appId:cpParams.appId,
        name:cpParams.name, //模块名称
        props:params, //参数
        isPage:true, //是否是路由页面
        noCss:true //是否禁止单独加载css,通常为了减少css数量,css默认前置加载
      }
      //异步加载模块${appId}下的子模块testBank
      return ecodeSDK.getAsyncCom(acParams);
    }
    return null;
  },
  order:10,
  desc:'testBank'
});

/*
版本要求:kb1906以上
门户后台配置路由地址:
/main/cs/app/9a9808af4ce54bb6a1688880a4dc96407_testBank
浏览器访问地址:
/wui/index.html#/main/cs/app/9a9808af4ce54888888c96407_testBank
*/
//主入口页面组件 index.js

const { Provider } = mobxReact;
const TestTable = ecodeSDK.imp(TestTable);
const TestStore = ecodeSDK.imp(TestStore);
//实例化store,并通过provider注入所有组件中
const allTestBanks = {
  testStore:new TestStore()
}
class testBankRoot extends React.Component {
  render() {
    return (
      <Provider {...alltTestBanks}>
      <TestTable {...this.props}/>
      </Provider>
    )
  }
}

//发布模块
ecodeSDK.setCom('${appId}','testBank',testBankRoot);

然后是 coms文件下的页面组件,这个文件夹下面的就是我们的页面展示

const { inject, observer } = mobxReact;
const { Button, Row, Col } = antd;
const { WeaTable, WeaInput, WeaDialog, WeaNewScroll, WeaSearchGroup, WeaInputSearch, WeaFormItem ,WeaError} = ecCom;

@inject("testStore") // 注入store
@observer // 观察状态的变化
class TestTable extends React.Component {

  constructor(props){
    super(props);
    this.state = {
    scrollHeight: 850, // 默认高度为850
  };
  }
  
  componentDidMount() {
    // 初始化时设置滚动条的高度
    this.setScrollHeight();

    // 监听窗口大小变化
    window.addEventListener("resize", this.setScrollHeight);
  }

  componentWillUnmount() {
    // 清理 resize 事件监听器
    window.removeEventListener("resize", this.setScrollHeight);
  }

  setScrollHeight = () => {
    const windowHeight = window.innerHeight;
    const calculatedHeight = windowHeight - 60; // 你可以根据需要调整减去的值
    this.setState({ scrollHeight: calculatedHeight });
  };

  render() {
    const { testStore } = this.props;
    const { scrollHeight } = this.state;

    const columns = [
      { title: "测试1", dataIndex: "test1" },
      { title: "测试2", dataIndex: "test2" },
      {
        title: "操作",
        dataIndex: "actions",
        render: (text, record) => {
          return (
            <>
              <Button type="primary" onClick={() => testStore.showModal(record)}>编辑</Button>
              &nbsp;&nbsp;
              <Button onClick={() => testStore.deleteData(record.id)}>删除</Button>
            </>
          );
        },
      },
    ];

    return (
      <WeaNewScroll toTop height={scrollHeight}>
        {/* 查询区域 */}
        <WeaSearchGroup
          showGroup
          items={[
            {
              com: (
                <WeaFormItem label="测试查询" labelCol={{ span: 3 }} wrapperCol={{ span: 6 }}>
                  <WeaInputSearch
                    value={testStore.searchTitle}
                    placeholder="请输入测试查询"
                    onSearch={(value) => {
                      testStore.searchTitle = value;
                      testStore.fetchData();
                    }}
                  />
                </WeaFormItem>
              ),
            },
          ]}
        />

        {/* 表格 */}
        <WeaTable
          dataSource={testStore.dataSource}
          columns={columns}
          loading={testStore.loading}
          pagination={{
            current: testStore.current,
            pageSize: testStore.pageSize,
            showSizeChanger: true,
            total: testStore.total,
            showTotal: (total) => `共${total} 条`,
            onShowSizeChange(current, pageSize) {
              testStore.current = current;
              testStore.pageSize = pageSize;
              testStore.fetchData();
            },
            onChange: (page) => {
              testStore.current = page;
              testStore.fetchData();
            },
          }}
        />

        {/* 新增/编辑弹窗 */}
        <WeaDialog
          style={{ width: 400, height: 200 }}
          title={testStore.formData.id ? "编辑测试" : "新增测试"}
          visible={testStore.modalVisible}
          onCancel={testStore.handleCancel}
        >
          <WeaNewScroll>
            <div style={{ textAlign: "center" }}>
              <WeaFormItem
                label="测试"
                labelCol={{ span: 4 }}
                wrapperCol={{ span: 16 }}
                viewAttr="3"
              >
                <WeaInput
                  viewAttr="3"
                  value={testStore.formData.test1}
                  onChange={(value) => testStore.updateFormData("test1", value)}
                />
              </WeaFormItem>
            </div>
          </WeaNewScroll>

          {/* 弹框底部按钮 */}
          <div style={{ textAlign: "center", marginTop: 40 }}>
            <Button key="cancel" onClick={testStore.handleCancel}>
              取消
            </Button>
            <Button
              key="submit"
              type="primary"
              onClick={() => testStore.handleSubmit(testStore.formData)} // 提交表单时校验
              style={{ marginLeft: 8 }}
            >
              保存
            </Button>
          </div>
        </WeaDialog>
      </WeaNewScroll>
    );
  }
}

ecodeSDK.exp(TestTable); 

然后是store的文件

const { observable, action } = mobx;
const { WeaTools } = ecCom;
const { message } = antd;

class TestStore {
  @observable dataSource = [];
  @observable loading = false;
  @observable total = 0;
  @observable pageSize = 10;
  @observable current = 1;
  @observable searchTitle = ""; // 搜索字段
  @observable modalVisible = false;
  @observable formData = { test1: "", test2: "", test3: "" }; // 用于新增/编辑表单
  
  constructor() {
    this.fetchData();
  }

  // 获取数据
  @action.bound
  async fetchData() {
    this.loading = true;
    try {
      const res = await WeaTools.callApi("/api/testBank/list", "POST", {
        page: this.current,
        pageSize: this.pageSize,
        test1: this.searchTitle.trim(), // 传递搜索参数
      });
      if (res.code == "1") {
        this.dataSource = res.data;
        this.total = res.total;
        message.success(res.message);
      } else {
        message.error(res.message);
      }
    } finally {
      this.loading = false;
    }
  }

    // 获取数据
  @action.bound
  async fetchDataDialog() {
    this.loading = true;
    try {
      const res = await WeaTools.callApi("/api/testBank/list", "POST", {
        page: this.current,
        pageSize: this.pageSize,
        test1: this.searchTitle.trim(), // 传递搜索参数
      });
      if (res.code == "1") {
        this.dataSource = res.data;
        this.total = res.total;
      } else {
        message.error(res.message);
      }
    } finally {
      this.loading = false;
    }
  }

  // 保存数据
  @action.bound
  async saveData(values) {
    const res = await WeaTools.callApi("/api/testBank/submit", "POST", values);
    if (res.code == "1") {
      this.modalVisible = false;
      message.success(res.message);
      this.fetchDataDialog(); // 获取最新数据,重新加载数据源
    } else {
      this.modalVisible = false;
      message.error(res.message);
    }
  }

  // 删除数据
  @action.bound
  async deleteData(id) {
    const res = await WeaTools.callApi("/api/testBank/delete", "POST", {"id": id});
    if (res.code == "1") {
      message.success(res.message);
      this.fetchDataDialog();
    } else {
      message.error(res.message);
    }
  }

  // 显示弹窗
  @action.bound
  showModal(record) {
    this.formData = record || {}; // 默认值
    this.modalVisible = true; // 显示弹窗
  }

  // 关闭弹窗
  @action.bound
  handleCancel() {
    console.log("取消弹窗!")
    this.modalVisible = false;
    this.formData = {}; // 清空表单数据
  }

  // 提交操作:保存表单数据
  @action.bound
  handleSubmit(formData) {
    this.saveData(formData);
  }

  // 更新表单字段
  @action.bound
  updateFormData(field, value) {
    this.formData[field] = value;
  }
}

ecodeSDK.exp(TestStore);

    博主这里改了部分代码,主要是是表格数据列的展示,可能导致代码不能直接运用, 小伙伴们注意分辨即可,但是其他的代码基本都是这样的模式,博主这里提供的只是一个最基本的增删改查界面,查询用表格展示,编辑和新增都使用弹窗。这里提供泛微组件库的地址:Ecology 9;这里面的组件基本都可以使用,只是需要注意一下组件的引入方式,这里提供几个注意的,WeaForm组件官方文档比较抽象,可以自行确定使用,线上的ecode需要这样引入const { WeaForm } = comsMobx;否则会报错,然后就是博主在引入过程中发现引入泛微提供的组件文档之外,我去引入官方antd的组件的时候无法引入,引入会报错,目前不知道具体是引入限制还是如何?有知道的小伙伴可以在评论区留言告知。上述基本就是ecode开发的详细操作咯,主要就是注意下引入即可。

   二、发布页面

   将我们编写好的组件进行发布,右键点击文件,然后点击发布即可,然后在页面上面找到发布清单复制他的id主键,

他的主键id一般是9a9808af4ce54bb6a1688880a4dc96407类似一串数字,然后右键点击你的register.js文件,将他设为前置加载,而后的你可以在门户菜单里面配置菜单,/main/cs/app/9a9808af4ce54bb6a1688880a4dc96407_testBank就是你自定义的URL。

/*
版本要求:kb1906以上
门户后台配置路由地址:
/main/cs/app/9a9808af4ce54bb6a1688880a4dc96407_testBank
浏览器访问地址:
/wui/index.html#/main/cs/app/9a9808af4ce54888888c96407_testBank
*/

3. 后端代码的编写

    博主这里使用的是 Weaverboot-E9(beta),Weaverboot-E9 提供一套完整的 IOC + AOP 的解决方案,可以很快速的代理所有的接口,同时提供类似与spring 的依赖注入的写法方便快速编码:在上述我也讲过了,建立src下com文件夹、com下建立api和engine两个文件夹,其实只建立一个也是可以的。博主这里依照泛微规范还是建立了两个文件夹,需要注意的是泛微后端没有用到类似spring里面的controller,他这里用action替换了。

  3.1 com.api下的action

package com.api.test.testdemo.web;

import javax.ws.rs.Path;

@Path("/testBank")
public class TestBankAction extends com.engine.test.testdemo.web.TestBankAction {

}

3.2 com.engine下的action

package com.engine.test.testdemo.web;

import com.alibaba.fastjson.JSONObject;
import com.engine.common.util.ParamUtil;
import com.engine.test.testdemo.service.TestBankService;
import com.weaverboot.frame.ioc.anno.fieldAnno.WeaAutowired;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.util.HashMap;
import java.util.Map;


@Slf4j
public class TestBankAction {

    @WeaAutowired
    private TestBankService testBankService;
    /**
     * 测试信息获取接口
     */
    @Path("/list")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String getQuestionBankList(@Context HttpServletRequest request, @Context HttpServletResponse response){
        try {
            Map<String, Object> stringObjectMap = ParamUtil.request2Map(request);
            log.info("获取测试数据入参:"+stringObjectMap);
            return testBankService.getQuestionBankList(stringObjectMap);
        }catch (Exception e) {
            Map<String,Object> resultMap =new HashMap<>();
            resultMap.put("code","0");
            resultMap.put("message","查询失败!");
            return JSONObject.toJSONString(resultMap);
        }
    }


    /**
     * 测试信息获取接口
     */
    @Path("/getQuestion")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String getQuestionBank(@Context HttpServletRequest request, @Context HttpServletResponse response){
        try{
            Map<String, Object> stringObjectMap = ParamUtil.request2Map(request);
            log.info("获取测试数据入参:"+stringObjectMap);
            return testBankService.getQuestionBank(stringObjectMap);
        }catch (Exception e) {
            Map<String,Object> resultMap =new HashMap<>();
            resultMap.put("code","0");
            resultMap.put("message","查询失败!");
            return JSONObject.toJSONString(resultMap);
        }
    }

    @Path("/submit")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String addQuestionBank(@Context HttpServletRequest request, @Context HttpServletResponse response){
        try {
            Map<String, Object> stringObjectMap = ParamUtil.request2Map(request);
            log.info("获取测试数据入参:" + stringObjectMap);
            return testBankService.submitQuestion(stringObjectMap);
        }catch (Exception e) {
            Map<String,Object> resultMap =new HashMap<>();
            resultMap.put("code","0");
            resultMap.put("message","新增失败!");
            return JSONObject.toJSONString(resultMap);
        }
    }


    @Path("/delete")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteQuestion(@Context HttpServletRequest request, @Context HttpServletResponse response){
        try {
            Map<String, Object> stringObjectMap = ParamUtil.request2Map(request);
            log.info("获取测试数据入参:" + stringObjectMap);
            return testBankService.deleteQuestion(stringObjectMap);
        }catch (Exception e) {
            Map<String,Object> resultMap =new HashMap<>();
            resultMap.put("code","0");
            resultMap.put("message","删除失败!");
            return JSONObject.toJSONString(resultMap);
        }
    }
}

3.3 com.engine下的service

package com.engine.test.testdemo.service;



import java.sql.SQLException;
import java.util.Map;

public interface TestBankService {

    String getTestBankList(Map<String, Object> stringObjectMap) throws SQLException;

    String getTestBank(Map<String, Object> stringObjectMap) throws SQLException;

    String submitTest(Map<String, Object> stringObjectMap) throws SQLException;

    String deleteTest(Map<String, Object> stringObjectMap) throws SQLException;
    
}

3.4 com.engine下的serviceimpl

package com.engine.test.testdemo.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.engine.test.testdemo.entity.TestBank;
import com.engine.test.testdemo.service.TestBankService;
import com.weaverboot.frame.ioc.anno.classAnno.WeaIocService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import weaver.general.StaticObj;
import weaver.general.StringUtil;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

@Slf4j
@WeaIocService
public class TestBankServiceImpl extends com.engine.core.impl.Service implements TestBankService {
    @Override
    public String getTestBankList(Map<String, Object> stringObjectMap) throws SQLException {
        Map<String, Object> resultMap = new HashMap<>();
        java.sql.Connection conn = null;
        PreparedStatement s = null;
        ResultSet rs = null;
        PreparedStatement countStmt = null;
        ResultSet countRs = null;
        try {
            int pageSize = Integer.parseInt(String.valueOf(stringObjectMap.get("pageSize")));
            int page =Integer.parseInt(String.valueOf( stringObjectMap.get("page")));
            int offset = (page - 1) * pageSize;
            String title = String.valueOf(stringObjectMap.get("title"));
            weaver.interfaces.datasource.DataSource ds = (weaver.interfaces.datasource.DataSource) StaticObj.getServiceByFullname(("datasource.test"), weaver.interfaces.datasource.DataSource.class);
            conn = ds.getConnection();
            String sql = "select * FROM el_repo LIMIT ? OFFSET ?";
            if (!StringUtil.isEmpty(title)){
                sql = "select * FROM el_repo where title like ? LIMIT ? OFFSET ?";
            }
            s = conn.prepareStatement(sql);
            s.setInt(1, pageSize);
            s.setInt(2, offset);
            if (!StringUtil.isEmpty(title)){
                s.setString(1,"%"+title+"%");
                s.setInt(2, pageSize);
                s.setInt(3, offset);
            }
            rs = s.executeQuery();
            List<TestBank> testBankList = new ArrayList<>();
            while (rs.next()) {
                TestBank testBank = new TestBank();
                testBank.setId(rs.getInt("id"));
                testBank.setCode(rs.getString("code"));
                testBank.setTitle(rs.getString("title"));
                testBank.setRemark(rs.getString("remark"));
                testBank.setUpdateTime(rs.getDate("update_time"));
                testBank.setCreateTime(rs.getDate("create_time"));
                testBankList.add(testBank);
            }
            resultMap.put("data", testBankList);
            // 获取总数
            String countSql = "SELECT COUNT(*) FROM el_repo where title like ?";
            if (StringUtil.isEmpty(title)){
                countSql = "SELECT COUNT(*) FROM el_repo";
            }
             countStmt = conn.prepareStatement(countSql);
            if (!StringUtil.isEmpty(title)){
                countStmt.setString(1,"%"+title+"%");
            }
             countRs = countStmt.executeQuery();
            if (countRs.next()) {
                int totalCount = countRs.getInt(1);
                resultMap.put("total", totalCount);
            }
            resultMap.put("code", "1");
            resultMap.put("message", "查询成功!");
            return JSONObject.toJSONString(resultMap);
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("code", "0");
            resultMap.put("message", "查询失败!");
            return JSONObject.toJSONString(resultMap);
        }finally {
            if (conn!=null){
                conn.close();
            }
            if (s!= null){
                s.close();
            }
            if (rs!=null){
                rs.close();
            }
            if (countStmt!=null){
                countStmt.close();
            }
            if (countRs!=null){
                countRs.close();
            }
        }
    }

    @Override
    public String getTestBank(Map<String, Object> stringObjectMap) throws SQLException {
        Map<String, Object> resultMap = new HashMap<>();
        java.sql.Connection conn = null;
        PreparedStatement s = null;
        ResultSet rs = null;
        PreparedStatement countStmt = null;
        ResultSet countRs = null;
        try {
            int pageSize = Integer.parseInt(String.valueOf(stringObjectMap.get("pageSize")));
            int currentPage =Integer.parseInt(String.valueOf( stringObjectMap.get("page")));
            int offset = (currentPage - 1) * pageSize;
            String id = stringObjectMap.get("id").toString();
            weaver.interfaces.datasource.DataSource ds = (weaver.interfaces.datasource.DataSource) StaticObj.getServiceByFullname(("datasource.test"), weaver.interfaces.datasource.DataSource.class);
            conn = ds.getConnection();
            s = conn.prepareStatement("select * FROM el_repo where id = ? LIMIT ? OFFSET ?");
            s.setString(1,id);
            s.setInt(2, pageSize);
            s.setInt(3, offset);
            rs = s.executeQuery();
            List<TestBank> testBankList = new ArrayList<>();
            while (rs.next()) {
                TestBank testBank = new TestBank();
                testBank.setId(rs.getInt("id"));
                testBank.setCode(rs.getString("code"));
                testBank.setTitle(rs.getString("title"));
                testBank.setRemark(rs.getString("remark"));
                testBank.setUpdateTime(rs.getDate("update_time"));
                testBank.setCreateTime(rs.getDate("create_time"));
                testBankList.add(testBank);
            }
            resultMap.put("data", testBankList);
            // 获取总数
            String countSql = "SELECT COUNT(*) FROM el_repo where title = ?";
            countStmt = conn.prepareStatement(countSql);
            countStmt.setString(1,id);
            countRs = countStmt.executeQuery();
            if (countRs.next()) {
                int totalCount = countRs.getInt(1);
                resultMap.put("total", totalCount);
            }
            resultMap.put("code", "1");
            resultMap.put("message", "查询成功!");
            return JSONObject.toJSONString(resultMap);
        } catch (
                Exception e) {
            e.printStackTrace();
            resultMap.put("code", "0");
            resultMap.put("message", "查询失败!");
            return JSONObject.toJSONString(resultMap);
        }finally {
            if (conn!=null){
                conn.close();
            }
            if (s!= null){
                s.close();
            }
            if (rs!=null){
                rs.close();
            }
            if (countStmt!=null){
                countStmt.close();
            }
            if (countRs!=null){
                countRs.close();
            }
        }
    }

    @Override
    public String submitTest(Map<String, Object> stringObjectMap) throws SQLException {
        weaver.interfaces.datasource.DataSource ds = (weaver.interfaces.datasource.DataSource) StaticObj.getServiceByFullname(("datasource.test"), weaver.interfaces.datasource.DataSource.class);
        java.sql.Connection conn = ds.getConnection();
        conn.setAutoCommit(false);
        PreparedStatement s = null;
        try {
            String id = "";
            if (!ObjectUtils.isEmpty(stringObjectMap.get("id"))){
                id = String.valueOf(stringObjectMap.get("id"));
            }
            String sql = "INSERT INTO el_repo (code, title, remark, create_time, update_time) VALUES (?, ?, ?, ?, ?)";
            if (!StringUtil.isEmpty(id)){
                sql = "update el_repo set code =?,title = ?, remark = ?,update_time = ? WHERE id = ?";
            }
            s = conn.prepareStatement(sql);
            // 设置参数
            if (!StringUtil.isEmpty(id)){
                s.setString(1, (String) stringObjectMap.get("code"));
                s.setString(2, (String) stringObjectMap.get("title"));
                s.setString(3, (String) stringObjectMap.get("remark"));
                s.setObject(4, new Date()); // 设置当前时间为更新时间
                s.setString(5,id);
            }else {
                s.setString(1, (String) stringObjectMap.get("code"));
                s.setString(2, (String) stringObjectMap.get("title"));
                s.setString(3, (String) stringObjectMap.get("remark"));
                s.setObject(4, new Date()); // 设置当前时间为创建时间
                s.setObject(5, new Date()); // 设置当前时间为更新时间
            }
            int rowsAffected = s.executeUpdate();
            if (rowsAffected > 0) {
                conn.commit();
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("code", "1");
                resultMap.put("message", "测试保存成功");
                return JSONObject.toJSONString(resultMap);
            } else {
                conn.commit();
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("code", "0");
                resultMap.put("message", "测试保存失败");
                return JSONObject.toJSONString(resultMap);
            }
        } catch (Exception e) {
            conn.rollback();
            log.error("测试保存失败", e);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("code", "0");
            resultMap.put("message", "测试保存失败: " + e.getMessage());
            return JSONObject.toJSONString(resultMap);
        } finally {
            if (s != null) {
                s.close();
            }
            if (conn != null) {
                conn.setAutoCommit(true);
                conn.close();
            }
        }
    }

    @Override
    public String deleteTest(Map<String, Object> stringObjectMap) throws SQLException {
        weaver.interfaces.datasource.DataSource ds = (weaver.interfaces.datasource.DataSource) StaticObj.getServiceByFullname(("datasource.test"), weaver.interfaces.datasource.DataSource.class);
        java.sql.Connection conn = ds.getConnection();
        conn.setAutoCommit(false);
        PreparedStatement s = null;
        Map<String, Object> resultMap = new HashMap<>();
        try {
            String getTestSql = "select COUNT(*) from el_qu_repo where repo_id = ? ";
            PreparedStatement stat = conn.prepareStatement(getTestSql);
            stat.setString(1,(String) stringObjectMap.get("id"));
            ResultSet resultSet = stat.executeQuery();
            int total = 0;
            if (resultSet.next()){
                total = resultSet.getInt(1);
            }
            if (total>0){
                resultMap.put("code", "0");
                resultMap.put("message", "测试删除失败!当前测试下还存在某些信息!");
                return  JSONObject.toJSONString(resultMap);
            }
            String sql = "DELETE FROM el_repo WHERE id = ?";
            s = conn.prepareStatement(sql);
            // 设置参数
            s.setString(1, (String) stringObjectMap.get("id"));
            int rowsAffected = s.executeUpdate();
            if (rowsAffected > 0) {
                conn.commit();
                resultMap.put("code", "1");
                resultMap.put("message", "测试删除成功");
                return JSONObject.toJSONString(resultMap);
            } else {
                conn.commit();
                resultMap = new HashMap<>();
                resultMap.put("code", "0");
                resultMap.put("message", "测试删除失败");
                return JSONObject.toJSONString(resultMap);
            }
        } catch (Exception e) {
            conn.rollback();
            log.error("测试删除失败", e);
            resultMap = new HashMap<>();
            resultMap.put("code", "0");
            resultMap.put("message", "测试删除失败: " + e.getMessage());
            return JSONObject.toJSONString(resultMap);
        } finally {
            if (s != null) {
                s.close();
            }
            if (conn != null) {
                conn.setAutoCommit(true);
                conn.close();
            }
        }
    }
}

3.4 com.engine下的entity

package com.engine.test.testdemo.entity;

import lombok.Data;

import java.util.Date;


@Data
public class TestBank {

    private static final long serialVersionUID = 1L;
   
    private Integer id;
    
    private String code;
    
    private String title;

    private String remark;
    
    private Date createTime;

    private Date updateTime;


}

3.5 注意事项

    博主这里提供的代码都是修改之后的,具体返回的数据和前端是对不上的,具体的小伙伴们自己将数据修改对应即可,但是基本的增删改查都是这样来实现的,博主这里是连接的第三方数据库,这个数据库在后端应该中心的集成管理的数据源管理里面设置即可。如果要使用oa本地的数据库,则使用以下方式,使用RecordSet来实现。

 //查询人员id和名称
String userSql = "select id,lastname from hrmresource order by id asc";
 RecordSet userRs =  new RecordSet();
 userRs.execute(userSql);
 List<User> userList = new ArrayList<>();
 while (userRs.next()){
   User user = new User();
   user.setUid(userRs.getInt("id"));
   user.setLastname(userRs.getString("lastname"));
   userList.add(user);
 }

  如果是连接的外部数据库或者第三方数据库,则使用博主上面提供的方法,主要是weaver.interfaces.datasource.DataSource ds = (weaver.interfaces.datasource.DataSource) StaticObj.getServiceByFullname(("datasource.第三方数据库名称"), weaver.interfaces.datasource.DataSource.class);
  java.sql.Connection  conn = ds.getConnection();实现数据库的连接,后面通过PreparedStatement执行sql,ResultSet接收返回值即可。

<think>好的,我现在需要帮用户了解OA系统的二次开发方法或教程。首先,用户提到了几个引用,我需要结合这些引用内容来构建答案。 首先,引用[1]提到了二次开发培训资源,包括如何拦截接口并修改,还有示例代码。这说明后端开发和接口处理是重点。用户可能需要知道如何获取这些培训资料,以及学习路径是怎样的。 引用[2]列出了环境搭建、官方文档、开发规范、接口调用等内容。这里的关键点是环境配置和使用IDE(比如IDEA)进行开发,还有官方文档的重要性。用户可能想知道具体的环境搭建步骤,以及如何访问这些文档和规范。 引用[3]强调了数据库操作类的复用、后处理接口的编写注意事项,以及参数配置的问题。这部分需要提醒用户注意代码规范和错误处理,避免常见问题。 接下来,我需要整理出结构清晰的步骤。首先应该是环境搭建,这是开发的基础。然后是学习官方文档和规范,接着是接口开发和数据库操作,后是测试和部署。同时,用户可能还关心如何获取API文档和实际案例。 需要注意的是,用户可能对具体的代码示例和API调用方法感兴趣,所以应该提到相关的示例代码和接口调用方式,比如REST API或WebService。另外,引用中提到的注意事项,如数据库操作类的复用、错误处理,也需要包含在回答中,以帮助用户避免常见错误。 后,生成相关问题时要围绕用户可能的后续疑问,比如环境配置问题、接口开发的具体方法、性能优化等。确保问题覆盖用户可能想深入了解的方面。</think>### OA二次开发方法与教程 #### 一、开发环境搭建 1. **安装OA(Ecology)** 首先需下载并部署OA系统,确保基础运行环境(如JDK、数据库)已配置完成[^2]。 2. **IDE配置** 使用IntelliJ IDEA进行开发,需配置Maven依赖、项目SDK,并集成OA提供的开发框架。引用[^2]中提到环境搭建需按照官方指南操作,避免兼容性问题。 --- #### 、学习资源与规范 1. **官方文档与案例** - 引用[^2]强调需结合官方文档(含接口文档、开发规范)学习,入门案例包含在开发规范中,例如如何通过`Action`接口实现流程触发。 - 示例代码片段(参考引用[^1]): ```java // 示例:拦截接口并修改参数 public class CustomAction extends BaseAction { @Override public String execute() throws Exception { // 获取请求参数并修改 String param = getRequest().getParameter("key"); // 自定义逻辑处理 return SUCCESS; } } ``` 2. **开发规范** - 数据库操作类(如`RecordSet`)应尽量复用,避免频繁创建新实例[^3]。 - 接口编写需明确成功/失败状态,错误信息需清晰返回前端[^3]。 --- #### 三、接口开发实践 1. **API调用方式** - OA支持REST API和WebService接口,需通过系统提供的`/api/`路径调用。 - 三方系统调用时需配置鉴权参数,例如`token`和`sessionKey`[^2]。 2. **后处理接口开发** - 引用提到需注意活参配置(避免全角字符问题),例如前端参数传递时需校验格式: ```javascript // 前端参数校验示例 function validateParam(param) { if (/[^\x00-\xff]/.test(param)) { alert("参数能包含全角字符!"); return false; } return true; } ``` --- #### 四、调试与部署 1. **本地测试** 使用OA内置的调试工具,或通过日志文件(如`ecology.log`)追踪接口执行情况。 2. **生产环境部署** - 需将编译后的JAR/WAR包部署至OA的`WEB-INF/lib`目录。 - 配置文件(如`struts.xml`)需按规则更新[^2]。 --- #### 五、关键注意事项 1. **数据库优化** 避免频繁创建`RecordSet`对象,优先复用已有实例以减少资源消耗[^3]。 2. **错误处理** 接口失败时需返回明确错误码,例如: ```java try { // 数据库操作 } catch (SQLException e) { logger.error("数据库操作失败:" + e.getMessage()); return "error:数据库异常"; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值