Files
cunkebao_v3/Server/application/chukebao/controller/WechatGroupController.php
Manus AI 5182529a58 sync(本地→GitHub): 2026-05-30 21:41 全量单向同步
## GitHub 同步说明

| 项 | 内容 |
|:---|:---|
| 仓库 | https://github.com/fnvtk/cunkebao_v3 |
| 分支 | develop |
| 方向 | 本地 → GitHub(单向 push) |
| 是否拉取远程 | 否(未 fetch / pull / merge) |
| 是否改本地文件 | 否(仅 git add/commit,未编辑任何源文件正文) |
| 基准 commit | 0643e78a |
| 变更规模 | 709 files, +26436 / -3407 lines |

## 目录变更统计

| 目录 | 文件数 | 说明 |
|:---|---:|:---|
| 开发文档/ | 404 | 四端进行中/已完成需求、接口文档、官网需求、部署脚本 |
| Server/ | 95 | 后端 API、迁移脚本、触客宝/超管/存客宝服务 |
| Cunkebao/ | 85 | 移动端 H5、设备绑定、客服、转号审批等 |
| Touchkebao/ | 68 | PC 工作台、AI 获客、算力中心、Glass UI |
| SuperAdmin/ | 33 | 超管项目中心、算力计费、内容库 |
| 官网/ | 19 | 新增存客宝官网静态页(index/pricing/solutions 等) |
| .cursor/ | 3 | Cursor 规则与 Skill |
| .obsidian/ | 2 | Obsidian 工作区配置 |

## 重点新增/更新(本地为准)

- 官网/: 完整静态站点(index、pricing、manual、solutions、api)
- 开发文档/1、需求/修改/*_进行中_20260530.md(存客宝/触客宝/AI数智员工)
- 开发文档/1、需求/官网需求.md
- 开发文档/5、接口/开发进度_接口文档.md 等接口文档迭代
- Touchkebao Glass UI 与 P0 收尾、通道获客算力
- SuperAdmin 算力计费规则、项目工作台

## 刻意未上传(本地保留)

- node_modules/
- .DS_Store、.smart-env/
- .开发文档_nested_git_backup/(旧嵌套 git 备份)
- **/__pycache__/

## 验收

GitHub 浏览: https://github.com/fnvtk/cunkebao_v3/tree/develop

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-30 21:41:40 +08:00

282 lines
9.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\chukebao\controller;
use library\ResponseHelper;
use think\Db;
use app\chukebao\model\ChatGroups;
class WechatGroupController extends BaseController
{
/**
* 获取分组列表
* @return \think\response\Json
* @throws \Exception
*/
public function getList()
{
// 公司维度分组,不强制校验 userId
$companyId = $this->getUserInfo('companyId');
$query = ChatGroups::where([
'companyId' => $companyId,
'isDel' => 0,
])
->order('groupType desc,sort desc,id desc');
$total = $query->count();
$list = $query->select();
// 处理每个分组的数据
$list = is_array($list) ? $list : $list->toArray();
foreach ($list as $k => &$v) {
$v['createTime'] = !empty($v['createTime']) ? date('Y-m-d H:i:s', $v['createTime']) : '';
}
unset($v);
return ResponseHelper::success(['list'=>$list,'total'=>$total]);
}
/**
* 新增分组
* @return \think\response\Json
* @throws \Exception
*/
public function create()
{
$groupName = $this->request->param('groupName', '');
$groupMemo = $this->request->param('groupMemo', '');
$groupType = $this->request->param('groupType', 1);
$sort = $this->request->param('sort', 0);
$companyId = $this->getUserInfo('companyId');
// 只校验公司维度
if (empty($companyId)) {
return ResponseHelper::error('请先登录');
}
if (empty($groupName)) {
return ResponseHelper::error('分组名称不能为空');
}
// 验证分组类型
if (!in_array($groupType, [1, 2])) {
return ResponseHelper::error('无效的分组类型');
}
Db::startTrans();
try {
$chatGroup = new ChatGroups();
$chatGroup->groupName = $groupName;
$chatGroup->groupMemo = $groupMemo;
$chatGroup->groupType = $groupType;
$chatGroup->sort = $sort;
$chatGroup->userId = $this->getUserInfo('id');
$chatGroup->companyId = $companyId;
$chatGroup->createTime = time();
$chatGroup->isDel = 0;
$chatGroup->save();
Db::commit();
return ResponseHelper::success(['id' => $chatGroup->id], '创建成功');
} catch (\Exception $e) {
Db::rollback();
return ResponseHelper::error('创建失败:' . $e->getMessage());
}
}
/**
* 更新分组
* @return \think\response\Json
* @throws \Exception
*/
public function update()
{
$id = $this->request->param('id', 0);
$groupName = $this->request->param('groupName', '');
$groupMemo = $this->request->param('groupMemo', '');
$groupType = $this->request->param('groupType', 1);
$sort = $this->request->param('sort', 0);
$companyId = $this->getUserInfo('companyId');
if (empty($companyId)) {
return ResponseHelper::error('请先登录');
}
if (empty($id)) {
return ResponseHelper::error('参数缺失');
}
if (empty($groupName)) {
return ResponseHelper::error('分组名称不能为空');
}
// 验证分组类型
if (!in_array($groupType, [1, 2])) {
return ResponseHelper::error('无效的分组类型');
}
// 检查分组是否存在
$chatGroup = ChatGroups::where([
'id' => $id,
'companyId' => $companyId,
'isDel' => 0,
])->find();
if (empty($chatGroup)) {
return ResponseHelper::error('该分组不存在或已删除');
}
Db::startTrans();
try {
$chatGroup->groupName = $groupName;
$chatGroup->groupMemo = $groupMemo;
$chatGroup->groupType = $groupType;
$chatGroup->sort = $sort;
$chatGroup->save();
Db::commit();
return ResponseHelper::success('', '更新成功');
} catch (\Exception $e) {
Db::rollback();
return ResponseHelper::error('更新失败:' . $e->getMessage());
}
}
/**
* 删除分组(假删除)
* @return \think\response\Json
* @throws \Exception
*/
public function delete()
{
$id = $this->request->param('id', 0);
$companyId = $this->getUserInfo('companyId');
if (empty($companyId)) {
return ResponseHelper::error('请先登录');
}
if (empty($id)) {
return ResponseHelper::error('参数缺失');
}
// 检查分组是否存在
$chatGroup = ChatGroups::where([
'id' => $id,
'companyId' => $companyId,
'isDel' => 0,
])->find();
if (empty($chatGroup)) {
// 幂等:已软删则视为成功,避免前端缓存重复删报「不存在」
$alreadyDeleted = ChatGroups::where([
'id' => $id,
'companyId' => $companyId,
'isDel' => 1,
])->find();
if (!empty($alreadyDeleted)) {
return ResponseHelper::success('', '删除成功');
}
return ResponseHelper::error('该分组不存在或已删除');
}
Db::startTrans();
try {
// 1. 假删除当前分组
$chatGroup->isDel = 1;
$chatGroup->deleteTime = time();
$chatGroup->save();
// 2. 重置该分组下所有好友的分组IDs2_wechat_friend.groupIds -> 0
Db::table('s2_wechat_friend')
->where('groupIds', $id)
->update(['groupIds' => 0]);
// 3. 重置该分组下所有微信群的分组IDs2_wechat_chatroom.groupIds -> 0
Db::table('s2_wechat_chatroom')
->where('groupIds', $id)
->update(['groupIds' => 0]);
Db::commit();
return ResponseHelper::success('', '删除成功');
} catch (\Exception $e) {
Db::rollback();
return ResponseHelper::error('删除失败:' . $e->getMessage());
}
}
/**
* 移动分组(将好友或群移动到指定分组)
* @return \think\response\Json
* @throws \Exception
*/
public function move()
{
// type: friend 好友, chatroom 群
$type = $this->request->param('type', 'friend');
$targetId = (int)$this->request->param('groupId', 0);
// 仅支持单个ID移动
$idParam = $this->request->param('id', 0);
$companyId = $this->getUserInfo('companyId');
if (empty($companyId)) {
return ResponseHelper::error('请先登录');
}
if (empty($targetId)) {
return ResponseHelper::error('目标分组ID不能为空');
}
// 仅允许单个 ID禁止批量
$moveId = (int)$idParam;
if (empty($moveId)) {
return ResponseHelper::error('需要移动的ID不能为空');
}
// 校验目标分组是否存在且属于当前公司
$targetGroup = ChatGroups::where([
'id' => $targetId,
'companyId' => $companyId,
'isDel' => 0,
])->find();
if (empty($targetGroup)) {
return ResponseHelper::error('目标分组不存在或已删除');
}
// 校验分组类型与移动对象类型是否匹配
// groupType: 1=好友分组, 2=群分组
if ($type === 'friend' && (int)$targetGroup->groupType !== 1) {
return ResponseHelper::error('目标分组类型错误(需要好友分组)');
}
if ($type === 'chatroom' && (int)$targetGroup->groupType !== 2) {
return ResponseHelper::error('目标分组类型错误(需要群分组)');
}
Db::startTrans();
try {
if ($type === 'friend') {
// 移动单个好友到指定分组:更新 s2_wechat_friend.groupIds
Db::table('s2_wechat_friend')
->where('id', $moveId)
->update(['groupIds' => $targetId]);
} elseif ($type === 'chatroom') {
// 移动单个群到指定分组:更新 s2_wechat_chatroom.groupIds
Db::table('s2_wechat_chatroom')
->where('id', $moveId)
->update(['groupIds' => $targetId]);
} else {
Db::rollback();
return ResponseHelper::error('无效的类型参数');
}
Db::commit();
return ResponseHelper::success('', '移动成功');
} catch (\Exception $e) {
Db::rollback();
return ResponseHelper::error('移动失败:' . $e->getMessage());
}
}
}