Compare commits
10 Commits
de417929cb
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 93c65b56f6 | |||
| 9eed7c87f6 | |||
| 94dc78cd9c | |||
| a5eb91fadd | |||
| f63a7db58f | |||
| 845bea4b81 | |||
| 8d52e863b9 | |||
| 254823e308 | |||
| 86be1c230e | |||
| a1c6ecf2b9 |
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"mcp__laravel-boost__database-schema",
|
||||
"Bash(php artisan *)"
|
||||
]
|
||||
},
|
||||
"enableAllProjectMcpServers": true,
|
||||
"enabledMcpjsonServers": [
|
||||
"laravel-boost"
|
||||
],
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"mcp__laravel-boost__database-schema"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -38,6 +38,12 @@ QUEUE_CONNECTION=database
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
# 微信小程序配置
|
||||
WECHAT_MINI_PROGRAM_APP_ID=
|
||||
WECHAT_MINI_PROGRAM_SECRET=
|
||||
WECHAT_MINI_PROGRAM_TOKEN=
|
||||
WECHAT_MINI_PROGRAM_AES_KEY=
|
||||
|
||||
# 系统设置
|
||||
SETTING_CACHE_KEY=settings
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\UserRegisterRequest;
|
||||
use App\Models\UserModel;
|
||||
use App\Services\Wechat\MiniProgramService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
@@ -16,11 +17,9 @@ use Modules\Common\Trait\RequestJson;
|
||||
class IndexController
|
||||
{
|
||||
use RequestJson;
|
||||
// 权限验证白名单
|
||||
protected array $noPermission = ['index', 'login', 'register', 'mail'];
|
||||
|
||||
/** 获取首页信息 */
|
||||
#[GetRoute('/index')]
|
||||
#[GetRoute('/index', false)]
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
$web_setting = site_config('web');
|
||||
@@ -29,7 +28,7 @@ class IndexController
|
||||
}
|
||||
|
||||
/** 用户登录 */
|
||||
#[PostRoute('/login')]
|
||||
#[PostRoute('/login', false)]
|
||||
public function login(Request $request): JsonResponse
|
||||
{
|
||||
$credentials = $request->validate([
|
||||
@@ -46,7 +45,7 @@ class IndexController
|
||||
}
|
||||
|
||||
/** 用户注册 */
|
||||
#[PostRoute('/register')]
|
||||
#[PostRoute('/register', false)]
|
||||
public function register(UserRegisterRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
@@ -60,4 +59,69 @@ class IndexController
|
||||
|
||||
return $this->error('创建用户失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序登录
|
||||
*
|
||||
* 仅需 code 完成 openid 换取,首次登录使用默认昵称和头像,
|
||||
* 用户信息后续通过编辑接口完善。
|
||||
*/
|
||||
#[PostRoute('/wx/login', false)]
|
||||
public function loginMiniProgram(Request $request, MiniProgramService $miniProgram): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'code' => 'required|string',
|
||||
'phoneCode' => 'nullable|string',
|
||||
]);
|
||||
|
||||
// 1. 通过 code 换取 openid、session_key、unionid
|
||||
$session = $miniProgram->codeToSession($validated['code']);
|
||||
|
||||
// 2. 构建用户数据,昵称/头像/性别使用默认值
|
||||
$userData = [
|
||||
'openid' => $session['openid'],
|
||||
'unionid' => $session['unionid'] ?? '',
|
||||
'username' => 'wx_'.uniqid(),
|
||||
'nickname' => '微信用户',
|
||||
'avatar' => '',
|
||||
'gender' => 0,
|
||||
'password' => '',
|
||||
];
|
||||
|
||||
// 3. 解密手机号
|
||||
if (! empty($validated['phoneCode'])) {
|
||||
try {
|
||||
$phoneInfo = $miniProgram->getPhoneNumber($validated['phoneCode']);
|
||||
$userData['mobile'] = $phoneInfo['phone_info']['purePhoneNumber'] ?? '';
|
||||
} catch (\Throwable) {
|
||||
// 手机号解密失败不阻塞登录
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 查找或创建用户
|
||||
$user = UserModel::firstOrCreate(
|
||||
['openid' => $userData['openid']],
|
||||
$userData
|
||||
);
|
||||
|
||||
// 5. 更新已有用户缺失的手机号和 unionid
|
||||
$needUpdate = false;
|
||||
foreach (['mobile', 'unionid'] as $field) {
|
||||
if (! empty($userData[$field]) && empty($user->$field)) {
|
||||
$user->$field = $userData[$field];
|
||||
$needUpdate = true;
|
||||
}
|
||||
}
|
||||
if ($needUpdate) {
|
||||
$user->save();
|
||||
}
|
||||
|
||||
// 6. 创建 Sanctum token
|
||||
$token = $user->createToken($user->username)->toArray();
|
||||
|
||||
return $this->success([
|
||||
'token' => $token['plainTextToken'],
|
||||
'user' => $user->toArray(),
|
||||
], __('user.login_success'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\PaymentTransactionModel;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
|
||||
#[RequestAttribute('/finance/payment-transaction', 'finance.transaction')]
|
||||
class PaymentTransactionController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'pay_type' => '=',
|
||||
'business_type' => '=',
|
||||
'user_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['transaction_no', 'out_trade_no'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = PaymentTransactionModel::query();
|
||||
$data = $this->buildSearch($params, $query)->paginate($pageSize)->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = PaymentTransactionModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -21,48 +21,43 @@ class UserController
|
||||
#[GetRoute]
|
||||
public function getUserInfo(): JsonResponse
|
||||
{
|
||||
$info = auth()->user();
|
||||
return $this->success(compact('info'));
|
||||
}
|
||||
$user = UserModel::query()->find(auth()->id());
|
||||
|
||||
#[PostRoute('/logout')]
|
||||
public function logout(): JsonResponse
|
||||
{
|
||||
$user_id = auth('users')->id();
|
||||
$model = new UserModel;
|
||||
if ($model->logout($user_id)) {
|
||||
return $this->success('退出登录成功');
|
||||
} else {
|
||||
return $this->error($model->getErrorMsg());
|
||||
if (! $user) {
|
||||
return $this->error('用户不存在');
|
||||
}
|
||||
|
||||
$data = $user->toArray();
|
||||
|
||||
// 手机号脱敏:13812345678 → 138****5678
|
||||
if (! empty($data['mobile'])) {
|
||||
$data['mobile'] = substr_replace($data['mobile'], '****', 3, 4);
|
||||
}
|
||||
|
||||
// 邮箱脱敏:test@example.com → t***@example.com
|
||||
if (! empty($data['email'])) {
|
||||
$parts = explode('@', $data['email']);
|
||||
$parts[0] = substr($parts[0], 0, 1).'***';
|
||||
$data['email'] = implode('@', $parts);
|
||||
}
|
||||
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PutRoute]
|
||||
public function setUserInfo(UserUpdateInfoRequest $request): JsonResponse
|
||||
{
|
||||
UserModel::where('user_id', auth('user')->id())->update($request->validated());
|
||||
|
||||
return $this->error('更新成功');
|
||||
}
|
||||
|
||||
#[PostRoute('/setPwd')]
|
||||
public function setPassword(Request $request): JsonResponse
|
||||
/** 编辑用户信息(头像、昵称、性别) */
|
||||
#[PutRoute('/profile')]
|
||||
public function updateProfile(Request $request): JsonResponse
|
||||
{
|
||||
$data = $request->validate([
|
||||
'oldPassword' => 'required|string|max:20',
|
||||
'newPassword' => 'required|string|min:6|max:20',
|
||||
'rePassword' => 'required|same:newPassword',
|
||||
'avatar' => 'required|string|max:500',
|
||||
'nickname' => 'required|string|max:32',
|
||||
'gender' => 'required|integer|in:0,1,2',
|
||||
]);
|
||||
$user_id = auth('user')->id();
|
||||
$user = UserModel::query()->find($user_id);
|
||||
if (! password_verify($data['oldPassword'], $user['password'])) {
|
||||
return $this->error('旧密码不正确!');
|
||||
}
|
||||
$user->password = password_hash($data['newPassword'], PASSWORD_DEFAULT);
|
||||
if ($user->save()) {
|
||||
return $this->success('更新成功');
|
||||
}
|
||||
|
||||
return $this->error('更新失败');
|
||||
$user = UserModel::query()->find(auth()->id());
|
||||
|
||||
$user->update($data);
|
||||
|
||||
return $this->success($user->toArray(), '更新成功');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* 统一三方支付流水模型
|
||||
*/
|
||||
class PaymentTransactionModel extends Model
|
||||
{
|
||||
protected $table = 'payment_transactions';
|
||||
|
||||
protected $fillable = [
|
||||
'transaction_no',
|
||||
'out_trade_no',
|
||||
'pay_type',
|
||||
'amount',
|
||||
'status',
|
||||
'business_type',
|
||||
'business_id',
|
||||
'user_id',
|
||||
'openid',
|
||||
'raw_data',
|
||||
'paid_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'amount' => 'decimal:2',
|
||||
'status' => 'integer',
|
||||
'business_id' => 'integer',
|
||||
'user_id' => 'integer',
|
||||
'raw_data' => 'array',
|
||||
'paid_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
@@ -28,5 +28,9 @@ class UserModel extends Authenticatable
|
||||
'email',
|
||||
'password',
|
||||
'nickname',
|
||||
'openid',
|
||||
'unionid',
|
||||
'avatar',
|
||||
'gender'
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Wechat;
|
||||
|
||||
use EasyWeChat\Kernel\Exceptions\HttpException;
|
||||
use EasyWeChat\MiniApp\Application;
|
||||
use EasyWeChat\MiniApp\Utils;
|
||||
|
||||
/**
|
||||
* 微信小程序服务基类
|
||||
*
|
||||
* 封装 EasyWeChat MiniApp Application,提供单例访问和小程序常用方法。
|
||||
* 业务模块可继承此类或通过依赖注入使用。
|
||||
*/
|
||||
class MiniProgramService
|
||||
{
|
||||
protected ?Application $app = null;
|
||||
|
||||
/**
|
||||
* 获取 EasyWeChat MiniApp Application 实例
|
||||
*/
|
||||
public function app(): Application
|
||||
{
|
||||
if (! $this->app) {
|
||||
$this->app = new Application(config('wechat.mini_program'));
|
||||
}
|
||||
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Utils 实例(code2Session、解密等)
|
||||
*/
|
||||
public function utils(): Utils
|
||||
{
|
||||
return $this->app()->getUtils();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 code 换取 session
|
||||
*
|
||||
* @return array{openid: string, session_key: string, unionid?: string}
|
||||
*
|
||||
* @throws HttpException
|
||||
*/
|
||||
public function codeToSession(string $code): array
|
||||
{
|
||||
return $this->utils()->codeToSession($code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密加密数据(如用户信息、手机号)
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function decryptData(string $sessionKey, string $iv, string $ciphertext): array
|
||||
{
|
||||
return $this->utils()->decryptSession($sessionKey, $iv, $ciphertext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户手机号
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*
|
||||
* @throws HttpException
|
||||
*/
|
||||
public function getPhoneNumber(string $code): array
|
||||
{
|
||||
return $this->utils()->getPhoneNumber($code);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,11 @@ use Modules\Common\Providers\PaginationProvider;
|
||||
use Modules\SystemAgent\Providers\SystemAgentServiceProvider;
|
||||
use Modules\SystemTool\Providers\SystemToolServiceProvider;
|
||||
use Modules\SystemUser\Providers\SystemUserServiceProvider;
|
||||
use Modules\Member\Providers\MemberServiceProvider;
|
||||
use Modules\Forum\Providers\ForumServiceProvider;
|
||||
use Modules\Merchant\Providers\MerchantServiceProvider;
|
||||
use Modules\Runner\Providers\RunnerServiceProvider;
|
||||
use Modules\Task\Providers\TaskServiceProvider;
|
||||
|
||||
return [
|
||||
AppServiceProvider::class,
|
||||
@@ -14,4 +19,9 @@ return [
|
||||
SystemAgentServiceProvider::class,
|
||||
SystemUserServiceProvider::class,
|
||||
SystemToolServiceProvider::class,
|
||||
MemberServiceProvider::class,
|
||||
ForumServiceProvider::class,
|
||||
MerchantServiceProvider::class,
|
||||
TaskServiceProvider::class,
|
||||
RunnerServiceProvider::class,
|
||||
];
|
||||
|
||||
+2
-1
@@ -14,7 +14,8 @@
|
||||
"laravel/framework": "^13.0",
|
||||
"laravel/sanctum": "^4.0",
|
||||
"laravel/tinker": "^3.0",
|
||||
"predis/predis": "2.0"
|
||||
"predis/predis": "2.0",
|
||||
"w7corp/easywechat": "^6.19"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/boost": "^2.0",
|
||||
|
||||
Generated
+1017
-4
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| 微信小程序配置
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
'mini_program' => [
|
||||
'app_id' => env('WECHAT_MINI_PROGRAM_APP_ID', ''),
|
||||
'secret' => env('WECHAT_MINI_PROGRAM_SECRET', ''),
|
||||
'token' => env('WECHAT_MINI_PROGRAM_TOKEN', ''),
|
||||
'aes_key' => env('WECHAT_MINI_PROGRAM_AES_KEY', ''),
|
||||
|
||||
/**
|
||||
* HTTP 客户端配置
|
||||
* 参考:https://symfony.com/doc/current/http_client.html
|
||||
*/
|
||||
'http' => [
|
||||
'throw' => false, // 是否直接抛出异常
|
||||
'timeout' => 10.0,
|
||||
'retry' => true, // 失败重试
|
||||
'max_retries' => 2,
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -23,7 +23,7 @@ return new class extends Migration
|
||||
$table->integer('sex')->default(0)->comment('性别(男、女)');
|
||||
$table->string('bio', 255)->default('')->nullable()->comment('个人简介');
|
||||
$table->string('mobile', 20)->default('')->comment('手机号');
|
||||
$table->string('email', 50)->unique()->comment('邮箱');
|
||||
$table->string('email', 50)->default('')->comment('邮箱');
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->integer('dept_id')->default(0)->comment('部门ID');
|
||||
$table->string('login_ip', 60)->default('')->comment('最后登录IP');
|
||||
|
||||
@@ -8,20 +8,19 @@ return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// 话题分类
|
||||
// 论坛板块
|
||||
if (! Schema::hasTable('forum_categories')) {
|
||||
Schema::create('forum_categories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedInteger('parent_id')->default(0)->comment('父级ID');
|
||||
$table->string('name', 50)->comment('分类名称');
|
||||
$table->string('slug', 50)->comment('标识');
|
||||
$table->string('description', 255)->default('')->comment('描述');
|
||||
$table->string('name', 50)->comment('板块名称');
|
||||
$table->string('description', 255)->default('')->comment('板块描述');
|
||||
$table->string('icon', 255)->default('')->comment('图标');
|
||||
$table->integer('sort')->default(0)->comment('排序');
|
||||
$table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常');
|
||||
$table->tinyInteger('review')->default(1)->comment('帖子是否审核:0=无需审核,1=需要审核');
|
||||
$table->tinyInteger('comment_review')->default(1)->comment('评论是否审核:0=无需审核,1=需要审核');
|
||||
$table->timestamps();
|
||||
$table->index('slug');
|
||||
$table->comment('话题分类');
|
||||
$table->comment('帖子板块');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,7 +29,7 @@ return new class extends Migration
|
||||
Schema::create('forum_posts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedInteger('user_id')->comment('发布用户ID');
|
||||
$table->unsignedBigInteger('category_id')->nullable()->comment('分类ID');
|
||||
$table->unsignedBigInteger('category_id')->nullable()->comment('帖子板块ID');
|
||||
$table->string('title', 100)->comment('帖子标题');
|
||||
$table->text('content')->comment('帖子内容');
|
||||
$table->json('images')->nullable()->comment('图片列表');
|
||||
@@ -40,7 +39,7 @@ return new class extends Migration
|
||||
$table->integer('favorite_count')->default(0)->comment('收藏数');
|
||||
$table->tinyInteger('is_hot')->default(0)->comment('是否热门:0=否,1=是');
|
||||
$table->tinyInteger('is_top')->default(0)->comment('是否置顶:0=否,1=是');
|
||||
$table->tinyInteger('status')->default(1)->comment('状态:0=草稿,1=发布,2=隐藏');
|
||||
$table->tinyInteger('status')->default(1)->comment('状态:1=发布,2=隐藏');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->index('user_id');
|
||||
|
||||
@@ -8,14 +8,15 @@ return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// 任务分类
|
||||
// 任务分类(跑腿/代取/租借等,后台可管理)
|
||||
if (! Schema::hasTable('task_categories')) {
|
||||
Schema::create('task_categories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name', 50)->comment('分类名称');
|
||||
$table->string('slug', 50)->comment('标识');
|
||||
$table->string('slug', 50)->comment('标识:errand=跑腿,pickup=代取,rental=租借');
|
||||
$table->string('description', 255)->default('')->comment('描述');
|
||||
$table->string('icon', 255)->default('')->comment('图标');
|
||||
$table->json('form_schema')->nullable()->comment('分类特有字段模板,前端据此动态渲染表单');
|
||||
$table->integer('sort')->default(0)->comment('排序');
|
||||
$table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常');
|
||||
$table->timestamps();
|
||||
@@ -24,26 +25,37 @@ return new class extends Migration
|
||||
});
|
||||
}
|
||||
|
||||
// 任务订单(跑腿/代取/租借)
|
||||
// 任务订单(跑腿/代取/租借统一,分类特有字段存 extra)
|
||||
if (! Schema::hasTable('task_orders')) {
|
||||
Schema::create('task_orders', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('order_no', 32)->comment('订单编号');
|
||||
$table->unsignedInteger('user_id')->comment('发布用户ID');
|
||||
$table->unsignedInteger('runner_id')->nullable()->comment('接单用户ID');
|
||||
$table->unsignedBigInteger('category_id')->comment('分类ID');
|
||||
$table->unsignedBigInteger('category_id')->comment('任务分类ID');
|
||||
$table->string('title', 100)->comment('任务标题');
|
||||
$table->text('description')->comment('任务描述');
|
||||
$table->text('description')->nullable()->comment('任务描述');
|
||||
$table->json('images')->nullable()->comment('图片列表');
|
||||
$table->decimal('price', 10, 2)->default(0)->comment('任务价格/报酬');
|
||||
$table->json('extra')->nullable()->comment('分类特有字段:跑腿{取件地址,送达地址},代取{取件地点,取件码},租借{押金,租借天数}');
|
||||
$table->decimal('price', 10, 2)->default(0)->comment('任务报酬');
|
||||
$table->string('address', 255)->default('')->comment('任务地址');
|
||||
$table->string('contact_name', 30)->default('')->comment('联系人');
|
||||
$table->string('contact_mobile', 20)->default('')->comment('联系电话');
|
||||
$table->timestamp('deadline')->nullable()->comment('截止时间');
|
||||
|
||||
// 支付信息(创建订单时支付)
|
||||
$table->tinyInteger('pay_type')->default(0)->comment('支付方式:0=余额,1=微信支付');
|
||||
$table->tinyInteger('pay_status')->default(0)->comment('支付状态:0=待支付,1=已支付,2=退款中,3=已退款');
|
||||
$table->timestamp('paid_at')->nullable()->comment('支付时间');
|
||||
|
||||
// 订单状态流转
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=待接单,1=已接单,2=进行中,3=已完成,4=已取消');
|
||||
$table->string('cancel_reason', 255)->default('')->comment('取消原因');
|
||||
$table->string('remark', 500)->default('')->comment('订单备注');
|
||||
$table->timestamp('accepted_at')->nullable()->comment('接单时间');
|
||||
$table->timestamp('completed_at')->nullable()->comment('完成时间');
|
||||
$table->timestamp('cancelled_at')->nullable()->comment('取消时间');
|
||||
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->unique('order_no');
|
||||
@@ -51,29 +63,56 @@ return new class extends Migration
|
||||
$table->index('runner_id');
|
||||
$table->index('category_id');
|
||||
$table->index('status');
|
||||
$table->index('pay_status');
|
||||
$table->comment('校园任务订单');
|
||||
});
|
||||
}
|
||||
|
||||
// 任务竞价/接单报价
|
||||
// 接单记录/竞价(用户对任务报价或申请接单)
|
||||
if (! Schema::hasTable('task_bids')) {
|
||||
Schema::create('task_bids', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('task_id')->comment('任务ID');
|
||||
$table->unsignedBigInteger('task_id')->comment('任务订单ID');
|
||||
$table->unsignedInteger('user_id')->comment('接单人ID');
|
||||
$table->decimal('price', 10, 2)->default(0)->comment('报价');
|
||||
$table->string('message', 500)->default('')->comment('留言');
|
||||
$table->decimal('price', 10, 2)->default(0)->comment('报价(等于任务价即为直接接单)');
|
||||
$table->string('message', 500)->default('')->comment('申请留言/自我介绍');
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=待确认,1=已接受,2=已拒绝');
|
||||
$table->timestamp('accepted_at')->nullable()->comment('接受时间');
|
||||
$table->timestamps();
|
||||
$table->index('task_id');
|
||||
$table->index('user_id');
|
||||
$table->comment('任务竞价');
|
||||
$table->unique(['task_id', 'user_id'], 'uk_task_user');
|
||||
$table->comment('任务接单/竞价记录');
|
||||
});
|
||||
}
|
||||
|
||||
// 任务支付日志(支付成功后写入,关联三方支付流水)
|
||||
if (! Schema::hasTable('task_payments')) {
|
||||
Schema::create('task_payments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('payment_no', 32)->comment('支付日志编号');
|
||||
$table->unsignedBigInteger('order_id')->comment('任务订单ID');
|
||||
$table->unsignedInteger('user_id')->comment('支付用户ID');
|
||||
$table->unsignedBigInteger('payment_transaction_id')->nullable()->comment('三方支付流水ID');
|
||||
$table->decimal('amount', 10, 2)->comment('支付金额');
|
||||
$table->tinyInteger('pay_type')->comment('支付方式:0=余额,1=微信支付');
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=待支付,1=已支付,2=已退款');
|
||||
$table->timestamp('paid_at')->nullable()->comment('支付时间');
|
||||
$table->timestamp('refund_at')->nullable()->comment('退款时间');
|
||||
$table->timestamps();
|
||||
$table->unique('payment_no');
|
||||
$table->index('order_id');
|
||||
$table->index('user_id');
|
||||
$table->index('payment_transaction_id');
|
||||
$table->index('status');
|
||||
$table->comment('任务支付日志');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('task_payments');
|
||||
Schema::dropIfExists('task_bids');
|
||||
Schema::dropIfExists('task_orders');
|
||||
Schema::dropIfExists('task_categories');
|
||||
|
||||
@@ -8,79 +8,57 @@ return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// 兼职岗位
|
||||
if (! Schema::hasTable('part_time_jobs')) {
|
||||
Schema::create('part_time_jobs', function (Blueprint $table) {
|
||||
// 接单员申请
|
||||
if (! Schema::hasTable('runner_applications')) {
|
||||
Schema::create('runner_applications', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedInteger('merchant_id')->nullable()->comment('发布商户ID');
|
||||
$table->string('title', 100)->comment('岗位标题');
|
||||
$table->text('description')->nullable()->comment('岗位描述');
|
||||
$table->text('requirements')->nullable()->comment('任职要求');
|
||||
$table->decimal('salary', 10, 2)->default(0)->comment('薪资');
|
||||
$table->tinyInteger('salary_type')->default(1)->comment('薪资类型:1=时薪,2=日薪,3=月薪');
|
||||
$table->string('location', 255)->default('')->comment('工作地点');
|
||||
$table->string('contact_name', 30)->default('')->comment('联系人');
|
||||
$table->string('contact_mobile', 20)->default('')->comment('联系电话');
|
||||
$table->integer('quota')->default(1)->comment('招聘人数');
|
||||
$table->integer('applied_count')->default(0)->comment('已申请人数');
|
||||
$table->tinyInteger('status')->default(1)->comment('状态:0=草稿,1=发布,2=已关闭');
|
||||
$table->date('start_date')->nullable()->comment('开始日期');
|
||||
$table->date('end_date')->nullable()->comment('截止日期');
|
||||
$table->timestamps();
|
||||
$table->index('merchant_id');
|
||||
$table->index('status');
|
||||
$table->comment('兼职岗位');
|
||||
});
|
||||
}
|
||||
|
||||
// 兼职申请/报名
|
||||
if (! Schema::hasTable('part_time_applications')) {
|
||||
Schema::create('part_time_applications', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('job_id')->comment('岗位ID');
|
||||
$table->unsignedInteger('user_id')->comment('申请用户ID');
|
||||
$table->string('real_name', 30)->comment('真实姓名');
|
||||
$table->string('mobile', 20)->comment('联系电话');
|
||||
$table->string('resume', 500)->default('')->comment('个人简介/简历');
|
||||
$table->string('resume', 500)->default('')->comment('个人简介/申请理由');
|
||||
$table->string('id_card', 18)->comment('身份证号');
|
||||
$table->string('id_card_front', 255)->default('')->comment('身份证正面照');
|
||||
$table->string('id_card_back', 255)->default('')->comment('身份证背面照');
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=待审核,1=已通过,2=已拒绝');
|
||||
$table->string('review_remark', 255)->default('')->comment('审核备注');
|
||||
$table->timestamp('reviewed_at')->nullable()->comment('审核时间');
|
||||
$table->timestamps();
|
||||
$table->index('job_id');
|
||||
$table->index('user_id');
|
||||
$table->comment('兼职申请');
|
||||
$table->index('mobile');
|
||||
$table->comment('接单员申请');
|
||||
});
|
||||
}
|
||||
|
||||
// 兼职人员(已认证)
|
||||
if (! Schema::hasTable('part_time_workers')) {
|
||||
Schema::create('part_time_workers', function (Blueprint $table) {
|
||||
// 接单员列表(审核通过后写入)
|
||||
if (! Schema::hasTable('runner_workers')) {
|
||||
Schema::create('runner_workers', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedInteger('user_id')->comment('用户ID');
|
||||
$table->unsignedInteger('user_id')->unique()->comment('用户ID');
|
||||
$table->string('real_name', 30)->comment('真实姓名');
|
||||
$table->string('mobile', 20)->comment('联系电话');
|
||||
$table->string('id_card', 18)->comment('身份证号');
|
||||
$table->string('id_card_front', 255)->default('')->comment('身份证正面照');
|
||||
$table->string('id_card_back', 255)->default('')->comment('身份证背面照');
|
||||
$table->decimal('balance', 10, 2)->default(0)->comment('佣金余额');
|
||||
$table->decimal('total_income', 10, 2)->default(0)->comment('累计收入');
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=待认证,1=已认证,2=已拒绝');
|
||||
$table->timestamp('verified_at')->nullable()->comment('认证时间');
|
||||
$table->integer('total_order')->default(0)->comment('累计完成订单');
|
||||
$table->integer('cancel_order')->default(0)->comment('累计取消订单');
|
||||
$table->decimal('credit_score', 10, 2)->default(100)->comment('信誉分(满分100)');
|
||||
$table->timestamp('verified_at')->nullable()->comment('认证通过时间');
|
||||
$table->tinyInteger('status')->default(1)->comment('状态:0=禁止接单,1=正常,2=休息中');
|
||||
$table->timestamps();
|
||||
$table->index('user_id');
|
||||
$table->index('mobile');
|
||||
$table->comment('兼职人员');
|
||||
$table->index('credit_score');
|
||||
$table->comment('接单员');
|
||||
});
|
||||
}
|
||||
|
||||
// 兼职提现
|
||||
if (! Schema::hasTable('part_time_withdrawals')) {
|
||||
Schema::create('part_time_withdrawals', function (Blueprint $table) {
|
||||
// 接单员提现
|
||||
if (! Schema::hasTable('runner_withdrawals')) {
|
||||
Schema::create('runner_withdrawals', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('withdraw_no', 32)->comment('提现编号');
|
||||
$table->unsignedInteger('user_id')->comment('用户ID');
|
||||
$table->unsignedBigInteger('worker_id')->comment('兼职人员ID');
|
||||
$table->unsignedBigInteger('worker_id')->comment('接单员ID');
|
||||
$table->decimal('amount', 10, 2)->comment('提现金额');
|
||||
$table->decimal('fee', 10, 2)->default(0)->comment('手续费');
|
||||
$table->string('channel', 20)->comment('提现渠道:wechat=微信,alipay=支付宝,bank=银行卡');
|
||||
$table->json('account_info')->nullable()->comment('收款账户信息');
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=待审核,1=已通过,2=已完成,3=已拒绝');
|
||||
@@ -91,16 +69,127 @@ return new class extends Migration
|
||||
$table->index('user_id');
|
||||
$table->index('worker_id');
|
||||
$table->index('status');
|
||||
$table->comment('兼职提现');
|
||||
$table->comment('接单员提现');
|
||||
});
|
||||
}
|
||||
|
||||
// 信誉分变动记录
|
||||
if (! Schema::hasTable('runner_credit_logs')) {
|
||||
Schema::create('runner_credit_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('worker_id')->comment('接单员ID');
|
||||
$table->decimal('score', 5, 2)->comment('变动分值(正=加分,负=扣分)');
|
||||
$table->decimal('score_after', 5, 2)->comment('变动后分值');
|
||||
$table->string('type', 30)->comment('变动类型:order_complete=完成订单,order_cancel=取消订单,order_timeout=超时,complaint=被投诉,appeal_success=申诉成功,manual=管理员调整');
|
||||
$table->string('description', 255)->comment('变动说明');
|
||||
$table->string('related_type', 30)->nullable()->comment('关联类型');
|
||||
$table->unsignedBigInteger('related_id')->nullable()->comment('关联ID');
|
||||
$table->timestamps();
|
||||
$table->index('worker_id');
|
||||
$table->index('type');
|
||||
$table->index(['related_type', 'related_id']);
|
||||
$table->comment('接单员信誉分记录');
|
||||
});
|
||||
}
|
||||
|
||||
// 投诉记录
|
||||
if (! Schema::hasTable('runner_complaints')) {
|
||||
Schema::create('runner_complaints', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('complaint_no', 32)->comment('投诉编号');
|
||||
$table->unsignedInteger('user_id')->comment('投诉用户ID');
|
||||
$table->unsignedBigInteger('worker_id')->comment('被投诉接单员ID');
|
||||
$table->unsignedBigInteger('order_id')->nullable()->comment('关联任务订单ID');
|
||||
$table->string('type', 30)->comment('投诉类型:late=迟到/超时,attitude=服务态度,damage=物品损坏,lost=物品丢失,other=其他');
|
||||
$table->text('content')->comment('投诉内容');
|
||||
$table->json('images')->nullable()->comment('凭证图片');
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=待处理,1=已处理,2=已驳回');
|
||||
$table->string('result', 255)->default('')->comment('处理结果');
|
||||
$table->string('result_remark', 500)->default('')->comment('处理备注');
|
||||
$table->timestamp('handled_at')->nullable()->comment('处理时间');
|
||||
$table->timestamps();
|
||||
$table->unique('complaint_no');
|
||||
$table->index('user_id');
|
||||
$table->index('worker_id');
|
||||
$table->index('order_id');
|
||||
$table->index('status');
|
||||
$table->comment('接单员投诉记录');
|
||||
});
|
||||
}
|
||||
|
||||
// 投诉申诉记录
|
||||
if (! Schema::hasTable('runner_complaint_appeals')) {
|
||||
Schema::create('runner_complaint_appeals', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('complaint_id')->comment('投诉ID');
|
||||
$table->unsignedBigInteger('worker_id')->comment('申诉接单员ID');
|
||||
$table->text('content')->comment('申诉内容');
|
||||
$table->json('images')->nullable()->comment('凭证图片');
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=待审核,1=已通过,2=已驳回');
|
||||
$table->string('reply', 500)->default('')->comment('审核回复');
|
||||
$table->timestamp('reviewed_at')->nullable()->comment('审核时间');
|
||||
$table->timestamps();
|
||||
$table->index('complaint_id');
|
||||
$table->index('worker_id');
|
||||
$table->comment('接单员投诉申诉');
|
||||
});
|
||||
}
|
||||
|
||||
// 接单员保证金
|
||||
if (! Schema::hasTable('runner_deposits')) {
|
||||
Schema::create('runner_deposits', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('deposit_no', 32)->comment('保证金编号');
|
||||
$table->unsignedBigInteger('worker_id')->comment('接单员ID');
|
||||
$table->unsignedInteger('user_id')->comment('用户ID');
|
||||
$table->decimal('amount', 10, 2)->comment('保证金金额');
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=未缴纳,1=已缴纳,2=已退还,3=已扣除');
|
||||
$table->string('deduct_reason', 255)->default('')->comment('扣除原因');
|
||||
$table->timestamp('paid_at')->nullable()->comment('缴纳时间');
|
||||
$table->timestamp('refund_at')->nullable()->comment('退还时间');
|
||||
$table->timestamp('deducted_at')->nullable()->comment('扣除时间');
|
||||
$table->timestamps();
|
||||
$table->unique('deposit_no');
|
||||
$table->index('worker_id');
|
||||
$table->index('user_id');
|
||||
$table->index('status');
|
||||
$table->comment('接单员保证金');
|
||||
});
|
||||
}
|
||||
|
||||
// 保证金支付日志(支付成功后写入,关联三方支付流水)
|
||||
if (! Schema::hasTable('deposit_payments')) {
|
||||
Schema::create('deposit_payments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('payment_no', 32)->comment('支付日志编号');
|
||||
$table->unsignedBigInteger('deposit_id')->comment('保证金ID');
|
||||
$table->unsignedInteger('user_id')->comment('支付用户ID');
|
||||
$table->unsignedBigInteger('payment_transaction_id')->nullable()->comment('三方支付流水ID');
|
||||
$table->decimal('amount', 10, 2)->comment('支付金额');
|
||||
$table->tinyInteger('pay_type')->comment('支付方式:0=余额,1=微信支付');
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=待支付,1=已支付,2=已退款');
|
||||
$table->timestamp('paid_at')->nullable()->comment('支付时间');
|
||||
$table->timestamp('refund_at')->nullable()->comment('退款时间');
|
||||
$table->timestamps();
|
||||
$table->unique('payment_no');
|
||||
$table->index('deposit_id');
|
||||
$table->index('user_id');
|
||||
$table->index('payment_transaction_id');
|
||||
$table->index('status');
|
||||
$table->comment('保证金支付日志');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('part_time_withdrawals');
|
||||
Schema::dropIfExists('part_time_workers');
|
||||
Schema::dropIfExists('part_time_applications');
|
||||
Schema::dropIfExists('part_time_jobs');
|
||||
Schema::dropIfExists('deposit_payments');
|
||||
Schema::dropIfExists('runner_deposits');
|
||||
Schema::dropIfExists('runner_complaint_appeals');
|
||||
Schema::dropIfExists('runner_complaints');
|
||||
Schema::dropIfExists('runner_credit_logs');
|
||||
Schema::dropIfExists('runner_withdrawals');
|
||||
Schema::dropIfExists('runner_workers');
|
||||
Schema::dropIfExists('runner_applications');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,21 +8,6 @@ return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// 商户分类
|
||||
if (! Schema::hasTable('merchant_categories')) {
|
||||
Schema::create('merchant_categories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name', 50)->comment('分类名称');
|
||||
$table->string('slug', 50)->comment('标识');
|
||||
$table->string('description', 255)->default('')->comment('描述');
|
||||
$table->string('icon', 255)->default('')->comment('图标');
|
||||
$table->integer('sort')->default(0)->comment('排序');
|
||||
$table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常');
|
||||
$table->timestamps();
|
||||
$table->unique('slug');
|
||||
$table->comment('商户分类');
|
||||
});
|
||||
}
|
||||
|
||||
// 商户/店铺
|
||||
if (! Schema::hasTable('merchants')) {
|
||||
@@ -74,6 +59,22 @@ return new class extends Migration
|
||||
});
|
||||
}
|
||||
|
||||
// 商户商品分类
|
||||
if (! Schema::hasTable('platform_categories')) {
|
||||
Schema::create('platform_categories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name', 50)->comment('分类名称');
|
||||
$table->string('slug', 50)->comment('标识');
|
||||
$table->string('description', 255)->default('')->comment('描述');
|
||||
$table->string('icon', 255)->default('')->comment('图标');
|
||||
$table->integer('sort')->default(0)->comment('排序');
|
||||
$table->tinyInteger('status')->default(1)->comment('状态:0=禁用,1=正常');
|
||||
$table->timestamps();
|
||||
$table->unique('slug');
|
||||
$table->comment('商户分类');
|
||||
});
|
||||
}
|
||||
|
||||
// 商品
|
||||
if (! Schema::hasTable('merchant_products')) {
|
||||
Schema::create('merchant_products', function (Blueprint $table) {
|
||||
|
||||
@@ -79,6 +79,29 @@ return new class extends Migration
|
||||
});
|
||||
}
|
||||
|
||||
// 订单支付日志(支付成功后写入,关联三方支付流水)
|
||||
if (! Schema::hasTable('order_payments')) {
|
||||
Schema::create('order_payments', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('payment_no', 32)->comment('支付日志编号');
|
||||
$table->unsignedBigInteger('order_id')->comment('订单ID');
|
||||
$table->unsignedInteger('user_id')->comment('支付用户ID');
|
||||
$table->unsignedBigInteger('payment_transaction_id')->nullable()->comment('三方支付流水ID');
|
||||
$table->decimal('amount', 10, 2)->comment('支付金额');
|
||||
$table->tinyInteger('pay_type')->comment('支付方式:0=余额,1=微信支付');
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=待支付,1=已支付,2=已退款');
|
||||
$table->timestamp('paid_at')->nullable()->comment('支付时间');
|
||||
$table->timestamp('refund_at')->nullable()->comment('退款时间');
|
||||
$table->timestamps();
|
||||
$table->unique('payment_no');
|
||||
$table->index('order_id');
|
||||
$table->index('user_id');
|
||||
$table->index('payment_transaction_id');
|
||||
$table->index('status');
|
||||
$table->comment('订单支付日志');
|
||||
});
|
||||
}
|
||||
|
||||
// 商户提现
|
||||
if (! Schema::hasTable('merchant_withdrawals')) {
|
||||
Schema::create('merchant_withdrawals', function (Blueprint $table) {
|
||||
@@ -103,6 +126,7 @@ return new class extends Migration
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('merchant_withdrawals');
|
||||
Schema::dropIfExists('order_payments');
|
||||
Schema::dropIfExists('order_refunds');
|
||||
Schema::dropIfExists('order_items');
|
||||
Schema::dropIfExists('orders');
|
||||
|
||||
@@ -8,37 +8,28 @@ return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// 钱包
|
||||
if (! Schema::hasTable('wallets')) {
|
||||
Schema::create('wallets', function (Blueprint $table) {
|
||||
// 统一三方支付流水
|
||||
if (! Schema::hasTable('payment_transactions')) {
|
||||
Schema::create('payment_transactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('owner_type', 30)->comment('所属类型:user=用户,merchant=商户');
|
||||
$table->unsignedBigInteger('owner_id')->comment('所属ID');
|
||||
$table->decimal('balance', 10, 2)->default(0)->comment('可用余额');
|
||||
$table->decimal('frozen_balance', 10, 2)->default(0)->comment('冻结余额');
|
||||
$table->timestamps();
|
||||
$table->unique(['owner_type', 'owner_id']);
|
||||
$table->comment('钱包');
|
||||
});
|
||||
}
|
||||
|
||||
// 资金流水
|
||||
if (! Schema::hasTable('transactions')) {
|
||||
Schema::create('transactions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('transaction_no', 32)->comment('流水编号');
|
||||
$table->unsignedBigInteger('wallet_id')->comment('钱包ID');
|
||||
$table->tinyInteger('type')->comment('类型:1=收入,2=支出');
|
||||
$table->decimal('amount', 10, 2)->comment('金额');
|
||||
$table->decimal('balance_after', 10, 2)->comment('交易后余额');
|
||||
$table->string('description', 255)->comment('描述');
|
||||
$table->string('related_type', 30)->nullable()->comment('关联类型:order=订单,task=任务,withdrawal=提现,refund=退款');
|
||||
$table->unsignedBigInteger('related_id')->nullable()->comment('关联ID');
|
||||
$table->string('transaction_no', 64)->comment('第三方交易号(微信支付transaction_id)');
|
||||
$table->string('out_trade_no', 32)->comment('商户订单号');
|
||||
$table->string('pay_type', 20)->comment('支付方式:wechat=微信支付,alipay=支付宝');
|
||||
$table->decimal('amount', 10, 2)->comment('支付金额');
|
||||
$table->tinyInteger('status')->default(0)->comment('状态:0=待支付,1=成功,2=失败,3=已退款');
|
||||
$table->string('business_type', 30)->comment('业务类型:task=任务订单,deposit=保证金,order=商城订单');
|
||||
$table->unsignedBigInteger('business_id')->nullable()->comment('业务ID');
|
||||
$table->unsignedInteger('user_id')->comment('支付用户ID');
|
||||
$table->string('openid', 64)->default('')->comment('微信OpenID');
|
||||
$table->json('raw_data')->nullable()->comment('支付/退款回调原始数据');
|
||||
$table->timestamp('paid_at')->nullable()->comment('支付时间');
|
||||
$table->timestamps();
|
||||
$table->unique('transaction_no');
|
||||
$table->index('wallet_id');
|
||||
$table->index(['related_type', 'related_id']);
|
||||
$table->comment('资金流水');
|
||||
$table->unique('out_trade_no');
|
||||
$table->index('user_id');
|
||||
$table->index(['business_type', 'business_id']);
|
||||
$table->index('status');
|
||||
$table->comment('三方支付流水');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -65,7 +56,6 @@ return new class extends Migration
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('messages');
|
||||
Schema::dropIfExists('transactions');
|
||||
Schema::dropIfExists('wallets');
|
||||
Schema::dropIfExists('payment_transactions');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ class DatabaseSeeder extends Seeder
|
||||
{
|
||||
$this->call([
|
||||
SysUserSeeder::class,
|
||||
SysRuleSeeder::class,
|
||||
SysDataSeeder::class,
|
||||
SysAgentSeeder::class,
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,839 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class SysRuleSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// 每次执行前清空权限菜单和角色权限关联
|
||||
DB::table('sys_role_rule')->delete();
|
||||
DB::table('sys_rule')->delete();
|
||||
|
||||
$rules = [
|
||||
[
|
||||
'type' => 'menu',
|
||||
'name' => '仪表盘',
|
||||
'key' => 'dashboard',
|
||||
'icon' => 'PieChartOutlined',
|
||||
'local' => 'menu.dashboard',
|
||||
'children' => [
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '分析页',
|
||||
'local' => "menu.analysis",
|
||||
'key' => 'dashboard.analysis',
|
||||
'path' => '/dashboard/analysis',
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'menu',
|
||||
'name' => 'AI',
|
||||
'local' => "menu.ai",
|
||||
'icon' => "OpenAIOutlined",
|
||||
'key' => "ai",
|
||||
'children' => [
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "ai.chat",
|
||||
'name' => "AI对话",
|
||||
"path" => "/ai/chat",
|
||||
'local' => "menu.ai.chat",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '发送消息', 'key' => 'ai.chat.send'],
|
||||
['type' => 'rule', 'name' => '会话列表', 'key' => 'ai.chat.conversations'],
|
||||
['type' => 'rule', 'name' => '消息列表', 'key' => 'ai.chat.messages'],
|
||||
['type' => 'rule', 'name' => '删除会话', 'key' => 'ai.chat.delete'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "ai.conversation",
|
||||
'name' => "会话管理",
|
||||
"path" => "/ai/conversation",
|
||||
'local' => "menu.ai.conversation",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询会话列表', 'key' => 'ai.conversation.query'],
|
||||
['type' => 'rule', 'name' => '删除会话', 'key' => 'ai.conversation.delete'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "ai.agent",
|
||||
'name' => "Agent 管理",
|
||||
"path" => "/ai/agent",
|
||||
'local' => "menu.ai.agent",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'ai.agent.query'],
|
||||
['type' => 'rule', 'name' => '更新 Agent', 'key' => 'ai.agent.update'],
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "menu",
|
||||
'name' => "系统管理",
|
||||
'local' => "menu.system",
|
||||
'icon' => "SettingOutlined",
|
||||
'key' => "system",
|
||||
'children' => [
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "system.user",
|
||||
'name' => "用户管理",
|
||||
'path' => "/system/user",
|
||||
'local' => "menu.system.user",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'system.user.query'],
|
||||
['type' => 'rule', 'name' => '新增用户', 'key' => 'system.user.create'],
|
||||
['type' => 'rule', 'name' => '修改用户', 'key' => 'system.user.update'],
|
||||
['type' => 'rule', 'name' => '删除用户', 'key' => 'system.user.delete'],
|
||||
['type' => 'rule', 'name' => '重置用户密码', 'key' => 'system.user.resetPassword'],
|
||||
['type' => 'rule', 'name' => '获取角色选项', 'key' => 'system.user.role'],
|
||||
['type' => 'rule', 'name' => '获取部门选项', 'key' => 'system.user.dept'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "system.dept",
|
||||
'name' => "部门管理",
|
||||
'path' => "/system/dept",
|
||||
'local' => "menu.system.dept",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取部门列表', 'key' => 'system.dept.query'],
|
||||
['type' => 'rule', 'name' => '新建部门', 'key' => 'system.dept.create'],
|
||||
['type' => 'rule', 'name' => '更新部门信息', 'key' => 'system.dept.update'],
|
||||
['type' => 'rule', 'name' => '删除部门', 'key' => 'system.dept.delete'],
|
||||
['type' => 'rule', 'name' => '获取部门用户', 'key' => 'system.dept.users'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "system.role",
|
||||
'name' => "角色管理",
|
||||
'path' => "/system/role",
|
||||
'local' => "menu.system.role",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '新增角色', 'key' => 'system.role.create'],
|
||||
['type' => 'rule', 'name' => '查询角色列表', 'key' => 'system.role.query'],
|
||||
['type' => 'rule', 'name' => '更新角色信息', 'key' => 'system.role.update'],
|
||||
['type' => 'rule', 'name' => '删除角色', 'key' => 'system.role.delete'],
|
||||
['type' => 'rule', 'name' => '设置启用状态', 'key' => 'system.role.status'],
|
||||
['type' => 'rule', 'name' => '获取角色用户', 'key' => 'system.role.users'],
|
||||
['type' => 'rule', 'name' => '设置角色权限', 'key' => 'system.role.setRule'],
|
||||
['type' => 'rule', 'name' => '获取权限选项', 'key' => 'system.role.ruleList'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "system.rule",
|
||||
'name' => "菜单管理",
|
||||
'path' => "/system/rule",
|
||||
'local' => "menu.system.rule",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取权限列表', 'key' => 'system.rule.query'],
|
||||
['type' => 'rule', 'name' => '创建权限规则', 'key' => 'system.rule.create'],
|
||||
['type' => 'rule', 'name' => '更新权限规则', 'key' => 'system.rule.update'],
|
||||
['type' => 'rule', 'name' => '删除权限规则', 'key' => 'system.rule.delete'],
|
||||
['type' => 'rule', 'name' => '获取父级权限', 'key' => 'system.rule.parentQuery'],
|
||||
['type' => 'rule', 'name' => '设置显示状态', 'key' => 'system.rule.show'],
|
||||
['type' => 'rule', 'name' => '设置启用状态', 'key' => 'system.rule.status'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'name' => "文件管理",
|
||||
'local' => "menu.system.file",
|
||||
'key' => "system.file",
|
||||
'path' => "/system/file",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取文件夹', 'key' => 'system.file.group.query'],
|
||||
['type' => 'rule', 'name' => '新增文件夹', 'key' => 'system.file.group.create'],
|
||||
['type' => 'rule', 'name' => '编辑文件夹', 'key' => 'system.file.group.update'],
|
||||
['type' => 'rule', 'name' => '删除文件夹', 'key' => 'system.file.group.delete'],
|
||||
['type' => 'rule', 'name' => '查询文件列表', 'key' => 'system.file.list.query'],
|
||||
['type' => 'rule', 'name' => '上传文件', 'key' => 'system.file.list.upload'],
|
||||
['type' => 'rule', 'name' => '下载文件', 'key' => 'system.file.list.download'],
|
||||
['type' => 'rule', 'name' => '删除文件', 'key' => 'system.file.list.delete'],
|
||||
['type' => 'rule', 'name' => '永久删除文件', 'key' => 'system.file.list.force-delete'],
|
||||
['type' => 'rule', 'name' => '恢复文件', 'key' => 'system.file.list.restore'],
|
||||
['type' => 'rule', 'name' => '查看回收站', 'key' => 'system.file.list.trashed'],
|
||||
['type' => 'rule', 'name' => '清空回收站', 'key' => 'system.file.list.clean-trashed'],
|
||||
['type' => 'rule', 'name' => '复制文件', 'key' => 'system.file.list.copy'],
|
||||
['type' => 'rule', 'name' => '移动文件', 'key' => 'system.file.list.move'],
|
||||
['type' => 'rule', 'name' => '重命名文件', 'key' => 'system.file.list.rename']
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'name' => "系统字典",
|
||||
'local' => "menu.system.dict",
|
||||
'key' => "system.dict",
|
||||
'path' => "/system/dict",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '字典列表', 'key' => 'system.dict.list.query'],
|
||||
['type' => 'rule', 'name' => '新增字典', 'key' => 'system.dict.list.create'],
|
||||
['type' => 'rule', 'name' => '删除字典', 'key' => 'system.dict.list.delete'],
|
||||
['type' => 'rule', 'name' => '更新字典', 'key' => 'system.dict.list.update'],
|
||||
['type' => 'rule', 'name' => '字典项列表', 'key' => 'system.dict.item.query'],
|
||||
['type' => 'rule', 'name' => '字典项新增', 'key' => 'system.dict.item.create'],
|
||||
['type' => 'rule', 'name' => '字典项编辑', 'key' => 'system.dict.item.update'],
|
||||
['type' => 'rule', 'name' => '字典项删除', 'key' => 'system.dict.item.delete'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'name' => "系统配置",
|
||||
'local' => "menu.system.config",
|
||||
'key' => "system.config",
|
||||
'path' => "/system/config",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '配置列表', 'key' => 'system.config.items.query'],
|
||||
['type' => 'rule', 'name' => '新增配置', 'key' => 'system.config.items.create'],
|
||||
['type' => 'rule', 'name' => '编辑配置', 'key' => 'system.config.items.update'],
|
||||
['type' => 'rule', 'name' => '删除配置', 'key' => 'system.config.items.delete'],
|
||||
['type' => 'rule', 'name' => '保存配置', 'key' => 'system.config.items.save'],
|
||||
['type' => 'rule', 'name' => '刷新配置', 'key' => 'system.config.items.refresh'],
|
||||
['type' => 'rule', 'name' => '配置组编辑', 'key' => 'system.config.group.update'],
|
||||
['type' => 'rule', 'name' => '配置组删除', 'key' => 'system.config.items.item.delete'],
|
||||
['type' => 'rule', 'name' => '配置组列表', 'key' => 'system.config.group.query'],
|
||||
['type' => 'rule', 'name' => '配置组新增', 'key' => 'system.config.group.create'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'key' => 'system.mail',
|
||||
'name' => '邮件配置',
|
||||
'path' => '/system/mail',
|
||||
'local' => 'menu.system.mail',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取配置', 'key' => 'system.mail.config'],
|
||||
['type' => 'rule', 'name' => '保存配置', 'key' => 'system.mail.save'],
|
||||
['type' => 'rule', 'name' => '发送测试', 'key' => 'system.mail.test'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'key' => 'system.storage',
|
||||
'name' => '存储配置',
|
||||
'path' => '/system/storage',
|
||||
'local' => 'menu.system.storage',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取配置', 'key' => 'system.storage.config'],
|
||||
['type' => 'rule', 'name' => '保存配置', 'key' => 'system.storage.save'],
|
||||
['type' => 'rule', 'name' => '测试连接', 'key' => 'system.storage.test'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'key' => 'system.ai',
|
||||
'name' => 'AI 配置',
|
||||
'path' => '/system/ai',
|
||||
'local' => 'menu.system.ai',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取可用AI列表', 'key' => 'system.ai.list'],
|
||||
['type' => 'rule', 'name' => '获取AI配置', 'key' => 'system.ai.config'],
|
||||
['type' => 'rule', 'name' => '保存AI配置', 'key' => 'system.ai.save'],
|
||||
['type' => 'rule', 'name' => '测试连接', 'key' => 'system.ai.test'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'name' => "系统信息",
|
||||
'local' => "menu.system.info",
|
||||
'key' => "system.info",
|
||||
'path' => "/system/info",
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'menu',
|
||||
'name' => '小程序用户',
|
||||
'local' => 'menu.member',
|
||||
'icon' => 'UserOutlined',
|
||||
'key' => 'member',
|
||||
'children' => [
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '用户列表',
|
||||
'key' => 'member.user',
|
||||
'path' => '/member/user',
|
||||
'local' => 'menu.member.user',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'member.user.query'],
|
||||
['type' => 'rule', 'name' => '新增用户', 'key' => 'member.user.create'],
|
||||
['type' => 'rule', 'name' => '修改用户', 'key' => 'member.user.update'],
|
||||
['type' => 'rule', 'name' => '删除用户', 'key' => 'member.user.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '地址管理',
|
||||
'key' => 'member.address',
|
||||
'path' => '/member/address',
|
||||
'local' => 'menu.member.address',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'member.address.query'],
|
||||
['type' => 'rule', 'name' => '新增地址', 'key' => 'member.address.create'],
|
||||
['type' => 'rule', 'name' => '修改地址', 'key' => 'member.address.update'],
|
||||
['type' => 'rule', 'name' => '删除地址', 'key' => 'member.address.delete'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'menu',
|
||||
'name' => '校园论坛',
|
||||
'local' => 'menu.forum',
|
||||
'icon' => 'MessageOutlined',
|
||||
'key' => 'forum',
|
||||
'children' => [
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '话题管理',
|
||||
'key' => 'forum.category',
|
||||
'path' => '/forum/category',
|
||||
'local' => 'menu.forum.category',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'forum.category.query'],
|
||||
['type' => 'rule', 'name' => '新增分类', 'key' => 'forum.category.create'],
|
||||
['type' => 'rule', 'name' => '修改分类', 'key' => 'forum.category.update'],
|
||||
['type' => 'rule', 'name' => '删除分类', 'key' => 'forum.category.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '帖子管理',
|
||||
'key' => 'forum.post',
|
||||
'path' => '/forum/post',
|
||||
'local' => 'menu.forum.post',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'forum.post.query'],
|
||||
['type' => 'rule', 'name' => '新增帖子', 'key' => 'forum.post.create'],
|
||||
['type' => 'rule', 'name' => '修改帖子', 'key' => 'forum.post.update'],
|
||||
['type' => 'rule', 'name' => '删除帖子', 'key' => 'forum.post.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '评论管理',
|
||||
'key' => 'forum.comment',
|
||||
'path' => '/forum/comment',
|
||||
'local' => 'menu.forum.comment',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'forum.comment.query'],
|
||||
['type' => 'rule', 'name' => '新增评论', 'key' => 'forum.comment.create'],
|
||||
['type' => 'rule', 'name' => '修改评论', 'key' => 'forum.comment.update'],
|
||||
['type' => 'rule', 'name' => '删除评论', 'key' => 'forum.comment.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '敏感词管理',
|
||||
'key' => 'forum.sensitive-word',
|
||||
'path' => '/forum/sensitive-word',
|
||||
'local' => 'menu.forum.sensitive-word',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'forum.sensitive-word.query'],
|
||||
['type' => 'rule', 'name' => '新增敏感词', 'key' => 'forum.sensitive-word.create'],
|
||||
['type' => 'rule', 'name' => '修改敏感词', 'key' => 'forum.sensitive-word.update'],
|
||||
['type' => 'rule', 'name' => '删除敏感词', 'key' => 'forum.sensitive-word.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '点赞记录',
|
||||
'key' => 'forum.post-like',
|
||||
'path' => '/forum/post-like',
|
||||
'local' => 'menu.forum.post-like',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'forum.post-like.query'],
|
||||
['type' => 'rule', 'name' => '删除记录', 'key' => 'forum.post-like.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '收藏记录',
|
||||
'key' => 'forum.post-favorite',
|
||||
'path' => '/forum/post-favorite',
|
||||
'local' => 'menu.forum.post-favorite',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'forum.post-favorite.query'],
|
||||
['type' => 'rule', 'name' => '删除记录', 'key' => 'forum.post-favorite.delete'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'menu',
|
||||
'name' => '校园商户',
|
||||
'local' => 'menu.merchant',
|
||||
'icon' => 'ShopOutlined',
|
||||
'key' => 'merchant',
|
||||
'children' => [
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '商户分类',
|
||||
'key' => 'merchant.category',
|
||||
'path' => '/merchant/category',
|
||||
'local' => 'menu.merchant.category',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.category.query'],
|
||||
['type' => 'rule', 'name' => '新增分类', 'key' => 'merchant.category.create'],
|
||||
['type' => 'rule', 'name' => '修改分类', 'key' => 'merchant.category.update'],
|
||||
['type' => 'rule', 'name' => '删除分类', 'key' => 'merchant.category.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '商户管理',
|
||||
'key' => 'merchant.store',
|
||||
'path' => '/merchant/store',
|
||||
'local' => 'menu.merchant.store',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.store.query'],
|
||||
['type' => 'rule', 'name' => '新增商户', 'key' => 'merchant.store.create'],
|
||||
['type' => 'rule', 'name' => '修改商户', 'key' => 'merchant.store.update'],
|
||||
['type' => 'rule', 'name' => '删除商户', 'key' => 'merchant.store.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '商品分类',
|
||||
'key' => 'merchant.product-category',
|
||||
'path' => '/merchant/product-category',
|
||||
'local' => 'menu.merchant.product-category',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.product-category.query'],
|
||||
['type' => 'rule', 'name' => '新增分类', 'key' => 'merchant.product-category.create'],
|
||||
['type' => 'rule', 'name' => '修改分类', 'key' => 'merchant.product-category.update'],
|
||||
['type' => 'rule', 'name' => '删除分类', 'key' => 'merchant.product-category.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '商品管理',
|
||||
'key' => 'merchant.product',
|
||||
'path' => '/merchant/product',
|
||||
'local' => 'menu.merchant.product',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.product.query'],
|
||||
['type' => 'rule', 'name' => '新增商品', 'key' => 'merchant.product.create'],
|
||||
['type' => 'rule', 'name' => '修改商品', 'key' => 'merchant.product.update'],
|
||||
['type' => 'rule', 'name' => '删除商品', 'key' => 'merchant.product.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '打印机管理',
|
||||
'key' => 'merchant.printer',
|
||||
'path' => '/merchant/printer',
|
||||
'local' => 'menu.merchant.printer',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.printer.query'],
|
||||
['type' => 'rule', 'name' => '新增打印机', 'key' => 'merchant.printer.create'],
|
||||
['type' => 'rule', 'name' => '修改打印机', 'key' => 'merchant.printer.update'],
|
||||
['type' => 'rule', 'name' => '删除打印机', 'key' => 'merchant.printer.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '打印任务',
|
||||
'key' => 'merchant.print-task',
|
||||
'path' => '/merchant/print-task',
|
||||
'local' => 'menu.merchant.print-task',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.print-task.query'],
|
||||
['type' => 'rule', 'name' => '删除任务', 'key' => 'merchant.print-task.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '订单管理',
|
||||
'key' => 'merchant.order',
|
||||
'path' => '/merchant/order',
|
||||
'local' => 'menu.merchant.order',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.order.query'],
|
||||
['type' => 'rule', 'name' => '新增订单', 'key' => 'merchant.order.create'],
|
||||
['type' => 'rule', 'name' => '修改订单', 'key' => 'merchant.order.update'],
|
||||
['type' => 'rule', 'name' => '删除订单', 'key' => 'merchant.order.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '订单退款',
|
||||
'key' => 'merchant.refund',
|
||||
'path' => '/merchant/refund',
|
||||
'local' => 'menu.merchant.refund',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.refund.query'],
|
||||
['type' => 'rule', 'name' => '处理退款', 'key' => 'merchant.refund.update'],
|
||||
['type' => 'rule', 'name' => '删除记录', 'key' => 'merchant.refund.delete'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
// 校园任务
|
||||
[
|
||||
'type' => 'menu',
|
||||
'key' => 'task',
|
||||
'name' => '校园任务',
|
||||
'icon' => 'ThunderboltOutlined',
|
||||
'local' => 'menu.task',
|
||||
'children' => [
|
||||
// 任务分类
|
||||
[
|
||||
'type' => 'route', 'key' => 'task.category', 'name' => '任务分类',
|
||||
'path' => '/task/category', 'local' => 'menu.task.category',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'task.category.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'task.category.create', 'name' => '创建'],
|
||||
['type' => 'rule', 'key' => 'task.category.update', 'name' => '编辑'],
|
||||
['type' => 'rule', 'key' => 'task.category.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
// 跑腿订单
|
||||
[
|
||||
'type' => 'route', 'key' => 'task.order_errand', 'name' => '跑腿订单',
|
||||
'path' => '/task/order-errand', 'local' => 'menu.task.order_errand',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'task.order.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'task.order.create', 'name' => '创建'],
|
||||
['type' => 'rule', 'key' => 'task.order.update', 'name' => '编辑'],
|
||||
['type' => 'rule', 'key' => 'task.order.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
// 代取订单
|
||||
[
|
||||
'type' => 'route', 'key' => 'task.order_pickup', 'name' => '代取订单',
|
||||
'path' => '/task/order-pickup', 'local' => 'menu.task.order_pickup',
|
||||
],
|
||||
// 租借订单
|
||||
[
|
||||
'type' => 'route', 'key' => 'task.order_rental', 'name' => '租借订单',
|
||||
'path' => '/task/order-rental', 'local' => 'menu.task.order_rental',
|
||||
],
|
||||
// 接单记录
|
||||
[
|
||||
'type' => 'route', 'key' => 'task.bid', 'name' => '接单记录',
|
||||
'path' => '/task/bid', 'local' => 'menu.task.bid',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'task.bid.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'task.bid.create', 'name' => '创建'],
|
||||
['type' => 'rule', 'key' => 'task.bid.update', 'name' => '编辑'],
|
||||
['type' => 'rule', 'key' => 'task.bid.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
// 接单员管理
|
||||
[
|
||||
'type' => 'menu',
|
||||
'key' => 'runner',
|
||||
'name' => '接单员管理',
|
||||
'icon' => 'TeamOutlined',
|
||||
'local' => 'menu.runner',
|
||||
'children' => [
|
||||
// 接单员申请
|
||||
[
|
||||
'type' => 'route', 'key' => 'runner.application', 'name' => '接单员申请',
|
||||
'path' => '/runner/application', 'local' => 'menu.runner.application',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'runner.application.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'runner.application.create', 'name' => '创建'],
|
||||
['type' => 'rule', 'key' => 'runner.application.update', 'name' => '编辑'],
|
||||
['type' => 'rule', 'key' => 'runner.application.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
// 接单员列表 (query/update/delete)
|
||||
[
|
||||
'type' => 'route', 'key' => 'runner.worker', 'name' => '接单员列表',
|
||||
'path' => '/runner/worker', 'local' => 'menu.runner.worker',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'runner.worker.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'runner.worker.update', 'name' => '编辑'],
|
||||
['type' => 'rule', 'key' => 'runner.worker.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
// 信誉分记录 (query only)
|
||||
[
|
||||
'type' => 'route', 'key' => 'runner.credit_log', 'name' => '信誉分记录',
|
||||
'path' => '/runner/credit-log', 'local' => 'menu.runner.credit_log',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'runner.credit_log.query', 'name' => '查询'],
|
||||
],
|
||||
],
|
||||
// 投诉记录
|
||||
[
|
||||
'type' => 'route', 'key' => 'runner.complaint', 'name' => '投诉记录',
|
||||
'path' => '/runner/complaint', 'local' => 'menu.runner.complaint',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'runner.complaint.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'runner.complaint.create', 'name' => '创建'],
|
||||
['type' => 'rule', 'key' => 'runner.complaint.update', 'name' => '编辑'],
|
||||
['type' => 'rule', 'key' => 'runner.complaint.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
// 投诉申诉
|
||||
[
|
||||
'type' => 'route', 'key' => 'runner.complaint_appeal', 'name' => '投诉申诉',
|
||||
'path' => '/runner/complaint-appeal', 'local' => 'menu.runner.complaint_appeal',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'runner.complaint_appeal.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'runner.complaint_appeal.create', 'name' => '创建'],
|
||||
['type' => 'rule', 'key' => 'runner.complaint_appeal.update', 'name' => '编辑'],
|
||||
['type' => 'rule', 'key' => 'runner.complaint_appeal.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
// 财务管理
|
||||
[
|
||||
'type' => 'menu',
|
||||
'key' => 'finance',
|
||||
'name' => '财务管理',
|
||||
'icon' => 'AccountBookOutlined',
|
||||
'local' => 'menu.finance',
|
||||
'children' => [
|
||||
// 任务支付日志 (query/delete)
|
||||
[
|
||||
'type' => 'route', 'key' => 'task.payment', 'name' => '任务支付日志',
|
||||
'path' => '/finance/task-payment', 'local' => 'menu.finance.task_payment',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'task.payment.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'task.payment.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
// 保证金管理 (query/update/delete)
|
||||
[
|
||||
'type' => 'route', 'key' => 'runner.deposit', 'name' => '保证金管理',
|
||||
'path' => '/finance/deposit', 'local' => 'menu.finance.deposit',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'runner.deposit.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'runner.deposit.update', 'name' => '编辑'],
|
||||
['type' => 'rule', 'key' => 'runner.deposit.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
// 保证金支付日志 (query/delete)
|
||||
[
|
||||
'type' => 'route', 'key' => 'runner.deposit_payment', 'name' => '保证金支付日志',
|
||||
'path' => '/finance/deposit-payment', 'local' => 'menu.finance.deposit_payment',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'runner.deposit_payment.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'runner.deposit_payment.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
// 接单员提现 (query/update/delete)
|
||||
[
|
||||
'type' => 'route', 'key' => 'runner.withdrawal', 'name' => '接单员提现',
|
||||
'path' => '/finance/withdrawal', 'local' => 'menu.finance.withdrawal',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'runner.withdrawal.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'runner.withdrawal.update', 'name' => '编辑'],
|
||||
['type' => 'rule', 'key' => 'runner.withdrawal.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
// 资金流水 (query only)
|
||||
[
|
||||
'type' => 'route', 'key' => 'finance.transaction', 'name' => '资金流水',
|
||||
'path' => '/finance/transaction', 'local' => 'menu.finance.transaction',
|
||||
'children' => [
|
||||
['type' => 'rule', 'key' => 'finance.transaction.query', 'name' => '查询'],
|
||||
['type' => 'rule', 'key' => 'finance.transaction.delete', 'name' => '删除'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '订单支付日志',
|
||||
'key' => 'merchant.order_payment',
|
||||
'path' => '/finance/order-payment',
|
||||
'local' => 'menu.finance.order_payment',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询', 'key' => 'merchant.order_payment.query'],
|
||||
['type' => 'rule', 'name' => '删除', 'key' => 'merchant.order_payment.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '商户提现',
|
||||
'key' => 'merchant.withdrawal',
|
||||
'path' => '/finance/merchant-withdrawal',
|
||||
'local' => 'menu.finance.merchant_withdrawal',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询', 'key' => 'merchant.withdrawal.query'],
|
||||
['type' => 'rule', 'name' => '审核', 'key' => 'merchant.withdrawal.update'],
|
||||
['type' => 'rule', 'name' => '删除', 'key' => 'merchant.withdrawal.delete'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'menu',
|
||||
'name' => '商户管理',
|
||||
'local' => 'menu.merchant_portal',
|
||||
'icon' => 'ShopOutlined',
|
||||
'key' => 'merchant.portal',
|
||||
'children' => [
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '商品列表',
|
||||
'key' => 'merchant.portal.product',
|
||||
'path' => '/merchant-portal/product',
|
||||
'local' => 'menu.merchant_portal.product',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.portal.product.query'],
|
||||
['type' => 'rule', 'name' => '新增商品', 'key' => 'merchant.portal.product.create'],
|
||||
['type' => 'rule', 'name' => '修改商品', 'key' => 'merchant.portal.product.update'],
|
||||
['type' => 'rule', 'name' => '删除商品', 'key' => 'merchant.portal.product.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '商品分类',
|
||||
'key' => 'merchant.portal.product-category',
|
||||
'path' => '/merchant-portal/product-category',
|
||||
'local' => 'menu.merchant_portal.product-category',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.portal.product-category.query'],
|
||||
['type' => 'rule', 'name' => '新增分类', 'key' => 'merchant.portal.product-category.create'],
|
||||
['type' => 'rule', 'name' => '修改分类', 'key' => 'merchant.portal.product-category.update'],
|
||||
['type' => 'rule', 'name' => '删除分类', 'key' => 'merchant.portal.product-category.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '订单列表',
|
||||
'key' => 'merchant.portal.order',
|
||||
'path' => '/merchant-portal/order',
|
||||
'local' => 'menu.merchant_portal.order',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.portal.order.query'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '交易流水',
|
||||
'key' => 'merchant.portal.payment',
|
||||
'path' => '/merchant-portal/payment',
|
||||
'local' => 'menu.merchant_portal.payment',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.portal.payment.query'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '打印机管理',
|
||||
'key' => 'merchant.portal.printer',
|
||||
'path' => '/merchant-portal/printer',
|
||||
'local' => 'menu.merchant_portal.printer',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'merchant.portal.printer.query'],
|
||||
['type' => 'rule', 'name' => '新增打印机', 'key' => 'merchant.portal.printer.create'],
|
||||
['type' => 'rule', 'name' => '修改打印机', 'key' => 'merchant.portal.printer.update'],
|
||||
['type' => 'rule', 'name' => '删除打印机', 'key' => 'merchant.portal.printer.delete'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '商户信息',
|
||||
'key' => 'merchant.portal.store',
|
||||
'path' => '/merchant-portal/store',
|
||||
'local' => 'menu.merchant_portal.store',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查看信息', 'key' => 'merchant.portal.store.query'],
|
||||
['type' => 'rule', 'name' => '修改信息', 'key' => 'merchant.portal.store.update'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => 'XinAdmin',
|
||||
'local' => "menu.xin-admin",
|
||||
'key' => "xin-admin",
|
||||
'icon' => "LinkOutlined",
|
||||
'link' => 1,
|
||||
'path' => 'https://xinadmin.cn',
|
||||
]
|
||||
];
|
||||
|
||||
$this->insertRules($rules);
|
||||
|
||||
// 为超级管理员(role_id=1)授予全部启用权限
|
||||
DB::table('sys_role_rule')->insertUsing(
|
||||
['role_id', 'rule_id'],
|
||||
DB::table('sys_rule')
|
||||
->where('status', 1)
|
||||
->select(DB::raw('1 as role_id'), 'id')
|
||||
);
|
||||
|
||||
// 为商户角色分配 merchant.portal.* 及 dashboard 权限
|
||||
$portalRuleIds = DB::table('sys_rule')
|
||||
->where('status', 1)
|
||||
->where(function ($query) {
|
||||
$query->where('key', 'LIKE', 'merchant.portal%')
|
||||
->orWhere('key', 'dashboard')
|
||||
->orWhere('key', 'dashboard.analysis');
|
||||
})
|
||||
->pluck('id');
|
||||
|
||||
DB::table('sys_role_rule')->insert(
|
||||
$portalRuleIds->map(fn ($ruleId) => [
|
||||
'role_id' => 3,
|
||||
'rule_id' => $ruleId,
|
||||
])->toArray()
|
||||
);
|
||||
|
||||
// 为管理员角色分配所有启用权限,排除 merchant.portal.*(商户门户权限)
|
||||
$adminRuleIds = DB::table('sys_rule')
|
||||
->where('status', 1)
|
||||
->where('key', 'NOT LIKE', 'merchant.portal%')
|
||||
->pluck('id');
|
||||
|
||||
DB::table('sys_role_rule')->insert(
|
||||
$adminRuleIds->map(fn ($ruleId) => [
|
||||
'role_id' => 2,
|
||||
'rule_id' => $ruleId,
|
||||
])->toArray()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归插入权限规则数据
|
||||
*/
|
||||
private function insertRules(array $rules, int $pid = 0): void
|
||||
{
|
||||
$order = 0;
|
||||
foreach ($rules as $rule) {
|
||||
$insertData = [
|
||||
'parent_id' => $pid,
|
||||
'type' => $rule['type'],
|
||||
'key' => $rule['key'],
|
||||
'name' => $rule['name'],
|
||||
'path' => $rule['path'] ?? '',
|
||||
'icon' => $rule['icon'] ?? '',
|
||||
'order' => $order++,
|
||||
'local' => $rule['local'] ?? '',
|
||||
'status' => 1,
|
||||
'hidden' => 1,
|
||||
'link' => $rule['link'] ?? 0,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
];
|
||||
|
||||
$currentId = DB::table('sys_rule')->insertGetId($insertData);
|
||||
|
||||
if (! empty($rule['children']) && is_array($rule['children'])) {
|
||||
$this->insertRules($rule['children'], $currentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,8 @@ class SysUserSeeder extends Seeder
|
||||
DB::table('sys_user')->insert([
|
||||
[
|
||||
'id' => 1,
|
||||
'username' => 'admin',
|
||||
'nickname' => '管理员',
|
||||
'username' => 'super_admin',
|
||||
'nickname' => '超级管理员',
|
||||
'email' => Str::random(10).'@example.com',
|
||||
'password' => Hash::make('123456'),
|
||||
'dept_id' => 1,
|
||||
@@ -31,11 +31,11 @@ class SysUserSeeder extends Seeder
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'username' => 'user',
|
||||
'nickname' => '财务',
|
||||
'username' => 'admin',
|
||||
'nickname' => '管理员',
|
||||
'email' => Str::random(10).'@example.com',
|
||||
'password' => Hash::make('123456'),
|
||||
'dept_id' => 2,
|
||||
'dept_id' => 1,
|
||||
'avatar_id' => 1,
|
||||
'email_verified_at' => now(),
|
||||
'remember_token' => Str::random(10),
|
||||
@@ -45,9 +45,8 @@ class SysUserSeeder extends Seeder
|
||||
]);
|
||||
DB::table('sys_role')->insert([
|
||||
['id' => 1, 'name' => '超级管理员', 'created_at' => $date, 'updated_at' => $date],
|
||||
['id' => 2, 'name' => '财务', 'created_at' => $date, 'updated_at' => $date],
|
||||
['id' => 3, 'name' => '电商总监', 'created_at' => $date, 'updated_at' => $date],
|
||||
['id' => 4, 'name' => '市场运营', 'created_at' => $date, 'updated_at' => $date],
|
||||
['id' => 2, 'name' => '管理员', 'created_at' => $date, 'updated_at' => $date],
|
||||
['id' => 3, 'name' => '商户', 'created_at' => $date, 'updated_at' => $date],
|
||||
]);
|
||||
DB::table('sys_dept')->insert([
|
||||
[
|
||||
@@ -63,321 +62,8 @@ class SysUserSeeder extends Seeder
|
||||
'remark' => '总公司',
|
||||
'created_at' => $date,
|
||||
'updated_at' => $date
|
||||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'name' => '新时代软件技术(洛阳)有限公司',
|
||||
'code' => 'A01-B01',
|
||||
'type' => 0,
|
||||
'parent_id' => 1,
|
||||
'sort' => 0,
|
||||
'phone' => '19999999999',
|
||||
'email' => Str::random(10).'@example.com',
|
||||
'address' => '河南省洛阳市龙门区某某街道99号',
|
||||
'remark' => '洛阳市分公司',
|
||||
'created_at' => $date,
|
||||
'updated_at' => $date
|
||||
],
|
||||
[
|
||||
'id' => 3,
|
||||
'name' => '新时代智能科技(郑州)有限公司',
|
||||
'code' => 'A01-B02',
|
||||
'type' => 0,
|
||||
'parent_id' => 1,
|
||||
'sort' => 0,
|
||||
'phone' => '19999999999',
|
||||
'email' => Str::random(10).'@example.com',
|
||||
'address' => '河南省郑州市二七区某某街道69号',
|
||||
'remark' => '郑州市分公司',
|
||||
'created_at' => $date,
|
||||
'updated_at' => $date
|
||||
],
|
||||
[
|
||||
'id' => 4,
|
||||
'name' => '新征程科技(南阳)有限公司',
|
||||
'code' => 'A01-B03',
|
||||
'type' => 0,
|
||||
'parent_id' => 1,
|
||||
'sort' => 2,
|
||||
'phone' => '19999999999',
|
||||
'email' => Str::random(10).'@example.com',
|
||||
'address' => '河南省南阳市卧龙区某某街道77号',
|
||||
'remark' => '南阳市分公司',
|
||||
'created_at' => $date,
|
||||
'updated_at' => $date
|
||||
],
|
||||
[
|
||||
'id' => 5,
|
||||
'name' => '新时代投资发展有限公司',
|
||||
'code' => 'B01',
|
||||
'type' => 0,
|
||||
'parent_id' => 0,
|
||||
'sort' => 2,
|
||||
'phone' => '19999999999',
|
||||
'email' => Str::random(10).'@example.com',
|
||||
'address' => '北京市海淀区人民路666号',
|
||||
'remark' => '我们坚信,卓越的投资在于发现价值,而卓越的投资管理在于创造价值。我们立志成为科技创业者身边最懂业务、最能赋能、最长情的资本伙伴,共同将创新的火种,转化为引领行业的参天大树。',
|
||||
'created_at' => $date,
|
||||
'updated_at' => $date
|
||||
],
|
||||
]);
|
||||
|
||||
$rules = [
|
||||
[
|
||||
'type' => 'menu',
|
||||
'name' => '仪表盘',
|
||||
'key' => 'dashboard',
|
||||
'icon' => 'PieChartOutlined',
|
||||
'local' => 'menu.dashboard',
|
||||
'children' => [
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => '分析页',
|
||||
'local' => "menu.analysis",
|
||||
'key' => 'dashboard.analysis',
|
||||
'path' => '/dashboard/analysis',
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'menu',
|
||||
'name' => 'AI',
|
||||
'local' => "menu.ai",
|
||||
'icon' => "OpenAIOutlined",
|
||||
'key' => "ai",
|
||||
'children' => [
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "ai.chat",
|
||||
'name' => "AI对话",
|
||||
"path" => "/ai/chat",
|
||||
'local' => "menu.ai.chat",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '发送消息', 'key' => 'ai.chat.send'],
|
||||
['type' => 'rule', 'name' => '会话列表', 'key' => 'ai.chat.conversations'],
|
||||
['type' => 'rule', 'name' => '消息列表', 'key' => 'ai.chat.messages'],
|
||||
['type' => 'rule', 'name' => '删除会话', 'key' => 'ai.chat.delete'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "ai.conversation",
|
||||
'name' => "会话管理",
|
||||
"path" => "/ai/conversation",
|
||||
'local' => "menu.ai.conversation",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询会话列表', 'key' => 'ai.conversation.query'],
|
||||
['type' => 'rule', 'name' => '删除会话', 'key' => 'ai.conversation.delete'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "ai.agent",
|
||||
'name' => "Agent 管理",
|
||||
"path" => "/ai/agent",
|
||||
'local' => "menu.ai.agent",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'ai.agent.query'],
|
||||
['type' => 'rule', 'name' => '更新 Agent', 'key' => 'ai.agent.update'],
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "menu",
|
||||
'name' => "系统管理",
|
||||
'local' => "menu.system",
|
||||
'icon' => "SettingOutlined",
|
||||
'key' => "system",
|
||||
'children' => [
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "system.user",
|
||||
'name' => "用户管理",
|
||||
'path' => "/system/user",
|
||||
'local' => "menu.system.user",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '查询列表', 'key' => 'system.user.query'],
|
||||
['type' => 'rule', 'name' => '新增用户', 'key' => 'system.user.create'],
|
||||
['type' => 'rule', 'name' => '修改用户', 'key' => 'system.user.update'],
|
||||
['type' => 'rule', 'name' => '删除用户', 'key' => 'system.user.delete'],
|
||||
['type' => 'rule', 'name' => '重置用户密码', 'key' => 'system.user.resetPassword'],
|
||||
['type' => 'rule', 'name' => '获取角色选项', 'key' => 'system.user.role'],
|
||||
['type' => 'rule', 'name' => '获取部门选项', 'key' => 'system.user.dept'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "system.dept",
|
||||
'name' => "部门管理",
|
||||
'path' => "/system/dept",
|
||||
'local' => "menu.system.dept",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取部门列表', 'key' => 'system.dept.query'],
|
||||
['type' => 'rule', 'name' => '新建部门', 'key' => 'system.dept.create'],
|
||||
['type' => 'rule', 'name' => '更新部门信息', 'key' => 'system.dept.update'],
|
||||
['type' => 'rule', 'name' => '删除部门', 'key' => 'system.dept.delete'],
|
||||
['type' => 'rule', 'name' => '获取部门用户', 'key' => 'system.dept.users'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "system.role",
|
||||
'name' => "角色管理",
|
||||
'path' => "/system/role",
|
||||
'local' => "menu.system.role",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '新增角色', 'key' => 'system.role.create'],
|
||||
['type' => 'rule', 'name' => '查询角色列表', 'key' => 'system.role.query'],
|
||||
['type' => 'rule', 'name' => '更新角色信息', 'key' => 'system.role.update'],
|
||||
['type' => 'rule', 'name' => '删除角色', 'key' => 'system.role.delete'],
|
||||
['type' => 'rule', 'name' => '设置启用状态', 'key' => 'system.role.status'],
|
||||
['type' => 'rule', 'name' => '获取角色用户', 'key' => 'system.role.users'],
|
||||
['type' => 'rule', 'name' => '设置角色权限', 'key' => 'system.role.setRule'],
|
||||
['type' => 'rule', 'name' => '获取权限选项', 'key' => 'system.role.ruleList'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'key' => "system.rule",
|
||||
'name' => "菜单管理",
|
||||
'path' => "/system/rule",
|
||||
'local' => "menu.system.rule",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取权限列表', 'key' => 'system.rule.query'],
|
||||
['type' => 'rule', 'name' => '创建权限规则', 'key' => 'system.rule.create'],
|
||||
['type' => 'rule', 'name' => '更新权限规则', 'key' => 'system.rule.update'],
|
||||
['type' => 'rule', 'name' => '删除权限规则', 'key' => 'system.rule.delete'],
|
||||
['type' => 'rule', 'name' => '获取父级权限', 'key' => 'system.rule.parentQuery'],
|
||||
['type' => 'rule', 'name' => '设置显示状态', 'key' => 'system.rule.show'],
|
||||
['type' => 'rule', 'name' => '设置启用状态', 'key' => 'system.rule.status'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'name' => "文件管理",
|
||||
'local' => "menu.system.file",
|
||||
'key' => "system.file",
|
||||
'path' => "/system/file",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取文件夹', 'key' => 'system.file.group.query'],
|
||||
['type' => 'rule', 'name' => '新增文件夹', 'key' => 'system.file.group.create'],
|
||||
['type' => 'rule', 'name' => '编辑文件夹', 'key' => 'system.file.group.update'],
|
||||
['type' => 'rule', 'name' => '删除文件夹', 'key' => 'system.file.group.delete'],
|
||||
['type' => 'rule', 'name' => '查询文件列表', 'key' => 'system.file.list.query'],
|
||||
['type' => 'rule', 'name' => '上传文件', 'key' => 'system.file.list.upload'],
|
||||
['type' => 'rule', 'name' => '下载文件', 'key' => 'system.file.list.download'],
|
||||
['type' => 'rule', 'name' => '删除文件', 'key' => 'system.file.list.delete'],
|
||||
['type' => 'rule', 'name' => '永久删除文件', 'key' => 'system.file.list.force-delete'],
|
||||
['type' => 'rule', 'name' => '恢复文件', 'key' => 'system.file.list.restore'],
|
||||
['type' => 'rule', 'name' => '查看回收站', 'key' => 'system.file.list.trashed'],
|
||||
['type' => 'rule', 'name' => '清空回收站', 'key' => 'system.file.list.clean-trashed'],
|
||||
['type' => 'rule', 'name' => '复制文件', 'key' => 'system.file.list.copy'],
|
||||
['type' => 'rule', 'name' => '移动文件', 'key' => 'system.file.list.move'],
|
||||
['type' => 'rule', 'name' => '重命名文件', 'key' => 'system.file.list.rename']
|
||||
],
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'name' => "系统字典",
|
||||
'local' => "menu.system.dict",
|
||||
'key' => "system.dict",
|
||||
'path' => "/system/dict",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '字典列表', 'key' => 'system.dict.list.query'],
|
||||
['type' => 'rule', 'name' => '新增字典', 'key' => 'system.dict.list.create'],
|
||||
['type' => 'rule', 'name' => '删除字典', 'key' => 'system.dict.list.delete'],
|
||||
['type' => 'rule', 'name' => '更新字典', 'key' => 'system.dict.list.update'],
|
||||
['type' => 'rule', 'name' => '字典项列表', 'key' => 'system.dict.item.query'],
|
||||
['type' => 'rule', 'name' => '字典项新增', 'key' => 'system.dict.item.create'],
|
||||
['type' => 'rule', 'name' => '字典项编辑', 'key' => 'system.dict.item.update'],
|
||||
['type' => 'rule', 'name' => '字典项删除', 'key' => 'system.dict.item.delete'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'name' => "系统配置",
|
||||
'local' => "menu.system.config",
|
||||
'key' => "system.config",
|
||||
'path' => "/system/config",
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '配置列表', 'key' => 'system.config.items.query'],
|
||||
['type' => 'rule', 'name' => '新增配置', 'key' => 'system.config.items.create'],
|
||||
['type' => 'rule', 'name' => '编辑配置', 'key' => 'system.config.items.update'],
|
||||
['type' => 'rule', 'name' => '删除配置', 'key' => 'system.config.items.delete'],
|
||||
['type' => 'rule', 'name' => '保存配置', 'key' => 'system.config.items.save'],
|
||||
['type' => 'rule', 'name' => '刷新配置', 'key' => 'system.config.items.refresh'],
|
||||
['type' => 'rule', 'name' => '配置组编辑', 'key' => 'system.config.group.update'],
|
||||
['type' => 'rule', 'name' => '配置组删除', 'key' => 'system.config.items.item.delete'],
|
||||
['type' => 'rule', 'name' => '配置组列表', 'key' => 'system.config.group.query'],
|
||||
['type' => 'rule', 'name' => '配置组新增', 'key' => 'system.config.group.create'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'key' => 'system.mail',
|
||||
'name' => '邮件配置',
|
||||
'path' => '/system/mail',
|
||||
'local' => 'menu.system.mail',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取配置', 'key' => 'system.mail.config'],
|
||||
['type' => 'rule', 'name' => '保存配置', 'key' => 'system.mail.save'],
|
||||
['type' => 'rule', 'name' => '发送测试', 'key' => 'system.mail.test'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'key' => 'system.storage',
|
||||
'name' => '存储配置',
|
||||
'path' => '/system/storage',
|
||||
'local' => 'menu.system.storage',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取配置', 'key' => 'system.storage.config'],
|
||||
['type' => 'rule', 'name' => '保存配置', 'key' => 'system.storage.save'],
|
||||
['type' => 'rule', 'name' => '测试连接', 'key' => 'system.storage.test'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'key' => 'system.ai',
|
||||
'name' => 'AI 配置',
|
||||
'path' => '/system/ai',
|
||||
'local' => 'menu.system.ai',
|
||||
'children' => [
|
||||
['type' => 'rule', 'name' => '获取可用AI列表', 'key' => 'system.ai.list'],
|
||||
['type' => 'rule', 'name' => '获取AI配置', 'key' => 'system.ai.config'],
|
||||
['type' => 'rule', 'name' => '保存AI配置', 'key' => 'system.ai.save'],
|
||||
['type' => 'rule', 'name' => '测试连接', 'key' => 'system.ai.test'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => "route",
|
||||
'name' => "系统信息",
|
||||
'local' => "menu.system.info",
|
||||
'key' => "system.info",
|
||||
'path' => "/system/info",
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'route',
|
||||
'name' => 'XinAdmin',
|
||||
'local' => "menu.xin-admin",
|
||||
'key' => "xin-admin",
|
||||
'icon' => "LinkOutlined",
|
||||
'link' => 1,
|
||||
'path' => 'https://xinadmin.cn',
|
||||
]
|
||||
];
|
||||
|
||||
$this->insertRules($rules);
|
||||
|
||||
DB::table('sys_role_rule')->insertUsing(
|
||||
['role_id', 'rule_id'],
|
||||
DB::table('sys_rule')
|
||||
->where('status', 1)
|
||||
->select(DB::raw('1 as role_id'), 'id')
|
||||
);
|
||||
]);
|
||||
|
||||
DB::table('sys_user_role')->insert([
|
||||
[
|
||||
@@ -390,43 +76,4 @@ class SysUserSeeder extends Seeder
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 递归插入权限规则数据
|
||||
*
|
||||
* @param array $rules 规则数据
|
||||
* @param int $pid 父级ID,默认为0(顶级)
|
||||
* @return void
|
||||
*/
|
||||
function insertRules(array $rules, int $pid = 0): void
|
||||
{
|
||||
$order = 0;
|
||||
foreach ($rules as $rule) {
|
||||
// 准备插入数据
|
||||
$insertData = [
|
||||
'parent_id' => $pid,
|
||||
'type' => $rule['type'],
|
||||
'key' => $rule['key'],
|
||||
'name' => $rule['name'],
|
||||
'path' => $rule['path'] ?? '',
|
||||
'icon' => $rule['icon'] ?? '',
|
||||
'order' => $order++,
|
||||
'local' => $rule['local'] ?? '',
|
||||
'status' => 1,
|
||||
'hidden' => 1,
|
||||
'link' => $rule['link'] ?? 0,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
];
|
||||
|
||||
// 插入数据并获取插入的ID
|
||||
$currentId = DB::table('sys_rule')->insertGetId($insertData);
|
||||
|
||||
// 如果有子菜单,递归插入
|
||||
if (!empty($rule['children']) && is_array($rule['children'])) {
|
||||
$this->insertRules($rule['children'], $currentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,9 +108,10 @@ class RouteRegisterService
|
||||
} else {
|
||||
$authMiddleware[] = 'authGuard';
|
||||
}
|
||||
|
||||
if (is_string($authorize) && !empty($abilitiesPrefix)) {
|
||||
$authMiddleware[] = 'abilities:' . $abilitiesPrefix . '.' . $authorize;
|
||||
} else {
|
||||
} else if ($authorize !== true) {
|
||||
$authMiddleware[] = 'abilities:' . $authorize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,8 +167,8 @@ class GenerateRouteHelperCommand extends Command
|
||||
|
||||
if (is_string($authorize) && !empty($abilitiesPrefix)) {
|
||||
$authMiddleware[] = 'abilities:' . $abilitiesPrefix . '.' . $authorize;
|
||||
} else {
|
||||
$authMiddleware[] = 'abilities:' . (is_string($authorize) ? $authorize : '');
|
||||
} else if($authorize !== true) {
|
||||
$authMiddleware[] = 'abilities:' . $authorize;
|
||||
}
|
||||
|
||||
return $authMiddleware;
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Forum\Http\Requests\ForumCategoryFormRequest;
|
||||
use Modules\Forum\Models\ForumCategoryModel;
|
||||
|
||||
#[RequestAttribute('/forum/category', 'forum.category')]
|
||||
class ForumCategoryController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['name', 'slug'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = ForumCategoryModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(ForumCategoryFormRequest $request): JsonResponse
|
||||
{
|
||||
ForumCategoryModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, ForumCategoryFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = ForumCategoryModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('分类不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = ForumCategoryModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('分类不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Forum\Http\Requests\ForumCommentFormRequest;
|
||||
use Modules\Forum\Models\ForumCommentModel;
|
||||
|
||||
#[RequestAttribute('/forum/comment', 'forum.comment')]
|
||||
class ForumCommentController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'post_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['content'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = ForumCommentModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(ForumCommentFormRequest $request): JsonResponse
|
||||
{
|
||||
ForumCommentModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, ForumCommentFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = ForumCommentModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('评论不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = ForumCommentModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('评论不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Forum\Http\Requests\ForumPostFormRequest;
|
||||
use Modules\Forum\Models\ForumPostModel;
|
||||
|
||||
#[RequestAttribute('/forum/post', 'forum.post')]
|
||||
class ForumPostController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'is_hot' => '=',
|
||||
'is_top' => '=',
|
||||
'category_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['title'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = ForumPostModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(ForumPostFormRequest $request): JsonResponse
|
||||
{
|
||||
ForumPostModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, ForumPostFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = ForumPostModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('帖子不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = ForumPostModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('帖子不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Forum\Models\ForumPostFavoriteModel;
|
||||
|
||||
#[RequestAttribute('/forum/post-favorite', 'forum.post-favorite')]
|
||||
class ForumPostFavoriteController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'post_id' => '=',
|
||||
];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = ForumPostFavoriteModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = ForumPostFavoriteModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('收藏记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Forum\Models\ForumPostLikeModel;
|
||||
|
||||
#[RequestAttribute('/forum/post-like', 'forum.post-like')]
|
||||
class ForumPostLikeController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'post_id' => '=',
|
||||
];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = ForumPostLikeModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = ForumPostLikeModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('点赞记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Forum\Http\Requests\ForumSensitiveWordFormRequest;
|
||||
use Modules\Forum\Models\ForumSensitiveWordModel;
|
||||
|
||||
#[RequestAttribute('/forum/sensitive-word', 'forum.sensitive-word')]
|
||||
class ForumSensitiveWordController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'type' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['word'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = ForumSensitiveWordModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(ForumSensitiveWordFormRequest $request): JsonResponse
|
||||
{
|
||||
ForumSensitiveWordModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, ForumSensitiveWordFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = ForumSensitiveWordModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('敏感词不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = ForumSensitiveWordModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('敏感词不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Http\Requests;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class ForumCategoryFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
if (!$this->isUpdate()) {
|
||||
return [
|
||||
'name' => 'required|max:50',
|
||||
'slug' => 'required|max:50|unique:forum_categories,slug',
|
||||
'parent_id' => 'nullable|integer',
|
||||
'description' => 'nullable|max:255',
|
||||
'icon' => 'nullable|max:255',
|
||||
'sort' => 'nullable|integer',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
$id = $this->route('id');
|
||||
return [
|
||||
'name' => 'required|max:50',
|
||||
'slug' => [
|
||||
'required',
|
||||
'max:50',
|
||||
Rule::unique('forum_categories', 'slug')->ignore($id),
|
||||
],
|
||||
'parent_id' => 'nullable|integer',
|
||||
'description' => 'nullable|max:255',
|
||||
'icon' => 'nullable|max:255',
|
||||
'sort' => 'nullable|integer',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'name.required' => '分类名称不能为空',
|
||||
'slug.required' => '分类标识不能为空',
|
||||
'slug.unique' => '分类标识已存在',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Http\Requests;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class ForumCommentFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'post_id' => 'required|integer',
|
||||
'user_id' => 'required|integer',
|
||||
'content' => 'required',
|
||||
'parent_id' => 'nullable|integer',
|
||||
'reply_to' => 'nullable|integer',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'post_id.required' => '帖子ID不能为空',
|
||||
'user_id.required' => '评论用户不能为空',
|
||||
'content.required' => '评论内容不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Http\Requests;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class ForumPostFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'title' => 'required|max:100',
|
||||
'content' => 'required',
|
||||
'category_id' => 'nullable|integer',
|
||||
'user_id' => 'required|integer',
|
||||
'images' => 'nullable|array',
|
||||
'is_hot' => 'nullable|integer|in:0,1',
|
||||
'is_top' => 'nullable|integer|in:0,1',
|
||||
'status' => 'nullable|integer|in:0,1,2',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'title.required' => '帖子标题不能为空',
|
||||
'content.required' => '帖子内容不能为空',
|
||||
'user_id.required' => '发布用户不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Http\Requests;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class ForumSensitiveWordFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
if (!$this->isUpdate()) {
|
||||
return [
|
||||
'word' => 'required|max:100|unique:forum_sensitive_words,word',
|
||||
'replacement' => 'nullable|max:100',
|
||||
'type' => 'nullable|integer|in:1,2',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
$id = $this->route('id');
|
||||
return [
|
||||
'word' => [
|
||||
'required',
|
||||
'max:100',
|
||||
Rule::unique('forum_sensitive_words', 'word')->ignore($id),
|
||||
],
|
||||
'replacement' => 'nullable|max:100',
|
||||
'type' => 'nullable|integer|in:1,2',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'word.required' => '敏感词不能为空',
|
||||
'word.unique' => '敏感词已存在',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ForumCategoryModel extends Model
|
||||
{
|
||||
protected $table = 'forum_categories';
|
||||
|
||||
protected $fillable = [
|
||||
'parent_id',
|
||||
'name',
|
||||
'slug',
|
||||
'description',
|
||||
'icon',
|
||||
'sort',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'parent_id' => 'integer',
|
||||
'sort' => 'integer',
|
||||
'status' => 'integer',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ForumCommentModel extends Model
|
||||
{
|
||||
protected $table = 'forum_comments';
|
||||
|
||||
protected $fillable = [
|
||||
'post_id',
|
||||
'user_id',
|
||||
'parent_id',
|
||||
'reply_to',
|
||||
'content',
|
||||
'like_count',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'post_id' => 'integer',
|
||||
'user_id' => 'integer',
|
||||
'parent_id' => 'integer',
|
||||
'reply_to' => 'integer',
|
||||
'like_count' => 'integer',
|
||||
'status' => 'integer',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ForumPostFavoriteModel extends Model
|
||||
{
|
||||
protected $table = 'forum_post_favorites';
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'post_id',
|
||||
'user_id',
|
||||
'created_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'post_id' => 'integer',
|
||||
'user_id' => 'integer',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ForumPostLikeModel extends Model
|
||||
{
|
||||
protected $table = 'forum_post_likes';
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'post_id',
|
||||
'user_id',
|
||||
'created_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'post_id' => 'integer',
|
||||
'user_id' => 'integer',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class ForumPostModel extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'forum_posts';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'category_id',
|
||||
'title',
|
||||
'content',
|
||||
'images',
|
||||
'view_count',
|
||||
'comment_count',
|
||||
'like_count',
|
||||
'favorite_count',
|
||||
'is_hot',
|
||||
'is_top',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'user_id' => 'integer',
|
||||
'category_id' => 'integer',
|
||||
'images' => 'array',
|
||||
'view_count' => 'integer',
|
||||
'comment_count' => 'integer',
|
||||
'like_count' => 'integer',
|
||||
'favorite_count' => 'integer',
|
||||
'is_hot' => 'integer',
|
||||
'is_top' => 'integer',
|
||||
'status' => 'integer',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ForumSensitiveWordModel extends Model
|
||||
{
|
||||
protected $table = 'forum_sensitive_words';
|
||||
|
||||
protected $fillable = [
|
||||
'word',
|
||||
'replacement',
|
||||
'type',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'type' => 'integer',
|
||||
'status' => 'integer',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Forum\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\AnnoRoute\AnnoRoute;
|
||||
|
||||
class ForumServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function boot(AnnoRoute $annoRoute): void
|
||||
{
|
||||
$annoRoute->register(base_path('modules/Forum/Http/Controllers'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Member\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Member\Http\Requests\MemberAddressFormRequest;
|
||||
use Modules\Member\Models\UserAddressModel;
|
||||
|
||||
#[RequestAttribute('/member/address', 'member.address')]
|
||||
class MemberAddressController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'is_default' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['name', 'mobile', 'detail'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = UserAddressModel::with('user:id,username,nickname,mobile');
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(MemberAddressFormRequest $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validated();
|
||||
UserAddressModel::create($validated);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, MemberAddressFormRequest $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validated();
|
||||
$model = UserAddressModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error();
|
||||
}
|
||||
$model->update($validated);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = UserAddressModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('地址不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Member\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Member\Http\Requests\MemberUserFormRequest;
|
||||
use Modules\Member\Models\MemberUserModel;
|
||||
|
||||
#[RequestAttribute('/member/user', 'member.user')]
|
||||
class MemberUserController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'gender' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['username', 'nickname', 'mobile'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = MemberUserModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(MemberUserFormRequest $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validated();
|
||||
$validated['password'] = Hash::make($validated['password']);
|
||||
MemberUserModel::create($validated);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, MemberUserFormRequest $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validated();
|
||||
$model = MemberUserModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error();
|
||||
}
|
||||
if (!empty($validated['password'])) {
|
||||
$validated['password'] = Hash::make($validated['password']);
|
||||
} else {
|
||||
unset($validated['password']);
|
||||
}
|
||||
$model->update($validated);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$user = MemberUserModel::find($id);
|
||||
if (empty($user)) {
|
||||
return $this->error('用户不存在');
|
||||
}
|
||||
$user->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Member\Http\Requests;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class MemberAddressFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'user_id' => 'required|integer|exists:user,id',
|
||||
'name' => 'required|max:30',
|
||||
'mobile' => 'required|max:20',
|
||||
'province' => 'required|max:30',
|
||||
'city' => 'required|max:30',
|
||||
'district' => 'required|max:30',
|
||||
'detail' => 'required|max:255',
|
||||
'is_default' => 'nullable|integer|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'user_id.required' => '用户ID不能为空',
|
||||
'user_id.exists' => '用户不存在',
|
||||
'name.required' => '收货人不能为空',
|
||||
'name.max' => '收货人名称不能超过30个字符',
|
||||
'mobile.required' => '联系电话不能为空',
|
||||
'mobile.max' => '联系电话不能超过20个字符',
|
||||
'province.required' => '省份不能为空',
|
||||
'city.required' => '城市不能为空',
|
||||
'district.required' => '区县不能为空',
|
||||
'detail.required' => '详细地址不能为空',
|
||||
'is_default.in' => '默认地址格式错误',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Member\Http\Requests;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class MemberUserFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
if (!$this->isUpdate()) {
|
||||
return [
|
||||
'username' => 'required|unique:user,username',
|
||||
'password' => 'required|min:6',
|
||||
'nickname' => 'nullable',
|
||||
'email' => 'nullable|email',
|
||||
'mobile' => 'nullable',
|
||||
'gender' => 'nullable|integer|in:0,1,2',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
'avatar' => 'nullable',
|
||||
'birthday' => 'nullable|date',
|
||||
];
|
||||
}
|
||||
|
||||
$id = $this->route('id');
|
||||
return [
|
||||
'username' => [
|
||||
'required',
|
||||
Rule::unique('user', 'username')->ignore($id),
|
||||
],
|
||||
'password' => 'nullable|min:6',
|
||||
'nickname' => 'nullable',
|
||||
'email' => [
|
||||
'nullable',
|
||||
'email',
|
||||
],
|
||||
'mobile' => 'nullable',
|
||||
'gender' => 'nullable|integer|in:0,1,2',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
'avatar' => 'nullable',
|
||||
'birthday' => 'nullable|date',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'username.required' => '用户名不能为空',
|
||||
'username.unique' => '用户名已存在',
|
||||
'password.required' => '密码不能为空',
|
||||
'password.min' => '密码至少6位',
|
||||
'email.email' => '邮箱格式错误',
|
||||
'gender.in' => '性别格式错误',
|
||||
'status.in' => '状态格式错误',
|
||||
'birthday.date' => '生日格式错误',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Member\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class MemberUserModel extends Model
|
||||
{
|
||||
protected $table = 'user';
|
||||
|
||||
protected $primaryKey = 'id';
|
||||
|
||||
protected $fillable = [
|
||||
'username',
|
||||
'password',
|
||||
'nickname',
|
||||
'email',
|
||||
'avatar',
|
||||
'mobile',
|
||||
'gender',
|
||||
'birthday',
|
||||
'balance',
|
||||
'status',
|
||||
'last_login_at',
|
||||
'openid',
|
||||
'unionid',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'last_login_at' => 'datetime',
|
||||
'birthday' => 'date',
|
||||
'gender' => 'integer',
|
||||
'status' => 'integer',
|
||||
'balance' => 'decimal:2',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Member\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class UserAddressModel extends Model
|
||||
{
|
||||
protected $table = 'user_addresses';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'name',
|
||||
'mobile',
|
||||
'province',
|
||||
'city',
|
||||
'district',
|
||||
'detail',
|
||||
'is_default',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_default' => 'integer',
|
||||
];
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(MemberUserModel::class, 'user_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Member\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\AnnoRoute\AnnoRoute;
|
||||
|
||||
class MemberServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function boot(AnnoRoute $annoRoute): void
|
||||
{
|
||||
$annoRoute->register(base_path('modules/Member/Http/Controllers'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\MerchantCategoryFormRequest;
|
||||
use Modules\Merchant\Models\MerchantCategoryModel;
|
||||
|
||||
#[RequestAttribute('/merchant/category', 'merchant.category')]
|
||||
class MerchantCategoryController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['name', 'slug'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = MerchantCategoryModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(MerchantCategoryFormRequest $request): JsonResponse
|
||||
{
|
||||
MerchantCategoryModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, MerchantCategoryFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = MerchantCategoryModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('分类不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = MerchantCategoryModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('分类不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\MerchantProductFormRequest;
|
||||
use Modules\Merchant\Models\MerchantProductModel;
|
||||
|
||||
#[RequestAttribute('/merchant/product', 'merchant.product')]
|
||||
class MerchantProductController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'is_recommend' => '=',
|
||||
'merchant_id' => '=',
|
||||
'category_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['name'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = MerchantProductModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(MerchantProductFormRequest $request): JsonResponse
|
||||
{
|
||||
MerchantProductModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, MerchantProductFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = MerchantProductModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('商品不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = MerchantProductModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('商品不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\MerchantStoreFormRequest;
|
||||
use Modules\Merchant\Models\MerchantStoreModel;
|
||||
use Modules\SystemUser\Models\SysUserModel;
|
||||
|
||||
#[RequestAttribute('/merchant/store', 'merchant.store')]
|
||||
class MerchantStoreController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'category_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['name', 'contact_name', 'contact_mobile'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = MerchantStoreModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(MerchantStoreFormRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
// 检查用户名是否已存在
|
||||
$username = $data['username'];
|
||||
if (SysUserModel::where('username', $username)->exists()) {
|
||||
return $this->error('用户名已存在');
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
// 创建管理员用户
|
||||
$user = SysUserModel::create([
|
||||
'username' => $username,
|
||||
'password' => Hash::make($data['password']),
|
||||
'nickname' => $data['name'] ?? $username,
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
// 分配"商户"角色
|
||||
$merchantRole = DB::table('sys_role')->where('name', '商户')->first();
|
||||
if ($merchantRole) {
|
||||
DB::table('sys_user_role')->insert([
|
||||
'user_id' => $user->id,
|
||||
'role_id' => $merchantRole->id,
|
||||
]);
|
||||
}
|
||||
|
||||
// 创建商户,关联用户
|
||||
$data['user_id'] = $user->id;
|
||||
unset($data['username'], $data['password']);
|
||||
MerchantStoreModel::create($data);
|
||||
|
||||
DB::commit();
|
||||
return $this->success();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
return $this->error('创建商户失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, MerchantStoreFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = MerchantStoreModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('商户不存在');
|
||||
}
|
||||
|
||||
$data = $request->validated();
|
||||
// 更新时不允许通过此接口修改 username/password/user_id
|
||||
unset($data['username'], $data['password'], $data['user_id']);
|
||||
$model->update($data);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = MerchantStoreModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('商户不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\MerchantWithdrawalFormRequest;
|
||||
use Modules\Merchant\Models\MerchantWithdrawalModel;
|
||||
|
||||
#[RequestAttribute('/merchant/withdrawal', 'merchant.withdrawal')]
|
||||
class MerchantWithdrawalController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'channel' => '=',
|
||||
'merchant_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['withdraw_no'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = MerchantWithdrawalModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, MerchantWithdrawalFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = MerchantWithdrawalModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('提现记录不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = MerchantWithdrawalModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('提现记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\OrderFormRequest;
|
||||
use Modules\Merchant\Models\OrderModel;
|
||||
|
||||
#[RequestAttribute('/merchant/order', 'merchant.order')]
|
||||
class OrderController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'pay_status' => '=',
|
||||
'user_id' => '=',
|
||||
'merchant_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['order_no'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = OrderModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(OrderFormRequest $request): JsonResponse
|
||||
{
|
||||
OrderModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, OrderFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = OrderModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('订单不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = OrderModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('订单不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Models\OrderPaymentModel;
|
||||
|
||||
#[RequestAttribute('/merchant/order-payment', 'merchant.order_payment')]
|
||||
class OrderPaymentController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'pay_type' => '=',
|
||||
'order_id' => '=',
|
||||
'user_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['payment_no'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = OrderPaymentModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = OrderPaymentModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('支付记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\OrderRefundFormRequest;
|
||||
use Modules\Merchant\Models\OrderRefundModel;
|
||||
|
||||
#[RequestAttribute('/merchant/refund', 'merchant.refund')]
|
||||
class OrderRefundController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'order_id' => '=',
|
||||
'user_id' => '=',
|
||||
'merchant_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['refund_no'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = OrderRefundModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, OrderRefundFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = OrderRefundModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('退款记录不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = OrderRefundModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('退款记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers\Portal;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Modules\Merchant\Models\MerchantStoreModel;
|
||||
|
||||
trait MerchantAuthTrait
|
||||
{
|
||||
protected ?int $_merchantId = null;
|
||||
|
||||
/**
|
||||
* 获取当前登录商户的 ID
|
||||
* 通过 sys_user.id -> merchants.user_id 关联获取
|
||||
*/
|
||||
public function getMerchantId(): int
|
||||
{
|
||||
if ($this->_merchantId === null) {
|
||||
$userId = Auth::id();
|
||||
$merchant = MerchantStoreModel::where('user_id', $userId)->first(['id']);
|
||||
|
||||
if (!$merchant) {
|
||||
$this->throwError('商户信息不存在,请联系管理员');
|
||||
}
|
||||
|
||||
$this->_merchantId = $merchant->id;
|
||||
}
|
||||
|
||||
return $this->_merchantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录商户的完整模型
|
||||
*/
|
||||
public function getMerchant(): MerchantStoreModel
|
||||
{
|
||||
$userId = Auth::id();
|
||||
$merchant = MerchantStoreModel::where('user_id', $userId)->first();
|
||||
|
||||
if (!$merchant) {
|
||||
$this->throwError('商户信息不存在,请联系管理员');
|
||||
}
|
||||
|
||||
return $merchant;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers\Portal;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Models\OrderModel;
|
||||
|
||||
#[RequestAttribute('/merchant-portal/order', 'merchant.portal.order')]
|
||||
class OrderController extends BaseController
|
||||
{
|
||||
use MerchantAuthTrait;
|
||||
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'pay_status' => '=',
|
||||
'pay_type' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['order_no'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = OrderModel::where('merchant_id', $this->getMerchantId());
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers\Portal;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Models\OrderPaymentModel;
|
||||
|
||||
#[RequestAttribute('/merchant-portal/payment', 'merchant.portal.payment')]
|
||||
class PaymentController extends BaseController
|
||||
{
|
||||
use MerchantAuthTrait;
|
||||
|
||||
protected array $searchField = [
|
||||
'pay_type' => '=',
|
||||
'status' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['payment_no'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$merchantId = $this->getMerchantId();
|
||||
|
||||
$query = OrderPaymentModel::whereHas('order', function ($q) use ($merchantId) {
|
||||
$q->where('merchant_id', $merchantId);
|
||||
});
|
||||
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers\Portal;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\Portal\PrinterFormRequest;
|
||||
use Modules\Merchant\Models\PrinterModel;
|
||||
|
||||
#[RequestAttribute('/merchant-portal/printer', 'merchant.portal.printer')]
|
||||
class PrinterController extends BaseController
|
||||
{
|
||||
use MerchantAuthTrait;
|
||||
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'brand' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['name'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = PrinterModel::where('merchant_id', $this->getMerchantId());
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(PrinterFormRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
$data['merchant_id'] = $this->getMerchantId();
|
||||
PrinterModel::create($data);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, PrinterFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = PrinterModel::where('id', $id)
|
||||
->where('merchant_id', $this->getMerchantId())
|
||||
->first();
|
||||
if (empty($model)) {
|
||||
return $this->error('打印机不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = PrinterModel::where('id', $id)
|
||||
->where('merchant_id', $this->getMerchantId())
|
||||
->first();
|
||||
if (empty($model)) {
|
||||
return $this->error('打印机不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers\Portal;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\Portal\ProductCategoryFormRequest;
|
||||
use Modules\Merchant\Models\ProductCategoryModel;
|
||||
|
||||
#[RequestAttribute('/merchant-portal/product-category', 'merchant.portal.product-category')]
|
||||
class ProductCategoryController extends BaseController
|
||||
{
|
||||
use MerchantAuthTrait;
|
||||
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'parent_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['name'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = ProductCategoryModel::where('merchant_id', $this->getMerchantId());
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(ProductCategoryFormRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
$data['merchant_id'] = $this->getMerchantId();
|
||||
ProductCategoryModel::create($data);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, ProductCategoryFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = ProductCategoryModel::where('id', $id)
|
||||
->where('merchant_id', $this->getMerchantId())
|
||||
->first();
|
||||
if (empty($model)) {
|
||||
return $this->error('分类不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = ProductCategoryModel::where('id', $id)
|
||||
->where('merchant_id', $this->getMerchantId())
|
||||
->first();
|
||||
if (empty($model)) {
|
||||
return $this->error('分类不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers\Portal;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\Portal\ProductFormRequest;
|
||||
use Modules\Merchant\Models\MerchantProductModel;
|
||||
|
||||
#[RequestAttribute('/merchant-portal/product', 'merchant.portal.product')]
|
||||
class ProductController extends BaseController
|
||||
{
|
||||
use MerchantAuthTrait;
|
||||
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'is_recommend' => '=',
|
||||
'category_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['name'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = MerchantProductModel::where('merchant_id', $this->getMerchantId());
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(ProductFormRequest $request): JsonResponse
|
||||
{
|
||||
$data = $request->validated();
|
||||
$data['merchant_id'] = $this->getMerchantId();
|
||||
MerchantProductModel::create($data);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, ProductFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = MerchantProductModel::where('id', $id)
|
||||
->where('merchant_id', $this->getMerchantId())
|
||||
->first();
|
||||
if (empty($model)) {
|
||||
return $this->error('商品不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = MerchantProductModel::where('id', $id)
|
||||
->where('merchant_id', $this->getMerchantId())
|
||||
->first();
|
||||
if (empty($model)) {
|
||||
return $this->error('商品不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers\Portal;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\Portal\StoreFormRequest;
|
||||
|
||||
#[RequestAttribute('/merchant-portal/store', 'merchant.portal.store')]
|
||||
class StoreController extends BaseController
|
||||
{
|
||||
use MerchantAuthTrait;
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(): JsonResponse
|
||||
{
|
||||
$merchant = $this->getMerchant();
|
||||
return $this->success($merchant->toArray());
|
||||
}
|
||||
|
||||
#[PutRoute(authorize: 'update')]
|
||||
public function update(StoreFormRequest $request): JsonResponse
|
||||
{
|
||||
$merchant = $this->getMerchant();
|
||||
$merchant->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Models\PrintTaskModel;
|
||||
|
||||
#[RequestAttribute('/merchant/print-task', 'merchant.print-task')]
|
||||
class PrintTaskController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'printer_id' => '=',
|
||||
];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = PrintTaskModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = PrintTaskModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('打印任务不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\PrinterFormRequest;
|
||||
use Modules\Merchant\Models\PrinterModel;
|
||||
|
||||
#[RequestAttribute('/merchant/printer', 'merchant.printer')]
|
||||
class PrinterController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'merchant_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['name', 'brand', 'model'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = PrinterModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(PrinterFormRequest $request): JsonResponse
|
||||
{
|
||||
PrinterModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, PrinterFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = PrinterModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('打印机不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = PrinterModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('打印机不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Merchant\Http\Requests\ProductCategoryFormRequest;
|
||||
use Modules\Merchant\Models\ProductCategoryModel;
|
||||
|
||||
#[RequestAttribute('/merchant/product-category', 'merchant.product-category')]
|
||||
class ProductCategoryController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'merchant_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['name', 'slug'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = ProductCategoryModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(ProductCategoryFormRequest $request): JsonResponse
|
||||
{
|
||||
ProductCategoryModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, ProductCategoryFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = ProductCategoryModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('分类不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = ProductCategoryModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('分类不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class MerchantCategoryFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
if (!$this->isUpdate()) {
|
||||
return [
|
||||
'name' => 'required|max:50',
|
||||
'slug' => 'required|max:50|unique:merchant_categories,slug',
|
||||
'description' => 'nullable|max:255',
|
||||
'icon' => 'nullable|max:255',
|
||||
'sort' => 'nullable|integer',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
$id = $this->route('id');
|
||||
return [
|
||||
'name' => 'required|max:50',
|
||||
'slug' => [
|
||||
'required',
|
||||
'max:50',
|
||||
Rule::unique('merchant_categories', 'slug')->ignore($id),
|
||||
],
|
||||
'description' => 'nullable|max:255',
|
||||
'icon' => 'nullable|max:255',
|
||||
'sort' => 'nullable|integer',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'name.required' => '分类名称不能为空',
|
||||
'slug.required' => '分类标识不能为空',
|
||||
'slug.unique' => '分类标识已存在',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class MerchantProductFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'merchant_id' => 'required|integer',
|
||||
'category_id' => 'nullable|integer',
|
||||
'name' => 'required|max:100',
|
||||
'description' => 'nullable',
|
||||
'images' => 'nullable|array',
|
||||
'price' => 'required|numeric',
|
||||
'original_price' => 'nullable|numeric',
|
||||
'stock' => 'nullable|integer',
|
||||
'unit' => 'nullable|max:20',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
'is_recommend' => 'nullable|integer|in:0,1',
|
||||
'sort' => 'nullable|integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'merchant_id.required' => '所属商户不能为空',
|
||||
'name.required' => '商品名称不能为空',
|
||||
'price.required' => '售价不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class MerchantStoreFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'user_id' => 'nullable|integer',
|
||||
'username' => 'nullable|max:50',
|
||||
'password' => 'nullable|min:6|max:50',
|
||||
'category_id' => 'nullable|integer',
|
||||
'name' => 'required|max:50',
|
||||
'logo' => 'nullable|max:255',
|
||||
'banner' => 'nullable|max:255',
|
||||
'description' => 'nullable',
|
||||
'contact_name' => 'nullable|max:30',
|
||||
'contact_mobile' => 'nullable|max:20',
|
||||
'province' => 'nullable|max:30',
|
||||
'city' => 'nullable|max:30',
|
||||
'district' => 'nullable|max:30',
|
||||
'address' => 'nullable|max:255',
|
||||
'latitude' => 'nullable|max:20',
|
||||
'longitude' => 'nullable|max:20',
|
||||
'business_hours' => 'nullable|max:100',
|
||||
'min_price' => 'nullable|numeric',
|
||||
'status' => 'nullable|integer|in:0,1,2,3',
|
||||
'reject_reason' => 'nullable|max:255',
|
||||
];
|
||||
|
||||
// 新建时用户名和密码必填
|
||||
if (! $this->isUpdate()) {
|
||||
$rules['username'] = 'required|max:50';
|
||||
$rules['password'] = 'required|min:6|max:50';
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'name.required' => '店铺名称不能为空',
|
||||
'username.required' => '登录用户名不能为空',
|
||||
'password.required' => '登录密码不能为空',
|
||||
'password.min' => '登录密码不能少于6位',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class MerchantWithdrawalFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
if (!$this->isUpdate()) {
|
||||
return [
|
||||
'withdraw_no' => 'required|string|max:32|unique:merchant_withdrawals,withdraw_no',
|
||||
'merchant_id' => 'required|integer',
|
||||
'amount' => 'required|numeric',
|
||||
'channel' => 'required|string|max:50',
|
||||
'account_info' => 'required|array',
|
||||
'status' => 'required|integer|in:0,1,2',
|
||||
'remark' => 'nullable|string',
|
||||
'processed_at' => 'nullable|date',
|
||||
];
|
||||
}
|
||||
|
||||
$id = $this->route('id');
|
||||
return [
|
||||
'withdraw_no' => ['required', 'string', 'max:32', Rule::unique('merchant_withdrawals', 'withdraw_no')->ignore($id)],
|
||||
'merchant_id' => 'required|integer',
|
||||
'amount' => 'required|numeric',
|
||||
'channel' => 'required|string|max:50',
|
||||
'account_info' => 'required|array',
|
||||
'status' => 'required|integer|in:0,1,2',
|
||||
'remark' => 'nullable|string',
|
||||
'processed_at' => 'nullable|date',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'withdraw_no.required' => '提现单号不能为空',
|
||||
'withdraw_no.unique' => '提现单号已存在',
|
||||
'merchant_id.required' => '商户ID不能为空',
|
||||
'amount.required' => '提现金额不能为空',
|
||||
'channel.required' => '提现渠道不能为空',
|
||||
'account_info.required' => '账户信息不能为空',
|
||||
'status.required' => '提现状态不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class OrderFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
if (!$this->isUpdate()) {
|
||||
return [
|
||||
'order_no' => 'required|string|max:32|unique:orders,order_no',
|
||||
'user_id' => 'required|integer',
|
||||
'merchant_id' => 'required|integer',
|
||||
'address_id' => 'required|integer',
|
||||
'total_amount' => 'required|numeric',
|
||||
'discount_amount' => 'nullable|numeric',
|
||||
'delivery_fee' => 'nullable|numeric',
|
||||
'payment_amount' => 'required|numeric',
|
||||
'pay_type' => 'required|integer|in:0,1,2',
|
||||
'pay_status' => 'required|integer|in:0,1',
|
||||
'paid_at' => 'nullable|date',
|
||||
'status' => 'required|integer|in:0,1,2,3,4,5',
|
||||
'cancel_reason' => 'nullable|string',
|
||||
'remark' => 'nullable|string',
|
||||
'completed_at' => 'nullable|date',
|
||||
];
|
||||
}
|
||||
|
||||
$id = $this->route('id');
|
||||
return [
|
||||
'order_no' => ['required', 'string', 'max:32', Rule::unique('orders', 'order_no')->ignore($id)],
|
||||
'user_id' => 'required|integer',
|
||||
'merchant_id' => 'required|integer',
|
||||
'address_id' => 'required|integer',
|
||||
'total_amount' => 'required|numeric',
|
||||
'discount_amount' => 'nullable|numeric',
|
||||
'delivery_fee' => 'nullable|numeric',
|
||||
'payment_amount' => 'required|numeric',
|
||||
'pay_type' => 'required|integer|in:0,1,2',
|
||||
'pay_status' => 'required|integer|in:0,1',
|
||||
'paid_at' => 'nullable|date',
|
||||
'status' => 'required|integer|in:0,1,2,3,4,5',
|
||||
'cancel_reason' => 'nullable|string',
|
||||
'remark' => 'nullable|string',
|
||||
'completed_at' => 'nullable|date',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'order_no.required' => '订单号不能为空',
|
||||
'order_no.unique' => '订单号已存在',
|
||||
'user_id.required' => '用户ID不能为空',
|
||||
'merchant_id.required' => '商户ID不能为空',
|
||||
'address_id.required' => '地址ID不能为空',
|
||||
'total_amount.required' => '订单总金额不能为空',
|
||||
'payment_amount.required' => '支付金额不能为空',
|
||||
'pay_type.required' => '支付类型不能为空',
|
||||
'pay_status.required' => '支付状态不能为空',
|
||||
'status.required' => '订单状态不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class OrderPaymentFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
if (!$this->isUpdate()) {
|
||||
return [
|
||||
'payment_no' => 'required|string|max:32|unique:order_payments,payment_no',
|
||||
'order_id' => 'required|integer',
|
||||
'user_id' => 'required|integer',
|
||||
'payment_transaction_id' => 'nullable|integer',
|
||||
'amount' => 'required|numeric',
|
||||
'pay_type' => 'required|integer|in:0,1,2',
|
||||
'status' => 'required|integer|in:0,1,2',
|
||||
'paid_at' => 'nullable|date',
|
||||
'refund_at' => 'nullable|date',
|
||||
];
|
||||
}
|
||||
|
||||
$id = $this->route('id');
|
||||
return [
|
||||
'payment_no' => ['required', 'string', 'max:32', Rule::unique('order_payments', 'payment_no')->ignore($id)],
|
||||
'order_id' => 'required|integer',
|
||||
'user_id' => 'required|integer',
|
||||
'payment_transaction_id' => 'nullable|integer',
|
||||
'amount' => 'required|numeric',
|
||||
'pay_type' => 'required|integer|in:0,1,2',
|
||||
'status' => 'required|integer|in:0,1,2',
|
||||
'paid_at' => 'nullable|date',
|
||||
'refund_at' => 'nullable|date',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'payment_no.required' => '支付单号不能为空',
|
||||
'payment_no.unique' => '支付单号已存在',
|
||||
'order_id.required' => '订单ID不能为空',
|
||||
'user_id.required' => '用户ID不能为空',
|
||||
'amount.required' => '支付金额不能为空',
|
||||
'pay_type.required' => '支付类型不能为空',
|
||||
'status.required' => '支付状态不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class OrderRefundFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
if (!$this->isUpdate()) {
|
||||
return [
|
||||
'refund_no' => 'required|string|max:32|unique:order_refunds,refund_no',
|
||||
'order_id' => 'required|integer',
|
||||
'order_item_id' => 'nullable|integer',
|
||||
'user_id' => 'required|integer',
|
||||
'merchant_id' => 'required|integer',
|
||||
'amount' => 'required|numeric',
|
||||
'reason' => 'required|string',
|
||||
'images' => 'nullable|array',
|
||||
'status' => 'required|integer|in:0,1,2,3',
|
||||
'reply' => 'nullable|string',
|
||||
'processed_at' => 'nullable|date',
|
||||
];
|
||||
}
|
||||
|
||||
$id = $this->route('id');
|
||||
return [
|
||||
'refund_no' => ['required', 'string', 'max:32', Rule::unique('order_refunds', 'refund_no')->ignore($id)],
|
||||
'order_id' => 'required|integer',
|
||||
'order_item_id' => 'nullable|integer',
|
||||
'user_id' => 'required|integer',
|
||||
'merchant_id' => 'required|integer',
|
||||
'amount' => 'required|numeric',
|
||||
'reason' => 'required|string',
|
||||
'images' => 'nullable|array',
|
||||
'status' => 'required|integer|in:0,1,2,3',
|
||||
'reply' => 'nullable|string',
|
||||
'processed_at' => 'nullable|date',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'refund_no.required' => '退款单号不能为空',
|
||||
'refund_no.unique' => '退款单号已存在',
|
||||
'order_id.required' => '订单ID不能为空',
|
||||
'user_id.required' => '用户ID不能为空',
|
||||
'merchant_id.required' => '商户ID不能为空',
|
||||
'amount.required' => '退款金额不能为空',
|
||||
'reason.required' => '退款原因不能为空',
|
||||
'status.required' => '退款状态不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests\Portal;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class PrinterFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|max:50',
|
||||
'brand' => 'nullable|max:30',
|
||||
'model' => 'nullable|max:50',
|
||||
'device_no' => 'nullable|max:100',
|
||||
'secret_key' => 'nullable|max:100',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
'config' => 'nullable',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'name.required' => '打印机名称不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests\Portal;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class ProductCategoryFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'parent_id' => 'nullable|integer',
|
||||
'name' => 'required|max:100',
|
||||
'slug' => 'nullable|max:100',
|
||||
'description' => 'nullable',
|
||||
'icon' => 'nullable|max:255',
|
||||
'sort' => 'nullable|integer',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'name.required' => '分类名称不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests\Portal;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class ProductFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'category_id' => 'nullable|integer',
|
||||
'name' => 'required|max:100',
|
||||
'description' => 'nullable',
|
||||
'images' => 'nullable|array',
|
||||
'price' => 'required|numeric',
|
||||
'original_price' => 'nullable|numeric',
|
||||
'stock' => 'nullable|integer',
|
||||
'unit' => 'nullable|max:20',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
'is_recommend' => 'nullable|integer|in:0,1',
|
||||
'sort' => 'nullable|integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'name.required' => '商品名称不能为空',
|
||||
'price.required' => '售价不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests\Portal;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class StoreFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|max:50',
|
||||
'logo' => 'nullable|max:255',
|
||||
'banner' => 'nullable|max:255',
|
||||
'description' => 'nullable',
|
||||
'contact_name' => 'nullable|max:30',
|
||||
'contact_mobile' => 'nullable|max:20',
|
||||
'province' => 'nullable|max:30',
|
||||
'city' => 'nullable|max:30',
|
||||
'district' => 'nullable|max:30',
|
||||
'address' => 'nullable|max:255',
|
||||
'latitude' => 'nullable|max:20',
|
||||
'longitude' => 'nullable|max:20',
|
||||
'business_hours' => 'nullable|max:100',
|
||||
'min_price' => 'nullable|numeric',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'name.required' => '店铺名称不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class PrinterFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'merchant_id' => 'required|integer',
|
||||
'name' => 'required|max:50',
|
||||
'brand' => 'nullable|max:50',
|
||||
'model' => 'nullable|max:50',
|
||||
'device_no' => 'nullable|max:100',
|
||||
'secret_key' => 'nullable|max:255',
|
||||
'status' => 'nullable|integer|in:0,1,2',
|
||||
'config' => 'nullable|array',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'merchant_id.required' => '所属商户不能为空',
|
||||
'name.required' => '打印机名称不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Http\Requests;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class ProductCategoryFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'merchant_id' => 'required|integer',
|
||||
'parent_id' => 'nullable|integer',
|
||||
'name' => 'required|max:50',
|
||||
'slug' => 'required|max:50',
|
||||
'description' => 'nullable|max:255',
|
||||
'icon' => 'nullable|max:255',
|
||||
'sort' => 'nullable|integer',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'merchant_id.required' => '所属商户不能为空',
|
||||
'name.required' => '分类名称不能为空',
|
||||
'slug.required' => '分类标识不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class MerchantCategoryModel extends Model
|
||||
{
|
||||
protected $table = 'platform_categories';
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'slug',
|
||||
'description',
|
||||
'icon',
|
||||
'sort',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'sort' => 'integer',
|
||||
'status' => 'integer',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class MerchantProductModel extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'merchant_products';
|
||||
|
||||
protected $fillable = [
|
||||
'merchant_id',
|
||||
'category_id',
|
||||
'name',
|
||||
'description',
|
||||
'images',
|
||||
'price',
|
||||
'original_price',
|
||||
'stock',
|
||||
'unit',
|
||||
'sales',
|
||||
'status',
|
||||
'is_recommend',
|
||||
'sort',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'merchant_id' => 'integer',
|
||||
'category_id' => 'integer',
|
||||
'images' => 'array',
|
||||
'price' => 'decimal:2',
|
||||
'original_price' => 'decimal:2',
|
||||
'stock' => 'integer',
|
||||
'sales' => 'integer',
|
||||
'status' => 'integer',
|
||||
'is_recommend' => 'integer',
|
||||
'sort' => 'integer',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class MerchantStoreModel extends Model
|
||||
{
|
||||
protected $table = 'merchants';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'category_id',
|
||||
'name',
|
||||
'logo',
|
||||
'banner',
|
||||
'description',
|
||||
'contact_name',
|
||||
'contact_mobile',
|
||||
'province',
|
||||
'city',
|
||||
'district',
|
||||
'address',
|
||||
'latitude',
|
||||
'longitude',
|
||||
'business_hours',
|
||||
'balance',
|
||||
'total_income',
|
||||
'min_price',
|
||||
'status',
|
||||
'reject_reason',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'user_id' => 'integer',
|
||||
'category_id' => 'integer',
|
||||
'balance' => 'decimal:2',
|
||||
'total_income' => 'decimal:2',
|
||||
'min_price' => 'decimal:2',
|
||||
'status' => 'integer',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class MerchantWithdrawalModel extends Model
|
||||
{
|
||||
protected $table = 'merchant_withdrawals';
|
||||
|
||||
protected $fillable = [
|
||||
'withdraw_no',
|
||||
'merchant_id',
|
||||
'amount',
|
||||
'channel',
|
||||
'account_info',
|
||||
'status',
|
||||
'remark',
|
||||
'processed_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'merchant_id' => 'integer',
|
||||
'amount' => 'decimal:2',
|
||||
'account_info' => 'array',
|
||||
'status' => 'integer',
|
||||
'processed_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class OrderItemModel extends Model
|
||||
{
|
||||
protected $table = 'order_items';
|
||||
|
||||
protected $fillable = [
|
||||
'order_id',
|
||||
'product_id',
|
||||
'product_name',
|
||||
'product_image',
|
||||
'price',
|
||||
'quantity',
|
||||
'subtotal',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'order_id' => 'integer',
|
||||
'product_id' => 'integer',
|
||||
'price' => 'decimal:2',
|
||||
'quantity' => 'integer',
|
||||
'subtotal' => 'decimal:2',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class OrderModel extends Model
|
||||
{
|
||||
protected $table = 'orders';
|
||||
|
||||
protected $fillable = [
|
||||
'order_no',
|
||||
'user_id',
|
||||
'merchant_id',
|
||||
'address_id',
|
||||
'total_amount',
|
||||
'discount_amount',
|
||||
'delivery_fee',
|
||||
'payment_amount',
|
||||
'pay_type',
|
||||
'pay_status',
|
||||
'paid_at',
|
||||
'status',
|
||||
'cancel_reason',
|
||||
'remark',
|
||||
'completed_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'total_amount' => 'decimal:2',
|
||||
'discount_amount' => 'decimal:2',
|
||||
'delivery_fee' => 'decimal:2',
|
||||
'payment_amount' => 'decimal:2',
|
||||
'pay_type' => 'integer',
|
||||
'pay_status' => 'integer',
|
||||
'status' => 'integer',
|
||||
'user_id' => 'integer',
|
||||
'merchant_id' => 'integer',
|
||||
'address_id' => 'integer',
|
||||
'paid_at' => 'datetime',
|
||||
'completed_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class OrderPaymentModel extends Model
|
||||
{
|
||||
protected $table = 'order_payments';
|
||||
|
||||
protected $fillable = [
|
||||
'payment_no',
|
||||
'order_id',
|
||||
'user_id',
|
||||
'payment_transaction_id',
|
||||
'amount',
|
||||
'pay_type',
|
||||
'status',
|
||||
'paid_at',
|
||||
'refund_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'order_id' => 'integer',
|
||||
'user_id' => 'integer',
|
||||
'payment_transaction_id' => 'integer',
|
||||
'amount' => 'decimal:2',
|
||||
'pay_type' => 'integer',
|
||||
'status' => 'integer',
|
||||
'paid_at' => 'datetime',
|
||||
'refund_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function order(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(OrderModel::class, 'order_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class OrderRefundModel extends Model
|
||||
{
|
||||
protected $table = 'order_refunds';
|
||||
|
||||
protected $fillable = [
|
||||
'refund_no',
|
||||
'order_id',
|
||||
'order_item_id',
|
||||
'user_id',
|
||||
'merchant_id',
|
||||
'amount',
|
||||
'reason',
|
||||
'images',
|
||||
'status',
|
||||
'reply',
|
||||
'processed_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'order_id' => 'integer',
|
||||
'order_item_id' => 'integer',
|
||||
'user_id' => 'integer',
|
||||
'merchant_id' => 'integer',
|
||||
'amount' => 'decimal:2',
|
||||
'images' => 'array',
|
||||
'status' => 'integer',
|
||||
'processed_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class PrintTaskModel extends Model
|
||||
{
|
||||
protected $table = 'print_tasks';
|
||||
|
||||
protected $fillable = [
|
||||
'printer_id',
|
||||
'order_id',
|
||||
'content',
|
||||
'copies',
|
||||
'status',
|
||||
'error_msg',
|
||||
'printed_at',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'printer_id' => 'integer',
|
||||
'order_id' => 'integer',
|
||||
'copies' => 'integer',
|
||||
'status' => 'integer',
|
||||
'printed_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class PrinterModel extends Model
|
||||
{
|
||||
protected $table = 'printers';
|
||||
|
||||
protected $fillable = [
|
||||
'merchant_id',
|
||||
'name',
|
||||
'brand',
|
||||
'model',
|
||||
'device_no',
|
||||
'secret_key',
|
||||
'status',
|
||||
'config',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'merchant_id' => 'integer',
|
||||
'status' => 'integer',
|
||||
'config' => 'array',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ProductCategoryModel extends Model
|
||||
{
|
||||
protected $table = 'product_categories';
|
||||
|
||||
protected $fillable = [
|
||||
'merchant_id',
|
||||
'parent_id',
|
||||
'name',
|
||||
'slug',
|
||||
'description',
|
||||
'icon',
|
||||
'sort',
|
||||
'status',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'merchant_id' => 'integer',
|
||||
'parent_id' => 'integer',
|
||||
'sort' => 'integer',
|
||||
'status' => 'integer',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Merchant\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\AnnoRoute\AnnoRoute;
|
||||
|
||||
class MerchantServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function boot(AnnoRoute $annoRoute): void
|
||||
{
|
||||
$annoRoute->register(base_path('modules/Merchant/Http/Controllers'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Runner\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Runner\Models\DepositPaymentModel;
|
||||
|
||||
#[RequestAttribute('/runner/deposit-payment', 'runner.deposit_payment')]
|
||||
class DepositPaymentController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'pay_type' => '=',
|
||||
'deposit_id' => '=',
|
||||
'user_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['payment_no'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = DepositPaymentModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = DepositPaymentModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('支付记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Runner\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Runner\Http\Requests\RunnerApplicationFormRequest;
|
||||
use Modules\Runner\Models\RunnerApplicationModel;
|
||||
|
||||
#[RequestAttribute('/runner/application', 'runner.application')]
|
||||
class RunnerApplicationController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['real_name', 'mobile', 'id_card'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = RunnerApplicationModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(RunnerApplicationFormRequest $request): JsonResponse
|
||||
{
|
||||
RunnerApplicationModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, RunnerApplicationFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = RunnerApplicationModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('申请记录不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = RunnerApplicationModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('申请记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Runner\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Runner\Http\Requests\RunnerComplaintAppealFormRequest;
|
||||
use Modules\Runner\Models\RunnerComplaintAppealModel;
|
||||
|
||||
#[RequestAttribute('/runner/complaint-appeal', 'runner.complaint_appeal')]
|
||||
class RunnerComplaintAppealController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'complaint_id' => '=',
|
||||
'worker_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['content'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = RunnerComplaintAppealModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(RunnerComplaintAppealFormRequest $request): JsonResponse
|
||||
{
|
||||
RunnerComplaintAppealModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, RunnerComplaintAppealFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = RunnerComplaintAppealModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('申诉记录不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = RunnerComplaintAppealModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('申诉记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Runner\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Runner\Http\Requests\RunnerComplaintFormRequest;
|
||||
use Modules\Runner\Models\RunnerComplaintModel;
|
||||
|
||||
#[RequestAttribute('/runner/complaint', 'runner.complaint')]
|
||||
class RunnerComplaintController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'type' => '=',
|
||||
'user_id' => '=',
|
||||
'worker_id' => '=',
|
||||
'order_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['complaint_no', 'content'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = RunnerComplaintModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(RunnerComplaintFormRequest $request): JsonResponse
|
||||
{
|
||||
RunnerComplaintModel::create($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, RunnerComplaintFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = RunnerComplaintModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('投诉记录不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = RunnerComplaintModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('投诉记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Runner\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Runner\Models\RunnerCreditLogModel;
|
||||
|
||||
#[RequestAttribute('/runner/credit-log', 'runner.credit_log')]
|
||||
class RunnerCreditLogController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'type' => '=',
|
||||
'worker_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['description'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = RunnerCreditLogModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Runner\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Runner\Http\Requests\RunnerDepositFormRequest;
|
||||
use Modules\Runner\Models\RunnerDepositModel;
|
||||
|
||||
#[RequestAttribute('/runner/deposit', 'runner.deposit')]
|
||||
class RunnerDepositController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'worker_id' => '=',
|
||||
'user_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['deposit_no'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = RunnerDepositModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, RunnerDepositFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = RunnerDepositModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('保证金记录不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = RunnerDepositModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('保证金记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Runner\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Runner\Http\Requests\RunnerWithdrawalFormRequest;
|
||||
use Modules\Runner\Models\RunnerWithdrawalModel;
|
||||
|
||||
#[RequestAttribute('/runner/withdrawal', 'runner.withdrawal')]
|
||||
class RunnerWithdrawalController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
'channel' => '=',
|
||||
'user_id' => '=',
|
||||
'worker_id' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['withdraw_no'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = RunnerWithdrawalModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, RunnerWithdrawalFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = RunnerWithdrawalModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('提现记录不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = RunnerWithdrawalModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('提现记录不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Runner\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\Runner\Http\Requests\RunnerWorkerFormRequest;
|
||||
use Modules\Runner\Models\RunnerWorkerModel;
|
||||
|
||||
#[RequestAttribute('/runner/worker', 'runner.worker')]
|
||||
class RunnerWorkerController extends BaseController
|
||||
{
|
||||
protected array $searchField = [
|
||||
'status' => '=',
|
||||
];
|
||||
|
||||
protected array $quickSearchField = ['real_name', 'mobile'];
|
||||
|
||||
#[GetRoute(authorize: 'query')]
|
||||
public function query(Request $request): JsonResponse
|
||||
{
|
||||
$params = $request->all();
|
||||
$pageSize = $params['pageSize'] ?? 10;
|
||||
$query = RunnerWorkerModel::query();
|
||||
$data = $this->buildSearch($params, $query)
|
||||
->paginate($pageSize)
|
||||
->toArray();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
#[PutRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'update',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function update(int $id, RunnerWorkerFormRequest $request): JsonResponse
|
||||
{
|
||||
$model = RunnerWorkerModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('跑腿员不存在');
|
||||
}
|
||||
$model->update($request->validated());
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
#[DeleteRoute(
|
||||
route: '/{id}',
|
||||
authorize: 'delete',
|
||||
where: ['id' => '[0-9]+']
|
||||
)]
|
||||
public function delete(int $id): JsonResponse
|
||||
{
|
||||
$model = RunnerWorkerModel::find($id);
|
||||
if (empty($model)) {
|
||||
return $this->error('跑腿员不存在');
|
||||
}
|
||||
$model->delete();
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Runner\Http\Requests;
|
||||
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class DepositPaymentFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'payment_no' => 'required|string|max:50',
|
||||
'deposit_id' => 'required|integer|exists:runner_deposits,id',
|
||||
'user_id' => 'required|integer|exists:user,id',
|
||||
'payment_transaction_id' => 'nullable|integer',
|
||||
'amount' => 'required|numeric|min:0',
|
||||
'pay_type' => 'nullable|integer|in:0,1,2',
|
||||
'status' => 'nullable|integer|in:0,1,2',
|
||||
'paid_at' => 'nullable|date',
|
||||
'refund_at' => 'nullable|date',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'payment_no.required' => '支付单号不能为空',
|
||||
'deposit_id.required' => '保证金记录不能为空',
|
||||
'user_id.required' => '用户不能为空',
|
||||
'amount.required' => '金额不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Runner\Http\Requests;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
|
||||
class RunnerApplicationFormRequest extends BaseFormRequest
|
||||
{
|
||||
protected $stopOnFirstFailure = true;
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
if (!$this->isUpdate()) {
|
||||
return [
|
||||
'user_id' => 'required|integer|exists:user,id',
|
||||
'real_name' => 'required|string|max:30',
|
||||
'mobile' => 'required|string|max:20',
|
||||
'resume' => 'nullable|string|max:500',
|
||||
'id_card' => 'required|string|size:18',
|
||||
'id_card_front' => 'nullable|string|max:255',
|
||||
'id_card_back' => 'nullable|string|max:255',
|
||||
'status' => 'nullable|integer|in:0,1,2',
|
||||
'review_remark' => 'nullable|string|max:255',
|
||||
];
|
||||
}
|
||||
|
||||
$id = $this->route('id');
|
||||
return [
|
||||
'user_id' => 'required|integer|exists:user,id',
|
||||
'real_name' => 'required|string|max:30',
|
||||
'mobile' => 'required|string|max:20',
|
||||
'resume' => 'nullable|string|max:500',
|
||||
'id_card' => ['required', 'string', 'size:18', Rule::unique('runner_applications', 'id_card')->ignore($id)],
|
||||
'id_card_front' => 'nullable|string|max:255',
|
||||
'id_card_back' => 'nullable|string|max:255',
|
||||
'status' => 'nullable|integer|in:0,1,2',
|
||||
'review_remark' => 'nullable|string|max:255',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'real_name.required' => '真实姓名不能为空',
|
||||
'mobile.required' => '联系电话不能为空',
|
||||
'id_card.required' => '身份证号不能为空',
|
||||
];
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user