253 lines
9.0 KiB
PHP
Executable File
253 lines
9.0 KiB
PHP
Executable File
<?php
|
||
|
||
namespace App\Service\common\ai\xunfei\client;
|
||
|
||
use App\BaseApp\BaseClient;
|
||
use App\Service\common\ai\PromptService;
|
||
|
||
class XunFeiAiClientV1 extends BaseClient
|
||
{
|
||
// private $appId = '0970a6eb';
|
||
// private $apiSecret = 'MjVjZjk2ODM4NjAwOWM1MDVjZTU1MjQ2';
|
||
// private $apiKey = '578150544693a7c2108306db2b63cdcd';
|
||
// private $apiPassword = 'Bearer qlODxEjzXOVIIdIfyVZl:WxLxhqESNqMmOjskDVwt';
|
||
private $apiPassword = 'Bearer nZurRXizItjgjRmPkcRu:MiJrBykLPPEqNDHsGhCl';
|
||
public function __construct()
|
||
{
|
||
parent::__construct();
|
||
// $this->baseUrl = 'https://spark-api-open.xf-yun.com/v2/chat/completions';
|
||
$this->baseUrl = 'https://spark-api-open.xf-yun.com/v1/chat/completions';
|
||
$this->headers['Authorization'] = $this->apiPassword;
|
||
$this->promptService = new PromptService();
|
||
}
|
||
|
||
|
||
public function genSignPrompt(string $time, $dayDesc, $version = 1)
|
||
{
|
||
if (empty($time)) {
|
||
$time = get_time(true, 'Y-m-d');
|
||
}
|
||
|
||
if ($version == 1) {
|
||
$prompt = $this->promptService->genSignPrompt($time, $dayDesc);
|
||
} elseif ($version == 2) {
|
||
$prompt = $this->promptService->genSignPrompt2($time, $dayDesc);
|
||
} elseif ($version == 3) {
|
||
$prompt = $this->promptService->genHelpPrompt($time, $dayDesc, request()->post('prompt', ''));
|
||
} elseif ($version == 4) {
|
||
$prompt = $this->promptService->dailyCourseAnalysis($time, $dayDesc, request()->post('prompt', ''));
|
||
}
|
||
return $prompt. '\n 要求:不使用Markdown,纯文本输出,不要出现有关于Markdown的语法,分段清晰。';
|
||
}
|
||
|
||
/**
|
||
* 患者画像分析 - 构建提示词
|
||
*/
|
||
public function buildPatientProfilePrompt(array $userInfo, array $prescriptionHistory, string $diagnosis): string
|
||
{
|
||
$patientInfo = $this->formatPatientInfo($userInfo);
|
||
$historyInfo = $this->formatPrescriptionHistory($prescriptionHistory);
|
||
|
||
$prompt = "你是一名医疗数据分析专家,请根据以下患者信息分析患者画像:
|
||
|
||
患者基本信息:
|
||
{$patientInfo}
|
||
|
||
诊断信息:{$diagnosis}
|
||
|
||
处方历史:
|
||
{$historyInfo}
|
||
|
||
请生成一个完整的患者画像分析报告,包含以下部分:
|
||
1. 患者基本信息总结
|
||
2. 健康状况评估
|
||
3. 用药习惯分析
|
||
4. 疾病风险预测
|
||
5. 个性化医疗建议
|
||
|
||
请将分析结果以HTML格式返回,确保可以直接在iframe中展示。HTML结构要完整,包含必要的CSS样式。";
|
||
|
||
return $prompt;
|
||
}
|
||
|
||
/**
|
||
* 用户增长分析 - 构建提示词
|
||
*/
|
||
public function buildUserGrowthPrompt(string $type, array $growthData): string
|
||
{
|
||
$typeMap = [
|
||
0 => '天',
|
||
1 => '周',
|
||
2 => '月',
|
||
3 => '年'
|
||
];
|
||
|
||
$periodType = $typeMap[$type] ?? '未知周期';
|
||
$dataSummary = $this->formatGrowthData($growthData);
|
||
|
||
$prompt = "你是一名数据分析专家,请根据以下用户增长数据进行分析和预测:
|
||
|
||
统计周期:按{$periodType}统计
|
||
增长数据:
|
||
{$dataSummary}
|
||
|
||
请完成以下分析:
|
||
1. 当前增长趋势分析(上升/下降/平稳)
|
||
2. 增长模式识别(季节性、周期性等)
|
||
3. 未来3个{$periodType}的用户增长预测
|
||
4. 增长建议和优化策略
|
||
|
||
请将分析结果和预测以HTML格式返回,包含图表说明和趋势可视化(使用纯HTML+CSS实现简单的数据可视化),确保可以直接在iframe中展示。需要包含完整的HTML结构。";
|
||
|
||
return $prompt;
|
||
}
|
||
|
||
/**
|
||
* 格式化患者信息
|
||
*/
|
||
private function formatPatientInfo(array $userInfo): string
|
||
{
|
||
$info = [];
|
||
$info[] = "年龄:" . ($userInfo['age'] ?? '未知');
|
||
$info[] = "性别:" . ($userInfo['gender'] ?? '未知');
|
||
$info[] = "诊断:" . ($userInfo['diagnosis'] ?? '未提供');
|
||
|
||
if (!empty($userInfo['medical_history'])) {
|
||
$info[] = "患病历史:" . (is_array($userInfo['medical_history']) ?
|
||
implode('、', $userInfo['medical_history']) : $userInfo['medical_history']);
|
||
}
|
||
|
||
if (!empty($userInfo['treatment_history'])) {
|
||
$info[] = "就诊历史:" . (is_array($userInfo['treatment_history']) ?
|
||
implode('、', $userInfo['treatment_history']) : $userInfo['treatment_history']);
|
||
}
|
||
|
||
if (!empty($userInfo['symptoms'])) {
|
||
$info[] = "症状:" . (is_array($userInfo['symptoms']) ?
|
||
implode('、', $userInfo['symptoms']) : $userInfo['symptoms']);
|
||
}
|
||
|
||
return implode("\n", $info);
|
||
}
|
||
|
||
/**
|
||
* 格式化药品信息
|
||
*/
|
||
private function formatDrugsInfo(array $drugs): string
|
||
{
|
||
$drugList = [];
|
||
foreach ($drugs as $drug) {
|
||
// $drugInfo = "{index_id: {$drug['index_id']}, 药品ID: {$drug['drug_id']}, '名称: {$drug['drug_name']}', 单价: '{$drug['price']}'}";
|
||
// $drugInfo = "index_id: {$drug['index_id']}, 药品ID: {$drug['drug_id']}, '名称: {$drug['drug_name']}'";
|
||
$drugInfo = "ID:{$drug['drug_id']},名称:{$drug['drug_name']}";
|
||
|
||
if (!empty($drug['indications']?? '')) {
|
||
$drugInfo .= ", 适应症: {$drug['indications']}";
|
||
}
|
||
|
||
if (!empty($drug['contraindications']?? '')) {
|
||
$drugInfo .= ", 禁忌: {$drug['contraindications']}";
|
||
}
|
||
|
||
$drugList[] = $drugInfo;
|
||
}
|
||
|
||
return implode("\n", $drugList);
|
||
// return '{'. implode(",", $drugList). '}';
|
||
}
|
||
|
||
/**
|
||
* 格式化处方历史
|
||
*/
|
||
private function formatPrescriptionHistory(array $prescriptionHistory): string
|
||
{
|
||
if (empty($prescriptionHistory)) {
|
||
return "无处方历史记录";
|
||
}
|
||
|
||
$historyList = [];
|
||
foreach ($prescriptionHistory as $index => $history) {
|
||
$historyInfo = "处方" . ($index + 1) . ": ";
|
||
$historyInfo .= "日期: " . ($history['date'] ?? '未知') . ", ";
|
||
$historyInfo .= "诊断: " . ($history['diagnosis'] ?? '未知') . ", ";
|
||
$historyInfo .= "药品: " . (is_array($history['drugs']) ?
|
||
implode('、', $history['drugs']) : ($history['drugs'] ?? '无'));
|
||
|
||
$historyList[] = $historyInfo;
|
||
}
|
||
|
||
return implode("\n", $historyList);
|
||
}
|
||
|
||
/**
|
||
* 格式化增长数据
|
||
*/
|
||
private function formatGrowthData(array $growthData): string
|
||
{
|
||
$dataList = [];
|
||
foreach ($growthData as $period => $count) {
|
||
$dataList[] = "{$period}: {$count} 用户";
|
||
}
|
||
|
||
return implode("\n", $dataList);
|
||
}
|
||
|
||
/**
|
||
* 发送请求到讯飞星火API(模拟实现)
|
||
*/
|
||
public function sendRequest(string $prompt, string $type): array
|
||
{
|
||
if (empty($type)) {
|
||
$type = 'json_object';
|
||
}
|
||
// 这里构建实际的API请求参数
|
||
$requestData = [
|
||
'model' => 'lite',
|
||
'user' => 'user_123456',
|
||
'messages' => [
|
||
[
|
||
'role' => 'system',
|
||
'content' => $prompt
|
||
// 'content' => '你好,返回格式要用json:{id: xxxx, content: 你好}'
|
||
]
|
||
],
|
||
'temperature' => 0.7,
|
||
'response_format' => [
|
||
'type' => $type
|
||
],
|
||
];
|
||
$result = $this->init()->postJson('', $requestData);
|
||
|
||
if (!array_key_exists('body', $result)) {
|
||
$this->utils->errorThrow('OldShopApi Http请求失败: '. json_encode($result));
|
||
}
|
||
if ($result['body']['code'] !== 0) {
|
||
$this->utils->errorThrow('OldShopApi Http请求失败: '. $result['body']['errmsg']);
|
||
}
|
||
return $result['body'];
|
||
}
|
||
|
||
/**
|
||
* 解析AI响应(模拟实现)
|
||
*/
|
||
public function parseResponse(array $apiResponse): array
|
||
{
|
||
// 在实际实现中,这里会解析讯飞星火的API响应
|
||
// 替换 $apiResponse['choices'][0]['message']['content']的```json
|
||
$content = $apiResponse['choices'][0]['message']['content'];
|
||
// $content = str_replace('\"', '"', $content);
|
||
// $content = str_replace(PHP_EOL, '', $content);
|
||
// $content = str_replace(' ', '', $content);
|
||
// $content = str_replace(' ', '', $content);
|
||
// $content = str_replace('```json', '', $content);
|
||
// $content = str_replace('```', '', $content);
|
||
// $content = json_decode($content, true);
|
||
// 现在返回模拟数据
|
||
return [
|
||
'success' => true,
|
||
'data' => $content,
|
||
'message' => '响应解析完成'
|
||
];
|
||
}
|
||
}
|