|
|
@@ -3,15 +3,20 @@ package service
|
|
|
import (
|
|
|
"context"
|
|
|
"database/sql"
|
|
|
+ "encoding/base64"
|
|
|
"encoding/json"
|
|
|
"fmt"
|
|
|
+ "io"
|
|
|
+ "net/http"
|
|
|
"strconv"
|
|
|
+ "strings"
|
|
|
"time"
|
|
|
|
|
|
basedao "dashoo.cn/micro/app/dao/base"
|
|
|
dao "dashoo.cn/micro/app/dao/contract"
|
|
|
custdao "dashoo.cn/micro/app/dao/cust"
|
|
|
projdao "dashoo.cn/micro/app/dao/proj"
|
|
|
+ workflowdao "dashoo.cn/micro/app/dao/workflow"
|
|
|
model "dashoo.cn/micro/app/model/contract"
|
|
|
proj "dashoo.cn/micro/app/model/proj"
|
|
|
workflowModel "dashoo.cn/micro/app/model/workflow"
|
|
|
@@ -20,7 +25,9 @@ import (
|
|
|
workflowService "dashoo.cn/micro/app/service/workflow"
|
|
|
|
|
|
"dashoo.cn/opms_libary/micro_srv"
|
|
|
+ "dashoo.cn/opms_libary/multipart"
|
|
|
"dashoo.cn/opms_libary/myerrors"
|
|
|
+ "dashoo.cn/opms_libary/plugin/dingtalk"
|
|
|
"dashoo.cn/opms_libary/plugin/dingtalk/message"
|
|
|
"dashoo.cn/opms_libary/plugin/dingtalk/workflow"
|
|
|
"dashoo.cn/opms_libary/request"
|
|
|
@@ -38,6 +45,8 @@ type CtrContractService struct {
|
|
|
CtrProductDao *dao.CtrContractProductDao
|
|
|
ProductDao *basedao.BaseProductDao
|
|
|
DynamicsDao *dao.CtrContractDynamicsDao
|
|
|
+ WorkflowDao *workflowdao.PlatWorkflowDao
|
|
|
+ AppendDao *dao.CtrContractAppendDao
|
|
|
|
|
|
Tenant string
|
|
|
userInfo request.UserInfo
|
|
|
@@ -62,6 +71,8 @@ func NewCtrContractService(ctx context.Context) (*CtrContractService, error) {
|
|
|
CtrProductDao: dao.NewCtrContractProductDao(tenant),
|
|
|
ProductDao: basedao.NewBaseProductDao(tenant),
|
|
|
DynamicsDao: dao.NewCtrContractDynamicsDao(tenant),
|
|
|
+ WorkflowDao: workflowdao.NewPlatWorkflowDao(tenant),
|
|
|
+ AppendDao: dao.NewCtrContractAppendDao(tenant),
|
|
|
Tenant: tenant,
|
|
|
userInfo: userInfo,
|
|
|
DataScope: userInfo.DataScope,
|
|
|
@@ -422,43 +433,43 @@ func (s CtrContractService) Add(ctx context.Context, req *model.CtrContractAddRe
|
|
|
|
|
|
var ContractApplyProcessCode = "PROC-7057E20A-2066-4644-9B35-9331E4DA912C" // 创建合同
|
|
|
|
|
|
-func (s CtrContractService) Commit(ctx context.Context, req *model.CtrContractCommitReq) error {
|
|
|
+func (s CtrContractService) Commit(ctx context.Context, req *model.CtrContractCommitReq) (int64, error) {
|
|
|
validErr := gvalid.CheckStruct(ctx, req, nil)
|
|
|
if validErr != nil {
|
|
|
- return myerrors.TipsError(validErr.Current().Error())
|
|
|
+ return 0, myerrors.TipsError(validErr.Current().Error())
|
|
|
}
|
|
|
if !(req.ContractModel == "大数模板" || req.ContractModel == "客户模板") {
|
|
|
- return myerrors.TipsError("合同模板不合法")
|
|
|
+ return 0, myerrors.TipsError("合同模板不合法")
|
|
|
}
|
|
|
if !(req.Terms == "接纳全部条款" || req.Terms == "不接纳全部条款") {
|
|
|
- return myerrors.TipsError("条款情况不合法")
|
|
|
+ return 0, myerrors.TipsError("条款情况不合法")
|
|
|
}
|
|
|
if req.PayTerms == "" {
|
|
|
- return myerrors.TipsError("付款条件不能为空")
|
|
|
+ return 0, myerrors.TipsError("付款条件不能为空")
|
|
|
}
|
|
|
if len(req.File) == 0 {
|
|
|
- return myerrors.TipsError("附件不能为空")
|
|
|
+ return 0, myerrors.TipsError("附件不能为空")
|
|
|
}
|
|
|
|
|
|
ent, err := s.Dao.Where("id = ?", req.Id).One()
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return 0, err
|
|
|
}
|
|
|
if ent == nil {
|
|
|
- return myerrors.TipsError(fmt.Sprintf("合同不存在: %d", req.Id))
|
|
|
+ return 0, myerrors.TipsError(fmt.Sprintf("合同不存在: %d", req.Id))
|
|
|
}
|
|
|
|
|
|
fileinfoByte, err := json.Marshal(req.File)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return 0, err
|
|
|
}
|
|
|
|
|
|
workflowSrv, err := workflowService.NewFlowService(ctx)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return 0, err
|
|
|
}
|
|
|
bizCode := strconv.Itoa(ent.Id)
|
|
|
- _, err = workflowSrv.StartProcessInstance(bizCode, "30", "", &workflow.StartProcessInstanceRequest{
|
|
|
+ workflowId, err := workflowSrv.StartProcessInstance(bizCode, "30", "", &workflow.StartProcessInstanceRequest{
|
|
|
ProcessCode: &ContractApplyProcessCode,
|
|
|
FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
|
|
|
{
|
|
|
@@ -500,13 +511,151 @@ func (s CtrContractService) Commit(ctx context.Context, req *model.CtrContractCo
|
|
|
},
|
|
|
})
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return 0, err
|
|
|
}
|
|
|
|
|
|
_, err = s.Dao.Where("id = ?", ent.Id).Data(map[string]interface{}{
|
|
|
"appro_status": 20,
|
|
|
}).Update()
|
|
|
- return err
|
|
|
+ return workflowId, err
|
|
|
+}
|
|
|
+
|
|
|
+// var spaceId = "21042518430"
|
|
|
+
|
|
|
+var spaceId = "21077726250"
|
|
|
+
|
|
|
+func (s CtrContractService) CommitWithFile(ctx context.Context, args *multipart.MultipartFile) error {
|
|
|
+ if s.userInfo.DingtalkUid == "" {
|
|
|
+ return fmt.Errorf("该用户钉钉 uid 为空")
|
|
|
+ }
|
|
|
+ if args.FileName == "" {
|
|
|
+ return fmt.Errorf("文件名称不能为空")
|
|
|
+ }
|
|
|
+ if args.File == nil {
|
|
|
+ return fmt.Errorf("文件不能为空")
|
|
|
+ }
|
|
|
+ if args.File.Name() == "" {
|
|
|
+ return fmt.Errorf("文件路径不能为空")
|
|
|
+ }
|
|
|
+ contractId, err := strconv.Atoi(args.Meta["contractId"])
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("合同 Id 不合法 %s", args.Meta["contractId"])
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Println(args.File.Name(), args.FileName, args.FileSize, args.Meta)
|
|
|
+ fmt.Println(spaceId, s.userInfo.DingtalkId, args.FileName, args.File.Name())
|
|
|
+ // resp, err := s.UploadFile("21042518430", "8xljy04PZiS9iPxp5PhDnUzQiEiE", "引物导入模板-000000.xlsx", "/Users/chengjian/Downloads/引物导入模板.xlsx")
|
|
|
+
|
|
|
+ resp, err := dingtalk.Client.GetStorage().UploadFile(spaceId, s.userInfo.DingtalkId, args.FileName, args.File.Name())
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("钉钉上传文件异常 %s", err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+ _, err = s.Commit(ctx, &model.CtrContractCommitReq{
|
|
|
+ Id: contractId,
|
|
|
+ ContractModel: args.Meta["contractModel"],
|
|
|
+ Terms: args.Meta["terms"],
|
|
|
+ PayTerms: args.Meta["payTerms"],
|
|
|
+ File: []model.DingFileInfo{
|
|
|
+ {
|
|
|
+ SpaceId: resp.Dentry.SpaceId,
|
|
|
+ FileId: resp.Dentry.Id,
|
|
|
+ FileName: resp.Dentry.Name,
|
|
|
+ FileSize: resp.Dentry.Size,
|
|
|
+ FileType: resp.Dentry.Extension,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ // workflow, err := s.WorkflowDao.Where("id = ?", workflowId).One()
|
|
|
+ // if err != nil {
|
|
|
+ // return err
|
|
|
+ // }
|
|
|
+ // instance, err := dingtalk.Client.GetWorkflow().QueryProcessInstanceDetail(workflow.ProcessInstId)
|
|
|
+ // if err != nil {
|
|
|
+ // return fmt.Errorf("查询审批实例详情错误: %s", err.Error())
|
|
|
+ // }
|
|
|
+ // fmt.Println(workflow.ProcessInstId, instance.Result.ApproverUserIds)
|
|
|
+
|
|
|
+ // approverUserIds := g.Config().GetStrings("dingtalk.approver-user-ids")
|
|
|
+ // fmt.Println(approverUserIds)
|
|
|
+ // for _, uid := range approverUserIds {
|
|
|
+ // resp, err := dingtalk.Client.GetStorage().AddPermission(
|
|
|
+ // dingtalk.Client.Context.CorpId, spaceId, uid, "DOWNLOADER", "USER")
|
|
|
+ // if err != nil {
|
|
|
+ // return fmt.Errorf("添加审核附件权限异常: %s", err.Error())
|
|
|
+ // }
|
|
|
+ // fmt.Println(uid, resp)
|
|
|
+
|
|
|
+ // }
|
|
|
+
|
|
|
+ appendSrv, err := NewCtrContractAppendService(ctx)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ _, err = appendSrv.Add(ctx, &model.CtrContractAppendAddReq{
|
|
|
+ ContractId: contractId,
|
|
|
+ FileName: resp.Dentry.Name,
|
|
|
+ FileType: resp.Dentry.Extension,
|
|
|
+ FileUrl: strings.Join([]string{"dingtalk", resp.Dentry.SpaceId, resp.Dentry.Id}, ":"),
|
|
|
+ Remark: "",
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (s CtrContractService) DownloadDingtalkFile(ctx context.Context, id int) (string, error) {
|
|
|
+ ent, err := s.AppendDao.Where("id= ?", id).One()
|
|
|
+ if err != nil {
|
|
|
+ return "", err
|
|
|
+ }
|
|
|
+ if ent == nil {
|
|
|
+ return "", myerrors.TipsError("附件不存在")
|
|
|
+ }
|
|
|
+ if !strings.HasPrefix(ent.FileUrl, "dingtalk") {
|
|
|
+ return "", myerrors.TipsError("此附件不是钉钉附件")
|
|
|
+ }
|
|
|
+ fileInfo := strings.Split(ent.FileUrl, ":")
|
|
|
+ if len(fileInfo) != 3 {
|
|
|
+ return "", myerrors.TipsError("钉钉附件地址不合法")
|
|
|
+ }
|
|
|
+ spaceId := fileInfo[1]
|
|
|
+ fileId := fileInfo[2]
|
|
|
+
|
|
|
+ // res, err := dingtalk.Client.GetStorage().AddPermission(dingtalk.Client.Context.CorpId, spaceId, s.userInfo.DingtalkId, "EDITOR", "USER")
|
|
|
+ // fmt.Println(res, err)
|
|
|
+ // if err != nil {
|
|
|
+ // return "", fmt.Errorf("设置权限异常 %s", err.Error())
|
|
|
+ // }
|
|
|
+
|
|
|
+ resp, err := dingtalk.Client.GetStorage().QueryFileDownloadInfo(spaceId, fileId, s.userInfo.DingtalkId)
|
|
|
+ if err != nil {
|
|
|
+ return "", myerrors.TipsError("获取文件下载信息异常")
|
|
|
+ }
|
|
|
+ fmt.Println(resp, err)
|
|
|
+ req, err := http.NewRequest("GET", resp.HeaderSignatureInfo.ResourceUrls[0], nil)
|
|
|
+ if err != nil {
|
|
|
+ return "", fmt.Errorf("构建文件下载请求异常 %s", err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+ for k, v := range resp.HeaderSignatureInfo.Headers {
|
|
|
+ req.Header.Add(k, v)
|
|
|
+ }
|
|
|
+ fileresp, err := http.DefaultClient.Do(req)
|
|
|
+ if err != nil {
|
|
|
+ return "", fmt.Errorf("文件下载异常 %s", err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+ data, err := io.ReadAll(fileresp.Body)
|
|
|
+ if err != nil {
|
|
|
+ return "", fmt.Errorf("读取下载内容异常 %s", err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+ return base64.StdEncoding.EncodeToString(data), nil
|
|
|
}
|
|
|
|
|
|
func ContractApplyApproval(ctx context.Context, flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
|