You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1691 lines
70 KiB
1691 lines
70 KiB
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | Niucloud-admin 企业快速开发的多应用管理平台
|
|
// +----------------------------------------------------------------------
|
|
// | 官方网址:https://www.niucloud.com
|
|
// +----------------------------------------------------------------------
|
|
// | niucloud团队 版权所有 开源版本可自由商用
|
|
// +----------------------------------------------------------------------
|
|
// | Author: Niucloud Team
|
|
// +----------------------------------------------------------------------
|
|
|
|
namespace app\service\api\apiService;
|
|
|
|
use app\model\campus\Campus;
|
|
use app\model\campus_person_role\CampusPersonRole;
|
|
use app\model\communication_records\CommunicationRecords;
|
|
use app\model\customer_resources\CustomerResources;
|
|
use app\model\order_table\OrderTable;
|
|
use app\model\resource_assignment\ResourceAssignment;
|
|
use app\model\resource_sharing\ResourceSharing;
|
|
use app\model\sys\SysRole;
|
|
use core\base\BaseApiService;
|
|
|
|
/**
|
|
* 资源共享服务层
|
|
* Class MemberService
|
|
* @package app\service\api\member
|
|
*/
|
|
class ResourceSharingService extends BaseApiService
|
|
{
|
|
/**
|
|
* 新表模型实例
|
|
*/
|
|
protected ResourceAssignment $assignmentModel;
|
|
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
$this->model = new ResourceSharing();
|
|
$this->assignmentModel = new ResourceAssignment();
|
|
}
|
|
|
|
/**
|
|
* 抽象查询权限逻辑 - 计算用户可见的校区ID和权限范围
|
|
* @param int $personId 用户ID
|
|
* @return array ['is_admin' => bool, 'is_campus_admin' => bool, 'campus_ids' => array, 'role_keys' => array]
|
|
*/
|
|
protected function calculateUserPermissions(int $personId): array
|
|
{
|
|
// 查询当前用户在CampusPersonRole中的角色和校区
|
|
$campus_person_roles = CampusPersonRole::where('person_id', $personId)->select()->toArray();
|
|
|
|
$role_ids = array_unique(array_filter(array_column($campus_person_roles, 'role_id')));
|
|
$role_keys = [];
|
|
if (!empty($role_ids)) {
|
|
$role_keys = SysRole::whereIn('role_id', $role_ids)->column('role_key', 'role_id');
|
|
}
|
|
|
|
// 判断用户角色和校区权限
|
|
$is_admin = false;
|
|
$is_campus_admin = false;
|
|
$campus_ids = [];
|
|
|
|
foreach ($campus_person_roles as $item) {
|
|
// 记录用户所属的校区ID
|
|
if (!empty($item['campus_id']) && $item['campus_id'] > 0) {
|
|
$campus_ids[] = $item['campus_id'];
|
|
}
|
|
|
|
// 判断是否为管理员角色(1,4,7)
|
|
if (in_array($item['role_id'], [1, 4, 7])) {
|
|
if ((int) $item['campus_id'] === 0) {
|
|
$is_admin = true;
|
|
} else {
|
|
$is_campus_admin = true;
|
|
}
|
|
}
|
|
|
|
// 特殊处理市场经理角色
|
|
$role_key = $role_keys[$item['role_id']] ?? null;
|
|
if ($role_key === 'market_manager') {
|
|
if ((int) $item['campus_id'] === 0) {
|
|
$is_admin = true;
|
|
} else {
|
|
$is_campus_admin = true;
|
|
$campus_ids[] = $item['campus_id'];
|
|
}
|
|
}
|
|
}
|
|
|
|
$campus_ids = array_values(array_unique(array_filter($campus_ids)));
|
|
|
|
return [
|
|
'is_admin' => $is_admin,
|
|
'is_campus_admin' => $is_campus_admin,
|
|
'campus_ids' => $campus_ids,
|
|
'role_keys' => $role_keys,
|
|
'campus_person_roles' => $campus_person_roles
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 应用权限过滤到查询模型
|
|
* @param mixed $model 查询模型
|
|
* @param array $permissions 权限信息
|
|
* @param int $personId 当前用户ID
|
|
* @param string $shared_scope 查询范围
|
|
* @param int|null $shared_by 指定的分配人ID
|
|
* @param array $assignee_role_ids 指定的角色ID数组
|
|
* @return mixed
|
|
*/
|
|
protected function applyPermissionFilter($model, array $permissions, int $personId, string $shared_scope = '', ?int $shared_by = null, array $assignee_role_ids = [])
|
|
{
|
|
if ($shared_scope === 'user' && $shared_by) {
|
|
$model = $model->where(function ($query) use ($shared_by) {
|
|
$query->where(function ($subQuery) use ($shared_by) {
|
|
$subQuery->where('assignee_type', 'user')->where('assignee_id', $shared_by);
|
|
})->whereOr('assigned_by', $shared_by);
|
|
});
|
|
} elseif ($shared_scope === 'role' && !empty($assignee_role_ids)) {
|
|
$model = $model->where('assignee_type', 'role')
|
|
->whereIn('assignee_id', (array) $assignee_role_ids);
|
|
} else {
|
|
if ($shared_by) {
|
|
$model = $model->where(function ($query) use ($shared_by) {
|
|
$query->where(function ($subQuery) use ($shared_by) {
|
|
$subQuery->where('assignee_type', 'user')->where('assignee_id', $shared_by);
|
|
})->whereOr('assigned_by', $shared_by);
|
|
});
|
|
} elseif ($permissions['is_admin']) {
|
|
// 全局管理员无需额外限制
|
|
} elseif ($permissions['is_campus_admin'] && !empty($permissions['campus_ids'])) {
|
|
$campus_person_ids = CampusPersonRole::whereIn('campus_id', array_unique($permissions['campus_ids']))
|
|
->distinct(true)
|
|
->column('person_id');
|
|
|
|
if (!empty($campus_person_ids)) {
|
|
$model = $model->where(function ($query) use ($campus_person_ids) {
|
|
$query->where(function ($subQuery) use ($campus_person_ids) {
|
|
$subQuery->where('assignee_type', 'user')->whereIn('assignee_id', $campus_person_ids);
|
|
})->whereOr(function ($subQuery) use ($campus_person_ids) {
|
|
$subQuery->whereIn('assigned_by', $campus_person_ids);
|
|
});
|
|
});
|
|
}
|
|
} else {
|
|
$model = $model->where(function ($query) use ($personId) {
|
|
$query->where(function ($subQuery) use ($personId) {
|
|
$subQuery->where('assignee_type', 'user')->where('assignee_id', $personId);
|
|
})->whereOr('assigned_by', $personId);
|
|
});
|
|
}
|
|
}
|
|
|
|
return $model;
|
|
}
|
|
|
|
//查询资源共享详情 - 修改为使用 ResourceAssignment 表
|
|
public function info(array $where, string $field = '*')
|
|
{
|
|
$res = [
|
|
'code' => 0,
|
|
'msg' => '操作失败',
|
|
'data' => []
|
|
];
|
|
if (!$where) {
|
|
$res['msg'] = '缺少查询条件';
|
|
return $res;
|
|
}
|
|
|
|
// 使用 ResourceAssignment 表查询,resource_sharing_id 现在是 assignment 表的 id
|
|
$model = $this->assignmentModel;
|
|
|
|
if (!empty($where['id'])) {
|
|
$model = $model->where('id', $where['id']);
|
|
}
|
|
|
|
$data = $model->with([
|
|
'customerResource' => function ($query) {
|
|
$query->with([
|
|
'sixSpeed' => function ($query_2) {
|
|
$query_2->append([
|
|
'purchase_power_name',//购买力
|
|
'concept_awareness_name',//认知理念
|
|
]);
|
|
},
|
|
'personnel' => function ($query_2) {
|
|
}
|
|
])->append([
|
|
'source_channel_name',//来源渠道
|
|
'source_name',//来源
|
|
'gender_name',//性别
|
|
'purchasing_power_name',//购买力
|
|
'cognitive_idea_name',//认知理念
|
|
'initial_intent_name',//客户初步意向度
|
|
'status_name',//客户状态
|
|
]);
|
|
}
|
|
])->field($field)->find();
|
|
|
|
if ($data) {
|
|
$data = $data->toArray();
|
|
}
|
|
|
|
if (!empty($data['customerResource'])) {
|
|
$data['customerResource']['cj_count'] = OrderTable::where('resource_id', $data['customerResource']['id'])
|
|
->where('order_status', 'paid')
|
|
->count();//成交次数
|
|
}
|
|
|
|
if ($data) {
|
|
// 添加兼容字段
|
|
$data['resource_sharing_id'] = $data['id']; // assignment 表的 id
|
|
$data['user_id'] = ($data['assignee_type'] ?? '') === 'user' ? (int) $data['assignee_id'] : 0;
|
|
$data['role_id'] = ($data['assignee_type'] ?? '') === 'role' ? (int) $data['assignee_id'] : 0;
|
|
$data['shared_by'] = (int) ($data['assigned_by'] ?? 0);
|
|
$data['shared_at'] = $data['assigned_at'] ?? null;
|
|
|
|
$res['code'] = 1;
|
|
$res['msg'] = '操作成功';
|
|
$res['data'] = $data;
|
|
|
|
} else {
|
|
$res['code'] = 0;
|
|
$res['msg'] = '未找到数据';
|
|
$res['data'] = [];
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
//更新资源共享表
|
|
public function editData(array $where, array $data)
|
|
{
|
|
$res = [
|
|
'code' => 0,
|
|
'msg' => '操作失败',
|
|
'data' => []
|
|
];
|
|
if (!$where) {
|
|
$res['msg'] = '查询条件不能为空';
|
|
return $res;
|
|
}
|
|
|
|
$model = $this->model;
|
|
if ($where['id']) {
|
|
$model = $model->where('id', $where['id']);
|
|
}
|
|
$data = $model->update($data);
|
|
if ($data) {
|
|
$res = [
|
|
'code' => 1,
|
|
'msg' => '操作成功',
|
|
'data' => []
|
|
];
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
public function getList($where)
|
|
{
|
|
$page_params = $this->getPageParam();//获取请求参数中的页码+分页数
|
|
$page = $page_params['page'];
|
|
$limit = $page_params['limit'];
|
|
|
|
$shared_scope = $where['shared_scope'] ?? '';
|
|
$assignee_role_ids = $where['assignee_role_ids'] ?? [];
|
|
$shared_by_param = $where['shared_by'] ?? null;
|
|
|
|
// 兼容旧的shared_by=0参数,转换为新的shared_scope参数
|
|
if ($shared_scope === '' && $shared_by_param !== null && $shared_by_param !== '') {
|
|
$shared_scope = ((int) $shared_by_param === 0) ? 'unassigned' : 'user';
|
|
}
|
|
|
|
unset($where['shared_scope'], $where['assignee_role_ids']);
|
|
|
|
$person_id = $this->member_id;//当前登录的员工id
|
|
|
|
// 使用抽象的权限计算方法
|
|
$permissions = $this->calculateUserPermissions($person_id);
|
|
|
|
// 对于未分配资源的查询,暂时使用旧逻辑
|
|
if ($shared_scope === 'unassigned') {
|
|
return $this->getUnassignedList($where, $page, $limit, $person_id, $permissions['campus_ids'], $permissions['is_admin'], $permissions['is_campus_admin']);
|
|
}
|
|
|
|
// 初始化查询条件 - 使用新表
|
|
$model = (new ResourceAssignment())->alias('ra');
|
|
|
|
$shared_by = ($shared_by_param !== null && $shared_by_param !== '') ? (int) $shared_by_param : null;
|
|
|
|
// 应用权限过滤
|
|
$model = $this->applyPermissionFilter($model, $permissions, $person_id, $shared_scope, $shared_by, $assignee_role_ids);
|
|
|
|
// 全部资源场景下,固定按最近一次分配记录去重
|
|
if ($shared_scope === 'all') {
|
|
$latestAssignmentSub = $this->assignmentModel
|
|
->alias('sub')
|
|
->field('MAX(id) as latest_id, sub.resource_id')
|
|
->group('sub.resource_id')
|
|
->buildSql();
|
|
|
|
$model = $model
|
|
->join([$latestAssignmentSub => 'latest'], 'ra.id = latest.latest_id')
|
|
->field('ra.*');
|
|
}
|
|
|
|
// 处理查询条件 - CustomerResources模型的字段
|
|
$resource_conditions = [];
|
|
|
|
// 校区名称查询
|
|
if (!empty($where['campus_name'])) {
|
|
// 先查询匹配的校区ID
|
|
$campus = new Campus();
|
|
$matched_campus_ids = $campus->where('campus_name', 'like', '%' . $where['campus_name'] . '%')
|
|
->column('id');
|
|
|
|
if (!empty($matched_campus_ids)) {
|
|
$resource_conditions[] = ['campus', 'in', $matched_campus_ids];
|
|
} else {
|
|
// 没有匹配的校区,返回空结果
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
}
|
|
|
|
// 资源名称查询
|
|
if (!empty($where['name'])) {
|
|
$resource_conditions[] = ['name', 'like', '%' . $where['name'] . '%'];
|
|
}
|
|
|
|
// 手机号查询
|
|
if (!empty($where['phone_number'])) {
|
|
$resource_conditions[] = ['phone_number', 'like', '%' . $where['phone_number'] . '%'];
|
|
}
|
|
|
|
// 来源查询
|
|
if (!empty($where['source'])) {
|
|
$resource_conditions[] = ['source', 'like', '%' . $where['source'] . '%'];
|
|
}
|
|
|
|
// 来源渠道查询
|
|
if (!empty($where['source_channel'])) {
|
|
$resource_conditions[] = ['source_channel', 'like', '%' . $where['source_channel'] . '%'];
|
|
}
|
|
|
|
// 年龄查询 - varchar类型使用like查询,支持模糊匹配(如4可匹配4.1、4.12、14、24等)
|
|
if (isset($where['age']) && $where['age'] !== '' && $where['age'] !== null) {
|
|
$resource_conditions[] = ['age', 'like', '%' . trim($where['age']) . '%'];
|
|
}
|
|
|
|
// 黑名单状态查询
|
|
if (isset($where['blacklist']) && $where['blacklist'] !== '' && $where['blacklist'] !== null) {
|
|
$resource_conditions[] = ['blacklist', '=', $where['blacklist']];
|
|
}
|
|
|
|
// 查询符合条件的资源ID
|
|
$resource_ids = [];
|
|
if (!empty($resource_conditions)) {
|
|
$resource_ids = (new CustomerResources())->where($resource_conditions)->column('id');
|
|
if (empty($resource_ids)) {
|
|
// 没有匹配的资源,返回空结果
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
$model = $model->whereIn('resource_id', $resource_ids);
|
|
}
|
|
|
|
// 共享时间查询
|
|
if (!empty($where['shared_at_arr'])) {
|
|
$model = $model->where('assigned_at', '>=', $where['shared_at_arr'][0])
|
|
->where('assigned_at', '<=', $where['shared_at_arr'][1]);
|
|
}
|
|
|
|
// 处理有效性查询 - 需要通过six_speed表关联查询
|
|
if (!empty($where['valid_type'])) {
|
|
$six_speed_model = new \app\model\six_speed\SixSpeed();
|
|
if ($where['valid_type'] === '有效') {
|
|
$valid_resource_ids = $six_speed_model->where('efficacious', 1)->column('resource_id');
|
|
} else if ($where['valid_type'] === '无效') {
|
|
$valid_resource_ids = $six_speed_model->where('efficacious', 0)->column('resource_id');
|
|
}
|
|
|
|
if (isset($valid_resource_ids)) {
|
|
if (empty($resource_ids)) {
|
|
$resource_ids = $valid_resource_ids;
|
|
} else {
|
|
$resource_ids = array_intersect($resource_ids, $valid_resource_ids);
|
|
}
|
|
|
|
if (empty($resource_ids)) {
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
$model = $model->whereIn('resource_id', $resource_ids);
|
|
}
|
|
}
|
|
|
|
// 处理成交类型查询 - 通过订单表关联查询
|
|
if (!empty($where['deal_type'])) {
|
|
$order_model = new OrderTable();
|
|
if ($where['deal_type'] === '已成交') {
|
|
$deal_resource_ids = $order_model->where('order_status', 'paid')->column('resource_id');
|
|
} else if ($where['deal_type'] === '未成交') {
|
|
// 没有付费订单的资源
|
|
$paid_resource_ids = $order_model->where('order_status', 'paid')->column('resource_id');
|
|
$all_resource_ids = (new CustomerResources())->column('id');
|
|
$deal_resource_ids = array_diff($all_resource_ids, $paid_resource_ids);
|
|
} else if ($where['deal_type'] === '定金') {
|
|
// 没有付费订单的资源
|
|
$paid_resource_ids = $order_model->where('payment_type', 'deposit')->column('resource_id');
|
|
$all_resource_ids = (new CustomerResources())->column('id');
|
|
$deal_resource_ids = array_diff($all_resource_ids, $paid_resource_ids);
|
|
}
|
|
|
|
if (isset($deal_resource_ids)) {
|
|
if (empty($resource_ids)) {
|
|
$resource_ids = $deal_resource_ids;
|
|
} else {
|
|
$resource_ids = array_intersect($resource_ids, $deal_resource_ids);
|
|
}
|
|
|
|
if (empty($resource_ids)) {
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
$model = $model->whereIn('resource_id', $resource_ids);
|
|
}
|
|
}
|
|
|
|
// 处理沟通情况查询 - 通过沟通记录表关联查询
|
|
if (!empty($where['communication_status'])) {
|
|
if ($where['communication_status'] === '已沟通') {
|
|
$comm_resource_ids = CommunicationRecords::distinct(true)->column('resource_id');
|
|
} else if ($where['communication_status'] === '未沟通') {
|
|
// 没有沟通记录的资源
|
|
$comm_resource_ids_with_records = CommunicationRecords::distinct(true)->column('resource_id');
|
|
$all_resource_ids = (new CustomerResources())->column('id');
|
|
$comm_resource_ids = array_diff($all_resource_ids, $comm_resource_ids_with_records);
|
|
}
|
|
|
|
if (isset($comm_resource_ids)) {
|
|
if (empty($resource_ids)) {
|
|
$resource_ids = $comm_resource_ids;
|
|
} else {
|
|
$resource_ids = array_intersect($resource_ids, $comm_resource_ids);
|
|
}
|
|
|
|
if (empty($resource_ids)) {
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
$model = $model->whereIn('resource_id', $resource_ids);
|
|
}
|
|
}
|
|
|
|
// 过滤已分配的资源(只显示可再分配的资源)
|
|
// 注意:这里需要用子查询包装OR条件,避免与其他WHERE条件冲突
|
|
// 处理到课类型查询 - 通过PersonCourseSchedule表关联查询
|
|
if (!empty($where['attendance_type'])) {
|
|
if ($where['attendance_type'] === '一访已到') {
|
|
// 查询一访已到的资源ID - 通过至少有一次已完成课程来判断
|
|
$attendance_resource_ids = \app\model\person_course_schedule\PersonCourseSchedule::where('person_type', 'customer_resource')
|
|
->where('status', 1) // status=1表示已上课
|
|
->distinct(true)
|
|
->column('resources_id');
|
|
} else if ($where['attendance_type'] === '二访已到') {
|
|
// 查询二访已到的资源ID - 通过至少有两次已完成课程来判断
|
|
$attendance_resource_ids = \app\model\person_course_schedule\PersonCourseSchedule::where('person_type', 'customer_resource')
|
|
->where('status', 1) // status=1表示已上课
|
|
->group('resources_id')
|
|
->having('count(*) >= 2') // 至少有两次考勤记录
|
|
->column('resources_id');
|
|
} else {
|
|
// 其他到课类型的处理
|
|
$attendance_resource_ids = [];
|
|
}
|
|
|
|
if (isset($attendance_resource_ids)) {
|
|
if (empty($resource_ids)) {
|
|
$resource_ids = $attendance_resource_ids;
|
|
} else {
|
|
$resource_ids = array_intersect($resource_ids, $attendance_resource_ids);
|
|
}
|
|
|
|
if (empty($resource_ids)) {
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
$model = $model->whereIn('resource_id', $resource_ids);
|
|
}
|
|
}
|
|
|
|
// 处理课程搜索查询 - 通过订单表关联课程表查询
|
|
if (!empty($where['course_search'])) {
|
|
// 通过订单表关联查询包含指定课程的资源ID
|
|
$order_model = new OrderTable();
|
|
|
|
// 先查询课程表中匹配的课程ID
|
|
$course_ids = \app\model\school\Course::where('course_name', 'like', '%' . $where['course_search'] . '%')
|
|
->column('course_id');
|
|
|
|
if (!empty($course_ids)) {
|
|
// 查询订单表中包含这些课程的订单
|
|
$course_resource_ids = $order_model->whereIn('course_id', $course_ids)
|
|
->distinct(true)
|
|
->column('resource_id');
|
|
|
|
if (empty($course_resource_ids)) {
|
|
// 没有匹配的资源,返回空结果
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
} else {
|
|
// 没有匹配的课程,返回空结果
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
if (isset($course_resource_ids)) {
|
|
if (empty($resource_ids)) {
|
|
$resource_ids = $course_resource_ids;
|
|
} else {
|
|
$resource_ids = array_intersect($resource_ids, $course_resource_ids);
|
|
}
|
|
|
|
if (empty($resource_ids)) {
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
$model = $model->whereIn('resource_id', $resource_ids);
|
|
}
|
|
}
|
|
|
|
// 查询数据
|
|
$list = $model->with(['customerResource', 'sixSpeed'])
|
|
->order('assigned_at', 'desc')
|
|
->paginate([
|
|
'list_rows' => $limit,
|
|
'page' => $page,
|
|
])->toArray();
|
|
|
|
// 处理结果数据
|
|
if (!empty($list['data'])) {
|
|
// 获取校区信息
|
|
$campus_ids = [];
|
|
foreach ($list['data'] as $item) {
|
|
if (!empty($item['customerResource']) && !empty($item['customerResource']['campus'])) {
|
|
$campus_ids[] = $item['customerResource']['campus'];
|
|
}
|
|
}
|
|
|
|
$campus_ids = array_unique($campus_ids);
|
|
$campus_names = [];
|
|
|
|
if (!empty($campus_ids)) {
|
|
$campus = new Campus();
|
|
$campus_names = $campus->whereIn('id', $campus_ids)->column('campus_name', 'id');
|
|
}
|
|
|
|
// 获取资源ID列表用于查询关联信息
|
|
$resource_ids = array_column($list['data'], 'resource_id');
|
|
$resource_ids = array_unique(array_filter($resource_ids));
|
|
|
|
// resource_sharing_id 现在直接使用 ResourceAssignment 表的 id,不需要映射
|
|
// 获取分配人员ID列表
|
|
$shared_by_ids = array_column($list['data'], 'assigned_by');
|
|
$shared_by_ids = array_unique(array_filter($shared_by_ids));
|
|
|
|
// 获取市场老师ID列表
|
|
$consultant_ids = [];
|
|
foreach ($list['data'] as $item) {
|
|
if (!empty($item['customerResource']) && !empty($item['customerResource']['consultant'])) {
|
|
$consultant_ids[] = $item['customerResource']['consultant'];
|
|
}
|
|
}
|
|
$consultant_ids = array_unique(array_filter($consultant_ids));
|
|
|
|
// 查询分配人员信息
|
|
$shared_by_names = [];
|
|
if (!empty($shared_by_ids)) {
|
|
$personnel = new \app\model\personnel\Personnel();
|
|
$shared_by_names = $personnel->whereIn('id', $shared_by_ids)->column('name', 'id');
|
|
}
|
|
|
|
// 查询市场老师信息
|
|
$consultant_names = [];
|
|
if (!empty($consultant_ids)) {
|
|
$personnel = new \app\model\personnel\Personnel();
|
|
$consultant_names = $personnel->whereIn('id', $consultant_ids)->column('name', 'id');
|
|
}
|
|
|
|
// 查询销售老师信息(从资源分配表获取assigned_by=0的记录)
|
|
$sales_teachers = [];
|
|
if (!empty($resource_ids)) {
|
|
$assignment_model = new \app\model\resource_assignment\ResourceAssignment();
|
|
|
|
// 查询每个资源assigned_by=0的最新一条记录
|
|
$sales_assignments = [];
|
|
foreach ($resource_ids as $resource_id) {
|
|
$latest_assignment = $assignment_model
|
|
->where('resource_id', $resource_id)
|
|
->where('assignee_type', 'user')
|
|
->where('assigned_by', 0)
|
|
->order('assigned_at', 'desc')
|
|
->field('assignee_id')
|
|
->find();
|
|
|
|
if ($latest_assignment) {
|
|
$sales_assignments[$resource_id] = $latest_assignment['assignee_id'];
|
|
}
|
|
}
|
|
|
|
// 获取销售人员姓名
|
|
$sales_teacher_ids = array_values(array_unique(array_filter($sales_assignments)));
|
|
$sales_teacher_names = [];
|
|
if (!empty($sales_teacher_ids)) {
|
|
$personnel = new \app\model\personnel\Personnel();
|
|
$sales_teacher_names = $personnel->whereIn('id', $sales_teacher_ids)->column('name', 'id');
|
|
}
|
|
|
|
// 构建销售老师数组
|
|
foreach ($sales_assignments as $resource_id => $assignee_id) {
|
|
$sales_teachers[$resource_id] = $sales_teacher_names[$assignee_id] ?? '';
|
|
}
|
|
}
|
|
|
|
// 查询市场老师信息(从资源分配表获取assigned_source为auto_allocation或api的最新记录)
|
|
$market_teachers = [];
|
|
if (!empty($resource_ids)) {
|
|
$assignment_model = new \app\model\resource_assignment\ResourceAssignment();
|
|
|
|
// 查询每个资源assigned_source为auto_allocation或api的最新一条记录
|
|
$market_assignments = [];
|
|
foreach ($resource_ids as $resource_id) {
|
|
$latest_assignment = $assignment_model
|
|
->where('resource_id', $resource_id)
|
|
->whereIn('assigned_source', ['auto_allocation', 'api'])
|
|
->order('assigned_at', 'desc')
|
|
->field('assignee_id')
|
|
->find();
|
|
|
|
if ($latest_assignment) {
|
|
$market_assignments[$resource_id] = $latest_assignment['assignee_id'];
|
|
}
|
|
}
|
|
|
|
// 获取市场老师姓名
|
|
$market_teacher_ids = array_values(array_unique(array_filter($market_assignments)));
|
|
$market_teacher_names = [];
|
|
if (!empty($market_teacher_ids)) {
|
|
$personnel = new \app\model\personnel\Personnel();
|
|
$market_teacher_names = $personnel->whereIn('id', $market_teacher_ids)->column('name', 'id');
|
|
}
|
|
|
|
// 构建市场老师数组
|
|
foreach ($market_assignments as $resource_id => $assignee_id) {
|
|
$market_teachers[$resource_id] = $market_teacher_names[$assignee_id] ?? '';
|
|
}
|
|
}
|
|
|
|
// 查询最近沟通记录
|
|
$communication_times = [];
|
|
if (!empty($resource_ids)) {
|
|
$resource_ids = array_map('intval', $resource_ids);
|
|
$subQuery = CommunicationRecords::whereIn('resource_id', $resource_ids)
|
|
->field('resource_id, max(communication_time) as max_time')
|
|
->group('resource_id')
|
|
->select()
|
|
->toArray();
|
|
|
|
foreach ($subQuery as $item) {
|
|
$communication_times[$item['resource_id']] = $item['max_time'];
|
|
}
|
|
}
|
|
|
|
// 查询到访信息
|
|
$visit_info = [];
|
|
if (!empty($resource_ids)) {
|
|
// 需要先导入PersonCourseSchedule模型
|
|
$person_course_model = new \app\model\person_course_schedule\PersonCourseSchedule();
|
|
$visit_records = $person_course_model
|
|
->whereIn('resources_id', $resource_ids)
|
|
->where('person_type', 'customer_resource')
|
|
->field('resources_id, course_date, time_slot, status')
|
|
->order('course_date', 'desc')
|
|
->select()
|
|
->toArray();
|
|
|
|
// 处理到访信息
|
|
foreach ($visit_records as $record) {
|
|
$resource_id = $record['resources_id'];
|
|
|
|
if (!isset($visit_info[$resource_id])) {
|
|
$visit_info[$resource_id] = [
|
|
'first_visit_status' => '未到',
|
|
'second_visit_status' => '未到',
|
|
'visit_count' => 0
|
|
];
|
|
}
|
|
|
|
if ($record['status'] == 1) { // 假设status=1表示已到
|
|
$visit_info[$resource_id]['visit_count']++;
|
|
|
|
if ($visit_info[$resource_id]['visit_count'] == 1) {
|
|
$visit_info[$resource_id]['first_visit_status'] = '已到';
|
|
} elseif ($visit_info[$resource_id]['visit_count'] == 2) {
|
|
$visit_info[$resource_id]['second_visit_status'] = '已到';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 查询开单状态
|
|
$order_status = [];
|
|
if (!empty($resource_ids)) {
|
|
// 首先查询是否有付费订单
|
|
$order_model = new OrderTable();
|
|
$paid_orders = $order_model
|
|
->whereIn('resource_id', $resource_ids)
|
|
->where('order_status', 'paid')
|
|
->field('resource_id')
|
|
->select()
|
|
->toArray();
|
|
|
|
$paid_resource_ids = array_column($paid_orders, 'resource_id');
|
|
|
|
// 查询六速表的开单状态
|
|
$six_speed_model = new \app\model\six_speed\SixSpeed();
|
|
$six_speed_records = $six_speed_model
|
|
->whereIn('resource_id', $resource_ids)
|
|
->field('resource_id, is_closed')
|
|
->select()
|
|
->toArray();
|
|
|
|
// 设置每个资源的订单状态
|
|
foreach ($resource_ids as $resource_id) {
|
|
if (in_array($resource_id, $paid_resource_ids)) {
|
|
$order_status[$resource_id] = '已报名';
|
|
} else {
|
|
// 查找对应的六速记录
|
|
$six_speed_record = array_filter($six_speed_records, function($record) use ($resource_id) {
|
|
return $record['resource_id'] == $resource_id;
|
|
});
|
|
|
|
if (!empty($six_speed_record)) {
|
|
$six_speed_record = array_shift($six_speed_record);
|
|
$order_status[$resource_id] = $six_speed_record['is_closed'] ? '已开单' : '未开单';
|
|
} else {
|
|
$order_status[$resource_id] = '未报名';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 处理每条数据
|
|
foreach ($list['data'] as &$item) {
|
|
// resource_sharing_id 现在直接使用 ResourceAssignment 表的 id
|
|
$item['resource_sharing_id'] = (int) ($item['id'] ?? 0);
|
|
|
|
if (!empty($item['customerResource'])) {
|
|
// 确保数据类型转换:数据库中的数值需要转换为字符串
|
|
$source_value = (string) $item['customerResource']['source'];
|
|
$source_channel_value = (string) $item['customerResource']['source_channel'];
|
|
|
|
|
|
$item['customerResource']['source'] = get_dict_value('source', $source_value);
|
|
$item['customerResource']['source_channel'] = get_dict_value('SourceChannel', $source_channel_value);
|
|
$item['customerResource']['campus_name'] = $campus_names[$item['customerResource']['campus']] ?? '';
|
|
|
|
// customerResource 中的 resource_sharing_id 也使用 assignment 表的 id
|
|
$item['customerResource']['resource_sharing_id'] = (int) ($item['id'] ?? 0);
|
|
|
|
if (!empty($item['customerResource']['consultant'])) {
|
|
$item['customerResource']['consultant_name'] = $consultant_names[$item['customerResource']['consultant']] ?? '';
|
|
} else {
|
|
$item['customerResource']['consultant_name'] = '';
|
|
}
|
|
|
|
// 添加销售老师字段(从资源分配表获取)
|
|
$resource_id = $item['resource_id'];
|
|
$item['customerResource']['sales_teacher'] = $sales_teachers[$resource_id] ?? '';
|
|
|
|
// 添加市场老师字段(从资源分配表获取的最新分配记录)
|
|
$item['customerResource']['market_teacher'] = $market_teachers[$resource_id] ?? '';
|
|
|
|
$item['customerResource']['communication_time'] = $communication_times[$item['resource_id']] ?? '';
|
|
|
|
$resource_id = $item['resource_id'];
|
|
$item['customerResource']['first_visit_status'] = $visit_info[$resource_id]['first_visit_status'] ?? '未到';
|
|
$item['customerResource']['second_visit_status'] = $visit_info[$resource_id]['second_visit_status'] ?? '未到';
|
|
|
|
$item['customerResource']['order_status'] = $order_status[$resource_id] ?? '未报名';
|
|
}
|
|
|
|
$item['user_id'] = ($item['assignee_type'] ?? '') === 'user' ? (int) $item['assignee_id'] : 0;
|
|
$item['role_id'] = ($item['assignee_type'] ?? '') === 'role' ? (int) $item['assignee_id'] : 0;
|
|
$item['shared_by'] = (int) ($item['assigned_by'] ?? 0);
|
|
$item['shared_at'] = $item['assigned_at'] ?? null;
|
|
$item['shared_by_name'] = $shared_by_names[$item['shared_by']] ?? '未分配';
|
|
$item['can_reassign'] = empty($item['assignee_type']) || (int) ($item['assigned_by'] ?? 0) === 0;
|
|
}
|
|
}
|
|
|
|
return $list;
|
|
}
|
|
|
|
protected function getUnassignedList(array $where, int $page, int $limit, int $personId, array $campusIds, bool $isAdmin, bool $isCampusAdmin)
|
|
{
|
|
// 暂时复用旧逻辑,后续迁移完成后改为基于 resource_assignment 的查询
|
|
$legacyResult = $this->getListLegacy($where);
|
|
|
|
if (empty($legacyResult['data'])) {
|
|
return $legacyResult;
|
|
}
|
|
|
|
foreach ($legacyResult['data'] as &$item) {
|
|
$userId = (int)($item['user_id'] ?? 0);
|
|
$roleId = (int)($item['role_id'] ?? 0);
|
|
if ($userId > 0) {
|
|
$item['assignee_type'] = 'user';
|
|
$item['assignee_id'] = $userId;
|
|
} elseif ($roleId > 0) {
|
|
$item['assignee_type'] = 'role';
|
|
$item['assignee_id'] = $roleId;
|
|
} else {
|
|
$item['assignee_type'] = null;
|
|
$item['assignee_id'] = 0;
|
|
}
|
|
|
|
$item['assigned_by'] = (int)($item['shared_by'] ?? 0);
|
|
$item['assigned_at'] = $item['shared_at'] ?? null;
|
|
}
|
|
|
|
return $legacyResult;
|
|
}
|
|
|
|
public function getListLegacy($where)
|
|
{
|
|
$page_params = $this->getPageParam();//获取请求参数中的页码+分页数
|
|
$page = $page_params['page'];
|
|
$limit = $page_params['limit'];
|
|
|
|
$person_id = $this->member_id;//当前登录的员工id
|
|
|
|
// 查询当前用户在CampusPersonRole中的角色和校区
|
|
$campus_person_roles = CampusPersonRole::where('person_id', $person_id)->select()->toArray();
|
|
|
|
// 初始化查询条件
|
|
$model = $this->model;
|
|
|
|
// 判断用户角色和校区权限
|
|
$is_admin = false;
|
|
$is_campus_admin = false;
|
|
$campus_ids = [];
|
|
|
|
foreach ($campus_person_roles as $item) {
|
|
// 记录用户所属的校区ID
|
|
if ($item['campus_id'] > 0) {
|
|
$campus_ids[] = $item['campus_id'];
|
|
}
|
|
|
|
// 判断是否为管理员角色(1,4,7)
|
|
if (in_array($item['role_id'], [1, 4, 7])) {
|
|
// 如果没有校区,则为全局管理员
|
|
if ($item['campus_id'] == 0) {
|
|
$is_admin = true;
|
|
} else {
|
|
// 有校区的管理员
|
|
$is_campus_admin = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 共享人查询 - 如果指定了shared_by,优先处理这个条件
|
|
if (isset($where['shared_by']) && $where['shared_by']) {
|
|
$model = $model->where(function ($query) use ($where) {
|
|
$query->where('user_id', $where['shared_by'])
|
|
->whereOr('shared_by', $where['shared_by']);
|
|
});
|
|
} else {
|
|
// 根据角色权限设置查询条件
|
|
if ($is_admin) {
|
|
// 全局管理员可以查看所有数据,不需要额外条件
|
|
} else if ($is_campus_admin && !empty($campus_ids)) {
|
|
// 校区管理员可以查看自己校区所有人的数据
|
|
// 先获取校区内所有人员ID
|
|
$campus_person_ids = CampusPersonRole::whereIn('campus_id', $campus_ids)
|
|
->distinct(true)
|
|
->column('person_id');
|
|
|
|
if (!empty($campus_person_ids)) {
|
|
$model = $model->where(function ($query) use ($campus_person_ids) {
|
|
$query->whereIn('user_id', $campus_person_ids)
|
|
->whereOr('shared_by', 'in', $campus_person_ids);
|
|
});
|
|
}
|
|
} else {
|
|
// 普通角色只能查看user_id是自己或shared_by是自己的数据
|
|
$model = $model->where(function ($query) use ($person_id) {
|
|
$query->where('user_id', $person_id)
|
|
->whereOr('shared_by', $person_id);
|
|
});
|
|
}
|
|
}
|
|
|
|
// 处理查询条件 - CustomerResources模型的字段
|
|
$resource_conditions = [];
|
|
|
|
// 校区名称查询
|
|
if (!empty($where['campus_name'])) {
|
|
// 先查询匹配的校区ID
|
|
$campus = new Campus();
|
|
$matched_campus_ids = $campus->where('campus_name', 'like', '%' . $where['campus_name'] . '%')
|
|
->column('id');
|
|
|
|
if (!empty($matched_campus_ids)) {
|
|
$resource_conditions[] = ['campus', 'in', $matched_campus_ids];
|
|
} else {
|
|
// 没有匹配的校区,返回空结果
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
}
|
|
|
|
// 资源名称查询
|
|
if (!empty($where['name'])) {
|
|
$resource_conditions[] = ['name', 'like', '%' . $where['name'] . '%'];
|
|
}
|
|
|
|
// 手机号查询
|
|
if (!empty($where['phone_number'])) {
|
|
$resource_conditions[] = ['phone_number', 'like', '%' . $where['phone_number'] . '%'];
|
|
}
|
|
|
|
// 来源查询
|
|
if (!empty($where['source'])) {
|
|
$resource_conditions[] = ['source', 'like', '%' . $where['source'] . '%'];
|
|
}
|
|
|
|
// 来源渠道查询
|
|
if (!empty($where['source_channel'])) {
|
|
$resource_conditions[] = ['source_channel', 'like', '%' . $where['source_channel'] . '%'];
|
|
}
|
|
|
|
// 年龄查询 - varchar类型使用like查询,支持模糊匹配(如4可匹配4.1、4.12、14、24等)
|
|
if (isset($where['age']) && $where['age'] !== '' && $where['age'] !== null) {
|
|
$resource_conditions[] = ['age', 'like', '%' . trim($where['age']) . '%'];
|
|
}
|
|
|
|
// 黑名单状态查询
|
|
if (isset($where['blacklist']) && $where['blacklist'] !== '' && $where['blacklist'] !== null) {
|
|
$resource_conditions[] = ['blacklist', '=', $where['blacklist']];
|
|
}
|
|
|
|
// 查询符合条件的资源ID
|
|
$resource_ids = [];
|
|
if (!empty($resource_conditions)) {
|
|
$resource_ids = (new CustomerResources())->where($resource_conditions)->column('id');
|
|
if (empty($resource_ids)) {
|
|
// 没有匹配的资源,返回空结果
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
$model = $model->whereIn('resource_id', $resource_ids);
|
|
}
|
|
|
|
// 共享时间查询
|
|
if (!empty($where['shared_at_arr'])) {
|
|
$model = $model->where('shared_at', '>=', $where['shared_at_arr'][0])
|
|
->where('shared_at', '<=', $where['shared_at_arr'][1]);
|
|
}
|
|
|
|
// 处理有效性查询 - 需要通过six_speed表关联查询
|
|
if (!empty($where['valid_type'])) {
|
|
$six_speed_model = new \app\model\six_speed\SixSpeed();
|
|
if ($where['valid_type'] === '有效') {
|
|
$valid_resource_ids = $six_speed_model->where('efficacious', 1)->column('resource_id');
|
|
} else if ($where['valid_type'] === '无效') {
|
|
$valid_resource_ids = $six_speed_model->where('efficacious', 0)->column('resource_id');
|
|
}
|
|
|
|
if (isset($valid_resource_ids)) {
|
|
if (empty($resource_ids)) {
|
|
$resource_ids = $valid_resource_ids;
|
|
} else {
|
|
$resource_ids = array_intersect($resource_ids, $valid_resource_ids);
|
|
}
|
|
|
|
if (empty($resource_ids)) {
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
$model = $model->whereIn('resource_id', $resource_ids);
|
|
}
|
|
}
|
|
|
|
// 处理成交类型查询 - 通过订单表关联查询
|
|
if (!empty($where['deal_type'])) {
|
|
$order_model = new OrderTable();
|
|
if ($where['deal_type'] === '已成交') {
|
|
$deal_resource_ids = $order_model->where('order_status', 'paid')->column('resource_id');
|
|
} else if ($where['deal_type'] === '未成交') {
|
|
// 没有付费订单的资源
|
|
$paid_resource_ids = $order_model->where('order_status', 'paid')->column('resource_id');
|
|
$all_resource_ids = (new CustomerResources())->column('id');
|
|
$deal_resource_ids = array_diff($all_resource_ids, $paid_resource_ids);
|
|
} else if ($where['deal_type'] === '定金') {
|
|
// 没有付费订单的资源
|
|
$paid_resource_ids = $order_model->where('payment_type', 'deposit')->column('resource_id');
|
|
$all_resource_ids = (new CustomerResources())->column('id');
|
|
$deal_resource_ids = array_diff($all_resource_ids, $paid_resource_ids);
|
|
}
|
|
|
|
if (isset($deal_resource_ids)) {
|
|
if (empty($resource_ids)) {
|
|
$resource_ids = $deal_resource_ids;
|
|
} else {
|
|
$resource_ids = array_intersect($resource_ids, $deal_resource_ids);
|
|
}
|
|
|
|
if (empty($resource_ids)) {
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
$model = $model->whereIn('resource_id', $resource_ids);
|
|
}
|
|
}
|
|
|
|
// 处理沟通情况查询 - 通过沟通记录表关联查询
|
|
if (!empty($where['communication_status'])) {
|
|
if ($where['communication_status'] === '已沟通') {
|
|
$comm_resource_ids = CommunicationRecords::distinct(true)->column('resource_id');
|
|
} else if ($where['communication_status'] === '未沟通') {
|
|
// 没有沟通记录的资源
|
|
$comm_resource_ids_with_records = CommunicationRecords::distinct(true)->column('resource_id');
|
|
$all_resource_ids = (new CustomerResources())->column('id');
|
|
$comm_resource_ids = array_diff($all_resource_ids, $comm_resource_ids_with_records);
|
|
}
|
|
|
|
if (isset($comm_resource_ids)) {
|
|
if (empty($resource_ids)) {
|
|
$resource_ids = $comm_resource_ids;
|
|
} else {
|
|
$resource_ids = array_intersect($resource_ids, $comm_resource_ids);
|
|
}
|
|
|
|
if (empty($resource_ids)) {
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
$model = $model->whereIn('resource_id', $resource_ids);
|
|
}
|
|
}
|
|
|
|
// 处理课程搜索查询 - 通过订单表关联课程表查询
|
|
if (!empty($where['course_search'])) {
|
|
// 通过订单表关联查询包含指定课程的资源ID
|
|
$order_model = new OrderTable();
|
|
|
|
// 先查询课程表中匹配的课程ID
|
|
$course_ids = \app\model\school\Course::where('course_name', 'like', '%' . $where['course_search'] . '%')
|
|
->column('course_id');
|
|
|
|
if (!empty($course_ids)) {
|
|
// 查询订单表中包含这些课程的订单
|
|
$course_resource_ids = $order_model->whereIn('course_id', $course_ids)
|
|
->distinct(true)
|
|
->column('resource_id');
|
|
|
|
if (empty($course_resource_ids)) {
|
|
// 没有匹配的资源,返回空结果
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
} else {
|
|
// 没有匹配的课程,返回空结果
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
if (isset($course_resource_ids)) {
|
|
if (empty($resource_ids)) {
|
|
$resource_ids = $course_resource_ids;
|
|
} else {
|
|
$resource_ids = array_intersect($resource_ids, $course_resource_ids);
|
|
}
|
|
|
|
if (empty($resource_ids)) {
|
|
return [
|
|
'count' => 0,
|
|
'total' => 0,
|
|
'current_page' => $page,
|
|
'last_page' => 0,
|
|
'data' => []
|
|
];
|
|
}
|
|
$model = $model->whereIn('resource_id', $resource_ids);
|
|
}
|
|
}
|
|
|
|
// 过滤已分配的资源(只显示可再分配的资源)
|
|
// 注意:这里需要用子查询包装OR条件,避免与其他WHERE条件冲突
|
|
$model = $model->when($where['shared_by'] > 0, function ($query) use ($where) {
|
|
$query->where(function ($subQuery) use ($where) {
|
|
$subQuery->where('shared_by', $where['shared_by'])->whereOr('user_id', $where['shared_by']);
|
|
});
|
|
}, function ($query) {
|
|
$query->where(function ($subQuery) {
|
|
$subQuery->where('shared_by', 0)->whereOr('shared_by', null);
|
|
});
|
|
});
|
|
|
|
// 查询数据
|
|
$list = $model->with(['customerResource', 'sixSpeed'])
|
|
->order('shared_at', 'desc')
|
|
->paginate([
|
|
'list_rows' => $limit,
|
|
'page' => $page,
|
|
])->toArray();
|
|
|
|
// 处理结果数据
|
|
if (!empty($list['data'])) {
|
|
// 获取校区信息
|
|
$campus_ids = [];
|
|
foreach ($list['data'] as $item) {
|
|
if (!empty($item['customerResource']) && !empty($item['customerResource']['campus'])) {
|
|
$campus_ids[] = $item['customerResource']['campus'];
|
|
}
|
|
}
|
|
|
|
$campus_ids = array_unique($campus_ids);
|
|
$campus_names = [];
|
|
|
|
if (!empty($campus_ids)) {
|
|
$campus = new Campus();
|
|
$campus_names = $campus->whereIn('id', $campus_ids)->column('campus_name', 'id');
|
|
}
|
|
|
|
// 获取资源ID列表用于查询关联信息
|
|
$resource_ids = array_column($list['data'], 'resource_id');
|
|
$resource_ids = array_unique(array_filter($resource_ids));
|
|
|
|
// resource_sharing_id 现在直接使用 ResourceAssignment 表的 id,不需要映射
|
|
// 获取分配人员ID列表
|
|
$shared_by_ids = array_column($list['data'], 'shared_by');
|
|
$shared_by_ids = array_unique(array_filter($shared_by_ids));
|
|
|
|
// 获取市场老师ID列表
|
|
$consultant_ids = [];
|
|
foreach ($list['data'] as $item) {
|
|
if (!empty($item['customerResource']) && !empty($item['customerResource']['consultant'])) {
|
|
$consultant_ids[] = $item['customerResource']['consultant'];
|
|
}
|
|
}
|
|
$consultant_ids = array_unique(array_filter($consultant_ids));
|
|
|
|
// 查询分配人员信息
|
|
$shared_by_names = [];
|
|
if (!empty($shared_by_ids)) {
|
|
$personnel = new \app\model\personnel\Personnel();
|
|
$shared_by_names = $personnel->whereIn('id', $shared_by_ids)->column('name', 'id');
|
|
}
|
|
|
|
// 查询市场老师信息
|
|
$consultant_names = [];
|
|
if (!empty($consultant_ids)) {
|
|
$personnel = new \app\model\personnel\Personnel();
|
|
$consultant_names = $personnel->whereIn('id', $consultant_ids)->column('name', 'id');
|
|
}
|
|
|
|
// 查询销售老师信息(从资源分配表获取assigned_by=0的记录)
|
|
$sales_teachers = [];
|
|
if (!empty($resource_ids)) {
|
|
$assignment_model = new \app\model\resource_assignment\ResourceAssignment();
|
|
|
|
// 查询每个资源assigned_by=0的最新一条记录
|
|
$sales_assignments = [];
|
|
foreach ($resource_ids as $resource_id) {
|
|
$latest_assignment = $assignment_model
|
|
->where('resource_id', $resource_id)
|
|
->where('assignee_type', 'user')
|
|
->where('assigned_by', 0)
|
|
->order('assigned_at', 'desc')
|
|
->field('assignee_id')
|
|
->find();
|
|
|
|
if ($latest_assignment) {
|
|
$sales_assignments[$resource_id] = $latest_assignment['assignee_id'];
|
|
}
|
|
}
|
|
|
|
// 获取销售人员姓名
|
|
$sales_teacher_ids = array_values(array_unique(array_filter($sales_assignments)));
|
|
$sales_teacher_names = [];
|
|
if (!empty($sales_teacher_ids)) {
|
|
$personnel = new \app\model\personnel\Personnel();
|
|
$sales_teacher_names = $personnel->whereIn('id', $sales_teacher_ids)->column('name', 'id');
|
|
}
|
|
|
|
// 构建销售老师数组
|
|
foreach ($sales_assignments as $resource_id => $assignee_id) {
|
|
$sales_teachers[$resource_id] = $sales_teacher_names[$assignee_id] ?? '';
|
|
}
|
|
}
|
|
|
|
// 查询市场老师信息(从资源分配表获取assigned_source为auto_allocation或api的最新记录)
|
|
$market_teachers = [];
|
|
if (!empty($resource_ids)) {
|
|
$assignment_model = new \app\model\resource_assignment\ResourceAssignment();
|
|
|
|
// 查询每个资源assigned_source为auto_allocation或api的最新一条记录
|
|
$market_assignments = [];
|
|
foreach ($resource_ids as $resource_id) {
|
|
$latest_assignment = $assignment_model
|
|
->where('resource_id', $resource_id)
|
|
->whereIn('assigned_source', ['auto_allocation', 'api'])
|
|
->order('assigned_at', 'desc')
|
|
->field('assignee_id')
|
|
->find();
|
|
|
|
if ($latest_assignment) {
|
|
$market_assignments[$resource_id] = $latest_assignment['assignee_id'];
|
|
}
|
|
}
|
|
|
|
// 获取市场老师姓名
|
|
$market_teacher_ids = array_values(array_unique(array_filter($market_assignments)));
|
|
$market_teacher_names = [];
|
|
if (!empty($market_teacher_ids)) {
|
|
$personnel = new \app\model\personnel\Personnel();
|
|
$market_teacher_names = $personnel->whereIn('id', $market_teacher_ids)->column('name', 'id');
|
|
}
|
|
|
|
// 构建市场老师数组
|
|
foreach ($market_assignments as $resource_id => $assignee_id) {
|
|
$market_teachers[$resource_id] = $market_teacher_names[$assignee_id] ?? '';
|
|
}
|
|
}
|
|
|
|
// 查询最近沟通记录
|
|
$communication_times = [];
|
|
if (!empty($resource_ids)) {
|
|
$resource_ids = array_map('intval', $resource_ids);
|
|
$subQuery = CommunicationRecords::whereIn('resource_id', $resource_ids)
|
|
->field('resource_id, max(communication_time) as max_time')
|
|
->group('resource_id')
|
|
->select()
|
|
->toArray();
|
|
|
|
foreach ($subQuery as $item) {
|
|
$communication_times[$item['resource_id']] = $item['max_time'];
|
|
}
|
|
}
|
|
|
|
// 查询到访信息
|
|
$visit_info = [];
|
|
if (!empty($resource_ids)) {
|
|
// 需要先导入PersonCourseSchedule模型
|
|
$person_course_model = new \app\model\person_course_schedule\PersonCourseSchedule();
|
|
$visit_records = $person_course_model
|
|
->whereIn('resources_id', $resource_ids)
|
|
->where('person_type', 'customer_resource')
|
|
->field('resources_id, course_date, time_slot, status')
|
|
->order('course_date', 'desc')
|
|
->select()
|
|
->toArray();
|
|
|
|
// 处理到访信息
|
|
foreach ($visit_records as $record) {
|
|
$resource_id = $record['resources_id'];
|
|
|
|
if (!isset($visit_info[$resource_id])) {
|
|
$visit_info[$resource_id] = [
|
|
'first_visit_status' => '未到',
|
|
'second_visit_status' => '未到',
|
|
'visit_count' => 0
|
|
];
|
|
}
|
|
|
|
if ($record['status'] == 1) { // 假设status=1表示已到
|
|
$visit_info[$resource_id]['visit_count']++;
|
|
|
|
if ($visit_info[$resource_id]['visit_count'] == 1) {
|
|
$visit_info[$resource_id]['first_visit_status'] = '已到';
|
|
} elseif ($visit_info[$resource_id]['visit_count'] == 2) {
|
|
$visit_info[$resource_id]['second_visit_status'] = '已到';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 查询开单状态
|
|
$order_status = [];
|
|
if (!empty($resource_ids)) {
|
|
// 首先查询是否有付费订单
|
|
$order_model = new OrderTable();
|
|
$paid_orders = $order_model
|
|
->whereIn('resource_id', $resource_ids)
|
|
->where('order_status', 'paid')
|
|
->field('resource_id')
|
|
->select()
|
|
->toArray();
|
|
|
|
$paid_resource_ids = array_column($paid_orders, 'resource_id');
|
|
|
|
// 查询六速表的开单状态
|
|
$six_speed_model = new \app\model\six_speed\SixSpeed();
|
|
$six_speed_records = $six_speed_model
|
|
->whereIn('resource_id', $resource_ids)
|
|
->field('resource_id, is_closed')
|
|
->select()
|
|
->toArray();
|
|
|
|
// 设置每个资源的订单状态
|
|
foreach ($resource_ids as $resource_id) {
|
|
if (in_array($resource_id, $paid_resource_ids)) {
|
|
$order_status[$resource_id] = '已报名';
|
|
} else {
|
|
// 查找对应的六速记录
|
|
$six_speed_record = array_filter($six_speed_records, function($record) use ($resource_id) {
|
|
return $record['resource_id'] == $resource_id;
|
|
});
|
|
|
|
if (!empty($six_speed_record)) {
|
|
$six_speed_record = array_shift($six_speed_record);
|
|
$order_status[$resource_id] = $six_speed_record['is_closed'] ? '已开单' : '未开单';
|
|
} else {
|
|
$order_status[$resource_id] = '未报名';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 处理每条数据
|
|
foreach ($list['data'] as &$item) {
|
|
// resource_sharing_id 现在直接使用 ResourceAssignment 表的 id
|
|
$item['resource_sharing_id'] = (int) ($item['id'] ?? 0);
|
|
|
|
if (!empty($item['customerResource'])) {
|
|
// customerResource 中的 resource_sharing_id 也使用 assignment 表的 id
|
|
$item['customerResource']['resource_sharing_id'] = (int) ($item['id'] ?? 0);
|
|
// 确保数据类型转换:数据库中的数值需要转换为字符串
|
|
$source_value = (string) $item['customerResource']['source'];
|
|
$source_channel_value = (string) $item['customerResource']['source_channel'];
|
|
|
|
// 设置来源和渠道名称
|
|
$item['customerResource']['source'] = get_dict_value('source', $source_value);
|
|
$item['customerResource']['source_channel'] = get_dict_value('SourceChannel', $source_channel_value);
|
|
$item['customerResource']['campus_name'] = $campus_names[$item['customerResource']['campus']] ?? '';
|
|
|
|
// 设置市场老师名称
|
|
if (!empty($item['customerResource']['consultant'])) {
|
|
$item['customerResource']['consultant_name'] = $consultant_names[$item['customerResource']['consultant']] ?? '';
|
|
} else {
|
|
$item['customerResource']['consultant_name'] = '';
|
|
}
|
|
|
|
// 修复沟通时间字段
|
|
$item['customerResource']['communication_time'] = $communication_times[$item['resource_id']] ?? '';
|
|
|
|
// 添加到访信息
|
|
$resource_id = $item['resource_id'];
|
|
$item['customerResource']['first_visit_status'] = $visit_info[$resource_id]['first_visit_status'] ?? '未到';
|
|
$item['customerResource']['second_visit_status'] = $visit_info[$resource_id]['second_visit_status'] ?? '未到';
|
|
|
|
// 添加开单状态
|
|
$item['customerResource']['order_status'] = $order_status[$resource_id] ?? '未报名';
|
|
}
|
|
|
|
// 添加分配人员信息
|
|
$item['shared_by_name'] = $shared_by_names[$item['shared_by']] ?? '未分配';
|
|
|
|
// 判断资源是否可再分配(如果已有shared_by且不为0,说明已分配)
|
|
$item['can_reassign'] = empty($item['shared_by']) || $item['shared_by'] == 0;
|
|
}
|
|
}
|
|
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* 新的资源分配方法 - 支持用户和角色双重分配
|
|
* @param int $resource_id 资源ID
|
|
* @param string $assignee_type 分配对象类型:user/role
|
|
* @param int $assignee_id 分配对象ID
|
|
* @param bool $is_primary 是否为主责分配
|
|
* @param int|null $campus_id 校区ID
|
|
* @return array
|
|
*/
|
|
public function assignResource(int $resource_id, string $assignee_type, int $assignee_id, bool $is_primary = false, ?int $campus_id = null): array
|
|
{
|
|
$result = [
|
|
'code' => 0,
|
|
'msg' => '操作失败',
|
|
'data' => []
|
|
];
|
|
|
|
if (!in_array($assignee_type, ['user', 'role'])) {
|
|
$result['msg'] = '分配对象类型错误';
|
|
return $result;
|
|
}
|
|
|
|
if (empty($resource_id) || empty($assignee_id)) {
|
|
$result['msg'] = '缺少必要参数';
|
|
return $result;
|
|
}
|
|
|
|
$assigned_by = $this->member_id; // 当前操作用户ID
|
|
|
|
try {
|
|
// 检查是否已存在相同的分配
|
|
$existing = $this->assignmentModel
|
|
->where('resource_id', $resource_id)
|
|
->where('assignee_type', $assignee_type)
|
|
->where('assignee_id', $assignee_id)
|
|
->find();
|
|
|
|
if ($existing) {
|
|
$result['code'] = 1;
|
|
$result['msg'] = '该资源已分配给指定对象';
|
|
return $result;
|
|
}
|
|
|
|
// 创建新的分配记录
|
|
$data = [
|
|
'resource_id' => $resource_id,
|
|
'assignee_type' => $assignee_type,
|
|
'assignee_id' => $assignee_id,
|
|
'is_primary' => $is_primary ? 1 : 0,
|
|
'assigned_by' => $assigned_by,
|
|
'assigned_at' => date('Y-m-d H:i:s'),
|
|
'campus_id' => $campus_id,
|
|
'assigned_source' => 'api'
|
|
];
|
|
|
|
$assignment = $this->assignmentModel->create($data);
|
|
|
|
if ($assignment) {
|
|
$result['code'] = 1;
|
|
$result['msg'] = '分配成功';
|
|
$result['data'] = $assignment->toArray();
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
$result['msg'] = '操作失败:' . $e->getMessage();
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* 移除资源分配
|
|
* @param int $resource_id 资源ID
|
|
* @param string $assignee_type 分配对象类型:user/role
|
|
* @param int $assignee_id 分配对象ID
|
|
* @return array
|
|
*/
|
|
public function removeAssignment(int $resource_id, string $assignee_type, int $assignee_id): array
|
|
{
|
|
$result = [
|
|
'code' => 0,
|
|
'msg' => '操作失败',
|
|
'data' => []
|
|
];
|
|
|
|
try {
|
|
$deleted = $this->assignmentModel
|
|
->where('resource_id', $resource_id)
|
|
->where('assignee_type', $assignee_type)
|
|
->where('assignee_id', $assignee_id)
|
|
->delete();
|
|
|
|
if ($deleted) {
|
|
$result['code'] = 1;
|
|
$result['msg'] = '移除成功';
|
|
} else {
|
|
$result['msg'] = '未找到对应的分配记录';
|
|
}
|
|
|
|
} catch (\Exception $e) {
|
|
$result['msg'] = '操作失败:' . $e->getMessage();
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* 兼容旧接口的资源分配方法
|
|
* @param int $resource_sharing_id 现在是 ResourceAssignment 表的 ID
|
|
* @param int $shared_by 分配给的用户ID
|
|
* @return array
|
|
*/
|
|
public function assignResourceLegacy(int $resource_sharing_id, int $shared_by): array
|
|
{
|
|
// 检查 ResourceAssignment 表中是否存在该记录
|
|
$assignment_record = $this->assignmentModel->where('id', $resource_sharing_id)->find();
|
|
|
|
if (!$assignment_record) {
|
|
return [
|
|
'code' => 0,
|
|
'msg' => '资源分配记录不存在',
|
|
'data' => []
|
|
];
|
|
}
|
|
|
|
$resource_id = $assignment_record['resource_id'];
|
|
$campus_id = $assignment_record['campus_id'];
|
|
|
|
// 使用新的分配方法
|
|
return $this->assignResource($resource_id, 'user', $shared_by, true, $campus_id);
|
|
}
|
|
|
|
/**
|
|
* 确保资源的 resource_sharing_id 映射存在
|
|
* @param array $resource_ids 资源ID数组
|
|
* @return array resource_id => resource_sharing_id 的映射
|
|
*/
|
|
protected function ensureResourceSharingIdMap(array $resource_ids): array
|
|
{
|
|
$resource_sharing_map = [];
|
|
if (empty($resource_ids)) {
|
|
return $resource_sharing_map;
|
|
}
|
|
|
|
// 查询现有的 legacy 记录
|
|
$legacy_records = $this->model
|
|
->whereIn('resource_id', $resource_ids)
|
|
->order('id', 'desc')
|
|
->field('resource_id, id')
|
|
->select()
|
|
->toArray();
|
|
|
|
foreach ($legacy_records as $record) {
|
|
$resourceId = (int) ($record['resource_id'] ?? 0);
|
|
$recordId = (int) ($record['id'] ?? 0);
|
|
if ($resourceId === 0 || $recordId === 0) {
|
|
continue;
|
|
}
|
|
if (!isset($resource_sharing_map[$resourceId])) {
|
|
$resource_sharing_map[$resourceId] = $recordId;
|
|
}
|
|
}
|
|
|
|
// 对于没有 legacy 记录的资源,自动创建或使用兜底方案
|
|
foreach ($resource_ids as $resource_id) {
|
|
$resource_id = (int) $resource_id;
|
|
if (!isset($resource_sharing_map[$resource_id])) {
|
|
// 尝试创建一条新的 legacy 记录以确保兼容性
|
|
try {
|
|
$new_legacy_record = [
|
|
'resource_id' => $resource_id,
|
|
'user_id' => 0,
|
|
'role_id' => 0,
|
|
'shared_by' => 0,
|
|
'shared_at' => date('Y-m-d H:i:s'),
|
|
'created_at' => date('Y-m-d H:i:s'),
|
|
'updated_at' => date('Y-m-d H:i:s')
|
|
];
|
|
$inserted_id = $this->model->insertGetId($new_legacy_record);
|
|
if ($inserted_id) {
|
|
$resource_sharing_map[$resource_id] = (int) $inserted_id;
|
|
}
|
|
} catch (\Exception $e) {
|
|
// 如果创建失败,使用 resource_id 作为兜底(确保总有值返回)
|
|
$resource_sharing_map[$resource_id] = $resource_id;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $resource_sharing_map;
|
|
}
|
|
|
|
/**
|
|
* 获取资源的所有分配信息
|
|
* @param int $resource_id 资源ID
|
|
* @return array
|
|
*/
|
|
public function getResourceAssignments(int $resource_id): array
|
|
{
|
|
$assignments = $this->assignmentModel
|
|
->where('resource_id', $resource_id)
|
|
->order('assigned_at', 'desc')
|
|
->select()
|
|
->toArray();
|
|
|
|
// 补充分配人员和分配对象的名称信息
|
|
foreach ($assignments as &$assignment) {
|
|
// 获取分配人员名称
|
|
if ($assignment['assigned_by'] > 0) {
|
|
$personnel = new \app\model\personnel\Personnel();
|
|
$assigned_by_name = $personnel->where('id', $assignment['assigned_by'])->value('name');
|
|
$assignment['assigned_by_name'] = $assigned_by_name ?: '未知';
|
|
} else {
|
|
$assignment['assigned_by_name'] = '系统';
|
|
}
|
|
|
|
// 获取分配对象名称
|
|
if ($assignment['assignee_type'] === 'user') {
|
|
$personnel = new \app\model\personnel\Personnel();
|
|
$assignee_name = $personnel->where('id', $assignment['assignee_id'])->value('name');
|
|
$assignment['assignee_name'] = $assignee_name ?: '未知用户';
|
|
} elseif ($assignment['assignee_type'] === 'role') {
|
|
$role_name = SysRole::where('role_id', $assignment['assignee_id'])->value('role_name');
|
|
$assignment['assignee_name'] = $role_name ?: '未知角色';
|
|
}
|
|
}
|
|
|
|
return $assignments;
|
|
}
|
|
|
|
}
|
|
|