8000 GitHub - thinkgem/jeesite: ðŸ‘Java 低代ç , è½»é‡çº§, Spring Boot, MyBatis, Flowable, TypeScript, Vue, Antdv, 包括核心模å—如:组织机构ã€è§’è‰²ç”¨æˆ·ã€æƒé™æŽˆæƒã€æ•°æ®æƒé™ã€å†…容管ç†ã€å·¥ä½œæµã€Spring Cloud å¾®æœåŠ¡ç­‰ã€‚
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

ðŸ‘Java 低代ç , è½»é‡çº§, Spring Boot, MyBatis, Flowable, TypeScript, Vue, Antdv, 包括核心模å—如:组织机构ã€è§’è‰²ç”¨æˆ·ã€æƒé™æŽˆæƒã€æ•°æ®æƒé™ã€å†…容管ç†ã€å·¥ä½œæµã€Spring Cloud å¾®æœåŠ¡ç­‰ã€‚

License

Notifications You must be signed in to change notification settings

thinkgem/jeesite

Repository files navigation

JeeSite

JeeSite Vue3 å‰ç«¯æºç 
使用 Turborepoã€Monorepoã€pnpm
å¿«é€Ÿæž„å»ºã€æ¨¡å—化ã€ä»£ç å¤ç”¨ã€é«˜æ•ˆç®¡ç†

TypeScript-Vue3 Ant Design Vue-V4.2 JeeSite-V5.x star star star star


如果你喜欢 JeeSite,请给她一个 â­ï¸ Star,您的支æŒå°†æ˜¯æˆ‘们å‰è¡Œçš„动力。

  1. å•仓多包 pnpm + Turborepo 涡轮增压,æå‡ç¼–译速度,方便统一管ç†è„šæœ¬ä»»åŠ¡
  2. 按功能模å—进行拆分为ä¸åŒçš„åŒ…ï¼Œæ–¹ä¾¿è¿›è¡Œå›¢é˜Ÿå¼€å‘æºç ç®¡ç†ï¼Œå¯æ ¹æ®éœ€è¦è¿›è¡Œå‘包
  3. 模å—之间æ¾è€¦åˆï¼Œå•ä¾èµ–,公共模å—,公共组件,公共工具,方便代ç å¤ç”¨
  4. 坿–¹ä¾¿ä»Žä¼ ç»Ÿæž¶æž„版本,å‡çº§åˆ° Monorepo 模å—化ã€åˆ†åŒ…æž¶æž„

技术交æµ

  JeeSite微信公众å·

  • QQ 群:127515876ã€209330483ã€223507718ã€709534275ã€730390092ã€1373527ã€183903863(外包)
  • 微信群:如果二维ç è¿‡æœŸï¼Œè¯·å°è¯•点击图片并F5刷新,或者添加客æœå¾®ä¿¡ jeesitex 邀请您进群

  JeeSite微信群

å¹³å°ä»‹ç»

  • JeeSite 快速开å‘å¹³å°ï¼Œä½Žä»£ç ï¼Œè½»é‡çº§ï¼Œä¸ä»…仅是一个åŽå°å¼€å‘框架,它是一个ä¼ä¸šçº§å¿«é€Ÿå¼€å‘解决方案,åŽç«¯åŸºäºŽç»å…¸ç»„åˆ Spring Bootã€Shiroã€MyBatis,å‰ç«¯é‡‡ç”¨åˆ†ç¦»ç‰ˆ Vue3ã€Viteã€Monorepoã€Ant Design Vueã€TypeScriptã€Vben Admin 最先进技术栈,或者 Beetlã€Bootstrapã€AdminLTE ç»å…¸å¼€å‘模å¼ã€‚

  • æä¾›åœ¨çº¿æ•°æ®æºç®¡ç†ã€æ•°æ®è¡¨å»ºæ¨¡ã€ä»£ç ç”Ÿæˆç­‰åŠŸèƒ½ï¼Œå¯è‡ªåŠ¨åˆ›å»ºä¸šåŠ¡æ¨¡å—代ç å·¥ç¨‹å’Œå¾®æœåŠ¡æ¨¡å—代ç å·¥ç¨‹ï¼Œè‡ªåŠ¨ç”Ÿæˆå‰ç«¯ä»£ç å’ŒåŽç«¯ä»£ç ï¼›åŒ…括核心功能模å—如:组织机构ã€ç”¨æˆ·ã€è§’色ã€å²—ä½ã€ç®¡ç†å‘˜ã€æƒé™å®¡è®¡ã€èœå•åŠæŒ‰é’®æƒé™ã€æ•°æ®æƒé™ã€æ¨¡å—管ç†ã€ç³»ç»Ÿå‚æ•°ã€å­—典管ç†ã€ç³»ç»Ÿç›‘æŽ§ã€æ•°æ®ç›‘控等;扩展功能如:工作æµå¼•擎ã€å†…容管ç†ã€æ¶ˆæ¯æŽ¨é€ã€å•点登录ã€ç¬¬ä¸‰æ–¹ç™»å½•ã€åœ¨çº¿ä½œä¸šè°ƒåº¦ã€å¯¹è±¡å­˜å‚¨ã€å¯è§†åŒ–æ•°æ®å¤§å±ã€æŠ¥è¡¨è®¾è®¡å™¨ã€åœ¨çº¿æ–‡ä»¶é¢„览ã€å›½é™…化ã€å…¨æ–‡æ£€ç´¢ã€ç»Ÿä¸€è®¤è¯æœåŠ¡ç­‰ã€‚

  • 本平å°é‡‡ç”¨æ¾è€¦åˆè®¾è®¡ï¼ŒçœŸæ­£çš„è½»é‡çº§ï¼Œå¾®å†…核,快速部署,æ’件架构,模å—增å‡ä¾¿æ·ï¼Œæ”¯æŒæ‰©å±• SaaS æž¶æž„ã€é›†ç¾¤éƒ¨ç½²ã€è¯»å†™åˆ†ç¦»ã€åˆ†åº“分表ã€Spring Cloud å¾®æœåŠ¡æž¶æž„ï¼›å¹¶å†…ç½®äº†ä¼—å¤šè´¦å·å®‰å…¨è®¾ç½®ã€å¯†ç ç­–ç•¥ã€ç³»ç»Ÿè®¿é—®é™åˆ¶ç­‰å®‰å…¨è§£å†³æ–¹æ¡ˆï¼Œæ”¯æŒç­‰ä¿è¯„测。

  • 本平å°ä¸“注于为åˆçº§ç ”å‘人员æä¾›å¼ºå¤§çš„æ”¯æŒï¼Œä½¿ä»–们能够高效ã€å¿«é€Ÿåœ°å¼€å‘å‡ºå¤æ‚çš„ä¸šåŠ¡åŠŸèƒ½ï¼ŒåŒæ—¶ä¸ºä¸­é«˜çº§äººå‘˜è…¾å‡ºå®è´µçš„æ—¶é—´ï¼Œä¸“注于更具战略性和创新性的任务。我们致力于让开å‘者能够全心投入业务逻辑中,而将ç¹ççš„æŠ€æœ¯ç»†èŠ‚äº¤ç”±å¹³å°æ¥å°è£…处ç†ã€‚è¿™ä¸ä»…é™ä½Žäº†æŠ€æœ¯å®žçŽ°çš„éš¾åº¦ï¼Œè¿˜ç¡®ä¿äº†ç³»ç»Ÿæž¶æž„的稳定性和安全性,进而帮助ä¼ä¸šèŠ‚çœäººåŠ›æˆæœ¬ã€ç¼©çŸ­é¡¹ç›®å‘¨æœŸï¼Œå¹¶æé«˜æ•´ä½“软件的安全性和质é‡ã€‚

  • 2013 å¹´å‘布以æ¥å·²è¢«å¹¿å¤§çˆ±å¥½è€…用到了ä¼ä¸šã€æ”¿åºœã€åŒ»ç–—ã€é‡‘èžã€äº’è”网等å„ä¸ªé¢†åŸŸä¸­ï¼Œæ‹¥æœ‰ï¼šç²¾è‰¯æž¶æž„ã€æ˜“于扩展ã€å¤§ä¼—æ€ç»´çš„设计模å¼ï¼Œå·¥åŒ ç²¾ç¥žï¼Œç”¨å¿ƒæ‰“磨æ¯ä¸€ä¸ªç»†èŠ‚ï¼Œæ·±å…¥å¼€å‘者的内心,并è£èŽ·å¼€æºä¸­å›½ã€Šæœ€å—欢迎中国开æºè½¯ä»¶ã€‹å¤šæ¬¡å¥–项,期间也帮助了ä¸å°‘刚毕业的大学生,教师作为入门教æï¼Œå¿«é€Ÿçš„去实践。

  • 2019 å¹´æ¢ä»£å‡çº§ï¼Œæˆ‘们结åˆäº†å¤šå¹´æ€»ç»“å’Œç»éªŒï¼Œä»¥åŠå„æ–¹é¢çš„应用案例,对架构完æˆäº†ä¸€æ¬¡å…¨éƒ¨é‡æž„,也纳入很多新的æ 9E88 €æƒ³ã€‚ä¸ç®¡æ˜¯ä»Žå¼€å‘者模å¼ã€åº•层架构ã€é€»è¾‘处ç†è¿˜æ˜¯åˆ°ç”¨æˆ·ç•Œé¢ï¼Œç”¨æˆ·äº¤äº’体验上都有很大的进步,在ä¸å¿˜å­¦ä¹ æˆæœ¬ã€æé«˜å¼€å‘效率的情况下,安全方é¢ä¹Ÿåšå’Œå¾ˆå¤šå·¥ä½œï¼ŒåŒ…括:身份认è¯ã€å¯†ç ç­–ç•¥ã€å®‰å…¨å®¡è®¡ã€æ—¥å¿—收集等众多安全选项供您选择。努力为大中å°å¾®ä¼ä¸šæ‰“造全方ä½ä¼ä¸šçº§å¿«é€Ÿå¼€å‘解决方案。

  • 2021 年终å‘布 Vue3 çš„å‰åŽåˆ†ç¦»ç‰ˆæœ¬ï¼Œä½¿å¾— JeeSite 拥有åŒä¸€ä¸ªåŽå°æœåŠ¡ Web æ¥æ”¯æ’‘分离版和全栈版两套å‰ç«¯æŠ€æœ¯æ ˆã€‚

  • å¯¹æŽ¥å¸¸è§ AI 大模型(OpenAPIã€Ollamaã€DeepSeekç­‰ï¼‰ï¼Œæ”¯æŒæ£€ç´¢å¢žå¼ºç”Ÿæˆ RAG 技术,实现ä¼ä¸šçŸ¥è¯†åº“智能对è¯ã€‚

  • 支æŒå›½äº§åŒ–è½¯ç¡¬ä»¶çŽ¯å¢ƒï¼Œå¦‚å›½äº§èŠ¯ç‰‡ã€æ“ä½œç³»ç»Ÿã€æ•°æ®åº“ã€ä¸­é—´ä»¶ã€å›½å¯†ç®—法等。

核心优势

  • JeeSite éžå¸¸æ˜“于二次开å‘ï¼Œå¯æŽ§æ€§é«˜ï¼Œæ•´ä½“æž¶æž„æ¸…æ™°ã€æŠ€æœ¯ç¨³å®šè€Œå…ˆè¿›ã€æºä»£ç ä¹¦å†™è§„范ã€ç»å…¸æŠ€æœ¯ä¼šçš„äººå¤šã€æ˜“äºŽç»´æŠ¤ã€æ˜“于扩展ã€å®‰å…¨ç¨³å®šã€‚

  • JeeSite 功能全,知识点éžå¸¸å¤šï¼Œä¹Ÿéžå¸¸å°‘。因为她使用的都是一些通用的技术,通俗的设计风格,大多数基础知识点,多数人都能掌æ¡ï¼Œæ‰€ä»¥æ¯ä¸€ä¸ª JeeSite 的功能点都éžå¸¸å®¹æ˜“掌æ¡ã€‚åªè¦æ‚¨å­¦ä¼šä½¿ç”¨è¿™äº›åŠŸèƒ½å’Œç»„ä»¶çš„åº”ç”¨ï¼Œå°±å¯ä»¥é¡ºåˆ©åœ°å®Œæˆç³»ç»Ÿå¼€å‘了。

  • JeeSite 是一个低代ç å¼€å‘å¹³å°ï¼Œå…·æœ‰è¾ƒé«˜çš„å°è£…åº¦ã€æ‰©å±•性,å°è£…䏿˜¯é™åˆ¶æ‚¨åŽ»åšä¸€äº›äº‹æƒ…,而是在便æ·çš„åŒæ—¶ï¼Œä¹Ÿå…·æœ‰è¾ƒå¥½çš„æ‰©å±•性,在ä¸å…·å¤‡ä¸€äº›åŠŸèƒ½çš„æƒ…å†µä¸‹ï¼ŒJeeSite æä¾›äº†æ‰©å±•接å£ï¼Œæä¾›äº†åŽŸç”Ÿè°ƒç”¨æ–¹æ³•ã€‚

  • 大家都在用 Spring,也在学习 Spring 的优点,Spring æä¾›äº†è¾ƒå¥½çš„æ‰©å±•性,å¯åˆæœ‰å¤šå°‘人去修改它的æºä»£ç å‘¢ï¼Œé€€ä¸€æ­¥è¯´ï¼Œå¤§å®¶åŽ»ä¿®æ”¹äº† Spring çš„æºç ï¼Œå而会对未æ¥å‡çº§é€ æˆå¾ˆå¤§å›°æ‰°ï¼Œæ‚¨è¯´ä¸æ˜¯å‘¢ï¼Ÿè¿™æ ·çš„例å­å¾ˆå¤šï¼Œæ‰€ä»¥ä¸è¦çº ç»“,我们éžå¸¸æ³¨é‡è¿™ä¸€ç‚¹ï¼ŒJeeSite 也一样具备强大的扩展性。为你解决å‡çº§çš„困扰。

  • 为什么说 JeeSite 比较易于学习?JeeSite 很好的把æ¡äº†è®¾è®¡çš„ “度â€ï¼Œé¿å…过度设计的情况。过度设计是在产å“设计过程中忽略了产å“和用户的实际需求,å而带æ¥äº†ä¸å¿…è¦çš„夿‚性,而忽略了系统的学习ã€å¼€å‘å’Œç»´æŠ¤æˆæœ¬ã€‚


  • 至今 JeeSite 平尿ž¶æž„å·²ç»éžå¸¸ç¨³å®šï¼Œæˆ‘们æŒç»­å‡çº§ï¼Œå¹¶ä¸å¤±æž¶æž„的先进性。
  • JeeSite 精益求精,用心打磨æ¯ä¸€ä¸ªç»†èŠ‚ï¼Œç•Œé¢ UI æ“作便æ·ï¼Œä½“验性好。
  • JeeSite 是一个专业的平å°ï¼Œæ˜¯ä¸€ä¸ªå¯ä»¥è®©æ‚¨ä½¿ç”¨æ”¾å¿ƒçš„å¹³å°ã€‚
  • 社区版基于 Apache License 2.0 å¼€æºå议,永久å…费使用。

架构特点åŠå®‰å…¨æ–¹é¢çš„优势:https://jeesite.com/docs/feature/

Vue å‰ç«¯ç®€ä»‹

基于 Vue3ã€Viteã€Ant-Design-Vueã€TypeScript å’Œ Vue Vben Admin ç­‰å‰æ²¿æŠ€æœ¯æ ˆæž„建,本软件采用最先进的技术架构, 帮助åˆå­¦è€…快速上手并èžå…¥å›¢é˜Ÿå¼€å‘。内置组织机构ã€è§’色用户ã€èœå•授æƒã€æ•°æ®æƒé™ã€ç³»ç»Ÿå‚数等核心模å—,结åˆå¼ºå¤§çš„组件å°è£… 与数æ®é©±åŠ¨è§†å›¾è®¾è®¡ï¼Œä¸ºå¾®å°ã€ä¸­å¤§åž‹é¡¹ç›®æä¾›å¼€ç®±å³ç”¨çš„解决方案和丰富的示例,助力高效开å‘。

用户界é¢ä¸“为信æ¯åŒ–管ç†åŽå°é‡èº«æ‰“造,在界é¢è®¾è®¡ä¸Šç²¾ç›Šæ±‚精,æ¯ä¸€å¤„细节都彰显ç€ç²¾è‡´ï¼Œä¸ºç”¨æˆ·å¸¦æ¥ä¼˜é›…且直观的æ“作体验。 它æä¾›å¤šæ ·åŒ–çš„èœå•å¸ƒå±€ã€æ™ºèƒ½çš„页签管ç†ã€é«˜æ•ˆçš„æ ‘表æ“作体验ã€å¼ºå¤§çš„表格组件ã€çµæ´»çš„表å•组件设计,具备强大的扩展能力, åŒæ—¶æ”¯æŒé»‘暗布局风格,为用户æä¾›é«˜æ•ˆã€çµæ´»ä¸”美观的æ“作体验,满足å„类管ç†åŽå°çš„夿‚需求。

å¦å¤–æˆ‘ä»¬è¿˜æ”¯æŒ Turborepo + Monorepo å¿«é€Ÿæž„å»ºã€æ¨¡å—化ã€ä»£ç å¤ç”¨ã€æ”¯æŒåˆ†åŒ…å¼€å‘ è¯¦è§ï¼šhttps://gitee.com/thinkgem/jeesite-vue/tree/monorepo/

å‰ç«¯æŠ€æœ¯ç‰¹ç‚¹

定义众多组件,éžå¸¸è´´å¿ƒçš„组件属性åŠå°åŠŸèƒ½ï¼Œç¬¦åˆ JeeSite ä»¥å¾€çš„è®¾è®¡æ€æƒ³ï¼Œåˆ—表和表å•以数æ®é©±åŠ¨è§†å›¾ï¼Œ æžå¤§ç®€åŒ–了业务功能开å‘, 注释分解详è§ã€æºç è§£æžã€‘

ä¸ºä»€ä¹ˆåšæ•°æ®é©±åŠ¨è§†å›¾ï¼Ÿå‰ç«¯å‘下兼容一直是最大的问题,有了一套相应的标准,会对框架å‡çº§å¸®åŠ©å¾ˆå¤§ã€‚ 比如你å¯ä»¥éžå¸¸å°çš„æˆæœ¬ï¼Œä¸šåŠ¡ä»£ç æ”¹åЍéžå¸¸å°çš„æƒ…况下,去å‡çº§å‰ç«¯ï¼›æ•°æ®é©±åŠ¨è§†å›¾å¯ä»¥ä¸ºæœªæ¥è‡ªå®šä¹‰æ‹–拽表å•åšæ›´å¥½çš„铺垫, æ•°æ®å­˜å‚¨ç»“构更清晰化,更利于维护。

æç¤ºï¼šè¯·ä»”细阅读æºç è§£æžï¼Œè¡¨å•è§†å›¾å’Œåˆ—è¡¨è§†å›¾ä¸Šçš„æ³¨é‡Šå“¦ï¼Œå¤æ‚表å•å¯ä»¥å¤šè¡¨å•è”åˆä½¿ç”¨ã€‚

演示地å€

  1. 地å€ï¼šhttp://vue.jeesite.com/

学习准备

  • VSCode - 推è IDE 集æˆå¼€å‘工具
  • Node.js 18 å’Œ git - å¼€å‘环境
  • Vite - 熟悉 Vite 特性
  • Vue-v3 - 熟悉 Vue 基础语法
  • TypeScript - 熟悉 TS 基本语法
  • ES6+ - 熟悉 ES6 基本语法
  • Vue-Router-v4 - 熟悉 vue-router 基本使用
  • Vue-Vben-Admin - 熟悉 UI åŠè¡¨å•列表åŠå¸¸ç”¨ç»„件使用
  • Ant-Design-Vue - 熟悉 UI 基本使用

安装使用

  • 如果没有安装 Node.js 18+,下载地å€ï¼šhttps://nodejs.org
# 验è¯
node -v
# é…置国内æº
npm config set registry https://registry.npmmirror.com
  • 如果没有安装 Pnpm 执行安装
npm i -g pnpm
# 验è¯
pnpm -v
# é…置国内æº
pnpm config set registry https://registry.npmmirror.com
  • èŽ·å–æºä»£ç 
git clone https://gitee.com/thinkgem/jeesite-vue.git
cd jeesite-vue

注æ„:ä¸è¦æ”¾åˆ°ä¸­æ–‡æˆ–带空格的目录下。

  • 安装ä¾èµ–
pnpm install
  • å¼€å‘环境è¿è¡Œè®¿é—®ï¼ˆæ–¹å¼ä¸€ï¼‰
pnpm dev

å¼€å‘环境会加载文件较多,便于调试,请è€å¿ƒç­‰å¾…。

  • 编译打包åŽè¿è¡Œè®¿é—®ï¼ˆæ–¹å¼äºŒï¼‰
pnpm preview

编译打包åŽï¼Œä¼šæ•´åˆè¿™äº›æ–‡ä»¶ï¼Œæ‰€ä»¥è®¿é—®æ€§èƒ½ä¼šå¤§å¤§æé«˜ï¼Œç”Ÿäº§çŽ¯å¢ƒå¯ä»¥å¼€å¯ gzip

  • 打包å‘布程åº
pnpm build

打包完æˆåŽï¼Œä¼šåœ¨æ ¹ç›®å½•ç”Ÿæˆ dist 文件夹,å‘布 nginx。

è¯¦è§æ–‡æ¡£ï¼šhttps://jeesite.com/docs/vue-install-deploy/#éƒ¨ç½²åˆ°æ­£å¼æœåС噍

åŽç«¯æœåŠ¡

# 代ç†è®¾ç½®ï¼Œå¯é…置多个,ä¸èƒ½æ¢è¡Œï¼Œæ ¼å¼ï¼š[访问接å£çš„æ ¹è·¯å¾„, 代ç†åœ°å€, 是å¦ä¿æŒHost头]
# VITE_PROXY = [["/js","https://vue.jeesite.com/js",true]]
VITE_PROXY = [["/js","http://127.0.0.1:8980/js",false]]

# 访问接å£çš„æ ¹è·¯å¾„(例如:https://vue.jeesite.com)
VITE_GLOB_API_URL = 

# 访问接å£çš„å‰ç¼€ï¼Œåœ¨æ ¹è·¯å¾„之åŽ
VITE_GLOB_API_URL_PREFIX = /js

如果您使用的 VSCode çš„è¯ï¼ŒæŽ¨è安装以下æ’件:

  • UnoCSS - UnoCSS æç¤ºæ’ä»¶
  • Iconify - Iconify 图标æ’ä»¶
  • I18n-ally - i18n æ’ä»¶
  • Volar - Vue3 å¼€å‘必备(Veturç¦ç”¨ï¼‰
  • ESLint - è„šæœ¬ä»£ç æ£€æŸ¥
  • Prettier - ä»£ç æ ¼å¼åŒ–
  • Stylelint - CSS æ ¼å¼åŒ–
  • DotENV - .env 文件高亮

常è§é—®é¢˜

  • Vue 版本的æµè§ˆå™¨æ”¯æŒæƒ…å†µï¼šæ”¯æŒæ‰€æœ‰çް代æµè§ˆå™¨ï¼ŒVue3 å·²ä¸å†æ”¯æŒ IE æµè§ˆå™¨ã€‚
  • 为什么使用抽屉作为表å•组件,因为抽屉空间更大,å¯ä»¥å±•示更多内容,且æ“作更å‹å¥½ã€‚
  • å¦‚ä½•å°†è¡¨å•æŠ½å±‰æ”¹ä¸ºå¼¹çª—ï¼Œæ›¿æ¢ list å’Œ form 页é¢çš„ Drawer 为 Modal å³å¯ï¼ŒV5.6增加了路由表å•和弹窗表å•的代ç ç”Ÿæˆã€‚
  • 打ä¸å¼€ä»£ç ç”Ÿæˆå·¥å…·æ€Žä¹ˆåŠžï¼Ÿæç¤º 404,请检查 .env.development 中的代ç†é…ç½® VITE_PROXY 最åŽä¸€ä¸ªå‚数(是å¦ä¿æŒHost头),本地æœåŠ¡ 127.0.0.1 应设置为 false,远程æœåŠ¡è®¾ç½®ä¸º true。

软件截图

附录

表å•视图

<template>
  <!-- 弹出抽屉组件,如果想改为弹窗,Drawer æ¢ä¸º Modal å³å¯å¿«é€Ÿæ›¿æ¢ -->
  <BasicDrawer
    v-bind="$attrs"    -- 传递æ¥è‡ªçˆ¶ç»„件的属性
    :showFooter="true" -- 显示弹窗底部按钮组
    :okAuth="'test:testData:edit'" -- æäº¤æŒ‰é’®æƒé™ï¼ŒæŽ§åˆ¶æŒ‰é’®æ˜¯å¦æ˜¾ç¤º
    @register="registerDrawer"     -- 弹窗åŽçš„回调方法
    @ok="handleSubmit" -- æäº¤æŒ‰é’®è°ƒç”¨æ–¹æ³•
    width="60%"        -- å¼¹çª—å®½åº¦ï¼Œæ”¯æŒæŒ‰æ¯”例
  >
    <!-- 弹窗标题 -->
    <template #title>
      <Icon :icon="getTitle.icon" class="pr-1 m-1" /> -- 图标
      <span> {{ getTitle.value }} </span>  -- 标题åç§°
    </template>
    <!-- 表å•组件 -->
    <BasicForm @register="registerForm">
      <!-- å®šä¹‰è¡¨å•æŽ§ä»¶æ’æ§½ã€ä¸ªæ€§åŒ–è¡¨å•æŽ§ä»¶ï¼Œå¦‚ï¼šè¿™æ˜¯ä¸€ä¸ªè¡¨å•å­è¡¨æ’æ§½ -->
      <template #testDataChildList>
        <BasicTable
          @register="registerTestDataChildTable"
          @row-click="handleTestDataChildRowClick"
        />
        <!-- å­è¡¨æ–°å¢žæŒ‰é’® -->
        <a-button class="mt-2" @click="handleTestDataChildAdd">
          <Icon icon="i-ant-design:plus-circle-outlined" /> {{ t('新增') }}
        </a-button>
      </template>
    </BasicForm>
  </BasicDrawer>
</template>
<!-- script name: 当å‰ç»„ä»¶å称(与路由å一致,如果ä¸ä¸€è‡´ä¼šé¡µé¢ç¼“存失效)-->
<script lang="ts" setup name="ViewsTestTestDataForm">

  // 导入当å‰ç”¨åˆ°çš„对象,部分çœç•¥
  import { ref, unref, computed } from 'vue';
  import { officeTreeData } from '/@/api/sys/office';

  // 页é¢äº‹ä»¶å®šä¹‰
  const emit = defineEmits(['success', 'register']);

  // å›½é™…åŒ–æ–¹æ³•è°ƒç”¨ï¼Œå‚æ•°æ˜¯å›½é™…化编ç çš„æ ¹è·¯å¾„
  const { t } = useI18n('test.testData');

  // 消æ¯å¼¹çª—方法
  const { showMessage } = useMessage();

  // 路由metaä¿¡æ¯
  const { meta } = unref(router.currentRoute);

  // 当å‰é¡µé¢æ•°æ®è®°å½•
  const record = ref<Recordable>({});

  // 当å‰é¡µé¢æ ‡é¢˜å®šä¹‰ï¼Œæ¥è‡ªèœå•管ç†å®šä¹‰
  const getTitle = computed(() => ({
    icon: meta.icon || 'ant-design:book-outlined',
    value: record.value.isNewRecord ? t('新增数æ®') : t('编辑数æ®'),
  }));

  // è¾“å…¥è¡¨å•æŽ§ä»¶å®šä¹‰
  const inputFormSchemas: FormSchema[] = [
    {
      label: t('å•行文本'), // 控件å‰é¢çš„页签
      field: 'testInput',  // 字段æäº¤å‚æ•°å
      component: 'Input',  // 控件类型(å¯è‡ªå®šä¹‰ï¼Œæ›´å¤šæŸ¥çœ‹ componentMap.ts )
      componentProps: {    // 组件属性定义
        maxlength: 200,
      },
      required: true,      // 表å•验è¯ï¼Œæ˜¯å¦å¿…填(快速定义)
      rules: [             // 如果ä¸åªæ˜¯å¿…填,需è¦é€šè¿‡ rules 定义,举例:
        { required: true },
        { min: 4, max: 20, message: t('请输入长度在 4 到 20 个字符之间') },
        { pattern: /^[\u0391-\uFFE5\w]+$/, message: t('ä¸èƒ½è¾“入特殊字符') },
        {
          validator(_rule, value) {
             return new Promise((resolve, reject) => {
              if (!value || value === '') return resolve();
              // 远程验è¯ï¼Œè®¿é—®åŽå°æ ¡éªŒæ•°æ®æ˜¯å¦é‡å¤
              checkTestInput(record.value.testInput || '', value)
                .then((res) => (res ? resolve() : reject(t('æ•°æ®å·²å­˜åœ¨'))))
                .catch((err) => reject(err.message || t('验è¯å¤±è´¥')));
            });
          },
          trigger: 'blur', // 如果是远程验è¯ï¼Œå¯ä»¥å‡å°‘请求频率
        },
      ],
      colProps: { lg: 24, md: 24 }, // 栅格布局(éµå¾ª Ant Design 风格)
    },
    {
      label: t('下拉框'),
      field: 'testSelect',
      component: 'Select',    // 选择框还有 RadioGroupã€CheckboxGroup
      componentProps: {
        dictType: 'sys_menu_type', // 下拉框选项数æ®ï¼ˆæ”¯æŒç›´æŽ¥æŒ‡å®šå­—典类型)
        allowClear: true,          // å¯ç”¨ç©ºé€‰é¡¹ï¼Œå¯æ¸…空选择
        mode: 'multiple',          // 下拉框模å—,å¯ç”¨å¤šé€‰
      },
    },
    {
      label: t('日期选择'),
      field: 'testDate',
      component: 'DatePicker',
      componentProps: {
        format: 'YYYY-MM-DD',      // 日期选择
        showTime: false,           // 关闭时间选择
      },
    },
    {
      label: t('日期时间'),
      field: 'testDatetime',
      component: 'DatePicker',
      componentProps: {
        format: 'YYYY-MM-DD HH:mm',    // 日期时间选择
        showTime: { format: 'HH:mm' }, // 设置时间的格å¼
      },
    },
    {
      label: t('用户选择'),
      field: 'testUser.userCode',
      fieldLabel: 'testUser.userName', //ã€æ”¯æŒè¿”回,如下拉框或树选择的节点å】
      component: 'TreeSelect',         // 树选择控件
      componentProps: {
        api: officeTreeData,           // æ•°æ®æº API å®šä¹‰ï¼Œæ”¯æŒ ztree æ ¼å¼
        params: { isLoadUser: true, userIdPrefix: '' }, // API 傿•°
        canSelectParent: false,        // 是å¦å…许选择父级
        allowClear: true,
      },
    },
    {
      label: t('å­è¡¨æ•°æ®'),
      field: 'testDataChildList',
      component: 'Input',
      colProps: { lg: 24, md: 24 },
      slot: 'testDataChildList',      // æŒ‡å®šæ’æ§½ã€ä¸ªæ€§åŒ–控件内容
    },
  ];

  // 当å‰è¡¨å•çš„å‚æ•°å®šä¹‰
  const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
    labelWidth: 120,                  // 控件å‰é¢çš„æ ‡ç­¾å®½åº¦
    schemas: inputFormSchemas,        // 控件定义列表
    baseColProps: { lg: 12, md: 24 }, // 控件默认栅格布局方å¼ï¼ˆå“应å¼ï¼‰
  });

  // 当å‰è¡¨å•å­è¡¨æ ¼å®šä¹‰
  const [registerTestDataChildTable, testDataChildTable] = useTable({
    actionColumn: {  // å­è¡¨çš„æ“ä½œåˆ—å®šä¹‰
      width: 60,     // æ“作列宽度
      actions: (record: Recordable) => [
        {
          icon: 'i-ant-design:delete-outlined',
          color: 'error',
          popConfirm: { // 是å¦éœ€è¦å¯ç”¨ç¡®è®¤æ¡†
            title: '是å¦ç¡®è®¤åˆ é™¤',
            confirm: handleTestDataChildDelete.bind(this, record),
          },
          auth: 'sys:empUser:edit',  // 按钮æƒé™ï¼ˆå¯æŽ§åˆ¶æŒ‰é’®æ˜¯å¦æ˜¾ç¤ºï¼‰
        },
      ],
    },
    rowKey: 'id',     // å­è¡¨ä¸»é”®å
    pagination: false,// 关闭分页
    bordered: true,   // å¼€å¯è¡¨æ ¼è¾¹æ¡†
    size: 'small',    // å•元格间è·
    inset: true,      // 是å¦å†…嵌(去除一些边è·ï¼‰
  });

  // 当å‰è¡¨å•å­è¡¨è‡ªåŠ¨å®šä¹‰
  async function setTestDataChildTableData(_res: Recordable) {
    testDataChildTable.setColumns([
      {
        title: t('å•行文本'),
        dataIndex: 'testInput',
        width: 230,
        align: 'left',
        editRow: true,          // 是å¦å¯ç”¨ç¼–辑
        editComponent: 'Input', // 编辑控件(å¯è‡ªå®šä¹‰ï¼Œæ›´å¤šæŸ¥çœ‹ componentMap.ts )
        editRule: true,         // 控件验è¯ï¼ˆæ˜¯å¦å¿…填)
      },
      {
        title: t('下拉框'),
        dataIndex: 'testSelect',
        width: 130,
        align: 'left',
        dictType: 'sys_menu_type',   // 指定字典类型,自动显示字典标签
        editRow: true,
        editComponent: 'Select',
        editComponentProps: {        // 控件属性
          dictType: 'sys_menu_type', // 下拉框的字段类型
          allowClear: true,
        },
        editRule: false,
      },
      // 更多组件控件ä¸ä¸¾ä¾‹äº†ï¼ŒåŒè¡¨å•控件 ...
    ]);
    // 设定å­è¡¨æ•°æ®
    testDataChildTable.setTableData(record.value.testDataChildList || []);
  }

  // 点击行,å¯ç”¨ç¼–辑
  function handleTestDataChildRowClick(record: Recordable) {
    record.onEdit?.(true, false);
  }

  // æ·»åŠ ç¼–è¾‘è¡Œï¼Œå¯æŒ‡å®šåˆå§‹æ•°æ®
  function handleTestDataChildAdd() {
    testDataChildTable.insertTableDataRecord({
      id: new Date().getTime(),
      isNewRecord: true,
      editable: true,
    });
  }

  // 删除编辑行方法
  function handleTestDataChildDelete(record: Recordable) {
    testDataChildTable.deleteTableDataRecord(record);
  }

  // 获å–å­è¡¨æ•°æ®ï¼ˆæ”¯æŒè¿”回删除未æäº¤çš„æ•°æ®ï¼‰
  async function getTestDataChildList() {
    let testDataChildListValid = true;
    let testDataChildList: Recordable[] = [];
    for (const record of testDataChildTable.getDataSource()) {
      // éªŒè¯æŽ§ä»¶å†…å®¹ï¼Œå¹¶å–æ¶ˆè¡Œçš„编辑状æ€ï¼ˆå¦‚果验è¯å¤±è´¥è¿”回false)
      if (!(await record.onEdit?.(false, true))) {
        testDataChildListValid = false;
      }
      testDataChildList.push({
        ...record,
        id: !!record.isNewRecord ? '' : record.id,
      });
    }
    for (const record of testDataChildTable.getDelDataSource()) {
      if (!!record.isNewRecord) continue;
      testDataChildList.push({
        ...record,
        status: '1',
      });
    }
    // å­è¡¨éªŒè¯äº‹ä»¶ï¼ŒæŠ›å‡ºå¼‚常消æ¯
    if (!testDataChildListValid) {
      throw { errorFields: [{ name: ['testDataChildList'] }] };
    }
    return testDataChildList;
  }

  // 弹窗åŽçš„å›žè°ƒäº‹ä»¶ï¼Œè¿›è¡Œä¸€äº›è¡¨å•æ•°æ®åˆå§‹åŒ–ç­‰æ“作
  const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
    resetFields(); // é‡ç½®è¡¨å•æ•°æ®
    setDrawerProps({ loading: true }); // 显示加载框
    const res = await testDataForm(data); // æŸ¥è¯¢è¡¨å•æ•°æ®
    record.value = (res.testData || {}) as Recordable;
    setFieldsValue(record.value);  // 设置字段值
    setTestDataChildTableData(res);  // 设置å­è¡¨æ•°æ®ï¼ˆæ²¡æœ‰å­è¡¨å¯ä¸å†™ï¼‰
    setDrawerProps({ loading: false }); // éšè—加载框
  });

  // è¡¨å•æäº¤æŒ‰é’®æ–¹æ³•
  async function handleSubmit() {
    try {
      const data = await validate(); // 验è¯è¡¨å•,并返回数æ®
      setDrawerProps({ confirmLoading: true }); // 显示æäº¤åŠ è½½ä¸­
      // 设置æäº¤çš„傿•°ï¼ˆQueryString,åŽå° Controller çš„ get 接å—)
      const params: any = {
        isNewRecord: record.value.isNewRecord,
        id: record.value.id,
      };
      // 获å–并设置å­è¡¨æ•°æ®
      data.testDataChildList = await getTestDataChildList();
      // console.log('submit', params, data, record);
      // å°†æ•°æ®æäº¤ç»™åŽå°ï¼ˆå¦‚果失败跳转到 catch)
      const res = await testDataSave(params, data);
      showMessage(res.message); // 显示æäº¤ç»“æžœ
      setTimeout(closeDrawer);  // éšè—抽屉弹窗
      emit('success', data);    // 触å‘事件,列表数æ®åˆ·æ–°
    } catch (error: any) {
      if (error && error.errorFields) {
        showMessage(t('æ‚¨å¡«å†™çš„ä¿¡æ¯æœ‰è¯¯ï¼Œè¯·æ ¹æ®æç¤ºä¿®æ­£ã€‚'));
      }
      console.log('error', error);
    } finally {
      setDrawerProps({ confirmLoading: false }); // éšè—æäº¤åŠ è½½ä¸­
    }
  }
</script>

列表视图

<template>
  <div>
    <!-- 表格组件 -->
    <BasicTable @register="registerTable">
      <!-- è¡¨æ ¼æ ‡é¢˜æ’æ§½ -->
      <template #tableTitle>
        <Icon :icon="getTitle.icon" class="m-1 pr-1" />
        <span> {{ getTitle.value }} </span>
      </template>
      <!-- 表格å³ä¾§æŒ‰é’®æ’槽,其中 v-auth 是按钮æƒé™æŽ§åˆ¶ -->
      <template #toolbar>
        <a-button type="primary" @click="handleForm({})" v-auth="'test:testData:edit'">
          <Icon icon="i-fluent:add-12-filled" /> {{ t('新增') }}
        </a-button>
      </template>
      <!-- é¦–åˆ—æ’æ§½ -->
      <template #firstColumn="{ record }">
        <a @click="handleForm({ id: record.id })">
          {{ record.testInput }}
        </a>
      </template>
    </BasicTable>
    <!-- 点击表格行进入的输入表å•弹窗 -->
    <InputForm @register="registerDrawer" @success="handleSuccess" />
  </div>
</template>
<!-- script name: 当å‰ç»„ä»¶å称(与路由å一致,如果ä¸ä¸€è‡´ä¼šé¡µé¢ç¼“存失效)-->
<script lang="ts" setup name="ViewsTestTestDataList">

  // 导入当å‰ç”¨åˆ°çš„对象,部分çœç•¥
  import InputForm from './form.vue';

  // å›½é™…åŒ–æ–¹æ³•è°ƒç”¨ï¼Œå‚æ•°æ˜¯å›½é™…化编ç çš„æ ¹è·¯å¾„
  const { t } = useI18n('test.testData');

  // 消æ¯å¼¹çª—方法
  const { showMessage } = useMessage();

  // 路由metaä¿¡æ¯
  const { meta } = unref(router.currentRoute);

  // 当å‰é¡µé¢æ ‡é¢˜å®šä¹‰ï¼Œæ¥è‡ªèœå•管ç†å®šä¹‰
  const getTitle = {
    icon: meta.icon || 'ant-design:book-outlined',
    value: meta.title || t('æ•°æ®ç®¡ç†'),
  };

  // 表格æœç´¢è¡¨å•控件定义
  const searchForm: FormProps = {
    baseColProps: { lg: 6, md: 8 }, // è¡¨å•æ …格布局
    labelWidth: 90,                 // è¡¨å•æ ‡ç­¾å®½åº¦
    schemas: [
      {
        label: t('å•行文本'),        // è¡¨å•æ ‡ç­¾
        field: 'testInput',         // 字段æäº¤å‚æ•°å
        component: 'Input',         // è¡¨å•æŽ§ä»¶
      },
      {
        label: t('下拉框'),
        field: 'testSelect',
        component: 'Select',    // 选择框还有 RadioGroupã€CheckboxGroup
        componentProps: {
          dictType: 'sys_menu_type', // 下拉框选项数æ®ï¼ˆæ”¯æŒç›´æŽ¥æŒ‡å®šå­—典类型)
          allowClear: true,          // å¯ç”¨ç©ºé€‰é¡¹ï¼Œå¯æ¸…空选择
          mode: 'multiple',          // 下拉框模å—,å¯ç”¨å¤šé€‰
        },
      },
      // æ›´å¤šæŽ§ä»¶ï¼Œå†æ¬¡ä¸å±•示了,和上一节表å•视图一致
    ],
  };

  // 表格列定义
  const tableColumns: BasicColumn[] = [
    {
      title: t('å•行文本'),    // 表头标题
      dataIndex: 'testInput', // 表列实体属性å
      key: 'a.test_input',    // æŽ’åºæ•°æ®åº“字段å
      sorter: true,           // 点击表头是å¦å¯æŽ’åº
      width: 230,             // 列宽
      align: 'left'<
BF76
/span>,          // åˆ—çš„å¯¹é½æ–¹å¼
      // 个性化列,å¯å®šä¹‰æ’槽(如样å¼ï¼Œå¢žåŠ æŽ§ä»¶ç­‰ï¼‰
      slot: 'firstColumn',
    },
    {
      title: t('下拉框'),
      dataIndex: 'testSelect',
      key: 'a.test_select',
      sorter: true,
      width: 130,
      align: 'center',
      dictType: 'sys_menu_type', // 字典列,快速显示字典标签
    },
  ];

  // 表格æ“作列定义
  const actionColumn: BasicColumn = {
    width: 160, // æ“作列宽
    actions: (record: Recordable) => [
      {
        icon: 'i-clarity:note-edit-line',
        title: t('编辑数æ®'),
        onClick: handleForm.bind(this, { id: record.id }),
        // 按钮æƒé™æŽ§åˆ¶ï¼ŒæŒ‡å®šæƒé™å­—符串
        auth: 'test:testData:edit',
      },
      {
        icon: 'i-ant-design:stop-outlined',
        color: 'error',
        title: t('åœç”¨æ•°æ®'),
        // 是å¦éœ€è¦å¯ç”¨ç¡®è®¤æ¡†
        popConfirm: {
          title: t('是å¦ç¡®è®¤åœç”¨æ•°æ®'),
          confirm: handleDisable.bind(this, { id: record.id }),
        },
        // 按钮æƒé™æŽ§åˆ¶ï¼ŒæŒ‡å®šæƒé™å­—符串
        auth: 'test:testData:edit',
        // æŽ§åˆ¶æŒ‰é’®æ˜¯å¦æ˜¾ç¤ºï¼ˆåŒºåˆ«ï¼šshow 是显示或éšè—ï¼›ifShow 是显示或移除)
        show: () => record.status === '0',
        ifShow: () => record.status === '0',
      },
    ],
    // æ“作列更多按钮定义
    dropDownActions: (record: Recordable) => [
      {
        icon: 'i-ant-design:reload-outlined',
        label: t('é‡ç½®å¯†ç '),
        onClick: handleResetpwd.bind(this, { userCode: record.userCode }),
        auth: 'sys:empUser:resetpwd',
      },
    ],
  };

  // 点击首列或编辑按钮是的抽屉弹窗定义
  const [registerDrawer, { openDrawer }] = useDrawer();

  // 表格定义
  const [registerTable, { reload }] = useTable({
    api: testDataListData,     // è¡¨æ ¼æ•°æ®æº API
    beforeFetch: (params) => {
      return params;           // API æäº¤ä¹‹å‰çš„傿•°ä¿®æ”¹
    },
    columns: tableColumns,     // 表格列
    actionColumn: actionColumn,// æ“作列
    formConfig: searchForm,    // æœç´¢è¡¨å•
    showTableSetting: true,    // æ˜¯å¦æ˜¾ç¤ºå³ä¸Šè§’的设置按钮
    useSearchForm: true,       // æ˜¯å¦æ˜¾ç¤ºæœç´¢è¡¨å•
    canResize: true,           // 是å¦è‡ªé€‚应表å•高度
  });

  // 弹窗æ“作方法
  function handleForm(record: Recordable) {
    openDrawer(true, record);
  }

  // æ“作列åœç”¨æŒ‰é’®æ–¹æ³•
  async function handleDisable(record: Recordable) {
    const res = await testDataDisable(record);
    showMessage(res.message);
    handleSuccess();
  }

  // 刷新表格数æ®ï¼ˆå«è¡¨å•回调)
  function handleSuccess() {
    reload();
  }
</script>

授æƒè®¸å¯åè®®æ¡æ¬¾

  1. 基于 Apache License Version 2.0 åè®®å‘布,å¯ç”¨äºŽå•†ä¸šé¡¹ç›®ï¼Œä½†å¿…é¡»éµå®ˆä»¥ä¸‹è¡¥å……æ¡æ¬¾ã€‚
  2. ä¸å¾—将本软件应用于å±å®³å›½å®¶å®‰å…¨ã€è£èª‰å’Œåˆ©ç›Šçš„行为,ä¸èƒ½ä»¥ä»»ä½•å½¢å¼ç”¨äºŽéžæ³•为目的的行为。
  3. 在使用本软件时,由于它集æˆäº†ä¼—多第三方开æºè½¯ä»¶ï¼Œè¯·å…±åŒéµå®ˆè¿™äº›å¼€æºè½¯ä»¶çš„ä½¿ç”¨è®¸å¯æ¡æ¬¾è§„定。
  4. 在延伸的代ç ä¸­ï¼ˆä¿®æ”¹å’Œæœ‰æºä»£ç è¡ç”Ÿçš„代ç ä¸­ï¼‰éœ€è¦å¸¦æœ‰åŽŸæ¥ä»£ç ä¸­çš„åè®®ã€ç‰ˆæƒå£°æ˜Žå’Œå…¶ä»–原作者 规定需è¦åŒ…å«çš„说明(请尊é‡åŽŸä½œè€…çš„è‘—ä½œæƒï¼Œä¸è¦åˆ é™¤æˆ–修改文件中的Copyrightå’Œ@authorä¿¡æ¯ï¼‰ æ›´ä¸è¦ï¼Œå…¨å±€æ›¿æ¢æºä»£ç ä¸­çš„ jeesite 或 ThinkGem 等字样,å¦åˆ™ä½ å°†è¿å本åè®®æ¡æ¬¾æ‰¿æ‹…责任。
  5. 基于本软件的作å“,åªèƒ½ä½¿ç”¨ JeeSite5 作为åŽå°æœåŠ¡ï¼Œé™¤å¤–æƒ…å†µä¸å¯å•†ç”¨ä¸”ä¸å…è®¸äºŒæ¬¡åˆ†å‘æˆ–å¼€æºã€‚
  6. æ‚¨è‹¥å¥—ç”¨æœ¬è½¯ä»¶çš„ä¸€äº›ä»£ç æˆ–功能å‚考,请ä¿ç•™æºæ–‡ä»¶ä¸­çš„版æƒå’Œä½œè€…,需è¦åœ¨æ‚¨çš„è½¯ä»¶ä»‹ç»æ˜Žæ˜¾ä½ç½® 说明出处,举例:本软件基于 JeeSite Vue 快速开å‘å¹³å°ï¼Œå¹¶é™„带链接:http://jeesite.com
  7. 任何基于本软件而产生的一切法律纠纷和责任,å‡äºŽæˆ‘叿— å…³ã€‚
  8. 如果你对本软件有改进,希望å¯ä»¥è´¡çŒ®ç»™æˆ‘们,共åŒè¿›æ­¥ã€‚
  9. 本项目已申请软件著作æƒï¼Œè¯·å°Šé‡å¼€æºï¼Œæ„Ÿè°¢é˜…读。

技术支æŒä¸ŽæœåŠ¡

  • 本软件å…费,我们也æä¾›äº†ç›¸åº”的收费æœåŠ¡ï¼Œå› ä¸ºï¼š
  • 没有资金的支撑就很难得到å‘展,特别是一个好的产å“,如果 JeeSite å¸®åŠ©äº†æ‚¨ï¼Œè¯·ä¸ºæˆ‘ä»¬ç‚¹èµžã€‚æ”¯æŒæˆ‘们,您å¯ä»¥èŽ·å¾—æ›´å¤šå›žé¦ˆï¼Œæˆ‘ä»¬ä¼šæŠŠå…¬ç›Šäº‹ä¸šåšçš„æ›´å¥½ï¼Œå¼€æ”¾æ›´å¤šèµ„æºï¼Œå›žæŠ¥ç¤¾åŒºå’Œç¤¾ä¼šã€‚请给我们一些动力å§ï¼Œåœ¨æ­¤éžå¸¸æ„Ÿè°¢å·²æ”¯æŒæˆ‘们的朋å‹ï¼
  • è”系我们:请访问技术支æŒä¸ŽæœåС页é¢ï¼šhttp://s.jeesite.com

专业版增加的功能

  1. 主题标签页的三ç§é£Žæ ¼è‡ªç”±åˆ‡æ¢
  2. 业务æµç¨‹ã€æµç¨‹è®¾è®¡ã€æµç¨‹åŠžç†
  3. 文件管ç†ã€ä¸Šä¼ ç§’ä¼ ã€æ–‡ä»¶é¢„览
  4. 高级折å è¡¨å•和个性化本地存储
  5. è¡¨æ ¼ä¸ªæ€§åŒ–è®¾ç½®å‚æ•°æœ¬åœ°å­˜å‚¨
  6. 租户管ç†åŠŸèƒ½ã€ç§Ÿæˆ·åˆ‡æ¢
  7. 动æ€è®¾ç½®é¡µé¢å­—体大å°
  8. 页签å³é”®ï¼Œåœ¨æ–°çª—壿‰“å¼€
  9. æ¶ˆæ¯æŽ¨é€ã€æ¶ˆæ¯æé†’
  10. è¯­è¨€å›½é™…åŒ–ã€æœ¬åœ°åŒ–
  11. 快速å‡çº§åˆ° Monorepo 脚本
  12. æ›´å¤šåŠŸèƒ½è¯¦è§æ–‡æ¡£

About

ðŸ‘Java 低代ç , è½»é‡çº§, Spring Boot, MyBatis, Flowable, TypeScript, Vue, Antdv, 包括核心模å—如:组织机构ã€è§’è‰²ç”¨æˆ·ã€æƒé™æŽˆæƒã€æ•°æ®æƒé™ã€å†…容管ç†ã€å·¥ä½œæµã€Spring Cloud å¾®æœåŠ¡ç­‰ã€‚

Resources

License

Stars

Watchers

Forks

Packages

No packages published
0