给数据表设置自动编号-格式(**yyyymm####)

本文介绍如何在SQL Server数据库中为数据表设置有意义的自动编号。通过使用自定义函数fu_Invoice_Code,实现根据年月自动生成带有特定格式的主键编号。

       当我们设置数据表的时候,一般设置一列为主键,如果利用MS的Sql Server 数据库,可以设置主键列自动编号,它默认的是,从1自动增加。可我们有时,需要将主键列变得有一点意义,比如用年月之后是几位的自动编号,这样看起来,有有一点意义。
例如:一个数据表的结构如下:

If Exists (Select * From SysObjects Where Id = Object_Id('Invoice'))
Drop Table dbo.Invoice
GO
Create Table dbo.Invoice(
    InvCode 
varchar(12Not null Primary key,--开票编号
    InvType    varchar(10Not null,        --开票类型:整机、配件;
    InvType1 varchar(10Not null,        --开票类型:采购、销售
    InvType2 varchar(10Not Null,        --开票类型:普通、增值税
    Tax Numeric(8,2Not Null,        --开票金额;
    Cess Numeric(2,2Not Null,        --税率;
    InvDate smalldatetime Not Null,        --开票日期;
    Code1 varchar(20Null,            --票号1
    Code2 varchar(20Null,            --票号2
    OPTaxCode varchar(20Not Null,        --往业单位税号
    OPName varchar(50Not Null,        --往来单位名称
    Note varchar(100Null,            --备注;
    IsValidate bit Not Null,         --确认标识:默认没有确认;
    Pact Varchar(12Null            --对应合同编号;
)
GO
当建立数据表后,需要设置InvCode数据列为函数所取得的编号,代码如下所示:
--=============================================================================
/****** 对象: 自定函数 dbo.fu_Invoice_Code ******/
/****** 说明:发票编号 ******/
--=============================================================================
if exists (select * from dbo.sysobjects where id = object_id('dbo.fu_Invoice_Code'))
drop function dbo.fu_Invoice_Code
GO
SET QUOTED_IDENTIFIER ON 
GO
SET ANSI_NULLS OFF 
GO
 
CREATE FUNCTION dbo.fu_Invoice_Code ()  
RETURNS varchar(12AS  
BEGIN 
    
declare @ResultCode varchar(12) , @ToDay SmallDatetime
    
Select @ToDay = ToDay From vw_GetDate
    
if Exists ( Select * From Invoice )
    
begin
        
Select  @ResultCode =  Max ( InvCode ) From Invoice
        
--取出数据表中最大年份,看是否是当年的信息
        If ( SubString ( @ResultCode , 3 , 4 ) = DateName ( Year,@ToDay ) )
        
begin
            
--取出数据表中的最大编号的月份,看是否是当前的月份
            If ( SubString ( @ResultCode , 7 , 2 ) = DateName ( Month , @ToDay ) )
                
--当是当前月份时,把最后四位进行处理,重新获取新的编号
                Set @ResultCode = Left ( @ResultCode , 8 ) + 
                
Right ( '0000' + Convert ( varchar , Convert ( int , SubString ( @ResultCode , 9 , 4 ) ) +1  ) , 4 )
            
else    
            
--当不是当前的月份时,取出前六位,之后把当前的月份编号添加上去,再加上0000,组成最大的编号    
                Set @ResultCode=Left(@ResultCode,6)+DateName(Month,@ToDay)+'0000'
        
end
        
else 
        
--当从数据表中取出的最大年份不是当年时 ,进行如下操作
            Set @ResultCode =  'FP' + DateName ( Year , @ToDay ) + DateName ( Month , @ToDay ) + '0000'
    
end
    
else
        
Set @ResultCode =  'FP' + DateName ( Year , @ToDay ) + DateName ( Month , @ToDay ) + '0000'
    
return @ResultCode
END-------------------------------------------------------------------------------
ALTER TABLE dbo.Invoice ADD 
--自动发票编号
    CONSTRAINT DF_Invoice_InvCode DEFAULT (dbo.fu_Invoice_Code()) FOR InvCode
GO
pipeline { agent any environment { // 基础配置 PHP_VERSION = '8.1' PROJECT_NAME = 'test_admin' DEPLOY_BASE_PATH = '/www/wwwroot' REMOTE_DIR = 'xsyd-admin' SITE_URL = 'http://118.89.182.70:8899/' SSH_CONFIG_NAME = 'testXsydAdmin' WXWORK_ROBOT = 'tesAdmin' GIT_CREDENTIALS = 'f3eace06-0d10-4af8-accb-c8e757110ffd' // 运行时变量 CHANGED_FILES = "" DEPLOY_MODE = "incremental" COMMIT_HISTORY_FILE = "last_commit.txt" } stages { stage('代码检出') { steps { echo "==================== 代码检出 ====================" checkout([ $class: 'GitSCM', branches: [[name: '*/main']], extensions: [[ $class: 'CloneOption', depth: 0, shallow: false, noTags: false ]], userRemoteConfigs: [[ url: "${env.GIT_URL}", credentialsId: "${env.GIT_CREDENTIALS}" ]] ]) } } stage('获取变更文件') { steps { echo "==================== 获取变更文件 ====================" script { // 获取当前提交 def currentCommit = bat(script: '@git rev-parse HEAD', returnStdout: true).trim() // 获取上次提交(带验证) def lastCommit = null try { lastCommit = readFile('last_commit.txt').trim() if (lastCommit == currentCommit) { echo "警告:提交记录未变化,将视为首次部署" lastCommit = null } } catch(e) { echo "首次部署或未找到上次提交记录" } // 获取变更文件(兼容Windows) if (!lastCommit) { env.DEPLOY_MODE = 'full' env.CHANGED_FILES = bat( script: '@git ls-files', returnStdout: true ).trim().replace('\r\n', '\n') } else { writeFile file: 'get_changes.bat', text: """ @echo off git diff --name-only --diff-filter=ACMRT ${lastCommit} ${currentCommit} > changes.txt type changes.txt """ env.CHANGED_FILES = bat( script: 'call get_changes.bat', returnStdout: true ).trim() env.DEPLOY_MODE = env.CHANGED_FILES ? 'incremental' : 'none' } // 调试输出 echo "===== 调试信息 =====" echo "当前提交: ${currentCommit}" echo "上次提交: ${lastCommit ?: '无'}" echo "变更文件列表:\n${env.CHANGED_FILES ?: '无变更'}" // 保存当前提交 writeFile file: 'last_commit.txt', text: currentCommit } } } stage('部署') { when { expression { env.DEPLOY_MODE != 'none' } } steps { script { def deployDir = "${env.DEPLOY_BASE_PATH}/${env.REMOTE_DIR}" if (env.DEPLOY_MODE == 'full') { echo "执行全量部署..." sshPublisher( publishers: [ sshPublisherDesc( configName: "${env.SSH_CONFIG_NAME}", transfers: [ sshTransfer( sourceFiles: "**/*", remoteDirectory: "${env.REMOTE_DIR}", execCommand: """ # 设置目录权限 chmod -R 755 ${deployDir} chmod -R 777 ${deployDir}/storage ${deployDir}/bootstrap/cache # 清理缓存 cd ${deployDir} && \ php artisan config:clear && \ php artisan view:clear """ ) ] ) ] ) } else { echo "执行增量部署..." // 创建变更文件清单 writeFile file: 'changed_files.txt', text: env.CHANGED_FILES // 使用批处理脚本处理增量部署 bat """ @echo off echo ${env.CHANGED_FILES} > changed_files.txt type changed_files.txt """ sshPublisher( publishers: [ sshPublisherDesc( configName: "${env.SSH_CONFIG_NAME}", transfers: [ sshTransfer( sourceFiles: 'changed_files.txt', remoteDirectory: '/tmp', removePrefix: '' ), sshTransfer( execCommand: """ # 准备变量 DEPLOY_DIR="${deployDir}" FILE_LIST="/tmp/changed_files.txt" BACKUP_DIR="/tmp/backup_\$(date +%s)" # 创建备份目录 mkdir -p "\${BACKUP_DIR}" # 处理每个变更文件 while IFS= read -r file; do [ -z "\$file" ] && continue # 备份原文件 if [ -f "\${DEPLOY_DIR}/\${file}" ]; then mkdir -p "\${BACKUP_DIR}/\$(dirname "\${file}")" cp "\${DEPLOY_DIR}/\${file}" "\${BACKUP_DIR}/\${file}" fi # 确保目标目录存在 mkdir -p "\${DEPLOY_DIR}/\$(dirname "\${file}")" # 同步文件 echo "同步文件: \${file}" rsync -avz "\${file}" "\${DEPLOY_DIR}/\${file}" done < "\${FILE_LIST}" # 清理临时文件 rm -f "\${FILE_LIST}" # 设置权限 while IFS= read -r file; do [ -z "\$file" ] && continue if [ -f "\${DEPLOY_DIR}/\${file}" ]; then chmod 755 "\${DEPLOY_DIR}/\${file}" fi done < "\${FILE_LIST}" echo "增量部署完成,备份保存在: \${BACKUP_DIR}" """ ) ] ) ] ) } } } } } post { always { script { def changedFilesCount = env.CHANGED_FILES ? env.CHANGED_FILES.split('\n').size() : 0 def lastCommitInfo = bat( script: '@git log -1 --pretty=format:"%h - %an, %ar : %s"', returnStdout: true ).trim() echo """ |==================== 流水线总结 ==================== | 项目名称: ${env.PROJECT_NAME} | 部署模式: ${env.DEPLOY_MODE} | 构建编号: #${env.BUILD_NUMBER} | Git 分支: ${env.GIT_BRANCH} | 变更文件数: ${changedFilesCount} | 最后提交: ${lastCommitInfo} | 执行时间: ${new Date()} |==================================================== """ } } success { script { currentBuild.description = "部署成功 - #${env.BUILD_NUMBER}" def markdownMsg = """ # ✅ 部署成功通知 ## 构建信息 - **项目名称**: `${env.PROJECT_NAME}` - **构建编号**: `#${env.BUILD_NUMBER}` - **部署模式**: `${env.DEPLOY_MODE}` - **Git分支**: `${env.GIT_BRANCH}` - **部署目录**: `${env.DEPLOY_BASE_PATH}/${env.REMOTE_DIR}` - **构建耗时**: `${currentBuild.durationString}` - **部署时间**: `${new Date().format('yyyy-MM-dd HH:mm:ss')}` ## 状态信息 > 所有阶段执行成功,项目已成功部署! --- [查看Jenkins详情](${env.BUILD_URL}) [访问部署站点](${env.SITE_URL}) **部署完成,可以开始测试了!** """ wxworkSendNotification(markdownMsg, false) } } failure { script { currentBuild.description = "部署失败 - #${env.BUILD_NUMBER}" def markdownMsg = """ # ❌ 部署失败通知 ## 构建信息 - **项目名称**: `${env.PROJECT_NAME}` - **构建编号**: `#${env.BUILD_NUMBER}` - **失败时间**: `${new Date().format('yyyy-MM-dd HH:mm:ss')}` ## 错误信息 > 部署过程中发生错误,请及时检查日志并处理! ## 处理建议 1. 检查代码是否有语法错误 2. 确认依赖包是否正常安装 3. 验证服务器连接是否正常 4. 查看详细的Jenkins日志 --- [立即查看Jenkins日志](${env.BUILD_URL}) **请相关人员及时处理部署失败问题!** """ wxworkSendNotification(markdownMsg, true) } } unstable { script { currentBuild.description = "构建不稳定 - #${env.BUILD_NUMBER}" def markdownMsg = """ # ⚠️ 构建不稳定通知 ## 构建信息 - **项目名称**: `${env.PROJECT_NAME}` - **构建编号**: `#${env.BUILD_NUMBER}` - **完成时间**: `${new Date().format('yyyy-MM-dd HH:mm:ss')}` ## 状态说明 > 构建完成但存在警告,建议检查日志信息 ## 建议操作 - 检查构建过程中的警告信息 - 验证功能是否正常工作 - 考虑修复警告以提高代码质量 --- [查看Jenkins详情](${env.BUILD_URL}) [访问部署站点](${env.SITE_URL}) **虽然构建不稳定,但项目可能已正常部署** """ wxworkSendNotification(markdownMsg, false) } } } } // 企业微信通知方法 def wxworkSendNotification(message, atAll) { try { wxwork( robot: "${env.WXWORK_ROBOT}", type: 'markdown_v2', atAll: atAll, text: message.split('\n') as String[] ) echo "企业微信通知发送成功" } catch (Exception e) { echo "企业微信通知发送失败: ${e.getMessage()}" } } 根据我当前的jenkinsfile文件来修改成我要的
08-17
;;; 电缆接线数据采集与生成系统 - 修复增强版 ;;; 功能:交互式电缆数据采集、接线图生成、数据导出 ;;; 使用方法:载后在CAD中输入 CABLE_COLLECT 启动程序 ;;; 全局变量定义 (setq *cable-connections* nil) ; 存储所有连接数据 (setq *current-connection* nil) ; 当前正在采集的连接 (setq *selection-step* 0) ; 当前选择步骤 (0-4) (setq *is-running* nil) ; 程序运行状态 (setq *last-selected-entity* nil) ; 最后选择的实体 (setq *last-selected-text* "") ; 最后选择的文本内容 (setq *auto-save-enabled* t) ; 自动保存开关 (setq *keyboard-input-mode* nil) ; 键盘输入模式标志 ;;; 连接数据结构 (defun create-connection-data () "创建新的连接数据结构" (list (cons 'cable-number "") ; 电缆编号 (cons 'cable-type "") ; 电缆型号 (cons 'specification "") ; 规格 (cons 'start-device "") ; 起点设备编号 (cons 'end-device "") ; 终点设备编号 (cons 'wire-color "") ; 线色(新增) (cons 'length "") ; 长度(新增) (cons 'remarks "") ; 备注(新增) (cons 'status "采集进行中") ; 状态 (cons 'timestamp (rtos (getvar "CDATE") 2 16)) ; 时间戳 ) ) ;;; 用户界面函数 (defun show-welcome-screen () "显示欢迎界面" (princ "\n") (princ "\n╔══════════════════════════════════════════════════╗") (princ "\n║ 电缆接线数据采集与生成系统 ║") (princ "\n║ Cable Data Collection ║") (princ "\n╠══════════════════════════════════════════════════╣") (princ "\n║ ║") (princ "\n║ 功能特点: ║") (princ "\n║ • 交互式电缆数据采集 ║") (princ "\n║ • 自动接线图生成 ║") (princ "\n║ • 数据导出与导入 ║") (princ "\n║ • 实时状态显示 ║") (princ "\n║ • 支持鼠标选择和键盘输入 ║") (princ "\n║ ║") (princ "\n╚══════════════════════════════════════════════════╝") (princ "\n") ) (defun show-control-panel () "显示控制面板" (princ "\n┌───────────────── 控制面板 ─────────────────┐") (princ "\n│ 快捷键: │") (princ "\n│ [鼠标左键] 选择文本实体 │") (princ "\n│ [鼠标右键] 撤销上一步 │") (princ "\n│ [空格键] 确认当前步骤 │") (princ "\n│ [回车键] 完成当前连接 │") (princ "\n│ [K] 切换到键盘输入 │") (princ "\n│ │") (princ "\n│ 命令键: │") (princ "\n│ [S] 显示状态 [L] 载数据 │") (princ "\n│ [E] 导出数据 [G] 生成接线图 │") (princ "\n│ [C] 清除数据 [A] 自动保存开关 │") (princ "\n│ [H] 帮助信息 [Q] 退出程序 │") (princ "\n└──────────────────────────────────────────┘") ) (defun show-progress-bar () "显示进度条" (setq total-steps 5) (setq progress (fix (* (/ (float *selection-step*) total-steps) 100))) (setq bar-length 20) (setq filled (fix (* (/ (float *selection-step*) total-steps) bar-length))) (setq empty (- bar-length filled)) (princ "\n┌─ 采集进度 [") (repeat filled (princ "█")) (repeat empty (princ "─")) (princ (strcat "] " (itoa progress) "% ─┐")) ) ;;; 工具函数优化 (defun connection-complete-p (conn) "检查连接数据是否完整" (and (not (equal (cdr (assoc 'cable-number conn)) "")) (not (equal (cdr (assoc 'cable-type conn)) "")) (not (equal (cdr (assoc 'specification conn)) "")) (not (equal (cdr (assoc 'start-device conn)) "")) (not (equal (cdr (assoc 'end-device conn)) "")) ) ) (defun get-step-info (step) "获取步骤的详细信息" (cond ((= step 0) (list "电缆编号" "选择电缆的唯一编号" "如: CABLE-001")) ((= step 1) (list "电缆型号" "选择电缆的型号规格" "如: YJV-0.6/1kV")) ((= step 2) (list "电缆规格" "选择电缆的截面积" "如: 3×4+1×2.5")) ((= step 3) (list "起点设备" "选择电缆起始设备编号" "如: MCC-01")) ((= step 4) (list "终点设备" "选择电缆终止设备编号" "如: MOTOR-01")) (t (list "完成" "数据采集完成" "")) ) ) (defun show-current-step () "显示当前步骤信息" (setq step-info (get-step-info *selection-step*)) (setq step-name (nth 0 step-info)) (setq step-desc (nth 1 step-info)) (setq step-example (nth 2 step-info)) (princ (strcat "\n\n当前步骤: 第 " (itoa (+ *selection-step* 1)) " 步 - " step-name)) (princ (strcat "\n步骤说明: " step-desc)) (if (/= step-example "") (princ (strcat "\n示例: " step-example)) ) (princ (strcat "\n提示: " (get-step-prompt))) (show-progress-bar) ) (defun get-step-prompt () "获取当前步骤的提示信息" (cond ((= *selection-step* 0) "请选择电缆编号文本 (左键选择文本) 或按 K 键盘输入") ((= *selection-step* 1) "请选择电缆型号文本 (左键选择文本) 或按 K 键盘输入") ((= *selection-step* 2) "请选择规格文本 (左键选择文本) 或按 K 键盘输入") ((= *selection-step* 3) "请选择起点设备编号文本 (左键选择文本) 或按 K 键盘输入") ((= *selection-step* 4) "请选择终点设备编号文本 (左键选择文本) 或按 K 键盘输入") (t "数据采集完成,按回车保存或继续选择") ) ) (defun highlight-selected-entity (ent) "高亮显示选择的实体" (if ent (progn ;; 取消之前的高亮 (if *last-selected-entity* (progn (setq old-ent (entget *last-selected-entity*)) (setq old-color (assoc 62 old-ent)) (if old-color (setq old-ent (subst '(62 . 256) old-color old-ent)) (setq old-ent (append old-ent '((62 . 256)))) ) (entmod old-ent) ) ) ;; 高亮新选择的实体 (setq new-ent (entget ent)) (setq new-color (assoc 62 new-ent)) (if new-color (setq new-ent (subst '(62 . 1) new-color new-ent)) (setq new-ent (append new-ent '((62 . 1)))) ) (entmod new-ent) (setq *last-selected-entity* ent) ) ) ) ;;; 键盘输入功能 (defun process-keyboard-input () "处理键盘输入模式" (setq *keyboard-input-mode* t) (setq step-info (get-step-info *selection-step*)) (setq step-name (nth 0 step-info)) (setq step-example (nth 2 step-info)) (princ (strcat "\n📝 键盘输入模式 - " step-name)) (if (/= step-example "") (princ (strcat " (示例: " step-example ")")) ) (princ "\n请输入数据: ") (setq input (getstring t)) (if (and input (> (strlen input) 0)) (progn (assign-text-to-step input) (show-selection-feedback input) (setq *keyboard-input-mode* nil) t ) (progn (princ "\n❌ 输入为空,取消键盘输入模式") (setq *keyboard-input-mode* nil) nil ) ) ) ;;; 主要交互功能优化 (defun process-mouse-click () "处理鼠标左键点击 - 选择实体" (princ "\n请选择文本实体: ") (setq ent (car (entsel))) (if ent (progn (setq text-content (extract-text-from-entity ent)) (if (and text-content (> (strlen text-content) 0)) (progn (highlight-selected-entity ent) (setq *last-selected-text* text-content) (assign-text-to-step text-content) (show-selection-feedback text-content) t ) (progn (princ "\n错误: 未找到有效文本内容,请重新选择") nil ) ) ) (progn (princ "\n取消选择") nil ) ) ) (defun show-selection-feedback (text) "显示选择反馈" (setq step-info (get-step-info *selection-step*)) (setq step-name (nth 0 step-info)) (princ (strcat "\n✓ 已选择" step-name ": \"" text "\"")) ) (defun extract-text-from-entity (ent) "从CAD实体中提取文本内容 - 增强版" (if ent (progn (setq ent-data (entget ent)) (setq entity-type (cdr (assoc 0 ent-data))) (cond ;; 普通文本 ((= entity-type "TEXT") (cdr (assoc 1 ent-data)) ) ;; 多行文本 ((= entity-type "MTEXT") (cdr (assoc 1 ent-data)) ) ;; 属性定义 ((= entity-type "ATTDEF") (cdr (assoc 1 ent-data)) ) ;; 块引用 - 提取属性 ((= entity-type "INSERT") (extract-attributes-from-block ent) ) ;; 尺寸标注 ((= entity-type "DIMENSION") (extract-dimension-text ent) ) (t (princ "\n警告: 选择的实体类型不支持文本提取") "" ) ) ) "" ) ) (defun extract-attributes-from-block (blk-ent) "从块引用中提取属性文本 - 增强版" (setq att-texts '()) (setq blk-name (cdr (assoc 2 (entget blk-ent)))) ;; 遍历块引用后的属性 (setq next-ent (entnext blk-ent)) (while (and next-ent (= (cdr (assoc 0 (entget next-ent))) "ATTRIB")) (setq att-data (entget next-ent)) (setq tag (cdr (assoc 2 att-data))) (setq value (cdr (assoc 1 att-data))) (if (and value (> (strlen value) 0)) (setq att-texts (cons value att-texts)) ) (setq next-ent (entnext next-ent)) ) (if att-texts (progn ;; 让用户选择使用哪个属性 (princ "\n检测到多个属性,请选择: ") (setq i 1) (foreach text att-texts (princ (strcat "\n " (itoa i) ": " text)) (setq i (1+ i)) ) (princ "\n输入编号选择 (直接回车使用第一个): ") (setq choice (getstring)) (if (and choice (/= choice "")) (progn (setq idx (atoi choice)) (if (and (>= idx 1) (<= idx (length att-texts))) (nth (- idx 1) att-texts) (car att-texts) ) ) (car att-texts) ) ) "" ) ) (defun extract-dimension-text (dim-ent) "从尺寸标注提取文本" (setq dim-data (entget dim-ent)) (setq measurement (cdr (assoc 1 dim-data))) (if (or (null measurement) (= measurement "")) (rtos (cdr (assoc 42 dim-data)) 2 2) ; 使用实际测量值 measurement ) ) (defun assign-text-to-step (text) "将文本分配到当前步骤" (cond ((= *selection-step* 0) ; 电缆编号 (setq *current-connection* (subst (cons 'cable-number text) (assoc 'cable-number *current-connection*) *current-connection*)) ) ((= *selection-step* 1) ; 电缆型号 (setq *current-connection* (subst (cons 'cable-type text) (assoc 'cable-type *current-connection*) *current-connection*)) ) ((= *selection-step* 2) ; 规格 (setq *current-connection* (subst (cons 'specification text) (assoc 'specification *current-connection*) *current-connection*)) ) ((= *selection-step* 3) ; 起点设备 (setq *current-connection* (subst (cons 'start-device text) (assoc 'start-device *current-connection*) *current-connection*)) ) ((= *selection-step* 4) ; 终点设备 (setq *current-connection* (subst (cons 'end-device text) (assoc 'end-device *current-connection*) *current-connection*)) ) ) ) (defun process-right-click () "处理鼠标右键点击 - 撤销上一步选择" (if (> *selection-step* 0) (progn (setq *selection-step* (- *selection-step* 1)) (reset-current-step) (princ "\n↶ 已撤销上一步选择") (show-current-step) ) (princ "\n⚠ 无法撤销,已在第一步") ) ) (defun reset-current-step () "重置当前步骤的数据" (cond ((= *selection-step* 0) (setq *current-connection* (subst (cons 'cable-number "") (assoc 'cable-number *current-connection*) *current-connection*)) ) ((= *selection-step* 1) (setq *current-connection* (subst (cons 'cable-type "") (assoc 'cable-type *current-connection*) *current-connection*)) ) ((= *selection-step* 2) (setq *current-connection* (subst (cons 'specification "") (assoc 'specification *current-connection*) *current-connection*)) ) ((= *selection-step* 3) (setq *current-connection* (subst (cons 'start-device "") (assoc 'start-device *current-connection*) *current-connection*)) ) ((= *selection-step* 4) (setq *current-connection* (subst (cons 'end-device "") (assoc 'end-device *current-connection*) *current-connection*)) ) ) ) (defun process-space () "处理空格键 - 确认当前步骤" (if (< *selection-step* 4) (if (not (equal (get-current-step-data) "")) (progn (setq *selection-step* (+ *selection-step* 1)) (princ "\n✓ 步骤确认") (show-current-step) ) (princ "\n❌ 当前步骤没有数据,请先选择文本") ) (complete-current-connection) ) ) (defun get-current-step-data () "获取当前步骤的数据" (cond ((= *selection-step* 0) (cdr (assoc 'cable-number *current-connection*))) ((= *selection-step* 1) (cdr (assoc 'cable-type *current-connection*))) ((= *selection-step* 2) (cdr (assoc 'specification *current-connection*))) ((= *selection-step* 3) (cdr (assoc 'start-device *current-connection*))) ((= *selection-step* 4) (cdr (assoc 'end-device *current-connection*))) (t "") ) ) (defun process-enter () "处理回车键 - 完成当前连接并开始下一个" (if (and (= *selection-step* 4) (not (equal (get-current-step-data) ""))) (complete-current-connection) (princ "\n⚠ 请先完成所有步骤的选择") ) ) (defun complete-current-connection () "完成当前连接" (if (connection-complete-p *current-connection*) (progn ;; 更新状态和时间戳 (setq *current-connection* (subst (cons 'status "已完成") (assoc 'status *current-connection*) *current-connection*)) (setq *current-connection* (subst (cons 'timestamp (rtos (getvar "CDATE") 2 16)) (assoc 'timestamp *current-connection*) *current-connection*)) (setq *cable-connections* (append *cable-connections* (list *current-connection*))) (show-connection-summary) ;; 自动保存到文件 (if *auto-save-enabled* (save-connections-to-file "cable_connections.txt") ) ;; 重置为新的连接 (reset-for-new-connection) ) (progn (setq incomplete-fields (get-incomplete-fields)) (princ (strcat "\n❌ 连接数据不完整,缺少: " incomplete-fields)) (show-current-step) ) ) ) (defun show-connection-summary () "显示连接摘要" (setq conn *current-connection*) (princ "\n\n┌────────────── 连接摘要 ──────────────┐") (princ (strcat "\n│ 电缆编号: " (cdr (assoc 'cable-number conn)))) (princ (strcat "\n│ 电缆型号: " (cdr (assoc 'cable-type conn)))) (princ (strcat "\n│ 规格: " (cdr (assoc 'specification conn)))) (princ (strcat "\n│ 路径: " (cdr (assoc 'start-device conn)) " → " (cdr (assoc 'end-device conn)))) (princ (strcat "\n│ 状态: " (cdr (assoc 'status conn)))) (princ (strcat "\n│ 总连接数: " (itoa (length *cable-connections*)))) (princ "\n└────────────────────────────────────┘") ) (defun get-incomplete-fields () "获取不完整的字段列表" (setq fields '()) (if (equal (cdr (assoc 'cable-number *current-connection*)) "") (setq fields (cons "电缆编号" fields)) ) (if (equal (cdr (assoc 'cable-type *current-connection*)) "") (setq fields (cons "电缆型号" fields)) ) (if (equal (cdr (assoc 'specification *current-connection*)) "") (setq fields (cons "规格" fields)) ) (if (equal (cdr (assoc 'start-device *current-connection*)) "") (setq fields (cons "起点设备" fields)) ) (if (equal (cdr (assoc 'end-device *current-connection*)) "") (setq fields (cons "终点设备" fields)) ) (apply 'strcat (mapcar '(lambda (x) (strcat x " ")) fields)) ) (defun reset-for-new-connection () "重置为新的连接" (setq *current-connection* (create-connection-data)) (setq *selection-step* 0) (setq *last-selected-entity* nil) (setq *last-selected-text* "") (princ "\n🔄 开始新的连接采集...") (show-current-step) ) ;;; 文件操作功能增强 (defun save-connections-to-file (filename / file i conn) "保存连接数据到文本文件 - 增强版" (setq file (open filename "w")) (if file (progn (write-line ";; 电缆连接数据 - 自动生成" file) (write-line ";; 生成系统: Cable Data Collection System" file) (write-line ";; =======================================" file) (write-line (strcat ";; 生成时间: " (menucmd "M=$(edtime,$(getvar,date),YYYY-MO-DD HH:MM:SS)")) file) (write-line (strcat ";; 总连接数: " (itoa (length *cable-connections*))) file) (write-line "" file) (setq i 1) (foreach conn *cable-connections* (write-line (strcat "CONNECTION_" (itoa i)) file) (write-line (strcat " CABLE_NUMBER=" (cdr (assoc 'cable-number conn))) file) (write-line (strcat " CABLE_TYPE=" (cdr (assoc 'cable-type conn))) file) (write-line (strcat " SPECIFICATION=" (cdr (assoc 'specification conn))) file) (write-line (strcat " START_DEVICE=" (cdr (assoc 'start-device conn))) file) (write-line (strcat " END_DEVICE=" (cdr (assoc 'end-device conn))) file) (write-line (strcat " STATUS=" (cdr (assoc 'status conn))) file) (write-line (strcat " TIMESTAMP=" (cdr (assoc 'timestamp conn))) file) (write-line "" file) (setq i (+ i 1)) ) (close file) (princ (strcat "\n💾 数据已保存到: " filename)) t ) (progn (princ (strcat "\n❌ 无法创建文件: " filename)) nil ) ) ) (defun load-connections-from-file (filename / file line conn) "从文件载连接数据 - 增强版" (if (findfile filename) (progn (setq file (open filename "r")) (if file (progn (setq *cable-connections* nil) (setq conn nil) ;; 读取文件 (while (setq line (read-line file)) (cond ((wcmatch line "CONNECTION_*") (if conn (setq *cable-connections* (append *cable-connections* (list conn))) ) (setq conn (create-connection-data)) ) ((wcmatch line " CABLE_NUMBER=*") (if conn (setq conn (subst (cons 'cable-number (substr line 15)) (assoc 'cable-number conn) conn)) ) ) ((wcmatch line " CABLE_TYPE=*") (if conn (setq conn (subst (cons 'cable-type (substr line 13)) (assoc 'cable-type conn) conn)) ) ) ((wcmatch line " SPECIFICATION=*") (if conn (setq conn (subst (cons 'specification (substr line 16)) (assoc 'specification conn) conn)) ) ) ((wcmatch line " START_DEVICE=*") (if conn (setq conn (subst (cons 'start-device (substr line 15)) (assoc 'start-device conn) conn)) ) ) ((wcmatch line " END_DEVICE=*") (if conn (setq conn (subst (cons 'end-device (substr line 13)) (assoc 'end-device conn) conn)) ) ) ) ) ;; 添最后一个连接 (if conn (setq *cable-connections* (append *cable-connections* (list conn))) ) (close file) (princ (strcat "\n📂 从文件载了 " (itoa (length *cable-connections*)) " 个连接")) t ) (progn (princ (strcat "\n❌ 无法读取文件: " filename)) nil ) ) ) (progn (princ (strcat "\n❌ 文件不存在: " filename)) nil ) ) ) ;;; 接线图生成功能增强 (defun generate-wiring-diagram (/ y-pos row-height i conn) "生成接线图 - 增强版" (if (null *cable-connections*) (progn (princ "\n❌ 错误: 没有可用的连接数据") nil ) (progn (princ "\n🔄 正在生成接线图...") (create-wiring-layers) (setq y-pos 250.0) (setq row-height 25.0) (setq i 0) (foreach conn *cable-connections* (if (< i 15) ; 限制每页显示数量 (progn (setq y (- y-pos (* i row-height))) (draw-connection-line conn y i) (setq i (+ i 1)) ) ) ) (draw-legend (- y-pos (* i row-height) 15.0)) (draw-title) (draw-table-header) (command "._zoom" "_extents") (princ "\n✅ 接线图生成完成!") t ) ) ) (defun create-wiring-layers () "创建接线图图层 - 增强版" (command "._-layer" "_m" "CABLE_WIRING" "_c" "1" "" "_lw" "0.3" "" "") (command "._-layer" "_m" "CABLE_TEXT" "_c" "2" "" "_lw" "0.18" "" "") (command "._-layer" "_m" "CABLE_DEVICE" "_c" "3" "" "_lw" "0.25" "" "") (command "._-layer" "_m" "CABLE_TITLE" "_c" "4" "" "_lw" "0.5" "" "") (command "._-layer" "_m" "CABLE_FRAME" "_c" "5" "" "_lw" "0.35" "" "") ) (defun draw-connection-line (conn y index) "绘制连接线 - 增强版" (setq start-x 50.0) (setq end-x 250.0) (setq mid-x (/ (+ start-x end-x) 2.0)) ;; 绘制连接线 (command "._-layer" "_s" "CABLE_WIRING" "") (command "._line" (list start-x y) (list end-x y) "") ;; 绘制设备节点 (command "._-layer" "_s" "CABLE_DEVICE" "") (command "._circle" (list start-x y) 1.5) (command "._circle" (list end-x y) 1.5) ;; 填充节点 (command "._hatch" "SOLID" "" (list (list start-x y)) "") (command "._hatch" "SOLID" "" (list (list end-x y)) "") ;; 添序号 (command "._-layer" "_s" "CABLE_TEXT" "") (command "._text" "_j" "_bl" (list 35.0 (- y 2.0)) 2.0 0.0 (itoa (+ index 1))) ;; 添设备文本 (command "._text" "_j" "_ml" (list (+ start-x 8.0) (+ y 3.0)) 2.5 0.0 (cdr (assoc 'start-device conn))) (command "._text" "_j" "_mr" (list (- end-x 8.0) (+ y 3.0)) 2.5 0.0 (cdr (assoc 'end-device conn))) ;; 添电缆信息 (setq cable-info (strcat (cdr (assoc 'cable-number conn)) " | " (cdr (assoc 'cable-type conn)) " | " (cdr (assoc 'specification conn)))) (command "._text" "_j" "_bc" (list mid-x (- y 6.0)) 1.8 0.0 cable-info) ) (defun draw-table-header () "绘制表格标题" (command "._-layer" "_s" "CABLE_TEXT" "") (command "._text" "_j" "_bl" (list 35.0 245.0) 3.0 0.0 "No.") (command "._text" "_j" "_bl" (list 50.0 245.0) 3.0 0.0 "起点设备") (command "._text" "_j" "_br" (list 250.0 245.0) 3.0 0.0 "终点设备") (command "._text" "_j" "_bc" (list 150.0 245.0) 3.0 0.0 "电缆信息") ;; 绘制标题线 (command "._line" (list 30.0 242.0) (list 260.0 242.0) "") ) (defun draw-legend (y-pos) "绘制图例 - 增强版" (command "._-layer" "_s" "CABLE_TEXT" "") (command "._text" "_j" "_ml" (list 50.0 y-pos) 2.5 0.0 "图例说明:") (command "._text" "_j" "_ml" (list 50.0 (- y-pos 6.0)) 1.8 0.0 "● - 设备连接节点") (command "._text" "_j" "_ml" (list 50.0 (- y-pos 9.0)) 1.8 0.0 "━━━ - 电缆连接线路") (command "._text" "_j" "_ml" (list 50.0 (- y-pos 12.0)) 1.8 0.0 "编号 | 型号 | 规格 - 电缆详细信息") ) (defun draw-title () "绘制标题 - 增强版" (command "._-layer" "_s" "CABLE_TITLE" "") (setq title (strcat "电缆接线图 - 基于交互数据采集系统" " | 总连接数: " (itoa (length *cable-connections*)) " | 生成时间: " (menucmd "M=$(edtime,$(getvar,date),YYYY-MO-DD)"))) (command "._text" "_j" "_mc" (list 150.0 270.0) 4.0 0.0 title) ) ;;; 状态显示功能增强 (defun show-status () "显示当前状态 - 增强版" (princ "\n") (princ "\n┌──────────────── 系统状态 ────────────────┐") (princ (strcat "\n│ 当前步骤: " (itoa (+ *selection-step* 1)) "/5")) (princ (strcat "\n│ 步骤名称: " (nth 0 (get-step-info *selection-step*)))) (princ (strcat "\n│ 已保存连接: " (itoa (length *cable-connections*)) " 个")) (princ (strcat "\n│ 自动保存: " (if *auto-save-enabled* "开启" "关闭"))) (princ (strcat "\n│ 键盘输入模式: " (if *keyboard-input-mode* "开启" "关闭"))) (princ "\n│ │") (princ "\n│ 当前连接数据: │") (princ (strcat "\n│ 电缆编号: " (cdr (assoc 'cable-number *current-connection*)))) (princ (strcat "\n│ 电缆型号: " (cdr (assoc 'cable-type *current-connection*)))) (princ (strcat "\n│ 规格: " (cdr (assoc 'specification *current-connection*)))) (princ (strcat "\n│ 起点设备: " (cdr (assoc 'start-device *current-connection*)))) (princ (strcat "\n│ 终点设备: " (cdr (assoc 'end-device *current-connection*)))) (princ "\n└────────────────────────────────────────┘") ) (defun show-statistics () "显示统计信息" (if (null *cable-connections*) (princ "\n暂无统计数据") (progn (princ "\n") (princ "\n┌─────────────── 数据统计 ───────────────┐") (princ (strcat "\n│ 总连接数: " (itoa (length *cable-connections*)))) ;; 统计设备使用情况 (setq devices '()) (foreach conn *cable-connections* (setq start-dev (cdr (assoc 'start-device conn))) (setq end-dev (cdr (assoc 'end-device conn))) (if (not (member start-dev devices)) (setq devices (cons start-dev devices)) ) (if (not (member end-dev devices)) (setq devices (cons end-dev devices)) ) ) (princ (strcat "\n│ 涉及设备数: " (itoa (length devices)))) ;; 统计电缆型号 (setq cable-types '()) (foreach conn *cable-connections* (setq type (cdr (assoc 'cable-type conn))) (if (not (member type cable-types)) (setq cable-types (cons type cable-types)) ) ) (princ (strcat "\n│ 电缆型号数: " (itoa (length cable-types)))) (princ "\n└────────────────────────────────────────┘") ) ) ) ;;; 新增功能 (defun clear-all-data () "清除所有数据" (initget "Yes No") (setq choice (getkword "\n确定要清除所有数据吗? [Yes/No] <No>: ")) (if (or (equal choice "Yes") (equal choice "Y")) (progn (setq *cable-connections* nil) (setq *current-connection* (create-connection-data)) (setq *selection-step* 0) (princ "\n🗑️ 所有数据已清除") ) (princ "\n操作已取消") ) ) (defun toggle-auto-save () "切换自动保存开关" (setq *auto-save-enabled* (not *auto-save-enabled*)) (princ (strcat "\n自动保存: " (if *auto-save-enabled* "开启" "关闭"))) ) ;;; 主交互循环 (defun C:CABLE_COLLECT () "主命令 - 启动电缆数据采集" (setq *is-running* t) (setq *current-connection* (create-connection-data)) (setq *selection-step* 0) (setq *last-selected-entity* nil) (setq *last-selected-text* "") (setq *keyboard-input-mode* nil) (show-welcome-screen) (show-control-panel) (show-current-step) (while *is-running* (initget "S S L L E E G G C C A A H H Q Q K K") (setq user-input (getstring "\n选择操作 (直接选择实体或输入命令): ")) (cond ((or (equal user-input "Q") (equal user-input "q")) (setq *is-running* nil) (princ "\n👋 感谢使用电缆接线数据采集系统!") ) ((or (equal user-input "S") (equal user-input "s")) (show-status) ) ((or (equal user-input "L") (equal user-input "l")) (setq filename (getstring "\n输入数据文件路径 [直接回车使用默认 cable_connections.txt]: ")) (if (equal filename "") (setq filename "cable_connections.txt") ) (load-connections-from-file filename) ) ((or (equal user-input "E") (equal user-input "e")) (setq filename (getstring "\n输入导出文件名 [直接回车使用默认 cable_connections_export.txt]: ")) (if (equal filename "") (setq filename "cable_connections_export.txt") ) (save-connections-to-file filename) ) ((or (equal user-input "G") (equal user-input "g")) (generate-wiring-diagram) ) ((or (equal user-input "C") (equal user-input "c")) (clear-all-data) ) ((or (equal user-input "A") (equal user-input "a")) (toggle-auto-save) ) ((or (equal user-input "H") (equal user-input "h")) (show-control-panel) (show-current-step) ) ((or (equal user-input "K") (equal user-input "k")) (process-keyboard-input) ) ((= (strlen user-input) 0) ;; 空输入,进行实体选择 (process-mouse-click) ) (t (princ "\n❓ 未知命令,请输入有效命令或直接选择实体") ) ) ) (princ) ) ;;; 独立命令 (defun C:CABLE_GENERATE () "生成电缆接线图命令" (if (null *cable-connections*) (progn (princ "\n⚠ 没有连接数据,尝试从文件载...") (if (findfile "cable_connections.txt") (progn (load-connections-from-file "cable_connections.txt") (generate-wiring-diagram) ) (princ "\n❌ 也没有找到数据文件,请先运行 CABLE_COLLECT 采集数据") ) ) (generate-wiring-diagram) ) (princ) ) (defun C:CABLE_EXPORT () "导出电缆数据命令" (if (null *cable-connections*) (princ "\n⚠ 没有连接数据可导出") (progn (setq filename (getstring "\n输入导出文件名 [直接回车使用默认 cable_connections_export.txt]: ")) (if (equal filename "") (setq filename "cable_connections_export.txt") ) (save-connections-to-file filename) ) ) (princ) ) (defun C:CABLE_STATS () "显示统计信息命令" (show-statistics) (princ) ) (defun C:CABLE_HELP () "显示帮助信息" (princ "\n🔧 电缆接线数据采集与生成系统 - 帮助信息") (princ "\n══════════════════════════════════════════════") (princ "\n") (princ "\n📋 可用命令:") (princ "\n CABLE_COLLECT - 启动交互式数据采集") (princ "\n CABLE_GENERATE - 生成接线图") (princ "\n CABLE_EXPORT - 导出数据到文件") (princ "\n CABLE_STATS - 显示统计信息") (princ "\n CABLE_HELP - 显示此帮助") (princ "\n") (princ "\n🎮 操作指南:") (princ "\n 1. 运行 CABLE_COLLECT 开始采集") (princ "\n 2. 按照步骤选择电缆编号、型号、规格等") (princ "\n 3. 鼠标左键选择CAD图中的文本实体") (princ "\n 4. 按 K 键可切换到键盘输入模式") (princ "\n 5. 右键撤销,空格确认,回车完成") (princ "\n 6. 数据自动保存,可随时生成接线图") (princ "\n") (princ "\n💡 提示:") (princ "\n • 支持选择普通文本、多行文本、属性块") (princ "\n • 支持键盘直接输入数据") (princ "\n • 自动高亮显示选择的实体") (princ "\n • 进度条显示采集进度") (princ "\n • 自动保存防止数据丢失") (princ "\n") (princ "\n📁 文件:") (princ "\n • 数据文件: cable_connections.txt") (princ "\n • 自动备份,可手动导入导出") (princ "\n══════════════════════════════════════════════") (princ) ) ;;; 初始化提示 (princ "\n✅ 电缆接线数据采集系统已载完成!") (princ "\n💡 输入 CABLE_COLLECT 开始数据采集") (princ "\n💡 输入 CABLE_HELP 查看详细帮助信息") (princ)为啥这个程序老是报以下错误,怎么修改?命令: (LOAD "C:/Users/User/Desktop/CableSystem.lsp") ; 错误: 输入中含有多余的闭括号 命令: 命令: (LOAD "C:/Users/User/Desktop/CableSystem.lsp") ; 错误: 输入中含有多余的闭括号
最新发布
11-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值