前言

新版本OA系统已于今日开发完毕,碰巧写前端的同事去抽掉走写别的项目了,所以前后端开发的任务就交到了我的身上,虽然前端不是很擅长,但是CV改一改还是能跑起来的,正好借这个机会写一下OA系统中的审批功能吧。

这就是审批模块的主页,因为审批是有层级的,所以在状态栏里是有一个临时状态的,第一个状态就属于临时状态,这个状态针对于当前登录人(审批人)的审批状态,后面的状态是针对这条数据的审批状态。打个比方说,一条报销审批,先到部门经理哪里,然后在部门经理的页面就显示待审批,等部门经理审批完后,临时状态就变成了审批完成,单后面的状态还是“未完成审批”,只有当这条数据彻底完成后,才会显示完成审批。在审批备注里就变成了部门经理已审批完毕,等待财务审批。这时在财务人员的OA页面中显示的是这条报销数据的临时状态是未审批,状态是“未完成审批”。

前端

<template><div> <div slot="top"><el-form><el-row :gutter="5"><el-col :span="3"><el-form-item><el-select v-model="searchParameter.dome3" clearable placeholder="合同类型" style="width: 100%"><el-optionv-for="item in bxTypeOptions":key="item.index":label="item.value":value="item.value"></el-option></el-select></el-form-item></el-col><el-col :span="3"><el-form-item><el-input placeholder="合同编号" v-model="searchParameter.htorder" clearable></el-input></el-form-item></el-col><el-col :span="3"><el-form-item><el-input placeholder="甲方名称" v-model="searchParameter.a" clearable></el-input></el-form-item></el-col><el-col :span="3"><el-form-item><el-input placeholder="乙方名称" v-model="searchParameter.b" clearable></el-input></el-form-item></el-col><el-col :span="3"><el-form-item><el-input placeholder="经办人员" v-model="searchParameter.username" clearable></el-input></el-form-item></el-col><el-col :span="3"><el-form-item><el-select v-model="searchParameter.status" clearable placeholder="审批状态" style="width: 100%"><el-optionv-for="item in spTypeOptions":key="item.index":label="item.label":value="item.value"></el-option></el-select></el-form-item></el-col><el-col :span="3"><el-form-item><el-select v-model="searchParameter.status4" clearable placeholder="审批完成" style="width: 100%"><el-optionv-for="item in spExceTypeOptions":key="item.index":label="item.label":value="item.value"></el-option></el-select></el-form-item></el-col><el-col :span="3"><el-button-group><el-tooltip content="查询" placement="bottom" open-delay="1000" effect="light"><el-button type="primary" icon="el-icon-search" @click="Search()"></el-button></el-tooltip><el-tooltip content="重置" placement="bottom" open-delay="1000" effect="light"><el-button type="primary" icon="el-icon-refresh" @click="ResetParameter()"></el-button></el-tooltip><el-tooltip content="导出" placement="bottom" open-delay="1000" effect="light"><el-button type="primary" icon="el-icon-upload" @click="exportExcel()"></el-button></el-tooltip><el-tooltip content="高级搜索" placement="bottom" open-delay="1000" effect="light"><el-button type="primary" icon="el-icon-zoom-in"></el-button></el-tooltip></el-button-group></el-col> </el-row></el-form></div><el-tableid="table" :data="tableData" :showPage="false" ref="table" style="width: 100%"  :border="true" :header-cell-style="{background: '#FFFAF0',color: '#000',fontFamily:'SimHei',fontSize:'16px'}"><el-table-columntype="selection"width="55px"></el-table-column><el-table-columnlabel="合同类型"prop="dome3" min-width="8%"></el-table-column><el-table-columnlabel="合同编号"prop="htorder" min-width="10%"></el-table-column><el-table-columnlabel="甲方名称"prop="a" min-width="8%"></el-table-column><el-table-columnlabel="乙方名称"prop="b" min-width="8%"></el-table-column>   <el-table-column label="内容简介" prop="sqwhy" min-width="8%"/>   <el-table-column label="经办人" prop="username" min-width="8%"/><el-table-column label="签订时间" prop="qddate" min-width="10%" show-overflow-tooltip></el-table-column><el-table-column label="状态" prop="dome1" min-width="12%" align="center"><template slot-scope="scope"><el-tag size="mini" :hit='true' :type="scope.row.spstatuls === '1' ? '': 'warning'">{{scope.row.spstatuls === '1' ? '已审批' : '待审批'}}</el-tag><el-tag size="mini" :hit='true' :type="scope.row.dome1 === '4' ? '': 'warning'">{{scope.row.dome1 === '4' ? '完成审批' : '未完成审批'}}</el-tag></template></el-table-column><el-table-column prop="spdate" label="审批备注" min-width="20%" show-overflow-tooltip>        </el-table-column><el-table-column fixed="right" label="操作" min-width="8%"><template slot-scope="scope"><el-button type="text" icon="el-icon-chat-dot-square" @click="ShowDetailDialog(scope.row)">详细情况</el-button></template></el-table-column></el-table><div class="block"><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="1":page-sizes="[20, 50, 100, 200, 1000]":page-size="50"layout="total, sizes, prev, pager, next, jumper":total="rows">></el-pagination></div><el-dialog title="详细情况  " width="800px" :visible.sync="DetailDialogValue"><div><el-table:data="bxItemDetails":span-method="objectSpanMethod"border:header-cell-style="{fontFamily:'SimHei',fontSize:'14px'}"><el-table-column prop="username" label="姓名" width="180">  <template slot-scope="scope"><div :style="{fontSize:'18px'}">                    {{scope.row.username}}</div></template>            </el-table-column><el-table-column prop="details" label="合同详情"><template slot-scope="scope"><div :style="{color:scope.row.important == 1 ?'red':'#333',fontSize:scope.row.important == 1 ?'18px':'14px'}">                    {{scope.row.details}}</div></template></el-table-column></el-table></div><div><div :style="{margin:'10px'}"><span :style="{fontFamily:'SimHei',fontSize:'18px'}">审批流程</span></div><div :style="{margin:'0 30px'}"><el-timeline><el-timeline-itemv-for="(activity, index) in activities":key="index":icon="activity.icon":type="activity.type":color="activity.color":size="activity.size":timestamp="activity.timestamp">{{activity.content}}</el-timeline-item></el-timeline></div></div><!-- <div><div :style="{margin:'10px'}"><span :style="{fontFamily:'SimHei',fontSize:'18px'}">报销单图片</span></div><div style="display:flex" class="border"><div class="block"  v-for="url in images" :key="url"><div><el-imagestyle="width: 100px; height: 100px; margin:10px":src="url":fit="contain":preview-src-list="images"></el-image><el-divider direction="vertical" v-if="images.indexOf(url) != images.length - 1"></el-divider></div></div><div class="block" v-for="url in images" :key="url"></div></div></div> --><div v-if="invoicePDFShow" ><div :style="{margin:'10px'}"><span :style="{fontFamily:'SimHei',fontSize:'18px'}">申请附件</span></div><div class="border"><el-table :data="FDPList"><el-table-column property="filename" label="文件名称" width="200px"></el-table-column><el-table-column property="filePath" label="文件路径" show-overflow-tooltip></el-table-column><el-table-column fixed="right" label="操作" width="150px"><template slot-scope="scope"><el-button type="text" icon="el-icon-search" @click="PreviewLoadFile(scope.row.filePath)">预览</el-button>             </template></el-table-column></el-table></div></div><div :style="{margin:'15px'}" v-if="SPShow"><el-button type="danger" @click="BatchPass('overrule')">驳回</el-button><el-button type="success" v-if="!overruleShow" @click="BatchPass('pass')">通过</el-button></div><div> <transition name="el-zoom-in-top"><div v-show="overruleShow"><el-inputplaceholder="驳回原因,Enter确认"v-model="BatchPassModel.remark"@keyup.enter.native='BatchPassEnter()'clearable></el-input></div></transition></div></el-dialog></div>
</template>

因为前端代码篇幅太长,就不沾出全部代码了。写解释的话我也不知道该怎么说,毕竟前端不是咱的强项,那么咱讲一下后端逻辑实现吧。

后端

在后端的控制器中,完成上述功能,其实只要三个方法,一个是整个页面的显示方法,一个是点击详情后的显示方法,另外一个就是审批和驳回的功能实现。我们先来说一下第一个。讲解写在以下代码注释中。

        /// <summary>/// 查询/// </summary>/// <returns></returns>[HttpGet][Route("GetHTSpList")]public async Task<IActionResult> GetHTSpList(string spusername, int pages, int bars, string status4, string status, string squsername, string htorder, string sqorder,string dome3,string a, string b,string username,string qddate){//传来的参数是条件查询,就是在前端页面上的搜索栏try{String spStatu = "";//这个数组声明就是审批层级的状态,0是驳回的状态string[] lvArr = { "0", "1", "2", "4" };ArrayList al = new ArrayList(lvArr);//这个针对的是前端分页功能,当前端不选择分页时,默认为一页显示50条数据if (bars == 0 || bars == null) bars = 50;if (pages == 0 || pages == null) pages = 1;//判断前端传来的字段,如果是空的话,返回if (string.IsNullOrWhiteSpace(spusername)) throw new Exception("无此用户,重新登陆后再试");var tablename = "log_ht_gd";List<LOG_HT_GD> logHTList = new List<LOG_HT_GD>();List<HTCheckViewModel> ykCheckViewModel = new List<HTCheckViewModel>();//根据名称和表名查询层级表,来查询状态var vr = await fsql.Select<log_sp_Newstatus>().Where(x => x.spusername == spusername && x.tablename == tablename).FirstAsync();//如果没查出来数据的话代表当前登录的人员没有审批权限if (vr == null){return Ok(new { code = 1, msg = "此用户不在审批权限内" });}//当前审批状态var spstatus = vr.spstatus;//审批后状态var spLv2 = vr.sp_lv;List<LOG_HT_GD> fkList = new List<LOG_HT_GD>();var fsqlFKList = fsql.Select<LOG_HT_GD>();//条件查询if (!string.IsNullOrWhiteSpace(squsername)){fsqlFKList = fsqlFKList.Where(x => x.username == squsername);}if (!string.IsNullOrWhiteSpace(htorder)){fsqlFKList = fsqlFKList.Where(x => x.order1 == htorder);}if (!string.IsNullOrWhiteSpace(dome3)){fsqlFKList = fsqlFKList.Where(x => x.dome3 == dome3);}if (!string.IsNullOrWhiteSpace(qddate)){fsqlFKList = fsqlFKList.Where(x => x.qddate == Convert.ToDateTime(qddate));}if (!string.IsNullOrWhiteSpace(a)){fsqlFKList = fsqlFKList.Where(x => x.a == a);}if (!string.IsNullOrWhiteSpace(b)){fsqlFKList = fsqlFKList.Where(x => x.b == b);}if (!string.IsNullOrWhiteSpace(username)){fsqlFKList = fsqlFKList.Where(x => x.username == username);}if (!string.IsNullOrWhiteSpace(sqorder)){fsqlFKList = fsqlFKList.Where(x => x.sqorder == sqorder);}if (!string.IsNullOrWhiteSpace(status4)){if (status4 == "Y"){fsqlFKList = fsqlFKList.Where(x => x.dome1 == "4");}else{fsqlFKList = fsqlFKList.Where(x => x.dome1 != "0" && x.dome1 != "4");}}if (status == "Y"){for (int i = 0; i < lvArr.ToList().IndexOf(spLv2); i++){al.RemoveAt(0);}fkList = await fsqlFKList.Where(x => al.Contains(x.dome1)).ToListAsync();}else if (status == "N"){fkList = await fsqlFKList.Where(x => x.dome1 == spstatus).ToListAsync();}else if (status == "R"){fkList = await fsqlFKList.Where(x => x.dome1 == "0").ToListAsync();}else{fkList = await fsqlFKList.ToListAsync();}//条件查询结束List<HTCheckViewModel> ykCheckViewModel0 = fkList.Adapt<List<HTCheckViewModel>>();ykCheckViewModel0 = ykCheckViewModel0.GroupBy(x => x.id).Select(a => a.First()).ToList();ykCheckViewModel0.FindAll(x => al.Contains(x.dome1)).ForEach(x => x.spstatuls = "1");ykCheckViewModel0.FindAll(x => x.dome1 == spstatus).ForEach(x => x.spstatuls = "0");//取出审批范围,比如说开发部的经理只能看到并审批开发部的人员报销数据,但是财务可以看到公司所有人员报销信息var spfw = vr.spfw;if (spfw == "all") ykCheckViewModel = ykCheckViewModel0;else{//通过前端传的部门负责人编号,获取整个部门的人员姓名var sq = fsql.Select<Departmenttable, Users_GD>().LeftJoin((a, b) => a.bmid == b.demo6).Where((a, b) => a.fuzr == spusername).ToList((a, b) => b.userName);//循环部门所有人姓名for (int j = 0; j < sq.Count; j++){//取出所有人员姓名var listModel = ykCheckViewModel0.FindAll(x => x.username.Contains(sq[j].ToString()));for (int i = 0; i < listModel.Count; i++){ykCheckViewModel.Add(listModel[i]);}}}var rows = ykCheckViewModel.Count();//分页,根据时间排序var data = (ykCheckViewModel.OrderByDescending(s => s.qddate).Skip((pages - 1) * bars).Take(bars)).ToList();return Ok(new { code = 0, data = data, msg = "success", rows = rows });}catch (Exception ex){return Ok(new { code = 1, msg = ex.Message });}}

这样的话我们就可以根据当前登录人员信息把他部门下所有人员报销数据查出来并返回给前端显示。其次就是点击详情后显示的功能。

 /// <summary>/// Item查询/// </summary>/// <returns></returns>[HttpGet][Route("GetHTItem")]public async Task<IActionResult> GetHTItem(int id){try{var fkItem = await fsql.Select<LOG_HT_GD>().Where(x => x.id == id).FirstAsync();if (fkItem == null){throw new Exception("该申请不存在,刷新后重试");}String imagesPath = "Images/" + fkItem.guid + "/";HTCheckViewModel ykCheckViewModel = fkItem.Adapt<HTCheckViewModel>();List<fileInfoHT> fileInfoFKList = new List<fileInfoHT>();List<spLog> spLogList = new List<spLog>();if (!string.IsNullOrWhiteSpace(fkItem.dome5)) fileInfoFKList.Add(new fileInfoHT() { filename = fkItem.dome5, filePath = imagesPath + fkItem.dome5 });if (!string.IsNullOrWhiteSpace(fkItem.dome6)) fileInfoFKList.Add(new fileInfoHT() { filename = fkItem.dome5, filePath = imagesPath + fkItem.dome6 });if (!string.IsNullOrWhiteSpace(fkItem.dome7)) fileInfoFKList.Add(new fileInfoHT() { filename = fkItem.dome5, filePath = imagesPath + fkItem.dome7 });if (!string.IsNullOrWhiteSpace(fkItem.dome8)) fileInfoFKList.Add(new fileInfoHT() { filename = fkItem.dome5, filePath = imagesPath + fkItem.dome8 });if (!string.IsNullOrWhiteSpace(fkItem.dome9)) fileInfoFKList.Add(new fileInfoHT() { filename = fkItem.dome5, filePath = imagesPath + fkItem.dome9 });if (!string.IsNullOrWhiteSpace(fkItem.dome10)) fileInfoFKList.Add(new fileInfoHT() { filename = fkItem.dome5, filePath = imagesPath + fkItem.dome10 });if (!string.IsNullOrWhiteSpace(fkItem.dome11)){spLogList = JsonConvert.DeserializeObject<List<spLog>>(fkItem.dome11);};ykCheckViewModel.spLogList = spLogList;ykCheckViewModel.fileInfoList = fileInfoFKList;return Ok(new { code = 0, data = ykCheckViewModel, msg = "success" });}catch (Exception ex){return Ok(new { code = 1, msg = ex.Message });}}

这个东西到是没什么好说的,我们只需要把数据传给前端就好,至于怎么显示审批流程,审批到了哪一步,那是前端应该考虑的事情。前端的事情,和我后端有什么关系呢,哈哈哈嗝。
那么说一下审批和驳回吧,这个写的挺多的。

/// <summary>/// 批量操作/// </summary>/// <param name="jsonData"></param>/// <returns></returns>[HttpPost][Route("BatchPass")]public async Task<IActionResult> BatchPass([FromBody] BatchOperate jsonData){try{//这个先把前端传来的数据取一下,一会要用得到var remark = jsonData.remark;var updtype = jsonData.uptype;var tablename = jsonData.tablename;var spusername = jsonData.spusername;String msg = "审批完成";//List<spLog> spLogList = new List<spLog>();写进封装方法里//判断前端点的是审批按钮还是驳回按钮if (updtype == "pass"){List<Batch> glist = jsonData.guidList;//重赋值//审批后状态var sp_lv = await fsql.Select<log_sp_Newstatus>().Where(x => x.spusername == jsonData.spusername && x.tablename == jsonData.tablename).FirstAsync(x => x.sp_lv);//当前审批人状态var sp_lvs = await fsql.Select<log_sp_Newstatus>().Where(x => x.spusername == jsonData.spusername && x.tablename == jsonData.tablename).FirstAsync(x => x.spstatus);//原来前端是把审批和驳回两个按钮放在操作栏里的,而且在搜索栏里也有批量审批功能,所以写了个循环来进行操作,后来前端取消了这种操作方式,但是懒得改了for (int i = 0; i < glist.Count; i++){string guid = glist[i].guid;var bxItem = await fsql.Select<LOG_HT_GD>().Where(x => x.guid == guid).FirstAsync();var dome11 = bxItem.dome11;//判断审批状态,如果是4的话这条数据是被审批完的。这其实也针对的批量操作if (bxItem.dome1 == "4"){msg = "已审批完成,无需再次审批";return Ok(new { code = 1, msg = msg });}这边写了一个封装类,封装的就是以下被注释掉的代码,封装类里又优化了一下。#region 使用封装类Encapsulation encapsulation = new Encapsulation(fsql, mapper);var spLogList = encapsulation.SPList(spusername, dome11, sp_lv, remark,updtype);#endregion#region 把此方法封装起来了,可以直接调用封装方法,此方法弃用当前登录人员姓名//var userName = await fsql.Select<Users_GD>().Where(x => x.account == spusername).FirstAsync(x => x.userName);//spLog spLog = new spLog();//spLog.username = userName;//spLog.spdate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");//spLog.spstatu = sp_lv != "4" ? 0 : 1;//spLog.remark1 = "已通过";//if (bxItem.dome11 == null || bxItem.dome11 == "")//{//    spLogList.Add(spLog) ;//}//else//{//    List<spLog> spLogList0 = new List<spLog>();//    spLogList0 = JsonConvert.DeserializeObject<List<spLog>>(bxItem.dome11.ToString());//    spLogList0.Add(spLog);//    spLogList = spLogList0;//}#endregion//审批后的人员编号var ds = fsql.Select<log_sp_Newstatus>().Where(x => x.tablename == jsonData.tablename && x.spstatus == sp_lv).ToList(x => x.spusername);if (ds.Count != 0){var xm = ds[0];var sqls = fsql.Select<Users_GD>().Where(x => x.account == xm).ToList(x => x.userName);//审批后的人员名称var name = sqls[0];//审批人的姓名var sql = await fsql.Select<Users_GD>().Where(x => x.account == spusername).FirstAsync(x => x.userName);var sprname = sql;string spLogListStr = JsonConvert.SerializeObject(spLogList);//这个地方就是修改了,通过查询当前人的姓名和下一级审批人的姓名,显示到审批备注里var xg = fsql.Update<LOG_HT_GD>().Set(x => x.dome1 == sp_lv).Set(x => x.dome11 == spLogListStr).Set(x => x.spdate == "【" + sprname + "】已审批,等待【" + name + "】审批").Where(x => x.guid == guid).ExecuteAffrows();if (xg <= 0){throw new Exception("审批失败");}}else{//老板就是最后一个审批人,不能显示老板已审批完成,等待我审批吧,所以要判断一下,如果是最后一个审批人的话,这个备注状态就改成审批完成+当前时间string spLogListStr = JsonConvert.SerializeObject(spLogList);var xgs = fsql.Update<LOG_HT_GD>().Set(x => x.dome1 == sp_lv).Set(x => x.dome11 == spLogListStr).Set(x => x.spdate == "审批完成 【" + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "】").Where(x => x.guid == guid).ExecuteAffrows();}}if (glist.Count > 1) msg = "批量审批成功";return Ok(new { code = 0, msg = msg });}else{msg = "驳回成功";List<Batch> glist = jsonData.guidList;//重赋值//审批后状态var sp_lv = await fsql.Select<log_sp_Newstatus>().Where(x => x.spusername == jsonData.spusername && x.tablename == jsonData.tablename).FirstAsync(x => x.sp_lv);if (string.IsNullOrWhiteSpace(jsonData.remark)){throw new Exception("请输入驳回原因");}for (int i = 0; i < glist.Count; i++){string guid = glist[i].guid;var bxItem = await fsql.Select<LOG_HT_GD>().Where(x => x.guid == guid).FirstAsync();var dome11 = bxItem.dome11;if (bxItem.dome1 == "4"){msg = "已审批完成,无需再次审批";return Ok(new { code = 1, msg = msg });}#region 使用封装类Encapsulation encapsulation = new Encapsulation(fsql, mapper);var spLogList = encapsulation.SPList(spusername, dome11, sp_lv, remark,updtype);#endregion#region 此方法已被封装,弃用//var userName = await fsql.Select<Users_GD>().Where(x => x.account == spusername).FirstAsync(x => x.userName);//spLog spLog = new spLog();//spLog.username = userName;//spLog.spdate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");//spLog.spstatu = -1;//spLog.remark1 = jsonData.remark;//if (bxItem.dome11 == null || bxItem.dome11 == "")//{//    spLogList.Add(spLog);//}//else//{//    List<spLog> spLogList0 = new List<spLog>();//    spLogList0 = JsonConvert.DeserializeObject<List<spLog>>(bxItem.dome11.ToString());//    spLogList0.Add(spLog);//    spLogList = spLogList0;//}#endregionstring spLogListStr = JsonConvert.SerializeObject(spLogList);var xg = fsql.Update<LOG_HT_GD>().Set(x => x.dome1 == "0").Set(x => x.dome2 == jsonData.remark).Set(x => x.dome11 == spLogListStr).Set(x => x.spdate == "已驳回").Where(x => x.guid == guid).ExecuteAffrows();if (xg <= 0){throw new Exception("驳回失败!");}}if (glist.Count > 1) msg = "批量驳回成功";return Ok(new { code = 0, msg = "驳回成功!" });}}catch (Exception ex){return Ok(new { code = 1, msg = ex.Message });}}

还是比较简单的,封装类里的代码在上述注释掉的代码中也有展示,因为耦合性太高,所以封装了一下并优化。总体来说,后端的难点并不是太难。

OA系统分级审批功能相关推荐

  1. 企业如何使用OA系统?OA系统有哪些功能和应用的场景?

    企业如何使用OA系统?OA系统有哪些功能和应用的场景? 办公自动化(Office Automation,简称OA),是将计算机.通信等现代化技术运用到传统办公方式,进而形成的一种新型办公方式.办公自动 ...

  2. OA系统有哪些功能?在企业中发挥怎样的作用?

    OA系统是什么?为什么企业要引进OA系统?OA系统的主要功能和作用又有哪些? 一.OA系统是什么 首先,OA是office automation的简写,也就是办公自动化的意思,面向组织的日常运作和管理 ...

  3. 如何玩转OA系统业务审批流程

    首先我们来谈一下什么是OA系统,从百度上查询的概念如下: OA英文名为Office Automation,简称OA,它是将现代化办公和计算机网络功能结合起来的一种新型的办公方式.基于工作流概念,使企业 ...

  4. 开源免费的OA系统——云文件功能详解

    在互联网和电子化的世界里,原来的纸质材料都被office文件.pdf文件.HTML文件等等格式的电子版文件替代.厚重的纸张.书册都被压缩到了计算机盘片.固态硬盘.磁盘和光盘等物理载体中储存,对比传统的 ...

  5. OA系统如何实现功能平台化

    http://www.68oa.cn 一.OA系统的平台化 从技术的层面来理解,平台化应是一套综合的工具和一组实践证明的共享的最佳程序,它形成了完整.久经考验.开放和模块化的解决方案,旨在随需应变世界 ...

  6. OA系统添加审批模板

    1.列表页面 1.1.动态添加路由 在"系统管理"->"菜单管理"添加"审批设置"->"审批类型" 对于菜单 ...

  7. 办公自动化OA系统的功能

    办公自动化OA系统的主要功能 办公自动化系统主要包括个人办公.公文系统.请示审批.计划管理.会议管理.资源管理.行政管理.办公指南.系统设置等模块.     1. 个人办公 个人办公是电子协作的基础, ...

  8. OA系统的功能和作用是什么(OA系统百科)

    OA系统的功能和作用是什么(OA系统百科).OA系统是一种非常实用的企业内部管理系统,它可以帮助公司实现各项管理工作,可以说是整个公司和团队的纽带,有助于提高工作效率和管理水平. 具体来说,OA系统的 ...

  9. OA系统,满足各行业办公所需的管理软件

    OA系统以其卓越的协同办公技术及完善的流程化管理体系一改传统办公流程冗杂.审批低效.资源浪费严重等弊端,成为各信息化建设.提升办公管理效率,节约管理成本的可信赖办公管理软件. 1.OA系统可助力金融行 ...

  10. LeaRun低代码OA系统构建平台

    随着信息技术的飞速发展,无论是大型企业亦或是中小型企业,为了规范工作流程,提高办公效率,都迫切需要建立一套办公自动化OA系统. 所谓OA系统就是用网络和OA软件构建的一个单位内部的办公通信平台用于辅助 ...

最新文章

  1. 10张 GIF 动图让你弄懂递归等概念
  2. 机器学里面的一些概念-召回率,精确度等的介绍
  3. python之路-双下方法
  4. 使用YouTube API V3视频的完整描述- Google YouTube API V3 - Get Video Durations
  5. CS229 6.5 Neurons Networks Implements of Sparse Autoencoder
  6. 信息学奥赛一本通C++语言——1017: 浮点型数据类型存储空间大小
  7. 最小生成树唯一吗_最小生成树 - 齐芒
  8. 07-03 pipenv-Python虚拟环境工具
  9. 插件中对动态表单数据模型进行赋值实现动态表单数据绑定
  10. 【Android应用开发】 推送原理解析 极光推送使用详解 (零基础精通推送)
  11. [高通MSM8909][Android7.1]电信卡信号优化
  12. 解决:xml文件单行注释、多行注释问题
  13. 在 Ubuntu Linux 上安装 Maya 2018
  14. 竞业限制没有明确说明哪家公司,是否会违反?
  15. Promise的resolve和reject使用
  16. WMTS服务及地图瓦片原理
  17. 苹果微信更新不了最新版本_微信登录不了,微信提示版本过低,请升级最新版本的解决办法...
  18. etch下面,用wine可以安装超星阅览器
  19. 【一、建站综述及步骤简介】2021最详细wordpress博客建站教程(2021.03.01更新)
  20. 深度学习之智能问答机器人实战

热门文章

  1. C++扑克牌随机洗牌抽牌算法
  2. dropbox中国大陆使用问题
  3. Hadoop HA 搭建
  4. 火灾报警管理系统java,火灾报警系统开题报告
  5. win8/8.1安装不了.net 4.6.2版本的解决方法
  6. 偏序集、偏序关系和格
  7. tradecenter日内交易_一个华尔街交易员一天的工作是怎样的?
  8. 留学回国人员申办上海常住户口实施细则
  9. Anaconda 的Jupyter Notebook更换默认浏览器
  10. 如果读书无用,那为什么还要读书