ci/woodpecker/push/main Pipeline was successful
- 表 strategy_charter(一账套一行,entity_id 唯一):mission/vision/vision_year/vision_measurable/values_text/value_items(JSON) 全 NOT NULL
- 迁移脚本 backend/scripts/migrate_strategy_charter_20261021.py:--check/--apply/--down(回滚先 mysqldump,有数据需 --force),零 INSERT
- API:GET 无行 → filled=false 空态(禁示例数据);PUT 字段白名单 + 账套隔离三道 + vision_year 4位年份 + value_items [{name,meaning}] 结构校验
- 前端:P 组「战略章程」入口 + MyDialog 编辑(ceo/finance 可写,其余只读);战略地图页顶部只读章程条
- 用例 43 条 + auth-surface 58 条 = 101 passed;vite build rc=0
577 lines
30 KiB
TypeScript
577 lines
30 KiB
TypeScript
import axios from 'axios'
|
||
import { ElMessage } from 'element-plus'
|
||
|
||
const api = axios.create({
|
||
baseURL: '/api/cma',
|
||
timeout: 15000,
|
||
})
|
||
|
||
// 网络层错误提示节流标记(3 秒内只弹一次)
|
||
let lastNetErrToast = 0
|
||
|
||
api.interceptors.request.use((config) => {
|
||
const token = localStorage.getItem('cma_token')
|
||
if (token) config.headers.Authorization = `Bearer ${token}`
|
||
// 账套模式:entity_id 由 token 绑定,前端不再自动附加 X-Entity-Id / entity_id
|
||
return config
|
||
})
|
||
|
||
api.interceptors.response.use(
|
||
(response) => response.data,
|
||
(error) => {
|
||
if (error.response?.status === 401) {
|
||
localStorage.removeItem('cma_token')
|
||
localStorage.removeItem('cma_user')
|
||
window.location.href = '/login'
|
||
} else if (error.code === 'ECONNABORTED' || !error.response) {
|
||
// BUG-001 兜底(2026-09-03):网络层失败(超时/断连)节流提示,避免并行请求重复弹窗
|
||
const now = Date.now()
|
||
if (now - lastNetErrToast > 3000) {
|
||
lastNetErrToast = now
|
||
ElMessage.warning(error.code === 'ECONNABORTED' ? '请求超时,请稍后重试' : '网络异常,请检查连接后重试')
|
||
}
|
||
}
|
||
return Promise.reject(error)
|
||
}
|
||
)
|
||
|
||
export const authApi = {
|
||
login: (data: any) => api.post('/auth/login', data),
|
||
register: (data: any) => api.post('/auth/register', data),
|
||
loginEntities: (username: string) => api.get('/auth/login-entities', { params: { username } }),
|
||
}
|
||
|
||
export const kpiApi = {
|
||
list: (params?: any) => api.get('/kpis', { params }),
|
||
get: (id: number) => api.get(`/kpis/${id}`),
|
||
create: (data: any) => api.post('/kpis', data),
|
||
update: (id: number, data: any) => api.put(`/kpis/${id}`, data),
|
||
delete: (id: number) => api.delete(`/kpis/${id}`),
|
||
restore: (id: number) => api.put(`/kpis/${id}/restore`),
|
||
listCategories: () => api.get('/kpis/categories'),
|
||
associateMap: (id: number, data: any) => api.put(`/kpis/${id}/associate-map`, data),
|
||
// KPI-5: 五档评分
|
||
score: (params?: any) => api.get('/kpis/score', { params }),
|
||
// KPI-6: 三级分解树
|
||
hierarchy: (params?: any) => api.get('/kpis/hierarchy', { params }),
|
||
// KPI-8: 因果链追踪
|
||
causalityChain: (id: number) => api.get(`/kpis/${id}/causality-chain`),
|
||
// KPI实际值列表(归集标签页)
|
||
values: (id: number, params?: any) => api.get(`/kpis/${id}/values`, { params }),
|
||
}
|
||
|
||
export const mapApi = {
|
||
list: () => api.get('/maps'),
|
||
create: (data: any) => api.post('/maps', data),
|
||
update: (id: number, data: any) => api.put(`/maps/${id}`, data),
|
||
delete: (id: number) => api.delete(`/maps/${id}`),
|
||
batchDelete: (ids: number[]) => api.post('/maps/batch-delete', { ids }),
|
||
createWithTemplate: (data: any) => api.post('/maps/create-with-template', data),
|
||
// 战略地图活看板(只读,2026-10-11 finance-20261011-strategy-map-frontend-fullstack)
|
||
strategyBoard: (id: number, params?: any) => api.get(`/maps/${id}/strategy-board`, { params }),
|
||
// 战略地图版本管理(2026-09-08 project-20260908-map-versions-page)
|
||
versions: (mapId: number) => api.get(`/maps/${mapId}/versions`),
|
||
versionDetail: (mapId: number, vid: number) => api.get(`/maps/${mapId}/versions/${vid}`),
|
||
versionRollback: (mapId: number, vid: number) => api.post(`/maps/${mapId}/versions/${vid}/rollback`),
|
||
versionUpdateComment: (mapId: number, vid: number, comment: string) => api.put(`/maps/${mapId}/versions/${vid}`, { comment }),
|
||
versionSnapshot: (mapId: number, comment?: string) => api.post(`/maps/${mapId}/versions/snapshot`, comment ? { comment } : {}),
|
||
// 数据完备度(口径 CMA-CALIBER-MAP-COMPLETENESS-20261018 v1.0 · 2026-10-18)
|
||
completenessSummary: () => api.get('/maps/completeness/summary'),
|
||
completenessObjectives: (params?: any) => api.get('/maps/completeness/objectives', { params }),
|
||
}
|
||
|
||
// 复盘记录持久化(大PDCA Act闭环 2026-08-27)
|
||
export const reviewRecordApi = {
|
||
list: (mapId: number, params?: any) => api.get(`/maps/${mapId}/review-records`, { params }),
|
||
get: (mapId: number, id: number) => api.get(`/maps/${mapId}/review-records/${id}`),
|
||
create: (mapId: number, data: any) => api.post(`/maps/${mapId}/review-records`, data),
|
||
}
|
||
|
||
export const dashboardApi = {
|
||
summary: (role: string) => api.get('/dashboard/summary', { params: { role } }),
|
||
kpis: (params: any) => api.get('/dashboard/kpis', { params }),
|
||
myKpis: (params?: any) => api.get('/dashboard/my-kpis', { params }),
|
||
financeAnalysis: (params?: any) => api.get('/dashboard/finance-analysis', { params }),
|
||
predict: (params?: any) => api.get('/dashboard/predict', { params }),
|
||
}
|
||
|
||
export const templateApi = {
|
||
list: (params?: any) => api.get('/templates', { params }),
|
||
get: (id: number) => api.get(`/templates/${id}`),
|
||
instantiate: (id: number, data: any) => api.post(`/templates/${id}/instantiate`, data),
|
||
create: (data: any) => api.post('/templates', data),
|
||
update: (id: number, data: any) => api.put(`/templates/${id}`, data),
|
||
delete: (id: number) => api.delete(`/templates/${id}`),
|
||
}
|
||
|
||
export const okrTemplateApi = {
|
||
list: (params?: any) => api.get('/okr-templates', { params }),
|
||
get: (id: number) => api.get(`/okr-templates/${id}`),
|
||
create: (data: any) => api.post('/okr-templates', data),
|
||
incrementUse: (id: number) => api.post(`/okr-templates/${id}/use`),
|
||
applyTemplate: (id: number, data: any) => api.post(`/okr-templates/${id}/apply`, data),
|
||
}
|
||
|
||
export const okrApi = {
|
||
list: (params?: any) => api.get('/okr', { params }),
|
||
get: (id: number) => api.get(`/okr/${id}`),
|
||
create: (data: any) => api.post('/okr', data),
|
||
update: (id: number) => api.patch(`/okr/${id}`),
|
||
decomposition: (id: number) => api.get(`/okr/${id}/decomposition`),
|
||
saveMilestones: (okrId: number, krId: number, milestones: any[]) =>
|
||
api.put(`/okr/${okrId}/decomposition/milestones/${krId}`, { milestones }),
|
||
generateMilestones: (okrId: number, krId: number) =>
|
||
api.post(`/okr/${okrId}/decomposition/milestones/generate`, { kr_id: krId }),
|
||
// KR完整修复(2026-08-27): krs表CRUD
|
||
createKr: (objectiveId: number, data: any) => api.post(`/okr/${objectiveId}/krs`, data),
|
||
updateKr: (objectiveId: number, krId: number, data: any) =>
|
||
api.put(`/okr/${objectiveId}/krs/${krId}`, data),
|
||
deleteKr: (objectiveId: number, krId: number) =>
|
||
api.delete(`/okr/${objectiveId}/krs/${krId}`),
|
||
syncKrs: (objectiveId: number, krs: any[]) =>
|
||
api.put(`/okr/${objectiveId}/krs/sync`, { krs }),
|
||
}
|
||
|
||
// ── 本体三支柱追溯链 (科目↔KPI↔OKR) ──
|
||
export const ontologyApi = {
|
||
trace: (objectiveId: number) => api.get('/ontology/trace', { params: { objective_id: objectiveId } }),
|
||
objectives: (params?: any) => api.get('/ontology/objectives', { params }),
|
||
}
|
||
|
||
export const dataApi = {
|
||
importExcel: (file: File, qs?: string) => {
|
||
const form = new FormData()
|
||
form.append('file', file)
|
||
return api.post(`/data/import-excel${qs ? '?' + qs : ''}`, form)
|
||
},
|
||
importExcelSmart: (file: File) => {
|
||
const form = new FormData()
|
||
form.append('file', file)
|
||
return api.post('/data/import-excel-smart', form, { timeout: 60000 })
|
||
},
|
||
listSources: () => api.get('/data/sources'),
|
||
createSource: (data: any) => api.post('/data/sources', data),
|
||
updateSource: (id: number, data: any) => api.put(`/data/sources/${id}`, data),
|
||
deleteSource: (id: number) => api.delete(`/data/sources/${id}`),
|
||
channelStatus: () => api.get('/data/channel-status'),
|
||
}
|
||
|
||
export const alertApi = {
|
||
list: (params?: any) => api.get('/alerts', { params }),
|
||
resolve: (id: number, data: any) => api.post(`/alerts/${id}/resolve`, data),
|
||
riskMatrix: (params?: any) => api.get('/alerts/risk-matrix', { params }),
|
||
}
|
||
|
||
export const alertRulesApi = {
|
||
list: (params?: any) => api.get('/alert-rules', { params }),
|
||
getKpiRules: (kpiId: number) => api.get(`/alert-rules/kpi/${kpiId}`),
|
||
create: (data: any) => api.post('/alert-rules', data),
|
||
update: (id: number, data: any) => api.put(`/alert-rules/${id}`, data),
|
||
delete: (id: number) => api.delete(`/alert-rules/${id}`),
|
||
batchCreate: (data: any) => api.post('/alert-rules/batch', data),
|
||
generateDefaults: () => api.post('/alert-rules/generate-defaults'),
|
||
checkAll: () => api.post('/alert-rules/check-all'),
|
||
calculateDynamic: () => api.post('/alert-rules/calculate-dynamic'),
|
||
dynamicThresholds: (params?: any) => api.get('/alert-rules/dynamic-thresholds', { params }),
|
||
// AI事前预警
|
||
checkForecast: () => api.post('/alert-rules/check-forecast'),
|
||
checkForecastDeviation: () => api.post('/alert-rules/run-forecast-deviation'),
|
||
checkConcentration: () => api.post('/alert-rules/run-customer-concentration'),
|
||
generateSuggestions: () => api.post('/alert-rules/generate-suggestions'),
|
||
}
|
||
|
||
export const userApi = {
|
||
list: () => api.get('/users'),
|
||
create: (data: any) => api.post('/users', data),
|
||
update: (id: number, data: any) => api.put(`/users/${id}`, data),
|
||
delete: (id: number) => api.delete(`/users/${id}`),
|
||
}
|
||
|
||
export const orgApi = {
|
||
nodes: () => api.get('/org/nodes'),
|
||
tree: () => api.get('/org/tree'),
|
||
}
|
||
|
||
export const notificationApi = {
|
||
list: () => api.get('/notifications/channels'),
|
||
create: (data: any) => api.post('/notifications/channels', data),
|
||
update: (id: number, data: any) => api.put(`/notifications/channels/${id}`, data),
|
||
delete: (id: number) => api.delete(`/notifications/channels/${id}`),
|
||
test: (id: number) => api.post(`/notifications/channels/${id}/test`),
|
||
logs: (params?: any) => api.get('/notifications/logs', { params }),
|
||
}
|
||
|
||
export const actionPlanApi = {
|
||
list: (params?: any) => api.get('/action-plans', { params }),
|
||
create: (data: any) => api.post('/action-plans', data),
|
||
update: (id: number, data: any) => api.put(`/action-plans/${id}`, data),
|
||
delete: (id: number) => api.delete(`/action-plans/${id}`),
|
||
cosoChecklist: (params?: any) => api.get('/action-plans/coso-checklist', { params }),
|
||
cosoGenerateActions: (data?: any) => api.post('/action-plans/coso-generate-actions', data || {}),
|
||
stats: () => api.get('/action-plans/stats'),
|
||
}
|
||
|
||
export const budgetApi = {
|
||
list: (params?: any) => api.get('/budget/plans', { params }),
|
||
create: (data: any) => api.post('/budget/plans', data),
|
||
update: (id: number, data: any) => api.put(`/budget/plans/${id}`, data),
|
||
delete: (id: number) => api.delete(`/budget/plans/${id}`),
|
||
autoDecompose: (data: any) => api.post('/budget/auto-decompose', data),
|
||
deviationReport: (params?: any) => api.get('/budget/deviation-report', { params }),
|
||
methodComparison: (data: any) => api.post('/budget/method-comparison', data),
|
||
applyMethod: (data: any) => api.post('/budget/apply-method', data),
|
||
// 版本管理
|
||
versions: (params?: any) => api.get('/budget/versions', { params }),
|
||
versionSubmit: (data: any) => api.post('/budget/versions/submit', data),
|
||
versionApprove: (data: any) => api.post('/budget/versions/approve', data),
|
||
versionDiff: (data: any) => api.post('/budget/versions/diff', data),
|
||
// 持续规划
|
||
getConfig: () => api.get('/budget/config'),
|
||
setConfig: (data: any) => api.post('/budget/config', data),
|
||
rollForward: () => api.post('/budget/roll-forward'),
|
||
getComparison: (params?: any) => api.get('/budget/comparison', { params }),
|
||
getKpiComparison: (kpiId: number, params?: any) => api.get(`/budget/comparison/kpi/${kpiId}`, { params }),
|
||
deviationCheck: (data: any) => api.post('/budget/deviation-check', data),
|
||
listDeviationAlerts: (params?: any) => api.get('/budget/deviation-alerts', { params }),
|
||
updateDeviationAlert: (id: number, data: any) => api.put(`/budget/deviation-alerts/${id}`, data),
|
||
// P1-③ 告警归因
|
||
getAlertAttribution: (alertId: number) => api.get(`/budget/deviation-alerts/${alertId}/attribution`),
|
||
getAlertDirection: () => api.get('/budget/alert-direction'),
|
||
updateAlertDirection: (data: any) => api.put('/budget/alert-direction', data),
|
||
// P1-④ 实际值自动归集
|
||
valueSources: (params?: any) => api.get('/budget/value-sources', { params }),
|
||
createValueSource: (data: any) => api.post('/budget/value-sources', data),
|
||
updateValueSource: (id: number, data: any) => api.put(`/budget/value-sources/${id}`, data),
|
||
deleteValueSource: (id: number) => api.delete(`/budget/value-sources/${id}`),
|
||
testValueSource: (data: any) => api.post('/budget/value-sources/test', data),
|
||
runValueCollect: (data: any) => api.post('/budget/value-collect/run', data),
|
||
valueCollectLogs: (params?: any) => api.get('/budget/value-collect/logs', { params }),
|
||
valueSourceCoverage: () => api.get('/budget/value-sources/coverage'),
|
||
// P2-① 零基逐项论证
|
||
zeroBasedItems: (params?: any) => api.get('/budget/zero-based/items', { params }),
|
||
createZeroBasedItem: (data: any) => api.post('/budget/zero-based/items', data),
|
||
updateZeroBasedItem: (id: number, data: any) => api.put(`/budget/zero-based/items/${id}`, data),
|
||
deleteZeroBasedItem: (id: number) => api.delete(`/budget/zero-based/items/${id}`),
|
||
generateZeroBased: (data: any) => api.post('/budget/zero-based/generate', data),
|
||
// P2-② 派生规则
|
||
derivationRules: (params?: any) => api.get('/budget/derivation-rules', { params }),
|
||
createDerivationRule: (data: any) => api.post('/budget/derivation-rules', data),
|
||
updateDerivationRule: (id: number, data: any) => api.put(`/budget/derivation-rules/${id}`, data),
|
||
deleteDerivationRule: (id: number) => api.delete(`/budget/derivation-rules/${id}`),
|
||
// P2-⑥ 现金流分类规则 + 待分类队列
|
||
cashClassifyRules: () => api.get('/budget/cash-classify-rules'),
|
||
createCashClassifyRule: (data: any) => api.post('/budget/cash-classify-rules', data),
|
||
updateCashClassifyRule: (id: number, data: any) => api.put(`/budget/cash-classify-rules/${id}`, data),
|
||
deleteCashClassifyRule: (id: number) => api.delete(`/budget/cash-classify-rules/${id}`),
|
||
cashUnclassified: (params?: any) => api.get('/budget/cash-unclassified', { params }),
|
||
classifyCashUnclassified: (id: number, data: any) => api.post(`/budget/cash-unclassified/${id}/classify`, data),
|
||
ignoreCashUnclassified: (id: number) => api.post(`/budget/cash-unclassified/${id}/ignore`),
|
||
// 预算治理四环(budget-governance 2026-10-03):控制状态 / 下达 / 调整 / 考核
|
||
versionRelease: (data: any) => api.post('/budget/versions/release', data),
|
||
adjustments: (data: any) => api.post('/budget/adjustments', data),
|
||
assessment: (params?: any) => api.get('/budget/assessment', { params }),
|
||
controlStatus: (params?: any) => api.get('/budget/control/status', { params }),
|
||
}
|
||
|
||
export const costApi = {
|
||
dashboard: (params?: any) => api.get('/cost/dashboard', { params }),
|
||
overview: (params?: any) => api.get('/cost/overview', { params }),
|
||
variance: (params?: any) => api.get('/cost/variance', { params }),
|
||
breakdown: (params?: any) => api.get('/cost/breakdown', { params }),
|
||
comparison: (params?: any) => api.get('/cost/comparison', { params }),
|
||
listStandardCosts: (params?: any) => api.get('/cost/standard-costs', { params }),
|
||
createStandardCost: (data: any) => api.post('/cost/standard-costs', data),
|
||
updateStandardCost: (id: number, data: any) => api.put(`/cost/standard-costs/${id}`, data),
|
||
deleteStandardCost: (id: number) => api.delete(`/cost/standard-costs/${id}`),
|
||
listActualCosts: (params?: any) => api.get('/cost/actual-costs', { params }),
|
||
createActualCost: (data: any) => api.post('/cost/actual-costs', data),
|
||
listAbcActivities: () => api.get('/cost/abc/activities'),
|
||
createAbcActivity: (data: any) => api.post('/cost/abc/activities', data),
|
||
doAbcAllocate: (data: any) => api.post('/cost/abc/allocate', data),
|
||
listAbcAllocations: (params?: any) => api.get('/cost/abc/allocations', { params }),
|
||
}
|
||
|
||
export const predictApi = {
|
||
cvp: (data: any) => api.post('/predict/cvp', data),
|
||
cvpDetailed: (data: any) => api.post('/predict/cvp-detailed', data),
|
||
investment: (data: any) => api.post('/predict/investment', data),
|
||
sensitivity: (data: any) => api.post('/predict/sensitivity', data),
|
||
scenario: (data: any) => api.post('/predict/scenario', data),
|
||
relevantDecision: (data: any) => api.post('/predict/relevant-decision', data),
|
||
growthQuality: (data: any) => api.post('/predict/growth-quality', data),
|
||
// AI事前预警
|
||
cashForecast: (data: any) => api.post('/predict/cash-forecast', data),
|
||
cashForecastHistory: (params?: any) => api.get('/predict/cash-forecast/history', { params }),
|
||
forecastAccuracy: (params?: any) => api.get('/predict/accuracy', { params }),
|
||
scenarioSuggestions: (params?: any) => api.get('/predict/scenario-suggestions', { params }),
|
||
generateSuggestion: (data: any) => api.post('/predict/scenario-suggestion/generate', data),
|
||
// KPI趋势预测(预测性成本智能)
|
||
kpiForecast: (params?: any) => api.get('/predict/kpi-forecast', { params }),
|
||
kpiForecastFinance: (params?: any) => api.get('/predict/kpi-forecast/finance', { params }),
|
||
kpiForecastSensitivity: (params?: any) => api.get('/predict/kpi-forecast/sensitivity', { params }),
|
||
}
|
||
|
||
export const deviationPushApi = {
|
||
pushToMap: (data: any) => api.post('/deviation-push/push-to-map', data),
|
||
getMapNodes: (mapId: number) => api.get(`/deviation-push/map-nodes/${mapId}`),
|
||
}
|
||
|
||
export const driverBudgetApi = {
|
||
// 驱动因子模式切换
|
||
getMode: () => api.get('/budget/driver/mode'),
|
||
setMode: (data: any) => api.post('/budget/driver/mode', data),
|
||
// 行业包
|
||
getIndustries: () => api.get('/budget/driver/industries'),
|
||
getTemplates: (params?: any) => api.get('/budget/driver/templates', { params }),
|
||
// 驱动因子计算
|
||
calculate: (data: any) => api.post('/budget/driver/calculate', data),
|
||
// 敏感性分析
|
||
sensitivity: (data: any) => api.post('/budget/driver/sensitivity', data),
|
||
// 历史记录
|
||
getHistory: (params?: any) => api.get('/budget/driver/history', { params }),
|
||
}
|
||
|
||
export const budgetGenerateApi = {
|
||
getCandidates: () => api.get('/budget/kpi-budget-candidates'),
|
||
generateFromKpis: (data: any) => api.post('/budget/generate-from-kpis', data),
|
||
}
|
||
|
||
export const knowledgeArticleApi = {
|
||
list: (params?: any) => api.get('/knowledge-articles', { params }),
|
||
get: (id: number) => api.get(`/knowledge-articles/${id}`),
|
||
}
|
||
|
||
export const roleApi = {
|
||
list: () => api.get('/roles'),
|
||
create: (data: any) => api.post('/roles', data),
|
||
update: (id: number, data: any) => api.put(`/roles/${id}`, data),
|
||
delete: (id: number) => api.delete(`/roles/${id}`),
|
||
}
|
||
|
||
export const permissionApi = {
|
||
getMenuTree: () => api.get('/permissions/menu-tree'),
|
||
getModules: () => api.get('/permissions/modules'),
|
||
getConfig: () => api.get('/permissions/config'),
|
||
saveConfig: (data: any) => api.put('/permissions/config', data),
|
||
getUserRoles: () => api.get('/user-roles'),
|
||
setUserRoles: (data: any) => api.post('/user-roles', data),
|
||
}
|
||
|
||
// ── KPI目标对齐(/alignment/* 由路由级 require_auth 保护,统一走本实例)──
|
||
export const alignmentApi = {
|
||
getConfig: () => api.get('/alignment/config'),
|
||
saveConfig: (data: any) => api.post('/alignment/config', data),
|
||
getTree: (params?: any) => api.get('/alignment/tree', { params }),
|
||
}
|
||
|
||
export const kpiCausalityApi = {
|
||
list: (params?: any) => api.get('/kpi-causality', { params }),
|
||
get: (id: number) => api.get(`/kpi-causality/${id}`),
|
||
create: (data: any) => api.post('/kpi-causality', data),
|
||
update: (id: number, data: any) => api.put(`/kpi-causality/${id}`, data),
|
||
delete: (id: number) => api.delete(`/kpi-causality/${id}`),
|
||
getNetwork: (kpiId: number) => api.get(`/kpi-causality/kpi/${kpiId}/network`),
|
||
getFullNetwork: () => api.get('/kpi-causality/full-network'),
|
||
simulate: (data: any) => api.post('/kpi-causality/simulate', data),
|
||
getVerifyStatus: (params?: any) => api.get('/kpi-causality/verify-status', { params }),
|
||
verify: (id: number, data: any) => api.put(`/kpi-causality/${id}/verify`, data),
|
||
}
|
||
|
||
export const dataQualityApi = {
|
||
check: () => api.get('/data-quality/check'),
|
||
stats: () => api.get('/data-quality/stats'),
|
||
logs: (params?: any) => api.get('/data-quality/logs', { params }),
|
||
updateLog: (id: number, data: any) => api.put(`/data-quality/logs/${id}`, data),
|
||
deleteLog: (id: number) => api.delete(`/data-quality/logs/${id}`),
|
||
// DAMA数据治理规则检查(财务七规则)— /check-governance 已于 2026-09-14 下线
|
||
// (cma-residual-cross-entity-cleanup-20260914:无调用方 + entity_id 参数无会话鉴权跨租户)
|
||
// 财务七规则检查(唯一入口:评分+7规则+实体筛选,只读幂等;实体按会话账套)
|
||
governanceCheck: (params?: any) => api.get('/data-quality/governance-check', { params }),
|
||
}
|
||
|
||
export const biReportApi = {
|
||
listTemplates: () => api.get('/bi-reports/templates'),
|
||
list: () => api.get('/bi-reports'),
|
||
get: (id: number) => api.get(`/bi-reports/${id}`),
|
||
create: (data: any) => api.post('/bi-reports', data),
|
||
update: (id: number, data: any) => api.put(`/bi-reports/${id}`, data),
|
||
delete: (id: number) => api.delete(`/bi-reports/${id}`),
|
||
templates: () => api.get('/bi-reports/templates'),
|
||
seedTemplates: () => api.post('/bi-reports/templates/seed'),
|
||
analyze: (data: any) => api.post('/bi-reports/analyze', data),
|
||
exportReport: (data: any) => api.post('/bi-reports/export', data),
|
||
}
|
||
|
||
export const entityApi = {
|
||
list: () => api.get('/entities'),
|
||
create: (data: any) => api.post('/entities', data),
|
||
update: (id: number, data: any) => api.put(`/entities/${id}`, data),
|
||
}
|
||
|
||
export const ethicsQuizApi = {
|
||
getQuestions: () => api.get('/knowledge/ethics-quiz'),
|
||
}
|
||
|
||
export const botKpiApi = {
|
||
list: (params?: any) => api.get('/bot-kpis', { params }),
|
||
updateValue: (id: number, data: any) => api.post(`/bot-kpis/${id}/value`, data),
|
||
}
|
||
|
||
export const analysisApi = {
|
||
getResults: (params?: any) => api.get('/analysis/result', { params }),
|
||
createResult: (params: any) => api.post('/analysis/result', null, { params }),
|
||
deleteResult: (id: number) => api.delete(`/analysis/result/${id}`),
|
||
autoCalculate: (params?: any) => api.post('/analysis/auto-calculate', null, { params }),
|
||
}
|
||
|
||
export const expenseApi = {
|
||
// 规则配置
|
||
listRules: (params?: any) => api.get('/expenses/rules', { params }),
|
||
createRule: (data: any) => api.post('/expenses/rules', data),
|
||
updateRule: (id: number, data: any) => api.put(`/expenses/rules/${id}`, data),
|
||
deleteRule: (id: number) => api.delete(`/expenses/rules/${id}`),
|
||
seedRules: () => api.post('/expenses/rules/seed'),
|
||
// 报销单
|
||
listReimbursements: (params?: any) => api.get('/expenses/reimbursements', { params }),
|
||
getReimbursement: (id: number) => api.get(`/expenses/reimbursements/${id}`),
|
||
submitReimbursement: (data: any) => api.post('/expenses/reimbursements', data),
|
||
approveReimbursement: (id: number, comment?: string) => api.post(`/expenses/reimbursements/${id}/approve`, { comment }),
|
||
rejectReimbursement: (id: number, comment: string) => api.post(`/expenses/reimbursements/${id}/reject`, { comment }),
|
||
returnReimbursement: (id: number, comment?: string) => api.post(`/expenses/reimbursements/${id}/return`, { comment }),
|
||
resubmitReimbursement: (id: number, data?: any) => api.post(`/expenses/reimbursements/${id}/resubmit`, data),
|
||
// 看板统计
|
||
stats: (params?: any) => api.get('/expenses/stats', { params }),
|
||
}
|
||
|
||
// ── 资金管理智能体:资金缺口预测 + 收付款计划 + 预警 ──
|
||
export const cashApi = {
|
||
// 资金缺口预测
|
||
gapForecast: (params?: any) => api.get('/cash/gap-forecast', { params }),
|
||
// 当前现金余额(预测基线)
|
||
getBalance: (params?: any) => api.get('/cash/balance', { params }),
|
||
setBalance: (data: any) => api.post('/cash/balance', data),
|
||
// 收付款计划 CRUD
|
||
listPlans: (params?: any) => api.get('/cash/plans', { params }),
|
||
createPlan: (data: any) => api.post('/cash/plans', data),
|
||
updatePlan: (id: number, data: any) => api.put(`/cash/plans/${id}`, data),
|
||
deletePlan: (id: number) => api.delete(`/cash/plans/${id}`),
|
||
completePlan: (id: number) => api.post(`/cash/plans/${id}/complete`),
|
||
// 应收款催收
|
||
receivables: (params?: any) => api.get('/cash/receivables', { params }),
|
||
registerPayment: (id: number, data: any) => api.post(`/cash/receivables/${id}/payment`, data),
|
||
importBohaiAR: () => api.post('/cash/import/bohai-ar', {}),
|
||
// 网银流水导入(P1方案② 2026-08-28)
|
||
importVouchers: (file: File) => {
|
||
const form = new FormData()
|
||
form.append('file', file)
|
||
return api.post('/cash/import/vouchers', form, { timeout: 60000 })
|
||
},
|
||
getVoucherTemplate: () => api.get('/cash/import/template', { responseType: 'blob' }),
|
||
// 到期提醒
|
||
upcoming: (params?: any) => api.get('/cash/upcoming', { params }),
|
||
// 页面看板(日历+预测+提醒)
|
||
dashboard: (params?: any) => api.get('/cash/dashboard', { params }),
|
||
// 资金预警
|
||
checkAlerts: (params?: any) => api.post('/cash/check-alerts', null, { params }),
|
||
alertStatus: (params?: any) => api.get('/cash/alerts/status', { params }),
|
||
}
|
||
|
||
// ── 税务合规智能体:税负监控 + 发票校验 + 社保比对 ──
|
||
export const taxApi = {
|
||
// ① 税负监控
|
||
listTaxRecords: (params?: any) => api.get('/tax/records', { params }),
|
||
createTaxRecord: (data: any) => api.post('/tax/records', data),
|
||
updateTaxRecord: (id: number, data: any) => api.put(`/tax/records/${id}`, data),
|
||
deleteTaxRecord: (id: number) => api.delete(`/tax/records/${id}`),
|
||
burdenAnalysis: (params?: any) => api.get('/tax/burden', { params }),
|
||
runTaxCheck: (params?: any) => api.post('/tax/check', null, { params }),
|
||
// ② 发票校验
|
||
listInvoices: (params?: any) => api.get('/tax/invoices', { params }),
|
||
createInvoice: (data: any) => api.post('/tax/invoices', data),
|
||
updateInvoice: (id: number, data: any) => api.put(`/tax/invoices/${id}`, data),
|
||
deleteInvoice: (id: number) => api.delete(`/tax/invoices/${id}`),
|
||
batchCheckInvoices: (params?: any) => api.post('/tax/invoices/check', null, { params }),
|
||
abnormalInvoices: (params?: any) => api.get('/tax/invoices/abnormal', { params }),
|
||
// ③ 社保比对
|
||
listSsRecords: (params?: any) => api.get('/tax/ss', { params }),
|
||
createSsRecord: (data: any) => api.post('/tax/ss', data),
|
||
updateSsRecord: (id: number, data: any) => api.put(`/tax/ss/${id}`, data),
|
||
deleteSsRecord: (id: number) => api.delete(`/tax/ss/${id}`),
|
||
batchCheckSs: (params?: any) => api.post('/tax/ss/check', null, { params }),
|
||
abnormalSs: (params?: any) => api.get('/tax/ss/abnormal', { params }),
|
||
// 看板聚合 + 演示数据
|
||
dashboard: (params?: any) => api.get('/tax/dashboard', { params }),
|
||
seedDemo: (params?: any) => api.post('/tax/demo-data', null, { params }),
|
||
}
|
||
|
||
// ── AI决策建议(路线图R1 2026-08-30):建议→一键应用到KPI/预算/行动方案 ──
|
||
export const aiSuggestionApi = {
|
||
list: (params?: any) => api.get('/ai/suggestions', { params }),
|
||
get: (id: number) => api.get(`/ai/suggestions/${id}`),
|
||
create: (data: any) => api.post('/ai/suggestions', data),
|
||
apply: (id: number, data: any) => api.post(`/ai/suggestions/${id}/apply`, data),
|
||
dismiss: (id: number) => api.post(`/ai/suggestions/${id}/dismiss`),
|
||
preview: (id: number) => api.get(`/ai/suggestions/${id}/preview`),
|
||
}
|
||
|
||
// ── 资金管理(账户池/头寸/支付内控 2026-09-15)──
|
||
export const treasuryApi = {
|
||
// 账户池
|
||
listAccounts: (params?: any) => api.get('/treasury/accounts', { params }),
|
||
createAccount: (data: any) => api.post('/treasury/accounts', data),
|
||
updateAccount: (id: number, data: any) => api.put(`/treasury/accounts/${id}`, data),
|
||
deleteAccount: (id: number) => api.delete(`/treasury/accounts/${id}`),
|
||
importAccounts: (rows: any[]) => api.post('/treasury/accounts/import', rows),
|
||
// 头寸
|
||
listBalances: (params?: any) => api.get('/treasury/balances', { params }),
|
||
upsertBalance: (data: any) => api.post('/treasury/balances', data),
|
||
importBalances: (rows: any[]) => api.post('/treasury/balances/import', rows),
|
||
positionsSummary: (params?: any) => api.get('/treasury/positions/summary', { params }),
|
||
dashboard: () => api.get('/treasury/dashboard'),
|
||
// 规则库 / 授权矩阵
|
||
listRules: (params?: any) => api.get('/treasury/control-rules', { params }),
|
||
updateRule: (id: number, data: any) => api.put(`/treasury/control-rules/${id}`, data),
|
||
testRules: (data: any) => api.post('/treasury/control-rules/test', data),
|
||
listLimits: (params?: any) => api.get('/treasury/limits', { params }),
|
||
updateLimit: (id: number, data: any) => api.put(`/treasury/limits/${id}`, data),
|
||
// 支付单
|
||
listPayments: (params?: any) => api.get('/treasury/payments', { params }),
|
||
createPayment: (data: any) => api.post('/treasury/payments', data),
|
||
updatePayment: (id: number, data: any) => api.put(`/treasury/payments/${id}`, data),
|
||
precheckPayment: (id: number) => api.post(`/treasury/payments/${id}/precheck`),
|
||
approvePayment: (id: number, data: any) => api.post(`/treasury/payments/${id}/approve`, data),
|
||
payPayment: (id: number) => api.post(`/treasury/payments/${id}/pay`),
|
||
waivePayment: (id: number, data: any) => api.post(`/treasury/payments/${id}/waive`, data),
|
||
// 规则命中留痕
|
||
listHits: (params?: any) => api.get('/treasury/control-hits', { params }),
|
||
}
|
||
|
||
// ── 应收账龄看板(T2 2026-10-20:逐户·六档·三口径禁合计,缺期不补 0)──
|
||
export const arAgingApi = {
|
||
meta: (params?: any) => api.get('/ar-aging/meta', { params }),
|
||
trend: (params?: any) => api.get('/ar-aging/trend', { params }),
|
||
overview: (params?: any) => api.get('/ar-aging/overview', { params }),
|
||
customers: (params?: any) => api.get('/ar-aging/customers', { params }),
|
||
exportUrl: (params: { period?: string; caliber?: string; overdue_only?: boolean }) => {
|
||
const q = new URLSearchParams()
|
||
if (params.period) q.set('period', params.period)
|
||
if (params.caliber) q.set('caliber', params.caliber)
|
||
if (params.overdue_only) q.set('overdue_only', 'true')
|
||
return `/api/cma/ar-aging/customers/export?${q.toString()}`
|
||
},
|
||
}
|
||
|
||
// ── 战略基座:战略章程(P0 2026-10-21)──
|
||
export const charterApi = {
|
||
get: () => api.get('/charter'),
|
||
save: (payload: {
|
||
mission: string
|
||
vision: string
|
||
vision_year: string
|
||
vision_measurable: string
|
||
values_text: string
|
||
value_items: Array<{ name: string; meaning: string }>
|
||
}) => api.put('/charter', payload),
|
||
}
|
||
|
||
export default api |