更新
This commit is contained in:
@@ -9,6 +9,7 @@ use app\adminapi\logic\qywx\CustomerLogic;
|
||||
use app\common\lists\ListsSearchInterface;
|
||||
use app\common\model\auth\Admin;
|
||||
use app\common\model\QywxExternalContact;
|
||||
use think\facade\Db;
|
||||
|
||||
/**
|
||||
* 企业微信客户列表
|
||||
@@ -26,6 +27,32 @@ class CustomerLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[] 入参 tag_ids 规范化后的非空字符串数组(实际为 string[])
|
||||
*/
|
||||
private function normalizeTagIds(): array
|
||||
{
|
||||
$raw = $this->params['tag_ids'] ?? null;
|
||||
if ($raw === null || $raw === '') {
|
||||
return [];
|
||||
}
|
||||
if (is_string($raw)) {
|
||||
$raw = explode(',', $raw);
|
||||
}
|
||||
if (!is_array($raw)) {
|
||||
return [];
|
||||
}
|
||||
$ids = [];
|
||||
foreach ($raw as $v) {
|
||||
$s = trim((string) $v);
|
||||
if ($s !== '') {
|
||||
$ids[] = $s;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values(array_unique($ids));
|
||||
}
|
||||
|
||||
private function baseQuery()
|
||||
{
|
||||
$query = QywxExternalContact::where($this->searchWhere);
|
||||
@@ -34,6 +61,22 @@ class CustomerLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
$query->whereLike('follow_users', '%' . $kw . '%');
|
||||
}
|
||||
|
||||
// 标签筛选:JOIN 关系表按 tag_id 过滤;多个标签为 OR(命中任一即返回)。
|
||||
// 走 zyt_qywx_external_contact_tag.idx_tag 索引,比 LIKE follow_users 快得多
|
||||
$tagIds = $this->normalizeTagIds();
|
||||
if ($tagIds !== []) {
|
||||
$matchedExtIds = Db::name('qywx_external_contact_tag')
|
||||
->whereIn('tag_id', $tagIds)
|
||||
->group('external_userid')
|
||||
->column('external_userid');
|
||||
if ($matchedExtIds === []) {
|
||||
// 没人命中:直接给一个不可能成立的条件,避免下面命中所有客户
|
||||
$query->whereRaw('1=0');
|
||||
} else {
|
||||
$query->whereIn('external_userid', $matchedExtIds);
|
||||
}
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
@@ -91,6 +134,10 @@ class CustomerLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
$followAdminIds = json_decode($item['follow_admin_ids'] ?? '[]', true);
|
||||
$item['follow_admin_ids'] = is_array($followAdminIds) ? $followAdminIds : [];
|
||||
|
||||
// 解析标签 JSON 数组(值由 CustomerLogic::extractFollowUserTags 写入;按 tag_id 去重)
|
||||
$tags = json_decode((string) ($item['tags'] ?? '[]'), true);
|
||||
$item['tags'] = is_array($tags) ? $tags : [];
|
||||
|
||||
$fromDb = (int) ($item['external_first_add_time'] ?? 0);
|
||||
$fromJson = CustomerLogic::minFollowCreatetime($followUsers);
|
||||
$item['external_first_add_time'] = $fromDb > 0 ? $fromDb : $fromJson;
|
||||
|
||||
@@ -17,6 +17,100 @@ use app\common\model\tcm\PrescriptionOrder;
|
||||
class PrescriptionLists extends BaseAdminDataLists implements ListsSearchInterface
|
||||
{
|
||||
use HasDataScopeFilter;
|
||||
|
||||
/**
|
||||
* 识别「有业务订单且处方药材为空白/重复」的处方 ID(用于全局置顶排序)
|
||||
*
|
||||
* @param array<int,int|string> $candidateIds
|
||||
* @return array<int,int>
|
||||
*/
|
||||
private function collectRiskPrescriptionIds(array $candidateIds): array
|
||||
{
|
||||
$candidateIds = array_values(array_unique(array_filter(array_map('intval', $candidateIds), static function (int $id): bool {
|
||||
return $id > 0;
|
||||
})));
|
||||
if ($candidateIds === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 仅在「存在有效业务订单」的处方里做风险判定
|
||||
$orderRxIds = PrescriptionOrder::whereIn('prescription_id', $candidateIds)
|
||||
->whereNull('delete_time')
|
||||
->where('fulfillment_status', '<>', 4)
|
||||
->column('prescription_id');
|
||||
$orderRxIds = array_values(array_unique(array_filter(array_map('intval', $orderRxIds), static function (int $id): bool {
|
||||
return $id > 0;
|
||||
})));
|
||||
if ($orderRxIds === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = Prescription::whereIn('id', $orderRxIds)
|
||||
->whereNull('delete_time')
|
||||
->field(['id', 'herbs'])
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$riskIds = [];
|
||||
foreach ($rows as $row) {
|
||||
$rid = (int) ($row['id'] ?? 0);
|
||||
if ($rid <= 0) {
|
||||
continue;
|
||||
}
|
||||
if ($this->isRiskHerbs($row['herbs'] ?? null)) {
|
||||
$riskIds[] = $rid;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values(array_unique($riskIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 药材风险判定:空白 or 重复(按名称,忽略空格与大小写)
|
||||
*/
|
||||
private function isRiskHerbs($herbsRaw): bool
|
||||
{
|
||||
$herbs = [];
|
||||
if (is_array($herbsRaw)) {
|
||||
$herbs = $herbsRaw;
|
||||
} elseif (is_string($herbsRaw) && $herbsRaw !== '') {
|
||||
$decoded = json_decode($herbsRaw, true);
|
||||
if (is_array($decoded)) {
|
||||
$herbs = $decoded;
|
||||
}
|
||||
}
|
||||
|
||||
$names = [];
|
||||
foreach ($herbs as $h) {
|
||||
if (!is_array($h)) {
|
||||
continue;
|
||||
}
|
||||
$name = trim((string) ($h['name'] ?? ''));
|
||||
if ($name !== '') {
|
||||
$names[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
// 空白药材
|
||||
if ($names === []) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 重复药材
|
||||
$seen = [];
|
||||
foreach ($names as $name) {
|
||||
$key = strtolower(preg_replace('/\s+/', '', $name) ?? '');
|
||||
if ($key === '') {
|
||||
continue;
|
||||
}
|
||||
if (isset($seen[$key])) {
|
||||
return true;
|
||||
}
|
||||
$seen[$key] = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @notes 搜索条件
|
||||
*/
|
||||
@@ -142,8 +236,16 @@ class PrescriptionLists extends BaseAdminDataLists implements ListsSearchInterfa
|
||||
$this->applyCreatorIdsFilter($query);
|
||||
$this->applyDataScopeByOwnerColumns($query, ['creator_id', 'assistant_id']);
|
||||
|
||||
$lists = $query
|
||||
->whereNull('delete_time')
|
||||
// 全局置顶:有业务订单且处方药材为空白/重复
|
||||
$candidateIds = (clone $query)->whereNull('delete_time')->column('id');
|
||||
$riskIds = $this->collectRiskPrescriptionIds(is_array($candidateIds) ? $candidateIds : []);
|
||||
|
||||
$listQuery = $query->whereNull('delete_time');
|
||||
if ($riskIds !== []) {
|
||||
$riskIdStr = implode(',', array_map('intval', $riskIds));
|
||||
$listQuery->orderRaw("CASE WHEN id IN ({$riskIdStr}) THEN 0 ELSE 1 END ASC");
|
||||
}
|
||||
$lists = $listQuery
|
||||
->order('id', 'desc')
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
->select()
|
||||
|
||||
@@ -71,13 +71,7 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
$this->applyDoctorAssistantFilters($query);
|
||||
$this->applyPatientKeywordFilter($query);
|
||||
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
|
||||
$diagIds = Diagnosis::where('assistant_id', $this->adminId)->whereNull('delete_time')->column('id');
|
||||
$query->where(function ($q) use ($diagIds) {
|
||||
$q->where('creator_id', $this->adminId);
|
||||
if ($diagIds !== []) {
|
||||
$q->whereOr('diagnosis_id', 'in', $diagIds);
|
||||
}
|
||||
});
|
||||
$query->where('creator_id', $this->adminId);
|
||||
}
|
||||
$this->applyDataScopeForPrescriptionOrder($query);
|
||||
}
|
||||
@@ -145,13 +139,7 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
return $query;
|
||||
}
|
||||
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
|
||||
$diagIds = Diagnosis::where('assistant_id', $this->adminId)->whereNull('delete_time')->column('id');
|
||||
$query->where(function ($q) use ($diagIds) {
|
||||
$q->where('creator_id', $this->adminId);
|
||||
if ($diagIds !== []) {
|
||||
$q->whereOr('diagnosis_id', 'in', $diagIds);
|
||||
}
|
||||
});
|
||||
$query->where('creator_id', $this->adminId);
|
||||
}
|
||||
$this->applyDataScopeForPrescriptionOrder($query);
|
||||
|
||||
@@ -319,9 +307,13 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
'stats_order_amount' => $s['order_amount'],
|
||||
'stats_order_amount_not_cancelled' => $s['order_amount_not_cancelled'],
|
||||
'stats_order_amount_cancelled' => $s['order_amount_cancelled'],
|
||||
/** 业绩:业务订单金额,剔除履约已取消(fulfillment_status=4),其余状态全部计入 */
|
||||
'stats_order_amount_performance' => $s['order_amount_not_cancelled'],
|
||||
'stats_linked_pay_amount' => $s['linked_pay_amount'],
|
||||
'stats_linked_pay_amount_not_cancelled' => $s['linked_pay_amount_not_cancelled'],
|
||||
'stats_linked_pay_amount_cancelled' => $s['linked_pay_amount_cancelled'],
|
||||
/** 业绩-关联实付:剔除履约已取消订单的关联支付金额 */
|
||||
'stats_linked_pay_amount_performance' => $s['linked_pay_amount_not_cancelled'],
|
||||
'stats_time_start' => $s['label_start'],
|
||||
'stats_time_end' => $s['label_end'],
|
||||
/** 统计口径:all=支付审核白名单全量;assistant=医助仅诊单协助业绩;restricted=与列表同域 */
|
||||
|
||||
Reference in New Issue
Block a user