neo-cmp-cli 1.13.1 → 1.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index2.js +1 -1
- package/dist/module/neoInitByCopy.js +1 -1
- package/dist/neo/env.js +1 -1
- package/dist/neo/neoService.js +1 -1
- package/dist/package.json.js +1 -1
- package/dist/utils/projectUtils/getEntries.js +1 -1
- package/docs/Web/347/253/257 NeoEntityGrid /344/275/277/347/224/250/350/257/264/346/230/216.md" +4 -0
- package/package.json +1 -1
- package/template/antd-custom-cmp-template/package.json +1 -1
- package/template/asset-manage-template/package.json +2 -2
- package/template/echarts-custom-cmp-template/package.json +1 -1
- package/template/empty-custom-cmp-template/package.json +1 -1
- package/template/map-custom-cmp-template/package.json +1 -1
- package/template/neo-bi-cmps/.npmrc copy +1 -0
- package/template/neo-bi-cmps/package.json +1 -1
- package/template/neo-custom-cmp-template/package.json +1 -1
- package/template/neo-custom-cmp-template/src/components/entityTable__c/index.tsx +2 -1
- package/template/neo-h5-cmps/package.json +1 -1
- package/template/neo-order-cmps/package.json +1 -1
- package/template/{neo-web-cmps → neo-web-entity-grid}/neo.config.js +4 -0
- package/template/{neo-web-cmps → neo-web-entity-grid}/package.json +2 -2
- package/template/neo-web-entity-grid/src/components/createForm__c/README.md +176 -0
- package/template/neo-web-entity-grid/src/components/createForm__c/index.tsx +786 -0
- package/template/neo-web-entity-grid/src/components/createForm__c/model.ts +130 -0
- package/template/neo-web-entity-grid/src/components/createForm__c/style.scss +370 -0
- package/template/neo-web-entity-grid/src/components/entityGrid2__c/index.tsx +139 -0
- package/template/{neo-web-cmps/src/components/entityGrid4__c → neo-web-entity-grid/src/components/entityGrid2__c}/model.ts +20 -3
- package/template/{neo-web-cmps/src/components/entityGrid4__c → neo-web-entity-grid/src/components/entityGrid2__c}/style.scss +1 -1
- package/template/{neo-web-cmps → neo-web-entity-grid}/src/components/entityGrid3__c/index.tsx +17 -6
- package/template/{neo-web-cmps → neo-web-entity-grid}/src/components/entityGrid3__c/model.ts +3 -2
- package/template/{neo-web-cmps → neo-web-entity-grid}/src/components/entityGrid4__c/index.tsx +57 -8
- package/template/{neo-web-cmps/src/components/entityGrid2__c → neo-web-entity-grid/src/components/entityGrid4__c}/style.scss +9 -13
- package/template/{neo-web-cmps/src/components/entityGrid2__c → neo-web-entity-grid/src/components/entityGrid__c}/index.tsx +6 -4
- package/template/{neo-web-cmps → neo-web-entity-grid}/src/components/entityGrid__c/model.ts +1 -1
- package/template/neo-web-entity-grid/src/components/searchForm__c/README.md +144 -0
- package/template/neo-web-entity-grid/src/components/searchForm__c/index.tsx +667 -0
- package/template/neo-web-entity-grid/src/components/searchForm__c/model.ts +135 -0
- package/template/neo-web-entity-grid/src/components/searchForm__c/style.scss +370 -0
- package/template/react-custom-cmp-template/package.json +1 -1
- package/template/react-ts-custom-cmp-template/package.json +1 -1
- package/template/vue2-custom-cmp-template/package.json +1 -1
- package/template/neo-web-cmps/src/components/entityGrid__c/index.tsx +0 -77
- /package/template/{neo-web-cmps → neo-web-entity-grid}/.prettierrc.js +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/@types/neo-ui-common.d.ts +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/README.md +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/commitlint.config.js +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/public/css/base.css +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/public/scripts/app/bluebird.js +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/public/template.html +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/css/common.scss +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/css/mixin.scss +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/AIBtn.gif +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/NeoCRM.jpg +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/aiLogo.png +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/card-list.svg +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/contact-form.svg +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/custom-form.svg +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/custom-widget.svg +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/data-list.svg +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/detail.svg +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/favicon.png +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/map.svg +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/search.svg +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/assets/img/table.svg +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/components/entityGrid3__c/style.scss +0 -0
- /package/template/{neo-web-cmps/src/components/entityGrid2__c → neo-web-entity-grid/src/components/entityGrid4__c}/model.ts +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/components/entityGrid__c/style.scss +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/utils/axiosFetcher.ts +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/utils/queryObjectData.ts +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/src/utils/xobjects.ts +0 -0
- /package/template/{neo-web-cmps → neo-web-entity-grid}/tsconfig.json +0 -0
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ neo-cmp-cli 是 Neo 自定义组件开发工具,基于 [AKFun](https://github.
|
|
|
29
29
|
|
|
30
30
|
| 模板类型 | 说明 | 参考仓库 |
|
|
31
31
|
|-------------|------|----------|
|
|
32
|
-
| `neo-web-
|
|
32
|
+
| `neo-web-entity-grid` | Web 端列表组件模板:含基础大列表、Picker 列表等示例组件 | (随 CLI 内置) |
|
|
33
33
|
| `neo-h5-cmps` | H5 端业务组件模板:含全局搜索、数据列表、数据 Tabs、打开 AI 对话页等示例组件 | [neo-h5-cmps](https://github.com/wibetter/neo-h5-cmps) |
|
|
34
34
|
| `neo` | 自定义业务组件模板:含实体表单、实体数据详情、实体数据表格等示例组件 | [neo-custom-cmp-template](https://github.com/wibetter/neo-custom-cmp-template) |
|
|
35
35
|
| `neo-bi-cmps` | 数值指标组件模板: 可配置展示实体数据源中关键数值指标 | [neo-bi-cmps](https://github.com/xsy-neoui/neo-bi-cmps) |
|
|
@@ -41,7 +41,7 @@ neo-cmp-cli 是 Neo 自定义组件开发工具,基于 [AKFun](https://github.
|
|
|
41
41
|
**非交互创建示例**(需同时提供 `-t` 与 `-n`):
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
neo init -t neo-web-
|
|
44
|
+
neo init -t neo-web-entity-grid -n myWebListCmp
|
|
45
45
|
neo init -t neo-h5-cmps -n myH5Cmp
|
|
46
46
|
neo init -t neo -n myNeoBizCmp
|
|
47
47
|
neo init -t antd -n myAntdCmp
|
package/dist/index2.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./_virtual/index.js"),s=require("figlet"),o=require("yargs"),a=require("chalk"),n=require("inquirer"),t=require("ora"),c=require("./main2.js"),i=require("./utils/common.js"),p=require("./neo/env.js"),m=require("./package.json.js");var l;exports.__require=function(){if(l)return e.__exports;l=1;const r=s,u=o,g=a,d=n,h=t,{neoInit:y,neoInitByCopy:v,inspect:b,neoConfigInit:C,validateProjectName:f,getCmpTypeByDir:$,NeoService:x,NeoLoginService:T,hasNeoProject:w,consoleTag:j}=c.__require(),{errorLog:U,successLog:D,warningLog:L}=i.__require(),_=c.__require(),{getNeoCrmAPI:q}=p.__require(),M=m.default,N=r.textSync("neo",{font:"Lean"}),A=_.projectConfig,S=function(e){return g.green(g.bold(e))},R={"config init":"初始化配置文件",config:"初始化配置文件",dev:"开启本地调试模式",build:"构建生产环境代码",build2lib:"构建 UMD 模块",build2esm:"构建 ESM 模块",publish2oss:"发布到 OSS",inspect:"输出配置文件",open:"打开项目"},k={...R,init:"初始化自定义组件项目",login:"登录 NeoCRM 平台",logout:"登出 NeoCRM 平台","create project":"创建自定义组件项目","create cmp":"创建自定义组件",linkDebug:"开启外链调试模式",preview:"预览自定义组件","pull cmp":"拉取线上自定义组件","push cmp":"发布自定义组件到平台","delete cmp":"删除线上自定义组件",pull:"拉取线上自定义组件",push:"发布自定义组件到平台",delete:"删除线上自定义组件"};return u.middleware(function(e){if(e.help||e.version)return;const s=function(e){if(!e._||0===e._.length)return"";const s=e._.join(" ");if(k[s])return s;const o=e._[0];return k[o]?o:s||o}(e);if(!s)return;const o=k[s]||s;R[s]&&(console.log(g.green(N)),console.log(g.green(`当前版本:v${M.version}.\n`))),console.log(""),console.log(g.cyan(`执行命令: ${o}`)),console.log("")}).command("init [options]","根据模板创建一个自定义组件",e=>{e.usage(S("Usage")+": $0 init [options]").option("type",{alias:"t",describe:"自定义组件类型(react ts 技术栈/ vue2.0 技术栈/ react 技术栈)"}).option("name",{alias:"n",describe:"自定义组件项目名称"}).alias("h","help")},e=>{if(e.type&&e.name)w()&&(U(`${j}创建自定义组件失败,当前目录(${process.cwd()})已经是一个自定义组件项目,请勿重复创建。`),process.exit(1)),"github"===e.mode?y(e.type,e.name):v(e.type,e.name);else{const s=[],o=[{name:"模板1.Web端列表组件: 含基础大列表、Picker 列表等示例组件",value:"neo-web-cmps",short:"neo-web-cmps"},{name:"模板2.H5端业务组件: 含全局搜索、数据列表、数据Tabs、打开AI对话页等示例组件",value:"neo-h5-cmps",short:"neo-h5-cmps"},{name:"模板3.自定义业务组件: 含实体表单、实体数据详情、实体数据表格等示例组件",value:"neo",short:"neo"},{name:"模板4.数值指标组件: 可配置展示实体数据源中关键数值指标",value:"neo-bi-cmps",short:"neo-bi-cmps"},{name:"模板5.antd 组件: 含基于 Antd 实现的数据仪表板、搜索组件等示例组件",value:"antd",short:"antd"},{name:"模板6.echarts 组件: 含基于 ECharts 实现的图表示例组件",value:"echarts",short:"echarts"},{name:"模板7.地图组件: 含基于 高德地图API 实现的示例组件",value:"amap",short:"amap"},{name:"模板8.vue2 组件: 含基于 Vue2 实现的示例组件",value:"vue2",short:"vue2"}];e.type||s.push({name:"type",type:"list",message:"请选择您要创建的自定义组件类型: ",default:"react-ts",choices:o}),e.name||s.push({name:"name",type:"input",message:"请设置自定义组件项目名称(默认 neoCustomCmp):",default:"neoCustomCmp"}),d.prompt(s).then(s=>{const{isValid:o,errors:a}=f(s.name);o||(U(a.join("\n")),process.exit(1)),"github"===e.mode?y(s.type,s.name):v(s.type,s.name)})}}).command("config init","创建 neo.config.js 配置文件",e=>{e.usage(S("Usage")+": $0 config init").alias("h","help")},()=>{C("neo.config.js")}).command("login","登录 NeoCRM 平台(OAuth2 授权)",e=>{e.usage(S("Usage")+": $0 login").alias("h","help")},()=>{const e=[{name:"env",type:"list",message:"请选择您要登录的环境:",default:"cd",choices:[{name:"线上生产环境(crm.xiaoshouyi.com)",value:"production"},{name:"灰度环境(crm-gray.xiaoshouyi.com)",value:"gray"},{name:"沙盒环境(crm-sandbox.xiaoshouyi.com)",value:"sandbox"},{name:"开发环境(crm-cd.xiaoshouyi.com)",value:"cd"},{name:"tencentuat环境(crm-tencentuat.xiaoshouyi.com)",value:"tencentuat"},{name:"自定义环境(在neo.config.js / neoConfig 中自行配置)",value:"custom"}]}];d.prompt(e).then(async e=>{const s=q(e.env,A.neoConfig);try{const e=new T(s);await e.login(),process.exit(0)}catch(e){U(`\n登录失败: ${e.message||e.msg}`),process.exit(1)}})}).command("logout","登出 NeoCRM 平台",e=>{e.usage(S("Usage")+": $0 logout").alias("h","help")},async()=>{try{const e=new T;await e.logout(),process.exit(0)}catch(e){U(`\n登出失败: ${e.message||e.msg}`),process.exit(1)}}).command("create","创建项目或者组件",e=>e.command("project [options]","创建自定义组件项目(含工程代码)",e=>{e.usage(S("Usage")+": $0 project [options]").option("name",{alias:"n",describe:"自定义组件项目名称"}).alias("h","help")},e=>{if(e.name)_.createCmpProjectByTemplate(e.name);else{const e=[{name:"name",type:"input",message:"请设置自定义组件项目名称:"}];d.prompt(e).then(e=>{const{isValid:s,errors:o}=f(e.name);s||(U(o.join("\n")),process.exit(1)),e.name?_.createCmpProjectByTemplate(e.name):(U("自定义组件项目名称不能为空。"),process.exit(1))})}}).command("cmp [options]","创建自定义组件",e=>{e.usage(S("Usage")+": $0 cmp [options]").option("name",{alias:"n",describe:"自定义组件名称"}).option("targetDevice",{alias:"d",describe:"终端类型(all: 所有端, web: 网页端, mobile: 移动端),不指定则交互选择",choices:["all","web","mobile"]}).alias("h","help")},e=>{const s=[{name:"所有端(all)",value:"all"},{name:"网页端(web)",value:"web"},{name:"移动端(mobile)",value:"mobile"}];if(e.name&&void 0!==e.targetDevice)_.createCmpByTemplate(e.name,{targetDevice:e.targetDevice});else if(e.name){const o=[{name:"targetDevice",type:"list",message:"请选择终端类型:",default:"all",choices:s}];d.prompt(o).then(s=>{_.createCmpByTemplate(e.name,{targetDevice:s.targetDevice})})}else{const e=[{name:"name",type:"input",message:"请设置自定义组件名称:"},{name:"targetDevice",type:"list",message:"请选择终端类型:",default:"all",choices:s}];d.prompt(e).then(e=>{e.name?_.createCmpByTemplate(e.name,{targetDevice:e.targetDevice}):(U("自定义组件名称不能为空。"),process.exit(1))})}})).command("pull cmp [options]","拉取线上自定义组件",e=>{e.usage(S("Usage")+": $0 pull cmp [options]").option("name",{alias:"n",describe:"自定义组件名称"}).alias("h","help")},async e=>{if(e.name){L(`[neo pull cmp] 即将拉取自定义组件:${e.name},如本地已存在同名组件目录,将可能被覆盖,请提前备份本地修改。`);try{await _.pullCmp(e.name)}catch(e){U(e.message||e.msg||"拉取线上自定义组件失败"),process.exit(1)}}else{const e=new x,s=h("正在拉取线上自定义组件列表...").start(),o=await e.getCustomCmpList();0===o.length&&(U("当前租户暂无任何自定义组件。"),process.exit(1)),s.stop("线上自定义组件列表拉取成功。");const a=[{name:"cmpType",type:"list",message:"请选择要拉取的自定义组件:",choices:[{name:"拉取所有组件(ALL)",value:"ALL"},...o.map(e=>({name:`${e.label}(${e.cmpType})`,value:e.cmpType}))]}];try{const s=await d.prompt(a);if(s.cmpType)if("ALL"===s.cmpType){L(`[neo pull cmp] 即将拉取当前租户下的所有自定义组件(共 ${o.length} 个),如本地存在同名组件目录,将可能被覆盖,请提前备份本地修改。`);for(let s=0,a=o.length;s<a;s++){const n=o[s];console.log(g.gray(`[neo pull cmp] 正在拉取第 ${s+1}/${a} 个组件: ${n.cmpType}`)),await _.pullCmp(n.cmpType,e)}D("[neo pull cmp]拉取所有组件命令已执行完成。")}else L(`[neo pull cmp] 即将拉取自定义组件:${s.cmpType},如本地已存在同名组件目录,将可能被覆盖,请提前备份本地修改。`),await _.pullCmp(s.cmpType,e);else U("请选择要拉取的自定义组件。"),process.exit(1)}catch(e){U(e.message||e.msg||"拉取线上自定义组件失败"),process.exit(1)}}}).command("delete cmp [options]","删除线上自定义组件",e=>{e.usage(S("Usage")+": $0 delete cmp [options]").option("name",{alias:"n",describe:"自定义组件名称"}).alias("h","help")},async e=>{if(e.name)_.deleteCmp(e.name);else{const e=new x,s=h("正在获取线上自定义组件列表...").start(),o=await e.getCustomCmpList();0===o.length&&(U("当前租户暂无任何自定义组件。"),process.exit(1)),s.stop("线上自定义组件列表获取成功。");const a=[{name:"cmpType",type:"list",message:"请选择要删除的自定义组件:",choices:o.map(e=>({name:`${e.label}(${e.cmpType})`,value:e.cmpType}))}];d.prompt(a).then(s=>{s.cmpType?_.deleteCmp(s.cmpType,e):(U("自定义组件名称不能为空。"),process.exit(1))})}}).command("preview [options]","预览指定自定义组件(仅预览组件本身内容)",e=>{e.usage(S("Usage")+": $0 preview [options]").option("name",{alias:"n",describe:"自定义组件名称"}).alias("h","help")},e=>{if(e.name)_.previewCmp(e.name);else{const e=$(A.componentsDir);0===e.length&&(U("当前自定义组件目录中未找到自定义组件。(./src/components 目录下)"),process.exit(1));const s=[{name:"cmpType",type:"list",message:"请选择要预览的自定义组件:",choices:e.map(e=>({name:e,value:e}))}];d.prompt(s).then(e=>{e.cmpType||(U("未选择要预览的自定义组件。"),process.exit(1)),_.previewCmp(e.cmpType)})}}).command("dev","开启本地调试模式",e=>{e.usage(S("Usage")+": $0 dev").alias("h","help")},()=>{_.dev()}).command("linkDebug","开启外链调试模式(在线上页面设计器端调试)",e=>{e.usage(S("Usage")+": $0 linkDebug").alias("h","help")},e=>{_.linkDebug()}).command("build","构建生产环境代码",e=>{e.usage(S("Usage")+": $0 build").alias("h","help")},e=>{_.build()}).command("build2lib","构建 UMD 模块",e=>{e.usage(S("Usage")+": $0 build2lib").alias("h","help")},e=>{_.build2lib()}).command("publish2oss [options]","发布到oss",e=>{e.usage(S("Usage")+": $0 publish2oss [options]").option("name",{alias:"n",describe:"自定义组件名称"}).alias("h","help")},e=>{if(e.name)_.publish2oss(e.name);else{const e=$(A.componentsDir);0===e.length&&(U("当前自定义组件目录中未找到自定义组件。(./src/components 目录下)"),process.exit(1));const s=[{name:"cmpType",type:"list",message:"请选择要发布的自定义组件:",choices:e.map(e=>({name:e,value:e}))}];d.prompt(s).then(e=>{e.cmpType||(U("未选择要发布的自定义组件。"),process.exit(1)),_.publish2oss(e.cmpType)})}}).command("push cmp [options]","构建并发布自定义组件到 NeoCRM 平台",e=>{e.usage(S("Usage")+": $0 push cmp [options]").option("name",{alias:"n",describe:"自定义组件名称"}).alias("h","help")},async e=>{if(e.name){L(`[neo push cmp] 即将构建并发布自定义组件:${e.name} 到 NeoCRM 平台,请确保已经通过 neo login 登录到正确的环境。`);try{await _.pushCmp(e.name)}catch(e){U(e.message||e.msg||"发布自定义组件失败"),process.exit(1)}}else{const e=$(A.componentsDir);0===e.length&&(U("当前自定义组件目录中未找到自定义组件。(./src/components 目录下)"),process.exit(1));const s=[{name:"cmpType",type:"list",message:"请选择要发布的自定义组件:",choices:[{name:"发布所有组件(ALL)",value:"ALL"},...e.map(e=>({name:e,value:e}))]}];d.prompt(s).then(async s=>{s.cmpType||(U("请选择要发布的自定义组件。"),process.exit(1));try{if("ALL"===s.cmpType){L(`[neo push cmp] 即将构建并发布当前目录下的所有自定义组件(共 ${e.length} 个)到 NeoCRM 平台,请确保已经通过 neo login 登录到正确的环境。`);for(let s=0,o=e.length;s<o;s++){const a=e[s];console.log(g.gray(`[neo push cmp] 正在拉取第 ${s+1}/${o} 个组件: ${a}`)),await _.pushCmp(a,!0)}D("[neo push cmp]发布所有组件命令已执行完成。")}else L(`[neo push cmp] 即将构建并发布自定义组件:${s.cmpType} 到 NeoCRM 平台,请确保已经通过 neo login 登录到正确的环境。`),await _.pushCmp(s.cmpType)}catch(e){U(e.message||e.msg||"发布失败"),process.exit(1)}})}}).command("build2esm","构建 ESM 模块",e=>{e.usage(S("Usage")+": $0 build2esm").alias("h","help")},()=>{_.build2esm()}).command("inspect","输出当前配置文件",e=>{e.usage(S("Usage")+": $0 inspect").option("type",{alias:"t",describe:"环境类型(本地调试环境/生产环境/library构建环境)",default:"build"}).alias("h","help")},e=>{b(e.type)}).command("open [options]","使用 Cursor 或 VSCode 打开项目",e=>{e.usage(S("Usage")+": $0 open [options]").option("editor",{alias:"e",describe:"编辑器类型(cursor/vscode/auto),默认为 auto(自动检测)",default:"auto",choices:["cursor","vscode","code","auto"]}).option("name",{alias:"n",describe:"要打开的项目名称,默认为当前目录"}).alias("h","help")},e=>{_.openEditor(e.editor,e.name)}).alias("h","help").alias("v","version").strict().fail((e,s,o)=>{U(`\n运行命令时发生错误: ${e}。\n`),console.log(S("当前可用命令列表:")),console.log("");[{cmd:"init [options]",desc:"根据模板创建一个自定义组件"},{cmd:"create project [options]",desc:"创建自定义组件项目(含工程代码)"},{cmd:"create cmp [options]",desc:"创建自定义组件"},{cmd:"preview [options]",desc:"预览指定自定义组件(仅预览组件本身内容)"},{cmd:"linkDebug",desc:"开启外链调试模式(在线上页面设计器端调试)"},{cmd:"login",desc:"登录 NeoCRM 平台(OAuth2 授权)"},{cmd:"logout",desc:"登出 NeoCRM 平台"},{cmd:"pull cmp [options]",desc:"拉取线上自定义组件"},{cmd:"delete cmp [options]",desc:"删除线上自定义组件"},{cmd:"push cmp [options]",desc:"构建并发布自定义组件到 NeoCRM 平台"},{cmd:"open [options]",desc:"使用 Cursor 或 VSCode 打开项目"}].forEach(({cmd:e,desc:s})=>{console.log(` ${g.cyan(e.padEnd(25))} ${s}`)}),console.log(""),console.log(`使用 ${g.cyan("neo <command> --help")} 查看具体命令的帮助信息。`),console.log(""),process.exit(1)}).help().updateStrings({"Usage:":S("Usage:"),"Commands:":S("Commands:"),"Options:":S("Options:")}).parseAsync().catch(e=>{e&&(U(`\n运行命令时发生错误: ${e.message||e}。\n`),process.exit(1))}),e.__exports};
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./_virtual/index.js"),s=require("figlet"),o=require("yargs"),a=require("chalk"),n=require("inquirer"),t=require("ora"),i=require("./main2.js"),c=require("./utils/common.js"),p=require("./neo/env.js"),m=require("./package.json.js");var l;exports.__require=function(){if(l)return e.__exports;l=1;const r=s,u=o,g=a,d=n,h=t,{neoInit:y,neoInitByCopy:v,inspect:b,neoConfigInit:C,validateProjectName:f,getCmpTypeByDir:$,NeoService:x,NeoLoginService:T,hasNeoProject:w,consoleTag:j}=i.__require(),{errorLog:U,successLog:D,warningLog:L}=c.__require(),_=i.__require(),{getNeoCrmAPI:q}=p.__require(),M=m.default,N=r.textSync("neo",{font:"Lean"}),A=_.projectConfig,S=function(e){return g.green(g.bold(e))},R={"config init":"初始化配置文件",config:"初始化配置文件",dev:"开启本地调试模式",build:"构建生产环境代码",build2lib:"构建 UMD 模块",build2esm:"构建 ESM 模块",publish2oss:"发布到 OSS",inspect:"输出配置文件",open:"打开项目"},k={...R,init:"初始化自定义组件项目",login:"登录 NeoCRM 平台",logout:"登出 NeoCRM 平台","create project":"创建自定义组件项目","create cmp":"创建自定义组件",linkDebug:"开启外链调试模式",preview:"预览自定义组件","pull cmp":"拉取线上自定义组件","push cmp":"发布自定义组件到平台","delete cmp":"删除线上自定义组件",pull:"拉取线上自定义组件",push:"发布自定义组件到平台",delete:"删除线上自定义组件"};return u.middleware(function(e){if(e.help||e.version)return;const s=function(e){if(!e._||0===e._.length)return"";const s=e._.join(" ");if(k[s])return s;const o=e._[0];return k[o]?o:s||o}(e);if(!s)return;const o=k[s]||s;R[s]&&(console.log(g.green(N)),console.log(g.green(`当前版本:v${M.version}.\n`))),console.log(""),console.log(g.cyan(`执行命令: ${o}`)),console.log("")}).command("init [options]","根据模板创建一个自定义组件",e=>{e.usage(S("Usage")+": $0 init [options]").option("type",{alias:"t",describe:"自定义组件类型(react ts 技术栈/ vue2.0 技术栈/ react 技术栈)"}).option("name",{alias:"n",describe:"自定义组件项目名称"}).alias("h","help")},e=>{if(e.type&&e.name)w()&&(U(`${j}创建自定义组件失败,当前目录(${process.cwd()})已经是一个自定义组件项目,请勿重复创建。`),process.exit(1)),"github"===e.mode?y(e.type,e.name):v(e.type,e.name);else{const s=[],o=[{name:"模板1.Web端列表组件: 含基础大列表、Picker 列表等示例组件",value:"neo-web-entity-grid",short:"neo-web-entity-grid"},{name:"模板2.H5端业务组件: 含全局搜索、数据列表、数据Tabs、打开AI对话页等示例组件",value:"neo-h5-cmps",short:"neo-h5-cmps"},{name:"模板3.自定义业务组件: 含实体表单、实体数据详情、实体数据表格等示例组件",value:"neo",short:"neo"},{name:"模板4.数值指标组件: 可配置展示实体数据源中关键数值指标",value:"neo-bi-cmps",short:"neo-bi-cmps"},{name:"模板5.antd 组件: 含基于 Antd 实现的数据仪表板、搜索组件等示例组件",value:"antd",short:"antd"},{name:"模板6.echarts 组件: 含基于 ECharts 实现的图表示例组件",value:"echarts",short:"echarts"},{name:"模板7.地图组件: 含基于 高德地图API 实现的示例组件",value:"amap",short:"amap"},{name:"模板8.vue2 组件: 含基于 Vue2 实现的示例组件",value:"vue2",short:"vue2"}];e.type||s.push({name:"type",type:"list",message:"请选择您要创建的自定义组件类型: ",default:"react-ts",choices:o}),e.name||s.push({name:"name",type:"input",message:"请设置自定义组件项目名称(默认 neoCustomCmp):",default:"neoCustomCmp"}),d.prompt(s).then(s=>{const{isValid:o,errors:a}=f(s.name);o||(U(a.join("\n")),process.exit(1)),"github"===e.mode?y(s.type,s.name):v(s.type,s.name)})}}).command("config init","创建 neo.config.js 配置文件",e=>{e.usage(S("Usage")+": $0 config init").alias("h","help")},()=>{C("neo.config.js")}).command("login","登录 NeoCRM 平台(OAuth2 授权)",e=>{e.usage(S("Usage")+": $0 login").alias("h","help")},()=>{const e=[{name:"env",type:"list",message:"请选择您要登录的环境:",default:"cd",choices:[{name:"线上生产环境(crm.xiaoshouyi.com)",value:"production"},{name:"灰度环境(crm-gray.xiaoshouyi.com)",value:"gray"},{name:"沙盒环境(crm-sandbox.xiaoshouyi.com)",value:"sandbox"},{name:"开发环境(crm-cd.xiaoshouyi.com)",value:"cd"},{name:"tencentuat环境(crm-tencentuat.xiaoshouyi.com)",value:"tencentuat"},{name:"自定义环境(在neo.config.js / neoConfig 中自行配置)",value:"custom"}]}];d.prompt(e).then(async e=>{const s=q(e.env,A.neoConfig);try{const e=new T(s);await e.login(),process.exit(0)}catch(e){U(`\n登录失败: ${e.message||e.msg}`),process.exit(1)}})}).command("logout","登出 NeoCRM 平台",e=>{e.usage(S("Usage")+": $0 logout").alias("h","help")},async()=>{try{const e=new T;await e.logout(),process.exit(0)}catch(e){U(`\n登出失败: ${e.message||e.msg}`),process.exit(1)}}).command("create","创建项目或者组件",e=>e.command("project [options]","创建自定义组件项目(含工程代码)",e=>{e.usage(S("Usage")+": $0 project [options]").option("name",{alias:"n",describe:"自定义组件项目名称"}).alias("h","help")},e=>{if(e.name)_.createCmpProjectByTemplate(e.name);else{const e=[{name:"name",type:"input",message:"请设置自定义组件项目名称:"}];d.prompt(e).then(e=>{const{isValid:s,errors:o}=f(e.name);s||(U(o.join("\n")),process.exit(1)),e.name?_.createCmpProjectByTemplate(e.name):(U("自定义组件项目名称不能为空。"),process.exit(1))})}}).command("cmp [options]","创建自定义组件",e=>{e.usage(S("Usage")+": $0 cmp [options]").option("name",{alias:"n",describe:"自定义组件名称"}).option("targetDevice",{alias:"d",describe:"终端类型(all: 所有端, web: 网页端, mobile: 移动端),不指定则交互选择",choices:["all","web","mobile"]}).alias("h","help")},e=>{const s=[{name:"所有端(all)",value:"all"},{name:"网页端(web)",value:"web"},{name:"移动端(mobile)",value:"mobile"}];if(e.name&&void 0!==e.targetDevice)_.createCmpByTemplate(e.name,{targetDevice:e.targetDevice});else if(e.name){const o=[{name:"targetDevice",type:"list",message:"请选择终端类型:",default:"all",choices:s}];d.prompt(o).then(s=>{_.createCmpByTemplate(e.name,{targetDevice:s.targetDevice})})}else{const e=[{name:"name",type:"input",message:"请设置自定义组件名称:"},{name:"targetDevice",type:"list",message:"请选择终端类型:",default:"all",choices:s}];d.prompt(e).then(e=>{e.name?_.createCmpByTemplate(e.name,{targetDevice:e.targetDevice}):(U("自定义组件名称不能为空。"),process.exit(1))})}})).command("pull cmp [options]","拉取线上自定义组件",e=>{e.usage(S("Usage")+": $0 pull cmp [options]").option("name",{alias:"n",describe:"自定义组件名称"}).alias("h","help")},async e=>{if(e.name){L(`[neo pull cmp] 即将拉取自定义组件:${e.name},如本地已存在同名组件目录,将可能被覆盖,请提前备份本地修改。`);try{await _.pullCmp(e.name)}catch(e){U(e.message||e.msg||"拉取线上自定义组件失败"),process.exit(1)}}else{const e=new x,s=h("正在拉取线上自定义组件列表...").start(),o=await e.getCustomCmpList();0===o.length&&(U("当前租户暂无任何自定义组件。"),process.exit(1)),s.stop("线上自定义组件列表拉取成功。");const a=[{name:"cmpType",type:"list",message:"请选择要拉取的自定义组件:",choices:[{name:"拉取所有组件(ALL)",value:"ALL"},...o.map(e=>({name:`${e.label}(${e.cmpType})`,value:e.cmpType}))]}];try{const s=await d.prompt(a);if(s.cmpType)if("ALL"===s.cmpType){L(`[neo pull cmp] 即将拉取当前租户下的所有自定义组件(共 ${o.length} 个),如本地存在同名组件目录,将可能被覆盖,请提前备份本地修改。`);for(let s=0,a=o.length;s<a;s++){const n=o[s];console.log(g.gray(`[neo pull cmp] 正在拉取第 ${s+1}/${a} 个组件: ${n.cmpType}`)),await _.pullCmp(n.cmpType,e)}D("[neo pull cmp]拉取所有组件命令已执行完成。")}else L(`[neo pull cmp] 即将拉取自定义组件:${s.cmpType},如本地已存在同名组件目录,将可能被覆盖,请提前备份本地修改。`),await _.pullCmp(s.cmpType,e);else U("请选择要拉取的自定义组件。"),process.exit(1)}catch(e){U(e.message||e.msg||"拉取线上自定义组件失败"),process.exit(1)}}}).command("delete cmp [options]","删除线上自定义组件",e=>{e.usage(S("Usage")+": $0 delete cmp [options]").option("name",{alias:"n",describe:"自定义组件名称"}).alias("h","help")},async e=>{if(e.name)_.deleteCmp(e.name);else{const e=new x,s=h("正在获取线上自定义组件列表...").start(),o=await e.getCustomCmpList();0===o.length&&(U("当前租户暂无任何自定义组件。"),process.exit(1)),s.stop("线上自定义组件列表获取成功。");const a=[{name:"cmpType",type:"list",message:"请选择要删除的自定义组件:",choices:o.map(e=>({name:`${e.label}(${e.cmpType})`,value:e.cmpType}))}];d.prompt(a).then(s=>{s.cmpType?_.deleteCmp(s.cmpType,e):(U("自定义组件名称不能为空。"),process.exit(1))})}}).command("preview [options]","预览指定自定义组件(仅预览组件本身内容)",e=>{e.usage(S("Usage")+": $0 preview [options]").option("name",{alias:"n",describe:"自定义组件名称"}).alias("h","help")},e=>{if(e.name)_.previewCmp(e.name);else{const e=$(A.componentsDir);0===e.length&&(U("当前自定义组件目录中未找到自定义组件。(./src/components 目录下)"),process.exit(1));const s=[{name:"cmpType",type:"list",message:"请选择要预览的自定义组件:",choices:e.map(e=>({name:e,value:e}))}];d.prompt(s).then(e=>{e.cmpType||(U("未选择要预览的自定义组件。"),process.exit(1)),_.previewCmp(e.cmpType)})}}).command("dev","开启本地调试模式",e=>{e.usage(S("Usage")+": $0 dev").alias("h","help")},()=>{_.dev()}).command("linkDebug","开启外链调试模式(在线上页面设计器端调试)",e=>{e.usage(S("Usage")+": $0 linkDebug").alias("h","help")},e=>{_.linkDebug()}).command("build","构建生产环境代码",e=>{e.usage(S("Usage")+": $0 build").alias("h","help")},e=>{_.build()}).command("build2lib","构建 UMD 模块",e=>{e.usage(S("Usage")+": $0 build2lib").alias("h","help")},e=>{_.build2lib()}).command("publish2oss [options]","发布到oss",e=>{e.usage(S("Usage")+": $0 publish2oss [options]").option("name",{alias:"n",describe:"自定义组件名称"}).alias("h","help")},e=>{if(e.name)_.publish2oss(e.name);else{const e=$(A.componentsDir);0===e.length&&(U("当前自定义组件目录中未找到自定义组件。(./src/components 目录下)"),process.exit(1));const s=[{name:"cmpType",type:"list",message:"请选择要发布的自定义组件:",choices:e.map(e=>({name:e,value:e}))}];d.prompt(s).then(e=>{e.cmpType||(U("未选择要发布的自定义组件。"),process.exit(1)),_.publish2oss(e.cmpType)})}}).command("push cmp [options]","构建并发布自定义组件到 NeoCRM 平台",e=>{e.usage(S("Usage")+": $0 push cmp [options]").option("name",{alias:"n",describe:"自定义组件名称"}).alias("h","help")},async e=>{if(e.name){L(`[neo push cmp] 即将构建并发布自定义组件:${e.name} 到 NeoCRM 平台,请确保已经通过 neo login 登录到正确的环境。`);try{await _.pushCmp(e.name)}catch(e){U(e.message||e.msg||"发布自定义组件失败"),process.exit(1)}}else{const e=$(A.componentsDir);0===e.length&&(U("当前自定义组件目录中未找到自定义组件。(./src/components 目录下)"),process.exit(1));const s=[{name:"cmpType",type:"list",message:"请选择要发布的自定义组件:",choices:[{name:"发布所有组件(ALL)",value:"ALL"},...e.map(e=>({name:e,value:e}))]}];d.prompt(s).then(async s=>{s.cmpType||(U("请选择要发布的自定义组件。"),process.exit(1));try{if("ALL"===s.cmpType){L(`[neo push cmp] 即将构建并发布当前目录下的所有自定义组件(共 ${e.length} 个)到 NeoCRM 平台,请确保已经通过 neo login 登录到正确的环境。`);for(let s=0,o=e.length;s<o;s++){const a=e[s];console.log(g.gray(`[neo push cmp] 正在拉取第 ${s+1}/${o} 个组件: ${a}`)),await _.pushCmp(a,!0)}D("[neo push cmp]发布所有组件命令已执行完成。")}else L(`[neo push cmp] 即将构建并发布自定义组件:${s.cmpType} 到 NeoCRM 平台,请确保已经通过 neo login 登录到正确的环境。`),await _.pushCmp(s.cmpType)}catch(e){U(e.message||e.msg||"发布失败"),process.exit(1)}})}}).command("build2esm","构建 ESM 模块",e=>{e.usage(S("Usage")+": $0 build2esm").alias("h","help")},()=>{_.build2esm()}).command("inspect","输出当前配置文件",e=>{e.usage(S("Usage")+": $0 inspect").option("type",{alias:"t",describe:"环境类型(本地调试环境/生产环境/library构建环境)",default:"build"}).alias("h","help")},e=>{b(e.type)}).command("open [options]","使用 Cursor 或 VSCode 打开项目",e=>{e.usage(S("Usage")+": $0 open [options]").option("editor",{alias:"e",describe:"编辑器类型(cursor/vscode/auto),默认为 auto(自动检测)",default:"auto",choices:["cursor","vscode","code","auto"]}).option("name",{alias:"n",describe:"要打开的项目名称,默认为当前目录"}).alias("h","help")},e=>{_.openEditor(e.editor,e.name)}).alias("h","help").alias("v","version").strict().fail((e,s,o)=>{U(`\n运行命令时发生错误: ${e}。\n`),console.log(S("当前可用命令列表:")),console.log("");[{cmd:"init [options]",desc:"根据模板创建一个自定义组件"},{cmd:"create project [options]",desc:"创建自定义组件项目(含工程代码)"},{cmd:"create cmp [options]",desc:"创建自定义组件"},{cmd:"preview [options]",desc:"预览指定自定义组件(仅预览组件本身内容)"},{cmd:"linkDebug",desc:"开启外链调试模式(在线上页面设计器端调试)"},{cmd:"login",desc:"登录 NeoCRM 平台(OAuth2 授权)"},{cmd:"logout",desc:"登出 NeoCRM 平台"},{cmd:"pull cmp [options]",desc:"拉取线上自定义组件"},{cmd:"delete cmp [options]",desc:"删除线上自定义组件"},{cmd:"push cmp [options]",desc:"构建并发布自定义组件到 NeoCRM 平台"},{cmd:"open [options]",desc:"使用 Cursor 或 VSCode 打开项目"}].forEach(({cmd:e,desc:s})=>{console.log(` ${g.cyan(e.padEnd(25))} ${s}`)}),console.log(""),console.log(`使用 ${g.cyan("neo <command> --help")} 查看具体命令的帮助信息。`),console.log(""),process.exit(1)}).help().updateStrings({"Usage:":S("Usage:"),"Commands:":S("Commands:"),"Options:":S("Options:")}).parseAsync().catch(e=>{e&&(U(`\n运行命令时发生错误: ${e.message||e}。\n`),process.exit(1))}),e.__exports};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("fs-extra"),t=require("node:path"),r=require("../utils/neoParams.js"),m=require("../utils/replaceInPackage.js"),a=require("../utils/resetPackageVersion.js"),o=require("../utils/autoEntryRootDir.js"),c=require("../utils/common.js");var p,s;exports.__require=function(){if(s)return p;s=1;const i=e,n=t,{consoleTag:l}=r.__require(),{replaceInPackage:u}=m.__require(),{resetPackageVersion:_}=a.__require(),d=o.__require(),{errorLog:j}=c.__require(),v={"neo-web-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("fs-extra"),t=require("node:path"),r=require("../utils/neoParams.js"),m=require("../utils/replaceInPackage.js"),a=require("../utils/resetPackageVersion.js"),o=require("../utils/autoEntryRootDir.js"),c=require("../utils/common.js");var p,s;exports.__require=function(){if(s)return p;s=1;const i=e,n=t,{consoleTag:l}=r.__require(),{replaceInPackage:u}=m.__require(),{resetPackageVersion:_}=a.__require(),d=o.__require(),{errorLog:j}=c.__require(),v={"neo-web-entity-grid":{projectName:"neo-web-entity-grid",dir:n.resolve(__dirname,"../../template/neo-web-entity-grid")},"neo-h5-cmps":{projectName:"neo-h5-cmps",dir:n.resolve(__dirname,"../../template/neo-h5-cmps")},neo:{projectName:"neo-custom-cmp-template",dir:n.resolve(__dirname,"../../template/neo-custom-cmp-template")},antd:{projectName:"antd-custom-cmp-template",dir:n.resolve(__dirname,"../../template/antd-custom-cmp-template")},"neo-bi-cmps":{projectName:"neo-bi-cmps",dir:n.resolve(__dirname,"../../template/neo-bi-cmps")},echarts:{projectName:"echarts-custom-cmp-template",dir:n.resolve(__dirname,"../../template/echarts-custom-cmp-template")},amap:{projectName:"map-custom-cmp-template",dir:n.resolve(__dirname,"../../template/map-custom-cmp-template")},react:{projectName:"react-custom-cmp-template",dir:n.resolve(__dirname,"../../template/react-custom-cmp-template")},"react-ts":{projectName:"react-ts-custom-cmp-template",dir:n.resolve(__dirname,"../../template/react-ts-custom-cmp-template")},vue2:{projectName:"vue2-custom-cmp-template",dir:n.resolve(__dirname,"../../template/vue2-custom-cmp-template")}};return p=function(e,t){const r=v[e||"react"],m=r.dir,a=t||"neoCustomCmp",o=n.resolve(process.cwd(),a);i.copy(m,o).then(()=>{u(o,r.projectName,a),u(o,"neo自定义组件模板","neo自定义组件"),_(o),console.log(`${l}已创建自定义组件(${a})!`),d(o)}).catch(e=>j(`${l}自定义组件模板下载失败:`,e))}};
|
package/dist/neo/env.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("lodash");var t,e;exports.__require=function(){if(e)return t;e=1;const a=o,
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("lodash");var t,e;exports.__require=function(){if(e)return t;e=1;const a=o,u={production:{neoBaseURL:"https://crm.xiaoshouyi.com",loginURL:"https://login.xiaoshouyi.com/auc/oauth2/auth",tokenURL:"https://login.xiaoshouyi.com/auc/oauth2/token"},gray:{neoBaseURL:"https://crm-gray.xiaoshouyi.com",loginURL:"https://login.xiaoshouyi.com/auc/oauth2/auth",tokenURL:"https://login.xiaoshouyi.com/auc/oauth2/token"},sandbox:{neoBaseURL:"https://crm-sandbox.xiaoshouyi.com",loginURL:"https://login-sandbox.xiaoshouyi.com/auc/oauth2/auth",tokenURL:"https://login-sandbox.xiaoshouyi.com/auc/oauth2/token"},cd:{neoBaseURL:"https://crm-cd.xiaoshouyi.com",loginURL:"https://login-cd.xiaoshouyi.com/auc/oauth2/auth",tokenURL:"https://login-cd.xiaoshouyi.com/auc/oauth2/token"},tencentuat:{neoBaseURL:"https://crm-tencentuat.xiaoshouyi.com",loginURL:"https://login-tencentuat.xiaoshouyi.com/auc/oauth2/auth",tokenURL:"https://login-tencentuat.xiaoshouyi.com/auc/oauth2/token"}},n={neoBaseURL:"https://crm-cd.xiaoshouyi.com",loginURL:"https://login-cd.xiaoshouyi.com/auc/oauth2/auth",tokenURL:"https://login-cd.xiaoshouyi.com/auc/oauth2/token",delete:"/rest/metadata/v3.0/ui/customComponents",saveAPI:"/rest/metadata/v3.0/ui/customComponents/actions/saveOrUpdateComponent",queryAll_v1:"/rest/metadata/v3.0/ui/components/filter?custom=true",queryAll:"/rest/metadata/v3.0/ui/customComponents/actions/queryCustomComponents",getCodeLibAPI:o=>`/rest/metadata/v3.0/ui/customComponents/${o}/codeLib`,uploadAPI:"/rest/metadata/v3.0/ui/customComponents/actions/upload",getUserInfoAPI:"/rest/auc/v2.0/userInfo",pcLinkDebugUrl:"/bff/spa/neo.ui.designer.web/index#/neoPage/layoutEdit/customPage/emptyPage/default?debug=true",h5LinkDebugUrl:"/bff/spa/neo.ui.designer.h5/index#/neoPage/layoutEdit/customPage/emptyPage/default?debug=true"};return t={DefaultNeoCrmAPI:n,getNeoCrmAPI:(o="cd",t={})=>{let e,s=a.cloneDeep(n);return e="custom"===o?{...t,neoBaseURL:t.neoBaseURL,loginURL:t.loginURL||t.loginAPI,tokenURL:t.tokenURL||t.tokenAPI}:u[o]||u.cd,{...s,...e}}}};
|
package/dist/neo/neoService.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("axios"),t=require("form-data"),s=require("node:fs"),i=require("node:path"),o=require("node:crypto"),r=require("ora"),n=require("lodash"),a=require("akfun"),c=require("./neoLogin.js"),h=require("../utils/projectUtils/updatePublishLog.js"),l=require("../utils/common.js"),u=require("./neoEnvManager.js"),d=require("../utils/tableLog.js");var p,m;exports.__require=function(){if(m)return p;m=1;const f=e,y=t,g=s,w=i,k=o,A=r,$=n,{resolve:C}=a,x=c.__require(),T=h.__require(),{getFramework:F,errorLog:L,successLog:P}=l.__require(),b=u.__require(),{tableLog:I}=d.__require();return p=class{constructor(){const e=b.getEnvConfig(),{assetsRoot:t,auth:s,authType:i}=e||{};this.authType=i||"oauth2",this.NeoCrmAPI=e||{},"password"!==this.authType||s||(L("密码授权模式时,neo.config.js / neoConfig / auth 配置不能为空"),process.exit(1)),"password"===this.authType?s.client_id&&s.client_secret&&s.username&&s.password||(L("neo.config.js / neoConfig / auth 配置不完整(password 模式),需要包含 client_id、client_secret、username、password"),process.exit(1)):"oauth2"!=this.authType&&(L(`不支持的授权类型: ${this.authType},可选值:oauth2、password`),process.exit(1)),this.assetsRoot=t||C("dist"),this.auth=s,this.cmpList=[],this.cmpInfoMap={},this.tokenCache={token:null,expiresAt:null}}buildFullUrl(e){return e.startsWith("http://")||e.startsWith("https://")?e:`${this.NeoCrmAPI.neoBaseURL}${e}`}uploadAPI(){return this.buildFullUrl(this.NeoCrmAPI.uploadAPI)}saveAPI(){return this.buildFullUrl(this.NeoCrmAPI.saveAPI)}isTokenExpired(){return!this.tokenCache.token||!this.tokenCache.expiresAt||Date.now()>=this.tokenCache.expiresAt}async getToken(){return this.isTokenExpired()?"oauth2"===this.authType?await this.getTokenByOAuth2():await this.getTokenByPassword():this.tokenCache.token}async getTokenByPassword(){const e=A("获取 token(密码模式)...").start();if(!this.isTokenExpired())return P("使用缓存的 token。",e),this.tokenCache.token;const t=new URLSearchParams;t.append("grant_type","password"),t.append("client_id",this.auth.client_id),t.append("client_secret",this.auth.client_secret),t.append("username",this.auth.username),t.append("password",this.auth.password);const s=this.buildFullUrl(this.NeoCrmAPI.tokenURL);try{const i=await f.post(s,t.toString(),{headers:{"Content-Type":"application/x-www-form-urlencoded"}}),o=i.data||{},{access_token:r,expires_in:n}=o;r||(L("获取 token 失败(授权配置错误):响应中未包含 access_token,"+JSON.stringify(i.data),e),process.exit(1));const a=parseInt(n)||3600;return this.tokenCache={...o,token:r,expiresAt:Date.now()+1e3*(a-60)},e.clear(),e.stop(),r}catch(i){L("获取 token 失败",e),L(`\n获取 token 失败: ${i.message||i.msg}`),L(`\ntoken 授权地址: ${s}`),L(`\ntoken 请求参数: ${t}`),i.response&&L(`响应数据: ${JSON.stringify(i.response.data)}`),process.exit(1)}}async getTokenByOAuth2(){const e=A("获取 token(OAuth2 模式)...").start();try{const t={neoBaseURL:this.NeoCrmAPI.neoBaseURL,loginURL:this.NeoCrmAPI.loginURL,tokenURL:this.NeoCrmAPI.tokenURL},s=new x(t),i=await s.getAccessToken(),o=i.access_token;return this.tokenCache={...i,token:o,expiresAt:Date.now()+72e5},e.clear(),e.stop(),o}catch(t){L("获取 token 失败(OAuth2 模式)",e),L(`\n获取 token 失败: ${t.message||t.msg}`),t.response&&L(`响应数据: ${JSON.stringify(t.response.data)}`),process.exit(1)}}async refreshToken(){return this.tokenCache={token:null,expiresAt:null},await this.getToken()}async ensureValidToken(){if(!this.tokenCache.token)return await this.getToken();if(this.isTokenExpired()){const e=A("token 已过期,正在刷新...").start();try{const t=await this.refreshToken();return P("token 刷新成功。",e),t}catch(t){throw L("token 刷新失败。",e),t}}return this.tokenCache.token}async uploadFile(e,t={}){const s=await this.ensureValidToken();if(!e||"string"!=typeof e)throw new Error(`文件路径无效: ${e}`);if(!g.existsSync(e))throw new Error(`文件不存在: ${e}`);const i=g.statSync(e);if(!i.isFile())throw new Error(`路径不是文件: ${e}`);const o=t.maxSize||5242880;if(i.size>o){const e=(i.size/1024/1024).toFixed(2),t=(o/1024/1024).toFixed(2);throw new Error(`文件大小超过限制: ${e}MB > ${t}MB`)}if(0===i.size)throw new Error(`文件为空: ${e}`);const r=w.basename(e),n=(i.size/1024).toFixed(2),a=A(`正在上传文件: ${r} (${n}KB)...`).start();try{const i=new y,o=t.fieldName||"customComponentCode",n=g.createReadStream(e);i.append(o,n,r);const c=this.uploadAPI(),h=t.timeout||6e4,l={headers:{Authorization:`Bearer ${s}`,"xsy-inner-source":"bff",...i.getHeaders()},timeout:h,maxContentLength:1/0,maxBodyLength:1/0},u=await f.post(c,i,l);let d;const p=u.data;if(200!==u.status&&201!==u.status)throw new Error(`上传失败: HTTP ${u.status}`);if("string"==typeof p)d=p.trim();else{if(!p||"object"!=typeof p)throw new Error("响应数据格式不正确: "+typeof p);if(void 0!==p.code&&200!==p.code&&0!==p.code){const e=p.message||p.msg||"未知错误";throw new Error(`上传失败: ${e} (code: ${p.code})`)}d=void 0!==p.data?p.data:void 0!==p.url?p.url:void 0!==p.fileUrl?p.fileUrl:p}if(!d)throw new Error("返回的文件地址为空");let m;return"string"==typeof d?m=d:d&&"object"==typeof d&&d.url&&(m=d.url),P(`文件上传成功: ${r} -> ${m}`,a),m}catch(t){if(L(`上传文件失败: ${t.message||t.msg}, 文件路径: ${e}`,a),t.response){const e=t.response.status,s=t.response.statusText,i=t.response.data,o=t.config?.url||this.uploadAPI();if(L("\n========== 上传请求详情 =========="),L(`请求 URL: ${o}`),L(`HTTP 状态码: ${e} ${s}`),L(`响应数据: ${JSON.stringify(i)}`),L("==================================\n"),404===e)throw new Error(`上传 API 不存在 (404): ${o}\n请检查 neo.config.js 中的 neoBaseURL 配置是否正确,或者 API 路径是否存在。\n当前配置的 API 路径: ${this.NeoCrmAPI.uploadAPI}`)}else t.request&&L("请求已发送但未收到响应,请检查网络连接或代理配置。");throw t}}async publish2oss(e,t=[".js",".css",".zip"]){if(!e)return void L(`自定义组件名称不能为空: ${e}`);if(!g.existsSync(this.assetsRoot))return void L(`未找到自定义组件资源目录: ${this.assetsRoot}`);const s={cmpType:e},i=g.readdirSync(this.assetsRoot).map(async i=>{const o=w.join(this.assetsRoot,i),r=g.statSync(o),n=w.parse(o);if(r.isFile()&&t.includes(n.ext)){let t=$.camelCase(e);if(i.indexOf(t)<0)return;try{const e=await this.uploadFile(o);i.indexOf("Model")>-1?s.modelAsset=e:i.endsWith(".css")?s.cssAsset=e:i.endsWith(".zip")?s.codeLib=e:s.asset=e}catch(e){L(`文件上传失败(${i}):\n`),process.exit(1)}}});return await Promise.all(i),s&&s.cmpType&&(console.info("上传至 OSS 的文件信息:\n",s),T(s)),s}async getCmpAssets(e,t=[".js",".css",".zip"]){if(!e)return void L(`自定义组件名称不能为空: ${e}`);if(!g.existsSync(this.assetsRoot))return void L(`未找到自定义组件资源目录: ${this.assetsRoot}`);const s={cmpType:e};return g.readdirSync(this.assetsRoot).forEach(i=>{const o=w.join(this.assetsRoot,i),r=g.statSync(o),n=w.parse(o);if(r.isFile()&&t.includes(n.ext)){let t=$.camelCase(e);if(i.indexOf(t)<0)return;const n=5242880;if(r.size>n){const e=(r.size/1024/1024).toFixed(2),t=(n/1024/1024).toFixed(2);throw new Error(`${i} 文件大小超过限制: ${e}MB > ${t}MB`)}const a=g.readFileSync(o),c=k.createHash("md5").update(a).digest("hex").substring(0,8),h={fileContent:g.createReadStream(o),fileName:`${c}-${i}`,fileSize:r.size};i.indexOf("Model")>-1?s.modelAssetFile=h:i.endsWith(".css")?s.cssAssetFile=h:i.endsWith(".zip")?s.codeLibFile=h:s.assetFile=h}}),s}async updateCustomComponent(e){const t=await this.ensureValidToken();if(!e)throw new Error("componentData 不能为空");const s=A("正在保存自定义组件信息...").start();try{const i=this.saveAPI(),o=new y;e.assetFile&&o.append("assetFile",e.assetFile.fileContent,e.assetFile.fileName),e.modelAssetFile&&o.append("modelAssetFile",e.modelAssetFile.fileContent,e.modelAssetFile.fileName),e.cssAssetFile&&o.append("cssAssetFile",e.cssAssetFile.fileContent,e.cssAssetFile.fileName),e.codeLibFile&&o.append("codeLibFile",e.codeLibFile.fileContent,e.codeLibFile.fileName),o.append("component",JSON.stringify($.omit(e,["assetFile","modelAssetFile","cssAssetFile","codeLibFile"])));const r=await f.post(i,o,{headers:{Authorization:`Bearer ${t}`,"xsy-inner-source":"bff",...o.getHeaders()},timeout:12e4,maxContentLength:1/0,maxBodyLength:1/0}),{code:n,message:a,msg:c}=r.data||{};n&&200!==n&&(L(`保存自定义组件信息失败: ${a||c||"未知错误"}`),process.exit(1)),s.clear(),s.stop()}catch(e){const t=e.message||e.msg;L(t?`保存自定义组件信息失败: ${t}`:`保存自定义组件信息失败: ${JSON.stringify(e)}`,s),process.exit(1)}}async getCustomCmpList(){const e=await this.ensureValidToken();try{let t=this.buildFullUrl(this.NeoCrmAPI.queryAll);const s=await f.post(t,{pageNo:1,pageSize:1e3},{headers:{Authorization:`Bearer ${e}`,"xsy-inner-source":"bff","Content-Type":"application/json"}}),{code:i,message:o,msg:r}=s.data||{};i&&200!==i&&(L(`获取自定义组件列表失败: ${o||r||"未知错误"}`),process.exit(1)),this.updateCustomCmpList(s.data.data||[])}catch(e){const t=e.message||e.msg;L(t?`获取自定义组件列表失败: ${t}`:`响应数据: ${JSON.stringify(e)}`),process.exit(1)}return this.cmpList||[]}getCodeLibByCmpType(e){return e?this.buildFullUrl(this.NeoCrmAPI.getCodeLibAPI(e)):null}async deleteCmp(e){const t=await this.ensureValidToken();e||(L("自定义组件名称不能为空。"),process.exit(1));let s=this.buildFullUrl(this.NeoCrmAPI.delete);s+=`/${e}`;const i=await f.delete(s,{headers:{Authorization:`Bearer ${t}`,"xsy-inner-source":"bff","Content-Type":"application/json"}}),{code:o,message:r,msg:n,errorInfo:a}=i.data||{};return o&&200!==o&&(a&&a.length>0?I(a,{title:"删除自定义组件失败",columns:["reason","instance"],headers:{reason:"原因",instance:"实例"},align:{reason:"center",instance:"center"},padding:2,showBorder:!0}):L(`删除自定义组件失败: ${r||n||"未知错误"}`),process.exit(1)),i.data}getCmpListByFramework(e){if(!e)return this.cmpList;const t=F(e);return this.cmpList.filter(e=>e.framework===t)}getCmpInfoByCmpType(e){return e&&this.cmpInfoMap[e]||null}updateCustomCmpList(e){e&&Array.isArray(e)&&(this.cmpList=e,e.forEach(e=>{this.cmpInfoMap[e.cmpType]=e}))}async request(e,t,s={}){const i=await this.ensureValidToken(),{data:o,headers:r={},params:n}=s,a=this.buildFullUrl(t);try{const t=await f({method:e,url:a,data:o,params:n,headers:{Authorization:`Bearer ${i}`,"xsy-inner-source":"bff",...r}});if(t.data&&t.data.code&&200!==t.data.code)throw new Error(`请求失败: ${t.data.message||t.data.msg||"未知错误"}`);return t.data}catch(s){throw L(`请求失败 [${e} ${t}]: ${s.message||s.msg}`),s.response&&L(`响应数据: ${JSON.stringify(s.response.data)}`),s}}async get(e,t={}){return await this.request("GET",e,t)}async post(e,t={}){return await this.request("POST",e,t)}async put(e,t={}){return await this.request("PUT",e,t)}async delete(e,t={}){return await this.request("DELETE",e,t)}}};
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("axios"),t=require("form-data"),s=require("node:fs"),i=require("node:path"),o=require("node:crypto"),r=require("ora"),n=require("lodash"),a=require("akfun"),c=require("./neoLogin.js"),h=require("../utils/projectUtils/updatePublishLog.js"),l=require("../utils/common.js"),u=require("./neoEnvManager.js"),d=require("../utils/tableLog.js");var p,m;exports.__require=function(){if(m)return p;m=1;const f=e,y=t,g=s,w=i,k=o,$=r,A=n,{resolve:C}=a,x=c.__require(),T=h.__require(),{getFramework:F,errorLog:L,successLog:P}=l.__require(),b=u.__require(),{tableLog:I}=d.__require();return p=class{constructor(){const e=b.getEnvConfig(),{assetsRoot:t,auth:s,authType:i}=e||{};this.authType=i||"oauth2",this.NeoCrmAPI=e||{},"password"!==this.authType||s||(L("密码授权模式时,neo.config.js / neoConfig / auth 配置不能为空"),process.exit(1)),"password"===this.authType?s.client_id&&s.client_secret&&s.username&&s.password||(L("neo.config.js / neoConfig / auth 配置不完整(password 模式),需要包含 client_id、client_secret、username、password"),process.exit(1)):"oauth2"!=this.authType&&(L(`不支持的授权类型: ${this.authType},可选值:oauth2、password`),process.exit(1)),this.assetsRoot=t||C("dist"),this.auth=s,this.cmpList=[],this.cmpInfoMap={},this.tokenCache={token:null,expiresAt:null}}buildFullUrl(e){return e.startsWith("http://")||e.startsWith("https://")?e:`${this.NeoCrmAPI.neoBaseURL}${e}`}uploadAPI(){return this.buildFullUrl(this.NeoCrmAPI.uploadAPI)}saveAPI(){return this.buildFullUrl(this.NeoCrmAPI.saveAPI)}isTokenExpired(){return!this.tokenCache.token||!this.tokenCache.expiresAt||Date.now()>=this.tokenCache.expiresAt}async getToken(){return this.isTokenExpired()?"oauth2"===this.authType?await this.getTokenByOAuth2():await this.getTokenByPassword():this.tokenCache.token}async getTokenByPassword(){const e=$("获取 token(密码模式)...").start();if(!this.isTokenExpired())return P("使用缓存的 token。",e),this.tokenCache.token;const t=new URLSearchParams;t.append("grant_type","password"),t.append("client_id",this.auth.client_id),t.append("client_secret",this.auth.client_secret),t.append("username",this.auth.username),t.append("password",this.auth.password);const s=this.buildFullUrl(this.NeoCrmAPI.tokenURL);try{const i=await f.post(s,t.toString(),{headers:{"Content-Type":"application/x-www-form-urlencoded"}}),o=i.data||{},{access_token:r,expires_in:n}=o;r||(L("获取 token 失败(授权配置错误):响应中未包含 access_token,"+JSON.stringify(i.data),e),process.exit(1));const a=parseInt(n)||3600;return this.tokenCache={...o,token:r,expiresAt:Date.now()+1e3*(a-60)},e.clear(),e.stop(),r}catch(i){L("获取 token 失败",e),L(`\n获取 token 失败: ${i.message||i.msg}`),L(`\ntoken 授权地址: ${s}`),L(`\ntoken 请求参数: ${t}`),i.response&&L(`响应数据: ${JSON.stringify(i.response.data)}`),process.exit(1)}}async getTokenByOAuth2(){const e=$("获取 token(OAuth2 模式)...").start();try{const t={neoBaseURL:this.NeoCrmAPI.neoBaseURL,loginURL:this.NeoCrmAPI.loginURL,tokenURL:this.NeoCrmAPI.tokenURL},s=new x(t),i=await s.getAccessToken(),o=i.access_token;return this.tokenCache={...i,token:o,expiresAt:Date.now()+72e5},e.clear(),e.stop(),o}catch(t){L("获取 token 失败(OAuth2 模式)",e),L(`\n获取 token 失败: ${t.message||t.msg}`),t.response&&L(`响应数据: ${JSON.stringify(t.response.data)}`),process.exit(1)}}async refreshToken(){return this.tokenCache={token:null,expiresAt:null},await this.getToken()}async ensureValidToken(){if(!this.tokenCache.token)return await this.getToken();if(this.isTokenExpired()){const e=$("token 已过期,正在刷新...").start();try{const t=await this.refreshToken();return P("token 刷新成功。",e),t}catch(t){throw L("token 刷新失败。",e),t}}return this.tokenCache.token}async uploadFile(e,t={}){const s=await this.ensureValidToken();if(!e||"string"!=typeof e)throw new Error(`文件路径无效: ${e}`);if(!g.existsSync(e))throw new Error(`文件不存在: ${e}`);const i=g.statSync(e);if(!i.isFile())throw new Error(`路径不是文件: ${e}`);const o=t.maxSize||5242880;if(i.size>o){const e=(i.size/1024/1024).toFixed(2),t=(o/1024/1024).toFixed(2);throw new Error(`文件大小超过限制: ${e}MB > ${t}MB`)}if(0===i.size)throw new Error(`文件为空: ${e}`);const r=w.basename(e),n=(i.size/1024).toFixed(2),a=$(`正在上传文件: ${r} (${n}KB)...`).start();try{const i=new y,o=t.fieldName||"customComponentCode",n=g.createReadStream(e);i.append(o,n,r);const c=this.uploadAPI(),h=t.timeout||6e4,l={headers:{Authorization:`Bearer ${s}`,"xsy-inner-source":"bff",...i.getHeaders()},timeout:h,maxContentLength:1/0,maxBodyLength:1/0},u=await f.post(c,i,l);let d;const p=u.data;if(200!==u.status&&201!==u.status)throw new Error(`上传失败: HTTP ${u.status}`);if("string"==typeof p)d=p.trim();else{if(!p||"object"!=typeof p)throw new Error("响应数据格式不正确: "+typeof p);if(void 0!==p.code&&200!==p.code&&0!==p.code){const e=p.message||p.msg||"未知错误";throw new Error(`上传失败: ${e} (code: ${p.code})`)}d=void 0!==p.data?p.data:void 0!==p.url?p.url:void 0!==p.fileUrl?p.fileUrl:p}if(!d)throw new Error("返回的文件地址为空");let m;return"string"==typeof d?m=d:d&&"object"==typeof d&&d.url&&(m=d.url),P(`文件上传成功: ${r} -> ${m}`,a),m}catch(t){if(L(`上传文件失败: ${t.message||t.msg}, 文件路径: ${e}`,a),t.response){const e=t.response.status,s=t.response.statusText,i=t.response.data,o=t.config?.url||this.uploadAPI();if(L("\n========== 上传请求详情 =========="),L(`请求 URL: ${o}`),L(`HTTP 状态码: ${e} ${s}`),L(`响应数据: ${JSON.stringify(i)}`),L("==================================\n"),404===e)throw new Error(`上传 API 不存在 (404): ${o}\n请检查 neo.config.js 中的 neoBaseURL 配置是否正确,或者 API 路径是否存在。\n当前配置的 API 路径: ${this.NeoCrmAPI.uploadAPI}`)}else t.request&&L("请求已发送但未收到响应,请检查网络连接或代理配置。");throw t}}async publish2oss(e,t=[".js",".css",".zip"]){if(!e)return void L(`自定义组件名称不能为空: ${e}`);if(!g.existsSync(this.assetsRoot))return void L(`未找到自定义组件资源目录: ${this.assetsRoot}`);const s={cmpType:e},i=g.readdirSync(this.assetsRoot).map(async i=>{const o=w.join(this.assetsRoot,i),r=g.statSync(o),n=w.parse(o);if(r.isFile()&&t.includes(n.ext)){let t=A.camelCase(e);if(i.indexOf(t)<0)return;try{const e=await this.uploadFile(o);i.indexOf("Model")>-1?s.modelAsset=e:i.endsWith(".css")?s.cssAsset=e:i.endsWith(".zip")?s.codeLib=e:s.asset=e}catch(e){L(`文件上传失败(${i}):\n`),process.exit(1)}}});return await Promise.all(i),s&&s.cmpType&&(console.info("上传至 OSS 的文件信息:\n",s),T(s)),s}async getCmpAssets(e,t=[".js",".css",".zip"]){if(!e)return void L(`自定义组件名称不能为空: ${e}`);if(!g.existsSync(this.assetsRoot))return void L(`未找到自定义组件资源目录: ${this.assetsRoot}`);const s={cmpType:e};return g.readdirSync(this.assetsRoot).forEach(i=>{const o=w.join(this.assetsRoot,i),r=g.statSync(o),n=w.parse(o);if(r.isFile()&&t.includes(n.ext)){let t=A.camelCase(e);if(i.indexOf(t)<0)return;const n=5242880;if(r.size>n){const e=(r.size/1024/1024).toFixed(2),t=(n/1024/1024).toFixed(2);throw new Error(`${i} 文件大小超过限制: ${e}MB > ${t}MB`)}const a=g.readFileSync(o),c=k.createHash("md5").update(a).digest("hex").substring(0,8),h={fileContent:g.createReadStream(o),fileName:`${c}-${(new Date).getTime()}-${i}`,fileSize:r.size};i.indexOf("Model")>-1?s.modelAssetFile=h:i.endsWith(".css")?s.cssAssetFile=h:i.endsWith(".zip")?s.codeLibFile=h:s.assetFile=h}}),s}async updateCustomComponent(e){const t=await this.ensureValidToken();if(!e)throw new Error("componentData 不能为空");const s=$("正在保存自定义组件信息...").start();try{const i=this.saveAPI(),o=new y;e.assetFile&&o.append("assetFile",e.assetFile.fileContent,e.assetFile.fileName),e.modelAssetFile&&o.append("modelAssetFile",e.modelAssetFile.fileContent,e.modelAssetFile.fileName),e.cssAssetFile&&o.append("cssAssetFile",e.cssAssetFile.fileContent,e.cssAssetFile.fileName),e.codeLibFile&&o.append("codeLibFile",e.codeLibFile.fileContent,e.codeLibFile.fileName),o.append("component",JSON.stringify(A.omit(e,["assetFile","modelAssetFile","cssAssetFile","codeLibFile"])));const r=await f.post(i,o,{headers:{Authorization:`Bearer ${t}`,"xsy-inner-source":"bff",...o.getHeaders()},timeout:12e4,maxContentLength:1/0,maxBodyLength:1/0}),{code:n,message:a,msg:c}=r.data||{};n&&200!==n&&(L(`保存自定义组件信息失败: ${a||c||"未知错误"}`),process.exit(1)),s.clear(),s.stop()}catch(e){const t=e.message||e.msg;L(t?`保存自定义组件信息失败: ${t}`:`保存自定义组件信息失败: ${JSON.stringify(e)}`,s),process.exit(1)}}async getCustomCmpList(){const e=await this.ensureValidToken();try{let t=this.buildFullUrl(this.NeoCrmAPI.queryAll);const s=await f.post(t,{pageNo:1,pageSize:1e3},{headers:{Authorization:`Bearer ${e}`,"xsy-inner-source":"bff","Content-Type":"application/json"}}),{code:i,message:o,msg:r}=s.data||{};i&&200!==i&&(L(`获取自定义组件列表失败: ${o||r||"未知错误"}`),process.exit(1)),this.updateCustomCmpList(s.data.data||[])}catch(e){const t=e.message||e.msg;L(t?`获取自定义组件列表失败: ${t}`:`响应数据: ${JSON.stringify(e)}`),process.exit(1)}return this.cmpList||[]}getCodeLibByCmpType(e){return e?this.buildFullUrl(this.NeoCrmAPI.getCodeLibAPI(e)):null}async deleteCmp(e){const t=await this.ensureValidToken();e||(L("自定义组件名称不能为空。"),process.exit(1));let s=this.buildFullUrl(this.NeoCrmAPI.delete);s+=`/${e}`;const i=await f.delete(s,{headers:{Authorization:`Bearer ${t}`,"xsy-inner-source":"bff","Content-Type":"application/json"}}),{code:o,message:r,msg:n,errorInfo:a}=i.data||{};return o&&200!==o&&(a&&a.length>0?I(a,{title:"删除自定义组件失败",columns:["reason","instance"],headers:{reason:"原因",instance:"实例"},align:{reason:"center",instance:"center"},padding:2,showBorder:!0}):L(`删除自定义组件失败: ${r||n||"未知错误"}`),process.exit(1)),i.data}getCmpListByFramework(e){if(!e)return this.cmpList;const t=F(e);return this.cmpList.filter(e=>e.framework===t)}getCmpInfoByCmpType(e){return e&&this.cmpInfoMap[e]||null}updateCustomCmpList(e){e&&Array.isArray(e)&&(this.cmpList=e,e.forEach(e=>{this.cmpInfoMap[e.cmpType]=e}))}async request(e,t,s={}){const i=await this.ensureValidToken(),{data:o,headers:r={},params:n}=s,a=this.buildFullUrl(t);try{const t=await f({method:e,url:a,data:o,params:n,headers:{Authorization:`Bearer ${i}`,"xsy-inner-source":"bff",...r}});if(t.data&&t.data.code&&200!==t.data.code)throw new Error(`请求失败: ${t.data.message||t.data.msg||"未知错误"}`);return t.data}catch(s){throw L(`请求失败 [${e} ${t}]: ${s.message||s.msg}`),s.response&&L(`响应数据: ${JSON.stringify(s.response.data)}`),s}}async get(e,t={}){return await this.request("GET",e,t)}async post(e,t={}){return await this.request("POST",e,t)}async put(e,t={}){return await this.request("PUT",e,t)}async delete(e,t={}){return await this.request("DELETE",e,t)}}};
|
package/dist/package.json.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var e="1.13.
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var e="1.13.2";const o={version:e};exports.default=o,exports.version=e;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("node:fs"),r=require("node:path"),t=require("lodash"),s=require("../pathUtils.js");var o,i;exports.__require=function(){if(i)return o;i=1;const n=e,c=r,a=t,{resolveToCurrentRoot:u}=s.__require();return o=(e="./src/components",r)=>{const t={},s={index:[]},o=[],i={},d=u(e);n.existsSync(d)||(console.error(`未找到组件目录,请检查 ${e} 目录是否存在`),process.exit(1));try{let u=[];u=r?[r]:n.readdirSync(d),u.forEach(r=>{const u=c.join(d,r);if(n.statSync(u).isDirectory()&&!r.startsWith(".")&&"node_modules"!==r){const u=c.join(d,r),l=r,x=a.camelCase(l);o.push(l),n.readdirSync(u).filter(e=>e.match(/[index|register|model]\.(tsx?|jsx?|vue)$/)).map(r=>c.join(e,l,r)).forEach(e=>{const r=`./${e}`;e.match(/register\.[tj]sx?$/)?t[x]=r:e.match(/model\.[tj]sx?$/)?t[`${x}Model`]=r:e.match(/index\.(tsx?|jsx?|vue)$/)&&(i[
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("node:fs"),r=require("node:path"),t=require("lodash"),s=require("../pathUtils.js");var o,i;exports.__require=function(){if(i)return o;i=1;const n=e,c=r,a=t,{resolveToCurrentRoot:u}=s.__require();return o=(e="./src/components",r)=>{const t={},s={index:[]},o=[],i={},d=u(e);n.existsSync(d)||(console.error(`未找到组件目录,请检查 ${e} 目录是否存在`),process.exit(1));try{let u=[];u=r?[r]:n.readdirSync(d),u.forEach(r=>{const u=c.join(d,r);if(n.statSync(u).isDirectory()&&!r.startsWith(".")&&"node_modules"!==r){const u=c.join(d,r),l=r,x=a.camelCase(l);o.push(l),n.readdirSync(u).filter(e=>e.match(/[index|register|model]\.(tsx?|jsx?|vue)$/)).map(r=>c.join(e,l,r)).forEach(e=>{const r=`./${e}`;e.match(/register\.[tj]sx?$/)?t[x]=r:e.match(/model\.[tj]sx?$/)?t[`${x}Model`]=r:e.match(/index\.(tsx?|jsx?|vue)$/)&&(i[l]=c.resolve(e)),s.index.push(r)})}})}catch(e){console.error("获取自定义组件入口文件失败(getEntries):",e),process.exit(1)}return{widgetEntries:t,linkDebugEntries:s,cmpTypes:o,defaultExports:i}}};
|
package/docs/Web/347/253/257 NeoEntityGrid /344/275/277/347/224/250/350/257/264/346/230/216.md"
CHANGED
|
@@ -210,6 +210,8 @@
|
|
|
210
210
|
| `onSmartViewChanged` | `(data) => void` | SmartView 切换回调 |
|
|
211
211
|
| `onSinglerClick` | `(clickData) => boolean` | 行单击拦截,返回 `true` 则阻止默认打开详情逻辑 |
|
|
212
212
|
| `onDetailPageChange` | `(data) => void` | 侧滑详情翻页时回调(分屏视图/地图视图) |
|
|
213
|
+
| `onSelectedCall` | `(data) => void` | picker 选择器模式时,点击「确认」的回调方法 |
|
|
214
|
+
| `onCancel` | `() => void` | picker 选择器模式时,点击「取消」的回调方法 |
|
|
213
215
|
|
|
214
216
|
### 其他属性
|
|
215
217
|
|
|
@@ -221,6 +223,8 @@
|
|
|
221
223
|
| `customEmptyMsg` | `string` | 自定义空数据提示文本,覆盖默认的「暂无数据」提示 |
|
|
222
224
|
| `scene` | `string` | 场景标识,如 `'standard'`(standard 场景下侧滑详情会带遮罩并可点击关闭) |
|
|
223
225
|
| `busiTypeApiKey` | `string` | 业务类型 ApiKey,用于打开详情时传入业务类型参数 |
|
|
226
|
+
| `selectedCount` | `number` | picker选择器模式时可选择的最多个数 |
|
|
227
|
+
|
|
224
228
|
|
|
225
229
|
## 四、核心方法介绍
|
|
226
230
|
|
package/package.json
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"neo-register": "^1.2.0",
|
|
39
39
|
"react": "^16.9.0",
|
|
40
40
|
"react-dom": "^16.9.0",
|
|
41
|
-
"axios": "^
|
|
41
|
+
"axios": "^1.7.0",
|
|
42
42
|
"antd": "4.9.4",
|
|
43
43
|
"lodash": "^4.17.21",
|
|
44
44
|
"neo-open-api": "^1.2.3",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@types/react": "^16.9.11",
|
|
53
53
|
"@types/react-dom": "^16.9.15",
|
|
54
54
|
"@types/axios": "^0.14.0",
|
|
55
|
-
"neo-cmp-cli": "^1.13.
|
|
55
|
+
"neo-cmp-cli": "^1.13.2",
|
|
56
56
|
"husky": "^4.2.5",
|
|
57
57
|
"lint-staged": "^10.2.9",
|
|
58
58
|
"prettier": "^2.0.5",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
registry = "https://registry.npmmirror.com/"
|
|
@@ -34,7 +34,8 @@ import { xObject } from 'neo-open-api'; // Neo Open API
|
|
|
34
34
|
// @ts-ignore
|
|
35
35
|
import isEqual from 'lodash/isEqual';
|
|
36
36
|
|
|
37
|
-
// Neo Open API
|
|
37
|
+
// Neo Open API
|
|
38
|
+
// 引入 neo-ui-common / BaseCmp
|
|
38
39
|
// @ts-ignore
|
|
39
40
|
import { BaseCmp } from 'neo-ui-common';
|
|
40
41
|
|
|
@@ -43,6 +43,10 @@ module.exports = {
|
|
|
43
43
|
],
|
|
44
44
|
ignoreNodeModules: false
|
|
45
45
|
},
|
|
46
|
+
neoCommonModule: {
|
|
47
|
+
remoteDeps: ['entityGrid__c'], // 远程依赖组件,表示当前自定义组件会用到的依赖组件,需要和 externals 配合使用
|
|
48
|
+
externals: ['entityGrid__c'], // 自定义组件中需要剔除的模块(仅支持数组写法)
|
|
49
|
+
},
|
|
46
50
|
linkDebug: {},
|
|
47
51
|
neoConfig: {
|
|
48
52
|
neoBaseURL: "https://crm-test.xiaoshouyi.com",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "neo-web-
|
|
2
|
+
"name": "neo-web-entity-grid",
|
|
3
3
|
"version": "1.1.0",
|
|
4
4
|
"description": "Web端列表组件模板: 含基础大列表、Picker 列表等示例组件。",
|
|
5
5
|
"framework": "react-ts",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@types/react-dom": "^16.9.15",
|
|
53
53
|
"husky": "^4.2.5",
|
|
54
54
|
"lint-staged": "^10.2.9",
|
|
55
|
-
"neo-cmp-cli": "^1.13.
|
|
55
|
+
"neo-cmp-cli": "^1.13.2",
|
|
56
56
|
"prettier": "^2.0.5"
|
|
57
57
|
},
|
|
58
58
|
"overrides": {
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Object Form 对象表单组件
|
|
2
|
+
|
|
3
|
+
基于 XObject 的对象表单组件,专门用于新增对象数据,支持动态字段渲染和多种字段类型。
|
|
4
|
+
备注:使用 Neo Open API SDK(neo-open-api)提供的方法实现数据对象的新增操作。
|
|
5
|
+
|
|
6
|
+
## 功能特性
|
|
7
|
+
|
|
8
|
+
- 📝 **动态表单渲染**:根据 XObject 字段描述自动生成表单项
|
|
9
|
+
- ➕ **数据新增**:支持向 Neo 平台新增数据记录
|
|
10
|
+
- 🎨 **多种字段类型**:支持文本、数字、日期、下拉选择等多种字段类型
|
|
11
|
+
- 📐 **响应式布局**:支持单列和双列布局,适配不同屏幕尺寸
|
|
12
|
+
- ✅ **表单验证**:自动根据字段配置进行必填验证
|
|
13
|
+
- 🔄 **表单重置**:支持快速重置表单内容
|
|
14
|
+
- 🎯 **成功提示**:提交成功后显示友好的提示信息
|
|
15
|
+
- ⚙️ **属性配置**:支持通过编辑器配置组件属性
|
|
16
|
+
|
|
17
|
+
## 组件属性
|
|
18
|
+
|
|
19
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
20
|
+
|--------|------|--------|------|
|
|
21
|
+
| formTitle | string | '新增数据' | 表单标题 |
|
|
22
|
+
| xObjectDataApi | object | - | 实体数据源配置,包含 xObjectApiKey 和 fields |
|
|
23
|
+
| xObjectDataApi.xObjectApiKey | string | '' | 数据对象的 API Key |
|
|
24
|
+
| xObjectDataApi.fields | string[] | [] | 要显示的字段列表(可选,不传则显示所有字段) |
|
|
25
|
+
| columnCount | 1 \| 2 | 1 | 表单列数(1列或2列) |
|
|
26
|
+
| showResetButton | boolean | true | 是否显示重置按钮 |
|
|
27
|
+
| onSuccess | function | - | 提交成功后的回调函数 |
|
|
28
|
+
|
|
29
|
+
## 使用方法
|
|
30
|
+
|
|
31
|
+
### 1. 在编辑器中使用
|
|
32
|
+
|
|
33
|
+
1. 从组件面板拖拽 "对象表单" 组件到页面
|
|
34
|
+
2. 在右侧属性面板中选择要操作的数据对象
|
|
35
|
+
3. 选择要在表单中显示的字段
|
|
36
|
+
4. 配置表单标题、列数等属性
|
|
37
|
+
5. 保存并预览
|
|
38
|
+
|
|
39
|
+
### 2. 代码中使用
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import EntityForm from './components/entity-form';
|
|
43
|
+
|
|
44
|
+
// 基础使用
|
|
45
|
+
<EntityForm
|
|
46
|
+
formTitle="新增联系人"
|
|
47
|
+
xObjectDataApi={{
|
|
48
|
+
xObjectApiKey: 'customContact__c',
|
|
49
|
+
fields: ['name', 'phone__c', 'email__c'],
|
|
50
|
+
}}
|
|
51
|
+
columnCount={2}
|
|
52
|
+
showResetButton={true}
|
|
53
|
+
onSuccess={(data) => {
|
|
54
|
+
console.log('提交成功:', data);
|
|
55
|
+
}}
|
|
56
|
+
/>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 支持的字段类型
|
|
60
|
+
|
|
61
|
+
组件支持以下字段类型,并自动渲染对应的输入组件:
|
|
62
|
+
|
|
63
|
+
| 字段类型 | 输入组件 | 说明 |
|
|
64
|
+
|---------|---------|------|
|
|
65
|
+
| text | Input | 单行文本输入框 |
|
|
66
|
+
| textarea | TextArea | 多行文本输入框 |
|
|
67
|
+
| int / float | InputNumber | 数字输入框 |
|
|
68
|
+
| email | Input (email) | 邮箱输入框 |
|
|
69
|
+
| phone | Input (tel) | 电话号码输入框 |
|
|
70
|
+
| url | Input (url) | URL 输入框 |
|
|
71
|
+
| date | DatePicker | 日期选择器 |
|
|
72
|
+
| datetime | DatePicker | 日期时间选择器 |
|
|
73
|
+
| time | DatePicker | 时间选择器 |
|
|
74
|
+
| picklist | Select | 单选下拉框 |
|
|
75
|
+
| multipicklist | Select (multiple) | 多选下拉框 |
|
|
76
|
+
| entityType | Select | 业务类型选择器 |
|
|
77
|
+
|
|
78
|
+
## 技术实现
|
|
79
|
+
|
|
80
|
+
### 核心依赖
|
|
81
|
+
|
|
82
|
+
- **Ant Design**:UI 组件库
|
|
83
|
+
- **React**:前端框架
|
|
84
|
+
- **TypeScript**:类型支持
|
|
85
|
+
- **Neo Open API**:数据操作 SDK
|
|
86
|
+
|
|
87
|
+
### 数据流程
|
|
88
|
+
|
|
89
|
+
1. **初始化**:组件挂载时获取字段描述和业务类型列表
|
|
90
|
+
2. **表单生成**:根据字段描述动态生成表单项
|
|
91
|
+
3. **数据验证**:提交前进行必填字段验证
|
|
92
|
+
4. **数据提交**:使用 `xObject.create` 创建新记录
|
|
93
|
+
5. **结果反馈**:显示成功或失败提示
|
|
94
|
+
|
|
95
|
+
### 表单布局
|
|
96
|
+
|
|
97
|
+
组件支持两种布局模式:
|
|
98
|
+
|
|
99
|
+
- **单列布局**:适合字段较多或需要宽输入框的场景
|
|
100
|
+
- **双列布局**:适合字段较少或需要紧凑布局的场景
|
|
101
|
+
|
|
102
|
+
## 样式定制
|
|
103
|
+
|
|
104
|
+
组件提供了完整的 SCSS 样式文件,支持以下定制:
|
|
105
|
+
|
|
106
|
+
- 表单样式(标签、输入框、间距等)
|
|
107
|
+
- 按钮样式(颜色、大小、位置等)
|
|
108
|
+
- 成功提示样式(动画、颜色等)
|
|
109
|
+
- 响应式设计(移动端适配)
|
|
110
|
+
|
|
111
|
+
## 注意事项
|
|
112
|
+
|
|
113
|
+
1. **权限要求**:确保用户有对应 XObject 的写入权限
|
|
114
|
+
2. **必填字段**:表单会根据字段的 required 属性进行验证
|
|
115
|
+
3. **日期格式**:日期类型字段会自动转换为时间戳格式提交
|
|
116
|
+
4. **错误处理**:组件内置了完善的错误处理和用户提示
|
|
117
|
+
5. **字段过滤**:如果指定了 fields 参数,只会显示指定的字段
|
|
118
|
+
|
|
119
|
+
## 扩展开发
|
|
120
|
+
|
|
121
|
+
如需扩展功能,可以:
|
|
122
|
+
|
|
123
|
+
1. **添加字段类型支持**:在 `renderForm()` 方法中添加新的字段类型
|
|
124
|
+
2. **自定义验证规则**:在表单项的 rules 中添加自定义验证
|
|
125
|
+
3. **添加提交前处理**:在 `handleSubmit()` 方法中添加数据预处理逻辑
|
|
126
|
+
4. **自定义样式**:修改 `style.scss` 文件定制组件外观
|
|
127
|
+
5. **添加回调事件**:扩展组件 props 支持更多回调事件
|
|
128
|
+
|
|
129
|
+
## 示例场景
|
|
130
|
+
|
|
131
|
+
### 场景一:客户信息录入
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
<EntityForm
|
|
135
|
+
formTitle="新增客户"
|
|
136
|
+
xObjectDataApi={{
|
|
137
|
+
xObjectApiKey: 'account',
|
|
138
|
+
fields: ['name', 'industry', 'phone', 'email', 'website'],
|
|
139
|
+
}}
|
|
140
|
+
columnCount={2}
|
|
141
|
+
onSuccess={(data) => {
|
|
142
|
+
message.success('客户创建成功');
|
|
143
|
+
// 跳转到客户详情页
|
|
144
|
+
}}
|
|
145
|
+
/>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 场景二:联系人快速录入
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
<EntityForm
|
|
152
|
+
formTitle="新增联系人"
|
|
153
|
+
xObjectDataApi={{
|
|
154
|
+
xObjectApiKey: 'customContact__c',
|
|
155
|
+
fields: ['name', 'phone__c', 'email__c'],
|
|
156
|
+
}}
|
|
157
|
+
columnCount={1}
|
|
158
|
+
showResetButton={true}
|
|
159
|
+
/>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 场景三:自定义对象数据录入
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
<EntityForm
|
|
166
|
+
formTitle="新增订单"
|
|
167
|
+
xObjectDataApi={{
|
|
168
|
+
xObjectApiKey: 'customOrder__c',
|
|
169
|
+
}}
|
|
170
|
+
columnCount={2}
|
|
171
|
+
onSuccess={(data) => {
|
|
172
|
+
console.log('订单创建成功:', data);
|
|
173
|
+
}}
|
|
174
|
+
/>
|
|
175
|
+
```
|
|
176
|
+
|