Files
gmv-analytics/__pycache__/project_bitable_common.cpython-312.pyc
T

497 lines
74 KiB
Plaintext
Raw Normal View History

Ë
2026-03-17 10:49:42 +08:00
�¨·i_ããóè—ddlZddlZddlZddlmZddlmZddlmZmZm Z ddl
m Z ddl m
Z
ddlmZddlmZddlZddlZdd lmZdd
lmZmZe
e«j5«j6Zed z Zed z Zd
ZdZ gd¢Z!gd¢Z"ed¬«Gd„d««Z#e#dddd¬«e#dddd¬«dœZ$ed¬«Gd„d««Z%ed¬«Gd „d!««Z&ed¬«Gd"„d#««Z'ed¬«Gd$„d%««Z(ed¬«Gd&„d'««Z)eGd(„d)««Z*d*e+d+dfd,„Z,d*e+d+dfd-„Z-d�d.e.ed/e/d+e+fd0„Z0efd1e
d+dfd2„Z1d+e+fd3„Z2d+e
2026-03-17 10:49:42 +08:00
fd4„Z3d+e+fd5„Z4d+e+fd6„Z5d+e+fd7„Z6d+e+fd8„Z7d+e+fd9„Z8d+e+fd:„Z9d;e.e:e+efd<e+d+e+fd=„Z;d>e+d+efd?„Z<d>e+d+e+fd@„Z=dAe+d+e+fdB„Z>dCe+d+e.e+fdD„Z?dEe
d+e:e+e+ffdF„Z@dGe+dHe:e+e+fd+e+fdI„ZAd+ej„j†fdJ„ZDdKedLedMe#d+e.e%fdN„ZEdOe.e%dHe:e+e+fdMe#d+e:e+e:eFe/e/fe:ee:e+e fffffdP„ZGdKedLedQe:e+e:eFe/e/fe:ee:e+e ffffd+e:e+e:eFe/e/fe:ee:e+e fffffdR„ZHdSe)d+e*fdT„ZId+e+fdU„ZJGdV„dW«ZKdXe+d+e:e+e+ffdY„ZLdZe+d[e+d\e+dKedLed+df d]„ZMd�d^e+d_e+dzd+e+fd`„ZN d‘dae+d[e+d\e+dKedLed^e+d_e+dzd+dfdb„ZO d�dce.e&dCe+dde/dee/dfe:e+e+fdzd+e&f dg„ZPd>e d+eQfdh„ZRdiedMe#d+e+fdj„ZSd>ed+eQdzfdk„ZTdKedLed+e.efdl„ZUdKedLed+e:eFe/e/fe.effdm„ZV d�d;e.e:e+efdne+doeWe+dzd+e.e:e+effdp„ZXdqe.e:e+efd+e:e+eWe+ffdr„ZYdqe.e:e+efd+e.e+fds„ZZdteKdue&dne+doeWe+dzdve[d+df dw„Z\dKedLed\e+dne+dxe+dve[dye[d+dfdz„Z] d’d{e*died|e[d}eWe+dzd+df
d~„Z^died\e+dne+dxe+dve[dye[d+dfd„Z_dteKdue&dne+d€e:ee:e+e ffdve[dMe#d+eFe'eWe+ffd�„Z`d{e*d‚e+dKedLed+e(f
dƒ„Zad‚e+dKedLed\e+d„e
dne+dxe+dve[dye[d+dfd…„Zbdied+e+fd†„Zcdied+e+fd‡„Zddied+e+fdˆ„ZedteKdue&died‰e+dve[d+e[f dŠ„Zfd{e*dKedLed+e(fd‹„ZgdKedLed\e+dne+dve[dye[d+dfdŒ„Zhd{e*died+dfd�„Zid{e*dKedLed+dfdŽ„Zjy)“éN©Ú defaultdict)Ú dataclass)ÚdateÚdatetimeÚ timedelta)ÚDecimal)ÚPath)ÚAny)Úurlparse)Ú
load_workbook)Ú
get_loggerÚ
setup_loggingz.envu店铺映射表.xlsxz
2026-02-25õ 店铺å��ç§°)u业务店铺å��ç§°ru 门店å��ç§°u店铺uå��ç§°©õ 大眼ç�›õ 羽心堂ÚMMMJÚEMõ 春回ç›�ú
BROKEN ZOOT)Úfrozencó6—eZdZUeed<eed<eed<eed<y)Ú MetricConfigÚnameÚ descriptionÚ sql_templateÚ field_suffixN©Ú__name__Ú
__module__Ú __qualname__ÚstrÚ__annotations__©óú?/Users/idss/YXT_Project/gmv-analytics/project_bitable_common.pyrrs…à
ƒIØÓØÓØÔr&rÚsalesu 销售é¢�u 总销售é¢�uŠ
SET TIMEZONE = 'Asia/Shanghai';
WITH base_data AS (
SELECT
f.支付时间::DATE AS 统计日期,
f.店铺主键,
s.店铺�称 AS 原始店铺�称,
p.�牌�称,
f.业务模�,
f.实付分摊金� AS 指标金�
FROM analytics_layer.fact_sales f
LEFT JOIN analytics_layer.dim_shop s
ON f.店铺主键 = s.店铺主键
LEFT JOIN analytics_layer.dim_product p
ON f.商�主键 = p.商�主键
AND f.统一规格编� = p.统一规格编�
WHERE f.支付时间 >= %(start_ts)s
AND f.支付时间 < %(end_ts_exclusive)s
),
brand_split AS (
SELECT
统计日期,
店铺主键,
原始店铺�称,
业务模�,
CASE
WHEN 店铺主键 IN (1,28,29) AND �牌�称 LIKE '羽心堂'
THEN 原始店铺�称 || '_羽心堂'
WHEN 店铺主键 IN (1,28,29) AND �牌�称 LIKE '春回�'
THEN 原始店铺�称 || '_春回�'
WHEN 店铺主键 IN (1,28,29) AND �牌�称 LIKE 'Mama Mujer'
THEN 原始店铺�称 || '_Mama Mujer'
WHEN 店铺主键 IN (1,28,29) AND �牌�称 LIKE 'ERBA MIGINA'
THEN 原始店铺�称 || '_ERBA MIGINA'
WHEN 店铺主键 IN (1,28,29) AND �牌�称 LIKE 'BROKEN ZOO'
THEN 原始店铺�称 || '_BROKEN ZOO'
WHEN 店铺主键 IN (1,28,29)
THEN 原始店铺�称 || '_其他'
WHEN 店铺主键 IN (3,9) AND �牌�称 LIKE '羽心堂'
THEN 原始店铺�称 || '_羽心堂'
WHEN 店铺主键 IN (3,9) AND �牌�称 LIKE 'Mama Mujer'
THEN 原始店铺�称 || '_Mama Mujer'
WHEN 店铺主键 IN (3,9)
THEN 原始店铺�称 || '_其他'
WHEN 店铺主键 IS NULL OR 原始店铺�称 IS NULL
THEN '分销/SEEDING'
ELSE 原始店铺�称
END AS 店铺�称,
指标金�
FROM base_data
),
shop_brand_detail AS (
SELECT
统计日期,
店铺主键,
店铺�称,
SUM(指标金�) AS 指标值
FROM brand_split
GROUP BY 1,2,3
)
SELECT
统计日期,
店铺�称,
指标值
FROM shop_brand_detail
WHERE NOT (
店铺主键 IN (1,9,28,29)
AND 店铺�称 LIKE '%%_其他'
)
UNION ALL
SELECT
统计日期,
原始店铺�称 AS 店铺�称,
SUM(指标金�)
FROM base_data
WHERE 店铺主键 IN (1,28,29,3)
GROUP BY 1,2
UNION ALL
SELECT
统计日期,
2026-03-17 10:49:42 +08:00
CASE
WHEN 业务模� IN ('三方计算','三方分销')
THEN 原始店铺�称 || '_三方'
ELSE 原始店铺�称 || '_自�'
END AS 店铺�称,
SUM(指标金�)
FROM base_data
WHERE 店铺主键 = 1
GROUP BY 1,2
ORDER BY 统计日期 DESC, 指标值 DESC;
)rrrrÚrefundu 退款é¢�u-
SET TIMEZONE = 'Asia/Shanghai';
WITH base_data AS (
SELECT
f.完结时间::DATE AS 统计日期,
f.店铺主键,
s.店铺�称 AS 原始店铺�称,
p.�牌�称,
f.退款金� AS 指标金�
FROM analytics_layer.fact_returns f
LEFT JOIN analytics_layer.dim_shop s
ON f.店铺主键 = s.店铺主键
LEFT JOIN analytics_layer.dim_product p
ON f.商�主键 = p.商�主键
AND f.统一规格编� = p.统一规格编�
WHERE f.完结时间 >= %(start_ts)s
AND f.完结时间 < %(end_ts_exclusive)s
),
brand_split AS (
SELECT
统计日期,
店铺主键,
原始店铺�称,
CASE
WHEN 店铺主键 IN (1,28,29) AND �牌�称 LIKE '羽心堂'
THEN 原始店铺�称 || '_羽心堂'
WHEN 店铺主键 IN (1,28,29) AND �牌�称 LIKE '春回�'
THEN 原始店铺�称 || '_春回�'
WHEN 店铺主键 IN (1,28,29) AND �牌�称 LIKE 'Mama Mujer'
THEN 原始店铺�称 || '_Mama Mujer'
WHEN 店铺主键 IN (1,28,29) AND �牌�称 LIKE 'ERBA MIGINA'
THEN 原始店铺�称 || '_ERBA MIGINA'
WHEN 店铺主键 IN (1,28,29) AND �牌�称 LIKE 'BROKEN ZOO'
THEN 原始店铺�称 || '_BROKEN ZOO'
WHEN 店铺主键 IN (1,28,29)
THEN 原始店铺�称 || '_其他'
WHEN 店铺主键 IN (3,9) AND �牌�称 LIKE '羽心堂'
THEN 原始店铺�称 || '_羽心堂'
WHEN 店铺主键 IN (3,9) AND �牌�称 LIKE 'Mama Mujer'
THEN 原始店铺�称 || '_Mama Mujer'
WHEN 店铺主键 IN (3,9)
THEN 原始店铺�称 || '_其他'
WHEN 店铺主键 IS NULL OR 原始店铺�称 IS NULL
THEN '分销/SEEDING'
ELSE 原始店铺�称
END AS 店铺�称,
指标金�
FROM base_data
),
shop_brand_detail AS (
SELECT
统计日期,
店铺主键,
店铺�称,
SUM(指标金�) AS 指标值
FROM brand_split
GROUP BY 1,2,3
)
SELECT
统计日期,
店铺�称,
指标值
FROM shop_brand_detail
WHERE NOT (
店铺主键 IN (1,9,28,29)
AND 店铺�称 LIKE '%%_其他'
)
2026-03-17 10:49:42 +08:00
UNION ALL
SELECT
统计日期,
原始店铺�称 AS 店铺�称,
SUM(指标金�)
FROM base_data
WHERE 店铺主键 IN (1,28,29,3)
GROUP BY 1,2
2026-03-17 10:49:42 +08:00
ORDER BY 统计日期 DESC, 指标值 DESC;
©r(r)có,—eZdZUeed<eed<eed<y)Ú MetricRowÚ stat_dateÚ
bi_store_nameÚamountN)r r!r"rr$r#r r%r&r'r,r,äs…àƒOØÓØ „Or&r,có"—eZdZUeed<eed<y)Ú TableInfoÚtable_idrNrr%r&r'r1r1ës …àƒMØ
2026-03-17 10:49:42 +08:00
„Ir&r1có.—eZdZUeeed<eeed<y)Ú
SyncResultÚsql_only_storesÚfeishu_only_storesN)r r!r"Úlistr#r$r%r&r'r4r4ñs…à˜#‘YÓØ˜S™ Ô!r&r4có—eZdZUeeed<y)ÚMetricSyncArtifactsÚcreated_fieldsN)r r!r"Úsetr#r$r%r&r'r9r9÷s …à˜‘HÔr&r9cót—eZdZUeed<eed<eed<eed<eed<eed<dZeed<dZeed <dZ eed
<y ) ÚDailySyncConfigÚbase_urlÚ mapping_fileÚstore_field_nameÚtable_map_fileÚdry_runÚskip_missing_tablesÚÚchat_idÚreport_image_pathÚ
group_webhookN)
r r!r"r#r$r
ÚboolrErFrGr%r&r'r=r=üsC…àƒMØÓØÓØÓØ
2026-03-17 10:49:42 +08:00
ƒMØÓØ€GˆSÓØÐ�sÓØ€M�3Ôr&r=cóZ—eZdZUded<eded<eeefed<eeefed<eed<y) ÚDailySyncContextÚFeishuBitableClientÚclientr1ÚtablesÚmappingÚtable_overridesÚconfigN)r r!r"r$r7Údictr#r=r%r&r'rJrJ s5…à !Ó!Ø �Ñ ÓØ
�#�s�(‰^ÓØ˜#˜s˜(‘^Ó#Ø Ôr&rJÚmessageÚreturncó6—t«j|«y©N)rÚinfo©rRs r'Úlog_steprXs€ÜƒL×Ñ�gÕr&có6—t«j|«yrU)rÚdebugrWs r'Ú log_debugr[s€ÜƒL×Ñ�wÕr&ÚvaluesÚlimitcó\—t|«|kr t|«S|d|›dt|«›d�S)Nu ... å…±u项)Úlenr#)r\r]s r'Ú preview_listr`s6€Ü
ˆ6ƒ{�eÒÜ�6‹{ÐØ�V�eˆnÐ
˜X¤c¨&£k ]°#Ð 6Ð6r&Úenv_filecó²—|j«std|›�«ytd|›�«|jd¬«j«D]{}|j «}|r|j d«sd|vrŒ+|j
2026-03-17 10:49:42 +08:00
dd«\}}tjj|j «|j ««Œ}td¬ «y)
Nu&未找到 .env 文件,跳过加载: u加载环境å�˜é‡�: úutf-8©ÚencodingÚ#Ú=éT)Úforce) ÚexistsrXÚ read_textÚ
splitlinesÚstripÚ
startswithÚsplitÚosÚenvironÚ
2026-03-17 10:49:42 +08:00
setdefaultr)raÚraw_lineÚlineÚkeyÚvalues r'Ú load_dotenvrw s²€Ø �?‰?Ô ÜÐ9¸(¸ÐDÔEØÜ Ð# H :Ð
.Ô/Ø×&Ñ&°Ð&Ó8×CÑCÖEˆØ�~‰~ÓˆÙ�t—‘ sÔ+¨s¸$©Ø Ø—Z‘Z  QÓ'‰
ˆˆUÜ
�
‰
×јcŸi™i›k¨5¯;©;«=Õ9ð Fô ˜Ör&cóJ—tjd«}|s td«‚|S)NÚFEISHU_BASE_URLu"缺少环境å�˜é‡� FEISHU_BASE_URL)rpÚgetenvÚ
ValueError)r>s r'Ú get_base_urlr|.s%€Ü�y‰yÐ*Ó+€HÙ ÜÐ=Ó>Ð>Ø €Or&cóZ—ttjdtt«««S)NÚPROJECT_MAPPING_FILE)r
rprzr#ÚDEFAULT_MAPPING_FILEr%r&r'Úget_mapping_filer€5s€Ü ”— ‘ Ð0´#Ô6JÓ2KÓLÓ MÐMr&có6—tjdt«S)NÚFEISHU_STORE_FIELD_NAME)rprzÚDEFAULT_STORE_FIELD_NAMEr%r&r'Úget_store_field_namer„9s€Ü
�9‰9Ð.Ô0HÓ IÐIr&có6—tjdt«S)NÚSYNC_START_DATE)rprzÚDEFAULT_START_DATEr%r&r'Úget_default_start_daterˆ=s€Ü
�9‰9Ð&Ô(:Ó ;Ð;r&có`—tj«td¬«z
2026-03-17 10:49:42 +08:00
j«S©Nrh©Údays)rÚtodayrÚ isoformatr%r&r'Úget_default_end_dater�As!€Ü �J‰J‹Lœ9¨!Ô,Ñ ,× 7Ñ 7Ó 9Ð9r&cóP—gd¢}|D]}tj|«}|sŒ|cSy)N)ÚFEISHU_BOT_WEBHOOKÚFEISHU_ROBOT_WEBHOOKÚFEISHU_WEBHOOKÚLARK_BOT_WEBHOOKÚLARK_ROBOT_WEBHOOKÚ
GROUP_WEBHOOKrD©rprz)Ú
candidatesrurvs r'Úget_group_webhook_urlr™Es/€ò€JóˆÜ— ‘ ˜#“ˆÚ ØŠLðð r&có.—tjdd«S)NÚFEISHU_CHAT_IDrDr—r%r&r'Úget_feishu_chat_idrœUs€Ü
�9‰9Ð% rÓ *Ð*r&có.—tjdd«S)NÚFEISHU_REPORT_IMAGE_PATHrDr—r%r&r'Úget_feishu_report_image_pathrŸYs€Ü
�9‰9Ð/°Ó 4Ð4r&ÚfieldsÚpreferred_field_namecó¶—|D�cgc] }t|jd«xsd«‘Œ"}}||vr|StD]
2026-03-17 10:49:42 +08:00
}||vsŒ|cStd|›d|›�«‚cc}w)NÚ
field_namerDu'未找到店铺å��称字段: preferred=u, å�¯ç”¨å­—段=)r#ÚgetÚSTORE_FIELD_CANDIDATESr{)r r¡ÚitemÚ field_namesÚ candidates r'Úresolve_store_field_namer©]su€ÙAGÓHÁ¸”3�t—x‘x  Ó-Ò3°Õ4À€KÐHؘ{Ñ*Ø#Ð#ß+ˆ Ø ˜ Ò #ØÒ ð,ô Ð>Ð?SÐ>TÐTcÐdoÐcpÐqÓ
rÐrùò
Is…%ArvcóJ—tj|d«j«S)Nz%Y-%m-%d)rÚstrptimer©rvs r'Ú
2026-03-17 10:49:42 +08:00
validate_dater­gs€Ü × Ñ ˜U JÓ /× 4Ñ 4Ó 6Ð6r&cóT—tjdd|xsd«j«S)Nu[\s_\-()()]+rD)ÚreÚsubÚlowerr¬s r'Únormalize_textr²ks#€Ü
�6‰6Ð% r¨5ª;°BÓ 7× =Ñ =Ó ?Ð?r&Ú
2026-03-17 10:49:42 +08:00
store_namec󘇗|xsdŠdgd¢fddgfdddgfddgfddgfg}|D]\}}tˆfd „|D««sŒ|cSd
‰vsd ‰vry
y) NrDr)ÚMamaÚmmmjrrrú ERBA MIGINArrc3ó&•K—|]}|‰v–—Œ
y­wrUr%)Ú.0Úkeywordrs €r'Ú <genexpr>z#classify_project.<locals>.<genexpr>ysøèø€Ð7©h 7ˆw˜$Œ©hùóƒru大西瓜籽妈妈)Úany)r³Úprioritized_rulesÚprojectÚkeywordsrs @r'Úclassify_projectrÁos…ø€Ø Ò ˜€Dà Ò)Ð*Ø �{�mÐ$Ø
2026-03-17 10:49:42 +08:00
��mÐ$Ð%Ø �{�mÐ$Ø ˜ �~Ð&ð Ðó/ш�Ü Ó7©hÓ7Õ 7ØŠNð/ð�dÑÐ2°dÑ:ØØ
r&r¿cóN—ddgdggd¢ddgdggd¢d œ}|j||g«S)
Nru大眼�买买买r)rz
Mama Mujerz
MAMA MUJERrr·r)rÚ BROKENZOOu 葆ç¦�颂r©r¤)r¿Úaliasess r'Úget_project_table_aliasesrÆ€s?€à!Ð#7Ð8Ø!�]Ú4Ø�]Ð#Ø!�]Ú>ñ
€Gð �;‰;�w   Ó *Ð*r&ÚpathcóŽ—td|›�«t|d¬«}|j}i}|jdd¬«D]m}|sŒt |«dk\r
|dd\}}}nt |«dk\r |dd\}}nŒ6|r|sŒ;t |«j
«|t |«j
«<Œotdt |«›d�«|S) Nu加载店铺映射表: T)Ú data_onlyé)Úmin_rowÚ values_onlyéu店铺映射加载完æˆ�: õ æ�¡)rXr
2026-03-17 10:49:42 +08:00
ÚactiveÚ iter_rowsr_r#rm)rÇÚwbÚwsrNÚrowÚ_Ú
business_nameÚbi_names r'Úload_store_mappingr׌s΀Ü Ð& t fÐ
-Ô.Ü �t tÔ ,€BØ �‰€BØ €GØ�|‰| A°4ˆ|Ö8ˆÙØ Ü ˆs‹8�qŠ=Ø(+¨B¨Q¨Ñ %ˆAˆ}™gÜ
�‹X˜Š]Ø%(¨¨! WÑ "ˆM™7à Ù¡GØ Ü(+¨MÓ(:×(@Ñ(@Ó(Bˆ”�G“ ×"Ñ"Ó$Ò%ð9ô
2026-03-16 14:21:12 +08:00
Ð)¬#¨g«,¨°tÐ
2026-03-17 10:49:42 +08:00
<Ô=Ø €Nr&r.Ú
store_mappingcó&—|j|d«S©NrDrÄ)r.rØs r'Úresolve_business_store_namerÛ¡s€Ø × Ñ ˜]¨BÓ /Ð/r&c ó—gd¢}|D�cgc]}tj|«rŒ|‘Œ}}|rtddj|«›�«‚t dtj
2026-03-16 14:21:12 +08:00
d›dtj
d›dtj
d ›�«t
2026-03-17 10:49:42 +08:00
jtj
dtj
dtj
d
tj
d tj
d ¬ «Scc}w)
N)ÚANALYTICS_DB_HOSTÚANALYTICS_DB_PORTÚANALYTICS_DB_USERÚANALYTICS_DB_PASSWORDÚANALYTICS_DB_NAMEu缺少数æ�®åº“环境å�˜é‡�: ú, u连接 PostgreSQL: host=rÝz port=rÞz db=rárßrà)ÚhostÚportÚuserÚpasswordÚdbname)rprzr{ÚjoinrXrqÚpsycopg2Úconnect)ÚrequiredruÚmissings r'Úget_db_connectionrí¥sö€ò€Hñ'Ó=™h�s¬b¯i©i¸­nŠs˜h€GÐ=ÙÜÐ8¸¿¹À7Ó9KÐ8LÐMÓNÐNÜ Ø
"¤2§:¡:Ð.AÑ#BÐ"CÀ6Ì"Ï*É*ÐUhÑJiÐIjÐjnÔoq×oyÑoyð{NñpOðoPð Qôô × Ñ Ü
2026-03-17 10:49:42 +08:00
�Z‰ZÐ+Ñ
,Ü
�Z‰ZÐ+Ñ
,Ü
�Z‰ZÐ+Ñ
,Ü—‘Ð3Ñ4Ü�z‰zÐ-Ñ.ô  ðùò
>s
‰C?¤C?Ú
start_dateÚend_dateÚ
metric_configc
óf—|j«›d�}|td¬«zj«›d�}td|j›d|›d|›d�«t «5}|j «5}|j
|j||dœ«|j«}ddd«ddd«t|j›d t«›d
2026-03-17 10:49:42 +08:00
�«|D�cgc]8}t|d |dxsd j«|d
xs td«¬«‘Œ:c}S#1swYŒyxYw#1swYŒ}xYwcc}w)Nz 00:00:00rhr‹u 开始查询z: ú -> u (å�³å¼€åŒºé—´))Ústart_tsÚend_ts_exclusiveu查询完æˆ�: u 行rrDrÊÚ0)r-r.r/)
rŽrrXrríÚcursorÚexecuterÚfetchallr_r,rmr ) rîrïrðrórôÚconnÚcurÚrowsrÓs r'Úfetch_metric_rowsrü¼s,€Ø×&Ñ&Ó(Ð)¨Ð3€HØ#¤i°QÔ&7Ñ7×BÑBÓDÐEÀYÐOÐÜ ˆ|˜M×5Ñ5Ð6°b¸¸
À$ÐGWÐFXÐXgÐ
2026-03-17 10:49:42 +08:00
hÔiÜ Ô  Ø
�[‰[Œ]˜cØ �K‰K˜
2026-03-17 10:49:42 +08:00
×2Ñ2ÀÐ_oÑ4pÔ qØ—<‘<“>ˆD÷÷
ô
�
×)Ñ)Ð*¨.¼¸T»¸ À4Ð
HÔIñó áˆCô ˜C ™F°3°q±6²<¸R×2FÑ2FÓ2HÐQTÐUVÑQWÒQgÔ[bÐcfÓ[gÖhØñ ð÷ ˆ]ú÷
2026-03-17 10:49:42 +08:00
Ð üò
2026-03-16 14:21:12 +08:00
 s*ÁD"Á.0DÂD"Ã=D.ÄD ÄD"Ä"D+rûcó8—td|j›�«td„«}|D]¨}t|j|«}|sŒt |«}|sŒ*|j j|j jf}||||j j|td««}||jz||||j |<Œªt|«} td„|j«D««}
2026-03-17 10:49:42 +08:00
t|j›d| ›d|
›�«|S)Nu 开始按项目/月/日期è�šå�ˆcó—td„«S)Ncó —tt«SrU)rrQr%r&r'Ú<lambda>z9build_project_metrics.<locals>.<lambda>.<locals>.<lambda>Òs €¤K´Ô$5r&rr%r&r'rz'build_project_metrics.<locals>.<lambda>Òs
€” Ñ5Ô6r&rõc3ó2K—|]}t|«–—Œy­wrU)r_)r¹Úmonthss r'r»z(build_project_metrics.<locals>.<genexpr>ßsèø€ÐAÑ0@ f”c˜&—kÑ0@ùó‚uè�šå�ˆå®Œæˆ�: 项目=u,项目月份组å�ˆ=)rXrrrÛr.rÁr-ÚyearÚmonthr¤r r/r_Úsumr\) rûrØrðÚgroupedrÓÚbusiness_store_namer¿Ú month_keyÚcurrent_amountÚ
2026-03-16 14:21:12 +08:00
project_countÚ month_counts r'Úbuild_project_metricsr
Ës€ô
2026-03-17 10:49:42 +08:00

Ð/°
×0IÑ0IÐ/JÐ
KÔLÜP[Ù6óQ€GóˆÜ9¸#×:KÑ:KÈ]Ó[ÐÙ"Ø Ü"Ð#6Ó7ˆÙØ Ø—]‘]×'Ñ'¨¯©×)<Ñ)<Ð=ˆ Ø  Ñ)¨)Ñ4°S·]±]ÑC×GÑGÐH[Ô]dÐehÓ]iÓjˆØJXÐ[^×[eÑ[eÑJeˆ�јÑ# C§M¡MÑ2Ð3FÒGðô˜“L€MÜÑA°·±Ô0@ÓAÓA€KÜ �
×)Ñ)Ð*Ð*?À
¸ÐNdÐepÐdqÐ
rÔsØ €Nr&Úgrouped_metricscó°—|j«D����cic]3\}}||j«D��cic]\}}|t|«“Œc}}“Œ5}}}}}|}||krn|j|jf}tD]8}|j |i«} | j |i«}
|
j |i«Œ:|t
d¬«z
}||krŒn|Scc}}wcc}}}}wrŠ)ÚitemsrQrrÚSUPPORTED_PROJECTSrrr) rîrïrr¿Ú
month_dictr Údate_mapÚresultÚcurrentÚproject_monthsÚmetrics_by_dates r'Úbuild_target_project_monthsräsë€ð$3×#8Ñ#8Ô#:öá#:Ñ ˆG�Zð Àz×GWÑGWÔGYÔZÑGYÑ0C° ¸8�)œT (›^Ñ+ÐGYÒZÑZØ#:ð óð€GØ
2026-03-16 14:21:12 +08:00
�XÒ
Ø—\‘\ 7§=¡=Ð1ˆ ß)ˆGØ#×.Ñ.¨w¸Ó;ˆNØ,×7Ñ7¸ À2ÓFˆOØ × &Ñ & w°Õ 3ð*ð ”9 !Ô$Ñ$ˆð
�XÓ
2026-03-17 10:49:42 +08:00
ð €Mùó[ùõs–C
²C
2026-03-16 14:21:12 +08:00
ÁC
2026-03-17 10:49:42 +08:00
Ã
2026-03-16 14:21:12 +08:00
C
rPcóô—t|j«}t|j«}|rt dt |«›d�«t
|j«}|j«}t|||||¬«S)Nu加载表å��映射完æˆ�: rÎ)rLrMrNrOrP)
2026-03-17 10:49:42 +08:00
r×r?Úload_table_name_overridesrArXr_rKr>Ú list_tablesrJ)rPrNrOrLrMs r'Úbuild_daily_sync_contextrøsu€Ü  ×!4Ñ!4Ó5€GÜ/°×0EÑ0EÓF€OÙÜÐ-¬c°/Ó.BÐ-CÀ4ÐHÔIÜ
 §¡Ó
1€FØ
×
2026-03-16 14:21:12 +08:00
Ñ
2026-03-17 10:49:42 +08:00
Ó
!€FÜ ØØØØ'Øô  ðr&cód—tjd«}tjd«}|r|s td«‚td«t j
d||dœd¬«}|j
«|j«}|jd «d
k7rtd |›�«‚td «|d
S)NÚ
FEISHU_APP_IDÚFEISHU_APP_SECRETu:缺少飞书环境å�˜é‡� FEISHU_APP_ID / FEISHU_APP_SECRETu&开始获å�–飞书 tenant_access_tokenzEhttps://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal)Úapp_idÚ
2026-03-16 14:21:12 +08:00
app_secreté©ÚjsonÚtimeoutÚcoderu获å�–飞书 token 失败: u'飞书 tenant_access_token 获å�–æˆ�功Útenant_access_token)
rprzr{rXÚrequestsÚpostÚraise_for_statusr$r¤Ú RuntimeError)r r!ÚrespÚpayloads r'Úget_feishu_tokenr.s§€Ü
2026-03-17 10:49:42 +08:00
�Y‰Y�Ó
'€FÜ—‘Ð.Ó/€JÙ ™ÜÐUÓVÐVÜ Ð
5Ô6Ü �=‰=ØOبjÑ
9Øô €Dð
 ×ÑÔØ�i‰i‹k€G؇{�{�6Ó˜aÒÜÐ8¸¸ ÐBÓCÐCÜ Ð
2026-03-16 14:21:12 +08:00
6Ô7Ø Ð(Ñ )Ð)r&c
ó*—eZdZdeddfd„Zededefd„«Zdedededeeeffd „Z de
2026-03-17 10:49:42 +08:00
e fd
„Z d ede
2026-03-16 14:21:12 +08:00
eeeffd „Z
d ed
edefd„Zd ede
eeefdzfd„Zd ede
2026-03-17 10:49:42 +08:00
eeefddfd„Zd ede
eeeffd„Zd ededeeefddfd„Zy)rKr>rSNcóR—||_|j|«|_td|j›�«t «|_i|_i|_d|_tj«|_ |jjjd|j
2026-03-17 10:49:42 +08:00
›�ddœ«y)Nu(è§£æž�飞书 Base URL æˆ�功: app_token=úBearer úapplication/json; charset=utf-8©Ú
Authorizationz Content-Type)r>Úextract_app_tokenÚ app_tokenrXr.ÚtokenÚ
_fields_cacheÚ_records_cacheÚ
_tables_cacher(ÚSessionÚsessionÚheadersÚupdate)Úselfr>s r'Ú__init__zFeishuBitableClient.__init__s�€Ø ˆŒ
2026-03-17 10:49:42 +08:00
Ø×/Ñ/°Ó9ˆŒÜÐ;¸D¿N¹NÐ;KÐLÔMÜ%Ó'ˆŒ
Ø>@ˆÔØ?AˆÔØ59ˆÔÜ×'Ñ'Ó)ˆŒ Ø � ‰ ×Ñ×#Ñ#à#*¨4¯:©:¨,Ð!7Ø Añ
õ
r&có¸—t|«jjd«}tjd|«}|st d|›�«‚|j
d«S)NÚ/z base/([^/]+)u$无法从链接中解æž� app_token: rh)r rÇrmr¯Úsearchr{Úgroup)r>rÇÚmatchs r'r5z%FeishuBitableClient.extract_app_token,sQ€ä˜Ó!×&Ñ&×,Ñ,¨SÓ1ˆÜ— ‘ ˜/¨4Ó0ˆÙÜÐCÀHÀ:ÐNÓOÐ OØ�{‰{˜1‹~Ðr&ÚmethodrÇÚkwargsc óh—d|›�}|jd«}|rtd|›d|›d|›�«ntd|›d|›�«|jj||fddi|¤Ž} |j «}|jd k\rj|jd «xsi}td
2026-03-17 10:49:42 +08:00
|j›d|›d|jd«›d|jd«›d|jdd«›d|›� «‚|jd«dk7r]|jd «xsi}td|›d|jd«›d|jd«›d|jdd«›d|›�
«‚|jd«xsiS#t
$r9|j
«td|j›d |jdd
›�«‚wxYw)Núhttps://open.feishu.cnÚparamsu请求飞书接å�£: Ú z params=r%é<u-飞书接å�£è¿”回了é�ž JSON å“�应: status=ú, body=éôé�Úerroru飞书接å�£ HTTP z: code=r&z msg=Úmsgz log_id=Úlog_idrDz payload=ru飞书接å�£å¤±è´¥ Údata)
r¤r[r<Úrequestr$r{r*r+Ú status_codeÚtext) r?rFrÇrGÚurlrJr,r-rPs r'rTzFeishuBitableClient.request4sö€Ø& t fÐ-ˆØ—‘˜HÓ%ˆÙ Ü Ð,¨V¨H°A°d°V¸8ÀFÀ8ÐLÕ Mä Ð,¨V¨H°A°d°VÐ<Ô =Ø#ˆt�|‰|×#Ñ# F¨CÑF¸ÐF¸vÑFˆð {Ø—i‘i“kˆGð × Ñ ˜sÒ "Ø—K‘K Ó(Ò.¨BˆEÜØ$ T×%5Ñ%5Ð$6°a¸°v¸WÀWÇ[Á[ÐQWÓEXÐDYÐY^Ð_f×_jÑ_jÐkpÓ_qÐ^rðsØŸ)™) H¨bÓ1Ð2°)¸G¸9ðFóð
ð �;‰;�vÓ  !Ò #Ø—K‘K Ó(Ò.¨BˆEÜØ% d V¨7°7·;±;¸vÓ3FÐ2GÀuÈWÏ[É[ÐY^ÓM_ÐL`ðaØŸ)™) H¨bÓ1Ð2°)¸G¸9ðFóð
2026-03-17 10:49:42 +08:00
ð�{‰{˜6Ó"Ò( bÐ(øôò {Ø × !Ñ !Ô #ÜÐ!NÈt×O_ÑO_ÐN`Ð`gÐhl×hqÑhqÐrvÐsvÐhwÐgxÐyÓzÐ zð {ús
Á E/Å/AF1c ód—|j�-tdt|j«›�«|jStd«g}d} i}|r||d<|j dd|j
›d�|¬«}|j
d «xsgD]$}|jt|d
|d ¬ ««Œ&|j
d
2026-03-16 14:21:12 +08:00
d«sn|j
2026-03-17 10:49:42 +08:00
d«xsd}|snŒ“tdt|D�cgc]}|j‘Œc}«›�«tdt|«›d�«||_|Scc}w)Nu命中数æ�®è¡¨ç¼“å­˜: 表数=u'开始获å�–多维表格数æ�®è¡¨åˆ—表rDÚ
page_tokenÚGETú/open-apis/bitable/v1/apps/z/tables©rJrr2r)r2rÚhas_moreFu 飞书返回的数æ�®è¡¨å��ç§°: uæ•°æ�®è¡¨åˆ—表获å�–完æˆ�: u 个) r:r[r_rXrTr6r¤Úappendr1r`r)r?rrYrJrSr¦s r'rzFeishuBitableClient.list_tablesOsB€Ø × Ñ Ð )Ü Ð6´s¸4×;MÑ;MÓ7NÐ6OÐPÔ QØ×%Ñ%Ð %ÜÐ:Ô;Ø!#ˆØˆ
ØØ%'ˆFÙØ'1��|Ñ$Ø—<‘< Ð)DÀTÇ^Á^ÐDTÐT[Ð'\Ðek�<ÓlˆDØŸ™ Ó)Ò/¨RÒ/�Ø— ‘ œY°°ZÑ0@ÀtÈFÁ|ÔTÕUð0à—8‘8˜J¨Ô.ØØŸ™ ,Ó/Ò5°2ˆJÙØðô Ð4´\ÑY^ÓB_ÑY^ÐQUÀ4Ç9Ã9ÐY^ÑB_Ó5`Ð4aÐbÔcÜÐ0´°U³° ¸DÐAÔBØ"ˆÔ؈ ùòC`sÃ,D-r2cóΗ||jvr6td|›dt|j|«›�«|j|Std|›�«g}d}t«}d} |dz
2026-03-16 14:21:12 +08:00
}ddi}|r+||d <||vrt d
|›d |›�«‚|j |«td |›d
|›d |xsd›�«|j
2026-03-17 10:49:42 +08:00
dd|j›d|›d�|¬«}|j|jd«xsg«|jdd«}|jd «xsd} td|›d
|›dt|«›d|›d| xsd›�
2026-03-16 14:21:12 +08:00
«|sn3| st d|›dt|«›�«‚| }|dk\rt d|›�«‚�Œ||j|<td|›d t|D�
2026-03-17 10:49:42 +08:00
cgc]}
2026-03-16 14:21:12 +08:00
|
2026-03-17 10:49:42 +08:00
jd!d«‘Œc}
«›�«td"|›dt|«›�«|Scc}
2026-03-16 14:21:12 +08:00
w)#Nu命中字段缓存: table_id=õ , 字段数=u#开始获å�–字段列表: table_id=rDrrhÚ page_sizeédrYu@字段列表分页出现é‡�å¤� page_token,已中断: table_id=ú
2026-03-17 10:49:42 +08:00
, page_token=u#获å�–字段列表分页: table_id=ú, page=ú<first>rZr[ú/tables/ú/fieldsr\rr]Fu#字段列表分页完æˆ�: table_id=u, 累计字段数=z , has_more=ú, next_page_token=ú<empty>uG字段列表分页返回 has_more=True 但 page_token 为空: table_id=u, 已获å�–字段数=u7字段列表分页超过 100 页,已中断: table_id=u&飞书返回的字段å��ç§°: table_id=ú , fields=r£u#字段列表获å�–完æˆ�: table_id=) r8r[r_r;r+ÚaddrTr6Úextendr¤r`) r?r2rrYÚ seen_tokensÚ
2026-03-16 14:21:12 +08:00
page_indexrJrSr]Únext_page_tokenr¦s r'Ú list_fieldszFeishuBitableClient.list_fieldsgsÀ€Ø �t×)Ñ)Ñ )Ü Ð5°h°Z¸|ÌCÐPT×PbÑPbÐckÑPlÓLmÐKnÐoÔ pØ×%Ñ% hÑ/Ð /ÜÐ7¸°zÐBÔCØ&(ˆØˆ
2026-03-17 10:49:42 +08:00
Ü #£ˆ ؈
2026-03-16 14:21:12 +08:00
ØØ ˜!‰OˆJØ! 3Ð'ˆFÙØ'1��|Ñ$Ø Ñ,Ü&Ð)iÐjrÐisðtAðBLðAMð(NóOðOØ—‘ 
2026-03-17 10:49:42 +08:00
Ô+Ü Ð;¸H¸:ÀWÈZÈLÐXeÐfpÒf}Ðt}Ðe~Ðô
2026-03-16 14:21:12 +08:00
AØ—<‘<ØØ-¨d¯n©nÐ-=¸XÀhÀZÈwÐWØð óˆDð
�L‰L˜Ÿ™ 'Ó*Ò0¨bÔ 1Ø—x‘x 
2026-03-17 10:49:42 +08:00
¨EÓ2ˆHØ"Ÿh™h |Ó4Ò:¸ˆOÜ Ø5°h°Z¸wÀzÀlÐRdÔehÐinÓeoÐdpðqØ$˜:Ð%7¸Ò8TÈ9Ð7UðWô
ñØÙ"Ü"Ð%lÐmuÐlvðwLôMPðQVóMWðLXð$YóZðZØ(ˆJؘSÒ Ü"Ð%\Ð]eÐ\fÐ#gÓhÐhñ7ð8(-ˆ×ј8Ñ$ÜÐ:¸8¸*ÀIÌlñDIó\JñDIÐ{Ð\`×\dÑ\dÐeqÐsuÕ\vðDIñ\JóOKðNLðMô NÜÐ7¸°zÀÌcÐRWËjÈ\ÐZÔ[؈ ùò\JsÆ G"r£cób‡—td|›d‰›�«|j|«}tˆfd„|D««rtd|›d‰›�«ytd|›d‰›�«|j dd|j
›d |›d
�‰d d œ¬
«|j j|d«td|›d‰›�«y)Nu#检查字段是å�¦å­˜åœ¨: table_id=ú, field=c3óF•K—|]}|jd«‰k(–—Œy­w)r£NrÄ)r¹r¦r£s €r'r»z:FeishuBitableClient.ensure_number_field.<locals>.<genexpr>”s øèø€ÐGÁ¸ˆt�x‰x˜ Ó%¨Õ3Áùsƒ!u)字段已存在,跳过创建: table_id=Fu#开始创建数字字段: table_id=ÚPOSTr[rfrgrÊ)r£Útype©r$u字段创建完æˆ�: table_id=T)r[rpr½rXrTr6r8Úpop)r?r2r£r s ` r'Úensure_number_fieldz'FeishuBitableClient.ensure_number_field‘sÌø€ÜÐ7¸°zÀÈ*ÈÐVÔWØ×!Ñ! (Ó+ˆÜ ÓGÁÓGÔ GÜ ÐAÀ(ÀÈ8ÐT^ÐS_Ð`Ô aØÜÐ6°x°jÀÈÈ ÐUÔVØ � ‰ Ø Ø)¨$¯.©.Ð)9¸À(ÀÈ7Ð SØ *°AÑ6ð ô
2026-03-16 14:21:12 +08:00
ð
2026-03-17 10:49:42 +08:00
×Ñ×јx¨Ô.ÜÐ0°°
¸(À:À,ÐOÔPØr&có^—d|j›d|›d�}d|›�}td|›�«|jjd|d¬«} |j «}|j d k(rtd |›d
|›�«y|j dk\s|jd«dk7rtd|›d
|›�«y|jd«xsi}|jd«xs|jd«xsg}td|›dt|«›�«|S#t
$rtd |›d
2026-03-17 10:49:42 +08:00
|j ›�«YywxYw)Nr[rfú
/field_groupsrIu#å°�试读å�–字段编组: table_id=rZrL)r%u:字段编组接å�£è¿”回é�ž JSON,跳过读å�–: table_id=z , status=i”u,字段编组读å�–接å�£ä¸�å�¯ç”¨: table_id=ú
2026-03-17 10:49:42 +08:00
, payload=rOr&ru2字段编组读å�–失败,跳过比对: table_id=rSrÚ field_groupsu#字段编组读å�–æˆ�功: table_id=u , 编组数=) r6r[r<rTr$r{rUr¤r_)r?r2rÇrWr,r-rSrs r'Útry_list_field_groupsz)FeishuBitableClient.try_list_field_groups¡sP€Ø,¨T¯^©^Ð,<¸HÀXÀJÈmÐ\ˆØ& t fÐ-ˆÜÐ7¸°zÐBÔCØ�|‰|×#Ñ# E¨3¸Ð#Ó;ˆð Ø—i‘i“kˆGð × Ñ ˜sÒ "Ü ÐDÀXÀJÈjÐY`ÐXaÐbÔ cØØ × Ñ ˜sÒ " g§k¡k°&Ó&9¸QÒ&>Ü ÐJÈ8È*ÐT^Ð_fÐ^gÐhÔ iØØ�{‰{˜6Ó"Ò( bˆØ—‘˜Ó!ÒC T§X¡X¨nÓ%=ÒCÀˆÜÐ7¸°zÀÌcÐRWËjÈ\ÐZÔ[؈ øôò Ü ÐRÐS[ÐR\Ð\eÐfj×fvÑfvÐewÐxÔ yÙð úsÁDÄ$D,Ä+D,r|có—td|›d|D�cgc]5}|jd«xsdt|jd«xsg«f‘Œ7c}›�«|jdd|j›d|›d �d
|i¬ «td |›�«ycc}w)
Nu#开始创建字段编组: table_id=z , groups=rrDÚchildrenrtr[rfrzr|rvu)字段编组创建请求完æˆ�: table_id=)rXr¤r_rTr6)r?r2r|rDs r'Úcreate_field_groupsz'FeishuBitableClient.create_field_groups¶s§€ÜØ1°(°ð<Ù`lÓmÑ`lÐW\˜Ÿ ™  &Ó)Ò/¨R´°U·Y±Y¸zÓ5JÒ5PÈbÓ1QÒRÐ`lÑmÐnð
pô
ð
� ‰ Ø Ø)¨$¯.©.Ð)9¸À(ÀÈ=Ð YØ  ,Ð/ð ô
ô
2026-03-17 10:49:42 +08:00
Ð<¸X¸JÐGÕHùònsŽ:Bc óf—||jvr6td|›dt|j|«›�«|j|Std|›�«g}d}d} |dz
}ddi}|r||d <td
|›d |›d |xsd
›�«|jdd|j›d|›d�|¬«}|j |j
d«xsg«|j
d «xsd}td|›d |›dt|«›d|xsd›�«|snŒ®td|›dt|«›�«||j|<|S)Nu命中记录缓存: table_id=u , 记录数=u#开始获å�–记录列表: table_id=rDrrhrarNrYu#获å�–记录列表分页: table_id=rdrcrerZr[rfz/recordsr\ru#记录列表分页完æˆ�: table_id=u, 累计记录数=rhriu#记录列表获å�–完æˆ�: table_id=)r9r[r_rTr6rlr¤)r?r2rrYrnrJrSs r'Ú list_recordsz FeishuBitableClient.list_recordsÂs‰€Ø �t×*Ñ*Ñ *Ü Ð5°h°Z¸|ÌCÐPT×PcÑPcÐdlÑPmÓLnÐKoÐpÔ qØ×&Ñ& xÑ0Ð 0ÜÐ7¸°zÐBÔCØ&(ˆØˆ
؈
ØØ ˜!‰OˆJØ! 3Ð'ˆFÙØ'1��|Ñ$Ü Ð;¸H¸:ÀWÈZÈLÐXeÐfpÒf}Ðt}Ðe~Ðô
AØ—<‘<ØØ-¨d¯n©nÐ-=¸XÀhÀZÈxÐXØð óˆDð
2026-03-17 10:49:42 +08:00
�L‰L˜Ÿ™ 'Ó*Ò0¨bÔ 1ØŸ™ ,Ó/Ò5°2ˆJÜ Ø5°h°Z¸wÀzÀlðS#Ü#& u£: ,Ð.@ÀÒAXÈyÐ@Yð[ô
ñØð%ô& Ð7¸°zÀÌcÐRWËjÈ\ÐZÔ[Ø(-ˆ×јHÑ%؈ r&Ú record_idr c ód—td|›d|›dt|j««›�«|jdd|j›d|›d|›�d|i¬ «|j
j
|«}|�?|D]9}|j
d
«|k(sŒ|jdi«j|«yyy) Nu更新记录: table_id=z , record_id=rjÚPUTr[rfz /records/r rvrƒ) r[r7ÚkeysrTr6r9r¤rrr>)r?r2rƒr Úcached_recordsr¦s r'Ú
update_recordz!FeishuBitableClient.update_recordás€ÜÐ+¨H¨:°\À)ÀÈIÔVZÐ[a×[fÑ[fÓ[hÓViÐUjÐkÔlØ � ‰ Ø Ø)¨$¯.©.Ð)9¸À(ÀÈ9ÐU^ÐT_Ð `ؘFÐ#ð ô
ð
×,Ñ,×0Ñ0°Ó:ˆØ Ð %Û&�Ø—8‘8˜KÓ(¨IÓ5Ø—O‘O H¨bÓ1×8Ñ8¸Ô@Ùñ'ð &r&)r r!r"r#r@Ú staticmethodr5r rQrTr7r1rrprHrxr}r€r‚rˆr%r&r'rKrKsF„ð
2026-03-17 10:49:42 +08:00
 ð
¨ó
2026-03-17 10:49:42 +08:00
ð ð Cð¨Còóðð)˜cð)¨ð)¸ð)ÀÀSÈ#ÀXÁó)ð6˜T )™_óð0( Cð(¨D°°c¸3°h±Ñ,@ó(ðT¨Cð¸SðÀTóð ¨cð°d¸4ÀÀSÀ¹>Ñ6JÈTÑ6Qóð*
I¨Cð
2026-03-17 10:49:42 +08:00
I¸tÀDÈÈcÈÁNÑ?Sð
IÐX\ó
Ið Sð¨T°$°s¸C°x±.Ñ-Aóð>  cð °cð À4ÈÈSÈÁ>ð ÐVZô r&rKÚ path_textcó—|siSt|«}|j«std|›�«‚tj|j d¬««}|j
«D��cic]\}}t|«t|«“Œc}}Scc}}w)Nu未找到表å��映射文件: rcrd)r
rjÚFileNotFoundErrorr$Úloadsrkrr#)rŠrÇr-rurvs r'rrðsw€Ù ؈ Ü � ‹?€DØ �;‰;Œ=ÜÐ"?À¸vÐ FÓGÐGÜ�j‰j˜Ÿ™°˜Ó9Ó:€GØ3:·=±=´?Ô C±?¡Z S¨%ŒC�‹H”c˜%“jÑ °?Ò CÐCùÓ CsÁ&B Ú webhook_urlÚtitler>c óz—|s td«ydddidd|dœdœd d
d |j«›d |j«›d
2026-03-17 10:49:42 +08:00
|›d�dœdœgdœdœ}td«tj||d¬«}|j «|j «}|j
d«dvrtd|›�«‚td«y)Nu;未é…�置飞书群机器人 webhook,跳过群消æ�¯æŽ¨é€�Ú interactiveÚwide_screen_modeTÚblueÚ
plain_text©ÚtagÚcontent©Útemplater�ÚdivÚlark_mdõ**å�Œæ­¥èŒƒå›´**
õ 至 u.
**多维表格**
[点击打开多维表格](Ú)©r–rV©rPÚheaderÚelements)Úmsg_typeÚcardu!开始推é€�飞书群å�¡ç‰‡æ¶ˆæ�¯r"r#r&)rNu飞书群消æ�¯æŽ¨é€�失败: u!飞书群å�¡ç‰‡æ¶ˆæ�¯æŽ¨é€�完æˆ�)rXrŽr(r)r*r$r¤r+)rŽr�r>rîrïr¤r,r-s r'Úsend_feishu_sync_cardr¥úsè€ñ ÜÐNÔOØà!à)¨4Ð0à"Ø!-¸%Ñ@ñð !à(à0°×1EÑ1EÓ1GÐ0HÈÈh×N`ÑN`ÓNbÐMcðdLØLTÈ:ÐUVðXññ ð ñ

ñ €Dô,
Ð
0Ô1Ü �=‰=˜¨4¸Ô <€DØ×ÑÔØ�i‰i‹k€G؇{�{�6Ó )Ñ+ÜÐ:¸7¸)ÐDÓEÐEÜ Ð
0Õ1r&Ú
image_pathr7có^—|syt|«}|j«std|›�«‚|xs
t«}dd|›�i}|j d«5}d|j
|dfi}dd i}t
d
|›�«tjd |||d ¬
«}ddd«j«|j«}|jd«dk7rtd|›�«‚|jd«xsijd«xsd} | std|›�«‚t
d| ›�«| S#1swYŒ“xYw)NrDu未找到预览图文件: r4r1ÚrbÚimagezapplication/octet-streamÚ
image_typerRu 开始上传飞书消æ�¯å›¾ç‰‡: z-https://open.feishu.cn/open-apis/im/v1/imagesrL)r=rSÚfilesr%r&ru飞书图片上传失败: rSÚ image_keyu0飞书图片上传æˆ�功但未返回 image_key: u*飞书消æ�¯å›¾ç‰‡ä¸Šä¼ å®Œæˆ�: image_key=)
2026-03-17 10:49:42 +08:00
r
rjrŒr.ÚopenrrXr(r)r*r$r¤r+)
r¦r7rÇr=Ú
image_filer«rSr,r-r¬s
r'Úupload_feishu_imager¯#sE€Ù ØÜ �
Ó €DØ �;‰;Œ=ÜÐ"<¸T¸FÐ CÓDÐDØ Ò 'Ô%Ó'€EØ '¨%¨Ð 1Ð2€GØ
�‰�4Œ˜Jؘ4Ÿ9™9 jÐ2LÐMÐNˆØ˜iÐ(ˆÜÐ3°D°6Ð:Ô;Ü�}‰}ÐLÐV]ÐdhÐpuð@BôCˆ÷
ð
2026-03-17 10:49:42 +08:00
 ×ÑÔØ�i‰i‹k€G؇{�{�6Ó˜aÒÜÐ7¸°yÐAÓBÐBØ—+‘+˜fÓ%Ò+¨×0Ñ0°Ó=ÒDÀ"€IÙ ÜÐMÈgÈYÐWÓXÐXÜ Ð9¸)¸Ð
2026-03-16 14:21:12 +08:00
EÔFØ Ð÷
2026-03-17 10:49:42 +08:00
ˆús Á>D#Ä#D,rEc ó6—|s td«y|xs
t«}|r
t||¬«nd}ddd|j«›d|j«›d|›d |›d
� d œd œg}|r|j d
2026-03-16 14:21:12 +08:00
|ddd œdœ«|j ddddd œd|dœgdœ«|dt j ddidd|d œdœ|dœd¬«dœ} d |›�d!d"œ}
td#|›�«tjd$|
| d%¬&«} | j «} | jd*k\rtd+| j›d,| ›�«‚| jd-«d.k7rtd/| ›�«‚td0«y#t$r9| j«td'| j›d(| jdd)›�«‚wxYw)1Nu<未é…�ç½® FEISHU_CHAT_ID,跳过应用机器人å�¡ç‰‡æŽ¨é€�)r7rDršr›rœr�u
2026-03-17 10:49:42 +08:00
**多维表格**
[z](ržr•rŸÚimgr”u报表预览图)r–Úimg_keyÚaltÚactionÚbuttonu打开仪表盘Úprimary)r–rVrurW)r–Úactionsr‘r’Tr“r˜r F)Ú ensure_ascii)Ú
receive_idr£r—r1r2r3u4开始通过应用机器人å�‘é€�群å�¡ç‰‡: chat_id=zGhttps://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_idrL)r=r$r%u>应用机器人å�‘é€�群å�¡ç‰‡å¤±è´¥ï¼Œè¿”回é�ž JSON: status=rMrNrOu-应用机器人å�‘é€�群å�¡ç‰‡å¤±è´¥: status=r{r&ru&应用机器人å�‘é€�群å�¡ç‰‡å¤±è´¥: u$应用机器人群å�¡ç‰‡å�‘é€�完æˆ�)rXr.r¯rŽr^r$Údumpsr(r)r{r*r+rUrVr¤)
rEr�r>rîrïr¦r7r¬r¢rRr=r,r-s
r'Úsend_feishu_app_cardr»;s1€ñ ÜÐOÔPØØ Ò 'Ô%Ó'€EÙ@JÔ# J°eÕ<ÐPR€Iðà à(¨×)=Ñ)=Ó)?Ð(@ÀÀh×FXÑFXÓFZÐE[ð\*Ø*/¨°°8°*¸Að?ññ
ð &€HñØ�‰ °)ÈLÐevÑDwÑxÔyØ ‡O�Oàð$Ø$0Ð=NÑOØ%Ø#ñ ðñ
ô ðØ!Ü—:‘:à-¨tÐ4Ø'-À ÐY^Ñ8_Ñ`Ø$ñ
ð
ô

ñ €Gð# 5 'Ð*Ø9ñ€Gô
ÐCÀGÀ9Ð
MÔNÜ �=‰=ØQØØ
Øô  €Dð HØ—)‘)“+ˆð ×ј3ÒÜÐJÈ4×K[ÑK[ÐJ\Ð\fÐgnÐfoÐpÓqÐq؇{�{�6Ó˜aÒÜÐCÀGÀ9ÐMÓNÐNÜ Ð