代码提交

This commit is contained in:
wong
2025-11-04 17:48:51 +08:00
parent a4060fec1b
commit adc22c7d19
11 changed files with 1444 additions and 38 deletions

View File

@@ -9,15 +9,19 @@ use think\Db;
class AutoGreetingsController extends BaseController
{
/**
* 获取问候规则列表
* @return \think\response\Json
*/
public function getList(){
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 10);
$keyword = $this->request->param('keyword', '');
$is_template = $this->request->param('is_template', 0);
$triggerType = $this->request->param('triggerType', ''); // 触发类型筛选
$userId = $this->getUserInfo('id');
$companyId = $this->getUserInfo('companyId');
if($is_template == 1){
$where = [
['is_template','=',1],
@@ -31,20 +35,46 @@ class AutoGreetingsController extends BaseController
];
}
if(!empty($keyword)){
$where[] = ['name','like','%'.$keyword.'%'];
}
if(!empty($triggerType)){
$where[] = ['trigger','=',$triggerType];
}
$query = AutoGreetings::where($where);
$total = $query->count();
$list = $query->where($where)->page($page,$limit)->order('id desc')->select();
$list = $query->where($where)->page($page,$limit)->order('level asc,id desc')->select();
// 获取使用次数
$list = is_array($list) ? $list : $list->toArray();
$ids = array_column($list, 'id');
$usageCounts = [];
if (!empty($ids)) {
$counts = Db::name('kf_auto_greetings_record')
->where('autoId', 'in', $ids)
->field('autoId, COUNT(*) as count')
->group('autoId')
->select();
foreach ($counts as $count) {
$usageCounts[$count['autoId']] = (int)$count['count'];
}
}
foreach ($list as &$item) {
$item['trigger'] = json_decode($item['trigger'],true);
$item['condition'] = json_decode($item['condition'], true);
$item['usageCount'] = $usageCounts[$item['id']] ?? 0;
// 格式化触发类型显示文本
$triggerTypes = [
1 => '新好友',
2 => '首次发消息',
3 => '时间触发',
4 => '关键词触发',
5 => '生日触发',
6 => '自定义'
];
$item['triggerText'] = $triggerTypes[$item['trigger']] ?? '未知';
}
unset($item);
@@ -52,6 +82,315 @@ class AutoGreetingsController extends BaseController
}
/**
* 校验trigger类型对应的condition
* @param int $trigger 触发类型
* @param mixed $condition 条件参数
* @return array|string 返回处理后的condition数组或错误信息字符串
*/
private function validateTriggerCondition($trigger, $condition)
{
// trigger类型1=新好友2=首次发消息3=时间触发4=关键词触发5=生日触发6=自定义
switch ($trigger) {
case 1: // 新好友
// 不需要condition
return [];
case 2: // 首次发消息
// 不需要condition
return [];
case 3: // 时间触发
// 需要condition格式为{"type": "daily_time|yearly_datetime|fixed_range|workday", "value": "..."}
if (empty($condition)) {
return '时间触发类型需要配置具体的触发条件';
}
$condition = is_array($condition) ? $condition : json_decode($condition, true);
if (empty($condition) || !is_array($condition)) {
return '时间触发类型的条件格式不正确,应为数组格式';
}
// 验证必须包含type字段
if (!isset($condition['type']) || empty($condition['type'])) {
return '时间触发类型必须指定触发方式daily_time每天固定时间、yearly_datetime每年固定日期时间、fixed_range固定时间段、workday工作日';
}
$timeType = $condition['type'];
$allowedTypes = ['daily_time', 'yearly_datetime', 'fixed_range', 'workday'];
// 兼容旧版本的 fixed_time自动转换为 daily_time
if ($timeType === 'fixed_time') {
$timeType = 'daily_time';
}
if (!in_array($timeType, $allowedTypes)) {
return '时间触发类型无效必须为daily_time每天固定时间、yearly_datetime每年固定日期时间、fixed_range固定时间段、workday工作日';
}
// 根据不同的type验证value
switch ($timeType) {
case 'daily_time': // 每天固定时间(每天的几点几分)
// value应该是时间字符串格式HH:mm如 "14:30"
if (!isset($condition['value']) || empty($condition['value'])) {
return '每天固定时间类型需要配置具体时间格式HH:mm如 14:30';
}
$timeValue = $condition['value'];
if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $timeValue)) {
return '每天固定时间格式不正确,应为 HH:mm 格式(如 14:30';
}
return [
'type' => 'daily_time',
'value' => $timeValue
];
case 'yearly_datetime': // 每年固定日期时间(每年的几月几号几点几分)
// value应该是日期时间字符串格式MM-dd HH:mm如 "12-25 14:30"
if (!isset($condition['value']) || empty($condition['value'])) {
return '每年固定日期时间类型需要配置具体日期和时间格式MM-dd HH:mm如 12-25 14:30';
}
$datetimeValue = $condition['value'];
// 验证格式MM-dd HH:mm
if (!preg_match('/^(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01]) ([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $datetimeValue)) {
return '每年固定日期时间格式不正确,应为 MM-dd HH:mm 格式(如 12-25 14:30';
}
// 进一步验证日期是否有效例如2月30日不存在
list($datePart, $timePart) = explode(' ', $datetimeValue);
list($month, $day) = explode('-', $datePart);
if (!checkdate((int)$month, (int)$day, 2000)) { // 使用2000年作为参考年份验证日期有效性
return '日期无效请检查月份和日期是否正确如2月不能有30日';
}
return [
'type' => 'yearly_datetime',
'value' => $datetimeValue
];
case 'fixed_range': // 固定时间段
// value应该是时间段数组格式["09:00", "18:00"]
if (!isset($condition['value']) || !is_array($condition['value'])) {
return '固定时间段类型需要配置时间段,格式:["开始时间", "结束时间"](如 ["09:00", "18:00"]';
}
$rangeValue = $condition['value'];
if (count($rangeValue) !== 2) {
return '固定时间段应为包含两个时间点的数组,格式:["09:00", "18:00"]';
}
// 验证时间格式
foreach ($rangeValue as $time) {
if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $time)) {
return '时间段格式不正确,应为 HH:mm 格式(如 09:00';
}
}
// 验证开始时间小于结束时间
$startTime = strtotime('2000-01-01 ' . $rangeValue[0]);
$endTime = strtotime('2000-01-01 ' . $rangeValue[1]);
if ($startTime >= $endTime) {
return '开始时间必须小于结束时间';
}
return [
'type' => 'fixed_range',
'value' => $rangeValue
];
case 'workday': // 工作日
// 工作日需要配置时间格式HH:mm如 09:00
if (!isset($condition['value']) || empty($condition['value'])) {
return '工作日触发类型需要配置时间格式HH:mm如 09:00';
}
$timeValue = trim($condition['value']);
// 验证格式HH:mm
if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $timeValue)) {
return '工作日时间格式不正确,应为 HH:mm 格式(如 09:00';
}
return [
'type' => 'workday',
'value' => $timeValue
];
default:
return '时间触发类型无效';
}
case 4: // 关键词触发
// 需要condition格式{"keywords": ["关键词1", "关键词2"], "match_type": "exact|fuzzy"}
if (empty($condition)) {
return '关键词触发类型需要配置至少一个关键词';
}
// 如果是字符串尝试解析JSON
if (is_string($condition)) {
$decoded = json_decode($condition, true);
if (json_last_error() === JSON_ERROR_NONE) {
$condition = $decoded;
} else {
return '关键词触发类型格式错误,应为对象格式:{"keywords": ["关键词1", "关键词2"], "match_type": "exact|fuzzy"}';
}
}
// 必须是对象格式
if (!is_array($condition) || !isset($condition['keywords'])) {
return '关键词触发类型格式错误,应为对象格式:{"keywords": ["关键词1", "关键词2"], "match_type": "exact|fuzzy"}';
}
$keywords = $condition['keywords'];
$matchType = isset($condition['match_type']) ? $condition['match_type'] : 'fuzzy';
// 验证match_type
if (!in_array($matchType, ['exact', 'fuzzy'])) {
return '匹配类型无效必须为exact精准匹配或 fuzzy模糊匹配';
}
// 处理keywords
if (is_string($keywords)) {
$keywords = explode(',', $keywords);
}
if (!is_array($keywords)) {
return '关键词格式不正确,应为数组格式';
}
// 过滤空值并去重
$keywords = array_filter(array_map('trim', $keywords));
if (empty($keywords)) {
return '关键词触发类型需要配置至少一个关键词';
}
// 验证每个关键词不为空
foreach ($keywords as $keyword) {
if (empty($keyword)) {
return '关键词不能为空';
}
}
return [
'keywords' => array_values($keywords),
'match_type' => $matchType
];
case 5: // 生日触发
// 需要condition格式支持
// 1. 月日字符串:'10-10' 或 '10-10 09:00'MM-DD格式不包含年份
// 2. 对象格式:{'month': 10, 'day': 10, 'time': '09:00'} 或 {'month': '10', 'day': '10', 'time_range': ['09:00', '10:00']}
if (empty($condition)) {
return '生日触发类型需要配置日期条件';
}
// 如果是字符串,只接受 MM-DD 格式(不包含年份)
if (is_string($condition)) {
// 检查是否包含时间部分
if (preg_match('/^(\d{1,2})-(\d{1,2})\s+(\d{2}:\d{2})$/', $condition, $matches)) {
// 格式:'10-10 09:00'
$month = (int)$matches[1];
$day = (int)$matches[2];
if ($month < 1 || $month > 12 || $day < 1 || $day > 31) {
return '生日日期格式不正确月份应为1-12日期应为1-31';
}
return [
'month' => $month,
'day' => $day,
'time' => $matches[3]
];
} elseif (preg_match('/^(\d{1,2})-(\d{1,2})$/', $condition, $matches)) {
// 格式:'10-10'(不指定时间,当天任何时间都可以触发)
$month = (int)$matches[1];
$day = (int)$matches[2];
if ($month < 1 || $month > 12 || $day < 1 || $day > 31) {
return '生日日期格式不正确月份应为1-12日期应为1-31';
}
return [
'month' => $month,
'day' => $day
];
} else {
return '生日日期格式不正确,应为 MM-DD 或 MM-DD HH:mm 格式(如 10-10 或 10-10 09:00不包含年份';
}
}
// 如果是数组,可能是对象格式或旧格式
if (is_array($condition)) {
// 检查是否是旧格式(仅兼容 MM-DD 格式的数组)
if (isset($condition[0]) && is_string($condition[0])) {
$dateStr = $condition[0];
// 只接受 MM-DD 格式:'10-10' 或 '10-10 09:00'
if (preg_match('/^(\d{1,2})-(\d{1,2})(?:\s+(\d{2}:\d{2}))?$/', $dateStr, $matches)) {
$month = (int)$matches[1];
$day = (int)$matches[2];
if ($month < 1 || $month > 12 || $day < 1 || $day > 31) {
return '生日日期格式不正确月份应为1-12日期应为1-31';
}
if (isset($matches[3])) {
return [
'month' => $month,
'day' => $day,
'time' => $matches[3]
];
} else {
return [
'month' => $month,
'day' => $day
];
}
} else {
return '生日日期格式不正确,应为 MM-DD 格式(如 10-10不包含年份';
}
}
// 新格式:{'month': 10, 'day': 10, 'time': '09:00'}
if (isset($condition['month']) && isset($condition['day'])) {
$month = (int)$condition['month'];
$day = (int)$condition['day'];
if ($month < 1 || $month > 12) {
return '生日月份格式不正确应为1-12';
}
if ($day < 1 || $day > 31) {
return '生日日期格式不正确应为1-31';
}
$result = [
'month' => $month,
'day' => $day
];
// 检查是否配置了时间
if (isset($condition['time']) && !empty($condition['time'])) {
$time = trim($condition['time']);
if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $time)) {
return '生日时间格式不正确,应为 HH:mm 格式(如 09:00';
}
$result['time'] = $time;
}
// 检查是否配置了时间范围
if (isset($condition['time_range']) && is_array($condition['time_range']) && count($condition['time_range']) === 2) {
$startTime = trim($condition['time_range'][0]);
$endTime = trim($condition['time_range'][1]);
if (!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $startTime) ||
!preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $endTime)) {
return '生日时间范围格式不正确,应为 ["HH:mm", "HH:mm"] 格式';
}
$result['time_range'] = [$startTime, $endTime];
}
return $result;
}
return '生日触发条件格式不正确需要提供month和day字段';
}
return '生日触发条件格式不正确';
case 6: // 自定义
// 自定义类型condition可选如果有则必须是数组格式
if (!empty($condition)) {
$condition = is_array($condition) ? $condition : json_decode($condition, true);
if (!is_array($condition)) {
return '自定义类型的条件格式不正确,应为数组格式';
}
return $condition;
}
return [];
default:
return '无效的触发类型';
}
}
/**
* 添加
* @return \think\response\Json
@@ -71,17 +410,18 @@ class AutoGreetingsController extends BaseController
return ResponseHelper::error('参数缺失');
}
if (in_array($trigger,[2,3]) && empty($condition)){
return ResponseHelper::error('具体条件不能为空');
// 校验trigger类型
if (!in_array($trigger, [1, 2, 3, 4, 5, 6])) {
return ResponseHelper::error('无效的触发类型');
}
if ($trigger == 2){
$condition = !empty($condition) ? $condition : [];
}
if ($trigger == 3){
$condition = explode(',',$condition);
// 校验并处理condition
$conditionResult = $this->validateTriggerCondition($trigger, $condition);
if (is_string($conditionResult)) {
// 返回的是错误信息
return ResponseHelper::error($conditionResult);
}
$condition = $conditionResult;
Db::startTrans();
@@ -97,9 +437,10 @@ class AutoGreetingsController extends BaseController
$AutoGreetings->companyId = $companyId;
$AutoGreetings->updateTime = time();
$AutoGreetings->createTime = time();
$AutoGreetings->usageCount = 0; // 初始化使用次数为0
$AutoGreetings->save();
Db::commit();
return ResponseHelper::success(' ','创建成功');
return ResponseHelper::success(['id' => $AutoGreetings->id],'创建成功');
} catch (\Exception $e) {
Db::rollback();
return ResponseHelper::error('创建失败:'.$e->getMessage());
@@ -128,11 +469,13 @@ class AutoGreetingsController extends BaseController
$data['condition'] = json_decode($data['condition'],true);
if ($data['trigger'] == 3){
$data['condition'] = implode(',',$data['condition']);
}
// 获取使用次数
$usageCount = Db::name('kf_auto_greetings_record')
->where('autoId', $id)
->count();
$data['usageCount'] = (int)$usageCount;
unset($data['createTime'],$data['updateTime'],$data['isDel'],$data['delTime']);
return ResponseHelper::success($data,'获取成功');
}
@@ -175,7 +518,7 @@ class AutoGreetingsController extends BaseController
$id = $this->request->param('id', '');
$name = $this->request->param('name', '');
$trigger = $this->request->param('trigger', 0);
$condition = $this->request->param('condition', []);
$condition = $this->request->param('condition', '');
$content = $this->request->param('content', '');
$level = $this->request->param('level', 0);
$status = $this->request->param('status', 1);
@@ -186,17 +529,18 @@ class AutoGreetingsController extends BaseController
return ResponseHelper::error('参数缺失');
}
if (in_array($trigger,[2,3]) && empty($condition)){
return ResponseHelper::error('具体条件不能为空');
// 校验trigger类型
if (!in_array($trigger, [1, 2, 3, 4, 5, 6])) {
return ResponseHelper::error('无效的触发类型');
}
if ($trigger == 2){
$condition = !empty($condition) ? $condition : [];
}
if ($trigger == 3){
$condition = explode(',',$condition);
// 校验并处理condition
$conditionResult = $this->validateTriggerCondition($trigger, $condition);
if (is_string($conditionResult)) {
// 返回的是错误信息
return ResponseHelper::error($conditionResult);
}
$condition = $conditionResult;
$query = AutoGreetings::where(['id'=>$id,'isDel' => 0,'userId' => $userId,'companyId' => $companyId])->find();
@@ -244,11 +588,16 @@ class AutoGreetingsController extends BaseController
}
Db::startTrans();
try {
$query->status = !empty($query['status']) ? 0 : 1;
$status = $this->request->param('status', '');
if ($status !== '') {
$query->status = (int)$status;
} else {
$query->status = $query->status == 1 ? 0 : 1;
}
$query->updateTime = time();
$query->save();
Db::commit();
return ResponseHelper::success(' ','修改成功');
return ResponseHelper::success(['status' => $query->status],'修改成功');
} catch (\Exception $e) {
Db::rollback();
return ResponseHelper::error('修改失败:'.$e->getMessage());