312 lines
8.0 KiB
PHP
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' => '其他']
|
|
];
|
|
}
|
|
}
|