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

498 lines
78 KiB
Plaintext
Raw Normal View History

Ë
2026-03-24 16:33:14 +08:00
›(ÂiÕïãó —ddlZddlZddlZddlmZddlmZddlmZmZm Z ddl
2026-03-17 10:49:42 +08:00
m Z ddl m
2026-03-24 16:33:14 +08:00
Z
ddlmZddlmZddlZddlZdd lmZdd
lmZmZe
e«j5«j6Zed z Zed z Zed
2026-03-17 10:49:42 +08:00
z ZdZ dZ!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/ed0e0d,e,fd1„Z1efd2e
d,dfd3„Z2d,e,fd4„Z3d,e
2026-03-24 16:33:14 +08:00
fd5„Z4d,e,fd6„Z5d,e
2026-03-17 10:49:42 +08:00
fd7„Z6d,e,fd8„Z7d,e,fd9„Z8d,e,fd:„Z9d,e,fd;„Z:d,e,fd<„Z;d=e/e<e,efd>e,d,e,fd?„Z=d@e,d,efdA„Z>d@e,d,e,fdB„Z?dCe,d,e,fdD„Z@dEe,d,e/e,fdF„ZAdGe
d,e<e,e,ffdH„ZBdIe,dJe<e,e,fd,e,fdK„ZCd,ejˆjŠfdL„ZFdMedNedOe$d,e/e&fdP„ZGdQe/e&dJe<e,e,fdOe$d,e<e,e<eHe0e0fe<ee<e,e fffffdR„ZIdMedNedSe<e,e<eHe0e0fe<ee<e,e ffffd,e<e,e<eHe0e0fe<ee<e,e fffffdT„ZJdUe*d,e+fdV„ZKd,e,fdW„ZLGdX„dY«ZMdZe,d,e<e,e,ffd[„ZNd\e,d]e,d^e,dMedNed,df d_„ZOd“d`e,dae,dzd,e,fdb„ZP d”dce,d]e,d^e,dMedNed`e,dae,dzd,dfdd„ZQ d“dee/e'dEe,dfe0dge0dhe<e,e,fdzd,e'f di„ZRd@e d,eSfdj„ZTdkedOe$d,e,fdl„ZUd@ed,eSdzfdm„ZVdMedNed,e/efdn„ZWdMedNed,e<eHe0e0fe/effdo„ZX d“d=e/e<e,efdpe,dqeYe,dzd,e/e<e,effdr„ZZdked,eYe,fds„Z[dte/e<e,efd,e<e,e<e,efffdu„Z\dveMdwe'dpe,dqeYe,dzdxe]d,df dy„Z^dMedNed^e,dpe,dze,dxe]d{e]d,dfd|„Z_ d•d}e+dked~e]deYe,dzd,df
d€„Z`dked^e,dpe,dze,dxe]d{e]d,dfd�„ZadveMdwe'dpe,d‚e<ee<e,e ffdxe]dOe$d,eHe(eYe,ffdƒ„Zbd}e+d„e,dMedNed,e)f
d…„Zcd„e,dMedNed^e,d†e
dpe,dze,dxe]d{e]d,dfd‡„Zddked,e,fdˆ„Zedked,e,fd‰„Zfdked,e,fdŠ„Zgd,e,fd‹„ZhdveMdwe'dkedŒe,dxe]d,eYe,f d�„Zid}e+dMedNed,e)fdŽ„ZjdMedNed^e,dpe,dxe]d{e]d,dfd�„Zkd}e+dked,dfd�„Zld}e+dMedNed,dfd‘„Zmy)–éN©Ú defaultdict)Ú dataclass)ÚdateÚdatetimeÚ timedelta)ÚDecimal)ÚPath)ÚAny)Úurlparse)Ú
load_workbook)Ú
get_loggerÚ
setup_loggingz.envu店铺映射表.xlsxzfield_group_state.jsonz
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
2026-03-24 16:33:14 +08:00
统计日期,
原始店铺�称 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-24 16:33:14 +08:00
2026-03-17 10:49:42 +08:00
UNION ALL
2026-03-24 16:33:14 +08:00
2026-03-17 10:49:42 +08:00
SELECT
统计日期,
2026-03-24 16:33:14 +08:00
原始店铺�称 AS 店铺�称,
SUM(指标金�)
2026-03-17 10:49:42 +08:00
FROM base_data
WHERE 店铺主键 IN (1,28,29,3)
GROUP BY 1,2
2026-03-24 16:33:14 +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)Ú
2026-03-24 16:33:14 +08:00
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ØÓØÓØÓØ
ƒ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
2026-03-24 16:33:14 +08:00
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)
2026-03-24 16:33:14 +08:00
Nu&未找到 .env 文件,跳过加载: u加载环境å�˜é‡�: úutf-8©ÚencodingÚ#Ú=éT)Úforce) ÚexistsrXÚ read_textÚ
2026-03-17 10:49:42 +08:00
splitlinesÚstripÚ
startswithÚsplitÚosÚenvironÚ
2026-03-24 16:33:14 +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€6s€Ü ”— ‘ Ð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„:s€Ü
�9‰9Ð.Ô0HÓ IÐIr&cóZ—ttjdtt«««S)NÚFIELD_GROUP_STATE_FILE)r
rprzr#ÚDEFAULT_FIELD_GROUP_STATE_FILEr%r&r'Úget_field_group_state_filerˆ>s€Ü ”— ‘ Ð2´CÔ8VÓ4WÓXÓ YÐYr&có6—tjdt«S)NÚSYNC_START_DATE)rprzÚDEFAULT_START_DATEr%r&r'Úget_default_start_daterŒBs€Ü
2026-03-24 16:33:14 +08:00
�9‰9Ð&Ô(:Ó ;Ð;r&có`—tj«td¬«z
j«S©Nrh©Údays)rÚtodayrÚ isoformatr%r&r'Úget_default_end_dater“Fs!€Ü �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�Js/€ò€JóˆÜ— ‘ ˜#“ˆÚ ØŠLðð r&có.—tjdd«S)NÚFEISHU_CHAT_IDrDr›r%r&r'Úget_feishu_chat_idr Zs€Ü
�9‰9Ð% rÓ *Ð*r&có.—tjdd«S)NÚFEISHU_REPORT_IMAGE_PATHrDr›r%r&r'Úget_feishu_report_image_pathr£^s€Ü
2026-03-24 16:33:14 +08:00
�9‰9Ð/°Ó 4Ð4r&ÚfieldsÚpreferred_field_namecó¶—|D�cgc] }t|jd«xsd«‘Œ"}}||vr|StD]
}||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­bsu€ÙAGÓHÁ¸”3�t—x‘x  Ó-Ò3°Õ4À€KÐHؘ{Ñ*Ø#Ð#ß+ˆ Ø ˜ Ò #ØÒ ð,ô Ð>Ð?SÐ>TÐTcÐdoÐcpÐqÓ
rÐrùò
2026-03-24 16:33:14 +08:00
Is…%ArvcóJ—tj|d«j«S)Nz%Y-%m-%d)rÚstrptimer©rvs r'Ú
validate_dater±ls€Ü × Ñ ˜U JÓ /× 4Ñ 4Ó 6Ð6r&cóT—tjdd|xsd«j«S)Nu[\s_\-()()]+rD)ÚreÚsubÚlowerr°s r'Únormalize_textr¶ps#€Ü
2026-03-24 16:33:14 +08:00
�6‰6Ð% r¨5ª;°BÓ 7× =Ñ =Ó ?Ð?r&Ú
store_namec󘇗|xsdŠdgd¢fddgfdddgfddgfddgfg}|D]\}}tˆfd „|D««sŒ|cSd
2026-03-17 10:49:42 +08:00
‰vsd ‰vry
y) NrDr)ÚMamaÚmmmjrrrú ERBA MIGINArrc3ó&•K—|]}|‰v–—Œ
2026-03-24 16:33:14 +08:00
y­wrUr%)Ú.0Úkeywordrs €r'Ú <genexpr>z#classify_project.<locals>.<genexpr>~søèø€Ð7©h 7ˆw˜$Œ©hùóƒru大西瓜籽妈妈)Úany)r·Úprioritized_rulesÚprojectÚkeywordsrs @r'Úclassify_projectrÅts…ø€Ø Ò ˜€Dà Ò)Ð*Ø �{�mÐ$Ø
��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
2026-03-24 16:33:14 +08:00
«<Œotdt |«›d�«|S) Nu加载店铺映射表: T)Ú data_onlyé)Úmin_rowÚ values_onlyéu店铺映射加载完æˆ�: õ æ�¡)rXr
Ú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Ü
2026-03-16 14:21:12 +08:00
�‹X˜Š]Ø%(¨¨! WÑ "ˆM™7à Ù¡GØ Ü(+¨MÓ(:×(@Ñ(@Ó(Bˆ”�G“ ×"Ñ"Ó$Ò%ð9ô
2026-03-24 16:33:14 +08:00
Ð)¬#¨g«,¨°tÐ
2026-03-17 10:49:42 +08:00
<Ô=Ø €Nr&r.Ú
2026-03-24 16:33:14 +08:00
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
d›dtj
d›dtj
d ›�«t
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ôô × Ñ Ü
�Z‰ZÐ+Ñ
,Ü
�Z‰ZÐ+Ñ
2026-03-24 16:33:14 +08:00
,Ü
�Z‰ZÐ+Ñ
2026-03-17 10:49:42 +08:00
,Ü—‘Ð3Ñ4Ü�z‰zÐ-Ñ.ô  ðùò
>s
2026-03-24 16:33:14 +08:00
‰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
�«|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¸¸
2026-03-24 16:33:14 +08:00
À$ÐGWÐFXÐXgÐ
hÔiÜ Ô  Ø
�[‰[Œ]˜cØ �K‰K˜
×2Ñ2ÀÐ_oÑ4pÔ qØ—<‘<“>ˆD÷÷
2026-03-17 10:49:42 +08:00
ô
�
2026-03-24 16:33:14 +08:00
×)Ñ)Ð*¨.¼¸T»¸ À4Ð
2026-03-17 10:49:42 +08:00
HÔIñó áˆCô ˜C ™F°3°q±6²<¸R×2FÑ2FÓ2HÐQTÐUVÑQWÒQgÔ[bÐcfÓ[gÖhØñ ð÷ ˆ]ú÷
2026-03-24 16:33:14 +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««}
t|j›d| ›d|
2026-03-24 16:33:14 +08:00
›�«|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Ú
project_countÚ month_counts r'Úbuild_project_metricsrÐs€ô

Ð/°
×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Ü �
×)Ñ)Ð*Ð*?À
2026-03-17 10:49:42 +08:00
¸Ð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«}
2026-03-24 16:33:14 +08:00
|
2026-03-17 10:49:42 +08:00
j |i«Œ:|t
2026-03-24 16:33:14 +08:00
d¬«z
2026-03-17 10:49:42 +08:00
}||krŒn|Scc}}wcc}}}}wrŽ)ÚitemsrQrr ÚSUPPORTED_PROJECTSrrr) ròrórrÃÚ
2026-03-24 16:33:14 +08:00
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Ø
�XÒ
Ø—\‘\ 7§=¡=Ð1ˆ ß)ˆGØ#×.Ñ.¨w¸Ó;ˆNØ,×7Ñ7¸ À2ÓFˆOØ × &Ñ & w°Õ 3ð*ð ”9 !Ô$Ñ$ˆð
�XÓ
2026-03-16 14:21:12 +08:00
ð €Mùó[ùõs–C
2026-03-24 16:33:14 +08:00
²C
2026-03-16 14:21:12 +08:00
ÁC
Ã
C
2026-03-24 16:33:14 +08:00
rPcóô—t|j«}t|j«}|rt dt |«›d�«t
2026-03-17 10:49:42 +08:00
|j«}|j«}t|||||¬«S)Nu加载表å��映射完æˆ�: rÒ)rLrMrNrOrP)
2026-03-24 16:33:14 +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Ü
2026-03-17 10:49:42 +08:00
 §¡Ó
2026-03-16 14:21:12 +08:00
1€FØ
2026-03-24 16:33:14 +08:00
×
Ñ
Ó
!€FÜ ØØØØ'Øô  ðr&cód—tjd«}tjd«}|r|s td«‚td«t j
d||dœd¬«}|j
«|j«}|jd «d
2026-03-17 10:49:42 +08:00
k7rtd |›�«‚td «|d
2026-03-16 14:21:12 +08:00
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-17 10:49:42 +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_tokenr2
s§€Ü
�Y‰Y�Ó
2026-03-24 16:33:14 +08:00
'€FÜ—‘Ð.Ó/€JÙ ™ÜÐUÓVÐVÜ Ð
2026-03-16 14:21:12 +08:00
5Ô6Ü �=‰=ØOبjÑ
9Øô €Dð
2026-03-24 16:33:14 +08:00
 ×ÑÔØ�i‰i‹k€G؇{�{�6Ó˜aÒÜÐ8¸¸ ÐBÓCÐCÜ Ð
6Ô7Ø Ð(Ñ )Ð)r&c
ób—eZdZdeddfd„Zededefd„«Zdeeeeefffd„Zdd„Z ded edefd
2026-03-16 14:21:12 +08:00
„Z
ded ed eddfd „Z d
edede deee ffd„Z
deefd„Zdedeeee ffd„Zdededefd„Zdedeeee fdeee ffd„Zdedeeee ffd„Zdededeee fddfd„Zy)rKr>rSNcó|—||_|j|«|_td|j›�«t «|_i|_i|_d|_|j«|_
2026-03-24 16:33:14 +08:00
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_tokenrXr2ÚtokenÚ
2026-03-24 16:33:14 +08:00
_fields_cacheÚ_records_cacheÚ
_tables_cacheÚ_load_field_group_registryÚ_field_group_registryr,ÚSessionÚsessionÚheadersÚupdate)Úselfr>s r'Ú__init__zFeishuBitableClient.__init__!s¡€Ø ˆŒ
2026-03-24 16:33:14 +08:00
Ø×/Ñ/°Ó9ˆŒÜÐ;¸D¿N¹NÐ;KÐLÔMÜ%Ó'ˆŒ
2026-03-17 10:49:42 +08:00
Ø>@ˆÔØ?AˆÔØ59ˆÔØ%)×%DÑ%DÓ%FˆÔ"Ü×'Ñ'Ó)ˆŒ Ø � ‰ ×Ñ×#Ñ#à#*¨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'r9z%FeishuBitableClient.extract_app_token2sQ€ä˜Ó!×&Ñ&×,Ñ,¨SÓ1ˆÜ— ‘ ˜/¨4Ó0ˆÙÜÐCÀHÀ:ÐNÓOÐ OØ�{‰{˜1‹~Ðr&c óæ—t«}|j«siS tj|j d¬««}|j|j«xsi}i}|j«D]K\}}|xsij«D�� cic]\}} t|«t| «“Œc} }|t|«<ŒM|S#t
2026-03-24 16:33:14 +08:00
$r}t
d|›d|›�«icYd}~Sd}~wwxYwcc} }w)Nrcrdu7读å�–字段编组状æ€�文件失败,已忽略: path=ú, error=) rˆrjr(ÚloadsrkÚ ExceptionrXr¨r:rr#)
rErËr1ÚexcÚ app_payloadÚregistryr2ÚgroupsrÚgroup_ids
r'r?z.FeishuBitableClient._load_field_group_registry:så€Ü)Ó+ˆØ�{‰{Œ}؈Ið Ü—j‘j §¡¸ Ó!AÓBˆGð—k‘k $§.¡.Ó1Ò7°Rˆ Ø.0ˆØ +× 1Ñ 1Ö 3Ñ ˆH�fØW]ÒWcÐac×VjÑVjÔVlÔ&mÑVlÁNÀDÈ(¤s¨4£y´#°h³-Ñ'?ÐVlÒ&mˆH”S˜“]Ò #ð!4àˆøôò Ü ÐNÈtÈfÐT\Ð]`Ð\aÐbÔ cØ�Iûð üó 'ns#ž%CÂC-à C*Ã
C%ÃC*Ã%C*cóZ—t«} i}|j«r%tj|j d¬««}|j
||j <|jtj|dd¬«d¬«y#t$r}td|›d|›�«Yd}~yd}~wwxYw)NrcrdFrÎ)Ú ensure_asciiÚindentu7写入字段编组状æ€�文件失败,已忽略: path=rM) rˆrjr(rNrkr@r:Ú
write_textÚdumpsrOrX)rErËr1rPs r'Ú_save_field_group_registryz.FeishuBitableClient._save_field_group_registryIs—€Ü)Ó+ˆð d؈GØ�{‰{Œ}ÜŸ*™* T§^¡^¸W ^Ó%EÓF�Ø&*×&@Ñ&@ˆG�D—N‘NÑ #Ø �O‰OœDŸJ™J w¸UÈ1ÔMÐX_ˆOÕ `øÜò dÜ ÐNÈtÈfÐT\Ð]`Ð\aÐb× cÑ cûð dúsŒA9B B*ÂB%Â%B*r2Ú
2026-03-24 16:33:14 +08:00
group_namecóZ—|jj|i«j|d«SrÞ)r@r¨)rEr2r[s r'Úget_field_group_idz&FeishuBitableClient.get_field_group_idTs(€Ø×)Ñ)×-Ñ-¨h¸Ó;×?Ñ?À
ÈBÓOÐOr&rTcóh—|sy||jj|i«|<|j«yrU)r@rrrZ)rEr2r[rTs r'Úset_field_group_idz&FeishuBitableClient.set_field_group_idWs1€ÙØ ØJRˆ×"Ñ"×-Ñ-¨h¸Ó;¸JÑGØ ×'Ñ'Õ)r&ÚmethodrËÚkwargsc óh—d|›�}|jd«}|rtd|›d|›d|›�«ntd|›d|›�«|jj||fddi|¤Ž} |j «}|jd k\rj|jd «xsi}td
|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)Nzhttps://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[rBÚrequestr(r{r.r/Ú status_codeÚtext) rEr`rËraÚurlrcr0r1ris r'rmzFeishuBitableClient.request]sö€Ø& 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óð
ð�{‰{˜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
d«sn|j
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©rcrr2r)r2rÚhas_moreFu 飞书返回的数æ�®è¡¨å��ç§°: uæ•°æ�®è¡¨åˆ—表获å�–完æˆ�: u 个) r>r[r_rXrmr:r¨Úappendr1r`r)rErrrrcrlrªs r'rzFeishuBitableClient.list_tablesxsB€Ø × Ñ Ð )Ü Ð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-cóΗ||jvr6td|›dt|j|«›�«|j|Std|›�«g}d}t«}d} |dz
}ddi}|r+||d <||vrt d
|›d |›�«‚|j |«td |›d
|›d |xsd›�«|j
2026-03-16 14:21:12 +08:00
dd|j›d|›d�|¬«}|j|jd«xsg«|jdd«}|jd «xsd} td|›d
2026-03-24 16:33:14 +08:00
|›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-24 16:33:14 +08:00
cgc]}
|
jd!d«‘Œc}
«›�«td"|›dt|«›�«|Scc}
w)#Nu命中字段缓存: table_id=õ , 字段数=u#开始获å�–字段列表: table_id=rDrrhÚ page_sizeédrru@字段列表分页出现é‡�å¤� page_token,已中断: table_id=ú
2026-03-17 10:49:42 +08:00
, page_token=u#获å�–字段列表分页: table_id=ú, page=ú<first>rsrtú/tables/ú/fieldsrurrvFu#字段列表分页完æˆ�: 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=) r<r[r_r;r/Úaddrmr:Úextendr¨r`) rEr2rrrÚ seen_tokensÚ
2026-03-24 16:33:14 +08:00
page_indexrcrlrvÚnext_page_tokenrªs r'Ú list_fieldszFeishuBitableClient.list_fields�sÀ€Ø �t×)Ñ)Ñ )Ü Ð5°h°Z¸|ÌCÐPT×PbÑPbÐckÑPlÓLmÐKnÐoÔ pØ×%Ñ% hÑ/Ð /ÜÐ7¸°zÐBÔCØ&(ˆØˆ
Ü #£ˆ ؈
ØØ ˜!‰OˆJØ! 3Ð'ˆFÙØ'1��|Ñ$Ø Ñ,Ü&Ð)iÐjrÐisðtAðBLðAMð(NóOðOØ—‘ 
Ô+Ü Ð;¸H¸:ÀWÈZÈLÐXeÐfpÒf}Ðt}Ðe~Ðô
AØ—<‘<ØØ-¨d¯n©nÐ-=¸XÀhÀZÈwÐWØð óˆDð
�L‰L˜Ÿ™ 'Ó*Ò0¨bÔ 1Ø—x‘x 
¨EÓ2ˆHØ"Ÿh™h |Ó4Ò:¸ˆOÜ Ø5°h°Z¸wÀzÀlÐRdÔehÐinÓeoÐdpðqØ$˜:Ð%7¸Ò8TÈ9Ð7UðWô
2026-03-17 10:49:42 +08:00
ñØÙ"Ü"Ð%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óh‡—td|›d‰›�«|j|«}tˆfd„|D««rtd|›d‰›�«ytd|›d‰›�«|j dd|j
›d |›d
2026-03-17 10:49:42 +08:00
�‰d d d
2026-03-24 16:33:14 +08:00
idœ¬«|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=ÚPOSTrtrr€rÎÚ formatterz0.00)r§ÚtypeÚproperty©r(u字段创建完æˆ�: table_id=T)r[r‰rÁrXrmr:r<Úpop)rEr2r§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À[ÐRXÐDYÑZð ô
ð
2026-03-17 10:49:42 +08:00
×Ñ×јx¨Ô.ÜÐ0°°
¸(À:À,ÐOÔPØr&Ú field_groupscó€—td|›d|D�cgc]5}|jd«xsdt|jd«xsg«f‘Œ7c}›�«|jdd|j›d|›d �d
|i¬ «}|jd «xs|jd
2026-03-17 10:49:42 +08:00
«xsg}|D]†}t |jd«xsd«j
«}t |jd
«xs|jd«xsd«j
«}|sŒq|sŒt|j|||«Œˆtd|›�«|Scc}w)Nu#开始创建字段编组: table_id=ú , groups=rrDÚchildrenr�rtrz
/field_groupsr”r‘rÚidÚfield_group_idu)字段编组创建请求完æˆ�: table_id=)rXr¨r_rmr:r#rmr_)rEr2r”rJrlÚreturned_groupsr[rTs r'Úcreate_field_groupsz'FeishuBitableClient.create_field_groupsÊsB€ÜØ1°(°ð<Ù`lÓmÑ`lÐW\˜Ÿ ™  &Ó)Ò/¨R´°U·Y±Y¸zÓ5JÒ5PÈbÓ1QÒRÐ`lÑmÐnð
pô
ð�|‰|Ø Ø)¨$¯.©.Ð)9¸À(ÀÈ=Ð YØ  ,Ð/ðó
2026-03-24 16:33:14 +08:00
ˆð
Ÿ(™( 7Ó+ÒM¨t¯x©x¸Ó/GÒMÈ2ˆÛ$ˆEܘUŸY™Y vÓ.Ò4°"Ó5×;Ñ;Ó=ˆJܘ5Ÿ9™9 T›?ÒO¨e¯i©iÐ8HÓ.IÒOÈRÓP×VÑVÓXˆHÚšhØ×'Ñ'¨°*¸hÕGð %ô
Ð<¸X¸JÐGÔH؈ ùònsŽ:D;c óf—||jvr6td|›dt|j|«›�«|j|Std|›�«g}d}d} |dz
2026-03-17 10:49:42 +08:00
}ddi}|r||d <td
|›d |›d |xsd
2026-03-24 16:33:14 +08:00
›�«|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=rDrrhrzrgrru#获å�–记录列表分页: table_id=r}r|r~rsrtrz/recordsruru#记录列表分页完æˆ�: table_id=u, 累计记录数=r�r‚u#记录列表获å�–完æˆ�: table_id=)r=r[r_rmr:r…r¨)rEr2rrrr‡rcrls 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ð
�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=rƒÚPUTrtrz /records/r¤r‘rž) r[r7Úkeysrmr:r=r¨rrrD)rEr2rž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&)rSN)r r!r"r#rFÚ staticmethodr9rQr?rZr]r_r rmr7r1rr‰rHr“r›r�r£r%r&r'rKrK s�„ð
 ð
¨ó
ð"ð Cð¨Còóðð
¨D°°d¸3À¸8±nÐ1DÑ,Eó
2026-03-24 16:33:14 +08:00
ó dðP¨3ðP¸CðPÀCóPð*¨3ð*¸Cð*È3ð*ÐSWó*ð )˜cð)¨ð)¸ð)ÀÀSÈ#ÀXÁó)ð6˜T )™_óð0( Cð(¨D°°c¸3°h±Ñ,@ó(ðT¨Cð¸SðÀTóð ¨Cð¸tÀDÈÈcÈÁNÑ?SðÐX\Ð]`ÐbeÐ]eÑXfóð& 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(rNrkrr#)r¥rËr1rurvs 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
2026-03-24 16:33:14 +08:00
d«dvrtd|›�«‚td«y)Nu;未é…�置飞书群机器人 webhook,跳过群消æ�¯æŽ¨é€�Ú interactiveÚwide_screen_modeTÚblueÚ
plain_text©ÚtagÚcontent©Útemplater©ÚdivÚlark_mdõ**å�Œæ­¥èŒƒå›´**
õ 至 u.
2026-03-17 10:49:42 +08:00
2026-03-24 16:33:14 +08:00
**多维表格**
[点击打开多维表格](Ú)©r°ro©rPÚheaderÚelements)Úmsg_typeÚcardu!开始推é€�飞书群å�¡ç‰‡æ¶ˆæ�¯r&r'r*)rNu飞书群消æ�¯æŽ¨é€�失败: u!飞书群å�¡ç‰‡æ¶ˆæ�¯æŽ¨é€�完æˆ�)rXr’r,r-r.r(r¨r/)r¨r©r>ròrór¾r0r1s r'Úsend_feishu_sync_cardr¿sè€ñ ÜÐNÔOØà!à)¨4Ð0à"Ø!-¸%Ñ@ñð !à(à0°×1EÑ1EÓ1GÐ0HÈÈh×N`ÑN`ÓNbÐMcðdLØLTÈ:ÐUVðXññ ð ñ
2026-03-17 10:49:42 +08:00

ñ €Dô,
2026-03-24 16:33:14 +08:00
Ð
0Ô1Ü �=‰=˜¨4¸Ô <€DØ×ÑÔØ�i‰i‹k€G؇{�{�6Ó )Ñ+ÜÐ:¸7¸)ÐDÓEÐEÜ Ð
2026-03-17 10:49:42 +08:00
0Õ1r&Ú
2026-03-24 16:33:14 +08:00
image_pathr;có^—|syt|«}|j«std|›�«‚|xs
t«}dd|›�i}|j d«5}d|j
|dfi}dd i}t
2026-03-24 16:33:14 +08:00
d
|›�«tjd |||d ¬
2026-03-17 10:49:42 +08:00
«}ddd«j«|j«}|jd«dk7rtd|›�«‚|jd«xsijd«xsd} | std|›�«‚t
2026-03-24 16:33:14 +08:00
d| ›�«| S#1swYŒ“xYw)NrDu未找到预览图文件: r8r5ÚrbÚimagezapplication/octet-streamÚ
image_typerRu 开始上传飞书消æ�¯å›¾ç‰‡: z-https://open.feishu.cn/open-apis/im/v1/imagesre)rCrlÚfilesr)r*ru飞书图片上传失败: rlÚ image_keyu0飞书图片上传æˆ�功但未返回 image_key: u*飞书消æ�¯å›¾ç‰‡ä¸Šä¼ å®Œæˆ�: image_key=)
r
rjr§r2ÚopenrrXr,r-r.r(r¨r/)
rÀr;rËrCÚ
2026-03-24 16:33:14 +08:00
image_filerÅrlr0r1rÆs
2026-03-16 14:21:12 +08:00
r'Úupload_feishu_imagerÉ>sE€Ù ØÜ �
2026-03-17 10:49:42 +08:00
Ó €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ˆ÷
ð
 ×ÑÔØ�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-24 16:33:14 +08:00
EÔFØ Ð÷
ˆús Á>D#Ä#D,rEc ó6—|s td«y|xs
t«}|r
t||¬«nd}ddd|j«›d|j«›d|›d |›d
2026-03-17 10:49:42 +08:00
� d œd œg}|r|j d
2026-03-24 16:33:14 +08:00
|ddd œdœ«|j ddddd œd|dœgdœ«|dt j ddidd|d œdœ|dœd¬«dœ} d |›�d!d"œ}
2026-03-17 10:49:42 +08:00
td#|›�«tjd$|
2026-03-24 16:33:14 +08:00
| d%¬&«} | j «} | jd*k\rtd+| j›d,| ›�«‚| jd-«d.k7rtd/| ›�«‚td0«y#t$r9| j«td'| j›d(| jdd)›�«‚wxYw)1Nu<未é…�ç½® FEISHU_CHAT_ID,跳过应用机器人å�¡ç‰‡æŽ¨é€�)r;rDr´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°ror�rp)r°Úactionsr«r¬Tr­r²rºF)rV)Ú
receive_idr½r±r5r6r7u4开始通过应用机器人å�‘é€�群å�¡ç‰‡: chat_id=zGhttps://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_idre)rCr(r)u>应用机器人å�‘é€�群å�¡ç‰‡å¤±è´¥ï¼Œè¿”回é�ž JSON: status=rfrgrhu-应用机器人å�‘é€�群å�¡ç‰‡å¤±è´¥: status=z
, payload=r*ru&应用机器人å�‘é€�群å�¡ç‰‡å¤±è´¥: u$应用机器人群å�¡ç‰‡å�‘é€�完æˆ�)rXr2rÉr’rwr(rYr,r-r{r.r/rnror¨)
2026-03-24 16:33:14 +08:00
rEr©r>ròrórÀr;rÆr¼rRrCr0r1s
r'Úsend_feishu_app_cardrÓVs1€ñ ÜÐOÔPØØ Ò 'Ô%Ó'€EÙ@JÔ# J°eÕ<ÐPR€Iðà à(¨×)=Ñ)=Ó)?Ð(@ÀÀh×FXÑFXÓFZÐE[ð\*Ø*/¨°°8°*¸Að?ññ
2026-03-17 10:49:42 +08:00
ð &€HñØ�‰ °)ÈLÐevÑDwÑxÔyØ ‡O�Oàð$Ø$0Ð=NÑOØ%Ø#ñ ðñ
2026-03-24 16:33:14 +08:00
2026-03-17 10:49:42 +08:00
ô ðØ!Ü—:‘:à-¨tÐ4Ø'-À ÐY^Ñ8_Ñ`Ø$ñ