Merge branch 'develop' into yongpxu-dev

# Conflicts:
#	Server/application/cunkebao/controller/plan/PostCreateAddFriendPlanV1Controller.php   resolved by develop version
#	Server/application/cunkebao/controller/plan/PostUpdateAddFriendPlanV1Controller.php   resolved by develop version
This commit is contained in:
笔记本里的永平
2025-07-17 10:20:28 +08:00
8 changed files with 437 additions and 111 deletions

View File

@@ -46,28 +46,28 @@ class AutomaticAssign extends BaseController
}
$params = [
'accountKeyword' => '',
'addFrom' => [],
'allotAccountId' => '',
'containAllLabel' => false,
'containSubDepartment' => false,
'departmentId' => '',
'extendFields' => [],
'friendKeyword' => '',
'friendPhoneKeyword' => '',
'friendPinYinKeyword' => '',
'friendRegionKeyword' => '',
'friendRemarkKeyword' => '',
'gender' => '',
'groupId' => null,
'isByRule' => false,
'accountKeyword' => !empty($data['accountKeyword']) ? $data['accountKeyword'] : '',
'addFrom' => !empty($data['addFrom']) ? $data['addFrom'] : [],
'allotAccountId' => !empty($data['allotAccountId']) ? $data['allotAccountId'] : '',
'containAllLabel' => !empty($data['containAllLabel']) ? $data['containAllLabel'] : false,
'containSubDepartment' => !empty($data['containSubDepartment']) ? $data['containSubDepartment'] : false,
'departmentId' => !empty($data['departmentId']) ? $data['departmentId'] : '',
'extendFields' => !empty($data['extendFields']) ? $data['extendFields'] : [],
'friendKeyword' => !empty($data['friendKeyword']) ? $data['friendKeyword'] : '',
'friendPhoneKeyword' => !empty($data['friendPhoneKeyword']) ? $data['friendPhoneKeyword'] : '',
'friendPinYinKeyword' => !empty($data['friendPinYinKeyword']) ? $data['friendPinYinKeyword'] : '',
'friendRegionKeyword' => !empty($data['friendRegionKeyword']) ? $data['friendRegionKeyword'] : '',
'friendRemarkKeyword' => !empty($data['friendRemarkKeyword']) ? $data['friendRemarkKeyword'] : '',
'gender' => !empty($data['gender']) ? $data['gender'] : '',
'groupId' => !empty($data['groupId']) ? $data['groupId'] : null,
'isByRule' => !empty($data['isByRule']) ? $data['isByRule'] : false,
'isDeleted' => $isDeleted,
'isPass' => true,
'keyword' => '',
'labels' => [],
'pageIndex' => 0,
'pageSize' => 100,
'preFriendId' => '',
'isPass' => !empty($data['isPass']) ? $data['isPass'] : true,
'keyword' => !empty($data['keyword']) ? $data['keyword'] : '',
'labels' => !empty($data['labels']) ? $data['labels'] : [],
'pageIndex' => !empty($data['pageIndex']) ? $data['pageIndex'] : 0,
'pageSize' => !empty($data['pageSize']) ? $data['pageSize'] : 100,
'preFriendId' => !empty($data['preFriendId']) ? $data['preFriendId'] : '',
'toAccountId' => $toAccountId,
'wechatAccountKeyword' => $wechatAccountKeyword
];
@@ -282,4 +282,64 @@ class AutomaticAssign extends BaseController
}
/**
* 分配搜索结果
* @param array $data 请求参数
* @return \think\response\Json
*/
public function allotSearchResult($data = [])
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}
try {
$params = [
'accountKeyword' => !empty($data['accountKeyword']) ? $data['accountKeyword'] : '',
'addFrom' => !empty($data['addFrom']) ? $data['addFrom'] : [],
'allotAccountId' => !empty($data['allotAccountId']) ? $data['allotAccountId'] : '',
'containAllLabel' => !empty($data['containAllLabel']) ? $data['containAllLabel'] : false,
'containSubDepartment' => !empty($data['containSubDepartment']) ? $data['containSubDepartment'] : false,
'departmentId' => !empty($data['departmentId']) ? $data['departmentId'] : '',
'extendFields' => !empty($data['extendFields']) ? json_encode($data['extendFields']) : json_encode([]),
'friendKeyword' => !empty($data['friendKeyword']) ? $data['friendKeyword'] : '',
'friendPhoneKeyword' => !empty($data['friendPhoneKeyword']) ? $data['friendPhoneKeyword'] : '',
'friendPinYinKeyword' => !empty($data['friendPinYinKeyword']) ? $data['friendPinYinKeyword'] : '',
'friendRegionKeyword' => !empty($data['friendRegionKeyword']) ? $data['friendRegionKeyword'] : '',
'friendRemarkKeyword' => !empty($data['friendRemarkKeyword']) ? $data['friendRemarkKeyword'] : '',
'gender' => !empty($data['gender']) ? $data['gender'] : '',
'groupId' => !empty($data['groupId']) ? $data['groupId'] : null,
'isByRule' => !empty($data['isByRule']) ? $data['isByRule'] : false,
'isDeleted' => !empty($data['isDeleted']) ? $data['isDeleted'] : false,
'isPass' => !empty($data['isPass']) ? $data['isPass'] : true,
'keyword' => !empty($data['keyword']) ? $data['keyword'] : '',
'labels' => !empty($data['labels']) ? $data['labels'] : [],
'pageIndex' => !empty($data['pageIndex']) ? $data['pageIndex'] : 0,
'pageSize' => !empty($data['pageSize']) ? $data['pageSize'] : 20,
'preFriendId' => !empty($data['preFriendId']) ? $data['preFriendId'] : '',
'toAccountId' => !empty($data['toAccountId']) ? $data['toAccountId'] : '',
'wechatAccountKeyword' => !empty($data['wechatAccountKeyword']) ? $data['wechatAccountKeyword'] : ''
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求
$result = requestCurl($this->baseUrl . 'api/WechatFriend/allotSearchResult', $params, 'POST', $header, 'json');
$response = handleApiResponse($result);
if($response){
return json_encode(['code'=>200,'msg'=>'分配成功']);
}else{
return json_encode(['code'=>500,'msg'=>$response]);
}
} catch (\Exception $e) {
return json_encode(['code'=>500,'msg'=>'微信好友分配失败:' . $e->getMessage()]);
}
}
}

View File

@@ -23,6 +23,7 @@ class PlanSceneV1Controller extends BaseController
$params = $this->request->param();
$page = isset($params['page']) ? intval($params['page']) : 1;
$limit = isset($params['limit']) ? intval($params['limit']) : 10;
$keyword = isset($params['keyword']) ? trim($params['keyword']) : '';
$sceneId = $this->request->param('sceneId','');
$where = [
'deleteTime' => 0,
@@ -37,6 +38,10 @@ class PlanSceneV1Controller extends BaseController
$where['sceneId'] = $sceneId;
}
if(!empty($keyword)){
$where[] = ['name', 'like', '%' . $keyword . '%'];
}
$total = Db::name('customer_acquisition_task')->where($where)->count();
$list = Db::name('customer_acquisition_task')
@@ -62,7 +67,7 @@ class PlanSceneV1Controller extends BaseController
$val['passRate'] = number_format($passRate,2);
}
$lastTime = Db::name('task_customer')->where(['task_id'=>$val['id']])->max('updated_at');
$lastTime = Db::name('task_customer')->where(['task_id'=>$val['id']])->max('updateTime');
$val['lastUpdated'] = !empty($lastTime) ? date('Y-m-d H:i', $lastTime) : '--';
@@ -379,7 +384,13 @@ class PlanSceneV1Controller extends BaseController
}
/**
* 获取微信小程序码
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getWxMinAppCode()
{
$params = $this->request->param();
@@ -399,4 +410,62 @@ class PlanSceneV1Controller extends BaseController
return ResponseHelper::success($result, '获取小程序码成功');
}
/**
* 获取已获客/已添加用户
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getUserList(){
$type = $this->request->param('type',1);
$planId = $this->request->param('planId','');
$page = $this->request->param('page',1);
$pageSize = $this->request->param('pageSize',10);
$keyword = $this->request->param('keyword','');
if (!in_array($type, [1, 2])) {
return ResponseHelper::error('类型错误');
}
if (empty($planId)){
return ResponseHelper::error('获客场景id不能为空');
}
$task = Db::name('customer_acquisition_task')->where(['id' => $planId, 'deleteTime' => 0])->find();
if(empty($task)) {
return ResponseHelper::error('活动不存在');
}
$query = Db::name('task_customer')->where(['task_id' => $task['id']]);
if ($type == 2){
$query = $query->where('status',4);
}
if (!empty($keyword)) {
$query = $query->where('name|phone|tags|siteTags', 'like', '%' . $keyword . '%');
}
$total = $query->count();
$list = $query->page($page, $pageSize)->order('id', 'desc')->select();
foreach ($list as &$item) {
$item['tags'] = json_decode($item['tags'], true);
$item['siteTags'] = json_decode($item['siteTags'], true);
$item['createTime'] = date('Y-m-d H:i:s', $item['createTime']);
$item['updateTime'] = date('Y-m-d H:i:s', $item['updateTime']);
}
$data = [
'total' => $total,
'list' => $list,
];
return ResponseHelper::success($data,'获取成功');
}
}

View File

@@ -13,10 +13,6 @@ use think\facade\Request;
class PostCreateAddFriendPlanV1Controller extends Controller
{
protected function yyyyyyy()
{
}
/**
* 生成唯一API密钥
@@ -60,6 +56,7 @@ class PostCreateAddFriendPlanV1Controller extends Controller
try {
$params = $this->request->param();
// 验证必填字段
if (empty($params['name'])) {
return ResponseHelper::error('计划名称不能为空', 400);
@@ -91,16 +88,25 @@ class PostCreateAddFriendPlanV1Controller extends Controller
// 其余参数归为sceneConf
$sceneConf = $params;
unset(
$sceneConf['id'],
$sceneConf['apiKey'],
$sceneConf['userId'],
$sceneConf['status'],
$sceneConf['planId'],
$sceneConf['name'],
$sceneConf['sceneId'],
$sceneConf['messagePlans'],
$sceneConf['scenarioTags'],
$sceneConf['customTags'],
$sceneConf['device'],
$sceneConf['orderTableFileName'],
$sceneConf['userInfo'],
$sceneConf['textUrl'],
$sceneConf['remarkType'],
$sceneConf['greeting'],
$sceneConf['addFriendInterval'],
$sceneConf['startTime'],
$sceneConf['orderTableFile'],
$sceneConf['endTime']
);
@@ -122,9 +128,9 @@ class PostCreateAddFriendPlanV1Controller extends Controller
// 开启事务
Db::startTrans();
try {
Db::startTrans();
// 插入数据
$planId = Db::name('customer_acquisition_task')->insertGetId($data);
@@ -132,7 +138,132 @@ class PostCreateAddFriendPlanV1Controller extends Controller
throw new \Exception('添加计划失败');
}
// 提交事务
//订单
if($params['sceneId'] == 2){
if(!empty($params['orderTableFile'])){
// 先下载到本地临时文件,再分析,最后删除
$originPath = $params['orderTableFile'];
$tmpFile = tempnam(sys_get_temp_dir(), 'order_');
// 判断是否为远程文件
if (preg_match('/^https?:\/\//i', $originPath)) {
// 远程URL下载到本地
$fileContent = file_get_contents($originPath);
if ($fileContent === false) {
exit('远程文件下载失败: ' . $originPath);
}
file_put_contents($tmpFile, $fileContent);
} else {
// 本地文件直接copy
if (!file_exists($originPath)) {
exit('文件不存在: ' . $originPath);
}
copy($originPath, $tmpFile);
}
// 解析临时文件
$ext = strtolower(pathinfo($originPath, PATHINFO_EXTENSION));
$rows = [];
if (in_array($ext, ['xls', 'xlsx'])) {
// 直接用composer自动加载的PHPExcel
$excel = \PHPExcel_IOFactory::load($tmpFile);
$sheet = $excel->getActiveSheet();
$data = $sheet->toArray();
if (count($data) > 1) {
array_shift($data); // 去掉表头
}
foreach ($data as $cols) {
$rows[] = [
'name' => isset($cols[0]) ? trim($cols[0]) : '',
'phone' => isset($cols[1]) ? trim($cols[1]) : '',
'wechat' => isset($cols[2]) ? trim($cols[2]) : '',
'source' => isset($cols[3]) ? trim($cols[3]) : '',
'orderAmount' => isset($cols[4]) ? trim($cols[4]) : '',
'orderDate' => isset($cols[5]) ? trim($cols[5]) : '',
];
}
} elseif ($ext === 'csv') {
$content = file_get_contents($tmpFile);
$lines = preg_split('/\r\n|\r|\n/', $content);
if (count($lines) > 1) {
array_shift($lines); // 去掉表头
foreach ($lines as $line) {
if (trim($line) === '') continue;
$cols = str_getcsv($line);
if (count($cols) >= 6) {
$rows[] = [
'name' => isset($cols[0]) ? trim($cols[0]) : '',
'phone' => isset($cols[1]) ? trim($cols[1]) : '',
'wechat' => isset($cols[2]) ? trim($cols[2]) : '',
'source' => isset($cols[3]) ? trim($cols[3]) : '',
'orderAmount' => isset($cols[4]) ? trim($cols[4]) : '',
'orderDate' => isset($cols[5]) ? trim($cols[5]) : '',
];
}
}
}
} else {
unlink($tmpFile);
exit('暂不支持的文件类型: ' . $ext);
}
// 删除临时文件
unlink($tmpFile);
// 1000条为一组进行批量处理
$batchSize = 1000;
$totalRows = count($rows);
for ($i = 0; $i < $totalRows; $i += $batchSize) {
$batchRows = array_slice($rows, $i, $batchSize);
if (!empty($batchRows)) {
// 1. 提取当前批次的phone
$phones = [];
foreach ($batchRows as $row) {
$phone = !empty($row['phone']) ? $row['phone'] : $row['wechat'];
if (!empty($phone)) {
$phones[] = $phone;
}
}
// 2. 批量查询已存在的phone
$existingPhones = [];
if (!empty($phones)) {
$existing = Db::name('task_customer')
->where('task_id', $planId)
->where('phone', 'in', $phones)
->field('phone')
->select();
$existingPhones = array_column($existing, 'phone');
}
// 3. 过滤出新数据,批量插入
$newData = [];
foreach ($batchRows as $row) {
$phone = !empty($row['phone']) ? $row['phone'] : $row['wechat'];
if (!empty($phone) && !in_array($phone, $existingPhones)) {
$newData[] = [
'task_id' => $planId,
'name' => $row['name'] ?? '',
'source' => $row['source'] ?? '',
'phone' => $phone,
'tags' => json_encode([], JSON_UNESCAPED_UNICODE),
'siteTags' => json_encode([], JSON_UNESCAPED_UNICODE),
'createTime' => time(),
];
}
}
// 4. 批量插入新数据
if (!empty($newData)) {
Db::name('task_customer')->insertAll($newData);
}
}
}
}
}
Db::commit();
return ResponseHelper::success(['planId' => $planId], '添加计划任务成功');

View File

@@ -231,7 +231,7 @@ class PostExternalApiV1Controller extends Controller
// 更新数据库中的站点标签
Db::name('task_customer')->where('id', $taskCustomerId)->update([
'siteTags' => json_encode($uniqueSiteTags, JSON_UNESCAPED_UNICODE),
'updated_at' => time()
'updateTime' => time()
]);
} catch (\Exception $e) {

View File

@@ -65,6 +65,10 @@ class PostUpdateAddFriendPlanV1Controller extends Controller
// 其余参数归为sceneConf
$sceneConf = $params;
unset(
$sceneConf['id'],
$sceneConf['apiKey'],
$sceneConf['userId'],
$sceneConf['status'],
$sceneConf['planId'],
$sceneConf['name'],
$sceneConf['sceneId'],
@@ -72,10 +76,14 @@ class PostUpdateAddFriendPlanV1Controller extends Controller
$sceneConf['scenarioTags'],
$sceneConf['customTags'],
$sceneConf['device'],
$sceneConf['orderTableFileName'],
$sceneConf['userInfo'],
$sceneConf['textUrl'],
$sceneConf['remarkType'],
$sceneConf['greeting'],
$sceneConf['addFriendInterval'],
$sceneConf['startTime'],
$sceneConf['orderTableFile'],
$sceneConf['endTime']
);
@@ -90,8 +98,8 @@ class PostUpdateAddFriendPlanV1Controller extends Controller
'updateTime'=> time(),
];
// 开启事务
Db::startTrans();
try {
// 更新数据
$result = Db::name('customer_acquisition_task')
@@ -102,8 +110,132 @@ class PostUpdateAddFriendPlanV1Controller extends Controller
throw new \Exception('更新计划失败');
}
// 提交事务
Db::commit();
//订单
if($params['sceneId'] == 2){
if(!empty($params['orderTableFile'])){
// 先下载到本地临时文件,再分析,最后删除
$originPath = $params['orderTableFile'];
$tmpFile = tempnam(sys_get_temp_dir(), 'order_');
// 判断是否为远程文件
if (preg_match('/^https?:\/\//i', $originPath)) {
// 远程URL下载到本地
$fileContent = file_get_contents($originPath);
if ($fileContent === false) {
exit('远程文件下载失败: ' . $originPath);
}
file_put_contents($tmpFile, $fileContent);
} else {
// 本地文件直接copy
if (!file_exists($originPath)) {
exit('文件不存在: ' . $originPath);
}
copy($originPath, $tmpFile);
}
// 解析临时文件
$ext = strtolower(pathinfo($originPath, PATHINFO_EXTENSION));
$rows = [];
if (in_array($ext, ['xls', 'xlsx'])) {
// 直接用composer自动加载的PHPExcel
$excel = \PHPExcel_IOFactory::load($tmpFile);
$sheet = $excel->getActiveSheet();
$data = $sheet->toArray();
if (count($data) > 1) {
array_shift($data); // 去掉表头
}
foreach ($data as $cols) {
$rows[] = [
'name' => isset($cols[0]) ? trim($cols[0]) : '',
'phone' => isset($cols[1]) ? trim($cols[1]) : '',
'wechat' => isset($cols[2]) ? trim($cols[2]) : '',
'source' => isset($cols[3]) ? trim($cols[3]) : '',
'orderAmount' => isset($cols[4]) ? trim($cols[4]) : '',
'orderDate' => isset($cols[5]) ? trim($cols[5]) : '',
];
}
} elseif ($ext === 'csv') {
$content = file_get_contents($tmpFile);
$lines = preg_split('/\r\n|\r|\n/', $content);
if (count($lines) > 1) {
array_shift($lines); // 去掉表头
foreach ($lines as $line) {
if (trim($line) === '') continue;
$cols = str_getcsv($line);
if (count($cols) >= 6) {
$rows[] = [
'name' => isset($cols[0]) ? trim($cols[0]) : '',
'phone' => isset($cols[1]) ? trim($cols[1]) : '',
'wechat' => isset($cols[2]) ? trim($cols[2]) : '',
'source' => isset($cols[3]) ? trim($cols[3]) : '',
'orderAmount' => isset($cols[4]) ? trim($cols[4]) : '',
'orderDate' => isset($cols[5]) ? trim($cols[5]) : '',
];
}
}
}
} else {
unlink($tmpFile);
exit('暂不支持的文件类型: ' . $ext);
}
// 删除临时文件
unlink($tmpFile);
// 1000条为一组进行批量处理
$batchSize = 1000;
$totalRows = count($rows);
for ($i = 0; $i < $totalRows; $i += $batchSize) {
$batchRows = array_slice($rows, $i, $batchSize);
if (!empty($batchRows)) {
// 1. 提取当前批次的phone
$phones = [];
foreach ($batchRows as $row) {
$phone = !empty($row['phone']) ? $row['phone'] : $row['wechat'];
if (!empty($phone)) {
$phones[] = $phone;
}
}
// 2. 批量查询已存在的phone
$existingPhones = [];
if (!empty($phones)) {
$existing = Db::name('task_customer')
->where('task_id', $params['planId'])
->where('phone', 'in', $phones)
->field('phone')
->select();
$existingPhones = array_column($existing, 'phone');
}
// 3. 过滤出新数据,批量插入
$newData = [];
foreach ($batchRows as $row) {
$phone = !empty($row['phone']) ? $row['phone'] : $row['wechat'];
if (!empty($phone) && !in_array($phone, $existingPhones)) {
$newData[] = [
'task_id' => $params['planId'],
'name' => $row['name'] ?? '',
'source' => $row['source'] ?? '',
'phone' => $phone,
'tags' => json_encode([], JSON_UNESCAPED_UNICODE),
'siteTags' => json_encode([], JSON_UNESCAPED_UNICODE),
'createTime' => time(),
];
}
}
// 4. 批量插入新数据
if (!empty($newData)) {
Db::name('task_customer')->insertAll($newData);
}
}
}
}
}
return ResponseHelper::success(['planId' => $params['planId']], '更新计划任务成功');

View File

@@ -35,7 +35,7 @@ class PosterWeChatMiniProgram extends Controller
// 调用接口生成小程序码
$response = $app->app_code->getUnlimit($scene, [
'page' => 'pages/poster/index', // 必须是已经发布的小程序页面
'page' => 'pages/poster/index2', // 必须是已经发布的小程序页面
'width' => 430, // 二维码的宽度默认430
// 'auto_color' => false, // 自动配置线条颜色
// 'line_color' => ['r' => 0, 'g' => 0, 'b' => 0], // 颜色设置

View File

@@ -69,7 +69,6 @@ class WorkbenchMomentsJob
try {
// 获取所有工作台
$workbenches = Workbench::where(['status' => 1, 'type' => 2, 'isDel' => 0])->order('id desc')->select();
foreach ($workbenches as $workbench) {
// 获取工作台配置
$config = WorkbenchMoments::where('workbenchId', $workbench->id)->find();
@@ -85,7 +84,6 @@ class WorkbenchMomentsJob
// 获取设备
$devices = $this->getDevice($workbench, $config);
if (empty($devices)) {
continue;
}
@@ -279,7 +277,6 @@ class WorkbenchMomentsJob
if (empty($contentids)) {
return false;
}
// 基础查询
$query = Db::name('content_library')->alias('cl')
->join('content_item ci', 'ci.libraryId = cl.id')
@@ -298,7 +295,9 @@ class WorkbenchMomentsJob
'ci.comment',
'ci.sendTime'
]);
// 复制 query
$query2 = clone $query;
$query3 = clone $query;
// 根据accountType处理不同的发送逻辑
if ($config['accountType'] == 1) {
// 可以循环发送
@@ -306,16 +305,17 @@ class WorkbenchMomentsJob
$unsentContent = $query->where('wmsi.id', 'null')
->order('ci.sendTime desc, ci.id desc')
->find();
if (!empty($unsentContent)) {
return $unsentContent;
}
$lastSendData = Db::name('workbench_moments_sync_item')->where('workbenchId' ,$workbench->id)->order('id desc')->find();
$fastSendData = Db::name('workbench_moments_sync_item')->where('workbenchId' ,$workbench->id)->order('id asc')->find();
// 2. 如果没有未发送的内容,则获取已发送的内容中最早发送的
$sentContent = $query->where('wmsi.id', 'not null')
->order('wmsi.createTime asc, ci.sendTime desc, ci.id desc')
->find();
$sentContent = $query2->where('wmsi.contentId','<' ,$lastSendData['contentId'])->order('wmsi.id ASC')->group('wmsi.contentId')->find();
if (empty($sentContent)) {
$sentContent = $query3->where('wmsi.contentId','=' ,$fastSendData['contentId'])->order('wmsi.id ASC')->group('wmsi.contentId')->find();
}
return $sentContent;
} else {
// 不能循环发送,只获取未发送的内容

View File

@@ -61,70 +61,4 @@ return [
'break_reconnect' => true,
// 断线标识字符串
'break_match_str' => [],
'clone' => [
// 数据库类型
'type' => 'mysql',
// 服务器地址
'hostname' => 'gz-cynosdbmysql-grp-2k3icgxh.sql.tencentcdb.com',
// 数据库名
'database' => 'clone',
// 数据库用户名
'username' => 'root',
// 数据库密码
'password' => 'Lo.EQ{%t9G#v-1qv*Y',
// 端口
'hostport' => '20626',
// 数据库编码默认采用utf8
'charset' => 'utf8mb4',
// 数据库表前缀
'prefix' => '',
],
'pgsql' => [
// 数据库类型
'type' => 'pgsql',
// 服务器地址
'hostname' => 'pgm-7xv383pbm1orihnpfo.pg.rds.aliyuncs.com',
// 数据库名
'database' => 'aggregate_chat_system',
// 数据库用户名
'username' => 'postgres',
// 数据库密码
'password' => 'JYJ4Bz0dbWdPRVgq',
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库表前缀
'prefix' => '',
],
'xm_pgsql' => [
// 数据库类型
'type' => 'pgsql',
// 服务器地址
'hostname' => 'pgm-7xv383pbm1orihnpfo.pg.rds.aliyuncs.com',
// 数据库名
'database' => 'xm_aggregate_chat_system',
// 数据库用户名
'username' => 'postgres',
// 数据库密码
'password' => 'JYJ4Bz0dbWdPRVgq',
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库表前缀
'prefix' => '',
],
'shouyou' => [
// 数据库类型
'type' => 'mysql',
// 服务器地址
'hostname' => 'rm-7xv05155q5pa291l3vo.mysql.rds.aliyuncs.com',
// 数据库名
'database' => 'shouyou',
// 数据库用户名
'username' => 'root',
// 数据库密码
'password' => '320Azai609',
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库表前缀
'prefix' => '',
],
];