feat(accounting): accounting 模块加入产线平台 + 账务配置初始化

- build.sh: 业务模块/clone/pip install/CRUD/wwwroot链接 加 accounting + 汇率定时任务 cron
- create_tables.py: accounting 幂等建表(13张)
- import_init.py: accounting 加入 INIT_MODULES + 扩展支持 subject/account_config/accounting_config/currency/exchange_rate
- rp.json: accounting 权限(any: fetch_forex_rates, logined: /accounting/**)
This commit is contained in:
yumoqing 2026-08-21 18:57:27 +08:00
parent 9ead91d303
commit 6ce55f6482
4 changed files with 42 additions and 8 deletions

View File

@ -53,7 +53,7 @@ for mod in pipeline_core pipeline_ops pipeline_dist; do
done
# 5. Install business modules (clone external, local already in pkgs)
for mod in pipeline-sdlc showcase evaluate pipeline-service pipeline-task tenant app_audit product_management discount pricing unipay smssend; do
for mod in pipeline-sdlc showcase evaluate pipeline-service pipeline-task tenant app_audit product_management discount pricing unipay smssend accounting; do
cd "$cdir/pkgs"
if [ ! -d "$mod" ]; then
git clone https://git.opencomputing.cn/yumoqing/$mod || echo "SKIP: $mod"
@ -62,7 +62,7 @@ for mod in pipeline-sdlc showcase evaluate pipeline-service pipeline-task tenant
done
# 6. pip install all modules from pkgs/pipeline-service 是普通 install 非 editable部署必 pull+pip install 都做)
for mod in pipeline_core pipeline_ops pipeline_dist pipeline-sdlc showcase pipeline-service tenant app_audit product_management discount pricing unipay smssend; do
for mod in pipeline_core pipeline_ops pipeline_dist pipeline-sdlc showcase pipeline-service tenant app_audit product_management discount pricing unipay smssend accounting; do
if [ -d "pkgs/$mod" ]; then
"$cdir/py3/bin/pip" install "pkgs/$mod/" 2>&1 | tail -1
fi
@ -89,7 +89,7 @@ if [ -d "pkgs/pipeline_core/skills_library" ]; then
fi
# 7. Regenerate CRUD from json for all pipeline modules
for mod in appbase pipeline_core pipeline_ops pipeline_dist pipeline-sdlc rbac dapi; do
for mod in appbase pipeline_core pipeline_ops pipeline_dist pipeline-sdlc rbac dapi accounting; do
json_dir="pkgs/$mod/json"
models_dir="pkgs/$mod/models"
wwwroot_dir="pkgs/$mod/wwwroot"
@ -102,7 +102,7 @@ done
# 8. Link module wwwroot directories (symlinks from pkgs/)
for mod in pipeline-sdlc showcase tenant pipeline_core pipeline_ops pipeline_dist appbase app_audit product_management discount pricing unipay rbac dapi; do
for mod in pipeline-sdlc showcase tenant pipeline_core pipeline_ops pipeline_dist appbase app_audit product_management discount pricing unipay rbac dapi accounting; do
src="pkgs/$mod/wwwroot"
dst="wwwroot/$mod"
if [ -d "$src" ]; then
@ -200,5 +200,18 @@ else
echo " WARN: scripts/import_rp.py not found"
fi
# 11.5 汇率自动获取定时任务(每日 8:00 抓取中国银行外汇牌价)
# accounting 模块 fetch_forex_rates.dspyUSD/JPY/GBP → CNY幂等写入 exchange_rate
if [ -f "$cdir/pkgs/accounting/wwwroot/api/fetch_forex_rates.dspy" ]; then
forex_cron="0 8 * * * curl -s http://localhost:9090/accounting/api/fetch_forex_rates.dspy"
cc=$(crontab -l 2>/dev/null || true)
if ! echo "$cc" | grep -Fq "fetch_forex_rates"; then
(echo "$cc"; echo "$forex_cron") | crontab -
echo " cron: 汇率任务已添加(每日 8:00"
else
echo " cron: 汇率任务已存在,未重复添加"
fi
fi
chmod +x "$cdir/start.sh" "$cdir/stop.sh" 2>/dev/null || true
echo "=== Build complete ==="

View File

@ -17,7 +17,8 @@
"/pricing/menu.ui",
"/unipay/usermenu.ui",
"/univer-office",
"/univer-office/**"
"/univer-office/**",
"/accounting/api/fetch_forex_rates.dspy"
],
"logined": [
"/pipeline-sdlc", "/pipeline-sdlc/**",
@ -33,7 +34,8 @@
"/pipeline_dist", "/pipeline_dist/**",
"/pipeline_task", "/pipeline_task/**",
"/app_audit", "/app_audit/**",
"/office", "/office/**"
"/office", "/office/**",
"/accounting", "/accounting/**"
],
"owner.superuser": [
"/rbac", "/rbac/**",

View File

@ -23,7 +23,8 @@ TABLE_MODULES = ['product_management', 'discount', 'pricing', 'unipay', 'smssend
# 幂等建表模块(不 DROP用 IF NOT EXISTS避免清空运行时数据如 llm/pipelines/skill_proposals/tasks 等)
# appbase 也放这里svgicon/appcodes/appcodes_kv/params 是系统级配置表含种子数据幂等建params 另在下方手动 ensure 默认参数)
# dapi 放这里downapp/downapikey 是下位系统接入表,幂等建(不 DROP避免误删已注册的下位系统
IDEMPOTENT_MODULES = ['pipeline_core', 'pipeline-service', 'appbase', 'dapi']
# accounting 放这里subject/account_config/accounting_config 是记账配置account/ledger 是运行时数据,幂等建(不 DROP
IDEMPOTENT_MODULES = ['pipeline_core', 'pipeline-service', 'appbase', 'dapi', 'accounting']
# appbase 系统级配置表(幂等建表 + 默认参数,不 DROP 以免清空运行时数据)

View File

@ -29,6 +29,7 @@ INIT_MODULES = [
('pipeline-sdlc', 'pkgs/pipeline-sdlc/init/data.json'),
('app_audit', 'pkgs/app_audit/init/data.json'),
('rbac', 'pkgs/rbac/init/data.json'),
('accounting', 'pkgs/accounting/init/data.json'),
]
@ -117,7 +118,24 @@ async def main():
'name': r.get('name', ''),
})
total['roles'] += 1
print(f'import_init: appcodes {total["appcodes"]}, appcodes_kv {total["appcodes_kv"]}, organization {total["organization"]}, roles {total["roles"]}')
# 记账配置表accounting 模块subject/account_config/accounting_config/currency/exchange_rate
# 幂等按主键 id 检查,字段名与表结构一致
for tbl, recs_data in [
('subject', data.get('subject', [])),
('account_config', data.get('account_config', [])),
('accounting_config', data.get('accounting_config', [])),
('currency', data.get('currency', [])),
('exchange_rate', data.get('exchange_rate', [])),
]:
for rec in recs_data:
existing = await sor.R(tbl, {'id': rec.get('id')})
if not existing:
# 去掉 None 值字段DB 用 NULL 而非 None
clean = {k: v for k, v in rec.items() if v is not None}
await sor.C(tbl, clean)
total[tbl] = total.get(tbl, 0) + 1
summary = ' '.join(f'{k} {v}' for k, v in total.items())
print(f'import_init: {summary}')
if __name__ == '__main__':