^ app\Request {#26
  #pathinfoFetch: array:3 [
    0 => "ORIG_PATH_INFO"
    1 => "REDIRECT_PATH_INFO"
    2 => "REDIRECT_URL"
  ]
  #varPathinfo: "s"
  #varMethod: "_method"
  #varAjax: "_ajax"
  #varPjax: "_pjax"
  #rootDomain: ""
  #httpsAgentName: ""
  #proxyServerIp: []
  #proxyServerIpHeader: array:5 [
    0 => "HTTP_X_REAL_IP"
    1 => "HTTP_X_FORWARDED_FOR"
    2 => "HTTP_CLIENT_IP"
    3 => "HTTP_X_CLIENT_IP"
    4 => "HTTP_X_CLUSTER_CLIENT_IP"
  ]
  #method: "GET"
  #domain: null
  #host: null
  #subDomain: "www"
  #panDomain: null
  #url: null
  #baseUrl: null
  #baseFile: null
  #root: null
  #pathinfo: "hy_news/10/ZO73X23K.html"
  #path: null
  #realIP: null
  #controller: "Index"
  #action: "info"
  #param: []
  #get: []
  #post: []
  #request: []
  #rule: think\route\RuleItem {#51
    #miss: false
    #autoOption: true
    #name: "index/info"
    #domain: null
    #router: think\Route {#41
      #rest: array:7 [
        "index" => array:3 [
          0 => "get"
          1 => ""
          2 => "index"
        ]
        "create" => array:3 [
          0 => "get"
          1 => "/create"
          2 => "create"
        ]
        "edit" => array:3 [
          0 => "get"
          1 => "/<id>/edit"
          2 => "edit"
        ]
        "read" => array:3 [
          0 => "get"
          1 => "/<id>"
          2 => "read"
        ]
        "save" => array:3 [
          0 => "post"
          1 => ""
          2 => "save"
        ]
        "update" => array:3 [
          0 => "put"
          1 => "/<id>"
          2 => "update"
        ]
        "delete" => array:3 [
          0 => "delete"
          1 => "/<id>"
          2 => "delete"
        ]
      ]
      #config: array:21 [
        "pathinfo_depr" => "/"
        "url_lazy_route" => false
        "url_route_must" => false
        "route_rule_merge" => false
        "route_complete_match" => false
        "remove_slash" => false
        "route_annotation" => false
        "default_route_pattern" => "[\w\.]+"
        "url_html_suffix" => "html"
        "controller_layer" => "controller"
        "empty_controller" => "Error"
        "controller_suffix" => false
        "default_controller" => "Index"
        "default_action" => "index"
        "action_suffix" => ""
        "url_common_param" => true
        "request_cache_key" => true
        "request_cache_expire" => 0
        "request_cache_except" => []
        "default_jsonp_handler" => "jsonpReturn"
        "var_jsonp_handler" => "callback"
      ]
      #app: think\App {#3
        #appDebug: false
        #beginTime: 1766116806.4576
        #beginMem: 742704
        #namespace: "app\index"
        #rootPath: "/var/www/html/"
        #thinkPath: "/var/www/html/vendor/topthink/framework/src/"
        #appPath: "/var/www/html/app/index/"
        #runtimePath: "/var/www/html/runtime/index/"
        #routePath: ""
        #configExt: ".php"
        #initializers: array:3 [
          0 => "think\initializer\Error"
          1 => "think\initializer\RegisterService"
          2 => "think\initializer\BootService"
        ]
        #services: array:6 [
          0 => app\AppService {#2
            #app: think\App {#3}
          }
          1 => think\service\PaginatorService {#7
            #app: think\App {#3}
          }
          2 => think\service\ValidateService {#12
            #app: think\App {#3}
          }
          3 => think\service\ModelService {#13
            #app: think\App {#3}
          }
          4 => think\app\Service {#14
            #app: think\App {#3}
          }
          5 => think\trace\Service {#15
            #app: think\App {#3}
          }
        ]
        #initialized: true
        #bind: array:27 [
          "app" => "think\App"
          "cache" => "think\Cache"
          "config" => "think\Config"
          "console" => "think\Console"
          "cookie" => "think\Cookie"
          "db" => "think\Db"
          "env" => "think\Env"
          "event" => "think\Event"
          "http" => "think\Http"
          "lang" => "think\Lang"
          "log" => "think\Log"
          "middleware" => "think\Middleware"
          "request" => "think\Request"
          "response" => "think\Response"
          "route" => "think\Route"
          "session" => "think\Session"
          "validate" => "think\Validate"
          "view" => "think\View"
          "filesystem" => "think\Filesystem"
          "think\DbManager" => "think\Db"
          "think\LogManager" => "think\Log"
          "think\CacheManager" => "think\Cache"
          "Psr\Log\LoggerInterface" => "think\Log"
          "think\Request" => "app\Request"
          "think\exception\Handle" => "app\ExceptionHandle"
          "think\Paginator" => "think\paginator\driver\Bootstrap"
          "think\route\Url" => "think\app\Url"
        ]
        #instances: array:18 [
          "think\App" => think\App {#3}
          "think\Container" => think\App {#3}
          "think\Http" => think\Http {#6
            #app: think\App {#3}
            #name: "index"
            #path: null
            #routePath: "/var/www/html/app/index/route/"
            #isBind: false
          }
          "think\Env" => think\Env {#5
            #data: array:38 [
              "HOSTNAME" => "e9dade6b462f"
              "PHP_VERSION" => "7.4.15"
              "APACHE_CONFDIR" => "/etc/apache2"
              "PHP_INI_DIR" => "/usr/local/etc/php"
              "GPG_KEYS" => "42670A7FE4D0441C8E4632349E4FDC074A4EF02D 5A52880781F755608BF815FC910DEB46F53EA312"
              "PHP_LDFLAGS" => "-Wl,-O1 -pie"
              "PWD" => "/var/www/html"
              "TZ" => "Asia/Shanghai"
              "APACHE_LOG_DIR" => "/var/log/apache2"
              "LANG" => "C"
              "PHP_SHA256" => "9b859c65f0cf7b3eff9d4a28cfab719fb3d36a1db3c20d874a79b5ec44d43cb8"
              "APACHE_PID_FILE" => "/var/run/apache2/apache2.pid"
              "PHPIZE_DEPS" => "autoconf \t\tdpkg-dev \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkg-config \t\tre2c"
              "PHP_URL" => "https://www.php.net/distributions/php-7.4.15.tar.xz"
              "APACHE_RUN_GROUP" => "www-data"
              "APACHE_LOCK_DIR" => "/var/lock/apache2"
              "PHP_EXTRA_CONFIGURE_ARGS" => "--with-apxs2 --disable-cgi"
              "SHLVL" => "0"
              "PHP_CFLAGS" => "-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
              "APACHE_RUN_DIR" => "/var/run/apache2"
              "APACHE_ENVVARS" => "/etc/apache2/envvars"
              "APACHE_RUN_USER" => "www-data"
              "PATH" => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
              "PHP_EXTRA_BUILD_DEPS" => "apache2-dev"
              "PHP_ASC_URL" => "https://www.php.net/distributions/php-7.4.15.tar.xz.asc"
              "PHP_CPPFLAGS" => "-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
              "APP_DEBUG" => ""
              "APP_DEFAULT_TIMEZONE" => "Asia/Shanghai"
              "DATABASE_TYPE" => "mysql"
              "DATABASE_HOSTNAME" => "192.168.88.88"
              "DATABASE_DATABASE" => "szhzywl"
              "DATABASE_USERNAME" => "hzy_web"
              "DATABASE_PASSWORD" => "hzy_24678_mydb"
              "DATABASE_HOSTPORT" => "3306"
              "DATABASE_CHARSET" => "utf8"
              "DATABASE_DEBUG" => "1"
              "DATABASE_PREFIX" => "web_"
              "LANG_DEFAULT_LANG" => "zh-cn"
            ]
          }
          "think\Config" => think\Config {#8
            #config: array:13 [
              "app" => array:12 [
                "app_host" => ""
                "app_namespace" => ""
                "with_route" => true
                "app_express" => true
                "default_app" => "index"
                "default_timezone" => "Asia/Shanghai"
                "app_map" => []
                "domain_bind" => []
                "deny_app_list" => []
                "exception_tmpl" => "/var/www/html/vendor/topthink/framework/src/tpl/think_exception.tpl"
                "error_message" => "页面错误!请稍后再试~"
                "show_error_msg" => false
              ]
              "cache" => array:2 [
                "default" => "file"
                "stores" => array:1 [
                  "file" => array:6 [
                    "type" => "File"
                    "path" => ""
                    "prefix" => ""
                    "expire" => 0
                    "tag_prefix" => "tag:"
                    "serialize" => []
                  ]
                ]
              ]
              "console" => array:1 [
                "commands" => []
              ]
              "cookie" => array:7 [
                "expire" => 0
                "path" => "/"
                "domain" => ""
                "secure" => false
                "httponly" => false
                "setcookie" => true
                "samesite" => ""
              ]
              "database" => array:5 [
                "default" => "mysql"
                "time_query_rule" => []
                "auto_timestamp" => true
                "datetime_format" => "Y-m-d H:i:s"
                "connections" => array:1 [
                  "mysql" => array:17 [
                    "type" => "mysql"
                    "hostname" => "192.168.88.88"
                    "database" => "szhzywl"
                    "username" => "hzy_web"
                    "password" => "hzy_24678_mydb"
                    "hostport" => "3306"
                    "params" => []
                    "charset" => "utf8"
                    "prefix" => "web_"
                    "deploy" => 0
                    "rw_separate" => false
                    "master_num" => 1
                    "slave_no" => ""
                    "fields_strict" => true
                    "break_reconnect" => false
                    "trigger_sql" => ""
                    "fields_cache" => false
                  ]
                ]
              ]
              "filesystem" => array:2 [
                "default" => "local"
                "disks" => array:2 [
                  "local" => array:2 [
                    "type" => "local"
                    "root" => "/var/www/html/runtime/bucket"
                  ]
                  "public" => array:4 [
                    "type" => "local"
                    "root" => "/var/www/html/public/static/bucket"
                    "url" => "/static/bucket"
                    "visibility" => "public"
                  ]
                ]
              ]
              "lang" => array:9 [
                "default_lang" => "zh-cn"
                "allow_lang_list" => []
                "detect_var" => "lang"
                "use_cookie" => true
                "cookie_var" => "think_lang"
                "header_var" => "think-lang"
                "extend_list" => []
                "accept_language" => array:1 [
                  "zh-hans-cn" => "zh-cn"
                ]
                "allow_group" => false
              ]
              "log" => array:6 [
                "default" => "file"
                "level" => []
                "type_channel" => []
                "close" => false
                "processor" => null
                "channels" => array:1 [
                  "file" => array:10 [
                    "type" => "File"
                    "path" => ""
                    "single" => false
                    "apart_level" => []
                    "max_files" => 0
                    "json" => false
                    "processor" => null
                    "close" => false
                    "format" => "[%s][%s] %s"
                    "realtime_write" => false
                  ]
                ]
              ]
              "middleware" => array:2 [
                "alias" => []
                "priority" => []
              ]
              "route" => array:19 [
                "pathinfo_depr" => "/"
                "url_html_suffix" => "html"
                "url_common_param" => true
                "url_lazy_route" => false
                "url_route_must" => false
                "route_rule_merge" => false
                "route_complete_match" => false
                "controller_layer" => "controller"
                "empty_controller" => "Error"
                "controller_suffix" => false
                "default_route_pattern" => "[\w\.]+"
                "request_cache_key" => true
                "request_cache_expire" => 0
                "request_cache_except" => []
                "default_controller" => "Index"
                "default_action" => "index"
                "action_suffix" => ""
                "default_jsonp_handler" => "jsonpReturn"
                "var_jsonp_handler" => "callback"
              ]
              "session" => array:6 [
                "name" => "PHPSESSID"
                "var_session_id" => ""
                "type" => "file"
                "store" => null
                "expire" => 14400
                "prefix" => ""
              ]
              "trace" => array:2 [
                "type" => "Html"
                "channel" => ""
              ]
              "view" => array:10 [
                "type" => "Think"
                "auto_rule" => 1
                "view_dir_name" => "view"
                "view_suffix" => "html"
                "view_depr" => "/"
                "tpl_begin" => "{"
                "tpl_end" => "}"
                "taglib_begin" => "{"
                "taglib_end" => "}"
                "tpl_replace_string" => array:8 [
                  "__PUBLIC__" => "/"
                  "__STATIC__" => "/static"
                  "__LIB__" => "/static/lib"
                  "__ADMIN__" => "/static/admin"
                  "__INDEX__" => "/static/index"
                  "__LOCAL_UPLOAD__" => think\app\Url {#49
                    #app: think\App {#3}
                    #route: think\Route {#41}
                    #vars: []
                    #url: "/admin/adminAccount/local_upload"
                    #root: ""
                    #https: null
                    #suffix: true
                    #domain: false
                    url: "/admin/adminAccount/local_upload"
                    vars: []
                    suffix: true
                    domain: false
                  }
                  "__REMOTE_UPLOAD__" => think\app\Url {#50
                    #app: think\App {#3}
                    #route: think\Route {#41}
                    #vars: []
                    #url: "/admin/adminAccount/remote_upload"
                    #root: ""
                    #https: null
                    #suffix: true
                    #domain: false
                    url: "/admin/adminAccount/remote_upload"
                    vars: []
                    suffix: true
                    domain: false
                  }
                  "__IMG_URL__" => ""
                ]
              ]
            ]
            #path: "/var/www/html/config/"
            #ext: ".php"
          }
          "think\Event" => think\Event {#9
            #listener: array:5 [
              "think\event\AppInit" => []
              "think\event\HttpRun" => array:1 [
                0 => Closure() {#24
                  class: "think\app\Service"
                  this: think\app\Service {#14}
                }
              ]
              "think\event\HttpEnd" => []
              "LogLevel" => []
              "think\event\LogWrite" => []
            ]
            #bind: array:5 [
              "AppInit" => "think\event\AppInit"
              "HttpRun" => "think\event\HttpRun"
              "HttpEnd" => "think\event\HttpEnd"
              "RouteLoaded" => "think\event\RouteLoaded"
              "LogWrite" => "think\event\LogWrite"
            ]
            #app: think\App {#3}
          }
          "think\Lang" => think\Lang {#11
            #config: array:9 [
              "default_lang" => "zh-cn"
              "allow_lang_list" => []
              "use_cookie" => true
              "extend_list" => []
              "cookie_var" => "think_lang"
              "header_var" => "think-lang"
              "detect_var" => "lang"
              "accept_language" => array:1 [
                "zh-hans-cn" => "zh-cn"
              ]
              "allow_group" => false
            ]
            -lang: array:1 [
              "zh-cn" => array:126 [
                "undefined variable" => "未定义变量"
                "undefined index" => "未定义数组索引"
                "undefined offset" => "未定义数组下标"
                "parse error" => "语法解析错误"
                "type error" => "类型错误"
                "fatal error" => "致命错误"
                "syntax error" => "语法错误"
                "dispatch type not support" => "不支持的调度类型"
                "method param miss" => "方法参数错误"
                "method not exists" => "方法不存在"
                "function not exists" => "函数不存在"
                "app not exists" => "应用不存在"
                "controller not exists" => "控制器不存在"
                "class not exists" => "类不存在"
                "property not exists" => "类的属性不存在"
                "template not exists" => "模板文件不存在"
                "illegal controller name" => "非法的控制器名称"
                "illegal action name" => "非法的操作名称"
                "url suffix deny" => "禁止的URL后缀访问"
                "undefined cache config" => "缓存配置未定义"
                "route not found" => "当前访问路由未定义或不匹配"
                "undefined db config" => "数据库配置未定义"
                "undefined log config" => "日志配置未定义"
                "undefined db type" => "未定义数据库类型"
                "variable type error" => "变量类型错误"
                "psr-4 error" => "PSR-4 规范错误"
                "not support type" => "不支持的分页索引字段类型"
                "not support total" => "简洁模式下不能获取数据总数"
                "not support last" => "简洁模式下不能获取最后一页"
                "error session handler" => "错误的SESSION处理器类"
                "not allow php tag" => "模板不允许使用PHP语法"
                "not support" => "不支持"
                "database config error" => "数据库配置信息错误"
                "redisd master" => "Redisd 主服务器错误"
                "redisd slave" => "Redisd 从服务器错误"
                "must run at sae" => "必须在SAE运行"
                "memcache init error" => "未开通Memcache服务,请在SAE管理平台初始化Memcache服务"
                "kvdb init error" => "没有初始化KVDB,请在SAE管理平台初始化KVDB服务"
                "fields not exists" => "数据表字段不存在"
                "where express error" => "查询表达式错误"
                "no data to update" => "没有任何数据需要更新"
                "miss data to insert" => "缺少需要写入的数据"
                "miss complex primary data" => "缺少复合主键数据"
                "miss update condition" => "缺少更新条件"
                "model data not found" => "模型数据不存在"
                "table data not found" => "表数据不存在"
                "delete without condition" => "没有条件不会执行删除操作"
                "miss relation data" => "缺少关联表数据"
                "tag attr must" => "模板标签属性必须"
                "tag error" => "模板标签错误"
                "cache write error" => "缓存写入失败"
                "sae mc write error" => "SAE mc 写入错误"
                "route name not exists" => "路由标识不存在(或参数不够)"
                "invalid request" => "非法请求"
                "bind attr has exists" => "模型的属性已经存在"
                "relation data not exists" => "关联数据不存在"
                "relation not support" => "关联不支持"
                "chunk not support order" => "Chunk不支持调用order方法"
                "route pattern error" => "路由变量规则定义错误"
                "route behavior will not support" => "路由行为废弃(使用中间件替代)"
                "closure not support cache(true)" => "使用闭包查询不支持cache(true),请指定缓存Key"
                "unknown upload error" => "未知上传错误!"
                "file write error" => "文件写入失败!"
                "upload temp dir not found" => "找不到临时文件夹!"
                "no file to uploaded" => "没有文件被上传!"
                "only the portion of file is uploaded" => "文件只有部分被上传!"
                "upload file size exceeds the maximum value" => "上传文件大小超过了最大值!"
                "upload write error" => "文件上传保存错误!"
                "has the same filename: {:filename}" => "存在同名文件:{:filename}"
                "upload illegal files" => "非法上传文件"
                "illegal image files" => "非法图片文件"
                "extensions to upload is not allowed" => "上传文件后缀不允许"
                "mimetype to upload is not allowed" => "上传文件MIME类型不允许!"
                "filesize not match" => "上传文件大小不符!"
                "directory {:path} creation failed" => "目录 {:path} 创建失败!"
                "the middleware must return response instance" => "中间件方法必须返回Response对象实例"
                "the queue was exhausted, with no response returned" => "中间件队列为空"
                ":attribute require" => ":attribute不能为空"
                ":attribute must" => ":attribute必须"
                ":attribute must be numeric" => ":attribute必须是数字"
                ":attribute must be integer" => ":attribute必须是整数"
                ":attribute must be float" => ":attribute必须是浮点数"
                ":attribute must be bool" => ":attribute必须是布尔值"
                ":attribute not a valid email address" => ":attribute格式不符"
                ":attribute not a valid mobile" => ":attribute格式不符"
                ":attribute must be a array" => ":attribute必须是数组"
                ":attribute must be yes,on or 1" => ":attribute必须是yes、on或者1"
                ":attribute not a valid datetime" => ":attribute不是一个有效的日期或时间格式"
                ":attribute not a valid file" => ":attribute不是有效的上传文件"
                ":attribute not a valid image" => ":attribute不是有效的图像文件"
                ":attribute must be alpha" => ":attribute只能是字母"
                ":attribute must be alpha-numeric" => ":attribute只能是字母和数字"
                ":attribute must be alpha-numeric, dash, underscore" => ":attribute只能是字母、数字和下划线_及破折号-"
                ":attribute not a valid domain or ip" => ":attribute不是有效的域名或者IP"
                ":attribute must be chinese" => ":attribute只能是汉字"
                ":attribute must be chinese or alpha" => ":attribute只能是汉字、字母"
                ":attribute must be chinese,alpha-numeric" => ":attribute只能是汉字、字母和数字"
                ":attribute must be chinese,alpha-numeric,underscore, dash" => ":attribute只能是汉字、字母、数字和下划线_及破折号-"
                ":attribute not a valid url" => ":attribute不是有效的URL地址"
                ":attribute not a valid ip" => ":attribute不是有效的IP地址"
                ":attribute must be dateformat of :rule" => ":attribute必须使用日期格式 :rule"
                ":attribute must be in :rule" => ":attribute必须在 :rule 范围内"
                ":attribute be notin :rule" => ":attribute不能在 :rule 范围内"
                ":attribute must between :1 - :2" => ":attribute只能在 :1 - :2 之间"
                ":attribute not between :1 - :2" => ":attribute不能在 :1 - :2 之间"
                "size of :attribute must be :rule" => ":attribute长度不符合要求 :rule"
                "max size of :attribute must be :rule" => ":attribute长度不能超过 :rule"
                "min size of :attribute must be :rule" => ":attribute长度不能小于 :rule"
                ":attribute cannot be less than :rule" => ":attribute日期不能小于 :rule"
                ":attribute cannot exceed :rule" => ":attribute日期不能超过 :rule"
                ":attribute not within :rule" => "不在有效期内 :rule"
                "access ip is not allowed" => "不允许的IP访问"
                "access ip denied" => "禁止的IP访问"
                ":attribute out of accord with :2" => ":attribute和确认字段:2不一致"
                ":attribute cannot be same with :2" => ":attribute和比较字段:2不能相同"
                ":attribute must greater than or equal :rule" => ":attribute必须大于等于 :rule"
                ":attribute must greater than :rule" => ":attribute必须大于 :rule"
                ":attribute must less than or equal :rule" => ":attribute必须小于等于 :rule"
                ":attribute must less than :rule" => ":attribute必须小于 :rule"
                ":attribute must equal :rule" => ":attribute必须等于 :rule"
                ":attribute has exists" => ":attribute已存在"
                ":attribute not conform to the rules" => ":attribute不符合指定规则"
                "invalid request method" => "无效的请求类型"
                "invalid token" => "令牌数据无效"
                "not conform to the rules" => "规则错误"
                "record has update" => "记录已经被更新了"
              ]
            ]
            -range: "zh-cn"
          }
          "think\initializer\Error" => think\initializer\Error {#4
            #app: think\App {#3}
          }
          "think\initializer\RegisterService" => think\initializer\RegisterService {#10
            #services: array:3 [
              0 => "think\service\PaginatorService"
              1 => "think\service\ValidateService"
              2 => "think\service\ModelService"
            ]
          }
          "think\Middleware" => think\Middleware {#19
            #queue: array:1 [
              "global" => array:2 [
                0 => array:2 [
                  0 => array:2 [
                    0 => "think\trace\TraceDebug"
                    1 => "handle"
                  ]
                  1 => []
                ]
                1 => array:2 [
                  0 => array:2 [
                    0 => "think\app\MultiApp"
                    1 => "handle"
                  ]
                  1 => []
                ]
              ]
            ]
            #app: think\App {#3}
          }
          "think\initializer\BootService" => think\initializer\BootService {#16}
          "think\Log" => think\Log {#34
            #namespace: "\think\log\driver\"
            #app: think\App {#3}
            #drivers: []
          }
          "think\Cache" => think\Cache {#35
            #namespace: "\think\cache\driver\"
            #app: think\App {#3}
            #drivers: array:1 [
              "file" => think\cache\driver\File {#30
                #options: array:9 [
                  "expire" => 0
                  "cache_subdir" => true
                  "prefix" => ""
                  "path" => "/var/www/html/runtime/cache/"
                  "hash_type" => "md5"
                  "data_compress" => false
                  "tag_prefix" => "tag:"
                  "serialize" => []
                  "type" => "File"
                ]
                #handler: null
                #readTimes: 0
                #writeTimes: 0
                #tag: []
              }
            ]
          }
          "think\Db" => think\Db {#32
            #instance: []
            #config: think\Config {#8}
            #event: think\Event {#9}
            #listen: []
            #dbLog: []
            #queryTimes: 0
            #cache: think\cache\driver\File {#30}
            #log: think\Log {#34}
          }
          "app\Request" => app\Request {#26}
          "think\trace\TraceDebug" => think\trace\TraceDebug {#42
            #log: []
            #config: array:2 [
              "type" => "Html"
              "channel" => ""
            ]
            #app: think\App {#3}
          }
          "think\app\MultiApp" => think\app\MultiApp {#39
            #app: think\App {#3}
            #name: ""
            #appName: "index"
            #path: ""
          }
          "think\Route" => think\Route {#41}
        ]
        #invokeCallback: []
      }
      #request: app\Request {#26}
      #ruleName: think\route\RuleName {#40
        #item: array:5 [
          "upload" => array:1 [
            0 => array:4 [
              "rule" => "guest/upload"
              "domain" => "www.szhzywl.com"
              "method" => "post"
              "suffix" => null
            ]
          ]
          "send_resume" => array:1 [
            0 => array:4 [
              "rule" => "guest/send_resume"
              "domain" => "www.szhzywl.com"
              "method" => "post"
              "suffix" => null
            ]
          ]
          "send_message" => array:1 [
            0 => array:4 [
              "rule" => "guest/send_message"
              "domain" => "www.szhzywl.com"
              "method" => "post"
              "suffix" => null
            ]
          ]
          "index/info" => array:1 [
            0 => array:4 [
              "rule" => "<name>/<id>/<sn>"
              "domain" => "www.szhzywl.com"
              "method" => "get"
              "suffix" => null
            ]
          ]
          "index/page" => array:2 [
            0 => array:4 [
              "rule" => "<name>/<id>"
              "domain" => "www.szhzywl.com"
              "method" => "get"
              "suffix" => null
            ]
            1 => array:4 [
              "rule" => "<name>"
              "domain" => "www.szhzywl.com"
              "method" => "get"
              "suffix" => null
            ]
          ]
        ]
        #rule: array:6 [
          "guest/upload" => array:1 [
            "upload" => think\route\RuleItem {#54
              #miss: false
              #autoOption: true
              #name: "upload"
              #domain: null
              #router: think\Route {#41}
              #parent: think\route\RuleGroup {#52
                #rules: array:6 [
                  0 => array:2 [
                    0 => "post"
                    1 => think\route\RuleItem {#54}
                  ]
                  1 => array:2 [
                    0 => "options"
                    1 => think\route\RuleItem {#54}
                  ]
                  2 => array:2 [
                    0 => "post"
                    1 => think\route\RuleItem {#55
                      #miss: false
                      #autoOption: true
                      #name: "send_resume"
                      #domain: null
                      #router: think\Route {#41}
                      #parent: think\route\RuleGroup {#52}
                      #rule: "guest/send_resume"
                      #route: "send_resume"
                      #method: "post"
                      #vars: []
                      #option: []
                      #pattern: []
                      #mergeOptions: array:3 [
                        0 => "model"
                        1 => "append"
                        2 => "middleware"
                      ]
                      name: "send_resume"
                      rule: "guest/send_resume"
                      route: "send_resume"
                      method: "post"
                      vars: []
                      option: []
                      pattern: []
                    }
                  ]
                  3 => array:2 [
                    0 => "options"
                    1 => think\route\RuleItem {#55}
                  ]
                  4 => array:2 [
                    0 => "post"
                    1 => think\route\RuleItem {#56
                      #miss: false
                      #autoOption: true
                      #name: "send_message"
                      #domain: null
                      #router: think\Route {#41}
                      #parent: think\route\RuleGroup {#52}
                      #rule: "guest/send_message"
                      #route: "send_message"
                      #method: "post"
                      #vars: []
                      #option: []
                      #pattern: []
                      #mergeOptions: array:3 [
                        0 => "model"
                        1 => "append"
                        2 => "middleware"
                      ]
                      name: "send_message"
                      rule: "guest/send_message"
                      route: "send_message"
                      method: "post"
                      vars: []
                      option: []
                      pattern: []
                    }
                  ]
                  5 => array:2 [
                    0 => "options"
                    1 => think\route\RuleItem {#56}
                  ]
                ]
                #rule: null
                #miss: null
                #fullName: "guest"
                #alias: null
                #name: "guest"
                #domain: "www.szhzywl.com"
                #router: think\Route {#41}
                #parent: think\route\Domain {#47
                  #rules: array:7 [
                    0 => array:2 [
                      0 => "*"
                      1 => think\route\RuleGroup {#52}
                    ]
                    1 => array:2 [
                      0 => "get"
                      1 => think\route\RuleItem {#51}
                    ]
                    2 => array:2 [
                      0 => "options"
                      1 => think\route\RuleItem {#51}
                    ]
                    3 => array:2 [
                      0 => "get"
                      1 => think\route\RuleItem {#53
                        #miss: false
                        #autoOption: true
                        #name: "index/page"
                        #domain: null
                        #router: think\Route {#41}
                        #parent: think\route\Domain {#47}
                        #rule: "<name>/<id>"
                        #route: "index/page"
                        #method: "get"
                        #vars: []
                        #option: []
                        #pattern: []
                        #mergeOptions: array:3 [
                          0 => "model"
                          1 => "append"
                          2 => "middleware"
                        ]
                        name: "index/page"
                        rule: "<name>/<id>"
                        route: "index/page"
                        method: "get"
                        vars: []
                        option: []
                        pattern: []
                      }
                    ]
                    4 => array:2 [
                      0 => "options"
                      1 => think\route\RuleItem {#53}
                    ]
                    5 => array:2 [
                      0 => "get"
                      1 => think\route\RuleItem {#57
                        #miss: false
                        #autoOption: true
                        #name: "index/page"
                        #domain: null
                        #router: think\Route {#41}
                        #parent: think\route\Domain {#47}
                        #rule: "<name>"
                        #route: "index/page"
                        #method: "get"
                        #vars: []
                        #option: []
                        #pattern: []
                        #mergeOptions: array:3 [
                          0 => "model"
                          1 => "append"
                          2 => "middleware"
                        ]
                        name: "index/page"
                        rule: "<name>"
                        route: "index/page"
                        method: "get"
                        vars: []
                        option: []
                        pattern: []
                      }
                    ]
                    6 => array:2 [
                      0 => "options"
                      1 => think\route\RuleItem {#57}
                    ]
                  ]
                  #rule: null
                  #miss: null
                  #fullName: null
                  #alias: null
                  #name: null
                  #domain: "www.szhzywl.com"
                  #router: think\Route {#41}
                  #parent: null
                  #route: null
                  #method: null
                  #vars: []
                  #option: array:2 [
                    "remove_slash" => false
                    "merge_rule_regex" => false
                  ]
                  #pattern: array:3 [
                    "name" => "\w+"
                    "id" => "\d+"
                    "sn" => "\w+"
                  ]
                  #mergeOptions: array:3 [
                    0 => "model"
                    1 => "append"
                    2 => "middleware"
                  ]
                  name: null
                  rule: null
                  route: null
                  method: null
                  vars: []
                  option: array:2 [
                    "remove_slash" => false
                    "merge_rule_regex" => false
                  ]
                  pattern: array:3 [
                    "name" => "\w+"
                    "id" => "\d+"
                    "sn" => "\w+"
                  ]
                }
                #route: null
                #method: null
                #vars: []
                #option: array:3 [
                  "remove_slash" => false
                  "merge_rule_regex" => false
                  "prefix" => "guest/"
                ]
                #pattern: []
                #mergeOptions: array:3 [
                  0 => "model"
                  1 => "append"
                  2 => "middleware"
                ]
                name: "guest"
                rule: null
                route: null
                method: null
                vars: []
                option: array:3 [
                  "remove_slash" => false
                  "merge_rule_regex" => false
                  "prefix" => "guest/"
                ]
                pattern: []
              }
              #rule: "guest/upload"
              #route: "upload"
              #method: "post"
              #vars: []
              #option: []
              #pattern: []
              #mergeOptions: array:3 [
                0 => "model"
                1 => "append"
                2 => "middleware"
              ]
              name: "upload"
              rule: "guest/upload"
              route: "upload"
              method: "post"
              vars: []
              option: []
              pattern: []
            }
          ]
          "guest/send_resume" => array:1 [
            "send_resume" => think\route\RuleItem {#55}
          ]
          "guest/send_message" => array:1 [
            "send_message" => think\route\RuleItem {#56}
          ]
          "<name>/<id>/<sn>" => array:1 [
            "index/info" => think\route\RuleItem {#51}
          ]
          "<name>/<id>" => array:1 [
            "index/page" => think\route\RuleItem {#53}
          ]
          "<name>" => array:1 [
            "index/page" => think\route\RuleItem {#57}
          ]
        ]
        #group: array:1 [
          "guest" => think\route\RuleGroup {#52}
        ]
      }
      #host: "www.szhzywl.com"
      #group: think\route\Domain {#43
        #rules: []
        #rule: null
        #miss: null
        #fullName: null
        #alias: null
        #name: null
        #domain: null
        #router: think\Route {#41}
        #parent: null
        #route: null
        #method: null
        #vars: []
        #option: array:1 [
          "remove_slash" => false
        ]
        #pattern: []
        #mergeOptions: array:3 [
          0 => "model"
          1 => "append"
          2 => "middleware"
        ]
        name: null
        rule: null
        route: null
        method: null
        vars: []
        option: array:1 [
          "remove_slash" => false
        ]
        pattern: []
      }
      #bind: []
      #domains: array:3 [
        "-" => think\route\Domain {#43}
        "www.szhzywl.com" => think\route\Domain {#47}
        "szhzywl.com" => "www.szhzywl.com"
      ]
      #cross: null
      #lazy: false
      #isTest: false
      #mergeRuleRegex: false
      #removeSlash: false
    }
    #parent: think\route\Domain {#47}
    #rule: "<name>/<id>/<sn>"
    #route: "index/info"
    #method: "get"
    #vars: array:3 [
      "name" => "hy_news"
      "id" => "10"
      "sn" => "ZO73X23K"
    ]
    #option: []
    #pattern: []
    #mergeOptions: array:3 [
      0 => "model"
      1 => "append"
      2 => "middleware"
    ]
    name: "index/info"
    rule: "<name>/<id>/<sn>"
    route: "index/info"
    method: "get"
    vars: array:3 [
      "name" => "hy_news"
      "id" => "10"
      "sn" => "ZO73X23K"
    ]
    option: []
    pattern: []
  }
  #route: array:3 [
    "name" => "hy_news"
    "id" => "10"
    "sn" => "ZO73X23K"
  ]
  #middleware: []
  #put: []
  #session: null
  #cookie: []
  #env: think\Env {#5}
  #server: array:37 [
    "REDIRECT_STATUS" => "200"
    "HTTP_HOST" => "www.szhzywl.com"
    "HTTP_X_REAL_IP" => "216.73.216.80"
    "HTTP_X_FORWARDED_FOR" => "216.73.216.80"
    "HTTP_X_FORWARDED_PROTO" => "https"
    "HTTP_CONNECTION" => "close"
    "HTTP_ACCEPT" => "*/*"
    "HTTP_USER_AGENT" => "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)"
    "HTTP_ACCEPT_ENCODING" => "gzip, br, zstd, deflate"
    "PATH" => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    "SERVER_SIGNATURE" => "<address>Apache/2.4.38 (Debian) Server at www.szhzywl.com Port 80</address>\n"
    "SERVER_SOFTWARE" => "Apache/2.4.38 (Debian)"
    "SERVER_NAME" => "www.szhzywl.com"
    "SERVER_ADDR" => "192.168.88.4"
    "SERVER_PORT" => "80"
    "REMOTE_ADDR" => "192.168.88.1"
    "DOCUMENT_ROOT" => "/var/www/html/public"
    "REQUEST_SCHEME" => "http"
    "CONTEXT_PREFIX" => ""
    "CONTEXT_DOCUMENT_ROOT" => "/var/www/html/public"
    "SERVER_ADMIN" => "[no address given]"
    "SCRIPT_FILENAME" => "/var/www/html/public/index.php"
    "REMOTE_PORT" => "42154"
    "REDIRECT_URL" => "/hy_news/10/ZO73X23K.html"
    "GATEWAY_INTERFACE" => "CGI/1.1"
    "SERVER_PROTOCOL" => "HTTP/1.0"
    "REQUEST_METHOD" => "GET"
    "QUERY_STRING" => ""
    "REQUEST_URI" => "/hy_news/10/ZO73X23K.html"
    "SCRIPT_NAME" => "/index.php"
    "PATH_INFO" => "/hy_news/10/ZO73X23K.html"
    "PATH_TRANSLATED" => "redirect:/index.php/hy_news/10/ZO73X23K.html/10/ZO73X23K.html"
    "PHP_SELF" => "/index.php/hy_news/10/ZO73X23K.html"
    "REQUEST_TIME_FLOAT" => 1766116806.4552
    "REQUEST_TIME" => 1766116806
    "argv" => []
    "argc" => 0
  ]
  #file: []
  #header: array:8 [
    "host" => "www.szhzywl.com"
    "x-real-ip" => "216.73.216.80"
    "x-forwarded-for" => "216.73.216.80"
    "x-forwarded-proto" => "https"
    "connection" => "close"
    "accept" => "*/*"
    "user-agent" => "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)"
    "accept-encoding" => "gzip, br, zstd, deflate"
  ]
  #mimeType: array:12 [
    "xml" => "application/xml,text/xml,application/x-xml"
    "json" => "application/json,text/x-json,application/jsonrequest,text/json"
    "js" => "text/javascript,application/javascript,application/x-javascript"
    "css" => "text/css"
    "rss" => "application/rss+xml"
    "yaml" => "application/x-yaml,text/yaml"
    "atom" => "application/atom+xml"
    "pdf" => "application/pdf"
    "text" => "text/plain"
    "image" => "image/png,image/jpg,image/jpeg,image/pjpeg,image/gif,image/webp,image/*"
    "csv" => "text/csv"
    "html" => "text/html,application/xhtml+xml,*/*"
  ]
  #content: null
  #filter: null
  #input: ""
  #secureKey: null
  #mergeParam: false
}
苏州慧珍园网络科技有限公司

中国工业软件没有“弯道超车”,“一拐弯就是车祸”

发布时间:2021-03-29 来源:搜狐

|山间有竹,前四载深埋地下,后破土而出,日渐疯长,终成竹海。工业软件国产替代也注定是这样一场漫长的追光过程。

在“卡脖子”成为热词的当下,工业软件近年来持续引起我国产学研政界广泛的关注。

作为工业领域里进行研发设计、业务管理、产品制造、生产调度和过程控制的相关软件与系统,工业软件已经被公认为“工业制造的大脑和神经”,是工业领域的“皇冠”。

但在过去一段时间里,“国产工业软件落后世界最高水平至少30年”“我国工业软件市场被欧美软件巨头严重垄断”“如果西方国家对我国全面实施工业软件禁运,我国工业研发和生产将何去何从?”等呼吁和疑问,陆续登上舆论风口,触目惊心,令人难以忽视。

为什么我国的工业软件做不起来?国产工业软件比国外差在哪?怎么才能加速工业软件国产替代进程?国产工业软件怎样才能“打个翻身仗”?

带着这一系列的问题,我们走访了多家一线企业,得到几乎一致的回答:中国工业软件人有信心绝地反击,但需要耐心、耐力,“工业软件没有‘弯道超车’一说,没有捷径可走,否则一拐弯就是车祸。”

▲ 2020年10月18日,2020全球工业互联网大会展示现场。图/视觉中国

“中国企业都歧视中国企业”

十多年前的一个夜晚,北京市朝阳区惠新西街1号安徽大厦的咖啡厅里,在代理霍尼韦尔、艾默生软件的李春燕,与国内某知名工业软件品牌的一个创始人如约见面。

见面的目的并不复杂——后者想寻求李春燕的帮助,希望借助她积累多年的业内渠道资源,为自己公司的DCS产品进入石油石化领域推一把力。

交谈间,产品价格免不了被提及。李春燕惊讶地发现,该公司的软件价格仅为国外软件的十分之一,却还是很难打开市场。“这点对我触动太大了!国产工业软件找个突破口太不容易了!”

此后十多年间,霍尼韦尔、艾默生、西门子等为了抢占中国市场,将价格降低了一半以上;李春燕创立了自己的工业软件品牌“北京智通云联科技有限公司”……时光轮转间,这个行业里的人来来往往、起起伏伏。

然而很遗憾,十年后的现在,即便在价格上依旧远低于国外软件,国产软件也仍然处在寻找市场突破口的困境中:市场份额在全球市场上仅为6%,在国内市场上不足10%。

为什么?因为纵然业界舆论大声疾呼“独立自主”,企业们上下求索“国产替代”,但在市场面前,这些热情依旧免不了被兜头浇来一盆冷水。

调研中我们发现,部分国产软件企业由于品牌、规模等问题资质受卡,手中的很多项目只能“躲在外企或者互联网大公司背后”接下。

一位北京工业软件企业高管透露,其公司产品在东南亚、日本、韩国市场都进展顺利,但国内项目中很多只能以丙方的身份承接,“事情是我们干,功劳和名头是别人的。”

某上海工厂IT采购人士也告诉记者,传统生产制造领域的采购态度向来偏保守,一来大型企业的采购“不缺钱,要买就买最好的”,二来中小型企业“一分钱恨不得掰成八瓣花,毕竟试错成本除了少则几十万元的金钱,还有宝贵的时间,根本耽搁不起。”

“中国的企业都歧视中国的企业,这是一件很悲哀的事情。”李春燕说。其他多家受访的工业软件企业高管也表达了类似的心声。还有相当一部分高管担忧,长此以往,如果不能在覆盖研发成本的基础上扩大利润空间,企业很难实现健康、持续发展。

尴尬境地的由来

为什么国产工业软件在国内市场上这么不吃香?

结合多方观点,我们发现,国产工业软件之所以陷入这样的尴尬境地,原因是多方面的:

一方面,国产工业软件短期内的确难以超越国外同类产品,是许多制造业企业选择后者的根本原因。

赛意信息副总裁、工业互联网子公司总经理蔡胜龙表示,“国内工业软件的标准其实不明确,一些系统的架构也比较落后,对外提供标准的集成能力也不是很强。在实施过程中,其实会影响到我们的一些信息系统和业务系统,包括这种自动化系统的融合等。”

另一方面,即便国产软件在某一领域技术水平不弱,且能够保障可靠的售后服务,也鲜有采购方愿意“第一个吃螃蟹”。

安世亚太高级副总裁田锋曾这样分析制造业企业的采购心理:即使软件功能和性能接近国外软件,国内客户为什么要拿你的软件替换当前已经在用的国外软件?价格可能是个变量,但低价甚至免费就能获得客户么?客户反倒会怀疑这个商业模式的可持续性。

除此之外,更深刻的原因还在于,工业软件研发周期比较长,技术壁垒比较高,回报比较慢,而工业软件企业多是轻资产运营,加之许多企业自身无法提前锁定软件的长期服务价值,不仅难以得到资本市场的青睐,也无力改变国内由来已久的“看衰”心理。

一个最典型的例子是,在互联网初创公司动辄数千万、上亿融资的时代背景下,成立了22年的国内领先的工业软件龙头厂商——广州中望龙腾软件股份有限公司,2018年底完成第一轮融资8000万元,2019年10月完成第二轮融资1.4亿元,这两轮融资竟然均为国内研发设计类工业软件领域彼时规模最大、估值最高的融资案例。

“很多企业在遭遇经济下行压力时,往往首先砍的预算就是信息化投入,他们宁愿买自动化设备,也不愿构建自己的‘心脏’和‘大脑’。”在某工业软件国产化高层论坛上,一位行业人士的发言,引起在场多数人的共鸣。

多位工业软件企业高管还谈及,在BAT等互联网巨头进军工业互联网后,不仅工业软件企业自身的人才发展遭遇冲击,整个行业的泡沫也增加了不少。

一位高管举例称,刚毕业的硕士研究生在其单位的年薪在12万到15万元之间,工作七八年后的开发人员年收入也仅能达到20万元,可一些互联网、游戏公司轻易就能用数倍年薪挖人,有经验的开发人员流失严重。

“更可惜的是,许多互联网公司需要一支技术牛的团队,是好去讲故事、筹资源、撬资本。但有经验的人才被挖过去之后才发现,他们就像被养起来的‘吉祥物’,根本没有切实的项目供他们发挥才干”,另一位被某互联网巨头挖走过重要开发人员的工业软件企业负责人说,“可接受了高薪后,他们也不愿意再回到原来的圈子,最终因为无用武之地而抑郁,好好的人才就这样被白白浪费了。”

走向智能研究院执行院长赵敏认为:“中国工业软件的生态环境较差,不仅开发者、决策者、用户之间存在较大认知差异,甚至在财务依据、税收、资产评估、人才培养、投/融资、知识产权、同业竞争等方面,都有较多问题。”

可以说,相比国外,中国自主工业软件的生态环境建设,还任重道远。

未来已来,过去未去

当然,也并不是没有国产工业软件成功牵手国内客户。只是,要想把产品落地到客户的生产线上,远比想象中要麻烦。

“一进入工厂车间,我们就发现,未来已来,但过去未去——我们面对的,是许多工厂还处在传统生产模式的状况。”李春燕说。

北京亚控科技发展有限公司总经理郑炳权提醒说,“工业互联网不是“工业”和“互联网”简单地相加,两者必须用一个符合工业生产的逻辑串联起来,才能真正发挥工业软件的应用价值。”

▲2019年6月20日,江苏常州,智慧城市展会现场的工业互联网展区。图/视觉中国

他表示,当前大量的工业互联网企业仅停留在产业链协同层面,聚焦制造企业生产线各环节仍是少数。而且,企业制造中每个工厂都不一样,要让制造企业看到国产软件在管控生产进度、成本管控等方面的价值问题,需要一个过程。

数据采集,是国产工业软件要面对的第一道门槛。

众所周知,设备厂商对自己设备的数据是严格控制的,工业软件采集设备上的数据必须获得设备厂商的授权。然而,我国绝大多数制造业厂房生产线上运转着的机器,来自世界各国。这些“万国设备”标准与非标混杂,要么不开放通信协议,要么过了质保期,要么连设备商都找不到,大量的基础数据、应用数据禁锢在设备本身,难以被采集出来。

而且,除了设备本身的数据,工业软件供应商们还要采集设备保养、大修、生产关联匹配度、关键供应参数等管理层面的数据,采集难度大。

李春燕告诉记者,一个较大型制造业工厂的核心设备约有十七八类,设备总量在800~1000台,数据采集点约有5万到8万个,“少一家设备厂商的数据,整个数据采集都无法完成,各行各业都如此。而这恰恰是工业软件第一步要解决的问题。”

第二道难题在于产线的智能化改造本身。

作为工业软件进步的重要成果,工业互联网的核心是工业云平台。工业云平台本身并不难搭建,真正难的是与设备本身和生产工艺、产品质检等具体应用层面的结合。

工业和信息化部信息通信管理局一级巡视员刘杰曾指出,工业互联网需要把物理接入、大数据分析、知识图谱管理、运营软件管理等综合运用联结起来,才会形成真正落地的服务,如果单独强调某一项就会存在最后一公里甚至最后一米打不通的情况,对广大制造企业来说还是没用。

以乳制品产线为例,食品质检标准要高于国家标准,工厂的牛奶要求复杂,比如每半小时对原奶、半成品、待装奶、罐装奶做一次测样,半成品从生产结束到质检环节再到半成品转续不能超过60分钟,其中质检时间约为30分钟,半成品在质检结果出来前不允许转续,等等。

如果将各环节隔离开来,这些复杂的检验及控制在各自的业务闭环内都很好实现,但在实际的生产过程中,不仅这些环节的把控要结合设备进行体现,而且整个系统必须保证质检环节、工艺控制、生产环节完全同步匹配、共同协作;任何一个小环节掉链子,就会给工厂带来实打实的损失。

▲ 某加工厂正在生产乳制品。图/新华社

有人会说,当前市面上主打工业互联网平台的国内公司越来越多,还不能顺利满足企业向智能制造模式转变吗?

答案是,这一趋势固然值得看好,但落地效果更值得长期考量。毕竟,任何工业互联网平台及运行其上的新型工业软件(工业APP),都是以为工业提质增效的水平来衡量的,这需要工业软件供应商对其服务的行业和具体业务场景有着非常深入的了解,相当于要成为半个“业内人”,才能开发出适用、好用的工业软件,而这,至少要花上5~10年的时间,甚至更长。目前工业互联网市场上,能用“一个符合工业生产的逻辑”把信息/网络技术(ICT)与工业场景紧密串接起来、融为一体的工业互联网平台,数量较少,有价值的工业APP总计不多——到去年底预计实现“百万工业APP”的目标只完成了30%。

前述北京工业软件企业高管认为,IT互联网企业暂时还难当IT和OT融合大任,“工业知识掌握在工业人的手中,工业软件要服务好工业制造,一定由工业人去主导才能完成,因为只有工业人才会不计成本、孜孜不倦为工业制造赋能。”

抢救工业知识数据库!

为什么要想实现工业软件国产替代这么难呢?

在诸多相关描述中,工业软件已经被公认为“虽然只占软件很小的比例,却是工业制造的大脑和神经”。但容易被人们忽略的一个“冷知识”是,没有深厚的工业知识数据做支撑,工业软件根本难以支撑工业制造的脱胎换骨。

工业软件是工业和信息产业的结合体,做工业软件,既要懂信息软件开发,又要对工业体系有系统性、深入性的了解,其中最大的难点不在于软件开发技术本身,而是IT人员对工业知识数据的掌握和调用。

赵敏也曾说过:“没有工业知识,没有制造业经验,只学过计算机软件的工程师,是设计不出先进的工业软件的。”

实际上,国外工业软件巨头之所以能够持续发展强大,根本原因之一就在于积累了几十年甚至上百年的工业生产的关键技术、流程、知识、工艺和数据,形成了扎实的工业数据知识库,具备了最重要、最核心、最底层的支撑。软件开发时,一手是市场需求,一手是随取随用的知识数据库,两手交汇贯通间,软件的优化升级顺利实现。

国产工业软件缺乏的,正是这样一个源头支撑。

自新中国成立至今,我国工业制造过程中的海量关键工艺流程、工业技术经验及研发数据,大都只锁闭在技术人员头脑中和企业的资料室里,随着企业的变迁、人员的流动甚至消失,不断耗散。

这就导致两个结果,一来,制造企业自身的知识经验及数据白白流失;二则,工业软件企业进入制造企业所处领域时,不得不花费大量时间和精力去学习、消化基础知识及参数,弄懂“一个符合工业生产的逻辑”之后才能进入软件开发阶段。

以石油勘探开采技术为例,我国在这一领域的成就早已获得世界认可。所谓“上天容易下地难”,人类对地下世界的持续探索离不开对过往经验的参照。但由于老专家、熟练技工的退休、离世或离职,大量宝贵的经验教训没有得到有效保存。

如果能利用工业软件技术,将这些经验教训以数字化、知识化形式进行保存、调用,不仅年轻一代的技术人员可以尽量减少重复错误、无效做工等问题,工业软件企业也可以根据勘探人员实时反馈的数据信息,对软件进行更贴合实际应用需求的优化升级。

“我国有大量的工业知识和数据亟须抢救,哪怕失败的教训也要留下来”,李春燕认为,“只有隐性知识显性化,显性知识组织化,残缺知识完整化,人走知识留,使数据和知识成为单位集体财富,才能更便于后来者高效地学习、对照。”

多位业内人士也指出,国产工业软件当前首要任务,是加快建立工业知识数据库,让大量的专家经验、工艺流程、核心参数等保留下来,企业知识财富成为行业集体的宝贵财富,从源头上为国产工业软件的发展积蓄动能。

▲2020年11月30日,人们在山东青岛一家工业互联网平台参观。图/IC photo

一步一个脚印

在此次调研中,记者不止一次抛出“弯道超车”一词,但惊讶的是,大多数受访的从业者都觉得,这个词用在工业软件上“略显浮躁”。

李春燕更是直言:“国产工业软件没有‘弯道超车’一说,没有捷径可走,否则一拐弯就是车祸,只能一步一个脚印。”

郑炳权也表示,工业软件企业要有“老黄牛”精神,凝聚干实事、干大事的的正能量,不要只想从工业挣钱,要想怎么做能让工业企业挣钱。

从长远上看,随着我国经济由高速增长阶段转向高质量发展阶段,尤其是外部势力持续加大倒逼力量,中国制造由量向质的跃迁,各有关行政部门都陆续给出利好政策,这些形成的合力,必然会开创出国产工业软件研发的春天。

但立足当下,考虑到国家近年来出台的优惠支持政策和国产工业软件发展情况,下一步想要切实加快工业软件国产替代进程,走到更广阔的国际舞台上,至少需要注意“两手抓”:

一是政策监督层面加强考察力度,对扶持企业设立考核指标,最好能跟踪到产品投入、应用效果,保证优惠与支持给到真正做技术研究的企业,避免滥竽充数;同时,坚持长期主义思想,鼓励国企特别是央企带头使用自主工业软件,鼓励软件企业进行探索性创新,对创新技术及人才进行定向奖励支持。

二是工业软件产业加强行业自律,自觉提高产品要求,形成自身验证、客户验证、产品验证、跨界验证、同行验证等层层锤炼的发展意识,全面提高产品及服务的市场竞争力。

山间有竹,前四载深埋地下,后破土而出,日渐疯长,终成竹海。工业软件国产替代也注定是这样一场漫长的追光过程。

庆幸的是,许多从业者清醒地知道,“在中国搞工业软件,必须要有信仰般坚定的意志。”