<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------
namespace app\adminapi\logic\write;
use app\common\enum\write\WriteCateEnum;
use app\common\logic\BaseLogic;
use app\common\model\write\WriteCategory;
use Exception;
/**
* 写作分类逻辑类
*/
class CategoryLogic extends BaseLogic
{
/**
* @notes AI模型
* @param int $type (类型: 1=仅返回渠道, 2=全部返回)
* @return array
* @author fzr
*/
public static function ai(int $type, int $other): array
{
$channelModel = [];
$defaultConfig = self::getAiChatConfig();
if ($other === 1) {
$defaultConfig = self::getAiChatConfig(false);
}
foreach ($defaultConfig as $key => &$item) {
if ($key == 'api2d3.5') {
$item['models'] = $defaultConfig['gpt3.5']['models'];
}
if ($key == 'api2d4.0') {
$item['models'] = $defaultConfig['gpt4.0']['models'];
}
$channelModel[$item['basis']['alias']] = $item['basis']['name'];
foreach (['context_num', 'top_p', 'n', 'presence_penalty', 'frequency_penalty'] as $k) {
if (isset($item['basis'][$k])) {
unset($item['basis'][$k]);
}
}
}
if ($type === 1) {
return [
'channel' => $channelModel
] ?? [];
}
return [
'open' => array_keys($channelModel)[0],
'channel' => $channelModel,
'lists' => $defaultConfig
] ?? [];
}
/**
* @notes 所有写作类型
* @return array
* @throws @\think\db\exception\DataNotFoundException
* @throws @\think\db\exception\DbException
* @throws @\think\db\exception\ModelNotFoundException
*/
public static function all(): array
{
$modelWriteCategory = new WriteCategory();
return $modelWriteCategory
->field(['id,title'])
->order('sort desc, id desc')
->select()
->toArray();
}
/**
* @notes 写作类型详情
* @param int $id
* @return array
* @author fzr
*/
public static function detail(int $id): array
{
// 获取详情
$modelWriteCategory = new WriteCategory();
$detail = $modelWriteCategory->where(['id'=>$id])->findOrEmpty()->toArray();
if (!$detail) {
return [];
}
// 模型设置
$channelModel = [];
$currentModel = $detail['ai'];
$defaultConfig = self::getAiChatConfig();
$cacheConfigs = json_decode($detail['model']??'[]', true);
foreach ($defaultConfig as $key => &$item) {
$cacheConfig = $cacheConfigs[$item['basis']['alias']] ?? [];
$makesConfig = array_merge($item['basis'], $cacheConfig);
$item['basis'] = $makesConfig;
if ($key === 'api2d3.5') {
$item['models'] = $defaultConfig['gpt3.5']['models'];
}
if ($key === 'api2d4.0') {
$item['models'] = $defaultConfig['gpt4.0']['models'];
}
$item['basis']['temperature'] = floatval($item['basis']['temperature'] ?? 0);
$channelModel[$item['basis']['alias']] = $item['basis']['name'];
foreach (['context_num', 'top_p', 'n', 'presence_penalty', 'frequency_penalty'] as $k) {
if (isset($item['basis'][$k])) {
unset($item['basis'][$k]);
}
}
}
$forms = json_decode($detail['forms'], true);
foreach ($forms as &$it) {
if (isset($it['props']['disabled'])) {
$it['props']['disabled'] = (bool)$it['props']['disabled'];
}
if (isset($it['props']['isRequired'])) {
$it['props']['isRequired'] = (bool)$it['props']['isRequired'];
}
}
unset($detail['ai']);
unset($detail['model']);
unset($detail['forms']);
unset($detail['delete_time']);
$detail['forms'] = $forms;
$detail['reduction_url'] = 'https://bailian.console.aliyun.com';// 模型reduce地址
return [
'basis' => $detail,
'aiConfig' => [
'open' => $currentModel,
'channel' => $channelModel,
'lists' => $defaultConfig
]
] ?? [];
}
/**
* @notes 写作类型新增
* @param array $post
* @return bool
* @author fzr
*/
public static function add(array $post): bool
{
try {
$prompt = $post['prompt_archive'] ?? '';
$outlineStatus = $post['outline_status'] ?? 1;
if (!str_contains($prompt, '${document}') && $outlineStatus) {
throw new Exception('全文调教文案中: “大纲内容” 是必填的');
}
if (!str_contains($prompt, '${abstract}') && $outlineStatus) {
throw new Exception('全文调教文案中: “章节摘要” 是必填的');
}
$sellPrice = [0];
foreach ($post['forms'] as $item) {
$name = $item['name'];
if ($item['props']['isPrice']) {
if ($name !== 'WidgetRadio') {
$sellPrice[0] = $item['props']['price'] ?: 0;
} else {
$sellPrice = array_values($item['props']['price']);
}
break;
}
}
if (isset($post['model']['agency_tips'])) {
unset($post['model']['agency_tips']);
}
$models[$post['ai']] = $post['model'];
WriteCategory::create([
'title' => $post['title'],
'type' => $post['type'] ?? WriteCateEnum::TYPE_NORMAL,
'image' => $post['image'] ?? '',
'banner' => $post['banner'] ?? '',
'intro' => $post['intro'] ?? '',
'added_service' => $post['added_service'] ?? [],
'prompt_outline' => $post['prompt_outline'] ?? '',
'prompt_archive' => $post['prompt_archive'] ?? '',
'prompt_abstract' => $post['prompt_abstract'] ?? '',
'words_num' => $post['words_num'] ?? 0,
'outline_status' => $outlineStatus,
'ai' => $post['ai'] ?? '',
'model' => json_encode($models, JSON_UNESCAPED_UNICODE),
'forms' => json_encode($post['forms'], JSON_UNESCAPED_UNICODE),
'sell_price' => json_encode($sellPrice),
'sort' => $post['sort'] ?? 0,
'status' => $post['status'] ?? 0,
'virtual_gen' => $post['virtual_gen'] ?? 0,
'gen_count' => 0,
'is_recommend' => $post['is_recommend'] ?? 0,
'reduction_status' => $post['reduction_status'] ?? 0,
'reduction_price' => $post['reduction_price'] ?? 0,
'create_time' => time(),
'update_time' => time()
]);
return true;
} catch (Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 写作类型编辑
* @param array $post
* @return bool
* @author fzr
*/
public static function edit(array $post): bool
{
try {
$prompt = $post['prompt_archive'] ?? '';
$outlineStatus = $post['outline_status'] ?? 1;
if (!str_contains($prompt, '${document}') && $outlineStatus) {
throw new Exception('全文调教文案中: “大纲内容” 是必填的');
}
if (!str_contains($prompt, '${abstract}') && $outlineStatus) {
throw new Exception('全文调教文案中: “章节摘要” 是必填的');
}
$modelWriteCategory = new WriteCategory();
$category = $modelWriteCategory->field(['id,model'])->where(['id'=>intval($post['id'])])->findOrEmpty()->toArray();
if (!$category) {
throw new Exception('数据不存在了!');
}
$sellPrice = [0];
foreach ($post['forms'] as $item) {
$name = $item['name'];
if ($item['props']['isPrice']) {
if ($name != 'WidgetRadio') {
$sellPrice[0] = $item['props']['price'] ?: 0;
} else {
$sellPrice = array_values($item['props']['price']);
}
break;
}
}
if (isset($post['model']['agency_tips'])) {
unset($post['model']['agency_tips']);
}
$category['model'] = json_decode($category['model'], true);
$category['model'][$post['ai']] = $post['model'];
WriteCategory::update([
'title' => $post['title'],
'type' => $post['type'] ?? WriteCateEnum::TYPE_NORMAL,
'image' => $post['image'] ?? '',
'banner' => $post['banner'] ?? '',
'intro' => $post['intro'] ?? '',
'added_service' => $post['added_service'] ?? [],
'prompt_outline' => $post['prompt_outline'] ?? '',
'prompt_archive' => $post['prompt_archive'] ?? '',
'prompt_abstract' => $post['prompt_abstract'] ?? '',
'words_num' => $post['words_num'] ?? 0,
'outline_status' => $outlineStatus,
'ai' => $post['ai'] ?? '',
'model' => json_encode($category['model'], JSON_UNESCAPED_UNICODE),
'forms' => json_encode($post['forms'], JSON_UNESCAPED_UNICODE),
'sell_price' => json_encode($sellPrice),
'sort' => $post['sort'] ?? 0,
'status' => $post['status'] ?? 0,
'virtual_gen' => $post['virtual_gen'] ?? 0,
'is_recommend' => $post['is_recommend'] ?? 0,
'reduction_status' => $post['reduction_status'] ?? 0,
'reduction_price' => $post['reduction_price'] ?? 0,
'update_time' => time()
], ['id'=>intval($post['id'])]);
return true;
} catch (Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 写作类型删除
* @param array $ids
* @return bool
* @author fzr
*/
public static function del(array $ids): bool
{
try {
WriteCategory::destroy($ids);
return true;
} catch (Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 写作类型状态
* @param int $id
* @return bool
* @author fzr
*/
public static function status(int $id): bool
{
try {
$modelWriteCategory = new WriteCategory();
$category = $modelWriteCategory->field(['id,status'])->where(['id'=>$id])->findOrEmpty();
if (!$category) {
throw new Exception('数据不存在了!');
}
WriteCategory::update([
'status' => !$category['status'],
'update_time' => time()
], ['id'=>$id]);
if ($category['status']) {
self::setError('禁用成功');
} else {
self::setError('启用成功');
}
return true;
} catch (Exception $e) {
self::setError($e->getMessage());
return false;
}
}
/**
* @notes 获取默认模型
* @param bool $filterPPT
* @return array
* @author mjf
* @date 2024/2/23 10:59
*/
public static function getAiChatConfig(bool $filterPPT = true): array
{
$defaultConfig = config('ai.ChatModels');
if (true === $filterPPT && !empty($defaultConfig['xunfei_ppt'])) {
unset($defaultConfig['xunfei_ppt']);
}
return $defaultConfig;
}
/**
* @notes 推荐状态
* @param int $id
* @return bool
* @author mjf
* @date 2024/4/8 11:50
*/
public static function recommend(int $id): bool
{
try {
$modelWriteCategory = new WriteCategory();
$category = $modelWriteCategory->field(['id,is_recommend'])->where(['id'=>$id])->findOrEmpty();
if (!$category) {
throw new Exception('数据不存在了!');
}
WriteCategory::update([
'is_recommend' => !$category['is_recommend'],
'update_time' => time()
], ['id'=>$id]);
if ($category['is_recommend']) {
self::setError('关闭成功');
} else {
self::setError('启用成功');
}
return true;
} catch (Exception $e) {
self::setError($e->getMessage());
return false;
}
}
}