diff --git a/.env b/.env index 261d0502c..83ac3c687 100644 --- a/.env +++ b/.env @@ -1,6 +1,9 @@ # 项目配置, 请根据实际情况修改 PROJECT_NAME=newshop +# ThinkPHP 6.x 配置, 请根据实际情况修改 +APP_ENV=development + # PHP/PHP-FPM 配置 PHP_VERSION=7.4 PHP_FPM_VERSION=7.4-fpm diff --git a/docker-compose.yml b/docker-compose.yml index 1a1bcc4c2..248828c3f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,9 @@ services: - "host.docker.internal:host-gateway" # 支持主机名解析 environment: PHP_ENV: ${PHP_ENV:-development} + # 环境变量, APP_ENV 应用于 ThinkPHP 6.x 框架, .env.local 要想启用,需要在项目根目录下创建 .env.local 文件,并将 APP_ENV 设置为 local + # 同理,如果要启用开发环境,则将 APP_ENV 设置为 development,如果要启用生产环境,则将 APP_ENV 设置为 production + # 不然,ThinkPHP 6.x 系列,会只加载 .env 文件,而不会加载 .env.local 文件,导致 .env.local 文件中的配置不会生效 APP_ENV: ${APP_ENV:-development} APP_DEBUG: ${APP_DEBUG:-true} XDEBUG_CONFIG: ${XDEBUG_CONFIG:-client_host=host.docker.internal client_port=9003} diff --git a/src/.env.development b/src/.env.development new file mode 100644 index 000000000..7ad370a71 --- /dev/null +++ b/src/.env.development @@ -0,0 +1,25 @@ +APP_DEBUG = true +APP_TRACE = true + +[APP] +DEFAULT_TIMEZONE = Asia/Shanghai +ENV_MODE = development + +[LANG] +default_lang = zh-cn + +[DATABASE] +TYPE = mysql +HOSTNAME = 127.0.0.1 +DATABASE = shop_mallnew_dev +USERNAME = root +PASSWORD = root +HOSTPORT = 3306 +CHARSET = utf8 +DEBUG = true + +[redis] +HOST = 127.0.0.1 +PORT = 6379 +PASSWORD = '' +EXPIRY = 604800 \ No newline at end of file diff --git a/src/.env.production b/src/.env.production new file mode 100644 index 000000000..458bde428 --- /dev/null +++ b/src/.env.production @@ -0,0 +1,25 @@ +APP_DEBUG = false +APP_TRACE = false + +[APP] +DEFAULT_TIMEZONE = Asia/Shanghai +ENV_MODE = production + +[LANG] +default_lang = zh-cn + +[DATABASE] +TYPE = mysql +HOSTNAME = production_mysql_host +DATABASE = shop_mallnew_prod +USERNAME = prod_user +PASSWORD = prod_password +HOSTPORT = 3306 +CHARSET = utf8 +DEBUG = false + +[redis] +HOST = production_redis_host +PORT = 6379 +PASSWORD = production_redis_password +EXPIRY = 86400 \ No newline at end of file diff --git a/src/app/api/controller/AI.php b/src/app/api/controller/AI.php deleted file mode 100644 index 0eb21163b..000000000 --- a/src/app/api/controller/AI.php +++ /dev/null @@ -1,505 +0,0 @@ -aiChatSessionModel = new AiChatSession(); - $this->aiChatHistoryModel = new AiChatHistory(); - $this->configModel = new Config(); - } - - /** - * 平台类型常量 - */ - const PLATFORM_DIFY = 'dify'; - const PLATFORM_RAGFLOW = 'ragflow'; - - /** - * AI对话接口 - * 发送对话或者创建会话 - * 1. 支持与Dify平台或RAGFlow平台的智能体进行交互 - * 2. 支持会话管理,每个用户在每个平台上的会话是独立的 - * 3. 支持上下文管理,每个会话都维护一个上下文信息,用于持续对话 - * - * @return Json - */ - public function chat() - { - log_write('AI chat request: ' . json_encode($this->params), 'info', $this->log_file); - try { - // 获取请求参数 - $message = $this->params['message'] ?? ''; // 用户消息 - $session_id = $this->params['session_id'] ?? ''; // 会话ID - $user_id = $this->params['user_id'] ?? $this->member_id; // 用户ID - $context = $this->params['context'] ?? []; // 上下文信息 - - $site_id = $this->params['uniacid'] ?? $this->site_id; // 站点ID - $app_module = $this->params['app_module'] ?? $this->app_module; // 应用模块 - - // 参数验证 - if (empty($message)) { - return $this->response($this->error('', 'MESSAGE_EMPTY')); - } - - // 获取平台配置 - $config = $this->getPlatformConfig($site_id, $app_module); - if (!$config['status']) { - return $this->response($this->error('', $config['message'])); - } - - $platform = $config['data']['default']['type'] ?? self::PLATFORM_DIFY; // 平台类型 - - // 生成或使用现有会话ID - $session_id = $session_id ?: $this->generateSessionId($user_id, $platform); - - // 根据平台类型调用不同的方法 - $result = []; - if ($platform === self::PLATFORM_DIFY) { - $result = $this->callDifyApi($config['data'], $message, $session_id, $user_id, $context); - } else if ($platform === self::PLATFORM_RAGFLOW) { - $result = $this->callRagflowApi($config['data'], $message, $session_id, $user_id, $context); - } - - if (!$result['status']) { - return $this->response($this->error('', $result['message'])); - } - - // 保存会话记录 - $this->saveChatHistory($user_id, $session_id, $platform, $message, $result['data']['content']); - - return $this->response($this->success([ - 'session_id' => $session_id, - 'content' => $result['data']['content'], - 'tokens' => $result['data']['tokens'] ?? null, - 'response_time' => $result['data']['response_time'] ?? null - ])); - - } catch (Exception $e) { - // 记录错误日志 - log_write('AI chat error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->response($this->error('', 'AI_SERVICE_ERROR')); - } - } - - /** - * 获取平台配置 - * @param int $site_id 站点ID 默认为1, 业务站点uniacid值与site_id保持一致 - * @param string $app_module 应用模块 默认为shop - * @return array - */ - private function getPlatformConfig($site_id, $app_module) - { - $config = []; - try { - // 从配置模型获取平台配置 - $config = $this->configModel->getAIPlatformConfig($site_id, $app_module); - - throw new \Exception('Get AI platform config error: ' . json_encode($config)); - - if (!$config || !$config['status']) { - return ['status' => false, 'message' => 'PLATFORM_CONFIG_NOT_FOUND']; - } - - $config_data = json_decode($config['config'], true); - if (!$config_data || empty($config_data['api_key']) || empty($config_data['base_url']) || empty($config_data['app_id'])) { - return ['status' => false, 'message' => 'PLATFORM_CONFIG_INVALID']; - } - - return ['status' => true, 'data' => $config_data]; - - } catch (Exception $e) { - return ['status' => false, 'message' => 'GET_CONFIG_ERROR' . $e->getMessage()]; - } - } - - /** - * 生成会话ID - * @param string $user_id - * @param string $platform - * @return string - */ - private function generateSessionId($user_id, $platform) - { - return md5($user_id . '_' . $platform . '_' . time() . '_' . rand(1000, 9999)); - } - - /** - * 调用Dify API - * @param array $config - * @param string $message - * @param string $session_id - * @param string $user_id - * @param array $context - * @return array - */ - private function callDifyApi($config, $message, $session_id, $user_id, $context = []) - { - try { - $start_time = microtime(true); - - $headers = [ - 'Authorization: Bearer ' . $config['api_key'], - 'Content-Type: application/json', - 'Accept: application/json', - ]; - - $data = [ - 'inputs' => $context, - 'query' => $message, - 'response_mode' => $config['response_mode'] ?? 'streaming', - 'user' => $user_id, - 'conversation_id' => $session_id - ]; - - $url = rtrim($config['base_url'], '/') . '/v1/chat-messages'; - - // 发送请求 - $result = $this->httpRequest($url, $data, $headers); - - if (!$result['status']) { - return ['status' => false, 'message' => 'DIFY_API_ERROR']; - } - - $response_time = round((microtime(true) - $start_time) * 1000, 2); - - return [ - 'status' => true, - 'data' => [ - 'content' => $result['data']['answer'] ?? $result['data']['choices'][0]['message']['content'] ?? '', - 'tokens' => [ - 'prompt' => $result['data']['usage']['prompt_tokens'] ?? 0, - 'completion' => $result['data']['usage']['completion_tokens'] ?? 0, - 'total' => $result['data']['usage']['total_tokens'] ?? 0 - ], - 'response_time' => $response_time - ] - ]; - - } catch (Exception $e) { - log_write('Dify API error: ' . $e->getMessage(), 'error', $this->log_file); - return ['status' => false, 'message' => 'DIFY_CALL_ERROR']; - } - } - - /** - * 调用RAGFlow API - * @param array $config - * @param string $message - * @param string $session_id - * @param string $user_id - * @param array $context - * @return array - */ - private function callRagflowApi($config, $message, $session_id, $user_id, $context = []) - { - try { - $start_time = microtime(true); - - $headers = [ - 'Authorization: Bearer ' . $config['api_key'], - 'Content-Type: application/json', - 'Accept: application/json', - ]; - - $data = [ - 'query' => $message, - 'conversation_id' => $session_id, - 'user_id' => $user_id, - 'agent_id' => $config['app_id'], - 'stream' => $config['stream'] ?? false - ]; - - $url = rtrim($config['base_url'], '/') . '/api/v1/chat/completions'; - - // 发送请求 - $result = $this->httpRequest($url, $data, $headers); - - if (!$result['status']) { - return ['status' => false, 'message' => 'RAGFLOW_API_ERROR']; - } - - $response_time = round((microtime(true) - $start_time) * 1000, 2); - - return [ - 'status' => true, - 'data' => [ - 'content' => $result['data']['choices'][0]['message']['content'] ?? $result['data']['answer'] ?? '', - 'tokens' => [ - 'prompt' => $result['data']['usage']['prompt_tokens'] ?? 0, - 'completion' => $result['data']['usage']['completion_tokens'] ?? 0, - 'total' => $result['data']['usage']['total_tokens'] ?? 0 - ], - 'response_time' => $response_time - ] - ]; - - } catch (Exception $e) { - log_write('RAGFlow API error: ' . $e->getMessage(), 'error', $this->log_file); - return ['status' => false, 'message' => 'RAGFLOW_CALL_ERROR']; - } - } - - /** - * 保存聊天记录 - * @param string $user_id - * @param string $session_id - * @param string $platform - * @param string $user_message - * @param string $ai_message - */ - private function saveChatHistory($user_id, $session_id, $platform, $user_message, $ai_message) - { - try { - $data = [ - 'site_id' => $this->site_id, - 'user_id' => $user_id, - 'session_id' => $session_id, - 'platform' => $platform, - 'user_message' => $user_message, - 'ai_message' => $ai_message, - 'create_time' => time(), - 'ip' => Request::ip() - ]; - - // 使用事务保存聊天记录 - Db::startTrans(); - try { - // 使用模型保存聊天记录 - $save_result = $this->aiChatHistoryModel->saveHistory($data); - if (!$save_result['success']) { - log_write('Save chat history failed: ' . $save_result['msg'], 'error', $this->log_file); - } - - // 更新会话最后活动时间 - $update_result = $this->aiChatSessionModel->updateLastActiveTime($session_id); - if (!$update_result['success']) { - log_write('Update session active time failed: ' . $update_result['msg'], 'error', $this->log_file); - } - - // 如果会话不存在,创建新会话 - $session_info = $this->aiChatSessionModel->getSessionInfo(['session_id' => $session_id]); - if (!$session_info['success']) { - $session_data = [ - 'site_id' => $this->site_id, - 'user_id' => $user_id, - 'session_id' => $session_id, - 'platform' => $platform, - 'create_time' => time(), - 'last_active_time' => time() - ]; - $create_result = $this->aiChatSessionModel->createSession($session_data); - if (!$create_result['success']) { - log_write('Create session failed: ' . $create_result['msg'], 'error', $this->log_file); - } - } - - Db::commit(); - } catch (Exception $e) { - Db::rollback(); - log_write('Save chat history error: ' . $e->getMessage(), 'error', $this->log_file); - } - } catch (Exception $e) { - // 记录错误但不影响主流程 - log_write('Save chat history exception: ' . $e->getMessage(), 'error', $this->log_file); - } - } - - /** - * HTTP请求方法 - * @param string $url - * @param array $data - * @param array $headers - * @return array - */ - private function httpRequest($url, $data = [], $headers = []) - { - try { - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_TIMEOUT, 30); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); - - if (!empty($data)) { - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); - } - - if (!empty($headers)) { - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - } - - $response = curl_exec($ch); - $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); - - curl_close($ch); - - if ($http_code != 200) { - log_write('HTTP request failed: URL=' . $url . ', Code=' . $http_code . ', Response=' . $response, 'error', $this->log_file); - return ['status' => false, 'message' => 'HTTP_REQUEST_FAILED', 'code' => $http_code]; - } - - $result = json_decode($response, true); - if (json_last_error() !== JSON_ERROR_NONE) { - log_write('JSON decode error: ' . json_last_error_msg(), 'error', $this->log_file); - return ['status' => false, 'message' => 'JSON_DECODE_ERROR']; - } - - return ['status' => true, 'data' => $result]; - - } catch (Exception $e) { - log_write('HTTP request exception: ' . $e->getMessage(), 'error', $this->log_file); - return ['status' => false, 'message' => 'HTTP_REQUEST_EXCEPTION']; - } - } - - /** - * 获取会话历史 - * @return Json - */ - public function getHistory() - { - try { - $session_id = $this->params['session_id'] ?? ''; - $user_id = $this->params['user_id'] ?? $this->member_id; - $page = $this->params['page'] ?? 1; - $page_size = $this->params['page_size'] ?? 20; - - if (empty($session_id)) { - return $this->response($this->error('', 'SESSION_ID_EMPTY')); - } - - // 使用模型获取会话历史 - $where = [ - 'site_id' => $this->site_id, - 'user_id' => $user_id - ]; - - $result = $this->aiChatHistoryModel->getHistoryBySessionId($session_id, $where, $page, $page_size); - - if (!$result['success']) { - log_write('Get history failed: ' . $result['msg'], 'error', $this->log_file); - return $this->response($this->error('', 'GET_HISTORY_ERROR')); - } - - return $this->response($this->success($result['data'])); - - } catch (Exception $e) { - log_write('Get history error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->response($this->error('', 'GET_HISTORY_ERROR')); - } - } - - /** - * 获取用户的会话列表 - * @return Json - */ - public function getSessions() - { - try { - $user_id = $this->params['user_id'] ?? $this->member_id; - $page = $this->params['page'] ?? 1; - $page_size = $this->params['page_size'] ?? 20; - - // 使用模型获取会话列表 - $where = [ - 'site_id' => $this->site_id, - 'user_id' => $user_id - ]; - - $result = $this->aiChatSessionModel->getSessionList($where, ['*'], 'last_active_time DESC', $page, $page_size); - - if (!$result['success']) { - return $this->response($this->error('', 'GET_SESSIONS_ERROR')); - } - - return $this->response($this->success($result['data'])); - - } catch (Exception $e) { - log_write('Get sessions error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->response($this->error('', 'GET_SESSIONS_ERROR')); - } - } - - /** - * 删除会话 - * @return Json - */ - public function deleteSession() - { - try { - $session_id = $this->params['session_id'] ?? ''; - $user_id = $this->params['user_id'] ?? $this->member_id; - - if (empty($session_id)) { - return $this->response($this->error('', 'SESSION_ID_EMPTY')); - } - - // 使用模型删除会话 - $where = [ - 'site_id' => $this->site_id, - 'session_id' => $session_id, - 'user_id' => $user_id - ]; - - $result = $this->aiChatSessionModel->deleteSession($where); - - if (!$result['success']) { - return $this->response($this->error('', 'DELETE_SESSION_ERROR')); - } - - return $this->response($this->success()); - - } catch (Exception $e) { - log_write('Delete session exception: ' . $e->getMessage(), 'error', $this->log_file); - return $this->response($this->error('', 'DELETE_SESSION_EXCEPTION')); - } - } -} \ No newline at end of file diff --git a/src/app/api/controller/Config.php b/src/app/api/controller/Config.php index 6931e4b28..74fb8feb7 100644 --- a/src/app/api/controller/Config.php +++ b/src/app/api/controller/Config.php @@ -11,7 +11,6 @@ use app\model\web\DiyView as DiyViewModel; use app\model\shop\Shop as ShopModel; use app\model\member\Config as ConfigMemberModel; - class Config extends BaseApi { @@ -108,6 +107,7 @@ class Config extends BaseApi */ public function init() { + $diy_view = new DiyViewModel(); $diy_style = $diy_view->getStyleConfig($this->site_id)[ 'data' ][ 'value' ]; @@ -126,9 +126,6 @@ class Config extends BaseApi $copyright = $config_model->getCopyright($this->site_id, 'shop')[ 'data' ][ 'value' ]; $map_config = $config_model->getMapConfig($this->site_id, 'shop')[ 'data' ][ 'value' ]; - // AI智能客服配置信息 - $aiagent_config = $config_model->getAIAgentServicesConfig($this->site_id, 'shop')[ 'data' ][ 'value' ]; - $website_model = new SiteModel(); $site_info = $website_model->getSiteInfo([ [ 'site_id', '=', $this->site_id ] ], 'site_id,site_domain,site_name,logo,seo_title,seo_keywords,seo_description,site_tel,logo_square')[ 'data' ]; @@ -151,8 +148,7 @@ class Config extends BaseApi 'servicer' => $servicer_info, 'shop_info'=>$shop_info, 'store_config' => $this->store_data[ 'config' ], - 'map_config' => $map_config, - 'aiagent_config' => $aiagent_config, + 'map_config' => $map_config ]; if (!empty($this->store_data[ 'store_info' ])) { $res[ 'store_info' ] = $this->store_data[ 'store_info' ]; diff --git a/src/app/model/ai/AiChatHistory.php b/src/app/model/ai/AiChatHistory.php deleted file mode 100644 index 867f70200..000000000 --- a/src/app/model/ai/AiChatHistory.php +++ /dev/null @@ -1,261 +0,0 @@ -error('', 'PARAMETERS_INCOMPLETE'); - } - - // 补充默认字段 - $data['create_time'] = $data['create_time'] ?? time(); - $data['ip'] = $data['ip'] ?? request()->ip(); - - // 保存数据 - $result = Db::name($this->name)->insert($data); - - if ($result) { - return $this->success(['id' => Db::name($this->name)->getLastInsID()]); - } else { - return $this->error('', 'SAVE_FAILED'); - } - } catch (Exception $e) { - // 记录错误日志 - log_write('Save chat history error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'SAVE_EXCEPTION'); - } - } - - /** - * 获取聊天历史记录列表 - * @param array $where 条件数组 - * @param array $field 查询字段 - * @param string $order 排序方式 - * @param int $page 页码 - * @param int $page_size 每页数量 - * @return array - */ - public function getHistoryList($where = [], $field = ['*'], $order = 'create_time ASC', $page = 1, $page_size = 20) - { - try { - // 计算偏移量 - $offset = ($page - 1) * $page_size; - - // 查询列表 - $list = Db::name($this->name) - ->field($field) - ->where($where) - ->order($order) - ->limit($offset, $page_size) - ->select(); - - // 查询总数 - $total = Db::name($this->name) - ->where($where) - ->count(); - - return $this->success([ - 'list' => $list, - 'total' => $total, - 'page' => $page, - 'page_size' => $page_size, - 'total_page' => ceil($total / $page_size) - ]); - } catch (Exception $e) { - log_write('Get chat history list error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'GET_LIST_FAILED'); - } - } - - /** - * 根据会话ID获取聊天记录 - * @param string $session_id 会话ID - * @param array $where 额外条件 - * @param int $page 页码 - * @param int $page_size 每页数量 - * @return array - */ - public function getHistoryBySessionId($session_id, $where = [], $page = 1, $page_size = 20) - { - if (empty($session_id)) { - return $this->error('', 'SESSION_ID_EMPTY'); - } - - $where['session_id'] = $session_id; - return $this->getHistoryList($where, ['*'], 'create_time ASC', $page, $page_size); - } - - /** - * 获取用户的所有聊天记录 - * @param string $user_id 用户ID - * @param array $where 额外条件 - * @param int $page 页码 - * @param int $page_size 每页数量 - * @return array - */ - public function getUserHistory($user_id, $where = [], $page = 1, $page_size = 20) - { - if (empty($user_id)) { - return $this->error('', 'USER_ID_EMPTY'); - } - - $where['user_id'] = $user_id; - return $this->getHistoryList($where, ['*'], 'create_time DESC', $page, $page_size); - } - - /** - * 删除聊天记录 - * @param array $where 条件数组 - * @return array - */ - public function deleteHistory($where) - { - try { - if (empty($where)) { - return $this->error('', 'DELETE_CONDITION_EMPTY'); - } - - $result = Db::name($this->name)->where($where)->delete(); - - if ($result !== false) { - return $this->success(['deleted' => $result]); - } else { - return $this->error('', 'DELETE_FAILED'); - } - } catch (Exception $e) { - log_write('Delete chat history error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'DELETE_EXCEPTION'); - } - } - - /** - * 根据会话ID删除聊天记录 - * @param string $session_id 会话ID - * @param array $where 额外条件 - * @return array - */ - public function deleteHistoryBySessionId($session_id, $where = []) - { - if (empty($session_id)) { - return $this->error('', 'SESSION_ID_EMPTY'); - } - - $where['session_id'] = $session_id; - return $this->deleteHistory($where); - } - - /** - * 获取用户的会话消息统计 - * @param string $user_id 用户ID - * @param array $where 额外条件 - * @return array - */ - public function getUserMessageStats($user_id, $where = []) - { - try { - if (empty($user_id)) { - return $this->error('', 'USER_ID_EMPTY'); - } - - $where['user_id'] = $user_id; - - // 统计总消息数 - $total_count = Db::name($this->name)->where($where)->count(); - - // 统计今日消息数 - $today_count = Db::name($this->name) - ->where($where) - ->whereTime('create_time', 'today') - ->count(); - - // 统计最近消息时间 - $last_message = Db::name($this->name) - ->where($where) - ->order('create_time DESC') - ->find(); - - return $this->success([ - 'total_count' => $total_count, - 'today_count' => $today_count, - 'last_message_time' => $last_message ? $last_message['create_time'] : 0 - ]); - } catch (Exception $e) { - log_write('Get user message stats error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'GET_STATS_FAILED'); - } - } - - /** - * 清理过期的聊天记录 - * @param int $days 保留天数 - * @param array $where 额外条件 - * @return array - */ - public function cleanupExpiredHistory($days = 30, $where = []) - { - try { - $expire_time = time() - ($days * 24 * 60 * 60); - $where['create_time'] = ['<', $expire_time]; - - return $this->deleteHistory($where); - } catch (Exception $e) { - log_write('Cleanup expired history error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'CLEANUP_FAILED'); - } - } - - /** - * 批量保存聊天记录 - * @param array $data 聊天记录数组 - * @return array - */ - public function batchSaveHistory($data) - { - try { - if (empty($data) || !is_array($data)) { - return $this->error('', 'DATA_EMPTY'); - } - - // 批量插入数据 - $result = Db::name($this->name)->insertAll($data); - - if ($result) { - return $this->success(['count' => $result]); - } else { - return $this->error('', 'BATCH_SAVE_FAILED'); - } - } catch (Exception $e) { - log_write('Batch save chat history error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'BATCH_SAVE_EXCEPTION'); - } - } -} \ No newline at end of file diff --git a/src/app/model/ai/AiChatSession.php b/src/app/model/ai/AiChatSession.php deleted file mode 100644 index 985782bbe..000000000 --- a/src/app/model/ai/AiChatSession.php +++ /dev/null @@ -1,266 +0,0 @@ -name) - ->where($where) - ->field($field) - ->find(); - - return $this->success($data); - } catch (\Exception $e) { - log_write('Get session info error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'GET_SESSION_INFO_ERROR'); - } - } - - /** - * 获取会话列表 - * @param array $where 条件 - * @param array $field 字段 - * @param string $order 排序 - * @param int $page 页码 - * @param int $page_size 每页数量 - * @return array - */ - public function getSessionList($where = [], $field = ['*'], $order = 'last_active_time DESC', $page = 1, $page_size = 20) - { - try { - $count = Db::name($this->name) - ->where($where) - ->count(); - - $list = []; - if ($count > 0) { - $list = Db::name($this->name) - ->where($where) - ->field($field) - ->order($order) - ->page($page, $page_size) - ->select(); - } - - return $this->success(json_encode([ - 'list' => $list, - 'total' => $count, - 'page' => $page, - 'page_size' => $page_size - ])); - } catch (\Exception $e) { - log_write('Get session list error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'GET_SESSION_LIST_ERROR'); - } - } - - /** - * 创建会话 - * @param array $data 数据 - * @return array - */ - public function createSession($data = []) - { - try { - // 确保必要字段存在 - if (empty($data['session_id']) || empty($data['user_id']) || empty($data['site_id'])) { - return $this->error('', 'MISSING_REQUIRED_FIELDS'); - } - - // 检查会话是否已存在 - $exists = Db::name($this->name) - ->where('session_id', $data['session_id']) - ->count(); - - if ($exists > 0) { - return $this->error('', 'SESSION_ALREADY_EXISTS'); - } - - // 设置默认值 - $data['create_time'] = $data['create_time'] ?? time(); - $data['last_active_time'] = $data['last_active_time'] ?? time(); - - $result = Db::name($this->name)->insert($data); - - if ($result) { - return $this->success(json_encode(['session_id' => $data['session_id']])); - } else { - return $this->error('', 'CREATE_SESSION_FAILED'); - } - } catch (\Exception $e) { - log_write('Create session error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'CREATE_SESSION_ERROR'); - } - } - - /** - * 更新会话 - * @param array $where 条件 - * @param array $data 数据 - * @return array - */ - public function updateSession($where = [], $data = []) - { - try { - if (empty($where)) { - return $this->error('', 'WHERE_CONDITION_EMPTY'); - } - - $result = Db::name($this->name) - ->where($where) - ->update($data); - - return $this->success(['affected_rows' => $result]); - } catch (\Exception $e) { - log_write('Update session error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'UPDATE_SESSION_ERROR'); - } - } - - /** - * 删除会话 - * @param array $where 条件 - * @return array - */ - public function deleteSession($where = []) - { - try { - if (empty($where)) { - return $this->error('', 'WHERE_CONDITION_EMPTY'); - } - - // 开启事务 - Db::startTrans(); - try { - // 删除会话 - $result = Db::name($this->name) - ->where($where) - ->delete(); - - // 删除相关的聊天历史 - Db::name('shop_ai_chat_history') - ->where($where) - ->delete(); - - Db::commit(); - return $this->success(['affected_rows' => $result]); - } catch (\Exception $e) { - Db::rollback(); - throw $e; - } - } catch (\Exception $e) { - log_write('Delete session error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'DELETE_SESSION_ERROR'); - } - } - - /** - * 更新会话最后活动时间 - * @param string $session_id 会话ID - * @param int $time 时间戳 - * @return array - */ - public function updateLastActiveTime($session_id, $time = null) - { - $time = $time ?? time(); - return $this->updateSession(['session_id' => $session_id], ['last_active_time' => $time]); - } - - /** - * 获取用户的活跃会话数 - * @param int $user_id 用户ID - * @param int $site_id 站点ID - * @param int $days 天数 - * @return array - */ - public function getUserActiveSessionsCount($user_id, $site_id, $days = 7) - { - try { - $start_time = time() - ($days * 24 * 3600); - - $count = Db::name($this->name) - ->where('user_id', $user_id) - ->where('site_id', $site_id) - ->where('last_active_time', '>=', $start_time) - ->count(); - - return $this->success(['count' => $count]); - } catch (\Exception $e) { - log_write('Get active sessions count error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'GET_ACTIVE_SESSIONS_COUNT_ERROR'); - } - } - - /** - * 清理过期会话 - * @param int $days 天数 - * @return array - */ - public function cleanupExpiredSessions($days = 30) - { - try { - $expire_time = time() - ($days * 24 * 3600); - - // 开启事务 - Db::startTrans(); - try { - // 找出所有过期会话ID - $expired_sessions = Db::name($this->name) - ->where('last_active_time', '<', $expire_time) - ->column('session_id'); - - if (!empty($expired_sessions)) { - // 删除过期会话 - $session_result = Db::name($this->name) - ->where('session_id', 'in', $expired_sessions) - ->delete(); - - // 删除相关聊天历史 - $history_result = Db::name('shop_ai_chat_history') - ->where('session_id', 'in', $expired_sessions) - ->delete(); - } - - Db::commit(); - return $this->success([ - 'expired_count' => count($expired_sessions), - 'session_deleted' => $session_result ?? 0, - 'history_deleted' => $history_result ?? 0 - ]); - } catch (\Exception $e) { - Db::rollback(); - throw $e; - } - } catch (\Exception $e) { - log_write('Cleanup expired sessions error: ' . $e->getMessage(), 'error', $this->log_file); - return $this->error('', 'CLEANUP_EXPIRED_SESSIONS_ERROR'); - } - } -} \ No newline at end of file diff --git a/src/app/model/web/Config.php b/src/app/model/web/Config.php index f9df67224..3d4fa0e69 100644 --- a/src/app/model/web/Config.php +++ b/src/app/model/web/Config.php @@ -93,19 +93,6 @@ class Config extends BaseModel return $res; } - /** - * 获取支持的应用模块 - * @return array - */ - public function getSupportAppModules() - { - return [ - ['value' => 'shop', 'label' => '商家'], - ['value' => 'h5', 'label' => 'H5轻应用'], - ['value' => 'weixin', 'label' => '微信小程序'], - ]; - } - /** * 默认图上传配置 * @param $data @@ -299,300 +286,6 @@ class Config extends BaseModel return $res; } - /** - * 获取支持的AI平台类型 - * @return array - */ - public function getSupportAIPlatformTypes() - { - return [ - ['value' => 'dify', 'label' => 'Dify'], - ['value' => 'ragflow', 'label' => 'Ragflow'], - ]; - } - - /** - * 通用AI相关配置获取方法 - * @param int $site_id 站点ID, 默认为-1, 业务站点uniacid值与site_id保持一致 - * @param string $app_module 应用模块, 默认为*,表示所有应用模块都生效 - * @param string $config_key 配置键, 默认为空字符串, 表示获取通用配置信息 - * @param array $common_config 通用配置信息, 默认为空数组 - * @return array - */ - private function _getAIConfig($site_id = -1, $app_module = '*', $config_key ='', $common_config = []) - { - // 应用模块配置获取 - try { - // 站点ID为-1时,获取通用配置信息 - if ($site_id == -1) { - return $this->error('', 'MISSING_SITE_ID'); - } - - // 配置键为空字符串, 表示获取通用配置信息 - if (empty($config_key)) { - return $this->error('', 'MISSING_CONFIG_KEY'); - } - - $config = new ConfigModel(); - $support_app_modules = $this->getSupportAppModules(); - - // 检查应用模块是否支持, 如果是*,则表示所有应用模块都生效 - if ($app_module != '*') { - if (!in_array($app_module, array_column($support_app_modules, 'value'))) { - return $this->error('', 'APP_MODULE_NOT_SUPPORTED'); - } - } - - // 如果是*,则表示所有应用模块都生效, 遍历所有应用模块,根据应用模块获取配置信息, 为每一种应用模块生成独立的配置信息,每一种类型的应用模块,对应自己的配置信息,然后将所有的配置信息返回 - $app_module_config = []; - foreach ($support_app_modules as $item) { - $app_module = $item['value']; - - // 检查应用模块是否支持 - try { - $res = $config->getConfig([['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', $config_key]]); - if (empty($res['data']['value'])) { - $res['data']['value'] = $common_config; - } - } catch (\Exception $e) { - $res['data']['value'] = $common_config; - } - - $app_module_config[$app_module] = $res['data']['value']; - } - $res['data']['value'] = $app_module_config; - - return $res; - } catch (\Exception $e) { - return $this->error('', 'GET_CONFIG_ERROR' . $e->getMessage()); - } - } - - /** - * 通用AI相关配置设置方法 - * @param $data 配置信息 - * @param int $site_id 站点ID, 默认为-1, 业务站点uniacid值与site_id保持一致 - * @param string $app_module 应用模块, 默认为空字符串 - * @param string $config_key 配置键, 默认为空字符串 - * @param string $data_desc 配置描述, 默认为空字符串 - * @return array - */ - private function _setAIConfig($data, $site_id = -1, $app_module = '', $config_key = '', $data_desc = '') - { - // 站点ID为-1时,设置通用配置信息 - if ($site_id == -1) { - return $this->error('', 'MISSING_SITE_ID'); - } - - // 应用模块为空字符串 - if (empty($app_module)) { - return $this->error('', 'MISSING_APP_MODULE'); - } - - // 配置键为空字符串 - if (empty($config_key)) { - return $this->error('', 'MISSING_CONFIG_KEY'); - } - - $config = new ConfigModel(); - $res = $config->setConfig($data, $data_desc, 1, [['site_id', '=', $site_id], ['app_module', '=', $app_module], ['config_key', '=', $config_key]]); - return $res; - } - - /** - * 设置AI第三平台提供的配置信息 - * @param $data 配置信息 - * @param int $site_id 站点ID, 默认为-1, 业务站点uniacid值与site_id保持一致 - * @param string $app_module 应用模块, 默认为*, 表示所有应用模块都生效 - * @return array - */ - public function setAIPlatformConfig($data, $site_id = -1, $app_module = '') - { - return $this->_setAIConfig($data, $site_id, $app_module, 'AI_PLATFORM_CONFIG', 'AI第三平台提供的配置信息'); - } - - /** - * 设置AI智能客服配置信息 - * @param $data 配置信息 - * @param int $site_id 站点ID, 默认为1, 业务站点uniacid值与site_id保持一致 - * @param string $app_module 应用模块, 默认为*, 表示所有应用模块都生效 - * @return array - */ - public function setAIAgentServicesConfig($data, $site_id = 1, $app_module = '*') - { - return $this->_setAIConfig($data, $site_id, $app_module, 'AI_AGENT_SERVICES_CONFIG', 'AI智能客服配置信息'); - } - - /** - * 获取AI第三平台提供的通用配置信息 - * @return array - */ - private function getCommonAIPlatformConfig() - { - // 默认ID - $id = time(); - - // 通用配置 - return [ - 'default' => ['id' => $id, 'name' => 'dify-demo'], - 'list' => [ - // Dify Demo 版本, - ['id' => $id, 'name' => 'dify-demo', 'type' => 'dify', 'type_label' => 'Dify', 'desc' => 'Dify 线上Demo 版本', 'enable' => 1, 'base_url' => 'https://localhost/api/ai', 'api_key' => 'xxxxxxx', 'create_time' => time()], - ] - ]; - } - - /** - * 获取AI第三平台提供的配置信息 - * @param int $site_id 站点ID, 默认为1, 业务站点uniacid值与site_id保持一致 - * @param string $app_module 应用模块, 默认为*, 表示所有应用模块都生效 - * @return array - */ - public function getAIPlatformConfig($site_id = 1, $app_module = '*') - { - return $this->_getAIConfig($site_id, $app_module, 'AI_PLATFORM_CONFIG', $this->getCommonAIPlatformConfig()); - } - - /** - * 获取AI智能客服的通用配置信息 - * @return array - */ - private function getCommonAIAgentServicesConfig() - { - return [ - // 是否开启AI功能 - 'enable' => false, - // 用户头像url - 'user_avatar' => [ - 'en' => '', - 'zh_CN' => '', - ], - // AI客服头像url - 'ai_avatar' => [ - 'en' => '', - 'zh_CN' => '', - ], - // AI客服姓名 - 'ai_name' => [ - 'en' => '', - 'zh_CN' => '', - ], - // 欢迎语, 也称为开场白,初始化消息 - 'welcome_messages' => [ - 'en' => [], - 'zh_CN' => [], - ], - // 是否显示加载更多按钮 - 'show_load_more_button' => true, - // 最大消息数量 - 'max_messages' => 100, - // 是否启用流式响应 - 'stream_mode' => true, - // 流式响应的超时时间,单位:秒 - 'stream_timeout' => 30, - // 流式响应速度(字符/秒) - 'stream_speed' => 20, - // 是否开启支持语音输入 - 'support_voice_input' => false, - // 语音输入的提示信息 - 'voice_input_prompt' => [ - 'en' => 'Please click the microphone icon to start recording', - 'zh_CN' => '请点击麦克风图标开始录音', - ], - // 是否开启语音输入提示 - 'support_voice_input_prompt' => false, - // 输入文本内容提示 - 'text_input_prompt' => [ - 'en' => 'Please enter your problem', - 'zh_CN' => '请输入您的问题', - ], - // 输入的问题描述的字符长度限制 - 'max_char_length_for_problem' => 500, - // 是否支持显示更多工具面板 - 'tool_panel_config' => [ - 'enable' => false, - 'title' => [ - 'en' => 'More Tools', - 'zh_CN' => '更多功能', - ], - 'icon' => 'icon-more', - // 工具面板中的工具项 - 'tools' => [ - 'image' => [ - 'enable' => false, - 'name' => [ - 'en' => 'Image', - 'zh_CN' => '图片', - ], - 'description' => [ - 'en' => 'Upload image', - 'zh_CN' => '上传图片', - ], - 'icon' => 'icon-image', - ], - 'video' => [ - 'enable' => false, - 'name' => [ - 'en' => 'Video', - 'zh_CN' => '视频', - ], - 'description' => [ - 'en' => 'Upload video', - 'zh_CN' => '上传视频', - ], - 'icon' => 'icon-video', - ], - 'file' => [ - 'enable' => false, - 'name' => [ - 'en' => 'File', - 'zh_CN' => '文件', - ], - 'description' => [ - 'en' => 'Upload file', - 'zh_CN' => '上传文件', - ], - 'icon' => 'icon-file', - ], - 'voice' => [ - 'enable' => false, - 'name' => [ - 'en' => 'Voice', - 'zh_CN' => '语音', - ], - 'description' => [ - 'en' => 'Voice input', - 'zh_CN' => '语音输入', - ], - 'icon' => 'icon-voice', - ], - 'location' => [ - 'enable' => false, - 'name' => [ - 'en' => 'Location', - 'zh_CN' => '位置', - ], - 'description' => [ - 'en' => 'Location input', - 'zh_CN' => '位置输入', - ], - 'icon' => 'icon-location', - ], - ], - ] - ]; - } - /** - * 获得AI智能客服配置信息 - * @param int $site_id 站点ID, 默认为1, 业务站点uniacid值与site_id保持一致 - * @param string $app_module 应用模块, 默认为*, 表示所有应用模块都生效 - * @return array - */ - public function getAIAgentServicesConfig($site_id = 1, $app_module = '*') - { - return $this->_getAIConfig($site_id, $app_module, 'AI_AGENT_SERVICES_CONFIG', $this->getCommonAIAgentServicesConfig()); - } - /** * 设置获取H5域名配置 * @param $data diff --git a/src/app/shop/controller/Config.php b/src/app/shop/controller/Config.php index c73eb57ad..a8316c045 100644 --- a/src/app/shop/controller/Config.php +++ b/src/app/shop/controller/Config.php @@ -188,52 +188,6 @@ class Config extends BaseShop } } - /** - * AI配置 - */ - public function ai() - { - // 获取当前请求的 site_id - $site_id = $this->site_id; - $app_module = $this->app_module; - - $config_model = new ConfigModel(); - if (request()->isJson()) { - $type = input('type', ''); - $data = input('config', []); - - if ($type == 'save_platform_cfg') { - $data = json_decode($data, true); - $result_platform = $config_model->setAIPlatformConfig($data, $site_id, $app_module); - return $result_platform; - } else if ($type == 'save_aiagent_cfg') { - $data = json_decode($data, true); - $result_agent = $config_model->setAIAgentServicesConfig($data, $site_id, $app_module); - return $result_agent; - } - - return '无法识别的操作类型: ' . $type; - } else { - $support_app_modules = $config_model->getSupportAppModules(); - $support_ai_platform_types = $config_model->getSupportAIPlatformTypes(); - $config_platform = $config_model->getAIPlatformConfig($site_id)[ 'data' ][ 'value' ]; - $config_agent = $config_model->getAIAgentServicesConfig($site_id)[ 'data' ][ 'value' ]; - - $this->assign('support_app_modules', $support_app_modules); - $this->assign('support_ai_platform_types', $support_ai_platform_types); - $this->assign('platform_info', $config_platform); - $this->assign('agent_info', $config_agent); - - // return json_encode([ - // 'support_ai_platform_types' => $support_ai_platform_types, - // 'support_app_modules' => $support_app_modules, - // 'platform_info' => $config_platform, - // ]); - - return $this->fetch('config/ai/index'); - } - } - /** * 客服配置 */ diff --git a/src/app/shop/view/config/ai/agent.html b/src/app/shop/view/config/ai/agent.html deleted file mode 100644 index 62297e4a8..000000000 --- a/src/app/shop/view/config/ai/agent.html +++ /dev/null @@ -1,141 +0,0 @@ -
- -
- -
- 基础设置 -
-
- -
- -
-
- - -
-
-
    -
  • 简体中文
  • -
  • English
  • -
-
-
-
- -
- -
-
- -
- -
- -
支持JPG、PNG、GIF格式,建议尺寸:100x100px
-
-
- -
- -
- -
支持JPG、PNG、GIF格式,建议尺寸:100x100px
-
-
- -
- -
- - -
-
-
-
-
- -
- -
-
- -
- -
- -
Support JPG, PNG, GIF formats, recommended size: - 100x100px
-
-
- -
- -
- -
Support JPG, PNG, GIF formats, recommended size: - 100x100px
-
-
- -
- -
- - -
-
-
-
-
- -
- - -
- 显示设置 -
-
- -
- -
-
- -
- -
- -
-
-
建议设置在10-500条之间
-
- -
- -
- -
-
- - -
- -
-
-
\ No newline at end of file diff --git a/src/app/shop/view/config/ai/index.html b/src/app/shop/view/config/ai/index.html deleted file mode 100644 index 05ffd3256..000000000 --- a/src/app/shop/view/config/ai/index.html +++ /dev/null @@ -1,209 +0,0 @@ - - - -
- -
- -
- - {include file="app/shop/view/config/ai/platform.html" /} -
-
-
- - - \ No newline at end of file diff --git a/src/app/shop/view/config/ai/js/platform.js b/src/app/shop/view/config/ai/js/platform.js deleted file mode 100644 index 60711b429..000000000 --- a/src/app/shop/view/config/ai/js/platform.js +++ /dev/null @@ -1,397 +0,0 @@ -// 平台选择下拉框处理 -form.on('select(platformSelect)', function (data) { - var platformId = data.value; - if (platformId) { - // 可以在这里添加根据平台ID高亮显示对应表格行的逻辑 - $('#platformTable tr').removeClass('layui-bg-blue'); - $('#platformTable tr[data-id="' + platformId + '"]').addClass('layui-bg-blue'); - } -}); - -// 应用模块选择下拉框处理 -form.on('select(appModuleSelect)', function (data) { - var appModule = data.value; - loadPlatformConfigByAppModule(appModule); -}); - -// 存储平台配置的初始状态,用于检测数据变更 -function storeInitialData() { - $('#platformTable tr[data-id]').each(function () { - var platformId = $(this).data('id'); - var initialData = { - name: $('input[name="platform_name[' + platformId + ']"]').val(), - type: $('select[name="platform_type[' + platformId + ']"]').val(), - base_url: $('input[name="platform_base_url[' + platformId + ']"]').val(), - api_key: $('input[name="platform_api_key[' + platformId + ']"]').val(), - desc: $('input[name="platform_desc[' + platformId + ']"]').val() - }; - // 使用data属性存储初始数据 - $(this).data('initial-data', initialData); - }); -} - -// 检查平台数据是否有变更 -function hasDataChanged(platformId) { - var row = $('#platformTable tr[data-id="' + platformId + '"]'); - var initialData = row.data('initial-data'); - - // 对于新添加的平台(没有初始数据),认为有变更 - if (!initialData) { - return true; - } - - var currentData = { - name: $('input[name="platform_name[' + platformId + ']"]').val(), - type: $('select[name="platform_type[' + platformId + ']"]').val(), - base_url: $('input[name="platform_base_url[' + platformId + ']"]').val(), - api_key: $('input[name="platform_api_key[' + platformId + ']"]').val(), - desc: $('input[name="platform_desc[' + platformId + ']"]').val() - }; - - // 比较初始数据和当前数据 - for (var key in initialData) { - if (initialData[key] !== currentData[key]) { - return true; - } - } - - return false; -} - -// 更新保存按钮图标 -function updateSaveButtonIcon(platformId) { - var saveButton = $('#platformTable tr[data-id="' + platformId + '"] .save-platform'); - var hasChanged = hasDataChanged(platformId); - - if (hasChanged) { - saveButton.find('i').removeClass('layui-icon-ok').addClass('layui-icon-edit'); - } else { - saveButton.find('i').removeClass('layui-icon-edit').addClass('layui-icon-ok'); - } -} - -// 监听输入框变化 -$(document).on('input propertychange', '#platformTable input.layui-table-edit', function () { - var platformId = $(this).closest('tr').data('id'); - updateSaveButtonIcon(platformId); -}); - -// 监听选择框变化 -$(document).on('change', '#platformTable select.layui-table-edit', function () { - var platformId = $(this).closest('tr').data('id'); - updateSaveButtonIcon(platformId); -}); - -// 初始化时存储初始数据 -storeInitialData(); - -function genNewPlatformId() { - return 'temp_' + new Date().getTime() + Math.random().toString(36).substring(2); -} - -// 保存平台配置 -$(document).on('click', '.save-platform', function () { - var platformId = $(this).data('id'); - var name = $('input[name="platform_name[' + platformId + ']"]').val(); - var type = $('select[name="platform_type[' + platformId + ']"]').val(); - var apiUrl = $('input[name="platform_base_url[' + platformId + ']"]').val(); - var apiKey = $('input[name="platform_api_key[' + platformId + ']"]').val(); - - if (!name) { - layer.msg('平台名称不能为空', { icon: 2 }); - return; - } - - if (!type) { - layer.msg('请选择平台类型', { icon: 2 }); - return; - } - - if (!apiUrl) { - layer.msg('API URL不能为空', { icon: 2 }); - return; - } - - if (!apiKey) { - layer.msg('API Key不能为空', { icon: 2 }); - return; - } - - // 建立临时的平台ID - var newPlatformId = String(platformId).startsWith('temp_') ? genNewPlatformId() : platformId; - - // 更新行的data-id属性 - $('#platformTable tr[data-id="' + platformId + '"]').attr('data-id', newPlatformId); - - // 更新表单元素的name属性中的ID - $('#platformTable tr[data-id="' + newPlatformId + '"] input, #platformTable tr[data-id="' + newPlatformId + '"] select').each(function () { - var oldName = $(this).attr('name'); - if (oldName) { // 确保oldName存在才调用replace方法 - var newName = oldName.replace(platformId, newPlatformId); - $(this).attr('name', newName); - } - }); - - // 更新按钮的data-id属性 - $('#platformTable tr[data-id="' + newPlatformId + '"] button').data('id', newPlatformId); - - // 更新默认平台下拉框 - var select = $('select[name="selected_platform"]'); - // 检查是否已存在相同ID的选项 - if (select.find('option[value="' + newPlatformId + '"]').length === 0) { - select.append(''); - form.render('select'); // 重新渲染select - } - - // 保存成功后,更新初始数据并将图标改回layui-icon-ok - var newRow = $('#platformTable tr[data-id="' + newPlatformId + '"]'); - var updatedData = { - name: name, - type: type, - base_url: apiUrl, - api_key: apiKey, - desc: $('input[name="platform_desc[' + newPlatformId + ']"]').val() - }; - newRow.data('initial-data', updatedData); - - // 更新保存按钮图标为layui-icon-ok - newRow.find('.save-platform i').removeClass('layui-icon-edit').addClass('layui-icon-ok'); - - // 显示保存成功提示 - layer.msg('保存成功', { icon: 1 }); -}); - -// 删除平台 -$(document).on('click', '.delete-platform', function () { - var platformId = $(this).data('id'); - layer.confirm('确定要删除这个平台配置吗?', { - btn: ['确定', '取消'] - }, function (index) { - // 删除行 - $('#platformTable tr[data-id="' + platformId + '"]').remove(); - - // 从下拉框中移除对应的选项 - $('select[name="selected_platform"] option[value="' + platformId + '"]').remove(); - form.render('select'); - - // 检查表格是否为空,如果为空则显示提示 - if ($('#platformTable tr').length === 0) { - $('#platformTable').append('暂无平台配置'); - } - - layer.close(index); - }); -}); - -// 禁用/开启平台 -$(document).on('click', '.toggle-platform', function () { - var platformId = $(this).data('id'); - var status = $(this).data('status'); - var newStatus = status === 1 ? 0 : 1; - - // 更新按钮状态 - $(this).data('status', newStatus); - $(this).html(newStatus === 1 ? '' : ''); - $(this).attr('title', newStatus === 1 ? '开启' : '禁用'); - - // 如果平台被禁用,从默认平台下拉框中移除 - if (newStatus === 0) { - var option = $('select[name="selected_platform"] option[value="' + platformId + '"]'); - if (option.length > 0) { - option.detach().data('disabled', true); // 保存选项但不显示 - form.render('select'); - } - } - // 如果平台被启用,将选项添加回下拉框 - else { - var savedOption = $('select[name="selected_platform"] option[data-disabled="true"][value="' + platformId + '"]'); - if (savedOption.length === 0) { - // 如果没有保存的选项,获取平台名称并创建新选项 - var platformName = $('#platformTable tr[data-id="' + platformId + '"] input[name^="platform_name"]').val(); - if (platformName) { - $('select[name="selected_platform"]').append(''); - form.render('select'); - } - } else { - savedOption.removeData('disabled').appendTo('select[name="selected_platform"]'); - form.render('select'); - } - } - - layer.msg(newStatus === 1 ? '已设置为开启,保存后生效' : '已设置为禁用,保存后生效', { icon: 1 }); -}); - -// 添加新平台 -$('#addPlatform').on('click', function () { - // 生成一个临时ID - var tempId = genNewPlatformId(); - - // 创建新行HTML - var newRow = '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - ''; - - // 获取表格body - var tbody = $('#platformTableBody'); - - // 检查是否有暂无平台配置的提示行 - var emptyRow = tbody.find('tr:has(td[colspan="5"])'); - if (emptyRow.length > 0) { - emptyRow.replaceWith(newRow); - } else { - tbody.append(newRow); - } - - // 重新渲染表单元素 - form.render(); - - // 为新添加的行设置初始数据为null,确保图标显示为编辑状态 - tbody.find('tr[data-id="' + tempId + '"]').data('initial-data', null); - - // 新添加的行默认显示编辑图标 - tbody.find('tr[data-id="' + tempId + '"] .save-platform i').removeClass('layui-icon-ok').addClass('layui-icon-edit'); - - // 聚焦到新添加的行的第一个输入框 - tbody.find('input[name="platform_name[' + tempId + ']"]').focus(); -}); - -// 保存平台配置 -form.on('submit(save_platform_cfg)', function (data) { - // 验证表单数据 - if (!form.verify()) { - return false; - } - - // 验证是否选择了默认平台 - if (!data.field['selected_platform']) { - layer.msg('请选择默认AI智能客服平台', { icon: 2 }); - return false; - } - - // 处理新增的平台配置 - var cfg = {}; - var platforms = []; - $('#platformTableBody tr[data-id]').each(function () { - var id = $(this).data('id'); - var platform = { - 'id': id, - 'name': $(this).find('input[name^="platform_name"]').val(), - 'type': $(this).find('select[name^="platform_type"]').val(), - 'type_label': $(this).find('select[name^="platform_type"]').find('option:selected').text(), - 'enable': parseInt($(this).find('button.toggle-platform').data('status') || 0), - 'desc': $(this).find('input[name^="platform_desc"]').val(), - 'base_url': $(this).find('input[name^="platform_base_url"]').val(), - 'api_key': $(this).find('input[name^="platform_api_key"]').val(), - }; - platforms.push(platform); - }); - - cfg = { - 'default': { - 'id': data.field['selected_platform'] || (platforms[0] ? platforms[0].id : ''), - 'name': data.field['selected_platform_name'] || (platforms[0] ? platforms[0].name : ''), - }, - 'list': platforms, - }; - - $.ajax({ - url: ns.url("shop/config/ai"), - data: { - config: JSON.stringify(cfg), - type: 'save_platform_cfg', - app_module: data.field['app_module'] - }, - dataType: 'JSON', - type: 'POST', - success: function (res) { - if (res.code == 0) { - layer.msg('保存成功', { icon: 1 }); - // 重新加载当前应用模块的配置,确保数据同步 - loadPlatformConfigByAppModule(data.field['app_module']); - layer.closeAll(); - } else { - layer.msg('保存失败:' + res.message, { icon: 2 }); - } - } - }); -}); - -// 保存AI智能客服平台配置 -form.on('submit(save_aiagent_cfg)', function (data) { - // 验证表单数据 - if (!form.verify()) { - return false; - } - - console.log('data.field =', data.field); - - var cfg = {}; - - // 处理关于AI智能客服配置,将ai_avater[en], ai_avater[zh] 合并到 ai_avater 字段 - ['ai_avater', 'ai_name', 'user_avater', 'welcome_messages'].forEach(function (field) { - cfg[field] = { - 'en': data.field[field + '[en]'], - 'zh_CN': data.field[field + '[zh_CN]'], - }; - }); - - ['show_load_more_button', 'stream_mode'].forEach(function (field) { - cfg[field] = data.field[field] === 'on'; - }); - - ['max_messages'].forEach(function (field) { - cfg[field] = data.field[field] || 0; - }); - - $.ajax({ - url: ns.url("shop/config/ai"), - data: { - config: JSON.stringify(cfg), - type: 'save_aiagent_cfg', - }, - dataType: 'JSON', - type: 'POST', - success: function (res) { - if (res.code == 0) { - layer.msg('保存成功', { icon: 1 }); - listenerHash(); // 刷新页面 - layer.closeAll(); - } else { - layer.msg('保存失败:' + res.message, { icon: 2 }); - } - } - }); -}); diff --git a/src/app/shop/view/config/ai/platform.html b/src/app/shop/view/config/ai/platform.html deleted file mode 100644 index 7bce932c3..000000000 --- a/src/app/shop/view/config/ai/platform.html +++ /dev/null @@ -1,465 +0,0 @@ -
- -
- -
- 应用模块选择 -
-
- -
- -
-
- - -
- 基本设置 -
- -
- -
- -
-
- - -
- AI服务平台配置 -
- -
- - - - - - - - - - - - - - - - -
名称类型Base URLAPI Key描述操作
请选择应用模块
-
- - -
- -
- - -
- -
-
-
- - \ No newline at end of file diff --git a/src/app/shop/view/layout/base.html b/src/app/shop/view/layout/base.html index bb1d39230..478e2681c 100644 --- a/src/app/shop/view/layout/base.html +++ b/src/app/shop/view/layout/base.html @@ -22,7 +22,6 @@ -