error('账号未绑定工厂'); } } /** * 打印历史 */ public function index() { $limit = $this->request->request('limit/d', 10); $list = (new PrintJobModel())->order('id desc')->paginate($limit); $this->success('', ['total' => $list->total(), 'rows' => $list->items()]); } /** * 预览套打数据:拆张、工序、填充字段。不锁定单次模板。 */ public function prepare() { $templateId = $this->request->param('template_id/d'); $bizType = $this->request->param('biz_type', 'workorder'); $bizId = $this->request->param('biz_id/d', 0); if (!$templateId) { $this->error(__('Invalid parameters')); } if ($bizId <= 0) { $no = trim((string)$this->request->param('no', $this->request->param('code', ''))); $name = trim((string)$this->request->param('name', '')); if ($no === '' && $name === '') { $this->error('请填写工单或产品编号、名称'); } } $template = Template::get($templateId); if (!$template) { $this->error(__('No Results were found')); } try { TemplateLicense::assertPrintable($template, FactoryContext::id()); $plan = PrintPlanner::prepare($bizType, $bizId, $this->planOptions()); } catch (Exception $e) { $this->error($e->getMessage()); } $schemaJson = PrintPlanner::schemaJson($template); $schema = PrintPlanner::decodeSchema($schemaJson, $template['cover']); $htmlTpl = $this->request->param('html', '', null); if (trim((string)$htmlTpl) === '') { $htmlTpl = PrintPlanner::htmlFromSchema($schemaJson, $template['cover'], false); } $pages = PrintPlanner::renderPages($plan, $htmlTpl, $schema); $lodop = LodopPrinter::buildTask($pages[0]['html'] ?? '', $template['name'], $pages, 1, $this->printPage($template)); $this->success('', [ 'template_id' => (int)$template['id'], 'template_name' => $template['name'], 'template_cover' => $template['cover'] ? cdnurl($template['cover'], true) : '', 'template_version_id' => (int)$template['current_version_id'], 'schema_json' => PrintPlanner::schemaJson($template), 'qty_plan' => $plan['qty_plan'], 'sheet_qty' => $plan['sheet_qty'], 'plate_total' => $plan['plate_total'] ?? $plan['total_sheets'], 'sheet_from' => $plan['sheet_from'] ?? 1, 'sheet_to' => $plan['sheet_to'] ?? $plan['total_sheets'], 'total_sheets' => $plan['total_sheets'], 'processes' => $plan['processes'], 'fill' => $plan['fill'], 'sheets' => $plan['sheets'], 'pages' => $pages, 'lodop' => $lodop, ]); } /** * 确认套打:按拆张落快照,整单只锁定一次单次授权,返回 Lodop 预览任务 */ public function confirm() { $templateId = $this->request->param('template_id/d'); $bizType = $this->request->param('biz_type', 'workorder'); $bizId = $this->request->param('biz_id/d', 0); $copies = $this->request->param('copies/d', 1); $htmlTpl = $this->request->param('html', '', null); if (!$templateId) { $this->error(__('Invalid parameters')); } if ($bizId <= 0) { $no = trim((string)$this->request->param('no', $this->request->param('code', ''))); $name = trim((string)$this->request->param('name', '')); if ($no === '' && $name === '') { $this->error('请填写工单或产品编号、名称'); } } $factoryId = FactoryContext::id(); $template = Template::get($templateId); if (!$template) { $this->error(__('No Results were found')); } $schemaJson = PrintPlanner::schemaJson($template); $schema = PrintPlanner::decodeSchema($schemaJson, $template['cover']); if (trim((string)$htmlTpl) === '') { $htmlTpl = PrintPlanner::htmlFromSchema($schemaJson, $template['cover'], false); } try { TemplateLicense::assertPrintable($template, $factoryId); $plan = PrintPlanner::prepare($bizType, $bizId, $this->planOptions()); } catch (Exception $e) { $this->error($e->getMessage()); } $postedPages = $this->request->param('pages/a'); if (is_array($postedPages) && $postedPages) { $pages = []; foreach ($postedPages as $index => $item) { $html = is_array($item) ? (isset($item['html']) ? $item['html'] : '') : (string)$item; $sheet = $plan['sheets'][$index] ?? null; $fill = $sheet ? $sheet['fill'] : $plan['fill']; $pages[] = [ 'no' => $sheet ? $sheet['no'] : ($index + 1), 'total' => $plan['total_sheets'], 'qty' => $sheet ? $sheet['qty'] : $plan['qty_plan'], 'title' => '流程单 ' . ($sheet ? $sheet['no_text'] : ($index + 1)), 'html' => $html, 'fill' => $fill, 'print_items' => PrintPlanner::isOverlay($schema) ? PrintPlanner::overlayPrintItems($schema, $fill, $plan['processes']) : [], ]; } } else { $pages = PrintPlanner::renderPages($plan, $htmlTpl, $schema); } $lodop = LodopPrinter::buildTask($pages[0]['html'] ?? '', $template['name'], $pages, $copies, $this->printPage($template)); $printNo = 'P' . date('YmdHis') . Random::numeric(4); Db::startTrans(); try { $job = new PrintJobModel(); $job->allowField(true)->save([ 'operator_user_id' => $this->auth->id, 'print_no' => $printNo, 'biz_type' => $bizType, 'biz_id' => $bizId, 'template_id' => $templateId, 'template_version_id' => (int)$template['current_version_id'], 'copies' => $copies > 0 ? $copies : 1, 'lodop_mode' => $lodop['mode'], 'status' => 'previewed', ]); $snapshot = new PrintSnapshot(); $snapshot->allowField(true)->save([ 'print_job_id' => $job->id, 'fill_json' => json_encode([ 'qty_plan' => $plan['qty_plan'], 'sheet_qty' => $plan['sheet_qty'], 'total_sheets' => $plan['total_sheets'], 'processes' => $plan['processes'], 'fill' => $plan['fill'], 'sheets' => $plan['sheets'], ], JSON_UNESCAPED_UNICODE), 'schema_json' => $schemaJson, 'lodop_html' => json_encode(array_column($pages, 'html'), JSON_UNESCAPED_UNICODE), ]); TemplateLicense::consumeOnConfirm($template, $factoryId); Db::commit(); } catch (Exception $e) { Db::rollback(); $this->error($e->getMessage()); } $this->success('', [ 'print_no' => $printNo, 'total_sheets' => $plan['total_sheets'], 'lodop' => $lodop, ]); } /** * 删除本厂打印记录 */ public function del() { $ids = $this->request->post('id'); if (!$ids) { $this->error(__('Parameter %s can not be empty', 'id')); } $list = (new PrintJobModel())->where('id', 'in', $ids)->select(); foreach ($list as $row) { PrintSnapshot::where('print_job_id', $row->id)->delete(); $row->delete(); } $this->success('已删除'); } /** * @return array */ protected function planOptions() { $extra = $this->request->param('extra/a'); $options = [ 'sheet_qty' => $this->request->param('sheet_qty', $this->request->param('tldx', 0)), 'no' => $this->request->param('no', ''), 'code' => $this->request->param('code', ''), 'name' => $this->request->param('name', ''), 'sheet_from' => $this->request->param('sheet_from/d', 0), 'sheet_to' => $this->request->param('sheet_to/d', 0), 'process_string' => $this->request->param('process_string', $this->request->param('string', '')), 'extra' => is_array($extra) ? $extra : [], ]; $rawProcesses = $this->request->param('processes/a'); if ($rawProcesses !== null) { $options['processes'] = is_array($rawProcesses) ? $rawProcesses : []; } $qty = $this->request->param('qty', null); if ($qty === null || $qty === '') { $qty = $this->request->param('num', null); } if ($qty !== null && $qty !== '') { $options['qty'] = $qty; } return $options; } /** * @param Template $template * @return array */ protected function printPage($template) { $schema = PrintPlanner::decodeSchema(PrintPlanner::schemaJson($template), $template['cover']); $page = isset($schema['page']) && is_array($schema['page']) ? $schema['page'] : []; $resolved = PaperSize::resolve( (string)($template['paper_size'] ?: ($page['paper_size'] ?? 'A4')), (float)($template['page_w'] ?: ($page['w'] ?? 0)), (float)($template['page_h'] ?: ($page['h'] ?? 0)) ); $page['w'] = $resolved['w']; $page['h'] = $resolved['h']; $page['paper_size'] = $resolved['name']; $cover = (string)($schema['background'] ?? $template['cover'] ?? ''); $page['background'] = $cover !== '' ? PrintPlanner::printImageSrc($cover) : ''; return $page; } }