diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..a25e513 Binary files /dev/null and b/.DS_Store differ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..081b737 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 数据源本地存储已忽略文件 +/dataSources/ +/dataSources.local.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ diff --git a/.idea/enterprise-wechat-payment-push.iml b/.idea/enterprise-wechat-payment-push.iml new file mode 100644 index 0000000..f936df0 --- /dev/null +++ b/.idea/enterprise-wechat-payment-push.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..a2e120d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..4adf23a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/1.py b/1.py new file mode 100644 index 0000000..65eaccb --- /dev/null +++ b/1.py @@ -0,0 +1,9 @@ +from utils import * +import os, _thread, urllib +from openpyxl import * +import pandas as pd + + +# add_payment({'pay_amount': 90853, 'id': 'JGKH2023110900001', 'jg': '金建', 'name': '周六日', 'form_code': ['YZWL2025010800044', 'YZWL2025010800030', 'YZWL2024122604583', 'YZWL2024122604581', 'YZWL2024122604544', 'YZWL2024122604492', 'YZWL2024122604455', 'YZWL2024122604425', 'YZWL2024122604336', 'YZWL2024122604176', 'YZWL2024122604161', 'YZWL2024122603954', 'YZWL2024122603746', 'YZWL2024122603480', 'YZWL2024122603050', 'YZWL2024122602824', 'YZWL2024122602356', 'YZWL2024122602238', 'YZWL2024122602231', 'YZWL2024122602222'], 'is_zx': 1}, 1) +add_payment({'pay_amount': 600, 'id': '91110117MA04F9JG9D', 'jg': '银建', 'name': '京晖', 'form_code': ['YZWL25050800007', 'YZWL25050800008'], 'is_zx': 1}, 1) + diff --git a/config.py b/config.py new file mode 100644 index 0000000..87a3a47 --- /dev/null +++ b/config.py @@ -0,0 +1,40 @@ +''' +coding:utf-8 +@Time:2025/5/7 15:02 PM +@Author:jefferyzhao +''' + +# 调用域名 +base_path = 'https://www.jiyuankeshang.com' +# 企微应用id 应用ID +corpid = 'wwc276f7a0347c310b' +SECRET = '8jSj7EF1J6P1zzDeqzMxc-1c4EV3tTGyB5yljB2RWtk' +# APIv3密钥 +v3_SECRET = '20230626yinjian13370189887jiyuan' +# 服务器IP +ip = '101.43.208.145' +# 未收付应用id +pay_app = "675b8d1a24d61bca7bf1cb4c" +# 已收表单Id +received_id = '67f37759de8bbe9eed71b793' +# received_id = '62f8646425997a0007fa2554' +# 未收表单Id +uncollected_id = '67e21d2ebaccd58c66fa7c77' +# uncollected_id = '65aa3055d0365889c79e775d' +# 充值明细 +pay_details_id = '67ee3fa22e399b68fef8d839' +# pay_details_id = '65aa30abd0365889c79e7948' +# 个人账户 +accout_id = '67ee40362e399b68fef8e000' +# 收付款事由基础设置表单 +reasons_id = '680ae70dde8bbe9eed7fa8f0' +# apikey +apikey = '82bl1lhsgjzhd9ahBYvaMNVAncYYRkbE' +# 财务管理应用ID +cw_app = '675b8d1a24d61bca7bf1cb4c' +# 辅助表单(查询驾驶员身份证号) +# fu_app = '628eeaace7f28c00089a60cc' +fu_app = "628eeaace7f28c00089a60cc" +fu_id = '667ccd162e0bccca52d91e66' +#驾驶员支付信息 +transactions_id = '66a850d3b3c800c6f541be2f' \ No newline at end of file diff --git a/lyapp.py b/lyapp.py new file mode 100644 index 0000000..a0cb07f --- /dev/null +++ b/lyapp.py @@ -0,0 +1,162 @@ +from flask import Flask, request, redirect, abort, session +from utils import * +import os, _thread, urllib +import logging +from logging.handlers import TimedRotatingFileHandler + +app = Flask(__name__) +app.config['SECRET_KEY'] = os.urandom(24) + +def setup_logging(): + """配置日志系统,按天分割日志文件""" + # 创建日志目录 + log_dir = "logs" + os.makedirs(log_dir, exist_ok=True) + + # 设置日志格式 + log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' + formatter = logging.Formatter(log_format) + + # 创建按天轮转的文件处理器 + file_handler = TimedRotatingFileHandler( + filename=os.path.join(log_dir, 'lyapp.log'), + when='midnight', # 每天午夜轮转 + interval=1, # 每天一个文件 + backupCount=30, # 保留30天的日志 + encoding='utf-8' + ) + file_handler.setFormatter(formatter) + file_handler.setLevel(logging.INFO) + + # 创建控制台处理器 + console_handler = logging.StreamHandler() + console_handler.setFormatter(formatter) + console_handler.setLevel(logging.DEBUG) + + # 获取根logger并配置 + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + logger.addHandler(file_handler) + logger.addHandler(console_handler) + + +# 初始化日志配置 +setup_logging() + +# 获取当前模块的 logger +logger = logging.getLogger(__name__) +logger.info(f"LYPayApp started") # 会输出到文件和控制台 + +@app.route('/queryUserId', methods=['GET']) +def queryUserId(): + # 获取支付明细 + try: + code = request.args.get('code') + data = query_wx_userid(code) + if len(data) <= 11: + res = query_wx_fj_info(data) + data = res + print(f'http://web.jiyuankeshang.com/?user={data}') + return redirect(f'http://web.jiyuankeshang.com/?user={data}') + except Exception as e: + return {} + + +@app.route('/queryUser', methods=['GET']) +def queryUserApi(): + # 获取支付明细 + try: + id = request.args.get('user') + data = queryUser(id) + return data + except Exception as e: + return {} + + +@app.route('/getPaymentDetails', methods=['GET']) +def getPaymentDetails(): + try: + id = request.args.get('user','') + + id = id.replace(" ", "") + + if not id: + return {} + data = query_pay_details(id) + return data + except Exception as e: + logger.error(f"getPaymentDetails",e) + return {} + + + +@app.route('/test', methods=['POST']) +def test(): + # 新增未收付明细 {"pay_amount": 20000, "id": "18515367096"} + try: + data = request.data.decode("utf-8") + print(data) + return {} + except Exception as e: + logger.error(f"addUnPayment",e) + return {} + + + + +@app.route('/addUnPayment', methods=['POST']) +def addUnPayment(): + # 新增未收付明细 {"pay_amount": 20000, "id": "18515367096"} + try: + data = request.data.decode("utf-8") + data = data.replace("null", "None") + data = eval(data) + data = data['data'] + if data['mode_type'] == "联合运营" and data['lydunjiao'] != "趸交": + logger.info(f"开始========", data) + data1 = {"pay_amount": 0, "id": "未收付","jg": data['jg'], "name": data['name'], + "form_code": data['form_code']} + print(data1) + _thread.start_new_thread(add_payment, ({"pay_amount": 0, "id": "未收付", + "jg": data['sijisuozaigongsi'], "name": data['company_jc'], + "form_code": data['yewubiaodanbianma']}, 1)) + + return {data} + else: + return {} + except Exception as e: + logger.error(f"addUnPayment",e) + return {} + + +@app.route('/addPayment', methods=['POST']) +def addPayment(): + # 新增充值明细 {"pay_amount": 20000, "id": "18515367096"} + try: + data = request.data.decode("utf-8") + print(data) + data = data.replace("null", "None") + data = eval(data) + data = data['data'] + if data['mode_type'] != "联合运营" or data['type'] != "转入" or data['zhtype'] != "预收款": + return {} + if not data['charge_amount']: + data['charge_amount'] = 0 + if data['zxform_code'] == "": + _thread.start_new_thread(add_payment, ({"pay_amount": data['charge_amount'], "id": data['id_card'], + "jg": data['jg'], "name": data['name'], + "form_code": data['form_code'], "is_zx": 0}, 1)) + else: + form_code = [] + form_code = data['zxform_code'].split(',') + _thread.start_new_thread(add_payment, ({"pay_amount": data['charge_amount'], "id": data['id_card'], + "jg": data['jg'], "name": data['name'], + "form_code": form_code, "is_zx": 1}, 1)) + return {} + except Exception as e: + logger.error(f"addPayment",e, data) + return {} + + +if __name__ == '__main__': + app.run(host="0.0.0.0", port=3009, processes=True) diff --git a/nohup-error.log b/nohup-error.log new file mode 100644 index 0000000..e69de29 diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..803eeaf --- /dev/null +++ b/utils.py @@ -0,0 +1,729 @@ +import requests, time, json, uuid, datetime +from config import * +from dateutil.relativedelta import relativedelta +import threading +import urllib3 +from Crypto.Cipher import AES +from base64 import b64encode, b64decode +import logging + +logger = logging.getLogger(__name__) + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +lock = threading.Lock() + + +def format_uct(origin_date_str): + origin_date_str = origin_date_str.split('.')[0] + utc_date = datetime.datetime.strptime(origin_date_str, "%Y-%m-%dT%H:%M:%S") + local_date = utc_date + datetime.timedelta(hours=8) + local_date_str = datetime.datetime.strftime(local_date, '%Y-%m-%d %H:%M:%S') + return local_date_str + +def query_reasons_for_payment(): + url = f'{base_path}/api/v5/app/entry/data/list' + filter_data = { + "app_id": pay_app, + "entry_id": reasons_id, + "limit": 100, + "filter": { + "rel": "and", + "cond": [ + { + "field": "business", + "method": "eq", + "value": ["联合运营"] + } + ] + } + } + reasons_data = turn_page(url, filter_data) + return reasons_data + +def get_reasons(): + """获取收付款事由明细""" + reasons_data = query_reasons_for_payment() + reasons_data = sorted(reasons_data, key=lambda x: x['sort']) + # 使用字典推导式创建reason为键,dktype为值的字典 + # 初始化字典,包含两个空列表作为值 + dktype_to_reasons_dict = { + '非专项扣除': [], + '专项扣除': [] + } + # 遍历数据,根据dktype的值将reason添加到对应的列表中 + for item in reasons_data: + dktype = item['dktype'] + reason = item['reason'] + if dktype in dktype_to_reasons_dict: + dktype_to_reasons_dict[dktype].append(reason) + + return dktype_to_reasons_dict + +def get_sort(): + """获取收付款事由明细""" + res = query_reasons_for_payment() + # 初始化两个空字典来存储结果 + reason_to_sort = {} + + # 遍历data列表 + for item in res: + reason = item['reason'] + sort = item['sort'] + + # 更新reason_to_sort字典 + if reason not in reason_to_sort: + reason_to_sort[reason] = sort + # 注意:这里我们没有处理相同reason但不同sort的情况,因为只保留了第一个sort值 + + # 打印结果以验证 + return reason_to_sort + +def queryUser(company_jc,jg): + # 个人账户余额查询 + url = f'{base_path}/api/v5/app/entry/data/list' + filter_data = { + "app_id": cw_app, + "entry_id": pay_details_id, + "limit": 100, + "filter": { + "rel": "and", + "cond": [ + { + "field": "name", + "method": "eq", + "value": [company_jc] + }, + { + "field": "mode_type", + "method": "eq", + "value": ["联合运营"] + }, + { + "field": "jg", + "method": "eq", + "value": [jg] + }, + { + "field": "type", + "method": "eq", + "value": "转入" + }, + { + "field": "zhtype", + "method": "eq", + "value": "预收款" + } + ] + } + } + # 查询充值明细 + pay_detail = turn_page(url, filter_data) + # for i in pay_detail: + # i['time'] = format_uct(i['time']) + + # 查询个人余额 + info = { + "app_id": pay_app, + "entry_id": accout_id, + "filter": {"rel": "and", + "cond": [ + { + "field": "name", + "method": "eq", + "value": [company_jc] + }, + { + "field": "mode_type", + "method": "eq", + "value": ["联合运营"] + }, + { + "field": "jg", + "method": "eq", + "value": [jg] + }, + { + "field": "account_type", + "method": "eq", + "value": "预收款" + } + ]} + } + + # 查询个人余额账户表 + res = req_tool_jdy(url, info) + balance = 0 + if res['data']: + balance = res['data'][0]['balance'] + balance = float("%.2f" % balance) + return {"balance": balance, "pay_detail": pay_detail} + + +def get_last_8_hour(): + _time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time() - 8 * 60 * 60)) + return _time + + +def turn_page(url, data): + """翻页查询""" + info = [] + while 1: + try: + res = req_tool_jdy(url, data) + info += res['data'] + if len(res['data']) < 100: + return info + data["data_id"] = res["data"][-1]["_id"] + except Exception as e: + logger.error(f"turn_page_error,e {e}, res{res}") + + +def query_pay_details(company_jc,jg): + # 查询某人未收付明细 + url = f'{base_path}/api/v5/app/entry/data/list' + filter_data = { + "app_id": pay_app, + "entry_id": uncollected_id, + "limit": 100, + "filter": { + "rel": "and", + "cond": [ + { + "field": "company_jc", + "method": "eq", + "value": [company_jc] + }, + { + "field": "mode_type", + "method": "eq", + "value": ["联合运营"] + }, + { + "field": "sijisuozaigongsi", + "method": "eq", + "value": [jg] + }, + ] + } + } + + uncollected_data = turn_page(url, filter_data) + _data = [] + reasons = get_reasons() + for i in uncollected_data: + flag = False + for keys in reasons.keys(): + for j in reasons[keys]: + # if j == i['fukuanshiyou'] and i['mode_type']=='联合运营' and i['lydunjiao'] != "趸交": + if j == i['fukuanshiyou'] and i['mode_type']=='联合运营': + flag = True + break + if not flag: + continue + i['money'] = float("%.2f" % i['money']) if i['money'] else 0 + i['pay'] = float("%.2f" % i['pay']) if i['pay'] != None and i['pay'] != '' else 0 + i['no_money'] = float("%.2f" % i['no_money']) if i['no_money'] != None and i['no_money'] != '' else 0 + i['sort'] = 9999 + rule_sort = get_sort() + for j in rule_sort: + if j == i['fukuanshiyou']: + i['sort'] = rule_sort[j] + _data.append(i) + uncollected_data = _data + uncollected_data = sorted(uncollected_data, key=lambda x: x['createTime'], reverse=True) + # 过滤已结清数据 + uncollected_data = [i for i in uncollected_data if i['money'] != i['pay']] + undata = {} + # # 按月份归类 uncollected_data + # for un in uncollected_data: + # if un['yuefen'] in undata.keys(): + # undata[un['yuefen']]['data'].append(un) + # else: + # undata[un['yuefen']] = {"data": []} + # undata[un['yuefen']]['data'] = [un] + # 按收付款事由归类 + for un in uncollected_data: + fukuanshiyou = un['fukuanshiyou'] + if fukuanshiyou in undata.keys(): + undata[fukuanshiyou]['data'].append(un) + else: + undata[fukuanshiyou] = {"data": []} + undata[fukuanshiyou]['data'] = [un] + # 按月查询增减项 flowState结束 + amount = 0 + for un in undata: + _th_amount = 0 + del_list = [] + for index, j in enumerate(undata[un]['data']): + j['no_money'] = j['no_money'] if j['no_money'] else j['money'] + + if '费税' in j['fukuanshiyou'] and j['yewubiaodanmingcheng'] == '费税计划': + # 定额 de = 表单中的金额-增减 + # 应付金额 money = 表单中的金额 + # 未付金额 no_money = 应付金额-增减-已付金额 + j['pay'] = j['pay'] if j['pay'] else 0 + # j['money'] = undata[un]['de'] + zj_sum + j['no_money'] = j['money'] - j['pay'] + amount += j['no_money'] if j['no_money'] else j['money'] + _th_amount += j['no_money'] if j['no_money'] else j['money'] + undata[un]['_th_amount'] = _th_amount + for d in del_list: + undata[un]['data'].pop(d) + undata['amount'] = float("%.2f" % amount) + for i in list(undata.keys()): + if i != 'amount' and not undata[i]['data']: + del undata[i] + return undata + + +# def req_tool_jdy(url, data): +# headers = {"Authorization": f"Bearer {apikey}"} +# while 1: +# try: +# res = requests.post(url, headers=headers, json=data, timeout=10, verify=False).json() +# if "code" in res.keys(): +# for count in range(0,5): +# logger.info(f"req_tool_jdy", res, url, data) +# time.sleep(2) +# continue +# return res +# except Exception as e: +# print(e) +def req_tool_jdy(url, data): + headers = {"Authorization": f"Bearer {apikey}"} + max_retries = 5 # 最大重试次数 + retries = 0 + + while retries < max_retries: + try: + res = requests.post(url, headers=headers, json=data, timeout=10, verify=False).json() + if "code" in res.keys(): + logger.error(f"req_tool_jdy response indicates an error:res{res}, url{url}, data{data}") + retries += 1 + time.sleep(2) # 等待时间,避免迅速重试 + else: + return res + except Exception as e: + logger.error(f"Request error:", e) + + logger.info(f"Max retries reached for url: {url} with data: {data}") + return None # 在多次尝试后返回 None + + + +def req_tool_vx(url, data=None, flag=None): + while 1: + try: + if not flag: + res = requests.post(url, json=data, timeout=10, verify=False).json() + else: + res = requests.get(url, timeout=10, verify=False).json() + return res + except Exception as e: + logger.error(f"error{e}") + + +def update_unpay(data,now_time,iszx): + """更新未收付,添加已收付明细""" + url = f'{base_path}/api/v5/app/entry/data/update' + add_url = f'{base_path}/api/v5/app/entry/data/create' + del_url = f'{base_path}/api/v1/app/{pay_app}/entry/{uncollected_id}/data_delete' + for i in data: + if 'amount' == i: + continue + for j in data[i]['data']: + info = { + "app_id": pay_app, + "entry_id": uncollected_id, + "data_id": j['_id'], + "is_start_trigger": True, + "is_start_workflow": True, + "data": { + "pay": {"value": j['pay']}, + "no_money": {"value": j['no_money']}, + } + } + req_tool_jdy(url, info) + # 新增已收付明细 + if 'flag' in j.keys() and float(j['flag_m']): + if not j['flag_m'] or not float(j['flag_m']): + continue + fs_p = j['fs_p']['dept_no'] if j['fs_p'] else "" + if iszx == 1: + add_info = { + "app_id": pay_app, + "entry_id": received_id, + "is_start_trigger": True, + "is_start_workflow": True, + "data": { + "code": {"value": j['code']}, "type": {"value": "收款"}, + "fukuanshiyou": {"value": j['fukuanshiyou']}, "month1": {"value": j['month1']}, + "month": {"value": j['month']},"yewubiaodanmingcheng": {"value": j['yewubiaodanmingcheng']}, + "yewubiaodanbianma": {"value": j['yewubiaodanbianma']}, + "sijixingming": {"value": j['sijixingming']}, "shfid": {"value": j['shfid']}, + "id_card": {"value": j['id_card']},"pay_time": {"value": now_time},"start_time": {"value": j['start_time']},"end_time": {"value": j['end_time']}, + "company_jc": {"value": j['company_jc']}, "xd": {"value": j['xd']},"cz_time": {"value": now_time}, + "sijisuozaigongsi": {"value": j['sijisuozaigongsi']}, "fs": {"value": j['fs']}, + "license_plate": {"value": j['license_plate']}, "money": {"value": j['money']}, + "pay": {"value": j['flag_m']}, "hz_month": {"value": j['hz_month']}, + "fs_p": {"value": fs_p}, "shgid": {"value": j['shgid']}, "mode_type": {"value": j['mode_type']}, + "sy": {"value": "联营账户抵扣-专项"}, "ys": {"value": j['ys']}, "lydunjiao": {"value": j['lydunjiao']},"bill_type": {"value": j['bill_type']}, + "car_dept": {"value": j['car_dept']},"contract_num": {"value": j['contract_num']} + } + } + else: + add_info = { + "app_id": pay_app, + "entry_id": received_id, + "is_start_trigger": True, + "is_start_workflow": True, + "data": { + "code": {"value": j['code']}, "type": {"value": "收款"}, + "fukuanshiyou": {"value": j['fukuanshiyou']}, "month1": {"value": j['month1']}, + "month": {"value": j['month']},"yewubiaodanmingcheng": {"value": j['yewubiaodanmingcheng']}, + "yewubiaodanbianma": {"value": j['yewubiaodanbianma']}, + "sijixingming": {"value": j['sijixingming']},"shfid": {"value": j['shfid']}, + "id_card": {"value": j['id_card']},"pay_time": {"value": now_time},"start_time": {"value": j['start_time']},"end_time": {"value": j['end_time']}, + "company_jc": {"value": j['company_jc']}, "xd": {"value": j['xd']},"cz_time": {"value": now_time}, + "sijisuozaigongsi": {"value": j['sijisuozaigongsi']}, "fs": {"value": j['fs']}, + "license_plate": {"value": j['license_plate']}, "money": {"value": j['money']}, + "pay": {"value": j['flag_m']}, "hz_month": {"value": j['hz_month']}, + "fs_p": {"value": fs_p}, "shgid": {"value": j['shgid']}, "mode_type": {"value": j['mode_type']}, + "sy": {"value": "联营账户抵扣-非专项"}, "ys": {"value": j['ys']},"lydunjiao": {"value": j['lydunjiao']},"bill_type": {"value": j['bill_type']}, + "car_dept": {"value": j['car_dept']},"contract_num": {"value": j['contract_num']} + } + } + req_tool_jdy(add_url, add_info) + logger.info(f"删除========={j['pay']}, {j['money']}") + print(f"删除========={j['pay']}, {j['money']}") + if j['sijixingming'] == '姓名': + print(j) + if j['pay'] == j['money']: + # 未收付已清缴,删除未收付明细 + j['sy'] = "联营账户抵扣" + del_info = { + "data_id": j["_id"], + "is_start_trigger": True + } + req_tool_jdy(del_url, del_info) + + +def update_info(cz, _balcace, balance, user_info): + # 余额 = 累计充值金额-累计抵扣金额 + # 本次抵扣=本次充值+本次余额-剩余金额 + di = cz + balance - _balcace + """更新个人账户余额""" + # if pay_amount: + # # 支付完有剩余余额可直接更新 + # amount = pay_amount + # else: + # # 查询未收付历史数据 + # details = query_pay_details(user_info['user']['username']) + # amount = details['amount'] + # amount *= -1 + url = f'{base_path}/api/v5/app/entry/data/list' + info = { + "app_id": pay_app, + "entry_id": accout_id, + "filter": {"rel": "and", + "cond": [ + { + "field": "name", + "method": "eq", + "value": [user_info['name']] + }, + { + "field": "mode_type", + "method": "eq", + "value": ["联合运营"] + }, + { + "field": "jg", + "method": "eq", + "value": [user_info['jg']] + }, + { + "field": "account_type", + "method": "eq", + "value": "预收款" + } + ]} + } + # 查询个人余额账户表 没有新增,有更新 + res = req_tool_jdy(url, info) + logger.info(f"查询信息{info}") + if res['data']: + # 更新 + logger.info(f"有账户") + url = f'{base_path}/api/v5/app/entry/data/update' + refund_amount = res['data'][-1]['refund_amount'] + pay = res['data'][-1]['pay'] + cz + di = di + (res['data'][-1]['deduction'] if res['data'][-1]['deduction'] else 0) + amount = pay - di - refund_amount# 累计充值-累计抵扣-退款金额 + info = { + "app_id": pay_app, + "entry_id": accout_id, + "data_id": res['data'][-1]["_id"], + "is_start_workflow": True, + "is_start_trigger": True, + "data": { + "pay": {"value": pay}, "balance": {"value": amount}, + "deduction": {"value": di} + } + } + req_tool_jdy(url, info) + else: + logger.info(f"====================未找到联营客户账户===========================,{user_info['name']},{user_info['jg']}") + +def add_payment(data, type=None): + lock.acquire() + logger.info(f"开始========{data}") + print(data, type) + # user = get_user_info(data['id']) + # 充值成功后 回写充值明细 + now_month = datetime.datetime.now().strftime("%Y-%m") + now_time = get_last_8_hour() + url = f'{base_path}/api/v5/app/entry/data/create' + if not type: + info = { + "app_id": cw_app, + "entry_id": pay_details_id, + "is_start_workflow": True, + "is_start_trigger": True, + "data": { + "id_card": {"value": data['id']}, "name": {"value": data['name']}, + "charge_amount": {"value": data['pay_amount']}, "pay_type": {"value": "企微支付"}, + "type": {"value": "转入"}, "rq": {"value": now_time},"mode_type": {"value": "联合运营"}, + "jg": {"value": data['jg']}, "laiyuan": {"value": "待定"}, + "zhtype": {"value": "待定"} + } + } + req_tool_jdy(url, info) + + details = query_pay_details(data['name'],data['jg']) + dates = set() # 使用集合来存储唯一的 yuefen + + for item in details: + if item == "amount": + continue + data_list = details[item]['data'] + for reason in data_list: + dates.add(reason['month1']) # 使用 add 方法,集合会自动处理重复元素 + # 将集合转换回列表 + dates = list(dates) + # 将日期字符串转换为日期对象,并存储在一个新列表中 + date_objects = [datetime.datetime.strptime(date_str, '%Y-%m') for date_str in dates] + + # 对日期对象进行排序 + date_objects.sort() + + # 如果需要,将排序后的日期对象转换回字符串 + sorted_dates = [date_obj.strftime('%Y-%m') for date_obj in date_objects] + pay_amount = data['pay_amount'] + # 查询余额 + balance = queryUser(data['name'],data['jg']) + pay_amount += balance['balance'] + if pay_amount <= 0: + logger.info(f"余额为0结束========{data}") + lock.release() + return + logger.info(f"执行add_payment, {data},pay_amount,{pay_amount}") + # next_month = (datetime.datetime.now().date() - relativedelta(months=-1)).strftime("%Y-%m") + # 先抵扣业务表单编码一致的 + reasons = get_reasons() + for keys in reasons.keys(): + for i in reasons[keys]: + if i not in details.keys(): + continue + _tmp = details[i]['data'] + _tmp = sorted(_tmp, key=lambda x: x['sort']) + for month in sorted_dates: + logger.info(f"nowmonth, {month}") + for j in _tmp: + if j['month1'] == month: + if pay_amount: + j['flag'] = 1 + if '保证金尾款' in j['fukuanshiyou'] or pay_amount == 0: + j['flag_m'] = 0 + continue + if data['is_zx'] == 1: + for code in data['form_code']: + if code == j['code']: + if j['money'] != j['pay']: + # 根据未支付的金额,扣除总金额 + df = j['money'] - j['pay'] + if pay_amount < df: + # 修改 i['pay'] 充值金额,推送修改 + j['pay'] += pay_amount + j['no_money'] = j['money'] - j['pay'] + j['flag_m'] = pay_amount + pay_amount = 0 + + else: + pay_amount -= df + j['pay'] = j['money'] + j['no_money'] = 0 + j['flag_m'] = df + else: + continue + else: + if data['form_code'] == j['yewubiaodanbianma']: + # if data['form_code'] == j['yewubiaodanbianma'] and j['fukuanshiyou'] in ["费税收取-首月", "费税收取-次月"]: + + if j['money'] != j['pay']: + # 根据未支付的金额,扣除总金额 + df = j['money'] - j['pay'] + if pay_amount < df: + # 修改 i['pay'] 充值金额,推送修改 + j['pay'] += pay_amount + j['no_money'] = j['money'] - j['pay'] + j['flag_m'] = pay_amount + pay_amount = 0 + + else: + pay_amount -= df + j['pay'] = j['money'] + j['no_money'] = 0 + j['flag_m'] = df + else: + continue + # 再抵扣其他 + for keys in reasons.keys(): + for i in reasons[keys]: + if i not in details.keys(): + continue + _tmp = details[i]['data'] + _tmp = sorted(_tmp, key=lambda x: x['sort']) + for month in sorted_dates: + logger.info(f"nowmonth, {month}") + for j in _tmp: + if j['month1'] == month: + if pay_amount: + j['flag'] = 1 + if '保证金尾款' in j['fukuanshiyou'] or pay_amount == 0: + # 检查 j['flag_m'] 是否已有值 + if 'flag_m' in j and j['flag_m'] is not None: + # 如果已有值,继续下一个循环 + continue + else: + # 如果没有值,给 j['flag_m'] 赋值为 0 + j['flag_m'] = 0 + if data['is_zx'] == 1: + if 'flag_m' in j and j['flag_m'] is not None: + # 如果已有值,继续下一个循环 + continue + else: + # 如果没有值,给 j['flag_m'] 赋值为 0 + if j['money'] != j['pay']: + # 根据未支付的金额,扣除总金额 + df = j['money'] - j['pay'] + if pay_amount < df: + # 修改 i['pay'] 充值金额,推送修改 + j['pay'] += pay_amount + j['no_money'] = j['money'] - j['pay'] + j['flag_m'] = pay_amount + pay_amount = 0 + + else: + pay_amount -= df + j['pay'] = j['money'] + j['no_money'] = 0 + j['flag_m'] = df + # if data['form_code'] == j['yewubiaodanbianma'] and j['fukuanshiyou'] in ["费税收取-首月","费税收取-次月"]: + if data['form_code'] == j['yewubiaodanbianma']: + # 承包金实际需要缴纳的 + if 'flag_m' in j and j['flag_m'] is not None: + # 如果已有值,继续下一个循环 + continue + else: + # 如果没有值,给 j['flag_m'] 赋值为 0 + if j['money'] != j['pay']: + # 根据未支付的金额,扣除总金额 + df = j['money'] - j['pay'] + if pay_amount < df: + # 修改 i['pay'] 充值金额,推送修改 + j['pay'] += pay_amount + j['no_money'] = j['money'] - j['pay'] + j['flag_m'] = pay_amount + pay_amount = 0 + + else: + pay_amount -= df + j['pay'] = j['money'] + j['no_money'] = 0 + j['flag_m'] = df + else: + if 'flag_m' in j and j['flag_m'] is not None: + # 如果已有值,继续下一个循环 + continue + else: + if j['money'] != j['pay']: + # 根据未支付的金额,扣除总金额 + df = j['money'] - j['pay'] + if pay_amount < df: + # 修改 i['pay'] 充值金额,推送修改 + j['pay'] += pay_amount + j['no_money'] = j['money'] - j['pay'] + j['flag_m'] = pay_amount + pay_amount = 0 + + else: + pay_amount -= df + j['pay'] = j['money'] + j['no_money'] = 0 + j['flag_m'] = df + # 根据抵扣规则,更新未支付的数据,将清缴数据新增至已收付明细 + logger.info(f"更新未收付{details}") + update_unpay(details,now_time,data['is_zx']) + # 未收付更新完后,更新个人账户余额update_info + logger.info(f"更新个人账户余额update_info") + logger.info(f"data['pay_amount'], {data['pay_amount']}, pay_amount, {pay_amount}, balance['balance'],{balance['balance']}, data, {data}") + update_info(data['pay_amount'], pay_amount, balance['balance'], data) + lock.release() + logger.info(f"结束========") + + +def decode_notify_data(res_json): + try: + ciphertext = res_json['resource']['ciphertext'] + nonce = res_json['resource']['nonce'] + associated_data = res_json['resource']['associated_data'] + cipher = AES.new(v3_SECRET.encode(), AES.MODE_GCM, nonce=nonce.encode()) + cipher.update(associated_data.encode()) + en_data = b64decode(ciphertext.encode('utf-8')) + auth_tag = en_data[-16:] + _en_data = en_data[:-16] + plaintext = cipher.decrypt_and_verify(_en_data, auth_tag) + decodejson = json.loads(plaintext.decode()) + except Exception as e: + logger.error(f"解密回调失败:{e}") + return None + return decodejson + + +def get_wx_token(): + url = f'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpid}&corpsecret={SECRET}' + res = req_tool_vx(url, flag=1) + return res['access_token'] + + +def query_wx_fj_info(id): + """查询企微中的附加信息""" + token = get_wx_token() + url = f'https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token={token}&userid={id}' + res = req_tool_vx(url, flag=1) + val = "" + logger.info(f"query_wx_fj_info,res,{res}, id, {id}") + for i in res['extattr']['attrs']: + if i['name'] == '附加信息': + val = i['value'] + return val + + +def query_wx_userid(code): + """查询企微中的userid""" + token = get_wx_token() + url = f'https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token={token}&code={code}' + res = req_tool_vx(url, flag=1) + return res['userid']