feat: 第五阶段办公协同/统计报表/知识库模块
- 新增3个migration(9张表): office(6表)/report(1表)/kb(2表) - 新增9个Model + 9个Controller - 新增43条API路由(总计305条) - 新增3个前端API模块 + 10个管理页面 - 迁移运行通过, vite build验证通过
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Kb;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Kb\KbArticle;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class KbArticleController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$query = KbArticle::query()->with(['category', 'author']);
|
||||
$query->when($request->category_id, fn($q, $v) => $q->where('category_id', $v));
|
||||
$query->when($request->filled('status'), fn($q) => $q->where('status', $request->status));
|
||||
$query->when($request->filled('visibility'), fn($q) => $q->where('visibility', $request->visibility));
|
||||
$query->when($request->keyword, fn($q, $v) => $q->where('title', 'like', "%{$v}%"));
|
||||
|
||||
return $this->paginate($query->latest()->paginate($request->input('per_page', 15)));
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'content' => 'nullable|string',
|
||||
'category_id' => 'nullable|exists:kb_categories,id',
|
||||
'visibility' => 'nullable|integer|in:1,2',
|
||||
'cover_image' => 'nullable|string|max:255',
|
||||
'attachments' => 'nullable|array',
|
||||
]);
|
||||
$validated['author_id'] = auth()->id();
|
||||
$validated['status'] = 0;
|
||||
|
||||
$article = KbArticle::create($validated);
|
||||
return $this->success($article->load(['category', 'author']));
|
||||
}
|
||||
|
||||
public function show(KbArticle $kbArticle): JsonResponse
|
||||
{
|
||||
$kbArticle->increment('views');
|
||||
return $this->success($kbArticle->load(['category', 'author']));
|
||||
}
|
||||
|
||||
public function update(Request $request, KbArticle $kbArticle): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'title' => 'sometimes|string|max:255',
|
||||
'content' => 'nullable|string',
|
||||
'category_id' => 'nullable|exists:kb_categories,id',
|
||||
'visibility' => 'nullable|integer|in:1,2',
|
||||
'cover_image' => 'nullable|string|max:255',
|
||||
'attachments' => 'nullable|array',
|
||||
]);
|
||||
$kbArticle->update($validated);
|
||||
return $this->success($kbArticle);
|
||||
}
|
||||
|
||||
public function destroy(KbArticle $kbArticle): JsonResponse
|
||||
{
|
||||
$kbArticle->delete();
|
||||
return $this->success(null);
|
||||
}
|
||||
|
||||
public function publish(KbArticle $kbArticle): JsonResponse
|
||||
{
|
||||
if ($kbArticle->status >= 2) {
|
||||
return $this->error('当前状态不允许发布');
|
||||
}
|
||||
$kbArticle->update(['status' => 2, 'published_at' => now()]);
|
||||
return $this->success($kbArticle);
|
||||
}
|
||||
|
||||
public function offline(KbArticle $kbArticle): JsonResponse
|
||||
{
|
||||
if ($kbArticle->status !== 2) {
|
||||
return $this->error('仅已发布文章可下架');
|
||||
}
|
||||
$kbArticle->update(['status' => 3]);
|
||||
return $this->success($kbArticle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Kb;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Kb\KbCategory;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class KbCategoryController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$query = KbCategory::query()->with('children');
|
||||
$query->when($request->filled('status'), fn($q) => $q->where('status', $request->status));
|
||||
$query->where('parent_id', 0);
|
||||
|
||||
return $this->success($query->orderBy('sort')->orderBy('id')->get());
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|string|max:100',
|
||||
'parent_id' => 'nullable|integer|min:0',
|
||||
'sort' => 'nullable|integer',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
]);
|
||||
$validated['parent_id'] = $validated['parent_id'] ?? 0;
|
||||
|
||||
$category = KbCategory::create($validated);
|
||||
return $this->success($category);
|
||||
}
|
||||
|
||||
public function show(KbCategory $kbCategory): JsonResponse
|
||||
{
|
||||
return $this->success($kbCategory->load('children'));
|
||||
}
|
||||
|
||||
public function update(Request $request, KbCategory $kbCategory): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'name' => 'sometimes|string|max:100',
|
||||
'parent_id' => 'nullable|integer|min:0',
|
||||
'sort' => 'nullable|integer',
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
]);
|
||||
$kbCategory->update($validated);
|
||||
return $this->success($kbCategory);
|
||||
}
|
||||
|
||||
public function destroy(KbCategory $kbCategory): JsonResponse
|
||||
{
|
||||
if ($kbCategory->children()->exists()) {
|
||||
return $this->error('请先删除子分类');
|
||||
}
|
||||
if ($kbCategory->articles()->exists()) {
|
||||
return $this->error('该分类下还有文章,无法删除');
|
||||
}
|
||||
$kbCategory->delete();
|
||||
return $this->success(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Office;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Office\Announcement;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AnnouncementController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$query = Announcement::query()->with('author');
|
||||
$query->when($request->type, fn($q, $v) => $q->where('type', $v));
|
||||
$query->when($request->has('publish_status'), fn($q) => $q->where('publish_status', $request->publish_status));
|
||||
|
||||
return $this->paginate($query->latest()->paginate($request->input('per_page', 15)));
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'content' => 'required|string',
|
||||
'type' => 'sometimes|integer|in:1,2,3',
|
||||
'is_top' => 'sometimes|boolean',
|
||||
]);
|
||||
$validated['author_id'] = auth()->id();
|
||||
|
||||
return $this->success(Announcement::create($validated));
|
||||
}
|
||||
|
||||
public function show(Announcement $announcement): JsonResponse
|
||||
{
|
||||
return $this->success($announcement->load('author'));
|
||||
}
|
||||
|
||||
public function update(Request $request, Announcement $announcement): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'title' => 'sometimes|string|max:255',
|
||||
'content' => 'sometimes|string',
|
||||
'type' => 'sometimes|integer|in:1,2,3',
|
||||
'is_top' => 'sometimes|boolean',
|
||||
]);
|
||||
$announcement->update($validated);
|
||||
|
||||
return $this->success($announcement);
|
||||
}
|
||||
|
||||
public function destroy(Announcement $announcement): JsonResponse
|
||||
{
|
||||
$announcement->delete();
|
||||
return $this->success(null);
|
||||
}
|
||||
|
||||
public function publish(Announcement $announcement): JsonResponse
|
||||
{
|
||||
if ($announcement->publish_status === 1) {
|
||||
return $this->error('该公告已发布', 40001);
|
||||
}
|
||||
$announcement->update([
|
||||
'publish_status' => 1,
|
||||
'published_at' => now(),
|
||||
]);
|
||||
|
||||
return $this->success($announcement);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Office;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Office\Approval;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ApprovalController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$query = Approval::query()->with(['template', 'applicant']);
|
||||
$query->when($request->has('status'), fn($q) => $q->where('status', $request->status));
|
||||
$query->when($request->applicant_id, fn($q, $v) => $q->where('applicant_id', $v));
|
||||
|
||||
return $this->paginate($query->latest()->paginate($request->input('per_page', 15)));
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'template_id' => 'nullable|exists:approval_templates,id',
|
||||
'form_data' => 'nullable|array',
|
||||
'related_type' => 'nullable|string|max:50',
|
||||
'related_id' => 'nullable|integer',
|
||||
]);
|
||||
$validated['applicant_id'] = auth()->id();
|
||||
$validated['status'] = 0;
|
||||
|
||||
return $this->success(Approval::create($validated));
|
||||
}
|
||||
|
||||
public function show(Approval $approval): JsonResponse
|
||||
{
|
||||
return $this->success($approval->load(['template', 'applicant', 'nodes.approver']));
|
||||
}
|
||||
|
||||
public function update(Request $request, Approval $approval): JsonResponse
|
||||
{
|
||||
if ($approval->status > 1) {
|
||||
return $this->error('该审批已完结,无法修改', 40001);
|
||||
}
|
||||
$validated = $request->validate([
|
||||
'title' => 'sometimes|string|max:255',
|
||||
'form_data' => 'nullable|array',
|
||||
]);
|
||||
$approval->update($validated);
|
||||
|
||||
return $this->success($approval);
|
||||
}
|
||||
|
||||
public function destroy(Approval $approval): JsonResponse
|
||||
{
|
||||
if ($approval->status > 1) {
|
||||
return $this->error('该审批已完结,无法删除', 40001);
|
||||
}
|
||||
$approval->delete();
|
||||
|
||||
return $this->success(null);
|
||||
}
|
||||
|
||||
public function approve(Approval $approval): JsonResponse
|
||||
{
|
||||
$node = $approval->nodes()
|
||||
->where('approver_id', auth()->id())
|
||||
->where('action', 0)
|
||||
->where('node_order', $approval->current_node)
|
||||
->first();
|
||||
|
||||
if (!$node) {
|
||||
return $this->error('无待处理的审批节点', 40001);
|
||||
}
|
||||
|
||||
$node->update(['action' => 1, 'acted_at' => now()]);
|
||||
|
||||
$pendingNodes = $approval->nodes()->where('action', 0)->exists();
|
||||
if (!$pendingNodes) {
|
||||
$approval->update(['status' => 2]);
|
||||
} else {
|
||||
$approval->update([
|
||||
'status' => 1,
|
||||
'current_node' => $approval->current_node + 1,
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->success($approval->load('nodes'));
|
||||
}
|
||||
|
||||
public function reject(Request $request, Approval $approval): JsonResponse
|
||||
{
|
||||
$node = $approval->nodes()
|
||||
->where('approver_id', auth()->id())
|
||||
->where('action', 0)
|
||||
->where('node_order', $approval->current_node)
|
||||
->first();
|
||||
|
||||
if (!$node) {
|
||||
return $this->error('无待处理的审批节点', 40001);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'comment' => 'nullable|string|max:255',
|
||||
]);
|
||||
|
||||
$node->update([
|
||||
'action' => 2,
|
||||
'comment' => $validated['comment'] ?? null,
|
||||
'acted_at' => now(),
|
||||
]);
|
||||
$approval->update(['status' => 3]);
|
||||
|
||||
return $this->success($approval->load('nodes'));
|
||||
}
|
||||
|
||||
public function withdraw(Approval $approval): JsonResponse
|
||||
{
|
||||
if ($approval->status > 1) {
|
||||
return $this->error('该审批已完结,无法撤回', 40001);
|
||||
}
|
||||
$approval->update(['status' => 4]);
|
||||
|
||||
return $this->success($approval);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Office;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Office\ApprovalTemplate;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ApprovalTemplateController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$query = ApprovalTemplate::query();
|
||||
$query->when($request->type, fn($q, $v) => $q->where('type', $v));
|
||||
$query->when($request->has('status'), fn($q) => $q->where('status', $request->status));
|
||||
|
||||
return $this->paginate($query->orderBy('sort')->latest()->paginate($request->input('per_page', 15)));
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|string|max:100',
|
||||
'type' => 'required|integer|in:1,2,3,4,5',
|
||||
'form_fields' => 'nullable|array',
|
||||
'flow_nodes' => 'nullable|array',
|
||||
'status' => 'sometimes|integer|in:0,1',
|
||||
'sort' => 'sometimes|integer',
|
||||
]);
|
||||
|
||||
return $this->success(ApprovalTemplate::create($validated));
|
||||
}
|
||||
|
||||
public function show(ApprovalTemplate $approvalTemplate): JsonResponse
|
||||
{
|
||||
return $this->success($approvalTemplate);
|
||||
}
|
||||
|
||||
public function update(Request $request, ApprovalTemplate $approvalTemplate): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'name' => 'sometimes|string|max:100',
|
||||
'type' => 'sometimes|integer|in:1,2,3,4,5',
|
||||
'form_fields' => 'nullable|array',
|
||||
'flow_nodes' => 'nullable|array',
|
||||
'status' => 'sometimes|integer|in:0,1',
|
||||
'sort' => 'sometimes|integer',
|
||||
]);
|
||||
$approvalTemplate->update($validated);
|
||||
|
||||
return $this->success($approvalTemplate);
|
||||
}
|
||||
|
||||
public function destroy(ApprovalTemplate $approvalTemplate): JsonResponse
|
||||
{
|
||||
$approvalTemplate->delete();
|
||||
return $this->success(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Office;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Office\Handover;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HandoverController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$query = Handover::query()->with(['handoverUser', 'receiverUser']);
|
||||
$query->when($request->shift_date, fn($q, $v) => $q->where('shift_date', $v));
|
||||
$query->when($request->shift_type, fn($q, $v) => $q->where('shift_type', $v));
|
||||
|
||||
return $this->paginate($query->latest('created_at')->paginate($request->input('per_page', 15)));
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'shift_date' => 'required|date',
|
||||
'shift_type' => 'required|integer|in:1,2,3,4',
|
||||
'content' => 'required|string',
|
||||
'issues' => 'nullable|string',
|
||||
]);
|
||||
$validated['handover_user_id'] = auth()->id();
|
||||
|
||||
return $this->success(Handover::create($validated));
|
||||
}
|
||||
|
||||
public function show(Handover $handover): JsonResponse
|
||||
{
|
||||
return $this->success($handover->load(['handoverUser', 'receiverUser']));
|
||||
}
|
||||
|
||||
public function confirm(Handover $handover): JsonResponse
|
||||
{
|
||||
if ($handover->status === 1) {
|
||||
return $this->error('该交接班已确认', 40001);
|
||||
}
|
||||
$handover->update([
|
||||
'receiver_user_id' => auth()->id(),
|
||||
'status' => 1,
|
||||
'confirmed_at' => now(),
|
||||
]);
|
||||
|
||||
return $this->success($handover);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Office;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Office\Notification;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class NotificationController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$query = Notification::query()->where('user_id', auth()->id());
|
||||
$query->when($request->type, fn($q, $v) => $q->where('type', $v));
|
||||
$query->when($request->has('is_read'), fn($q) => $q->where('is_read', $request->boolean('is_read')));
|
||||
|
||||
return $this->paginate($query->latest('created_at')->paginate($request->input('per_page', 15)));
|
||||
}
|
||||
|
||||
public function markRead(Notification $notification): JsonResponse
|
||||
{
|
||||
if ($notification->user_id !== auth()->id()) {
|
||||
return $this->error('无权操作', 40003, 403);
|
||||
}
|
||||
$notification->update(['is_read' => true, 'read_at' => now()]);
|
||||
|
||||
return $this->success($notification);
|
||||
}
|
||||
|
||||
public function markAllRead(): JsonResponse
|
||||
{
|
||||
Notification::query()
|
||||
->where('user_id', auth()->id())
|
||||
->where('is_read', false)
|
||||
->update(['is_read' => true, 'read_at' => now()]);
|
||||
|
||||
return $this->success(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Report;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Crm\Contract;
|
||||
use App\Models\Crm\Customer;
|
||||
use App\Models\Crm\Lead;
|
||||
use App\Models\Finance\FinanceRecord;
|
||||
use App\Models\Room\Room;
|
||||
use App\Models\Room\RoomType;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ReportController extends Controller
|
||||
{
|
||||
public function overview(Request $request): JsonResponse
|
||||
{
|
||||
$data = [
|
||||
'customer_count' => Customer::count(),
|
||||
'contract_amount' => Contract::where('status', 2)->sum('actual_amount'),
|
||||
'room_count' => Room::count(),
|
||||
'occupied_count' => Room::where('status', 3)->count(),
|
||||
'today_revenue' => FinanceRecord::where('type', 1)->where('audit_status', 1)
|
||||
->whereDate('record_date', today())->sum('amount'),
|
||||
'month_revenue' => FinanceRecord::where('type', 1)->where('audit_status', 1)
|
||||
->whereMonth('record_date', now()->month)
|
||||
->whereYear('record_date', now()->year)->sum('amount'),
|
||||
];
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
public function revenue(Request $request): JsonResponse
|
||||
{
|
||||
$year = $request->input('year', now()->year);
|
||||
$records = FinanceRecord::where('audit_status', 1)
|
||||
->whereYear('record_date', $year)
|
||||
->selectRaw('MONTH(record_date) as month, type, SUM(amount) as total')
|
||||
->groupBy('month', 'type')
|
||||
->get();
|
||||
return $this->success($records);
|
||||
}
|
||||
|
||||
public function occupancy(Request $request): JsonResponse
|
||||
{
|
||||
$data = RoomType::withCount([
|
||||
'rooms',
|
||||
'rooms as occupied_count' => fn($q) => $q->where('status', 3),
|
||||
])->get();
|
||||
return $this->success($data);
|
||||
}
|
||||
|
||||
public function crmConversion(Request $request): JsonResponse
|
||||
{
|
||||
$data = [
|
||||
'total_leads' => Lead::count(),
|
||||
'following' => Lead::where('status', 2)->count(),
|
||||
'contracted' => Lead::where('status', 5)->count(),
|
||||
'by_channel' => Lead::selectRaw('channel_id, COUNT(*) as total, SUM(CASE WHEN status=5 THEN 1 ELSE 0 END) as converted')
|
||||
->groupBy('channel_id')
|
||||
->with('channel:id,name')
|
||||
->get(),
|
||||
];
|
||||
return $this->success($data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin\Report;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Report\ReportExport;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ReportExportController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$query = ReportExport::query()->with('operator');
|
||||
$query->when($request->type, fn($q, $v) => $q->where('type', $v));
|
||||
$query->when($request->filled('status'), fn($q) => $q->where('status', $request->status));
|
||||
|
||||
return $this->paginate($query->latest()->paginate($request->input('per_page', 15)));
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|string|max:255',
|
||||
'type' => 'required|string|max:50',
|
||||
'params' => 'nullable|array',
|
||||
]);
|
||||
$validated['operator_id'] = auth()->id();
|
||||
$validated['status'] = 0;
|
||||
|
||||
$export = ReportExport::create($validated);
|
||||
return $this->success($export);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Kb;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Traits\BelongsToStore;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class KbArticle extends Model
|
||||
{
|
||||
use BelongsToStore;
|
||||
|
||||
protected $fillable = [
|
||||
'store_id', 'category_id', 'title', 'content', 'author_id',
|
||||
'status', 'visibility', 'cover_image', 'attachments',
|
||||
'views', 'likes', 'favorites', 'published_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'status' => 'integer',
|
||||
'visibility' => 'integer',
|
||||
'views' => 'integer',
|
||||
'likes' => 'integer',
|
||||
'favorites' => 'integer',
|
||||
'attachments' => 'array',
|
||||
'published_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function category(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(KbCategory::class, 'category_id');
|
||||
}
|
||||
|
||||
public function author(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'author_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Kb;
|
||||
|
||||
use App\Traits\BelongsToStore;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class KbCategory extends Model
|
||||
{
|
||||
use BelongsToStore;
|
||||
|
||||
protected $fillable = [
|
||||
'store_id', 'parent_id', 'name', 'sort', 'status',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'sort' => 'integer',
|
||||
'status' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function children(): HasMany
|
||||
{
|
||||
return $this->hasMany(self::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function parent(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(self::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function articles(): HasMany
|
||||
{
|
||||
return $this->hasMany(KbArticle::class, 'category_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Office;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Traits\BelongsToStore;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Announcement extends Model
|
||||
{
|
||||
use BelongsToStore;
|
||||
|
||||
protected $fillable = [
|
||||
'store_id', 'title', 'content', 'type', 'is_top',
|
||||
'publish_status', 'published_at', 'author_id',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'type' => 'integer',
|
||||
'publish_status' => 'integer',
|
||||
'is_top' => 'boolean',
|
||||
'published_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function author(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'author_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Office;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Traits\BelongsToStore;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class Approval extends Model
|
||||
{
|
||||
use BelongsToStore;
|
||||
|
||||
protected $fillable = [
|
||||
'store_id', 'template_id', 'title', 'applicant_id', 'form_data',
|
||||
'status', 'current_node', 'related_type', 'related_id',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'status' => 'integer',
|
||||
'current_node' => 'integer',
|
||||
'form_data' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
public function template(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ApprovalTemplate::class, 'template_id');
|
||||
}
|
||||
|
||||
public function applicant(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'applicant_id');
|
||||
}
|
||||
|
||||
public function nodes(): HasMany
|
||||
{
|
||||
return $this->hasMany(ApprovalNode::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Office;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class ApprovalNode extends Model
|
||||
{
|
||||
const UPDATED_AT = null;
|
||||
|
||||
protected $fillable = [
|
||||
'approval_id', 'node_order', 'approver_id', 'action', 'comment', 'acted_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'node_order' => 'integer',
|
||||
'action' => 'integer',
|
||||
'acted_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function approval(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Approval::class);
|
||||
}
|
||||
|
||||
public function approver(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'approver_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Office;
|
||||
|
||||
use App\Traits\BelongsToStore;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ApprovalTemplate extends Model
|
||||
{
|
||||
use BelongsToStore;
|
||||
|
||||
protected $fillable = [
|
||||
'store_id', 'name', 'type', 'form_fields', 'flow_nodes', 'status', 'sort',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'type' => 'integer',
|
||||
'status' => 'integer',
|
||||
'sort' => 'integer',
|
||||
'form_fields' => 'array',
|
||||
'flow_nodes' => 'array',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Office;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Traits\BelongsToStore;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Handover extends Model
|
||||
{
|
||||
use BelongsToStore;
|
||||
|
||||
const UPDATED_AT = null;
|
||||
|
||||
protected $fillable = [
|
||||
'store_id', 'shift_date', 'shift_type', 'handover_user_id',
|
||||
'receiver_user_id', 'content', 'issues', 'status', 'confirmed_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'shift_type' => 'integer',
|
||||
'status' => 'integer',
|
||||
'shift_date' => 'date',
|
||||
'confirmed_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function handoverUser(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'handover_user_id');
|
||||
}
|
||||
|
||||
public function receiverUser(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'receiver_user_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Office;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Traits\BelongsToStore;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Notification extends Model
|
||||
{
|
||||
use BelongsToStore;
|
||||
|
||||
const UPDATED_AT = null;
|
||||
|
||||
protected $table = 'notifications';
|
||||
|
||||
protected $fillable = [
|
||||
'store_id', 'user_id', 'title', 'content', 'type',
|
||||
'related_type', 'related_id', 'is_read', 'read_at',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'type' => 'integer',
|
||||
'is_read' => 'boolean',
|
||||
'read_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Report;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Traits\BelongsToStore;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class ReportExport extends Model
|
||||
{
|
||||
use BelongsToStore;
|
||||
|
||||
const UPDATED_AT = null;
|
||||
|
||||
protected $fillable = [
|
||||
'store_id', 'name', 'type', 'params', 'file_path', 'status', 'operator_id',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'params' => 'array',
|
||||
'status' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
public function operator(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'operator_id');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user