Files
account/modules/Account/app/Services/AdminBillService.php
2026-01-19 14:52:08 +08:00

312 lines
8.0 KiB
PHP

<?php
// +----------------------------------------------------------------------
// | SentCMS [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2024 http://www.tensent.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: molong <molong@tensent.cn> <http://www.tensent.cn>
// +----------------------------------------------------------------------
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' => '其他']
];
}
}