OA系统分级审批功能

前言

新版本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-option
                    v-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-option
                    v-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-option
                    v-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-table
      id="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-column
        type="selection"
        width="55px">
      </el-table-column>
      <el-table-column
        label="合同类型"
        prop="dome3" min-width="8%">
      </el-table-column>
      <el-table-column
        label="合同编号"
        prop="htorder" min-width="10%">
      </el-table-column>
      <el-table-column
        label="甲方名称"
        prop="a" min-width="8%">
      </el-table-column>
      <el-table-column
        label="乙方名称"
        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-item
                v-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-image
                style="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-input
                placeholder="驳回原因,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;
                        //}
                        #endregion
                        string 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 });
            }
        }

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

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
系统集:OA,HR,CRM,于一身。 OA部分: 个人办公:内部邮件、Internet邮件、短信息、手机短信、公告通知、新闻、投票、个人考勤、日程安排、工作日志、工作汇报、通讯录、个人文件柜、控制面板 工作流:印章管理、表单定义 、工作流管理(支持复制,WEB印章等强化应用)、新建工作、待办工作、工作查询、工作监控、归档工作、委托设置 综合行政:公告通知管理、新闻管理、物品管理、固定资产管理、图书管理、会议管理、车辆管理、组织机构信息 信息交流:内部消息、内部邮件、外部邮件、内部讨论区、互动聊天、网络硬盘、投票管理、文件传阅 、手机短信管理 人力资源管理:人事档案、考勤批示、考勤统计、薪资管理、培训记录 、奖惩记录、基础设置 销售管理:客户管理、客户忠诚度管理、产品信息、销售管理、供应商管理、统计分析、基础数据设置 项目管理:项目创建、项目浏览、项目公告、项目进度、项目资源、项目预算、任务计划、项目外包、项目利润、费用报销、报销管理、数据字典 档案管理:卷库管理、案卷管理、文件管理 、案卷借阅(案卷借阅,借阅审批)、档案统计 (借阅统计,案卷统计) 、档案销毁 知识管理:知识大类、知识小类、我的知识、知识排行、知识地图、知识检索、知识互动、知识审批、知识管理员 附件管理:万年历 、世界时间 、常用网址浏览、邮编区号、日常查询 系统管理:印章管理、红头文件管理、用户管理 、角色管理 、部门管理、职位管理、附件类型、系统日志、手机短信管理组织机构设置:包含单位管理、部门管理、用户管理、角色与权限管理 其他:工作台设置,在线人员(组织结构模式),全部人员(组织结构模式) HR人力资源部分 机构管理:分级树形管理模式,部门编制数,岗位编制数等 招聘管理:需求征集(工作流),招聘计划(工作流),招聘初选(登记),招聘面试(登记),人员录用,人才储备, 基础数据设置 人事资料: 1.人事档案:人事管理(基本信息,个人简历,学习经历,工作经历,社会关系,职称评定,执业资格) 查看明细包括(基本信息,个人简历,学习经历,工作经历,社会关系,职称评定,执业资格,证照资料,合同信息,保险记录,调动情况,奖惩情况,培训课程,培训考勤,考核记录),导入数据,生日查询,人事统计分析,部门编制分析。 群发手机短信 2.合同管理:合同信息管理,合同变更,合同续签,员工转正,合同信息报表 3.人事调动:员工调动,员工离职,员工复职,人员流动分析,离职人员分析 4.员工奖惩:奖惩管理,奖惩分析,奖惩报表。 5.证照管理:证照管理,证照分析 6.职称评定:职称管理,职称分析 7.基础数据设置 培训管理:培训计划,培训考勤,培训机构,培训课件,培训费用,培训绩效,培训协议,基础数据设置 考勤管理:考勤记录采集(采集进考勤记录),考勤记录,出勤管理,休假管理,加班管理,统计查询报表 绩效考核:考核类型,考核期间,考核等级,考核信息,考核查询,考核报表,考核统计分析 薪资福利:个人所得税 ,社会保险,计件工资,计时工资.,提成工资,工资计算,工资帐套管理,工资统计分析 企业文化:单位企业介绍,单位信息发布,劳动法规及政策, 基础数据设置 系统管理:用户管理,角色管理,附件类型,系统日志,数据备份还原,备份还原设置 系统提醒:系统提醒:正式合同到期,试用合同到期,保险到期,员工生日,证照到期,职称申报,招聘计划开始,需求计划开始,培训计划开始。 系统管理 CRM客户关系管理部分 客户管理:检测客户、我的客户、共享客户、客户联系人、客户关怀、工作报告、我的客户、回收站 客户监控:允许监控的客户、客户联系人、客户关怀、工作报告浏览、 客户转移 客户跟踪:待办事宜、交往记录、销售机会、报价记录、竞争对手、销售费用 客户跟踪监控:待办事宜、交往记录、销售机会、报价记录、竞争对手、销售费用 合同定单:合同/订单、交付计划 、交付记录 、回款计划 、回款记录 、开票记录 、销售出库 合同/订单监控:合同/订单、交付计划 、交付记录 、回款计划 、回款记录 、开票记录 、销售出库 客户服务:客服控制台 、QA库管理 、投诉处理 、客服记录 、客服数据显示方案 采购管理:采购订单 、交付计划 、交付记录 、付款计划 、付款记录 、付款发票 、采购入库 采购监控:采购订单 、交付计划 、交付记录 、付款计划 、付款记录 、付款发票 、采购入库 库存管理:库存列表 入库单 :采购入库、直接入库 ; 出库单 :销售出库、直接出库库存盘点、库间调拨、报损单、报溢单、仓库设置、库存初始化/清空/清零、库存流水账 市场管理:市场活动 、广告发布 、印刷品管理 印刷品管理 :印刷品领用 礼品管理 :礼品管理 、礼品领用 供应商:供应商管理 、联系人管理 财务管理:应收款 、应付款 、已收款 、已付款 、收款发票 、付款发票 、费用报销 统计分析 客户管理:客户种类 、客户行业 、客户关系等级、客户人员规模 、客户来源 、客户阶段 、客户价值评估 、客户信用等级 、 客户拥有人 、客户创建数量人员/月度统计 、客户创建数量种类/月度统计 、大客户top20(合同额) 、大客户top20(回款额) 销售跟踪 :交往记录类型 、交往记录人员/月度统计 、客户交往记录top10 、报价记录人员/月度统计 、销售机会月份统计 、 销售机会负责人分布 、负责人/机会状态统计 、负责人/机会阶段统计 、 机会来源分布 、机会可能性分布 、机会状态分布 、机会阶段分布 、预计签单月份统计 合同/订单:合同订单状态分布 、合同订单状态/金额分布 、合同订单拥有者/状态分布 、合同订单签约时间统计 、合同订单签约金额月份统计 、合同订单签约金额人员分布 、合同订单签约金额人员/月度统计 、合同订单签约数量人员/月度统计 、合同订单未尽收款金额按签约月份统计 、合同订单类型分布 、合同订单签约金额类型分布 、 回款月度统计 、 回款人员/月度统计 、回款分类/月度统计 、回款人员分布 、回款付款方式统计 、回款分类统计、回款计划月度统计 、回款计划人员/月度统计 、开票类型/月度统计 售后服务:投诉月度统计 、投诉紧急程度/月度统计 、投诉处理结果/月度统计 、客户投诉次数top10 、投诉类型分布 、客服类型分布、客服方式分布 、客服状态分布 、客服月度统计 、 客服类型/月度统计 、 客服方式/月度统计 、 客服状态/月度统计 、客服次数top10 采购管理:采购单数量分类分布 、采购单金额分类统计 、月度采购单数量 、月度采购单金额 、人员采购单数量 、人员采购单金额 、采购单数量人员/月度统计 、采购单金额人员/月度统计 、采购发票月度统计 、 付款月度统计 、付款人员/月度统计 、付款分类/月度统计 、付款人员分布 、付款方式统计 、付款分类统计 、付款计划月度统计 、付款计划人员/月度统计 费用管理:月度费用申报统计 、月度通过审核费用统计 、月度费用人员统计(通过审核) 、费用类别分布(通过审核) 、费用类别统计(通过审核) 、人员/费用类型统计(通过审核) 、客户费用(通过审核)top20 市场管理 :市场活动类型分布 、市场活动类型/月度分析 、广告媒体类型分布 库存管理:库存流水产品数量分布 、库存流水月度统计 系统管理 用户管理、角色管理 、 组织机构 、职位管理 、 系统日志 、产品设置 、监控设置 数据备份还原:数据备份 、数据还原 备份还原设置:备份数据库 、备份存放路径 手机短信:已发送短信 、等待发送短信 、发送失败短信 、接收短信 数据字典:客户种类 、客户行业 、客户关系等级 、客户人员规模 、客户来源 、客户阶段 、 联系人分类 、客户关怀类型 、待办事宜类型 、交往记录类型 、销售机会来源 、 销售机会阶段 、竞争对手能力 、销售费用类、付款方式 、 合同订单分类 、 采购分类 、回款记录分类 、票据类型 、QA库分类 、 投诉处理分类 、 服务类型 、服务方式 、市场活动类型 、广告投放类型 、供应商所属分类 、供应商信用等级 、 直接入库类型 、直接出库类型 其他 工作台设置,在线人员(组织结构模式),全部人员(组织结构模式)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晚风偷吻云朵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值