seal.go 34 KB

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