seal.go 36 KB

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