Merge branch 'master' of https://gitee.com/v_cms/zyt
This commit is contained in:
@@ -22,15 +22,15 @@ use think\facade\Db;
|
||||
* · **二中心及其组织下级在选定渠道下计 0**(与进线一致)
|
||||
* - 复诊统计 = 仅**名称含「二中心」的部门及其组织架构下级**:区间内业务单按患者 create_time 排序,第 1 笔不计,第 2 笔起分列「复诊2」「复诊3」…;口径同业绩单条件;按**订单创建人**所在部门在组织树内 rollup(含下级),与排行榜复诊一致
|
||||
* - 已完成挂号 = status=3 挂号条数(appointment_date),列「已完成挂号」;部门归属:有效医助→接诊医生→展示行映射。
|
||||
* - 接诊诊单 = 列名对应**业务订单条数**(非取消、create_time 区间),按**订单创建人**人事部门落在该行子树即计入;多行命中时取**最深的展示部门行**。与处方列表按 assistant_dept_id 筛选不同(列表保留旧口径:诊单医助 ∪ 创建人)。
|
||||
* - {渠道}成交单 = 选定渠道时与 {渠道}业绩同源:区间内 **非取消业务订单条数**(仅剔除 fulfillment_status=4;NULL 与其它状态计入,按 create_time 归日);dict(channels) 与 tag 口径均按订单计(按订单创建人归属),非挂号条数。
|
||||
* - 合计业绩 = 区间内业务订单 amount 求和(排除已取消(4) 与软删),**部门列**与「接诊诊单」一致:**订单创建人**人事部门落在该展示行子树则计入,多行命中取最深展示行;与排行榜诊金同口径。
|
||||
* - 接诊诊单 = 列名对应**业务订单条数**(剔除履约 4/9/10、create_time 区间),按**订单创建人**人事部门落在该行子树即计入;多行命中时取**最深的展示部门行**。与处方列表按 assistant_dept_id 筛选不同(列表保留旧口径:诊单医助 ∪ 创建人)。
|
||||
* - {渠道}成交单 = 选定渠道时与 {渠道}业绩同源:区间内 **计入业绩的业务订单条数**(剔除 fulfillment_status ∈ {4,9,10};NULL 与其它状态计入,按 create_time 归日);dict(channels) 与 tag 口径均按订单计(按订单创建人归属),非挂号条数。
|
||||
* - 合计业绩 = 区间内业务订单 amount 求和(排除已取消/拒收/退款(4,9,10) 与软删),**部门列**与「接诊诊单」一致:**订单创建人**人事部门落在该展示行子树则计入,多行命中取最深展示行;与排行榜诊金同口径。
|
||||
* 无法归入任一展示部门的金额单列「未归属中心」行;**底栏「合计业绩」「接诊诊单」= 当前表内各行业绩列相加**(含未归属行),与弹窗摊分口径一致。
|
||||
* · 时间窗与 stats_order_amount_performance 一致;列表若另有患者筛选或账号数据域收窄,金额可能仍不同
|
||||
* · 选定渠道时「{渠道}业绩」列仍按比例展示;合计列全量与渠道列含未归属补差;**二中心及其组织下级展示部门不参与该渠道进线/业绩/成交单/ROI 分子**(与同模块 DeptLogic::getErCenterSubtreeDeptIdSet 一致)
|
||||
* - {渠道}业绩 = 与「处方订单列表」业绩同口径(≠4):按 **o.create_time** 落入区间,按**订单创建人**归部门;
|
||||
* - {渠道}业绩 = 与「处方订单列表」业绩同口径(剔除 4/9/10):按 **o.create_time** 落入区间,按**订单创建人**归部门;
|
||||
* 渠道判定仅用 EXISTS:"患者有任一已完成挂号 (status=3) 且 channels 命中字典",**不限挂号时点**;无字典映射时回退 tag/creator 口径
|
||||
* - 成交单数 = 区间内非取消业务订单 **条数**;按**订单创建人**映射到「中心」;无法归属计入「未归属中心」;合计=全表 COUNT。
|
||||
* - 成交单数 = 区间内计入业绩的业务订单 **条数**(剔除 4/9/10);按**订单创建人**映射到「中心」;无法归属计入「未归属中心」;合计=全表 COUNT。
|
||||
* - 投放成本 = zyt_account_cost 在日期区间内 **amount** 合计(选定渠道时 `media_channel_code = channel_code` 过滤)。
|
||||
* · **各部门行投放成本** = 总投放成本 × (该部门进线 ÷ 各展示部门进线合计)。相当于先算 **单进线成本** = 总成本 ÷ 总进线,再乘部门进线。
|
||||
* · **二中心及其组织下级**不参与均摊投放成本(进线分摊分母对其计 0,与选定渠道下进线清零规则独立);其余部门按进线占比分摊。合计行成本 = 账务汇总总额。
|
||||
@@ -53,6 +53,9 @@ use think\facade\Db;
|
||||
*/
|
||||
class YejiStatsLogic
|
||||
{
|
||||
/** 不计入业绩的履约状态:已取消(4)、拒收(9)、退款(10);NULL 与其它值仍计业绩 */
|
||||
public const PRESCRIPTION_ORDER_FULFILLMENT_EXCLUDED_FROM_PERFORMANCE = [4, 9, 10];
|
||||
|
||||
/**
|
||||
* overview / assistantLeaderboards 共用的筛选与时间上下文。
|
||||
*
|
||||
@@ -557,7 +560,7 @@ class YejiStatsLogic
|
||||
. ($dataScopeRestricted
|
||||
? ' 当前账号受数据范围限制时,底栏合计业绩与列表同域。'
|
||||
: '');
|
||||
$baseNoteNoChannel = '业绩口径:除履约已取消(4)外全部计入。部门行「合计业绩」「接诊诊单」「复诊」均按**订单创建人人事部门 ∈ 该展示行子树**归属(多行命中取最深展示行),与医助排行榜诊金一致;与处方订单列表 assistant_dept_id 默认筛选(诊单医助 ∪ 创建人)不同——侧栏点击会自动收窄为创建人口径。多表「本月」区间为当月1日至服务器当日。**投放成本**按进线占比分摊,**二中心子树展示部门进线在分摊中计 0**(与部门 ErCenter 子树一致)。';
|
||||
$baseNoteNoChannel = '业绩口径:剔除履约已取消(4)、拒收(9)、退款(10),其余(含 NULL)计入。部门行「合计业绩」「接诊诊单」「复诊」均按**订单创建人人事部门 ∈ 该展示行子树**归属(多行命中取最深展示行),与医助排行榜诊金一致;与处方订单列表 assistant_dept_id 默认筛选(诊单医助 ∪ 创建人)不同——侧栏点击会自动收窄为创建人口径。多表「本月」区间为当月1日至服务器当日。**投放成本**按进线占比分摊,**二中心子树展示部门进线在分摊中计 0**(与部门 ErCenter 子树一致)。';
|
||||
|
||||
return [
|
||||
'start_date' => $startDate,
|
||||
@@ -567,9 +570,9 @@ class YejiStatsLogic
|
||||
'channel_name' => $channelInfo ? (string) $channelInfo['channel_name'] : '',
|
||||
'channel_group' => $channelInfo ? (string) $channelInfo['source_group_name'] : '',
|
||||
'channel_filter_note' => $channelCode !== ''
|
||||
? ('{渠道}业绩:按订单 create_time 归日、仅剔除履约已取消(4)(NULL 与其它状态均计入);渠道判定用"该患者是否有挂号 channels 命中 dict + status=3"(不限挂号时点)。部门归属按**订单创建人**人事部门 ∈ 子树。'
|
||||
. ' {渠道}成交单数:与{渠道}业绩同源,仅剔除已取消(4)的订单条数(非挂号条数),按订单创建人归部门。'
|
||||
. ' 「已完成挂号」列同 admin 挂号已完成列表;「接诊诊单」列为业务订单条数(非取消),同样按订单创建人归部门。**二中心及其组织下级**(与部门模块 ErCenter 子树一致)**不计入**该渠道进线、业绩与成交单。**投放成本**按各部门进线条数占展示部门进线合计的比例分摊,**二中心子树进线在分摊中计 0**(未选渠道时仍显示进线数,仅不参与均摊)。ROI = 渠道业绩(不含二中心子树)÷ 总投放成本。进线按所选标签客户精确过滤。'
|
||||
? ('{渠道}业绩:按订单 create_time 归日、剔除履约 4/9/10(NULL 与其它状态均计入);渠道判定用"该患者是否有挂号 channels 命中 dict + status=3"(不限挂号时点)。部门归属按**订单创建人**人事部门 ∈ 子树。'
|
||||
. ' {渠道}成交单数:与{渠道}业绩同源,剔除 4/9/10 的订单条数(非挂号条数),按订单创建人归部门。'
|
||||
. ' 「已完成挂号」列同 admin 挂号已完成列表;「接诊诊单」列为业务订单条数(同业绩剔除口径),同样按订单创建人归部门。**二中心及其组织下级**(与部门模块 ErCenter 子树一致)**不计入**该渠道进线、业绩与成交单。**投放成本**按各部门进线条数占展示部门进线合计的比例分摊,**二中心子树进线在分摊中计 0**(未选渠道时仍显示进线数,仅不参与均摊)。ROI = 渠道业绩(不含二中心子树)÷ 总投放成本。进线按所选标签客户精确过滤。'
|
||||
. ($tagFallback
|
||||
? ' ⚠ 当前业务尚未回填 tcm_diagnosis.external_userid 与 user_auth.unionid,已自动退化为「该标签客户的跟进医助 → 区间内接诊/业绩」口径,仅用于趋势观察。'
|
||||
: '')
|
||||
@@ -1799,7 +1802,7 @@ class YejiStatsLogic
|
||||
/**
|
||||
* 接诊诊单聚合:返回两组按部门归属的接诊计数。
|
||||
* - all: 区间内 status=3 挂号条数按部门归属(与列表计数一致),不含「仅 role_id=2」等额外限制。
|
||||
* - scoped: 选定渠道时「{渠道}成交单」= **非取消业务订单条数**(与 {渠道}业绩同源):dict 下 EXISTS 与侧栏一致(channels ∪ channel_source);有展示行时按列表部门摊行;否则走归因折叠。
|
||||
* - scoped: 选定渠道时「{渠道}成交单」= **计入业绩的业务订单条数**(与 {渠道}业绩同源,剔除 4/9/10):dict 下 EXISTS 与侧栏一致(channels ∪ channel_source);有展示行时按列表部门摊行;否则走归因折叠。
|
||||
* 未选渠道时 scoped == all(不再额外查一次)。
|
||||
*
|
||||
* @param int[] $appointmentChannelValues dict_data value 整型列表(通常 1=自媒体1)
|
||||
@@ -2996,7 +2999,7 @@ class YejiStatsLogic
|
||||
}
|
||||
|
||||
/**
|
||||
* 与 sumPerformanceByAdmin 对应:按订单创建人统计成交单数(非取消业务订单条数),全量/渠道分支一致。
|
||||
* 与 sumPerformanceByAdmin 对应:按订单创建人统计成交单数(剔除履约 4/9/10),全量/渠道分支一致。
|
||||
*
|
||||
* @param int[] $appointmentChannelValues
|
||||
*
|
||||
@@ -3296,18 +3299,19 @@ class YejiStatsLogic
|
||||
}
|
||||
|
||||
/**
|
||||
* 业绩/成交单统计:仅排除履约已取消 fulfillment_status = 4,其余(含 NULL 与任意其它状态)全部计入。
|
||||
* 与看板「合计业绩」、处方列表业绩 extend 口径一致;勿用 `<> 4`,以免误排除 NULL。
|
||||
* 业绩/成交单统计:排除履约「已取消/拒收/退款」(fulfillment_status 4、9、10),NULL 与其它状态计入。
|
||||
* 与看板「合计业绩」、处方列表业绩 extend 口径一致。
|
||||
*
|
||||
* @param \think\db\BaseQuery|\think\Model $query Db::name / Model::where 等查询实例
|
||||
* @param string $tableAlias 主表别名(如 Db 侧 `alias('o')` 传 `o`);无别名时传空字符串
|
||||
*/
|
||||
public static function applyPrescriptionOrderNotCancelledForPerformanceQuery($query, string $tableAlias = ''): void
|
||||
{
|
||||
$inList = implode(',', array_map(static fn (int $v): string => (string) $v, self::PRESCRIPTION_ORDER_FULFILLMENT_EXCLUDED_FROM_PERFORMANCE));
|
||||
if ($tableAlias !== '') {
|
||||
$query->whereRaw("NOT ({$tableAlias}.fulfillment_status <=> ?)", [4]);
|
||||
$query->whereRaw("({$tableAlias}.fulfillment_status IS NULL OR {$tableAlias}.fulfillment_status NOT IN ({$inList}))");
|
||||
} else {
|
||||
$query->whereRaw('NOT (fulfillment_status <=> ?)', [4]);
|
||||
$query->whereRaw("(fulfillment_status IS NULL OR fulfillment_status NOT IN ({$inList}))");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3609,7 +3613,7 @@ class YejiStatsLogic
|
||||
/**
|
||||
* 业绩聚合:返回两组按部门归属的业绩金额。
|
||||
* 口径与 /tcm.prescriptionOrder/lists 的 stats_*_performance 完全一致:
|
||||
* 业绩 = SUM(amount) WHERE NOT (fulfillment_status <=> 4) AND delete_time IS NULL
|
||||
* 业绩 = SUM(amount) WHERE fulfillment_status 为 NULL 或 NOT IN (4,9,10),且 delete_time IS NULL
|
||||
*
|
||||
* - all: 部门全量业绩(不限渠道)。用于「合计业绩」列展示。
|
||||
* - scoped: 「{渠道}业绩」:患者渠道 EXISTS 与侧栏/抽屉一致(channels ∪ channel_source);有展示行时部门列与「合计业绩」同为列表部门摊行。
|
||||
@@ -3725,7 +3729,7 @@ class YejiStatsLogic
|
||||
}
|
||||
|
||||
/**
|
||||
* 渠道业绩:与「处方订单列表」业绩完全同口径 —— 按 o.create_time 归日、仅剔除已取消(4)(含 NULL);
|
||||
* 渠道业绩:与「处方订单列表」业绩完全同口径 —— 按 o.create_time 归日、剔除履约 4/9/10(NULL 与其它状态计入);
|
||||
* EXISTS 仅用于"该患者属于此渠道"的判定(有任一挂号 channels 命中 + status=3,**不限挂号时点**);
|
||||
* 部门归属按业绩归属表达式(订单创建人 o.creator_id)。
|
||||
*/
|
||||
@@ -3812,7 +3816,7 @@ class YejiStatsLogic
|
||||
/**
|
||||
* 单次业绩聚合:与 aggregatePerformanceAmountsByAdmin / aggregateDealOrderCount 同源 ——
|
||||
* INNER 诊单,按业绩归属医助 SUM(amount) 后映射到展示「中心」。
|
||||
* WHERE: delete_time IS NULL、NOT(fulfillment <=> 4)、create_time 区间、diagnosis_id>0、归属医助>0;
|
||||
* WHERE: delete_time IS NULL、fulfillment ∈ (NULL ∪ 除 4/9/10 外)、create_time 区间、diagnosis_id>0、归属医助>0;
|
||||
* 可选 tag:diagnosis_id IN、归属医助 IN。
|
||||
*
|
||||
* @return array<int, float>
|
||||
@@ -3859,7 +3863,7 @@ class YejiStatsLogic
|
||||
}
|
||||
|
||||
/**
|
||||
* 全量成交单数:与 sumGlobalPerformanceAmount 同一 WHERE/COUNT(非取消订单条数)。
|
||||
* 全量成交单数:与 sumGlobalPerformanceAmount 同一 WHERE/COUNT(剔除 4/9/10)。
|
||||
*/
|
||||
private static function countGlobalDealOrders(int $startTs, int $endTs): int
|
||||
{
|
||||
@@ -4516,7 +4520,7 @@ class YejiStatsLogic
|
||||
'end_date' => (string) $c['endDate'],
|
||||
'channel_code' => (string) $c['channelCode'],
|
||||
'rows' => $rows,
|
||||
'note' => '与看板「未归属中心」补差一致:按订单 create_time、剔除履约已取消(4);**订单创建人**人事部门无法映射到任一展示「中心」计入各行;其余(无诊单/创建人为空)汇总在首行。账号数据权限下仅列出可见医助。',
|
||||
'note' => '与看板「未归属中心」补差一致:按订单 create_time、剔除履约 4/9/10;**订单创建人**人事部门无法映射到任一展示「中心」计入各行;其余(无诊单/创建人为空)汇总在首行。账号数据权限下仅列出可见医助。',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user