-
-
- 当月充值 -
- {formatMoneyMinor(summary.month_recharge_usd_minor)} -
- 月目标 -
- {formatMoneyMinor(summary.month_target_usd_minor)} -
- 缺口 -
- {heroGapText} -
| App | 负责区域 | - 区间充值 + + 区间充值 + | - 当月充值 - | -- App 月目标 - | -- 达成率 - | -- 需日均 + + 当月充值 + | {rows.map((row, index) => { const item = row.item; - const gap = gapMinorOf(item.month_target_usd_minor, item.month_recharge_usd_minor); return (|||
|---|---|---|---|---|---|---|---|---|---|
|
|
-
-
- {operatorLabelOf(item)}
- {item.data_error ? (
-
- 数据异常
-
- ) : null}
-
- {[item.operator_account, item.team || "未分组"].filter(Boolean).join(" · ")}
-
+ |
- - - {item.app_name || item.app_code} - - | -
- {item.whole_app_scope ? "全部区域" : item.region_names || `${formatCount(item.region_count)} 个区域`}
+ |
+ {item.whole_app_scope ? "全部区域" : item.region_names || `${formatCount(item.region_count)} 个区域`} | {formatMoneyMinor(item.range_recharge_usd_minor)} | {formatMoneyMinor(item.month_recharge_usd_minor)} | -{formatMoneyMinor(item.month_target_usd_minor)} | -
- |
- {dailyNeedText(gap, remainingDays)} |
| App | 区域 | - 区间充值 + + 区间充值 + | - 当月充值 - | -- 月目标 - | -- 达成率 - | -- 需日均 + + 当月充值 + | {rows.map((row, index) => { const item = row.item; - const gap = gapMinorOf(item.month_target_usd_minor, item.month_recharge_usd_minor); return (||
|---|---|---|---|---|---|---|---|---|
|
|
-
-
- {operatorLabelOf(item)}
- {item.data_error ? (
-
- 数据异常
-
- ) : null}
-
- {[item.operator_account, item.team || "未分组"].filter(Boolean).join(" · ")}
-
+ |
-
-
- {item.app_name || item.app_code}
-
+ |
{regionLabelOf(item)} | {formatMoneyMinor(item.range_recharge_usd_minor)} | {formatMoneyMinor(item.month_recharge_usd_minor)} | -{formatMoneyMinor(item.month_target_usd_minor)} | -
- |
- {dailyNeedText(gap, remainingDays)} | 名次 | 部门 | - 人数 + + 人数 + | - 区间充值 + + 区间充值 + | - 当月充值 - | -- 月目标 - | -- 达成率 + + 当月充值 + | @@ -574,10 +289,6 @@ function TeamTable({ rows }) {{formatCount(row.memberCount)} | {formatMoneyMinor(row.rangeMinor)} | {formatMoneyMinor(row.monthMinor)} | -{formatMoneyMinor(row.targetMinor)} | -
- |
))}
@@ -585,299 +296,27 @@ function TeamTable({ rows }) {
);
}
-function draftInvalid(draft) {
- return usdInputToMinor(draft.monthText) === null || usdInputToMinor(draft.dailyText) === null;
-}
-
-function TargetInputCell({ draft, label, onChange }) {
+function OperatorCell({ item }) {
return (
-
- );
-}
-
-// 配置目标抽屉:三级目标——
-// ① App 总目标(不分运营的全员共同目标) ② 运营×App 总目标(该运营在此 App 的总盘子)
-// ③ 运营×App×区域 明细目标。月/日目标同时填 0 表示清除该条。
-function KpiTargetDrawer({ appCodes, kpi, onClose, onSaved }) {
- const [appDrafts, setAppDrafts] = useState(() =>
- (kpi.app_rows || []).map((row) => ({
- appCode: row.app_code,
- appName: row.app_name || row.app_code,
- dailyText: usdInputText(row.daily_target_usd_minor),
- monthText: usdInputText(row.month_target_usd_minor)
- }))
- );
- // 整 App 范围(region 0)的运营在明细区已有"全部区域"行(同一存储键),此处排除避免同键两处编辑。
- const [groupDrafts, setGroupDrafts] = useState(() =>
- (kpi.operator_app_rows || [])
- .filter((row) => !row.whole_app_scope)
- .map((row) => ({
- appCode: row.app_code,
- appName: row.app_name || row.app_code,
- dailyText: usdInputText(row.daily_target_usd_minor),
- monthText: usdInputText(row.month_target_usd_minor),
- operatorAccount: row.operator_account || "",
- operatorLabel: row.operator_name || row.operator_account || `#${row.operator_user_id}`,
- regionNames: row.region_names || "",
- userId: row.operator_user_id
- }))
- );
- const [regionDrafts, setRegionDrafts] = useState(() =>
- (kpi.items || []).map((item) => ({
- appCode: item.app_code,
- appName: item.app_name || item.app_code,
- dailyText: usdInputText(item.daily_target_usd_minor),
- monthText: usdInputText(item.month_target_usd_minor),
- operatorAccount: item.operator_account || "",
- operatorLabel: operatorLabelOf(item),
- regionId: Number(item.region_id ?? 0),
- regionName: regionLabelOf(item),
- userId: item.operator_user_id
- }))
- );
- const [isSaving, setIsSaving] = useState(false);
- const [saveError, setSaveError] = useState("");
-
- const hasInvalid = [...appDrafts, ...groupDrafts, ...regionDrafts].some(draftInvalid);
- const hasRows = appDrafts.length > 0 || groupDrafts.length > 0 || regionDrafts.length > 0;
-
- const updateAt = (setDrafts) => (index, key, value) => {
- setDrafts((current) => current.map((draft, draftIndex) => (draftIndex === index ? { ...draft, [key]: value } : draft)));
- };
- const updateAppDraft = updateAt(setAppDrafts);
- const updateGroupDraft = updateAt(setGroupDrafts);
- const updateRegionDraft = updateAt(setRegionDrafts);
-
- const handleSave = async () => {
- const items = [
- ...groupDrafts.map((draft) => ({
- appCode: draft.appCode,
- dailyTargetUsdMinor: usdInputToMinor(draft.dailyText),
- periodMonth: kpi.period_month,
- regionId: 0,
- targetUsdMinor: usdInputToMinor(draft.monthText),
- userId: draft.userId
- })),
- ...regionDrafts.map((draft) => ({
- appCode: draft.appCode,
- dailyTargetUsdMinor: usdInputToMinor(draft.dailyText),
- periodMonth: kpi.period_month,
- regionId: draft.regionId,
- targetUsdMinor: usdInputToMinor(draft.monthText),
- userId: draft.userId
- }))
- ];
- const appItems = appDrafts.map((draft) => ({
- appCode: draft.appCode,
- dailyTargetUsdMinor: usdInputToMinor(draft.dailyText),
- periodMonth: kpi.period_month,
- targetUsdMinor: usdInputToMinor(draft.monthText)
- }));
- setIsSaving(true);
- setSaveError("");
- try {
- await replaceSocialBiKpiTargets({ appItems, items });
- onSaved();
- } catch (error) {
- setSaveError(error?.message || "保存失败,请稍后重试");
- setIsSaving(false);
- }
- };
-
- return (
-