// +---------------------------------------------------------------------- namespace Modules\Account\Services; use Illuminate\Http\Request; use Modules\Account\Models\Bill; class AdminBillService { /** * @title 获取账单列表 * * @param Request $request * @return void */ public function getDataList($request) { $map = []; // 用户筛选 if ($request->filled('user_id')) { $map[] = ['user_id', '=', $request->input('user_id')]; } // 家庭筛选 if ($request->filled('family_id')) { $map[] = ['family_id', '=', $request->input('family_id')]; } // 类型筛选 if ($request->filled('type') && in_array($request->input('type'), ['income', 'expense'])) { $map[] = ['type', '=', $request->input('type')]; } // 分类筛选 if ($request->filled('category')) { $map[] = ['category', 'like', '%' . $request->input('category') . '%']; } // 支付方式筛选 if ($request->filled('payment_method')) { $map[] = ['payment_method', '=', $request->input('payment_method')]; } // 备注搜索 if ($request->filled('remark')) { $map[] = ['remark', 'like', '%' . $request->input('remark') . '%']; } // 日期范围筛选 if ($request->filled('start_date')) { $map[] = ['bill_date', '>=', $request->input('start_date')]; } if ($request->filled('end_date')) { $map[] = ['bill_date', '<=', $request->input('end_date')]; } // 年月筛选 if ($request->filled('year') && $request->filled('month')) { $startDate = $request->input('year') . '-' . str_pad($request->input('month'), 2, '0', STR_PAD_LEFT) . '-01'; $endDate = $request->input('year') . '-' . str_pad($request->input('month'), 2, '0', STR_PAD_LEFT) . '-31'; // 清除之前的日期条件 $map = array_filter($map, function($item) { return !isset($item[0]) || !in_array($item[0], ['bill_date']); }); $map[] = ['bill_date', '>=', $startDate]; $map[] = ['bill_date', '<=', $endDate]; } $query = Bill::with(['user:uid,nickname,username', 'family:id,name']); $query->where($map); // 排序 $query->orderBy($request->input('order', 'bill_date'), $request->input('sort', 'desc')); // 分页 if ($request->filled('page')) { $data = [ 'total' => $query->count(), 'page' => $request->input('page', 1), 'data' => $query->offset($request->input('offset', 0)) ->limit($request->input('limit', 10)) ->get(), ]; } else { $data = $query->get(); } // 计算统计数据 if ($request->filled('page')) { $statsQuery = Bill::query()->where($map); $totalExpense = (clone $statsQuery)->where('type', 'expense')->sum('amount'); $totalIncome = (clone $statsQuery)->where('type', 'income')->sum('amount'); $data['statistics'] = [ 'total_expense' => (float)$totalExpense, 'total_income' => (float)$totalIncome, 'total_balance' => (float)($totalIncome - $totalExpense), 'total_count' => $data['total'] ]; } return $data; } /** * @title 添加账单 * * @param Request $request * @return void */ public function create($request) { $request->validate([ 'user_id' => 'required|integer', 'type' => 'required|in:income,expense', 'amount' => 'required|numeric|min:0.01', 'category_id' => 'required|integer', 'payment_method' => 'nullable|string|in:微信,支付宝,银行卡,现金,其他', 'remark' => 'nullable|string|max:255', 'date' => 'required|date', 'family_id' => 'nullable|integer|exists:account_families,id' ], [ 'user_id.required' => '请选择用户', 'type.required' => '请选择账单类型', 'amount.required' => '请输入金额', 'category_id.required' => '请选择分类', 'date.required' => '请选择日期' ]); $data = $request->all(); // 将category_id转换为category字符串 $categoryMap = $this->getCategoryMap($data['type']); if (!isset($categoryMap[$data['category_id']])) { throw new \Exception('分类不存在'); } $data['category'] = $categoryMap[$data['category_id']]; $data['bill_date'] = $data['date']; // 移除前端字段 unset($data['category_id'], $data['date']); return Bill::create($data); } /** * @title 更新账单 * * @param Request $request * @return void */ public function update($request) { $request->validate([ 'id' => 'required|integer', 'user_id' => 'required|integer', 'type' => 'required|in:income,expense', 'amount' => 'required|numeric|min:0.01', 'category_id' => 'required|integer', 'payment_method' => 'nullable|string|in:微信,支付宝,银行卡,现金,其他', 'remark' => 'nullable|string|max:255', 'date' => 'required|date', 'family_id' => 'nullable|integer|exists:account_families,id' ], [ 'id.required' => '请提供账单ID', 'user_id.required' => '请选择用户', 'type.required' => '请选择账单类型', 'amount.required' => '请输入金额', 'category_id.required' => '请选择分类', 'date.required' => '请选择日期' ]); $bill = Bill::findOrFail($request->input('id')); $data = $request->all(); // 将category_id转换为category字符串 $categoryMap = $this->getCategoryMap($data['type']); if (!isset($categoryMap[$data['category_id']])) { throw new \Exception('分类不存在'); } $data['category'] = $categoryMap[$data['category_id']]; $data['bill_date'] = $data['date']; // 移除前端字段 unset($data['category_id'], $data['date'], $data['id']); $bill->update($data); return $bill; } /** * @title 删除账单 * * @param Request $request * @return void */ public function delete($request) { if ($request->filled('id')) { try { $bill = Bill::findOrFail($request->input('id')); $bill->delete(); } catch (\Throwable $th) { throw new \Exception("账单不存在!", 1); } } if ($request->filled('ids')) { try { $bill = Bill::whereIn('id', $request->input('ids')); $bill->delete(); } catch (\Throwable $th) { throw new \Exception($th->getMessage(), 1); } } return $bill; } /** * @title 账单详情 * * @param Request $request * @return void */ public function detail($request) { $id = $request->input('id'); $bill = Bill::with(['user:uid,nickname,username', 'family:id,name,owner_id']) ->findOrFail($id); return $bill; } /** * @title 获取分类映射 * * @param string $type * @return array */ private function getCategoryMap($type) { if ($type === 'income') { return [ 101 => '工资', 102 => '奖金', 103 => '投资', 104 => '兼职', 105 => '其他' ]; } else { return [ 1 => '餐饮', 2 => '交通', 3 => '购物', 4 => '娱乐', 5 => '医疗', 6 => '教育', 7 => '居住', 8 => '其他' ]; } } /** * @title 获取分类列表 * * @return array */ public function getCategoryList() { return [ 'expense' => [ ['id' => 1, 'name' => '餐饮'], ['id' => 2, 'name' => '交通'], ['id' => 3, 'name' => '购物'], ['id' => 4, 'name' => '娱乐'], ['id' => 5, 'name' => '医疗'], ['id' => 6, 'name' => '教育'], ['id' => 7, 'name' => '居住'], ['id' => 8, 'name' => '其他'] ], 'income' => [ ['id' => 101, 'name' => '工资'], ['id' => 102, 'name' => '奖金'], ['id' => 103, 'name' => '投资'], ['id' => 104, 'name' => '兼职'], ['id' => 105, 'name' => '其他'] ] ]; } /** * @title 获取支付方式列表 * * @return array */ public function getPaymentMethods() { return [ ['value' => '微信', 'label' => '微信'], ['value' => '支付宝', 'label' => '支付宝'], ['value' => '银行卡', 'label' => '银行卡'], ['value' => '现金', 'label' => '现金'], ['value' => '其他', 'label' => '其他'] ]; } }