## GitHub 同步说明 | 项 | 内容 | |:---|:---| | 仓库 | https://github.com/fnvtk/cunkebao_v3 | | 分支 | develop | | 方向 | 本地 → GitHub(单向 push) | | 是否拉取远程 | 否(未 fetch / pull / merge) | | 是否改本地源文件 | 否(仅 git add/commit,未编辑业务/文档正文) | | 远程基准 | origin/develop @b5b40e8b| | 本批工作区变更 | 999 files, +47622 / -4007 lines | ## 一并推送的本地已有 commit(此前未 push) 1.3aa7ecf8deploy: 官网 ckb.quwanzhi.com 宝塔上线 DNS+SSL+验收文档 2.16a70045fix(官网): 桌面导航仅保留一个留资 CTA 并重新上线 3.dbe7b7aafix(官网): Hero 改为主 CTA 按钮并去掉重复 1200+ 数据条 4.ac82726echore(部署): 五端上线验收46项并统一留资与缓存版本 ## 本 commit 目录统计 | 目录 | 文件数 | 说明 | |:---|---:|:---| | 开发文档/ | 639 | 10、项目管理、未完成项跨仓汇总、五端需求/部署/接口 | | Server/ | 129 | 后端 API、迁移、部署相关 | | Touchkebao/ | 80 | PC 工作台、获客、算力 | | 官网/ | 61 | ckb.quwanzhi.com 静态站与 CTA 迭代 | | Cunkebao/ | 49 | 移动端场景/设置/流量池 | | SuperAdmin/ | 26 | 超管后台 | | .cursor/ | 11 | 规则与 Skill | | 其他 | 14 | docker-compose、.obsidian、.codegraph 等 | ## 重点文件(本地为准) - 开发文档/1、需求/修改/未完成项与跨仓验收汇总.md - 开发文档/10、项目管理/账号密码与登录环境一览.md - 开发文档/10、项目管理/(新建项目管理目录与截图) - 官网/ 全站 + 宝塔上线文档 - 五端上线验收 46 项(见 ac82726e) ## 刻意未上传 - node_modules/、.DS_Store、.smart-env/ - .开发文档_nested_git_backup/ - **/__pycache__/ ## 验收 - 提交页(含本说明): https://github.com/fnvtk/cunkebao_v3/commit/HEAD - 分支树: https://github.com/fnvtk/cunkebao_v3/tree/develop Co-authored-by: Cursor <cursoragent@cursor.com>
130 lines
4.1 KiB
PHP
130 lines
4.1 KiB
PHP
<?php
|
||
|
||
namespace app\superadmin\service;
|
||
|
||
use think\Db;
|
||
|
||
/**
|
||
* 私域银行全局提示词模板库(REQ-CKB-70 · PromptMergeService 第 7 层真源)
|
||
*
|
||
* 表 ck_ai_prompt_global_template(懒建):
|
||
* id, name, content, isDefault, status, createTime, updateTime, deleteTime
|
||
* 触客宝/官网通过 PromptMergeService::layerSuperAdminGlobal 只读取用。
|
||
*/
|
||
class PromptTemplateService
|
||
{
|
||
private static $ensured = false;
|
||
|
||
private static function ensureTable(): void
|
||
{
|
||
if (self::$ensured) {
|
||
return;
|
||
}
|
||
Db::execute("CREATE TABLE IF NOT EXISTS `ck_ai_prompt_global_template` (
|
||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||
`name` varchar(128) NOT NULL DEFAULT '',
|
||
`content` text NULL,
|
||
`isDefault` tinyint(1) NOT NULL DEFAULT 0,
|
||
`status` tinyint(1) NOT NULL DEFAULT 1,
|
||
`createTime` int(11) NOT NULL DEFAULT 0,
|
||
`updateTime` int(11) NOT NULL DEFAULT 0,
|
||
`deleteTime` int(11) NOT NULL DEFAULT 0,
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_default` (`isDefault`,`status`,`deleteTime`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
|
||
self::$ensured = true;
|
||
}
|
||
|
||
public function list(): array
|
||
{
|
||
self::ensureTable();
|
||
$rows = Db::name('ai_prompt_global_template')
|
||
->where('deleteTime', 0)
|
||
->order('isDefault DESC, id DESC')
|
||
->select();
|
||
return array_map(function ($r) {
|
||
$r['isDefault'] = (int)$r['isDefault'] === 1;
|
||
$r['status'] = (int)$r['status'] === 1;
|
||
return $r;
|
||
}, $rows ?: []);
|
||
}
|
||
|
||
public function save(array $data): array
|
||
{
|
||
self::ensureTable();
|
||
$id = (int)($data['id'] ?? 0);
|
||
$name = trim((string)($data['name'] ?? ''));
|
||
$content = (string)($data['content'] ?? '');
|
||
$status = (int)($data['status'] ?? 1) === 1 ? 1 : 0;
|
||
$isDefault = (int)($data['isDefault'] ?? 0) === 1 ? 1 : 0;
|
||
if ($name === '') {
|
||
throw new \Exception('模板名称不能为空', 400);
|
||
}
|
||
$now = time();
|
||
|
||
Db::startTrans();
|
||
try {
|
||
if ($isDefault === 1) {
|
||
// 同一时间仅一个默认
|
||
Db::name('ai_prompt_global_template')->where('deleteTime', 0)->update(['isDefault' => 0]);
|
||
}
|
||
if ($id > 0) {
|
||
Db::name('ai_prompt_global_template')->where('id', $id)->update([
|
||
'name' => $name,
|
||
'content' => $content,
|
||
'status' => $status,
|
||
'isDefault' => $isDefault,
|
||
'updateTime' => $now,
|
||
]);
|
||
} else {
|
||
$id = Db::name('ai_prompt_global_template')->insertGetId([
|
||
'name' => $name,
|
||
'content' => $content,
|
||
'status' => $status,
|
||
'isDefault' => $isDefault,
|
||
'createTime' => $now,
|
||
'updateTime' => $now,
|
||
'deleteTime' => 0,
|
||
]);
|
||
}
|
||
Db::commit();
|
||
} catch (\Throwable $e) {
|
||
Db::rollback();
|
||
throw $e;
|
||
}
|
||
return ['id' => $id];
|
||
}
|
||
|
||
public function delete(int $id): void
|
||
{
|
||
self::ensureTable();
|
||
if ($id <= 0) {
|
||
throw new \Exception('id 缺失', 400);
|
||
}
|
||
Db::name('ai_prompt_global_template')->where('id', $id)->update([
|
||
'deleteTime' => time(),
|
||
]);
|
||
}
|
||
|
||
public function setDefault(int $id): void
|
||
{
|
||
self::ensureTable();
|
||
if ($id <= 0) {
|
||
throw new \Exception('id 缺失', 400);
|
||
}
|
||
Db::startTrans();
|
||
try {
|
||
Db::name('ai_prompt_global_template')->where('deleteTime', 0)->update(['isDefault' => 0]);
|
||
Db::name('ai_prompt_global_template')->where('id', $id)->update([
|
||
'isDefault' => 1,
|
||
'status' => 1,
|
||
'updateTime' => time(),
|
||
]);
|
||
Db::commit();
|
||
} catch (\Throwable $e) {
|
||
Db::rollback();
|
||
throw $e;
|
||
}
|
||
}
|
||
}
|