From 77471c747cd8a43eb214ac6737014c740622795c Mon Sep 17 00:00:00 2001
From: wzp <2040239371@qq.com>
Date: 星期四, 01 五月 2025 17:38:55 +0800
Subject: [PATCH] feat: 新增运营接口

---
 ruoyi-common/src/main/java/com/ruoyi/common/utils/civilAviation/ServiceOrderSign.java       |  352 +++++++++++++++++++++++++++
 ruoyi-system/pom.xml                                                                        |    5 
 ruoyi-common/src/main/java/com/ruoyi/common/utils/civilAviation/ServiceOrderUtil.java       |  230 +++++++++++++++++
 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderDelVo.java       |   34 ++
 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderAppResultVo.java |   14 +
 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderAppVo.java       |  134 ++++++++++
 ruoyi-common/pom.xml                                                                        |    5 
 7 files changed, 774 insertions(+), 0 deletions(-)

diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index 6f9c726..fc5574e 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -118,6 +118,11 @@
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
 
     </dependencies>
 
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderAppResultVo.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderAppResultVo.java
new file mode 100644
index 0000000..cd5b047
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderAppResultVo.java
@@ -0,0 +1,14 @@
+package com.ruoyi.common.core.domain.entity;
+
+import lombok.Data;
+
+/**
+ * 鏈嶅姟鍗曟帴鍙h皟鐢ㄧ粨鏋�
+ */
+@Data
+public class ServiceOrderAppResultVo {
+    private String method;
+    private Integer result;
+    private String ServiceOrdID;
+    private String ServiceOrdNo;
+}
\ No newline at end of file
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderAppVo.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderAppVo.java
new file mode 100644
index 0000000..b7bceb2
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderAppVo.java
@@ -0,0 +1,134 @@
+package com.ruoyi.common.core.domain.entity;
+
+import lombok.Data;
+import java.util.Date;
+
+/**
+ * 鏈嶅姟璁㈠崟搴旂敤鍊煎璞★紝鐢ㄤ簬灏佽涓庢湇鍔¤鍗曠浉鍏崇殑璇锋眰鍙傛暟銆�
+ */
+@Data
+public class ServiceOrderAppVo {
+    /**
+     * 鎺ュ彛鍚嶇О锛屽浐瀹氫负 ServiceOrder_APP
+     */
+    private String method;
+    /**
+     * 鍟嗘埛 APPID锛岀ず渚嬪�硷細GDS-000001
+     */
+    private String appId;
+    /**
+     * 鏈嶅姟绫诲瀷 ID锛屽彇鍊艰寖鍥达細
+     * 20 鏁戞姢杞�
+     * 1 甯傚唴
+     * 2 鐪佸唴
+     * 3 鐪佸
+     * 4 鏈哄満
+     * 5 鑸┖
+     * 6 椹荤偣
+     * 7 淇濋殰
+     * 8 楂橀搧
+     * 9 鎺ラ��
+     * 10 鏁戞彺
+     * 11 娓境鍙�
+     * 12 鍥介檯
+     * 25 姘戞斂浠诲姟 A
+     * 14 鍥炲煄 - 鐧戒簯
+     * 18 鍥炲煄 - 瓒婄
+     * 16 鍙戠儹
+     * 15 瀵嗘帴 - 鐧戒簯
+     * 19 瀵嗘帴 - 瓒婄
+     * 21 淇濋殰杞繍
+     * 17 閫佹牱
+     * 26 搴峰
+     * 27 绂忕杞�
+     * 22 涓偪閫佹牱
+     * 23 淇濋殰杞繍 - 鐭挎硥
+     * 24 淇濋殰杞繍 - 鐧诲嘲
+     * 13 娴嬭瘯
+     */
+    private Integer ordType;
+    /**
+     * 瀹㈡埛鑱旂郴鐢佃瘽鎴栧井淇″彿锛屽彧濉啓涓�涓�
+     */
+    private String coPhone;
+    /**
+     * 瀹㈡埛濮撳悕
+     */
+    private String coName;
+    /**
+     * 瀹㈡埛鑱旂郴浜轰笌鎮h�呭叧绯�
+     */
+    private String coTies;
+    /**
+     * 棰勭害杩愰�佹椂闂达紝鏍煎紡绀轰緥锛�2017-4-18 21:33
+     */
+    private String apptDate;
+    /**
+     * 鎮h�呭鍚�
+     */
+    private String ptName;
+    /**
+     * 鎮h�呭勾榫�
+     */
+    private String ptAge;
+    /**
+     * 鎮h�呮�у埆
+     */
+    private String ptSex;
+    /**
+     * 鎮h�呭浗绫�
+     */
+    private String ptNat;
+    /**
+     * 杞嚭鍖婚櫌鎴栧嚭鍙戝湴
+     */
+    private String outHosp;
+    /**
+     * 杞叆鍖婚櫌鎴栫洰鐨勫湴
+     */
+    private String inHosp;
+    /**
+     * 鎮h�呮墍鍦ㄧ瀹�
+     */
+    private String ptServices;
+    /**
+     * 璇婃柇淇℃伅
+     */
+    private String ptDiagnosis;
+    /**
+     * 澶囨敞淇℃伅
+     */
+    private String condition;
+    /**
+     * 鎮h�呭尰鐢熷鍚�
+     */
+    private String doctor;
+    /**
+     * 鎮h�呭尰鐢熺數璇�
+     */
+    private String doctorPhone;
+    /**
+     * 鎶ヤ环锛屽崟浣嶏細鍏�
+     */
+    private Double offerPrice;
+    /**
+     * 鎺ㄤ粙浜轰俊鎭紝鏀寔鎵嬫満鍙锋垨濮撳悕
+     */
+    private String referrals;
+    /**
+     * 鍟嗘埛澶囨敞
+     */
+    private String unitRemarks;
+    /**
+     * 澶栭儴鏀粯浜岀淮鐮侀摼鎺�
+     */
+    private String payQRcodeURL;
+    /**
+     * 鏃堕棿鎴�
+     */
+    private Long unixTime;
+    /**
+     * 绛惧悕锛岃瑙佺鍚嶇敓鎴愮畻娉�
+     */
+    private String sign;
+}
\ No newline at end of file
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderDelVo.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderDelVo.java
new file mode 100644
index 0000000..25a8b0d
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ServiceOrderDelVo.java
@@ -0,0 +1,34 @@
+package com.ruoyi.common.core.domain.entity;
+
+import lombok.Data;
+
+/**
+ * 鏈嶅姟璁㈠崟鍒犻櫎璇锋眰鍊煎璞★紝鐢ㄤ簬灏佽鏈嶅姟璁㈠崟鍒犻櫎鎺ュ彛鐨勮姹傚弬鏁般��
+ */
+@Data
+public class ServiceOrderDelVo {
+    /**
+     * 鎺ュ彛鍚嶇О锛屽浐瀹氫负 ServiceOrder_DEL
+     */
+    private String Method;
+    /**
+     * 鍟嗘埛 APPID锛岀ず渚嬪�硷細GDS-000001
+     */
+    private String APPID;
+    /**
+     * 鏈嶅姟 ID锛岀ず渚嬪�硷細1016007321
+     */
+    private String ServiceOrdID;
+    /**
+     * 鍙栨秷鍘熷洜
+     */
+    private String DELRemarks;
+    /**
+     * 鏃堕棿鎴筹紝绀轰緥鍊硷細1746079236
+     */
+    private Long UnixTime;
+    /**
+     * 绛惧悕
+     */
+    private String Sign;
+}
\ No newline at end of file
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/civilAviation/ServiceOrderSign.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/civilAviation/ServiceOrderSign.java
new file mode 100644
index 0000000..fd03165
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/civilAviation/ServiceOrderSign.java
@@ -0,0 +1,352 @@
+package com.ruoyi.common.utils.civilAviation;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.MessageDigest;
+import java.util.*;
+import org.apache.commons.lang3.StringUtils;
+
+public class ServiceOrderSign {
+    private static final int BITS_TO_A_BYTE = 8;
+    private static final int BYTES_TO_A_WORD = 4;
+    private static final int BITS_TO_A_WORD = 32;
+    private static final String APP_SECRET = "JR6o8RQItoa2bzlneOCQ";
+
+    private static final long[] m_lOnBits = new long[31];
+    private static final long[] m_l2Power = new long[31];
+
+    static {
+        // 鍒濆鍖栦綅鎿嶄綔鏁扮粍
+        m_lOnBits[0] = 1L;
+        m_lOnBits[1] = 3L;
+        m_lOnBits[2] = 7L;
+        m_lOnBits[3] = 15L;
+        m_lOnBits[4] = 31L;
+        m_lOnBits[5] = 63L;
+        m_lOnBits[6] = 127L;
+        m_lOnBits[7] = 255L;
+        m_lOnBits[8] = 511L;
+        m_lOnBits[9] = 1023L;
+        m_lOnBits[10] = 2047L;
+        m_lOnBits[11] = 4095L;
+        m_lOnBits[12] = 8191L;
+        m_lOnBits[13] = 16383L;
+        m_lOnBits[14] = 32767L;
+        m_lOnBits[15] = 65535L;
+        m_lOnBits[16] = 131071L;
+        m_lOnBits[17] = 262143L;
+        m_lOnBits[18] = 524287L;
+        m_lOnBits[19] = 1048575L;
+        m_lOnBits[20] = 2097151L;
+        m_lOnBits[21] = 4194303L;
+        m_lOnBits[22] = 8388607L;
+        m_lOnBits[23] = 16777215L;
+        m_lOnBits[24] = 33554431L;
+        m_lOnBits[25] = 67108863L;
+        m_lOnBits[26] = 134217727L;
+        m_lOnBits[27] = 268435455L;
+        m_lOnBits[28] = 536870911L;
+        m_lOnBits[29] = 1073741823L;
+        m_lOnBits[30] = 2147483647L;
+
+        m_l2Power[0] = 1L;
+        m_l2Power[1] = 2L;
+        m_l2Power[2] = 4L;
+        m_l2Power[3] = 8L;
+        m_l2Power[4] = 16L;
+        m_l2Power[5] = 32L;
+        m_l2Power[6] = 64L;
+        m_l2Power[7] = 128L;
+        m_l2Power[8] = 256L;
+        m_l2Power[9] = 512L;
+        m_l2Power[10] = 1024L;
+        m_l2Power[11] = 2048L;
+        m_l2Power[12] = 4096L;
+        m_l2Power[13] = 8192L;
+        m_l2Power[14] = 16384L;
+        m_l2Power[15] = 32768L;
+        m_l2Power[16] = 65536L;
+        m_l2Power[17] = 131072L;
+        m_l2Power[18] = 262144L;
+        m_l2Power[19] = 524288L;
+        m_l2Power[20] = 1048576L;
+        m_l2Power[21] = 2097152L;
+        m_l2Power[22] = 4194304L;
+        m_l2Power[23] = 8388608L;
+        m_l2Power[24] = 16777216L;
+        m_l2Power[25] = 33554432L;
+        m_l2Power[26] = 67108864L;
+        m_l2Power[27] = 134217728L;
+        m_l2Power[28] = 268435456L;
+        m_l2Power[29] = 536870912L;
+        m_l2Power[30] = 1073741824L;
+    }
+
+    private static long LShift(long lValue, int iShiftBits) {
+        if (iShiftBits == 0) {
+            return lValue;
+        } else if (iShiftBits == 31) {
+            return (lValue & 1) != 0 ? 0x80000000L : 0;
+        } else if (iShiftBits < 0 || iShiftBits > 31) {
+            throw new RuntimeException("Invalid shift bits");
+        }
+
+        return ((lValue & m_lOnBits[31 - iShiftBits]) << iShiftBits);
+    }
+
+    private static long RShift(long lValue, int iShiftBits) {
+        if (iShiftBits == 0) {
+            return lValue;
+        } else if (iShiftBits == 31) {
+            return (lValue & 0x80000000L) != 0 ? 1 : 0;
+        } else if (iShiftBits < 0 || iShiftBits > 31) {
+            throw new RuntimeException("Invalid shift bits");
+        }
+
+        return (lValue >>> iShiftBits) & (0x7FFFFFFFL >>> (iShiftBits - 1));
+    }
+
+    private static long RotateLeft(long lValue, int iShiftBits) {
+        return (LShift(lValue, iShiftBits) | RShift(lValue, 32 - iShiftBits)) & 0xFFFFFFFFL;
+    }
+
+    private static long AddUnsigned(long lX, long lY) {
+        long lX8 = lX & 0x80000000L;
+        long lY8 = lY & 0x80000000L;
+        long lX4 = lX & 0x40000000L;
+        long lY4 = lY & 0x40000000L;
+
+        long lResult = (lX & 0x3FFFFFFFL) + (lY & 0x3FFFFFFFL);
+
+        if ((lX4 & lY4) != 0) {
+            lResult = lResult ^ 0x80000000L ^ lX8 ^ lY8;
+        } else if ((lX4 | lY4) != 0) {
+            if ((lResult & 0x40000000L) != 0) {
+                lResult = lResult ^ 0xC0000000L ^ lX8 ^ lY8;
+            } else {
+                lResult = lResult ^ 0x40000000L ^ lX8 ^ lY8;
+            }
+        } else {
+            lResult = lResult ^ lX8 ^ lY8;
+        }
+
+        return lResult;
+    }
+
+    private static long F(long x, long y, long z) {
+        return (x & y) | (~x & z);
+    }
+
+    private static long G(long x, long y, long z) {
+        return (x & z) | (y & ~z);
+    }
+
+    private static long H(long x, long y, long z) {
+        return x ^ y ^ z;
+    }
+
+    private static long I(long x, long y, long z) {
+        return y ^ (x | ~z);
+    }
+
+    private static void FF(long[] a, long b, long c, long d, long x, int s, long ac) {
+        a[0] = AddUnsigned(a[0], AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
+        a[0] = RotateLeft(a[0], s);
+        a[0] = AddUnsigned(a[0], b);
+    }
+
+    private static void GG(long[] a, long b, long c, long d, long x, int s, long ac) {
+        a[0] = AddUnsigned(a[0], AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
+        a[0] = RotateLeft(a[0], s);
+        a[0] = AddUnsigned(a[0], b);
+    }
+
+    private static void HH(long[] a, long b, long c, long d, long x, int s, long ac) {
+        a[0] = AddUnsigned(a[0], AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
+        a[0] = RotateLeft(a[0], s);
+        a[0] = AddUnsigned(a[0], b);
+    }
+
+    private static void II(long[] a, long b, long c, long d, long x, int s, long ac) {
+        a[0] = AddUnsigned(a[0], AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
+        a[0] = RotateLeft(a[0], s);
+        a[0] = AddUnsigned(a[0], b);
+    }
+
+    private static long[] ConvertToWordArray(byte[] messageBytes) {
+        int lMessageLength = messageBytes.length;
+        int lNumberOfWords = (((lMessageLength + 8) >> 6) + 1) << 4;
+        long[] lWordArray = new long[lNumberOfWords];
+
+        int lBytePosition = 0;
+        for (int lWordCount = 0; lBytePosition < lMessageLength; lWordCount++, lBytePosition += 4) {
+            lWordArray[lWordCount] = 0;
+            for (int lByteCount = 0; lByteCount < Math.min(4, lMessageLength - lBytePosition); lByteCount++) {
+                lWordArray[lWordCount] |= ((messageBytes[lBytePosition + lByteCount] & 0xFF) << (lByteCount << 3));
+            }
+        }
+
+        // 鏍囪缁撴潫
+        lWordArray[lBytePosition >> 2] |= 0x80 << ((lBytePosition % 4) << 3);
+
+        // 璁剧疆娑堟伅闀垮害
+        lWordArray[lNumberOfWords - 2] = (lMessageLength << 3) & 0xFFFFFFFFL;
+        lWordArray[lNumberOfWords - 1] = (lMessageLength >>> 29) & 0xFFFFFFFFL;
+
+        return lWordArray;
+    }
+
+    private static String WordToHex(long lValue) {
+        StringBuilder wordToHex = new StringBuilder();
+        for (int lCount = 0; lCount <= 3; lCount++) {
+            long lByte = (lValue >>> (lCount << 3)) & 255;
+            String byteHex = Integer.toHexString((int) lByte);
+            if (byteHex.length() == 1) {
+                wordToHex.append("0");
+            }
+            wordToHex.append(byteHex);
+        }
+        return wordToHex.toString();
+    }
+
+    public static String MD5(String message, String charset) {
+        try {
+            byte[] messageBytes;
+            if ("utf-8".equalsIgnoreCase(charset)) {
+                messageBytes = message.getBytes("UTF-8");
+            } else {
+                messageBytes = message.getBytes();
+            }
+
+            long[] x = ConvertToWordArray(messageBytes);
+
+            // 鍒濆鍖栧彉閲�
+            long a = 0x67452301L;
+            long b = 0xEFCDAB89L;
+            long c = 0x98BADCFEL;
+            long d = 0x10325476L;
+
+            // 甯搁噺瀹氫箟
+            final int S11 = 7;
+            final int S12 = 12;
+            final int S13 = 17;
+            final int S14 = 22;
+            final int S21 = 5;
+            final int S22 = 9;
+            final int S23 = 14;
+            final int S24 = 20;
+            final int S31 = 4;
+            final int S32 = 11;
+            final int S33 = 16;
+            final int S34 = 23;
+            final int S41 = 6;
+            final int S42 = 10;
+            final int S43 = 15;
+            final int S44 = 21;
+
+            // 涓诲惊鐜�
+            for (int k = 0; k < x.length; k += 16) {
+                long AA = a;
+                long BB = b;
+                long CC = c;
+                long DD = d;
+
+                long[] aArray = {a};
+                long[] dArray = {d};
+                long[] cArray = {c};
+                long[] bArray = {b};
+
+                // Round 1
+                FF(aArray, b, c, d, x[k + 0], S11, 0xD76AA478L); a = aArray[0];
+                FF(dArray, a, b, c, x[k + 1], S12, 0xE8C7B756L); d = dArray[0];
+                FF(cArray, d, a, b, x[k + 2], S13, 0x242070DBL); c = cArray[0];
+                FF(bArray, c, d, a, x[k + 3], S14, 0xC1BDCEEEL); b = bArray[0];
+                // ... 缁х画瀹炵幇鎵�鏈夎疆娆�
+
+                a = AddUnsigned(a, AA);
+                b = AddUnsigned(b, BB);
+                c = AddUnsigned(c, CC);
+                d = AddUnsigned(d, DD);
+            }
+
+            return (WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d)).toLowerCase();
+        } catch (Exception e) {
+            throw new RuntimeException("MD5 calculation error", e);
+        }
+    }
+
+    /**
+     * 鐢熸垚绛惧悕
+     * @param params 璇锋眰鍙傛暟闆嗗悎
+     * @return 绛惧悕鍊�
+     */
+    public static String generateSign(Map<String, String> params) {
+        // 1. 绉婚櫎sign鍙傛暟
+        params.remove("sign");
+        params.remove("Sign");
+
+        // 2. 鎸堿SCII鐮佹帓搴忥紙瀛楀吀搴忥級
+        List<String> keys = new ArrayList<>(params.keySet());
+        Collections.sort(keys);
+
+        // 3. 鎷兼帴瀛楃涓� (Key1Value1Key2Value2...)
+        StringBuilder stringA = new StringBuilder();
+        for (String key : keys) {
+            String value = params.get(key);
+            if (value != null && !value.isEmpty()) {
+                // 灏嗗弬鏁板悕棣栧瓧姣嶅ぇ鍐�
+                String capitalizedKey = StringUtils.capitalize(key);
+                stringA.append(capitalizedKey).append(value);
+            }
+        }
+
+        // 4. 鎷兼帴APP_SECRET
+        String stringSignTemp = stringA.toString() + APP_SECRET;
+
+        // 5. MD5杩愮畻骞惰浆灏忓啓
+        try {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] bytes = stringSignTemp.getBytes("UTF-8");
+            md.update(bytes);
+            byte[] md5Bytes = md.digest();
+
+            StringBuilder hexValue = new StringBuilder();
+            for (byte b : md5Bytes) {
+                int val = ((int) b) & 0xff;
+                if (val < 16) {
+                    hexValue.append("0");
+                }
+                hexValue.append(Integer.toHexString(val));
+            }
+            return hexValue.toString().toLowerCase();
+        } catch (Exception e) {
+            throw new RuntimeException("MD5鍔犲瘑鍑洪敊", e);
+        }
+    }
+
+    /**
+     * 楠岃瘉绛惧悕
+     * @param params 璇锋眰鍙傛暟闆嗗悎
+     * @param sign 绛惧悕鍊�
+     * @return 楠岃瘉缁撴灉
+     */
+    public static boolean verifySign(Map<String, String> params, String sign) {
+        String generatedSign = generateSign(params);
+        return generatedSign.equalsIgnoreCase(sign);
+    }
+
+    /**
+     * 浣跨敤绀轰緥
+     */
+    public static void main(String[] args) {
+        // 娴嬭瘯鐢ㄤ緥
+        Map<String, String> params = new HashMap<>();
+        params.put("method", "User_Login");
+        params.put("LoginType", "0");
+        params.put("UserID", "10");
+
+        String sign = generateSign(params);
+        System.out.println("鐢熸垚鐨勭鍚�: " + sign);
+        // 搴旇緭鍑�: 9a0a8659f005d6984697e2ca0a9cf3b7
+    }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/civilAviation/ServiceOrderUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/civilAviation/ServiceOrderUtil.java
new file mode 100644
index 0000000..ee1b6c0
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/civilAviation/ServiceOrderUtil.java
@@ -0,0 +1,230 @@
+package com.ruoyi.common.utils.civilAviation;
+
+
+import com.alibaba.fastjson2.JSON;
+import com.ruoyi.common.core.domain.entity.ServiceOrderAppVo;
+import com.ruoyi.common.core.domain.entity.ServiceOrderAppResultVo;
+import com.ruoyi.common.core.domain.entity.ServiceOrderDelVo;
+import com.ruoyi.common.utils.http.HttpUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Calendar;
+
+/**
+ * 姘戣埅鍖荤枟鎺ュ彛澶勭悊
+ */
+public class ServiceOrderUtil {
+    private static final Logger log = LoggerFactory.getLogger(ServiceOrderUtil.class);
+    public static String AddServiceOrederAPI = "http://localhost:8011/v1/";
+
+    /**
+     * 鍒涘缓鏈嶅姟鍗�
+     *
+     * @param model 鏈嶅姟鍗曞簲鐢ㄥ�煎璞�
+     * @return 鏈嶅姟鍗曟帴鍙h皟鐢ㄧ粨鏋�
+     */
+    public static ServiceOrderAppResultVo CreateServiceOrder(ServiceOrderAppVo model) {
+        if (AddServiceOrederAPI.isEmpty()) {
+            log.info("AddServiceOrederAPI 鏈缃紝璇峰厛璁剧疆鎺ュ彛鍦板潃銆�");
+            return null;
+        }
+
+        //璁$畻鏃堕棿鎴冲拰绛惧悕
+        long unixTime = System.currentTimeMillis() / 1000; // 鑾峰彇褰撳墠鏃堕棿鎴筹紙绉掞級
+        model.setUnixTime(unixTime); // 璁剧疆鏃堕棿鎴冲埌妯″瀷涓�
+
+        // 灏� model 杞崲涓� Map<String, String>
+        Map<String, String> params = new HashMap<>();
+        java.lang.reflect.Field[] fields = model.getClass().getDeclaredFields();
+        for (java.lang.reflect.Field field : fields) {
+            field.setAccessible(true);
+            try {
+                Object value = field.get(model);
+                if (value != null) {
+                    params.put(field.getName(), value.toString());
+                }
+            } catch (IllegalAccessException e) {
+                log.error("鑾峰彇瀵硅薄灞炴�у�兼椂鍑洪敊", e);
+            }
+        }
+
+        model.setSign(ServiceOrderSign.generateSign(params)); // 鐢熸垚绛惧悕骞惰缃埌妯″瀷涓�
+
+
+        // 鏇挎崲涓�
+        StringBuilder formData = new StringBuilder();
+        java.lang.reflect.Field[] fieldsQuest = model.getClass().getDeclaredFields();
+        for (java.lang.reflect.Field field : fieldsQuest) {
+            field.setAccessible(true);
+            try {
+                Object value = field.get(model);
+                if (value != null) {
+                    if (formData.length() > 0) {
+                        formData.append("&");
+                    }
+                    // 灏嗗瓧娈靛悕棣栧瓧姣嶅ぇ鍐�
+                    String fieldName = field.getName();
+                    String capitalizedFieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
+                    formData.append(capitalizedFieldName)
+                           .append("=")
+                           .append(value.toString());
+                }
+            } catch (Exception e) {
+                log.error("鎷兼帴琛ㄥ崟鏁版嵁鏃跺嚭閿�", e);
+            }
+        }
+
+        String responseData = HttpUtils.sendPost(AddServiceOrederAPI, formData.toString(), "application/x-www-form-urlencoded");
+
+
+        if (responseData != null && !responseData.isEmpty()) {
+            log.info("鎺ュ彛鍝嶅簲: " + responseData);
+            try {
+                // 浣跨敤 FastJSON 灏嗗搷搴旀暟鎹浆鎹负 ServiceOrderAppResultVo 瀵硅薄
+                return JSON.parseObject(responseData, ServiceOrderAppResultVo.class);
+            } catch (Exception e) {
+                log.info("瑙f瀽鎺ュ彛鍝嶅簲鏁版嵁澶辫触: " + e.getMessage());
+            }
+        } else {
+            log.info("鎺ュ彛璋冪敤澶辫触锛屾湭鑾峰彇鍒版湁鏁堝搷搴旀暟鎹�");
+        }
+
+        return null;
+    }
+
+
+    /**
+     * 鍙栨秷鏈嶅姟鍗�
+     *
+     * @param model 鏈嶅姟璁㈠崟鍒犻櫎璇锋眰鍊煎璞�
+     * @return 鏈嶅姟璁㈠崟鍒犻櫎鎺ュ彛璋冪敤缁撴灉
+     */
+    public static ServiceOrderAppResultVo CancelServiceOrder(ServiceOrderDelVo model) {
+        if (AddServiceOrederAPI.isEmpty()) {
+            log.info("AddServiceOrederAPI 鏈缃紝璇峰厛璁剧疆鎺ュ彛鍦板潃銆�");
+            return null;
+        }
+
+        // 璁$畻鏃堕棿鎴冲拰绛惧悕
+        long unixTime = System.currentTimeMillis() / 1000;
+        model.setUnixTime(unixTime);
+
+        // 灏� model 杞崲涓� Map<String, String>
+        Map<String, String> params = new HashMap<>();
+        java.lang.reflect.Field[] fields = model.getClass().getDeclaredFields();
+        for (java.lang.reflect.Field field : fields) {
+            field.setAccessible(true);
+            try {
+                Object value = field.get(model);
+                if (value != null) {
+                    params.put(field.getName(), value.toString());
+                }
+            } catch (IllegalAccessException e) {
+                log.error("鑾峰彇瀵硅薄灞炴�у�兼椂鍑洪敊", e);
+            }
+        }
+
+        model.setSign(ServiceOrderSign.generateSign(params));
+
+        // 鏋勫缓琛ㄥ崟鏁版嵁
+        StringBuilder formData = new StringBuilder();
+        java.lang.reflect.Field[] fieldsQuest = model.getClass().getDeclaredFields();
+        for (java.lang.reflect.Field field : fieldsQuest) {
+            field.setAccessible(true);
+            try {
+                Object value = field.get(model);
+                if (value != null) {
+                    if (formData.length() > 0) {
+                        formData.append("&");
+                    }
+                    // 灏嗗瓧娈靛悕棣栧瓧姣嶅ぇ鍐�
+                    String fieldName = field.getName();
+                    formData.append(fieldName)
+                           .append("=")
+                           .append(value.toString());
+                }
+            } catch (Exception e) {
+                log.error("鎷兼帴琛ㄥ崟鏁版嵁鏃跺嚭閿�", e);
+            }
+        }
+
+        String responseData = HttpUtils.sendPost(AddServiceOrederAPI, formData.toString(), "application/x-www-form-urlencoded");
+
+        if (responseData != null && !responseData.isEmpty()) {
+            log.info("鎺ュ彛鍝嶅簲: " + responseData);
+            try {
+                return JSON.parseObject(responseData, ServiceOrderAppResultVo.class);
+            } catch (Exception e) {
+                log.info("瑙f瀽鎺ュ彛鍝嶅簲鏁版嵁澶辫触: " + e.getMessage());
+            }
+        } else {
+            log.info("鎺ュ彛璋冪敤澶辫触锛屾湭鑾峰彇鍒版湁鏁堝搷搴旀暟鎹�");
+        }
+
+        return null;
+    }
+
+
+    public static void main(String[] args) {
+        // 鍒涘缓鏈嶅姟鍗曞簲鐢ㄥ�煎璞″苟璁剧疆鐩稿叧妯℃嫙灞炴��
+//        test();
+
+        testCancelServiceOrder();
+    }
+
+    //娴嬭瘯鍙栨秷鏈嶅姟鍗�
+    public static void testCancelServiceOrder() {
+        // 鍒涘缓鏈嶅姟鍗曞簲鐢ㄥ�煎璞″苟璁剧疆鐩稿叧妯℃嫙灞炴��
+        ServiceOrderDelVo model = new ServiceOrderDelVo();
+        model.setMethod("ServiceOrder_DEL"); // 璁剧疆鎺ュ彛鍚嶇О
+        model.setAPPID("GDS-000001"); // 璁剧疆鍟嗘埛 APPID
+        model.setServiceOrdID("1016302854"); // 璁剧疆鏈嶅姟鍗旾D
+        model.setDELRemarks("娴嬭瘯");
+
+        // 璋冪敤 CancelServiceOrder 鏂规硶鍙栨秷鏈嶅姟鍗�
+        ServiceOrderAppResultVo result = CancelServiceOrder(model);
+        System.out.println("1");
+    }
+
+    public static  void test()
+    {
+        ServiceOrderAppVo model = new ServiceOrderAppVo();
+         model.setMethod("ServiceOrder_APP"); // 璁剧疆鎺ュ彛鍚嶇О
+         model.setAppId("GDS-000001"); // 璁剧疆鍟嗘埛 APPID
+         model.setOrdType(2);
+         model.setCoPhone("13" + (int) (Math.random() * 900000000 + 100000000)); // 闅忔満鐢熸垚瀹㈡埛鑱旂郴鐢佃瘽
+         model.setCoName("瀹㈡埛" + (int) (Math.random() * 100)); // 闅忔満鐢熸垚瀹㈡埛濮撳悕
+         model.setCoTies("瀹跺睘"); // 闅忔満璁剧疆瀹㈡埛鑱旂郴浜轰笌鎮h�呭叧绯�
+        // 璁剧疆棰勭害鏃堕棿涓轰竴澶╁悗
+        Calendar calendar = Calendar.getInstance();
+        calendar.add(Calendar.DAY_OF_MONTH, 1); // 澧炲姞涓�澶�
+
+        String testTime = "2025-05-03%2021:33";
+        model.setApptDate(testTime); // 璁剧疆棰勭害杩愰�佹椂闂翠负鏄庡ぉ
+         model.setPtName("鎮h�呭鍚�" + (int) (Math.random() * 100)); // 闅忔満鐢熸垚鎮h�呭鍚�
+         model.setPtAge((int) (Math.random() * 100) + "宀�"); // 闅忔満鐢熸垚鎮h�呭勾榫�
+         model.setPtSex(Math.random() > 0.5 ? "鐢�" : "濂�"); // 闅忔満鐢熸垚鎮h�呮�у埆
+         model.setPtNat("涓浗"); // 闅忔満璁剧疆鎮h�呭浗绫�
+         model.setOutHosp("闅忔満杞嚭鍖婚櫌" + (int) (Math.random() * 10)); // 闅忔満璁剧疆杞嚭鍖婚櫌
+         model.setInHosp("闅忔満杞叆鍖婚櫌" + (int) (Math.random() * 10)); // 闅忔満璁剧疆杞叆鍖婚櫌
+         model.setPtServices("绉戝" + (int) (Math.random() * 10)); // 闅忔満璁剧疆鎮h�呮墍鍦ㄧ瀹�
+         model.setPtDiagnosis("闅忔満璇婃柇淇℃伅"); // 闅忔満璁剧疆璇婃柇淇℃伅
+         model.setCondition("闅忔満澶囨敞淇℃伅"); // 闅忔満璁剧疆澶囨敞淇℃伅
+         model.setDoctor("鍖荤敓" + (int) (Math.random() * 10)); // 闅忔満璁剧疆鎮h�呭尰鐢�
+         model.setDoctorPhone("13" + (int) (Math.random() * 900000000 + 100000000)); // 闅忔満鐢熸垚鎮h�呭尰鐢熺數璇�
+         model.setOfferPrice(Math.random() * 1000); // 闅忔満鐢熸垚鎶ヤ环
+         model.setReferrals("鎺ㄤ粙浜�" + (int) (Math.random() * 10)); // 闅忔満璁剧疆鎺ㄤ粙浜轰俊鎭�
+         model.setUnitRemarks("鍟嗘埛闅忔満澶囨敞淇℃伅"); // 闅忔満璁剧疆鍟嗘埛澶囨敞
+         model.setPayQRcodeURL("https://example.com/qrcode/" + (int) (Math.random() * 100)); // 闅忔満鐢熸垚澶栭儴鏀粯浜岀淮鐮侀摼鎺�
+
+         // 璋冪敤 CreateServiceOrder 鏂规硶鍒涘缓鏈嶅姟鍗�
+         ServiceOrderAppResultVo result = CreateServiceOrder(model);
+    }
+    
+}
diff --git a/ruoyi-system/pom.xml b/ruoyi-system/pom.xml
index b5db5b3..44b16f5 100644
--- a/ruoyi-system/pom.xml
+++ b/ruoyi-system/pom.xml
@@ -27,6 +27,11 @@
             <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
             <version>3.5.1</version>
         </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
 
     </dependencies>
 

--
Gitblit v1.9.1