package com.ruoyi.account.service.impl; 
 | 
  
 | 
  
 | 
import com.baomidou.mybatisplus.core.metadata.IPage; 
 | 
import com.baomidou.mybatisplus.core.toolkit.Wrappers; 
 | 
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 
 | 
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 
 | 
import com.ruoyi.account.dto.AccountDto; 
 | 
import com.ruoyi.account.dto.AccountDto2; 
 | 
import com.ruoyi.account.dto.AccountDto3; 
 | 
import com.ruoyi.account.mapper.AccountExpenseMapper; 
 | 
import com.ruoyi.account.mapper.AccountIncomeMapper; 
 | 
import com.ruoyi.account.pojo.AccountExpense; 
 | 
import com.ruoyi.account.pojo.AccountIncome; 
 | 
import com.ruoyi.account.service.AccountExpenseService; 
 | 
import com.ruoyi.common.utils.poi.ExcelUtil; 
 | 
import com.ruoyi.dto.DateQueryDto; 
 | 
import com.ruoyi.project.system.domain.SysDictData; 
 | 
import com.ruoyi.project.system.mapper.SysDictDataMapper; 
 | 
import lombok.AllArgsConstructor; 
 | 
import org.springframework.stereotype.Service; 
 | 
  
 | 
import javax.servlet.http.HttpServletResponse; 
 | 
import java.math.BigDecimal; 
 | 
import java.time.DayOfWeek; 
 | 
import java.time.LocalDate; 
 | 
import java.time.format.DateTimeFormatter; 
 | 
import java.util.ArrayList; 
 | 
import java.util.HashMap; 
 | 
import java.util.List; 
 | 
import java.util.Map; 
 | 
  
 | 
@AllArgsConstructor 
 | 
@Service 
 | 
public class AccountExpenseServiceImpl extends ServiceImpl<AccountExpenseMapper, AccountExpense> implements AccountExpenseService { 
 | 
  
 | 
    private AccountExpenseMapper accountExpenseMapper; 
 | 
  
 | 
    private AccountIncomeMapper accountIncomeMapper; 
 | 
  
 | 
    private SysDictDataMapper sysDictDataMapper; 
 | 
  
 | 
  
 | 
    //分页查询 
 | 
    @Override 
 | 
    public IPage<AccountExpense> accountExpenseListPage(Page page, AccountExpense accountExpense) { 
 | 
        return accountExpenseMapper.accountExpenseListPage(page,accountExpense); 
 | 
    } 
 | 
  
 | 
    //导出 
 | 
    @Override 
 | 
    public void accountExpenseExport(HttpServletResponse response, AccountExpense accountExpense) { 
 | 
        List<AccountExpense> accountExpenses =accountExpenseMapper.accountExpenseExport(accountExpense); 
 | 
        ExcelUtil<AccountExpense> util = new ExcelUtil<AccountExpense>(AccountExpense.class); 
 | 
        util.exportExcel(response, accountExpenses, "支出管理导出"); 
 | 
    } 
 | 
  
 | 
    //财务报表图表 
 | 
    @Override 
 | 
    public AccountDto report(DateQueryDto dateQueryDto) { 
 | 
        AccountDto accountDto = new AccountDto(); 
 | 
        //获取该段时间内的所有收入 
 | 
        List<AccountDto2> accountIncomes =accountIncomeMapper.report(dateQueryDto); 
 | 
  
 | 
        Long incomeNumber = accountIncomeMapper.selectCount(Wrappers.<AccountIncome>lambdaQuery() 
 | 
                .between(AccountIncome::getIncomeDate, dateQueryDto.getEntryDateStart(), dateQueryDto.getEntryDateEnd())); 
 | 
        accountDto.setIncomeNumber(incomeNumber); 
 | 
        BigDecimal totalIncome = accountIncomes.stream().map(AccountDto2::getAccount).reduce(BigDecimal.ZERO, BigDecimal::add); 
 | 
        accountDto.setTotalIncome(totalIncome); 
 | 
        accountIncomes.stream().forEach(accountDto2 -> { 
 | 
            accountDto2.setProportion(accountDto2.getAccount().divide(totalIncome,2,BigDecimal.ROUND_HALF_UP)); 
 | 
        }); 
 | 
        accountDto.setIncomeType(accountIncomes); 
 | 
        //获取该段时间内的所有支出 
 | 
        List<AccountDto2> accountExpenses =accountExpenseMapper.report(dateQueryDto); 
 | 
        accountDto.setExpenseType(accountExpenses); 
 | 
        Long expenseNumber = accountExpenseMapper.selectCount(Wrappers.<AccountExpense>lambdaQuery() 
 | 
                .between(AccountExpense::getExpenseDate, dateQueryDto.getEntryDateStart(), dateQueryDto.getEntryDateEnd())); 
 | 
        accountDto.setExpenseNumber(expenseNumber); 
 | 
        BigDecimal totalExpense = accountExpenses.stream().map(AccountDto2::getAccount).reduce(BigDecimal.ZERO, BigDecimal::add); 
 | 
        accountDto.setTotalExpense(totalExpense); 
 | 
        accountExpenses.stream().forEach(accountDto2 -> { 
 | 
            accountDto2.setProportion(accountDto2.getAccount().divide(totalExpense,2,BigDecimal.ROUND_HALF_UP)); 
 | 
        }); 
 | 
        accountDto.setExpenseType(accountExpenses); 
 | 
        //净收入 
 | 
        BigDecimal netRevenue = totalIncome.subtract(totalExpense); 
 | 
        accountDto.setNetRevenue(netRevenue); 
 | 
        return accountDto; 
 | 
    } 
 | 
  
 | 
    //财务报表年查询 
 | 
    @Override 
 | 
    public  List<AccountDto3> reportExpense() { 
 | 
        List<AccountDto3> accountDto3s = new ArrayList<>(); 
 | 
        //先查询收入类型有哪些 
 | 
        List<SysDictData> incomeTypes = sysDictDataMapper.selectDictDataByType("expense_types"); 
 | 
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); 
 | 
        int currentYear = LocalDate.now().getYear(); // 获取当前年份(如2025) 
 | 
        for (SysDictData incomeType : incomeTypes) { 
 | 
            AccountDto3 accountDto3 = new AccountDto3(); 
 | 
            accountDto3.setTypeName(incomeType.getDictLabel());//类型 
 | 
            List<BigDecimal> account=new ArrayList<>(); 
 | 
            for (int i = 1; i <= 12; i++) { 
 | 
                // 当月第一天:年份为当前年,月份为i,日期为1 
 | 
                LocalDate firstDay = LocalDate.of(currentYear, i, 1); 
 | 
                DateQueryDto dateQueryDto = new DateQueryDto(); 
 | 
                dateQueryDto.setEntryDateStart(firstDay.format(formatter)); 
 | 
                // 当月最后一天:第一天的月份的最后一天 
 | 
                dateQueryDto.setEntryDateEnd(firstDay.plusMonths(1).minusDays(1).format(formatter)); 
 | 
                account.add(accountExpenseMapper.report1(dateQueryDto,incomeType.getDictValue())); 
 | 
            } 
 | 
            accountDto3.setAccount(account);//类型 
 | 
            accountDto3s.add(accountDto3); 
 | 
        } 
 | 
        return accountDto3s; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public Map<String, List<String>> analysis() { 
 | 
        // 获取本周的时间范围 
 | 
        LocalDate startOfWeek = LocalDate.now().with(DayOfWeek.MONDAY); 
 | 
        LocalDate endOfWeek = LocalDate.now().with(DayOfWeek.SUNDAY); 
 | 
        Map<String, List<String>> result = new HashMap<>(); 
 | 
        List<String> days = new ArrayList<>(); 
 | 
        List<String> totalIncomeList = new ArrayList<>(); 
 | 
        List<String> totalExpenseList = new ArrayList<>(); 
 | 
        List<String> netIncomeList = new ArrayList<>(); 
 | 
        // 根据时间范围循环查询每一天的总收入,总支出,净收入(总收入-总支出) 
 | 
        for (LocalDate date = startOfWeek; date.isBefore(endOfWeek) || date.isEqual(endOfWeek); date = date.plusDays(1)) { 
 | 
            BigDecimal totalIncome = accountIncomeMapper.selectList(Wrappers.<AccountIncome>lambdaQuery() 
 | 
                    .eq(AccountIncome::getInputTime, date.toString())) 
 | 
                    .stream() 
 | 
                    .map(AccountIncome::getIncomeMoney) 
 | 
                    .reduce(BigDecimal.ZERO, BigDecimal::add); 
 | 
            BigDecimal totalExpense = accountExpenseMapper.selectList(Wrappers.<AccountExpense>lambdaQuery() 
 | 
                    .eq(AccountExpense::getInputTime, date.toString())) 
 | 
                    .stream() 
 | 
                    .map(AccountExpense::getExpenseMoney) 
 | 
                    .reduce(BigDecimal.ZERO, BigDecimal::add); 
 | 
            BigDecimal netIncome = totalIncome.subtract(totalExpense); 
 | 
            days.add(date.toString()); 
 | 
            totalIncomeList.add(totalIncome.toString()); 
 | 
            totalExpenseList.add(totalExpense.toString()); 
 | 
            netIncomeList.add(netIncome.toString()); 
 | 
        } 
 | 
        result.put("days", days);  //  天 
 | 
        result.put("totalIncome", totalIncomeList); // 收入 
 | 
        result.put("totalExpense", totalExpenseList); // 支出 
 | 
        result.put("netIncome", netIncomeList); // 净收入 
 | 
  
 | 
        return result; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public AccountExpense getByInvoiceNumber(String purchaseContractNumber) { 
 | 
        return accountExpenseMapper.selectOne(Wrappers.<AccountExpense>lambdaQuery() 
 | 
                .eq(AccountExpense::getInvoiceNumber, purchaseContractNumber)); 
 | 
    } 
 | 
  
 | 
  
 | 
} 
 |