chore: 重写初始提交(清空历史,整理后全量提交)

This commit is contained in:
ywxapp
2026-08-16 16:54:14 +08:00
commit 6c1a106bc1
1808 changed files with 238144 additions and 0 deletions
+227
View File
@@ -0,0 +1,227 @@
<?php
// +----------------------------------------------------------------------
// | YwxApp [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: ywxapp<admin@ywxapp.cn>
// +----------------------------------------------------------------------
declare (strict_types = 1);
namespace addon\docs\controller\backend;
use addon\docs\model\DocsDoc;
use addon\docs\model\DocsProject;
use addon\docs\model\DocsVersion;
use addon\docs\service\DocSearchService;
use addon\docs\service\DocTreeService;
use ywxapp\controller\BackendBase;
/**
* 文档项目管理
*
* @author ywxapp <admin@ywxapp.cn>
*/
class Project extends BackendBase
{
/**
* 项目列表
*/
public function index()
{
$keyword = trim((string) $this->request->get('keyword', ''));
$query = DocsProject::order('sort', 'asc')->order('id', 'asc');
if ($keyword !== '') {
$query->where(function ($q) use ($keyword) {
$q->whereLike('title', '%' . $keyword . '%')
->whereOr('name', 'like', '%' . $keyword . '%');
});
}
$list = $query->select()->toArray();
// 附加每个项目的版本数与文档数,便于列表直观查看
foreach ($list as &$item) {
$item['version_count'] = DocsVersion::where('project_id', $item['id'])->count();
$item['doc_count'] = DocsDoc::where('project_id', $item['id'])->count();
}
unset($item);
$this->assign('list', $list);
$this->assign('keyword', $keyword);
return $this->fetch('project/index');
}
/**
* 新增页面
*/
public function add()
{
$this->assign('addonList', $this->addonOptions());
return $this->fetch('project/add');
}
/**
* 保存新增
*/
public function save()
{
$data = $this->collect();
if (is_string($data)) {
return $this->result->error($data);
}
if (DocsProject::where('name', $data['name'])->find()) {
return $this->result->error('项目标识已存在,请更换');
}
$project = DocsProject::create($data);
// 新项目自动建默认版本,避免建完项目无法直接添加文档
DocsVersion::create([
'project_id' => $project->id,
'name' => 'v1',
'title' => '默认版本',
'is_default' => 1,
'sort' => 1,
'status' => 1,
]);
DocTreeService::clearCache();
return $this->result->success(null, '添加成功');
}
/**
* 编辑页面
*
* @param int $id 项目ID
*/
public function edit($id = null)
{
$project = DocsProject::find((int) $id);
if (!$project) {
return $this->result->error('项目不存在');
}
$this->assign('item', $project);
$this->assign('addonList', $this->addonOptions());
$this->assign('versionList', DocsVersion::where('project_id', $project->id)->order('sort', 'asc')->select());
return $this->fetch('project/edit');
}
/**
* 保存编辑
*
* @param int $id 项目ID
*/
public function update($id)
{
$project = DocsProject::find((int) $id);
if (!$project) {
return $this->result->error('项目不存在');
}
$data = $this->collect();
if (is_string($data)) {
return $this->result->error($data);
}
if (DocsProject::where('name', $data['name'])->where('id', '<>', $project->id)->find()) {
return $this->result->error('项目标识已存在,请更换');
}
$project->save($data);
DocTreeService::clearCache();
return $this->result->success(null, '保存成功');
}
/**
* 删除项目(连同版本与文档)
*
* @param int $id 项目ID
*/
public function delete($id)
{
$id = (int) $id;
$project = DocsProject::find($id);
if (!$project) {
return $this->result->error('项目不存在');
}
$docIds = DocsDoc::where('project_id', $id)->column('id');
foreach ($docIds as $docId) {
DocSearchService::remove((int) $docId);
}
DocsDoc::where('project_id', $id)->delete();
DocsVersion::where('project_id', $id)->delete();
$project->delete();
DocTreeService::clearCache();
return $this->result->success(null, '删除成功');
}
/**
* 收集并校验表单数据
*
* @return array|string 校验失败返回错误提示字符串
*/
protected function collect()
{
$name = trim((string) $this->request->post('name', ''));
$title = trim((string) $this->request->post('title', ''));
if ($name === '' || !preg_match('/^[a-z][a-z0-9_\-]{1,49}$/i', $name)) {
return '项目标识只能为字母开头的字母数字组合,长度 2-50';
}
if ($title === '') {
return '请填写项目名称';
}
return [
'name' => $name,
'title' => $title,
'intro' => trim((string) $this->request->post('intro', '')),
'logo' => trim((string) $this->request->post('logo', '')),
'addon' => trim((string) $this->request->post('addon', '')),
'default_version' => trim((string) $this->request->post('default_version', '')),
'sort' => (int) $this->request->post('sort', 0),
'status' => (int) $this->request->post('status', 1) === 1 ? 1 : 0,
];
}
/**
* 扫描已安装插件,供项目归属下拉使用
*
* @return array
*/
protected function addonOptions(): array
{
$dir = root_path() . 'addon';
$list = [];
if (!is_dir($dir)) {
return $list;
}
foreach ((array) scandir($dir) as $item) {
if ($item === '.' || $item === '..' || !is_dir($dir . DIRECTORY_SEPARATOR . $item)) {
continue;
}
$infoFile = $dir . DIRECTORY_SEPARATOR . $item . DIRECTORY_SEPARATOR . 'info.php';
if (!is_file($infoFile)) {
continue;
}
$info = @include $infoFile;
if (is_array($info) && !empty($info['name'])) {
$list[] = [
'name' => (string) $info['name'],
'title' => (string) ($info['title'] ?? $info['name']),
];
}
}
return $list;
}
}