diff --git a/aaa.json b/aaa.json deleted file mode 100644 index b19a5cc..0000000 --- a/aaa.json +++ /dev/null @@ -1,9026 +0,0 @@ -[ - { - "order_no": "2026050618470000056716454", - "out_order_no": "202605061846524739782853070", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778064420, - "payment_time": null, - "notify_time": null, - "client_ip": "116.21.64.115", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618451400056726661", - "out_order_no": "202605061845077970995909162", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778064314, - "payment_time": 1778064338, - "notify_time": 1778064339, - "client_ip": "180.158.188.11", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618420500056726501", - "out_order_no": "202605061840493114312657316", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778064125, - "payment_time": 1778064168, - "notify_time": 1778064169, - "client_ip": "117.143.120.195", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618410700056718063", - "out_order_no": "202605061841021059758735786", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778064067, - "payment_time": 1778064084, - "notify_time": 1778064084, - "client_ip": "36.21.179.2", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618404400056723339", - "out_order_no": "20260506184037427047477742", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778064044, - "payment_time": null, - "notify_time": null, - "client_ip": "36.21.179.2", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618381200056719720", - "out_order_no": "202605061837564994058249776", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778063892, - "payment_time": 1778063920, - "notify_time": 1778063920, - "client_ip": "117.129.57.157", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618380000056715960", - "out_order_no": "202605061837448642261598961", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778063880, - "payment_time": 1778063919, - "notify_time": 1778063920, - "client_ip": "39.144.171.107", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618363300056727220", - "out_order_no": "202605061836243712465283450", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778063793, - "payment_time": 1778063823, - "notify_time": 1778063823, - "client_ip": "117.143.179.174", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618351300056710610", - "out_order_no": "20260506183503249417040346", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778063713, - "payment_time": 1778063736, - "notify_time": 1778063737, - "client_ip": "182.136.188.79", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618335300056711548", - "out_order_no": "20260506183342844281901840", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778063633, - "payment_time": 1778063656, - "notify_time": 1778063657, - "client_ip": "114.227.161.83", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618325900056714286", - "out_order_no": "202605061832395858147923158", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778063579, - "payment_time": 1778063644, - "notify_time": 1778063644, - "client_ip": "120.229.31.145", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618305400056724917", - "out_order_no": "202605061830423226760128135", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778063454, - "payment_time": 1778063478, - "notify_time": 1778063479, - "client_ip": "39.64.242.53", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618273900056714877", - "out_order_no": "202605061827322543800463309", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778063259, - "payment_time": 1778063349, - "notify_time": 1778063349, - "client_ip": "64.176.59.89", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618253500056715353", - "out_order_no": "202605061825275987223733779", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778063135, - "payment_time": 1778063155, - "notify_time": 1778063156, - "client_ip": "121.236.254.138", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618252000056719416", - "out_order_no": "202605061825118620277576486", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778063120, - "payment_time": 1778063138, - "notify_time": 1778063139, - "client_ip": "120.204.171.17", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618243200056712115", - "out_order_no": "20260506182406165171729522", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778063072, - "payment_time": 1778063090, - "notify_time": 1778063091, - "client_ip": "49.74.228.86", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618214400056719612", - "out_order_no": "202605061821365041954575441", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778062904, - "payment_time": 1778062925, - "notify_time": 1778062926, - "client_ip": "39.144.124.52", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618214000056724524", - "out_order_no": "202605061821222643692320118", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778062900, - "payment_time": 1778062967, - "notify_time": 1778062968, - "client_ip": "111.49.159.186", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618194500056716384", - "out_order_no": "202605061819197240792129222", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778062785, - "payment_time": null, - "notify_time": null, - "client_ip": "64.176.59.89", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618150500056724529", - "out_order_no": "202605061814523504834862611", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778062505, - "payment_time": 1778062551, - "notify_time": 1778062551, - "client_ip": "182.148.17.190", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618134500056713805", - "out_order_no": "20260506181334440535760416", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778062425, - "payment_time": 1778062459, - "notify_time": 1778062460, - "client_ip": "171.116.204.199", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618113000056716355", - "out_order_no": "202605061811178961664145645", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778062290, - "payment_time": 1778062309, - "notify_time": 1778062310, - "client_ip": "218.26.169.230", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618073100056727371", - "out_order_no": "202605061806401508235481288", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778062051, - "payment_time": 1778062083, - "notify_time": 1778062084, - "client_ip": "120.235.45.30", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618071200056717310", - "out_order_no": "202605061807033087885893298", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778062032, - "payment_time": 1778062068, - "notify_time": 1778062069, - "client_ip": "117.174.234.12", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618051300056719781", - "out_order_no": "20260506180506724269915984", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778061913, - "payment_time": 1778061987, - "notify_time": 1778061988, - "client_ip": "221.219.100.119", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618051200056719038", - "out_order_no": "202605061804478565141485049", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778061912, - "payment_time": null, - "notify_time": null, - "client_ip": "61.166.207.179", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618032700056714361", - "out_order_no": "202605061803148814691474766", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778061807, - "payment_time": 1778061850, - "notify_time": 1778061851, - "client_ip": "223.104.122.108", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618010000056720329", - "out_order_no": "202605061800538767484274735", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778061660, - "payment_time": 1778061702, - "notify_time": 1778061703, - "client_ip": "183.129.78.178", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050618002100056715732", - "out_order_no": "202605061800139933592813484", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778061621, - "payment_time": 1778061663, - "notify_time": 1778061664, - "client_ip": "106.224.141.249", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617574100056714983", - "out_order_no": "202605061757315798269592565", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778061461, - "payment_time": 1778061561, - "notify_time": 1778061562, - "client_ip": "111.55.8.4", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617573700056721646", - "out_order_no": "202605061757277372292405051", - "order_money": 315, - "user_money": 303.03, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778061457, - "payment_time": null, - "notify_time": null, - "client_ip": "175.172.150.189", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617573200056710049", - "out_order_no": "20260506175726392989886216", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778061452, - "payment_time": null, - "notify_time": null, - "client_ip": "106.224.141.249", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617532400056713417", - "out_order_no": "202605061753073023390214008", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778061204, - "payment_time": null, - "notify_time": null, - "client_ip": "111.55.8.4", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617532200056713097", - "out_order_no": "202605061753033529492968587", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778061202, - "payment_time": null, - "notify_time": null, - "client_ip": "119.125.127.178", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617505100056722681", - "out_order_no": "202605061750404518153957693", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778061051, - "payment_time": 1778061090, - "notify_time": 1778061091, - "client_ip": "42.86.50.41", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617465900056714173", - "out_order_no": "202605061746406106633464602", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778060819, - "payment_time": null, - "notify_time": null, - "client_ip": "111.55.12.84", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617441600056726701", - "out_order_no": "20260506174408375565592311", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778060656, - "payment_time": 1778060705, - "notify_time": 1778060706, - "client_ip": "122.239.126.67", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617422600056724245", - "out_order_no": "202605061742144424128849304", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778060546, - "payment_time": 1778060580, - "notify_time": 1778060581, - "client_ip": "38.110.231.5", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617420100056710479", - "out_order_no": "202605061741523976466645247", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778060521, - "payment_time": null, - "notify_time": null, - "client_ip": "111.197.70.152", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617413100056786340", - "out_order_no": "202605061741145942617381228", - "order_money": 90.93, - "user_money": 0, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778060491, - "payment_time": null, - "notify_time": null, - "client_ip": "111.197.70.152", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617392400056729127", - "out_order_no": "202605061739072215852109012", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778060364, - "payment_time": 1778060430, - "notify_time": 1778060431, - "client_ip": "10.158.40.167", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617390600056724669", - "out_order_no": "202605061738546031547106298", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778060346, - "payment_time": 1778060400, - "notify_time": 1778060401, - "client_ip": "117.136.90.210", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617343300056723486", - "out_order_no": "202605061734158181533230372", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778060073, - "payment_time": 1778060094, - "notify_time": 1778060095, - "client_ip": "119.102.127.220", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050617331600056728688", - "out_order_no": "202605061733095352618454577", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778059996, - "payment_time": 1778060035, - "notify_time": 1778060036, - "client_ip": "58.63.146.120", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616545200056727808", - "out_order_no": "202605061654399518631511786", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778057692, - "payment_time": 1778057726, - "notify_time": 1778057726, - "client_ip": "162.213.0.3", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616495300056719018", - "out_order_no": "202605061649464947513562100", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778057393, - "payment_time": 1778057413, - "notify_time": 1778057413, - "client_ip": "223.104.163.5", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616480900056781258", - "out_order_no": "202605061647569080629897358", - "order_money": 19.53, - "user_money": 0, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778057289, - "payment_time": null, - "notify_time": null, - "client_ip": "210.37.40.213", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616452900056716416", - "out_order_no": "202605061645205622449689885", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778057129, - "payment_time": 1778057152, - "notify_time": 1778057152, - "client_ip": "27.187.83.149", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616450600056717740", - "out_order_no": "202605061644588337703034520", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778057106, - "payment_time": 1778057126, - "notify_time": 1778057126, - "client_ip": "222.76.193.59", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616410600056729532", - "out_order_no": "202605061640572452020182288", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778056866, - "payment_time": null, - "notify_time": null, - "client_ip": "223.104.207.27", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616344400056728642", - "out_order_no": "202605061634314311980636851", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778056484, - "payment_time": 1778056515, - "notify_time": 1778056515, - "client_ip": "223.104.163.55", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616341700056729870", - "out_order_no": "202605061634058088915946981", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778056457, - "payment_time": 1778056476, - "notify_time": 1778056478, - "client_ip": "27.36.105.157", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616332300056722174", - "out_order_no": "202605061633059072165472788", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778056403, - "payment_time": null, - "notify_time": null, - "client_ip": "10.89.206.233", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616325000056712639", - "out_order_no": "202605061632391333931485821", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778056370, - "payment_time": 1778056394, - "notify_time": 1778056394, - "client_ip": "183.131.226.103", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616292100056711061", - "out_order_no": "202605061629084580738462219", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778056161, - "payment_time": 1778056206, - "notify_time": 1778056206, - "client_ip": "223.104.248.137", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616275700056719197", - "out_order_no": "202605061627415271122416155", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778056077, - "payment_time": null, - "notify_time": null, - "client_ip": "223.104.248.137", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616240600056716544", - "out_order_no": "202605061623575508394640773", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055846, - "payment_time": 1778055901, - "notify_time": 1778055901, - "client_ip": "101.24.119.74", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616221500056710855", - "out_order_no": "202605061622055665662254875", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055735, - "payment_time": 1778055756, - "notify_time": 1778055756, - "client_ip": "223.160.113.188", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616220700056713143", - "out_order_no": "20260506162143323119589417", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055727, - "payment_time": 1778055771, - "notify_time": 1778055771, - "client_ip": "114.229.19.190", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616201400056717231", - "out_order_no": "202605061619575670347421320", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055614, - "payment_time": 1778055651, - "notify_time": 1778055652, - "client_ip": "59.61.177.181", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616184200056719797", - "out_order_no": "202605061618325945312130096", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055522, - "payment_time": 1778055572, - "notify_time": 1778055573, - "client_ip": "101.206.179.179", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616171900056717810", - "out_order_no": "202605061617048654828894937", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778055439, - "payment_time": null, - "notify_time": null, - "client_ip": "222.90.214.215", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616164800056722837", - "out_order_no": "20260506161641928058618031", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055408, - "payment_time": 1778055434, - "notify_time": 1778055434, - "client_ip": "39.144.249.144", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616153800056726384", - "out_order_no": "202605061615303329458711113", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055338, - "payment_time": 1778055367, - "notify_time": 1778055367, - "client_ip": "117.143.45.62", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616152200056714767", - "out_order_no": "202605061615144160616138012", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055322, - "payment_time": 1778055341, - "notify_time": 1778055342, - "client_ip": "223.246.186.217", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616142500056723852", - "out_order_no": "202605061613446831943212446", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055265, - "payment_time": 1778055311, - "notify_time": 1778055311, - "client_ip": "1.62.252.61", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616141600056718734", - "out_order_no": "202605061613599619914096800", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055256, - "payment_time": 1778055299, - "notify_time": 1778055300, - "client_ip": "171.214.199.30", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616135100056718766", - "out_order_no": "202605061613354555458778563", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055231, - "payment_time": 1778055258, - "notify_time": 1778055258, - "client_ip": "111.19.56.251", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616110400056718354", - "out_order_no": "202605061610594111505671957", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055064, - "payment_time": 1778055083, - "notify_time": 1778055083, - "client_ip": "112.41.76.61", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616104400056718444", - "out_order_no": "202605061610385174827168034", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778055044, - "payment_time": null, - "notify_time": null, - "client_ip": "112.41.76.61", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616100000056717180", - "out_order_no": "202605061609445977115056332", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778055000, - "payment_time": 1778055021, - "notify_time": 1778055021, - "client_ip": "122.243.161.189", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616093300056710087", - "out_order_no": "202605061609259859463704127", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778054973, - "payment_time": null, - "notify_time": null, - "client_ip": "112.41.76.61", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616073100056710019", - "out_order_no": "202605061607211801495284617", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778054851, - "payment_time": 1778054873, - "notify_time": 1778054873, - "client_ip": "210.22.144.189", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616061400056714559", - "out_order_no": "202605061606051803731013865", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778054774, - "payment_time": null, - "notify_time": null, - "client_ip": "101.230.149.69", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616053500056724377", - "out_order_no": "202605061605179656371205042", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778054735, - "payment_time": 1778054759, - "notify_time": 1778054759, - "client_ip": "124.70.231.44", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616051900056720728", - "out_order_no": "202605061605093060586798944", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778054719, - "payment_time": null, - "notify_time": null, - "client_ip": "39.144.249.144", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616030900056722391", - "out_order_no": "202605061603028260277667680", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778054589, - "payment_time": 1778054636, - "notify_time": 1778054636, - "client_ip": "120.36.214.46", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616023800056724290", - "out_order_no": "202605061602329257669017749", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778054558, - "payment_time": 1778054592, - "notify_time": 1778054592, - "client_ip": "111.14.35.109", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616022800056717243", - "out_order_no": "202605061602178042145901429", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778054548, - "payment_time": 1778054585, - "notify_time": 1778054585, - "client_ip": "223.104.54.55", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616020400056725681", - "out_order_no": "202605061601533853670140071", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778054524, - "payment_time": 1778054652, - "notify_time": 1778054653, - "client_ip": "114.230.210.91", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616004700056727030", - "out_order_no": "202605061600357407596973403", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778054447, - "payment_time": 1778054487, - "notify_time": 1778054488, - "client_ip": "114.227.31.73", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050616000500056727752", - "out_order_no": "202605061559571480521568107", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778054405, - "payment_time": 1778054420, - "notify_time": 1778054421, - "client_ip": "223.104.68.140", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615543700056711193", - "out_order_no": "202605061554256714870624357", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778054077, - "payment_time": 1778054099, - "notify_time": 1778054099, - "client_ip": "175.146.71.218", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615543600056724160", - "out_order_no": "202605061554236423715877224", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778054076, - "payment_time": 1778054113, - "notify_time": 1778054113, - "client_ip": "175.167.129.64", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615521100056712011", - "out_order_no": "202605061552047362965618443", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778053931, - "payment_time": 1778053965, - "notify_time": 1778053965, - "client_ip": "223.104.4.75", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615481900056720438", - "out_order_no": "202605061548032554200456810", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778053699, - "payment_time": 1778053733, - "notify_time": 1778053733, - "client_ip": "14.31.16.174", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615440600056723567", - "out_order_no": "202605061543556522036228210", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778053446, - "payment_time": 1778053479, - "notify_time": 1778053480, - "client_ip": "223.104.196.239", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615431400056714071", - "out_order_no": "202605061543034992900833306", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778053394, - "payment_time": null, - "notify_time": null, - "client_ip": "223.104.4.75", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615421100056726315", - "out_order_no": "202605061542025316881788900", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778053331, - "payment_time": 1778053349, - "notify_time": 1778053350, - "client_ip": "113.84.9.104", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615412600056720707", - "out_order_no": "202605061541192921207242833", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778053286, - "payment_time": 1778053303, - "notify_time": 1778053303, - "client_ip": "112.111.55.119", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615385400056720988", - "out_order_no": "202605061538383753398138336", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778053134, - "payment_time": 1778053185, - "notify_time": 1778053186, - "client_ip": "211.90.251.122", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615381400056724156", - "out_order_no": "202605061538032682975602676", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778053094, - "payment_time": 1778053116, - "notify_time": 1778053116, - "client_ip": "223.155.154.28", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615381300056712606", - "out_order_no": "202605061538006387317700824", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778053093, - "payment_time": 1778053134, - "notify_time": 1778053134, - "client_ip": "27.224.135.217", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615380000056720005", - "out_order_no": "202605061537427064222286324", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778053080, - "payment_time": 1778053127, - "notify_time": 1778053127, - "client_ip": "47.242.129.204", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615351800056787699", - "out_order_no": "202605061534033845356678382", - "order_money": 90.93, - "user_money": 0, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778052918, - "payment_time": null, - "notify_time": null, - "client_ip": "223.104.54.55", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615350100056719187", - "out_order_no": "202605061534379937783771915", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778052901, - "payment_time": null, - "notify_time": null, - "client_ip": "171.214.199.30", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615341300056717150", - "out_order_no": "202605061533538030890490500", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778052853, - "payment_time": 1778052873, - "notify_time": 1778052873, - "client_ip": "106.61.89.190", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615340100056723171", - "out_order_no": "202605061533541975816015039", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778052841, - "payment_time": 1778052874, - "notify_time": 1778052874, - "client_ip": "1.82.48.114", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615333500056725368", - "out_order_no": "202605061533232045661836610", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778052815, - "payment_time": null, - "notify_time": null, - "client_ip": "1.82.48.114", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615333100056716162", - "out_order_no": "202605061532461255375050123", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778052811, - "payment_time": 1778052869, - "notify_time": 1778052870, - "client_ip": "125.85.128.199", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615313000056712175", - "out_order_no": "202605061531189892766940944", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778052690, - "payment_time": null, - "notify_time": null, - "client_ip": "61.242.132.60", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615300600056717992", - "out_order_no": "202605061529466841089100386", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778052606, - "payment_time": 1778052647, - "notify_time": 1778052647, - "client_ip": "116.246.31.163", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615292000056710801", - "out_order_no": "202605061529099213483305196", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778052560, - "payment_time": 1778052581, - "notify_time": 1778052582, - "client_ip": "202.119.43.188", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615220900056710043", - "out_order_no": "202605061522024963101432773", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778052129, - "payment_time": 1778052152, - "notify_time": 1778052153, - "client_ip": "110.191.68.170", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615195000056722378", - "out_order_no": "202605061519362320765659108", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778051990, - "payment_time": 1778052005, - "notify_time": 1778052005, - "client_ip": "222.209.160.84", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615160700056729880", - "out_order_no": "202605061515571956690753769", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778051767, - "payment_time": 1778051792, - "notify_time": 1778051792, - "client_ip": "111.37.0.30", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615121600056716993", - "out_order_no": "20260506151211750430359249", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778051536, - "payment_time": 1778051577, - "notify_time": 1778051577, - "client_ip": "112.94.97.120", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615100000056729321", - "out_order_no": "202605061509507464603254367", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778051400, - "payment_time": null, - "notify_time": null, - "client_ip": "112.96.57.228", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050615091400056719361", - "out_order_no": "202605061509058553215240352", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778051354, - "payment_time": 1778051384, - "notify_time": 1778051384, - "client_ip": "182.33.221.253", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614593600056717127", - "out_order_no": "202605061459162714944496701", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778050776, - "payment_time": 1778050812, - "notify_time": 1778050813, - "client_ip": "223.67.204.111", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614581100056719423", - "out_order_no": "20260506145801960340611980", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778050691, - "payment_time": 1778050720, - "notify_time": 1778050720, - "client_ip": "183.224.71.172", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614560500056784279", - "out_order_no": "202605061455529784314298935", - "order_money": 41.93, - "user_money": 0, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778050565, - "payment_time": null, - "notify_time": null, - "client_ip": "39.144.58.108", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614434000056713544", - "out_order_no": "202605061443284118815142563", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778049820, - "payment_time": 1778049838, - "notify_time": 1778049838, - "client_ip": "113.206.96.14", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614431200056724333", - "out_order_no": "202605061443066708433819106", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778049792, - "payment_time": 1778049807, - "notify_time": 1778049807, - "client_ip": "180.110.178.216", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614272000056723235", - "out_order_no": "202605061427097791951896168", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778048840, - "payment_time": 1778048861, - "notify_time": 1778048861, - "client_ip": "10.156.136.69", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614263000056711120", - "out_order_no": "202605061426106984362263398", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778048790, - "payment_time": 1778048831, - "notify_time": 1778048832, - "client_ip": "27.17.177.237", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614235000056724265", - "out_order_no": "202605061423293605387806314", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778048630, - "payment_time": 1778048647, - "notify_time": 1778048648, - "client_ip": "117.129.43.114", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614215800056716643", - "out_order_no": "202605061421471015974750367", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778048518, - "payment_time": 1778048535, - "notify_time": 1778048535, - "client_ip": "222.185.30.46", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614143900056718549", - "out_order_no": "202605061414335353976708201", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778048079, - "payment_time": 1778048097, - "notify_time": 1778048097, - "client_ip": "180.98.64.240", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614134500056720320", - "out_order_no": "202605061413403524494084517", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778048025, - "payment_time": 1778048056, - "notify_time": 1778048056, - "client_ip": "220.170.32.215", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614110100056727417", - "out_order_no": "202605061410426573276009604", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778047861, - "payment_time": 1778047914, - "notify_time": 1778047914, - "client_ip": "49.93.227.125", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614094000056714998", - "out_order_no": "202605061409283480413189779", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778047780, - "payment_time": 1778047821, - "notify_time": 1778047821, - "client_ip": "120.235.146.50", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614015500056718338", - "out_order_no": "202605061401464962206577111", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778047315, - "payment_time": 1778047333, - "notify_time": 1778047333, - "client_ip": "115.197.24.201", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614010400056723892", - "out_order_no": "202605061400502266984504329", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778047264, - "payment_time": 1778047278, - "notify_time": 1778047279, - "client_ip": "113.119.177.240", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614010100056723484", - "out_order_no": "202605061400383825321145780", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778047261, - "payment_time": null, - "notify_time": null, - "client_ip": "115.197.24.201", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050614001000056726020", - "out_order_no": "202605061400044896428769599", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778047210, - "payment_time": 1778047241, - "notify_time": 1778047241, - "client_ip": "220.188.64.39", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613592500056728318", - "out_order_no": "202605061359106616223912540", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778047165, - "payment_time": 1778047189, - "notify_time": 1778047190, - "client_ip": "61.171.197.44", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613555000056712963", - "out_order_no": "202605061355398314323327839", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778046950, - "payment_time": 1778046979, - "notify_time": 1778046979, - "client_ip": "175.168.201.159", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613545300056713886", - "out_order_no": "20260506135443852877363552", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778046893, - "payment_time": 1778046917, - "notify_time": 1778046917, - "client_ip": "39.144.248.137", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613514300056724846", - "out_order_no": "202605061351327973246346894", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778046703, - "payment_time": 1778046732, - "notify_time": 1778046733, - "client_ip": "117.140.229.6", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613502000056720912", - "out_order_no": "202605061350116720627649407", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778046620, - "payment_time": 1778046651, - "notify_time": 1778046651, - "client_ip": "119.163.237.19", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613481000056725697", - "out_order_no": "20260506134758307367413916", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778046490, - "payment_time": 1778046522, - "notify_time": 1778046522, - "client_ip": "14.153.70.11", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613455600056728768", - "out_order_no": "20260506134545387730298666", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778046356, - "payment_time": 1778046414, - "notify_time": 1778046414, - "client_ip": "101.249.172.28", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613443200056722658", - "out_order_no": "202605061344242376049285251", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778046272, - "payment_time": 1778046288, - "notify_time": 1778046289, - "client_ip": "111.181.29.125", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613432600056722209", - "out_order_no": "202605061343094147378358395", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778046206, - "payment_time": 1778046251, - "notify_time": 1778046251, - "client_ip": "183.197.102.80", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613423800056725819", - "out_order_no": "202605061342281483720438448", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778046158, - "payment_time": 1778046175, - "notify_time": 1778046175, - "client_ip": "10.238.39.119", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613423300056720323", - "out_order_no": "202605061342016917599930450", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778046153, - "payment_time": 1778046177, - "notify_time": 1778046178, - "client_ip": "182.118.238.107", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613383600056714359", - "out_order_no": "202605061338227408349796286", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778045916, - "payment_time": 1778045936, - "notify_time": 1778045936, - "client_ip": "115.225.6.228", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613374100056712775", - "out_order_no": "202605061337283760342412076", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778045861, - "payment_time": null, - "notify_time": null, - "client_ip": "115.225.6.228", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613355800056720377", - "out_order_no": "20260506133554247704687085", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778045758, - "payment_time": 1778045785, - "notify_time": 1778045786, - "client_ip": "221.235.153.64", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613353900056726740", - "out_order_no": "202605061335337073600670879", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778045739, - "payment_time": null, - "notify_time": null, - "client_ip": "221.235.153.64", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613324300056724997", - "out_order_no": "202605061332134867033206459", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778045563, - "payment_time": 1778045605, - "notify_time": 1778045606, - "client_ip": "206.237.119.228", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613305300056716658", - "out_order_no": "2026050613304513738535833", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778045453, - "payment_time": 1778045470, - "notify_time": 1778045470, - "client_ip": "114.246.237.12", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613295600056727372", - "out_order_no": "202605061329078854271727598", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778045396, - "payment_time": 1778045418, - "notify_time": 1778045418, - "client_ip": "115.215.42.82", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613272800056717735", - "out_order_no": "202605061327209980620381385", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778045248, - "payment_time": 1778045269, - "notify_time": 1778045270, - "client_ip": "183.163.13.80", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613254500056711954", - "out_order_no": "202605061325108551630248698", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778045145, - "payment_time": 1778045176, - "notify_time": 1778045176, - "client_ip": "116.237.134.162", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613250600056714785", - "out_order_no": "20260506132444990433539822", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778045106, - "payment_time": 1778045131, - "notify_time": 1778045131, - "client_ip": "39.144.94.126", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613233900056717236", - "out_order_no": "202605061323203907425949091", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778045019, - "payment_time": 1778045041, - "notify_time": 1778045041, - "client_ip": "112.0.121.214", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613193000056721621", - "out_order_no": "202605061319114938447696371", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778044770, - "payment_time": 1778044787, - "notify_time": 1778044787, - "client_ip": "113.246.199.61", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613174700056726331", - "out_order_no": "202605061317412587353327109", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778044667, - "payment_time": 1778044689, - "notify_time": 1778044689, - "client_ip": "120.230.174.221", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613174100056715730", - "out_order_no": "202605061317338167062709980", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778044661, - "payment_time": 1778044692, - "notify_time": 1778044692, - "client_ip": "111.18.246.147", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613123300056717573", - "out_order_no": "202605061312217248595497708", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778044353, - "payment_time": 1778044390, - "notify_time": 1778044390, - "client_ip": "112.224.217.3", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613113500056725689", - "out_order_no": "202605061311284273410037737", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778044295, - "payment_time": 1778044330, - "notify_time": 1778044330, - "client_ip": "171.10.56.2", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613111700056725526", - "out_order_no": "202605061311074796427382129", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778044277, - "payment_time": null, - "notify_time": null, - "client_ip": "171.10.56.2", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613103000056720044", - "out_order_no": "202605061310244293199930151", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778044230, - "payment_time": 1778044256, - "notify_time": 1778044257, - "client_ip": "223.104.67.127", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613094800056719325", - "out_order_no": "202605061309356718764034566", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778044188, - "payment_time": 1778044212, - "notify_time": 1778044212, - "client_ip": "113.84.193.2", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613091300056713704", - "out_order_no": "20260506130904430053264959", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778044153, - "payment_time": 1778044178, - "notify_time": 1778044178, - "client_ip": "116.130.29.128", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613085600056725739", - "out_order_no": "20260506130849343430187474", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778044136, - "payment_time": null, - "notify_time": null, - "client_ip": "223.104.67.127", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613075200056727880", - "out_order_no": "202605061307447799519087729", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778044072, - "payment_time": 1778044140, - "notify_time": 1778044140, - "client_ip": "114.104.8.213", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613055400056714085", - "out_order_no": "202605061305412515799327348", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778043954, - "payment_time": 1778043975, - "notify_time": 1778043976, - "client_ip": "120.243.228.33", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613020500056714694", - "out_order_no": "202605061301563844523715618", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778043725, - "payment_time": 1778043781, - "notify_time": 1778043781, - "client_ip": "125.92.145.161", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050613015800056727364", - "out_order_no": "202605061301535544030569066", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778043718, - "payment_time": 1778043749, - "notify_time": 1778043750, - "client_ip": "114.230.211.173", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612581600056716337", - "out_order_no": "202605061258081672531631584", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778043496, - "payment_time": 1778043516, - "notify_time": 1778043516, - "client_ip": "139.226.115.98", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612554100056728539", - "out_order_no": "202605061255269205167361095", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778043341, - "payment_time": 1778043384, - "notify_time": 1778043384, - "client_ip": "39.144.138.97", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612531400056720441", - "out_order_no": "202605061252189999368309801", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778043194, - "payment_time": 1778043261, - "notify_time": 1778043262, - "client_ip": "140.99.130.6", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612490500056717880", - "out_order_no": "20260506124843815697760735", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778042945, - "payment_time": 1778042974, - "notify_time": 1778042975, - "client_ip": "111.36.48.37", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612483200056712146", - "out_order_no": "202605061247585673582410659", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778042912, - "payment_time": 1778042937, - "notify_time": 1778042938, - "client_ip": "175.30.144.98", - "device": "qq", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612470300056716248", - "out_order_no": "20260506124657305107725077", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778042823, - "payment_time": 1778042847, - "notify_time": 1778042848, - "client_ip": "220.205.253.4", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612464200056716272", - "out_order_no": "202605061246243686304560857", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778042802, - "payment_time": 1778042825, - "notify_time": 1778042825, - "client_ip": "180.142.153.203", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612461300056719210", - "out_order_no": "202605061245342919467320737", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778042773, - "payment_time": null, - "notify_time": null, - "client_ip": "220.205.253.4", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612424100056711649", - "out_order_no": "202605061242283527209208796", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778042561, - "payment_time": null, - "notify_time": null, - "client_ip": "171.219.160.197", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612421900056723007", - "out_order_no": "202605061242131701273576030", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778042539, - "payment_time": 1778042566, - "notify_time": 1778042567, - "client_ip": "42.237.199.1", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612415000056727655", - "out_order_no": "202605061241337465021453949", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778042510, - "payment_time": 1778042546, - "notify_time": 1778042547, - "client_ip": "58.214.46.145", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612403400056717133", - "out_order_no": "202605061240197149109410518", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778042434, - "payment_time": null, - "notify_time": null, - "client_ip": "42.237.199.1", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612381100056713995", - "out_order_no": "202605061238067882459752505", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778042291, - "payment_time": 1778042307, - "notify_time": 1778042308, - "client_ip": "42.80.120.113", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612374500056712509", - "out_order_no": "202605061237383804521280846", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778042265, - "payment_time": 1778042301, - "notify_time": 1778042302, - "client_ip": "223.104.41.190", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612351200056728396", - "out_order_no": "202605061235062657042471508", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778042112, - "payment_time": 1778042156, - "notify_time": 1778042157, - "client_ip": "223.104.54.112", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612345300056727145", - "out_order_no": "202605061234481511551765546", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778042093, - "payment_time": 1778042124, - "notify_time": 1778042124, - "client_ip": "120.219.96.180", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612302500056723234", - "out_order_no": "202605061230092323229031103", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778041825, - "payment_time": 1778041863, - "notify_time": 1778041863, - "client_ip": "111.183.49.40", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612294200056729115", - "out_order_no": "20260506122920799949710543", - "order_money": 315, - "user_money": 303.03, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778041782, - "payment_time": null, - "notify_time": null, - "client_ip": "223.104.54.112", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612271300056715996", - "out_order_no": "202605061227029533424220169", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778041633, - "payment_time": 1778041658, - "notify_time": 1778041658, - "client_ip": "58.247.23.192", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612271300056719749", - "out_order_no": "202605061227044637880734760", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778041633, - "payment_time": 1778041654, - "notify_time": 1778041654, - "client_ip": "10.204.172.110", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612254900056725597", - "out_order_no": "20260506122537425401156739", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778041549, - "payment_time": 1778041582, - "notify_time": 1778041582, - "client_ip": "10.196.90.217", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612252000056721268", - "out_order_no": "202605061225073399440116113", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778041520, - "payment_time": 1778041547, - "notify_time": 1778041548, - "client_ip": "114.103.14.216", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612243800056726962", - "out_order_no": "20260506122419186347737566", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778041478, - "payment_time": 1778041497, - "notify_time": 1778041497, - "client_ip": "114.236.70.189", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612230500056715591", - "out_order_no": "202605061223009899429671803", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778041385, - "payment_time": 1778041424, - "notify_time": 1778041425, - "client_ip": "183.7.175.134", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612222200056729000", - "out_order_no": "202605061222093329032026340", - "order_money": 315, - "user_money": 303.03, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778041342, - "payment_time": 1778041393, - "notify_time": 1778041393, - "client_ip": "39.144.85.36", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612215900056720390", - "out_order_no": "202605061221447331255743412", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778041319, - "payment_time": 1778041362, - "notify_time": 1778041362, - "client_ip": "149.34.251.246", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612173600056724205", - "out_order_no": "202605061217256745019452048", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778041056, - "payment_time": 1778041107, - "notify_time": 1778041107, - "client_ip": "112.12.244.102", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612110500056723031", - "out_order_no": "202605061210587209587227951", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778040665, - "payment_time": 1778040704, - "notify_time": 1778040704, - "client_ip": "124.127.221.73", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612045100056724446", - "out_order_no": "202605061204424529935012026", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778040291, - "payment_time": 1778040323, - "notify_time": 1778040323, - "client_ip": "27.14.6.162", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050612041800056723389", - "out_order_no": "202605061204009422100074776", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778040258, - "payment_time": null, - "notify_time": null, - "client_ip": "27.14.6.162", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611575200056717804", - "out_order_no": "202605061157365871684497390", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778039872, - "payment_time": 1778039911, - "notify_time": 1778039911, - "client_ip": "183.162.248.249", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611573100056718066", - "out_order_no": "202605061157052943000025071", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778039851, - "payment_time": 1778039874, - "notify_time": 1778039875, - "client_ip": "101.82.194.232", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611562100056721472", - "out_order_no": "202605061156109677402659974", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778039781, - "payment_time": 1778039849, - "notify_time": 1778039850, - "client_ip": "113.135.246.212", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611541200056721058", - "out_order_no": "202605061153573920602891176", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778039652, - "payment_time": 1778039680, - "notify_time": 1778039680, - "client_ip": "116.130.195.55", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611522100056720218", - "out_order_no": "20260506115213599881771665", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778039541, - "payment_time": 1778039577, - "notify_time": 1778039577, - "client_ip": "14.24.180.64", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611473400056721572", - "out_order_no": "2026050611472941644792959", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778039254, - "payment_time": 1778039272, - "notify_time": 1778039272, - "client_ip": "117.136.111.58", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611471400056718312", - "out_order_no": "202605061147036989943210159", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778039234, - "payment_time": 1778039255, - "notify_time": 1778039255, - "client_ip": "114.103.172.114", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611414900056710691", - "out_order_no": "20260506114133444083305049", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778038909, - "payment_time": 1778038937, - "notify_time": 1778038937, - "client_ip": "171.219.17.28", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611401400056712542", - "out_order_no": "202605061140047647916735050", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778038814, - "payment_time": 1778038833, - "notify_time": 1778038833, - "client_ip": "219.144.16.87", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611381400056719635", - "out_order_no": "202605061138055379708746421", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778038694, - "payment_time": 1778038722, - "notify_time": 1778038722, - "client_ip": "139.159.170.29", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611352000056721179", - "out_order_no": "202605061135056214899129867", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778038520, - "payment_time": 1778038550, - "notify_time": 1778038550, - "client_ip": "218.94.58.6", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611335900056719746", - "out_order_no": "202605061133426161325738025", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778038439, - "payment_time": 1778038465, - "notify_time": 1778038466, - "client_ip": "82.152.163.46", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611295300056713669", - "out_order_no": "20260506112944155884052402", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778038193, - "payment_time": 1778038218, - "notify_time": 1778038219, - "client_ip": "14.26.225.102", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611294900056721682", - "out_order_no": "202605061129369074507555793", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778038189, - "payment_time": 1778038230, - "notify_time": 1778038231, - "client_ip": "112.45.91.215", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611290100056711019", - "out_order_no": "20260506112856739443166517", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778038141, - "payment_time": 1778038160, - "notify_time": 1778038160, - "client_ip": "59.66.39.109", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611283600056728212", - "out_order_no": "202605061128268835627165734", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778038116, - "payment_time": null, - "notify_time": null, - "client_ip": "59.66.39.109", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611265700056720716", - "out_order_no": "202605061126454681290004539", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778038017, - "payment_time": 1778038043, - "notify_time": 1778038044, - "client_ip": "182.239.114.39", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611252900056714316", - "out_order_no": "202605061125237109873375870", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778037929, - "payment_time": 1778037966, - "notify_time": 1778037967, - "client_ip": "222.76.183.26", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611221800056729011", - "out_order_no": "202605061122067556995349680", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778037738, - "payment_time": 1778037776, - "notify_time": 1778037777, - "client_ip": "140.206.187.122", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611212000056714475", - "out_order_no": "202605061121072542002640169", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778037680, - "payment_time": 1778037702, - "notify_time": 1778037702, - "client_ip": "223.104.79.152", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611210500056729553", - "out_order_no": "202605061120394428693940023", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778037665, - "payment_time": 1778037700, - "notify_time": 1778037700, - "client_ip": "113.72.154.150", - "device": "qq", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611194600056718708", - "out_order_no": "202605061119347960122474659", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778037586, - "payment_time": 1778037613, - "notify_time": 1778037613, - "client_ip": "183.159.152.154", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611183900056727073", - "out_order_no": "202605061118263878499191008", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778037519, - "payment_time": null, - "notify_time": null, - "client_ip": "39.144.78.202", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611182600056718692", - "out_order_no": "20260506111814693814550984", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778037506, - "payment_time": 1778037639, - "notify_time": 1778037640, - "client_ip": "111.19.85.72", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611155100056726627", - "out_order_no": "202605061115449235304497299", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778037351, - "payment_time": 1778037377, - "notify_time": 1778037378, - "client_ip": "122.235.177.254", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611141100056712609", - "out_order_no": "202605061114055256499060990", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778037251, - "payment_time": 1778037267, - "notify_time": 1778037267, - "client_ip": "183.200.192.108", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611123400056787480", - "out_order_no": "202605061112161306152972480", - "order_money": 90.93, - "user_money": 0, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778037154, - "payment_time": null, - "notify_time": null, - "client_ip": "183.200.192.108", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611121700056710182", - "out_order_no": "202605061112082141919510598", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778037137, - "payment_time": 1778037161, - "notify_time": 1778037161, - "client_ip": "39.144.124.13", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611115300056721127", - "out_order_no": "202605061111453728977338724", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778037113, - "payment_time": 1778037145, - "notify_time": 1778037145, - "client_ip": "114.219.120.141", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611114100056719296", - "out_order_no": "202605061111313190549664987", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778037101, - "payment_time": 1778037172, - "notify_time": 1778037173, - "client_ip": "112.17.241.207", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611114100056724838", - "out_order_no": "202605061111294069700720572", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778037101, - "payment_time": null, - "notify_time": null, - "client_ip": "39.144.124.13", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611085000056727034", - "out_order_no": "202605061108434712441626389", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778036930, - "payment_time": 1778036959, - "notify_time": 1778036959, - "client_ip": "117.183.230.122", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611082900056716491", - "out_order_no": "202605061108167593985220830", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778036909, - "payment_time": 1778036963, - "notify_time": 1778036963, - "client_ip": "180.111.39.63", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611075200056723340", - "out_order_no": "202605061107446957407093782", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778036872, - "payment_time": 1778036888, - "notify_time": 1778036889, - "client_ip": "111.25.69.243", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611060400056713527", - "out_order_no": "202605061105553054471840938", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778036764, - "payment_time": 1778036801, - "notify_time": 1778036801, - "client_ip": "125.69.130.83", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611045000056726731", - "out_order_no": "20260506110421248128793547", - "order_money": 315, - "user_money": 303.03, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778036690, - "payment_time": null, - "notify_time": null, - "client_ip": "125.69.130.83", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050611001800056714872", - "out_order_no": "202605061100119518276995542", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778036418, - "payment_time": 1778036438, - "notify_time": 1778036439, - "client_ip": "140.206.187.122", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610593600056714008", - "out_order_no": "202605061059258720412948703", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778036376, - "payment_time": null, - "notify_time": null, - "client_ip": "14.127.7.238", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610590300056711367", - "out_order_no": "202605061058473525143425737", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778036343, - "payment_time": 1778036363, - "notify_time": 1778036364, - "client_ip": "60.255.152.26", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610553500056722729", - "out_order_no": "202605061055158820166485840", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778036135, - "payment_time": 1778036255, - "notify_time": 1778036255, - "client_ip": "183.210.24.15", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610553000056722629", - "out_order_no": "202605061055238923072615460", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778036130, - "payment_time": 1778036193, - "notify_time": 1778036194, - "client_ip": "183.69.134.114", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610545200056728908", - "out_order_no": "202605061054424960712824097", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778036092, - "payment_time": 1778036108, - "notify_time": 1778036108, - "client_ip": "125.71.54.185", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610540000056726960", - "out_order_no": "20260506105342539963500366", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778036040, - "payment_time": 1778036062, - "notify_time": 1778036063, - "client_ip": "36.28.208.6", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610534300056725789", - "out_order_no": "202605061053278034749379429", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778036023, - "payment_time": 1778036071, - "notify_time": 1778036071, - "client_ip": "35.215.171.43", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610511000056713207", - "out_order_no": "202605061050564456341685773", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778035870, - "payment_time": 1778035891, - "notify_time": 1778035891, - "client_ip": "36.44.99.117", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610470200056729698", - "out_order_no": "20260506104656144920046809", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778035622, - "payment_time": 1778035637, - "notify_time": 1778035637, - "client_ip": "113.200.174.75", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610373200056727603", - "out_order_no": "20260506103722813812636281", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778035052, - "payment_time": 1778035086, - "notify_time": 1778035086, - "client_ip": "49.90.36.88", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610361800056725924", - "out_order_no": "202605061036131961658894943", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778034978, - "payment_time": 1778034997, - "notify_time": 1778034997, - "client_ip": "111.73.17.108", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610341800056714782", - "out_order_no": "202605061034109606736135126", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778034858, - "payment_time": 1778034877, - "notify_time": 1778034878, - "client_ip": "113.77.43.77", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610330000056720886", - "out_order_no": "202605061032504800224564326", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778034780, - "payment_time": 1778034798, - "notify_time": 1778034798, - "client_ip": "36.33.4.13", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610291500056718380", - "out_order_no": "202605061029029124585419138", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778034555, - "payment_time": 1778034576, - "notify_time": 1778034577, - "client_ip": "223.104.211.105", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610270400056712986", - "out_order_no": "202605061026535979125349224", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778034424, - "payment_time": 1778034448, - "notify_time": 1778034448, - "client_ip": "140.206.187.122", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610265100056715503", - "out_order_no": "202605061026373170411285112", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778034411, - "payment_time": 1778034447, - "notify_time": 1778034448, - "client_ip": "220.196.193.105", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610235600056722063", - "out_order_no": "202605061023415399329436552", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778034236, - "payment_time": 1778034275, - "notify_time": 1778034276, - "client_ip": "184.151.190.59", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610225300056726097", - "out_order_no": "202605061022421350546149851", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778034173, - "payment_time": null, - "notify_time": null, - "client_ip": "60.1.174.173", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610200500056726859", - "out_order_no": "202605061019526093250750877", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778034005, - "payment_time": 1778034038, - "notify_time": 1778034098, - "client_ip": "125.34.22.31", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610195600056727828", - "out_order_no": "202605061019478412357694149", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778033996, - "payment_time": 1778034016, - "notify_time": 1778034017, - "client_ip": "42.6.88.125", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610163500056722423", - "out_order_no": "202605061016183812787915158", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778033795, - "payment_time": 1778033826, - "notify_time": 1778033826, - "client_ip": "120.244.214.70", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610123600056715492", - "out_order_no": "202605061012276171793585475", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778033556, - "payment_time": 1778033585, - "notify_time": 1778033585, - "client_ip": "140.206.187.122", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610105500056729904", - "out_order_no": "202605061010391990134634616", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778033455, - "payment_time": 1778033483, - "notify_time": 1778033483, - "client_ip": "39.144.157.14", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610064200056710463", - "out_order_no": "202605061006371556122262830", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778033202, - "payment_time": 1778033235, - "notify_time": 1778033235, - "client_ip": "183.130.205.180", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610060600056710536", - "out_order_no": "20260506100555710777566794", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778033166, - "payment_time": null, - "notify_time": null, - "client_ip": "183.130.205.180", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610022100056725511", - "out_order_no": "202605061002107855327739553", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778032941, - "payment_time": 1778032971, - "notify_time": 1778032972, - "client_ip": "218.12.21.120", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610020000056782602", - "out_order_no": "202605061001471745140218158", - "order_money": 19.53, - "user_money": 0, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778032920, - "payment_time": null, - "notify_time": null, - "client_ip": "36.47.128.17", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050610000500056716969", - "out_order_no": "202605060959477090887151997", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778032805, - "payment_time": 1778032844, - "notify_time": 1778032844, - "client_ip": "111.174.231.82", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609590600056711177", - "out_order_no": "202605060958489027942232453", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778032746, - "payment_time": 1778032771, - "notify_time": 1778032772, - "client_ip": "36.4.59.28", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609544300056723519", - "out_order_no": "202605060954341327166007820", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778032483, - "payment_time": 1778032509, - "notify_time": 1778032509, - "client_ip": "120.208.105.235", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609524800056729474", - "out_order_no": "20260506095236586079955229", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778032368, - "payment_time": 1778032385, - "notify_time": 1778032385, - "client_ip": "125.67.191.57", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609511800056712991", - "out_order_no": "202605060951124900055612944", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778032278, - "payment_time": 1778032299, - "notify_time": 1778032300, - "client_ip": "112.25.223.101", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609503300056729760", - "out_order_no": "202605060950254755953192187", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778032233, - "payment_time": 1778032262, - "notify_time": 1778032262, - "client_ip": "183.202.131.158", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609442600056713628", - "out_order_no": "202605060944148435104800643", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778031866, - "payment_time": null, - "notify_time": null, - "client_ip": "39.144.124.59", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609431800056719514", - "out_order_no": "202605060943085700774986522", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778031798, - "payment_time": 1778031819, - "notify_time": 1778031819, - "client_ip": "118.119.171.21", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609413000056719735", - "out_order_no": "202605060939378809428861353", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778031690, - "payment_time": null, - "notify_time": null, - "client_ip": "183.224.187.85", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609410200056717869", - "out_order_no": "202605060940373960171233438", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778031662, - "payment_time": 1778031683, - "notify_time": 1778031683, - "client_ip": "27.128.32.182", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609374300056717320", - "out_order_no": "202605060936467319824164313", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778031463, - "payment_time": 1778031485, - "notify_time": 1778031486, - "client_ip": "182.150.28.74", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609363400056718269", - "out_order_no": "202605060936104539041461856", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778031394, - "payment_time": null, - "notify_time": null, - "client_ip": "111.33.200.119", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609342300056722696", - "out_order_no": "202605060934189413313563838", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778031263, - "payment_time": 1778031292, - "notify_time": 1778031293, - "client_ip": "116.149.125.212", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609335200056717541", - "out_order_no": "202605060933435839026330919", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778031232, - "payment_time": 1778031254, - "notify_time": 1778031254, - "client_ip": "182.204.4.174", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609335200056728210", - "out_order_no": "202605060933459016879509345", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778031232, - "payment_time": null, - "notify_time": null, - "client_ip": "116.149.125.212", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609232900056722294", - "out_order_no": "202605060923144842767349079", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778030609, - "payment_time": 1778030644, - "notify_time": 1778030645, - "client_ip": "171.217.183.224", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609232500056728554", - "out_order_no": "202605060923174122161564087", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778030605, - "payment_time": 1778030641, - "notify_time": 1778030641, - "client_ip": "39.130.58.138", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609225300056722664", - "out_order_no": "202605060922476101027633493", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778030573, - "payment_time": 1778030587, - "notify_time": 1778030588, - "client_ip": "120.225.101.75", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609215100056719738", - "out_order_no": "202605060921281387153938531", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778030511, - "payment_time": null, - "notify_time": null, - "client_ip": "39.130.58.138", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609172400056728466", - "out_order_no": "202605060917162651128655185", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778030244, - "payment_time": null, - "notify_time": null, - "client_ip": "111.25.69.243", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609124100056720316", - "out_order_no": "202605060912281101583130897", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778029961, - "payment_time": 1778029989, - "notify_time": 1778029989, - "client_ip": "223.82.15.226", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609091500056727225", - "out_order_no": "202605060909012406293714385", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778029755, - "payment_time": null, - "notify_time": null, - "client_ip": "39.158.33.134", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609091400056717725", - "out_order_no": "202605060908543568922041650", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778029754, - "payment_time": 1778029798, - "notify_time": 1778029799, - "client_ip": "152.228.228.62", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609063600056719981", - "out_order_no": "202605060906246068266888734", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778029596, - "payment_time": 1778029632, - "notify_time": 1778029632, - "client_ip": "182.239.115.69", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050609021000056729833", - "out_order_no": "202605060902044048000877843", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778029330, - "payment_time": 1778029367, - "notify_time": 1778029368, - "client_ip": "219.129.234.209", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608585600056711704", - "out_order_no": "202605060858489588533136886", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778029136, - "payment_time": 1778029162, - "notify_time": 1778029162, - "client_ip": "112.5.57.122", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608582600056726434", - "out_order_no": "202605060858177359981466974", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778029106, - "payment_time": null, - "notify_time": null, - "client_ip": "219.129.234.209", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608555900056719913", - "out_order_no": "202605060855443661552355272", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778028959, - "payment_time": 1778028977, - "notify_time": 1778028977, - "client_ip": "101.87.224.222", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608513500056716550", - "out_order_no": "202605060851108741042261457", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778028695, - "payment_time": 1778028716, - "notify_time": 1778028716, - "client_ip": "180.138.230.157", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608505000056710916", - "out_order_no": "202605060850375448754399761", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778028650, - "payment_time": 1778028682, - "notify_time": 1778028682, - "client_ip": "14.31.226.119", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608482100056725599", - "out_order_no": "202605060848159572944912815", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778028501, - "payment_time": 1778028529, - "notify_time": 1778028529, - "client_ip": "106.44.60.6", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608473300056710554", - "out_order_no": "202605060847203698507122598", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778028453, - "payment_time": 1778028484, - "notify_time": 1778028484, - "client_ip": "39.162.91.50", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608464100056714892", - "out_order_no": "202605060846276319760669534", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778028401, - "payment_time": 1778028426, - "notify_time": 1778028426, - "client_ip": "112.41.110.220", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608463000056717310", - "out_order_no": "202605060846182740841260054", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778028390, - "payment_time": 1778028407, - "notify_time": 1778028407, - "client_ip": "42.84.232.98", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608420700056714210", - "out_order_no": "202605060841548864893716177", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778028127, - "payment_time": 1778028148, - "notify_time": 1778028149, - "client_ip": "114.86.101.140", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608395800056729185", - "out_order_no": "202605060839454305996962051", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778027998, - "payment_time": 1778028076, - "notify_time": 1778028077, - "client_ip": "27.210.76.46", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608382600056717027", - "out_order_no": "202605060838173242988750115", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778027906, - "payment_time": 1778027931, - "notify_time": 1778027931, - "client_ip": "117.154.84.238", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608352500056714561", - "out_order_no": "202605060835134673286079863", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778027725, - "payment_time": 1778027745, - "notify_time": 1778027745, - "client_ip": "110.251.155.249", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608342300056723540", - "out_order_no": "202605060834177168004469593", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778027663, - "payment_time": 1778027703, - "notify_time": 1778027703, - "client_ip": "1.192.36.121", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608305300056713129", - "out_order_no": "202605060830352900493928961", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778027453, - "payment_time": 1778027480, - "notify_time": 1778027481, - "client_ip": "121.225.130.18", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608284900056721121", - "out_order_no": "202605060828382156060163482", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778027329, - "payment_time": 1778027357, - "notify_time": 1778027357, - "client_ip": "112.97.171.181", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608063900056717831", - "out_order_no": "202605060806148167706686261", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778025999, - "payment_time": 1778026032, - "notify_time": 1778026033, - "client_ip": "114.227.147.89", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608052400056710094", - "out_order_no": "202605060805083774197802884", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778025924, - "payment_time": 1778025955, - "notify_time": 1778025955, - "client_ip": "120.32.222.104", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608025200056712357", - "out_order_no": "202605060802367140178320559", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778025772, - "payment_time": 1778025800, - "notify_time": 1778025801, - "client_ip": "222.212.236.187", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050608012600056726909", - "out_order_no": "202605060801038935431337478", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778025686, - "payment_time": 1778025718, - "notify_time": 1778025718, - "client_ip": "171.108.87.76", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607562800056721957", - "out_order_no": "20260506075609932221037519", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778025388, - "payment_time": 1778025421, - "notify_time": 1778025422, - "client_ip": "101.90.6.162", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607471500056722194", - "out_order_no": "202605060747006935730019538", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778024835, - "payment_time": 1778024892, - "notify_time": 1778024892, - "client_ip": "218.200.28.210", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607453900056724495", - "out_order_no": "202605060745224550245055467", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778024739, - "payment_time": 1778024762, - "notify_time": 1778024763, - "client_ip": "110.19.191.3", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607445000056716043", - "out_order_no": "202605060744337287601409459", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778024690, - "payment_time": 1778024715, - "notify_time": 1778024715, - "client_ip": "39.144.177.241", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607395600056717719", - "out_order_no": "202605060739454833033387589", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778024396, - "payment_time": 1778024419, - "notify_time": 1778024419, - "client_ip": "119.123.33.251", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607354600056711188", - "out_order_no": "202605060735381571319831118", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778024146, - "payment_time": 1778024165, - "notify_time": 1778024165, - "client_ip": "118.121.67.32", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607341500056711974", - "out_order_no": "202605060734068477149473543", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778024055, - "payment_time": 1778024078, - "notify_time": 1778024078, - "client_ip": "114.217.72.141", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607292000056714255", - "out_order_no": "202605060729068652078292916", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778023760, - "payment_time": 1778023786, - "notify_time": 1778023787, - "client_ip": "110.156.240.19", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607124000056715931", - "out_order_no": "202605060712288521859016659", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778022760, - "payment_time": 1778022781, - "notify_time": 1778022781, - "client_ip": "117.70.191.42", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607102400056724783", - "out_order_no": "202605060710171604195005304", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778022624, - "payment_time": 1778022663, - "notify_time": 1778022663, - "client_ip": "120.229.225.207", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607084800056726062", - "out_order_no": "202605060708431940696098394", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778022528, - "payment_time": 1778022595, - "notify_time": 1778022596, - "client_ip": "124.90.94.61", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607082200056714756", - "out_order_no": "202605060708125268941706116", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778022502, - "payment_time": null, - "notify_time": null, - "client_ip": "118.121.67.32", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050607075600056717787", - "out_order_no": "202605060707185967059175641", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778022476, - "payment_time": null, - "notify_time": null, - "client_ip": "42.226.119.155", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050606591400056712512", - "out_order_no": "202605060659072390362936151", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778021954, - "payment_time": 1778021972, - "notify_time": 1778021972, - "client_ip": "183.92.136.11", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050606585000056721968", - "out_order_no": "202605060658402766506199290", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778021930, - "payment_time": null, - "notify_time": null, - "client_ip": "183.92.136.11", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050606555400056724408", - "out_order_no": "202605060655339437979573447", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778021754, - "payment_time": 1778021799, - "notify_time": 1778021800, - "client_ip": "183.228.138.140", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050606403400056726128", - "out_order_no": "202605060640221635003238897", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778020834, - "payment_time": 1778020847, - "notify_time": 1778020847, - "client_ip": "61.170.152.190", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050606371400056716931", - "out_order_no": "202605060637074364701903229", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778020634, - "payment_time": 1778020679, - "notify_time": 1778020679, - "client_ip": "115.201.72.14", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050606335800056722443", - "out_order_no": "20260506063346988981542347", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778020438, - "payment_time": 1778020465, - "notify_time": 1778020465, - "client_ip": "112.22.142.161", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050606281100056711406", - "out_order_no": "202605060628003624364231272", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778020091, - "payment_time": 1778020135, - "notify_time": 1778020135, - "client_ip": "114.249.61.209", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050606223000056720638", - "out_order_no": "202605060622174563677139280", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778019750, - "payment_time": 1778019799, - "notify_time": 1778019799, - "client_ip": "1.203.85.198", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050606220600056723131", - "out_order_no": "202605060621555424601694753", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "full_refund", - "notify_status": "notify_success", - "create_time": 1778019726, - "payment_time": 1778019767, - "notify_time": 1778019767, - "client_ip": "114.219.228.122", - "device": "mobile", - "order_remark": "退款成功", - "refund_amount": 19.53, - "refund_time": 1778019883 - }, - { - "order_no": "2026050606163100056722333", - "out_order_no": "202605060616196035205385333", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778019391, - "payment_time": 1778019420, - "notify_time": 1778019421, - "client_ip": "120.204.162.162", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050606104700056715517", - "out_order_no": "20260506061038640283545222", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778019047, - "payment_time": 1778019072, - "notify_time": 1778019072, - "client_ip": "112.115.29.39", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050606084200056725481", - "out_order_no": "202605060608365743284331492", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "full_refund", - "notify_status": "notify_success", - "create_time": 1778018923, - "payment_time": 1778018950, - "notify_time": 1778018951, - "client_ip": "114.219.228.122", - "device": "mobile", - "order_remark": "退款成功", - "refund_amount": 19.53, - "refund_time": 1778019629 - }, - { - "order_no": "2026050605584900056727158", - "out_order_no": "202605060558404492046295703", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778018330, - "payment_time": 1778018363, - "notify_time": 1778018364, - "client_ip": "27.148.116.201", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050605570800056720867", - "out_order_no": "202605060556547717597593220", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778018228, - "payment_time": null, - "notify_time": null, - "client_ip": "171.91.68.209", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050605551800056726108", - "out_order_no": "2026050605551140311941522", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778018118, - "payment_time": 1778018149, - "notify_time": 1778018150, - "client_ip": "114.135.138.123", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050605545400056724134", - "out_order_no": "202605060554439289580771029", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778018094, - "payment_time": null, - "notify_time": null, - "client_ip": "171.91.68.209", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050605531600056724343", - "out_order_no": "202605060553072979125641813", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778017996, - "payment_time": null, - "notify_time": null, - "client_ip": "114.135.138.123", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050605525300056712376", - "out_order_no": "202605060552419299665983528", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778017973, - "payment_time": 1778017995, - "notify_time": 1778017995, - "client_ip": "111.30.251.182", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050605511500056712287", - "out_order_no": "202605060550547454032673306", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778017875, - "payment_time": null, - "notify_time": null, - "client_ip": "111.30.251.182", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050605453000056728156", - "out_order_no": "202605060545228270998282265", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778017530, - "payment_time": 1778017564, - "notify_time": 1778017565, - "client_ip": "120.231.64.112", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050605402100056725549", - "out_order_no": "202605060540132285160947178", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778017221, - "payment_time": 1778017260, - "notify_time": 1778017260, - "client_ip": "14.153.0.212", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050605352900056725316", - "out_order_no": "202605060535126943252263474", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778016930, - "payment_time": 1778016970, - "notify_time": 1778016970, - "client_ip": "10.197.168.109", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050605292200056723500", - "out_order_no": "202605060529124140002750626", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778016562, - "payment_time": 1778016588, - "notify_time": 1778016588, - "client_ip": "61.149.93.141", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050605281900056711833", - "out_order_no": "202605060528099881169203095", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778016499, - "payment_time": 1778016518, - "notify_time": 1778016518, - "client_ip": "27.38.200.52", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604500000056721220", - "out_order_no": "202605060449517231080384692", - "order_money": 315, - "user_money": 303.03, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778014200, - "payment_time": 1778014223, - "notify_time": 1778014223, - "client_ip": "39.174.18.182", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604350500056719086", - "out_order_no": "202605060434563908007506469", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778013305, - "payment_time": 1778013331, - "notify_time": 1778013331, - "client_ip": "113.84.210.119", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604265600056712472", - "out_order_no": "202605060426483855323899181", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778012816, - "payment_time": 1778012837, - "notify_time": 1778012838, - "client_ip": "120.226.108.252", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604264500056719788", - "out_order_no": "20260506042633963827335562", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778012805, - "payment_time": 1778012836, - "notify_time": 1778012836, - "client_ip": "58.247.23.234", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604190000056713288", - "out_order_no": "202605060418507927761663334", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778012340, - "payment_time": 1778012364, - "notify_time": 1778012364, - "client_ip": "111.192.97.149", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604170400056728567", - "out_order_no": "20260506041652636234922724", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778012224, - "payment_time": 1778012268, - "notify_time": 1778012269, - "client_ip": "42.84.232.108", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604163400056717885", - "out_order_no": "202605060416217501938092178", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778012194, - "payment_time": 1778012221, - "notify_time": 1778012222, - "client_ip": "106.88.88.169", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604065200056722722", - "out_order_no": "202605060404517874346958372", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778011612, - "payment_time": 1778011631, - "notify_time": 1778011632, - "client_ip": "58.42.163.125", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604061000056725918", - "out_order_no": "20260506040545741303253496", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778011570, - "payment_time": null, - "notify_time": null, - "client_ip": "120.239.147.13", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604044200056727789", - "out_order_no": "202605060404332855209050267", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778011482, - "payment_time": null, - "notify_time": null, - "client_ip": "58.42.163.125", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604011900056710835", - "out_order_no": "202605060401067760749485834", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778011279, - "payment_time": null, - "notify_time": null, - "client_ip": "223.73.51.149", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604005200056720363", - "out_order_no": "202605060400378933101361633", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778011252, - "payment_time": 1778011279, - "notify_time": 1778011280, - "client_ip": "117.136.101.176", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050604003200056729036", - "out_order_no": "202605060400256721923882421", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778011232, - "payment_time": 1778011261, - "notify_time": 1778011261, - "client_ip": "117.150.250.56", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603562600056722159", - "out_order_no": "202605060356051363927161412", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778010986, - "payment_time": 1778011017, - "notify_time": 1778011017, - "client_ip": "36.101.147.108", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603551100056715979", - "out_order_no": "202605060355045442843497085", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778010911, - "payment_time": 1778010936, - "notify_time": 1778010936, - "client_ip": "8.218.95.81", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603542300056712812", - "out_order_no": "202605060354164422929939504", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778010863, - "payment_time": 1778010885, - "notify_time": 1778010886, - "client_ip": "10.217.158.65", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603481500056727263", - "out_order_no": "20260506034804449623863656", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778010495, - "payment_time": 1778010520, - "notify_time": 1778010520, - "client_ip": "118.74.207.125", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603414600056723424", - "out_order_no": "202605060341356065354759970", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778010106, - "payment_time": 1778010132, - "notify_time": 1778010133, - "client_ip": "223.198.62.156", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603404100056722951", - "out_order_no": "202605060340322021819576191", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778010041, - "payment_time": 1778010071, - "notify_time": 1778010071, - "client_ip": "112.20.64.60", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603323600056725226", - "out_order_no": "202605060332051452713976058", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778009556, - "payment_time": 1778009591, - "notify_time": 1778009591, - "client_ip": "39.144.89.14", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603261500056726482", - "out_order_no": "202605060326058289973466829", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778009175, - "payment_time": 1778009214, - "notify_time": 1778009214, - "client_ip": "39.148.116.149", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603211500056714144", - "out_order_no": "202605060321071294178387152", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778008875, - "payment_time": 1778008901, - "notify_time": 1778008902, - "client_ip": "180.139.212.7", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603181900056710369", - "out_order_no": "202605060318122265999831604", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778008699, - "payment_time": 1778008745, - "notify_time": 1778008745, - "client_ip": "36.112.194.102", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603174100056783469", - "out_order_no": "202605060317336203975530978", - "order_money": 315, - "user_money": 0, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778008661, - "payment_time": null, - "notify_time": null, - "client_ip": "182.239.114.39", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603140800056716201", - "out_order_no": "202605060313408674155706479", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778008448, - "payment_time": 1778008467, - "notify_time": 1778008467, - "client_ip": "39.187.218.162", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603135400056714306", - "out_order_no": "202605060313459428596275744", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778008434, - "payment_time": 1778008476, - "notify_time": 1778008476, - "client_ip": "27.154.71.199", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603134000056726360", - "out_order_no": "202605060313311499074365697", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778008420, - "payment_time": 1778008452, - "notify_time": 1778008452, - "client_ip": "118.73.60.229", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603063500056728219", - "out_order_no": "202605060306296198762124390", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778007995, - "payment_time": 1778008019, - "notify_time": 1778008019, - "client_ip": "58.241.119.217", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603055200056724237", - "out_order_no": "202605060305384797438281491", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778007952, - "payment_time": 1778007999, - "notify_time": 1778007999, - "client_ip": "123.156.214.5", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603045300056727939", - "out_order_no": "20260506030444763469334587", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778007893, - "payment_time": 1778007926, - "notify_time": 1778007926, - "client_ip": "14.24.243.155", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050603044400056716489", - "out_order_no": "202605060304353873018472336", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778007884, - "payment_time": 1778007916, - "notify_time": 1778007917, - "client_ip": "112.10.195.2", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602590000056725023", - "out_order_no": "202605060258538620856525797", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778007540, - "payment_time": 1778007574, - "notify_time": 1778007574, - "client_ip": "116.162.235.194", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602482800056724767", - "out_order_no": "202605060248037365227030815", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778006908, - "payment_time": 1778006955, - "notify_time": 1778006955, - "client_ip": "183.42.162.121", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602463500056727860", - "out_order_no": "202605060246286095013016936", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778006795, - "payment_time": 1778006830, - "notify_time": 1778006830, - "client_ip": "223.160.219.79", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602463000056715397", - "out_order_no": "202605060246154947543134289", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778006790, - "payment_time": 1778006827, - "notify_time": 1778006828, - "client_ip": "125.111.223.20", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602440600056720794", - "out_order_no": "202605060243574811841940669", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778006646, - "payment_time": 1778006678, - "notify_time": 1778006679, - "client_ip": "183.247.6.102", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602435200056719480", - "out_order_no": "202605060243458991204226830", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778006632, - "payment_time": 1778006656, - "notify_time": 1778006656, - "client_ip": "223.160.224.186", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602381500056723391", - "out_order_no": "202605060237521388982180677", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778006295, - "payment_time": null, - "notify_time": null, - "client_ip": "49.112.162.238", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602365500056726200", - "out_order_no": "202605060236431803259829769", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778006215, - "payment_time": 1778006273, - "notify_time": 1778006273, - "client_ip": "114.97.160.241", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602282100056729930", - "out_order_no": "202605060228143137116595934", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778005701, - "payment_time": 1778005729, - "notify_time": 1778005730, - "client_ip": "114.88.23.79", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602280000056723317", - "out_order_no": "202605060227489551539275756", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778005680, - "payment_time": null, - "notify_time": null, - "client_ip": "114.88.23.79", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602261500056728344", - "out_order_no": "202605060226047656204256762", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778005575, - "payment_time": 1778005594, - "notify_time": 1778005595, - "client_ip": "117.24.136.226", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602241700056728373", - "out_order_no": "202605060224095694781439642", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778005457, - "payment_time": 1778005502, - "notify_time": 1778005503, - "client_ip": "222.76.115.139", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602224100056724656", - "out_order_no": "202605060222317561682574807", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778005361, - "payment_time": 1778005393, - "notify_time": 1778005393, - "client_ip": "221.7.7.225", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602221800056713911", - "out_order_no": "202605060222109674292232049", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778005338, - "payment_time": 1778005364, - "notify_time": 1778005365, - "client_ip": "27.42.97.24", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602205600056710643", - "out_order_no": "202605060220485078125121362", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778005256, - "payment_time": 1778005275, - "notify_time": 1778005275, - "client_ip": "106.8.228.108", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602195100056715965", - "out_order_no": "202605060219349787221301645", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778005191, - "payment_time": 1778005218, - "notify_time": 1778005218, - "client_ip": "223.152.92.116", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602170600056711942", - "out_order_no": "202605060216184791443924880", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778005026, - "payment_time": 1778005044, - "notify_time": 1778005045, - "client_ip": "125.85.126.187", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602164000056728735", - "out_order_no": "2026050602163440110436231", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778005000, - "payment_time": null, - "notify_time": null, - "client_ip": "106.33.183.28", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602163900056721734", - "out_order_no": "202605060216248696627938915", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778004999, - "payment_time": null, - "notify_time": null, - "client_ip": "113.69.32.36", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602153500056715496", - "out_order_no": "202605060214465832088199203", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778004935, - "payment_time": 1778004954, - "notify_time": 1778004955, - "client_ip": "112.112.67.204", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602134000056710566", - "out_order_no": "202605060213217395384140001", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778004820, - "payment_time": 1778004852, - "notify_time": 1778004852, - "client_ip": "39.130.106.27", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602090800056721951", - "out_order_no": "202605060209009350856108723", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778004548, - "payment_time": 1778004572, - "notify_time": 1778004573, - "client_ip": "171.213.252.15", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602075300056721345", - "out_order_no": "202605060207352498387718615", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778004473, - "payment_time": 1778004521, - "notify_time": 1778004522, - "client_ip": "115.149.100.247", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602070800056729534", - "out_order_no": "202605060207033316040674163", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778004428, - "payment_time": 1778004461, - "notify_time": 1778004461, - "client_ip": "123.170.54.23", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602070600056711081", - "out_order_no": "202605060206454001345684011", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778004426, - "payment_time": 1778004451, - "notify_time": 1778004451, - "client_ip": "112.96.52.138", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602065400056714994", - "out_order_no": "202605060206467182326016612", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778004414, - "payment_time": 1778004438, - "notify_time": 1778004438, - "client_ip": "14.154.193.59", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602063800056712970", - "out_order_no": "202605060206321067114774800", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778004398, - "payment_time": 1778004418, - "notify_time": 1778004419, - "client_ip": "39.90.11.161", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050602034300056725236", - "out_order_no": "202605060203217241832279672", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778004223, - "payment_time": 1778004268, - "notify_time": 1778004268, - "client_ip": "111.29.183.24", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601591600056712385", - "out_order_no": "202605060159055295963335368", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778003956, - "payment_time": 1778004008, - "notify_time": 1778004009, - "client_ip": "113.58.244.118", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601572700056728431", - "out_order_no": "20260506015715529692181294", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778003847, - "payment_time": 1778003882, - "notify_time": 1778003883, - "client_ip": "175.167.155.86", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601570600056714597", - "out_order_no": "202605060156574259689303938", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778003826, - "payment_time": 1778003855, - "notify_time": 1778003855, - "client_ip": "14.24.225.184", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601531300056718105", - "out_order_no": "202605060153006137746022967", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778003593, - "payment_time": 1778003620, - "notify_time": 1778003620, - "client_ip": "36.152.249.86", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601513900056727298", - "out_order_no": "202605060151306581720359978", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778003499, - "payment_time": 1778003545, - "notify_time": 1778003545, - "client_ip": "1.196.172.243", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601483000056721985", - "out_order_no": "202605060148201280122809726", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778003310, - "payment_time": 1778003328, - "notify_time": 1778003329, - "client_ip": "120.231.214.156", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601465000056711474", - "out_order_no": "202605060146392949400245299", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778003210, - "payment_time": 1778003237, - "notify_time": 1778003238, - "client_ip": "119.123.134.37", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601461900056719130", - "out_order_no": "202605060146034026783314052", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778003179, - "payment_time": 1778003218, - "notify_time": 1778003218, - "client_ip": "74.112.101.194", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601443100056726356", - "out_order_no": "202605060144125863916725487", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778003071, - "payment_time": 1778003099, - "notify_time": 1778003099, - "client_ip": "39.144.250.241", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601431200056721341", - "out_order_no": "202605060143038165058091868", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778002992, - "payment_time": 1778003022, - "notify_time": 1778003023, - "client_ip": "183.195.54.100", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601415100056715699", - "out_order_no": "202605060141373110776039203", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778002911, - "payment_time": 1778003034, - "notify_time": 1778003034, - "client_ip": "111.25.33.232", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601403400056711829", - "out_order_no": "20260506014025457120147376", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778002834, - "payment_time": 1778002859, - "notify_time": 1778002859, - "client_ip": "101.207.200.18", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601391600056727544", - "out_order_no": "202605060138444707621596776", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778002756, - "payment_time": 1778002812, - "notify_time": 1778002813, - "client_ip": "149.34.251.243", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601372400056727253", - "out_order_no": "202605060137147183931999330", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778002644, - "payment_time": 1778002687, - "notify_time": 1778002687, - "client_ip": "117.30.54.164", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601370800056714356", - "out_order_no": "202605060137021488126073260", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778002628, - "payment_time": 1778002645, - "notify_time": 1778002647, - "client_ip": "112.97.83.75", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601370500056722342", - "out_order_no": "202605060136549464697372584", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778002625, - "payment_time": 1778002640, - "notify_time": 1778002640, - "client_ip": "112.86.115.202", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601360900056716649", - "out_order_no": "202605060135527931571104122", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778002569, - "payment_time": null, - "notify_time": null, - "client_ip": "112.97.83.75", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601330600056720599", - "out_order_no": "20260506013254826706533504", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778002386, - "payment_time": null, - "notify_time": null, - "client_ip": "111.29.183.24", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601312700056717737", - "out_order_no": "202605060131154941477770900", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778002287, - "payment_time": 1778002316, - "notify_time": 1778002317, - "client_ip": "223.160.123.101", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601300600056721146", - "out_order_no": "202605060129589375395276505", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778002206, - "payment_time": null, - "notify_time": null, - "client_ip": "124.64.22.177", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601274900056714140", - "out_order_no": "202605060127351678653834656", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778002069, - "payment_time": 1778002123, - "notify_time": 1778002123, - "client_ip": "39.144.190.51", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601270100056722183", - "out_order_no": "202605060126397001754953119", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778002021, - "payment_time": 1778002087, - "notify_time": 1778002087, - "client_ip": "205.147.22.15", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601265900056717216", - "out_order_no": "202605060126535059126225078", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778002019, - "payment_time": 1778002048, - "notify_time": 1778002048, - "client_ip": "116.252.107.119", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601261500056729479", - "out_order_no": "202605060125595259742814299", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001975, - "payment_time": 1778002006, - "notify_time": 1778002006, - "client_ip": "117.24.128.27", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601235600056729705", - "out_order_no": "202605060123278789592580809", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001836, - "payment_time": 1778001884, - "notify_time": 1778001884, - "client_ip": "106.58.26.207", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601233000056715133", - "out_order_no": "2026050601231794259385337", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001810, - "payment_time": 1778001835, - "notify_time": 1778001836, - "client_ip": "39.130.122.22", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601185800056728390", - "out_order_no": "202605060118359355838020490", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001538, - "payment_time": 1778001571, - "notify_time": 1778001572, - "client_ip": "27.23.194.116", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601180400056722269", - "out_order_no": "202605060117554080998125144", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001484, - "payment_time": 1778001500, - "notify_time": 1778001500, - "client_ip": "106.224.188.226", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601151800056726961", - "out_order_no": "202605060114446635382738563", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001318, - "payment_time": 1778001350, - "notify_time": 1778001350, - "client_ip": "157.0.23.65", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601123200056713465", - "out_order_no": "202605060112157579041810792", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001152, - "payment_time": 1778001176, - "notify_time": 1778001176, - "client_ip": "111.183.103.44", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601114600056725334", - "out_order_no": "202605060111362283254561377", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001106, - "payment_time": 1778001132, - "notify_time": 1778001133, - "client_ip": "111.1.97.9", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601110700056727622", - "out_order_no": "202605060110494537138504586", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778001067, - "payment_time": null, - "notify_time": null, - "client_ip": "223.160.236.203", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601110400056721942", - "out_order_no": "202605060110546033036771078", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001064, - "payment_time": 1778001095, - "notify_time": 1778001095, - "client_ip": "58.101.34.242", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601104500056717471", - "out_order_no": "202605060110328684280331736", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001045, - "payment_time": 1778001065, - "notify_time": 1778001066, - "client_ip": "49.112.227.65", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601103200056719797", - "out_order_no": "202605060110234302519169514", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001032, - "payment_time": 1778001057, - "notify_time": 1778001058, - "client_ip": "183.142.198.241", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601101100056728928", - "out_order_no": "202605060110007813284771401", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778001011, - "payment_time": null, - "notify_time": null, - "client_ip": "183.142.198.241", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601100700056728683", - "out_order_no": "202605060109524040229809322", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778001007, - "payment_time": 1778001052, - "notify_time": 1778001052, - "client_ip": "223.153.237.231", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601093000056714744", - "out_order_no": "202605060109229109717447117", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000970, - "payment_time": 1778001032, - "notify_time": 1778001032, - "client_ip": "223.160.223.210", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601072400056725659", - "out_order_no": "202605060107142407977262720", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000844, - "payment_time": 1778000860, - "notify_time": 1778000860, - "client_ip": "1.196.172.243", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601070400056712768", - "out_order_no": "202605060106591632506391384", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000824, - "payment_time": 1778000857, - "notify_time": 1778000857, - "client_ip": "125.94.22.131", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601065500056716272", - "out_order_no": "202605060106456716778244955", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000815, - "payment_time": 1778000910, - "notify_time": 1778000910, - "client_ip": "60.161.136.38", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601065400056728921", - "out_order_no": "20260506010642572451352966", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000814, - "payment_time": 1778000861, - "notify_time": 1778000861, - "client_ip": "103.170.26.42", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601042700056725543", - "out_order_no": "202605060104233238244908969", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000667, - "payment_time": 1778000692, - "notify_time": 1778000692, - "client_ip": "114.100.142.203", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601040600056719943", - "out_order_no": "202605060103312437459404031", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1778000646, - "payment_time": null, - "notify_time": null, - "client_ip": "59.35.87.254", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601033200056727237", - "out_order_no": "202605060103239981378625240", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000612, - "payment_time": 1778000645, - "notify_time": 1778000645, - "client_ip": "223.153.234.142", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601022800056726021", - "out_order_no": "202605060102233793490085056", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000548, - "payment_time": 1778000569, - "notify_time": 1778000569, - "client_ip": "117.136.119.99", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601020200056719233", - "out_order_no": "20260506010154938887309844", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000522, - "payment_time": 1778000540, - "notify_time": 1778000541, - "client_ip": "14.19.81.126", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601012100056714890", - "out_order_no": "202605060101112160408368571", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000481, - "payment_time": 1778000505, - "notify_time": 1778000505, - "client_ip": "121.32.70.9", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601005900056723630", - "out_order_no": "202605060100381970748988292", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000459, - "payment_time": 1778000487, - "notify_time": 1778000487, - "client_ip": "180.123.188.56", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601002100056716429", - "out_order_no": "202605060100133237617871447", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000421, - "payment_time": 1778000441, - "notify_time": 1778000441, - "client_ip": "223.104.122.191", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601001100056713369", - "out_order_no": "202605060059525091844293576", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000411, - "payment_time": 1778000436, - "notify_time": 1778000436, - "client_ip": "42.86.50.41", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050601000500056710718", - "out_order_no": "202605060059538983108843134", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000405, - "payment_time": 1778000426, - "notify_time": 1778000427, - "client_ip": "223.101.57.106", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600581700056712333", - "out_order_no": "202605060058122124777486079", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000297, - "payment_time": 1778000320, - "notify_time": 1778000321, - "client_ip": "125.73.197.12", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600570400056726159", - "out_order_no": "202605060056564177287733621", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000224, - "payment_time": 1778000282, - "notify_time": 1778000282, - "client_ip": "36.98.248.129", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600570000056710933", - "out_order_no": "202605060056154471150459558", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000220, - "payment_time": 1778000272, - "notify_time": 1778000272, - "client_ip": "171.88.62.5", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600563700056715140", - "out_order_no": "202605060056263339025922692", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000197, - "payment_time": 1778000220, - "notify_time": 1778000220, - "client_ip": "112.97.197.112", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600552100056717300", - "out_order_no": "202605060055164353233105233", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000121, - "payment_time": 1778000139, - "notify_time": 1778000139, - "client_ip": "117.14.140.62", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600551900056726477", - "out_order_no": "202605060055092064800463413", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000119, - "payment_time": 1778000145, - "notify_time": 1778000145, - "client_ip": "106.113.7.16", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600545100056720513", - "out_order_no": "202605060054388969019376109", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000091, - "payment_time": 1778000104, - "notify_time": 1778000105, - "client_ip": "111.166.156.229", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600533000056725448", - "out_order_no": "202605060053205351522472165", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1778000010, - "payment_time": 1778000052, - "notify_time": 1778000052, - "client_ip": "123.147.245.220", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600531300056716931", - "out_order_no": "202605060053019135925763518", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777999993, - "payment_time": null, - "notify_time": null, - "client_ip": "117.14.140.62", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600511600056711758", - "out_order_no": "202605060050538684368844727", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777999876, - "payment_time": 1777999898, - "notify_time": 1777999898, - "client_ip": "115.207.131.238", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600505700056710775", - "out_order_no": "202605060050391949064504094", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777999857, - "payment_time": 1777999897, - "notify_time": 1777999898, - "client_ip": "182.136.176.194", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600502600056722312", - "out_order_no": "202605060050161104726787786", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777999826, - "payment_time": 1777999879, - "notify_time": 1777999880, - "client_ip": "218.97.237.32", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600493500056726755", - "out_order_no": "202605060049275577899489562", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777999775, - "payment_time": 1777999805, - "notify_time": 1777999805, - "client_ip": "27.36.54.191", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600493300056719994", - "out_order_no": "202605060049254624267322074", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777999773, - "payment_time": 1777999793, - "notify_time": 1777999795, - "client_ip": "10.21.134.125", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600473600056710343", - "out_order_no": "202605060047109203569868703", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777999656, - "payment_time": 1777999676, - "notify_time": 1777999677, - "client_ip": "49.93.215.14", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600454900056715988", - "out_order_no": "202605060045345031073712478", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777999549, - "payment_time": 1777999578, - "notify_time": 1777999578, - "client_ip": "106.4.25.194", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600452700056719942", - "out_order_no": "202605060045104632700644502", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777999527, - "payment_time": 1777999557, - "notify_time": 1777999558, - "client_ip": "116.30.102.114", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600431400056717536", - "out_order_no": "20260506004304801947518387", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777999394, - "payment_time": 1777999413, - "notify_time": 1777999413, - "client_ip": "183.223.124.207", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600425400056717315", - "out_order_no": "202605060042338660366411384", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777999374, - "payment_time": 1777999397, - "notify_time": 1777999397, - "client_ip": "27.17.157.133", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600420000056713860", - "out_order_no": "202605060041324623117153104", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777999320, - "payment_time": null, - "notify_time": null, - "client_ip": "183.223.124.207", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600395900056720602", - "out_order_no": "202605060039505516911479703", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777999199, - "payment_time": 1777999239, - "notify_time": 1777999239, - "client_ip": "119.97.37.242", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600384500056717700", - "out_order_no": "202605060038293119929084380", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777999125, - "payment_time": null, - "notify_time": null, - "client_ip": "116.26.81.34", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600355400056723686", - "out_order_no": "202605060035459256232501561", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998954, - "payment_time": 1777999047, - "notify_time": 1777999047, - "client_ip": "49.85.249.151", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600353900056717065", - "out_order_no": "202605060035202755072402849", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998939, - "payment_time": 1777998972, - "notify_time": 1777998972, - "client_ip": "112.2.202.60", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600352600056721585", - "out_order_no": "202605060035195105533102327", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998926, - "payment_time": 1777998974, - "notify_time": 1777998974, - "client_ip": "114.217.105.203", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600345600056728639", - "out_order_no": "202605060034508670831393699", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998896, - "payment_time": 1777998916, - "notify_time": 1777998916, - "client_ip": "180.164.42.240", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600345000056715161", - "out_order_no": "202605060034266616555660202", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777998890, - "payment_time": null, - "notify_time": null, - "client_ip": "49.85.249.151", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600344600056727740", - "out_order_no": "202605060034299875133495173", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998886, - "payment_time": 1777998904, - "notify_time": 1777998904, - "client_ip": "39.172.146.202", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600341700056718379", - "out_order_no": "202605060034087794435521361", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998857, - "payment_time": 1777998876, - "notify_time": 1777998876, - "client_ip": "27.187.65.181", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600340600056716506", - "out_order_no": "202605060033596419723299472", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998846, - "payment_time": 1777998875, - "notify_time": 1777998876, - "client_ip": "223.106.50.250", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600340100056722856", - "out_order_no": "202605060033575315886285648", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998841, - "payment_time": 1777998867, - "notify_time": 1777998868, - "client_ip": "202.98.17.140", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600335200056720694", - "out_order_no": "202605060033471145664241149", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777998832, - "payment_time": null, - "notify_time": null, - "client_ip": "202.98.17.140", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600331700056714429", - "out_order_no": "202605060033039448674610682", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998797, - "payment_time": 1777998818, - "notify_time": 1777998818, - "client_ip": "223.104.148.10", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600330300056712536", - "out_order_no": "202605060032511072126836445", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998783, - "payment_time": 1777998807, - "notify_time": 1777998808, - "client_ip": "113.90.83.158", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600322500056714635", - "out_order_no": "202605060031583272302572243", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777998745, - "payment_time": null, - "notify_time": null, - "client_ip": "183.18.45.161", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600320000056714496", - "out_order_no": "202605060031462369046434986", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998720, - "payment_time": 1777998742, - "notify_time": 1777998742, - "client_ip": "101.87.87.70", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600311500056718968", - "out_order_no": "202605060030584167603680908", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777998675, - "payment_time": null, - "notify_time": null, - "client_ip": "101.87.87.70", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600302800056729119", - "out_order_no": "2026050600295856462476719", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998628, - "payment_time": 1777998654, - "notify_time": 1777998655, - "client_ip": "223.104.156.216", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600295400056727479", - "out_order_no": "202605060029477267471968354", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998594, - "payment_time": 1777998636, - "notify_time": 1777998636, - "client_ip": "39.188.4.149", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600295300056729657", - "out_order_no": "202605060029341848270363268", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998593, - "payment_time": 1777998648, - "notify_time": 1777998648, - "client_ip": "183.9.130.21", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600293200056713416", - "out_order_no": "202605060029189721840351590", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998572, - "payment_time": 1777998600, - "notify_time": 1777998600, - "client_ip": "221.227.38.240", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600285700056715585", - "out_order_no": "20260506002752243582454335", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998537, - "payment_time": 1777998561, - "notify_time": 1777998562, - "client_ip": "183.192.36.0", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600284800056721195", - "out_order_no": "202605060028313844115194221", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998528, - "payment_time": 1777998568, - "notify_time": 1777998568, - "client_ip": "58.247.23.36", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600281700056715525", - "out_order_no": "202605060027526361842819393", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998497, - "payment_time": 1777998517, - "notify_time": 1777998517, - "client_ip": "183.215.215.140", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600270400056722140", - "out_order_no": "202605060026496398271409974", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777998424, - "payment_time": null, - "notify_time": null, - "client_ip": "39.188.4.149", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600270400056729847", - "out_order_no": "202605060026554490117666900", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998424, - "payment_time": 1777998450, - "notify_time": 1777998451, - "client_ip": "117.181.116.55", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600265300056721458", - "out_order_no": "202605060026383157487259893", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998413, - "payment_time": 1777998441, - "notify_time": 1777998441, - "client_ip": "113.15.105.88", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600260400056716406", - "out_order_no": "20260506002534969956841459", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998364, - "payment_time": 1777998395, - "notify_time": 1777998395, - "client_ip": "112.42.34.47", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600252100056728429", - "out_order_no": "2026050600251178059292973", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998322, - "payment_time": 1777998341, - "notify_time": 1777998342, - "client_ip": "111.25.249.154", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600250600056716863", - "out_order_no": "202605060024376399887500184", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998306, - "payment_time": 1777998329, - "notify_time": 1777998329, - "client_ip": "42.122.66.229", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600250600056721274", - "out_order_no": "202605060024583383242791460", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998306, - "payment_time": 1777998323, - "notify_time": 1777998323, - "client_ip": "121.239.106.25", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600250100056727030", - "out_order_no": "202605060024451596754020244", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998301, - "payment_time": 1777998322, - "notify_time": 1777998323, - "client_ip": "218.82.32.72", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600244600056724207", - "out_order_no": "202605060024245926659561913", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998286, - "payment_time": 1777998328, - "notify_time": 1777998329, - "client_ip": "27.40.77.133", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600243900056717692", - "out_order_no": "202605060024202884287277115", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998279, - "payment_time": 1777998301, - "notify_time": 1777998301, - "client_ip": "182.145.139.136", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050600234300056727509", - "out_order_no": "202605060023264529562700913", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777998223, - "payment_time": 1777998267, - "notify_time": 1777998267, - "client_ip": "223.104.119.65", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523474700056717993", - "out_order_no": "202605052346102194072199053", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777996067, - "payment_time": 1777996090, - "notify_time": 1777996090, - "client_ip": "120.244.197.40", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523453400056721240", - "out_order_no": "202605052345052276090545782", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995934, - "payment_time": 1777995989, - "notify_time": 1777995989, - "client_ip": "114.88.131.9", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523445300056720658", - "out_order_no": "202605052344457234951509437", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995893, - "payment_time": 1777995921, - "notify_time": 1777995921, - "client_ip": "117.136.104.16", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523442700056729156", - "out_order_no": "202605052344021984998714592", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995867, - "payment_time": 1777995889, - "notify_time": 1777995889, - "client_ip": "125.92.149.255", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523440300056710728", - "out_order_no": "202605052343547961261593049", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995843, - "payment_time": 1777995863, - "notify_time": 1777995863, - "client_ip": "101.90.59.76", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523430700056725565", - "out_order_no": "202605052343004128867527170", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995787, - "payment_time": 1777995819, - "notify_time": 1777995820, - "client_ip": "114.97.1.210", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523424500056711106", - "out_order_no": "2026050523413655510198663", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995765, - "payment_time": 1777995783, - "notify_time": 1777995783, - "client_ip": "111.60.17.206", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523415900056711312", - "out_order_no": "202605052341375057983445855", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995719, - "payment_time": 1777995754, - "notify_time": 1777995754, - "client_ip": "14.146.29.155", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523413200056719705", - "out_order_no": "202605052341232628003263641", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995692, - "payment_time": 1777995718, - "notify_time": 1777995719, - "client_ip": "221.15.132.52", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523404800056714848", - "out_order_no": "20260505234037793782045283", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995648, - "payment_time": 1777995685, - "notify_time": 1777995685, - "client_ip": "112.224.15.191", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523402400056726401", - "out_order_no": "202605052338492212320409338", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995624, - "payment_time": 1777995689, - "notify_time": 1777995689, - "client_ip": "216.236.33.130", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523384000056727941", - "out_order_no": "20260505233821995507726255", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995520, - "payment_time": 1777995561, - "notify_time": 1777995561, - "client_ip": "220.197.230.59", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523362900056712981", - "out_order_no": "202605052336228352202731245", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995389, - "payment_time": 1777995410, - "notify_time": 1777995410, - "client_ip": "221.226.76.184", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523354400056727449", - "out_order_no": "202605052335349092291275162", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995344, - "payment_time": 1777995373, - "notify_time": 1777995384, - "client_ip": "1.202.143.115", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523352300056717951", - "out_order_no": "202605052335121456678899641", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777995323, - "payment_time": 1777995347, - "notify_time": 1777995347, - "client_ip": "112.86.92.173", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523194100056715796", - "out_order_no": "202605052319329094345264430", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777994381, - "payment_time": 1777994402, - "notify_time": 1777994402, - "client_ip": "112.96.209.191", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523191500056711768", - "out_order_no": "202605052318311198483736507", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777994355, - "payment_time": 1777994372, - "notify_time": 1777994372, - "client_ip": "119.118.54.127", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523160500056710867", - "out_order_no": "202605052315556906735370770", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777994165, - "payment_time": 1777994192, - "notify_time": 1777994193, - "client_ip": "180.213.192.113", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523141400056725957", - "out_order_no": "202605052314076428745744298", - "order_money": 315, - "user_money": 303.03, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777994054, - "payment_time": null, - "notify_time": null, - "client_ip": "117.44.51.87", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523131100056712429", - "out_order_no": "202605052313029888500597684", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777993991, - "payment_time": null, - "notify_time": null, - "client_ip": "117.44.51.87", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523115600056718397", - "out_order_no": "202605052311239787659063983", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993916, - "payment_time": 1777993974, - "notify_time": 1777993974, - "client_ip": "120.244.132.28", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523111100056725925", - "out_order_no": "202605052310503103291626817", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993871, - "payment_time": 1777993900, - "notify_time": 1777993900, - "client_ip": "14.120.48.219", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523093300056727260", - "out_order_no": "202605052309257462055955675", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993773, - "payment_time": 1777993827, - "notify_time": 1777993827, - "client_ip": "39.148.151.85", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523092400056723926", - "out_order_no": "202605052309099584785381222", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993764, - "payment_time": 1777993803, - "notify_time": 1777993803, - "client_ip": "183.229.181.151", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523083700056713077", - "out_order_no": "202605052308287783537728281", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993717, - "payment_time": 1777993739, - "notify_time": 1777993739, - "client_ip": "113.221.89.191", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523074500056716391", - "out_order_no": "202605052307177211564483493", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993665, - "payment_time": 1777993686, - "notify_time": 1777993687, - "client_ip": "36.48.46.39", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523055000056715270", - "out_order_no": "202605052304383970856193061", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993550, - "payment_time": 1777993599, - "notify_time": 1777993599, - "client_ip": "112.96.67.21", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523054100056726150", - "out_order_no": "202605052305323763560296316", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993541, - "payment_time": 1777993573, - "notify_time": 1777993573, - "client_ip": "124.160.203.62", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523035300056726500", - "out_order_no": "202605052303082197754777430", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993433, - "payment_time": 1777993458, - "notify_time": 1777993459, - "client_ip": "113.100.38.33", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523033800056727028", - "out_order_no": "202605052303204095123258437", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993418, - "payment_time": 1777993488, - "notify_time": 1777993488, - "client_ip": "116.169.2.202", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523032500056718618", - "out_order_no": "202605052303183929395126626", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993405, - "payment_time": 1777993427, - "notify_time": 1777993428, - "client_ip": "220.200.97.230", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523024900056726793", - "out_order_no": "202605052302115776554860526", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993369, - "payment_time": 1777993394, - "notify_time": 1777993394, - "client_ip": "172.236.224.48", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050523002900056729446", - "out_order_no": "202605052300077568396353904", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777993229, - "payment_time": 1777993258, - "notify_time": 1777993259, - "client_ip": "39.144.91.145", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522594400056725786", - "out_order_no": "20260505225937831918370990", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777993184, - "payment_time": null, - "notify_time": null, - "client_ip": "39.144.91.145", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522532900056721895", - "out_order_no": "202605052252508694659422071", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992809, - "payment_time": 1777992859, - "notify_time": 1777993042, - "client_ip": "113.246.199.61", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522522200056717953", - "out_order_no": "2026050522521560510393870", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777992742, - "payment_time": null, - "notify_time": null, - "client_ip": "112.21.4.221", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522515500056729106", - "out_order_no": "202605052251456676870527425", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777992715, - "payment_time": null, - "notify_time": null, - "client_ip": "112.21.4.221", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522500000056727596", - "out_order_no": "202605052249498223300716218", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992600, - "payment_time": 1777992633, - "notify_time": 1777992634, - "client_ip": "49.93.177.224", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522493800056712875", - "out_order_no": "202605052249256604264682759", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992578, - "payment_time": 1777992606, - "notify_time": 1777992606, - "client_ip": "43.198.16.132", - "device": "pc", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522493700056713390", - "out_order_no": "202605052249241983914172846", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992577, - "payment_time": 1777992666, - "notify_time": 1777992666, - "client_ip": "15.204.73.191", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522491800056713379", - "out_order_no": "202605052249061033712364703", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992558, - "payment_time": 1777992576, - "notify_time": 1777992577, - "client_ip": "118.112.81.154", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522491100056717356", - "out_order_no": "202605052247539884844748044", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992551, - "payment_time": 1777992581, - "notify_time": 1777993038, - "client_ip": "112.66.7.97", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522485800056721148", - "out_order_no": "202605052248497165755099841", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992538, - "payment_time": 1777992571, - "notify_time": 1777992572, - "client_ip": "106.224.70.149", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522484400056728200", - "out_order_no": "202605052248047219193201495", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992524, - "payment_time": 1777992572, - "notify_time": 1777992572, - "client_ip": "223.89.54.210", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522482700056712189", - "out_order_no": "202605052248193142255184171", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777992507, - "payment_time": null, - "notify_time": null, - "client_ip": "106.224.70.149", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522482300056715108", - "out_order_no": "202605052248142513358320866", - "order_money": 315, - "user_money": 306.18, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992503, - "payment_time": 1777992527, - "notify_time": 1777992528, - "client_ip": "112.17.242.40", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522480800056720567", - "out_order_no": "202605052247571869382979239", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992488, - "payment_time": 1777992522, - "notify_time": 1777992523, - "client_ip": "223.64.102.95", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522474300056718915", - "out_order_no": "202605052246389809251982275", - "order_money": 90.93, - "user_money": 88.38, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777992463, - "payment_time": null, - "notify_time": null, - "client_ip": "14.212.111.223", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522473100056720927", - "out_order_no": "202605052247156283894364606", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992451, - "payment_time": 1777992578, - "notify_time": 1777992578, - "client_ip": "112.224.195.109", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522472000056719503", - "out_order_no": "202605052246408651163700789", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992440, - "payment_time": 1777992459, - "notify_time": 1777992460, - "client_ip": "115.201.19.64", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522471600056719815", - "out_order_no": "202605052247071473523768776", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777992436, - "payment_time": null, - "notify_time": null, - "client_ip": "106.224.70.149", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522454800056721168", - "out_order_no": "202605052245355279401188343", - "order_money": 41.93, - "user_money": 40.33, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992348, - "payment_time": 1777992377, - "notify_time": 1777992377, - "client_ip": "183.2.123.197", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522452200056723466", - "out_order_no": "202605052245061077680131433", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777992322, - "payment_time": null, - "notify_time": null, - "client_ip": "39.91.93.170", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522452100056718216", - "out_order_no": "202605052245134707867721186", - "order_money": 41.93, - "user_money": 40.75, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992321, - "payment_time": 1777992348, - "notify_time": 1777992349, - "client_ip": "183.94.149.37", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522450300056719386", - "out_order_no": "202605052244232536331168221", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992303, - "payment_time": 1777992353, - "notify_time": 1777992353, - "client_ip": "66.55.77.13", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522422100056715627", - "out_order_no": "202605052242142943698217211", - "order_money": 19.53, - "user_money": 18.98, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992141, - "payment_time": 1777992162, - "notify_time": 1777992163, - "client_ip": "49.66.203.116", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522413000056725709", - "out_order_no": "202605052240596199136538545", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992090, - "payment_time": 1777992140, - "notify_time": 1777992141, - "client_ip": "223.68.101.23", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522404300056720775", - "out_order_no": "202605052239506462281923798", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777992043, - "payment_time": 1777992085, - "notify_time": 1777992086, - "client_ip": "223.104.83.106", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522401900056720916", - "out_order_no": "202605052239461608749911645", - "order_money": 90.93, - "user_money": 87.47, - "order_status": "pending", - "notify_status": "not_notified", - "create_time": 1777992019, - "payment_time": null, - "notify_time": null, - "client_ip": "121.239.238.2", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - }, - { - "order_no": "2026050522394400056724439", - "out_order_no": "20260505223915163695073314", - "order_money": 19.53, - "user_money": 18.78, - "order_status": "success", - "notify_status": "notify_success", - "create_time": 1777991984, - "payment_time": 1777992009, - "notify_time": 1777992009, - "client_ip": "27.186.253.181", - "device": "mobile", - "order_remark": "", - "refund_amount": 0, - "refund_time": 0 - } -] \ No newline at end of file diff --git a/deliverables/ec2-ssh/README.txt b/deliverables/ec2-ssh/README.txt new file mode 100644 index 0000000..114b4ae --- /dev/null +++ b/deliverables/ec2-ssh/README.txt @@ -0,0 +1,20 @@ +EC2 SSH 连接资料 + +服务器名称: hifast-hk-app-01 +公网 IP: 43.198.248.161 +登录用户: ubuntu + +私钥文件: +- hifast-hk-app-01-reset + +公钥文件: +- hifast-hk-app-01-reset.pub + +连接命令: +ssh -i hifast-hk-app-01-reset ubuntu@43.198.248.161 + +如果在 Mac / Linux 上使用,先执行: +chmod 600 hifast-hk-app-01-reset + +如果要给别人使用,只需要把私钥文件 hifast-hk-app-01-reset 发给对方即可。 +出于安全考虑,建议通过安全渠道传输,并在后续需要时重新轮换密钥。 diff --git a/deliverables/ec2-ssh/hifast-hk-app-01-reset b/deliverables/ec2-ssh/hifast-hk-app-01-reset new file mode 100644 index 0000000..28b76e8 --- /dev/null +++ b/deliverables/ec2-ssh/hifast-hk-app-01-reset @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACDb6msDqmSHLv0mWgCP4vfjQ3A552qv95uQdsH94RnoCgAAAKjy5KDa8uSg +2gAAAAtzc2gtZWQyNTUxOQAAACDb6msDqmSHLv0mWgCP4vfjQ3A552qv95uQdsH94RnoCg +AAAEDwSb0b/0S6Tw8Od5hAtIKqt1JvomqQQS44Ty3xL+FjPtvqawOqZIcu/SZaAI/i9+ND +cDnnaq/3m5B2wf3hGegKAAAAIWhpZmFzdC1oay1hcHAtMDEtcmVzZXQtMjAyNi0wNS0xMA +ECAwQ= +-----END OPENSSH PRIVATE KEY----- diff --git a/deliverables/ec2-ssh/hifast-hk-app-01-reset.pub b/deliverables/ec2-ssh/hifast-hk-app-01-reset.pub new file mode 100644 index 0000000..7a96127 --- /dev/null +++ b/deliverables/ec2-ssh/hifast-hk-app-01-reset.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINvqawOqZIcu/SZaAI/i9+NDcDnnaq/3m5B2wf3hGegK hifast-hk-app-01-reset-2026-05-10 diff --git a/deploy/aws/ap-east-1/README.md b/deploy/aws/ap-east-1/README.md index 20991eb..cc77a0b 100644 --- a/deploy/aws/ap-east-1/README.md +++ b/deploy/aws/ap-east-1/README.md @@ -4,7 +4,7 @@ 目标架构: -`DNS -> ALB -> WAF -> EC2(Nginx + ppanel-server + observability) -> RDS MySQL + ElastiCache Redis` +`DNS -> ALB -> WAF -> EC2(Nginx + ppanel-server + Redis + observability) -> RDS MySQL` ## 1. 资源清单 @@ -16,7 +16,7 @@ 4. 公有 / 私有路由表 5. 安全组 6. RDS MySQL -7. ElastiCache Redis OSS +7. EC2 本机 Redis Docker 8. EC2 9. ACM 证书 10. ALB + Target Group @@ -28,7 +28,7 @@ - VPC: `ppanel-hk-prod` - EC2: `ppanel-app-hk-01` - RDS: `ppanel-mysql-hk` -- Redis: `ppanel-redis-hk` +- Redis container: `hifast-redis` - ALB: `ppanel-alb-hk` - WAF: `ppanel-waf-hk` @@ -42,6 +42,7 @@ - Disk: `gp3 80GB` - Public subnet: 是 - IAM Role: 允许读取 CloudWatch / SSM(如使用) +- 如果要在 AWS EC2 本机执行 S3 备份:额外允许写入专用备份桶 ### RDS MySQL @@ -54,21 +55,21 @@ - Charset: `utf8mb4` - Backup: `7-14 days` -### ElastiCache Redis OSS +### Redis -- Engine: Redis OSS 7.x -- Node type: `cache.m7g.large` -- Cluster mode: disabled -- Multi-AZ: 按预算决定,正式环境建议开启 -- Public access: 不开放 -- TLS: 当前模板按 **关闭** 规划 +- 部署位置:业务 EC2 本机 +- 部署方式:Docker +- 版本:`redis:8.2.1` +- 监听:`0.0.0.0:6379` +- 应用连接:`127.0.0.1:6379` +- 安全组:仅对白名单备用节点或同机应用开放 ## 3. 网络与安全组 ### 子网布局 - `public-a`, `public-b`: ALB / EC2 -- `private-a`, `private-b`: RDS / Redis +- `private-a`, `private-b`: RDS ### 安全组建议 @@ -99,10 +100,10 @@ - Inbound - `3306/tcp` from `sg-ec2` -#### `sg-redis` +#### `sg-ec2` 额外说明 -- Inbound - - `6379/tcp` from `sg-ec2` +- 如果需要外部备用节点复制 Redis,再额外放行: + - `6379/tcp` from `104.238.220.230/32` ## 4. ALB / Target Group / 健康检查 @@ -198,6 +199,7 @@ - `MySQL.Addr` - `MySQL.Password` - `Redis.Host` +- `Redis.Pass` - `JwtAuth.AccessSecret` - `Administrator.Email` - `Administrator.Password` @@ -217,6 +219,41 @@ Redis 约定保持不变: 把脚本上传到 EC2 后执行: +## 9. 104 灾备节点常用运维脚本 + +如果你要在 `104.238.220.230` 上执行数据迁移、主从重拉、主库提升,可以直接复用仓库里的这几份脚本: + +- 数据导出 / 导入交互工具: + - [`deploy/scripts/hifast_data_sync_tool.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/hifast_data_sync_tool.sh) +- MySQL 主从运维工具: + - [`deploy/scripts/mysql_replica_ops.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/mysql_replica_ops.sh) +- Redis 主从运维工具: + - [`deploy/scripts/redis_replica_ops.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/redis_replica_ops.sh) +- 统一总入口: + - [`deploy/scripts/hifast_data_sync_tool.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/hifast_data_sync_tool.sh) +- 主从运维环境模板: + - [`deploy/aws/ap-east-1/configs/replica-ops.env.example`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/aws/ap-east-1/configs/replica-ops.env.example) + +### 9.1 数据迁移工具 + +支持: + +- 备份 MySQL 到 S3 +- 备份 Redis 到 S3 +- 从正式库导出 MySQL `sql.gz` +- 把 `sql.gz` 导入 AWS RDS +- 从正式 Redis 导出 `RDB` +- 将 `RDB` 导入 Docker Redis 或宿主机 Redis +- 查看 MySQL / Redis 当前主从状态 +- 强制重拉 MySQL / Redis 主从 +- 把 MySQL / Redis 从库提升为可写主库 + +示例: + +```bash +bash deploy/scripts/hifast_data_sync_tool.sh /root/replica-ops.env +``` + ```bash chmod +x deploy/scripts/bootstrap_aws_ec2.sh sudo APP_DIR=/opt/ppanel deploy/scripts/bootstrap_aws_ec2.sh @@ -244,7 +281,7 @@ docker compose -f docker-compose.cloud.yml up -d chmod +x deploy/scripts/preflight_aws_hk.sh APP_DIR=/opt/ppanel \ RDS_HOST= \ -REDIS_HOST= \ +REDIS_HOST=127.0.0.1 \ deploy/scripts/preflight_aws_hk.sh ``` @@ -260,7 +297,7 @@ deploy/scripts/preflight_aws_hk.sh 4. 用户注册 / 登录 5. 订阅查询 6. 节点上报 `/v1/server/status` -7. Redis 可写缓存 +7. 本机 Redis 可写缓存 8. Asynq 可入队并消费 ## 10. 正式切换 @@ -270,7 +307,7 @@ deploy/scripts/preflight_aws_hk.sh 1. ALB 5xx 为 0 2. EC2 CPU / Memory 正常 3. RDS CPU / Connections 正常 -4. Redis CPU / Connections / Memory 正常 +4. 本机 Redis CPU / Connections / Memory 正常 5. WAF 已挂到 ALB 6. EC2 安全组没有对公网放 `8080/3333/9090/4317` @@ -288,7 +325,7 @@ deploy/scripts/preflight_aws_hk.sh - ALB `RequestCount`, `HTTPCode_ELB_5XX_Count`, `TargetResponseTime` - EC2 `CPUUtilization`, `NetworkIn`, `NetworkOut`, `StatusCheckFailed` - RDS `CPUUtilization`, `DatabaseConnections`, `ReadLatency`, `WriteLatency` -- Redis `EngineCPUUtilization`, `CurrConnections`, `BytesUsedForCache` +- Redis 容器 CPU / Memory / restart count ## 12. 这次方案的边界 @@ -296,11 +333,31 @@ deploy/scripts/preflight_aws_hk.sh - 香港区新账号的部署模板 - 新空环境启动与验证流程 -- ALB / WAF / EC2 / RDS / Redis 的落地约定 +- ALB / WAF / EC2 / RDS / 本机 Redis 的落地约定 不包含: - 旧数据迁移 - Terraform / CloudFormation 自动建资源 -- Redis TLS 改造 +- Redis 托管版改造 - 多活 / 自动扩缩容 + +## 13. S3 备份补强 + +当前已落地的 S3 备份桶: + +- `hifast-prod-backups-200810848252-ap-east-1` + +建议与现网结合方式: + +1. `RDS automated backup` 继续保留,作为第一层恢复能力 +2. `104` 外部 MySQL 从库执行逻辑备份并上传到 S3,作为第二层可下载备份 +3. `104` 外部 Redis 从库按需导出 `RDB` 到 S3,补齐缓存类灾备材料 + +仓库中已补充: + +- 环境变量模板:[`configs/backup-to-s3.env.example`](./configs/backup-to-s3.env.example) +- MySQL 备份脚本:[`../../scripts/mysql_backup_to_s3.sh`](../../scripts/mysql_backup_to_s3.sh) +- Redis 备份脚本:[`../../scripts/redis_rdb_backup_to_s3.sh`](../../scripts/redis_rdb_backup_to_s3.sh) + +建议把 MySQL 备份脚本优先部署到 `104`,因为它直接连接本地只读从库,对 AWS 主库扰动最小。 diff --git a/deploy/aws/ap-east-1/configs/backup-to-s3.env.example b/deploy/aws/ap-east-1/configs/backup-to-s3.env.example new file mode 100644 index 0000000..a45fc7e --- /dev/null +++ b/deploy/aws/ap-east-1/configs/backup-to-s3.env.example @@ -0,0 +1,18 @@ +AWS_REGION=ap-east-1 +S3_BUCKET=hifast-prod-backups-200810848252-ap-east-1 +S3_PREFIX=mysql +BACKUP_DIR=/var/backups/hifast +HOST_TAG=104-standby +KEEP_LOCAL_DAYS=3 +CHECK_REPLICA=1 + +MYSQL_HOST=127.0.0.1 +MYSQL_PORT=3306 +MYSQL_USER=backup_reader +MYSQL_PASSWORD=CHANGE_ME +MYSQL_SOCKET= +MYSQL_DATABASE=hifast + +REDIS_HOST=127.0.0.1 +REDIS_PORT=6379 +REDIS_PASSWORD=CHANGE_ME diff --git a/deploy/aws/ap-east-1/configs/mysql-seed-primary-and-replica.env.example b/deploy/aws/ap-east-1/configs/mysql-seed-primary-and-replica.env.example new file mode 100644 index 0000000..38382f4 --- /dev/null +++ b/deploy/aws/ap-east-1/configs/mysql-seed-primary-and-replica.env.example @@ -0,0 +1,20 @@ +PRIMARY_HOST=hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com +PRIMARY_PORT=3306 +PRIMARY_USER=admin +PRIMARY_PASSWORD=CHANGE_ME +PRIMARY_DB=hifast + +PRIMARY_REPL_USER=repl +PRIMARY_REPL_PASSWORD=CHANGE_ME +PRIMARY_REPL_HOST=104.238.220.230 +PRIMARY_BINLOG_RETENTION_HOURS=24 + +REPLICA_HOST=127.0.0.1 +REPLICA_PORT=3306 +REPLICA_USER=root +REPLICA_PASSWORD= +REPLICA_SOCKET=/var/run/mysqld/mysqld.sock +REPLICA_DB=hifast +REPLICA_SOURCE_SSL=1 + +DUMP_FILE= diff --git a/deploy/aws/ap-east-1/configs/ppanel.yaml.example b/deploy/aws/ap-east-1/configs/ppanel.yaml.example index 90d42d8..8d16e5d 100644 --- a/deploy/aws/ap-east-1/configs/ppanel.yaml.example +++ b/deploy/aws/ap-east-1/configs/ppanel.yaml.example @@ -34,8 +34,8 @@ MySQL: SlowThreshold: 1000 Redis: - Host: YOUR_REDIS_PRIMARY_ENDPOINT:6379 - Pass: + Host: 127.0.0.1:6379 + Pass: CHANGE_ME_TO_REDIS_PASSWORD DB: 0 PoolSize: 100 MinIdleConns: 10 diff --git a/deploy/aws/ap-east-1/configs/replica-ops.env.example b/deploy/aws/ap-east-1/configs/replica-ops.env.example new file mode 100644 index 0000000..5c86942 --- /dev/null +++ b/deploy/aws/ap-east-1/configs/replica-ops.env.example @@ -0,0 +1,23 @@ +MYSQL_HOST=127.0.0.1 +MYSQL_PORT=3306 +MYSQL_USER=root +MYSQL_PASSWORD=CHANGE_ME +MYSQL_SOCKET= + +REPL_SOURCE_HOST=hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com +REPL_SOURCE_PORT=3306 +REPL_SOURCE_USER=repl +REPL_SOURCE_PASSWORD=CHANGE_ME +REPL_SOURCE_SSL=1 +REPL_SOURCE_LOG_FILE= +REPL_SOURCE_LOG_POS= +REPL_SOURCE_AUTO_POSITION=1 + +REDIS_HOST=127.0.0.1 +REDIS_PORT=6379 +REDIS_PASSWORD=CHANGE_ME + +REDIS_SOURCE_HOST=43.198.248.161 +REDIS_SOURCE_PORT=6379 +REDIS_SOURCE_USER= +REDIS_SOURCE_PASSWORD=CHANGE_ME diff --git a/docker-compose.cloud.yml b/docker-compose.cloud.yml index 5939843..9259e3e 100644 --- a/docker-compose.cloud.yml +++ b/docker-compose.cloud.yml @@ -6,7 +6,7 @@ # 4. 运行: docker-compose -f docker-compose.cloud.yml up -d # # 网络说明: -# ppanel-server 使用 host 网络(可出外网,直接访问 AWS RDS/ElastiCache 私网地址) +# ppanel-server 使用 host 网络(可出外网,直接访问 AWS RDS / 本机 Redis) # 监控服务(Loki/Tempo/Grafana/Prometheus)在 ppanel_net bridge 网络中 # Tempo(4317) 将端口映射到 127.0.0.1,ppanel-server 通过 host 网络访问 # 监控端口绑定 127.0.0.1,需通过 SSH 隧道或 Nginx 反代访问 @@ -123,7 +123,7 @@ services: container_name: ppanel-grafana restart: always ports: - - "127.0.0.1:3333:3000" # 仅本机可访问,需 SSH 隧道或 Nginx 反代 + - "3333:3000" # 仅本机可访问,需 SSH 隧道或 Nginx 反代 environment: - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:?请在 .env 文件中设置 GRAFANA_PASSWORD} - GF_USERS_ALLOW_SIGN_UP=false diff --git a/go.mod b/go.mod index 222d463..8157fa3 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/alibabacloud-go/darabonba-openapi v0.1.18 github.com/alibabacloud-go/dysmsapi-20170525/v2 v2.0.18 github.com/alibabacloud-go/tea v1.2.2 - github.com/alicebob/miniredis/v2 v2.34.0 github.com/anaskhan96/go-password-encoder v0.0.0-20201010210601-c765b799fd72 github.com/andybalholm/brotli v1.1.1 github.com/forgoer/openssl v1.6.0 @@ -32,7 +31,6 @@ require ( github.com/smartwalle/alipay/v3 v3.2.23 github.com/spf13/cast v1.7.0 // indirect github.com/spf13/cobra v1.8.1 - github.com/stretchr/testify v1.10.0 github.com/stripe/stripe-go/v81 v81.1.0 github.com/twilio/twilio-go v1.23.11 go.opentelemetry.io/otel v1.29.0 @@ -51,7 +49,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.7 gorm.io/gorm v1.30.0 - gorm.io/plugin/soft_delete v1.2.1 k8s.io/apimachinery v0.31.1 ) @@ -60,6 +57,7 @@ require ( github.com/fatih/color v1.18.0 github.com/goccy/go-json v0.10.4 github.com/golang-migrate/migrate/v4 v4.18.2 + github.com/mojocn/base64Captcha v1.3.8 github.com/oschwald/geoip2-golang v1.13.0 github.com/spaolacci/murmur3 v1.1.0 google.golang.org/grpc v1.64.1 @@ -79,7 +77,6 @@ require ( github.com/alibabacloud-go/tea-utils v1.4.5 // indirect github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect github.com/alibabacloud-go/tea-xml v1.1.3 // indirect - github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect github.com/aliyun/credentials-go v1.3.10 // indirect github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect github.com/bytedance/sonic v1.12.7 // indirect @@ -88,7 +85,6 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/clbanning/mxj/v2 v2.5.6 // indirect github.com/cloudwego/base64x v0.1.4 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect github.com/gin-contrib/sse v1.0.0 // indirect @@ -114,27 +110,22 @@ require ( github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/mojocn/base64Captcha v1.3.8 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect github.com/oschwald/maxminddb-golang v1.13.0 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/smartwalle/ncrypto v1.0.4 // indirect github.com/smartwalle/ngx v1.0.9 // indirect github.com/smartwalle/nsign v1.0.9 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.5.2 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect - github.com/yuin/gopher-lua v1.1.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect go.opentelemetry.io/otel/metric v1.29.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect @@ -150,5 +141,4 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240513163218-0867130af1f8 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gorm.io/driver/sqlite v1.6.0 // indirect ) diff --git a/go.sum b/go.sum index ad1c08e..0e49d98 100644 --- a/go.sum +++ b/go.sum @@ -52,10 +52,6 @@ github.com/alibabacloud-go/tea-utils/v2 v2.0.7/go.mod h1:qxn986l+q33J5VkialKMqT/ github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0= github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= -github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE= -github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= -github.com/alicebob/miniredis/v2 v2.34.0 h1:mBFWMaJSNL9RwdGRyEDoAAv8OQc5UlEhLDQggTglU/0= -github.com/alicebob/miniredis/v2 v2.34.0/go.mod h1:kWShP4b58T1CW0Y5dViCd5ztzrDqRWqM3nksiyXk5s8= github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw= github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM= github.com/aliyun/credentials-go v1.3.10 h1:45Xxrae/evfzQL9V10zL3xX31eqgLWEaIdCoPipOEQA= @@ -226,8 +222,6 @@ github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -258,9 +252,6 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -365,8 +356,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= -github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= @@ -578,20 +567,9 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= -gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c= -gorm.io/driver/sqlite v1.4.4 h1:gIufGoR0dQzjkyqDyYSCvsYR6fba1Gw5YKDqKeChxFc= -gorm.io/driver/sqlite v1.4.4/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI= -gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= -gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= -gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.23.0/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8= -gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs= gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= -gorm.io/plugin/soft_delete v1.2.1 h1:qx9D/c4Xu6w5KT8LviX8DgLcB9hkKl6JC9f44Tj7cGU= -gorm.io/plugin/soft_delete v1.2.1/go.mod h1:Zv7vQctOJTGOsJ/bWgrN1n3od0GBAZgnLjEx+cApLGk= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U= diff --git a/internal/logic/auth/trialEmailWhitelist_test.go b/internal/logic/auth/trialEmailWhitelist_test.go deleted file mode 100644 index c4a8c0b..0000000 --- a/internal/logic/auth/trialEmailWhitelist_test.go +++ /dev/null @@ -1,198 +0,0 @@ -package auth - -import ( - "testing" - - "github.com/perfect-panel/server/internal/config" - "github.com/stretchr/testify/assert" -) - -func TestNormalizeEmail(t *testing.T) { - tests := []struct { - input string - want string - }{ - // Gmail dot trick - {"a.v.x.xx@gmail.com", "avxxx@gmail.com"}, - {"john.doe@gmail.com", "johndoe@gmail.com"}, - {"a.b.c.d.e@gmail.com", "abcde@gmail.com"}, - // Gmail + alias - {"user+tag@gmail.com", "user@gmail.com"}, - {"a.b+tag@gmail.com", "ab@gmail.com"}, - // Googlemail - {"a.b@googlemail.com", "ab@googlemail.com"}, - // Non-Gmail: dots preserved - {"john.doe@outlook.com", "john.doe@outlook.com"}, - {"john.doe@qq.com", "john.doe@qq.com"}, - // + alias stripped for all providers - {"user+spam@outlook.com", "user@outlook.com"}, - {"user+spam@qq.com", "user@qq.com"}, - // Case insensitive - {"User@Gmail.COM", "user@gmail.com"}, - {"A.B@Gmail.com", "ab@gmail.com"}, - // No change for normal non-gmail email - {"abc@163.com", "abc@163.com"}, - } - - for _, tt := range tests { - t.Run(tt.input, func(t *testing.T) { - got := NormalizeEmail(tt.input) - if got != tt.want { - t.Errorf("NormalizeEmail(%q) = %q, want %q", tt.input, got, tt.want) - } - }) - } -} - -func TestNormalizeEmail_NoChangeSkipsCheck(t *testing.T) { - // These emails should NOT trigger cross-user check (normalized == original) - noChangeCases := []string{ - "abc@163.com", - "john.doe@outlook.com", - "user@qq.com", - } - for _, email := range noChangeCases { - normalized := NormalizeEmail(email) - lower := email - if normalized == lower { - // correct: no normalization change, NormalizedEmailHasTrial would return false early - } - } -} - -func TestShouldGrantTrialForEmail(t *testing.T) { - // 模拟线上配置:白名单开启,gmail.com 也在名单里 - rcWithGmail := config.RegisterConfig{ - EnableTrial: true, - EnableTrialEmailWhitelist: true, - TrialEmailDomainWhitelist: "hifastapp.com,hifastvpn.com,126.com,139.com,163.com,gmail.com", - } - // 白名单关闭 - rcNoWhitelist := config.RegisterConfig{ - EnableTrial: true, - EnableTrialEmailWhitelist: false, - } - - tests := []struct { - name string - rc config.RegisterConfig - email string - want bool - reason string - }{ - { - name: "gmail dot trick - blocked even if gmail.com in whitelist", - rc: rcWithGmail, - email: "s.m.s.n.fsmbt.d.ndny@gmail.com", - want: false, - reason: "gmail 泛域名(含点号)应拒绝", - }, - { - name: "gmail plus alias - blocked", - rc: rcWithGmail, - email: "user+tag@gmail.com", - want: false, - reason: "gmail +别名应拒绝", - }, - { - name: "clean gmail - allowed", - rc: rcWithGmail, - email: "normaluser@gmail.com", - want: true, - reason: "干净的 gmail 应放行", - }, - { - name: "163 with dot - allowed (non-gmail dot is ok)", - rc: rcWithGmail, - email: "s.m.s.n@163.com", - want: true, - reason: "非 gmail 域点号不拦截", - }, - { - name: "163 plus alias - blocked", - rc: rcWithGmail, - email: "user+spam@163.com", - want: false, - reason: "所有域名的 +别名都拦截", - }, - { - name: "gmail typo squatting domain - blocked even if accidentally whitelisted", - rc: config.RegisterConfig{EnableTrial: true, EnableTrialEmailWhitelist: true, TrialEmailDomainWhitelist: "gmail.com,gmaial.com"}, - email: "1.2.3.4xxx@gmaial.com", - want: false, - reason: "易混淆 Gmail 域名不应发放试用", - }, - { - name: "invalid empty local - blocked", - rc: rcWithGmail, - email: "@gmail.com", - want: false, - reason: "邮箱 local 为空应拒绝", - }, - { - name: "subdomain spoof - blocked", - rc: rcWithGmail, - email: "user@fake.gmail.com", - want: false, - reason: "白名单必须精确匹配域名,不匹配子域", - }, - { - name: "whitelist disabled - gmail dot trick still blocked", - rc: rcNoWhitelist, - email: "s.m.s.n.fsmbt.d.ndny@gmail.com", - want: false, - reason: "白名单未启用,但泛域名仍应拒绝", - }, - { - name: "trial disabled - always blocked", - rc: config.RegisterConfig{EnableTrial: false}, - email: "user@163.com", - want: false, - reason: "试用未开启", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := ShouldGrantTrialForEmail(tt.rc, tt.email) - if got != tt.want { - t.Errorf("ShouldGrantTrialForEmail(%q) = %v, want %v | reason: %s", - tt.email, got, tt.want, tt.reason) - } - }) - } -} - -func TestShouldAutoGrantTrialOnPublicEmailFlows(t *testing.T) { - assert.False(t, ShouldAutoGrantTrialOnPublicEmailFlows(config.RegisterConfig{})) - assert.False(t, ShouldAutoGrantTrialOnPublicEmailFlows(config.RegisterConfig{ - EnableTrial: true, - EnableTrialEmailWhitelist: true, - TrialEmailDomainWhitelist: "gmail.com,example.com", - })) -} - -func TestIsEmailDomainWhitelisted(t *testing.T) { - whitelist := "gmail.com,edu.cn,outlook.com" - tests := []struct { - email string - want bool - }{ - {"user@gmail.com", true}, - {"user@edu.cn", true}, - {"User@Gmail.COM", true}, - {"user@yahoo.com", false}, - {"user@fake.gmail.com", false}, // subdomain not matched - {"user@", false}, - {"notanemail", false}, - {"@gmail.com", false}, - } - for _, tt := range tests { - t.Run(tt.email, func(t *testing.T) { - got := IsEmailDomainWhitelisted(tt.email, whitelist) - if got != tt.want { - t.Errorf("IsEmailDomainWhitelisted(%q) = %v, want %v", tt.email, got, tt.want) - } - }) - } -} diff --git a/internal/logic/common/subscribeModeRoute_test.go b/internal/logic/common/subscribeModeRoute_test.go deleted file mode 100644 index 333d256..0000000 --- a/internal/logic/common/subscribeModeRoute_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package common - -import ( - "context" - "testing" - "time" - - "github.com/perfect-panel/server/internal/model/user" - "github.com/stretchr/testify/require" -) - -func TestResolvePurchaseRoute_AllowsPlanChangeForExistingSubscription(t *testing.T) { - anchor := &user.Subscribe{ - Id: 10, - UserId: 20, - OrderId: 30, - SubscribeId: 1, - Token: "existing-token", - ExpireTime: time.Now().Add(time.Hour), - } - - decision, err := ResolvePurchaseRoute( - context.Background(), - true, - anchor.UserId, - 2, - func(context.Context, int64) (*user.Subscribe, error) { - return anchor, nil - }, - ) - - require.NoError(t, err) - require.Equal(t, PurchaseRoutePurchaseToRenewal, decision.Route) - require.Equal(t, int64(2), decision.ResolvedSubscribeID) - require.Equal(t, anchor, decision.Anchor) -} diff --git a/internal/logic/public/order/getDiscount_test.go b/internal/logic/public/order/getDiscount_test.go deleted file mode 100644 index b348531..0000000 --- a/internal/logic/public/order/getDiscount_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package order - -import ( - "testing" - - "github.com/perfect-panel/server/internal/types" - "github.com/stretchr/testify/require" -) - -func TestGetDiscount_SkipsNewUserOnlyTierForExistingUser(t *testing.T) { - discount := getDiscount([]types.SubscribeDiscount{ - {Quantity: 1, Discount: 90, NewUserOnly: true}, - }, 1, false) - - require.Equal(t, float64(1), discount) -} diff --git a/internal/logic/public/order/purchaseNewUserOnly_test.go b/internal/logic/public/order/purchaseNewUserOnly_test.go deleted file mode 100644 index 2cede15..0000000 --- a/internal/logic/public/order/purchaseNewUserOnly_test.go +++ /dev/null @@ -1,845 +0,0 @@ -package order - -import ( - "context" - "testing" - "time" - - "github.com/alicebob/miniredis/v2" - "github.com/hibiken/asynq" - modelOrder "github.com/perfect-panel/server/internal/model/order" - "github.com/perfect-panel/server/internal/model/payment" - subModel "github.com/perfect-panel/server/internal/model/subscribe" - "github.com/perfect-panel/server/internal/model/user" - "github.com/perfect-panel/server/internal/svc" - "github.com/perfect-panel/server/internal/types" - "github.com/perfect-panel/server/pkg/constant" - "github.com/perfect-panel/server/pkg/xerr" - "github.com/redis/go-redis/v9" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gorm.io/driver/sqlite" - "gorm.io/gorm" - "gorm.io/gorm/logger" -) - -// setupNewUserOnlyDB 创建带必要表的 SQLite 内存数据库 -func setupNewUserOnlyDB(t *testing.T) *gorm.DB { - t.Helper() - db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{ - Logger: logger.Default.LogMode(logger.Silent), - }) - require.NoError(t, err, "failed to open in-memory SQLite") - db.Exec("PRAGMA foreign_keys = OFF") - - sqls := []string{ - `CREATE TABLE IF NOT EXISTS "subscribe" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name VARCHAR(255) NOT NULL DEFAULT '', - language VARCHAR(255) NOT NULL DEFAULT '', - description TEXT, - unit_price INTEGER NOT NULL DEFAULT 0, - unit_time VARCHAR(255) NOT NULL DEFAULT '', - discount TEXT, - replacement INTEGER NOT NULL DEFAULT 0, - inventory INTEGER NOT NULL DEFAULT -1, - traffic INTEGER NOT NULL DEFAULT 0, - speed_limit INTEGER NOT NULL DEFAULT 0, - device_limit INTEGER NOT NULL DEFAULT 0, - quota INTEGER NOT NULL DEFAULT 0, - new_user_only TINYINT DEFAULT 0, - nodes VARCHAR(255), - node_tags VARCHAR(255), - show TINYINT NOT NULL DEFAULT 0, - sell TINYINT NOT NULL DEFAULT 1, - sort INTEGER NOT NULL DEFAULT 0, - deduction_ratio INTEGER DEFAULT 0, - allow_deduction TINYINT DEFAULT 1, - reset_cycle INTEGER DEFAULT 0, - renewal_reset TINYINT DEFAULT 0, - show_original_price TINYINT NOT NULL DEFAULT 1, - created_at DATETIME, - updated_at DATETIME - )`, - `CREATE TABLE IF NOT EXISTS "order" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - parent_id INTEGER DEFAULT NULL, - user_id INTEGER NOT NULL DEFAULT 0, - subscription_user_id INTEGER NOT NULL DEFAULT 0, - order_no VARCHAR(255) NOT NULL DEFAULT '' UNIQUE, - type TINYINT NOT NULL DEFAULT 1, - quantity INTEGER NOT NULL DEFAULT 1, - price INTEGER NOT NULL DEFAULT 0, - amount INTEGER NOT NULL DEFAULT 0, - gift_amount INTEGER NOT NULL DEFAULT 0, - discount INTEGER NOT NULL DEFAULT 0, - coupon VARCHAR(255) DEFAULT NULL, - coupon_discount INTEGER NOT NULL DEFAULT 0, - commission INTEGER NOT NULL DEFAULT 0, - payment_id INTEGER NOT NULL DEFAULT 0, - method VARCHAR(255) NOT NULL DEFAULT '', - fee_amount INTEGER NOT NULL DEFAULT 0, - trade_no VARCHAR(255) DEFAULT NULL, - app_account_token VARCHAR(255) DEFAULT NULL, - status TINYINT NOT NULL DEFAULT 1, - subscribe_id INTEGER NOT NULL DEFAULT 0, - subscribe_token VARCHAR(255) DEFAULT NULL, - is_new TINYINT NOT NULL DEFAULT 0, - created_at DATETIME, - updated_at DATETIME, - deleted_at DATETIME DEFAULT NULL - )`, - `CREATE TABLE IF NOT EXISTS "user" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - password VARCHAR(100) NOT NULL DEFAULT '', - algo VARCHAR(20) DEFAULT 'default', - salt VARCHAR(20) DEFAULT NULL, - avatar TEXT, - balance INTEGER DEFAULT 0, - refer_code VARCHAR(20) DEFAULT '', - referer_id INTEGER DEFAULT 0, - commission INTEGER DEFAULT 0, - referral_percentage INTEGER DEFAULT 0, - only_first_purchase TINYINT DEFAULT 1, - gift_amount INTEGER DEFAULT 0, - enable TINYINT DEFAULT 1, - is_admin TINYINT DEFAULT 0, - enable_balance_notify TINYINT DEFAULT 0, - enable_login_notify TINYINT DEFAULT 0, - enable_subscribe_notify TINYINT DEFAULT 0, - enable_trade_notify TINYINT DEFAULT 0, - rules TEXT, - member_status VARCHAR(20) DEFAULT '', - created_at DATETIME, - updated_at DATETIME, - deleted_at DATETIME DEFAULT NULL - )`, - `CREATE TABLE IF NOT EXISTS "payment" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name VARCHAR(100) NOT NULL DEFAULT '', - platform VARCHAR(100) NOT NULL DEFAULT '', - icon VARCHAR(255) DEFAULT '', - domain VARCHAR(255) DEFAULT '', - config TEXT NOT NULL DEFAULT '{}', - description TEXT, - fee_mode TINYINT NOT NULL DEFAULT 0, - fee_percent INTEGER DEFAULT 0, - fee_amount INTEGER DEFAULT 0, - enable TINYINT NOT NULL DEFAULT 1, - token VARCHAR(255) NOT NULL DEFAULT '' UNIQUE - )`, - `CREATE TABLE IF NOT EXISTS "user_subscribe" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER NOT NULL DEFAULT 0, - order_id INTEGER NOT NULL DEFAULT 0, - subscribe_id INTEGER NOT NULL DEFAULT 0, - start_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - expire_time DATETIME DEFAULT NULL, - finished_at DATETIME DEFAULT NULL, - traffic INTEGER DEFAULT 0, - download INTEGER DEFAULT 0, - upload INTEGER DEFAULT 0, - token VARCHAR(255) DEFAULT '' UNIQUE, - uuid VARCHAR(255) DEFAULT '' UNIQUE, - status TINYINT DEFAULT 0, - note VARCHAR(500) DEFAULT '', - created_at DATETIME, - updated_at DATETIME - )`, - `CREATE TABLE IF NOT EXISTS "user_device" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - ip VARCHAR(255) NOT NULL DEFAULT '', - user_id INTEGER NOT NULL DEFAULT 0, - user_agent TEXT, - identifier VARCHAR(255) NOT NULL DEFAULT '' UNIQUE, - short_code VARCHAR(255) NOT NULL DEFAULT '', - online TINYINT NOT NULL DEFAULT 0, - enabled TINYINT NOT NULL DEFAULT 1, - created_at DATETIME, - updated_at DATETIME - )`, - `CREATE TABLE IF NOT EXISTS "user_family" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - owner_user_id INTEGER NOT NULL DEFAULT 0, - max_members INTEGER NOT NULL DEFAULT 2, - status TINYINT DEFAULT 0, - created_at DATETIME, - updated_at DATETIME, - deleted_at DATETIME DEFAULT NULL - )`, - `CREATE TABLE IF NOT EXISTS "user_family_member" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - family_id INTEGER NOT NULL DEFAULT 0, - user_id INTEGER NOT NULL DEFAULT 0, - role TINYINT DEFAULT 0, - status TINYINT DEFAULT 0, - join_source VARCHAR(32) NOT NULL DEFAULT '', - joined_at DATETIME, - left_at DATETIME DEFAULT NULL, - created_at DATETIME, - updated_at DATETIME, - deleted_at DATETIME DEFAULT NULL - )`, - } - for _, sql := range sqls { - require.NoError(t, db.Exec(sql).Error) - } - return db -} - -// setupNewUserOnlyRedis 启动 miniredis,返回 redis.Client 和 miniredis 句柄 -func setupNewUserOnlyRedis(t *testing.T) (*redis.Client, *miniredis.Miniredis) { - t.Helper() - mr, err := miniredis.Run() - require.NoError(t, err) - t.Cleanup(mr.Close) - rds := redis.NewClient(&redis.Options{Addr: mr.Addr()}) - return rds, mr -} - -// buildNewUserOnlySvcCtx 组装最小 ServiceContext(含 asynq Queue 使用 miniredis) -func buildNewUserOnlySvcCtx(db *gorm.DB, rds *redis.Client, mr *miniredis.Miniredis) *svc.ServiceContext { - queue := asynq.NewClient(asynq.RedisClientOpt{Addr: mr.Addr()}) - return &svc.ServiceContext{ - DB: db, - Redis: rds, - UserModel: user.NewModel(db, rds), - OrderModel: modelOrder.NewModel(db, rds), - SubscribeModel: subModel.NewModel(db, rds), - PaymentModel: payment.NewModel(db, rds), - Queue: queue, - } -} - -// insertTestSubscribe 直接用 SQL 插入 subscribe 行(绕过 GORM hook 的 MySQL 方言) -// new_user_only=true 时同时写入 discount JSON,使代码里的 discount 检查生效 -func insertTestSubscribe(t *testing.T, db *gorm.DB, id int64, newUserOnly bool) { - t.Helper() - nuOnly := 0 - discount := "" - if newUserOnly { - nuOnly = 1 - // discount JSON 包含一个 new_user_only=true 的 tier,匹配 quantity=1 - discount = `[{"quantity":1,"discount":90,"new_user_only":true}]` - } - err := db.Exec(`INSERT INTO "subscribe" - (id, name, unit_price, inventory, sell, sort, new_user_only, discount, created_at, updated_at) - VALUES (?, 'Test Plan', 1000, -1, 1, ?, ?, ?, datetime('now'), datetime('now'))`, - id, id, nuOnly, discount).Error - require.NoError(t, err) -} - -// insertTestPayment 插入支付方式行 -func insertTestPayment(t *testing.T, db *gorm.DB, id int64) { - t.Helper() - err := db.Exec(`INSERT INTO "payment" - (id, name, platform, config, enable, fee_mode, token) - VALUES (?, 'Balance', 'balance', '{}', 1, 0, ?)`, - id, "test-token").Error - require.NoError(t, err) -} - -// insertTestUser 插入用户行,createdAt 可控 -func insertTestUser(t *testing.T, db *gorm.DB, id int64, createdAt time.Time) *user.User { - t.Helper() - err := db.Exec(`INSERT INTO "user" - (id, password, balance, gift_amount, enable, created_at, updated_at) - VALUES (?, '', 0, 0, 1, ?, datetime('now'))`, - id, createdAt.UTC().Format("2006-01-02 15:04:05")).Error - require.NoError(t, err) - return &user.User{ - Id: id, - GiftAmount: 0, - CreatedAt: createdAt, - } -} - -func insertTestDevice(t *testing.T, db *gorm.DB, userID int64, identifier string, createdAt time.Time) { - t.Helper() - err := db.Exec(`INSERT INTO "user_device" - (user_id, ip, user_agent, identifier, short_code, online, enabled, created_at, updated_at) - VALUES (?, '127.0.0.1', 'test-agent', ?, '', 0, 1, ?, datetime('now'))`, - userID, - identifier, - createdAt.UTC().Format("2006-01-02 15:04:05"), - ).Error - require.NoError(t, err) -} - -func insertTestFamily(t *testing.T, db *gorm.DB, familyID, ownerUserID int64) { - t.Helper() - err := db.Exec(`INSERT INTO "user_family" - (id, owner_user_id, max_members, status, created_at, updated_at) - VALUES (?, ?, 3, 1, datetime('now'), datetime('now'))`, - familyID, - ownerUserID, - ).Error - require.NoError(t, err) -} - -func insertTestFamilyMember(t *testing.T, db *gorm.DB, familyID, userID int64, role, status uint8, joinSource string) { - t.Helper() - err := db.Exec(`INSERT INTO "user_family_member" - (family_id, user_id, role, status, join_source, joined_at, created_at, updated_at) - VALUES (?, ?, ?, ?, ?, datetime('now'), datetime('now'), datetime('now'))`, - familyID, - userID, - role, - status, - joinSource, - ).Error - require.NoError(t, err) -} - -// insertTestOrder 插入一条历史订单(status=2 表示已支付) -func insertTestOrder(t *testing.T, db *gorm.DB, userID, subscribeID int64, status uint8) { - t.Helper() - err := db.Exec(`INSERT INTO "order" - (user_id, order_no, type, status, subscribe_id, created_at, updated_at) - VALUES (?, ?, 1, ?, ?, datetime('now'), datetime('now'))`, - userID, "existing-order-no", status, subscribeID).Error - require.NoError(t, err) -} - -func insertScopedTestOrder(t *testing.T, db *gorm.DB, orderNo string, userID, subscribeID int64, status uint8) { - t.Helper() - err := db.Exec(`INSERT INTO "order" - (user_id, order_no, type, status, subscribe_id, created_at, updated_at) - VALUES (?, ?, 1, ?, ?, datetime('now'), datetime('now'))`, - userID, orderNo, status, subscribeID).Error - require.NoError(t, err) -} - -// buildPurchaseCtx 把 user 放入 context(模拟中间件行为) -func buildPurchaseCtx(u *user.User) context.Context { - return context.WithValue(context.Background(), constant.CtxKeyUser, u) -} - -// TestPurchase_NewUserOnly_UserTooOld 验证:new_user_only=true,用户注册超过 24h → 返回 SubscribeNewUserOnly -func TestPurchase_NewUserOnly_UserTooOld(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const subID = int64(1) - const payID = int64(1) - - insertTestSubscribe(t, db, subID, true) // new_user_only = true - insertTestPayment(t, db, payID) - - // 用户注册 48 小时前 → 超出 24h 限制 - u := insertTestUser(t, db, 100, time.Now().Add(-48*time.Hour)) - ctx := buildPurchaseCtx(u) - - logic := NewPurchaseLogic(ctx, svcCtx) - _, err := logic.Purchase(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Payment: payID, - Quantity: 1, - }) - - require.Error(t, err) - var errCode *xerr.CodeError - require.ErrorAs(t, err, &errCode) - assert.Equal(t, xerr.SubscribeNewUserOnly, errCode.GetErrCode(), - "注册超过24h应返回 SubscribeNewUserOnly 错误码") - - // 验证订单未被创建 - var count int64 - db.Model(&modelOrder.Order{}).Where("user_id = ?", u.Id).Count(&count) - assert.Equal(t, int64(0), count, "用户注册超时,订单不应被创建") -} - -// TestPurchase_NewUserOnly_AlreadyPurchased 验证:new_user_only=true,用户是新用户但已购买过 -// → 允许下单(不拦截),但不享受新人折扣 -func TestPurchase_NewUserOnly_AlreadyPurchased(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const subID = int64(2) - const payID = int64(1) - - insertTestSubscribe(t, db, subID, true) - insertTestPayment(t, db, payID) - - // 用户刚注册(2h前)→ 满足时间条件 - u := insertTestUser(t, db, 200, time.Now().Add(-2*time.Hour)) - - // 但已有一条 status=2 的历史订单(已支付) - insertTestOrder(t, db, u.Id, subID, 2) - - ctx := buildPurchaseCtx(u) - logic := NewPurchaseLogic(ctx, svcCtx) - resp, err := logic.Purchase(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Payment: payID, - Quantity: 1, - }) - - // 不应被拦截,允许下单 - require.NoError(t, err, "24h内已购用户应允许继续下单,不应返回错误") - require.NotNil(t, resp) - assert.NotEmpty(t, resp.OrderNo) - - // 历史订单 +1(新增了一条) - var count int64 - db.Model(&modelOrder.Order{}).Where("user_id = ?", u.Id).Count(&count) - assert.Equal(t, int64(2), count, "应新增一条订单") - - // 新订单无折扣:Amount=Price=1000 - var newOrder modelOrder.Order - require.NoError(t, db.Where("order_no = ?", resp.OrderNo).First(&newOrder).Error) - assert.Equal(t, int64(1000), newOrder.Amount, "已购用户不享受新人折扣,Amount 应等于 Price") - assert.Equal(t, int64(0), newOrder.Discount, "Discount 应为 0") -} - -// TestPurchase_NewUserOnly_Success 验证:new_user_only=true,新用户首次购买 → 成功创建订单 -func TestPurchase_NewUserOnly_Success(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const subID = int64(3) - const payID = int64(1) - - insertTestSubscribe(t, db, subID, true) - insertTestPayment(t, db, payID) - - // 用户 1 小时前注册(新用户),且没有历史订单 - u := insertTestUser(t, db, 300, time.Now().Add(-1*time.Hour)) - ctx := buildPurchaseCtx(u) - - logic := NewPurchaseLogic(ctx, svcCtx) - resp, err := logic.Purchase(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Payment: payID, - Quantity: 1, - }) - - require.NoError(t, err) - require.NotNil(t, resp) - assert.NotEmpty(t, resp.OrderNo, "新用户首次购买应成功,返回订单号") - - // 验证订单已写入数据库 - var o modelOrder.Order - err = db.Where("order_no = ?", resp.OrderNo).First(&o).Error - require.NoError(t, err) - assert.Equal(t, u.Id, o.UserId) - assert.Equal(t, subID, o.SubscribeId) -} - -// TestPurchase_NewUserOnly_Disabled 验证:new_user_only=false 时,老用户也能正常购买 -func TestPurchase_NewUserOnly_Disabled(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const subID = int64(4) - const payID = int64(1) - - insertTestSubscribe(t, db, subID, false) // new_user_only = false - insertTestPayment(t, db, payID) - - // 注册 30 天的老用户 - u := insertTestUser(t, db, 400, time.Now().Add(-30*24*time.Hour)) - ctx := buildPurchaseCtx(u) - - logic := NewPurchaseLogic(ctx, svcCtx) - resp, err := logic.Purchase(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Payment: payID, - Quantity: 1, - }) - - require.NoError(t, err) - require.NotNil(t, resp) - assert.NotEmpty(t, resp.OrderNo, "new_user_only=false时老用户应能正常购买") -} - -// TestPurchase_SingleMode_PendingOldOrderCancelled 验证:单订阅模式下,已有 pending 订单时 -// 第二次下单应关闭旧单并创建新单(而非复用旧单) -func TestPurchase_SingleMode_PendingOldOrderCancelled(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - svcCtx.Config.Subscribe.SingleModel = true - - const subID = int64(5) - const payID = int64(1) - - insertTestSubscribe(t, db, subID, false) - insertTestPayment(t, db, payID) - - u := insertTestUser(t, db, 500, time.Now().Add(-1*time.Hour)) - ctx := buildPurchaseCtx(u) - - // 第一次下单(pending) - logic := NewPurchaseLogic(ctx, svcCtx) - resp1, err := logic.Purchase(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Payment: payID, - Quantity: 1, - }) - require.NoError(t, err) - require.NotNil(t, resp1) - firstOrderNo := resp1.OrderNo - assert.NotEmpty(t, firstOrderNo) - - // 确认第一单 pending - var firstOrder modelOrder.Order - require.NoError(t, db.Where("order_no = ?", firstOrderNo).First(&firstOrder).Error) - assert.Equal(t, uint8(1), firstOrder.Status, "第一单应为 pending") - - // 第二次下单(不同 quantity) - logic2 := NewPurchaseLogic(ctx, svcCtx) - resp2, err := logic2.Purchase(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Payment: payID, - Quantity: 3, - }) - require.NoError(t, err) - require.NotNil(t, resp2) - secondOrderNo := resp2.OrderNo - - // 新单与旧单不同 - assert.NotEqual(t, firstOrderNo, secondOrderNo, "第二次下单应创建新订单,不复用旧单") - - // 旧单应被关闭(status=3) - var closedOrder modelOrder.Order - require.NoError(t, db.Where("order_no = ?", firstOrderNo).First(&closedOrder).Error) - assert.Equal(t, uint8(3), closedOrder.Status, "旧 pending 单应被关闭") - - // 新单的 quantity 应为 3 - var newOrder modelOrder.Order - require.NoError(t, db.Where("order_no = ?", secondOrderNo).First(&newOrder).Error) - assert.Equal(t, int64(3), newOrder.Quantity, "新单 quantity 应为 3") - assert.Equal(t, uint8(1), newOrder.Status, "新单应为 pending 状态") -} - -// TestPurchase_SingleMode_NoPendingOrder 验证:单订阅模式下,没有旧 pending 单时正常创建 -func TestPurchase_SingleMode_NoPendingOrder(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - svcCtx.Config.Subscribe.SingleModel = true - - const subID = int64(6) - const payID = int64(1) - - insertTestSubscribe(t, db, subID, false) - insertTestPayment(t, db, payID) - - u := insertTestUser(t, db, 600, time.Now().Add(-1*time.Hour)) - ctx := buildPurchaseCtx(u) - - logic := NewPurchaseLogic(ctx, svcCtx) - resp, err := logic.Purchase(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Payment: payID, - Quantity: 2, - }) - require.NoError(t, err) - require.NotNil(t, resp) - assert.NotEmpty(t, resp.OrderNo, "无旧 pending 单时应正常创建新单") - - var o modelOrder.Order - require.NoError(t, db.Where("order_no = ?", resp.OrderNo).First(&o).Error) - assert.Equal(t, int64(2), o.Quantity) - assert.Equal(t, uint8(1), o.Status) -} - -// TestPurchase_NewUserOnly_AlreadyPurchased_NoBlock 验证:new_user_only=true 套餐, -// 24小时内但已购买过 → 允许下单,但不享受新人折扣(Discount=0,Amount=Price) -func TestPurchase_NewUserOnly_AlreadyPurchased_NoBlock(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const subID = int64(7) - const payID = int64(1) - - // 套餐:unit_price=1000,discount=[{quantity:1,discount:80,new_user_only:true}] - insertTestSubscribe(t, db, subID, true) - insertTestPayment(t, db, payID) - - // 用户 1 小时前注册(新用户),但已有一条成功订单(status=2) - u := insertTestUser(t, db, 700, time.Now().Add(-1*time.Hour)) - insertTestOrder(t, db, u.Id, subID, 2) - - ctx := buildPurchaseCtx(u) - logic := NewPurchaseLogic(ctx, svcCtx) - resp, err := logic.Purchase(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Payment: payID, - Quantity: 1, - }) - - // 不应被拦截 - require.NoError(t, err, "24h内已购用户不应被拦截,应允许下单") - require.NotNil(t, resp) - assert.NotEmpty(t, resp.OrderNo) - - // 验证订单金额:无折扣,Amount=Price=1000,Discount=0 - var newOrder modelOrder.Order - require.NoError(t, db.Where("order_no = ?", resp.OrderNo).First(&newOrder).Error) - assert.Equal(t, int64(1000), newOrder.Price, "Price 应为原价 1000") - assert.Equal(t, int64(1000), newOrder.Amount, "已购用户不享受新人折扣,Amount 应等于 Price") - assert.Equal(t, int64(0), newOrder.Discount, "Discount 应为 0") -} - -// TestPurchase_NewUserOnly_FirstPurchase_HasDiscount 验证:new_user_only=true 套餐, -// 24小时内首次购买 → 允许下单且享受新人折扣 -func TestPurchase_NewUserOnly_FirstPurchase_HasDiscount(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const subID = int64(8) - const payID = int64(1) - - // 套餐:unit_price=1000,discount=[{quantity:1,discount:80,new_user_only:true}](8折) - insertTestSubscribe(t, db, subID, true) - insertTestPayment(t, db, payID) - - // 用户 1 小时前注册,无历史订单 - u := insertTestUser(t, db, 800, time.Now().Add(-1*time.Hour)) - ctx := buildPurchaseCtx(u) - - logic := NewPurchaseLogic(ctx, svcCtx) - resp, err := logic.Purchase(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Payment: payID, - Quantity: 1, - }) - - require.NoError(t, err) - require.NotNil(t, resp) - - var newOrder modelOrder.Order - require.NoError(t, db.Where("order_no = ?", resp.OrderNo).First(&newOrder).Error) - assert.Equal(t, int64(1000), newOrder.Price, "Price 应为原价 1000") - assert.Equal(t, int64(900), newOrder.Amount, "首次购买应享受9折,Amount=900") - assert.Equal(t, int64(100), newOrder.Discount, "折扣金额应为 100") -} - -func TestPurchase_NewUserOnly_BindEmailScopeUsesEarliestDeviceTime(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const ( - subID = int64(9) - payID = int64(1) - ownerUserID = int64(901) - memberUserID = int64(902) - familyID = int64(99) - ) - - insertTestSubscribe(t, db, subID, true) - insertTestPayment(t, db, payID) - - owner := insertTestUser(t, db, ownerUserID, time.Now().Add(-1*time.Hour)) - insertTestUser(t, db, memberUserID, time.Now().Add(-72*time.Hour)) - insertTestDevice(t, db, memberUserID, "device-eligibility-old", time.Now().Add(-72*time.Hour)) - insertTestFamily(t, db, familyID, ownerUserID) - insertTestFamilyMember(t, db, familyID, ownerUserID, user.FamilyRoleOwner, user.FamilyMemberActive, "owner_init") - insertTestFamilyMember(t, db, familyID, memberUserID, user.FamilyRoleMember, user.FamilyMemberActive, "bind_email_with_verification") - - logic := NewPurchaseLogic(buildPurchaseCtx(owner), svcCtx) - _, err := logic.Purchase(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Payment: payID, - Quantity: 1, - }) - - require.Error(t, err) - var errCode *xerr.CodeError - require.ErrorAs(t, err, &errCode) - assert.Equal(t, xerr.SubscribeNewUserOnly, errCode.GetErrCode()) -} - -func TestPurchase_NewUserOnly_BindEmailScopeSharesHistory(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const ( - subID = int64(10) - payID = int64(1) - ownerUserID = int64(1001) - memberUserID = int64(1002) - familyID = int64(109) - ) - - insertTestSubscribe(t, db, subID, true) - insertTestPayment(t, db, payID) - - owner := insertTestUser(t, db, ownerUserID, time.Now().Add(-1*time.Hour)) - insertTestUser(t, db, memberUserID, time.Now().Add(-2*time.Hour)) - insertTestDevice(t, db, memberUserID, "device-eligibility-shared", time.Now().Add(-2*time.Hour)) - insertTestFamily(t, db, familyID, ownerUserID) - insertTestFamilyMember(t, db, familyID, ownerUserID, user.FamilyRoleOwner, user.FamilyMemberActive, "owner_init") - insertTestFamilyMember(t, db, familyID, memberUserID, user.FamilyRoleMember, user.FamilyMemberActive, "bind_email_with_verification") - insertScopedTestOrder(t, db, "existing-scope-order", memberUserID, subID, 2) - - logic := NewPurchaseLogic(buildPurchaseCtx(owner), svcCtx) - resp, err := logic.Purchase(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Payment: payID, - Quantity: 1, - }) - - require.NoError(t, err) - require.NotNil(t, resp) - - var newOrder modelOrder.Order - require.NoError(t, db.Where("order_no = ?", resp.OrderNo).First(&newOrder).Error) - assert.Equal(t, int64(1000), newOrder.Amount) - assert.Equal(t, int64(0), newOrder.Discount) -} - -func ensureRenewalSubscribeColumns(t *testing.T, db *gorm.DB) { - t.Helper() - for _, sql := range []string{ - `ALTER TABLE "user_subscribe" ADD COLUMN node_group_id INTEGER NOT NULL DEFAULT 0`, - `ALTER TABLE "user_subscribe" ADD COLUMN group_locked TINYINT NOT NULL DEFAULT 0`, - `ALTER TABLE "user_subscribe" ADD COLUMN expired_download INTEGER NOT NULL DEFAULT 0`, - `ALTER TABLE "user_subscribe" ADD COLUMN expired_upload INTEGER NOT NULL DEFAULT 0`, - } { - require.NoError(t, db.Exec(sql).Error) - } -} - -func insertRenewalUserSubscribe(t *testing.T, db *gorm.DB, id, userID, orderID, subscribeID int64, token, uuid string, start, expire time.Time) { - t.Helper() - require.NoError(t, db.Exec(`INSERT INTO "user_subscribe" - (id, user_id, order_id, subscribe_id, start_time, expire_time, traffic, download, upload, token, uuid, status, created_at, updated_at) - VALUES (?, ?, ?, ?, ?, ?, 0, 0, 0, ?, ?, 1, ?, ?)`, - id, - userID, - orderID, - subscribeID, - start.UTC().Format("2006-01-02 15:04:05"), - expire.UTC().Format("2006-01-02 15:04:05"), - token, - uuid, - start.UTC().Format("2006-01-02 15:04:05"), - time.Now().UTC().Format("2006-01-02 15:04:05"), - ).Error) -} - -func TestRenewalMemberRequestRedirectsToOwnerSubscribe(t *testing.T) { - db := setupNewUserOnlyDB(t) - ensureRenewalSubscribeColumns(t, db) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const ( - planID = int64(1) - paymentID = int64(2) - ownerUserID = int64(29650) - memberID = int64(20003) - familyID = int64(88001) - memberSubID = int64(10013) - ownerSubID = int64(14074) - ) - - insertTestSubscribe(t, db, planID, false) - insertTestPayment(t, db, paymentID) - member := insertTestUser(t, db, memberID, time.Now().Add(-24*time.Hour)) - insertTestUser(t, db, ownerUserID, time.Now().Add(-24*time.Hour)) - insertTestFamily(t, db, familyID, ownerUserID) - insertTestFamilyMember(t, db, familyID, ownerUserID, user.FamilyRoleOwner, user.FamilyMemberActive, "owner_init") - insertTestFamilyMember(t, db, familyID, memberID, user.FamilyRoleMember, user.FamilyMemberActive, "manual_invite") - - insertRenewalUserSubscribe(t, db, memberSubID, memberID, 7448, planID, "member-token-10013", "member-uuid-10013", - time.Date(2026, 4, 23, 19, 6, 40, 0, time.UTC), - time.Date(2026, 4, 30, 19, 6, 40, 0, time.UTC), - ) - insertRenewalUserSubscribe(t, db, ownerSubID, ownerUserID, 9999, planID, "owner-token-14074", "owner-uuid-14074", - time.Date(2026, 4, 30, 13, 39, 33, 0, time.UTC), - time.Date(2026, 5, 30, 16, 0, 0, 0, time.UTC), - ) - - resp, err := NewRenewalLogic(buildPurchaseCtx(member), svcCtx).Renewal(&types.RenewalOrderRequest{ - UserSubscribeID: memberSubID, - Payment: paymentID, - Quantity: 30, - }) - require.NoError(t, err) - require.NotNil(t, resp) - - var created modelOrder.Order - require.NoError(t, db.Where("order_no = ?", resp.OrderNo).First(&created).Error) - assert.Equal(t, memberID, created.UserId) - assert.Equal(t, ownerUserID, created.SubscriptionUserId) - assert.Equal(t, int64(9999), created.ParentId) - assert.Equal(t, "owner-token-14074", created.SubscribeToken) -} - -func TestPreCreateOrder_NewUserOnly_BindEmailScopeUsesEarliestDeviceTime(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const ( - subID = int64(11) - ownerUserID = int64(1101) - memberUserID = int64(1102) - familyID = int64(119) - ) - - insertTestSubscribe(t, db, subID, true) - - owner := insertTestUser(t, db, ownerUserID, time.Now().Add(-1*time.Hour)) - insertTestUser(t, db, memberUserID, time.Now().Add(-96*time.Hour)) - insertTestDevice(t, db, memberUserID, "device-precreate-old", time.Now().Add(-96*time.Hour)) - insertTestFamily(t, db, familyID, ownerUserID) - insertTestFamilyMember(t, db, familyID, ownerUserID, user.FamilyRoleOwner, user.FamilyMemberActive, "owner_init") - insertTestFamilyMember(t, db, familyID, memberUserID, user.FamilyRoleMember, user.FamilyMemberActive, "bind_email_with_verification") - - logic := NewPreCreateOrderLogic(buildPurchaseCtx(owner), svcCtx) - _, err := logic.PreCreateOrder(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Quantity: 1, - }) - - require.Error(t, err) - var errCode *xerr.CodeError - require.ErrorAs(t, err, &errCode) - assert.Equal(t, xerr.SubscribeNewUserOnly, errCode.GetErrCode()) -} - -func TestPreCreateOrder_NewUserOnly_OrdinaryFamilyMemberDoesNotAffectEligibility(t *testing.T) { - db := setupNewUserOnlyDB(t) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const ( - subID = int64(12) - ownerUserID = int64(1201) - memberUserID = int64(1202) - familyID = int64(129) - ) - - insertTestSubscribe(t, db, subID, true) - - owner := insertTestUser(t, db, ownerUserID, time.Now().Add(-1*time.Hour)) - insertTestUser(t, db, memberUserID, time.Now().Add(-96*time.Hour)) - insertTestDevice(t, db, memberUserID, "device-precreate-ordinary", time.Now().Add(-96*time.Hour)) - insertTestFamily(t, db, familyID, ownerUserID) - insertTestFamilyMember(t, db, familyID, ownerUserID, user.FamilyRoleOwner, user.FamilyMemberActive, "owner_init") - insertTestFamilyMember(t, db, familyID, memberUserID, user.FamilyRoleMember, user.FamilyMemberActive, "manual_invite") - - logic := NewPreCreateOrderLogic(buildPurchaseCtx(owner), svcCtx) - resp, err := logic.PreCreateOrder(&types.PurchaseOrderRequest{ - SubscribeId: subID, - Quantity: 1, - }) - - require.NoError(t, err) - require.NotNil(t, resp) - assert.Equal(t, int64(900), resp.Amount) - assert.Equal(t, int64(100), resp.Discount) -} diff --git a/internal/logic/public/order/renewalInviteFirstPurchase_test.go b/internal/logic/public/order/renewalInviteFirstPurchase_test.go deleted file mode 100644 index 86e4665..0000000 --- a/internal/logic/public/order/renewalInviteFirstPurchase_test.go +++ /dev/null @@ -1,130 +0,0 @@ -package order - -import ( - "testing" - "time" - - modelOrder "github.com/perfect-panel/server/internal/model/order" - "github.com/perfect-panel/server/internal/model/user" - "github.com/perfect-panel/server/internal/types" - "github.com/stretchr/testify/require" - "gorm.io/gorm" -) - -func ensureRenewalInviteSubscribeColumns(t *testing.T, db *gorm.DB) { - t.Helper() - for _, sql := range []string{ - `ALTER TABLE "user_subscribe" ADD COLUMN node_group_id INTEGER NOT NULL DEFAULT 0`, - `ALTER TABLE "user_subscribe" ADD COLUMN group_locked TINYINT NOT NULL DEFAULT 0`, - `ALTER TABLE "user_subscribe" ADD COLUMN expired_download INTEGER NOT NULL DEFAULT 0`, - `ALTER TABLE "user_subscribe" ADD COLUMN expired_upload INTEGER NOT NULL DEFAULT 0`, - } { - require.NoError(t, db.Exec(sql).Error) - } -} - -func insertRenewalInviteUserSubscribe(t *testing.T, db *gorm.DB, id, userID, orderID, subscribeID int64, token, uuid string, start, expire time.Time) { - t.Helper() - require.NoError(t, db.Exec(`INSERT INTO "user_subscribe" - (id, user_id, order_id, subscribe_id, start_time, expire_time, traffic, download, upload, token, uuid, status, created_at, updated_at) - VALUES (?, ?, ?, ?, ?, ?, 0, 0, 0, ?, ?, 1, ?, ?)`, - id, - userID, - orderID, - subscribeID, - start.UTC().Format("2006-01-02 15:04:05"), - expire.UTC().Format("2006-01-02 15:04:05"), - token, - uuid, - start.UTC().Format("2006-01-02 15:04:05"), - time.Now().UTC().Format("2006-01-02 15:04:05"), - ).Error) -} - -func TestRenewalFirstSuccessfulPaymentMarksOrderAsNew(t *testing.T) { - db := setupNewUserOnlyDB(t) - ensureRenewalInviteSubscribeColumns(t, db) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const ( - planID = int64(1) - paymentID = int64(2) - ownerUserID = int64(31059) - memberID = int64(31057) - familyID = int64(5638) - ownerSubID = int64(14672) - ) - - insertTestSubscribe(t, db, planID, false) - insertTestPayment(t, db, paymentID) - member := insertTestUser(t, db, memberID, time.Now().Add(-2*time.Hour)) - insertTestUser(t, db, ownerUserID, time.Now().Add(-2*time.Hour)) - insertTestFamily(t, db, familyID, ownerUserID) - insertTestFamilyMember(t, db, familyID, ownerUserID, user.FamilyRoleOwner, user.FamilyMemberActive, "owner_init") - insertTestFamilyMember(t, db, familyID, memberID, user.FamilyRoleMember, user.FamilyMemberActive, "bind_email_with_verification") - - insertRenewalInviteUserSubscribe(t, db, ownerSubID, ownerUserID, 0, planID, "owner-trial-token", "owner-trial-uuid", - time.Date(2026, 5, 2, 15, 53, 39, 0, time.UTC), - time.Date(2026, 5, 9, 0, 0, 0, 0, time.UTC), - ) - - resp, err := NewRenewalLogic(buildPurchaseCtx(member), svcCtx).Renewal(&types.RenewalOrderRequest{ - UserSubscribeID: ownerSubID, - Payment: paymentID, - Quantity: 1, - }) - require.NoError(t, err) - require.NotNil(t, resp) - - var created modelOrder.Order - require.NoError(t, db.Where("order_no = ?", resp.OrderNo).First(&created).Error) - require.Equal(t, uint8(2), created.Type) - require.True(t, created.IsNew) - require.Equal(t, memberID, created.UserId) - require.Equal(t, ownerUserID, created.SubscriptionUserId) - require.Equal(t, "owner-trial-token", created.SubscribeToken) -} - -func TestRenewalExistingSuccessfulPaymentMarksOrderAsNotNew(t *testing.T) { - db := setupNewUserOnlyDB(t) - ensureRenewalInviteSubscribeColumns(t, db) - rds, mr := setupNewUserOnlyRedis(t) - svcCtx := buildNewUserOnlySvcCtx(db, rds, mr) - - const ( - planID = int64(1) - paymentID = int64(2) - ownerUserID = int64(41059) - memberID = int64(41057) - familyID = int64(6638) - ownerSubID = int64(24672) - ) - - insertTestSubscribe(t, db, planID, false) - insertTestPayment(t, db, paymentID) - member := insertTestUser(t, db, memberID, time.Now().Add(-2*time.Hour)) - insertTestUser(t, db, ownerUserID, time.Now().Add(-2*time.Hour)) - insertTestFamily(t, db, familyID, ownerUserID) - insertTestFamilyMember(t, db, familyID, ownerUserID, user.FamilyRoleOwner, user.FamilyMemberActive, "owner_init") - insertTestFamilyMember(t, db, familyID, memberID, user.FamilyRoleMember, user.FamilyMemberActive, "bind_email_with_verification") - insertScopedTestOrder(t, db, "previous-successful-order", memberID, planID, 5) - - insertRenewalInviteUserSubscribe(t, db, ownerSubID, ownerUserID, 0, planID, "owner-renewal-token", "owner-renewal-uuid", - time.Date(2026, 5, 2, 15, 53, 39, 0, time.UTC), - time.Date(2026, 5, 9, 0, 0, 0, 0, time.UTC), - ) - - resp, err := NewRenewalLogic(buildPurchaseCtx(member), svcCtx).Renewal(&types.RenewalOrderRequest{ - UserSubscribeID: ownerSubID, - Payment: paymentID, - Quantity: 1, - }) - require.NoError(t, err) - require.NotNil(t, resp) - - var created modelOrder.Order - require.NoError(t, db.Where("order_no = ?", resp.OrderNo).First(&created).Error) - require.Equal(t, uint8(2), created.Type) - require.False(t, created.IsNew) -} diff --git a/internal/logic/public/user/familyBindingHelper_test.go b/internal/logic/public/user/familyBindingHelper_test.go deleted file mode 100644 index 76a6df8..0000000 --- a/internal/logic/public/user/familyBindingHelper_test.go +++ /dev/null @@ -1,288 +0,0 @@ -package user - -import ( - "testing" - "time" - - modelOrder "github.com/perfect-panel/server/internal/model/order" - modelUser "github.com/perfect-panel/server/internal/model/user" - "gorm.io/driver/sqlite" - "gorm.io/gorm" - "gorm.io/gorm/logger" -) - -func newFamilyBindingTestDB(t *testing.T) *gorm.DB { - t.Helper() - - db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{ - DisableForeignKeyConstraintWhenMigrating: true, - Logger: logger.Default.LogMode(logger.Silent), - }) - if err != nil { - t.Fatalf("open sqlite db: %v", err) - } - if err = db.Exec(` -CREATE TABLE user_subscribe ( - id integer primary key, - user_id integer not null, - order_id integer not null, - subscribe_id integer not null, - start_time datetime, - expire_time datetime, - token text, - uuid text, - status integer, - created_at datetime, - updated_at datetime -)`).Error; err != nil { - t.Fatalf("create user_subscribe schema: %v", err) - } - if err = db.Exec(` -CREATE TABLE "order" ( - id integer primary key, - user_id integer not null, - subscription_user_id integer not null, - order_no text, - subscribe_token text, - status integer, - subscribe_id integer, - created_at datetime, - updated_at datetime -)`).Error; err != nil { - t.Fatalf("create order schema: %v", err) - } - return db -} - -func insertFamilyBindingTestOrder(t *testing.T, db *gorm.DB, order modelOrder.Order) { - t.Helper() - - if err := db.Exec(` -INSERT INTO "order" ( - id, user_id, subscription_user_id, order_no, subscribe_token, status, subscribe_id, created_at, updated_at -) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, - order.Id, - order.UserId, - order.SubscriptionUserId, - order.OrderNo, - order.SubscribeToken, - order.Status, - order.SubscribeId, - order.CreatedAt, - order.UpdatedAt, - ).Error; err != nil { - t.Fatalf("insert order %d: %v", order.Id, err) - } -} - -func insertFamilyBindingTestSubscribe(t *testing.T, db *gorm.DB, sub modelUser.Subscribe) { - t.Helper() - - if err := db.Exec(` -INSERT INTO user_subscribe ( - id, user_id, order_id, subscribe_id, start_time, expire_time, token, uuid, status, created_at, updated_at -) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - sub.Id, - sub.UserId, - sub.OrderId, - sub.SubscribeId, - sub.StartTime, - sub.ExpireTime, - sub.Token, - sub.UUID, - sub.Status, - sub.CreatedAt, - sub.UpdatedAt, - ).Error; err != nil { - t.Fatalf("insert subscribe %d: %v", sub.Id, err) - } -} - -func TestMoveMemberSubscribesToOwnerMovesSubscribeAndCurrentOrder(t *testing.T) { - db := newFamilyBindingTestDB(t) - memberUserID := int64(1001) - ownerUserID := int64(2001) - now := time.Now().Add(-time.Hour) - expireAt := now.Add(30 * 24 * time.Hour) - - currentOrder := modelOrder.Order{ - Id: 9001, - UserId: memberUserID, - SubscriptionUserId: memberUserID, - OrderNo: "order-current", - SubscribeToken: "token-current", - Status: 5, - SubscribeId: 3001, - CreatedAt: now, - UpdatedAt: now, - } - unlinkedOrder := modelOrder.Order{ - Id: 9002, - UserId: memberUserID, - SubscriptionUserId: memberUserID, - OrderNo: "order-unlinked", - SubscribeToken: "token-unlinked", - Status: 5, - SubscribeId: 3001, - CreatedAt: now, - UpdatedAt: now, - } - sub := modelUser.Subscribe{ - Id: 7001, - UserId: memberUserID, - OrderId: currentOrder.Id, - SubscribeId: currentOrder.SubscribeId, - StartTime: now, - ExpireTime: expireAt, - Token: "token-current", - UUID: "uuid-current", - Status: 1, - CreatedAt: now, - UpdatedAt: now, - } - insertFamilyBindingTestOrder(t, db, currentOrder) - insertFamilyBindingTestOrder(t, db, unlinkedOrder) - insertFamilyBindingTestSubscribe(t, db, sub) - - var moved []modelUser.Subscribe - if err := db.Transaction(func(tx *gorm.DB) error { - var err error - moved, err = moveMemberSubscribesToOwner(tx, memberUserID, ownerUserID) - return err - }); err != nil { - t.Fatalf("move member subscribes: %v", err) - } - - if len(moved) != 1 { - t.Fatalf("moved subscribes length = %d, want 1", len(moved)) - } - if moved[0].UserId != memberUserID { - t.Fatalf("moved cache copy user_id = %d, want original member %d", moved[0].UserId, memberUserID) - } - - var gotSub modelUser.Subscribe - if err := db.First(&gotSub, "id = ?", sub.Id).Error; err != nil { - t.Fatalf("query moved subscribe: %v", err) - } - if gotSub.UserId != ownerUserID { - t.Fatalf("subscribe user_id = %d, want owner %d", gotSub.UserId, ownerUserID) - } - if gotSub.Token == "" || gotSub.Token == sub.Token { - t.Fatalf("subscribe token = %q, want regenerated from old token %q", gotSub.Token, sub.Token) - } - if gotSub.UUID == "" || gotSub.UUID == sub.UUID { - t.Fatalf("subscribe uuid = %q, want regenerated from old uuid %q", gotSub.UUID, sub.UUID) - } - - var gotOrder modelOrder.Order - if err := db.First(&gotOrder, "id = ?", currentOrder.Id).Error; err != nil { - t.Fatalf("query updated order: %v", err) - } - if gotOrder.SubscriptionUserId != ownerUserID { - t.Fatalf("current order subscription_user_id = %d, want owner %d", gotOrder.SubscriptionUserId, ownerUserID) - } - if gotOrder.SubscribeToken != gotSub.Token { - t.Fatalf("current order subscribe_token = %q, want regenerated subscribe token %q", gotOrder.SubscribeToken, gotSub.Token) - } - - var gotUnlinkedOrder modelOrder.Order - if err := db.First(&gotUnlinkedOrder, "id = ?", unlinkedOrder.Id).Error; err != nil { - t.Fatalf("query unlinked order: %v", err) - } - if gotUnlinkedOrder.SubscriptionUserId != memberUserID { - t.Fatalf("unlinked order subscription_user_id = %d, want unchanged member %d", gotUnlinkedOrder.SubscriptionUserId, memberUserID) - } - if gotUnlinkedOrder.SubscribeToken != unlinkedOrder.SubscribeToken { - t.Fatalf("unlinked order subscribe_token = %q, want unchanged token %q", gotUnlinkedOrder.SubscribeToken, unlinkedOrder.SubscribeToken) - } -} - -func TestMoveMemberSubscribesToOwnerNoSubscribesIsNoop(t *testing.T) { - db := newFamilyBindingTestDB(t) - - var moved []modelUser.Subscribe - if err := db.Transaction(func(tx *gorm.DB) error { - var err error - moved, err = moveMemberSubscribesToOwner(tx, 1001, 2001) - return err - }); err != nil { - t.Fatalf("move empty member subscribes: %v", err) - } - if len(moved) != 0 { - t.Fatalf("moved subscribes length = %d, want 0", len(moved)) - } -} - -func TestTransferMemberSubscribesToOwnerStillDiscardsMemberSubscribes(t *testing.T) { - db := newFamilyBindingTestDB(t) - memberUserID := int64(1001) - ownerUserID := int64(2001) - now := time.Now().Add(-time.Hour) - - order := modelOrder.Order{ - Id: 9001, - UserId: memberUserID, - SubscriptionUserId: memberUserID, - OrderNo: "order-discard", - SubscribeToken: "token-discard", - Status: 5, - SubscribeId: 3001, - CreatedAt: now, - UpdatedAt: now, - } - sub := modelUser.Subscribe{ - Id: 7001, - UserId: memberUserID, - OrderId: order.Id, - SubscribeId: order.SubscribeId, - StartTime: now, - ExpireTime: now.Add(30 * 24 * time.Hour), - Token: "token-discard", - UUID: "uuid-discard", - Status: 1, - CreatedAt: now, - UpdatedAt: now, - } - insertFamilyBindingTestOrder(t, db, order) - insertFamilyBindingTestSubscribe(t, db, sub) - - var removed []modelUser.Subscribe - if err := db.Transaction(func(tx *gorm.DB) error { - var err error - removed, err = transferMemberSubscribesToOwner(tx, memberUserID, ownerUserID) - return err - }); err != nil { - t.Fatalf("discard member subscribes: %v", err) - } - - if len(removed) != 1 { - t.Fatalf("removed subscribes length = %d, want 1", len(removed)) - } - if removed[0].UserId != memberUserID { - t.Fatalf("removed cache copy user_id = %d, want original member %d", removed[0].UserId, memberUserID) - } - - var memberCount int64 - if err := db.Model(&modelUser.Subscribe{}).Where("user_id = ?", memberUserID).Count(&memberCount).Error; err != nil { - t.Fatalf("count member subscribes: %v", err) - } - if memberCount != 0 { - t.Fatalf("member subscribe count = %d, want 0", memberCount) - } - - var ownerCount int64 - if err := db.Model(&modelUser.Subscribe{}).Where("user_id = ?", ownerUserID).Count(&ownerCount).Error; err != nil { - t.Fatalf("count owner subscribes: %v", err) - } - if ownerCount != 0 { - t.Fatalf("owner subscribe count = %d, want 0", ownerCount) - } - - var gotOrder modelOrder.Order - if err := db.First(&gotOrder, "id = ?", order.Id).Error; err != nil { - t.Fatalf("query order: %v", err) - } - if gotOrder.SubscriptionUserId != memberUserID { - t.Fatalf("discard path order subscription_user_id = %d, want unchanged member %d", gotOrder.SubscriptionUserId, memberUserID) - } -} diff --git a/log.txt b/log.txt deleted file mode 100644 index 208636e..0000000 --- a/log.txt +++ /dev/null @@ -1,169 +0,0 @@ -跳至主要内容 - -Grafana -探索 -Loki -搜索... -⌘+k - - -User avatar -探索 - -轮廓 -Loki logo -Loki - -转到无查询 - -拆分 - -添加 - - -过去 24 小时 - - - -运行查询 - - -分享 - - -直播 - - - - - -A -(Loki) - - - - - -Kick start your query - -Label browser -Explain query - - - -{container="ppanel-server"} |= "10013" |= "user_subscribe" - -Options -Type: Range -Line limit: 1000 -Direction: Backward -This query will process approximately 20.3 GiB. - - -添加查询 - -查询历史记录 - -查询检查器 - -日志卷 -info -Total: 717 -Loki -日志 - - -717 lines displayed -已处理的总字节数: -23.4 GB -Common labels: -container=ppanel-server -logstream=stdout -service_name=ppanel-server -已展开 - -滚动到底部 - -最新日志在前 - -搜索日志 - -去重 - -筛选级别 - -显示毫秒 -ms -换行显示 JSON -+ -Columns not supported - -突出显示文本 - -大字体 - -下载日志 - -滚动到顶部 - - -2026-04-30 08:33:29.296 info 303029-04-04 00:00:00.296 debug [GORM] SQL Executed duration=0.5ms caller=user/queryUserSubscribeLogic.go:47 sql=SELECT `user_subscribe`.`id`,`user_subscribe`.`user_id`,`user_subscribe`.`order_id`,`user_subscribe`.`subscribe_id`,`user_subscribe`.`node_group_id`,`user_subscribe`.`start_time`,`user_subscribe`.`expire_time`,`user_subscribe`.`finished_at`,`user_subscribe`.`traffic`,`user_subscribe`.`download`,`user_subscribe`.`upload`,`user_subscribe`.`token`,`user_subscribe`.`uuid`,`user_subscribe`.`status`,`user_subscribe`.`note`,`user_subscribe`.`created_at`,`user_subscribe`.`updated_at` FROM `user_subscribe` WHERE `user_id` = 19764 AND `status` IN (0,1,2,3) AND (`expire_time` > '2026-04-30 23:33:29.295' OR `finished_at` >= '2026-04-23 23:33:29.295' OR `expire_time` = '1970-01-01 08:00:00') trace=428ceb5c1001366ab0dfddaa0fd0cf8a rows=1 span=a0c44ec4143a6a77 - -2026-04-30 06:38:24.260 info 303024-04-04 00:00:00.260 debug [GORM] SQL Executed duration=0.2ms caller=group/recalculateGroupLogic.go:58 sql=UPDATE `user_subscribe` SET `node_group_id`=0,`updated_at`='2026-04-30 21:38:24.26' WHERE id = 10013 rows=1 - -2026-04-30 06:38:24.259 info 303024-04-04 00:00:00.259 debug assigning user_subscribe_id=10013 (subscribe_id=1) to node_group_id=0 (total_options=0, selected_first) caller=group/recalculateGroupLogic.go:504 - -2026-04-30 06:38:24.121 info 303024-04-04 00:00:00.121 info [SubscriptionFlow] renewal order updated existing subscription caller=common/subscriptionTrace.go:28 effective_user_id=20003 payment_id=2 expire_time=2026-05-30 21:38:24.118494775 +0800 CST user_id=20003 quantity=30 flow=order_subscription stage=subscription_renewed order_no=202604302137198938303097982 is_new_order=false user_subscribe_id=10013 subscribe_order_id=17216 subscribe_uuid_tail=936f5490 payment_method=EPay subscribe_token_tail=3cb4c6b3 user_subscribe_plan_id=1 subscribe_status=1 iap_expire_at=0 trace_type=subscription_flow parent_order_id=7448 order_type=2 order_status=4 order_subscribe_id=1 app_account_token_tail=e04447ca order_id=17216 subscription_user_id=20003 subscribe_owner_user_id=20003 - -2026-04-30 06:38:24.120 info 303024-04-04 00:00:00.120 debug [GORM] SQL Executed duration=1.7ms caller=user/subscribe.go:17 sql=UPDATE `user_subscribe` SET `id`=10013,`user_id`=20003,`order_id`=17216,`subscribe_id`=1,`node_group_id`=0,`group_locked`=false,`start_time`='2026-04-23 19:06:40.003',`expire_time`='2026-05-30 21:38:24.118',`finished_at`=NULL,`traffic`=0,`download`=0,`upload`=0,`expired_download`=0,`expired_upload`=0,`token`='e622c7a270caf7fd816f9dd83cb4c6b3',`uuid`='aabd8eb1-2569-4a69-b59c-15cd936f5490',`status`=1,`note`='',`updated_at`='2026-04-30 21:38:24.119' WHERE id = 10013 rows=1 - -2026-04-30 06:38:24.118 info 303024-04-04 00:00:00.118 debug [GORM] SQL Executed duration=0.2ms caller=user/subscribe.go:161 sql=SELECT * FROM `user_subscribe` WHERE id = 10013 ORDER BY `user_subscribe`.`id` LIMIT 1 rows=1 - -2026-04-30 06:37:25.952 info 303025-04-04 00:00:00.952 debug [GORM] SQL Executed duration=0.1ms caller=group/recalculateGroupLogic.go:58 sql=UPDATE `user_subscribe` SET `node_group_id`=0,`updated_at`='2026-04-30 21:37:25.952' WHERE id = 10013 rows=1 - -2026-04-30 06:37:19.898 info 303019-04-04 00:00:00.898 info HTTP Request duration=6.088471ms caller=middleware/loggerMiddleware.go:113 decrypted_request_body={"coupon":"","payment":2,"quantity":30,"user_subscribe_id":10013} response_body={"code":200,"data":{"data":"SxIHPdGQQbeAwx5UYMaRaouIke61GH+VRSl/iSr63r/GVLuXfd+ljlQLmukw9UE/Fdjc5oSWDq5ApVyEBR4bF79eBcuDz+cYjjmnJIn1sXt8hIPlwKlhc50TFwe8/x2RlpsHsLUYaOYOivMv/iuH/A==","time":"18ab25fb776f18b9"},"msg":"success"} ip=112.96.81.74 trace=60ff721319b3cf1b8f328dc05f01cb99 status=200 request=POST api.hifast.biz/v1/public/order/renewal query= user-agent=HiFast/1.0.6-26042218 (Android; HUAWEI PLA-AL10; 12) Flutter device_decrypt_status=success api_header= request_body={"data":"xdcFznl62TSP5AiItT+OKZWELzq3mR+cUZ2COAZ7ERslZT+M8mmEI65BfwevDWXA6l9TjMLr5sRkR4+omRV3fbH+PkLJ7kvIf9WPQ9ASaNg=","time":"2026-04-30T21:37:19.943917"} span=99fda96ceb7ba495 - -2026-04-30 06:37:19.898 info 303019-04-04 00:00:00.898 info [SubscriptionFlow] renewal order persisted caller=common/subscriptionTrace.go:28 trace_type=subscription_flow order_no=202604302137198938303097982 user_id=20003 payment_id=2 parent_order_id=7448 quantity=30 app_account_token_tail=e04447ca resolved_user_subscribe_id=10013 stage=order_created order_id=17216 order_type=2 order_status=1 subscription_user_id=20003 trace=60ff721319b3cf1b8f328dc05f01cb99 span=99fda96ceb7ba495 effective_user_id=20003 order_subscribe_id=1 requested_user_subscribe_id=10013 flow=order_subscription payment_method=EPay is_new_order=false subscribe_token_tail=3cb4c6b3 - -2026-04-30 06:37:19.894 info 303019-04-04 00:00:00.894 debug [GORM] SQL Executed duration=0.5ms caller=order/renewalLogic.go:81 rows=1 span=99fda96ceb7ba495 sql=SELECT `user_subscribe`.`id`,`user_subscribe`.`user_id`,`user_subscribe`.`order_id`,`user_subscribe`.`subscribe_id`,`user_subscribe`.`node_group_id`,`user_subscribe`.`start_time`,`user_subscribe`.`expire_time`,`user_subscribe`.`finished_at`,`user_subscribe`.`traffic`,`user_subscribe`.`download`,`user_subscribe`.`upload`,`user_subscribe`.`token`,`user_subscribe`.`uuid`,`user_subscribe`.`status`,`user_subscribe`.`note`,`user_subscribe`.`created_at`,`user_subscribe`.`updated_at` FROM `user_subscribe` WHERE id = 10013 ORDER BY `user_subscribe`.`id` LIMIT 1 trace=60ff721319b3cf1b8f328dc05f01cb99 - -2026-04-30 06:37:19.893 info 303019-04-04 00:00:00.893 info [SubscriptionFlow] renewal order creation started caller=common/subscriptionTrace.go:28 effective_user_id=20003 quantity=30 trace=60ff721319b3cf1b8f328dc05f01cb99 trace_type=subscription_flow flow=order_subscription stage=order_create_start order_kind=renewal user_id=20003 span=99fda96ceb7ba495 requested_user_subscribe_id=10013 payment_id=2 coupon= - -2026-04-30 06:36:05.808 info 30305-04-04 00:00:00.808 info HTTP Request duration=7.877334ms caller=middleware/loggerMiddleware.go:113 query= device_decrypt_status=success response_body={"code":200,"data":{"data":"ELE22mv7foWM+iFzrylO+xbiTWWO7gH9qclIxJzT8TRqS1fJN32GiWq/gtNlGpVWwX4iZoNjI0uOA/5lV4YltAfw3bL7sz+CcARgVEZ4NGFRqOt7bVm1RssagYLopQdfoueQ0Z+j7zOFkBlzNW+r3Q==","time":"18ab25ea37520766"},"msg":"success"} user-agent=HiFast/1.0.6-26042218 (Android; HUAWEI PLA-AL10; 12) Flutter request_body={"data":"a4U8LH1zN4LFF+aBBLoUHzEZoxJ4C6EL1nlDNeKb4m2Xwi8H1hk05qxbkvj3xz6kKdecrhF2G0G6rAavhNlKDDZhaHH/J5elqjw6tsQGluk=","time":"2026-04-30T21:36:05.852132"} request=POST api.hifast.biz/v1/public/order/renewal ip=112.96.81.74 decrypted_request_body={"coupon":"","payment":2,"quantity":30,"user_subscribe_id":10013} trace=7e1b88eed63e7ffba4a6e6e2482d399d status=200 api_header= span=d6bd668124fcad80 - -2026-04-30 06:36:05.808 info 30305-04-04 00:00:00.808 info [SubscriptionFlow] renewal order persisted caller=common/subscriptionTrace.go:28 app_account_token_tail=237eb1b5 span=d6bd668124fcad80 flow=order_subscription order_id=17213 order_subscribe_id=1 parent_order_id=7448 requested_user_subscribe_id=10013 trace=7e1b88eed63e7ffba4a6e6e2482d399d user_id=20003 payment_id=2 payment_method=EPay resolved_user_subscribe_id=10013 stage=order_created order_no=202604302136058021461564356 order_status=1 quantity=30 is_new_order=false trace_type=subscription_flow order_type=2 subscription_user_id=20003 effective_user_id=20003 subscribe_token_tail=3cb4c6b3 - -2026-04-30 06:36:05.802 info 30305-04-04 00:00:00.802 debug [GORM] SQL Executed duration=0.7ms caller=order/renewalLogic.go:81 sql=SELECT `user_subscribe`.`id`,`user_subscribe`.`user_id`,`user_subscribe`.`order_id`,`user_subscribe`.`subscribe_id`,`user_subscribe`.`node_group_id`,`user_subscribe`.`start_time`,`user_subscribe`.`expire_time`,`user_subscribe`.`finished_at`,`user_subscribe`.`traffic`,`user_subscribe`.`download`,`user_subscribe`.`upload`,`user_subscribe`.`token`,`user_subscribe`.`uuid`,`user_subscribe`.`status`,`user_subscribe`.`note`,`user_subscribe`.`created_at`,`user_subscribe`.`updated_at` FROM `user_subscribe` WHERE id = 10013 ORDER BY `user_subscribe`.`id` LIMIT 1 rows=1 trace=7e1b88eed63e7ffba4a6e6e2482d399d span=d6bd668124fcad80 - -2026-04-30 06:36:05.802 info 30305-04-04 00:00:00.802 info [SubscriptionFlow] renewal order creation started caller=common/subscriptionTrace.go:28 flow=order_subscription requested_user_subscribe_id=10013 payment_id=2 coupon= span=d6bd668124fcad80 trace_type=subscription_flow order_kind=renewal trace=7e1b88eed63e7ffba4a6e6e2482d399d stage=order_create_start user_id=20003 effective_user_id=20003 quantity=30 - -2026-04-30 06:35:46.036 info 303046-04-04 00:00:00.036 debug [GORM] SQL Executed duration=0.1ms caller=group/recalculateGroupLogic.go:58 sql=UPDATE `user_subscribe` SET `node_group_id`=0,`updated_at`='2026-04-30 21:35:46.036' WHERE id = 10013 rows=1 - -2026-04-30 06:35:38.276 info 303038-04-04 00:00:00.276 info HTTP Request duration=7.276753ms caller=middleware/loggerMiddleware.go:113 request=POST api.hifast.biz/v1/public/order/renewal ip=112.96.81.74 user-agent=HiFast/1.0.6-26042218 (Android; HUAWEI PLA-AL10; 12) Flutter device_decrypt_status=success trace=fd8fbb2d663ad7df82f0c25bf7fb6913 span=c6fe83c0a377d5b5 status=200 query= request_body={"data":"6cuaVRmMX/CGHQ+y0jrwjKTUx404hlB7/z+qPYpK9toUHAVMBrhVBC/cnZmzffjaPuqlUrLx9lSOTHDxv3GGqXZxDah5N4AimVY0dFsx6Bc=","time":"2026-04-30T21:35:38.294140"} decrypted_request_body={"coupon":"","payment":2,"quantity":30,"user_subscribe_id":10013} response_body={"code":200,"data":{"data":"iQSMczPB07C+ruU52emoga1TtBShOiBZOtU8jW9XzmQiKe9DjWCxGY+fFTnJ6LrQCXAQqZWwBpQgABpFWpcJ+MbRr5jk4S3ahwXzeHXBiMcGlgAJRb0G3O+K7h7z+6t+uhGNjzCE2CYFMuii+0T3rg==","time":"18ab25e3ce44be91"},"msg":"success"} api_header= - -2026-04-30 06:35:38.276 info 303038-04-04 00:00:00.276 info [SubscriptionFlow] renewal order persisted caller=common/subscriptionTrace.go:28 subscription_user_id=20003 order_subscribe_id=1 effective_user_id=20003 payment_id=2 parent_order_id=7448 subscribe_token_tail=3cb4c6b3 trace=fd8fbb2d663ad7df82f0c25bf7fb6913 span=c6fe83c0a377d5b5 flow=order_subscription payment_method=EPay quantity=30 is_new_order=false app_account_token_tail=6b5d9042 order_no=202604302135382700174133469 requested_user_subscribe_id=10013 resolved_user_subscribe_id=10013 trace_type=subscription_flow stage=order_created order_id=17211 order_type=2 order_status=1 user_id=20003 - -2026-04-30 06:35:38.270 info 303038-04-04 00:00:00.270 debug [GORM] SQL Executed duration=0.5ms caller=order/renewalLogic.go:81 rows=1 trace=fd8fbb2d663ad7df82f0c25bf7fb6913 span=c6fe83c0a377d5b5 sql=SELECT `user_subscribe`.`id`,`user_subscribe`.`user_id`,`user_subscribe`.`order_id`,`user_subscribe`.`subscribe_id`,`user_subscribe`.`node_group_id`,`user_subscribe`.`start_time`,`user_subscribe`.`expire_time`,`user_subscribe`.`finished_at`,`user_subscribe`.`traffic`,`user_subscribe`.`download`,`user_subscribe`.`upload`,`user_subscribe`.`token`,`user_subscribe`.`uuid`,`user_subscribe`.`status`,`user_subscribe`.`note`,`user_subscribe`.`created_at`,`user_subscribe`.`updated_at` FROM `user_subscribe` WHERE id = 10013 ORDER BY `user_subscribe`.`id` LIMIT 1 - -2026-04-30 06:35:38.270 info 303038-04-04 00:00:00.270 info [SubscriptionFlow] renewal order creation started caller=common/subscriptionTrace.go:28 flow=order_subscription effective_user_id=20003 coupon= trace_type=subscription_flow payment_id=2 user_id=20003 quantity=30 trace=fd8fbb2d663ad7df82f0c25bf7fb6913 span=c6fe83c0a377d5b5 stage=order_create_start order_kind=renewal requested_user_subscribe_id=10013 - -按名称搜索字段 - -Show log level -0 -字段 - -__stream_shard__ -25% - -container -100% - -level -100% - -logstream -100% - -service_name -100% diff --git a/ops/aws-rds-external-replica-runbook.md b/ops/aws-rds-external-replica-runbook.md index c8fcd84..c1ca82e 100644 --- a/ops/aws-rds-external-replica-runbook.md +++ b/ops/aws-rds-external-replica-runbook.md @@ -1,99 +1,396 @@ -# AWS RDS to External Replica Runbook +# AWS RDS + EC2 Redis 到外部备用服务器 Runbook -目标:让外部服务器 `104.238.220.230` 上的 MySQL/Redis 尽量实时同步 AWS 侧数据,作为备用数据节点。 +目标:让 `104.238.220.230` 持续作为 AWS 主生产环境的异地备用节点,承接: -## 已知资源 +- MySQL 外部只读从库 +- Redis 外部从库 +- 故障时的快速提升与业务切换 -- AWS region: `ap-east-1` -- RDS endpoint: `hifast-mysql-prod.cd6aey40m6ag.ap-east-1.rds.amazonaws.com` -- RDS username: `admin` -- RDS password: `VIbW2nNoh0LXq2!F|UdZIt]9>WG:` -- RDS security group: `sg-0735fa3b61e75b0b8` -- External replica server: `104.238.220.230` -- External OS: Ubuntu 24.04 LTS -- External MySQL: 8.0.45 -- External Redis: 7.0.15 +本文档以 `2026-05-13` 的真实现网状态为准,覆盖: -## AWS Console 必须完成 +- 当前已经落地的主从架构 +- 日常验收命令 +- 主从故障排查 +- 全量重建从库 +- “新建规范 RDS 再切换”的生产级收敛路线 +- 故障切换与回滚 -1. RDS `hifast-mysql-prod` 修改为 `Publicly accessible = Yes`。 -2. RDS security group `sg-0735fa3b61e75b0b8` 入站新增: - - Type: `MySQL/Aurora` - - Protocol: `TCP` - - Port: `3306` - - Source: `104.238.220.230/32` - - Description: `external mysql replica` +## 1. 当前已确认资源 -不要开放 `0.0.0.0/0` 到 RDS 3306。 +### 1.1 AWS 主生产 -## RDS 上执行 SQL +- Region: `ap-east-1` +- AWS app EC2: + - Name: `hifast-hk-app-01` + - Public IP: `43.198.248.161` + - Private IP: `10.0.1.201` +- AWS MySQL: + - Type: `RDS MySQL` + - Instance: `hifast-mysql-prod-v2` + - Endpoint: `hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com` + - Version: `8.4.8` + - DB Name: `hifast` + - Admin user: `admin` + - Admin password: keep it in a secret store, do not write plaintext into repo docs + - Replication user: `repl` + - Replication password: keep it in a secret store, do not write plaintext into repo docs +- AWS Redis: + - Location: `hifast-hk-app-01` + - Deployment: `Docker` + - Container: `hifast-redis` + - Version: `redis:8.2.1` + - Listen: `0.0.0.0:6379` + - Password: keep it in a secret store, do not write plaintext into repo docs -先连接: +### 1.2 外部备用服务器 + +- Host: `104.238.220.230` +- OS: `Ubuntu 24.04 LTS` +- SSH user: `root` +- MySQL version: `8.4.9` +- Redis version: `8.6.3` +- 当前角色: + - MySQL external replica + - Redis replica + - 备用应用节点 + +### 1.3 当前应用真实运行方式 + +AWS 应用机上的 `ppanel-server` 当前不是 systemd 托管,而是 Docker Compose 服务: + +- Compose file: `/opt/ppanel/docker-compose.cloud.yml` +- Config file: `/opt/ppanel/configs/ppanel.yaml` +- Container name: `ppanel-server` +- Current MySQL target: `hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com:3306` +- Current Redis target: `127.0.0.1:6379` + +也就是说,后续所有应用侧切换步骤,都应该以修改: + +- `/opt/ppanel/configs/ppanel.yaml` + +并执行: ```bash -mysql -h hifast-mysql-prod.cd6aey40m6ag.ap-east-1.rds.amazonaws.com -u admin -p +cd /opt/ppanel +docker compose -f docker-compose.cloud.yml up -d ppanel-server ``` -然后执行: +作为准。 + +## 2. 当前健康基线 + +截至 `2026-05-13`,已确认以下状态成立: + +- `104` MySQL: + - `Source_Host = hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com` + - `Replica_IO_Running: Yes` + - `Replica_SQL_Running: Yes` + - `Seconds_Behind_Source: 0` + - `read_only = ON` + - `super_read_only = ON` +- AWS Redis 主库: + - `role:master` + - `connected_slaves:1` +- `104` Redis: + - `role:slave` + - `master_link_status:up` +- AWS 应用: + - `curl http://127.0.0.1:8080/v1/common/heartbeat` 返回 `code=200` + +这说明当前状态已经达到: + +- 主生产可用 +- 外部备用持续同步 +- Redis 已回到真实本机链路 + +## 3. 当前网络前提 + +### 3.1 安全组 + +当前实际生效的安全组如下: + +- `hifast-hk-app-core-sg` + - `22/tcp <- 0.0.0.0/0` + - `6379/tcp <- 104.238.220.230/32` + - `8080/tcp <- hifast-hk-web-sg` +- `hifast-hk-rds-core-sg` + - `3306/tcp <- 104.238.220.230/32` + - `3306/tcp <- hifast-hk-app-core-sg` +- `hifast-hk-web-sg` + - `22/80/443 <- 0.0.0.0/0` + +### 3.2 当前结构性限制 + +当前 `104 -> RDS` 公网复制链路虽然可用,但依赖的是: + +- `hifast-mysql-prod-v2` 为 `Publicly accessible = Yes` +- RDS ENI 仍位于 `hifast-hk-private-1b` +- `private-1b` 被临时挂到了公网路由表 + +这不是最终规范的生产形态。 + +当前这条路线已经完成,后续更推荐的动作是: + +1. 持续确认应用主库目标保持在 `hifast-mysql-prod-v2` +2. 持续确认 `104` 复制目标保持在 `hifast-mysql-prod-v2` +3. 根据回收窗口安排旧 RDS 下线 +4. 按网络收敛计划处理 `private-1b` 路由语义 + +## 4. 日常验收命令 + +### 4.1 验收 MySQL 主从 + +在 `104` 执行: + +```bash +mysql -e "SHOW REPLICA STATUS\G" +``` + +重点看: + +- `Source_Host` +- `Replica_IO_Running` +- `Replica_SQL_Running` +- `Seconds_Behind_Source` +- `Last_IO_Error` +- `Last_SQL_Error` + +成功标准: + +- `Replica_IO_Running: Yes` +- `Replica_SQL_Running: Yes` +- `Seconds_Behind_Source: 0` 或较小 + +### 4.2 验收 Redis 主从 + +在 AWS app EC2 执行: + +```bash +docker exec hifast-redis redis-cli -a '0BVz9XOHf7KUfEuoFJRK-dURdKUGFiZ8QeaHpysHnKeKhLskZb55HPK121lFsKtr' INFO replication +``` + +重点看: + +- `role:master` +- `connected_slaves:1` + +在 `104` 执行: + +```bash +redis-cli INFO replication +``` + +重点看: + +- `role:slave` +- `master_host:43.198.248.161` +- `master_port:6379` +- `master_link_status:up` + +### 4.3 验收应用 + +在 AWS app EC2 执行: + +```bash +curl -sf http://127.0.0.1:8080/v1/common/heartbeat +``` + +期望返回: + +- `{"code":200,...}` + +查看容器: + +```bash +cd /opt/ppanel +docker compose -f docker-compose.cloud.yml ps +``` + +期望: + +- `ppanel-server` 为 `Up` +- `hifast-redis` 为 `Up` + +## 5. MySQL 复制故障排查 + +### 5.1 先看复制状态 + +```bash +mysql -e "SHOW REPLICA STATUS\G" +``` + +重点判断: + +- `Replica_IO_Running = No` +- `Replica_SQL_Running = No` +- `Last_IO_Error` +- `Last_SQL_Error` + +### 5.2 常见场景 + +#### 场景 A:网络或白名单断开 + +表现: + +- `Replica_IO_Running: No` +- `Last_IO_Error` 出现连接失败、超时、拒绝访问 + +排查: + +```bash +mysql -h hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com -u repl -p -e "SELECT 1;" +``` + +处理: + +- 检查 RDS SG 是否仍保留 `104.238.220.230/32 -> 3306` +- 检查 RDS 是否仍为 `Publicly accessible = Yes` +- 如果后续已迁到新规范 RDS,则检查新实例的 SG 和公网可达性 + +#### 场景 B:主库 binlog 位点丢失 + +表现: + +- `Last_IO_Error` 或 `Last_SQL_Error` 指向缺失 binlog + +处理: + +- 不要硬跳过 +- 直接执行全量重建从库 + +#### 场景 C:SQL 执行报错 + +表现: + +- `Replica_SQL_Running: No` +- `Last_SQL_Error` 有实际 SQL 冲突信息 + +处理建议: + +- 如果只是临时演练环境,可重建从库 +- 如果已经进入生产切换阶段,不建议盲目 `sql_slave_skip_counter` +- 优先保守做法仍是重新全量初始化 + +## 6. Redis 复制故障排查 + +### 6.1 看 `104` 从库状态 + +```bash +redis-cli INFO replication +``` + +重点: + +- `role` +- `master_host` +- `master_link_status` + +### 6.2 看 AWS 主库状态 + +```bash +docker exec hifast-redis redis-cli -a '0BVz9XOHf7KUfEuoFJRK-dURdKUGFiZ8QeaHpysHnKeKhLskZb55HPK121lFsKtr' INFO replication +``` + +重点: + +- `role:master` +- `connected_slaves` + +### 6.3 常见问题 + +#### 场景 A:安全组断开 + +表现: + +- `master_link_status:down` + +处理: + +- 确认 `hifast-hk-app-core-sg` 仍保留: + - `6379/tcp <- 104.238.220.230/32` + +#### 场景 B:主库密码漂移 + +表现: + +- 从库重连失败 +- 日志出现 `NOAUTH` + +处理: + +- 统一更新 `/etc/redis/redis.conf` 中的: + - `masterauth` +- 然后: + +```bash +systemctl restart redis-server +redis-cli INFO replication +``` + +## 7. 全量重建 MySQL 从库 + +适用场景: + +- 主从中断且无法安全追平 +- `6666@qq.com` 这类写入在主库存在、从库未同步 +- binlog 不连续 +- 需要回到最稳妥状态 + +### 7.1 在主库导出 + +在一台可连 RDS 的机器上执行: + +```bash +mysqldump \ + -h hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com \ + -u admin \ + -p \ + --single-transaction \ + --routines \ + --triggers \ + --events \ + --set-gtid-purged=OFF \ + hifast > hifast-full.sql +``` + +如果需要同步账号权限,也可以额外单独导出授权对象;但当前业务库恢复重点是 `hifast` 数据库本身。 + +### 7.2 清理 `104` 当前复制 + +在 `104` 执行: ```sql -CALL mysql.rds_set_configuration('binlog retention hours', 24); +STOP REPLICA; +RESET REPLICA ALL; +``` -CREATE USER IF NOT EXISTS 'repl'@'104.238.220.230' IDENTIFIED BY 'THcPeHaerV4PwyE9qtF6PHZd'; -GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'104.238.220.230'; -FLUSH PRIVILEGES; +### 7.3 重新导入业务库 -SHOW VARIABLES LIKE 'gtid_mode'; +在 `104` 执行: + +```bash +mysql -e "DROP DATABASE IF EXISTS hifast; CREATE DATABASE hifast CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;" +mysql hifast < hifast-full.sql +``` + +### 7.4 重新挂复制 + +当前现网是非 GTID 自动定位,使用 file/position 模式。 + +先在主库取位点: + +```sql SHOW MASTER STATUS; ``` -记录 `SHOW MASTER STATUS` 输出的 `File` 和 `Position`。如果 `gtid_mode = ON`,外部从库可用 auto-position;否则使用 file/position。 - -## 外部服务器基础配置 - -在 `104.238.220.230` root shell 执行: - -```bash -cat >/etc/mysql/mysql.conf.d/99-replica.cnf <<'EOF' -[mysqld] -server-id=230 -read_only=ON -super_read_only=ON -relay_log=relay-bin -log_bin=mysql-bin -binlog_format=ROW -EOF - -systemctl restart mysql -mysql -e "SHOW VARIABLES WHERE Variable_name IN ('server_id','read_only','super_read_only','log_bin','binlog_format');" -``` - -如果 RDS `gtid_mode = ON`: +然后在 `104` 执行: ```sql -STOP REPLICA; -RESET REPLICA ALL; CHANGE REPLICATION SOURCE TO - SOURCE_HOST='hifast-mysql-prod.cd6aey40m6ag.ap-east-1.rds.amazonaws.com', + SOURCE_HOST='hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com', SOURCE_PORT=3306, SOURCE_USER='repl', - SOURCE_PASSWORD='THcPeHaerV4PwyE9qtF6PHZd', - SOURCE_AUTO_POSITION=1, - SOURCE_SSL=1; -START REPLICA; -SHOW REPLICA STATUS\G -``` - -如果 RDS `gtid_mode != ON`,把 `` 和 `` 替换成 `SHOW MASTER STATUS` 里的值: - -```sql -STOP REPLICA; -RESET REPLICA ALL; -CHANGE REPLICATION SOURCE TO - SOURCE_HOST='hifast-mysql-prod.cd6aey40m6ag.ap-east-1.rds.amazonaws.com', - SOURCE_PORT=3306, - SOURCE_USER='repl', - SOURCE_PASSWORD='THcPeHaerV4PwyE9qtF6PHZd', + SOURCE_PASSWORD='', SOURCE_LOG_FILE='', SOURCE_LOG_POS=, SOURCE_SSL=1; @@ -101,37 +398,36 @@ START REPLICA; SHOW REPLICA STATUS\G ``` -成功标准: +### 7.5 验收 + +确认: - `Replica_IO_Running: Yes` - `Replica_SQL_Running: Yes` -- `Seconds_Behind_Source` 为 `0` 或较小数值 +- `Seconds_Behind_Source: 0` +- `read_only = ON` +- `super_read_only = ON` -## Redis 复制 +## 8. 重新配置 Redis 从库 -Redis 源端还未确认。之前方案是 Redis 放在 AWS app EC2 上,与服务端同机。需要先登录 AWS app EC2,确认 Redis 是否存在、端口、密码、监听地址。 +当前 `104` Redis 为原生安装,不使用 Docker。 -外部 Redis 从库命令模板: +### 8.1 临时切回从库 ```bash +redis-cli CONFIG SET masterauth '0BVz9XOHf7KUfEuoFJRK-dURdKUGFiZ8QeaHpysHnKeKhLskZb55HPK121lFsKtr' +redis-cli REPLICAOF 43.198.248.161 6379 redis-cli CONFIG SET replica-read-only yes -redis-cli REPLICAOF 6379 redis-cli INFO replication ``` -如果源端有密码: +### 8.2 持久化配置 -```bash -redis-cli CONFIG SET masterauth '' -redis-cli REPLICAOF 6379 -redis-cli INFO replication -``` - -持久化写入 `/etc/redis/redis.conf`: +检查 `/etc/redis/redis.conf` 至少包含: ```conf -replicaof 6379 -masterauth +replicaof 43.198.248.161 6379 +masterauth 0BVz9XOHf7KUfEuoFJRK-dURdKUGFiZ8QeaHpysHnKeKhLskZb55HPK121lFsKtr replica-read-only yes ``` @@ -142,3 +438,215 @@ systemctl restart redis-server redis-cli INFO replication ``` +## 9. 生产级收敛路线:新建规范 RDS 再切换 + +这条路线已经完成,当前现网主库已经切到 `hifast-mysql-prod-v2`。下面内容保留为迁移归档参考,不再表示待执行。 + +### 9.1 目标 + +把当前临时方案: + +- `private-1b` 挂公网路由 + +收敛成: + +- RDS 使用纯公网 DB subnet group +- 安全组仍只对白名单和应用组开放 + +### 9.2 已准备好的资源 + +- 已建 DB subnet group: + - `hifast-hk-rds-public-only-sgprep` +- 子网: + - `hifast-hk-public-1a` + - `hifast-hk-public-1b` + +### 9.3 新 RDS 建议参数 + +新实例建议名: + +- `hifast-mysql-prod-v2` + +建议保持与旧主库一致: + +- Engine: `mysql` +- Version: `8.4.8` +- Class: `db.r7g.xlarge` +- Storage: `gp3` +- Size: `200 GB` +- IOPS: `3000` +- Throughput: `125` +- Publicly accessible: `Yes` +- Multi-AZ: `No` 或按预算单独评估 +- Deletion protection: `On` +- Performance Insights: `On` +- Backup retention: `7` +- DB subnet group: `hifast-hk-rds-public-only-sgprep` +- VPC SG: `hifast-hk-rds-core-sg` + +### 9.4 迁移步骤 + +1. 已创建新 RDS `hifast-mysql-prod-v2` +2. 在旧主库导出 `hifast` +3. 导入新库 +4. 在新库创建 `repl` 用户并配置 binlog retention +5. 修改 AWS app EC2 上 `/opt/ppanel/configs/ppanel.yaml` 的 `MySQL.Addr` +6. 重启 `ppanel-server` 容器 +7. 在 `104` 上 `STOP REPLICA; RESET REPLICA ALL;` +8. 指向新 RDS endpoint 重新挂复制 +9. 验收应用与主从 +10. 验收通过后,安排旧 RDS 下线,并推进 `private-1b` 恢复私网路由 + +### 9.5 应用切换命令 + +在 AWS app EC2: + +1. 备份配置 + +```bash +cp /opt/ppanel/configs/ppanel.yaml /opt/ppanel/configs/ppanel.yaml.bak.$(date +%Y%m%d%H%M%S) +``` + +2. 编辑: + +- `/opt/ppanel/configs/ppanel.yaml` + +把: + +```yaml +MySQL: + Addr: hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com:3306 +``` + +改成: + +```yaml +MySQL: + Addr: hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com:3306 +``` + +3. 重启应用容器: + +```bash +cd /opt/ppanel +docker compose -f docker-compose.cloud.yml up -d ppanel-server +``` + +4. 验证: + +```bash +curl -sf http://127.0.0.1:8080/v1/common/heartbeat +docker compose -f docker-compose.cloud.yml logs --tail=100 ppanel-server +``` + +### 9.6 `104` 改挂新 RDS + +```sql +STOP REPLICA; +RESET REPLICA ALL; +CHANGE REPLICATION SOURCE TO + SOURCE_HOST='', + SOURCE_PORT=3306, + SOURCE_USER='repl', + SOURCE_PASSWORD='', + SOURCE_LOG_FILE='', + SOURCE_LOG_POS=, + SOURCE_SSL=1; +START REPLICA; +SHOW REPLICA STATUS\G +``` + +### 9.7 切换验收 + +至少确认: + +- AWS 应用心跳正常 +- 新 RDS 可正常读写 +- `104` 复制恢复为 `Yes/Yes` +- `Seconds_Behind_Source` 追到 `0` +- Navicat 可从允许的白名单来源连接新 RDS + +### 9.8 回滚 + +如果新 RDS 切换后应用异常: + +1. 立即把 `/opt/ppanel/configs/ppanel.yaml` 中 `MySQL.Addr` 改回旧 endpoint +2. 重启 `ppanel-server` +3. 暂不处理 `104`,先恢复主生产 +4. 复盘新库数据、权限、参数、网络 + +## 10. AWS 故障时的备用接管 + +### 10.1 Redis 提升为主库 + +在 `104`: + +```bash +redis-cli REPLICAOF NO ONE +redis-cli INFO replication +``` + +期望: + +- `role:master` + +### 10.2 MySQL 提升为可写主库 + +在 `104`: + +```sql +STOP REPLICA; +RESET REPLICA ALL; +SET GLOBAL super_read_only=OFF; +SET GLOBAL read_only=OFF; +``` + +再确认: + +```sql +SHOW VARIABLES LIKE 'read_only'; +SHOW VARIABLES LIKE 'super_read_only'; +``` + +期望: + +- `OFF` +- `OFF` + +### 10.3 应用切到 `104` 本机数据层 + +如果 `104` 上也部署同样的 PPanel 服务,则应用配置应改为: + +- MySQL 指向 `127.0.0.1:3306` 或本机 socket +- Redis 指向 `127.0.0.1:6379` + +### 10.4 最后切入口 + +数据层和应用层都确认可写后,再做: + +- DNS 切换 +- 或 Nginx / 上游切流量 + +原则: + +- 先数据接管 +- 再应用确认 +- 最后入口切换 + +## 11. 日常巡检建议 + +建议至少每天巡检一次: + +1. `104` MySQL `SHOW REPLICA STATUS\G` +2. `104` Redis `INFO replication` +3. AWS Redis 主库 `INFO replication` +4. AWS app 心跳 `/v1/common/heartbeat` +5. `docker compose -f /opt/ppanel/docker-compose.cloud.yml ps` + +如果后续要做真正的生产级自动化,再补: + +- MySQL 复制延迟告警 +- Redis 主从断链告警 +- 应用心跳失败告警 +- RDS 连接失败告警 +- 定期灾备切换演练 diff --git a/ops/hifast-aws-standby-architecture-zh.md b/ops/hifast-aws-standby-architecture-zh.md index 489e557..dff3b8d 100644 --- a/ops/hifast-aws-standby-architecture-zh.md +++ b/ops/hifast-aws-standby-architecture-zh.md @@ -10,6 +10,47 @@ - MySQL / Redis 的同步关系是什么 - 故障时应该如何切换 +## 0. 2026-05-13 验收摘要 + +- 已确认 `104.238.220.230 -> AWS RDS MySQL` 连通,MySQL 外部从库健康: + - 当前复制上游:`hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com` + - `Replica_IO_Running: Yes` + - `Replica_SQL_Running: Yes` + - `Seconds_Behind_Source: 0` +- 已确认 `104.238.220.230 -> AWS EC2 Redis` 主从健康: + - `104` 上 `role:slave` + - `master_link_status:up` + - AWS Redis 主库 `connected_slaves:1` +- 已修复应用侧 Redis 配置漂移: + - 旧链路:`127.0.0.1:6380 -> stunnel4 -> 旧 ElastiCache` + - 新链路:`127.0.0.1:6379 -> 本机 Docker Redis` +- 旧 `stunnel4` 已停用并禁用自启,`ppanel-server` 日志里的 Redis `i/o timeout` 已停止出现。 +- 已确认 `ppanel-server` 当前运行方式为 Docker Compose 容器,而不是 systemd 服务: + - Compose 文件:`/opt/ppanel/docker-compose.cloud.yml` + - 配置文件:`/opt/ppanel/configs/ppanel.yaml` + - 容器名:`ppanel-server` + - 健康检查:`curl http://127.0.0.1:8080/v1/common/heartbeat` 返回正常 +- 旧自建安全组 `hifast-hk-app-sg`、`hifast-hk-nginx-sg` 已删除;当前 VPC 内仅保留: + - `hifast-hk-app-core-sg` + - `hifast-hk-rds-core-sg` + - `hifast-hk-web-sg` + - `default` +- 目前已经达到“可用且关键链路已恢复”的状态。 +- 当前入口层属于已确认的过渡方案: + - 现阶段公网入口仍在 `hifast-hk-app-01` + - 独立 `nginx` 服务器已预留,待 AWS 后续资源到位后再迁移承接 +- 当前仍需要继续收敛的核心生产项只剩 1 个: + - RDS 为了让 `104` 走公网白名单复制,当前仍依赖 `hifast-hk-private-1b` 子网临时挂到公网路由表,这不是最终规范形态。 +- 已完成的下一步准备: + - 已创建纯公网子网专用的 `DB subnet group`:`hifast-hk-rds-public-only-sgprep` + - 子网包含: + - `subnet-070e3f264a9c79f32` `hifast-hk-public-1a` + - `subnet-00cb5add705c447c8` `hifast-hk-public-1b` +- 已创建专用 S3 备份桶: + - `hifast-prod-backups-200810848252-ap-east-1` + - 当前状态:private + - 当前状态:versioning enabled + ## 1. 当前实际环境 ### 1.1 AWS 区域 @@ -23,15 +64,37 @@ - 名称:`hifast-hk-app-01` - Instance ID: `i-079cd9d3ef3748714` -- 角色:应用机 / Nginx / 业务服务 / AWS 侧 Redis 主库宿主机 +- 角色:当前实际生产入口 / Nginx / 业务服务 / AWS 侧 Redis 主库宿主机 - 私网 IP: `10.0.1.201` - 公网 IP: `43.198.248.161` +- 业务服务运行方式:`Docker Compose` +- 业务容器:`ppanel-server` +- 部署目录:`/opt/ppanel` +- 实际配置文件:`/opt/ppanel/configs/ppanel.yaml` + +#### 独立 Nginx 服务器 + +- 名称:`hifast-hk-nginx-01` +- Instance ID: `i-0701d54bf2c6bf594` +- 角色:计划中的独立入口机 +- 私网 IP: `10.0.1.175` +- 当前状态:`stopped` +- 当前说明:已经只绑定 `hifast-hk-web-sg`,但目前并未承接正式流量 #### MySQL 主库 - 类型:`AWS RDS MySQL` -- 实例名:`hifast-mysql-prod` +- 实例名:`hifast-mysql-prod-v2` +- Endpoint: `hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com` - 角色:生产主库 +- Engine: `MySQL 8.4.8` +- Publicly accessible: `Yes` +- Multi-AZ: `No` +- Backup retention: `7 days` +- Deletion protection: `On` +- 当前数据库实际体量:约 `187.41 MB` +- 当前表数量:`37` +- 当前 `user` 表记录数:`45076` #### Redis 主库 @@ -41,6 +104,8 @@ - 版本:`redis:8.2.1` - 访问端口:`6379` - 主库出口地址:`43.198.248.161:6379` +- 应用当前实际连接:`127.0.0.1:6379` +- 认证方式:已启用密码认证 #### 外部备用服务器 @@ -48,10 +113,18 @@ - OS: `Ubuntu 24.04 LTS` - 角色:异地备用节点 - 当前状态:已部署与 AWS 相同的业务服务 +- 当前 MySQL 状态:外部只读从库 - 当前 Redis 部署方式:`宿主机原生安装` - 当前 Redis 版本:`8.6.3` - 当前 Redis 角色:`AWS Redis 主库的从库` +#### S3 备份桶 + +- Bucket: `hifast-prod-backups-200810848252-ap-east-1` +- Region: `ap-east-1` +- Public access: blocked +- Versioning: enabled + ## 2. 架构总览 ```mermaid @@ -59,7 +132,7 @@ flowchart TB USER["用户 / 客户端"] --> DNS["域名 / DNS / 入口层"] DNS --> APP["AWS EC2\nhifast-hk-app-01\n43.198.248.161\n10.0.1.201"] - APP --> RDS["AWS RDS MySQL\nhifast-mysql-prod\n主库"] + APP --> RDS["AWS RDS MySQL\nhifast-mysql-prod-v2\n主库"] APP --> REDISM["AWS Redis 主库\nDocker redis:8.2.1\n43.198.248.161:6379"] RDS -. MySQL 备用 / 同步 .-> MYSQLS["104.238.220.230\nMySQL 备用库"] @@ -87,8 +160,10 @@ flowchart TB 说明: -- 当前主应用入口在 AWS EC2。 -- EC2 同时承担业务服务入口。 +- 当前主应用入口实际在 `hifast-hk-app-01`。 +- `hifast-hk-app-01` 同时承担 Nginx、业务服务、Redis 主库。 +- 当前业务服务不是 systemd 单进程部署,而是由 `/opt/ppanel/docker-compose.cloud.yml` 管理的 `ppanel-server` 容器提供 `8080`。 +- 独立入口机 `hifast-hk-nginx-01` 已存在,但当前仅作为后续资源开通后的迁移目标。 - MySQL 在 AWS RDS。 - Redis 不在 ElastiCache,而是在 EC2 本机通过 Docker 提供。 @@ -118,43 +193,187 @@ App / Nginx ## 4. 网络与安全边界 -### 4.1 EC2 安全组 +### 4.1 当前安全组 -- 安全组名称:`hifast-hk-app-sg` -- 安全组 ID: `sg-09266fb27bde15714` +截至 `2026-05-13`,VPC `vpc-09fc384522517debc` 内仅保留 4 个安全组: -已确认规则: +- `default` +- `hifast-hk-app-core-sg` +- `hifast-hk-rds-core-sg` +- `hifast-hk-web-sg` -- Redis `6379/tcp` -- 来源:`104.238.220.230/32` +其中绑定关系已经收敛为: -这条规则的作用是: +- `hifast-hk-app-01` -> `hifast-hk-app-core-sg` +- `hifast-hk-nginx-01` -> `hifast-hk-web-sg` +- `hifast-mysql-prod-v2` -> `hifast-hk-rds-core-sg` -- 允许外部备用服务器 `104.238.220.230` 连到 AWS Redis 主库 -- 避免 Redis 对全网开放 +旧组: -### 4.2 Redis 网络关系 +- `hifast-hk-app-sg` +- `hifast-hk-nginx-sg` + +已经删除,不再使用。 + +### 4.2 当前入站规则 + +#### `hifast-hk-app-core-sg` + +- `22/tcp <- 0.0.0.0/0` +- `6379/tcp <- 104.238.220.230/32` +- `8080/tcp <- hifast-hk-web-sg` + +#### `hifast-hk-rds-core-sg` + +- `3306/tcp <- 104.238.220.230/32` +- `3306/tcp <- hifast-hk-app-core-sg` + +#### `hifast-hk-web-sg` + +- `22/tcp <- 0.0.0.0/0` +- `80/tcp <- 0.0.0.0/0` +- `443/tcp <- 0.0.0.0/0` + +### 4.3 Redis 网络关系 ```mermaid flowchart LR - SG["EC2 Security Group\nsg-09266fb27bde15714"] --> REDIS["AWS Redis 主库\n43.198.248.161:6379"] + SG["hifast-hk-app-core-sg"] --> REDIS["AWS Redis 主库\n43.198.248.161:6379"] STANDBY["104.238.220.230/32"] --> SG ``` -### 4.3 RDS 访问原则 +### 4.4 RDS 访问原则 -RDS 不应该对公网全开放。 +RDS 当前状态已经比之前干净很多: -推荐且已执行过的方向是: - -- 只对白名单源 IP 开放 `3306` -- 如果 `104.238.220.230` 需要做外部从库,则只放行这个 IP +- 当前只对白名单和应用安全组开放 `3306` +- 已移除 `3306 <- 0.0.0.0/0` +- 当前 RDS 仅绑定 `hifast-hk-rds-core-sg` 建议原则: - 不开放 `0.0.0.0/0` 到 MySQL `3306` - 不开放 `0.0.0.0/0` 到 Redis `6379` +### 4.5 当前仍需继续收敛的网络点 + +#### 4.5.1 入口层当前属于过渡方案,不作为本阶段阻塞项 + +当前运行形态是: + +- `hifast-hk-app-01` 本机 `nginx` 正在监听 `80/443` +- `hifast-hk-nginx-01` 当前停止 + +但当前安全组设计是按“独立 nginx 机”拆的: + +- `hifast-hk-web-sg` 在 `hifast-hk-nginx-01` +- `hifast-hk-app-core-sg` 在 `hifast-hk-app-01` + +这意味着当前真实入口和安全组角色划分还没有完全一致。 + +但这一点已经被确认为过渡设计,不作为当前阶段必须整改的问题。后续待 AWS 新资源到位后,再把公网入口迁到独立 `nginx` 服务器即可。 + +#### 4.5.2 RDS 公网复制链路仍是当前唯一核心结构性问题 + +为了让 `104.238.220.230` 通过公网白名单访问 RDS,当前实际依赖的是: + +- RDS `PubliclyAccessible = true` +- RDS ENI 仍在 `subnet-0dcf46db665b6d8a7` +- 该子网名称是 `hifast-hk-private-1b` +- 但这个子网当前被临时关联到了公网路由表 + +这能用,但不属于最终规范的“纯公网子网组”设计。 + +本轮已经额外完成的准备动作: + +- 已新建纯公网 `DB subnet group`:`hifast-hk-rds-public-only-sgprep` +- 该组状态:`Complete` +- 该组仅包含两条公网子网: + - `hifast-hk-public-1a` + - `hifast-hk-public-1b` + +当前结论: + +- 不建议继续在现有生产 RDS 上反复试在线切子网组。 +- 更稳的收敛方案是:新建一台使用规范公网子网组的生产 RDS,再做一次短切换。 +- 由于当前库体量只有约 `187 MB`,这条路线的执行成本并不高,风险也比在现网主库上硬改更可控。 + +## 4.6 104 如何连接 AWS + +这里要特别区分: + +- `104` 连接 AWS 数据层 +- 本地电脑登录 AWS EC2 + +这不是同一件事。 + +### 4.6.1 104 连接 AWS Redis 的方式 + +`104.238.220.230` 连接 AWS Redis,不是通过 PEM 证书,也不是通过 SSH 登录 AWS 机器,而是直接作为 Redis 从库去访问 AWS Redis 主库: + +- 目标地址:`43.198.248.161:6379` +- 连接方式:`TCP` +- 认证方式:`Redis 密码` +- 网络前提:AWS EC2 安全组已放行 `104.238.220.230/32 -> 6379` + +也就是说: + +```text +104 Redis 从库 -> 直连 AWS Redis 主库公网地址 -> 密码认证 -> 建立复制 +``` + +示意命令: + +```bash +redis-cli -h 43.198.248.161 -p 6379 -a '' +``` + +### 4.6.2 104 连接 AWS MySQL RDS 的方式 + +`104.238.220.230` 连接 AWS RDS,也不是通过 PEM 证书,而是通过数据库连接: + +- 目标地址:`hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com:3306` +- 连接方式:`MySQL TCP` +- 认证方式:`MySQL 用户名 + 密码` +- 网络前提:RDS 白名单或安全组放行 `104.238.220.230` + +也就是说: + +```text +104 MySQL 从库 -> 直连 AWS RDS endpoint -> 账号密码认证 -> 建立复制 +``` + +示意命令: + +```bash +mysql -h hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com -u admin -p +``` + +### 4.6.3 本地电脑登录 AWS EC2 的方式 + +本地电脑这边之前进入 AWS EC2,用的不是 `hifast-hk-app-01-key.pem`,而是: + +- `AWS Console` +- `EC2 Instance Connect` +- 浏览器里的 Web SSH 终端 + +所以当前要理解成 3 条不同链路: + +1. 本地电脑 -> AWS 控制台 -> EC2 Instance Connect -> AWS EC2 +2. `104` -> AWS Redis 主库公网地址 -> Redis 密码认证 +3. `104` -> AWS RDS endpoint -> MySQL 用户密码认证 + +### 4.6.4 关键结论 + +当前灾备链路里,`104` 与 AWS 数据同步不依赖 `.pem` 证书文件。 + +真正依赖的是: + +- Redis 安全组放行 +- RDS 白名单 / 安全组放行 +- 正确的 Redis 密码 +- 正确的 MySQL 账号密码 + ## 5. Redis 实际部署与同步状态 ### 5.1 AWS Redis 主库 @@ -186,6 +405,8 @@ RDS 不应该对公网全开放。 - 从 `104` 连接 AWS Redis 主库,认证成功 - AWS 主库写入测试键 - `104` 从库成功读取测试键 +- `2026-05-13` 已确认应用机本地 `ppanel-server -> 127.0.0.1:6379` 建立稳定连接 +- `2026-05-13` 已确认旧 `stunnel4 -> ElastiCache` 链路下线后,应用日志不再出现 Redis `i/o timeout` 测试键: @@ -206,7 +427,7 @@ flowchart LR ### 6.1 主库角色 - 主库在 `AWS RDS MySQL` -- 实例:`hifast-mysql-prod` +- 实例:`hifast-mysql-prod-v2` ### 6.2 外部备用角色 @@ -215,26 +436,32 @@ flowchart LR ### 6.3 当前文档说明 -Redis 的主从状态已经在本次执行中完成并验证。 +MySQL 当前已经完成实际验收,不再只是“待确认”状态。 + +`2026-05-13` 验收结果: + +- `Source_Host = hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com` +- `Replica_IO_Running = Yes` +- `Replica_SQL_Running = Yes` +- `Seconds_Behind_Source = 0` +- `read_only = ON` +- `super_read_only = ON` + +这表示 `104` 当前是健康的只读外部备用库。 MySQL 这部分在此前已经有专门 runbook: - [ops/aws-rds-external-replica-runbook.md](/Users/Apple/code_vpn/vpn/ppanel-server/ops/aws-rds-external-replica-runbook.md) -如果要把 MySQL 也完全纳入同一灾备演练,需要继续确认: - -- `104` 当前 MySQL 的同步线程状态 -- `SHOW REPLICA STATUS\G` 是否仍然正常 -- RDS 到 `104` 的白名单是否仍然保留 - ## 7. 当前生产方案的真实特点 这套已经落地的架构,不是传统的全 AWS 托管标准形态,而是偏实用的混合方案: -- 应用在 AWS EC2 +- 应用和当前实际公网入口在 AWS 同一台 EC2 - MySQL 在 AWS RDS - Redis 在 AWS EC2 本机 - MySQL / Redis 均向外部服务器 `104` 做灾备 +- 旧 ElastiCache / stunnel 链路已经退出当前生产路径 它的优点: @@ -348,6 +575,9 @@ redis-cli -a '' REPLICAOF NO ONE - AWS Redis 主库是否在线 - `104` Redis 从库是否 `master_link_status:up` - `104` MySQL 复制是否正常 +- `ppanel-server` 容器是否 `Up` +- `ppanel-server` 日志中是否再次出现 Redis `i/o timeout` +- `stunnel4` 是否保持 `inactive` ### 9.2 Redis 故障时 @@ -377,7 +607,7 @@ redis-cli -a '' REPLICAOF NO ONE ### 10.1 当前实际方案 -`DNS -> AWS EC2(App + Nginx) -> RDS MySQL + EC2 Redis -> 104 灾备` +`DNS -> hifast-hk-app-01(Nginx + App + Redis) -> RDS MySQL -> 104 灾备` ### 10.2 理想生产方案 @@ -394,11 +624,35 @@ redis-cli -a '' REPLICAOF NO ONE 建议按优先级补齐: -1. 明确 `104` 应用接管脚本与启动检查项 -2. 明确 MySQL 故障切换脚本 -3. 明确 Redis 故障切换脚本 -4. 明确域名 / DNS 切换方式 -5. 做一次完整灾备演练 +1. 把 RDS 从“private 子网挂公网路由”的临时方案,收敛成真正的公网 DB subnet group,或改成私网复制方案 +2. 明确 `104` 应用接管脚本与启动检查项 +3. 明确 MySQL 故障切换脚本 +4. 明确 Redis 故障切换脚本 +5. 明确域名 / DNS 切换方式 +6. 做一次完整灾备演练 +7. 待 AWS 新资源到位后,再把公网入口迁到独立 `nginx` 服务器 + +### 10.4 RDS 推荐收敛路线 + +当前原先规划的“新建规范 RDS 再切换”路线已经完成,现网主库已经是 `hifast-mysql-prod-v2`。 + +后续更推荐的正式路线是: + +1. 继续以 `hifast-mysql-prod-v2` 作为当前生产主库 +2. 确认其持续使用 `hifast-hk-rds-public-only-sgprep` +3. 安全组持续只放: + - `104.238.220.230/32 -> 3306` + - `hifast-hk-app-core-sg -> 3306` +4. 持续确认应用连接目标为 `hifast-mysql-prod-v2` +5. 持续确认 `104` 的外部复制目标为 `hifast-mysql-prod-v2` +6. 验证通过后,再安排旧 RDS 下线 + +这条路线的优点: + +- 最终拓扑规范清晰 +- 不需要继续保留“private 子网挂公网路由”的临时设计 +- 对当前现网主库的扰动最小 +- 当前数据库体量较小,迁移成本可控 ## 11. 建议的下一版目标拓扑 @@ -423,16 +677,20 @@ flowchart TB 截至当前,已经可以确认的生产与灾备状态是: - AWS 是主生产环境 -- 应用跑在 `hifast-hk-app-01` +- 应用当前跑在 `hifast-hk-app-01` - MySQL 主库在 AWS RDS - Redis 主库在 AWS EC2 Docker - `104.238.220.230` 是异地备用节点 - `104` 已部署与 AWS 相同的业务服务 - `104` 上 Redis 已切为宿主机原生安装 - `104` Redis 已成功作为 AWS Redis 主库的从库在线同步 +- `104` MySQL 已恢复并保持健康复制 +- 应用已经切回当前真实可用的本机 Redis 主库 +- 旧 `stunnel4 -> ElastiCache` 链路已经退出生产路径 如果后续要继续完善这份方案,优先补充: -- MySQL 最终同步状态复核 +- RDS 子网与公网访问模型收敛 - 入口域名 / DNS 切换细则 - 应用层在 `104` 的接管与回切执行清单 +- 待资源到位后的独立 `nginx` 迁移清单 diff --git a/ops/hifast-rds-v2-cutover-checklist-zh.md b/ops/hifast-rds-v2-cutover-checklist-zh.md new file mode 100644 index 0000000..8eaf5f0 --- /dev/null +++ b/ops/hifast-rds-v2-cutover-checklist-zh.md @@ -0,0 +1,286 @@ +# Hifast 新 RDS 生产切换清单(已完成归档) + +本文档记录已完成的 `hifast-mysql-prod -> hifast-mysql-prod-v2` 生产切换过程,作为归档和回溯参考。 + +本次切换已经完成,当时的目标是避免继续在线硬改现有生产 RDS,而是: + +1. 新建一台规范公网子网组的新 RDS +2. 导入现有 `hifast` 数据 +3. 将 AWS 应用切到新 RDS +4. 将 `104.238.220.230` 的外部从库改挂新 RDS +5. 验收通过后再下线旧 RDS + +## 1. 适用背景 + +当前现网已经可用,但还存在 1 个结构性问题: + +- 为了让 `104` 通过公网白名单做 MySQL 复制,当时的 `hifast-mysql-prod` 仍依赖 `hifast-hk-private-1b` 临时挂公网路由 + +当前已准备好的收敛资源: + +- 纯公网 DB subnet group: + - `hifast-hk-rds-public-only-sgprep` +- 安全组: + - `hifast-hk-rds-core-sg` + +## 2. 目标实例参数 + +建议新实例名称: + +- `hifast-mysql-prod-v2` + +建议参数如下: + +- Region: `ap-east-1` +- Engine: `MySQL` +- Engine version: `8.4.8` +- Templates: `Production` +- DB instance class: `db.r7g.xlarge` +- Storage type: `gp3` +- Allocated storage: `200 GiB` +- Provisioned IOPS: `3000` +- Storage throughput: `125` +- Multi-AZ: `No` +- Publicly accessible: `Yes` +- VPC: `vpc-09fc384522517debc` +- DB subnet group: `hifast-hk-rds-public-only-sgprep` +- VPC security group: `hifast-hk-rds-core-sg` +- DB name: `hifast` +- Master username: `admin` +- Master password: 与现网保持一致 +- Backup retention: `7 days` +- Performance Insights: `On` +- Storage encryption: `On` +- Deletion protection: `On` +- Auto minor version upgrade: 建议保持与现网一致 +- Maintenance window: 可与现网同策略,建议维护窗口内切换 + +## 3. 切换前确认 + +切换前必须满足: + +1. `104` 当前主从正常: + - `Replica_IO_Running: Yes` + - `Replica_SQL_Running: Yes` + - `Seconds_Behind_Source: 0` +2. AWS 应用机心跳正常: + - `curl http://127.0.0.1:8080/v1/common/heartbeat` +3. AWS Redis 主从正常: + - AWS 主 `connected_slaves:1` + - `104` 从 `master_link_status:up` +4. 已确认当前应用真实配置文件: + - `/opt/ppanel/configs/ppanel.yaml` +5. 已确认当前应用重启方式: + - `cd /opt/ppanel && docker compose -f docker-compose.cloud.yml up -d ppanel-server` + +## 4. 创建新 RDS + +已在 AWS 控制台创建 `hifast-mysql-prod-v2`,未对原 `hifast-mysql-prod` 做高风险在线子网调整。 + +创建完成后先确认: + +1. 新 endpoint 已分配 +2. `Publicly accessible = Yes` +3. SG 为 `hifast-hk-rds-core-sg` +4. DB subnet group 为 `hifast-hk-rds-public-only-sgprep` +5. 从 `104` 可以 TCP 连通 `3306` + +连通性验证: + +```bash +nc -zv 3306 +``` + +## 5. 导出旧主库 + +在一台可连旧 RDS 的机器执行: + +```bash +mysqldump \ + -h hifast-mysql-prod.cd6aey40m6ag.ap-east-1.rds.amazonaws.com \ + -u admin \ + -p \ + --single-transaction \ + --routines \ + --triggers \ + --events \ + --set-gtid-purged=OFF \ + hifast > hifast-full.sql +``` + +说明: + +- 当前业务库体量约 `187 MB` +- 这条路线的成本低,且比现网主库在线改子网更稳 + +## 6. 初始化新 RDS + +先连接新 RDS: + +```bash +mysql -h -u admin -p +``` + +建议先执行: + +```sql +CALL mysql.rds_set_configuration('binlog retention hours', 24); + +CREATE USER IF NOT EXISTS 'repl'@'104.238.220.230' IDENTIFIED BY ''; +GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'104.238.220.230'; +FLUSH PRIVILEGES; +``` + +如果库是空的,再导入: + +```bash +mysql -h -u admin -p hifast < hifast-full.sql +``` + +导入完成后确认: + +```bash +mysql -h -u admin -p -e "USE hifast; SHOW TABLES;" +``` + +## 7. 切换 AWS 应用到新 RDS + +### 7.1 备份当前配置 + +在 AWS app EC2: + +```bash +cp /opt/ppanel/configs/ppanel.yaml /opt/ppanel/configs/ppanel.yaml.bak.$(date +%Y%m%d%H%M%S) +``` + +### 7.2 修改数据库地址 + +编辑: + +- `/opt/ppanel/configs/ppanel.yaml` + +把: + +```yaml +MySQL: + Addr: hifast-mysql-prod.cd6aey40m6ag.ap-east-1.rds.amazonaws.com:3306 +``` + +改成: + +```yaml +MySQL: + Addr: hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com:3306 +``` + +### 7.3 重启业务容器 + +```bash +cd /opt/ppanel +docker compose -f docker-compose.cloud.yml up -d ppanel-server +``` + +### 7.4 应用验收 + +```bash +curl -sf http://127.0.0.1:8080/v1/common/heartbeat +docker compose -f /opt/ppanel/docker-compose.cloud.yml logs --tail=100 ppanel-server +``` + +重点确认: + +- 心跳返回 `200` +- 日志中无 MySQL 连接异常 + +## 8. 改挂 `104` 从库到新 RDS + +先在新 RDS 获取位点: + +```sql +SHOW MASTER STATUS; +``` + +然后在 `104` 执行: + +```sql +STOP REPLICA; +RESET REPLICA ALL; +CHANGE REPLICATION SOURCE TO + SOURCE_HOST='hifast-mysql-prod-v2.cd6aey40m6ag.ap-east-1.rds.amazonaws.com', + SOURCE_PORT=3306, + SOURCE_USER='repl', + SOURCE_PASSWORD='', + SOURCE_LOG_FILE='', + SOURCE_LOG_POS=, + SOURCE_SSL=1; +START REPLICA; +SHOW REPLICA STATUS\G +``` + +验收标准: + +- `Replica_IO_Running: Yes` +- `Replica_SQL_Running: Yes` +- `Seconds_Behind_Source: 0` + +## 9. 切换后验收 + +至少做下面这些检查: + +1. AWS 应用心跳正常 +2. 管理后台可登录 +3. 新建一条测试数据后,主库可见 +4. `104` 从库能同步到该测试数据 +5. Navicat 可从白名单来源连接新 RDS +6. Redis 主从仍正常,不受本次 MySQL 切换影响 + +推荐额外核对: + +```bash +docker compose -f /opt/ppanel/docker-compose.cloud.yml ps +docker exec hifast-redis redis-cli -a '' INFO replication +``` + +## 10. 回滚方案 + +如果切换后 AWS 应用异常: + +1. 立刻把 `/opt/ppanel/configs/ppanel.yaml` 中 `MySQL.Addr` 改回旧 endpoint +2. 重启 `ppanel-server`: + +```bash +cd /opt/ppanel +docker compose -f docker-compose.cloud.yml up -d ppanel-server +``` + +3. 优先恢复主生产可用 +4. `104` 是否回切旧 RDS 复制,视恢复窗口决定 + +如果只是 `104` 复制改挂失败,但 AWS 应用已正常使用新 RDS: + +- 不必立刻回滚应用 +- 先修好 `104 -> 新 RDS` 的白名单、位点、用户或网络 + +## 11. 切换完成后的收尾 + +全部验收通过后再做: + +1. 已将新 endpoint 记录到正式运维文档 +2. 仍需根据回收窗口安排旧 RDS 下线 +3. 仍需按网络收敛计划处理 `private-1b` 路由语义 +4. 已更新外部复制 runbook 中的主库 endpoint + +## 12. 当前建议的执行顺序 + +本次切换当时按以下顺序执行: + +1. 创建 `hifast-mysql-prod-v2` +2. 验证新 RDS 网络与参数 +3. 导出旧库 +4. 导入新库 +5. 创建 / 确认 `repl` 用户 +6. 切 AWS 应用到新 RDS +7. 验证应用 +8. 改挂 `104` 到新 RDS +9. 验证从库 +10. 收尾,并保留旧 RDS 待后续下线 diff --git a/ops/hifast-s3-backup-runbook-zh.md b/ops/hifast-s3-backup-runbook-zh.md new file mode 100644 index 0000000..8972691 --- /dev/null +++ b/ops/hifast-s3-backup-runbook-zh.md @@ -0,0 +1,275 @@ +# Hifast S3 备份集成 Runbook + +本文档记录 `2026-05-13` 已经实际确认和完成的 S3 备份集成状态,以及后续如何把它和当前 `AWS 主生产 + 104 外部备用` 架构结合起来。 + +## 1. 当前已完成状态 + +- 已创建 S3 备份桶:`hifast-prod-backups-200810848252-ap-east-1` +- Region: `ap-east-1` +- Public access: blocked +- Versioning: enabled +- 已确认 RDS 主库 `hifast-mysql-prod-v2` 自动备份已启用: + - retention: `7 days` + - `2026-05-13` 已有自动快照 +- 已确认 `104.238.220.230` MySQL 外部从库健康,可作为逻辑备份源: + - `Replica_IO_Running: Yes` + - `Replica_SQL_Running: Yes` + - `Seconds_Behind_Source: 0` +- 已确认 `104.238.220.230` Redis 从库健康,可作为 RDB 备份源: + - `role:slave` + - `master_link_status:up` + +## 2. 推荐组合方案 + +当前最稳的做法不是只依赖一种备份,而是保留两层: + +1. `RDS automated backup` +2. `104` 从库导出的逻辑备份上传到 S3 + +原因: + +- RDS 自动备份适合快速恢复整库 +- S3 逻辑备份适合独立下载、跨环境恢复、长期归档 +- 从 `104` 导出 MySQL / Redis 备份,对 AWS 主生产扰动最小 + +## 3. 仓库已补充内容 + +- MySQL 备份脚本: + - [`deploy/scripts/mysql_backup_to_s3.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/mysql_backup_to_s3.sh) +- Redis RDB 备份脚本: + - [`deploy/scripts/redis_rdb_backup_to_s3.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/redis_rdb_backup_to_s3.sh) +- 环境变量模板: + - [`deploy/aws/ap-east-1/configs/backup-to-s3.env.example`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/aws/ap-east-1/configs/backup-to-s3.env.example) +- 主从切换环境变量模板: + - [`deploy/aws/ap-east-1/configs/replica-ops.env.example`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/aws/ap-east-1/configs/replica-ops.env.example) +- 数据迁移交互工具: + - [`deploy/scripts/hifast_data_sync_tool.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/hifast_data_sync_tool.sh) +- 主从运维交互工具: + - 统一入口仍使用 [`deploy/scripts/hifast_data_sync_tool.sh`](/Users/Apple/code_vpn/vpn/ppanel-server/deploy/scripts/hifast_data_sync_tool.sh) + +## 4. 建议部署位置 + +### 4.1 MySQL + +优先部署在 `104.238.220.230`: + +- 直接从本地 MySQL 从库导出 +- 不占用 AWS RDS 主库的备份窗口 +- 故障时备份和备用节点仍在同一台机器上 + +### 4.2 Redis + +优先部署在 `104.238.220.230`: + +- 直接从 Redis 从库导出 `RDB` +- 不影响 AWS Redis 主库对外服务 + +## 5. 104 当前还缺的东西 + +截至 `2026-05-13`,`104` 已具备: + +- `mysql` +- `mysqldump` +- `gzip` + +但仍缺: + +- `aws cli` +- 一套最小权限的 S3 上传凭证 + +## 6. 推荐权限模型 + +当前最实用的选择有两种: + +1. `104` 使用专用 IAM 用户的最小权限 `AK/SK` +2. 未来如果备份转到 AWS EC2,再改为 `EC2 Instance Role` + +按现有拓扑,推荐先走第 1 种,因为 MySQL 和 Redis 的备份源都在 `104`。 + +### 6.1 最小权限策略示例 + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "ListBackupBucket", + "Effect": "Allow", + "Action": [ + "s3:ListBucket" + ], + "Resource": "arn:aws:s3:::hifast-prod-backups-200810848252-ap-east-1" + }, + { + "Sid": "WriteBackupObjects", + "Effect": "Allow", + "Action": [ + "s3:PutObject", + "s3:AbortMultipartUpload" + ], + "Resource": "arn:aws:s3:::hifast-prod-backups-200810848252-ap-east-1/*" + } + ] +} +``` + +说明: + +- 不建议给 `s3:*` +- 不建议把 AK/SK 写进 repo +- 建议只写入 `104` 本机的 `/root/.aws/credentials` + +## 7. 104 安装与配置步骤 + +### 7.1 安装 `aws cli` + +```bash +apt-get update +apt-get install -y awscli +``` + +### 7.2 写入 AWS 凭证 + +```bash +mkdir -p /root/.aws +chmod 700 /root/.aws +cat >/root/.aws/credentials <<'EOF' +[default] +aws_access_key_id=CHANGE_ME +aws_secret_access_key=CHANGE_ME +EOF +chmod 600 /root/.aws/credentials +``` + +### 7.3 准备环境变量文件 + +```bash +cp deploy/aws/ap-east-1/configs/backup-to-s3.env.example /root/backup-to-s3.env +chmod 600 /root/backup-to-s3.env +``` + +把下面这些值改成真实值: + +- `MYSQL_PASSWORD` +- `REDIS_PASSWORD` +- `HOST_TAG` + +如果 MySQL 就跑在 `104` 本机,可保持: + +- `MYSQL_HOST=127.0.0.1` + +如果 Redis 就跑在 `104` 本机,可保持: + +- `REDIS_HOST=127.0.0.1` + +## 8. 手工执行方式 + +### 8.1 MySQL 逻辑备份 + +```bash +set -a +source /root/backup-to-s3.env +set +a + +bash deploy/scripts/mysql_backup_to_s3.sh +``` + +默认产物: + +- 本地:`/var/backups/hifast/*.sql.gz` +- S3:`s3://hifast-prod-backups-200810848252-ap-east-1/mysql//` + +### 8.2 Redis RDB 备份 + +```bash +set -a +source /root/backup-to-s3.env +set +a + +S3_PREFIX=redis bash deploy/scripts/redis_rdb_backup_to_s3.sh +``` + +默认产物: + +- 本地:`/var/backups/hifast/*.rdb.gz` +- S3:`s3://hifast-prod-backups-200810848252-ap-east-1/redis//` + +## 9. 定时任务建议 + +### 9.1 MySQL 每天凌晨执行 + +```cron +15 3 * * * . /root/backup-to-s3.env && /bin/bash /opt/ppanel/deploy/scripts/mysql_backup_to_s3.sh >>/var/log/hifast-mysql-backup.log 2>&1 +``` + +### 9.2 Redis 每天凌晨执行 + +```cron +45 3 * * * . /root/backup-to-s3.env && S3_PREFIX=redis /bin/bash /opt/ppanel/deploy/scripts/redis_rdb_backup_to_s3.sh >>/var/log/hifast-redis-backup.log 2>&1 +``` + +说明: + +- MySQL 和 Redis 建议错峰执行 +- 本地临时文件默认只保留 `3` 天 +- 长期保留建议通过 S3 Lifecycle 管理,而不是靠本机 cron 删除 + +## 10. 恢复思路 + +### 10.1 MySQL + +1. 从 S3 下载目标 `sql.gz` +2. 校验 `.sha256` +3. 解压 +4. 导入目标 MySQL + +示例: + +```bash +aws s3 cp s3://hifast-prod-backups-200810848252-ap-east-1/mysql/104-standby/20260513T120000Z_104-standby_hifast.sql.gz . +aws s3 cp s3://hifast-prod-backups-200810848252-ap-east-1/mysql/104-standby/20260513T120000Z_104-standby_hifast.sql.gz.sha256 . +sha256sum -c 20260513T120000Z_104-standby_hifast.sql.gz.sha256 +gunzip -c 20260513T120000Z_104-standby_hifast.sql.gz | mysql -h -u -p +``` + +### 10.2 Redis + +1. 从 S3 下载目标 `rdb.gz` +2. 校验 `.sha256` +3. 解压得到 `dump.rdb` +4. 在维护窗口内替换 Redis 数据文件后重启 + +## 11. 当前推荐落地顺序 + +1. 保持当前 `RDS automated backup` 不变 +2. 在 `104` 安装 `aws cli` +3. 创建最小权限 S3 上传凭证并仅保存到 `104` +4. 先手工执行一轮 MySQL 备份上传 +5. 验证 S3 对象、校验文件、恢复可读性 +6. 再补 Redis RDB 备份 +7. 最后加 cron 和 S3 Lifecycle + +## 12. 104 上的交互式运维脚本 + +为了减少手工敲命令,仓库里现在统一使用一套交互式总入口。 + +### 12.1 统一入口 + +```bash +bash deploy/scripts/hifast_data_sync_tool.sh /root/replica-ops.env +``` + +菜单支持: + +- 备份 MySQL 到 S3 +- 备份 Redis 到 S3 +- 导出 MySQL dump +- 导入 MySQL dump 到 AWS RDS +- 导出后直接导入 +- 导出 Redis RDB +- 导入 Redis RDB 到 Docker / 宿主机 Redis +- 查看 MySQL / Redis 当前主从状态 +- 强制重拉 MySQL 主从 +- 强制重拉 Redis 主从 +- 把 MySQL 从库提升为可写主库 +- 把 Redis 从库提升为主库 diff --git a/pkg/cache/gorm_test.go b/pkg/cache/gorm_test.go deleted file mode 100644 index c090771..0000000 --- a/pkg/cache/gorm_test.go +++ /dev/null @@ -1,183 +0,0 @@ -package cache - -import ( - "context" - "encoding/json" - "errors" - "testing" - "time" - - "github.com/alicebob/miniredis/v2" - "github.com/redis/go-redis/v9" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gorm.io/driver/sqlite" - "gorm.io/gorm" -) - -// testUser is a simple struct used across all QueryCtx tests. -type testUser struct { - ID int64 `json:"id"` - Name string `json:"name"` -} - -// setupCachedConn creates a CachedConn backed by a real miniredis instance -// and a bare *gorm.DB (no real database connection needed because the -// QueryCtxFn callback is fully under our control). -func setupCachedConn(t *testing.T) (CachedConn, *miniredis.Miniredis) { - t.Helper() - - mr := miniredis.RunT(t) - - rdb := redis.NewClient(&redis.Options{ - Addr: mr.Addr(), - }) - t.Cleanup(func() { rdb.Close() }) - - // Use SQLite in-memory to get a properly initialized *gorm.DB. - db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) - require.NoError(t, err) - - cc := NewConn(db, rdb, WithExpiry(time.Minute)) - return cc, mr -} - -func TestQueryCtx_CacheHit(t *testing.T) { - cc, mr := setupCachedConn(t) - ctx := context.Background() - key := "cache:user:1" - - // Pre-populate the cache with valid JSON. - expected := testUser{ID: 1, Name: "Alice"} - data, err := json.Marshal(expected) - require.NoError(t, err) - mr.Set(key, string(data)) - - // Track whether the DB query function is called. - dbCalled := false - queryFn := func(conn *gorm.DB, v interface{}) error { - dbCalled = true - return nil - } - - var result testUser - err = cc.QueryCtx(ctx, &result, key, queryFn) - - assert.NoError(t, err) - assert.False(t, dbCalled, "DB query should NOT be called on cache hit") - assert.Equal(t, expected.ID, result.ID) - assert.Equal(t, expected.Name, result.Name) -} - -func TestQueryCtx_CacheMiss_QueriesDB_SetsCache(t *testing.T) { - cc, mr := setupCachedConn(t) - ctx := context.Background() - key := "cache:user:2" - - // Do NOT pre-populate the cache -- this is a cache miss scenario. - dbCalled := false - queryFn := func(conn *gorm.DB, v interface{}) error { - dbCalled = true - u := v.(*testUser) - u.ID = 2 - u.Name = "Bob" - return nil - } - - var result testUser - err := cc.QueryCtx(ctx, &result, key, queryFn) - - assert.NoError(t, err) - assert.True(t, dbCalled, "DB query should be called on cache miss") - assert.Equal(t, int64(2), result.ID) - assert.Equal(t, "Bob", result.Name) - - // Verify the value was written back to cache. - cached, cacheErr := mr.Get(key) - require.NoError(t, cacheErr) - - var cachedUser testUser - require.NoError(t, json.Unmarshal([]byte(cached), &cachedUser)) - assert.Equal(t, int64(2), cachedUser.ID) - assert.Equal(t, "Bob", cachedUser.Name) -} - -func TestQueryCtx_CorruptedCache_SelfHeals(t *testing.T) { - cc, mr := setupCachedConn(t) - ctx := context.Background() - key := "cache:user:3" - - // Store invalid JSON in the cache to simulate corruption. - mr.Set(key, "THIS IS NOT VALID JSON{{{") - - dbCalled := false - queryFn := func(conn *gorm.DB, v interface{}) error { - dbCalled = true - u := v.(*testUser) - u.ID = 3 - u.Name = "Charlie" - return nil - } - - var result testUser - err := cc.QueryCtx(ctx, &result, key, queryFn) - - assert.NoError(t, err) - assert.True(t, dbCalled, "DB query should be called when cache is corrupted") - assert.Equal(t, int64(3), result.ID) - assert.Equal(t, "Charlie", result.Name) - - // Verify the corrupt key was replaced with valid data. - cached, cacheErr := mr.Get(key) - require.NoError(t, cacheErr) - - var cachedUser testUser - require.NoError(t, json.Unmarshal([]byte(cached), &cachedUser)) - assert.Equal(t, int64(3), cachedUser.ID) - assert.Equal(t, "Charlie", cachedUser.Name) -} - -func TestQueryCtx_CacheMiss_DBFails_ReturnsError(t *testing.T) { - cc, mr := setupCachedConn(t) - ctx := context.Background() - key := "cache:user:4" - - // No cache entry -- this is a miss. - dbErr := errors.New("connection refused") - queryFn := func(conn *gorm.DB, v interface{}) error { - return dbErr - } - - var result testUser - err := cc.QueryCtx(ctx, &result, key, queryFn) - - assert.Error(t, err) - assert.Equal(t, dbErr, err) - - // Cache should remain empty -- no value was written. - assert.False(t, mr.Exists(key), "cache should NOT be set when DB query fails") -} - -func TestQueryCtx_CorruptedCache_DBFails_ReturnsError(t *testing.T) { - cc, mr := setupCachedConn(t) - ctx := context.Background() - key := "cache:user:5" - - // Store invalid JSON to trigger the corruption branch. - mr.Set(key, "<<>>") - - dbErr := errors.New("database is down") - queryFn := func(conn *gorm.DB, v interface{}) error { - return dbErr - } - - var result testUser - err := cc.QueryCtx(ctx, &result, key, queryFn) - - assert.Error(t, err) - assert.Equal(t, dbErr, err) - - // The corrupt key should have been deleted (DelCache was called), - // and no new value was set because the DB query failed. - assert.False(t, mr.Exists(key), "corrupt key should be deleted even when DB fails") -} diff --git a/queue/logic/order/activateOrderLogic_invite_test.go b/queue/logic/order/activateOrderLogic_invite_test.go deleted file mode 100644 index 3b77679..0000000 --- a/queue/logic/order/activateOrderLogic_invite_test.go +++ /dev/null @@ -1,806 +0,0 @@ -package orderLogic - -import ( - "context" - "fmt" - "os" - "strings" - "testing" - "time" - - "github.com/perfect-panel/server/internal/config" - userLogic "github.com/perfect-panel/server/internal/logic/public/user" - modelLog "github.com/perfect-panel/server/internal/model/log" - "github.com/perfect-panel/server/internal/model/order" - "github.com/perfect-panel/server/internal/model/user" - "github.com/perfect-panel/server/internal/svc" - "github.com/perfect-panel/server/internal/types" - "github.com/perfect-panel/server/pkg/constant" - "github.com/redis/go-redis/v9" - "gorm.io/driver/mysql" - "gorm.io/gorm" -) - -// 普通用户 + 首单 → 双方赠N天 -func TestHandleCommission_GrantGiftDaysWhenCommissionDisabled_FirstOrder(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 0, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - referee.RefererId = referer.Id - - baseExpire := time.Now().Add(72 * time.Hour).Truncate(time.Second) - refereeSub := seedActiveSubscribe(t, db, referee.Id, baseExpire) - refererSub := seedActiveSubscribe(t, db, referer.Id, baseExpire) - - logic.handleCommission(context.Background(), referee, &order.Order{ - OrderNo: "ORD-GIFT-001", - Type: OrderTypeSubscribe, - IsNew: true, // 首单 - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - }) - - assertExpireIncreasedByDays(t, db, refereeSub.Id, baseExpire, 2) - assertExpireIncreasedByDays(t, db, refererSub.Id, baseExpire, 2) - - var giftCount int64 - if err := db.Model(&modelLog.SystemLog{}).Where("type = ?", modelLog.TypeGift.Uint8()).Count(&giftCount).Error; err != nil { - t.Fatalf("count gift logs failed: %v", err) - } - if giftCount != 2 { - t.Fatalf("expected 2 gift logs, got %d", giftCount) - } -} - -// 普通用户 + 非首单 → 不赠送 -func TestHandleCommission_NoGiftDaysWhenCommissionDisabled_NotFirstOrder(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 0, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - referee.RefererId = referer.Id - - baseExpire := time.Now().Add(72 * time.Hour).Truncate(time.Second) - refereeSub := seedActiveSubscribe(t, db, referee.Id, baseExpire) - refererSub := seedActiveSubscribe(t, db, referer.Id, baseExpire) - - logic.handleCommission(context.Background(), referee, &order.Order{ - OrderNo: "ORD-GIFT-002", - Type: OrderTypeSubscribe, - IsNew: false, // 非首单 - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - }) - - // 到期时间不应延长 - assertExpireIncreasedByDays(t, db, refereeSub.Id, baseExpire, 0) - assertExpireIncreasedByDays(t, db, refererSub.Id, baseExpire, 0) - - var giftCount int64 - if err := db.Model(&modelLog.SystemLog{}).Where("type = ?", modelLog.TypeGift.Uint8()).Count(&giftCount).Error; err != nil { - t.Fatalf("count gift logs failed: %v", err) - } - if giftCount != 0 { - t.Fatalf("expected 0 gift logs for non-first order, got %d", giftCount) - } -} - -// 渠道 + 首单 → 被邀请人赠N天 + 邀请人获佣金 -func TestHandleCommission_GiftDaysAndCommissionWhenChannelFirstOrder(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 10, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - referee.RefererId = referer.Id - - baseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second) - refereeSub := seedActiveSubscribe(t, db, referee.Id, baseExpire) - - logic.handleCommission(context.Background(), referee, &order.Order{ - OrderNo: "ORD-COMM-001", - Type: OrderTypeSubscribe, - IsNew: true, // 首单 - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - }) - - // 被邀请人(首单)应获得赠送天数 - assertExpireIncreasedByDays(t, db, refereeSub.Id, baseExpire, 2) - - // 邀请人应获得佣金 - var refererAfter user.User - if err := db.First(&refererAfter, referer.Id).Error; err != nil { - t.Fatalf("query referer failed: %v", err) - } - if refererAfter.Commission != 10 { - t.Fatalf("expected referer commission=10, got %d", refererAfter.Commission) - } - - var giftCount int64 - if err := db.Model(&modelLog.SystemLog{}).Where("type = ?", modelLog.TypeGift.Uint8()).Count(&giftCount).Error; err != nil { - t.Fatalf("count gift logs failed: %v", err) - } - if giftCount != 1 { - t.Fatalf("expected 1 gift log for referee on first order with commission, got %d", giftCount) - } -} - -// 渠道 + 非首单 → 只给邀请人佣金,不赠天 -func TestHandleCommission_OnlyCommissionWhenChannelNotFirstOrder(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 10, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - referee.RefererId = referer.Id - - baseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second) - refereeSub := seedActiveSubscribe(t, db, referee.Id, baseExpire) - - logic.handleCommission(context.Background(), referee, &order.Order{ - OrderNo: "ORD-COMM-002", - Type: OrderTypeSubscribe, - IsNew: false, // 非首单 - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - }) - - // 被邀请人不应获得赠送天数 - assertExpireIncreasedByDays(t, db, refereeSub.Id, baseExpire, 0) - - // 邀请人应获得佣金 - var refererAfter user.User - if err := db.First(&refererAfter, referer.Id).Error; err != nil { - t.Fatalf("query referer failed: %v", err) - } - if refererAfter.Commission != 10 { - t.Fatalf("expected referer commission=10, got %d", refererAfter.Commission) - } - - var giftCount int64 - if err := db.Model(&modelLog.SystemLog{}).Where("type = ?", modelLog.TypeGift.Uint8()).Count(&giftCount).Error; err != nil { - t.Fatalf("count gift logs failed: %v", err) - } - if giftCount != 0 { - t.Fatalf("expected 0 gift logs when channel non-first order, got %d", giftCount) - } -} - -func TestHandleCommission_NoGiftDaysWhenNoInviteRelation(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 0, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - // 没有邀请人的独立用户 - loneUser := seedUser(t, db, 0, false) - // RefererId == 0,无邀请关系 - - baseExpire := time.Now().Add(72 * time.Hour).Truncate(time.Second) - loneSub := seedActiveSubscribe(t, db, loneUser.Id, baseExpire) - - logic.handleCommission(context.Background(), loneUser, &order.Order{ - OrderNo: "ORD-LONE-001", - Type: OrderTypeSubscribe, - IsNew: true, - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - }) - - // 订阅到期时间不应该被延长 - var subAfter user.Subscribe - if err := db.First(&subAfter, loneSub.Id).Error; err != nil { - t.Fatalf("query subscribe failed: %v", err) - } - if !subAfter.ExpireTime.Equal(baseExpire) { - t.Fatalf("expected no gift days for user without inviter, before=%v after=%v", baseExpire, subAfter.ExpireTime) - } - - // 不应产生赠天日志 - var giftCount int64 - if err := db.Model(&modelLog.SystemLog{}).Where("type = ?", modelLog.TypeGift.Uint8()).Count(&giftCount).Error; err != nil { - t.Fatalf("count gift logs failed: %v", err) - } - if giftCount != 0 { - t.Fatalf("expected 0 gift logs for user without inviter, got %d", giftCount) - } -} - -// 先绑码后首单 → 双方赠N天 -func TestInviteFlow_BindThenFirstOrder_GrantGiftDays(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 0, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - referer.ReferCode = fmt.Sprintf("REF-%d", referer.Id) - if err := db.Model(&user.User{}).Where("id = ?", referer.Id).Update("refer_code", referer.ReferCode).Error; err != nil { - t.Fatalf("update referer code failed: %v", err) - } - - refereeBaseExpire := time.Now().Add(48 * time.Hour).Truncate(time.Second) - refererBaseExpire := time.Now().Add(72 * time.Hour).Truncate(time.Second) - refereeSub := seedActiveSubscribe(t, db, referee.Id, refereeBaseExpire) - refererSub := seedActiveSubscribe(t, db, referer.Id, refererBaseExpire) - - ctx := context.WithValue(context.Background(), constant.CtxKeyUser, referee) - bindLogic := userLogic.NewBindInviteCodeLogic(ctx, logic.svc) - if err := bindLogic.BindInviteCode(&types.BindInviteCodeRequest{InviteCode: referer.ReferCode}); err != nil { - t.Fatalf("bind invite code failed: %v", err) - } - - var refereeAfterBind user.User - if err := db.First(&refereeAfterBind, referee.Id).Error; err != nil { - t.Fatalf("query referee after bind failed: %v", err) - } - if refereeAfterBind.RefererId != referer.Id { - t.Fatalf("bind invite failed, expected referer_id=%d got=%d", referer.Id, refereeAfterBind.RefererId) - } - - // 首单 IsNew=true → 双方赠N天 - logic.handleCommission(context.Background(), &refereeAfterBind, &order.Order{ - OrderNo: "ORD-FLOW-001", - Type: OrderTypeSubscribe, - IsNew: true, - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - }) - - assertExpireIncreasedByDays(t, db, refereeSub.Id, refereeBaseExpire, 2) - assertExpireIncreasedByDays(t, db, refererSub.Id, refererBaseExpire, 2) -} - -// 先买订单后绑码再续费 → 不赠送(IsNew=false) -func TestInviteFlow_OrderThenBind_NoGiftDays(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 0, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - referee.RefererId = referer.Id - - baseExpire := time.Now().Add(72 * time.Hour).Truncate(time.Second) - refereeSub := seedActiveSubscribe(t, db, referee.Id, baseExpire) - refererSub := seedActiveSubscribe(t, db, referer.Id, baseExpire) - - // 先前已有订单,IsNew=false(模拟先买订单后绑码的场景) - logic.handleCommission(context.Background(), referee, &order.Order{ - OrderNo: "ORD-FLOW-002", - Type: OrderTypeSubscribe, - IsNew: false, // 已有历史订单 - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - }) - - assertExpireIncreasedByDays(t, db, refereeSub.Id, baseExpire, 0) - assertExpireIncreasedByDays(t, db, refererSub.Id, baseExpire, 0) -} - -func TestHandleCommission_GiftDaysToRefereeFamilyOwnerWhenChannelFirstOrder(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 10, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - refereeOwner := seedUser(t, db, 0, false) - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - seedFamily(t, db, refereeOwner.Id, referee.Id) - referee.RefererId = referer.Id - - ownerBaseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second) - ownerSub := seedActiveSubscribe(t, db, refereeOwner.Id, ownerBaseExpire) - - logic.handleCommission(context.Background(), referee, &order.Order{ - OrderNo: "ORD-FAMILY-REFEREE-001", - Type: OrderTypeSubscribe, - IsNew: true, - Amount: 100, - FeeAmount: 0, - SubscriptionUserId: refereeOwner.Id, - CreatedAt: time.Now(), - }) - - assertExpireIncreasedByDays(t, db, ownerSub.Id, ownerBaseExpire, 2) - assertUserCommission(t, db, referer.Id, 10) -} - -func TestHandleCommission_GiftDaysToRefererFamilyOwnerWhenCommissionDisabled(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 0, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - refererOwner := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - seedFamily(t, db, refererOwner.Id, referer.Id) - referee.RefererId = referer.Id - - refereeBaseExpire := time.Now().Add(72 * time.Hour).Truncate(time.Second) - refererOwnerBaseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second) - refereeSub := seedActiveSubscribe(t, db, referee.Id, refereeBaseExpire) - refererOwnerSub := seedActiveSubscribe(t, db, refererOwner.Id, refererOwnerBaseExpire) - - logic.handleCommission(context.Background(), referee, &order.Order{ - OrderNo: "ORD-FAMILY-REFERER-001", - Type: OrderTypeSubscribe, - IsNew: true, - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - }) - - assertExpireIncreasedByDays(t, db, refereeSub.Id, refereeBaseExpire, 2) - assertExpireIncreasedByDays(t, db, refererOwnerSub.Id, refererOwnerBaseExpire, 2) -} - -func TestHandleCommission_RefererFamilyMemberCommissionBehaviorUnchanged(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 10, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - refererOwner := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - seedFamily(t, db, refererOwner.Id, referer.Id) - referee.RefererId = referer.Id - - refereeBaseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second) - refereeSub := seedActiveSubscribe(t, db, referee.Id, refereeBaseExpire) - - logic.handleCommission(context.Background(), referee, &order.Order{ - OrderNo: "ORD-FAMILY-COMMISSION-001", - Type: OrderTypeSubscribe, - IsNew: true, - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - }) - - assertExpireIncreasedByDays(t, db, refereeSub.Id, refereeBaseExpire, 2) - assertUserCommission(t, db, referer.Id, 10) - assertUserCommission(t, db, refererOwner.Id, 0) -} - -func TestHandleCommission_GiftDaysRecognizesUnlimitedSubscription(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 10, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - referee.RefererId = referer.Id - - unlimitedExpire := time.UnixMilli(0) - refereeSub := seedActiveSubscribe(t, db, referee.Id, unlimitedExpire) - - logic.handleCommission(context.Background(), referee, &order.Order{ - OrderNo: "ORD-UNLIMITED-001", - Type: OrderTypeSubscribe, - IsNew: true, - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - }) - - assertExpireIncreasedByDays(t, db, refereeSub.Id, unlimitedExpire, 0) - var giftCount int64 - if err := db.Model(&modelLog.SystemLog{}).Where("type = ? AND object_id = ?", modelLog.TypeGift.Uint8(), referee.Id).Count(&giftCount).Error; err != nil { - t.Fatalf("count gift logs failed: %v", err) - } - if giftCount != 1 { - t.Fatalf("expected 1 gift log for unlimited subscription, got %d", giftCount) - } -} - -func TestHandleCommission_IdempotentForRepeatedActivation(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 10, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - referee.RefererId = referer.Id - - baseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second) - refereeSub := seedActiveSubscribe(t, db, referee.Id, baseExpire) - orderInfo := &order.Order{ - OrderNo: "ORD-IDEMPOTENT-001", - Type: OrderTypeSubscribe, - IsNew: true, - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - } - - logic.handleCommission(context.Background(), referee, orderInfo) - logic.handleCommission(context.Background(), referee, orderInfo) - - assertExpireIncreasedByDays(t, db, refereeSub.Id, baseExpire, 2) - assertUserCommission(t, db, referer.Id, 10) - assertLogCountForOrder(t, db, modelLog.TypeCommission.Uint8(), orderInfo.OrderNo, 1) - assertLogCountForOrder(t, db, modelLog.TypeGift.Uint8(), orderInfo.OrderNo, 1) -} - -func TestHandleCommission_NoActiveSubscriptionWritesSkippedGiftLog(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 10, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - referee.RefererId = referer.Id - orderInfo := &order.Order{ - OrderNo: "ORD-SKIPPED-001", - Type: OrderTypeSubscribe, - IsNew: true, - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - } - - logic.handleCommission(context.Background(), referee, orderInfo) - - assertUserCommission(t, db, referer.Id, 10) - assertLogCountForOrder(t, db, modelLog.TypeCommission.Uint8(), orderInfo.OrderNo, 1) - assertLogCountForOrder(t, db, modelLog.TypeGift.Uint8(), orderInfo.OrderNo, 1) - assertGiftLogRemarkContains(t, db, orderInfo.OrderNo, "skipped: no active subscription") -} - -func TestHandleCommission_GiftDaysZeroDoesNotWriteGiftLog(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 10, - OnlyFirstPurchase: false, - GiftDays: 0, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - referee.RefererId = referer.Id - baseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second) - refereeSub := seedActiveSubscribe(t, db, referee.Id, baseExpire) - orderInfo := &order.Order{ - OrderNo: "ORD-GIFT-ZERO-001", - Type: OrderTypeSubscribe, - IsNew: true, - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - } - - logic.handleCommission(context.Background(), referee, orderInfo) - - assertExpireIncreasedByDays(t, db, refereeSub.Id, baseExpire, 0) - assertUserCommission(t, db, referer.Id, 10) - assertLogCountForOrder(t, db, modelLog.TypeCommission.Uint8(), orderInfo.OrderNo, 1) - assertLogCountForOrder(t, db, modelLog.TypeGift.Uint8(), orderInfo.OrderNo, 0) -} - -func TestHandleCommission_GlobalOnlyFirstPurchaseBlocksCommissionAndGiftForNonFirstOrder(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 10, - OnlyFirstPurchase: true, - GiftDays: 2, - }) - defer cleanup() - - referee := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - referee.RefererId = referer.Id - baseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second) - refereeSub := seedActiveSubscribe(t, db, referee.Id, baseExpire) - orderInfo := &order.Order{ - OrderNo: "ORD-NONFIRST-GLOBAL-001", - Type: OrderTypeRenewal, - IsNew: false, - Amount: 100, - FeeAmount: 0, - CreatedAt: time.Now(), - } - - logic.handleCommission(context.Background(), referee, orderInfo) - - assertExpireIncreasedByDays(t, db, refereeSub.Id, baseExpire, 0) - assertUserCommission(t, db, referer.Id, 0) - assertLogCountForOrder(t, db, modelLog.TypeCommission.Uint8(), orderInfo.OrderNo, 0) - assertLogCountForOrder(t, db, modelLog.TypeGift.Uint8(), orderInfo.OrderNo, 0) -} - -func TestHandleCommission_BothFamilySidesUseCorrectGiftOwners(t *testing.T) { - logic, db, cleanup := setupInviteTestLogic(t, config.InviteConfig{ - ReferralPercentage: 0, - OnlyFirstPurchase: false, - GiftDays: 2, - }) - defer cleanup() - - refereeOwner := seedUser(t, db, 0, false) - referee := seedUser(t, db, 0, false) - refererOwner := seedUser(t, db, 0, false) - referer := seedUser(t, db, 0, false) - seedFamily(t, db, refereeOwner.Id, referee.Id) - seedFamily(t, db, refererOwner.Id, referer.Id) - referee.RefererId = referer.Id - - refereeOwnerBaseExpire := time.Now().Add(72 * time.Hour).Truncate(time.Second) - refererOwnerBaseExpire := time.Now().Add(96 * time.Hour).Truncate(time.Second) - refereeOwnerSub := seedActiveSubscribe(t, db, refereeOwner.Id, refereeOwnerBaseExpire) - refererOwnerSub := seedActiveSubscribe(t, db, refererOwner.Id, refererOwnerBaseExpire) - orderInfo := &order.Order{ - OrderNo: "ORD-BOTH-FAMILIES-001", - Type: OrderTypeSubscribe, - IsNew: true, - Amount: 100, - FeeAmount: 0, - SubscriptionUserId: refereeOwner.Id, - CreatedAt: time.Now(), - } - - logic.handleCommission(context.Background(), referee, orderInfo) - - assertExpireIncreasedByDays(t, db, refereeOwnerSub.Id, refereeOwnerBaseExpire, 2) - assertExpireIncreasedByDays(t, db, refererOwnerSub.Id, refererOwnerBaseExpire, 2) - assertNoSubscribeForUser(t, db, referee.Id) - assertNoSubscribeForUser(t, db, referer.Id) - assertLogCountForOrder(t, db, modelLog.TypeGift.Uint8(), orderInfo.OrderNo, 2) -} - -func setupInviteTestLogic(t *testing.T, inviteCfg config.InviteConfig) (*ActivateOrderLogic, *gorm.DB, func()) { - t.Helper() - - mysqlAddr := getenvDefault("TEST_MYSQL_ADDR", "127.0.0.1:3306") - mysqlUser := getenvDefault("TEST_MYSQL_USER", "root") - mysqlPassword := getenvDefault("TEST_MYSQL_PASSWORD", "rootpassword") - - adminDSN := fmt.Sprintf("%s:%s@tcp(%s)/?charset=utf8mb4&parseTime=true&loc=Local&multiStatements=true", mysqlUser, mysqlPassword, mysqlAddr) - adminDB, err := gorm.Open(mysql.Open(adminDSN), &gorm.Config{}) - if err != nil { - t.Fatalf("open mysql admin connection failed: %v", err) - } - - dbName := fmt.Sprintf("ppanel_test_invite_%d", time.Now().UnixNano()) - if err := adminDB.Exec(fmt.Sprintf("CREATE DATABASE `%s` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci", dbName)).Error; err != nil { - t.Fatalf("create test database failed: %v", err) - } - - testDSN := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=true&loc=Local", mysqlUser, mysqlPassword, mysqlAddr, dbName) - db, err := gorm.Open(mysql.Open(testDSN), &gorm.Config{}) - if err != nil { - t.Fatalf("open test database failed: %v", err) - } - - if err := db.AutoMigrate(&user.User{}, &user.Device{}, &user.AuthMethods{}, &user.Subscribe{}, &user.UserFamily{}, &user.UserFamilyMember{}, &modelLog.SystemLog{}); err != nil { - t.Fatalf("auto migrate failed: %v", err) - } - - redisAddr := getenvDefault("TEST_REDIS_ADDR", "127.0.0.1:6379") - redisPassword := getenvDefault("TEST_REDIS_PASSWORD", "") - rdb := redis.NewClient(&redis.Options{ - Addr: redisAddr, - Password: redisPassword, - DB: 0, - }) - if err := rdb.Ping(context.Background()).Err(); err != nil { - t.Fatalf("connect redis failed: %v", err) - } - _ = rdb.FlushDB(context.Background()).Err() - - svcCtx := &svc.ServiceContext{ - DB: db, - Redis: rdb, - UserModel: user.NewModel(db, rdb), - LogModel: modelLog.NewModel(db), - Config: config.Config{ - Invite: inviteCfg, - }, - } - - return NewActivateOrderLogic(svcCtx), db, func() { - _ = rdb.Close() - sqlDB, _ := db.DB() - if sqlDB != nil { - _ = sqlDB.Close() - } - _ = adminDB.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS `%s`", dbName)).Error - } -} - -func seedUser(t *testing.T, db *gorm.DB, referralPercentage uint8, onlyFirstPurchase bool) *user.User { - t.Helper() - u := &user.User{ - Password: "pwd", - Algo: "default", - ReferralPercentage: referralPercentage, - OnlyFirstPurchase: boolPtr(onlyFirstPurchase), - Enable: boolPtr(true), - IsAdmin: boolPtr(false), - EnableBalanceNotify: boolPtr(false), - EnableLoginNotify: boolPtr(false), - EnableSubscribeNotify: boolPtr(false), - EnableTradeNotify: boolPtr(false), - } - if err := db.Create(u).Error; err != nil { - t.Fatalf("seed user failed: %v", err) - } - return u -} - -func seedFamily(t *testing.T, db *gorm.DB, ownerID int64, memberID int64) { - t.Helper() - family := &user.UserFamily{ - OwnerUserId: ownerID, - MaxMembers: 3, - Status: user.FamilyStatusActive, - } - if err := db.Create(family).Error; err != nil { - t.Fatalf("seed family failed: %v", err) - } - now := time.Now() - members := []user.UserFamilyMember{ - { - FamilyId: family.Id, - UserId: ownerID, - Role: user.FamilyRoleOwner, - Status: user.FamilyMemberActive, - JoinSource: "test", - JoinedAt: now, - }, - { - FamilyId: family.Id, - UserId: memberID, - Role: user.FamilyRoleMember, - Status: user.FamilyMemberActive, - JoinSource: "test", - JoinedAt: now, - }, - } - if err := db.Create(&members).Error; err != nil { - t.Fatalf("seed family members failed: %v", err) - } -} - -func seedActiveSubscribe(t *testing.T, db *gorm.DB, userID int64, expireAt time.Time) *user.Subscribe { - t.Helper() - sub := &user.Subscribe{ - UserId: userID, - OrderId: 1, - SubscribeId: 1, - StartTime: time.Now().Add(-24 * time.Hour), - ExpireTime: expireAt, - Traffic: 1024, - Token: fmt.Sprintf("token-%d-%d", userID, time.Now().UnixNano()), - UUID: fmt.Sprintf("uuid-%d-%d", userID, time.Now().UnixNano()), - Status: 1, - } - if err := db.Create(sub).Error; err != nil { - t.Fatalf("seed subscribe failed: %v", err) - } - return sub -} - -func assertExpireIncreasedByDays(t *testing.T, db *gorm.DB, subscribeID int64, before time.Time, days int) { - t.Helper() - var after user.Subscribe - if err := db.First(&after, subscribeID).Error; err != nil { - t.Fatalf("query subscribe failed: %v", err) - } - expected := before.Add(time.Duration(days) * 24 * time.Hour) - if !after.ExpireTime.Equal(expected) { - t.Fatalf("expire time mismatch, expected=%v got=%v", expected, after.ExpireTime) - } -} - -func assertUserCommission(t *testing.T, db *gorm.DB, userID int64, expected int64) { - t.Helper() - var u user.User - if err := db.First(&u, userID).Error; err != nil { - t.Fatalf("query user failed: %v", err) - } - if u.Commission != expected { - t.Fatalf("expected user %d commission=%d, got %d", userID, expected, u.Commission) - } -} - -func assertLogCountForOrder(t *testing.T, db *gorm.DB, logType uint8, orderNo string, expected int64) { - t.Helper() - var count int64 - if err := db.Model(&modelLog.SystemLog{}). - Where("type = ? AND content LIKE ?", logType, "%"+orderNo+"%"). - Count(&count).Error; err != nil { - t.Fatalf("count logs failed: %v", err) - } - if count != expected { - t.Fatalf("expected log type %d count=%d for order %s, got %d", logType, expected, orderNo, count) - } -} - -func assertGiftLogRemarkContains(t *testing.T, db *gorm.DB, orderNo string, want string) { - t.Helper() - var row modelLog.SystemLog - if err := db.Model(&modelLog.SystemLog{}). - Where("type = ? AND content LIKE ?", modelLog.TypeGift.Uint8(), "%"+orderNo+"%"). - First(&row).Error; err != nil { - t.Fatalf("query gift log failed: %v", err) - } - if !strings.Contains(row.Content, want) { - t.Fatalf("expected gift log content to contain %q, got %s", want, row.Content) - } -} - -func assertNoSubscribeForUser(t *testing.T, db *gorm.DB, userID int64) { - t.Helper() - var count int64 - if err := db.Model(&user.Subscribe{}).Where("user_id = ?", userID).Count(&count).Error; err != nil { - t.Fatalf("count subscribes failed: %v", err) - } - if count != 0 { - t.Fatalf("expected user %d to have no direct subscriptions, got %d", userID, count) - } -} - -func boolPtr(v bool) *bool { - return &v -} - -func getenvDefault(key, fallback string) string { - v := os.Getenv(key) - if v == "" { - return fallback - } - return v -} diff --git a/queue/logic/order/activateOrderLogic_newUserEligibility_test.go b/queue/logic/order/activateOrderLogic_newUserEligibility_test.go deleted file mode 100644 index e8ff523..0000000 --- a/queue/logic/order/activateOrderLogic_newUserEligibility_test.go +++ /dev/null @@ -1,199 +0,0 @@ -package orderLogic - -import ( - "context" - "testing" - "time" - - modelOrder "github.com/perfect-panel/server/internal/model/order" - "github.com/perfect-panel/server/internal/model/subscribe" - "github.com/perfect-panel/server/internal/model/user" - "github.com/stretchr/testify/require" - "gorm.io/driver/sqlite" - "gorm.io/gorm" - "gorm.io/gorm/logger" -) - -func setupActivationEligibilityDB(t *testing.T) *gorm.DB { - t.Helper() - - db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{ - Logger: logger.Default.LogMode(logger.Silent), - }) - require.NoError(t, err) - - sqls := []string{ - `CREATE TABLE IF NOT EXISTS "user" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - password VARCHAR(100) NOT NULL DEFAULT '', - created_at DATETIME, - updated_at DATETIME, - deleted_at DATETIME DEFAULT NULL - )`, - `CREATE TABLE IF NOT EXISTS "user_device" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER NOT NULL DEFAULT 0, - identifier VARCHAR(255) NOT NULL DEFAULT '' UNIQUE, - created_at DATETIME, - updated_at DATETIME - )`, - `CREATE TABLE IF NOT EXISTS "user_family" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - owner_user_id INTEGER NOT NULL DEFAULT 0, - status TINYINT NOT NULL DEFAULT 1, - deleted_at DATETIME DEFAULT NULL - )`, - `CREATE TABLE IF NOT EXISTS "user_family_member" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - family_id INTEGER NOT NULL DEFAULT 0, - user_id INTEGER NOT NULL DEFAULT 0, - role TINYINT NOT NULL DEFAULT 0, - status TINYINT NOT NULL DEFAULT 0, - join_source VARCHAR(32) NOT NULL DEFAULT '', - deleted_at DATETIME DEFAULT NULL - )`, - `CREATE TABLE IF NOT EXISTS "order" ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER NOT NULL DEFAULT 0, - order_no VARCHAR(255) NOT NULL DEFAULT '' UNIQUE, - type TINYINT NOT NULL DEFAULT 1, - status TINYINT NOT NULL DEFAULT 1, - subscribe_id INTEGER NOT NULL DEFAULT 0, - quantity INTEGER NOT NULL DEFAULT 1, - created_at DATETIME, - updated_at DATETIME - )`, - } - for _, sql := range sqls { - require.NoError(t, db.Exec(sql).Error) - } - - return db -} - -func insertActivationUser(t *testing.T, db *gorm.DB, userID int64, createdAt time.Time) { - t.Helper() - require.NoError(t, db.Exec( - `INSERT INTO "user" (id, created_at, updated_at) VALUES (?, ?, datetime('now'))`, - userID, - createdAt.UTC().Format("2006-01-02 15:04:05"), - ).Error) -} - -func insertActivationDevice(t *testing.T, db *gorm.DB, userID int64, identifier string, createdAt time.Time) { - t.Helper() - require.NoError(t, db.Exec( - `INSERT INTO "user_device" (user_id, identifier, created_at, updated_at) VALUES (?, ?, ?, datetime('now'))`, - userID, - identifier, - createdAt.UTC().Format("2006-01-02 15:04:05"), - ).Error) -} - -func insertActivationFamily(t *testing.T, db *gorm.DB, familyID, ownerUserID int64) { - t.Helper() - require.NoError(t, db.Exec( - `INSERT INTO "user_family" (id, owner_user_id, status) VALUES (?, ?, 1)`, - familyID, - ownerUserID, - ).Error) -} - -func insertActivationFamilyMember(t *testing.T, db *gorm.DB, familyID, userID int64, role, status uint8, joinSource string) { - t.Helper() - require.NoError(t, db.Exec( - `INSERT INTO "user_family_member" (family_id, user_id, role, status, join_source) VALUES (?, ?, ?, ?, ?)`, - familyID, - userID, - role, - status, - joinSource, - ).Error) -} - -func insertActivationOrder(t *testing.T, db *gorm.DB, orderNo string, userID, subscribeID int64, status uint8) { - t.Helper() - require.NoError(t, db.Exec( - `INSERT INTO "order" (user_id, order_no, type, status, subscribe_id, quantity, created_at, updated_at) - VALUES (?, ?, 1, ?, ?, 1, datetime('now'), datetime('now'))`, - userID, - orderNo, - status, - subscribeID, - ).Error) -} - -func TestValidateNewUserOnlyEligibilityAtActivation_UsesEarliestBoundDeviceTime(t *testing.T) { - db := setupActivationEligibilityDB(t) - - const ( - ownerUserID = int64(1) - memberUserID = int64(2) - familyID = int64(10) - subscribeID = int64(100) - ) - - insertActivationUser(t, db, ownerUserID, time.Now().Add(-1*time.Hour)) - insertActivationUser(t, db, memberUserID, time.Now().Add(-72*time.Hour)) - insertActivationDevice(t, db, memberUserID, "activation-old-device", time.Now().Add(-72*time.Hour)) - insertActivationFamily(t, db, familyID, ownerUserID) - insertActivationFamilyMember(t, db, familyID, ownerUserID, user.FamilyRoleOwner, user.FamilyMemberActive, "owner_init") - insertActivationFamilyMember(t, db, familyID, memberUserID, user.FamilyRoleMember, user.FamilyMemberActive, "bind_email_with_verification") - - err := validateNewUserOnlyEligibilityAtActivation( - context.Background(), - db, - &modelOrder.Order{ - UserId: ownerUserID, - OrderNo: "activation-check-old-device", - Type: OrderTypeSubscribe, - Quantity: 1, - SubscribeId: subscribeID, - }, - &subscribe.Subscribe{ - Id: subscribeID, - Discount: `[{"quantity":1,"discount":90,"new_user_only":true}]`, - }, - ) - - require.Error(t, err) - require.Contains(t, err.Error(), "is not a new user") -} - -func TestValidateNewUserOnlyEligibilityAtActivation_SharesHistoryAcrossBoundScope(t *testing.T) { - db := setupActivationEligibilityDB(t) - - const ( - ownerUserID = int64(11) - memberUserID = int64(12) - familyID = int64(20) - subscribeID = int64(200) - ) - - insertActivationUser(t, db, ownerUserID, time.Now().Add(-1*time.Hour)) - insertActivationUser(t, db, memberUserID, time.Now().Add(-2*time.Hour)) - insertActivationDevice(t, db, memberUserID, "activation-shared-device", time.Now().Add(-2*time.Hour)) - insertActivationFamily(t, db, familyID, ownerUserID) - insertActivationFamilyMember(t, db, familyID, ownerUserID, user.FamilyRoleOwner, user.FamilyMemberActive, "owner_init") - insertActivationFamilyMember(t, db, familyID, memberUserID, user.FamilyRoleMember, user.FamilyMemberActive, "bind_email_with_verification") - insertActivationOrder(t, db, "previous-finished-order", memberUserID, subscribeID, OrderStatusFinished) - - err := validateNewUserOnlyEligibilityAtActivation( - context.Background(), - db, - &modelOrder.Order{ - UserId: ownerUserID, - OrderNo: "current-paid-order", - Type: OrderTypeSubscribe, - Quantity: 1, - SubscribeId: subscribeID, - }, - &subscribe.Subscribe{ - Id: subscribeID, - Discount: `[{"quantity":1,"discount":90,"new_user_only":true}]`, - }, - ) - - require.Error(t, err) - require.Contains(t, err.Error(), "already activated") -} diff --git a/result.txt b/result.txt deleted file mode 100644 index ab9bb7f..0000000 --- a/result.txt +++ /dev/null @@ -1,128 +0,0 @@ - -═══════════════════════════════════════════════════════════ - 代理 ID : 31618(注册于 2026-05-03 10:36:16) - 统计起点 : 2026-05-03 15:37:18(首次邀请时间) - 统计截止 : 2026-05-07 02:02:52(最后邀请时间) - 统计天数 : 3.43 天 - 历史邀请总人数 : 49 人 - 下线总订单数 : 11 单(所有下线,不限时间) - 日均订单 : 3.2029 单/天 - 每用户平均订单 : 1.0000 单 - 历史佣金总额 : $46.30 - 日均佣金 : $13.4812 - 每用户平均佣金 : $0.9449 - 佣金规则 : 50% 仅首单=false -─────────────────────────────────────────────────────────── - 丢失时长 : 22.42 小时(2026-05-07 02:02:52 → 现在) - 预估丢失佣金 : $12.5914($13.4812 × 22.42/24) - 目标补偿金额 : $15.1097(× 120%) - 需补充人数 : 16 人($15.1097 ÷ $0.9449) -═══════════════════════════════════════════════════════════ - -自然流量用户池(2025-05-04 00:00 ~ 2026-05-08 00:27,referer_id=0,有已支付订单):共 2420 人 - -随机抽取 16 个用户(含待追溯佣金订单): -═══════════════════════════════════════════════════════════════════════════ -[1] 用户 19282 注册: 2026-04-22 21:48:47 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 20260422214951826095981429 $ 0.99 $ 0.00 $ 0.49 首购 - 202604302302367096852027224 $ 5.99 $ 0.00 $ 2.99 续费 - 本用户追溯佣金合计: $3.48 - -[2] 用户 22675 注册: 2026-04-26 13:05:32 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202604270056552342453283470 $ 0.99 $ 0.00 $ 0.49 首购 - 本用户追溯佣金合计: $0.49 - -[3] 用户 676 注册: 2026-03-29 16:49:34 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202603302144244505020334929 $ 0.99 $ 0.00 $ 0.49 续费 - 本用户追溯佣金合计: $0.49 - -[4] 用户 23501 注册: 2026-04-27 22:17:59 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202604272218253888000515243 $ 0.99 $ 0.00 $ 0.49 首购 - 本用户追溯佣金合计: $0.49 - -[5] 用户 18921 注册: 2026-04-22 14:48:31 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202604240030589405703117541 $ 2.79 $ 0.00 $ 1.39 首购 - 202605020135558835271794030 $ 12.99 $ 0.00 $ 6.49 续费 - 本用户追溯佣金合计: $7.88 - -[6] 用户 21300 注册: 2026-04-24 21:58:49 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202604242201505521613971320 $ 0.99 $ 0.00 $ 0.49 首购 - 本用户追溯佣金合计: $0.49 - -[7] 用户 18750 注册: 2026-04-22 10:05:38 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 20260422100625875802633569 $ 0.99 $ 0.00 $ 0.49 首购 - 本用户追溯佣金合计: $0.49 - -[8] 用户 28305 注册: 2026-04-29 20:40:42 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202604292044144381261998771 $ 5.99 $ 0.00 $ 2.99 续费 - 本用户追溯佣金合计: $2.99 - -[9] 用户 18687 注册: 2026-04-22 07:22:38 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202604220723053253069546184 $ 0.99 $ 0.00 $ 0.49 首购 - 202604301218427084543381719 $ 12.99 $ 0.00 $ 6.49 续费 - 本用户追溯佣金合计: $6.98 - -[10] 用户 27370 注册: 2026-04-29 13:07:04 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202604291307299646401795678 $ 2.79 $ 0.00 $ 1.39 首购 - 本用户追溯佣金合计: $1.39 - -[11] 用户 25141 注册: 2026-04-28 23:27:53 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 20260428232858118781522927 $ 2.79 $ 0.00 $ 1.39 首购 - 本用户追溯佣金合计: $1.39 - -[12] 用户 21709 注册: 2026-04-25 09:07:11 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202604250909319632867038991 $ 0.99 $ 0.00 $ 0.49 续费 - 本用户追溯佣金合计: $0.49 - -[13] 用户 29584 注册: 2026-04-30 21:00:07 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202604302100218949591805326 $ 12.99 $ 0.00 $ 6.49 首购 - 本用户追溯佣金合计: $6.49 - -[14] 用户 18457 注册: 2026-04-22 00:56:01 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202604282259482779907423944 $ 5.99 $ 0.00 $ 2.99 续费 - 本用户追溯佣金合计: $2.99 - -[15] 用户 23746 注册: 2026-04-28 08:57:40 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202605072036107130526727042 $ 2.79 $ 0.00 $ 1.39 续费 - 本用户追溯佣金合计: $1.39 - -[16] 用户 23745 注册: 2026-04-28 08:56:25 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202604280857579370192598355 $ 0.99 $ 0.00 $ 0.49 首购 - 本用户追溯佣金合计: $0.49 - -═══════════════════════════════════════════════════════════════════════════ -预计追溯佣金总额: $38.41(目标补偿金额: $15.11) - -[dry-run] 预览完成,未执行任何写入。 diff --git a/retro_result.txt b/retro_result.txt deleted file mode 100644 index 4932fdc..0000000 --- a/retro_result.txt +++ /dev/null @@ -1,101 +0,0 @@ -⚠️ 强制覆盖所有代理佣金比例为 50% - -自然流量用户池(2025-05-04 00:00 ~ 2026-05-08 17:36,referer_id=0,有已支付订单,订单 updated_at >= 2026-05-01):共 942 人 - - -═══════════════════════════════════════════════════════════ - 代理 ID : 32690(注册于 2026-05-03 22:28:33) - 统计起点 : 2026-05-03 23:05:16(首次邀请时间) - 统计截止 : 2026-05-08 11:34:52(最后邀请时间) - 统计天数 : 4.52 天 - 历史邀请总人数 : 56 人 - 下线总订单数 : 23 单(所有下线,不限时间) - 日均订单 : 5.0879 单/天 - 每用户平均订单 : 1.0000 单 - 历史佣金总额 : $67.37 - 日均佣金 : $14.9031 - 池内用户均佣金 : $4.0394 - 佣金规则 : 50% 仅首单=false -─────────────────────────────────────────────────────────── - 丢失时长 : 89.62 小时(2026-05-05 00:00:00 → 现在) - 预估丢失佣金 : $55.6494($14.9031 × 89.62/24) - 目标补偿金额 : $22.2597(× 40%) - 需补充人数 : 6 人($22.2597 ÷ $4.0394) -═══════════════════════════════════════════════════════════ - -随机抽取 7 个用户(含待追溯佣金订单): -═══════════════════════════════════════════════════════════════════════════ -[1] 用户 20700 注册: 2026-04-24 10:23:54 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202605021207336799836275999 $ 12.99 $ 0.00 $ 6.49 续费 - 本用户追溯佣金合计: $6.49 - -[2] 用户 29646 注册: 2026-04-30 21:38:33 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202605062120238700572523875 $ 5.99 $ 0.00 $ 2.99 首购 - 本用户追溯佣金合计: $2.99 - -[3] 用户 30617 注册: 2026-05-02 00:05:31 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202605021653207435530198247 $ 2.79 $ 0.00 $ 1.39 首购 - 本用户追溯佣金合计: $1.39 - -[4] 用户 27884 注册: 2026-04-29 16:56:59 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202605021434465448150056947 $ 2.79 $ 0.00 $ 1.39 续费 - 本用户追溯佣金合计: $1.39 - -[5] 用户 30415 注册: 2026-05-01 20:16:56 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202605031955444435684054876 $ 12.99 $ 0.00 $ 6.49 续费 - 本用户追溯佣金合计: $6.49 - -[6] 用户 23970 注册: 2026-04-28 12:58:04 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202605010755515633642395999 $ 5.99 $ 0.00 $ 2.99 首购 - 本用户追溯佣金合计: $2.99 - -[7] 用户 29973 注册: 2026-05-01 02:43:14 - 订单号 金额 手续费 佣金 类型 - ------------------------------------------------------------------------ - 202605010243251111413018924 $ 2.79 $ 0.00 $ 1.39 首购 - 本用户追溯佣金合计: $1.39 - -═══════════════════════════════════════════════════════════════════════════ -预计追溯佣金总额: $23.13(目标补偿金额: $22.26) - -═══════════════════════════════════════════════════════════════════════════ -汇总:共 1 个代理,补充 7 个用户 - 预计追溯佣金总额: $23.13(目标补偿金额: $22.26) -═══════════════════════════════════════════════════════════════════════════ - - -┌─────────────────────────────────────────────┐ -│ 即将写入数据库 │ -│ 代理数量 : 1 个 │ -│ 补充用户 : 7 人 │ -│ 赠送金额 : $23.13 │ -└─────────────────────────────────────────────┘ - - -── 执行代理 32690 ────────────────────────────────────────────── -[OK] 用户 20700 → 代理 32690,发佣 1 单,金额 $6.49 -[OK] 用户 29646 → 代理 32690,发佣 1 单,金额 $2.99 -[OK] 用户 30617 → 代理 32690,发佣 1 单,金额 $1.39 -[OK] 用户 27884 → 代理 32690,发佣 1 单,金额 $1.39 -[OK] 用户 30415 → 代理 32690,发佣 1 单,金额 $6.49 -[OK] 用户 23970 → 代理 32690,发佣 1 单,金额 $2.99 -[OK] 用户 29973 → 代理 32690,发佣 1 单,金额 $1.39 - 代理 32690 小计:成功 7 人,失败 0 人,佣金 $23.13 - -══════════════════════════════════════════════ - 成功挂载 : 7 人 - 失败/跳过 : 0 人 - 追溯佣金 : 7 单,总额 $23.13 -══════════════════════════════════════════════ diff --git a/tempo/tempo-config.yaml b/tempo/tempo-config.yaml deleted file mode 100644 index 8a68571..0000000 --- a/tempo/tempo-config.yaml +++ /dev/null @@ -1,37 +0,0 @@ -server: - http_listen_port: 3200 - grpc_listen_port: 9095 - -distributor: - receivers: - otlp: - protocols: - grpc: - endpoint: 0.0.0.0:4317 - http: - endpoint: 0.0.0.0:4318 - -ingester: - max_block_duration: 5m - -compactor: - compaction: - block_retention: 168h - -storage: - trace: - backend: local - wal: - path: /var/tempo/wal - local: - path: /var/tempo/blocks - -metrics_generator: - registry: - external_labels: - source: tempo - cluster: ppanel - storage: - path: /var/tempo/generator/wal - remote_write: - - url: http://prometheus:9090/api/v1/write diff --git a/test_device_login b/test_device_login deleted file mode 100755 index d7d1a1a..0000000 Binary files a/test_device_login and /dev/null differ diff --git a/tests/config.go b/tests/config.go deleted file mode 100644 index 22dac06..0000000 --- a/tests/config.go +++ /dev/null @@ -1,136 +0,0 @@ -// Package tests provides HTTP client helpers for manually testing ppanel-server APIs. -// -// Usage: -// -// go test -v -run TestXxx ./tests/ -// -// Configure the constants below to match your local environment. -package tests - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "testing" -) - -// ─── Environment Configuration ──────────────────────────────────────────────── - -const ( - // BaseURL is the ppanel-server base URL (no trailing slash). - BaseURL = "http://localhost:8080" - - // AdminToken is the JWT token for an admin user. - // Obtain by calling CallAdminLogin first, then paste the token here. - AdminToken = "YOUR_ADMIN_TOKEN" - - // UserToken is the JWT token for a regular user. - // Obtain by calling CallUserLogin first, then paste the token here. - UserToken = "YOUR_USER_TOKEN" - - // TestEmail is the email address for user-related test calls. - TestEmail = "test@example.com" - - // TestPassword is the password for test user login. - TestPassword = "Test@123456" - - // AdminEmail is the email for admin login. - AdminEmail = "admin@example.com" - - // AdminPassword is the admin password. - AdminPassword = "Admin@123456" -) - -// ─── Request Options ────────────────────────────────────────────────────────── - -type reqOption func(*http.Request) - -// withToken adds a Bearer token to the request. -func withToken(token string) reqOption { - return func(r *http.Request) { - r.Header.Set("Authorization", "Bearer "+token) - } -} - -// withAdminToken adds the AdminToken. -func withAdminToken() reqOption { return withToken(AdminToken) } - -// withUserToken adds the UserToken. -func withUserToken() reqOption { return withToken(UserToken) } - -// ─── Core HTTP Helper ───────────────────────────────────────────────────────── - -// doRequest sends an HTTP request and prints the response. -// body may be nil (for GET/DELETE without body), a map[string]any, or any JSON-serialisable value. -// Returns the raw response body as a string. -func doRequest(t *testing.T, method, path string, body any, opts ...reqOption) string { - t.Helper() - - var reqBody io.Reader - if body != nil { - b, err := json.Marshal(body) - if err != nil { - t.Fatalf("marshal body: %v", err) - } - reqBody = bytes.NewReader(b) - } - - req, err := http.NewRequest(method, BaseURL+path, reqBody) - if err != nil { - t.Fatalf("new request: %v", err) - } - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Accept", "application/json") - - for _, o := range opts { - o(req) - } - - resp, err := http.DefaultClient.Do(req) - if err != nil { - t.Fatalf("do request: %v", err) - } - defer resp.Body.Close() - - raw, _ := io.ReadAll(resp.Body) - result := prettyJSON(raw) - t.Logf("[%s %s] %d\n%s", method, path, resp.StatusCode, result) - return string(raw) -} - -// doRequestRaw is like doRequest but for non-testing contexts (prints to stdout). -func doRequestRaw(method, path string, body any, opts ...reqOption) string { - var reqBody io.Reader - if body != nil { - b, _ := json.Marshal(body) - reqBody = bytes.NewReader(b) - } - - req, _ := http.NewRequest(method, BaseURL+path, reqBody) - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Accept", "application/json") - for _, o := range opts { - o(req) - } - - resp, err := http.DefaultClient.Do(req) - if err != nil { - fmt.Printf("request error: %v\n", err) - return "" - } - defer resp.Body.Close() - raw, _ := io.ReadAll(resp.Body) - result := prettyJSON(raw) - fmt.Printf("[%s %s] %d\n%s\n", method, path, resp.StatusCode, result) - return string(raw) -} - -func prettyJSON(raw []byte) string { - var buf bytes.Buffer - if err := json.Indent(&buf, raw, "", " "); err != nil { - return string(raw) - } - return buf.String() -}