diff --git a/app/api/document-types/document-types.ts b/app/api/document-types/document-types.ts new file mode 100644 index 0000000..36606d9 --- /dev/null +++ b/app/api/document-types/document-types.ts @@ -0,0 +1,764 @@ +import { postgrestGet, postgrestDelete, postgrestPost, postgrestPut, type PostgrestParams } from '../postgrest-client'; +import dayjs from 'dayjs'; + +// 定义文档类型接口 +export interface DocumentType { + id: number; + name: string; + description: string | null; + evaluation_point_groups_ids: number[]; // jsonb数组字段 + prompt_config?: { + summary_template?: number; + llm_extract_template?: number; + vlm_extract_template?: number; + evaluation_template?: number; + execution_template?: number; + } | null; + created_at: string; + updated_at: string; + code?: string | null; +} + +// 定义用于UI展示的文档类型接口 +export interface DocumentTypeUI { + id: number; + name: string; + description: string; + groups: DocumentTypeGroup[]; + llm_extraction_template_id?: number | null; + vlm_extraction_template_id?: number | null; + evaluation_template_id?: number | null; + summary_template_id?: number | null; + created_at: string; + updated_at: string; + code?: string | null; +} + +// 文档类型创建接口 +export interface DocumentTypeCreateDTO { + name: string; + description?: string; + group_ids: string[]; + llm_extraction_template_id?: number | null; + vlm_extraction_template_id?: number | null; + evaluation_template_id?: number | null; + summary_template_id?: number | null; + code?: string | null; +} + +// 文档类型更新接口 +export interface DocumentTypeUpdateDTO extends DocumentTypeCreateDTO { + id: number; +} + +// 文档类型分组关系 +export interface DocumentTypeGroup { + id: string; + name: string; +} + +// 搜索参数 +export interface DocumentTypeSearchParams { + name?: string; + group_id?: string; + page?: number; + pageSize?: number; +} + +/** + * 格式化日期 + * @param dateString 日期字符串 + * @returns 格式化后的日期字符串 + */ +function formatDate(dateString: string): string { + if (!dateString) return ''; + try { + return dayjs(dateString).format('YYYY-MM-DD HH:mm:ss'); + } catch (error) { + console.error('日期格式化失败:', error); + return dateString; + } +} + +/** + * 从不同格式的 API 响应中提取数据 + * @param responseData API 响应数据 + * @returns 提取后的数据或 null + */ +function extractApiData(responseData: unknown): T | null { + if (!responseData) return null; + + // 格式1: { code: number, msg: string, data: T } + if (typeof responseData === 'object' && responseData !== null && + 'code' in responseData && + 'data' in responseData && + (responseData as { data: unknown }).data) { + return (responseData as { data: T }).data; + } + + // 格式2: 直接是数据对象 + return responseData as T; +} + +/** + * 获取所有评查点分组 + * @returns 评查点分组列表 + */ +export async function getAllEvaluationPointGroups(): Promise<{ + data?: DocumentTypeGroup[]; + error?: string; + status?: number; +}> { + try { + const params: PostgrestParams = { + select: 'id, name' + }; + + const response = await postgrestGet>('evaluation_point_groups', params); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + // 使用extractApiData提取数据 + const extractedData = extractApiData>(response.data); + + if (!extractedData) { + return { data: [] }; + } + + // 转换为DocumentTypeGroup格式 + const groups: DocumentTypeGroup[] = extractedData.map(item => ({ + id: item.id.toString(), + name: item.name + })); + + return { data: groups }; + } catch (error) { + console.error('获取所有评查点分组失败:', error); + return { error: error instanceof Error ? error.message : '获取所有评查点分组失败' }; + } +} + +/** + * 根据ID获取评查点分组信息 + * @param ids 评查点分组ID数组 + * @returns 评查点分组信息 + */ +export async function getEvaluationPointGroupsByIds(ids: number[] | number): Promise<{ + data?: DocumentTypeGroup[]; + error?: string; + status?: number; +}> { + try { + // 确保ids是数组 + if (!ids) { + return { data: [] }; + } + + // 将单个ID转换为数组 + const idsArray = Array.isArray(ids) ? ids : [ids]; + if (idsArray.length === 0) { + return { data: [] }; + } + + // console.log('获取评查点分组,ID类型:', typeof ids, '转换后的ID数组:', idsArray); + + const params: PostgrestParams = { + select: 'id, name', + filter: { + 'id': `in.(${idsArray.join(',')})` + } + }; + + // console.log('获取评查点分组,查询参数:', params); + + const response = await postgrestGet>('evaluation_point_groups', params); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + // 使用extractApiData提取数据 + const extractedData = extractApiData>(response.data); + + if (!extractedData) { + return { data: [] }; + } + + // 转换为DocumentTypeGroup格式 + const groups: DocumentTypeGroup[] = extractedData.map(item => ({ + id: item.id.toString(), + name: item.name + })); + + return { data: groups }; + } catch (error) { + console.error('根据ID获取评查点分组失败:', error); + return { error: error instanceof Error ? error.message : '根据ID获取评查点分组失败' }; + } +} + +/** + * 获取文档类型列表 + * @param searchParams 搜索参数 + * @returns 文档类型列表和总数 + */ +export async function getDocumentTypes(searchParams: DocumentTypeSearchParams = {}): Promise<{ + data?: { types: DocumentTypeUI[], total: number }; + error?: string; + status?: number; +}> { + try { + const page = searchParams.page || 1; + const pageSize = searchParams.pageSize || 10; + + // 构建查询参数 + const params: PostgrestParams = { + select: ` + id, + name, + description, + evaluation_point_groups_ids, + prompt_config, + created_at, + updated_at, + code + `, + order: 'updated_at.desc', + headers: { + 'Prefer': 'count=exact' + }, + limit: pageSize, + offset: (page - 1) * pageSize, + filter: {} as Record + }; + + // 添加筛选条件 + const filter: Record = {}; + if (searchParams.name) { + filter['name'] = `ilike.%${searchParams.name}%`; + } + + // 如果有分组ID筛选条件 + if (searchParams.group_id) { + filter['evaluation_point_groups_ids'] = `cs.{${searchParams.group_id}}`; + } + + params.filter = filter; + + // console.log('获取文档类型列表,参数:', params); + const response = await postgrestGet('document_types', params); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + // 使用extractApiData提取数据 + const extractedData = extractApiData(response.data); + const documentTypes = extractedData || []; + + // console.log('提取的文档类型数据:', documentTypes); + + // 为每个文档类型获取关联的分组 + const typesWithGroups = await Promise.all(documentTypes.map(async (type) => { + // 获取文档类型关联的分组IDs + let groupIds: number[] = []; + + try { + // 尝试解析evaluation_point_groups_ids + if (typeof type.evaluation_point_groups_ids === 'string') { + // 如果是JSON字符串,解析它 + groupIds = JSON.parse(type.evaluation_point_groups_ids as unknown as string); + } else if (Array.isArray(type.evaluation_point_groups_ids)) { + // 如果已经是数组,直接使用 + groupIds = type.evaluation_point_groups_ids; + } else if (type.evaluation_point_groups_ids) { + // 其他情况,尝试将其转换为数组 + groupIds = [type.evaluation_point_groups_ids as unknown as number]; + } + } catch (error) { + console.error('解析分组ID失败:', error, '原始值:', type.evaluation_point_groups_ids); + groupIds = []; + } + + console.log(`文档类型 ${type.id} 的分组IDs:`, groupIds); + + // 获取这些ID对应的分组信息 + const groupsResponse = await getEvaluationPointGroupsByIds(groupIds); + + // 返回包含分组信息的文档类型 + return { + ...type, + groups: groupsResponse.data || [] + }; + })); + + // 转换为UI类型 + const uiTypes = typesWithGroups.map(convertToUIDocumentType); + + // 获取总数 + let totalCount = 0; + const responseWithHeaders = response as { + data: unknown; + headers: Record + }; + if (responseWithHeaders.headers) { + const rangeHeader = responseWithHeaders.headers['content-range']; + if (rangeHeader) { + const total = rangeHeader.split('/')[1]; + if (total !== '*') { + totalCount = parseInt(total, 10); + } + } + } + + return { + data: { + types: uiTypes, + total: totalCount || uiTypes.length + } + }; + } catch (error) { + console.error('获取文档类型列表失败:', error); + return { + error: error instanceof Error ? error.message : '获取文档类型列表失败', + status: 500 + }; + } +} + +/** + * 删除文档类型 + * @param id 文档类型ID + * @returns 删除结果 + */ +export async function deleteDocumentType(id: string): Promise<{ + success?: boolean; + error?: string; + status?: number; +}> { + try { + if (!id) { + return { error: '文档类型ID不能为空', status: 400 }; + } + + // 删除文档类型 + const response = await postgrestDelete( + 'document_types', + { + filter: { + 'id': `eq.${id}` + } + } + ); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + return { success: true }; + } catch (error) { + console.error('删除文档类型失败:', error); + return { + error: error instanceof Error ? error.message : '删除文档类型失败', + status: 500 + }; + } +} + +/** + * 将API返回的文档类型转换为UI文档类型 + */ +function convertToUIDocumentType(type: DocumentType & { groups: DocumentTypeGroup[] }): DocumentTypeUI { + // 提取提示词模板ID,确保安全处理以避免控制台警告 + let llmExtractionTemplateId: number | null = null; + let vlmExtractionTemplateId: number | null = null; + let evaluationTemplateId: number | null = null; + let summaryTemplateId: number | null = null; + + // 安全地获取prompt_config字段 + if (type.prompt_config) { + // 转换为字符串或保持为null + if (type.prompt_config.llm_extract_template !== undefined && type.prompt_config.llm_extract_template !== null) { + llmExtractionTemplateId = type.prompt_config.llm_extract_template; + } + + if (type.prompt_config.vlm_extract_template !== undefined && type.prompt_config.vlm_extract_template !== null) { + vlmExtractionTemplateId = type.prompt_config.vlm_extract_template; + } + + // 注意: 后端字段可能是 evaluation_template 或 execution_template + // 优先使用 evaluation_template,如果不存在则尝试使用 execution_template + if (type.prompt_config.evaluation_template !== undefined && type.prompt_config.evaluation_template !== null) { + evaluationTemplateId = type.prompt_config.evaluation_template; + } else if (type.prompt_config.execution_template !== undefined && type.prompt_config.execution_template !== null) { + evaluationTemplateId = type.prompt_config.execution_template; + } + + if (type.prompt_config.summary_template !== undefined && type.prompt_config.summary_template !== null) { + summaryTemplateId = type.prompt_config.summary_template; + } + } + + return { + id: type.id, + name: type.name, + description: type.description || '', + groups: type.groups || [], + llm_extraction_template_id: llmExtractionTemplateId, + vlm_extraction_template_id: vlmExtractionTemplateId, + evaluation_template_id: evaluationTemplateId, + summary_template_id: summaryTemplateId, + created_at: formatDate(type.created_at), + updated_at: formatDate(type.updated_at), + code: type.code + }; +} + +/** + * 获取文档类型详情 + * @param id 文档类型ID + * @returns 文档类型详情 + */ +export async function getDocumentType(id: string): Promise<{ + data?: DocumentTypeUI; + error?: string; + status?: number; +}> { + try { + if (!id) { + return { error: '文档类型ID不能为空', status: 400 }; + } + + const params: PostgrestParams = { + select: ` + id, + name, + description, + evaluation_point_groups_ids, + prompt_config, + created_at, + updated_at, + code + `, + filter: { + 'id': `eq.${id}` + } + }; + + const response = await postgrestGet('document_types', params); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + // 使用extractApiData提取数据 + const extractedData = extractApiData(response.data); + + if (!extractedData || extractedData.length === 0) { + return { error: '未找到文档类型', status: 404 }; + } + + const documentType = extractedData[0]; + + // 获取关联分组 + let groupIds: number[] = []; + + try { + // 尝试解析evaluation_point_groups_ids + if (typeof documentType.evaluation_point_groups_ids === 'string') { + // 如果是JSON字符串,解析它 + groupIds = JSON.parse(documentType.evaluation_point_groups_ids as unknown as string); + } else if (Array.isArray(documentType.evaluation_point_groups_ids)) { + // 如果已经是数组,直接使用 + groupIds = documentType.evaluation_point_groups_ids; + } else if (documentType.evaluation_point_groups_ids) { + // 其他情况,尝试将其转换为数组 + groupIds = [documentType.evaluation_point_groups_ids as unknown as number]; + } + } catch (error) { + console.error('解析分组ID失败:', error, '原始值:', documentType.evaluation_point_groups_ids); + groupIds = []; + } + + console.log(`文档类型 ${id} 的分组IDs:`, groupIds); + + const groupsResponse = await getEvaluationPointGroupsByIds(groupIds); + + if (groupsResponse.error) { + return { error: groupsResponse.error, status: 500 }; + } + + // 添加分组信息 + const typeWithGroups = { + ...documentType, + groups: groupsResponse.data || [] + }; + + return { data: convertToUIDocumentType(typeWithGroups) }; + } catch (error) { + console.error('获取文档类型详情失败:', error); + return { + error: error instanceof Error ? error.message : '获取文档类型详情失败', + status: 500 + }; + } +} + +/** + * 创建文档类型 + * @param documentType 文档类型数据 + * @returns 创建结果 + */ +export async function createDocumentType(documentType: DocumentTypeCreateDTO): Promise<{ + data?: DocumentTypeUI; + error?: string; + status?: number; +}> { + try { + // 验证必填字段 + if (!documentType.name) { + return { error: '文档类型名称不能为空', status: 400 }; + } + + if (!documentType.group_ids || documentType.group_ids.length === 0) { + return { error: '请至少选择一个关联的评查点分组', status: 400 }; + } + + // 目前因为关联操作是做单选的,所以传过来的拿第一个值即可。 + const groupId = documentType.group_ids[0]; + if (!groupId || isNaN(parseInt(groupId, 10))) { + return { error: '无效的评查点分组ID', status: 400 }; + } + const groupIds = parseInt(groupId, 10); // 修改为数组形式 + // const groupIds = [parseInt(groupId, 10)]; // 修改为数组形式 + + // 构建提示词配置 - 确保所有字段都有明确的设置 + const promptConfig: Record = { + llm_extract_template: null, + vlm_extract_template: null, + // evaluation_template: null, + execution_template: null, + summary_template: null + }; + + // 只有当ID存在且不为空字符串时才设置值 + if (documentType.llm_extraction_template_id) { + const llmId = documentType.llm_extraction_template_id; + if (isNaN(llmId)) { + return { error: '无效的llm抽取提示词模板ID', status: 400 }; + } + promptConfig.llm_extract_template = llmId; + } + + if (documentType.vlm_extraction_template_id) { + const vlmId = documentType.vlm_extraction_template_id; + if (isNaN(vlmId)) { + return { error: '无效的vlm抽取提示词模板ID', status: 400 }; + } + promptConfig.vlm_extract_template = vlmId; + } + + if (documentType.evaluation_template_id) { + const evaluationId = documentType.evaluation_template_id; + if (isNaN(evaluationId)) { + return { error: '无效的评查提示词模板ID', status: 400 }; + } + promptConfig.execution_template = evaluationId; + } + + if (documentType.summary_template_id) { + const summaryId = documentType.summary_template_id; + if (isNaN(summaryId)) { + return { error: '无效的总结提示词模板ID', status: 400 }; + } + promptConfig.summary_template = summaryId; + } + + // 构建API请求数据 - 始终包含prompt_config对象 + const apiDocumentType = { + name: documentType.name.trim(), + description: documentType.description || '', + evaluation_point_groups_ids: groupIds, + prompt_config: promptConfig, + code: documentType.code || null + }; + + // console.log('创建文档类型请求数据:', JSON.stringify(apiDocumentType, null, 2)); + // console.log('创建文档类型请求数据:', apiDocumentType); + // if(apiDocumentType){ + // throw new Error('测试错误'); + // } + + // 发送创建请求 + const response = await postgrestPost( + 'document_types', + apiDocumentType + ); + + if (response.error) { + console.error('创建文档类型API返回错误:', response.error, '状态码:', response.status); + return { error: response.error, status: response.status }; + } + + console.log('创建文档类型响应数据:', JSON.stringify(response.data, null, 2)); + + // 处理响应数据 + const newDocumentType = extractApiData(response.data); + + if (!newDocumentType) { + return { error: '创建文档类型失败: 无法获取新创建的数据', status: 500 }; + } + + // 获取关联分组信息 + const groupsResponse = await getEvaluationPointGroupsByIds(groupIds); + + // 添加分组信息并转换为UI类型 + const typeWithGroups = { + ...newDocumentType, + groups: groupsResponse.data || [] + }; + + return { data: convertToUIDocumentType(typeWithGroups) }; + } catch (error) { + console.error('创建文档类型失败:', error); + return { + error: error instanceof Error ? error.message : '创建文档类型失败', + status: 500 + }; + } +} + +/** + * 更新文档类型 + * @param id 文档类型ID + * @param documentType 文档类型数据 + * @returns 更新结果 + */ +export async function updateDocumentType(id: string, documentType: DocumentTypeUpdateDTO): Promise<{ + data?: DocumentTypeUI; + error?: string; + status?: number; +}> { + try { + // 验证必填字段 + if (!id) { + return { error: '文档类型ID不能为空', status: 400 }; + } + + if (!documentType.name) { + return { error: '文档类型名称不能为空', status: 400 }; + } + + if (!documentType.group_ids || documentType.group_ids.length === 0) { + return { error: '请至少选择一个关联的评查点分组', status: 400 }; + } + + // 将分组ID转换为数字数组 + const groupIds = documentType.group_ids.map(id => parseInt(id, 10)); + + // 构建提示词配置 - 始终创建一个包含所有字段的对象,并明确设置值 + const promptConfig: Record = { + llm_extract_template: null, + vlm_extract_template: null, + evaluation_template: null, + execution_template: null, + summary_template: null + }; + + // 只有当ID存在且不为空字符串时才设置值 + if (documentType.llm_extraction_template_id) { + const llmId = documentType.llm_extraction_template_id; + if (isNaN(llmId)) { + return { error: '无效的llm抽取提示词模板ID', status: 400 }; + } + promptConfig.llm_extract_template = llmId; + } + + if (documentType.vlm_extraction_template_id) { + const vlmId = documentType.vlm_extraction_template_id; + if (isNaN(vlmId)) { + return { error: '无效的vlm抽取提示词模板ID', status: 400 }; + } + promptConfig.vlm_extract_template = vlmId; + } + + if (documentType.evaluation_template_id) { + const evaluationId = documentType.evaluation_template_id; + if (isNaN(evaluationId)) { + return { error: '无效的评查提示词模板ID', status: 400 }; + } + promptConfig.execution_template = evaluationId; + } + + if (documentType.summary_template_id) { + const summaryId = documentType.summary_template_id; + if (isNaN(summaryId)) { + return { error: '无效的总结提示词模板ID', status: 400 }; + } + promptConfig.summary_template = summaryId; + } + + // 构建API请求数据 - 始终包含prompt_config对象 + const apiDocumentType = { + name: documentType.name.trim(), + description: documentType.description || '', + evaluation_point_groups_ids: groupIds, + prompt_config: promptConfig, + code: documentType.code || null + }; + + console.log('更新文档类型请求数据:', JSON.stringify(apiDocumentType, null, 2)); + + // 发送更新请求 + const response = await postgrestPut( + 'document_types', + apiDocumentType, + {id} + ); + + if (response.error) { + console.error('更新文档类型API返回错误:', response.error, '状态码:', response.status); + return { error: response.error, status: response.status }; + } + + console.log('更新文档类型响应数据:', JSON.stringify(response.data, null, 2)); + + // 处理响应数据 + const updatedDocumentType = extractApiData(response.data); + + if (!updatedDocumentType) { + return { error: '更新文档类型失败: 无法获取更新后的数据', status: 500 }; + } + + // 获取关联分组信息 + const groupsResponse = await getEvaluationPointGroupsByIds(groupIds); + + // 添加分组信息并转换为UI类型 + const typeWithGroups = { + ...updatedDocumentType, + groups: groupsResponse.data || [] + }; + + return { data: convertToUIDocumentType(typeWithGroups) }; + } catch (error) { + console.error('更新文档类型失败:', error); + return { + error: error instanceof Error ? error.message : '更新文档类型失败', + status: 500 + }; + } +} \ No newline at end of file diff --git a/app/api/files/documents.ts b/app/api/files/documents.ts new file mode 100644 index 0000000..61ab079 --- /dev/null +++ b/app/api/files/documents.ts @@ -0,0 +1,318 @@ +import { postgrestGet, postgrestDelete, type PostgrestParams } from '../postgrest-client'; +import dayjs from 'dayjs'; +import { getDocumentTypes } from '../document-types/document-types'; + +/** + * 从不同格式的 API 响应中提取数据 + * @param responseData API 响应数据 + * @returns 提取后的数据或 null + */ +function extractApiData(responseData: unknown): T | null { + if (!responseData) return null; + + // 格式1: { code: number, msg: string, data: T } + if (typeof responseData === 'object' && responseData !== null && + 'code' in responseData && + 'data' in responseData && + (responseData as { data: unknown }).data) { + return (responseData as { data: T }).data; + } + + // 格式2: 直接是数据对象 + return responseData as T; +} + +/** + * 格式化日期 + * @param dateString 日期字符串 + * @returns 格式化后的日期字符串 + */ +function formatDate(dateString: string): string { + if (!dateString) return ''; + try { + return dayjs(dateString).format('YYYY-MM-DD HH:mm:ss'); + } catch (error) { + console.error('日期格式化失败:', error); + return dateString; + } + } + +/** + * 查询参数 + */ +export interface DocumentSearchParams { + name?: string; + documentNumber?: string; + documentType?: string; + status?: string; + dateFrom?: string; + dateTo?: string; + page?: number; + pageSize?: number; +} + +/** + * 数据库文档结构 + */ +export interface Document { + id: number; + user_id: number | null; + type_id: number; + name: string; + document_number: string; + path: string; + storage_type: string; + file_size: number; + upload_time: string; + is_test_document: boolean; + evaluation_level: string; + status: 'pass' | 'warning' | 'waiting' | 'processing' | 'fail'; + ocr_result: unknown; + extracted_results: unknown; + summary: unknown; + remark: string; + created_at: string; + updated_at: string; +} + +/** + * 前端UI文档结构 + */ +export interface DocumentUI { + id: number; + name: string; + documentNumber: string; + type: string; + typeName: string; + size: number; + status: string; + issues: number | null; + uploadTime: string; + fileType: string; + path: string; + isTest: boolean; +} + +/** + * 获取文件扩展名 + * @param filename 文件名 + * @returns 文件扩展名 + */ +function getFileExtension(filename: string): string { + const parts = filename.split('.'); + return parts.length > 1 ? parts.pop()?.toLowerCase() || '' : ''; +} + +/** + * 将API文档转换为UI文档 + */ +async function convertToUIDocument(doc: Document): Promise { + // 获取文档类型信息 + const typeResponse = await getDocumentTypes(); + const documentTypes = typeResponse.data?.types || []; + const docType = documentTypes.find(type => type.id.toString() === doc.type_id.toString()); + + return { + id: doc.id, + name: doc.name, + documentNumber: doc.document_number, + type: doc.type_id.toString(), + typeName: docType?.name || '未知类型', + size: doc.file_size, + status: doc.status, + issues: 0, // 固定为0 + uploadTime: formatDate(doc.updated_at), + fileType: getFileExtension(doc.name), + path: doc.path, + isTest: doc.is_test_document + }; +} + +/** + * 获取文档列表 + * @param searchParams 搜索参数 + * @returns 文档列表和总数 + */ +export async function getDocuments(searchParams: DocumentSearchParams = {}): Promise<{ + data?: { documents: DocumentUI[], total: number }; + error?: string; + status?: number; +}> { + try { + const page = searchParams.page || 1; + const pageSize = searchParams.pageSize || 10; + + // 构建查询参数 + const params: PostgrestParams = { + select: '*', + order: 'updated_at.desc', + headers: { + 'Prefer': 'count=exact' + }, + limit: pageSize, + offset: (page - 1) * pageSize, + filter: {} as Record + }; + + // 添加筛选条件 + const filter: Record = {}; + + if (searchParams.name) { + filter['name'] = `ilike.%${searchParams.name}%`; + } + + if (searchParams.documentNumber) { + filter['document_number'] = `ilike.%${searchParams.documentNumber}%`; + } + + if (searchParams.documentType) { + filter['type_id'] = `eq.${searchParams.documentType}`; + } + + if (searchParams.status) { + filter['status'] = `eq.${searchParams.status}`; + } + + // 处理日期范围 + if (searchParams.dateFrom) { + filter['updated_at'] = `gte.${searchParams.dateFrom}`; + } + + if (searchParams.dateTo) { + const dateToKey = searchParams.dateFrom ? 'and.updated_at.lte' : 'updated_at'; + filter[dateToKey] = `lte.${searchParams.dateTo}`; + } + + params.filter = filter; + + // 发送请求 + const response = await postgrestGet('documents', params); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + // 提取数据 + const extractedData = extractApiData(response.data); + if (!extractedData) { + return { error: '获取文档数据失败', status: 500 }; + } + + // 转换为UI格式 + const documents = await Promise.all(extractedData.map(convertToUIDocument)); + + // 获取总数 + let totalCount = 0; + const responseWithHeaders = response as { + data: unknown; + headers?: Record + }; + + if (responseWithHeaders.headers) { + const rangeHeader = responseWithHeaders.headers['content-range']; + if (rangeHeader) { + const total = rangeHeader.split('/')[1]; + if (total !== '*') { + totalCount = parseInt(total, 10); + } + } + } + + return { + data: { + documents, + total: totalCount || documents.length + } + }; + } catch (error) { + console.error('获取文档列表失败:', error); + return { + error: error instanceof Error ? error.message : '获取文档列表失败', + status: 500 + }; + } +} + +/** + * 删除文档 + * @param id 文档ID + * @returns 删除结果 + */ +export async function deleteDocument(id: string): Promise<{ + success?: boolean; + error?: string; + status?: number; +}> { + try { + if (!id) { + return { error: '文档ID不能为空', status: 400 }; + } + + const response = await postgrestDelete( + 'documents', + { + filter: { + 'id': `eq.${id}` + } + } + ); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + return { success: true }; + } catch (error) { + console.error('删除文档失败:', error); + return { + error: error instanceof Error ? error.message : '删除文档失败', + status: 500 + }; + } +} + +/** + * 获取单个文档详情 + * @param id 文档ID + * @returns 文档详情 + */ +export async function getDocument(id: string): Promise<{ + data?: DocumentUI; + error?: string; + status?: number; +}> { + try { + if (!id) { + return { error: '文档ID不能为空', status: 400 }; + } + + const response = await postgrestGet( + 'documents', + { + filter: { + 'id': `eq.${id}` + }, + limit: 1 + } + ); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + const extractedData = extractApiData(response.data); + if (!extractedData || extractedData.length === 0) { + return { error: '文档不存在', status: 404 }; + } + + const documentUI = await convertToUIDocument(extractedData[0]); + + return { data: documentUI }; + } catch (error) { + console.error('获取文档详情失败:', error); + return { + error: error instanceof Error ? error.message : '获取文档详情失败', + status: 500 + }; + } +} \ No newline at end of file diff --git a/app/api/filesApi.ts b/app/api/filesApi.ts index c36395a..b7f2340 100644 --- a/app/api/filesApi.ts +++ b/app/api/filesApi.ts @@ -64,16 +64,22 @@ export async function getDocumentType(id: string): Promise { } // 创建文档类型 +// 请使用 ~/api/document-types/document-types.ts 中的实现 +/* export async function createDocumentType(documentType: Omit): Promise { const url = buildUrl('/api/document-types'); return apiRequest(url, 'POST', documentType); } +*/ // 更新文档类型 +// 请使用 ~/api/document-types/document-types.ts 中的实现 +/* export async function updateDocumentType(id: string, documentType: Partial>): Promise { const url = buildUrl(`/api/document-types/${id}`); return apiRequest(url, 'PUT', documentType); } +*/ // 删除文档类型 export async function deleteDocumentType(id: string): Promise { diff --git a/app/api/prompts/prompts.ts b/app/api/prompts/prompts.ts index 18b4b2d..58b0277 100644 --- a/app/api/prompts/prompts.ts +++ b/app/api/prompts/prompts.ts @@ -20,7 +20,7 @@ export interface PromptTemplate { export interface PromptTemplateUI { id: string; template_name: string; - template_type: 'Extraction' | 'Evaluation' | 'Summary' | 'Common'; + template_type: 'LLM_Extraction' | 'VLM_Extraction' | 'Evaluation' | 'Summary' | 'Common'; description: string; template_content: string; variables: Record; // 变量定义 @@ -112,7 +112,7 @@ export function convertToUITemplate(template: PromptTemplate): PromptTemplateUI return { id: template.id ? template.id.toString() : '', template_name: template.template_name, - template_type: template.template_type as "Extraction" | "Evaluation" | "Summary" | "Common", + template_type: template.template_type as "LLM_Extraction" | "VLM_Extraction" | "Evaluation" | "Summary" | "Common", description: template.description || '', template_content: template.template_content, variables: template.variables, @@ -207,7 +207,7 @@ export async function getPromptTemplates(searchParams: PromptSearchParams = {}): return { error: '获取提示词模板数据失败', status: 500 }; } - console.log(`成功获取${extractedData.length}条提示词模板数据`); + // console.log(`成功获取${extractedData.length}条提示词模板数据`); // 从响应头中获取总数 let totalCount = 0; diff --git a/app/components/layout/Sidebar.tsx b/app/components/layout/Sidebar.tsx index 663fb02..51ad4b4 100644 --- a/app/components/layout/Sidebar.tsx +++ b/app/components/layout/Sidebar.tsx @@ -49,6 +49,12 @@ export function Sidebar({ onToggle, collapsed }: SidebarProps) { path:'/documents', icon:'ri-file-list-3-line' } + // { + // id:'documents-edit', + // title:'文档编辑', + // path:'/documents/edit', + // icon:'ri-file-edit-line' + // } ] }, { @@ -110,7 +116,7 @@ export function Sidebar({ onToggle, collapsed }: SidebarProps) { { id: 'document-types', title: '文档类型', - path: '/doc-types', + path: '/document-types', icon: 'ri-file-list-line' }, { diff --git a/app/components/ui/FileTypeTag.tsx b/app/components/ui/FileTypeTag.tsx index 419aedc..aa3cba3 100644 --- a/app/components/ui/FileTypeTag.tsx +++ b/app/components/ui/FileTypeTag.tsx @@ -14,6 +14,7 @@ interface FileTypeTagProps { className?: string; size?: 'default' | 'sm' | 'lg'; showIcon?: boolean; + fileType?: string; } export function links() { @@ -28,13 +29,15 @@ export function links() { * @param className 额外的类名 * @param size 尺寸:default, sm, lg * @param showIcon 是否显示图标,默认为true + * @param fileType 文件类型,不提供则使用文档类型决定样式 */ export function FileTypeTag({ type, text, className = '', size = 'default', - showIcon = true + showIcon = true, + fileType }: FileTypeTagProps) { // 文档类型对应的图标 const getTypeIcon = () => { @@ -64,9 +67,37 @@ export function FileTypeTag({ // 获取文档类型对应的类名 const getTypeClass = () => { + // 如果有文件类型,优先使用文件类型决定样式 + if (fileType) { + const fileTypeClass = getFileTypeClass(fileType); + if (fileTypeClass) { + return `file-type-tag ${fileTypeClass}`; + } + } return `file-type-tag file-type-${type}`; }; + // 根据文件扩展名获取对应的样式类名 + const getFileTypeClass = (ext: string) => { + ext = ext.toLowerCase(); + if (ext === 'pdf') { + return 'file-type-tag-pdf'; + } else if (ext === 'doc' || ext === 'docx') { + return 'file-type-tag-doc'; + } else if (ext === 'xls' || ext === 'xlsx') { + return 'file-type-tag-xls'; + } else if (ext === 'ppt' || ext === 'pptx') { + return 'file-type-tag-ppt'; + } else if (ext === 'zip' || ext === 'rar') { + return 'file-type-tag-zip'; + } else if (ext === 'jpg' || ext === 'jpeg' || ext === 'png' || ext === 'gif') { + return 'file-type-tag-img'; + } else if (ext === 'txt') { + return 'file-type-tag-txt'; + } + return null; + }; + // 获取尺寸类名 const getSizeClass = () => { return size !== 'default' ? `file-type-tag-${size}` : ''; diff --git a/app/routes/document-types._index.tsx b/app/routes/document-types._index.tsx index e69de29..0a1e825 100644 --- a/app/routes/document-types._index.tsx +++ b/app/routes/document-types._index.tsx @@ -0,0 +1,405 @@ +import { useState } from "react"; +import { useSearchParams, useNavigate, useLoaderData } from "@remix-run/react"; +import { ActionFunctionArgs, LoaderFunctionArgs, MetaFunction, json } from "@remix-run/node"; +import { Table } from "~/components/ui/Table"; +import { Card } from "~/components/ui/Card"; +import { Button } from "~/components/ui/Button"; +import { Pagination } from "~/components/ui/Pagination"; +import { FilterPanel, FilterSelect, SearchFilter } from "~/components/ui/FilterPanel"; +import { + getDocumentTypes, + deleteDocumentType, + getAllEvaluationPointGroups, + type DocumentTypeUI, + type DocumentTypeSearchParams, + type DocumentTypeGroup +} from "~/api/document-types/document-types"; +import documentTypesStyles from "~/styles/pages/document-types_index.css?url"; + +// 引入CSS样式 +export function links() { + return [ + { rel: "stylesheet", href: documentTypesStyles } + ]; +} + +// 页面元数据 +export const meta: MetaFunction = () => { + return [ + { title: "文档类型管理 - 中国烟草AI合同及卷宗审核系统" }, + { name: "description", content: "管理文档类型,包括查看、编辑和删除文档类型" }, + ]; +}; + +// 定义加载器返回的数据类型 +interface LoaderData { + types: DocumentTypeUI[]; + total: number; + pageSize: number; + currentPage: number; + error?: string; + groups: DocumentTypeGroup[]; +} + +// 加载函数 - 获取文档类型列表 +export async function loader({ request }: LoaderFunctionArgs) { + try { + const url = new URL(request.url); + const name = url.searchParams.get('name') || undefined; + const group_id = url.searchParams.get('group_id') || undefined; + const page = parseInt(url.searchParams.get('page') || '1', 10); + const pageSize = parseInt(url.searchParams.get('pageSize') || '10', 10); + + // 构建搜索参数 + const searchParams: DocumentTypeSearchParams = { + name, + group_id, + page, + pageSize + }; + + // 并行获取文档类型数据和所有评查点分组 + const [typesResult, groupsResult] = await Promise.all([ + getDocumentTypes(searchParams), + getAllEvaluationPointGroups() + ]); + + // console.log('文档类型数据:', typesResult.data?.types); + // console.log('评查点分组数据:', groupsResult.data); + + if (typesResult.error) { + return json( + { + types: [], + total: 0, + pageSize, + currentPage: page, + error: typesResult.error, + groups: groupsResult.data || [] + }, + { status: typesResult.status || 500 } + ); + } + + return json({ + types: typesResult.data?.types || [], + total: typesResult.data?.total || 0, + pageSize, + currentPage: page, + groups: groupsResult.data || [] + }); + } catch (error) { + console.error("加载文档类型列表失败:", error); + return json( + { + types: [], + total: 0, + pageSize: 10, + currentPage: 1, + error: "加载文档类型列表失败", + groups: [] + }, + { status: 500 } + ); + } +} + +// 动作函数 - 处理删除请求 +export async function action({ request }: ActionFunctionArgs) { + // 获取表单数据 + const formData = await request.formData(); + const id = formData.get("id") as string; + const intent = formData.get("intent") as string; + + if (intent === "delete" && id) { + try { + const result = await deleteDocumentType(id); + + if (result.error) { + return Response.json({ success: false, error: result.error }, { status: result.status || 500 }); + } + + return Response.json({ success: true }); + } catch (error) { + return Response.json( + { success: false, error: error instanceof Error ? error.message : "删除文档类型失败" }, + { status: 500 } + ); + } + } + + return Response.json({ success: false, error: "无效的操作" }, { status: 400 }); +} + +// 文档类型列表组件 +export default function DocumentTypesList() { + const navigate = useNavigate(); + const [searchParams, setSearchParams] = useSearchParams(); + const [isDeleting, setIsDeleting] = useState(false); + + // 获取加载器数据 + const { types, total, pageSize: initialPageSize, currentPage: initialPage, error, groups } = useLoaderData(); + + // 获取搜索参数 + const name = searchParams.get('name') || ''; + const group_id = searchParams.get('group_id') || ''; + const currentPage = parseInt(searchParams.get('page') || String(initialPage), 10); + const pageSize = parseInt(searchParams.get('pageSize') || String(initialPageSize), 10); + + // 处理名称搜索 + const handleNameSearch = (value: string) => { + const newParams = new URLSearchParams(searchParams); + if (value) { + newParams.set('name', value); + } else { + newParams.delete('name'); + } + newParams.set('page', '1'); + setSearchParams(newParams); + }; + + // 处理分组筛选 + const handleGroupChange = (e: React.ChangeEvent) => { + const { value } = e.target; + const newParams = new URLSearchParams(searchParams); + if (value) { + newParams.set('group_id', value); + } else { + newParams.delete('group_id'); + } + newParams.set('page', '1'); + setSearchParams(newParams); + }; + + // 处理重置筛选 + const handleReset = () => { + const nameInput = document.querySelector('input[name="name"]'); + if (nameInput) { + (nameInput as HTMLInputElement).value = ''; + } + const groupIdInput = document.querySelector('select[name="group_id"]'); + if (groupIdInput) { + (groupIdInput as HTMLSelectElement).value = ''; + } + setSearchParams(new URLSearchParams()); + }; + + // 处理删除文档类型 + const handleDelete = async (id: number) => { + if (confirm('确定要删除该文档类型吗?此操作不会影响关联的评查点分组,但可能会影响使用该类型的文档评查。')) { + setIsDeleting(true); + + try { + const formData = new FormData(); + formData.append('id', id.toString()); + formData.append('intent', 'delete'); + + const response = await fetch('/document-types?index', { + method: 'POST', + body: formData + }); + + const result = await response.json(); + + if (result.success) { + alert('删除成功!'); + // 刷新页面 + window.location.reload(); + } else { + alert(`删除失败: ${result.error || '未知错误'}`); + } + } catch (error) { + alert(`删除失败: ${error instanceof Error ? error.message : '未知错误'}`); + } finally { + setIsDeleting(false); + } + } + }; + + // 处理编辑文档类型 + const handleEdit = (id: number) => { + navigate(`/document-types/new?id=${id}`); + }; + + // 处理分页变更 + const handlePageChange = (page: number) => { + const newParams = new URLSearchParams(searchParams); + newParams.set('page', page.toString()); + setSearchParams(newParams); + }; + + // 处理每页条数变更 + const handlePageSizeChange = (size: number) => { + const newParams = new URLSearchParams(searchParams); + newParams.set('pageSize', size.toString()); + newParams.set('page', '1'); + setSearchParams(newParams); + }; + + // 定义表格列配置 + const columns = [ + { + title: "文档类型名称", + key: "name", + width: "200px", + render: (_: unknown, record: DocumentTypeUI) => ( +
+ + {record.name} +
+ ) + }, + { + title: "描述", + key: "description", + width: "300px", + render: (_: unknown, record: DocumentTypeUI) => ( +
+ {record.description} +
+ ) + }, + { + title: "关联的评查点分组", + key: "groups", + render: (_: unknown, record: DocumentTypeUI) => ( +
+ {record.groups && record.groups.length > 0 ? ( + record.groups.map(group => ( + + {group.name} + + )) + ) : ( + 暂无关联分组 + )} +
+ ) + }, + { + title: "创建时间", + key: "created_at", + width: "150px", + render: (_: unknown, record: DocumentTypeUI) => record.created_at + }, + { + title: "更新时间", + key: "updated_at", + width: "150px", + render: (_: unknown, record: DocumentTypeUI) => record.updated_at + }, + { + title: "操作", + key: "operation", + width: "150px", + render: (_: unknown, record: DocumentTypeUI) => ( + <> + + + + ) + } + ]; + + return ( +
+ {error && ( +
+

{error}

+
+ )} + + {/* 页面头部 */} +
+

文档类型管理

+
+ +
+
+ + {/* 搜索栏 */} + + + + } + noActionDivider={true} + > + + + ({ + value: group.id, + label: group.name + })) + ]} + onChange={handleGroupChange} + className="flex-1 min-w-[200px]" + /> + + + {/* 数据表格 */} + + + + {/* 分页 */} +
+ +
+ + + ); +} + diff --git a/app/routes/document-types.new.tsx b/app/routes/document-types.new.tsx new file mode 100644 index 0000000..a21e0a4 --- /dev/null +++ b/app/routes/document-types.new.tsx @@ -0,0 +1,614 @@ +import React, { useState, useEffect } from "react"; +import { Form, useActionData, useLoaderData, useNavigate, useSearchParams } from "@remix-run/react"; +import { redirect, type MetaFunction, type ActionFunctionArgs, type LoaderFunctionArgs } from "@remix-run/node"; +import { Card } from "~/components/ui/Card"; +import { Button } from "~/components/ui/Button"; +import documentTypesNewStyles from "~/styles/pages/document-types_new.css?url"; +import { getAllRuleGroups, type RuleGroup } from "~/api/evaluation_points/rule-groups"; +import { getDocumentType, createDocumentType, updateDocumentType } from "~/api/document-types/document-types"; +import { getPromptTemplates, type PromptTemplateUI } from "~/api/prompts/prompts"; + +export function links() { + return [{ rel: "stylesheet", href: documentTypesNewStyles }]; +} + +export const handle = { + breadcrumb: (data:LoaderData) => { + if (data.isEdit) { + return "编辑文档类型"; + } else { + return "新增文档类型"; + } + } +}; + +interface LoaderData { + isEdit: boolean; +} + +export const meta: MetaFunction = ({ location }) => { + const isEdit = new URLSearchParams(location.search).has("id"); + return [ + { title: `${isEdit ? "编辑" : "新增"}文档类型 - 中国烟草AI合同及卷宗审核系统` }, + { name: "description", content: `${isEdit ? "编辑" : "新增"}文档类型,设置文档类型名称、描述和关联的评查点分组` } + ]; +}; + +// 定义模板类型 +const TEMPLATE_TYPES = { + LLM_EXTRACTION: "LLM_Extraction", + VLM_EXTRACTION: "VLM_Extraction", + EVALUATION: "Evaluation", + SUMMARY: "Summary" +}; + + +// 加载函数 - 获取数据 +export async function loader({ request }: LoaderFunctionArgs) { + try { + const url = new URL(request.url); + const id = url.searchParams.get("id"); + const isEdit = id ? true : false; + + // 1. 获取评查点分组 - 使用getAllRuleGroups获取所有分组 + const ruleGroupsResponse = await getAllRuleGroups(); + if (ruleGroupsResponse.error) { + console.error("获取评查点分组失败:", ruleGroupsResponse.error); + } + + // ruleGroupsResponse.data已经是树形结构数据,getAllRuleGroups内部已处理好parent-children关系 + const groupsTree = ruleGroupsResponse.error ? [] : ruleGroupsResponse.data || []; + + + // 2. 获取各类型的提示词模板 + const [llmExtractionTemplatesResponse, vlmExtractionTemplatesResponse, evaluationTemplatesResponse, summaryTemplatesResponse] = + await Promise.all([ + getPromptTemplates({ type: TEMPLATE_TYPES.LLM_EXTRACTION }), + getPromptTemplates({ type: TEMPLATE_TYPES.VLM_EXTRACTION }), + getPromptTemplates({ type: TEMPLATE_TYPES.EVALUATION }), + getPromptTemplates({ type: TEMPLATE_TYPES.SUMMARY }) + ]); + + // 3. 如果是编辑模式,获取文档类型详情 + let documentType = undefined; + if (id) { + const typeResponse = await getDocumentType(id); + if (typeResponse.data) { + documentType = typeResponse.data; + } + } + + return Response.json({ + isEdit, + documentType, + ruleGroups: groupsTree, + llmExtractionTemplates: llmExtractionTemplatesResponse.data?.templates || [], + vlmExtractionTemplates: vlmExtractionTemplatesResponse.data?.templates || [], + evaluationTemplates: evaluationTemplatesResponse.data?.templates || [], + summaryTemplates: summaryTemplatesResponse.data?.templates || [] + }); + } catch (error) { + console.error("加载数据失败:", error); + return Response.json({ + isEdit: false, + documentType: undefined, + ruleGroups: [], + llmExtractionTemplates: [], + vlmExtractionTemplates: [], + evaluationTemplates: [], + summaryTemplates: [] + }); + } +} + +// 定义动作返回的数据类型 +interface ActionData { + success?: boolean; + errors?: { + name?: string; + groups?: string; + general?: string; + llmExtractionTemplate?: string; + vlmExtractionTemplate?: string; + evaluationTemplate?: string; + summaryTemplate?: string; + }; +} + +// 动作函数 - 处理表单提交 +export async function action({ request }: ActionFunctionArgs) { + const formData = await request.formData(); + const id = formData.get("id") as string | null; + const name = formData.get("name") as string; + const description = formData.get("description") as string; + const llmExtractionTemplateId = formData.get("llm_extraction_template") as string; + const vlmExtractionTemplateId = formData.get("vlm_extraction_template") as string; + const evaluationTemplateId = formData.get("evaluation_template") as string; + const summaryTemplateId = formData.get("summary_template") as string; + + // 获取选中的评查点分组ID列表 + const selectedGroups = formData.getAll("checkpoint_group_ids") as string[]; + + // 表单验证 + const errors: ActionData["errors"] = {}; + + // 收集所有错误 + if (!name || name.trim() === "") { + errors.name = "文档类型名称不能为空"; + } + + if (selectedGroups.length === 0) { + errors.groups = "请至少选择一个关联的评查点分组"; + } + + if (!llmExtractionTemplateId) { + errors.llmExtractionTemplate = "请选择llm抽取提示词模板"; + } + + if (!vlmExtractionTemplateId) { + errors.vlmExtractionTemplate = "请选择vlm抽取提示词模板"; + } + + if (!evaluationTemplateId) { + errors.evaluationTemplate = "请选择评查提示词模板"; + } + + if (!summaryTemplateId) { + errors.summaryTemplate = "请选择总结提示词模板"; + } + + // 如果有错误,返回错误信息 + if (Object.keys(errors).length > 0) { + return Response.json({ errors }); + } + + try { + // 构建文档类型数据 + const documentTypeData = { + name, + description, + group_ids: selectedGroups, + // 确保映射关系与prompt_config字段对应正确 + llm_extraction_template_id: llmExtractionTemplateId ? parseInt(llmExtractionTemplateId) : null, + vlm_extraction_template_id: vlmExtractionTemplateId ? parseInt(vlmExtractionTemplateId) : null, + evaluation_template_id: evaluationTemplateId ? parseInt(evaluationTemplateId) : null, + summary_template_id: summaryTemplateId ? parseInt(summaryTemplateId) : null + }; + + // 调用API创建或更新文档类型 + let response; + if (id) { + // 更新文档类型 + response = await updateDocumentType(id, { + ...documentTypeData, + id: parseInt(id) + }); + } else { + // 创建新文档类型 + response = await createDocumentType(documentTypeData); + } + + if (response.error) { + console.error("保存/更新文档类型失败:", response.error); + throw new Error(response.error); + } + + // 操作成功,重定向到列表页 + return redirect("/document-types"); + } catch (error) { + console.error("保存文档类型失败:", error); + return Response.json({ + success: false, + errors: { + general: error instanceof Error ? error.message : "保存文档类型失败" + } + }); + } +} + +export default function DocumentTypeNew() { + const navigate = useNavigate(); + const [searchParams] = useSearchParams(); + const isEditMode = searchParams.has("id"); + + const { + documentType, + ruleGroups, + llmExtractionTemplates, + vlmExtractionTemplates, + evaluationTemplates, + summaryTemplates + } = useLoaderData(); + + const actionData = useActionData(); + + // 状态管理 + const [formData, setFormData] = useState({ + id: documentType?.id || "", + name: documentType?.name || "", + description: documentType?.description || "", + llmExtractionTemplateId: documentType?.llm_extraction_template_id || "", + vlmExtractionTemplateId: documentType?.vlm_extraction_template_id || "", + evaluationTemplateId: documentType?.evaluation_template_id || "", + summaryTemplateId: documentType?.summary_template_id || "", + selectedGroups: documentType?.groups?.map((g: { id: string }) => g.id) || [] + }); + + // 添加本地验证错误状态 + const [localErrors, setLocalErrors] = useState({} as ActionData["errors"]); + + // 从actionData初始化本地错误 + useEffect(() => { + if (actionData?.errors) { + setLocalErrors(actionData.errors); + } + }, [actionData]); + + // 分组展开状态 + const [expandedGroups, setExpandedGroups] = useState>({}); + + // 当文档类型数据加载完成时更新表单 + useEffect(() => { + if (documentType) { + setFormData({ + id: documentType.id, + name: documentType.name, + description: documentType.description, + llmExtractionTemplateId: documentType.llm_extraction_template_id || "", + vlmExtractionTemplateId: documentType.vlm_extraction_template_id || "", + evaluationTemplateId: documentType.evaluation_template_id || "", + summaryTemplateId: documentType.summary_template_id || "", + selectedGroups: documentType.groups.map((g: { id: string }) => g.id) + }); + + // 初始化展开状态 - 对于有选中子分组的父分组,默认展开 + const newExpandedGroups: Record = {}; + + ruleGroups.forEach((parentGroup: RuleGroup) => { + // 如果父分组被选中或者有子分组被选中,则展开 + const isParentSelected = documentType.groups.some((g: { id: string }) => g.id === parentGroup.id); + const hasSelectedChild = parentGroup.children && + parentGroup.children.some(child => + documentType.groups.some((g: { id: string }) => g.id === child.id) + ); + + if (isParentSelected || hasSelectedChild) { + newExpandedGroups[parentGroup.id] = true; + } + }); + + setExpandedGroups(newExpandedGroups); + } + }, [documentType, ruleGroups]); + + // 处理分组勾选 + const handleGroupCheckChange = ( + groupId: string, + isChecked: boolean + ) => { + // 单选模式:清空之前所有选择,只保留当前选中的 + let newSelectedGroups: string[] = []; + + if (isChecked) { + // 只添加当前选中的分组 + newSelectedGroups = [groupId]; + + // 如果选择的是父分组,不自动选择子分组 + // 如果选择的是子分组,不影响父分组状态 + } + // 如果取消选中,则清空选择(在单选模式下可能不需要,但保留逻辑以防万一) + + setFormData(prev => ({ ...prev, selectedGroups: newSelectedGroups })); + + // 清除groups相关的错误 + if (localErrors?.groups) { + setLocalErrors(prev => ({...prev, groups: undefined})); + } + }; + + // 修复展开/折叠功能 + const handleGroupExpand = (groupId: string, event: React.MouseEvent) => { + // 阻止事件冒泡,避免触发checkbox选中 + event.stopPropagation(); + + setExpandedGroups(prev => ({ + ...prev, + [groupId]: !prev[groupId] + })); + }; + + // 处理表单输入变化 + const handleInputChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + + // 根据name属性映射到对应的formData字段 + if (name === 'llm_extraction_template') { + setFormData(prev => ({ ...prev, llmExtractionTemplateId: value })); + // 清除相关错误 + if (localErrors?.llmExtractionTemplate) { + setLocalErrors(prev => ({...prev, llmExtractionTemplate: undefined})); + } + } else if (name === 'vlm_extraction_template') { + setFormData(prev => ({ ...prev, vlmExtractionTemplateId: value })); + // 清除相关错误 + if (localErrors?.vlmExtractionTemplate) { + setLocalErrors(prev => ({...prev, vlmExtractionTemplate: undefined})); + } + } else if (name === 'evaluation_template') { + setFormData(prev => ({ ...prev, evaluationTemplateId: value })); + // 清除相关错误 + if (localErrors?.evaluationTemplate) { + setLocalErrors(prev => ({...prev, evaluationTemplate: undefined})); + } + } else if (name === 'summary_template') { + setFormData(prev => ({ ...prev, summaryTemplateId: value })); + // 清除相关错误 + if (localErrors?.summaryTemplate) { + setLocalErrors(prev => ({...prev, summaryTemplate: undefined})); + } + } else if (name === 'name') { + setFormData(prev => ({ ...prev, [name]: value })); + // 清除相关错误 + if (localErrors?.name) { + setLocalErrors(prev => ({...prev, name: undefined})); + } + } else { + // 其他表单字段(description等) + setFormData(prev => ({ ...prev, [name]: value })); + } + }; + + return ( +
+ {/* 页面头部 */} +
+

{isEditMode ? "编辑文档类型" : "新增文档类型"}

+
+ + +
+
+ + {/* 表单内容 */} + +
+ {/* 如果是编辑模式,添加隐藏的ID字段 */} + {formData.id && } + +
+ {/* 错误提示 */} + {localErrors?.general && ( +
+ + {localErrors.general} +
+ )} + + {/* 文档类型名称 */} +
+ + +
例如:销售合同、采购合同、专卖许可证等
+ {localErrors?.name && ( +
{localErrors.name}
+ )} +
+ + {/* 类型描述 */} +
+ + +
+ + {/* 提示词模板选择区域 */} +
+ {/* llm抽取提示词模板 */} +
+ + + {localErrors?.llmExtractionTemplate && ( +
{localErrors.llmExtractionTemplate}
+ )} +
选择用于从此类文档中抽取信息的llm提示词模板
+
+ + {/* vlm抽取提示词模板 */} +
+ + + {localErrors?.vlmExtractionTemplate && ( +
{localErrors.vlmExtractionTemplate}
+ )} +
选择用于从此类文档中抽取信息的vlm提示词模板
+
+ + {/* 评查提示词模板 */} +
+ + + {localErrors?.evaluationTemplate && ( +
{localErrors.evaluationTemplate}
+ )} +
选择用于评估此类文档内容的提示词模板
+
+ + {/* 总结提示词模板 */} +
+ + + {localErrors?.summaryTemplate && ( +
{localErrors.summaryTemplate}
+ )} +
选择用于生成此类文档摘要的提示词模板
+
+
+ + {/* 关联评查点分组 */} +
+
+ + 关联评查点分组 * + +
+ {ruleGroups.map((group: RuleGroup) => ( + + {/* 父分组 */} +
+ + handleGroupCheckChange(group.id, e.target.checked)} + className="radio-input" + /> + +
+ + {/* 子分组 */} + {group.children && group.children.length > 0 && expandedGroups[group.id] && ( + group.children.map((child: RuleGroup) => ( +
+ handleGroupCheckChange(child.id, e.target.checked)} + className="radio-input" + /> + +
+ )) + )} +
+ ))} +
+
选择与此文档类型关联的评查点分组,文档上传后将应用这些分组中的评查点进行审核
+ {localErrors?.groups && ( +
{localErrors.groups}
+ )} +
+
+
+ +
+
+ ); +} + diff --git a/app/routes/document-types.tsx b/app/routes/document-types.tsx index 679e3dd..af2b462 100644 --- a/app/routes/document-types.tsx +++ b/app/routes/document-types.tsx @@ -1,22 +1,24 @@ -import { Outlet } from "react-router-dom"; -import {type MetaFunction} from "@remix-run/node"; +import { Outlet } from "@remix-run/react"; +import { MetaFunction } from "@remix-run/node"; export const meta: MetaFunction = () => { return [ - {title: "文档类型列表 - 中国烟草AI合同及卷宗审核系统"}, - {name: "document-types", content: "文档类型列表,新增,修改"} + {title: "文档类型管理 - 中国烟草AI合同及卷宗审核系统"}, + {name: "description", content: "管理文档类型,包括查看、创建、编辑和删除文档类型"} ] } export const handle = { - breadcrumb: "文档类型列表" + breadcrumb: "文档类型管理" } /** - * 文档类型列表路由布局 + * 文档类型管理路由布局 */ export default function DocumentTypesLayout() { return ( - +
+ +
) } diff --git a/app/routes/documents._index.tsx b/app/routes/documents._index.tsx index 3de39fe..09b9350 100644 --- a/app/routes/documents._index.tsx +++ b/app/routes/documents._index.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { useSearchParams, Link } from "@remix-run/react"; +import { useSearchParams, Link, useLoaderData, useFetcher } from "@remix-run/react"; import { type MetaFunction, type ActionFunctionArgs, type LoaderFunctionArgs } from "@remix-run/node"; import { Card } from "~/components/ui/Card"; import { Button } from "~/components/ui/Button"; @@ -10,6 +10,8 @@ import { FileTypeTag } from "~/components/ui/FileTypeTag"; import { FileTag } from "~/components/ui/FileTag"; import { FilterPanel, FilterSelect, SearchFilter, DateRangeFilter } from "~/components/ui/FilterPanel"; import documentsIndexStyles from "~/styles/pages/documents_index.css?url"; +import { getDocuments, deleteDocument, type DocumentUI } from "~/api/files/documents"; +import { getDocumentTypes } from "~/api/document-types/document-types"; // 导入样式 export function links() { @@ -26,20 +28,6 @@ export const meta: MetaFunction = () => { ]; }; -interface DocumentItem { - id: string; - name: string; - documentNumber: string; - type: string; - typeName: string; - size: number; - status: string; - issues: number | null; - uploadTime: string; - fileType: string; - tags?: string[]; -} - // 数据加载器 export const loader = async ({ request }: LoaderFunctionArgs) => { // 获取URL查询参数 @@ -51,84 +39,41 @@ export const loader = async ({ request }: LoaderFunctionArgs) => { const dateFrom = url.searchParams.get("dateFrom") || ""; const dateTo = url.searchParams.get("dateTo") || ""; const page = parseInt(url.searchParams.get("page") || "1", 10); - const pageSize = parseInt(url.searchParams.get("pageSize") || "20", 10); + const pageSize = parseInt(url.searchParams.get("pageSize") || "10", 10); - // 在实际应用中,这里会调用API获取数据 - // const response = await fetch(`/api/documents?search=${search}&...`); - // const data = await response.json(); - - // 使用模拟数据 - const mockData = { - documents: [ - { - id: "1", - name: "2023年度烟草销售框架合同.pdf", - documentNumber: "XS20230001", - type: "sales-contract", - typeName: "销售合同", - size: 2.5 * 1024 * 1024, // 2.5MB - status: "pass", - issues: 0, - uploadTime: "2023-10-15 15:30", - fileType: "pdf" - }, - { - id: "2", - name: "设备采购合同-打印机.docx", - documentNumber: "CG20230052", - type: "purchase-contract", - typeName: "采购合同", - size: 1.2 * 1024 * 1024, // 1.2MB - status: "warning", - issues: 3, - uploadTime: "2023-10-14 09:15", - fileType: "docx" - }, - { - id: "3", - name: "烟草零售许可证.pdf", - documentNumber: "ZM2023100345", - type: "license", - typeName: "专卖许可证", - size: 0.8 * 1024 * 1024, // 0.8MB - status: "pending", - issues: null, - uploadTime: "2023-10-13 14:20", - fileType: "pdf" - }, - { - id: "4", - name: "非法售烟行政处罚决定书.docx", - documentNumber: "CF20230087", - type: "punishment", - typeName: "行政处罚决定书", - size: 1.5 * 1024 * 1024, // 1.5MB - status: "processing", - issues: null, - uploadTime: "2023-10-10 16:45", - fileType: "docx" - }, - { - id: "5", - name: "烟草种植承包协议-2023.pdf", - documentNumber: "CB20230024", - type: "agreement", - typeName: "承包协议", - size: 3.2 * 1024 * 1024, // 3.2MB - status: "fail", - issues: 8, - uploadTime: "2023-10-09 10:30", - fileType: "pdf", - tags: ["测试"] - }, - ], - total: 156, + // 构建搜索参数 + const searchParams = { + name: search || undefined, + documentNumber: documentNumber || undefined, + documentType: documentType || undefined, + status: status || undefined, + dateFrom: dateFrom || undefined, + dateTo: dateTo || undefined, page, pageSize }; - // 返回数据 - return Response.json(mockData); + // 获取文档列表 + const documentsResponse = await getDocuments(searchParams); + if (documentsResponse.error) { + throw new Error(documentsResponse.error); + } + + // 获取文档类型列表,用于筛选条件 + const typesResponse = await getDocumentTypes(); + const documentTypes = typesResponse.data?.types || []; + const documentTypeOptions = documentTypes.map(type => ({ + value: type.id, + label: type.name + })); + + return Response.json({ + documents: documentsResponse.data?.documents || [], + total: documentsResponse.data?.total || 0, + page, + pageSize, + documentTypeOptions + }); }; // 处理表单提交和删除等操作 @@ -136,22 +81,31 @@ export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.formData(); const action = formData.get("_action"); - // 在实际应用中,这里会根据action类型调用相应的API - // 例如删除文档,批量删除,等等 - if (action === "delete") { - const id = formData.get("id"); - // await fetch(`/api/documents/${id}`, { method: "DELETE" }); + const id = formData.get("id") as string; + const response = await deleteDocument(id); + + if (response.error) { + return Response.json({ success: false, message: response.error }, { status: response.status || 500 }); + } + return Response.json({ success: true, message: "文档已成功删除" }); } if (action === "batchDelete") { - const ids = formData.getAll("ids"); - // await fetch(`/api/documents/batch-delete`, { - // method: "POST", - // body: JSON.stringify({ ids }), - // headers: { "Content-Type": "application/json" } - // }); + const ids = formData.getAll("ids") as string[]; + + // 批量删除处理 + const results = await Promise.all(ids.map(id => deleteDocument(id))); + const failures = results.filter(r => r.error); + + if (failures.length > 0) { + return Response.json({ + success: false, + message: `删除失败: ${failures.map(f => f.error).join(', ')}` + }, { status: 400 }); + } + return Response.json({ success: true, message: `已成功删除${ids.length}个文档` }); } @@ -159,18 +113,9 @@ export const action = async ({ request }: ActionFunctionArgs) => { return Response.json({ success: false, message: "未知操作" }, { status: 400 }); }; -// 文档类型选项 -const documentTypeOptions = [ - { value: "sales-contract", label: "销售合同" }, - { value: "purchase-contract", label: "采购合同" }, - { value: "license", label: "专卖许可证" }, - { value: "punishment", label: "行政处罚决定书" }, - { value: "agreement", label: "承包协议" }, -]; - // 文档状态选项 const documentStatusOptions = [ - { value: "pending", label: "待审核" }, + { value: "waiting", label: "待审核" }, { value: "processing", label: "审核中" }, { value: "pass", label: "通过" }, { value: "warning", label: "警告" }, @@ -203,7 +148,9 @@ const formatFileSize = (bytes: number) => { export default function DocumentsIndex() { const [searchParams, setSearchParams] = useSearchParams(); const [selectedRowKeys, setSelectedRowKeys] = useState([]); - + const loaderData = useLoaderData(); + const fetcher = useFetcher(); + // 从URL获取当前筛选条件 const search = searchParams.get("search") || ""; const documentType = searchParams.get("documentType") || ""; @@ -212,77 +159,10 @@ export default function DocumentsIndex() { const dateFrom = searchParams.get("dateFrom") || ""; const dateTo = searchParams.get("dateTo") || ""; const currentPage = parseInt(searchParams.get("page") || "1", 10); - const pageSize = parseInt(searchParams.get("pageSize") || "20", 10); + const pageSize = parseInt(searchParams.get("pageSize") || "10", 10); - // API 返回的模拟数据 - const mockData = { - documents: [ - { - id: "1", - name: "2023年度烟草销售框架合同.pdf", - documentNumber: "XS20230001", - type: "sales-contract", - typeName: "销售合同", - size: 2.5 * 1024 * 1024, // 2.5MB - status: "pass", - issues: 0, - uploadTime: "2023-10-15 15:30", - fileType: "pdf" - }, - { - id: "2", - name: "设备采购合同-打印机.docx", - documentNumber: "CG20230052", - type: "purchase-contract", - typeName: "采购合同", - size: 1.2 * 1024 * 1024, // 1.2MB - status: "warning", - issues: 3, - uploadTime: "2023-10-14 09:15", - fileType: "docx" - }, - { - id: "3", - name: "烟草零售许可证.pdf", - documentNumber: "ZM2023100345", - type: "license", - typeName: "专卖许可证", - size: 0.8 * 1024 * 1024, // 0.8MB - status: "pending", - issues: null, - uploadTime: "2023-10-13 14:20", - fileType: "pdf" - }, - { - id: "4", - name: "非法售烟行政处罚决定书.docx", - documentNumber: "CF20230087", - type: "punishment", - typeName: "行政处罚决定书", - size: 1.5 * 1024 * 1024, // 1.5MB - status: "processing", - issues: null, - uploadTime: "2023-10-10 16:45", - fileType: "docx" - }, - { - id: "5", - name: "烟草种植承包协议-2023.pdf", - documentNumber: "CB20230024", - type: "agreement", - typeName: "承包协议", - size: 3.2 * 1024 * 1024, // 3.2MB - status: "fail", - issues: 8, - uploadTime: "2023-10-09 10:30", - fileType: "pdf", - tags: ["测试"] - }, - ], - total: 156, - page: currentPage, - pageSize - }; + // 获取API返回的数据 + const { documents, total, documentTypeOptions } = loaderData; // 分页处理函数 const handlePageChange = (page: number) => { @@ -359,6 +239,30 @@ export default function DocumentsIndex() { // 重置搜索条件 const handleReset = () => { + // 直接重置所有筛选条件的DOM值 + const resetInput = (selector: string, value: string = "") => { + const element = document.querySelector(selector); + if (element) { + element.value = value; + + // 对于搜索框,触发其input事件以激活搜索 + if (element instanceof HTMLInputElement && element.type === "text") { + // 创建一个input事件 + const event = new Event('input', { bubbles: true }); + element.dispatchEvent(event); + } + } + }; + + // 重置所有搜索字段 + resetInput('input[placeholder="请输入文档名称"]'); + resetInput('input[placeholder="请输入文档编号"]'); + resetInput('select[name="documentType"]'); + resetInput('select[name="status"]'); + resetInput('input[name="dateFrom"]'); + resetInput('input[name="dateTo"]'); + + // 重置URL参数 setSearchParams(new URLSearchParams({ page: "1", pageSize: pageSize.toString() @@ -377,33 +281,57 @@ export default function DocumentsIndex() { // 全选处理 const handleSelectAll = (checked: boolean) => { if (checked) { - setSelectedRowKeys(mockData.documents.map(doc => doc.id)); + setSelectedRowKeys(documents.map((doc: DocumentUI) => doc.id.toString())); } else { setSelectedRowKeys([]); } }; - // 删除确认 - const confirmDelete = (id: string, name: string) => { + // 下载文档 + const handleDownload = (path: string, fileName: string) => { + console.log('handleDownload',path,fileName) + // 创建一个隐藏的a标签并点击它 + const a = document.createElement('a'); + a.href = path; + a.download = fileName; // 设置下载的文件名 + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + }; + + // 删除文档 + const handleDelete = (id: string, name: string) => { if (window.confirm(`确认删除文档 "${name}"?`)) { - // 在实际应用中这里会提交表单到action处理 - console.log('删除文档:', id, name); + // 使用fetcher提交表单 + const formData = new FormData(); + formData.append('_action', 'delete'); + formData.append('id', id); + + fetcher.submit(formData, { method: 'post' }); // 更新选中行 setSelectedRowKeys(selectedRowKeys.filter(key => key !== id)); } }; - // 批量删除确认 - const confirmBatchDelete = () => { + // 批量删除 + const handleBatchDelete = () => { if (selectedRowKeys.length === 0) { alert('请至少选择一个文档'); return; } if (window.confirm(`确认删除选中的 ${selectedRowKeys.length} 个文档?`)) { - // 在实际应用中这里会提交表单到action处理 - console.log('批量删除文档IDs:', selectedRowKeys); + // 使用fetcher提交表单 + const formData = new FormData(); + formData.append('_action', 'batchDelete'); + + // 添加所有选中的ID + selectedRowKeys.forEach(id => { + formData.append('ids', id); + }); + + fetcher.submit(formData, { method: 'post' }); // 清空选中行 setSelectedRowKeys([]); @@ -416,24 +344,24 @@ export default function DocumentsIndex() { title: ( handleSelectAll(e.target.checked)} /> ), key: "selection", width: "50px", - render: (_: unknown, record: DocumentItem) => ( + render: (_: unknown, record: DocumentUI) => ( handleRowSelectionChange(record.id)} + checked={selectedRowKeys.includes(record.id.toString())} + onChange={() => handleRowSelectionChange(record.id.toString())} /> ) }, { title: "文档名称", key: "name", - render: (_: unknown, record: DocumentItem) => ( + render: (_: unknown, record: DocumentUI) => (
- {record.tags && record.tags.map((tag: string) => ( - {tag} - ))} + {record.isTest && ( + 测试 + )}
@@ -463,41 +392,43 @@ export default function DocumentsIndex() { { title: "文档编号", key: "documentNumber", - render: (_: unknown, record: DocumentItem) => ( + render: (_: unknown, record: DocumentUI) => ( {record.documentNumber} ) }, { title: "文件大小", key: "size", - render: (_: unknown, record: DocumentItem) => formatFileSize(record.size) + width: "100px", + render: (_: unknown, record: DocumentUI) => formatFileSize(record.size) }, { title: "审核状态", key: "status", - render: (_: unknown, record: DocumentItem) => ( + render: (_: unknown, record: DocumentUI) => ( ) }, { title: "问题数量", key: "issues", - render: (_: unknown, record: DocumentItem) => ( + width:"60px", + render: (_: unknown, record: DocumentUI) => ( record.issues === null ? "-" : record.issues ) }, { title: "上传时间", key: "uploadTime", - render: (_: unknown, record: DocumentItem) => record.uploadTime + render: (_: unknown, record: DocumentUI) => record.uploadTime }, { title: "操作", key: "actions", width: "280px", - render: (_: unknown, record: DocumentItem) => ( + render: (_: unknown, record: DocumentUI) => (
- {record.status === "pending" ? ( + {record.status === "waiting" ? ( )} @@ -532,7 +463,7 @@ export default function DocumentsIndex() { - + */} } noActionDivider={true} @@ -648,7 +579,7 @@ export default function DocumentsIndex() {
- 共 {mockData.total} 条记录 + 共 {total} 条记录
@@ -678,7 +609,7 @@ export default function DocumentsIndex() { {/* 分页 */} { + return [ + { title: "修改文档 - 中国烟草AI合同及卷宗审核系统" }, + { name: "description", content: "修改文档信息,包括文档类型、编号、状态和备注信息等" } + ]; +}; + +// 文档状态定义 +enum DocumentStatus { + PENDING = "pending", + PROCESSING = "processing", + PASS = "pass", + WARNING = "warning", + FAIL = "fail" +} + +// 文档状态对应的中文标签 +const STATUS_LABELS: Record = { + [DocumentStatus.PENDING]: "待审核", + [DocumentStatus.PROCESSING]: "审核中", + [DocumentStatus.PASS]: "通过", + [DocumentStatus.WARNING]: "警告", + [DocumentStatus.FAIL]: "不通过" +}; + +// 文档类型接口 +interface DocumentType { + id: string; + name: string; +} + +// 历史记录项接口 +interface HistoryItem { + time: string; + user: string; + action: string; + details: string; +} + +// 文档接口 +interface Document { + id: string; + name: string; + type_id: string; + document_number: string | null; + file_size: number; + upload_time: string; + is_test_document: boolean; + status: DocumentStatus; + remark: string | null; + history: HistoryItem[]; + file_url?: string; +} + +// 模拟API获取文档类型列表 +async function getDocumentTypes(): Promise { + // 这里应该是实际API调用 + return [ + { id: "1", name: "销售合同" }, + { id: "2", name: "采购合同" }, + { id: "3", name: "专卖许可证" }, + { id: "4", name: "行政处罚决定书" }, + { id: "5", name: "承包协议" } + ]; +} + +// 模拟API获取文档详情 +async function getDocument(id: string): Promise { + // 这里应该是实际API调用 + return { + id, + name: "2023年度烟草销售框架合同.pdf", + type_id: "1", // 销售合同 + document_number: "XS20230001", + file_size: 2.5 * 1024 * 1024, // 2.5MB + upload_time: "2023-10-15 15:30", + is_test_document: false, + status: DocumentStatus.PASS, + remark: "此合同为2023年度与XX公司的销售框架协议,适用于全年的烟草销售业务。", + history: [ + { + time: "2023-10-15 15:30", + user: "系统", + action: "创建了此文档", + details: "首次上传文档,文档类型:销售合同,状态:待审核" + }, + { + time: "2023-10-15 16:45", + user: "张三", + action: "启动了文档审核", + details: "状态由'待审核'变更为'审核中'" + }, + { + time: "2023-10-15 17:20", + user: "系统", + action: "完成了文档审核", + details: "状态由'审核中'变更为'通过',未发现问题" + }, + { + time: "2023-10-16 09:10", + user: "李四", + action: "修改了文档属性", + details: "添加了备注信息,完善了文档编号" + } + ], + file_url: "/mock/documents/sample.pdf" + }; +} + +// 模拟API更新文档信息 +async function updateDocument(id: string, data: Partial): Promise { + // 这里应该是实际API调用 + console.log("更新文档:", id, data); + + // 模拟获取原始数据 + const document = await getDocument(id); + + // 合并更新的数据 + const updatedDocument = { + ...document, + ...data, + // 添加新的历史记录 + history: [ + { + time: new Date().toISOString().replace("T", " ").slice(0, 16), + user: "当前用户", + action: "修改了文档信息", + details: `更新了文档类型、状态和备注信息` + }, + ...document.history + ] + }; + + return updatedDocument; +} + +// 格式化文件大小 +function formatFileSize(bytes: number): string { + if (bytes === 0) return "0 Bytes"; + + const k = 1024; + const sizes = ["Bytes", "KB", "MB", "GB", "TB"]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; +} + +// Loader函数 +export async function loader({ request }: LoaderFunctionArgs) { + try { + // 从URL查询参数获取文档ID + const url = new URL(request.url); + const id = url.searchParams.get("id"); + + if (!id) { + throw new Response("缺少文档ID", { status: 400 }); + } + + // 并行获取文档详情和文档类型列表 + const [document, documentTypes] = await Promise.all([ + getDocument(id), + getDocumentTypes() + ]); + + return Response.json({ document, documentTypes }); + } catch (error) { + console.error("加载文档数据失败:", error); + throw new Response("加载文档数据失败", { status: 500 }); + } +} + +// Action函数处理表单提交 +export async function action({ request }: ActionFunctionArgs) { + // 从URL查询参数获取文档ID + const url = new URL(request.url); + const id = url.searchParams.get("id"); + + if (!id) { + return Response.json({ error: "缺少文档ID" }, { status: 400 }); + } + + try { + const formData = await request.formData(); + + // 从表单数据中提取字段 + const type_id = formData.get("type_id") as string; + const document_number = formData.get("document_number") as string; + const status = formData.get("status") as DocumentStatus; + const is_test_document = formData.get("is_test_document") === "on"; + const remark = formData.get("remark") as string; + + // 验证必填字段 + if (!type_id || !status) { + return Response.json( + { + error: "缺少必填字段", + fieldErrors: { + type_id: !type_id ? "文档类型不能为空" : null, + status: !status ? "状态不能为空" : null + } + }, + { status: 400 } + ); + } + + // 更新文档 + await updateDocument(id, { + type_id, + document_number: document_number || null, + status, + is_test_document, + remark: remark || null + }); + + // 重定向回文档列表 + return redirect("/documents"); + } catch (error) { + console.error("更新文档失败:", error); + return Response.json({ error: "更新文档失败" }, { status: 500 }); + } +} + +// 文档编辑页面组件 +export default function DocumentEdit() { + const { document, documentTypes } = useLoaderData(); + const actionData = useActionData(); + const navigate = useNavigate(); + + // 状态 + const [localStatus, setLocalStatus] = useState(document.status); + + // 处理状态变更 + const handleStatusChange = (e: React.ChangeEvent) => { + setLocalStatus(e.target.value as DocumentStatus); + }; + + // 获取文档类型名称 + const getDocumentTypeName = (typeId: string): string => { + const docType = documentTypes.find((type: DocumentType) => type.id === typeId); + return docType ? docType.name : "未知类型"; + }; + + // 渲染状态徽章 + const renderStatusBadge = (status: DocumentStatus) => { + const statusClasses: Record = { + [DocumentStatus.PENDING]: "status-badge status-pending", + [DocumentStatus.PROCESSING]: "status-badge status-processing", + [DocumentStatus.PASS]: "status-badge status-pass", + [DocumentStatus.WARNING]: "status-badge status-warning", + [DocumentStatus.FAIL]: "status-badge status-fail" + }; + + return ( + + {STATUS_LABELS[status]} + + ); + }; + + return ( +
+ {/* 页面头部 */} +
+

修改文档信息

+
+ + +
+
+ + {/* 文档信息 */} + +
+
+ +
+
+
{document.name}
+
+
+ + {getDocumentTypeName(document.type_id)} +
+
+ + {document.upload_time} +
+
+ + {formatFileSize(document.file_size)} +
+
+ {renderStatusBadge(document.status)} +
+
+
+
+ +
+ 您可以修改此文档的基本信息,但不能更改文档内容。如需修改内容,请删除后重新上传新文档。 +
+ +
+
+
+ + +
更改文档类型将重新应用对应的评查规则
+ {actionData?.fieldErrors?.type_id && ( +
{actionData.fieldErrors.type_id}
+ )} +
+ +
+ + +
如无编号可留空
+
+ +
+ + +
更改状态可能会影响此文档在列表中的显示和排序
+ {actionData?.fieldErrors?.status && ( +
{actionData.fieldErrors.status}
+ )} +
+ +
+
文档属性
+
+ + 标记为测试文档(不计入正式统计) +
+
+ +
+ + +
+
+ +
+ + {/* 文档预览 */} + +
+
+
+ + {document.name} +
+
+ +
+
+
+
+ +

预览功能暂不可用

+

PDF文件需要外部查看器支持

+ +
+
+
+
+ + {/* 修改历史 */} + +
+ {document.history.map((item: HistoryItem, index: number) => ( +
+
{item.time}
+
+
{item.user} {item.action}
+
{item.details}
+
+
+ ))} +
+
+
+ ); +} + +// 错误边界 +export function ErrorBoundary() { + return ( +
+

出错了

+

文档编辑页面加载失败。请检查文档ID是否正确,或稍后重试。

+ +
+ ); +} diff --git a/app/routes/files.upload.tsx b/app/routes/files.upload.tsx index 8a29bcb..2c2d159 100644 --- a/app/routes/files.upload.tsx +++ b/app/routes/files.upload.tsx @@ -30,21 +30,11 @@ export const meta: MetaFunction = () => { ]; }; -// 文件类型定义 -export enum FileType { - CONTRACT = "1", - LICENSE = "2", - PUNISHMENT = "3", - OTHER = "4" -} +// 文件类型定义为字符串类型,以适应从API动态获取的ID +export type FileType = string; -// 文件类型标签映射 -export const FILE_TYPE_LABELS: Record = { - [FileType.CONTRACT]: "合同文档", - [FileType.LICENSE]: "专卖许可证", - [FileType.PUNISHMENT]: "行政处罚决定书", - [FileType.OTHER]: "其他文档" -}; +// 动态构建的文件类型标签映射 +export const FILE_TYPE_LABELS: Record = {}; // 优先级定义 export enum Priority { @@ -85,7 +75,7 @@ export enum StepStatus { // 上传的文件信息接口 export interface UploadedFile { - id: string; + id: number; name: string; size: number; type: string; @@ -346,6 +336,19 @@ export default function FilesUpload() { const [queueFiles, setQueueFiles] = useState(documents); const [documentTypesState] = useState(documentTypes); + // 构建文件类型标签映射 + useEffect(() => { + // 清空之前的映射 + Object.keys(FILE_TYPE_LABELS).forEach(key => { + delete FILE_TYPE_LABELS[key]; + }); + + // 使用从API获取的文档类型构建新的映射 + documentTypes.forEach(type => { + FILE_TYPE_LABELS[type.id.toString()] = type.name; + }); + }, [documentTypes]); + // 上传完成后的文件信息列表 const [completedFiles, setCompletedFiles] = useState([]); @@ -388,7 +391,7 @@ export default function FilesUpload() { // 获取所有未完成的文档ID const incompleteIds = queueFiles - .filter(file => file.status !== DocumentStatus.COMPLETED) + .filter(file => file.status !== DocumentStatus.COMPLETED && file.id) .map(file => file.id); console.log('未完成的文档ID:', incompleteIds); @@ -435,12 +438,17 @@ export default function FilesUpload() { // 处理文件类型变化 const handleFileTypeChange = (e: React.ChangeEvent) => { - const newFileType = e.target.value as FileType; - setFileType(newFileType); - - // 如果已经有选中的文件,且选择了文件类型,则开始上传 - if (currentFiles.length > 0 && newFileType) { - startUpload(currentFiles); + const value = e.target.value; + // 确保只有选择了有效的文件类型才进行设置 + if (value) { + setFileType(value as FileType); + + // 如果已经有选中的文件,且选择了文件类型,则开始上传 + if (currentFiles.length > 0) { + startUpload(currentFiles); + } + } else { + setFileType(""); } }; @@ -510,7 +518,7 @@ export default function FilesUpload() { // 创建新的文件对象 const newFile: UploadedFile = { - id: response.result.id.toString(), + id: response.result.id, name: response.result.file_name, size: response.result.file_size, type: file.type, @@ -537,14 +545,18 @@ export default function FilesUpload() { setUploadSpeed("完成"); // 更新队列 - const newDocuments: Document[] = uploadedFiles.map(file => ({ - id: parseInt(file.id), - name: file.name, - type_id: parseInt(fileType), - file_size: file.size, - status: DocumentStatus.CUTTING, - created_at: new Date().toISOString() - })); + const newDocuments: Document[] = uploadedFiles.map(file => { + // 确保id能够被正确解析为数字 + const id = file.id; + return { + id, + name: file.name, + type_id: fileType ? parseInt(fileType) : 0, + file_size: file.size, + status: DocumentStatus.CUTTING, + created_at: new Date().toISOString() + }; + }); setQueueFiles(prev => [...newDocuments, ...prev]); @@ -587,7 +599,7 @@ export default function FilesUpload() { setProcessingSteps(updatedSteps); // 获取文件ID列表 - const fileIds = files.map(file => parseInt(file.id)); + const fileIds = files.map(file => file.id).filter(id => id > 0); console.log('开始处理文件,设置文件处理进度定时器'); @@ -802,8 +814,8 @@ export default function FilesUpload() { }; // 获取文档类型名称 - const getDocumentTypeName = (typeId: number) => { - const type = documentTypesState.find(t => t.id === typeId); + const getDocumentTypeName = (codeId: number) => { + const type = documentTypesState.find(t => t.id === codeId); return type ? type.name : '未知类型'; }; @@ -920,10 +932,9 @@ export default function FilesUpload() { disabled={uploadStage !== "idle"} > - - - - + {documentTypes.map(type => ( + + ))} {actionData?.errors?.fileType && ( @@ -1007,7 +1018,9 @@ export default function FilesUpload() {
  • 文件类型: - {FILE_TYPE_LABELS[file.fileType]} + + {FILE_TYPE_LABELS[file.fileType] || getDocumentTypeName(parseInt(file.fileType))} +
  • 审核规则: diff --git a/app/routes/prompts._index.tsx b/app/routes/prompts._index.tsx index 017d6fc..d3b7d08 100644 --- a/app/routes/prompts._index.tsx +++ b/app/routes/prompts._index.tsx @@ -227,13 +227,17 @@ export default function PromptsIndex() { { title: "类型", key: "template_type", - width: "100px", + width: "120px", render: (_: unknown, record: PromptTemplateUI) => { let typeText = ''; let typeClass = ''; switch (record.template_type) { - case 'Extraction': + case 'LLM_Extraction': + typeText = '抽取'; + typeClass = 'type-extraction'; + break; + case 'VLM_Extraction': typeText = '抽取'; typeClass = 'type-extraction'; break; @@ -400,7 +404,8 @@ export default function PromptsIndex() { name="type" value={searchParams.get('type') || ''} options={[ - { value: "Extraction", label: "抽取(Extraction)" }, + { value: "LLM_Extraction", label: "LLM抽取(LLM_Extraction)" }, + { value: "VLM_Extraction", label: "VLM抽取(VLM_Extraction)" }, { value: "Evaluation", label: "评估(Evaluation)" }, { value: "Summary", label: "摘要(Summary)" }, { value: "Common", label: "通用(Common)" } diff --git a/app/routes/prompts.new.tsx b/app/routes/prompts.new.tsx index 313a014..27302c7 100644 --- a/app/routes/prompts.new.tsx +++ b/app/routes/prompts.new.tsx @@ -52,7 +52,7 @@ interface ActionData { }; formData?: { template_name: string; - template_type: "Extraction" | "Evaluation" | "Summary" | "Common"; + template_type: 'LLM_Extraction' | 'VLM_Extraction' | 'Evaluation' | 'Summary' | 'Common'; description: string; template_content: string; variables: string; @@ -108,7 +108,7 @@ export async function action({ request }: ActionFunctionArgs) { const formData = await request.formData(); const id = formData.get("id") as string; const template_name = formData.get("template_name") as string; - const template_type = formData.get("template_type") as "Extraction" | "Evaluation" | "Summary" | "Common"; + const template_type = formData.get("template_type") as 'LLM_Extraction' | 'VLM_Extraction' | 'Evaluation' | 'Summary' | 'Common'; const description = formData.get("description") as string; const template_content = formData.get("template_content") as string; const variables = formData.get("variables") as string; @@ -488,7 +488,8 @@ export default function PromptsNew() { > - + + diff --git a/app/styles/pages/document-types_index.css b/app/styles/pages/document-types_index.css index e69de29..7c7832e 100644 --- a/app/styles/pages/document-types_index.css +++ b/app/styles/pages/document-types_index.css @@ -0,0 +1,35 @@ +.document-types-page { + @apply w-full; +} + +.document-types-page .page-header { + @apply flex justify-between items-center mb-4; +} + +.document-types-page .page-title { + @apply text-xl font-medium; +} + +.document-types-page .type-badge { + @apply inline-flex items-center px-2 py-0.5 rounded-full text-xs bg-primary-50 text-primary-600 mr-1 mb-1; +} + +.document-types-page .groups-container { + @apply flex flex-wrap gap-1 max-w-md; +} + +.document-types-page .operation-btn { + @apply inline-flex items-center text-sm px-2 py-1 rounded hover:bg-gray-100; +} + +.document-types-page .operation-btn i { + @apply mr-1; +} + +.document-types-page .text-primary { + @apply text-primary-600; +} + +.document-types-page .text-error { + @apply text-red-600; +} diff --git a/app/styles/pages/document-types_new.css b/app/styles/pages/document-types_new.css new file mode 100644 index 0000000..71d97f5 --- /dev/null +++ b/app/styles/pages/document-types_new.css @@ -0,0 +1,142 @@ +.document-type-new-page { + @apply w-full; +} + +.document-type-new-page .page-header { + @apply flex justify-between items-center mb-4; +} + +.document-type-new-page .page-title { + @apply text-xl font-medium; +} + +.document-type-new-page .form-group { + @apply mb-4; +} + +.document-type-new-page .form-label { + @apply block text-sm font-medium text-gray-700 mb-1; +} + +.document-type-new-page .form-input, +.document-type-new-page .form-textarea, +.document-type-new-page .form-select { + @apply w-full rounded-md border border-gray-300 shadow-sm px-3 py-2 transition-all duration-300; + @apply focus:outline-none focus:border-[var(--primary-color)] focus:shadow-[0_0_0_2px_rgba(0,104,74,0.2)]; +} + +.document-type-new-page .form-textarea { + @apply resize-none; +} + +.document-type-new-page .form-tip { + @apply text-xs text-gray-500 mt-1; +} + +.document-type-new-page .input-error { + @apply border-red-500; +} + +.document-type-new-page .error-message { + @apply text-sm text-red-600 mt-1 font-medium; + display: flex; + align-items: center; +} + +.document-type-new-page .error-message::before { + content: "⚠️"; + margin-right: 0.25rem; +} + +.document-type-new-page .error-show { + display: flex !important; + color: #ff4d4f; + font-weight: 500; + visibility: visible; +} + +.document-type-new-page .general-error { + @apply flex items-center p-3 mb-4 bg-red-50 rounded-md text-red-600 text-sm; +} + +.document-type-new-page .general-error i { + @apply mr-2; +} + +.document-type-new-page .group-error { + @apply border border-red-500 rounded-md; +} + +/* 复选框样式 */ +.document-type-new-page .checkbox-group { + @apply flex flex-col gap-2 mt-2; +} + +.document-type-new-page .checkbox-item { + @apply flex items-center p-2 border border-gray-200 rounded cursor-pointer transition-all; +} + +.document-type-new-page .checkbox-item:hover { + @apply border-[var(--primary-color)] bg-[rgba(0,104,74,0.15)]; +} + +.document-type-new-page .checkbox-item.checked { + @apply border-[var(--primary-color)] bg-[rgba(0,104,74,0.25)]; +} + +/* 父子级分组样式 */ +.document-type-new-page .parent-checkbox-item { + @apply bg-gray-50 font-medium; +} + +.document-type-new-page .child-checkbox-item { + @apply ml-8 border-l-2 border-l-[var(--primary-color)]; +} + +.document-type-new-page .expand-icon { + @apply w-6 h-6 flex items-center justify-center rounded hover:bg-[rgba(0,104,74,0.15)] mr-2 cursor-pointer; +} + +.document-type-new-page .group-badge { + @apply inline-flex items-center px-2 py-0.5 rounded-full text-xs ml-2; +} + +.document-type-new-page .parent-badge { + @apply bg-[rgba(0,104,74,1)] text-white; +} + +.document-type-new-page .child-badge { + @apply bg-[rgba(0,104,1,0.61)] text-white; +} + +/* 添加checkbox-input样式,使用视觉上更美观的自定义复选框样式 */ +.document-type-new-page .checkbox-input { + @apply mr-2 h-4 w-4 text-primary-600 border-gray-300 rounded; + @apply focus:ring-primary-500 cursor-pointer; +} + +.document-type-new-page .checkbox-label { + @apply text-gray-700 font-normal cursor-pointer flex-1 flex items-center; + @apply bg-transparent border-none p-0 text-left appearance-none; + outline: none; +} + +.document-type-new-page .checkbox-label:focus { + @apply outline-none ring-2 ring-primary-300 rounded; +} + +.document-type-new-page .checkbox-item.checked .checkbox-label { + @apply text-[var(--primary-color)] font-medium; +} + +.document-type-new-page .radio-input { + @apply mr-1 h-4 w-4 text-primary-600 border-gray-300 rounded; + @apply focus:ring-primary-500 cursor-pointer; + accent-color: #00684a; +} + +/* 更完整的自定义单选按钮样式(可选) */ +.document-type-new-page .radio-input:checked { + background-color: #00684a; + border-color: #00684a; +} diff --git a/app/styles/pages/documents_edit.css b/app/styles/pages/documents_edit.css new file mode 100644 index 0000000..bfff123 --- /dev/null +++ b/app/styles/pages/documents_edit.css @@ -0,0 +1,201 @@ +.document-edit-page { + @apply w-full; +} + +.document-edit-page .page-header { + @apply flex justify-between items-center mb-4; +} + +.document-edit-page .page-title { + @apply text-xl font-medium; +} + +.document-edit-page .form-group { + @apply mb-4; +} + +.document-edit-page .form-label { + @apply block text-sm font-medium text-gray-700 mb-1; +} + +.document-edit-page .form-input, +.document-edit-page .form-textarea, +.document-edit-page .form-select { + @apply w-full rounded-md border border-gray-300 shadow-sm px-3 py-2; + @apply focus:outline-none focus:ring-1 focus:ring-primary-500 focus:border-primary-500; +} + +.document-edit-page .text-secondary { + @apply text-gray-500; +} + +/* 文档信息样式 */ +.document-info { + @apply flex items-start mb-6; +} + +.document-icon { + @apply text-3xl mr-4 p-2 bg-gray-50 rounded-lg; +} + +.document-details { + @apply flex-1; +} + +.document-name { + @apply text-lg font-medium mb-1; +} + +.document-meta { + @apply flex items-center flex-wrap gap-4 text-sm text-gray-600; +} + +.meta-item { + @apply flex items-center; +} + +.meta-item i { + @apply mr-1; +} + +/* 状态徽章样式 */ +.status-badge { + @apply inline-flex items-center px-2 py-0.5 rounded-full text-xs; +} + +.status-pending { + @apply bg-blue-50 text-blue-600; +} + +.status-processing { + @apply bg-yellow-50 text-yellow-600; +} + +.status-pass { + @apply bg-green-50 text-green-600; +} + +.status-warning { + @apply bg-orange-50 text-orange-600; +} + +.status-fail { + @apply bg-red-50 text-red-600; +} + +/* 提示框样式 */ +.alert { + @apply flex items-center p-3 rounded-md; +} + +.alert-info { + @apply bg-blue-50 border border-blue-100 text-blue-700; +} + +/* 切换开关样式 */ +.switch { + position: relative; + display: inline-block; + width: 36px; + height: 20px; + @apply align-middle; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + transition: .4s; + border-radius: 34px; +} + +.slider:before { + position: absolute; + content: ""; + height: 16px; + width: 16px; + left: 2px; + bottom: 2px; + background-color: white; + transition: .4s; + border-radius: 50%; +} + +input:checked + .slider { + @apply bg-primary-500; +} + +input:focus + .slider { + @apply ring-2 ring-offset-2 ring-primary-500; +} + +input:checked + .slider:before { + transform: translateX(16px); +} + +/* 文档预览样式 */ +.document-preview { + @apply border border-gray-200 rounded-md overflow-hidden h-96; +} + +.preview-toolbar { + @apply px-4 py-2 bg-gray-50 border-b border-gray-200 flex justify-between items-center; +} + +.preview-content { + @apply h-full overflow-auto p-4 bg-white; +} + +.preview-placeholder { + @apply flex flex-col justify-center items-center h-full text-gray-500; +} + +.preview-placeholder i { + @apply text-4xl mb-4 text-gray-300; +} + +/* 历史时间线样式 */ +.history-timeline { + @apply relative pl-5 mt-5; +} + +.history-timeline::before { + content: ''; + @apply absolute left-0 top-2 bottom-2 w-0.5 bg-gray-100; +} + +.timeline-item { + @apply relative pb-4; +} + +.timeline-item::before { + content: ''; + @apply absolute w-2.5 h-2.5 rounded-full bg-primary-500 -left-6 top-1.5; +} + +.timeline-item:last-child { + @apply pb-0; +} + +.timeline-time { + @apply text-xs text-gray-500 mb-1; +} + +.timeline-content { + @apply bg-gray-50 p-2 rounded; +} + +/* 错误容器样式 */ +.error-container { + @apply p-6; +} diff --git a/json.txt b/json.txt index 951bce2..8b3e8f3 100644 --- a/json.txt +++ b/json.txt @@ -1,108 +1,75 @@ [ { - "id": 1, - "template_name": "行政处罚-抽取通用模板", - "template_type": "Extraction", - "description": "本模板用于抽取行政处罚决定书编号等信息", - "template_content": "你是一个专业的文档信息抽取助手。请从以下{docType}文档中抽取关键信息:\n\n1. 处罚决定书编号\n2. 处罚对象名称\n3. 处罚事由\n4. 处罚依据\n5. 处罚内容\n6. 处罚金额\n7. 发文日期\n\n请将结果以JSON格式输出,包含以上字段。如果某个字段在文档中未找到,则该字段的值设为null。", - "variables": { - "docType": "文档类型" - }, - "status": 2, - "version": "v1.0", - "created_by": 1, - "created_at": "2025-03-26T01:23:58.549908", - "updated_at": "2025-03-26T01:23:58.549908" + "id": 78, + "user_id": null, + "type_id": 3, + "name": "2024年度华烟处第46号.pdf", + "document_number": "XZCF-20250409-5fKn6P", + "path": "http://172.18.0.100:9000/docauditai/documents/%E8%A1%8C%E6%94%BF%E5%A4%84%E7%BD%9A%E5%86%B3%E5%AE%9A%E4%B9%A6/2025/04%E6%9C%8809%E6%97%A5/2024%E5%B9%B4%E5%BA%A6%E5%8D%8E%E7%83%9F%E5%A4%84%E7%AC%AC46%E5%8F%B7_20%E6%97%B653%E5%88%8627%E7%A7%92/2024%E5%B9%B4", + "storage_type": "minio", + "file_size": 4931297, + "upload_time": "2025-04-09T12:53:20.807077", + "is_test_document": true, + "evaluation_level": "普通", + "status": "waiting", + "ocr_result": null, + "extracted_results": null, + "sumary": null, + "remark": "", + "created_at": "2025-04-09T12:53:20.807077+00:00", + "updated_at": "2025-04-09T12:53:20.807077+00:00" }, { - "id": 2, - "template_name": "销售合同-甲方信息评估", - "template_type": "Evaluation", - "description": "评估销售合同中甲方信息是否完整", - "template_content": "你是一个专业的合同审核助手。请评估以下{docType}中甲方信息的完整性:\n\n请检查以下要素是否存在且完整:\n1. 甲方全称\n2. 注册地址\n3. 统一社会信用代码\n4. 法定代表人\n5. 联系方式\n\n请给出评估结果,并标明缺失或不完整的信息。", - "variables": { - "docType": "文档类型" + "id": 64, + "user_id": null, + "type_id": 3, + "name": "2024年度华烟处第46号.pdf", + "document_number": "XZCF-20250409-g6wfCb", + "path": "http://172.18.0.100:9000/docauditai/documents/%E8%A1%8C%E6%94%BF%E5%A4%84%E7%BD%9A%E5%86%B3%E5%AE%9A%E4%B9%A6/2025/04%E6%9C%8809%E6%97%A5/2024%E5%B9%B4%E5%BA%A6%E5%8D%8E%E7%83%9F%E5%A4%84%E7%AC%AC46%E5%8F%B7_16%E6%97%B648%E5%88%8606%E7%A7%92/2024%E5%B9%B4", + "storage_type": "minio", + "file_size": 4931297, + "upload_time": "2025-04-09T08:48:01.155882", + "is_test_document": true, + "evaluation_level": "普通", + "status": "extractioning", + "ocr_result": { + "__meta": { + "completed": true, + "is_digital": true, + "page_count": 51, + "result_url": "http://172.18.0.100:9000/documents/行政处罚决定书/2025/04月09日/2024年度华烟处第46号_16时48分08秒/ocr_result.json", + "elapsed_time": 0.340202808380127 + }, + "现场笔录": "广东省五华县烟草专卖局\n送达回证\n华烟送(2024)第56-1号\n送达文书\n送达文书\n华烟处(2024)第\n行政处罚决定书\n名称\n文号\n46号\n受送达人\n曾丽周\n送达地点\n广东省梅州市五华县棉洋镇北斗新街\n送达方式\n直接送达\n收件人签名\n或盖章\n签收日期\n代收人注明\n代收理由\n见证人签名\n或盖章\n东梅\n送达人签名\n刘蒸\n备注\n专卖局\n广东省五华县烟草\n东\n2025年1月20", + "询问笔录": "广东省五华县烟草专卖局\n卷烟、雪茄烟鉴别检验报告\n31\n\n广东省五华县烟草专卖局\n卷烟鉴别检验样品返还清单\n32\n\n广东省五华县烟草专卖局\n询问笔录\n询问时间:2024年12月27日11时7分至2024年12月27日11时16分\n询问地点:五华县烟草专卖局梅林专卖管理所办公室\n询问人:张清锐(19080852020),颜帜东(19080852010)记录人:张清锐\n被询问人:曾丽周性别:男性\n年龄:55民族:汉族\n证件类型及号码:居民身份证441424196909145598\n住址:广东省五华县棉洋镇洛阳村红日\n经营地址:五华县棉洋镇北斗新街联系电话:15016277310\n执法人员表明身份、出示证件及被询问人确认的记录:_我们是广东省五华县烟\n草专卖局的行政执法人员张清锐,颜帜东,这是我们的执法证件,执法证号分别\n是19080852020,19080852010。\n告知陈述(申辩)和申请回避的权利:根据《中华人民共和国行政处罚法》第\n五十五条第二款和《烟草专卖行政处罚程序规定》第二十三条、第三十八条第\n二款、第四十三条第一款的规定,你应当如实回答询问,不得提供伪证或隐匿\n证据,并协助调查或者检查,不得拒绝或者阻挠,否则将承担相应的法律责任,\n同时你依法享有陈述权、申辩权和申请办案人员回避的权利。请问你是否清楚?\n是否申请回避?\n被询问人:我清楚了,不需要申请回避。\n我清楚了,不要求你们回避,\n问:我局梅林专卖管理所执法人员于2024年12月5日在你的经营场所内查获\n一批条码刮毁的卷烟,现就此案向你调查,请你如实回答问题。\n签:好的。\n以上笔录经被询问人核对无误。\n被询问人(签名):\n年月日\n颜帜东执法证号:\n询问人(签名):\n月27日\n张清锐执法证号:\n月27日\n第1页/共3页\n33", + "送达回证": "广东省五华县烟草专卖局\n行政处罚决定书\n华烟处(2024)第46号\n当事人:曾丽周,字号:五华县棉洋镇周誉商店,性别:男性,民族:\n汉族,身份证住址:广东省五华县棉洋镇洛阳村红日,身份证号码:\n441424196909145598,烟草专卖许可证号:441424106675,统一社会信用\n代码:92441424MA50L2H04X,经营地址:五华县棉洋镇北斗新街,联系电\n话: 15016277310。\n案由:未在当地烟草专卖批发企业进货。\n2024年12月5日10时06分,接群众举报,我局专卖执法人员联合\n五华县公安局于警经出示执法证件,表明身份,说明来意,告知当事人曾\n丽周执法人员正在进行全程录像后,依法对当事人经营场所五华县棉洋镇\n北斗新街五华县棉洋镇周誉商店检查,当事人在场并同意接受检查。联合\n执法人员在其经营场所及附属区域仓库内发现条码有刮痕和刮毁的卷烟庐\n山(黄精品)150条、龙凤呈祥(鸿运朝天门)500条共2个品种合计\n650条。经现场询问当事人,其无法提供上述卷烟从当地烟草专卖批发企\n业进货的发票或其他合法有效凭证。当事人的行为涉嫌违反了《中华人民\n东省\n共和国烟草专卖法实施条例》第二十三条第二款的规定,涉嫌未在当地烟\n草专卖批发企业进货,为了案件进一步调查取证,经报局领导批准同意后,\n我局专卖执法人员依法将上述卷烟作证据先行登记保存。\n经我局依法立案后查实,涉案2个品种650条卷烟为当事人曾丽周所\n有。曾丽周系我县卷烟零售户,其在五华县棉洋镇北斗新街经营五华县棉\n洋镇周誉商店,办有烟草专卖零售许可证(证号为441424106675)。经调\n查和当事人交代,上述涉案卷烟是当事人从上门兜售卷烟的人员处购进的,\n当事人将涉案卷烟放置于经营场所内进行销售,于12月5日被我局梅林\n专卖管理所执法人员查获。经调查核实当事人未存在被烟草专卖局或其他\n执法机关行政处罚的行为。曾丽周无法提供该条涉案卷烟在当地烟草批发\n企业进货的合法来源证明及价格证明,经抽样送广东省烟草质量监督检测\n站鉴定,鉴定结论为真品卷烟(检验报告编号:JYBGZW202417767),当事\n人对检验结果无异议。经梅州市烟草专卖局(公司)涉案卷烟价格管理小\n组核价,涉案卷烟总价值为28250.00元。\n当事人曾丽周的经营行为违反了《中华人民共和国烟草专卖法实施条\n例》第二十三条第二款“取得烟草专卖零售许可证的企业或者个人,应当\n在当地的烟草专卖批发企业进货,并接受烟草专卖许可证发证机关的监督\n第1页/共2页\n\n广东省五华县烟草专卖局\n案件处理初审表\n40", + "举报记录表": "管理”,实属未在当地烟草专卖批发企业进货的行为,证据有:1.现场笔\n录;2.证据先行登记保存通知书;3.当事人店面照片、执法人员检查过\n程照片、涉案卷烟照片;4.当事人的身份证、营业执照、烟草专卖零售许\n可证照片;5.先行登记保存证据处理通知书;6.抽样取证物品清单、涉案\n卷烟抽样、封存照片;7.涉案卷烟32位喷码列表;8.卷烟、雪茄烟鉴别\n检验送样单、委托单、检验报告;9.询问笔录;10.涉案物品核价表。\n2025年1月8日,我局依法向当事人送达了《广东省五华县烟草专\n卖局行政处罚事先告知书》(华烟处告(2024)第46号),当事人在规定\n期限内未向我局提出任何陈述、申辩。\n专卖零售许可证的企业或者个人违反本条例第二十三条第二款的规定,未\n在当地烟草专卖批发企业进货的,由烟草专卖行政主管部门没收违法所得,\n可处以进货总额5%以上10%以下的罚款”和《广东省烟草专卖行政处罚裁\n,中《华\n人未在当地烟草专卖批发企业进货,进货总额5000元以上不满3万元的,\n没收违法所得,处以进货总额7%以上9%以下的罚款”的规定,我局决定\n对曾丽周作出如下处罚:处以进货总额28250.00元的8%罚款,即罚款\n2260.00元。\n当事人应当自收到行政处罚决定书之日起根据广东省非税收入一般缴\n款书进行缴纳罚款。到期不缴纳罚款,依据《烟草专卖行政处罚程序规定\n第六十七条第二款的规定,每日按罚款数额的百分之三加处罚款。\n当事人如不服本行政处罚决定,可以自收到本行政处罚决定书之日起\n60日内向梅州市烟草专卖局或五华县人民政府申请行政复议,也可以15\n日内向广东省兴宁市人民法院提出行政诉讼。如当事人逾期既不申请行政\n复议,也不向人民法院提起行政诉讼,又不履行行政处罚决定的,我局将\n向人民法院申请强制执行。\n广东省五华县烟草专美两\n(印意\n2025年\n月20\n第2页/共2页\n2", + "卷内备考表": "广东省非税收入一般缴款书(电子)\n47", + "立案报告表": "广东省五华县烟草专卖局\n证据复制(提取)单\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n410295a ddak\ntYC340eade\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410304*****\n**YC360****\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295***\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n410305**********\n**YC510****\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295*****p*\n**YC340******4*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n1\n410305*\n**YC340***\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410295*******6*0*\n+**YC3614aptt\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n410305**\n**YC510*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽者\n410285\nYC310\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n410305\nWYYC51W\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295********\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n**YC340**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n410295**\n**YC340*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n410305***\n**YC511*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n*+YC361**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295**\n**YC340\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n410310**\n**YC361*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽者\n410285\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江酉省\n410310*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410310*\nYC361-\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n410295*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n**YC361*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410295*\n**YC360\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n410310**\n**YC511=\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n410310**\n**YC361=\n兽丽周\n龙风呈祥(鸿运朝天门)\n江西省\n110295\nYC3\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江酉省\n1\n410310**\n*JYC36*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n410310**\n*YC361*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410310**\n*YC361*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295*\n**YC340*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江酉省\n410310***\n**YC361**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295***\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n410295*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n410310*\n**YC511**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江酉省\n410310********\n**YC361****4a0\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n410310中\n*YC361*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295*\n**YC340#\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410310*********\n**YC361*********\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽者\n410295*4*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n410310**\n**YC361#\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n410295\n曾丽周\n龙风呈祥(鸿适朝天门)\n江西省\n410310*\nYC361**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295**\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n410310***\n**YC361*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410310*\n**YC361\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295*\n**YC340*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n**YC511*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n410285*\nWYC5100\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n410315**\n*AYC34**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295***\n$*YC340*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n410315*a\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295***\n**YC340**\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n410315**\n*CYC36*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295**\n曾丽周\n龙风呈祥(鸿运朝天门)\n1\n**YC340**\n江西省\n410315*********\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410295**\n**YC340**\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n一\n410453**\n*YYC51*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽者\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411013*******\n**YC360****\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411015**\n*YYC51*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411015*\nISOAA\n说明事项:五华县烟草专卖局梅林专卖管理所专卖执法人员对查获的涉案卷烟32\n位喷码进行提取\n复制(提取)地点:五华县烟草专卖局梅林专卖管理所办公室\n复制(提取)时间:2024年12月10日16时18分\n颜帜东\n执法人员及执法证号:\n柔清锐\n第1页/共1页\n13", + "结案报告表": "广东省非税收入一般缴款书 (电子)\n缴款识别码:441900xxxxx3299422\n执收单位编码:441900xxx\n票据代码:\n校验码:\n执收单位名称:xx市财政局\n票据号码:\n填制日期:2024-08-12\n全\n称\n广东xxxx有限公司\n全\n称\n付\n收\n款\n账\n号\n款\n账\n号\n人\n人\n开户银行\n开户银行\n币种:人民币\n金额(大写):捌拾陆万陆仟伍佰肆拾玖元玖角\n(小写)\n2260.00元\n收费项目编码\n收费项目名称\n单位\n数量\n收费标准\n金额\n103xxxx9700\n其他一般罚没收入-财政罚没收入\n元\n2260.0000\n1. 00000\n2260.00\n执收单位 (盖章)\n经办人 (盖章)\n备注\nxx市xx局\n电子缴款书专用章\n附加信息\n微信/支付宝“扫一扫”缴款↓\n号码校验码\n51137\n全书校验码\n35872\n加罚金额\n0.00\n限缴日期\n2024-11-12\n滞纳金计算\n起计天数\n15天\n滞纳金率\n3.00%\n滞纳金上限\n本金100.00%\n处罚决定书号\nx财罚(2024)8号\n广东xxxx有限公司在参与xx活动中存在提供虚假材料\n处罚原因\nXxXx的情形。\n加罚原因\n温馨提示:二维码有效期为缴费后三个月内,超期后\n请前往【广东公共服务支付平台】查询及获取电子缴\n款凭证。\n请扫描二维码查看缴款须知\n(1)PC端网址\nhttps://ggzf. czt. gd. gov. cn/onlinePay/\n(2)关注【广东财政】微信公众号,选择政务服务\n【公共服务支付平台】入口查询\n46", + "案件处理初审表": "广东省五华县烟草专卖局\n案件调查终结报告\n案由\n涉嫌未在当地烟草专卖批发企业进货\n案件来源\n投诉举报\n立案日期\n2024年12月5日\n姓名\n曾丽周\n性别\n男性\n年龄\n55\n个人(个\n民族\n汉族\n联系电话\n15016277310\n事\n体工商户)\n人\n证件类型及号码\n居民身份证 441424196909145598\n住址\n广东省五华县棉洋镇洛阳村红日\n调查人\n张清锐(19080852020),颜帜东(19080852010)\n2024年12月5日10时06分,接群众举报,我局专卖执法人员联\n合五华县公安局于警经出示执法证件,表明身份,说明来意,告\n知当事人曾丽周执法人员正在进行全程录像后,依法对当事人经\n营场所五华县棉洋镇北斗新街五华县棉洋镇周誉商店检查,当事\n人在场并同意接受检查。联合执法人员在其经营场所及附属区域\n仓库内发现条码有刮痕和刮毁的卷烟庐山(黄精品)150条、龙\n凤呈祥(鸿运朝天门)500条共2个品种合计650条。经现场询问\n当事人,其无法提供上述卷烟从当地烟草专卖批发企业进货的发\n票或其他合法有效凭证。当事人的行为涉嫌违反了《中华人民共\n和国烟草专卖法实施条例》第二十三条第二款的规定,涉嫌未在\n调查事实\n当地烟草专卖批发企业进货,为了案件进一步调查取证,经报局领\n导批准同意后,我局专卖执法人员依法将上述卷烟作证据先行登\n记保存。\n经我局依法立案后查实,涉案2个品种650条卷烟为当事人曾\n丽周所有。曾丽周系我县卷烟零售户,其在五华县棉洋镇北斗新\n街经营五华县棉洋镇周誉商店,办有烟草专卖零售许可证(证号\n为441424106675)。经调查和当事人交代,上述涉案卷烟是当事人\n从上门兜售卷烟的人员处购进的,当事人将涉案卷烟放置于经营\n场所内进行销售,于12月5日被我局梅林专卖管理所执法人员查获。\n经调查核实当事人未存在被烟草专卖局或其他执法机关行政处罚\n的行为。曾丽周无法提供该条涉案卷烟在当地烟草批发企业进货\n第1页/共2页\n37\n\n的合法来源证明及价格证明,经抽样送广东省烟草质量监督检测\n站鉴定,鉴定结论为真品卷烟(检验报告编号:\nJYBGZW202417767),当事人对检验结果无异议。经梅州市烟草专\n卖局(公司)涉案卷烟价格管理小组核价,涉案卷烟总价值为\n28250.00元。\n以上事实有以下证据予以证实:1.现场笔录;2.证据先行登\n记保存通知书;3.当事人店面照片、执法人员检查过程照片、涉\n案卷烟照片;4.当事人的身份证、营业执照、烟草专卖零售许可\n证照片;5.先行登记保存证据处理通知书;6.抽样取证物品清单、\n涉案卷烟抽样、封存照片;7.涉案卷烟32位喷码列表;8.卷烟、\n雪茄烟鉴别检验送样单、委托单、检验报告;9.询问笔录;10.涉\n案物品核价表。\n案件性质\n涉嫌未在当地烟草专卖批发企业进货\n《中华人民共和国烟草专卖法实施条例》第五十六条、《广东省烟\n处罚(处理)依据\n草专卖行政处罚裁量权管理办法》附件1序号9\n当事人的行为涉嫌违反了《中华人民共和国烟草专卖法实施\n条例》第二十三条第二款的规定,涉嫌构成未在当地烟草专卖批\n发企业进货,建议根据《中华人民共和国烟草专卖法实施条例》\n第五十六条的规定进行处罚,当事人涉嫌未在当地烟草专卖批发\n企业进货总额28250.00元属于《广东省烟草专卖行政处罚裁量权\n处理意见\n个人未在当地烟草专卖批发企业进货,进货总额5000元以上不满3\n万元的,没收违法所得,处以进货总额7%以上9%以下的罚款”,建\n议对当事人曾丽周处以进货总额28250.00元的8%罚款,即罚款\n2260.00元,本案调查终结。\n承办人签名:颜帜东\n日期:2024年12月27日\n备注\n第2页/共2页\n38", + "案件处理审批表": "广东省五华县烟草专卖局\n行政处罚事先告知书\n华烟处告(2024)第46号\n曾丽周:\n经查,你(单位)于2024年12月5日因未在当地烟草专卖批发企业进货行\n为,违反了《中华人民共和国烟草专卖法实施条例》第二十三条第二款规定,\n依据《中华人民共和国烟草专卖法实施条例》第五十六条、《广东省烟草专卖行\n政处罚裁量权管理办法》附件1序号9规定,我局拟对你作出如下行政处罚:\n处以进货总额28250.00元的8%罚款,即罚款2260.00元。\n根据《中华人民共和国行政处罚法》第四十四条、第四十五条的规定你\n(单位)享有陈述权和申辩权。如果要求陈述、申辩,应当在收到本告知书3\n日内向本局提出陈述和申辩。逾期未提出的,视为放弃此权利。\n本局地址:广东省五华县水寨镇华兴中路57号五华县烟草专卖局\n邮编:514400联系电话:0753-4435764\n请书写你的陈述和申辩意见,并签署姓名和日期。\n当事人:\n广东省五华县烟草\n2025年1\n41\n\n广东省五华县烟草专卖局\n送达回证\n华烟送(2024)第56号\n送达文书\n送达文书\n华烟处告(2024)\n行政处罚事先告知书\n名称\n文号\n第46号\n受送达人\n曾丽周\n送达地点\n广东省梅州市五华县棉洋镇北斗新街\n送达方式\n直接送达\n收件人签名\n或盖章\n签收日期\n代收人注明\n代收理由\n见证人签名\n或盖章\n东梅\n送达人签名\n刘蒸\n备注\n专卖局\n写\n广东省五华县烟草\n东\n2025年1月\n42", + "涉案物品核价表": "问:你叫什么名字,现今年龄多大?住在什么地方?从事什么职业?\n答:我叫曾丽周55岁,住在广东省五华县棉洋镇洛阳村红日,从事个体经营。\n问:你的经营场所地址是什么?商店名称、字号是什么?\n答:五华县棉洋镇北斗新街,五华县棉洋镇周誉商店。\n问:你经营的商店办有烟草专卖零售许可证吗?证号多少?\n答:有,证号是:441424106675。\n问:这批卷烟是谁的?有什么烟?\n答:是我的,有庐山(黄精品)150条、龙凤呈祥(鸿运朝天门)500条,共2个品\n种合计650条卷烟。\n问:你知道你这批卷烟是真烟还是假烟,从哪里购进的?\n答:不知道。是从上门兜售卷烟的人员处购进的。\n问:你知道这个上门兜售人员叫什么名字?住在哪里吗?\n答:不认识,也不知道他住在哪里。\n问:你们是怎样联系的?有没有他的联系电话?为什么要购进这些卷烟?\n答:我没有他的联系电话。是他主动上门问我要不要烟的。刚好有亲戚家里办\n好事需要大量用烟所以购进的。\n问:上述卷烟有没有进货凭证吗?多少钱购进的?你是多少钱卖出去?销售出\n去了多少?\n答:没有进货凭证,忘记多少钱购进的了,都是按照零售价销售的。卷烟购进\n后放在店里还没卖出去就被你们查了。\n问:因为你没有合法有效的进货凭证,我们无法确定这批卷烟的进货价格,我\n们根据《广东省烟草专卖局关于发布2024年度全省涉案烟草专卖品价值估算的\n价格计算标准及有关事项的通知》(粤烟计(2024)1号)进行核价,你有无\n异议?\n签:无异议。\n以上笔录经被询问人核对无误。\n被询问人(签名):\n年月日\n颜帜东执法证号:\n询问人(签名):\n月27日\n张清锐执法证号:\n月27日\n第2页/共3页\n34", + "行政处罚决定书": "广东省五华县烟草专卖局\n卷宗\n2024 年度华烟处第 46号\n案由\n未在当地烟草专卖批发企业进货\n当事人\n曾丽周\n颜帜东(19080852010),张清锐(19080852020)\n承办人\n刘燕(19080852027),陈梅(19080852013)\n根据《中华人民共和国烟草专卖法实施条\n例》第二十三条第二款和广东省烟草专卖行政\n处理结果\n处罚裁量权管理办法》附件1序号9的规定,\n对当事人曾丽周处以进货总额28250.00元的\n8%罚款,即罚款2260.00元。\n立案日期\n结案日期\n2025年1月田\n2024年12月5日\n归档日期\n保存期限\n永久\n2025年1月20日\n审批人\n姚永刚\n此卷共计52页\n\n卷宗目录\n文书名称\n页次\n文书名称\n页次\n行政处罚决定书\n1-2\n证据复制(提取)单\n23\n送达回证\n3\n证据复制(提取)单\n24\n举报记录表\n4\n证据复制(提取)单\n25\n现场笔录\n5\n证据复制(提取)单\n26\n证据先行登记保存批准书\n6\n证据复制(提取)单\n27\n证据先行登记保存通知书\n7\n卷烟、雪茄烟鉴别检验送样单\n28\n证据复制(提取)单\n8\n卷烟、雪茄烟鉴别检验委托单\n29\n证据复制 (提取)单\n6\n卷烟鉴别检验样品耗用量清单\n30\n证据复制(提取)单\n10\n卷烟、雪茄烟鉴别检验报告\n31\n证据复制(提取)单\n11\n卷烟鉴别检验样品返还清单\n32\n证据复制(提取)单\n12\n询问笔录\n33-35\n证据复制 (提取)单\n13\n涉案物品核价表\n36\n证据复制(提取)单\n14\n案件调查终结报告\n37-38\n立案报告表\n15\n案件处理初审表\n39-40\n先行登记保存证据处理通知书\n16\n行政处罚事先告知书\n41\n抽样取证物品清单\n17\n送达回证\n42\n证据复制 (提取)单\n18\n案件处理审批表\n43-44\n证据复制(提取)单\n19\n涉案物品返还清单\n45\n广东省非税收入一般缴款书\n证据复制 (提取)单\n20\n46-47\n(电子)\n证据复制(提取)单\n21\n结案报告表\n48\n证据复制 (提取)单\n22\n卷内备考表\n49\n备注\n本卷连面带底共计52页,附证物0袋", + "抽样取证物品清单": "广东省五华县烟草专卖局\n立案报告表\n15", + "案件调查终结报告": "问:我局专卖执法人员在现场对查获的卷烟抽样送广东省烟草质量监督检测站\n鉴定,鉴定结论:为真品卷烟。检验报告编号:JYBGZW202417767。对此你有无\n异议?\n签:无异议\n问:你以前还有没有其他违法违规经营的行为被烟草专卖局或其他行政执法部\n门查处?\n签:没有。\n问:以上询问笔录请你阅读核对,若你不具备阅读能力或有其他因素导致无法\n自行阅读,你可以提出来,我们可以给你宣读。若是核对时发现有差错或是遗\n漏的地方,你可以要求我们补充、更正。\n答:以上询问笔录我已经看过,没有差错或是遗漏的地方,没有补充的。\n被询问人:本询问笔录已经本人逐一核对(已向本人宣读),无误。\n以上笔录经被询问人核对无误。\n被询问人(签名):\n年月日\n颜帜东执法证号:\n询问人(签名):\n27日\n承清\n执法证号:\n月27日\n第3页/共3页\n35\n\n广东省五华县烟草专卖局\n涉案物品核价表\n广东省五华县烟草专卖局于2024年12月5日立案(立案编号:华烟\n立【2024)第56号)的曾丽周涉嫌未在当地烟草专卖批发企业进货案件\n中,涉案物品价格如下:\n序号\n品种规格\n数量 (单位)\n单价 (元)\n合计 (元)\n备注\n84mm庐山(黄\n150条\n1\n55\n8250\n精品)\n84mm龙凤呈祥\n500条\n2\n40\n20000\n(鸿运朝天门)\n/\n合计\n650\n28250\n价格证明依据:根据《中华人民共和国烟草专卖法》及其实施例、《国家\n烟草专卖局关于印发涉案卷烟价格管理规定的通知》(国烟计(2021)93\n理规定的通知》(粤烟计(2021)55号)、《广东省烟草专卖局关于发布\n2024年度全省涉案烟草专卖品价值估算的价格计算标准及有关事项的通\n知》(粤烟计(2024)1号)的有关规定,经核查,对此案出具涉案烟草\n专卖品价格证明。\n颜帜來\n经办人:\n省局\n广东省五华县烟草\n2024年121\n枣\n第1页/共1页\n36", + "涉案物品返还清单": "广东省五华县烟草专卖局\n案件处理审批表\n案由\n未在当地烟草专卖批发企业进货\n案件来源\n投诉举报\n立案编号\n华烟立(2024)第56号\n立案日期\n2024年12月5日\n姓名\n曾丽周\n性别\n男性「年龄\n55\n个人\n当\n(个体\n民族\n汉族\n联系电话\n15016277310\n事\n工商户)\n人\n证件类型及号码\n居民身份证441424196909145598\n住址\n广东省五华县棉洋镇洛阳村红日\n同案人\n/\n违法事实\n2024年12月5日10时06分,接群众举报,我局专卖执\n法人员联合五华县公安局干警经出示执法证件,表明身份,\n说明来意,告知当事人曾丽周执法人员正在进行全程录像后,\n依法对当事人经营场所五华县棉洋镇北斗新街五华县棉洋镇\n周誉商店检查,当事人在场并同意接受检查。联合执法人员\n在其经营场所及附属区域仓库内发现条码有刮痕和刮毁的卷\n烟庐山(黄精品)150条、龙凤呈祥(鸿运朝天门)500条共\n2个品种合计650条。经现场询问当事人,其无法提供上述\n卷烟从当地烟草专卖批发企业进货的发票或其他合法有效凭\n证。当事人的行为涉嫌违反了《中华人民共和国烟草专卖法\n实施条例》第二十三条第二款的规定,涉嫌未在当地烟草专\n卖批发企业进货,为了案件进一步调查取证,经报局领导批准\n同意后,我局专卖执法人员依法将上述卷烟作证据先行登记\n保存。\n经我局依法立案后查实,涉案2个品种650条卷烟为当\n事人曾丽周所有。曾丽周系我县卷烟零售户,其在五华县棉\n洋镇北斗新街经营五华县棉洋镇周誉商店,办有烟草专卖零\n售许可证(证号为441424106675)。经调查和当事人交代,\n上述涉案卷烟是当事人从上门兜售卷烟的人员处购进的,当\n事人将涉案卷烟放置于经营场所内进行销售,于12月5日被\n我局梅林专卖管理所执法人员查获。经调查核实当事人未存\n在被烟草专卖局或其他执法机关行政处罚的行为。曾丽周无\n法提供该条涉案卷烟在当地烟草批发企业进货的合法来源证\n明及价格证明,经抽样送广东省烟草质量监督检测站鉴定,\n第1页/共2页\n43", + "行政处罚事先告知书": "广东省五华县烟草专卖局\n案件处理初审表\n39", + "证据复制(提取)单": "广东省五华县烟草专卖局\n证据先行登记保存批准书\n因曾丽周涉嫌 未在当地烟草专卖批发企业进货行为,违反《中华人民共和\n国烟草专卖法》及其实施条例的有关规定,根据《中华人民共和国行政处罚法》\n第五十六条的规定,现拟对下列证据予以先行登记保存:\n品种规格\n单位\n数量\n品种规格\n单位\n数量\n龙凤呈祥(鸿运朝天门)\n庐山 (黄精品)\n条\n150\n条\n500\n/\n/\n/\n/\n/\n共计:(品种)2个\n总计:(数量)650条\n备注\n真假待鉴定\n对先行登记保存的证据,应当在七日内及时作出处理决定。\n承办人(签名):颜帜东\n执法证号:\n月5日\n來清\n执法证号:\n月5日\n负责人意见并签名:\n桃永刚\n第1页/共1页\nb\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n五金店\n鸿运美发\n电号:610038\n66650\n做\n运美发\n价格真\nWELCOMEY\n20元\n丽\n30元\n这限一家理发店\n您司以进来\n梅市快招人力资源有限公司(棉举)\n说明事项:五华县烟草专卖局梅林专卖管理所专卖执法人员对当事人曾丽周的经\n营场所店面进行拍照提取。当事人店面招牌名称为鸿运美发,营业执照上的字号\n名称为五华县棉洋镇周誉商店。\n复制(提取)地点:广东省梅州市五华县棉洋镇北斗新街\n复制(提取)时间:2024年12月5日10时18分\n颜帜来\n执法人员及执法证号:\n清\n第1页/共1页\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n可聘\n元记\n金oTaw\n元08\n元08\n元8\n5.元8\n元or安\n说明事项:五华县烟草专卖局专卖执法人员联合五华县公安局千警在当事人曾丽\n周的经营场所内对其存放的卷烟进行检查。\n复制(提取)地点:广东省梅州市五华县棉洋镇北斗新街\n复制(提取)时间:2024年12月5日10时20分\n颜帜來\n执法人员及执法证号:\n柔清镜\n第1页/共1页\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n涉案卷烟32位喷码列表\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n1\n405212*\nYC340\n当事人\n品牌\n来源\n数量(条)\n32位喷码\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n1\n405221*\nYC340\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n**Y C361**ppppp**\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n曾丽周\n龙风皇祥(鸿适朝天门)\n江西省\n1\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n1\n405230中\nFYC340\n曾丽周\n龙凤呈祥(鸿运朝天门)\n不详\n7\n曾副周\n龙风呈祥(鸿运朝天门)\n四川省\n405230***\n*SYC51*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n405230*\nSYC5\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n*YC511***\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n405230**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n*YC360*4\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n405230\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n*YC3614\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n405230\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n311223**\n***YC341**4*4*42*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n405230*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n312043**\n*YC340**\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n405230*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n**99021\n**YC341**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n405230*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n4030444\n*YC360*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n405231*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n403184*4\n**YC3604\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n405231*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n403252**\n*YC511**\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n405231*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n404011*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n405283*\n曾丽周\n龙凤星祥(鸿运朝天门)\n安徽省\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n405301***\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n404021*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n404023**\n曾副周\n龙风呈祥(鸿运朝天门)\n安徽者\n406063*\n0\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n**00\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n406135**\n*YC510\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n、\n406144***\nYC340*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n**YC361=\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n406153****\n*JYC3\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n1\n404224*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n406203***\n**YC361\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n1\n404233\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n406203***\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n404233*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n*YYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n404243*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n407041**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n404244**\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n407041*\n*SYC51\n曾丽周\n龙风皇祥(鸿运朝天门)\n四川省\n1\n404253\nYC510\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n407041***\n*SYC51\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n404253*4\n**YC361**4*4****\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n407041\np*YC511**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n890905\n*YC360**\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n407041**\nISYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n405081**\n**YC511*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n407041中中\ntSYC51中\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n405161**\n*YC340*\n曾围周\n龙风呈祥(鸿运朝天门)\n四川省\n407041***\n曾丽周\n龙风皇祥(鸿运朝天门)\n江西省\n1\n*+Y C3614thd thhk\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n***10404\n*SYC51*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n405201***\n*YC511*中\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n407041**\n*SYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n405201**\n*YC360*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n407041***\n*SYC51*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n405211***\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n1\n407081**\n**YC340*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n405212**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n407083**\n**YC361*\n说明事项:五华县烟草专卖局梅林专卖管理所专卖执法人员对查获的涉案卷烟32\n位喷码进行提取\n复制(提取)地点:五华县烟草专卖局梅林专卖管理所办公室\n复制(提取)时间:2024年12月10日14时47分\n颜帜东\n执法人员及执法证号:\n第1页/共1页\n10\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n407090*******\n**YC340****\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n409285**\n*YC361*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n**YC361********\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n1\n**YC340*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n407101****\n++*YC510*****\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n*YYC51*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n407101*\n***YC360*********\n曾丽周\n龙凤星祥(鸿运朝天门)\n安徽省\n1\n410075***\n**YC341*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n407101*\n**YC340*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n+YC510\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n407153**\n*CYC36**\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n407172*\n**YC360*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410084**\nYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n*YC360*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n410091\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n**YC51\n曾丽周\n龙风呈祥(鸿适朝天门)\n江西省\n410103*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n407303*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n410104*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n408063*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n408123*\n**YC511\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410104#\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n408131+\nYC511\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n410112*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n408140*\n**YC510\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410114\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n408142*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n408150*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410142\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n161801\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410142*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n408211\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n410142*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n408212*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n410142\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n408213*\nYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410142*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n408222\n**YC360*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n410143*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n408222*\n*YC360*\n曾丽周\n龙风呈祥(鸿适朝天门)\n江西省\n410143*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n40919*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n410143*\nAYC34\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n409230*\n**YC511*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n410143*\nAYC34\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n109235\n*AYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410162*\n邮YC360m\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n409235*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410164*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n409245*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410164*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n409251*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江酉省\n1\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n409261*\n*YC510F\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410171*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n陕西省\n409263*\n**C3611\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410172\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n409264**\n*YYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410172**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n409264**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410180*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n409274*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410181*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n409280*\n**YC360**\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n410184*\nYC510\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n409280**ddt*\n*+YC511*daddk\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n410184****\n*YC511\n曾丽周\n龙凤星祥(鸿运朝天门)\n江西省\n409283**\n**YC361*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n410210**\nCYC36*\n说明事项:五华县烟草专卖局梅林专卖管理所专卖执法人员对查获的涉案卷烟32\n位喷码进行提取\n复制(提取)地点:五华县烟草专卖局梅林专卖管理所办公室\n复制(提取)时间:2024年12月10日14时52分\n颜帜东\n执法人员及执法证号:\n柔清\n第1页/共1页\n11\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n410210*4\ntYC360dbhhh.hh\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410232*\n*SYC51*\n曾丽周\n龙凤星祥(鸿运朝天门)\n江西省\n410210\nttYC360ptt\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410232****\n**YC511********\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410212*********\n********+***\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410233**\n**YC360*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410212******4p*\nra*198人**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410233\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410213*******\n**YC361******\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410234***\n*YC360\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n410215**\n*AYC34**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410234*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410215**********\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410215**********\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n410235*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n410215**\n**YC510*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410235*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n410215**\n*YYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410235**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410215****\n*JYC36**\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n410240#\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410215*\n*YYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410240-*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410240*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410215*\n*CYC36*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410241**\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n410215*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410243**\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n410215*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n*YC361\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n4102154*\nHCYC364\n曾丽周\n龙凤呈祥(鸿适朝天门)\n江西省\n410244**\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n410221*\n*YC361*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n410253\n\"AYC34\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410221*\n*YC360*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410254****\n**YC360*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410222*\n**YC511**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410254*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410223*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n410254\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410223*\n*YC361\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410255*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410225*\n**YC360*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410282*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410225**\n*AYC51\n曾丽周\n龙风呈祥(鸿适朝天门)\n四川省\n410282*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410225*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410282\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410225**\n**YC340**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410283*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410230*\n*CYC36*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410284*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410230**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410285\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410230**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410285**\n曾丽周\n龙凤呈祥(冯运朝天门)\n四川省\n410230**\n*YC511\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410285*\nYYC5\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n410230*\n*RYC36**\n曾丽周\n龙凤呈祥(鸿适朝天门)\n江西省\n410285*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410230\nm*YC360P\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n410285*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410231*\n**YC511*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n*YYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410231*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n410285**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n1\n410232*\n*YC360\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n410285*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n410232*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n**YC340**\n位喷码进行提取\n复制(提取)地点:五华县烟草专卖局梅林专卖管理所办公室\n复制(提取)时间:2024年12月10日15时1分\n颜帜來\n执法人员及执法证号:\n來清\n第1页/共1页\n12\n\n广东省五华县烟草专卖局\n先行登记保存证据处理通知书\n16\n\n广东省五华县烟草专卖局\n抽样取证物品清单\n17\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411073***** *pp*\n**YC340****0p\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n1\n411124***\n**YC340****\n曾丽周\n龙凤星祥(鸿运朝天门)\n四川省\n1\n411073******p*\n**YC510********\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n411124********\n*YYC51*rp*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n1\n411074******\n**YC360*****\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411124*rpta\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n**YC511***\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n411084******\n*AYC34****\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411124**\n**YC360***\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n1\n411085**\n*AYC34*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n龙风呈祥(鸿运朝天门)\n**YC340*\n曹丽周\n四川省\n411085*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124**\n**YC340*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411114**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124**\n龙凤呈祥(鸿运朝天门)\n**YC340**\n曾丽周\n江西省\n411114\n**YC361*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411124*\n*YYC51\n龙凤呈祥(鸿运朝天门)\n江西省\n11111\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411124**\n*YYC51\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\nAYC51*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411124*\n**YC361\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411124**\n*AYC51*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\nPYYC51档\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411124*\n*YYC51*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\nFAYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124**\n**YC340*\n曾丽周\n龙凤呈样(鸿运朝天门)\n江西省\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411124*\n*YC360\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411124*\n*YYC51\n曾丽周\n龙风呈样(鸿运朝天门)\n四川省\nYYC51\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124*\n0\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124**\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\nCYC36*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411124**\nYYC51\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\nYC3615\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411124***\n**0986**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n**YC511\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411124*\n*AYC51\n曾丽周\n龙凤呈样(鸿运朝天门)\n四川省\n411114*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n411124**\n+**YC3404\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411114\n*YYC51*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411124**\n*AYC51*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411114*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411124*\n**YC361*\n曾丽周\n龙风呈祥(鸿适朝天门)\n江西省\n411120\n$YC361*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411123*\nP*YC361*中\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124*\n*YC340*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411124*\n*YC360*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124*******\n**YC340*******\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124\n**YC340*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124**\n**YC340*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411124*\n**YC361***\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124*4********\n+**YC340*******\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411124**\n曾丽周\n龙凤呈样(鸿运朝天门)\n江西省\n411124**\n*RYC36**\n曾丽周\n龙凤呈样(鸿运朝天门)\n江西省\n411124**\n*CYC36*******\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411124**\n*YYC51**\n曾丽周\n龙风皇样(鸿适朝天门)\n江西省\n411124\n*YC360*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411124**\n*RYC36**\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411124****4*p4*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124********\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n411124*\n**YC340*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n**YC360\n龙凤呈祥(鸿运朝天门)\n四川省\n*AYC51*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411124*\n说明事项:五华县烟草专卖局梅林专卖管理所专卖执法人员对查获的涉案卷烟32\n位喷码进行提取。\n复制(提取)地点:五华县烟草专卖局梅林专卖管理所办公室\n复制(提取)时间:2024年12月10日16时25分\n颜帜来\n执法人员及执法证号:\n柔清锐\n第1页/共1页\n18\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n19\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n20\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n21\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n22\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n23\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n24\n\n广东省五华县烟草专卖局\n证据复制(提取)单\n25", + "证据先行登记保存批准书": "广东省五华县烟草专卖局\n举报记录表\n2024年12月5日\n举报时间\n举报形式\n电话举报\n08时37分\n举报人\n举报人要求保密\n有关情况\n举报人称在五华县棉洋镇北斗新街棉洋镇周誉商店\n举报内容\n存放有数量不明的违法卷烟,望五华县烟草专卖局\n前往查处。\n该举报线索具体可靠,马上向局领导汇报,\n接待人意\n并联合五华县公安局干警前往查处\n见\n签名:采清镜\n日期:2024年12月5日\n承办部门\n负责人意\n签名:张颖锡\n见\n日期:\n备注\n需要领取举报奖励\n第1页/共1页", + "证据先行登记保存通知书": "广东省五华县烟草专卖局\n现场笔录\n检查时间:2024年12月5日10时6分至2024年12月5日11时1分\n检查地点:广东省梅州市五华县棉洋镇北斗新街\n被检查人名称:—/\n法定代表人(负责人):-/\n被检查人姓名:曾丽周\n性别:男性\n证件类型及号码:居民身份证\n441424196909145598\n地址:广东省五华县棉洋镇洛阳村红日_联系电话:15016277310\n烟草专卖许可证号码:441424106675\n现场负责人:_\n性别:_/\n证件类型及号码:\n联系电话:\nL\n与被检查人关系:\n告知事项:已出示执法证件,并已告知被检查人(现场负责人)有陈述与申辩权、申\n请回避的权利和如实陈述相关情况、提供证据、不得阻挠的义务。\n现场情况:2024年12月5日10时06分,接群众举报,我局专卖执法人员联合五华\n县公安局干警经出示执法证件,表明身份,说明来意,告知当事人曾丽周执法人员正\n在进行全程录像后,依法对当事人经营场所五华县棉洋镇北斗新街五华县棉洋镇周誉\n商店检查,当事人在场并同意接受检查。联合执法人员在其经营场所及附属区域仓库\n内发现条码有刮痕和刮毁的卷烟庐山(黄精品)150条、龙凤呈祥(鸿运朝天门)500\n条共2个品种合计650条。经现场询问当事人,其无法提供上述卷烟从当地烟草专\n卖批发企业进货的发票或其他合法有效凭证。因当事人的行为涉嫌违反《中华人民共\n和国烟草专卖法实施条例》第二十三条第二款的规定,有未在当地烟草专卖批发企业\n进货的嫌疑。经本局负责人批准,专卖执法人员即将上述涉案物品作为证据,依法予\n以先行登记保存。\n被检查人或者现场负责人意见\n被检查人或现场负责人(签名):\n见证人(签名):\n年〇月〇日\n颜帜来\n检查人(签名):\n执法证号:\n2月5日\n执法证号:\n2月5日\n第1页/共1页\n5", + "卷烟、雪茄烟鉴别检验报告": "广东省五华县烟草专卖局\n卷烟、雪茄烟鉴别检验委托单\n29", + "卷烟鉴别检验样品返还清单": "广东省五华县烟草专卖局\n卷烟鉴别检验样品耗用量清单\n0E", + "先行登记保存证据处理通知书": "广东省五华县烟草专卖局\n证据复制(提取)单\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n*YYC51***ppp*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411054******\n*YYC51*******\n曾丽周\n龙凤呈样(鸿运朝天门)\n安徽省\n1\n*AYC34******\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n1\n411054********\n*YYC51**********\n曾丽周\n龙凤呈样(鸿运朝天门)\n江西省\n1\n411015**********\n**YC360*******\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n*YYC51**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411028***\n*YC361*4\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411054****p*t:\n**YC341*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411041*\n**YC361*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n411054*\n*YC511\n曾丽周\n龙凤星样(鸿运朝天门)\n江西省\n1\n411042**\n**YC361*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411054**\n*YC341\n曾丽周\n龙凤呈样(鸿运朝天门)\n江西省\n411042**\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411054*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411054*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411045\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411054**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411045*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411054*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411045*\n*AYC51*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411054*\nRY\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411045*\n*YC511*\n曾丽周\n龙风呈样(鸿运朝天门)\n江西省\n411054\n曾丽周\n龙凤呈样(鸿运朝天门)\n江西省\n111045\n*YC360\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411054*\n曾丽周\n龙凤呈样(鸿运朝天门)\n安徽省\n411045*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411054\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411045*\n**YC511*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411054\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411045*\n*YC361*\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411054\n曾丽周\n龙凤呈样(鸿运朝天门)\n安徽省\n411045\n*YC340P\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411054\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411054*\n曾丽周\n龙凤呈样(鸿运朝天门)\n江西省\n411045\n**YC360\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411054\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n411045*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n411054\n曾丽周\n龙凤呈样(鸿运朝天门)\n安徽省\n411050*\n*YC341\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411054*\n曾丽周\n龙凤呈样(鸿运朝天门)\n江西省\n411051\n**YC361\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411052*\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411055\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n111052\nYC511\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n411055\n曾丽周\n龙凤呈样(鸿运朝天门)\n四川省\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411060*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411053\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411061*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411053\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411061*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n411053\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411063*\n曾丽周\n龙凤呈样(鸿运朝天门)\n江西省\n411053\n**YC361*\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411064\n曾丽周\n龙凤呈祥(鸿运朝天门)\n江西省\n411053*\n**YC361*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n411064**\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411053**\n*YC340*\n曾丽周\n龙风呈祥(鸿运朝天门)\n安省\n411064*\n00\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411053\n曾丽周\n龙凤呈祥(鸿运朝天门)\n安徽省\n411064***\nYC340*\n曾丽周\n龙凤呈样(鸿运朝天门)\n四川省\n411054**\n**YC510**\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411064*\n曾丽周\n龙凤呈样(鸿运朝天门)\n安徽省\n**YC341*******\n曾丽周\n龙风呈祥(鸿运朝天门)\n安徽省\n1\n411064*\n曾丽周\n龙凤星样(鸿运朝天门)\n四川省\n411054********\n**Yc511*******\n曾丽周\n龙凤呈祥(鸿运朝天门)\n四川省\n1\n411064**\n曾丽周\n龙风呈祥(鸿运朝天门)\n江西省\n411054*\n*YC3614\n曾丽周\n龙风呈祥(鸿运朝天门)\n四川省\n411065\n说明事项:五华县烟草专卖局梅林专卖管理所专卖执法人员对查获的涉案卷烟32\n位喷码进行提取\n复制(提取)地点:五华县烟草专卖局梅林专卖管理所办公室\n复制(提取)时间:2024年12月10日16时23分\n颜帜来\n执法人员及执法证号:\n柔清锐\n第1页/共1页\n14", + "卷烟、雪茄烟鉴别检验委托单": "广东省五华县烟草专卖局\n证据复制(提取)单\n27", + "卷烟、雪茄烟鉴别检验送样单": "广东省五华县烟草专卖局\n证据复制(提取)单\n26", + "卷烟鉴别检验样品耗用量清单": "广东省五华县烟草专卖局\n卷烟、雪茄烟鉴别检验送样单\n填单日期:2024年12月20日\n委托方\n广东省五华县烟草专卖局\n委托方电话\n07534435764\n广东省五华县水寨镇华\n委托方式\n送检\n委托方地址\n兴中路57号\n张清锐(19080852020),颜帜东\n经办人\n经办人电话\n07534435764\n(19080852010)\n案情状况\n普通\n案件情况\n零售户\n案件编号\n4414240202410056\n案卷编号\n华烟(2024)第56号\n查获地址或当事\n广东省梅州市五华县棉\n当事人\n曾丽周\n人地址\n洋镇北斗新街\n检毕样品处置方式\n取回\n送样单编号\nS202418225\n拟送检验受理点\n广东省质检站\n报告领取地点\n广东省梅州市烟草专卖局\n备注\n序\n申报数量/\n送样/抽\n送样名称\n条装条码\n单位\n单位\n样品状态描述\n说明\n号\n抽样基数\n样数量\n1\n庐山 (黄精品)\n6901028134583\n150\n条\n1\n条\n条包装完好\n龙凤呈祥(鸿\n2\n6901028227797\n500\n条\n1\n条\n条包装完好\n运朝天门)\n/\n/\n/\n/\n/\n1/1\n28", + "广东省非税收入一般缴款书(电子)": "鉴定结论为真品卷烟(检验报告编号:JYBGZW202417767),当\n事人对检验结果无异议。经梅州市烟草专卖局(公司)涉案\n卷烟价格管理小组核价,涉案卷烟总价值为28250.00元。\n处罚 (处理)\n《中华人民共和国烟草专卖法实施条例》第五十六条、《广\n依据\n东省烟草专卖行政处罚裁量权管理办法》附件1序号9\n当事人的行为涉嫌违反了《中华人民共和国烟草专卖法\n实施条例》第二十三条第二款的规定,涉嫌构成未在当地烟\n草专卖批发企业进货,建议根据《中华人民共和国烟草专卖\n法实施条例》第五十六条的规定进行处罚,当事人涉嫌未在\n当地烟草专卖批发企业进货总额28250.00元属于《广东省烟\n承办人\n草专卖行政处罚裁量权管理办法》附件1序号9中“取得烟\n意见\n草专卖零售许可证的企业或者个人未在当地烟草专卖批发企\n业进货,进货总额5000元以上不满3万元的,没收违法所得,\n处以进货总额7%以上9%以下的罚款”,建议对当事人曾丽周\n处以进货当额28250.00元的8%罚款,即罚款2260.00元。\n签名:东梅\n刘蒸\n日期:2025年1月20日\n承办部门\n意见\n签名:张疑锡\n日期:\n法制部门\n意见\n审核人签名:曾性\n负责人签名:徐小\n日期:\n负责人\n意见\n桃永刚\n签名:\n日期:\n备注\n第2页/共2页\n44\n\n广东省五华县烟草专卖局\n涉案物品返还清单\n品种\n规格\n数量 (单位)\n备注\n检验损耗数量0.2条,补偿\n庐山 (黄精品)\n84mm\n149.8条\n损耗费用9.54元\n检验损耗数量0.2条,补偿\n龙凤呈祥 (鸿运朝天门)\n84mm\n499.8条\n损耗费用7.2元\n合计\n649.6条\n鉴别检验样品损耗费合计16.74元(大写壹拾陆元柒角肆分)\n自愿放弃损耗费,返还卷烟已收到。\n不省\n返\n上述卷烟及检验损耗费已收到。\n东\n返达地点:广东省玉物具\n水寨镇华兴中路\n57号宝华县烟草专卖\n接收单位(印章):\n返还人:\n东梅\n接收人:\n刘蒸\n年月日\n2025年1月20日\n第1页/共1页\n45" }, - "status": 1, - "version": "v1.2", - "created_by": 2, - "created_at": "2025-03-26T01:23:58.549908", - "updated_at": "2025-03-26T01:23:58.549908" + "extracted_results": null, + "sumary": null, + "remark": "", + "created_at": "2025-04-09T08:48:01.155882+00:00", + "updated_at": "2025-04-09T16:51:09.529427+00:00" }, - { - "id": 3, - "template_name": "专卖许可证-摘要模板", - "template_type": "Summary", - "description": "生成专卖许可证申请文件的内容摘要", - "template_content": "你是一个专业的文档摘要助手。请为以下{docType}生成一份简洁的摘要:\n\n摘要应包含以下要点:\n1. 申请人基本信息\n2. 许可证类型\n3. 申请事项\n4. 经营范围\n5. 申请日期\n\n请控制摘要在200字以内,保留关键信息。", - "variables": { - "docType": "文档类型" - }, - "status": 1, - "version": "v1.0", - "created_by": 2, - "created_at": "2025-03-26T01:23:58.549908", - "updated_at": "2025-03-26T01:23:58.549908" - }, - { - "id": 4, - "template_name": "采购合同-乙方资质抽取", - "template_type": "Extraction", - "description": "抽取采购合同中乙方的资质信息", - "template_content": "你是一个专业的合同信息抽取助手。请从以下{docType}中抽取乙方的资质信息:\n\n需要抽取的信息包括:\n1. 乙方全称\n2. 资质证书类型\n3. 资质证书编号\n4. 资质等级\n5. 证书有效期\n\n请将结果以JSON格式输出,包含以上字段。", - "variables": { - "docType": "文档类型" - }, - "status": 0, - "version": "v1.1", - "created_by": 3, - "created_at": "2025-03-26T01:23:58.549908", - "updated_at": "2025-03-26T01:23:58.549908" - }, - { - "id": 5, - "template_name": "合同通用-关键条款评估", - "template_type": "Evaluation", - "description": "评估合同中关键条款是否明确、合规", - "template_content": "你是一个专业的{industry}行业合同审核助手。请评估以下合同中的关键条款是否明确、合规:\n\n请重点关注以下条款:\n1. 合同标的\n2. 价格条款\n3. 付款条件\n4. 交付方式\n5. 违约责任\n6. 争议解决\n\n请对每一项给出评估结果,并指出不明确或存在风险的条款。", - "variables": { - "docType": "文档类型", - "industry": "行业类型" - }, - "status": 1, - "version": "v2.0", - "created_by": 4, - "created_at": "2025-03-26T01:23:58.549908", - "updated_at": "2025-03-26T01:23:58.549908" - }, - { - "id": 6, - "template_name": "LLM通用抽取Prompt", - "template_type": "Extraction", - "description": "", - "template_content": "上面的文本为{{文档名称}}文档,请帮我结构化抽取下列信息:\n{{提取字段}}\n\n以 下面的json 结构输出抽取结果\n**输出格式**:\n - 以JSON格式输出结果:\n{\n \"{{文档名称}}\": {\n \"案件来源\": \"字段值\", \n \"案由\": \"字段值\"\n }\n}", - "variables": { - - }, - "status": 1, - "version": "v2.0", - "created_by": 4, - "created_at": "2025-03-26T01:23:58.549908", - "updated_at": "2025-03-26T01:23:58.549908" - }, - { - "id": 7, - "template_name": "VLM通用抽取Prompt", - "template_type": "Extraction", - "description": null, - "template_content": "上面的文本为{{文档名称}}文档,请帮我结构化抽取下列信息:\n{{提取字段}}\n\n以 下面的json 结构输出抽取结果\n**输出格式**:\n - 以JSON格式输出结果:\n{\n \"{{文档名称}}\": {\n \"案件来源\": \"字段值\", \n \"案由\": \"字段值\"\n }\n}", - "variables": { - - }, - "status": 1, - "version": "v2.0", - "created_by": 4, - "created_at": "2025-03-26T01:23:58.549908", - "updated_at": "2025-03-26T01:23:58.549908" - } ] \ No newline at end of file