Files
MrleeAdmin/.windsurf/skills/backend-gen-api-service/SKILL.md
T
2026-08-31 11:33:59 +08:00

385 lines
8.9 KiB
Markdown

---
name: backend-gen-api-service
description: Generate API service class for madong module前台API服务层. Supports both app (main project) and plugin targets. Creates service extending BaseService with DAO injection and standard CRUD operations for public/member access.
globs:
- "app/service/api/**/*.php"
- "plugin/**/app/service/api/**/*.php"
---
# Generate API Service (前台 API 服务层)
Create service class for module (前台 API 访问).
## File Location
**App (主项目):**
```
app/service/api/{module}/{Model}Service.php
```
**Plugin (插件):**
```
plugin/{plugin}/app/service/api/{module}/{Model}Service.php
```
## Target Variables
| 变量 | App | Plugin |
|------|-----|--------|
| `{prefix}` | `` (空) | `plugin\{Plugin}` |
| `{ns}` | `app` | `plugin\{Plugin}\app` |
| `{dao_ns}` | `app\dao` | `plugin\{Plugin}\app\dao` |
| `{model_ns}` | `app\model` | `plugin\{Plugin}\app\model` |
## API Service Features
- **继承 BaseService**: 继承 `core\base\BaseService`
- **轻量级操作**: 不触发事件,适合公开访问
- **雪花ID**: 支持雪花ID作为主键
- **会员关联**: 支持与会员关联的数据操作
## API Service Template
```php
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
*/
namespace {ns}\service\api\{module};
use {dao_ns}\{module}\{Model}Dao;
use {model_ns}\{module}\{Model};
use core\base\BaseService;
/**
* {Model}前台API服务类
*
* Class {Model}Service
*/
class {Model}Service extends BaseService
{
/**
* 注入{Model}Dao
*
* @param {Model}Dao $dao
*/
public function __construct({Model}Dao $dao)
{
$this->dao = $dao;
}
/**
* 获取{Model}Dao
*
* @return {Model}Dao
*/
public function getDao(): {Model}Dao
{
return $this->dao;
}
/**
* 获取列表
*
* @param array $where 查询条件
* @param string $field 查询字段
* @param int $page 页码
* @param int $limit 每页数量
* @param string $order 排序
* @return array
*/
public function selectList(array $where = [], string $field = '*', int $page = 1, int $limit = 20, string $order = 'id desc'): array
{
$list = $this->dao->selectList($where, $field, $page, $limit, $order);
return {Model}::formatList($list);
}
/**
* 获取总数
*
* @param array $where 查询条件
* @return int
*/
public function count(array $where = []): int
{
return $this->dao->count($where);
}
/**
* 获取详情
*
* @param int $id
* @param array $field
* @return array
*/
public function get(int $id, array $field = ['*']): array
{
$data = $this->dao->findOrFail($id, $field);
return {Model}::formatDetail($data);
}
/**
* 创建
*
* @param array $data
* @return {Model}
*/
public function save(array $data): {Model}
{
// 如果需要关联会员,自动设置会员ID
if ($this->hasMemberField() && isset($this->memberId)) {
$memberField = $this->getMemberField();
if ($memberField && !isset($data[$memberField])) {
$data[$memberField] = $this->memberId;
}
}
return $this->dao->create($data);
}
/**
* 更新
*
* @param int $id
* @param array $data
* @return bool
*/
public function update(int $id, array $data): bool
{
// 检查是否为会员自己的数据
if ($this->hasMemberField()) {
$memberField = $this->getMemberField();
$record = $this->dao->findWhere([$memberField => $this->memberId, 'id' => $id]);
if (!$record) {
throw new \Exception('无权修改此数据');
}
}
return $this->dao->update($id, $data);
}
/**
* 删除
*
* @param int $id
* @return bool
*/
public function delete(int $id): bool
{
// 检查是否为会员自己的数据
if ($this->hasMemberField()) {
$memberField = $this->getMemberField();
$record = $this->dao->findWhere([$memberField => $this->memberId, 'id' => $id]);
if (!$record) {
throw new \Exception('无权删除此数据');
}
}
return $this->dao->delete($id);
}
/**
* 获取会员ID
*
* @return int|null
*/
protected function getMemberId(): ?int
{
try {
$currentMember = \app\api\CurrentMember::create();
return $currentMember->id();
} catch (\Exception $e) {
return null;
}
}
/**
* 检查是否有会员关联字段
*
* @return bool
*/
protected function hasMemberField(): bool
{
return in_array('member_id', (new {Model}())->getFillable());
}
/**
* 获取会员关联字段名
*
* @return string|null
*/
protected function getMemberField(): ?string
{
return $this->hasMemberField() ? 'member_id' : null;
}
}
```
## Complete Example (App)
```php
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
*/
namespace app\service\api\question;
use app\dao\question\QuestionDao;
use app\model\question\Question;
use core\base\BaseService;
/**
* 问题前台API服务类
*
* Class QuestionService
*/
class QuestionService extends BaseService
{
public function __construct(QuestionDao $dao)
{
$this->dao = $dao;
}
public function selectList(array $where = [], string $field = '*', int $page = 1, int $limit = 20, string $order = 'id desc'): array
{
$list = $this->dao->selectList($where, $field, $page, $limit, $order);
return Question::formatList($list);
}
public function count(array $where = []): int
{
return $this->dao->count($where);
}
public function get(int $id, array $field = ['*']): array
{
$data = $this->dao->findOrFail($id, $field);
return Question::formatDetail($data);
}
public function save(array $data): Question
{
if (isset($this->memberId)) {
$data['member_id'] = $this->memberId;
}
return $this->dao->create($data);
}
public function update(int $id, array $data): bool
{
$record = $this->dao->findWhere(['member_id' => $this->memberId, 'id' => $id]);
if (!$record) {
throw new \Exception('无权修改此问题');
}
return $this->dao->update($id, $data);
}
public function delete(int $id): bool
{
$record = $this->dao->findWhere(['member_id' => $this->memberId, 'id' => $id]);
if (!$record) {
throw new \Exception('无权删除此问题');
}
return $this->dao->delete($id);
}
protected function getMemberId(): ?int
{
try {
return \app\api\CurrentMember::create()->id();
} catch (\Exception $e) {
return null;
}
}
}
```
## Complete Example (Plugin)
```php
<?php
declare(strict_types=1);
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
*/
namespace plugin\official\app\service\api\question;
use plugin\official\app\dao\question\QuestionDao;
use plugin\official\app\model\question\Question;
use core\base\BaseService;
/**
* 问题前台API服务类
*
* Class QuestionService
*/
class QuestionService extends BaseService
{
public function __construct(QuestionDao $dao)
{
$this->dao = $dao;
}
// ... 方法同上
}
```
## Service Methods
### CRUD Operations
| Method | Description |
|--------|-------------|
| `selectList()` | Get paginated list |
| `count()` | Get total count |
| `get()` | Get single record |
| `save()` | Create new record (with member_id if applicable) |
| `update()` | Update existing record (with ownership check) |
| `delete()` | Delete record (with ownership check) |
### Member Support Methods
| Method | Description |
|--------|-------------|
| `getMemberId()` | Get current member ID |
| `hasMemberField()` | Check if model has member_id field |
| `getMemberField()` | Get member field name |
## Auto-generation Checklist
When generating API service:
- [ ] Set correct namespace based on target
- [ ] Import BaseService
- [ ] Import DAO
- [ ] Import Model class
- [ ] Inject DAO in constructor
- [ ] Implement standard CRUD methods
- [ ] Add member ownership check for update/delete
- [ ] Add getMemberId() helper method