Explorar o código

添加验证报告生成上传接口

Sherlock hai 10 meses
pai
achega
24b9424491
Modificáronse 6 ficheiros con 115 adicións e 22 borrados
  1. 62 5
      api.py
  2. 23 11
      api_test.py
  3. 2 1
      config/service_config.yaml
  4. 7 0
      models/rank/data/config.py
  5. 8 3
      utils/report_utils.py
  6. 13 2
      utils/reports_process.py

+ 62 - 5
api.py

@@ -41,6 +41,12 @@ class ReportRequest(BaseModel):
     city_uuid: str              # 城市id
     product_code: str           # 卷烟编码
     
+class EvalReportRequest(BaseModel):
+    city_uuid: str              # 城市id
+    product_code: str           # 卷烟编码
+    start_time: str              # 开始投放时间
+    end_time: str               # 结束投放时间
+    
 @app.post("/brandcultivation/api/v1/recommend")
 async def recommend(request: RecommendRequest, backgroundTasks: BackgroundTasks):
     gbdtlr_model_path = os.path.join("./models/rank/weights", request.city_uuid, "gbdtlr_model.pkl")
@@ -102,11 +108,11 @@ def upload_file(reports_dir):
     }
     # 设置Cookie
     cookies = {
-        "ecp_token": "ZXlKamIyUmxJam9pTURZMVltUXpZbUV5T0dWaFl6ZzRPREJqTkRjNU5ERXpaV0k0T1dRd1pERWlMQ0p6WTI5d1pTSTZJbkJ5YjNSbFkzUmxaQ0lzSW1Oc2FXVnVkQ0k2SW1Oc2FXVnVkRjlzYjI1bmFta2lmUT09",
-        "acw_tc": "0a03176c17452016143048775e73c8e9556c4c3ee2dbc80f405a9314a5d0e5",
-        "cna": "09T8H5zH8SoCASeqHG9RyLbu",
+        "expires_in": "10800000",
+        "ecp_token": "ZXlKamIyUmxJam9pT1dZNFltRTNOVGhrTW1WbVpUYzRaR05oWkRZME5ERTRPREU1TkRObU9EY2lMQ0p6WTI5d1pTSTZJbkJ5YjNSbFkzUmxaQ0lzSW1Oc2FXVnVkQ0k2SW1Oc2FXVnVkRjlzYjI1bmFta2lmUT09",
+        "acw_tc": "0a067c4317466919842786603e2653311180a2a4fa0fd05acb99cf0458b890",
         "isg": "BDAwNyXyI9cQD__-0PkIodjTAfiCeRTD-vUtYyqmIw3d5bGP0Y0nUayWOe2F3syb",
-        "dd-ztna-token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIwNTAwMzQzMDM4MjYxNDMwOTQiLCJjb3JwSWQiOiJkaW5nYzc2YTJhMzdiMjRhODYwYTRhYzVkNjk4MDg2NGQzMzUiLCJkZXB0SWRzIjoiW1s4Mzk0NzIxNjAsODM2MjQ1MTUzLDFdXSIsInJvbGVJZHMiOiJbMjEwNDk3MDY1OF0iLCJ1bmlvbklkIjoiVXFyYTB4U0VQcWNxdFNhQTFqSzRzZ2lFaUUiLCJleHAiOjE3NDU4MDY0MjIsImlhdCI6MTc0NTIwMTYyMn0.S0K3UWF0fBP5fF6TQaUkxe8I7piSQjrXqG3DdviqTzdO9Y0J7wsydcRvfp-OuHUkXbY92diIBGRHBr5Bb0eYgmCZ946Q8CHk12WXWvJmMDPrQ4i2C1J7W7uzUuPYJiWQLGQd40iCxNKfZIGq2ML-6r1i_k0iA7L_f6En1e9b5gLIs0GaluUwhCTTpAHBsmb-FquQER2Um9igARbMT6aaNrJzQbcPPWntQ3Pz_65PgjtTUMiFtBZW-YeAm2iB9JtYo_SJUsoX0d_oYo-6D4IfgZtkYKZZxbLj5rWnhoaJHm5acELAO8otQNZYQra0PfRIaKTT1vNkr1L5rShIxZk3yQ"
+        "dd-ztna-token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIwNTAwMzQzMDM4MjYxNDMwOTQiLCJjb3JwSWQiOiJkaW5nYzc2YTJhMzdiMjRhODYwYTRhYzVkNjk4MDg2NGQzMzUiLCJkZXB0SWRzIjoiW1s4Mzk0NzIxNjAsODM2MjQ1MTUzLDFdXSIsInJvbGVJZHMiOiJbMjEwNDk3MDY1OF0iLCJ1bmlvbklkIjoiVXFyYTB4U0VQcWNxdFNhQTFqSzRzZ2lFaUUiLCJleHAiOjE3NDcxODQ3MjksImlhdCI6MTc0NjU3OTkyOX0.dfv612-LwnIdoKL2G73gg7LYy8SBmvr3Zaan97Q5wGUbEFdWw0JUqOQQ1jdeom_Nd9FNCHlkZM32DvwyUrNnvbg1QQy2JeYEpAgysG4h0MT_OghE6-xGVQBIkg72GPTo_cvdMYG9SMfaCo5H-73zFfwMFASFoXCDoIPha6NioIskOJMmvQVsDkHtRXYh_gv0XaJxSWirDWhKC9vxPGaIwDff8doHwPdi9uO-tO9LFy9RXdyIsBXWem31rBSD3D6FmqZLZjOOZhCKMym1VenfIKC10Oa1zm8-Y8bGyMHG0LO_68AJstKYT4alJoBVDHXpMp3zvSXXQB6da_fIthQD4A"
     }
     files_id = {}
     for file in files:
@@ -169,7 +175,58 @@ async def get_file_id(request: ReportRequest):
         )
     
     return {"code": 200, "msg": "success", "data": {"reportInfo": request_data}}
-        
+
+@app.post("/brandcultivation/api/v1/eval_report")
+async def get_eval_report(request: EvalReportRequest):
+    """获取验证报告"""
+    reports_dir = os.path.join('./data/reports', request.city_uuid, request.product_code)
+    # 首先生成验证报告
+    report_util = ReportUtils(request.city_uuid, request.product_code)
+    report_util.generate_eval_data(request.start_time, request.end_time)
+    
+    # 其次上传验证报告到阿里云
+    base_url = cfgs["aliyun"]["upload_url"]
+    
+    headers = {
+        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
+        "Accept": "*/*",
+    }
+    
+    cookies = {
+        "expires_in": "10800000",
+        "ecp_token": "ZXlKamIyUmxJam9pT1dZNFltRTNOVGhrTW1WbVpUYzRaR05oWkRZME5ERTRPREU1TkRObU9EY2lMQ0p6WTI5d1pTSTZJbkJ5YjNSbFkzUmxaQ0lzSW1Oc2FXVnVkQ0k2SW1Oc2FXVnVkRjlzYjI1bmFta2lmUT09",
+        "acw_tc": "0a067c4317466919842786603e2653311180a2a4fa0fd05acb99cf0458b890",
+        "isg": "BDAwNyXyI9cQD__-0PkIodjTAfiCeRTD-vUtYyqmIw3d5bGP0Y0nUayWOe2F3syb",
+        "dd-ztna-token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIwNTAwMzQzMDM4MjYxNDMwOTQiLCJjb3JwSWQiOiJkaW5nYzc2YTJhMzdiMjRhODYwYTRhYzVkNjk4MDg2NGQzMzUiLCJkZXB0SWRzIjoiW1s4Mzk0NzIxNjAsODM2MjQ1MTUzLDFdXSIsInJvbGVJZHMiOiJbMjEwNDk3MDY1OF0iLCJ1bmlvbklkIjoiVXFyYTB4U0VQcWNxdFNhQTFqSzRzZ2lFaUUiLCJleHAiOjE3NDcxODQ3MjksImlhdCI6MTc0NjU3OTkyOX0.dfv612-LwnIdoKL2G73gg7LYy8SBmvr3Zaan97Q5wGUbEFdWw0JUqOQQ1jdeom_Nd9FNCHlkZM32DvwyUrNnvbg1QQy2JeYEpAgysG4h0MT_OghE6-xGVQBIkg72GPTo_cvdMYG9SMfaCo5H-73zFfwMFASFoXCDoIPha6NioIskOJMmvQVsDkHtRXYh_gv0XaJxSWirDWhKC9vxPGaIwDff8doHwPdi9uO-tO9LFy9RXdyIsBXWem31rBSD3D6FmqZLZjOOZhCKMym1VenfIKC10Oa1zm8-Y8bGyMHG0LO_68AJstKYT4alJoBVDHXpMp3zvSXXQB6da_fIthQD4A"
+    }
+    
+    eval_file_path = os.path.join(reports_dir, "投放验证报告.xlsx")
+    try:
+        with open(eval_file_path, 'rb') as f:
+            files = {'file': (os.path.basename(eval_file_path), f)}
+                
+            response = requests.post(
+                base_url,
+                headers=headers,
+                files=files,
+                verify=True
+            )
+                
+            if response.json()["success"]:
+                file_id = response.json()["data"]["file_info"]["fileid"]
+                return {"code": 200, "msg": "success", "data": {"reportInfo": {"id": 1, "filename": "投放验证报告", "file_id": file_id}}}
+            
+            else:
+                raise HTTPException(
+                    status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
+                    detail="reports upload failed"
+                )
+                
+    except requests.exceptions.RequestException as e:
+        print("请求出错:", e)
+    except Exception as e:
+        print("发生错误:", e)
+    # 最后将file_id返回给前端
     
 if __name__ == "__main__":
     uvicorn.run(app, host="0.0.0.0", port=7960)

+ 23 - 11
api_test.py

@@ -1,17 +1,17 @@
 import requests
 import json
 
-url = "http://127.0.0.1:7960/brandcultivation/api/v1/recommend"
-payload = {
-    "city_uuid": "00000000000000000000000011445301",
-    "product_code": "440298",
-    "recall_cust_count": 100,
-    "delivery_count": 200
-}
-headers = {'Content-Type': 'application/json'}
+# url = "http://127.0.0.1:7960/brandcultivation/api/v1/recommend"
+# payload = {
+#     "city_uuid": "00000000000000000000000011445301",
+#     "product_code": "440298",
+#     "recall_cust_count": 500,
+#     "delivery_count": 1100
+# }
+# headers = {'Content-Type': 'application/json'}
 
-response = requests.post(url, data=json.dumps(payload), headers=headers)
-print(response.json())
+# response = requests.post(url, data=json.dumps(payload), headers=headers)
+# print(response.json())
 
 # url = "http://127.0.0.1:7960/brandcultivation/api/v1/report"
 # payload = {
@@ -21,4 +21,16 @@ print(response.json())
 # headers = {'Content-Type': 'application/json'}
 
 # response = requests.post(url, data=json.dumps(payload), headers=headers)
-# print(response.json())
+# print(response.json())
+
+url = "http://127.0.0.1:7960/brandcultivation/api/v1/eval_report"
+payload = {
+    "city_uuid": "00000000000000000000000011445301",
+    "product_code": "440298",
+    "start_time": "2025/2/10",
+    "end_time": "2025/2/16"
+}
+headers = {'Content-Type': 'application/json'}
+
+response = requests.post(url, data=json.dumps(payload), headers=headers)
+print(response.json())

+ 2 - 1
config/service_config.yaml

@@ -1,2 +1,3 @@
 aliyun:
-  upload_url: "http://file-center.jcpt:8080/file/fileUpload"
+  upload_url: "http://file-center.jcpt:8080/file/fileUpload"
+  # upload_url: "https://10-79-117-86-8p1kxyomtjwgt3.ztna-dingtalk.com/screen/mapi/file/fileUpload"

+ 7 - 0
models/rank/data/config.py

@@ -844,4 +844,11 @@ class DeliveryConfig:
         "turnover_rate_collpoint":              {"method": "fillna", "opt": "fill", "value": 0.0000, "type": "num"},
         "turnover_rate_terminal":               {"method": "fillna", "opt": "fill", "value": 0.0000, "type": "num"},
         "sale_qty":                             {"method": "fillna", "opt": "fill", "value": 0, "type": "num"},
+    }
+    
+    FEATURES_MAP = {
+        "retail_index_week": "市场零售价格监测指数(周)",
+        "turnover_rate_collpoint": "采集点销售量动销率(周)",
+        "turnover_rate_terminal": "零售终端销售量动销率(周)",
+        "sale_qty": "周销售量"
     }

+ 8 - 3
utils/report_utils.py

@@ -6,7 +6,7 @@ from models.rank import generate_feats_map
 
 import os
 import pandas as pd
-from utils.reports_process import feats_relation_process, calculate_delivery_by_recommend_data, eval_report_process
+from utils.reports_process import feats_relation_process, calculate_delivery_by_recommend_data, eval_report_process_pre, eval_report_process
 class ReportUtils:
     def __init__(self, city_uuid, product_id):
         self._recommend_model = Recommend(city_uuid)
@@ -123,7 +123,7 @@ class ReportUtils:
         if not os.path.exists(os.path.join(self._save_dir, "商户售卖推荐表.xlsx")):
             print("请先生成'商户售卖推荐表'")
         recommend_data = pd.read_excel(os.path.join(self._save_dir, "商户售卖推荐表.xlsx"))
-        report = eval_report_process(eval_order_data, recommend_data)
+        report = eval_report_process_pre(eval_order_data, recommend_data)
         
         report.to_excel(os.path.join(self._save_dir, "效果验证表.xlsx"), index=False)
         
@@ -136,8 +136,13 @@ class ReportUtils:
         delivery_data = self._dao.get_delivery_data_by_product(self._city_uuid, eval_product_id, start_time, end_time)
         delivery_data = delivery_data[DeliveryConfig.FEATURE_COLUMNS]
         delivery_data = sample_data_clear(delivery_data, DeliveryConfig)
+
+        recommend_data = pd.read_excel(os.path.join(self._save_dir, "商户售卖推荐表.xlsx"))
+        recommend_data = recommend_data.drop(columns=["建议投放量(条)"])
+        
+        report = eval_report_process(delivery_data, recommend_data)
         
-        delivery_data.to_excel('./data/delivery.xlsx', index=False)
+        report.to_excel(os.path.join(self._save_dir, "投放验证报告.xlsx"), index=False)
     
     def generate_all_data(self, recall_count, delivery_count):
         self.generate_feats_ralation_report(recall_count)

+ 13 - 2
utils/reports_process.py

@@ -1,4 +1,4 @@
-from models.rank.data.config import ImportanceFeaturesMap
+from models.rank.data.config import ImportanceFeaturesMap, DeliveryConfig
 import os
 import pandas as pd
 
@@ -72,7 +72,7 @@ def calculate_delivery_by_recommend_data(recommend_data, recommend_cust_infos, d
     
     return recommend_data
 
-def eval_report_process(eval_order_data, recommend_data):
+def eval_report_process_pre(eval_order_data, recommend_data):
     # 获取订单数据并处理
     eval_order_data = eval_order_data[["cust_code", "cust_name", "product_code", "product_name", "sale_qty", "sale_amt"]]
     
@@ -102,6 +102,17 @@ def eval_report_process(eval_order_data, recommend_data):
     )
     return merge_data
 
+def eval_report_process(delivery_data, recommend_data):
+    report = recommend_data.merge(delivery_data, left_on="商户编号", right_on="customer_code", how="left")
+    report = report.drop(columns=["customer_code", "goods_code"])
+    report = report.rename(columns={
+        "retail_index_week": DeliveryConfig.FEATURES_MAP["retail_index_week"],
+        "turnover_rate_collpoint": DeliveryConfig.FEATURES_MAP["turnover_rate_collpoint"],
+        "turnover_rate_terminal": DeliveryConfig.FEATURES_MAP["turnover_rate_terminal"],
+        "sale_qty": DeliveryConfig.FEATURES_MAP["sale_qty"],
+    })
+    return report
+
 def split_relation_subtable(data, filter_dict, save_dir):
     """拆分卷烟商户特征相关性子表"""
     data = filter_data(data, filter_dict).copy()