|
|
@@ -4320,41 +4320,86 @@ class AnimeService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取角色库列表(支持文件夹)
|
|
|
- * @param array $data 包含 parent_id(父文件夹ID,默认0)、role(搜索关键词)
|
|
|
- * @return array 返回文件夹和角色列表
|
|
|
+ * 获取角色库列表(支持文件夹递归查询)
|
|
|
+ * @param array $data 包含 parent_id(父文件夹ID,默认0表示最外层)、role(搜索关键词)
|
|
|
+ * @return array 返回当前目录下的所有子目录和角色列表(递归)
|
|
|
*/
|
|
|
public function globalRoles($data) {
|
|
|
$cpid = Site::getCpid();
|
|
|
$parent_id = getProp($data, 'parent_id', 0);
|
|
|
$role = getProp($data, 'role');
|
|
|
|
|
|
- // 构建查询
|
|
|
- $query = DB::table('mp_roles')
|
|
|
+ // 如果有搜索关键词,只搜索角色图片
|
|
|
+ if ($role) {
|
|
|
+ $result = DB::table('mp_roles')
|
|
|
+ ->where('cpid', $cpid)
|
|
|
+ ->where('is_deleted', 0)
|
|
|
+ ->where('type', 1)
|
|
|
+ ->where('role', 'like', "%{$role}%")
|
|
|
+ ->select('id', 'type', 'parent_id', 'level', 'role', 'url', 'pic_prompt', 'three_view_image_url', 'versions', 'created_at')
|
|
|
+ ->orderByRaw('sort_order DESC, created_at DESC')
|
|
|
+ ->get()
|
|
|
+ ->map(function($value) {
|
|
|
+ $value = (array)$value;
|
|
|
+ $value['created_at'] = transDate($value['created_at'], 'Y-m-d');
|
|
|
+ $value['type'] = (int)$value['type'];
|
|
|
+ $value['parent_id'] = (int)$value['parent_id'];
|
|
|
+ $value['level'] = (int)$value['level'];
|
|
|
+ $value['versions'] = json_decode($value['versions'], true) ?: [];
|
|
|
+ return $value;
|
|
|
+ })
|
|
|
+ ->toArray();
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 递归获取所有子目录和角色
|
|
|
+ return $this->getChildrenRecursive($cpid, $parent_id);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 递归获取指定目录下的所有子目录和角色
|
|
|
+ * @param int $cpid 公司ID
|
|
|
+ * @param int $parent_id 父目录ID
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function getChildrenRecursive($cpid, $parent_id) {
|
|
|
+ // 查询当前层级的所有项(文件夹和角色)
|
|
|
+ $items = DB::table('mp_roles')
|
|
|
->where('cpid', $cpid)
|
|
|
->where('is_deleted', 0)
|
|
|
->where('parent_id', $parent_id)
|
|
|
- ->select('id', 'type', 'parent_id', 'level', 'role', 'url', 'pic_prompt', 'three_view_image_url', 'sort_order', 'created_at');
|
|
|
+ ->select('id', 'type', 'parent_id', 'level', 'role', 'url', 'pic_prompt', 'three_view_image_url', 'versions', 'created_at')
|
|
|
+ ->orderByRaw('type DESC, sort_order DESC, created_at DESC')
|
|
|
+ ->get();
|
|
|
|
|
|
- // 如果有搜索关键词,只搜索角色图片(type=1)
|
|
|
- if ($role) {
|
|
|
- $query->where('type', 1)->where('role', 'like', "%{$role}%");
|
|
|
+ $result = [];
|
|
|
+
|
|
|
+ foreach ($items as $item) {
|
|
|
+ $itemArray = [
|
|
|
+ 'id' => $item->id,
|
|
|
+ 'type' => (int)$item->type,
|
|
|
+ 'parent_id' => (int)$item->parent_id,
|
|
|
+ 'level' => (int)$item->level,
|
|
|
+ 'role' => $item->role,
|
|
|
+ 'url' => $item->url,
|
|
|
+ 'pic_prompt' => $item->pic_prompt,
|
|
|
+ 'three_view_image_url' => $item->three_view_image_url,
|
|
|
+ 'created_at' => transDate($item->created_at, 'Y-m-d')
|
|
|
+ ];
|
|
|
+ $itemArray['versions'] = json_decode($item->versions, true) ?: [];
|
|
|
+
|
|
|
+ // 如果是文件夹,递归获取其子项
|
|
|
+ if ($item->type == 2) {
|
|
|
+ $children = $this->getChildrenRecursive($cpid, $item->id);
|
|
|
+ if (!empty($children)) {
|
|
|
+ $itemArray['children'] = $children;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $result[] = $itemArray;
|
|
|
}
|
|
|
|
|
|
- // 排序:文件夹优先,然后按 sort_order 降序,最后按创建时间降序
|
|
|
- $result = $query->orderByRaw('type DESC, sort_order DESC, created_at DESC')
|
|
|
- ->get()
|
|
|
- ->map(function($value) {
|
|
|
- $value = (array)$value;
|
|
|
- $value['created_at'] = transDate($value['created_at'], 'Y-m-d');
|
|
|
- $value['type'] = (int)$value['type'];
|
|
|
- $value['parent_id'] = (int)$value['parent_id'];
|
|
|
- $value['level'] = (int)$value['level'];
|
|
|
- $value['sort_order'] = (int)$value['sort_order'];
|
|
|
- return $value;
|
|
|
- })
|
|
|
- ->toArray();
|
|
|
-
|
|
|
return $result;
|
|
|
}
|
|
|
|
|
|
@@ -4733,6 +4778,7 @@ class AnimeService
|
|
|
if (!$role) Utils::throwError('20003:角色不存在');
|
|
|
|
|
|
$updateData = [];
|
|
|
+ $needVersionRecord = false; // 是否需要记录版本
|
|
|
|
|
|
// 角色名
|
|
|
$roleName = trim(getProp($data, 'role'));
|
|
|
@@ -4751,12 +4797,23 @@ class AnimeService
|
|
|
if (!in_array($extension, $allowedExtensions)) {
|
|
|
Utils::throwError('20003:图片格式不正确,仅支持 jpg、jpeg、png、gif、webp、bmp 格式');
|
|
|
}
|
|
|
+
|
|
|
+ // 如果 url 有变更,记录版本
|
|
|
+ if ($url !== $role->url) {
|
|
|
+ $needVersionRecord = true;
|
|
|
+ }
|
|
|
+
|
|
|
$updateData['url'] = $url;
|
|
|
}
|
|
|
|
|
|
// 角色提示词
|
|
|
$pic_prompt = trim(getProp($data, 'pic_prompt'));
|
|
|
if ($pic_prompt) {
|
|
|
+ // 如果 pic_prompt 有变更,记录版本
|
|
|
+ if ($pic_prompt !== $role->pic_prompt) {
|
|
|
+ $needVersionRecord = true;
|
|
|
+ }
|
|
|
+
|
|
|
$updateData['pic_prompt'] = $pic_prompt;
|
|
|
}
|
|
|
|
|
|
@@ -4764,12 +4821,158 @@ class AnimeService
|
|
|
Utils::throwError('20003:没有需要更新的数据');
|
|
|
}
|
|
|
|
|
|
+ // 如果需要记录版本,将数据添加到 versions 数组
|
|
|
+ if ($needVersionRecord) {
|
|
|
+ // 获取现有的 versions 数据
|
|
|
+ $versions = json_decode($role->versions, true) ?: [];
|
|
|
+ $isFirstVersion = empty($versions); // 判断是否是第一次记录版本
|
|
|
+
|
|
|
+ // 如果是第一次记录版本,先添加旧版本(变更前)
|
|
|
+ if ($isFirstVersion) {
|
|
|
+ $oldVersion = [
|
|
|
+ 'url' => $role->url,
|
|
|
+ 'description' => $role->pic_prompt,
|
|
|
+ ];
|
|
|
+ // 旧版本添加到数组末尾
|
|
|
+ $versions[] = $oldVersion;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建新版本(变更后)
|
|
|
+ $newVersion = [
|
|
|
+ 'url' => isset($updateData['url']) ? $updateData['url'] : $role->url,
|
|
|
+ 'description' => isset($updateData['pic_prompt']) ? $updateData['pic_prompt'] : $role->pic_prompt,
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 检查新版本是否已存在于历史版本中
|
|
|
+ $existingIndex = -1;
|
|
|
+ foreach ($versions as $index => $version) {
|
|
|
+ if ($version['url'] === $newVersion['url'] && $version['description'] === $newVersion['description']) {
|
|
|
+ $existingIndex = $index;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($existingIndex !== -1) {
|
|
|
+ // 如果已存在,移除旧的位置
|
|
|
+ array_splice($versions, $existingIndex, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 新版本添加到数组开头(最新的在前)
|
|
|
+ array_unshift($versions, $newVersion);
|
|
|
+
|
|
|
+ // // 限制版本数量(可选,例如只保留最近10个版本)
|
|
|
+ // if (count($versions) > 10) {
|
|
|
+ // $versions = array_slice($versions, 0, 10);
|
|
|
+ // }
|
|
|
+
|
|
|
+ $updateData['versions'] = json_encode($versions, 256);
|
|
|
+ }
|
|
|
+
|
|
|
$updateData['updated_at'] = date('Y-m-d H:i:s');
|
|
|
|
|
|
return DB::table('mp_roles')
|
|
|
->where('cpid', $cpid)
|
|
|
->where('id', $id)->update($updateData);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取角色版本历史
|
|
|
+ * @param array $data 包含 id(角色ID)
|
|
|
+ * @return array 返回版本历史列表
|
|
|
+ */
|
|
|
+ public function getRoleVersions($data) {
|
|
|
+ $cpid = Site::getCpid();
|
|
|
+ $id = getProp($data, 'id');
|
|
|
+ if (!$id) Utils::throwError('20003:角色ID不能为空');
|
|
|
+
|
|
|
+ $role = DB::table('mp_roles')
|
|
|
+ ->where('id', $id)
|
|
|
+ ->where('cpid', $cpid)
|
|
|
+ ->where('type', 1)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$role) Utils::throwError('20003:角色不存在');
|
|
|
+
|
|
|
+ // 获取版本历史
|
|
|
+ $versions = json_decode($role->versions, true) ?: [];
|
|
|
+
|
|
|
+ // 添加当前版本作为最新版本
|
|
|
+ $currentVersion = [
|
|
|
+ 'version' => 0, // 0 表示当前版本
|
|
|
+ 'url' => $role->url,
|
|
|
+ 'pic_prompt' => $role->pic_prompt,
|
|
|
+ 'updated_at' => $role->updated_at,
|
|
|
+ 'is_current' => true
|
|
|
+ ];
|
|
|
+
|
|
|
+ array_unshift($versions, $currentVersion);
|
|
|
+
|
|
|
+ return $versions;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 恢复到指定版本
|
|
|
+ * @param array $data 包含 id(角色ID)、version(版本号)
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public function restoreRoleVersion($data) {
|
|
|
+ $uid = Site::getUid();
|
|
|
+ $cpid = Site::getCpid();
|
|
|
+ $id = getProp($data, 'id');
|
|
|
+ $version = getProp($data, 'version');
|
|
|
+
|
|
|
+ if (!$id) Utils::throwError('20003:角色ID不能为空');
|
|
|
+ if (!$version) Utils::throwError('20003:版本号不能为空');
|
|
|
+
|
|
|
+ $role = DB::table('mp_roles')
|
|
|
+ ->where('id', $id)
|
|
|
+ ->where('cpid', $cpid)
|
|
|
+ ->where('type', 1)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$role) Utils::throwError('20003:角色不存在');
|
|
|
+
|
|
|
+ // 获取版本历史
|
|
|
+ $versions = json_decode($role->versions, true) ?: [];
|
|
|
+
|
|
|
+ // 查找指定版本
|
|
|
+ $targetVersion = null;
|
|
|
+ foreach ($versions as $v) {
|
|
|
+ if ($v['version'] == $version) {
|
|
|
+ $targetVersion = $v;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$targetVersion) Utils::throwError('20003:版本不存在');
|
|
|
+
|
|
|
+ // 先将当前版本保存到历史
|
|
|
+ $newVersion = [
|
|
|
+ 'version' => count($versions) + 1,
|
|
|
+ 'url' => $role->url,
|
|
|
+ 'pic_prompt' => $role->pic_prompt,
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s'),
|
|
|
+ 'updated_by' => $uid
|
|
|
+ ];
|
|
|
+
|
|
|
+ array_unshift($versions, $newVersion);
|
|
|
+
|
|
|
+ // 限制版本数量
|
|
|
+ if (count($versions) > 10) {
|
|
|
+ $versions = array_slice($versions, 0, 10);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 恢复到指定版本
|
|
|
+ return DB::table('mp_roles')
|
|
|
+ ->where('id', $id)
|
|
|
+ ->where('cpid', $cpid)
|
|
|
+ ->update([
|
|
|
+ 'url' => $targetVersion['url'],
|
|
|
+ 'pic_prompt' => $targetVersion['pic_prompt'],
|
|
|
+ 'versions' => json_encode($versions, JSON_UNESCAPED_UNICODE),
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s')
|
|
|
+ ]);
|
|
|
+ }
|
|
|
|
|
|
public function deleteRole($data) {
|
|
|
$uid = Site::getUid();
|