[{"data":1,"prerenderedAt":2313},["ShallowReactive",2],{"docs-nav":3,"doc-\u002Fdocs\u002Fdatabase-flyway":2133},[4,390,872,1140,1730],{"id":5,"title":6,"body":7,"category":379,"description":380,"extension":381,"icon":382,"meta":383,"navigation":384,"order":217,"path":385,"seo":386,"stem":387,"updatedAt":388,"__hash__":389},"docs\u002Fdocs\u002Fgetting-started.md","快速开始与环境要求",{"type":8,"value":9,"toc":367},"minimark",[10,14,30,33,36,39,155,170,173,183,186,195,283,289,326,339,343,363],[11,12,13],"h2",{"id":13},"系统简介",[15,16,17,21,22,25,26,29],"p",{},[18,19,20],"strong",{},"CatCRM"," 是一套基于现代主流技术栈研发的企业级全流程客户关系管理系统（CRM）。系统围绕 B2B 销售核心场景设计，完整覆盖",[18,23,24],{},"线索、客户、公海池、联系人、跟进记录、商机、产品、合同、销售订单、回款计划与核销、发票管理","以及",[18,27,28],{},"动态自定义表单","。",[15,31,32],{},"无论是采用官方 All-in-One Docker 镜像在 30 秒内完成私有化部署，还是基于全量源码进行深度二次开发，CatCRM 都能提供清晰、稳健的工程体验。",[11,34,35],{"id":35},"环境要求",[15,37,38],{},"在进行本地源码编译或开发环境搭建前，请确保宿主机满足以下版本要求：",[40,41,42,58],"table",{},[43,44,45],"thead",{},[46,47,48,52,55],"tr",{},[49,50,51],"th",{},"组件 \u002F 工具",[49,53,54],{},"版本要求",[49,56,57],{},"说明",[59,60,61,82,97,125,140],"tbody",{},[46,62,63,69,75],{},[64,65,66],"td",{},[18,67,68],{},"Java (JDK)",[64,70,71],{},[72,73,74],"code",{},"Java 25",[64,76,77,78,81],{},"后端核心开发与运行环境（以 ",[72,79,80],{},"mvn -v"," 输出版本为准）",[46,83,84,89,94],{},[64,85,86],{},[18,87,88],{},"Maven",[64,90,91],{},[72,92,93],{},"3.9+",[64,95,96],{},"后端依赖管理与打包工具",[46,98,99,104,114],{},[64,100,101],{},[18,102,103],{},"Node.js",[64,105,106,109,110,113],{},[72,107,108],{},"22.12+","（或 ",[72,111,112],{},"20.19+","）",[64,115,116,117,120,121,124],{},"前端（",[72,118,119],{},"frontend\u002F","）与官网（",[72,122,123],{},"site\u002F","）开发与打包环境",[46,126,127,132,137],{},[64,128,129],{},[18,130,131],{},"PostgreSQL",[64,133,134],{},[72,135,136],{},"18",[64,138,139],{},"核心关系型数据库，支持高性能事务与复杂统计查询",[46,141,142,147,152],{},[64,143,144],{},[18,145,146],{},"Redis",[64,148,149],{},[72,150,151],{},"8.10",[64,153,154],{},"高速缓存与会话状态管理",[156,157,158],"blockquote",{},[15,159,160,163,164,169],{},[18,161,162],{},"提示","：如果您仅需体验或生产部署 CatCRM，无需在宿主机手工安装上述环境，直接参阅 ",[165,166,168],"a",{"href":167},"\u002Fdocs\u002Fdocker-deploy","Docker 单容器部署"," 即可一键运行。",[11,171,172],{"id":172},"仓库目录结构",[174,175,181],"pre",{"className":176,"code":178,"language":179,"meta":180},[177],"language-text","CatCRM\u002F\n├── backend\u002F       # Spring Boot 4.1 + Java 25 后端工程\n├── frontend\u002F      # Vue 3.5 + Element Plus 2.14 + Vite 8 前端管理后台\n├── site\u002F          # Nuxt 3 + Nuxt UI v3 + Nuxt Content v3 官方网站与文档中心\n├── deploy\u002F        # Docker All-in-One 镜像构建、Nginx 配置与打包脚本\n├── upload\u002F        # 本地文件存储目录（图片、合同附件等）\n└── logs\u002F          # 系统运行日志目录\n","text","",[72,182,178],{"__ignoreMap":180},[11,184,185],{"id":185},"本地前后端开发启动",[187,188,190,191,194],"h3",{"id":189},"_1-启动后端服务-backend","1. 启动后端服务 (",[72,192,193],{},"backend\u002F",")",[196,197,198,247,254,265],"ol",{},[199,200,201,202,205,206],"li",{},"在本地 PostgreSQL 18 中创建空数据库 ",[72,203,204],{},"catcrm","：\n",[174,207,211],{"className":208,"code":209,"language":210,"meta":180,"style":180},"language-sql shiki shiki-themes material-theme-lighter github-dark github-dark","CREATE DATABASE catcrm ENCODING 'UTF8';\n","sql",[72,212,213],{"__ignoreMap":180},[214,215,218,222,225,229,232,236,240,243],"span",{"class":216,"line":217},"line",1,[214,219,221],{"class":220},"s1Wpa","CREATE",[214,223,224],{"class":220}," DATABASE",[214,226,228],{"class":227},"sK_r7"," catcrm",[214,230,231],{"class":220}," ENCODING",[214,233,235],{"class":234},"sF_wb"," '",[214,237,239],{"class":238},"s0vBq","UTF8",[214,241,242],{"class":234},"'",[214,244,246],{"class":245},"sMo7A",";\n",[199,248,249,250,253],{},"修改 ",[72,251,252],{},"backend\u002Fsrc\u002Fmain\u002Fresources\u002Fapplication-dev.yml"," 中的数据库连接与 Redis 密码配置。",[199,255,256,257,260,261,264],{},"启动后端主类，系统将通过 ",[18,258,259],{},"Flyway"," 自动按 ",[72,262,263],{},"V1 -> V3"," 顺序完成全部 33 张表结构、系统字典、管理员账号及 3217 条行政区划数据的初始化，无需手工导入任何 SQL 文件。",[199,266,267,268,271,272,275,276,279,280,29],{},"后端默认运行在 ",[72,269,270],{},"18080"," 端口，统一接口前缀（",[72,273,274],{},"context-path","）为 ",[72,277,278],{},"\u002Fapi","，接口文档地址为 ",[72,281,282],{},"http:\u002F\u002Flocalhost:18080\u002Fapi\u002Fdoc.html",[187,284,286,287,194],{"id":285},"_2-启动前端管理后台-frontend","2. 启动前端管理后台 (",[72,288,119],{},[174,290,294],{"className":291,"code":292,"language":293,"meta":180,"style":180},"language-bash shiki shiki-themes material-theme-lighter github-dark github-dark","cd frontend\nnpm install\nnpm run dev\n","bash",[72,295,296,305,315],{"__ignoreMap":180},[214,297,298,302],{"class":216,"line":217},[214,299,301],{"class":300},"sUkpR","cd",[214,303,304],{"class":238}," frontend\n",[214,306,308,312],{"class":216,"line":307},2,[214,309,311],{"class":310},"soiBB","npm",[214,313,314],{"class":238}," install\n",[214,316,318,320,323],{"class":216,"line":317},3,[214,319,311],{"class":310},[214,321,322],{"class":238}," run",[214,324,325],{"class":238}," dev\n",[15,327,328,329,332,333,335,336,338],{},"前端开发服务器默认启动在 ",[72,330,331],{},"http:\u002F\u002Flocalhost:3000","，Vite 会自动将 ",[72,334,278],{}," 前缀请求代理至本机 ",[72,337,270],{}," 端口的后端服务。",[187,340,342],{"id":341},"_3-默认登录账号","3. 默认登录账号",[344,345,346,355],"ul",{},[199,347,348,351,352],{},[18,349,350],{},"管理员账号","：",[72,353,354],{},"admin",[199,356,357,351,360],{},[18,358,359],{},"默认密码",[72,361,362],{},"admin123",[364,365,366],"style",{},"html pre.shiki code .sUkpR, html code.shiki .sUkpR{--shiki-light:#6182B8;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .s0vBq, html code.shiki .s0vBq{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .soiBB, html code.shiki .soiBB{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s1Wpa, html code.shiki .s1Wpa{--shiki-light:#F76D47;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .sK_r7, html code.shiki .sK_r7{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .sF_wb, html code.shiki .sF_wb{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .sMo7A, html code.shiki .sMo7A{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}",{"title":180,"searchDepth":317,"depth":317,"links":368},[369,370,371,372],{"id":13,"depth":307,"text":13},{"id":35,"depth":307,"text":35},{"id":172,"depth":307,"text":172},{"id":185,"depth":307,"text":185,"children":373},[374,376,378],{"id":189,"depth":317,"text":375},"1. 启动后端服务 (backend\u002F)",{"id":285,"depth":317,"text":377},"2. 启动前端管理后台 (frontend\u002F)",{"id":341,"depth":317,"text":342},"快速入门","了解 CatCRM 的运行环境要求、目录结构以及本地前后端开发启动方式。","md","i-lucide-rocket",{},true,"\u002Fdocs\u002Fgetting-started",{"title":6,"description":380},"docs\u002Fgetting-started","2026-10-27","zYCzOis7dweiQ6fHHDPiJV6RZ4H6jR5g-IuZRW_BLXU",{"id":391,"title":392,"body":393,"category":864,"description":865,"extension":381,"icon":866,"meta":867,"navigation":384,"order":307,"path":868,"seo":869,"stem":870,"updatedAt":388,"__hash__":871},"docs\u002Fdocs\u002Farchitecture.md","系统架构与技术栈",{"type":8,"value":394,"toc":853},[395,398,401,407,518,527,606,609,635,674,678,689,790,793,796],[11,396,397],{"id":397},"前后端技术栈概览",[15,399,400],{},"CatCRM 采用前后端完全分离的架构设计，后端 Jar 包专注于提供高性能 RESTful API，不再内置前端静态页面。",[187,402,404,405,194],{"id":403},"后端技术栈-backend","后端技术栈 (",[72,406,193],{},[40,408,409,425],{},[43,410,411],{},[46,412,413,416,419,422],{},[49,414,415],{},"类别",[49,417,418],{},"技术选型",[49,420,421],{},"版本",[49,423,424],{},"核心职责",[59,426,427,443,459,475,491,504],{},[46,428,429,432,435,440],{},[64,430,431],{},"开发语言",[64,433,434],{},"Java",[64,436,437],{},[72,438,439],{},"25",[64,441,442],{},"启用现代语法特性与垃圾回收性能优化",[46,444,445,448,451,456],{},[64,446,447],{},"核心框架",[64,449,450],{},"Spring Boot",[64,452,453],{},[72,454,455],{},"4.1",[64,457,458],{},"应用装配、配置管理与 Web 容器底座",[46,460,461,464,467,472],{},[64,462,463],{},"安全框架",[64,465,466],{},"Spring Security",[64,468,469],{},[72,470,471],{},"7.1",[64,473,474],{},"认证鉴权、Token 校验与细粒度 RBAC 权限控制",[46,476,477,480,483,488],{},[64,478,479],{},"ORM 框架",[64,481,482],{},"MyBatis-Plus",[64,484,485],{},[72,486,487],{},"3.5.16",[64,489,490],{},"数据持久化、分页插件与动态数据权限拦截",[46,492,493,496,498,501],{},[64,494,495],{},"数据库迁移",[64,497,259],{},[64,499,500],{},"内置",[64,502,503],{},"启动自动建表、版本演进与 Checksum 校验",[46,505,506,509,512,515],{},[64,507,508],{},"工具类库",[64,510,511],{},"Hutool \u002F Lombok",[64,513,514],{},"最新稳定版",[64,516,517],{},"集合\u002F字符串防御性判空与构造器依赖注入",[187,519,521,522,524,525,194],{"id":520},"前端与官网技术栈-frontend-site","前端与官网技术栈 (",[72,523,119],{}," & ",[72,526,123],{},[40,528,529,541],{},[43,530,531],{},[46,532,533,536,539],{},[49,534,535],{},"工程目录",[49,537,538],{},"核心技术栈",[49,540,57],{},[59,542,543,582],{},[46,544,545,550,571],{},[64,546,547,549],{},[72,548,119],{},"（CRM 业务系统）",[64,551,552,555,556,555,559,555,562,555,565,555,568],{},[72,553,554],{},"Vue 3.5.39"," + ",[72,557,558],{},"Vite 8",[72,560,561],{},"Pinia 3.0.4",[72,563,564],{},"Vue Router 5.1.0",[72,566,567],{},"Element Plus 2.14.3",[72,569,570],{},"ECharts 5.5",[64,572,573,574,577,578,581],{},"专注国内企业级交互体验，含国密 ",[72,575,576],{},"sm-crypto"," 与 ",[72,579,580],{},"Sortable.js"," 自定义表单拖拽",[46,583,584,589,603],{},[64,585,586,588],{},[72,587,123],{},"（产品官网与文档）",[64,590,591,555,594,555,597,555,600],{},[72,592,593],{},"Nuxt 3",[72,595,596],{},"Nuxt UI v3",[72,598,599],{},"Nuxt Content v3",[72,601,602],{},"Tailwind CSS v4",[64,604,605],{},"支持全站 SSG 静态预渲染，可直接托管至任意云厂商 CDN",[11,607,608],{"id":608},"接口前缀与反向代理机制",[15,610,611,612,614,615,617,618,621,622,625,626,628,629,632,633,351],{},"后端统一设置 ",[72,613,274],{}," 为 ",[72,616,278],{},"，所有接口（包含文件预览 ",[72,619,620],{},"\u002Fapi\u002Fupload\u002F{id}"," 以及接口文档 ",[72,623,624],{},"\u002Fapi\u002Fdoc.html","）均带有 ",[72,627,278],{}," 前缀；前端环境变量 ",[72,630,631],{},"VITE_API_URL"," 同样固定为 ",[72,634,278],{},[344,636,637,657],{},[199,638,639,351,642,645,646,649,650,652,653,656],{},[18,640,641],{},"开发环境",[72,643,644],{},"npm run dev"," 启动在 ",[72,647,648],{},"3000"," 端口，由 Vite Dev Server 将 ",[72,651,278],{}," 代理转发到本机 ",[72,654,655],{},"127.0.0.1:18080"," 的后端。",[199,658,659,662,663,666,667,669,670,673],{},[18,660,661],{},"生产环境","：由 Nginx 统一监听 ",[72,664,665],{},"8080"," 端口托管前端静态页面，并将 ",[72,668,278],{}," 路径平滑转发至后端服务（详见 ",[72,671,672],{},"deploy\u002Fnginx.conf","）。",[11,675,677],{"id":676},"crm-核心业务模块划分","CRM 核心业务模块划分",[15,679,680,681,684,685,688],{},"前端 ",[72,682,683],{},"frontend\u002Fsrc\u002Fviews\u002Fcrm\u002F"," 与后端 ",[72,686,687],{},"net.maku.crm"," 包采用一一对应的领域模块划分：",[196,690,691,700,709,718,727,736,745,754,763,772,781],{},[199,692,693,699],{},[18,694,695,696,194],{},"线索管理 (",[72,697,698],{},"lead","：市场线索采集、分配、转化跟踪。",[199,701,702,708],{},[18,703,704,705,194],{},"客户管理 (",[72,706,707],{},"customer","：客户档案、省市区联动、客户池与公海自动回收领取。",[199,710,711,717],{},[18,712,713,714,194],{},"联系人管理 (",[72,715,716],{},"contact","：客户关联的多决策人信息维护。",[199,719,720,726],{},[18,721,722,723,194],{},"跟进记录 (",[72,724,725],{},"record","：全生命周期跟进流水与富文本拜访记录。",[199,728,729,735],{},[18,730,731,732,194],{},"商机管理 (",[72,733,734],{},"opportunity","：销售阶段推进、预计成交金额与赢率分析。",[199,737,738,744],{},[18,739,740,741,194],{},"产品管理 (",[72,742,743],{},"product","：产品分类、标准单价、上下架状态维护。",[199,746,747,753],{},[18,748,749,750,194],{},"合同管理 (",[72,751,752],{},"contract","：合同签署人、产品明细、审批状态与应收汇总。",[199,755,756,762],{},[18,757,758,759,194],{},"订单管理 (",[72,760,761],{},"order","：销售订单履约与交付明细管理。",[199,764,765,771],{},[18,766,767,768,194],{},"回款管理 (",[72,769,770],{},"payment","：分期回款计划、实际回款核销与账期跟踪。",[199,773,774,780],{},[18,775,776,777,194],{},"发票管理 (",[72,778,779],{},"invoice","：增值税发票开具申请与税务信息核验。",[199,782,783,789],{},[18,784,785,786,194],{},"自定义表单 (",[72,787,788],{},"form","：基于元数据驱动的动态字段配置与布局排序。",[11,791,792],{"id":792},"架构与编码规范守则",[15,794,795],{},"CatCRM 严格遵循《阿里巴巴 Java 开发手册》，核心工程规范包括：",[344,797,798,816,833],{},[199,799,800,803,804,807,808,811,812,815],{},[18,801,802],{},"构造器依赖注入","：所有 Service\u002FController 依赖声明为 ",[72,805,806],{},"private final","，配合类级别 ",[72,809,810],{},"@AllArgsConstructor"," 注入，严禁 ",[72,813,814],{},"@Autowired"," 字段注入。",[199,817,818,821,822,825,826,829,830,29],{},[18,819,820],{},"金额与精度安全","：涉及合同金额、订单折扣、回款与发票金额等计算，一律使用 ",[72,823,824],{},"BigDecimal","，严禁使用 ",[72,827,828],{},"double"," 或 ",[72,831,832],{},"float",[199,834,835,838,839,842,843,842,846,848,849,852],{},[18,836,837],{},"POJO 包装类型与枚举化","：Entity、VO、DTO、Query 成员变量统一采用包装类型（",[72,840,841],{},"Long","、",[72,844,845],{},"Integer",[72,847,824],{},"），所有业务状态与类型杜绝魔法值，全部使用以 ",[72,850,851],{},"Enum"," 结尾的枚举类。",{"title":180,"searchDepth":317,"depth":317,"links":854},[855,861,862,863],{"id":397,"depth":307,"text":397,"children":856},[857,859],{"id":403,"depth":317,"text":858},"后端技术栈 (backend\u002F)",{"id":520,"depth":317,"text":860},"前端与官网技术栈 (frontend\u002F & site\u002F)",{"id":608,"depth":307,"text":608},{"id":676,"depth":307,"text":677},{"id":792,"depth":307,"text":792},"架构与数据库","深入了解 CatCRM 的前后端技术选型、接口转发机制、业务模块划分与编码规范。","i-lucide-layers",{},"\u002Fdocs\u002Farchitecture",{"title":392,"description":865},"docs\u002Farchitecture","NmCVswSCJW3GhYjKyQHEzEzGez0Gy2kiWswTiW0ZGww",{"id":873,"title":874,"body":875,"category":864,"description":1133,"extension":381,"icon":1134,"meta":1135,"navigation":384,"order":317,"path":1136,"seo":1137,"stem":1138,"updatedAt":388,"__hash__":1139},"docs\u002Fdocs\u002Fdatabase-flyway.md","数据库初始化与 Flyway 演进",{"type":8,"value":876,"toc":1126},[877,881,891,913,916,985,988,1030,1034,1046,1049,1071,1074,1095],[11,878,880],{"id":879},"零手工-sql-自动初始化","零手工 SQL 自动初始化",[15,882,883,884,886,887,890],{},"CatCRM 内置 ",[18,885,259],{}," 数据库版本管理引擎。无论是本地开发还是 Docker 容器首次启动，都",[18,888,889],{},"不需要手工执行任何 SQL 脚本","，应用启动时会自动完成建表与初始种子数据写入，保证开发、测试与生产环境严格一致。",[344,892,893,901],{},[199,894,895,351,898],{},[18,896,897],{},"脚本存放目录",[72,899,900],{},"backend\u002Fsrc\u002Fmain\u002Fresources\u002Fdb\u002Fmigration",[199,902,903,351,906,909,910],{},[18,904,905],{},"脚本命名规则",[72,907,908],{},"V{版本号}__{描述}.sql","，版本号唯一且递增，例如新增表结构变更可使用 ",[72,911,912],{},"V7__add_contract_signer.sql",[11,914,915],{"id":915},"内置迁移脚本说明",[40,917,918,930],{},[43,919,920],{},[46,921,922,924,927],{},[49,923,421],{},[49,925,926],{},"脚本文件名",[49,928,929],{},"核心内容说明",[59,931,932,955,970],{},[46,933,934,939,944],{},[64,935,936],{},[18,937,938],{},"V1",[64,940,941],{},[72,942,943],{},"V1__init_schema.sql",[64,945,946,947,950,951,954],{},"初始化全部 33 张表结构：包含 17 张 ",[72,948,949],{},"sys_"," 系统基础表 + 16 张 ",[72,952,953],{},"crm_"," 核心业务表",[46,956,957,962,967],{},[64,958,959],{},[18,960,961],{},"V2",[64,963,964],{},[72,965,966],{},"V2__init_data.sql",[64,968,969],{},"写入初始化数据：系统参数配置、数据字典、权限菜单、默认管理员账号、CRM 动态字段元数据，并重置自增序列",[46,971,972,977,982],{},[64,973,974],{},[18,975,976],{},"V3",[64,978,979],{},[72,980,981],{},"V3__init_region_data.sql",[64,983,984],{},"写入全国省市区行政区划基础数据（共 3217 条），并重置行政区划序列",[11,986,987],{"id":987},"空库与存量库兼容策略",[344,989,990,1000,1020],{},[199,991,992,995,996,999],{},[18,993,994],{},"全新空库","：首次启动时按 ",[72,997,998],{},"V1 -> V2 -> V3"," 顺序自动执行，数秒内即可得到完整表结构与初始业务数据。",[199,1001,1002,1005,1006,1009,1010,1013,1014,842,1017,673],{},[18,1003,1004],{},"存量数据库（已手工建表）","：首次启动时会自动打基线（",[72,1007,1008],{},"baseline","）到版本 ",[72,1011,1012],{},"3","，不会重复执行 V1~V3 建表，此后仅按序执行新增版本脚本（如 ",[72,1015,1016],{},"V4",[72,1018,1019],{},"V5",[199,1021,1022,1025,1026,1029],{},[18,1023,1024],{},"人工接管模式","：如生产环境有严格的 DBA 审批要求、需要人工执行脚本，只需在配置中设置 ",[72,1027,1028],{},"spring.flyway.enabled=false","，再按版本顺序手工执行 SQL。",[11,1031,1033],{"id":1032},"重要铁律禁止修改已发布脚本","重要铁律：禁止修改已发布脚本",[156,1035,1036],{},[15,1037,1038,1041,1042,1045],{},[18,1039,1040],{},"警告","：已执行过的 Flyway 脚本严禁修改内容！Flyway 在每次启动时会校验已执行脚本的 Checksum（校验和），任何字符改动都会触发 ",[72,1043,1044],{},"Migration checksum mismatch"," 导致应用启动失败。任何表结构或数据变更，请一律新增递增版本脚本。",[15,1047,1048],{},"如果在开发环境中因调试改动了历史脚本导致报错：",[344,1050,1051,1061],{},[199,1052,1053,1056,1057,1060],{},[18,1054,1055],{},"开发测试库","：直接执行 ",[72,1058,1059],{},"DROP DATABASE catcrm; CREATE DATABASE catcrm;"," 重建即可。",[199,1062,1063,1066,1067,1070],{},[18,1064,1065],{},"需保留数据的环境","：使用 Flyway CLI 执行 ",[72,1068,1069],{},"flyway repair"," 重新计算并修复校验和。",[11,1072,1073],{"id":1073},"本地文件存储配置说明",[15,1075,1076,1078,1079,1082,1083,1086,1087,1090,1091,1094],{},[72,1077,966],{}," 种子数据中的 ",[72,1080,1081],{},"STORAGE_CONFIG"," 默认配置为",[18,1084,1085],{},"本地存储","（",[72,1088,1089],{},"type=0","，路径 ",[72,1092,1093],{},"upload","，按进程工作目录解析）：",[344,1096,1097,1114],{},[199,1098,1099,1102,1103,1106,1107,1110,1111,673],{},[18,1100,1101],{},"Docker 容器内","：容器 ",[72,1104,1105],{},"WORKDIR=\u002Fapp"," → 上传的图片与合同附件自动保存在 ",[72,1108,1109],{},"\u002Fapp\u002Fupload","（对应宿主机挂载的 ",[72,1112,1113],{},"~\u002Fcatcrm\u002Fupload",[199,1115,1116,1119,1120,1122,1123,29],{},[18,1117,1118],{},"本地开发启动","：在 ",[72,1121,193],{}," 工作目录启动 → 文件保存在 ",[72,1124,1125],{},"backend\u002Fupload",{"title":180,"searchDepth":317,"depth":317,"links":1127},[1128,1129,1130,1131,1132],{"id":879,"depth":307,"text":880},{"id":915,"depth":307,"text":915},{"id":987,"depth":307,"text":987},{"id":1032,"depth":307,"text":1033},{"id":1073,"depth":307,"text":1073},"详解 CatCRM 基于 Flyway 的自动化数据库建表机制、版本脚本规范与文件存储配置。","i-lucide-database",{},"\u002Fdocs\u002Fdatabase-flyway",{"title":874,"description":1133},"docs\u002Fdatabase-flyway","nMgTn0cquEQqMMAZtArD8nB19J8i-7fp0Jpl6OtAPQ0",{"id":1141,"title":1142,"body":1143,"category":1723,"description":1724,"extension":381,"icon":1725,"meta":1726,"navigation":384,"order":1255,"path":167,"seo":1727,"stem":1728,"updatedAt":388,"__hash__":1729},"docs\u002Fdocs\u002Fdocker-deploy.md","Docker 单容器部署指南",{"type":8,"value":1144,"toc":1712},[1145,1149,1156,1184,1188,1203,1365,1376,1394,1397,1400,1486,1489,1580,1584,1591,1626,1629,1709],[11,1146,1148],{"id":1147},"架构设计all-in-one-单容器","架构设计：All-in-One 单容器",[15,1150,1151,1152,1155],{},"CatCRM 官方 Docker 镜像内置了 ",[18,1153,1154],{},"Nginx、Spring Boot 后端应用、PostgreSQL 18 和 Redis 8"," 四大组件，一个容器即可完整运行整套系统：",[344,1157,1158,1174],{},[199,1159,1160,1161,1167,1168,1170,1171,1173],{},"容器对外",[18,1162,1163,1164,1166],{},"仅暴露 Nginx 的 ",[72,1165,665],{}," 端口","：前端页面由 Nginx 直接高效响应，",[72,1169,278],{}," 请求在容器内部转发至 ",[72,1172,655],{}," 的后端服务。",[199,1175,1176,1179,1180,1183],{},[18,1177,1178],{},"高安全性隔离","：PostgreSQL 18 与 Redis 8 仅监听容器内部回环地址（",[72,1181,1182],{},"127.0.0.1","），不对外网暴露端口，彻底杜绝外部扫段与弱口令爆破风险。",[11,1185,1187],{"id":1186},"快速运行推荐","快速运行（推荐）",[15,1189,1190,1191,1194,1195,1198,1199,1202],{},"数据默认统一挂载在宿主机的 ",[72,1192,1193],{},"~\u002Fcatcrm"," 目录下。",[18,1196,1197],{},"请先手工创建宿主机目录","，避免 Docker 自动以 ",[72,1200,1201],{},"root"," 权限创建空目录：",[174,1204,1206],{"className":291,"code":1205,"language":293,"meta":180,"style":180},"mkdir -p $HOME\u002Fcatcrm\u002F{postgres,redis,upload,logs}\n\ndocker run -d --name catcrm --restart unless-stopped \\\n  --stop-timeout 30 \\\n  -p 8080:8080 \\\n  -e DB_PASSWORD='123456' \\\n  -e REDIS_PASSWORD='123456' \\\n  -v $HOME\u002Fcatcrm\u002Fpostgres:\u002Fdata\u002Fpostgres \\\n  -v $HOME\u002Fcatcrm\u002Fredis:\u002Fdata\u002Fredis \\\n  -v $HOME\u002Fcatcrm\u002Fupload:\u002Fapp\u002Fupload \\\n  -v $HOME\u002Fcatcrm\u002Flogs:\u002Fapp\u002Flogs \\\n  makunet\u002Fcatcrm:0.1.0\n",[72,1207,1208,1223,1228,1253,1265,1276,1294,1310,1323,1335,1347,1359],{"__ignoreMap":180},[214,1209,1210,1213,1217,1220],{"class":216,"line":217},[214,1211,1212],{"class":310},"mkdir",[214,1214,1216],{"class":1215},"sSJ72"," -p",[214,1218,1219],{"class":245}," $HOME",[214,1221,1222],{"class":238},"\u002Fcatcrm\u002F{postgres,redis,upload,logs}\n",[214,1224,1225],{"class":216,"line":307},[214,1226,1227],{"emptyLinePlaceholder":384},"\n",[214,1229,1230,1233,1235,1238,1241,1243,1246,1249],{"class":216,"line":317},[214,1231,1232],{"class":310},"docker",[214,1234,322],{"class":238},[214,1236,1237],{"class":1215}," -d",[214,1239,1240],{"class":1215}," --name",[214,1242,228],{"class":238},[214,1244,1245],{"class":1215}," --restart",[214,1247,1248],{"class":238}," unless-stopped",[214,1250,1252],{"class":1251},"sVPC0"," \\\n",[214,1254,1256,1259,1263],{"class":216,"line":1255},4,[214,1257,1258],{"class":1215},"  --stop-timeout",[214,1260,1262],{"class":1261},"s_k96"," 30",[214,1264,1252],{"class":1251},[214,1266,1268,1271,1274],{"class":216,"line":1267},5,[214,1269,1270],{"class":1215},"  -p",[214,1272,1273],{"class":238}," 8080:8080",[214,1275,1252],{"class":1251},[214,1277,1279,1282,1285,1287,1290,1292],{"class":216,"line":1278},6,[214,1280,1281],{"class":1215},"  -e",[214,1283,1284],{"class":238}," DB_PASSWORD=",[214,1286,242],{"class":234},[214,1288,1289],{"class":238},"123456",[214,1291,242],{"class":234},[214,1293,1252],{"class":1251},[214,1295,1297,1299,1302,1304,1306,1308],{"class":216,"line":1296},7,[214,1298,1281],{"class":1215},[214,1300,1301],{"class":238}," REDIS_PASSWORD=",[214,1303,242],{"class":234},[214,1305,1289],{"class":238},[214,1307,242],{"class":234},[214,1309,1252],{"class":1251},[214,1311,1313,1316,1318,1321],{"class":216,"line":1312},8,[214,1314,1315],{"class":1215},"  -v",[214,1317,1219],{"class":245},[214,1319,1320],{"class":238},"\u002Fcatcrm\u002Fpostgres:\u002Fdata\u002Fpostgres",[214,1322,1252],{"class":1251},[214,1324,1326,1328,1330,1333],{"class":216,"line":1325},9,[214,1327,1315],{"class":1215},[214,1329,1219],{"class":245},[214,1331,1332],{"class":238},"\u002Fcatcrm\u002Fredis:\u002Fdata\u002Fredis",[214,1334,1252],{"class":1251},[214,1336,1338,1340,1342,1345],{"class":216,"line":1337},10,[214,1339,1315],{"class":1215},[214,1341,1219],{"class":245},[214,1343,1344],{"class":238},"\u002Fcatcrm\u002Fupload:\u002Fapp\u002Fupload",[214,1346,1252],{"class":1251},[214,1348,1350,1352,1354,1357],{"class":216,"line":1349},11,[214,1351,1315],{"class":1215},[214,1353,1219],{"class":245},[214,1355,1356],{"class":238},"\u002Fcatcrm\u002Flogs:\u002Fapp\u002Flogs",[214,1358,1252],{"class":1251},[214,1360,1362],{"class":216,"line":1361},12,[214,1363,1364],{"class":238},"  makunet\u002Fcatcrm:0.1.0\n",[15,1366,1367,1368,1371,1372,1375],{},"启动后在浏览器访问 ",[72,1369,1370],{},"http:\u002F\u002F\u003Chost>:8080","。首次启动会自动初始化数据库并执行 Flyway 建表脚本，约需几十秒，期间容器健康检查状态显示为 ",[72,1373,1374],{},"starting","。可通过以下命令实时查看启动日志：",[174,1377,1379],{"className":291,"code":1378,"language":293,"meta":180,"style":180},"docker logs -f catcrm\n",[72,1380,1381],{"__ignoreMap":180},[214,1382,1383,1385,1388,1391],{"class":216,"line":217},[214,1384,1232],{"class":310},[214,1386,1387],{"class":238}," logs",[214,1389,1390],{"class":1215}," -f",[214,1392,1393],{"class":238}," catcrm\n",[11,1395,1396],{"id":1396},"环境变量与目录挂载说明",[187,1398,1399],{"id":1399},"环境变量表",[40,1401,1402,1417],{},[43,1403,1404],{},[46,1405,1406,1409,1412,1415],{},[49,1407,1408],{},"变量名",[49,1410,1411],{},"是否必填",[49,1413,1414],{},"默认值",[49,1416,57],{},[59,1418,1419,1437,1453,1470],{},[46,1420,1421,1426,1431,1434],{},[64,1422,1423],{},[72,1424,1425],{},"DB_PASSWORD",[64,1427,1428],{},[18,1429,1430],{},"是",[64,1432,1433],{},"无",[64,1435,1436],{},"PostgreSQL 数据库密码（缺失时容器立即退出并提示）",[46,1438,1439,1444,1448,1450],{},[64,1440,1441],{},[72,1442,1443],{},"REDIS_PASSWORD",[64,1445,1446],{},[18,1447,1430],{},[64,1449,1433],{},[64,1451,1452],{},"Redis 认证密码（缺失时容器立即退出并提示）",[46,1454,1455,1460,1463,1467],{},[64,1456,1457],{},[72,1458,1459],{},"DB_NAME",[64,1461,1462],{},"否",[64,1464,1465],{},[72,1466,204],{},[64,1468,1469],{},"数据库名（仅允许小写字母、数字、下划线）",[46,1471,1472,1477,1479,1483],{},[64,1473,1474],{},[72,1475,1476],{},"DB_USER",[64,1478,1462],{},[64,1480,1481],{},[72,1482,204],{},[64,1484,1485],{},"数据库用户名（仅允许小写字母、数字、下划线）",[187,1487,1488],{"id":1488},"持久化数据目录映射",[40,1490,1491,1507],{},[43,1492,1493],{},[46,1494,1495,1498,1501,1504],{},[49,1496,1497],{},"宿主机目录（默认）",[49,1499,1500],{},"容器内路径",[49,1502,1503],{},"是否必须挂载",[49,1505,1506],{},"用途说明",[59,1508,1509,1529,1547,1562],{},[46,1510,1511,1516,1521,1526],{},[64,1512,1513],{},[72,1514,1515],{},"~\u002Fcatcrm\u002Fpostgres",[64,1517,1518],{},[72,1519,1520],{},"\u002Fdata\u002Fpostgres",[64,1522,1523],{},[18,1524,1525],{},"必须挂载",[64,1527,1528],{},"PostgreSQL 18 数据文件（未挂载时容器拒绝启动，防止数据丢失）",[46,1530,1531,1536,1541,1544],{},[64,1532,1533],{},[72,1534,1535],{},"~\u002Fcatcrm\u002Fredis",[64,1537,1538],{},[72,1539,1540],{},"\u002Fdata\u002Fredis",[64,1542,1543],{},"强烈建议",[64,1545,1546],{},"Redis 8 AOF \u002F RDB 持久化数据",[46,1548,1549,1553,1557,1559],{},[64,1550,1551],{},[72,1552,1113],{},[64,1554,1555],{},[72,1556,1109],{},[64,1558,1543],{},[64,1560,1561],{},"上传的客户附件、合同扫描件与图片",[46,1563,1564,1569,1574,1577],{},[64,1565,1566],{},[72,1567,1568],{},"~\u002Fcatcrm\u002Flogs",[64,1570,1571],{},[72,1572,1573],{},"\u002Fapp\u002Flogs",[64,1575,1576],{},"建议挂载",[64,1578,1579],{},"Spring Boot 与系统运行日志",[11,1581,1583],{"id":1582},"从源码自建-docker-镜像","从源码自建 Docker 镜像",[15,1585,1586,1587,1590],{},"如果您购买了企业版源码或需要自行定制打包，项目在 ",[72,1588,1589],{},"deploy\u002F"," 目录下提供了完整的自动化构建脚本。前端与后端在宿主机完成打包，Dockerfile 仅负责拷贝产物，一条命令即可完成：",[174,1592,1594],{"className":291,"code":1593,"language":293,"meta":180,"style":180},"# 本地打包并构建当前机器架构镜像 makunet\u002Fcatcrm:0.1.0\n.\u002Fdeploy\u002Fdocker-build.sh 0.1.0\n\n# 构建 linux\u002Famd64 + linux\u002Farm64 多架构镜像并推送至 Docker Hub\n.\u002Fdeploy\u002Fdocker-push.sh 0.1.0\n",[72,1595,1596,1602,1610,1614,1619],{"__ignoreMap":180},[214,1597,1598],{"class":216,"line":217},[214,1599,1601],{"class":1600},"sutJx","# 本地打包并构建当前机器架构镜像 makunet\u002Fcatcrm:0.1.0\n",[214,1603,1604,1607],{"class":216,"line":307},[214,1605,1606],{"class":310},".\u002Fdeploy\u002Fdocker-build.sh",[214,1608,1609],{"class":1261}," 0.1.0\n",[214,1611,1612],{"class":216,"line":317},[214,1613,1227],{"emptyLinePlaceholder":384},[214,1615,1616],{"class":216,"line":1255},[214,1617,1618],{"class":1600},"# 构建 linux\u002Famd64 + linux\u002Farm64 多架构镜像并推送至 Docker Hub\n",[214,1620,1621,1624],{"class":216,"line":1267},[214,1622,1623],{"class":310},".\u002Fdeploy\u002Fdocker-push.sh",[214,1625,1609],{"class":1261},[187,1627,1628],{"id":1628},"常用打包命令与参数",[174,1630,1632],{"className":291,"code":1631,"language":293,"meta":180,"style":180},"# 仅在宿主机打包前后端产物到 deploy\u002Fdist，不构建 Docker 镜像\n.\u002Fdeploy\u002Fpackage.sh\n\n# 企业版源码开发：跳过 Allatori 字节码混淆加密，直接纯净打包\n.\u002Fdeploy\u002Fpackage.sh --no-obfuscate\n\n# 使用国内镜像源加速前端依赖安装并构建镜像\nNPM_REGISTRY=https:\u002F\u002Fregistry.npmmirror.com .\u002Fdeploy\u002Fdocker-build.sh 0.1.0\n\n# 仅修改了 Dockerfile \u002F nginx.conf \u002F entrypoint 时，跳过编译直接复用 dist 产物构建\nSKIP_PACKAGE=1 .\u002Fdeploy\u002Fdocker-build.sh\n",[72,1633,1634,1639,1644,1648,1653,1661,1665,1670,1687,1691,1696],{"__ignoreMap":180},[214,1635,1636],{"class":216,"line":217},[214,1637,1638],{"class":1600},"# 仅在宿主机打包前后端产物到 deploy\u002Fdist，不构建 Docker 镜像\n",[214,1640,1641],{"class":216,"line":307},[214,1642,1643],{"class":310},".\u002Fdeploy\u002Fpackage.sh\n",[214,1645,1646],{"class":216,"line":317},[214,1647,1227],{"emptyLinePlaceholder":384},[214,1649,1650],{"class":216,"line":1255},[214,1651,1652],{"class":1600},"# 企业版源码开发：跳过 Allatori 字节码混淆加密，直接纯净打包\n",[214,1654,1655,1658],{"class":216,"line":1267},[214,1656,1657],{"class":310},".\u002Fdeploy\u002Fpackage.sh",[214,1659,1660],{"class":1215}," --no-obfuscate\n",[214,1662,1663],{"class":216,"line":1278},[214,1664,1227],{"emptyLinePlaceholder":384},[214,1666,1667],{"class":216,"line":1296},[214,1668,1669],{"class":1600},"# 使用国内镜像源加速前端依赖安装并构建镜像\n",[214,1671,1672,1675,1679,1682,1685],{"class":216,"line":1312},[214,1673,1674],{"class":245},"NPM_REGISTRY",[214,1676,1678],{"class":1677},"sFfmW","=",[214,1680,1681],{"class":238},"https:\u002F\u002Fregistry.npmmirror.com",[214,1683,1684],{"class":310}," .\u002Fdeploy\u002Fdocker-build.sh",[214,1686,1609],{"class":1261},[214,1688,1689],{"class":216,"line":1325},[214,1690,1227],{"emptyLinePlaceholder":384},[214,1692,1693],{"class":216,"line":1337},[214,1694,1695],{"class":1600},"# 仅修改了 Dockerfile \u002F nginx.conf \u002F entrypoint 时，跳过编译直接复用 dist 产物构建\n",[214,1697,1698,1701,1703,1706],{"class":216,"line":1349},[214,1699,1700],{"class":245},"SKIP_PACKAGE",[214,1702,1678],{"class":1677},[214,1704,1705],{"class":238},"1",[214,1707,1708],{"class":310}," .\u002Fdeploy\u002Fdocker-build.sh\n",[364,1710,1711],{},"html pre.shiki code .soiBB, html code.shiki .soiBB{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .sSJ72, html code.shiki .sSJ72{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sMo7A, html code.shiki .sMo7A{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .s0vBq, html code.shiki .s0vBq{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .sVPC0, html code.shiki .sVPC0{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .s_k96, html code.shiki .s_k96{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sF_wb, html code.shiki .sF_wb{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sFfmW, html code.shiki .sFfmW{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583}",{"title":180,"searchDepth":317,"depth":317,"links":1713},[1714,1715,1716,1720],{"id":1147,"depth":307,"text":1148},{"id":1186,"depth":307,"text":1187},{"id":1396,"depth":307,"text":1396,"children":1717},[1718,1719],{"id":1399,"depth":317,"text":1399},{"id":1488,"depth":317,"text":1488},{"id":1582,"depth":307,"text":1583,"children":1721},[1722],{"id":1628,"depth":317,"text":1628},"部署与运维","使用官方 All-in-One Docker 镜像在 30 秒内完成 CatCRM 生产级私有化部署与自建镜像打包。","i-lucide-container",{},{"title":1142,"description":1724},"docs\u002Fdocker-deploy","OOsrzKRNnIBBWP4M0BkN_sIST71WcFEU8r8t9q65hQQ",{"id":1731,"title":1732,"body":1733,"category":1723,"description":2126,"extension":381,"icon":2127,"meta":2128,"navigation":384,"order":1267,"path":2129,"seo":2130,"stem":2131,"updatedAt":388,"__hash__":2132},"docs\u002Fdocs\u002Foperations.md","生产运维、升级与 CDN 托管",{"type":8,"value":1734,"toc":2111},[1735,1738,1744,1759,1829,1832,1889,1893,1897,1900,1945,1949,1959,1980,1986,1996,2000,2030,2034,2054,2065,2069,2076,2108],[11,1736,1737],{"id":1737},"容器平滑升级",[15,1739,1740,1741,1743],{},"CatCRM 容器本身无状态，所有业务数据均保存在宿主机挂载目录（默认 ",[72,1742,1193],{},"）中，容器可以随时删除重建而不会丢失数据。",[15,1745,1746,1747,1750,1751,1754,1755,1758],{},"升级新版本时，使用与首次部署相同的 ",[72,1748,1749],{},"-e"," 和 ",[72,1752,1753],{},"-v"," 参数重新 ",[72,1756,1757],{},"docker run"," 即可：",[174,1760,1762],{"className":291,"code":1761,"language":293,"meta":180,"style":180},"# 1. 拉取新版本镜像\ndocker pull makunet\u002Fcatcrm:0.1.1\n\n# 2. 优雅停止容器（等待 30 秒让 PostgreSQL 与 Redis 完成落盘）\ndocker stop -t 30 catcrm\n\n# 3. 移除旧容器\ndocker rm catcrm\n\n# 4. 使用新版本镜像标签（0.1.1）重新执行 docker run\n",[72,1763,1764,1769,1779,1783,1788,1802,1806,1811,1820,1824],{"__ignoreMap":180},[214,1765,1766],{"class":216,"line":217},[214,1767,1768],{"class":1600},"# 1. 拉取新版本镜像\n",[214,1770,1771,1773,1776],{"class":216,"line":307},[214,1772,1232],{"class":310},[214,1774,1775],{"class":238}," pull",[214,1777,1778],{"class":238}," makunet\u002Fcatcrm:0.1.1\n",[214,1780,1781],{"class":216,"line":317},[214,1782,1227],{"emptyLinePlaceholder":384},[214,1784,1785],{"class":216,"line":1255},[214,1786,1787],{"class":1600},"# 2. 优雅停止容器（等待 30 秒让 PostgreSQL 与 Redis 完成落盘）\n",[214,1789,1790,1792,1795,1798,1800],{"class":216,"line":1267},[214,1791,1232],{"class":310},[214,1793,1794],{"class":238}," stop",[214,1796,1797],{"class":1215}," -t",[214,1799,1262],{"class":1261},[214,1801,1393],{"class":238},[214,1803,1804],{"class":216,"line":1278},[214,1805,1227],{"emptyLinePlaceholder":384},[214,1807,1808],{"class":216,"line":1296},[214,1809,1810],{"class":1600},"# 3. 移除旧容器\n",[214,1812,1813,1815,1818],{"class":216,"line":1312},[214,1814,1232],{"class":310},[214,1816,1817],{"class":238}," rm",[214,1819,1393],{"class":238},[214,1821,1822],{"class":216,"line":1325},[214,1823,1227],{"emptyLinePlaceholder":384},[214,1825,1826],{"class":216,"line":1337},[214,1827,1828],{"class":1600},"# 4. 使用新版本镜像标签（0.1.1）重新执行 docker run\n",[187,1830,1831],{"id":1831},"升级注意事项",[344,1833,1834,1844,1878],{},[199,1835,1836,1839,1840,1843],{},[18,1837,1838],{},"禁止强杀容器","：请勿使用 ",[72,1841,1842],{},"docker rm -f"," 强制杀死运行中的容器，否则 PostgreSQL 下次启动时需要执行崩溃恢复（Crash Recovery）。",[199,1845,1846,1849,1850],{},[18,1847,1848],{},"清理系统配置缓存","：如果新版本升级修改了系统配置表数据，请手动清理 Redis 中的配置缓存以立即生效：\n",[174,1851,1853],{"className":291,"code":1852,"language":293,"meta":180,"style":180},"docker exec catcrm sh -c 'redis-cli -a \"$REDIS_PASSWORD\" --no-auth-warning -n 0 DEL system:config'\n",[72,1854,1855],{"__ignoreMap":180},[214,1856,1857,1859,1862,1864,1867,1870,1872,1875],{"class":216,"line":217},[214,1858,1232],{"class":310},[214,1860,1861],{"class":238}," exec",[214,1863,228],{"class":238},[214,1865,1866],{"class":238}," sh",[214,1868,1869],{"class":1215}," -c",[214,1871,235],{"class":234},[214,1873,1874],{"class":238},"redis-cli -a \"$REDIS_PASSWORD\" --no-auth-warning -n 0 DEL system:config",[214,1876,1877],{"class":234},"'\n",[199,1879,1880,1883,1884,842,1886,1888],{},[18,1881,1882],{},"修改密码","：如需更换数据库或 Redis 密码，只需用新的 ",[72,1885,1425],{},[72,1887,1443],{}," 重建容器，启动脚本会自动同步数据库用户密码。",[11,1890,1892],{"id":1891},"数据备份与-jvm-内存调整","数据备份与 JVM 内存调整",[187,1894,1896],{"id":1895},"在线备份-postgresql-数据库","在线备份 PostgreSQL 数据库",[15,1898,1899],{},"无需进入容器，直接在宿主机执行以下命令即可导出完整 SQL 备份文件：",[174,1901,1903],{"className":291,"code":1902,"language":293,"meta":180,"style":180},"docker exec catcrm sh -c 'PGPASSWORD=\"$DB_PASSWORD\" pg_dump -h 127.0.0.1 -U \"${DB_USER:-catcrm}\" \"${DB_NAME:-catcrm}\"' > catcrm_backup_$(date +%F).sql\n",[72,1904,1905],{"__ignoreMap":180},[214,1906,1907,1909,1911,1913,1915,1917,1919,1922,1924,1927,1930,1934,1937,1940,1942],{"class":216,"line":217},[214,1908,1232],{"class":310},[214,1910,1861],{"class":238},[214,1912,228],{"class":238},[214,1914,1866],{"class":238},[214,1916,1869],{"class":1215},[214,1918,235],{"class":234},[214,1920,1921],{"class":238},"PGPASSWORD=\"$DB_PASSWORD\" pg_dump -h 127.0.0.1 -U \"${DB_USER:-catcrm}\" \"${DB_NAME:-catcrm}\"",[214,1923,242],{"class":234},[214,1925,1926],{"class":1677}," >",[214,1928,1929],{"class":238}," catcrm_backup_",[214,1931,1933],{"class":1932},"sG-J9","$(",[214,1935,1936],{"class":310},"date",[214,1938,1939],{"class":238}," +%F",[214,1941,194],{"class":1932},[214,1943,1944],{"class":238},".sql\n",[187,1946,1948],{"id":1947},"调整-jvm-内存占比","调整 JVM 内存占比",[15,1950,1951,1952,1955,1956,1958],{},"容器默认配置 ",[72,1953,1954],{},"JAVA_TOOL_OPTIONS=\"-XX:MaxRAMPercentage=60.0\"","。如需在内存较小的机器或大内存服务器上自定义 JVM 堆上限，可在 ",[72,1957,1757],{}," 时通过环境变量覆盖：",[174,1960,1962],{"className":291,"code":1961,"language":293,"meta":180,"style":180},"-e JAVA_TOOL_OPTIONS=\"-Xms512m -Xmx2048m\"\n",[72,1963,1964],{"__ignoreMap":180},[214,1965,1966,1968,1971,1974,1977],{"class":216,"line":217},[214,1967,1749],{"class":310},[214,1969,1970],{"class":238}," JAVA_TOOL_OPTIONS=",[214,1972,1973],{"class":234},"\"",[214,1975,1976],{"class":238},"-Xms512m -Xmx2048m",[214,1978,1979],{"class":234},"\"\n",[11,1981,1983,1984,194],{"id":1982},"官网静态化打包与-cdn-托管-site","官网静态化打包与 CDN 托管 (",[72,1985,123],{},[15,1987,1988,1989,1991,1992,1995],{},"CatCRM 官方网站（位于仓库 ",[72,1990,123],{}," 目录）基于 ",[18,1993,1994],{},"Nuxt 3 + Nuxt UI v3 + Nuxt Content v3"," 构建，已预置全站静态预渲染（SSG）配置，生成的纯静态文件可直接托管至阿里云 OSS + CDN、腾讯云 COS + EdgeOne、Cloudflare Pages、Vercel 或任意 Nginx 静态服务器。",[187,1997,1999],{"id":1998},"_1-本地开发与预览","1. 本地开发与预览",[174,2001,2003],{"className":291,"code":2002,"language":293,"meta":180,"style":180},"cd site\nnpm install\nnpm run dev      # 启动在 http:\u002F\u002Flocalhost:3001\n",[72,2004,2005,2012,2018],{"__ignoreMap":180},[214,2006,2007,2009],{"class":216,"line":217},[214,2008,301],{"class":300},[214,2010,2011],{"class":238}," site\n",[214,2013,2014,2016],{"class":216,"line":307},[214,2015,311],{"class":310},[214,2017,314],{"class":238},[214,2019,2020,2022,2024,2027],{"class":216,"line":317},[214,2021,311],{"class":310},[214,2023,322],{"class":238},[214,2025,2026],{"class":238}," dev",[214,2028,2029],{"class":1600},"      # 启动在 http:\u002F\u002Flocalhost:3001\n",[187,2031,2033],{"id":2032},"_2-生成全站静态产物ssg","2. 生成全站静态产物（SSG）",[174,2035,2037],{"className":291,"code":2036,"language":293,"meta":180,"style":180},"cd site\nnpm run generate\n",[72,2038,2039,2045],{"__ignoreMap":180},[214,2040,2041,2043],{"class":216,"line":217},[214,2042,301],{"class":300},[214,2044,2011],{"class":238},[214,2046,2047,2049,2051],{"class":216,"line":307},[214,2048,311],{"class":310},[214,2050,322],{"class":238},[214,2052,2053],{"class":238}," generate\n",[15,2055,2056,2057,2060,2061,2064],{},"执行完成后，所有预渲染好的 HTML、CSS、JS 与内置 SQLite WASM 内容库将输出到 ",[72,2058,2059],{},"site\u002F.output\u002Fpublic","（以及软链 ",[72,2062,2063],{},"site\u002Fdist","）目录。",[187,2066,2068],{"id":2067},"_3-上传至-cdn-对象存储","3. 上传至 CDN \u002F 对象存储",[15,2070,2071,2072,2075],{},"只需将 ",[72,2073,2074],{},"site\u002F.output\u002Fpublic\u002F"," 目录下的全部文件上传至您的对象存储桶（Bucket）或 CDN 源站目录：",[344,2077,2078,2084,2090],{},[199,2079,2080,2081],{},"默认首页设置为：",[72,2082,2083],{},"index.html",[199,2085,2086,2087],{},"404 错误页设置为：",[72,2088,2089],{},"404.html",[199,2091,2092,2093,2096,2097,2100,2101,2104,2105,673],{},"建议对 ",[72,2094,2095],{},"\u002F_nuxt\u002F*"," 静态带哈希资源配置长期强缓存（",[72,2098,2099],{},"Cache-Control: public, max-age=31536000, immutable","），对 ",[72,2102,2103],{},"*.html"," 页面配置协商缓存（",[72,2106,2107],{},"Cache-Control: no-cache",[364,2109,2110],{},"html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .soiBB, html code.shiki .soiBB{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .s0vBq, html code.shiki .s0vBq{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .sSJ72, html code.shiki .sSJ72{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .s_k96, html code.shiki .s_k96{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sF_wb, html code.shiki .sF_wb{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .sFfmW, html code.shiki .sFfmW{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .sG-J9, html code.shiki .sG-J9{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sUkpR, html code.shiki .sUkpR{--shiki-light:#6182B8;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}",{"title":180,"searchDepth":317,"depth":317,"links":2112},[2113,2116,2120],{"id":1737,"depth":307,"text":1737,"children":2114},[2115],{"id":1831,"depth":317,"text":1831},{"id":1891,"depth":307,"text":1892,"children":2117},[2118,2119],{"id":1895,"depth":317,"text":1896},{"id":1947,"depth":317,"text":1948},{"id":1982,"depth":307,"text":2121,"children":2122},"官网静态化打包与 CDN 托管 (site\u002F)",[2123,2124,2125],{"id":1998,"depth":317,"text":1999},{"id":2032,"depth":317,"text":2033},{"id":2067,"depth":317,"text":2068},"涵盖容器无损升级、PostgreSQL 备份恢复、JVM 内存调优以及官网全站静态化 CDN 托管指南。","i-lucide-server-cog",{},"\u002Fdocs\u002Foperations",{"title":1732,"description":2126},"docs\u002Foperations","KDcspzR6hC6bF_CJx_aP1cPyXCUyVhjcIxzfeIPXYiQ",{"id":873,"title":874,"body":2134,"category":864,"description":1133,"extension":381,"icon":1134,"meta":2311,"navigation":384,"order":317,"path":1136,"seo":2312,"stem":1138,"updatedAt":388,"__hash__":1139},{"type":8,"value":2135,"toc":2304},[2136,2138,2144,2160,2162,2216,2218,2244,2246,2254,2256,2270,2272,2284],[11,2137,880],{"id":879},[15,2139,883,2140,886,2142,890],{},[18,2141,259],{},[18,2143,889],{},[344,2145,2146,2152],{},[199,2147,2148,351,2150],{},[18,2149,897],{},[72,2151,900],{},[199,2153,2154,351,2156,909,2158],{},[18,2155,905],{},[72,2157,908],{},[72,2159,912],{},[11,2161,915],{"id":915},[40,2163,2164,2174],{},[43,2165,2166],{},[46,2167,2168,2170,2172],{},[49,2169,421],{},[49,2171,926],{},[49,2173,929],{},[59,2175,2176,2192,2204],{},[46,2177,2178,2182,2186],{},[64,2179,2180],{},[18,2181,938],{},[64,2183,2184],{},[72,2185,943],{},[64,2187,946,2188,950,2190,954],{},[72,2189,949],{},[72,2191,953],{},[46,2193,2194,2198,2202],{},[64,2195,2196],{},[18,2197,961],{},[64,2199,2200],{},[72,2201,966],{},[64,2203,969],{},[46,2205,2206,2210,2214],{},[64,2207,2208],{},[18,2209,976],{},[64,2211,2212],{},[72,2213,981],{},[64,2215,984],{},[11,2217,987],{"id":987},[344,2219,2220,2226,2238],{},[199,2221,2222,995,2224,999],{},[18,2223,994],{},[72,2225,998],{},[199,2227,2228,1005,2230,1009,2232,1013,2234,842,2236,673],{},[18,2229,1004],{},[72,2231,1008],{},[72,2233,1012],{},[72,2235,1016],{},[72,2237,1019],{},[199,2239,2240,1025,2242,1029],{},[18,2241,1024],{},[72,2243,1028],{},[11,2245,1033],{"id":1032},[156,2247,2248],{},[15,2249,2250,1041,2252,1045],{},[18,2251,1040],{},[72,2253,1044],{},[15,2255,1048],{},[344,2257,2258,2264],{},[199,2259,2260,1056,2262,1060],{},[18,2261,1055],{},[72,2263,1059],{},[199,2265,2266,1066,2268,1070],{},[18,2267,1065],{},[72,2269,1069],{},[11,2271,1073],{"id":1073},[15,2273,2274,1078,2276,1082,2278,1086,2280,1090,2282,1094],{},[72,2275,966],{},[72,2277,1081],{},[18,2279,1085],{},[72,2281,1089],{},[72,2283,1093],{},[344,2285,2286,2296],{},[199,2287,2288,1102,2290,1106,2292,1110,2294,673],{},[18,2289,1101],{},[72,2291,1105],{},[72,2293,1109],{},[72,2295,1113],{},[199,2297,2298,1119,2300,1122,2302,29],{},[18,2299,1118],{},[72,2301,193],{},[72,2303,1125],{},{"title":180,"searchDepth":317,"depth":317,"links":2305},[2306,2307,2308,2309,2310],{"id":879,"depth":307,"text":880},{"id":915,"depth":307,"text":915},{"id":987,"depth":307,"text":987},{"id":1032,"depth":307,"text":1033},{"id":1073,"depth":307,"text":1073},{},{"title":874,"description":1133},1793095990353]