| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823 |
- <?php
- namespace app\api\controller;
- use app\common\controller\Api;
- use think\Db;
- use think\Queue;
- use app\service\UnifiedCostCalculationService;
- use think\Request;
- class CostCalculation extends Api
- {
- protected $noNeedLogin = ['*'];
- protected $noNeedRight = ['*'];
- // // 楼层编组映射(优化版)
- // const FLOOR_GROUP_MAP = [
- // '1' => ['02、胶印机组', '03、卷凹机组', '06、单凹机组', '05、圆切机组', '04、圆烫机组', '10、模切机组', '09、烫金机组'], // 1楼编组
- // '2' => ['01、切纸机组', '11、检品机组', '07、丝印机组', '12、覆膜机组', '08、喷码机组'], // 2楼编组
- // ];
- //
- // // 科目名称常量(简化版)
- // const SUBJECT_WASTE_GAS = '废气处理(RTO)';
- // const SUBJECT_BOILER = '锅炉';
- // const SUBJECT_AIR_COMPRESSOR = '空压机';
- // const SUBJECT_HOT_WATER_BOILER = '热水锅炉';
- // const SUBJECT_VACUUM_BLOWER = '真空鼓风机';
- // const SUBJECT_CENTRAL_AIR_CONDITIONER = '中央空调';
- // const SUBJECT_TOTAL_TO_APPORTION = '待分摊总额';
- //
- // // 需要分配到卷凹机组的科目列表
- // const ROLL_COATER_ONLY_SUBJECTS = [
- // self::SUBJECT_BOILER,
- // self::SUBJECT_HOT_WATER_BOILER,
- // ];
- //
- // // 简化科目列表
- // const SIMPLIFIED_SUBJECTS = [
- // self::SUBJECT_WASTE_GAS,
- // self::SUBJECT_BOILER,
- // self::SUBJECT_AIR_COMPRESSOR,
- // self::SUBJECT_HOT_WATER_BOILER,
- // self::SUBJECT_VACUUM_BLOWER,
- // self::SUBJECT_CENTRAL_AIR_CONDITIONER,
- // self::SUBJECT_TOTAL_TO_APPORTION,
- // ];
- //
- // /**
- // * 根据设备编号获取楼层信息
- // */
- // protected function getFloorByMachineCode($machineCode)
- // {
- // static $machineFloorCache = [];
- //
- // if (isset($machineFloorCache[$machineCode])) {
- // return $machineFloorCache[$machineCode];
- // }
- //
- // // 查询设备编组
- // $group = Db::name('设备_基本资料')
- // ->where('sys_sbID', '<>','')
- // ->where('设备编号', $machineCode)
- // ->value('设备编组');
- //
- // if (!$group) {
- // $machineFloorCache[$machineCode] = null;
- // return null;
- // }
- //
- // // 根据编组判断楼层
- // foreach (self::FLOOR_GROUP_MAP as $floor => $groups) {
- // foreach ($groups as $groupName) {
- // if (strpos($group, $groupName) !== false) {
- // $machineFloorCache[$machineCode] = $floor;
- // return $floor;
- // }
- // }
- // }
- //
- // $machineFloorCache[$machineCode] = null;
- // return null;
- // }
- //
- // /**
- // * 根据楼层获取该楼层的所有机台
- // */
- // protected function getMachinesByFloor($floor, $month)
- // {
- // // 获取该楼层的所有编组
- // $groups = self::FLOOR_GROUP_MAP[$floor] ?? [];
- // if (empty($groups)) {
- // return [];
- // }
- //
- // try {
- // // 方法1:使用更简单的查询条件构建方式
- // $query = Db::name('成本v23_月度成本明细')
- // ->alias('c')
- // ->join('设备_基本资料 e', 'c.sczl_jtbh = e.设备编号', 'LEFT')
- // ->where('c.sys_ny', $month)
- // ->where('e.设备编号', '<>', '')
- // ->whereIn('e.设备编组', $groups);
- //
- //
- // $query->field([
- // 'c.sczl_jtbh' => '机台编号',
- // 'c.占用机时',
- // 'e.设备编组',
- // 'c.sczl_gdbh' => '工单编号',
- // 'c.sczl_yjno' => '印件号',
- // 'c.sczl_gxh' => '工序号',
- // 'c.Uniqid',
- // 'c.车间名称'
- // ]);
- //
- // $machines = $query->select();
- //
- // return $machines ?: [];
- //
- // } catch (\Exception $e) {
- // throw new \Exception('查询机台数据失败: ' . $e->getMessage());
- //
- // }
- // }
- //
- // /**
- // * 获取所有机台(不分楼层)
- // */
- // protected function getAllMachines($month)
- // {
- // return Db::name('成本v23_月度成本明细')
- // ->alias('c')
- // ->join('设备_基本资料 e', 'c.sczl_jtbh = e.设备编号')
- // ->where('c.sys_ny', $month)
- // ->where('e.设备编号', '<>', '')
- // ->field([
- // 'c.sczl_jtbh' => '机台编号',
- // 'c.占用机时',
- // 'e.设备编组',
- // 'c.sczl_gdbh' => '工单编号',
- // 'c.sczl_yjno' => '印件号',
- // 'c.sczl_gxh' => '工序号',
- // 'c.Uniqid',
- // 'c.车间名称'
- // ])
- // ->select();
- // }
- //
- // /**
- // * 获取卷凹机组的所有机台
- // */
- // protected function getRollCoaterMachines($month)
- // {
- // return Db::name('成本v23_月度成本明细')
- // ->alias('c')
- // ->join('设备_基本资料 e', 'c.sczl_jtbh = e.设备编号')
- // ->where('c.sys_ny', $month)
- // ->where('e.设备编号', '<>', '')
- // ->where('e.设备编组', 'like', '%03、卷凹机组%')
- // ->field([
- // 'c.sczl_jtbh' => '机台编号',
- // 'c.占用机时',
- // 'e.设备编组',
- // 'c.sczl_gdbh' => '工单编号',
- // 'c.sczl_yjno' => '印件号',
- // 'c.sczl_gxh' => '工序号',
- // 'c.Uniqid',
- // 'c.车间名称'
- // ])
- // ->select();
- // }
- //
- // /**
- // * 主计算方法
- // */
- // public function costCalculation()
- // {
- // if (!$this->request->isGet()) {
- // $this->error('请求错误');
- // }
- //
- // $param = $this->request->param();
- // if (empty($param['month'])) {
- // $this->error('请选择月份');
- // }
- //
- // $month = $param['month'];
- // $sysId = $param['sys_id'] ?? '';
- //
- //
- // // 计算分摊
- // $apportionmentResults = $this->calculateApportionment($month);
- //
- // // 格式化结果并保存
- // $formattedResults = $this->formatApportionmentResults($apportionmentResults, $month, $sysId);
- // $this->saveApportionmentCoefficients($formattedResults, $month);
- //
- // // 进行二次分配(到工单)
- // $this->allocateToWorkOrders($month);
- //
- // $this->success('成本分摊计算成功');
- // }
- //
- // /**
- // * 计算分摊(核心方法)
- // */
- // protected function calculateApportionment($month)
- // {
- // // 获取水电气分摊数据
- // $utilityData = $this->getUtilityData($month);
- //
- // $results = [];
- //
- // foreach ($utilityData as $item) {
- // $subject = $this->simplifySubjectName($item['科目名称']);
- // $amount = $this->calculateAmount($item);
- //
- // if ($subject === self::SUBJECT_TOTAL_TO_APPORTION) {
- // // 待分摊总额按楼层分摊
- // $floorResults = $this->allocateByFloor($amount, $month);
- //
- // foreach ($floorResults as $floor => $machineAllocations) {
- // foreach ($machineAllocations as $machineCode => $machineAmount) {
- // if (!isset($results[$machineCode])) {
- // $results[$machineCode] = [];
- // }
- // $results[$machineCode][$subject] = $machineAmount;
- // }
- // }
- // } elseif (in_array($subject, self::ROLL_COATER_ONLY_SUBJECTS)) {
- // // 锅炉和热水锅炉只分配到卷凹机组
- // $rollCoaterResults = $this->allocateToRollCoaterOnly($amount, $month);
- //
- // foreach ($rollCoaterResults as $machineCode => $machineAmount) {
- // if (!isset($results[$machineCode])) {
- // $results[$machineCode] = [];
- // }
- // if (!isset($results[$machineCode][$subject])) {
- // $results[$machineCode][$subject] = $machineAmount;
- // }
- // }
- // } else {
- // // 其他科目按所有机台分摊
- // $globalResults = $this->allocateGlobally($amount, $month);
- // foreach ($globalResults as $machineCode => $machineAmount) {
- // if (!isset($results[$machineCode])) {
- // $results[$machineCode] = [];
- // }
- // $results[$machineCode][$subject] = $machineAmount;
- // }
- // }
- // }
- //
- // return $results;
- // }
- //
- // /**
- // * 获取水电气数据
- // */
- // protected function getUtilityData($month)
- // {
- // return Db::name('成本_各月水电气')
- // ->where('Sys_ny', $month)
- // ->whereLike('费用类型', '%分摊%')
- // ->select();
- // }
- //
- // /**
- // * 简化科目名称
- // */
- // protected function simplifySubjectName($subjectName)
- // {
- // $simplifiedMap = [
- // '废气处理(RTO)' => self::SUBJECT_WASTE_GAS,
- // '锅炉' => self::SUBJECT_BOILER,
- // '热水锅炉' => self::SUBJECT_HOT_WATER_BOILER,
- // '空压机' => self::SUBJECT_AIR_COMPRESSOR,
- // '真空鼓风机' => self::SUBJECT_VACUUM_BLOWER,
- // '中央空调' => self::SUBJECT_CENTRAL_AIR_CONDITIONER,
- // '待分摊总额' => self::SUBJECT_TOTAL_TO_APPORTION,
- // ];
- //
- // foreach ($simplifiedMap as $keyword => $simplified) {
- // if (strpos($subjectName, $keyword) !== false) {
- // return $simplified;
- // }
- // }
- //
- // return $subjectName;
- // }
- //
- // /**
- // * 计算金额
- // */
- // protected function calculateAmount($item)
- // {
- // $electricity = ($this->getSafeNumericValue($item['耗电量']) * $this->getSafeNumericValue($item['单位电价']));
- // $gas = ($this->getSafeNumericValue($item['耗气量']) * $this->getSafeNumericValue($item['单位气价']));
- //
- // return round($electricity + $gas, 2);
- // }
- //
- // /**
- // * 按楼层分摊
- // */
- // protected function allocateByFloor($totalAmount, $month)
- // {
- // $results = [];
- //
- // // 计算每个楼层的总机时
- // $floorTotalHours = [];
- // foreach ([1, 2] as $floor) {
- // $machines = $this->getMachinesByFloor($floor, $month);
- // $totalHours = 0;
- // foreach ($machines as $machine) {
- // $totalHours += $machine['占用机时'];
- // }
- // $floorTotalHours[$floor] = $totalHours;
- // }
- //
- // $allFloorsTotal = array_sum($floorTotalHours);
- // if ($allFloorsTotal <= 0) {
- // return $results;
- // }
- //
- // // 按楼层比例分摊
- // foreach ($floorTotalHours as $floor => $hours) {
- // $floorAmount = round($totalAmount * ($hours / $allFloorsTotal), 2);
- //
- // // 在楼层内按机台分摊
- // $machines = $this->getMachinesByFloor($floor, $month);
- // $floorResults = $this->allocateWithinGroup($floorAmount, $machines);
- //
- // $results[$floor] = $floorResults;
- // }
- //
- // return $results;
- // }
- //
- // /**
- // * 全局分摊(不分楼层)
- // */
- // protected function allocateGlobally($totalAmount, $month)
- // {
- // $machines = $this->getAllMachines($month);
- // return $this->allocateWithinGroup($totalAmount, $machines);
- // }
- //
- // /**
- // * 只分摊到卷凹机组
- // */
- // protected function allocateToRollCoaterOnly($totalAmount, $month)
- // {
- // $machines = $this->getRollCoaterMachines($month);
- // return $this->allocateWithinGroup($totalAmount, $machines);
- // }
- //
- // /**
- // * 在组内按机台运行时间分摊
- // */
- // protected function allocateWithinGroup($totalAmount, $machines)
- // {
- // $results = [];
- //
- // if (empty($machines)) {
- // return $results;
- // }
- //
- // $totalHours = 0;
- // $machineHours = [];
- //
- // foreach ($machines as $machine) {
- // $hours = floatval($machine['占用机时']);
- // $machineCode = $machine['机台编号'];
- //
- // if ($hours > 0) {
- // $totalHours += $hours;
- // if (!isset($machineHours[$machineCode])) {
- // $machineHours[$machineCode] = $hours;
- // } else {
- // $machineHours[$machineCode] += $hours;
- // }
- // }
- // }
- //
- // if ($totalHours <= 0) {
- // return $results;
- // }
- //
- // foreach ($machineHours as $machineCode => $hours) {
- // $results[$machineCode] = round($totalAmount * ($hours / $totalHours), 2);
- // }
- //
- // return $results;
- // }
- //
- // /**
- // * 格式化分摊结果
- // */
- // protected function formatApportionmentResults($results, $month, $sysId)
- // {
- // $formatted = [];
- // $now = date('Y-m-d H:i:s');
- //
- // foreach ($results as $machineCode => $subjects) {
- // foreach ($subjects as $subject => $amount) {
- // $formatted[] = [
- // 'Sys_ny' => $month,
- // '科目名称' => $subject,
- // '设备编号' => $machineCode,
- // '分摊系数' => 1,
- // '分摊金额' => $amount,
- // 'Sys_id' => $sysId,
- // 'Sys_rq' => $now,
- // ];
- // }
- // }
- //
- // return $formatted;
- // }
- //
- // /**
- // * 保存分摊系数
- // */
- // protected function saveApportionmentCoefficients($data, $month)
- // {
- // // 删除旧数据
- // Db::name('成本_各月分摊系数')->where('Sys_ny', $month)->delete();
- //
- // if (!empty($data)) {
- // $sql = Db::name('成本_各月分摊系数')->fetchSql(true)->insertAll($data);
- // \db()->query($sql);
- // }
- // }
- //
- // /**
- // * 分摊到工单(二次分配)
- // */
- // protected function allocateToWorkOrders($month)
- // {
- // // 获取所有机台的分摊系数(每机时费用)
- // $coefficients = $this->getMachineCoefficients($month);
- //
- // // 获取所有机台的工单
- // $workOrders = $this->getWorkOrdersByMonth($month);
- //
- // $updates = [];
- // foreach ($workOrders as $order) {
- // $machineCode = $order['机台编号'];
- //
- // if (!isset($coefficients[$machineCode])) {
- // continue;
- // }
- //
- // $machineCoeffs = $coefficients[$machineCode];
- // $hours = floatval($order['占用机时']);
- //
- // if ($hours <= 0) {
- // continue;
- // }
- //
- // // 计算各科目分摊金额
- // $updateData = [
- // '直接水电' => round($hours * 0.69, 2), // 直接水电费
- // ];
- //
- // foreach ($machineCoeffs as $subject => $rate) {
- // $subjectKey = ($subject === '待分摊总额') ? '分摊水电' : $subject;
- // $updateData[$subjectKey] = round($hours * $rate, 2);
- // }
- //
- // // 构建更新条件
- // $where = [
- // 'sys_ny' => $month,
- // 'sczl_gdbh' => $order['工单编号'],
- // 'sczl_yjno' => $order['印件号'],
- // 'sczl_gxh' => $order['工序号'],
- // 'sczl_jtbh' => $machineCode,
- // ];
- //
- // $updates[] = [
- // 'where' => $where,
- // 'data' => $updateData
- // ];
- // }
- //
- // // 批量更新
- // $this->batchUpdateWorkOrders($updates, $month);
- // }
- //
- // /**
- // * 获取机台分摊系数(每机时费用)
- // */
- // protected function getMachineCoefficients($month)
- // {
- // // 查询分摊系数和机台运行时间
- // $data = Db::name('成本_各月分摊系数')
- // ->alias('c')
- // ->join('成本v23_月度成本明细 d', 'd.sys_ny = c.Sys_ny AND d.sczl_jtbh = c.设备编号')
- // ->where('c.Sys_ny', $month)
- // ->field([
- // 'c.设备编号',
- // 'c.科目名称',
- // 'c.分摊金额',
- // 'SUM(d.占用机时)' => 'total_hours'
- // ])
- // ->group('c.设备编号, c.科目名称')
- // ->select();
- //
- // $coefficients = [];
- //
- // foreach ($data as $item) {
- // $machineCode = $item['设备编号'];
- // $subject = $item['科目名称'];
- // $amount = floatval($item['分摊金额']);
- // $hours = floatval($item['total_hours']);
- //
- // if ($hours > 0) {
- // $rate = round($amount / $hours, 4);
- //
- // if (!isset($coefficients[$machineCode])) {
- // $coefficients[$machineCode] = [];
- // }
- //
- // $coefficients[$machineCode][$subject] = $rate;
- // }
- // }
- //
- // return $coefficients;
- // }
- //
- // /**
- // * 获取所有工单
- // */
- // protected function getWorkOrdersByMonth($month)
- // {
- // return Db::name('成本v23_月度成本明细')
- // ->where('sys_ny', $month)
- // ->field([
- // 'sczl_gdbh' => '工单编号',
- // 'sczl_yjno' => '印件号',
- // 'sczl_gxh' => '工序号',
- // 'sczl_jtbh' => '机台编号',
- // '占用机时'
- // ])
- // ->select();
- // }
- //
- // /**
- // * 批量更新工单数据
- // */
- // protected function batchUpdateWorkOrders($updates, $month)
- // {
- // $db = Db::name('成本v23_月度成本明细');
- //
- // foreach ($updates as $update) {
- // $sql = $db->where($update['where'])->fetchSql(true)->update($update['data']);
- // $db->query($sql);
- // }
- // }
- //
- // /**
- // * 安全数值获取
- // */
- // protected function getSafeNumericValue($value)
- // {
- // if ($value === null || $value === '' || $value === false) {
- // return 0;
- // }
- // return floatval($value);
- // }
- // app/controller/UnifiedCostController.php
- /**
- * 执行成本计算
- * @ApiMethod POST
- * @param string month 年月
- * @param string sys_id 系统ID
- */
- public function calculate()
- {
- if (Request::instance()->isPost() == false) {
- $this->error('非法请求');
- }
- $params = Request::instance()->param();
- if (!isset($params['month']) || empty($params['month'])) {
- $this->error('月份参数错误');
- }
- $month = trim($params['month']);
- $sysId = $params['sys_id'] ?? '';
- // 检查是否有正在执行的任务
- $runningTask = Db::name('queue_tasks')
- ->where('task_type', 'cost_calculation')
- ->where('task_data', 'like', '%"month":"' . $month . '"%')
- ->where('status', 'in', ['pending', 'processing'])
- ->find();
- if ($runningTask) {
- $this->success('该月份的成本计算任务已在执行中,请勿重复提交');
- }
- // 检查工资计算是否在执行中(可选)
- $salaryRunning = Db::name('queue_tasks')
- ->where('task_type', 'salary_calculation')
- ->where('task_data', 'like', '%"date":"' . $month . '"%')
- ->where('status', 'in', ['pending', 'processing'])
- ->find();
- if ($salaryRunning) {
- $this->error('该月份的工资计算正在执行中,建议等待工资计算完成后再进行成本计算');
- }
- // 准备任务数据
- $taskData = [
- 'month' => $month,
- 'sys_id' => $sysId,
- 'user_id' => session('user_id') ?? 0,
- 'user_name' => session('user_name') ?? '系统',
- 'request_time' => date('Y-m-d H:i:s')
- ];
- // 先创建任务记录
- $taskId = Db::name('queue_tasks')->insertGetId([
- 'task_type' => 'cost_calculation',
- 'task_data' => json_encode($taskData, JSON_UNESCAPED_UNICODE),
- 'status' => 'pending',
- 'queue_name' => 'cost_calculation',
- 'create_time' => date('Y-m-d H:i:s')
- ]);
- // 添加到任务数据中
- $taskData['task_id'] = $taskId;
- // 提交到成本计算队列
- $jobHandlerClassName = 'app\job\CostCalculationJob';
- $queueName = 'cost_calculation';
- $jobId = Queue::push($jobHandlerClassName, $taskData, $queueName);
- if ($jobId) {
- // 更新任务记录
- Db::name('queue_tasks')
- ->where('id', $taskId)
- ->update([
- 'job_id' => $jobId,
- 'update_time' => date('Y-m-d H:i:s')
- ]);
- $this->success('成本计算任务已提交到队列,请稍后查看结果', null, [
- 'task_id' => $taskId,
- 'job_id' => $jobId,
- 'month' => $month,
- 'queue_name' => $queueName
- ]);
- } else {
- // 更新任务状态为失败
- Db::name('queue_tasks')
- ->where('id', $taskId)
- ->update([
- 'status' => 'failed',
- 'error' => '任务提交到队列失败',
- 'update_time' => date('Y-m-d H:i:s')
- ]);
- $this->error('成本计算任务提交失败');
- }
- }
- /**
- * 查询成本计算状态
- * @ApiMethod GET
- * @param string month 年月
- */
- public function status()
- {
- $month = Request::instance()->param('month');
- if (empty($month)) {
- $this->error('月份参数错误');
- }
- // 查询任务记录
- $task = Db::name('queue_tasks')
- ->where('task_type', 'cost_calculation')
- ->where('task_data', 'like', '%"month":"' . $month . '"%')
- ->order('id', 'desc')
- ->find();
- if ($task) {
- $result = json_decode($task['result'] ?? '{}', true);
- $taskData = json_decode($task['task_data'] ?? '{}', true);
- $response = [
- 'exists' => true,
- 'task_id' => $task['id'],
- 'month' => $month,
- 'status' => $task['status'],
- 'queue_name' => $task['queue_name'],
- 'job_id' => $task['job_id'],
- 'start_time' => $task['start_time'],
- 'end_time' => $task['end_time'],
- 'retry_count' => $task['retry_count'],
- 'result' => $result,
- 'error' => $task['error'] ?? '',
- 'create_time' => $task['create_time'],
- 'user_info' => [
- 'user_id' => $taskData['user_id'] ?? 0,
- 'user_name' => $taskData['user_name'] ?? ''
- ]
- ];
- } else {
- $response = ['exists' => false, 'month' => $month];
- }
- $this->success('查询成功', null, $response);
- }
- /**
- * 获取成本计算任务列表
- * @ApiMethod GET
- */
- public function list()
- {
- $page = Request::instance()->param('page', 1);
- $limit = Request::instance()->param('limit', 20);
- $month = Request::instance()->param('month');
- $status = Request::instance()->param('status');
- $query = Db::name('queue_tasks')
- ->where('task_type', 'cost_calculation');
- if ($month) {
- $query->where('task_data', 'like', '%"month":"' . $month . '"%');
- }
- if ($status) {
- $query->where('status', $status);
- }
- $total = $query->count();
- $list = $query->order('id', 'desc')
- ->page($page, $limit)
- ->select();
- // 解析任务数据
- foreach ($list as &$item) {
- $taskData = json_decode($item['task_data'] ?? '{}', true);
- $item['month'] = $taskData['month'] ?? '';
- $item['user_name'] = $taskData['user_name'] ?? '';
- $item['request_time'] = $taskData['request_time'] ?? '';
- if (!empty($item['result'])) {
- $item['result_data'] = json_decode($item['result'], true);
- }
- }
- $this->success('查询成功', null, [
- 'list' => $list,
- 'total' => $total,
- 'page' => $page,
- 'pages' => ceil($total / $limit)
- ]);
- }
- /**
- * 手动重试失败的任务
- * @ApiMethod POST
- * @param int task_id 任务ID
- */
- public function retry()
- {
- $taskId = Request::instance()->param('task_id');
- if (empty($taskId)) {
- $this->error('任务ID不能为空');
- }
- $task = Db::name('queue_tasks')
- ->where('id', $taskId)
- ->where('task_type', 'cost_calculation')
- ->where('status', 'failed')
- ->find();
- if (!$task) {
- $this->error('任务不存在或无法重试');
- }
- // 解析原任务数据
- $taskData = json_decode($task['task_data'], true);
- $taskData['task_id'] = $taskId;
- $taskData['retry_time'] = date('Y-m-d H:i:s');
- // 更新原任务状态
- Db::name('queue_tasks')
- ->where('id', $taskId)
- ->update([
- 'status' => 'retrying',
- 'update_time' => date('Y-m-d H:i:s')
- ]);
- // 提交到队列
- $jobHandlerClassName = 'app\job\CostCalculationJob';
- $queueName = 'cost_calculation';
- $jobId = Queue::push($jobHandlerClassName, $taskData, $queueName);
- if ($jobId) {
- $this->success('任务已重新提交到队列', null, [
- 'task_id' => $taskId,
- 'new_job_id' => $jobId,
- 'queue_name' => $queueName
- ]);
- } else {
- $this->error('任务重试失败');
- }
- }
- }
|