error('账号未绑定工厂'); } $this->model = new TemplateModel; } /** * 本厂模板库 */ public function index() { $limit = $this->request->request('limit/d', 50); $printable = $this->request->request('printable/d', 0); $query = $this->model->where('status', 'normal')->order('id desc'); if ($printable) { $query->printable(); } $list = $query->paginate($limit); $rows = []; foreach ($list->items() as $item) { $rows[] = $this->formatRow($item); } $this->attachMarket($rows); $this->success('', ['total' => $list->total(), 'rows' => $rows]); } /** * 详情 */ public function info() { $id = $this->request->request('id/d'); $row = $this->model->find($id); if (!$row) { $this->error(__('No Results were found')); } $this->success('', $this->formatRow($row, true)); } /** * 封面用站内相对路径,工厂端 Vite 才能代理到 /uploads。 * @param mixed $item * @param bool $withMarket * @return array */ protected function formatRow($item, $withMarket = false) { $row = is_array($item) ? $item : $item->toArray(); $cover = isset($row['cover']) ? trim((string)$row['cover']) : ''; if ($cover === '' && !empty($row['id'])) { $versionId = (int)($row['current_version_id'] ?? 0); if ($versionId > 0) { $schema = \think\Db::name('ps_template_version')->where('id', $versionId)->value('schema_json'); $decoded = $schema ? json_decode($schema, true) : []; if (is_array($decoded)) { $cover = (string)($decoded['background'] ?? $decoded['file_url'] ?? $decoded['image'] ?? ''); } } } $row['cover'] = $cover; $schemaJson = ''; if (!empty($row['current_version_id'])) { $schemaJson = (string)\think\Db::name('ps_template_version')->where('id', (int)$row['current_version_id'])->value('schema_json'); } $schema = \app\common\library\ps\PrintPlanner::decodeSchema($schemaJson, $cover); $row['schema'] = $schema; $row['schema_json'] = json_encode($schema, JSON_UNESCAPED_UNICODE); $row['cover_url'] = $this->coverUrl($schema['background'] ?: $cover); $row['field_catalog'] = \app\common\library\ps\PrintPlanner::fieldCatalog(); $row['can_delete'] = (int)$row['is_system'] !== 1 && (int)($row['factory_id'] ?? 0) === (int)FactoryContext::id(); $row['can_publish'] = (int)$row['is_system'] !== 1 && ($row['source'] ?? '') !== 'market' && strpos((string)($row['license_type'] ?? ''), 'market_') !== 0; if ($withMarket) { $rows = [$row]; $this->attachMarket($rows); return $rows[0]; } return $row; } /** * @param array $rows */ protected function attachMarket(array &$rows) { $ids = []; foreach ($rows as $row) { if (!empty($row['id'])) { $ids[] = (int)$row['id']; } } $ids = array_values(array_unique($ids)); $map = []; if ($ids) { $goods = (new MarketGoods()) ->where('factory_id', FactoryContext::id()) ->where('template_id', 'in', $ids) ->select(); foreach ($goods as $item) { $g = is_array($item) ? $item : $item->toArray(); $map[(int)$g['template_id']] = [ 'id' => (int)$g['id'], 'status' => $g['status'], 'price_single' => (int)$g['price_single'], 'price_buyout' => (int)$g['price_buyout'], 'title' => $g['title'], 'intro' => $g['intro'], 'on_sale' => $g['status'] === 'on_sale', ]; } } foreach ($rows as &$row) { $row['market'] = isset($map[(int)$row['id']]) ? $map[(int)$row['id']] : null; } unset($row); } /** * @param string $path * @return string */ protected function coverUrl($path) { $path = trim((string)$path); if ($path === '') { return ''; } if (preg_match('#^(https?:)?//#i', $path) || strpos($path, 'data:') === 0) { return $path; } return '/' . ltrim(str_replace('\\', '/', $path), '/'); } /** * 保存套打坐标与文字(生成新版本) */ public function saveSchema() { $id = $this->request->post('id/d'); $row = $this->model->find($id); if (!$row) { $this->error(__('No Results were found')); } if ((int)$row['is_system'] === 1) { $this->error('官方模板不可修改'); } $name = trim((string)$this->request->post('name', '')); $schema = $this->request->post('schema/a'); if (!$schema) { $raw = $this->request->post('schema_json', '', null); $schema = json_decode((string)$raw, true); } if (!is_array($schema)) { $this->error('排版数据不正确'); } $schema = \app\common\library\ps\PrintPlanner::decodeSchema(json_encode($schema, JSON_UNESCAPED_UNICODE), $row['cover']); if ($name !== '') { $schema['name'] = $name; } $next = (int)\think\Db::name('ps_template_version')->where('template_id', $row->id)->max('version') + 1; if ($next < 1) { $next = 1; } $ver = new \app\common\model\ps\TemplateVersion(); $ver->allowField(true)->save([ 'template_id' => $row->id, 'version' => $next, 'schema_json' => json_encode($schema, JSON_UNESCAPED_UNICODE), 'remark' => '页面调整', ]); $save = [ 'current_version_id' => $ver->id, ]; if ($name !== '') { $save['name'] = $name; } if (!empty($schema['background'])) { $save['cover'] = $schema['background']; } $row->allowField(true)->save($save); $this->success('已保存', ['id' => (int)$row->id, 'version_id' => (int)$ver->id]); } /** * 保存套打坐标与文字 */ public function save_schema() { return $this->saveSchema(); } /** * 添加(保存到本厂模板库) */ public function add() { $params = $this->request->post(); if (!$params) { $this->error(__('Parameter %s can not be empty', '')); } $params['creator_user_id'] = $this->auth->id; $params['is_system'] = 0; $params['license_type'] = isset($params['license_type']) ? $params['license_type'] : 'self'; unset($params['id'], $params['factory_id']); $this->model->allowField(true)->save($params); $this->success('', ['id' => $this->model->id]); } /** * 编辑 */ public function edit() { $id = $this->request->post('id/d'); $row = $this->model->find($id); if (!$row) { $this->error(__('No Results were found')); } if ((int)$row['is_system'] === 1) { $this->error('官方模板不可修改,请先复制到本厂模板库'); } $params = $this->request->post(); unset($params['id'], $params['factory_id'], $params['is_system']); $row->allowField(true)->save($params); $this->success(); } /** * 删除 */ public function del() { $id = $this->request->post('id/d'); $row = $this->model->find($id); if (!$row) { $this->error(__('No Results were found')); } if ((int)$row['is_system'] === 1) { $this->error('官方模板不可删除'); } \think\Db::name('ps_template_version')->where('template_id', $row->id)->delete(); \think\Db::name('ps_ai_job')->where('template_id', $row->id)->update(['template_id' => 0]); MarketPublisher::offByTemplate($row->id, FactoryContext::id()); $row->delete(); $this->success('已删除'); } /** * 从空白纸新建可套打模板 */ public function create_blank() { $name = trim((string)$this->request->post('name', '')); if ($name === '') { $name = '空白模板 ' . date('m-d H:i'); } $schema = [ 'name' => $name, 'mode' => 'compose', 'page' => ['w' => 210, 'h' => 297, 'background' => '#ffffff'], 'background' => '', 'file_url' => '', 'elements' => [], 'source' => 'manual', ]; $row = new TemplateModel(); $row->allowField(true)->save([ 'creator_user_id' => $this->auth->id, 'name' => $name, 'cover' => '', 'source' => 'manual', 'license_type' => 'self', 'locked' => 0, 'is_system' => 0, 'status' => 'normal', ]); $ver = new \app\common\model\ps\TemplateVersion(); $ver->allowField(true)->save([ 'template_id' => $row->id, 'version' => 1, 'schema_json' => json_encode($schema, JSON_UNESCAPED_UNICODE), 'remark' => '空白新建', ]); $row->save(['current_version_id' => $ver->id]); $this->success('已创建空白模板', ['id' => (int)$row->id]); } /** * 复制为本厂新模板 */ public function copy() { $id = $this->request->post('id/d'); $row = $this->model->find($id); if (!$row) { $this->error(__('No Results were found')); } $schemaJson = \app\common\library\ps\PrintPlanner::schemaJson($row); $schema = \app\common\library\ps\PrintPlanner::decodeSchema($schemaJson, $row['cover']); $name = trim((string)$row['name']) . ' 副本'; $schema['name'] = $name; $dup = new TemplateModel(); $dup->allowField(true)->save([ 'creator_user_id' => $this->auth->id, 'name' => $name, 'cover' => (string)$row['cover'], 'source' => 'manual', 'license_type' => 'self', 'locked' => 0, 'source_template_id' => (int)$row->id, 'source_version_id' => (int)$row['current_version_id'], 'is_system' => 0, 'status' => 'normal', ]); $ver = new \app\common\model\ps\TemplateVersion(); $ver->allowField(true)->save([ 'template_id' => $dup->id, 'version' => 1, 'schema_json' => json_encode($schema, JSON_UNESCAPED_UNICODE), 'remark' => '复制模板', ]); $dup->save(['current_version_id' => $ver->id]); $this->success('已复制', ['id' => (int)$dup->id]); } }