移动办公OA系统

好久没有更新文章了,总觉得心里空空的,最近由于工作的原因,没有来的及及时更新,总感觉应该把学习到的东西做个记录,供大家学习,也供自己复习,温故而知新。今天趁着周末休息时间,把自己最近在公司的做的项目做一个总结。由于是刚入职不久,进公司负责的项目内容也很少,主要还是以学习为主。

一、项目介绍

       某银行移动办公系统,简称移动OA,是我进公司参与的第一个项目,主要负责的是java后台接口的开发,该系统涉及iOS,android,pad三个前台页面,后台就是为这三个客户端提供公共的接口,根据业务需要,以json格式传递过来的数据在后台进行处理,然后返回到前台进行展示。我们项目组负责的是OA里面的一个小项目-督办,该项目要实现银行项目申报、催促、进度查看、项目再分解等一些功能。根据页面展示需要,我完成了一下几个接口的开发,其中包括一些常用的查找功能和图片压缩下载。

  在介绍接口实现之前,有必要把自己学到的json解析再分析一遍,之前接触啊到的json格式的的字符串数据量很小,但在实际项目中数据量是如此之大,面对如此大的数据量,我也曾迷茫过,怎么解析是个问题,后来在项目经理的帮助和自己的努力下,终于完成了json解析这个工具类的开发,我觉的这个类可以应用到很多项目中,只要是涉及到json的地方都可以。

json解析代码如下:

/**
	 * 将json转化成map
	 * @param json
	 * @return
	 * @date 2017年2月25日
	 * @return Map<String,Object>
	 * @author 我心自在
	 */
	public static Map<String, Object> json2Map(Object json){
		if(json.equals("null")){
			return null;
		}
		JSONObject object = JSONObject.fromObject(json);
		Map map = new HashMap();
		Iterator it = object.keys();
		while (it.hasNext()) {
			String key = (String)it.next();
			String value = object.getString(key);
			if (JSONUtils.isObject(object.get(key))) {
				map.put(key, json2Map(value));
			} else if (JSONUtils.isArray(object.get(key))) {
				List list = new ArrayList();
				JSONArray jArray = JSONArray.fromObject(value);
				for (int i = 0; i < jArray.size(); i++) {
					if(JSONUtils.isObject(jArray.get(i)) ){
						list.add(json2Map(jArray.get(i)));
					}else if ( JSONUtils.isArray(jArray.get(i))){
						list.add(json2List(jArray.get(i)));
					}else {
						list.add(jArray.get(i));
					}
				}
				map.put(key, list);
			} else {
				map.put(key, ConvertUtil.obj2Str(object.get(key)));
			}
		}
		return map;
	}
      //下面是ConvertUtil中的部分代码,下面的方法将Object转化为String

        public static String obj2Str(Object obj) {
          return obj == null ? null : obj.toString();
        }


下面适用于json里面带数组的:

/**
	 * 用于 JSON里面带数组的
	 * @param json
	 * @return
	 */
	public static Map<String, Object> jsonArray2Map(Object json){
//		if(StringUtils.startsWith(json, "{") && StringUtils.endsWith(json, "}")){
//			json = "["+json+"]";
//		}
		JSONArray jsonArray = JSONArray.fromObject(json);
		JSONObject object = jsonArray.getJSONObject(0);
		Map map = new HashMap();
		Iterator it = object.keys();
		while (it.hasNext()) {
			String key = (String)it.next();
			String value = object.getString(key);
			if (JSONUtils.isObject(object.get(key))) {
				map.put(key, json2Map(value));
			} else if (JSONUtils.isArray(object.get(key))) {
				List list = new ArrayList();
				JSONArray jArray = JSONArray.fromObject(value);
				for (int i = 0; i < jArray.size(); i++) {
					if(JSONUtils.isObject(jArray.get(i)) ){
						list.add(json2Map(jArray.get(i)));
					}else if ( JSONUtils.isArray(jArray.get(i))){
						list.add(json2List(jArray.get(i)));
					}else {
						list.add(jArray.get(i));
					}
				}
				map.put(key, list);
			} else {
				map.put(key, ConvertUtil.obj2Str(object.get(key)));
			}
		}
		return map;
	}

二、接口的开发

2.1 接口一:左侧菜单显示

       该接口主要实现的功能是:将json传递过来的数据到展示到前台页面,主要是左侧菜单的三个按钮。

代码如下:

 

public class LeftMenuListServlet extends HttpServlet {
    private static final long serialVersionUID = -169633978370129408L;
    private Logger logger = Logger.getLogger(this.getClass());
    private SuperviseService superviseService = (SuperviseService) ApplicationContextProvider.getBean("superviseService");

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        response.setContentType("application/x-www-form-urlencoded");
        response.setContentType("text/html;charset=UTF-8");
        request.setCharacterEncoding("UTF-8");
//        //获取入参
        String loginUserId = ConvertUtil.obj2Str(request.getSession(true).getAttribute(Current.SESSION_KEY_USER_ID));

        MDC.put("user", loUserId);
        MDC.put("sessionid", request.getSession().getId());
        MDC.put("starttime", System.currentTimeMillis());

        String opCode = "code_0001_0018_0001";
        MDC.put("opcode", opCode);

        ResultJson resultJson = new ResultJson();

        try {
            String json = request.getParameter("json");
            if (StringUtils.isBlank(json)) {
                resultJson.setEc(CurrencyVariable.EC_PARAMETER_EXCEPTION);
                resultJson.setEm(CurrencyVariable.EM_PARAMETER_EXCEPTION);
            } else {
//                设置入参
                Map jsonMap = JsonUtil.json2Map(json);
                Map dataMap = (Map) jsonMap.get("data");
                String bottomTab = (String) dataMap.get("bottomTab");
                String headerTab = (String) dataMap.get("headerTab");
                Object currentUserId = loginUserId;
                logger.info("code_0001_0018_0002");
                logger.info("\t currentUserId = " + currentUserId);

                resultJson = superviseService.leftMenulist(opCode, loginUserId, bottomTab,headerTab);
                resultJson.setOpCode(opCode);
            }
        } catch (Exception e) {
            logger.error("参数异常 ", e);
            resultJson.setEc(CurrencyVariable.EC_PARAMETER_EXCEPTION);
            resultJson.setEm(CurrencyVariable.EM_PARAMETER_EXCEPTION);
        }
        String newsResultJson = new GsonBuilder().serializeNulls().create().toJson(resultJson);

        logger.info(opCode + " newsResultJson==" + newsResultJson);
        response.getOutputStream().write(newsResultJson.getBytes("UTF-8"));
        //业务逻辑结束。。。
        MDC.put("endtime", System.currentTimeMillis());//请求结束后put
//        logger.info("操作结果:"+resultJson.getEc());
        logger.log(SeriousLogger.SERIOUS_LEVEL, "操作结果:" + resultJson.getEc());
    }
}

//service方法如下:
@Override
    public ResultJson leftMenulist(String opCode, String loginId,
            String bottomTab, String headerTab) {
        CloseableHttpClient httpClient = getHttpClient();
        ResultJson resultJson = new ResultJson();
        resultJson.setOpCode(opCode);
        // resultJson.setData(jsonObject.get("data"););
        CloseableHttpResponse httpResponse = null;
        HttpPost post = new HttpPost(SUPERWISE_HOST + LEFT_MENU_LIST_PATH);
        log.info(post.getURI());
        List<NameValuePair> list = new ArrayList<NameValuePair>();

        // 封装入参
        list.add(new BasicNameValuePair("bottomTab", bottomTab));
        list.add(new BasicNameValuePair("loginId", loginId));
        list.add(new BasicNameValuePair("headerTab", headerTab));

        // 重写ec,em
        Common.util(httpClient, resultJson, httpResponse, post, list);

        return resultJson;
    }

这里解释一下opCode。该项目的设计思想是通过OpCode来访问servlet,提高访问速度,有利于后期项目的维护,具体的配置在web.xml中可见:

首先定义opcode使之指向要访问的servlet如:

//左侧菜单
public static final String code_0001_0001 = "/mobileoa/web/servlet/dd/LeftMListServlet.do";

然后通过反射的方式加载此类

static{
try{ 
Class<?> c = Class.forName("com.mobileoa.util.ForwardCtrlVariable"); 
  Field[] fields = c.getDeclaredFields(); 
  for (int i = 0; i < fields.length; i++) { 
  String m = Modifier.toString(fields[i].getModifiers()); 
  if (m != null && m.indexOf("final") > -1 && !("map".equals(fields[i].getName()))) {
    map.put(fields[i].getName(), (String) fields[i].get(String.class));
  } 
} 
  }catch (ClassNotFoundException e){ 
    log.error("ForwardCtrlVariable:",e);
  }catch (IllegalArgumentException e){ 
    log.error("ForwardCtrlVariable:",e);
  }catch (IllegalAccessException e){
    log.error("ForwardCtrlVariable:",e);
}

获得opcode值,从而访问servlet,web.xml中的配置如下:

<servlet>
<servlet-name>dubanLeftMenuListServlet</servlet-name>
<servlet-class>com.thitect.middletier.mobileoa.web.servlet.dd.LeftMListServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ddLeftMenuListServlet</servlet-name>
<url-pattern>/mobileoa/web/servlet/dd/LeftMListServlet.do</url-pattern>
</servlet-mapping>

Common中util方法主要是对http请求进行了封装,关于http请求的实现方法,参见文章:http://www.cnblogs.com/10158wsj/p/6767209.html

public class Common {
    private static final Logger log = Logger.getLogger(Common.class);
    static ResultJson util(CloseableHttpClient httpClient, ResultJson resultJson, CloseableHttpResponse httpResponse, HttpPost post, List<NameValuePair> list) {
        try {
            UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(list, "UTF-8");
            post.setEntity(uefEntity);
            httpResponse = httpClient.execute(post);
            HttpEntity entity = httpResponse.getEntity();
            String s = EntityUtils.toString(entity);

            JSONObject jsonObject = JSONObject.fromObject(s);
            log.info(jsonObject);
            Object result = jsonObject.get("data");
            resultJson.setData(result);
            String ec = (String) jsonObject.get("ec");
            if (ec.equals("0001")) {
                resultJson.setEc(CurrencyVariable.EC_DUBAN_NOEXIST);
                resultJson.setEm(CurrencyVariable.EM_DUBAN_NOEXIST);
            }
            if (ec.equals("0002")) {
                resultJson.setEc(CurrencyVariable.EC_DUBAN_EXCEED);
                resultJson.setEm(CurrencyVariable.EM_DUBAN_EXCEED);
            }
            if (ec.equals("0003") || ec.equals("0005")) {
                resultJson.setEc(CurrencyVariable.EC_DUBAN_DBERROR);
                resultJson.setEm(CurrencyVariable.EC_DUBAN_DBERROR);
            }
            if (ec.equals("0004")) {
                resultJson.setEc(CurrencyVariable.EC_DUBAN_EXCEPTION);
                resultJson.setEm(CurrencyVariable.EC_DUBAN_EXCEPTION);
            }

            EntityUtils.consume(entity);
            if (ec.equals("0000")) {
                resultJson.setEc(CurrencyVariable.EC_SUCESS);
                resultJson.setEm(CurrencyVariable.EM_SUCESS);
                resultJson.setData(result);

            }
        } catch (Exception e) {
            e.printStackTrace();
            resultJson.setEc(CurrencyVariable.EC_RUNTIME_EXCEPTION);
            resultJson.setEm(CurrencyVariable.EM_RUNTIME_EXCEPTION);
        } finally {
            Common.CloseableHttpResponse(httpResponse);
            Common.CloseableHttpClient(httpClient);
        }

        return resultJson;
    }
    private static void CloseableHttpResponse(CloseableHttpResponse httpResponse) {
        if (httpResponse != null) {
            try {
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void CloseableHttpClient(CloseableHttpClient client) {
        if (client != null) {
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 至此,完成了第一个接口的开发,主要的实现就是这样,后面还陆续写了几个这种类型接口的开发,个人认为这几个接口大同小异,没有必要一一罗列,如图所示:

2.2接口二:图片压缩功能

       督办项目中,有一些文件信息十一图片的形式给出的,这就要求前端打开的图片的速度要快,用户体验要好,由于之前没有做图片压缩,导致打开图片事件较长且耗费流量,所以为了实现用户体验,有必要对图片做一下压缩,压缩之后以流的方式进行下载,这个方法是写在action中的也就是struts框架。实现代码如下:

    /**
     * 查看流程意见图片
     */
    public void showNodeOpinionPic(){
        String picURL = request.getParameter("pic_url");
        log.info("流程框架页面:ProcBaseForm_正文表单:查看流程处理意见图片=" + picURL);
        String kmURL = this.getKMHttpUrl();
        String url=kmURL+picURL;
        String fdId = getParamFormUrl(url);
        logger.info("fdId=" + fdId);
        String loginUserId = this.getUserId();
        logger.info("loginUserId=" + loginUserId);
        InputStream ins = null;
        BufferedInputStream bis = null;
        OutputStream out = null;
        HttpServletResponse response = ServletActionContext.getResponse();
        
        List filePathResultList = oaImageReduceService.getImageList(fdId, url,request);
        
        try {
            if (filePathResultList != null && filePathResultList.size() > 0) {
                // 下载
                Map<String, Object> filePathMap = (Map) filePathResultList.get(0);
                logger.info("filePathMap===" + filePathMap);
                String filePath = (String) filePathMap.get("file_path");
                if (!filePath.contains(File.separator) && !filePath.contains("/")) {
                    filePath = auditDownloadService.getFileNameByAuditCode(
                            loginUserId, filePath);
                }
                logger.info("filePath===" + filePath);
                if (StringUtils.isNotEmpty(filePath)) {
                    File file = new File(filePath);
                    if (file.exists()) {
                        long p = 0L;
                        long toLength = 0L;
                        long contentLength = 0L;
                        int rangeSwitch = 0; // 0,从头开始的全文下载;1,从某字节开始的下载(bytes=27000-);2,从某字节开始到某字节结束的下载(ex:bytes=27000-39000)
                        long fileLength;
                        String rangBytes = "";
                        fileLength = file.length();
                        logger.info("fileLength Value = " + fileLength);
                        ins = new FileInputStream(file);
                        bis = new BufferedInputStream(ins);
                        response.reset();
                        response.setHeader("Accept-Ranges", "bytes");
                        String range = request.getHeader("Range");
                        logger.info("Range's Value = " + range);
                        if (range != null && range.trim().length() > 0
                                && !"null".equals(range)) {
                            response.setStatus(javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT);
                            rangBytes = range.replaceAll("bytes=", "");
                            if (rangBytes.endsWith("-")) { // bytes=270000-
                                rangeSwitch = 1;
                                p = Long.parseLong(rangBytes.substring(0,
                                        rangBytes.indexOf("-")));
                                contentLength = fileLength - p; // 客户端请求的是270000之后的字节(包括bytes下标索引为270000的字节)
                            } else { // bytes=270000-320000
                                rangeSwitch = 2;
                                String temp1 = rangBytes.substring(0,
                                        rangBytes.indexOf("-"));
                                String temp2 = rangBytes.substring(
                                        rangBytes.indexOf("-") + 1,
                                        rangBytes.length());
                                p = Long.parseLong(temp1);
                                toLength = Long.parseLong(temp2);
                                contentLength = toLength - p + 1; // 客户端请求的是270000-320000之间的字节
                            }
                        } else {
                            contentLength = fileLength;
                        }
                        // 如果设设置了Content-Length,则客户端会自动进行多线程下载。如果不希望支持多线程,则不要设置这个参数。
                        // Content-Length: [文件的总大小] - [客户端请求的下载的文件块的开始字节]
                        //response.setHeader("Content-Length",new Long(contentLength).toString());
                        // 断点开始
                        // 响应的格式是:
                        // Content-Range: bytes [文件块的开始字节]-[文件的总大小 - 1]/[文件的总大小]
                        if (rangeSwitch == 1) {
                            String contentRange = new StringBuffer("bytes ")
                                    .append(new Long(p).toString()).append("-")
                                    .append(new Long(fileLength - 1).toString())
                                    .append("/")
                                    .append(new Long(fileLength).toString())
                                    .toString();
                            response.setHeader("Content-Range", contentRange);
                            bis.skip(p);
                        } else if (rangeSwitch == 2) {
                            String contentRange = range.replace("=", " ") + "/"
                                    + new Long(fileLength).toString();
                            response.setHeader("Content-Range", contentRange);
                            bis.skip(p);
                        } else {
                            String contentRange = new StringBuffer("bytes ")
                                    .append("0-").append(fileLength - 1)
                                    .append("/").append(fileLength).toString();
                            response.setHeader("Content-Range", contentRange);
                        }
                        String fileName = file.getName();
                        response.setContentType("application/octet-stream");
                        response.addHeader("Content-Disposition","attachment;filename=" + fileName);
                        out = response.getOutputStream();
                        int n = 0;
                        long readLength = 0;
                        int bsize = 1024;
                        byte[] bytes = new byte[bsize];
                        if (rangeSwitch == 2) {
                            // 针对 bytes=27000-39000 的请求,从27000开始写数据
                            while (readLength <= contentLength - bsize) {
                                n = bis.read(bytes);
                                readLength += n;
                                out.write(bytes, 0, n);
                            }
                            if (readLength <= contentLength) {
                                n = bis.read(bytes, 0,(int) (contentLength - readLength));
                                out.write(bytes, 0, n);
                            }
                        } else {
                            while ((n = bis.read(bytes)) != -1) {
                                out.write(bytes, 0, n);
                            }
                        }
                    } else {
                        logger.info("文件不存在!");
                    }
                }
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 业务处理结束
        if (bis != null) {
            try {
                bis.close();
            } catch (Exception e2) {
            }
        }
        if (ins != null) {
            try {
                ins.close();
            } catch (Exception e2) {
            }
        }
        if (out != null) {
            try {
                out.flush();
                out.close();
            } catch (Exception e2) {
            }
        }
    }
    
    /**
     * 从url中获取fdId
     */
    private static String getParamFormUrl(String url) {
        String fdId = "";
        if (StringUtils.isEmpty(url)) {
            fdId = null;
        }
        String[] urlArr = url.split("\\?");
        if (urlArr == null || urlArr.length == 0) {
            fdId = null;
        }
        for (int i = 0; i < urlArr.length; i++) {
            if (urlArr[i].contains("FCheckbox=")) {
                String[] params = urlArr[i].split("\\/");
                for (int j = 0; j < params.length; j++) {
                    if (params[j].endsWith(".jpg")) {
                        fdId = params[j].replace(".jpg", "");
                    }
                }
            }
        }
        return fdId;
    }
//service部分代码
@Override
    @Transactional
    public List getImageList(String fdId, String url, HttpServletRequest request) {
        logger.info("services param[fdId="+ fdId + ", url=" + url+ "]");
        List markList = fileDao.findFileByExtendMark(fdId);
        logger.info("markList="+ markList);
        byte[] fileByte = null;
        String fileNameTemp = null;
        if(markList == null || markList.size() == 0){
            fileByte = this.getImageFromURLNew1(url);
            fileNameTemp = this.getNewPicName(fileByte, url);
            logger.info("生成图片名称"+fileNameTemp);
        } else {
            fileNameTemp = (String)((Map)markList.get(0)).get("file_path");
            logger.info("从数据库获取图片信息:" + fileNameTemp);
        }

        List list = fileDao.findChildFileNameByFileName(fileNameTemp, "source");
        logger.info("fileDao.findChildFileNameByFileName(fileNameTemp, 'source')"+list);
        if (list == null || list.size() == 0) {
            list = postfixFileConvertService.postfixConvert(fileNameTemp, CurrencyVariable.FILE_TYPE_SOURCE_TO_IMAGE, true, fileByte, null, null, request, CurrencyVariable.PORTAL, fdId);
        } else {
            list = postfixFileConvertService.postfixConvert(fileNameTemp, CurrencyVariable.FILE_TYPE_SOURCE_TO_IMAGE, true, null, null, null, request, CurrencyVariable.PORTAL, fdId);
        }
        return list;
    }

这段代码基本完成了图片压缩功能的实现,另外通过设置http请求告诉浏览器以流的方式下载图片并显示到前台页页面。

三、总结

       这是从学校毕业毕业工作以来,真正意义上接触到的企业大项目,该项目主要的架构就是Spring+Struts+Hibernate,另外还有部分业务的实现用的是Servlet,其实struts本身就是一个大大的Servlet,只不过是更好的对Servlet进行了封装,并且能够更好的实现MVC模式。通过该项目,大大的增加了企业项目的开发经验,熟悉了很多开发工具的使用,本项目采用的是Spring-tools-suitIDE,目的是能够更好的使用Spring。熟悉了代码管理工具SVN的使用,进一步熟悉了开发服务器Weblogic的使用,在linux环境下部署、开发javaWEB项目。

  写这篇博文的目的就是及时把自己的项目经验写出来与大家共勉,也为增加自己的开发经验,进一步熟悉企业项目的开发流程,开发特点。

 

转载于:https://www.cnblogs.com/10158wsj/p/7044789.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
除了具有传统OA的邮件、工作流、文档等功能外,还引进了项目管理和知识管理的思想,更加注重工作任务的分解、协同和监督;知识的积累、沉淀和分享,多条件跳转的分支流更为特色,有效为企业构筑协同工作平台 我的任务:今天未完成任务列表 我的邮件:最新收到的邮件列表 我的文档:最新归档的项目文档 我的审批:待我审批的项目文档 考勤:成员上下班的考勤 全文检索:对系统中项目文档的全文检索,并有权限过滤机制 系统设置各类接点:系统的权限中心和配置中心 人员管理:系统账户;由系统管理员添加、修改;可以定义新增、离职、调职还可自定义查询 职位管理:组织内的职位结构树,是权限的基本结构 角色管理:权力的集合,可以自由定义。系统默认的有组长、组员和系统成员。 修改口令:成员修改自己的口令(系统管理员在成员模块中修改口令) 考勤查询:查询包括自己在内的考勤纪录,或系统指定的成员如人事助理可查全部成员 考勤设置:考勤日和考勤时间的设置 公司论坛:包括公司公告和各版块BBS;有BBS管理权可以添加桌面公告和版块公告,版主可以自由添加版块和版块公告。BBS的功能同常见的,但无须登录; 客户管理(客户接触点的管理) 我的客户:显示由我负责的客户信息,并添加接触纪录(电话、拜访等) 查询、统计:客户资料的统计和分析,销售人员的业绩管理 我的联系人 公司内部联系人:系统成员列表中获得 公司外部联系人:等同于公司客户的联系人 自定义联系人:管理私人的联系人 我的任务:(含任务协同、任务指派、任务查询) 待完成任务:显示今日往后的未完成任务,并对任务操作,如新建、取消、完成、接受 未完成任务:显示今日以前的未完成任务 已完成任务:显示完成的任务 我的发起任务:显示所有我发起的任务,其中包括我仅发起而不执行的指派任务 订阅/查询任务:显示我不参加的任务,查询他人的任务 我的邮件 收件箱:我收到的邮件,全部显示 发件箱 :我曾经发送的邮件,全部显示 废件箱 :我删除的收到过的的邮件 撰写新邮件:可以有项目属性,并可归档 公文流转 待批文档:流程走到我这里的文档,等待我处理 我的申请:我发起的流转申请 已批文档:从我这里过的,被我处理过的文档 流程管理:由我创建和管理的流程,需要制定环节和绑定角色 拟稿箱:我可以发起的文档流转的入口,凡流程的第一环节有我的,都显示;并可以对流程有条件查询 我的文档 已归档:我可以查看的已归档项目文档 待审批:正等待我审批的项目文档;审批权包括角色指定,或是项目组长。 公司项目:项目树的管理,每人看到自己参与的项目内容或权限赋予的内容 投递文档:对该项目投递相关的文档 撰写邮件:对该项目组成员发送邮件 项目管理:项目的创建、删除、修改、移动 成员管理:项目成员的添加、删除;组长的标记;组员权限的变更 项目订阅:显示我关心的项目内容(本人并不是项目成员,但有权查看) 目录管理:创建项目文档库,并有严格权限限制,文档目录可扩展 短信管理: 站内短信:系统内的消息机制 站外手机短讯:发送多个附加手机号码 USB_Key 设置:对硬件加密的设置
本程序结合了OA办公系统+HR人力资源管理系统+CRM客户关系管理系统集合而成。我们把程序设计信息化应用分为三个方面的内容:通用办公应用、业务管理和决策支持。采用现代最新技术,建立一种新概念的、开放的现代管理和办公环境,它以TCP/IP、广域网互连、路由、防火墙和网络管理技术为核心,建立一个安全可靠的网络应用平台。利用最新的ASP.NET平台、javascript和AJAX、SQLSERVER关系型数据库等技术,结合OA思想的独特设计,建立一个开放的信息资源管理平台。 利用数据库及分布式处理技术、模块化功能设计,构造信息存储与事务处理平台。该智能办公平台结合了广大机构的信息需求所研发,适用于全部的政府和企业的信息办公需要。程序具体商业价值型,同时也是完全的开源,可以供下载者研究和进行二次的开发均可。该智能办公平台具有如下几大特色亮点: 亮点一:office文档在线编辑。 两点二:动态生成各类报表。 亮点三:工作流优化,方便新建任意格式审批单。 亮点四:功能授权于数据授权并用,可对多部门,多人员进行进行交叉授权。 亮点五:提供“智能窗体”向导,可任您快速且自由地制作多功能的网页办公系统。 亮点六:自定义工作流程,系统所有参数可自定义配置,支持多分公司、多部门架构。 亮点七:系统基于B/S结构,客户端零管理,避免了C/S系统维护的烦琐,降低维护成本。 亮点八:细分的权限管理,可满足用户不同的权限管理要求。 亮点九:灵活的配置,可方便自定义工作表单、环节和流程。 亮点十:良好的系统开放性和可扩展性,为企业轻松架构Internet应用。 政 府、企事业单位的信息化建设是一个集办公自动化、业务管理、领导决策等应用为一体综合信息管理系统,是一个应用覆盖面广泛,涉及部门多的应用系统。财务、 人事、或业务管理系统往往只是涉及一个部门,或者一部分人员使用的业务管理系统。而整个单位的信息化涉及各个部门和各项业务,使用人员包括单位的最高级领 导、管理部门和全体员工。因此,政府和企业的信息化是一个涉及面广泛的综合信息管理系统。该OA办公程序是一套通用的信息管理平台,平台主要包含八个主要部分:个人事务、工作流程、公共事务、信息交流、人力资源、销售管理、附件程序和系统管理。 个人事务:主要是与个人办公、通讯、考勤、会议等等相关内容的整合。 工作流程:涉及个人的网络公章管理及使用记录,各种表单的定制、类别管理,工作流的管理及工作管理。 公共事务:涉及工作计划、办公用品的管理、会议、车辆以及固定资产的管理。 信息交流:用于建立公司企业内部的交流平台及短信发送。 人力资源:对公司人员的信息档案有一定的管理,涵盖了人事档案、考勤批示、统计、薪资管理、培训记录及奖惩记录等等。 销售管理:大致分为客户方面的管理、产品方面管理以及销售方面管理的综合业务管理。 附件管理:提供常用的日历、世界时间查询、常用网址的保存(便于一键打开特定的地址)、全国各个省、县、市的邮政编码和电话区号。 系统管理:用于规划本单位信息系统的结构、内容、印章、公告、红头文件的管理。按照组织机构、业务分类、功能需要设计信息系统的菜单,按照用户所属的部门、角色、职位、管理范围进行管理和权限指派。其中主要的功能模块和说明如下解释: 个人办公: 内部邮件---系统内部的信息交流、文件交流、信息提醒等 Internet邮件---接口外部邮箱,采用pop3和smtp协议代收代发 单位公告通知---管理公告通知、新闻等信息,可选定特定部门发送 投票---内部信息投票,每个用户拥有一次投票权利 手机短信---发送内部或者外部的手机短信消息,用于提醒等 日程安排---个人日程以日历形式重点体现,到期自动提醒 工作日志---工作过程中的记录以及工作日志等 通讯簿 --- 包含各种分类,主要用于联系使用 个人设置 --- 设置个人参数、邮箱参数、提醒参数、修改密码等 审批流程: 新建工作---新建新的审批工作流,选定需要的工作新建即可 我的工作--- 个人发起的所有工作,包括已审批、未审批的所有工作 待办工作---需要当前用户进行办理或者审批的工作列表 已办工作---当前用户已经办理过的各项工作,包含历史工作 工作查询---查询系统中工作的信息,全面检索 工作监控---管理员监控运行,发现问题,可强制干预 归档工作---已办理完成的工作,自动进行归档 工作委托 --- 当前用户指定办理人,所有待办事项自动提交到委托人办理 流程设置 --- 自定义流程、自定义表单、表单各个字段在流程中权限控制 印章管理 --- 管理公章与私章,查看印章的各项使用日志等 公文收发: 接收文件--- 需要接受的文件,未签收时有颜色标注 传阅文件 --- 传阅发送出去文件 接收分类 --- 按照指定文件夹分类查看 传阅分类 --- 传阅文件夹个人分类查看 工作管理: 我的计划---个人工作计划,可共享给其他指定用户协同查看 协同计划--- 其他用户协同共享查看的工作计划信息 我的汇报---个人工作汇报,可共享给其他指定用户协同查看 协同汇报---其他用户协同共享查看的工作汇报信息 下属任务: 我的任务 --- 个人接收到的各项任务,提交工作任务报告 任务分配--- 对下属用户分派工作任务,实时监控任务情况 下属日程 --- 下属员工的日程安排信息 下属日志 --- 下属员工的工作日志信息 下属计划--- 下属员工的工作计划信息 下属汇报 --- 下属员工的工作汇报信息 下属邮件 --- 下属员工的内部邮件信息 下属客户--- 下属员工的客户资料信息 知识文档: 个人文件 --- 类同与网络硬盘、个人文件柜存储等文件存储类 单位文件 --- 单位各类文件存储区 项目文件 --- 项目实施、进度、评审等文件存储类 电子刊物 --- 电子刊物等文件存储类 重要文件 --- 特别重要的文件额外存储类 机密文件 --- 机密文件存储类 知识库 --- 各项知识库、技术资料、学习资料、单位规范等 技术文件 --- 技术类文件存储 共享文件 --- 查看各类共享的文件资料 回收站 --- 删除的文件,可恢复或者彻底删除 扩展应用: 资产管理--- 管理固定资产、仪器、办公用品等 培训管理--- 管理培训信息 会议管理 --- 各项会议会议、上传会议记录 车辆管理 --- 车辆信息、使用、维修、保险、加油等 图书管理 --- 图书信息、借阅、归还等 档案卷库 --- 各类档案分卷库保存、销毁 考试管理 --- 在线考试、可分题库、题目类型、试卷制定、自动评分等 学习管理--- 在线学习、学习心得、领导批注等 客户管理: 会员管理 --- 会员信息管理,即为个人类别的客户 我的客户 --- 个人客户资料、联系记录、需求等 客户管理 --- 管理所有客户资料,联系人、联系记录、需求计划等 进销存类: 产品管理--- 产品管理、库存列表显示、库存报警等 销售管理 --- 销售合同、产品销售出库、利润等 采购管理 --- 采购合同、产品采购入库等 供应商管理 --- 管理各个供应商、供应商联系人 项目管理: 项目信息 --- 项目各项信息、状态等 评审信息 --- 评审记录 项目进度--- 项目具体进度安排、时间进度 收款信息 --- 收款具体情况,按照项目分类 项目实施 --- 项目的具体实施情况 报销申请 --- 项目类单独报销,也可使用审批流程中的自定义流程 报销管理 --- 审批报销记录,复杂流程可使用审批流程 项目利润 --- 核算具体利润情况 数据统计 --- 数据各项统计 人力资源: 考勤管理 --- 考勤记录、考勤设置、查询、统计等 人事档案--- 人事基本资料维护 人事合同--- 合同管理情况 奖惩记录 --- 奖惩各类记录管理 奖惩制度 --- 各类具体制度安排、单位规章制度等。 应聘简历 --- 简历管理,建立单位人才库 面试管理 --- 具体面试情况管理 绩效考核 --- 绩效考核数据上报等 绩效参数 --- 绩效各项参数的设置 薪酬管理--- 薪酬各类数据管理 薪酬参数 --- 各个参数设置 报表中心: 报表分类--- 报表分类设置,根据需要可分多个类别 报表管理--- 动态定制报表、动态数据抓取。报表可自定义。 信息交流: 论坛BBS---论坛各个信息、帖子发帖信息 版块设置 --- 版块具体设置 内部聊天室 --- 各个聊天室进入后可自由聊天 聊天室设置 ---聊天室的基本设置 组织机构: 单位信息查询 --- 查询单位基本信息 部门信息查询 --- 查询部门信息 用户信息查询 --- 查询用户个人信息 附件程序: 电话区号查询--- 电话区号查询 邮政编码查询---邮政编码查询,超级链接到网址 列车时刻查询 --- 链接到列车时刻查询网址 公交线路查询 --- 公交线路查询 法律法规查询 --- 法律法规各项资料超级链接查询 休闲游戏 --- 链接到游戏网 万年历--- 日历基本信息 世界时钟 --- 时间查询 常用网址---常用的网站

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值