feat: 添加附件(下载管理)分页/详情/新增/更新/设置排序值/删除接口

This commit is contained in:
2025-02-21 15:28:26 +08:00
parent 3b91869844
commit c4af51e57d
6 changed files with 409 additions and 1 deletions

View File

@@ -0,0 +1,189 @@
<?php
declare (strict_types = 1);
namespace app\admin\controller\v1;
use app\admin\model\v1\AttachmentModel;
use app\admin\validate\v1\AttachmentValidate;
/**
* 附件(下载管理)管理控制器
*/
class Attachment
{
/**
* 分页数据
*/
public function index()
{
$params = request()->param([
'name',
'category_id',
'created_at',
'page/d' => 1,
'size/d' => 10
]);
$attachments = AttachmentModel::field([
'id',
'image',
'name',
'category_id',
'sort',
'recommend',
'status',
'created_at'
])
->with(['category' => function ($query) {
$query->field(['id', 'name' => 'category_name']);
}])
->withSearch(['name', 'created_at'], [
'name' => $params['name']??null,
'created_at' => !empty($params['created_at']) ? explode(',', $params['created_at']) : null
])
->language(request()->lang_id)
->categoryId($params['category_id']??null)
->order(['sort' => 'asc', 'id' => 'desc'])
->paginate([
'list_rows' => $params['size'],
'page' => $params['page']
])
->bindAttr('category', ['category_name'])
->hidden(['category_id', 'category']);
return success('获取成功', $attachments);
}
/**
* 附件详情
*/
public function read()
{
$id = request()->param('id');
$attachment = AttachmentModel::withoutField([
'language_id',
'created_at',
'updated_at',
'deleted_at'
])
->bypk($id)
->find();
if (empty($attachment)) {
return error('附件不存在');
}
return success('获取成功', $attachment);
}
/**
* 附件添加
*/
public function save()
{
$post = request()->post([
'name',
'category_id',
'sort',
'recommend',
'image',
'aplicable_to',
'support_platform',
'attach',
'seo_title',
'seo_keywords',
'seo_desc'
]);
$data = array_merge($post, ['language_id' => request()->lang_id]);
$validate = new AttachmentValidate;
if (!$validate->scene('create')->check($data)) {
return error($validate->getError());
}
$attachment = AttachmentModel::create($data);
if ($attachment->isEmpty()) {
return error('操作失败');
}
return success('操作成功');
}
/**
* 附件更新
*/
public function update()
{
$id = request()->param('id');
$put = request()->put([
'name',
'category_id',
'sort',
'recommend',
'image',
'aplicable_to',
'support_platform',
'attach',
'seo_title',
'seo_keywords',
'seo_desc'
]);
$validate = new AttachmentValidate;
if (!$validate->scene('update')->check(array_merge($put, ['id' => $id]))) {
return error($validate->getError());
}
$attachment = AttachmentModel::bypk($id)->find();
if (empty($attachment)) {
return error('请确认操作对象是否存在');
}
if (!$attachment->save($put)) {
return error('操作失败');
}
return success('操作成功');
}
/**
* 设置排序值
*/
public function sort()
{
$id = request()->param('id');
$sort = request()->post('sort');
$validate = new AttachmentValidate;
if (!$validate->scene('sort')->check(['sort' => $sort])) {
return error($validate->getError());
}
$attachment = AttachmentModel::bypk($id)->find();
if (empty($attachment)) {
return error('请确认操作对象是否存在');
}
$attachment->sort = $sort;
if (!$attachment->save()) {
return error('操作失败');
}
return success('操作成功');
}
/**
* 附件删除
*/
public function delete()
{
$id = request()->param('id');
$attachment = AttachmentModel::bypk($id)->find();
if (empty($attachment)) {
return error('请确认操作对象是否存在');
}
if (!$attachment->delete()) {
return error('操作失败');
}
return success('操作成功');
}
}

View File

@@ -0,0 +1,71 @@
<?php
declare (strict_types = 1);
namespace app\admin\model\v1;
use app\common\model\AttachmentBaseModel;
use think\model\concern\SoftDelete;
/**
* 附件(下载管理)模型
* @mixin \think\Model
*/
class AttachmentModel extends AttachmentBaseModel
{
// 启用软删除
use SoftDelete;
// 软删除字段
protected $deleteTime = 'deleted_at';
// 自动写入时间格式
protected $autoWriteTimestamp = 'datetime';
// JSON字段
protected $json = ['attach'];
// 设置JSON数据返回数组
protected $jsonAssoc = true;
// JSON字段属性类型
protected $jsonType = [
'attach[*]->file_path' => 'string',
'attach[*]->file_ext' => 'string',
'attach[*]->btn_name' => 'string',
];
// 关联附件分类模型
public function category()
{
return $this->belongsTo(AttachmentCategoryModel::class, 'category_id', 'id');
}
// 名称搜索
public function searchNameAttr($query, $value)
{
if (empty($value)) return;
$query->where('name', 'like', '%' . $value . '%');
}
// 新增时间搜索
public function searchCreatedAtAttr($query, $value)
{
if (empty($value)) return;
if (is_array($value)) {
if (count($value) > 1) {
$query->whereBetweenTime('created_at', $value[0], $value[1]);
} else {
$query->whereTime('created_at', '>=', $value[0]);
}
}
}
// 语言查询
public function scopeLanguage($query, $value)
{
$query->where('language_id', '=', $value);
}
// 分类查询
public function scopeCategoryId($query, $value)
{
if (empty($value)) return;
$query->where('category_id', '=', $value);
}
}

View File

@@ -273,6 +273,27 @@ Route::group('v1', function () {
// 产品回收站删除 // 产品回收站删除
Route::delete('delete/:id', 'ProductTrash/delete'); Route::delete('delete/:id', 'ProductTrash/delete');
}); });
// 附件(下载管理)
Route::group('attachment', function () {
// 附件(下载管理)列表
Route::get('index', 'Attachment/index');
// 附件(下载管理)详情
Route::get('read/:id', 'Attachment/read');
// 附件(下载管理)新增
Route::post('save', 'Attachment/save');
// 附件(下载管理)更新
Route::put('update/:id', 'Attachment/update');
// 附件(下载管理)设置排序值
Route::get('sort/:id', 'Attachment/sort');
// 附件(下载管理)删除
Route::delete('delete/:id', 'Attachment/delete');
});
}); });
})->prefix('v1.'); })->prefix('v1.');

View File

@@ -0,0 +1,87 @@
<?php
declare (strict_types = 1);
namespace app\admin\validate\v1;
use think\Validate;
class AttachmentValidate extends Validate
{
/**
* 定义验证规则
* 格式:'字段名' => ['规则1','规则2'...]
*
* @var array
*/
protected $rule = [
'id' => 'require|integer',
'language_id' => 'require|integer',
'category_id' => 'require|integer',
'name' => 'require|max:64',
'desc' => 'max:255',
'image' => 'max:255',
'applicable_to' => 'max:255',
'support_platform' => 'max:255',
'attach.*.filepath' => 'string',
'attach.*.ext' => 'string',
'attach.*.btn_name' => 'string',
'sort' => 'integer',
'recommend' => 'in:0,1',
'seo_title' => 'max:255',
'seo_keywords' => 'max:255',
'seo_desc' => 'max:255',
];
/**
* 定义错误信息
* 格式:'字段名.规则名' => '错误信息'
*
* @var array
*/
protected $message = [
'id.require' => 'ID不能为空',
'id.integer' => 'ID必须是整数',
'language_id.require' => '语言ID不能为空',
'language_id.integer' => '语言ID必须是整数',
'category_id.require' => '分类ID不能为空',
'category_id.integer' => '分类ID必须是整数',
'name.require' => '名称不能为空',
'name.max' => '名称不能超过64个字符',
'desc.max' => '描述不能超过255个字符',
'image.max' => '图片不能超过255个字符',
'applicable_to.max' => '适用对象不能超过255个字符',
'support_platform.max' => '支持平台不能超过255个字符',
'attach.*.file_path.string' => '附件路径必须是字符串',
'attach.*.file_ext.string' => '附件扩展名必须是字符串',
'attach.*.btn_name.string' => '附件按钮名必须是字符串',
'sort.integer' => '排序必须是整数',
'recommend.in' => '推荐状态必须是0或1',
'seo_title.max' => 'SEO标题不能超过255个字符',
'seo_keywords.max' => 'SEO关键字不能超过255个字符',
'seo_desc.max' => 'SEO描述不能超过255个字符',
];
/**
* 新增场景
*/
public function sceneCreate()
{
return $this->remove('id', 'require|integer');
}
/**
* 更新场景
*/
public function sceneUpdate()
{
return $this->remove('language_id', 'require|integer');
}
/**
* 排序场景
*/
public function sceneSort()
{
return $this->only(['sort']);
}
}

View File

@@ -0,0 +1,40 @@
<?php
declare (strict_types = 1);
namespace app\common\model;
use think\Model;
/**
* 附件(下载管理)模型
* @mixin \think\Model
*/
class AttachmentBaseModel extends Model
{
// 表名
protected $name = 'attachment';
// 主键
protected $pk = 'id';
// 字段信息
protected $schema = [
'id' => 'int',
'language_id' => 'int',
'category_id' => 'int',
'name' => 'string',
'desc' => 'string',
'image' => 'string',
'applicable_to' => 'string',
'support_platform' => 'string',
'attach' => 'string',
'sort' => 'int',
'recommend' => 'int',
'seo_title' => 'string',
'seo_keywords' => 'string',
'seo_desc' => 'string',
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
];
}

View File

@@ -35,7 +35,7 @@ class CreateAttachment extends Migrator
->addColumn('image', 'string', ['limit' => 255, 'default' => null, 'comment' => '图片地址']) ->addColumn('image', 'string', ['limit' => 255, 'default' => null, 'comment' => '图片地址'])
->addColumn('applicable_to', 'string', ['limit' => 255, 'default' => null, 'comment' => '适用于(型号),多个以英文逗号分隔']) ->addColumn('applicable_to', 'string', ['limit' => 255, 'default' => null, 'comment' => '适用于(型号),多个以英文逗号分隔'])
->addColumn('support_platform', 'string', ['limit' => 255, 'default' => null, 'comment' => '支持平台,多个以英文逗号分隔']) ->addColumn('support_platform', 'string', ['limit' => 255, 'default' => null, 'comment' => '支持平台,多个以英文逗号分隔'])
->addColumn('attach', 'json', ['null' => false, 'comment' => '附件地址: $[*].url为附件地址, $[*].ext为文件格式, $[*].btn_name为下载按钮名称']) ->addColumn('attach', 'json', ['null' => false, 'comment' => '附件地址: $[*].file_path为附件地址, $[*].file_ext为文件格式, $[*].btn_name为下载按钮名称'])
->addColumn('sort', 'integer', ['null' => false, 'default' => 0, 'comment' => '排序']) ->addColumn('sort', 'integer', ['null' => false, 'default' => 0, 'comment' => '排序'])
->addColumn('recommend', 'boolean', ['null' => false, 'default' => 0, 'comment' => '是否推荐:1是,0否']) ->addColumn('recommend', 'boolean', ['null' => false, 'default' => 0, 'comment' => '是否推荐:1是,0否'])
->addColumn('seo_title', 'string', ['limit' => 255, 'default' => null, 'comment' => 'SEO标题']) ->addColumn('seo_title', 'string', ['limit' => 255, 'default' => null, 'comment' => 'SEO标题'])