From d641f0285b5d20920e8efdaf20c0465251d9a889 Mon Sep 17 00:00:00 2001 From: zhangxiaofeng <1939543722@qq.com> Date: Thu, 31 Oct 2024 17:45:37 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E5=8F=B7=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs index 1bed1c63..7ca66e7f 100644 --- a/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs +++ b/ds-wms-service/DS.WMS.Core/TaskPlat/Method/TaskManageService.cs @@ -616,7 +616,7 @@ namespace DS.WMS.Core.TaskPlat.Method } // 获取任务流水号 - DataResult sequence = commonService.GetSequenceNext(tenantDb, user); + DataResult sequence = await commonService.GetSequenceNextAsync(tenantDb, user); string taskNo = sequence.Data ?? ""; if (string.IsNullOrEmpty(taskNo)) From 3c9c06b15f703d2a8a2c5634f682f34ddad5d69f Mon Sep 17 00:00:00 2001 From: douhandong Date: Thu, 31 Oct 2024 17:48:07 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=8A=A5=E9=94=80=E5=8D=95=E7=9B=B8?= =?UTF-8?q?=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DS.Module.Core/Enums/OrgEnum.cs | 39 ++ .../Enums/TaskPlat/TaskBaseTypeEnum.cs | 6 +- .../DS.Module.Core/Helpers/DingDingHelper.cs | 476 ++++++++++++++++++ .../DS.WMS.Core/Fee/Dtos/AuditRequest.cs | 14 + .../Fee/Dtos/FeeReimbursementDto.cs | 11 + .../Fee/Entity/FeeReimbursement.cs | 11 + .../Fee/Interface/IReimbursementService.cs | 4 +- .../DS.WMS.Core/Fee/Method/DingDing.cs | 355 +++++++++++++ .../Fee/Method/FeeReimbursementService.cs | 161 ++++-- .../QuarztJobs/Method/BankStatementService.cs | 2 +- .../QuarztJobs/Method/InInvoiceService.cs | 53 +- .../DS.WMS.Core/Sys/Entity/SysOrgAuth.cs | 5 +- .../Controllers/ReimbursementController.cs | 8 +- 13 files changed, 1083 insertions(+), 62 deletions(-) create mode 100644 ds-wms-service/DS.Module.Core/Enums/OrgEnum.cs create mode 100644 ds-wms-service/DS.Module.Core/Helpers/DingDingHelper.cs create mode 100644 ds-wms-service/DS.WMS.Core/Fee/Method/DingDing.cs diff --git a/ds-wms-service/DS.Module.Core/Enums/OrgEnum.cs b/ds-wms-service/DS.Module.Core/Enums/OrgEnum.cs new file mode 100644 index 00000000..52d49e7f --- /dev/null +++ b/ds-wms-service/DS.Module.Core/Enums/OrgEnum.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DS.Module.Core.Enums +{ + + /// + /// 组织机构授权类型枚举 + /// + public enum OrgAuthTypeEnum + { + /// + /// 进项发票请求密钥 + /// + [Description("InInvoice")] + InInvoice = 1, + /// + /// 银行流水请求密钥 + /// + [Description("BankStatement")] + BankStatement = 2, + /// + /// 钉钉请求密钥 + /// + [Description("DingConfig")] + DingConfig = 3, + /// + /// 钉钉报销审批模板编号 + /// + [Description("DingProcessCode")] + DingProcessCode = 4, + + } + +} diff --git a/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs b/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs index 80748bd2..29426272 100644 --- a/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs +++ b/ds-wms-service/DS.Module.Core/Enums/TaskPlat/TaskBaseTypeEnum.cs @@ -380,7 +380,7 @@ namespace DS.Module.Core /// /// 客户干系人争议驳回 /// - [Description("客户干系人争议处理")] + [Description("客户干系人争议驳回")] CLIENT_STAKEHOLDER_DISPUTE_REJECTED = -503, /// /// 费用审核驳回 @@ -525,9 +525,9 @@ namespace DS.Module.Core ReimbursementApproval =1101, /// - /// 报销单审核 + /// 报销单驳回 /// - [Description("报销单审核")] + [Description("报销单驳回")] Reimbursement_REJECTED = -1101 #endregion diff --git a/ds-wms-service/DS.Module.Core/Helpers/DingDingHelper.cs b/ds-wms-service/DS.Module.Core/Helpers/DingDingHelper.cs new file mode 100644 index 00000000..66fe275b --- /dev/null +++ b/ds-wms-service/DS.Module.Core/Helpers/DingDingHelper.cs @@ -0,0 +1,476 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace DS.Module.Core.Helpers +{ + + #region + /** + * 钉钉开放平台加解密方法 + */ + public class DingTalkEncryptor + { + //private static readonly Charset CHARSET = Charset.forName("utf-8"); + //private static readonly Base64 base64 = new Base64(); + private byte[] aesKey; + private String token; + private String corpId; + /**ask getPaddingBytes key固定长度**/ + private static readonly int AES_ENCODE_KEY_LENGTH = 43; + /**加密随机字符串字节长度**/ + private static readonly int RANDOM_LENGTH = 16; + + /** + * 构造函数 + * @param token 钉钉开放平台上,开发者设置的token + * @param encodingAesKey 钉钉开放台上,开发者设置的EncodingAESKey + * @param corpId 企业自建应用-事件订阅, 使用appKey + * 企业自建应用-注册回调地址, 使用corpId + * 第三方企业应用, 使用suiteKey + * + * @throws DingTalkEncryptException 执行失败,请查看该异常的错误码和具体的错误信息 + */ + public DingTalkEncryptor(String token, String encodingAesKey, String corpId) + { + if (null == encodingAesKey || encodingAesKey.Length != AES_ENCODE_KEY_LENGTH) + { + throw new DingTalkEncryptException(DingTalkEncryptException.AES_KEY_ILLEGAL); + } + this.token = token; + this.corpId = corpId; + aesKey = Convert.FromBase64String(encodingAesKey + "="); + } + + /** + * 将和钉钉开放平台同步的消息体加密,返回加密Map + */ + public Dictionary getEncryptedMap(String plaintext) + { + + var time = DateTime.Now.Millisecond; + return getEncryptedMap(plaintext, time); + } + + /** + * 将和钉钉开放平台同步的消息体加密,返回加密Map + * @param plaintext 传递的消息体明文 + * @param timeStamp 时间戳 + * @param nonce 随机字符串 + * @return + * @throws DingTalkEncryptException + */ + public Dictionary getEncryptedMap(String plaintext, long timeStamp) + { + if (null == plaintext) + { + throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_PLAINTEXT_ILLEGAL); + } + var nonce = Utils.getRandomStr(RANDOM_LENGTH); + if (null == nonce) + { + throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_NONCE_ILLEGAL); + } + + String encrypt = this.encrypt(nonce, plaintext); + String signature = getSignature(token, timeStamp.ToString(), nonce, encrypt); + Dictionary resultMap = new Dictionary(); + resultMap["msg_signature"] = signature; + resultMap["encrypt"] = encrypt; + resultMap["timeStamp"] = timeStamp.ToString(); + resultMap["nonce"] = nonce; + return resultMap; + } + + /** + * 密文解密 + * @param msgSignature 签名串 + * @param timeStamp 时间戳 + * @param nonce 随机串 + * @param encryptMsg 密文 + * @return 解密后的原文 + * @throws DingTalkEncryptException + */ + public String getDecryptMsg(String msgSignature, String timeStamp, String nonce, String encryptMsg) + { + //校验签名 + String signature = getSignature(token, timeStamp, nonce, encryptMsg); + if (!signature.Equals(msgSignature)) + { + throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR); + } + // 解密 + String result = decrypt(encryptMsg); + return result; + } + + + /* + * 对明文加密. + * @param text 需要加密的明文 + * @return 加密后base64编码的字符串 + */ + private String encrypt(String random, String plaintext) + { + try + { + byte[] randomBytes = System.Text.Encoding.UTF8.GetBytes(random);// random.getBytes(CHARSET); + byte[] plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plaintext);// plaintext.getBytes(CHARSET); + byte[] lengthByte = Utils.int2Bytes(plainTextBytes.Length); + byte[] corpidBytes = System.Text.Encoding.UTF8.GetBytes(corpId);// corpId.getBytes(CHARSET); + //MemoryStream byteStream = new MemoryStream(); + var bytestmp = new List(); + bytestmp.AddRange(randomBytes); + bytestmp.AddRange(lengthByte); + bytestmp.AddRange(plainTextBytes); + bytestmp.AddRange(corpidBytes); + byte[] padBytes = PKCS7Padding.getPaddingBytes(bytestmp.Count); + bytestmp.AddRange(padBytes); + byte[] unencrypted = bytestmp.ToArray(); + + RijndaelManaged rDel = new RijndaelManaged(); + rDel.Mode = CipherMode.CBC; + rDel.Padding = PaddingMode.Zeros; + rDel.Key = aesKey; + rDel.IV = aesKey.ToList().Take(16).ToArray(); + ICryptoTransform cTransform = rDel.CreateEncryptor(); + byte[] resultArray = cTransform.TransformFinalBlock(unencrypted, 0, unencrypted.Length); + return Convert.ToBase64String(resultArray, 0, resultArray.Length); + + + //Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + //SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES"); + //IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16); + //cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv); + //byte[] encrypted = cipher.doFinal(unencrypted); + //String result = base64.encodeToString(encrypted); + //return result; + } + catch (Exception e) + { + throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_ENCRYPT_TEXT_ERROR); + } + } + + /* + * 对密文进行解密. + * @param text 需要解密的密文 + * @return 解密得到的明文 + */ + private String decrypt(String text) + { + byte[] originalArr; + try + { + byte[] toEncryptArray = Convert.FromBase64String(text); + RijndaelManaged rDel = new RijndaelManaged(); + rDel.Mode = CipherMode.CBC; + rDel.Padding = PaddingMode.Zeros; + rDel.Key = aesKey; + rDel.IV = aesKey.ToList().Take(16).ToArray(); + ICryptoTransform cTransform = rDel.CreateDecryptor(); + originalArr = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); + //return System.Text.UTF8Encoding.UTF8.GetString(resultArray); + + //设置解密模式为AES的CBC模式 + //Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + //SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES"); + //IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16)); + //cipher.init(Cipher.DECRYPT_MODE, keySpec, iv); + //使用BASE64对密文进行解码 + //byte[] encrypted = Base64.decodeBase64(text); + //解密 + //originalArr = cipher.doFinal(encrypted); + } + catch (Exception e) + { + throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_ERROR); + } + + String plainText; + String fromCorpid; + try + { + // 去除补位字符 + byte[] bytes = PKCS7Padding.removePaddingBytes(originalArr); + Console.Out.WriteLine("bytes size:" + bytes.Length); + + // 分离16位随机字符串,网络字节序和corpId + byte[] networkOrder = bytes.Skip(16).Take(4).ToArray();// Arrays.copyOfRange(bytes, 16, 20); + for (int i = 0; i < 4; i++) + { + Console.Out.WriteLine("networkOrder size:" + (int)networkOrder[i]); + } + + // Console.Out.WriteLine("bytes plainText:" + networkOrder.Length + " " + JsonSerializer.Serialize(networkOrder)); + int plainTextLegth = Utils.bytes2int(networkOrder); + Console.Out.WriteLine("bytes size:" + plainTextLegth); + + plainText = System.Text.UTF8Encoding.UTF8.GetString(bytes.Skip(20).Take(plainTextLegth).ToArray()); // new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET); + fromCorpid = System.Text.UTF8Encoding.UTF8.GetString(bytes.Skip(20 + plainTextLegth).ToArray()); //new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET); + Console.Out.WriteLine("bytes plainText:" + plainText); + + } + catch (Exception e) + { + throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_LENGTH_ERROR); + } + Console.Out.WriteLine(fromCorpid + "=====" + corpId); + + + // corpid不相同的情况 + if (!fromCorpid.Equals(corpId)) + { + throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_CORPID_ERROR); + } + return plainText; + } + + /** + * 数字签名 + * @param token isv token + * @param timestamp 时间戳 + * @param nonce 随机串 + * @param encrypt 加密文本 + * @return + * @throws DingTalkEncryptException + */ + public String getSignature(String token, String timestamp, String nonce, String encrypt) + { + try + { + Console.Out.WriteLine(encrypt); + + String[] array = new String[] { token, timestamp, nonce, encrypt }; + System.Array.Sort(array, StringComparer.Ordinal); + //var tmparray = array.ToList(); + //tmparray.Sort(new JavaStringComper()); + //array = tmparray.ToArray(); + // Console.Out.WriteLine("array:" + JsonSerializer.Serialize(array)); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 4; i++) + { + sb.Append(array[i]); + } + String str = sb.ToString(); + Console.Out.WriteLine(str); + //MessageDigest md = MessageDigest.getInstance("SHA-1"); + //md.update(str.getBytes()); + //byte[] digest = md.digest(); + System.Security.Cryptography.SHA1 hash = System.Security.Cryptography.SHA1.Create(); + System.Text.Encoding encoder = System.Text.Encoding.ASCII; + byte[] combined = encoder.GetBytes(str); + // byte 转换 + //sbyte[] myByte = new sbyte[] + //byte[] mySByte = new byte[myByte.Length]; + + + + //for (int i = 0; i < myByte.Length; i++) + + //{ + + // if (myByte[i] > 127) + + // mySByte[i] = (sbyte)(myByte[i] - 256); + + // else + + // mySByte[i] = (sbyte)myByte[i]; + + //} + + byte[] digest = hash.ComputeHash(combined); + StringBuilder hexstr = new StringBuilder(); + String shaHex = ""; + for (int i = 0; i < digest.Length; i++) + { + shaHex = ((int)digest[i]).ToString("x");// Integer.toHexString(digest[i] & 0xFF); + if (shaHex.Length < 2) + { + hexstr.Append(0); + } + hexstr.Append(shaHex); + } + return hexstr.ToString(); + } + catch (Exception e) + { + throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR); + } + } + } + + + /** + * 钉钉开放平台加解密异常类 + */ + public class DingTalkEncryptException : Exception + { + /**成功**/ + public static readonly int SUCCESS = 0; + /**加密明文文本非法**/ + public readonly static int ENCRYPTION_PLAINTEXT_ILLEGAL = 900001; + /**加密时间戳参数非法**/ + public readonly static int ENCRYPTION_TIMESTAMP_ILLEGAL = 900002; + /**加密随机字符串参数非法**/ + public readonly static int ENCRYPTION_NONCE_ILLEGAL = 900003; + /**不合法的aeskey**/ + public readonly static int AES_KEY_ILLEGAL = 900004; + /**签名不匹配**/ + public readonly static int SIGNATURE_NOT_MATCH = 900005; + /**计算签名错误**/ + public readonly static int COMPUTE_SIGNATURE_ERROR = 900006; + /**计算加密文字错误**/ + public readonly static int COMPUTE_ENCRYPT_TEXT_ERROR = 900007; + /**计算解密文字错误**/ + public readonly static int COMPUTE_DECRYPT_TEXT_ERROR = 900008; + /**计算解密文字长度不匹配**/ + public readonly static int COMPUTE_DECRYPT_TEXT_LENGTH_ERROR = 900009; + /**计算解密文字corpid不匹配**/ + public readonly static int COMPUTE_DECRYPT_TEXT_CORPID_ERROR = 900010; + + private static Dictionary msgMap = new Dictionary(); + static DingTalkEncryptException() + { + msgMap[SUCCESS] = "成功"; + msgMap[ENCRYPTION_PLAINTEXT_ILLEGAL] = "加密明文文本非法"; + msgMap[ENCRYPTION_TIMESTAMP_ILLEGAL] = "加密时间戳参数非法"; + msgMap[ENCRYPTION_NONCE_ILLEGAL] = "加密随机字符串参数非法"; + msgMap[SIGNATURE_NOT_MATCH] = "签名不匹配"; + msgMap[COMPUTE_SIGNATURE_ERROR] = "签名计算失败"; + msgMap[AES_KEY_ILLEGAL] = "不合法的aes key"; + msgMap[COMPUTE_ENCRYPT_TEXT_ERROR] = "计算加密文字错误"; + msgMap[COMPUTE_DECRYPT_TEXT_ERROR] = "计算解密文字错误"; + msgMap[COMPUTE_DECRYPT_TEXT_LENGTH_ERROR] = "计算解密文字长度不匹配"; + msgMap[COMPUTE_DECRYPT_TEXT_CORPID_ERROR] = "计算解密文字corpid不匹配"; + } + + private int code; + public DingTalkEncryptException(int exceptionCode) : base(msgMap[exceptionCode]) + { + this.code = exceptionCode; + } + } + + /* + * PKCS7算法的加密填充 + */ + public class PKCS7Padding + { + //private readonly static Charset CHARSET = Charset.forName("utf-8"); + private readonly static int BLOCK_SIZE = 32; + + /** + * 填充mode字节 + * @param count + * @return + */ + public static byte[] getPaddingBytes(int count) + { + int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); + if (amountToPad == 0) + { + amountToPad = BLOCK_SIZE; + } + char padChr = chr(amountToPad); + String tmp = string.Empty; ; + for (int index = 0; index < amountToPad; index++) + { + tmp += padChr; + } + return System.Text.Encoding.UTF8.GetBytes(tmp); + } + + /** + * 移除mode填充字节 + * @param decrypted + * @return + */ + public static byte[] removePaddingBytes(byte[] decrypted) + { + int pad = (int)decrypted[decrypted.Length - 1]; + if (pad < 1 || pad > BLOCK_SIZE) + { + pad = 0; + } + //Array.Copy() + var output = new byte[decrypted.Length - pad]; + System.Array.Copy(decrypted, output, decrypted.Length - pad); + return output; + } + + private static char chr(int a) + { + byte target = (byte)(a & 0xFF); + return (char)target; + } + + } + + /** + * 加解密工具类 + */ + public class Utils + { + /** + * + * @return + */ + public static String getRandomStr(int count) + { + String baset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + Random random = new Random(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < count; i++) + { + int number = random.Next(baset.Length); + sb.Append(baset[number]); + } + return sb.ToString(); + } + + + /* + * int转byte数组,高位在前 + */ + public static byte[] int2Bytes(int count) + { + byte[] byteArr = new byte[4]; + byteArr[3] = (byte)(count & 0xFF); + byteArr[2] = (byte)(count >> 8 & 0xFF); + byteArr[1] = (byte)(count >> 16 & 0xFF); + byteArr[0] = (byte)(count >> 24 & 0xFF); + return byteArr; + } + + /** + * 高位在前bytes数组转int + * @param byteArr + * @return + */ + public static int bytes2int(byte[] byteArr) + { + int count = 0; + for (int i = 0; i < 4; ++i) + { + count <<= 8; + count |= byteArr[i] & 255; + } + return count; + } + } + + public class JavaStringComper : IComparer + { + public int Compare(string x, string y) + { + return String.Compare(x, y); + } + } + + #endregion +} diff --git a/ds-wms-service/DS.WMS.Core/Fee/Dtos/AuditRequest.cs b/ds-wms-service/DS.WMS.Core/Fee/Dtos/AuditRequest.cs index 6579b064..6e0254f0 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Dtos/AuditRequest.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Dtos/AuditRequest.cs @@ -63,4 +63,18 @@ namespace DS.WMS.Core.Fee.Dtos public bool AuditOnly { get; set; } } + + public class ReimbursementRevokedInput + { + public long Id { get; set; } + } + + public class ReimbursementAuditRequest: AuditRequest + { + /// + /// 会计科目 + /// + public string LedgerAccount { get; set; } + } + } diff --git a/ds-wms-service/DS.WMS.Core/Fee/Dtos/FeeReimbursementDto.cs b/ds-wms-service/DS.WMS.Core/Fee/Dtos/FeeReimbursementDto.cs index 2a04c275..27ba2b31 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Dtos/FeeReimbursementDto.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Dtos/FeeReimbursementDto.cs @@ -81,6 +81,11 @@ namespace DS.WMS.Core.Fee.Dtos /// public decimal Amount { get; set; } + /// + /// 报销事由 + /// + public string Reason { get; set; } + } @@ -106,6 +111,12 @@ namespace DS.WMS.Core.Fee.Dtos /// public string PayeeName { get; set; } + + /// + /// 事由 + /// + public string Reason { get; set; } + public List Data { get; set; } } diff --git a/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursement.cs b/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursement.cs index f0c8e3eb..a4d4bdfb 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursement.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Entity/FeeReimbursement.cs @@ -76,5 +76,16 @@ namespace DS.WMS.Core.Fee.Entity /// public decimal Amount { get; set; } + /// + /// 报销事由 + /// + public string Reason { get; set; } + + + /// + /// 会计科目 + /// + public string LedgerAccount { get; set; } + } } diff --git a/ds-wms-service/DS.WMS.Core/Fee/Interface/IReimbursementService.cs b/ds-wms-service/DS.WMS.Core/Fee/Interface/IReimbursementService.cs index 558f6933..af054b73 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Interface/IReimbursementService.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Interface/IReimbursementService.cs @@ -45,7 +45,7 @@ namespace DS.WMS.Core.Fee.Interface /// /// /// - Task< DataResult> ReimbursementRevoked(string id); + Task< DataResult> ReimbursementRevoked(long id); /// /// 根据审批结果更新审批状态 @@ -67,7 +67,7 @@ namespace DS.WMS.Core.Fee.Interface /// /// /// - Task AuditAsync(AuditRequest request); + Task AuditAsync(ReimbursementAuditRequest request); } } diff --git a/ds-wms-service/DS.WMS.Core/Fee/Method/DingDing.cs b/ds-wms-service/DS.WMS.Core/Fee/Method/DingDing.cs new file mode 100644 index 00000000..bff38019 --- /dev/null +++ b/ds-wms-service/DS.WMS.Core/Fee/Method/DingDing.cs @@ -0,0 +1,355 @@ +using AlibabaCloud.SDK.Dingtalkworkflow_1_0.Models; +using DS.Module.SqlSugar; +using DS.WMS.Core.Fee.Entity; +using DS.WMS.Core.Invoice.Dtos; +using DS.WMS.Core.Sys.Interface; +using Microsoft.Extensions.DependencyInjection; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tea; + +namespace DS.WMS.Core.Fee.Method +{ + public class DingDing + { + + /// + /// 获取token + /// + public static string GetDingToken(string Key, string Secret) + { + AlibabaCloud.SDK.Dingtalkoauth2_1_0.Client client = CreateClient1(); + AlibabaCloud.SDK.Dingtalkoauth2_1_0.Models.GetAccessTokenRequest getAccessTokenRequest = new AlibabaCloud.SDK.Dingtalkoauth2_1_0.Models.GetAccessTokenRequest + { + AppKey = Key, //"dingplilbecwnldzcdwc", + AppSecret = Secret //"V1jtywZwJNtcTw9PfY5am2nsqacgserqNVOx-_yHsv-5YIypKKG2R0Qm19lpnHCj", + }; + try + { + var p = client.GetAccessToken(getAccessTokenRequest); + return p.Body.AccessToken; + } + catch (TeaException err) + { + if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message)) + { + // err 中含有 code 和 message 属性,可帮助开发定位问题 + } + } + catch (Exception _err) + { + TeaException err = new TeaException(new Dictionary + { + { "message", _err.Message } + }); + if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message)) + { + // err 中含有 code 和 message 属性,可帮助开发定位问题 + } + + } + return ""; + } + + /// + /// 更新表单 + /// + /// 钉钉token + /// 审批模板Id + /// 租户Id + public static void UpDingOAForm(string token, string ProcessCode, List inInvoicesData) + { + AlibabaCloud.SDK.Dingtalkworkflow_1_0.Client client = CreateClient(); + FormCreateHeaders formCreateHeaders = new FormCreateHeaders(); + formCreateHeaders.XAcsDingtalkAccessToken = token; + + #region 费用类别 + + FormComponent fylx = new FormComponent + { + ComponentType = "DDSelectField", + Props = new FormComponentProps + { + ComponentId = "DDSelectField-fylx", // 控件id,表单内唯一,与bizAlias二选一 + Required = true, // 控件是否必填 + Label = "费用类别", // 控件标题 + Placeholder = "请选择", // 输入提示 + Print = "1",//是否参与打印 + Disabled = false, //是否可编辑 + Options = new List { + new SelectOption{Value = "项目费用",Key = "1"}, + new SelectOption { Value = "部门费用", Key = "2" }, + new SelectOption { Value = "差旅费用", Key = "3" }, + new SelectOption { Value = "其他", Key = "4" } + } + } + }; + + #endregion + + #region 项目名称 + FormComponent xmmc = new FormComponent + { + ComponentType = "TextField", + Props = new FormComponentProps + { + ComponentId = "TextField-abcd", // 控件id,表单内唯一,与bizAlias二选一 + Required = true, // 控件是否必填 + Label = "项目名称", // 控件标题 + Placeholder = "请输入",// 输入提示 + + Print = "1",//是否参与打印 + Disabled = false, //是否可编辑 + + } + + }; + + #endregion + + #region 费用明细 + + var taxinfo = inInvoicesData; + + List selectOptions = new List(); + foreach (var item in taxinfo) + { + SelectOption st = new SelectOption(); + st.Value = ($"金额:{item.Amount};销方名称:{item.SellerName};发票号码:{item.InvoiceNumber}"); + st.Key = item.InvoiceNumber; + selectOptions.Add(st); + } + + FormComponent fymx = new FormComponent + { + ComponentType = "DDSelectField", + Props = new FormComponentProps + { + ComponentId = "DDSelectField-fymx", // 控件id,表单内唯一,与bizAlias二选一 + Required = false, // 控件是否必填 + Label = "费用明细", // 控件标题 + Placeholder = "请选择", // 输入提示 + Print = "1",//是否参与打印 + Disabled = false, //是否可编辑 + + Options = selectOptions + } + }; + #endregion + + #region 金额 + FormComponent xmmcA = new FormComponent + { + ComponentType = "MoneyField", + Props = new FormComponentProps + { + ComponentId = "MoneyField_1JZJIQ", // 控件id,表单内唯一,与bizAlias二选一 + Required = true, // 控件是否必填 + Label = "金额(元)", // 控件标题 + Placeholder = "请输入金额",// 输入提示 + Print = "1",//是否参与打印 + Disabled = false, //是否可编辑 + } + }; + #endregion + + #region 收款账户 + FormComponent skzh = new FormComponent + { + ComponentType = "RecipientAccountField", + Props = new FormComponentProps + { + ComponentId = "RecipientAccountField_7KZ7T", // 控件id,表单内唯一,与bizAlias二选一 + Required = true, // 控件是否必填 + Label = "收款账户", // 控件标题 + Placeholder = "请选择",// 输入提示 + Disabled = false, + } + }; + #endregion + + #region 关联审批单 + FormComponent glspd = new FormComponent + { + ComponentType = "RelateField", + Props = new FormComponentProps + { + ComponentId = "RelateField_7KZ7T", // 控件id,表单内唯一,与bizAlias二选一 + Required = false, // 控件是否必填 + Label = "关联审批单", // 控件标题 + Placeholder = "请选择",// 输入提示 + Disabled = false, + } + }; + #endregion + + FormCreateRequest formCreateRequest = new FormCreateRequest + { + ProcessCode = ProcessCode,// "PROC-528BFFFF-00D1-4AF0-AB5F-7BFB89787994", + Name = "测试费用报销(电子发票)", + Description = "测试费用报销使用", + FormComponents = new List + { + fylx,//费用类别 + xmmc,//项目名称 + fymx,//费用明细 + xmmcA,//金额 + skzh,//收款账户 + glspd //关联审批单 + }, + }; + try + { + client.FormCreateWithOptions(formCreateRequest, formCreateHeaders, new AlibabaCloud.TeaUtil.Models.RuntimeOptions()); + } + catch (TeaException err) + { + if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message)) + { + // err 中含有 code 和 message 属性,可帮助开发定位问题 + } + } + catch (Exception _err) + { + TeaException err = new TeaException(new Dictionary + { + { "message", _err.Message } + }); + if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message)) + { + // err 中含有 code 和 message 属性,可帮助开发定位问题 + } + } + } + + + /** + * 使用 Token 初始化账号Client + * @return Client + * @throws Exception + */ + public static AlibabaCloud.SDK.Dingtalkoauth2_1_0.Client CreateClient1() + { + AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config(); + config.Protocol = "https"; + config.RegionId = "central"; + return new AlibabaCloud.SDK.Dingtalkoauth2_1_0.Client(config); + } + public static AlibabaCloud.SDK.Dingtalkworkflow_1_0.Client CreateClient() + { + AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config(); + config.Protocol = "https"; + config.RegionId = "central"; + return new AlibabaCloud.SDK.Dingtalkworkflow_1_0.Client(config); + } + + + /// + /// 获取审批实例详情 + /// + /// 审批实例Id + /// 钉钉token + /// + public static GetProcessInstanceResponse GetProcessInstanceWithOptions(string ProcessInstanceId, string Token) + { + AlibabaCloud.SDK.Dingtalkworkflow_1_0.Client client = CreateClient(); + AlibabaCloud.SDK.Dingtalkworkflow_1_0.Models.GetProcessInstanceHeaders getProcessInstanceHeaders = new AlibabaCloud.SDK.Dingtalkworkflow_1_0.Models.GetProcessInstanceHeaders(); + getProcessInstanceHeaders.XAcsDingtalkAccessToken = Token; + AlibabaCloud.SDK.Dingtalkworkflow_1_0.Models.GetProcessInstanceRequest getProcessInstanceRequest = new AlibabaCloud.SDK.Dingtalkworkflow_1_0.Models.GetProcessInstanceRequest + { + ProcessInstanceId = ProcessInstanceId, + }; + try + { + return client.GetProcessInstanceWithOptions(getProcessInstanceRequest, getProcessInstanceHeaders, new AlibabaCloud.TeaUtil.Models.RuntimeOptions()); + } + catch (TeaException err) + { + if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message)) + { + // err 中含有 code 和 message 属性,可帮助开发定位问题 + } + } + catch (Exception _err) + { + TeaException err = new TeaException(new Dictionary + { + { "message", _err.Message } + }); + if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message)) + { + // err 中含有 code 和 message 属性,可帮助开发定位问题 + } + } + return new GetProcessInstanceResponse(); + } + + + /// + /// 获取钉钉报销审批列表 + /// + /// 钉钉token + /// 钉钉模板Id + /// 开始时间 + /// 结束时间 + /// 获取到的数据集 + /// 分页游标 + /// + public static List GetProcessList(string token, string ProcessCode, long StartTime, long EndTime, List Data, int NextToken = 0) + { + AlibabaCloud.SDK.Dingtalkworkflow_1_0.Client client = CreateClient(); + ListProcessInstanceIdsHeaders listProcessInstanceIdsHeaders = new ListProcessInstanceIdsHeaders(); + listProcessInstanceIdsHeaders.XAcsDingtalkAccessToken = token; + ListProcessInstanceIdsRequest listProcessInstanceIdsRequest = new ListProcessInstanceIdsRequest + { + ProcessCode = ProcessCode, + StartTime = StartTime, + EndTime = EndTime, + NextToken = NextToken, + MaxResults = 20 + + }; + try + { + var data = client.ListProcessInstanceIdsWithOptions(listProcessInstanceIdsRequest, listProcessInstanceIdsHeaders, new AlibabaCloud.TeaUtil.Models.RuntimeOptions()); + + foreach (var item in data.Body.Result.List) + { + Data.Add(item); + } + + if (data.Body.Result.NextToken != null) + { + GetProcessList(token, ProcessCode, StartTime, EndTime, Data, Convert.ToInt32(data.Body.Result.NextToken)); + } + return Data; + } + catch (TeaException err) + { + if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message)) + { + // err 中含有 code 和 message 属性,可帮助开发定位问题 + } + } + catch (Exception _err) + { + TeaException err = new TeaException(new Dictionary + { + { "message", _err.Message } + }); + if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message)) + { + // err 中含有 code 和 message 属性,可帮助开发定位问题 + } + } + + return new List(); + } + + + } +} diff --git a/ds-wms-service/DS.WMS.Core/Fee/Method/FeeReimbursementService.cs b/ds-wms-service/DS.WMS.Core/Fee/Method/FeeReimbursementService.cs index c2f9b602..dbb0ba35 100644 --- a/ds-wms-service/DS.WMS.Core/Fee/Method/FeeReimbursementService.cs +++ b/ds-wms-service/DS.WMS.Core/Fee/Method/FeeReimbursementService.cs @@ -1,4 +1,5 @@ -using DS.Module.Core; +using AngleSharp.Dom; +using DS.Module.Core; using DS.Module.Core.Enums; using DS.Module.Core.Extensions; using DS.Module.SqlSugar; @@ -8,6 +9,7 @@ using DS.WMS.Core.Fee.Entity; using DS.WMS.Core.Fee.Interface; using DS.WMS.Core.Flow.Dtos; using DS.WMS.Core.Flow.Interface; +using DS.WMS.Core.Sys.Entity; using DS.WMS.Core.Sys.Interface; using DS.WMS.Core.Sys.Method; using DS.WMS.Core.TaskInteraction.Dtos; @@ -72,7 +74,7 @@ namespace DS.WMS.Core.Fee.Method return data; } /// - /// 提交报销申请 + /// 新增报销申请 /// /// /// @@ -123,7 +125,7 @@ namespace DS.WMS.Core.Fee.Method return DataResult.Failed($"发票号{item.InvoiceNumber}不存在,请检查"); } - //发票报销状态 校验 待完善 + //发票报销状态 校验 if (inviceinfo.ReimbursementType == ReimbursementTypeEnums.UnderReview) //报销中 { return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}正在报销,请检查"); @@ -132,9 +134,8 @@ namespace DS.WMS.Core.Fee.Method { return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}已报销,请检查"); } - - - inviceinfo.ReimbursementType = ReimbursementTypeEnums.NotSubmitted; + + inviceinfo.ReimbursementType = ReimbursementTypeEnums.UnderReview; tenantDb.Updateable(inviceinfo).ExecuteCommand(); var dataDetail = item.Adapt(); @@ -169,7 +170,7 @@ namespace DS.WMS.Core.Fee.Method { return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}已报销,请检查"); } - + } #endregion @@ -194,9 +195,15 @@ namespace DS.WMS.Core.Fee.Method dataDetail.PId = info.Id; dataDetail.Amount = (decimal)inviceinfo.Amount; tenantDb.Insertable(dataDetail).ExecuteReturnEntity(); + + inviceinfo.ReimbursementType = ReimbursementTypeEnums.UnderReview; + tenantDb.Updateable(inviceinfo).ExecuteCommand(); } + return DataResult.Successed("添加成功!", info.Id, MultiLanguageConst.DataCreateSuccess); } + + return await Task.FromResult(DataResult.Successed("操作成功")); } @@ -231,15 +238,15 @@ namespace DS.WMS.Core.Fee.Method return DataResult.Failed($"发票号{item.InvoiceNumber}不存在,请检查"); } - //发票报销状态 校验 待完善 - if (inviceinfo.ReimbursementType == ReimbursementTypeEnums.UnderReview) //报销中 - { - return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}正在报销,请检查"); - } - if (inviceinfo.ReimbursementType == ReimbursementTypeEnums.Approved) //已报销 - { - return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}已报销,请检查"); - } + ////发票报销状态 校验 待完善 + //if (inviceinfo.ReimbursementType == ReimbursementTypeEnums.UnderReview) //报销中 + //{ + // return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}正在报销,请检查"); + //} + //if (inviceinfo.ReimbursementType == ReimbursementTypeEnums.Approved) //已报销 + //{ + // return DataResult.Failed($"提交失败,发票号{item.InvoiceNumber}已报销,请检查"); + //} } #endregion @@ -279,9 +286,7 @@ namespace DS.WMS.Core.Fee.Method { return await Task.FromResult(DataResult.Successed(result.Message)); } - #endregion - } /// @@ -298,21 +303,24 @@ namespace DS.WMS.Core.Fee.Method .First(); var dtlist= tenantDb.Queryable().Where(t => t.PId == data.Id).ToList(); + data.Data = new List(); foreach (var item in dtlist) { var dt= tenantDb.Queryable().Where(t => t.InvoiceNumber == item.InvoiceNumber).Select().First(); if (dt != null) { - data.Data = new List(); data.Data.Add(dt); - - foreach (var itemdata in data.Data) - { - itemdata.Data = new List(); - itemdata.Data = tenantDb.Queryable().Where(t => t.InvoiceNumber == item.InvoiceNumber).ToList(); - } } } + + + foreach (var itemdata in data.Data) + { + itemdata.Data = new List(); + itemdata.Data = tenantDb.Queryable().Where(t => t.InvoiceNumber == itemdata.InvoiceNumber).ToList(); + } + + return DataResult.Success(data, MultiLanguageConst.DataQuerySuccess); } @@ -322,51 +330,85 @@ namespace DS.WMS.Core.Fee.Method /// /// /// - public async Task ReimbursementRevoked(string id) + public async Task ReimbursementRevoked(long id) { //查询当前报销单 var tenantDb = saasService.GetBizDbScopeById(user.TenantId); var data = tenantDb.Queryable() - .Where(a => a.Id == long.Parse(id)) + .Where(a => a.Id == id) .Select() .First(); - if (data.ReimbursementType != ReimbursementTypeEnums.NotSubmitted) + if (data.ReimbursementType == ReimbursementTypeEnums.Approved) + { + return DataResult.Failed("报销单审批已通过,不可撤回!"); + } + + if (data.ReimbursementType == ReimbursementTypeEnums.Rejected) + { + return DataResult.Failed("报销单已审批,不可撤回!"); + } + + if (data.ReimbursementType == ReimbursementTypeEnums.Revoked) { - return DataResult.Failed("报销单只有未审批可撤回!"); + return DataResult.Failed("报销单已撤销,不可重复撤回!"); } data.ReimbursementType = ReimbursementTypeEnums.Revoked; - db.Updateable(data).ExecuteCommand(); + tenantDb.Updateable(data).ExecuteCommand(); var dataDetail = tenantDb.Queryable() - .Where(a => a.PId == long.Parse(id)) - .Select() + .Where(a => a.PId == id) + .ToList(); foreach (var item in dataDetail) { - item.ReimbursementType = ReimbursementTypeEnums.Revoked; - db.Updateable(item).ExecuteCommand(); + item.Status = ReimbursementTypeEnums.Revoked; + tenantDb.Updateable(item).ExecuteCommand(); + + var inviceinfo = tenantDb.Queryable().Where(t => t.InvoiceNumber == item.InvoiceNumber).First(); + inviceinfo.ReimbursementType = ReimbursementTypeEnums.NotSubmitted; //审核撤销,将对应的报销发票设为未审核状态 + tenantDb.Updateable(inviceinfo).ExecuteCommand(); } - //撤销审批任务 - var tsreq = new TaskRequest + if (data.ReimbursementType == ReimbursementTypeEnums.UnderReview) { - BusinessId = data.Id, - TaskTypeName = TaskBaseTypeEnum.ReimbursementApproval.ToString(), - }; + #region 撤销钉钉审批任务 + + + #endregion + + #region 撤销东胜8工作流的审批任务 + //撤销审批任务 + var tsreq = new TaskRequest + { + BusinessId = data.Id, + TaskTypeName = TaskBaseTypeEnum.ReimbursementApproval.ToString(), + }; + + var result = await taskService.WithdrawAsync(tsreq); + if (!result.Succeeded) + { + return await Task.FromResult(DataResult.Failed(result.Message)); + } + else + { + return await Task.FromResult(DataResult.Successed(result.Message)); + } + + #endregion + - var result = await taskService.WithdrawAsync(tsreq); - if (!result.Succeeded) - { - return await Task.FromResult(DataResult.Failed(result.Message)); - } - else - { - return await Task.FromResult(DataResult.Successed(result.Message)); } + + + + + + return await Task.FromResult(DataResult.Successed("操作成功")); + } /// @@ -434,8 +476,31 @@ namespace DS.WMS.Core.Fee.Method /// /// /// - public async Task AuditAsync(AuditRequest request) + public async Task AuditAsync(ReimbursementAuditRequest request) { + var tenantDb = saasService.GetBizDbScopeById(user.TenantId); + + var info = await tenantDb.Queryable().Where(x =>request.Ids.Contains( x.Id)).ToListAsync(); + if (info.IsNull()) + return await Task.FromResult(DataResult.Failed("不存在的报销单信息!")); + + //修改会计科目 + foreach (var item in info) + { + item.LedgerAccount = request.LedgerAccount; + } + db.Updateable(info).ExecuteCommand(); + + //获取当前审批人信息 + var userinfo= db.Queryable().Where(t => t.Id.ToString()== user.UserId).First(); + + if (!string.IsNullOrWhiteSpace( userinfo.DingUserId)) + { + //TODO 窦汉东 同步钉钉当前审批人的审批状态 + + + } + if (await taskService2.Value.HasAuthorizedAsync()) { return await taskService2.Value.AuditAsync(new TaskAuditRequest diff --git a/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/BankStatementService.cs b/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/BankStatementService.cs index ba1fb524..85e70b62 100644 --- a/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/BankStatementService.cs +++ b/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/BankStatementService.cs @@ -39,7 +39,7 @@ namespace DS.WMS.Core.QuarztJobs.Method return; } - var orgauthlist = db.Queryable().ClearFilter().Where(t => t.Deleted == false && t.Type == "BankStatement").ToList(); + var orgauthlist = db.Queryable().ClearFilter().Where(t => t.Deleted == false && t.Type == Module.Core.Enums.OrgAuthTypeEnum.BankStatement).ToList(); //遍历授权数据集 diff --git a/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/InInvoiceService.cs b/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/InInvoiceService.cs index 6f718f18..464660a9 100644 --- a/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/InInvoiceService.cs +++ b/ds-wms-service/DS.WMS.Core/QuarztJobs/Method/InInvoiceService.cs @@ -1,5 +1,6 @@ using DS.Module.Core.Enums; using DS.WMS.Core.Fee.Entity; +using DS.WMS.Core.Fee.Method; using DS.WMS.Core.QuarztJobs.Dtos; using DS.WMS.Core.QuarztJobs.Interface; using DS.WMS.Core.QuarztJobs.Other; @@ -9,6 +10,7 @@ using Newtonsoft.Json; using SqlSugar; using System.Net.Http.Headers; + namespace DS.WMS.Core.QuarztJobs.Method { /// @@ -37,11 +39,16 @@ namespace DS.WMS.Core.QuarztJobs.Method return; } - var orgauthlist= db.Queryable().ClearFilter().Where(t => t.Deleted == false&&t.Type=="ininvice").ToList(); + var orgauthlist= db.Queryable().ClearFilter().Where(t => t.Deleted == false&&t.Type==OrgAuthTypeEnum.InInvoice).ToList(); + + + //遍历授权数据集 foreach (var item in orgauthlist) { + bool tb = false; //根据此字段判断是否需要同步发票数据到钉钉 + //组织请求远程接口api数据 Dictionary header = new Dictionary(); header.Add("USER_KEY", item.Key); @@ -80,8 +87,10 @@ namespace DS.WMS.Core.QuarztJobs.Method gidi.fphm = itemdata.fphm; var resultinfo = await HttpHellp.PostAsync("http://47.105.115.105:26650/api/XSD/GetInInvoiceDataInfo", JsonConvert.SerializeObject(gidi), header); var Iinfo = JsonConvert.DeserializeObject(resultinfo); - if (Iinfo.code == 0) //调整 - { + if (Iinfo.success == true) + { + tb = true; + //添加发票数据 InInvoice inInvoice = new InInvoice(); inInvoice.InvoicingDate = Iinfo.data.kprq; @@ -175,12 +184,50 @@ namespace DS.WMS.Core.QuarztJobs.Method inInvoicedtl.CreateTime = DateTime.Now; await tenantDb.Insertable(inInvoicedtl).ExecuteCommandAsync(); } + + } } } + + + if (tb) + { + try + { + #region 同步发票到钉钉审批 + var dingconfig = db.Queryable().Where(t => t.Type == OrgAuthTypeEnum.DingConfig &&t.OrgId==item.OrgId).First(); + + if (dingconfig!=null) + { + //获取钉钉密钥 + var token = DingDing.GetDingToken(dingconfig.Key, dingconfig.Secret); + //获取对应的组织机构的发票列表 + var ininviceList = await tenantDb.Queryable().Where(x => x.ReimbursementType == ReimbursementTypeEnums.NotSubmitted && x.OrgId == item.OrgId).ToListAsync(); + //将发票信息同步更新到钉钉 + var DingProcess = db.Queryable().Where(t => t.Type == OrgAuthTypeEnum.DingProcessCode && t.OrgId == item.OrgId).First(); + + + DingDing.UpDingOAForm(token, DingProcess.Key, ininviceList); + + } + + + #endregion + } + catch (Exception ex) + { + + throw; + } + + } } + } + + } } diff --git a/ds-wms-service/DS.WMS.Core/Sys/Entity/SysOrgAuth.cs b/ds-wms-service/DS.WMS.Core/Sys/Entity/SysOrgAuth.cs index a66df5e5..b3135a97 100644 --- a/ds-wms-service/DS.WMS.Core/Sys/Entity/SysOrgAuth.cs +++ b/ds-wms-service/DS.WMS.Core/Sys/Entity/SysOrgAuth.cs @@ -1,4 +1,5 @@ using DS.Module.Core.Data; +using DS.Module.Core.Enums; using System; using System.Collections.Generic; using System.Linq; @@ -20,7 +21,9 @@ namespace DS.WMS.Core.Sys.Entity /// /// 类型 /// - public string Type { get; set; } + + public OrgAuthTypeEnum Type { get; set; } + /// /// 请求key /// diff --git a/ds-wms-service/DS.WMS.FeeApi/Controllers/ReimbursementController.cs b/ds-wms-service/DS.WMS.FeeApi/Controllers/ReimbursementController.cs index 5a0763cd..1e59c96e 100644 --- a/ds-wms-service/DS.WMS.FeeApi/Controllers/ReimbursementController.cs +++ b/ds-wms-service/DS.WMS.FeeApi/Controllers/ReimbursementController.cs @@ -34,7 +34,7 @@ namespace DS.WMS.FeeApi.Controllers [HttpPost] [Route("GetReimbursementList")] public DataResult> GetReimbursementList([FromBody] PageRequest request) - { + { var res = _service.GetListByPage(request); return res; } @@ -85,9 +85,9 @@ namespace DS.WMS.FeeApi.Controllers /// [HttpPost] [Route("ReimbursementRevoked")] - public async Task ReimbursementRevoked([FromBody] string id) + public async Task ReimbursementRevoked([FromBody] ReimbursementRevokedInput Model) { - var res = await _service.ReimbursementRevoked(id); + var res = await _service.ReimbursementRevoked(Model.Id); return res; } @@ -97,7 +97,7 @@ namespace DS.WMS.FeeApi.Controllers /// /// [HttpPost, Route("Audit")] - public async Task AuditAsync([FromBody] AuditRequest request) + public async Task AuditAsync([FromBody] ReimbursementAuditRequest request) { if (request.Ids.Length == 0 || (request.Result != 1 && request.Result != 2)) return DataResult.Failed("参数无效", MultiLanguageConst.IllegalRequest);