seal.go 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. package seal
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/beego/beego/v2/client/orm"
  6. "hongze/hz_crm_api/models/company"
  7. "hongze/hz_crm_api/models/contract"
  8. "hongze/hz_crm_api/models/seal"
  9. "hongze/hz_crm_api/models/seal/request"
  10. "hongze/hz_crm_api/models/seal/response"
  11. "hongze/hz_crm_api/models/system"
  12. "hongze/hz_crm_api/services"
  13. "hongze/hz_crm_api/utils"
  14. "mime/multipart"
  15. "reflect"
  16. "strconv"
  17. "strings"
  18. "time"
  19. )
  20. // UploadCheckBackFile 上传签回用印附件(实际操作)
  21. func UploadCheckBackFile(sealId int, fileUrl string, opUser *system.Admin) (sealInfo *seal.Seal, err error) {
  22. //查询当前用印信息
  23. sealInfo, err = seal.GetSealInfoByContractId(sealId)
  24. if err != nil {
  25. return
  26. }
  27. //用印状态判断
  28. if sealInfo.Status != "已审批" && sealInfo.Status != "已签回" {
  29. err = errors.New("用印状态异常,不允许上传签回用印附件,当前用印状态:" + sealInfo.Status)
  30. return
  31. }
  32. sealInfo.CheckBackFileUrl = fileUrl
  33. sealInfo.Status = "已签回"
  34. sealInfo.ModifyTime = time.Now()
  35. sealInfo.CheckBackFileTime = time.Now()
  36. err = sealInfo.Update([]string{"CheckBackFileUrl", "Status", "ModifyTime", "CheckBackFileTime"})
  37. if err != nil {
  38. return
  39. }
  40. // 给销售发送模版消息
  41. sellerInfo, tErr := system.GetSysAdminById(sealInfo.UserId)
  42. if tErr == nil {
  43. if sellerInfo.Mobile != "" {
  44. go services.SendSealFinishedWxTemplateMsg(sellerInfo.Mobile, sealInfo.CompanyName, sealInfo.SealId)
  45. }
  46. }
  47. return
  48. }
  49. // UploadCheckBackFileFromSeal 用印上传签回用印附件
  50. func UploadCheckBackFileFromSeal(sealId int, ext string, fileMulti multipart.File, opUser *system.Admin) (sealInfo *seal.Seal, err error) {
  51. //查询当前用印信息
  52. sealInfo, err = seal.GetSealInfoById(sealId)
  53. if err != nil {
  54. return
  55. }
  56. //用印状态判断
  57. if sealInfo.Status != "已审批" && sealInfo.Status != "已签回" {
  58. err = errors.New("用印状态异常,不允许上传签回用印附件,当前用印状态:" + sealInfo.Status)
  59. return
  60. }
  61. fileName := ``
  62. //保存的文件名
  63. fileName = sealInfo.CompanyName + "_" + sealInfo.Code + "(签回)"
  64. if sealInfo.ContractId > 0 {
  65. //获取合同信息
  66. contractInfo, tmpErr := contract.GetContractById(sealInfo.ContractId)
  67. if tmpErr != nil {
  68. err = tmpErr
  69. return
  70. }
  71. //保存的文件名
  72. fileName = contractInfo.CompanyName + "_" + contractInfo.ContractCode + "(签回)"
  73. }
  74. //非正式环境下,文件名上面还是加上随机数
  75. if utils.RunMode != "release" {
  76. fileName += "_" + utils.GetRandStringNoSpecialChar(10)
  77. }
  78. fileName += ext
  79. //上传到阿里云
  80. resourceUrl, err := services.UploadToOssAndFileName(fileMulti, fileName)
  81. if err != nil {
  82. err = errors.New("文件保存失败,Err:" + err.Error())
  83. return
  84. }
  85. sealInfo.CheckBackFileUrl = resourceUrl
  86. sealInfo.Status = "已签回"
  87. sealInfo.ModifyTime = time.Now()
  88. sealInfo.CheckBackFileTime = time.Now()
  89. err = sealInfo.Update([]string{"CheckBackFileUrl", "Status", "ModifyTime", "CheckBackFileTime"})
  90. if err != nil {
  91. return
  92. }
  93. // 给销售发送模版消息
  94. sellerInfo, tErr := system.GetSysAdminById(sealInfo.UserId)
  95. if tErr == nil {
  96. if sellerInfo.Mobile != "" {
  97. go services.SendSealFinishedWxTemplateMsg(sellerInfo.Mobile, sealInfo.CompanyName, sealInfo.SealId)
  98. }
  99. }
  100. return
  101. }
  102. // ApplySeal 申请用印
  103. func ApplySeal(sysUser *system.Admin, req request.SealApprovalApplyReq) (err error) {
  104. o := orm.NewOrm()
  105. to, err := o.Begin()
  106. if err != nil {
  107. return
  108. }
  109. defer func() {
  110. if err != nil {
  111. _ = to.Rollback()
  112. } else {
  113. _ = to.Commit()
  114. }
  115. }()
  116. // 添加用印
  117. sealInfo, err := addSeal(sysUser.AdminId, req.ContractId, req.FileNum, sysUser.RealName, req.Use, req.CompanyName, req.UseCompanyName, req.CreditCode, req.ServiceType, req.SealType, req.Remark, req.FileUrls, req.AffiliatedCompany)
  118. if err != nil {
  119. return
  120. }
  121. // 添加操作日志
  122. err = seal.AddSealOperationRecord(sealInfo.SealId, sysUser.AdminId, 0, "apply", sysUser.RealName, "提交审批", "")
  123. if err != nil {
  124. return
  125. }
  126. // 用印审批
  127. err = SubmitApproval(sealInfo)
  128. return
  129. }
  130. // addSeal 新增用印
  131. func addSeal(userId, contractId, fileNum int, userName, use, companyName, useCompanyName, creditCode, serviceType, sealType, remark string, fileUrls []string, affiliatedCompany string) (sealInfo *seal.Seal, err error) {
  132. if !strings.Contains(strings.Join(seal.EnumUse, ","), use) {
  133. err = errors.New("用印用途异常")
  134. return
  135. }
  136. if !strings.Contains(strings.Join(seal.EnumServiceType, ","), serviceType) {
  137. err = errors.New("业务类型异常")
  138. return
  139. }
  140. sealCode, err := seal.GetSealCode()
  141. if err != nil {
  142. return
  143. }
  144. fileUrl := ""
  145. now := time.Now()
  146. attachments := make([]*seal.Attachment, 0)
  147. if len(fileUrls) == 1 {
  148. fileUrl = fileUrls[0]
  149. }
  150. sealInfo = &seal.Seal{
  151. Code: sealCode,
  152. UserId: userId,
  153. UserName: userName,
  154. Use: use,
  155. CompanyName: companyName,
  156. UseCompanyName: useCompanyName,
  157. CreditCode: creditCode,
  158. ServiceType: serviceType,
  159. SealType: sealType,
  160. Status: "待提交",
  161. Remark: remark,
  162. FileUrl: fileUrl,
  163. FileNum: fileNum,
  164. ContractId: contractId,
  165. ModifyTime: now,
  166. CreateTime: now,
  167. AffiliatedCompany: affiliatedCompany,
  168. }
  169. err = seal.AddSeal(sealInfo)
  170. if err != nil {
  171. return
  172. }
  173. if len(fileUrls) > 1 {
  174. for _, v := range fileUrls {
  175. tmp := &seal.Attachment{
  176. SealId: sealInfo.SealId,
  177. FileUrl: v,
  178. ModifyTime: now,
  179. CreateTime: now,
  180. }
  181. attachments = append(attachments, tmp)
  182. }
  183. err = seal.AddAttachments(attachments)
  184. }
  185. return
  186. }
  187. // EditApply 编辑用印审批
  188. func EditApply(sysUser *system.Admin, req request.SealApprovalEditReq) (err error) {
  189. o := orm.NewOrm()
  190. to, err := o.Begin()
  191. if err != nil {
  192. return
  193. }
  194. defer func() {
  195. if err != nil {
  196. _ = to.Rollback()
  197. } else {
  198. _ = to.Commit()
  199. }
  200. }()
  201. // 编辑用印
  202. sealInfo, err := editSeal(req.SealId, sysUser.AdminId, req.ContractId, req.FileNum, req.Use, req.CompanyName, req.UseCompanyName, req.CreditCode, req.ServiceType, req.SealType, req.Remark, req.FileUrls, req.AffiliatedCompany)
  203. if err != nil {
  204. return
  205. }
  206. // 添加操作日志
  207. err = seal.AddSealOperationRecord(sealInfo.SealId, sysUser.AdminId, 0, "edit", sysUser.RealName, "重提审批", "")
  208. if err != nil {
  209. return
  210. }
  211. // 用印审批
  212. err = SubmitApproval(sealInfo)
  213. return
  214. }
  215. // editSeal 编辑用印申请
  216. func editSeal(sealId, userId, contractId, fileNum int, use, companyName, userCompanyName, creditCode, serviceType, sealType, remark string, fileUrls []string, affiliatedCompany string) (sealInfo *seal.Seal, err error) {
  217. if !strings.Contains(strings.Join(seal.EnumUse, ","), use) {
  218. err = errors.New("用印用途异常")
  219. return
  220. }
  221. if !strings.Contains(strings.Join(seal.EnumServiceType, ","), serviceType) {
  222. err = errors.New("业务类型异常")
  223. return
  224. }
  225. sealInfo, err = seal.GetSealInfoById(sealId)
  226. if err != nil {
  227. if err.Error() == utils.ErrNoRow() {
  228. err = errors.New("获取用印申请失败")
  229. }
  230. return
  231. }
  232. if sealInfo.UserId != userId {
  233. err = errors.New("当前账号无操作权限")
  234. return
  235. }
  236. ignoreStatus := []string{"待提交", "已撤回", "已驳回"}
  237. if !strings.Contains(strings.Join(ignoreStatus, ","), sealInfo.Status) {
  238. err = errors.New("用印状态异常,不允许修改,当前用印状态:" + sealInfo.Status)
  239. return
  240. }
  241. fileUrl := ""
  242. now := time.Now()
  243. attachments := make([]*seal.Attachment, 0)
  244. if len(fileUrls) == 1 {
  245. fileUrl = fileUrls[0]
  246. }
  247. sealInfo.Use = use
  248. sealInfo.CompanyName = companyName
  249. sealInfo.UseCompanyName = userCompanyName
  250. sealInfo.CreditCode = creditCode
  251. sealInfo.ServiceType = serviceType
  252. sealInfo.SealType = sealType
  253. sealInfo.Remark = remark
  254. sealInfo.FileUrl = fileUrl
  255. sealInfo.FileNum = fileNum
  256. sealInfo.ContractId = contractId
  257. sealInfo.ModifyTime = now
  258. sealInfo.CreateTime = now // 更新提交时间
  259. sealInfo.Status = "待提交"
  260. sealInfo.AffiliatedCompany = affiliatedCompany
  261. err = sealInfo.Update([]string{"Use", "CompanyName", "UseCompanyName", "CreditCode", "ServiceType", "SealType", "Remark", "FileUrl", "FileNum", "ContractId", "ModifyTime", "CreateTime", "Status", "AffiliatedCompany"})
  262. if err != nil {
  263. return
  264. }
  265. //删除原有的附件,新增最新的附件
  266. err = seal.DelAttachmentBySealId(sealId)
  267. if err != nil {
  268. return
  269. }
  270. if len(fileUrls) > 1 {
  271. for _, v := range fileUrls {
  272. tmp := &seal.Attachment{
  273. SealId: sealInfo.SealId,
  274. FileUrl: v,
  275. ModifyTime: now,
  276. CreateTime: now,
  277. }
  278. attachments = append(attachments, tmp)
  279. }
  280. err = seal.AddAttachments(attachments)
  281. }
  282. return
  283. }
  284. // VerifierEditApply 合规编辑用印申请
  285. func VerifierEditApply(sysUser *system.Admin, req request.SealApprovalEditReq) (err error) {
  286. // 审批权限校验
  287. sealInfo, approvalInfo, approvalRecord, err := CheckApprovalAuth(req.SealId, sysUser)
  288. if err != nil {
  289. return
  290. }
  291. // 数据状态校验
  292. if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_COMPLIANCE {
  293. err = errors.New("当前账号无修改权限")
  294. return
  295. }
  296. if sealInfo.Status != "待审批" {
  297. err = errors.New("用印状态异常,不允许修改,当前用印状态:" + sealInfo.Status)
  298. return
  299. }
  300. if !strings.Contains(strings.Join(seal.EnumUse, ","), req.Use) {
  301. err = errors.New("用印用途异常")
  302. return
  303. }
  304. if !strings.Contains(strings.Join(seal.EnumServiceType, ","), req.ServiceType) {
  305. err = errors.New("业务类型异常")
  306. return
  307. }
  308. // 变更字段判断
  309. updateCol := make([]string, 0)
  310. updateContent := make([]string, 0)
  311. if sealInfo.Use != req.Use {
  312. updateCol = append(updateCol, "Use")
  313. updateContent = append(updateContent, "用印用途")
  314. }
  315. if sealInfo.SealType != req.SealType {
  316. updateCol = append(updateCol, "SealType")
  317. updateContent = append(updateContent, "加盖何种印章")
  318. }
  319. if sealInfo.Remark != req.Remark {
  320. updateCol = append(updateCol, "Remark")
  321. updateContent = append(updateContent, "备注")
  322. }
  323. if sealInfo.FileNum != req.FileNum {
  324. updateCol = append(updateCol, "FileNum")
  325. updateContent = append(updateContent, "文件份数")
  326. }
  327. //判断附件地址是否相等:
  328. sealAttachements, err := seal.GetAttachmentBySealId(sealInfo.SealId)
  329. if err != nil {
  330. err = errors.New(fmt.Sprint("获取用印附件失败,Err:"+err.Error(), err))
  331. return
  332. }
  333. oldFileUrls := make([]string, 0)
  334. if sealInfo.FileUrl != "" {
  335. oldFileUrls = append(oldFileUrls, sealInfo.FileUrl)
  336. }
  337. if len(sealAttachements) > 0 {
  338. for _, v := range sealAttachements {
  339. oldFileUrls = append(oldFileUrls, v.FileUrl)
  340. }
  341. }
  342. attachmentFlag := false
  343. if !reflect.DeepEqual(oldFileUrls, req.FileUrls) {
  344. updateCol = append(updateCol, "FileUrl")
  345. updateContent = append(updateContent, "文件附件")
  346. attachmentFlag = true
  347. }
  348. if sealInfo.AffiliatedCompany != req.AffiliatedCompany {
  349. updateCol = append(updateCol, "AffiliatedCompany")
  350. updateContent = append(updateContent, "归属公司")
  351. }
  352. if len(updateCol) <= 0 {
  353. err = errors.New("没有变更信息")
  354. return
  355. }
  356. content := "用印修改:" + sysUser.RealName + "修改了" + strings.Join(updateContent, "、")
  357. // 通过盖章类型判断是否需要变更审批流程
  358. originFlowType := GetFlowTypeBySealType(sealInfo.SealType)
  359. reqFlowType := GetFlowTypeBySealType(req.SealType)
  360. //如果变更了盖章类型(涉及到审批流程变更),那么需要变更审批流
  361. //变更审批流:先驳回用印申请,再修改用印,再发消息给申请人,再替申请人重新发起申请,
  362. //然后遍历审批流程,当前操作人节点之前的全部审核通过,最后通过当前操作人的节点(改成如果一级审批人如果是自己,那么直接通过这一级审批,否则不通过,让审批单重走流程)
  363. newFileUrl := ""
  364. if len(req.FileUrls) == 1 {
  365. newFileUrl = req.FileUrls[0]
  366. }
  367. if originFlowType != reqFlowType {
  368. // 先驳回
  369. err = reject(sealInfo, approvalInfo, approvalRecord, sysUser, "")
  370. if err != nil {
  371. return
  372. }
  373. //修改用印申请,给申请人发消息
  374. sealInfo.Use = req.Use
  375. sealInfo.SealType = req.SealType
  376. sealInfo.Remark = req.Remark
  377. sealInfo.FileNum = req.FileNum
  378. sealInfo.FileUrl = newFileUrl
  379. sealInfo.ModifyTime = time.Now()
  380. sealInfo.AffiliatedCompany = req.AffiliatedCompany
  381. verifierEdit(sealInfo, updateCol, approvalRecord.ContractApprovalRecordId, content, sysUser, attachmentFlag, req.FileUrls)
  382. // 重新获取最新的用印单
  383. sealInfo, tmpErr := seal.GetSealInfoById(sealInfo.SealId)
  384. if tmpErr != nil {
  385. err = tmpErr
  386. return
  387. }
  388. err = reapply(sealInfo, sysUser)
  389. if err != nil {
  390. return
  391. }
  392. // 重新发起申请
  393. } else {
  394. // 修改用印申请,给申请人发消息
  395. sealInfo.Use = req.Use
  396. sealInfo.SealType = req.SealType
  397. sealInfo.Remark = req.Remark
  398. sealInfo.FileNum = req.FileNum
  399. sealInfo.FileUrl = newFileUrl
  400. sealInfo.ModifyTime = time.Now()
  401. sealInfo.AffiliatedCompany = req.AffiliatedCompany
  402. verifierEdit(sealInfo, updateCol, approvalRecord.ContractApprovalRecordId, content, sysUser, attachmentFlag, req.FileUrls)
  403. // 审核通过
  404. err = ApprovedApproval(sealInfo.SealId, sysUser, "")
  405. }
  406. // 操作日志
  407. err = seal.AddSealOperationRecord(sealInfo.SealId, sysUser.AdminId, approvalRecord.ContractApprovalRecordId, "edit", sysUser.RealName, "审批人修改信息", "")
  408. if err != nil {
  409. return
  410. }
  411. return
  412. }
  413. // verifierEdit 审批人修改用印信息
  414. func verifierEdit(sealInfo *seal.Seal, updateCol []string, approvalRecordId int, content string, opUser *system.Admin, attachmentFlag bool, fileUrls []string) {
  415. if attachmentFlag {
  416. // 同时更新用印申请和附件
  417. _ = updateSealAndAttachment(sealInfo, updateCol, fileUrls)
  418. } else {
  419. _ = sealInfo.Update(updateCol)
  420. }
  421. //给用印人,发送修改消息
  422. sysUserMobile := ""
  423. sysUser, _ := system.GetSysAdminById(opUser.AdminId)
  424. if sysUser != nil {
  425. sysUserMobile = sysUser.Mobile
  426. }
  427. go services.AddCompanyApprovalMessage(opUser.AdminId, sealInfo.UserId, 0, approvalRecordId, 3, sourceType, 2, sealInfo.CompanyName, content, content, sysUserMobile)
  428. return
  429. }
  430. // reapply 重新提交审批单
  431. func reapply(sealInfo *seal.Seal, opUser *system.Admin) (err error) {
  432. // 发起审批
  433. approvalInfo, contractApprovalRecordList, err := addApproval(sealInfo)
  434. if err != nil {
  435. return
  436. }
  437. // 校验一级审批人是否与当前提交人一致,如果一致的话,那么审批通过且不发送消息给一级审批人
  438. var contractApprovalRecord *contract.ContractApprovalRecord
  439. for _, tmpContractApprovalRecord := range contractApprovalRecordList {
  440. if tmpContractApprovalRecord.NodeId == approvalInfo.CurrNodeId && tmpContractApprovalRecord.ApproveUserId == opUser.AdminId {
  441. contractApprovalRecord = tmpContractApprovalRecord
  442. }
  443. }
  444. // 如果一级审批人和当前提交人一致,那么审批通过,且不发送消息给一级审批人
  445. if contractApprovalRecord != nil {
  446. err = ApprovedApproval(sealInfo.SealId, opUser, "")
  447. } else {
  448. //如果一级审批人和当前提交人不一致,那么发送消息给一级审批人,重走审批流程
  449. //待办通知
  450. {
  451. //发送消息下级审批人
  452. go MessageToNodeUser(contractApprovalRecordList[0].NodeId, approvalInfo.ApplyUserId, approvalInfo.ContractApprovalId, 1, 1, sealInfo.CompanyName, sealInfo.Use)
  453. }
  454. }
  455. return
  456. }
  457. // GetSealApprovalPageList 获取用印审批分页列表
  458. func GetSealApprovalPageList(condition, joinCondition string, pars []interface{}, startSize, pageSize int, sysUser *system.Admin) (newList []*response.SealApprovalList, total int, err error) {
  459. // 1.列表数据
  460. list, total, err := seal.GetSealApprovalListByWhere(condition, joinCondition, pars, startSize, pageSize)
  461. if err != nil {
  462. err = errors.New(fmt.Sprint("获取用印审批列表失败,Err:"+err.Error(), err))
  463. return
  464. }
  465. // 2.操作权限
  466. if len(list) > 0 {
  467. // 取出所有列表最新的审批IDs
  468. approvalIdSlice := make([]string, 0)
  469. // 取出所有列表的关联合同id
  470. contractIdSlice := make([]string, 0)
  471. for i := 0; i < len(list); i++ {
  472. approvalIdSlice = append(approvalIdSlice, strconv.Itoa(list[i].ContractApprovalId))
  473. contractIdSlice = append(contractIdSlice, strconv.Itoa(list[i].ContractId))
  474. }
  475. approvalIdStr := strings.Join(approvalIdSlice, ",")
  476. // 通过审批IDs获取所有的审批流
  477. approvalRecordList, tempErr := contract.GetContractApprovalRecordListByContractApprovalIds(approvalIdStr)
  478. //approvalRecordList, tempErr := contract.GetContractApprovalRecordList(approvalIdStr, sysUser.AdminId)
  479. if tempErr != nil {
  480. err = errors.New(fmt.Sprint("获取审批流失败,Err:"+tempErr.Error(), err))
  481. return
  482. }
  483. // 获取自己的审批流列表数据
  484. selfContractApprovalRecordList, tempErr := contract.GetSelfContractApprovalRecordList(approvalIdStr, sysUser.AdminId)
  485. if tempErr != nil {
  486. err = errors.New(fmt.Sprint("获取审批列表失败,Err:"+tempErr.Error(), err))
  487. return
  488. }
  489. selfContractApprovalRecordMap := make(map[int]*contract.ContractApprovalRecord)
  490. for i := 0; i < len(selfContractApprovalRecordList); i++ {
  491. selfContractApprovalRecordMap[selfContractApprovalRecordList[i].ContractApprovalId] = selfContractApprovalRecordList[i]
  492. }
  493. // 获取所有关联的合同列表
  494. selfContractMap := make(map[int]*contract.ContractList)
  495. {
  496. if len(contractIdSlice) > 0 {
  497. contractIdStr := strings.Join(contractIdSlice, ",")
  498. contractList, tempErr := contract.GetContractListByContractIds(contractIdStr)
  499. if tempErr != nil {
  500. err = errors.New(fmt.Sprint("获取合同失败,Err:"+tempErr.Error(), err))
  501. return
  502. }
  503. for i := 0; i < len(contractList); i++ {
  504. selfContractMap[contractList[i].ContractId] = contractList[i]
  505. }
  506. }
  507. }
  508. for i := 0; i < len(list); i++ {
  509. item := list[i]
  510. list[i].CreateTimeStr = item.CreateTime.Format(utils.FormatDateTime)
  511. list[i].ModifyTimeStr = item.ModifyTime.Format(utils.FormatDateTime)
  512. list[i].ApproveTimeStr = item.ApproveTime.Format(utils.FormatDateTime)
  513. list[i].InvalidTimeStr = item.InvalidTime.Format(utils.FormatDateTime)
  514. list[i].CheckBackFileTimeStr = item.CheckBackFileTime.Format(utils.FormatDateTime)
  515. if item.ApproveStatus == "已审批" || item.ApproveStatus == "已驳回" {
  516. list[i].ApproveTime = item.ModifyTime
  517. list[i].ApproveTimeStr = item.ModifyTime.Format(utils.FormatDateTime)
  518. }
  519. // 如果当前状态是待审批的话,那么校验自己的审批流数据,然后去返回对应的状态
  520. if item.Status == "待审批" {
  521. // 如果是自己发起的审批单,同时已经经过了一轮审批,那么标记为处理中
  522. if item.ApplyUserId == sysUser.AdminId && item.CurrNodeId > item.StartNodeId {
  523. list[i].Status = "处理中"
  524. } else if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN && item.CurrNodeId > item.StartNodeId {
  525. // 如果是超管角色,同时已经经过了一轮审批,那么标记为处理中
  526. list[i].Status = "处理中"
  527. } else {
  528. // 此处可能出现同一审批人同时有权限处理一级二级的情况
  529. maxNodeId := 0
  530. tempStatus := "待审批"
  531. for _, selfRecord := range selfContractApprovalRecordList {
  532. if item.ContractApprovalId == selfRecord.ContractApprovalId {
  533. if selfRecord.NodeId > maxNodeId {
  534. maxNodeId = selfRecord.NodeId
  535. }
  536. if maxNodeId < item.CurrNodeId && selfRecord.NodeType != "cc" {
  537. tempStatus = "处理中"
  538. } else if maxNodeId == item.CurrNodeId && selfRecord.NodeType != "cc" {
  539. tempStatus = "待审批"
  540. }
  541. }
  542. }
  543. list[i].Status = tempStatus
  544. /*if contractApprovalRecord, has := selfContractApprovalRecordMap[item.ContractApprovalId]; has {
  545. if contractApprovalRecord.NodeId < item.CurrNodeId && contractApprovalRecord.NodeType != "cc" {
  546. list[i].Status = "处理中"
  547. }
  548. }*/
  549. }
  550. }
  551. // 合同编码
  552. if selfContract, has := selfContractMap[item.ContractId]; has {
  553. list[i].ContractCode = selfContract.ContractCode
  554. }
  555. // 取出item对应approval_id的审批流
  556. var tempApprovalRecordMap []*contract.ContractApprovalRecord
  557. for _, recordItem := range approvalRecordList {
  558. if item.ContractApprovalId == recordItem.ContractApprovalId {
  559. tempApprovalRecordMap = append(tempApprovalRecordMap, recordItem)
  560. }
  561. }
  562. // 获取对该条数据的操作权限
  563. opButton, tempErr := handleListOpButton(item, tempApprovalRecordMap, sysUser)
  564. if tempErr != nil {
  565. err = errors.New(fmt.Sprint("获取操作权限失败,Err:"+tempErr.Error(), err))
  566. return
  567. }
  568. tempNewList := &response.SealApprovalList{
  569. SealApprovalItem: item,
  570. OpButton: opButton,
  571. }
  572. newList = append(newList, tempNewList)
  573. }
  574. }
  575. return
  576. }
  577. // handleOpButton 列表数据操作权限
  578. func handleListOpButton(approvalItem *seal.SealApprovalItem, recordList []*contract.ContractApprovalRecord, sysUser *system.Admin) (opButton response.SealApprovalOpButton, err error) {
  579. // 待审批状态下,如果是自己发起的审批单,同时已经经过了一轮审批,那么标记为处理中
  580. if approvalItem.Status == "待审批" {
  581. if approvalItem.ApplyUserId == sysUser.AdminId && approvalItem.CurrNodeId > approvalItem.StartNodeId {
  582. approvalItem.Status = "处理中"
  583. }
  584. }
  585. flowNodeMap := make(map[int][]contract.ContractApprovalRecord, 0)
  586. keySort := make([]int, 0)
  587. for _, approvalRecord := range recordList {
  588. // 如果当前节点正好是该节点,同时审批单状态是待审批状态,然后当前账号又有权限,该账号也正是审批人,那么允许审批操作
  589. if approvalItem.CurrNodeId == approvalRecord.NodeId && approvalItem.Status == "待审批" {
  590. if sysUser.AdminId == approvalRecord.ApproveUserId && approvalRecord.NodeType == "check" {
  591. opButton.Approval = true
  592. }
  593. // 合规在审批过程中具有 部分修改权限
  594. if sysUser.AdminId == approvalRecord.ApproveUserId && sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_COMPLIANCE && approvalRecord.NodeType == "check" {
  595. opButton.CheckEdit = true
  596. }
  597. }
  598. // 如果当前节点正好是该节点,同时审批单状态又是第一层节点
  599. if approvalItem.CurrNodeId == approvalRecord.NodeId && approvalRecord.PrevNodeId == 0 && approvalItem.Status == "待审批" {
  600. // 发起人具有撤回审批单权限
  601. if sysUser.AdminId == approvalItem.ApplyUserId {
  602. opButton.Cancel = true
  603. }
  604. }
  605. if tmpFlowNodeList, ok := flowNodeMap[approvalRecord.NodeId]; ok {
  606. flowNodeMap[approvalRecord.NodeId] = append(tmpFlowNodeList, *approvalRecord)
  607. } else {
  608. tmpFlowNodeList := make([]contract.ContractApprovalRecord, 1)
  609. tmpFlowNodeList[0] = *approvalRecord
  610. flowNodeMap[approvalRecord.NodeId] = tmpFlowNodeList
  611. keySort = append(keySort, approvalRecord.NodeId)
  612. }
  613. // 待审批状态下,如果当前审批节点就是操作人,审批节点超过当前审批节点,且节点类型是抄送人,,那么标记为处理中
  614. if approvalItem.Status == "待审批" {
  615. if approvalRecord.ApproveUserId == sysUser.AdminId && approvalRecord.NodeId < approvalItem.CurrNodeId && approvalRecord.NodeType == "cc" {
  616. approvalItem.Status = "处理中"
  617. }
  618. }
  619. }
  620. // 作废权限
  621. if sysUser.AdminId == approvalItem.ApplyUserId && approvalItem.Status == "已审批" {
  622. opButton.Invalid = true
  623. }
  624. // 是否具有签回合同用印权限
  625. uploadStatus := []string{"已审批", "已签回"}
  626. if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_COMPLIANCE && strings.Contains(strings.Join(uploadStatus, ","), approvalItem.Status) {
  627. opButton.UploadFile = true
  628. }
  629. // 编辑权限
  630. editStatus := []string{"已驳回", "待提交", "已撤回"}
  631. if sysUser.AdminId == approvalItem.ApplyUserId && strings.Contains(strings.Join(editStatus, ","), approvalItem.Status) {
  632. opButton.Edit = true
  633. }
  634. return
  635. }
  636. // GetSealApprovalDetail 获取审批详情
  637. func GetSealApprovalDetail(sealId int, sysUser *system.Admin) (sealMore *response.SealMoreResp, flowNodeListResp [][]contract.ContractApprovalRecord, opButton response.SealApprovalOpButton, err error) {
  638. sealInfo, err := seal.GetSealInfoById(sealId)
  639. if err != nil {
  640. err = errors.New(fmt.Sprint("获取用印详情失败,Err:"+err.Error(), err))
  641. return
  642. }
  643. sealAttachements, err := seal.GetAttachmentBySealId(sealId)
  644. if err != nil {
  645. err = errors.New(fmt.Sprint("获取用印附件失败,Err:"+err.Error(), err))
  646. return
  647. }
  648. fileUrls := make([]string, 0)
  649. if sealInfo.FileUrl != "" {
  650. fileUrls = append(fileUrls, sealInfo.FileUrl)
  651. }
  652. for _, v := range sealAttachements {
  653. fileUrls = append(fileUrls, v.FileUrl)
  654. }
  655. sealMore = &response.SealMoreResp{
  656. Seal: sealInfo,
  657. FileUrls: fileUrls,
  658. }
  659. // 查询最近一次审批单信息
  660. lastApprovalInfo, err := contract.GetLastContractApprovalByContractId(sealInfo.SealId, "seal")
  661. if err != nil {
  662. if err.Error() != utils.ErrNoRow() {
  663. err = errors.New("获取最近一次审批单信息失败,ERR:" + err.Error())
  664. }
  665. err = nil
  666. return
  667. }
  668. if lastApprovalInfo != nil {
  669. // 获取审批操作和审批流数据
  670. tmpSealOpButton, tmpFlowNodeListResp, tmpErr := GetSealOpButton(sealInfo, lastApprovalInfo, sysUser)
  671. if tmpErr != nil {
  672. err = errors.New("获取用印按钮权限、审批流程失败,Err:" + tmpErr.Error())
  673. return
  674. }
  675. opButton = tmpSealOpButton
  676. flowNodeListResp = tmpFlowNodeListResp
  677. }
  678. return
  679. }
  680. // GetSealOpButton 获取用印审批操作权限
  681. func GetSealOpButton(sealInfo *seal.Seal, contractApprovalInfo *contract.ContractApproval, opUser *system.Admin) (sealOpButton response.SealApprovalOpButton, flowNodeListResp [][]contract.ContractApprovalRecord, err error) {
  682. // 审批流
  683. approvalRecordList, err := contract.GetApprovalRecordListByApprovalId(contractApprovalInfo.ContractApprovalId)
  684. if err != nil {
  685. err = errors.New("获取审批失败,Err:" + err.Error())
  686. return
  687. }
  688. // 待审批状态下,如果是自己发起的审批单,同时已经经过了一轮审批,那么标记为处理中
  689. if contractApprovalInfo.Status == "待审批" {
  690. if contractApprovalInfo.ApplyUserId == opUser.AdminId && contractApprovalInfo.CurrNodeId > contractApprovalInfo.StartNodeId {
  691. sealInfo.Status = "处理中"
  692. }
  693. }
  694. flowNodeMap := make(map[int][]contract.ContractApprovalRecord, 0)
  695. keySort := make([]int, 0)
  696. for _, approvalRecord := range approvalRecordList {
  697. // 如果当前节点正好是该节点,同时审批单状态是待审批状态,然后当前账号又有权限,该账号也正是审批人,那么允许审批操作
  698. if contractApprovalInfo.CurrNodeId == approvalRecord.NodeId && contractApprovalInfo.Status == "待审批" {
  699. if opUser.AdminId == approvalRecord.ApproveUserId && approvalRecord.NodeType == "check" {
  700. sealOpButton.Approval = true
  701. }
  702. // 合规在审批过程中具有 部分修改权限
  703. if opUser.AdminId == approvalRecord.ApproveUserId && opUser.RoleTypeCode == utils.ROLE_TYPE_CODE_COMPLIANCE && approvalRecord.NodeType == "check" {
  704. sealOpButton.CheckEdit = true
  705. }
  706. }
  707. // 如果当前节点正好是该节点,同时审批单状态又是第一层节点
  708. if contractApprovalInfo.CurrNodeId == approvalRecord.NodeId && approvalRecord.PrevNodeId == 0 && contractApprovalInfo.Status == "待审批" {
  709. // 发起人具有撤回审批单权限
  710. if opUser.AdminId == sealInfo.UserId {
  711. sealOpButton.Cancel = true
  712. }
  713. }
  714. if tmpFlowNodeList, ok := flowNodeMap[approvalRecord.NodeId]; ok {
  715. flowNodeMap[approvalRecord.NodeId] = append(tmpFlowNodeList, *approvalRecord)
  716. } else {
  717. tmpFlowNodeList := make([]contract.ContractApprovalRecord, 1)
  718. tmpFlowNodeList[0] = *approvalRecord
  719. flowNodeMap[approvalRecord.NodeId] = tmpFlowNodeList
  720. keySort = append(keySort, approvalRecord.NodeId)
  721. }
  722. // 待审批状态下,如果当前审批节点就是操作人,审批节点超过当前审批节点,且节点类型是抄送人,,那么标记为处理中
  723. if contractApprovalInfo.Status == "待审批" {
  724. if approvalRecord.ApproveUserId == opUser.AdminId && approvalRecord.NodeId < contractApprovalInfo.CurrNodeId && approvalRecord.NodeType == "cc" {
  725. sealInfo.Status = "处理中"
  726. }
  727. }
  728. }
  729. for _, key := range keySort {
  730. flowNodeListResp = append(flowNodeListResp, flowNodeMap[key])
  731. }
  732. // 作废权限
  733. if opUser.AdminId == sealInfo.UserId && sealInfo.Status == "已审批" {
  734. sealOpButton.Invalid = true
  735. }
  736. // 是否具有签回合同用印权限
  737. uploadStatus := []string{"已审批", "已签回"}
  738. if opUser.RoleTypeCode == utils.ROLE_TYPE_CODE_COMPLIANCE && strings.Contains(strings.Join(uploadStatus, ","), sealInfo.Status) {
  739. sealOpButton.UploadFile = true
  740. }
  741. // 编辑权限
  742. editStatus := []string{"已驳回", "待提交", "已撤回"}
  743. if opUser.AdminId == sealInfo.UserId && strings.Contains(strings.Join(editStatus, ","), sealInfo.Status) {
  744. sealOpButton.Edit = true
  745. }
  746. return
  747. }
  748. // CancelSealApproval 撤回用印审批
  749. func CancelSealApproval(sealId int, sysUser *system.Admin) (err error) {
  750. // 审批信息
  751. sealInfo, err := seal.GetSealInfoById(sealId)
  752. if err != nil {
  753. if err.Error() == utils.ErrNoRow() {
  754. err = errors.New("用印审批信息有误,Err:" + err.Error())
  755. }
  756. return
  757. }
  758. // 审批状态判断
  759. if sealInfo.Status != "待审批" {
  760. err = errors.New("用印状态异常,不允许撤回申请,当前用印状态:" + sealInfo.Status)
  761. return
  762. }
  763. // 操作人与申请人是否一致
  764. if sealInfo.UserId != sysUser.AdminId {
  765. err = errors.New("不允许撤回非本人提交的申请:" + strconv.Itoa(sealInfo.UserId))
  766. return
  767. }
  768. // 获取最近一次待审批的审批单信息
  769. approvalInfo, err := contract.GetLastContractApprovalByContractId(sealInfo.SealId, "seal")
  770. if err != nil {
  771. return
  772. }
  773. if approvalInfo.Status != "待审批" {
  774. err = errors.New("审批单状态异常,审批单状态:" + approvalInfo.Status)
  775. return
  776. }
  777. //获取当前审批单的审批流信息
  778. approvalRecordList, err := contract.GetContractApprovalRecordListByContractApprovalIdAndNodeId(approvalInfo.ContractApprovalId, approvalInfo.CurrNodeId)
  779. if err != nil {
  780. err = errors.New("获取审批流失败,Err:" + err.Error())
  781. return
  782. }
  783. if len(approvalRecordList) <= 0 {
  784. err = errors.New("找不到对应的审批流")
  785. return
  786. }
  787. for _, tmpApprovalRecord := range approvalRecordList {
  788. // 判断当前节点是否存在上级节点,如果存在,那么说明
  789. if tmpApprovalRecord.PrevNodeId > 0 {
  790. err = errors.New("合同已存在审批操作,不允许撤回申请")
  791. return
  792. }
  793. }
  794. // 获取当前审批单中所有待审批的流程流
  795. contractApprovalRecordList, err := contract.GetPendingContractApprovalRecordListByContractId(approvalInfo.ContractApprovalId, approvalInfo.CurrNodeId)
  796. if err != nil {
  797. return
  798. }
  799. // 撤回审批流
  800. err = approvalInfo.Cancel(approvalInfo, contractApprovalRecordList)
  801. if err != nil {
  802. return
  803. }
  804. // 添加操作日志
  805. err = seal.AddSealOperationRecord(sealInfo.SealId, sysUser.AdminId, 0, "cancel", sysUser.RealName, "撤回申请", "")
  806. if err != nil {
  807. return
  808. }
  809. // 作废原有消息
  810. for _, contractApprovalRecord := range contractApprovalRecordList {
  811. go company.CancelCompanyApprovalMessage(contractApprovalRecord.ContractApprovalRecordId, 3)
  812. }
  813. return
  814. }
  815. // DelSealApproval 删除用印审批
  816. func DelSealApproval(sealId int, sysUser *system.Admin) (err error) {
  817. // 审批信息
  818. sealInfo, err := seal.GetSealInfoById(sealId)
  819. if err != nil {
  820. if err.Error() == utils.ErrNoRow() {
  821. err = errors.New("用印审批信息有误,Err:" + err.Error())
  822. }
  823. return
  824. }
  825. // 审批状态判断
  826. if sealInfo.Status != "已撤回" {
  827. err = errors.New("用印状态异常,不允许删除,当前用印状态:" + sealInfo.Status)
  828. return
  829. }
  830. // 操作人与申请人是否一致
  831. if sealInfo.UserId != sysUser.AdminId {
  832. err = errors.New("不允许删除非本人提交的申请:" + strconv.Itoa(sealInfo.UserId))
  833. return
  834. }
  835. // 删除用印审批
  836. err = seal.DeleteSeal(sealInfo)
  837. if err != nil {
  838. err = errors.New("删除用印申请失败:" + strconv.Itoa(sealInfo.UserId))
  839. return
  840. }
  841. // 添加操作日志
  842. err = seal.AddSealOperationRecord(sealInfo.SealId, sysUser.AdminId, 0, "del", sysUser.RealName, "删除申请", "")
  843. if err != nil {
  844. return
  845. }
  846. return
  847. }
  848. // InvalidSealApproval 作废用印审批
  849. func InvalidSealApproval(sealId int, opUser *system.Admin) (err error) {
  850. //查询当前用印信息
  851. sealInfo, err := seal.GetSealInfoById(sealId)
  852. if err != nil {
  853. if err.Error() == utils.ErrNoRow() {
  854. err = errors.New(fmt.Sprint("根据用印编号:", sealId, " 找不到初始用印"))
  855. }
  856. return
  857. }
  858. if sealInfo.UserId != opUser.AdminId && opUser.RoleTypeCode != utils.ROLE_TYPE_CODE_COMPLIANCE {
  859. err = errors.New("当前账号无操作权限")
  860. return
  861. }
  862. if sealInfo.Status != "已审批" {
  863. err = errors.New("用印状态异常,不允许作废,当前用印状态:" + sealInfo.Status)
  864. return
  865. }
  866. //如果删除状态 >0,那么代表已经被删除了
  867. if sealInfo.IsDelete > 0 {
  868. err = errors.New("该用印已删除")
  869. return
  870. }
  871. //用印作废
  872. err = seal.Invalid(sealInfo)
  873. if err != nil {
  874. return
  875. }
  876. // 操作日志
  877. err = seal.AddSealOperationRecord(sealInfo.SealId, opUser.AdminId, 0, "invalid", opUser.RealName, "作废审批", "")
  878. if err != nil {
  879. return
  880. }
  881. //获取最近一次提交的审批单信息
  882. contractApproval, err := contract.GetLastContractApprovalByContractId(sealInfo.SealId, "seal")
  883. if err != nil {
  884. err = nil
  885. return
  886. }
  887. //如果有提测信息,那么需要给对应的审批人发送消息
  888. if contractApproval != nil {
  889. //作废后需要给审批者发送消息
  890. contractApprovalRecordList, tmpErr := contract.GetContractApprovalRecordListByContractApprovalId(contractApproval.ContractApprovalId)
  891. if tmpErr != nil {
  892. return
  893. }
  894. content := fmt.Sprint("作废", sealInfo.CompanyName, "用印申请")
  895. for _, contractApprovalRecord := range contractApprovalRecordList {
  896. if contractApprovalRecord.NodeType == "check" { //如果是审批人,那么需要发送消息给对方
  897. //操作人信息
  898. sysUserMobile := ""
  899. sysUser, _ := system.GetSysAdminById(contractApprovalRecord.ApproveUserId)
  900. if sysUser != nil {
  901. sysUserMobile = sysUser.Mobile
  902. }
  903. go services.AddCompanyApprovalMessage(opUser.AdminId, contractApprovalRecord.ApproveUserId, 0, contractApprovalRecord.ContractApprovalRecordId, 3, sourceType, 2, sealInfo.CompanyName, content, content, sysUserMobile)
  904. }
  905. }
  906. }
  907. return
  908. }
  909. // GetSealOperationRecordList 获取用印操作日志列表
  910. func GetSealOperationRecordList(sealId int) (list []*seal.SealOperationRecordList, err error) {
  911. list, err = seal.GetSealOperationListBySealId(sealId)
  912. if len(list) > 0 {
  913. for k, item := range list {
  914. list[k].CreateTimeStr = item.CreateTime.Format(utils.FormatDateTime)
  915. }
  916. }
  917. return
  918. }
  919. // updateSealAndAttachment 更新用印申请,并更新附件
  920. func updateSealAndAttachment(sealInfo *seal.Seal, updateCol []string, fileUrls []string) (err error) {
  921. o := orm.NewOrm()
  922. to, err := o.Begin()
  923. if err != nil {
  924. return
  925. }
  926. defer func() {
  927. if err != nil {
  928. _ = to.Rollback()
  929. } else {
  930. _ = to.Commit()
  931. }
  932. }()
  933. err = sealInfo.Update(updateCol)
  934. if err != nil {
  935. return
  936. }
  937. now := time.Now()
  938. //删除原有的附件,新增最新的附件
  939. err = seal.DelAttachmentBySealId(sealInfo.SealId)
  940. if err != nil {
  941. return
  942. }
  943. attachments := make([]*seal.Attachment, 0)
  944. if len(fileUrls) > 1 {
  945. for _, v := range fileUrls {
  946. tmp := &seal.Attachment{
  947. SealId: sealInfo.SealId,
  948. FileUrl: v,
  949. ModifyTime: now,
  950. CreateTime: now,
  951. }
  952. attachments = append(attachments, tmp)
  953. }
  954. err = seal.AddAttachments(attachments)
  955. }
  956. return
  957. }