智慧教务系统
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.
 
 
 
 
 
 

289 lines
8.7 KiB

<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址:https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\admin\contract;
use app\model\contract\Contract;
use app\model\contract_sign\ContractSign;
use app\model\personnel\Personnel;
use app\model\member\Member;
use core\base\BaseAdminService;
use think\facade\Db;
/**
* 合同分发服务类
* Class ContractDistributionService
* @package app\service\admin\contract
*/
class ContractDistributionService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new ContractSign();
}
/**
* 手动分发合同
* @param int $contractId 合同ID
* @param array $personnelIds 人员ID数组
* @param int $type 人员类型:1内部员工,2外部会员
* @return bool
*/
public function manualDistribute(int $contractId, array $personnelIds, int $type = 1): bool
{
// 验证合同是否存在
$contract = (new Contract())->find($contractId);
if (!$contract) {
throw new \Exception('合同不存在');
}
if (empty($personnelIds)) {
throw new \Exception('人员列表不能为空');
}
// 验证人员是否存在
$this->validatePersonnel($personnelIds, $type);
// 开启事务
Db::startTrans();
try {
foreach ($personnelIds as $personnelId) {
// 检查是否已经分发过
$exists = $this->model->where([
['contract_id', '=', $contractId],
['personnel_id', '=', $personnelId],
['type', '=', $type]
])->findOrEmpty();
if (!$exists->isEmpty()) {
continue; // 跳过已分发的
}
$data = [
'contract_id' => $contractId,
'personnel_id' => $personnelId,
'type' => $type,
'status' => 'pending',
'source_type' => 'manual',
'source_id' => null,
'created_at' => time()
];
$this->model->create($data);
}
Db::commit();
return true;
} catch (\Exception $e) {
Db::rollback();
throw $e;
}
}
/**
* 自动分发合同(课程购买触发)
* @param int $contractId 合同ID
* @param int $memberId 会员ID
* @param int $sourceId 来源ID(如课程ID、订单ID)
* @param string $sourceType 来源类型
* @return bool
*/
public function autoDistribute(int $contractId, int $memberId, int $sourceId, string $sourceType = 'auto_course'): bool
{
// 验证合同是否存在
$contract = (new Contract())->find($contractId);
if (!$contract) {
throw new \Exception('合同不存在');
}
// 验证会员是否存在
$member = (new Member())->find($memberId);
if (!$member) {
throw new \Exception('会员不存在');
}
// 检查是否已经分发过
$exists = $this->model->where([
['contract_id', '=', $contractId],
['personnel_id', '=', $memberId],
['type', '=', 2], // 外部会员
['source_type', '=', $sourceType],
['source_id', '=', $sourceId]
])->findOrEmpty();
if (!$exists->isEmpty()) {
return true; // 已分发过,直接返回成功
}
$data = [
'contract_id' => $contractId,
'personnel_id' => $memberId,
'type' => 2, // 外部会员
'status' => 'pending',
'source_type' => $sourceType,
'source_id' => $sourceId,
'created_at' => time()
];
$result = $this->model->create($data);
return !empty($result);
}
/**
* 批量分发合同
* @param array $distributions 分发配置数组
* @return bool
*/
public function batchDistribute(array $distributions): bool
{
if (empty($distributions)) {
throw new \Exception('分发配置不能为空');
}
Db::startTrans();
try {
foreach ($distributions as $distribution) {
$contractId = $distribution['contract_id'] ?? 0;
$personnelIds = $distribution['personnel_ids'] ?? [];
$type = $distribution['type'] ?? 1;
if ($contractId && !empty($personnelIds)) {
$this->manualDistribute($contractId, $personnelIds, $type);
}
}
Db::commit();
return true;
} catch (\Exception $e) {
Db::rollback();
throw $e;
}
}
/**
* 获取分发记录列表
* @param array $where 查询条件
* @return array
*/
public function getDistributionList(array $where = []): array
{
$field = 'id, contract_id, personnel_id, type, status, source_type, source_id, created_at, sign_time, signature_image';
$order = 'created_at desc';
$search_model = $this->model
->withSearch(['contract_id', 'personnel_id', 'type', 'status', 'source_type'], $where)
->field($field)
->order($order);
$list = $this->pageQuery($search_model, $where);
// 关联合同和人员信息
if (!empty($list['data'])) {
$this->attachRelationInfo($list['data']);
}
return $list;
}
/**
* 取消分发
* @param int $id 分发记录ID
* @return bool
*/
public function cancelDistribution(int $id): bool
{
$info = $this->model->find($id);
if (!$info) {
throw new \Exception('分发记录不存在');
}
if ($info['status'] === 'signed') {
throw new \Exception('已签署的合同不能取消分发');
}
$result = $info->delete();
return !empty($result);
}
/**
* 验证人员是否存在
* @param array $personnelIds 人员ID数组
* @param int $type 人员类型
* @throws \Exception
*/
private function validatePersonnel(array $personnelIds, int $type): void
{
if ($type === 1) {
// 内部员工
$count = (new Personnel())->whereIn('id', $personnelIds)->count();
} else {
// 外部会员
$count = (new Member())->whereIn('id', $personnelIds)->count();
}
if ($count !== count($personnelIds)) {
throw new \Exception('部分人员不存在');
}
}
/**
* 关联合同和人员信息
* @param array $list 分发记录列表
*/
private function attachRelationInfo(array &$list): void
{
// 获取合同信息
$contractIds = array_unique(array_column($list, 'contract_id'));
$contracts = (new Contract())->whereIn('id', $contractIds)->column('name', 'id');
// 获取人员信息
$personnelData = $this->getPersonnelInfo($list);
foreach ($list as &$item) {
$item['contract_name'] = $contracts[$item['contract_id']] ?? '';
$item['personnel_name'] = $personnelData[$item['type']][$item['personnel_id']] ?? '';
}
}
/**
* 获取人员信息
* @param array $list 分发记录列表
* @return array
*/
private function getPersonnelInfo(array $list): array
{
$personnelData = [1 => [], 2 => []];
// 分类收集人员ID
$staffIds = [];
$memberIds = [];
foreach ($list as $item) {
if ($item['type'] === 1) {
$staffIds[] = $item['personnel_id'];
} else {
$memberIds[] = $item['personnel_id'];
}
}
// 查询员工信息
if (!empty($staffIds)) {
$personnelData[1] = (new Personnel())->whereIn('id', array_unique($staffIds))->column('name', 'id');
}
// 查询会员信息
if (!empty($memberIds)) {
$personnelData[2] = (new Member())->whereIn('id', array_unique($memberIds))->column('nickname', 'id');
}
return $personnelData;
}
}