.cursorrules 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469
  1. # Art Design Pro UI 规范 - Plus UI 重构版
  2. ## 设计理念
  3. 基于 Art Design Pro 的设计语言,追求现代化、精致、用户友好的界面体验。注重细节、动效和用户交互的流畅性。
  4. ## 1. 颜色系统
  5. ### 主色调 (Primary Colors)
  6. ```css
  7. --art-primary: 93, 135, 255; /* 主品牌色 - 蓝色 */
  8. --art-secondary: 73, 190, 255; /* 辅助色 - 天蓝色 */
  9. --art-success: 19, 222, 185; /* 成功色 - 绿色 */
  10. --art-warning: 255, 174, 31; /* 警告色 - 橙色 */
  11. --art-error: 250, 137, 107; /* 错误色 - 红色 */
  12. --art-info: 83, 155, 255; /* 信息色 - 蓝色 */
  13. --art-danger: 255, 77, 79; /* 危险色 - 红色 */
  14. ```
  15. ### 背景色系统 (Background Colors)
  16. ```css
  17. /* 浅色主题 */
  18. --art-bg-color: #fafbfc; /* 页面底色 */
  19. --art-main-bg-color: #ffffff; /* 主要内容背景 */
  20. --art-bg-primary: 236, 242, 255; /* 主色背景 */
  21. --art-bg-secondary: 232, 247, 255; /* 辅助背景 */
  22. --art-bg-success: 230, 255, 250; /* 成功背景 */
  23. --art-bg-warning: 254, 245, 229; /* 警告背景 */
  24. --art-bg-error: 253, 237, 232; /* 错误背景 */
  25. /* 暗色主题 */
  26. html.dark {
  27. --art-bg-color: #070707; /* 页面底色 */
  28. --art-main-bg-color: #161618; /* 主要内容背景 */
  29. }
  30. ```
  31. ### 灰度色系 (Gray Scale)
  32. ```css
  33. --art-gray-100: #f9f9f9;
  34. --art-gray-200: #f1f1f4;
  35. --art-gray-300: #dbdfe9;
  36. --art-gray-400: #c4cada;
  37. --art-gray-500: #99a1b7;
  38. --art-gray-600: #78829d;
  39. --art-gray-700: #4b5675;
  40. --art-gray-800: #252f4a;
  41. --art-gray-900: #071437;
  42. ```
  43. ## 2. 字体系统
  44. ### 字体家族
  45. ```css
  46. font-family: 'DMSans', 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  47. ```
  48. ### 字体大小
  49. - 超大标题:24px (1.5rem)
  50. - 大标题:20px (1.25rem)
  51. - 中标题:18px (1.125rem)
  52. - 小标题:16px (1rem)
  53. - 正文:14px (0.875rem)
  54. - 小字:12px (0.75rem)
  55. - 辅助文字:10px (0.625rem)
  56. ### 字体权重
  57. - Light: 300
  58. - Normal: 400
  59. - Medium: 500
  60. - Semibold: 600
  61. - Bold: 700
  62. ## 3. 间距系统
  63. ### 间距单位 (基于 4px 网格)
  64. ```css
  65. --space-xs: 4px;
  66. --space-sm: 8px;
  67. --space-md: 12px;
  68. --space-lg: 16px;
  69. --space-xl: 20px;
  70. --space-2xl: 24px;
  71. --space-3xl: 32px;
  72. --space-4xl: 48px;
  73. --space-5xl: 64px;
  74. ```
  75. ### 内边距规范
  76. - 卡片内边距:20px
  77. - 按钮内边距:8px 16px
  78. - 输入框内边距:10px 12px
  79. - 表格单元格:12px
  80. - 弹窗内边距:25px 20px
  81. ### 外边距规范
  82. - 组件间距:20px
  83. - 段落间距:16px
  84. - 按钮间距:8px
  85. - 表单项间距:12px
  86. ## 4. 圆角系统
  87. ### 圆角规范
  88. ```css
  89. --border-radius-xs: 4px;
  90. --border-radius-sm: 6px;
  91. --border-radius-md: 8px;
  92. --border-radius-lg: 10px;
  93. --border-radius-xl: 12px;
  94. --border-radius-2xl: 16px;
  95. --border-radius-full: 50%;
  96. ```
  97. ### 应用场景
  98. - 按钮:6px
  99. - 输入框:8px
  100. - 卡片:10px
  101. - 弹窗:10px
  102. - 图片:6px
  103. - 头像:50%
  104. ## 5. 阴影系统
  105. ### 阴影等级
  106. ```css
  107. --shadow-xs: 0 0.1rem 0.75rem 0.25rem rgba(0, 0, 0, 0.05);
  108. --shadow-sm: 0 0.1rem 1rem 0.25rem rgba(0, 0, 0, 0.05);
  109. --shadow-md: 0 0.5rem 1.5rem 0.5rem rgba(0, 0, 0, 0.075);
  110. --shadow-lg: 0 1rem 2rem 1rem rgba(0, 0, 0, 0.1);
  111. --shadow-card: 0px 3px 4px 0px rgba(0, 0, 0, 0.03);
  112. ```
  113. ### 应用场景
  114. - 卡片阴影:shadow-card
  115. - 悬浮效果:shadow-sm
  116. - 弹窗阴影:shadow-lg
  117. - 按钮悬浮:shadow-xs
  118. ## 6. 边框系统
  119. ### 边框颜色
  120. ```css
  121. --border-color: #eaebf1;
  122. --border-dashed-color: #dbdfe9;
  123. --border-card-color: #f1f1f4;
  124. ```
  125. ### 边框宽度
  126. - 默认:1px
  127. - 粗边框:2px
  128. - 表格边框:1px
  129. ## 7. 动画系统
  130. ### 缓动曲线
  131. ```css
  132. --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  133. --ease-out: cubic-bezier(0, 0, 0.2, 1);
  134. --ease-in: cubic-bezier(0.4, 0, 1, 1);
  135. ```
  136. ### 动画时长
  137. - 快速:0.15s
  138. - 标准:0.3s
  139. - 慢速:0.5s
  140. ### 常用动画
  141. - 淡入淡出:opacity transition
  142. - 悬浮效果:transform scale
  143. - 按钮点击:transform scale(0.95)
  144. - 页面切换:fade + slide
  145. ## 8. 组件规范
  146. ### 按钮 (Button)
  147. #### 基础规范
  148. - **尺寸系统**:Large(40px) / Default(32px) / Small(28px)
  149. - **圆角规范**:6px(默认) / 8px(大) / 4px(小) / 50%(圆形)
  150. - **字体权重**:500 (Medium)
  151. - **过渡动画**:cubic-bezier(0.4, 0, 0.2, 1) 0.3s
  152. - **字母间距**:0.02em
  153. #### 按钮类型 - 全部采用轮廓式设计
  154. - **Primary按钮**:轮廓式主色设计,主色边框和文字,5%透明度主色背景
  155. - **Success按钮**:轮廓式成功色设计,成功色边框和文字,5%透明度成功色背景
  156. - **Warning按钮**:轮廓式警告色设计,警告色边框和文字,5%透明度警告色背景
  157. - **Danger按钮**:轮廓式危险色设计,危险色边框和文字,5%透明度危险色背景
  158. - **Info按钮**:轮廓式信息色设计,信息色边框和文字,5%透明度信息色背景
  159. - **Default按钮**:白色背景,灰色边框,灰色文字
  160. #### 变体样式
  161. - **Plain按钮**:与标准按钮完全相同的轮廓式设计,无差异化
  162. - **Outline按钮**:轮廓式设计(现已作为全部按钮的标准样式)
  163. - **Text按钮**:无背景边框,彩色文字,悬浮10%透明背景
  164. - **Link按钮**:下划线样式,主色文字,无背景
  165. #### 交互效果 - 轮廓式按钮专用
  166. - **悬浮状态**:上移1px + 背景透明度变为10% + 边框透明度变为80% + 彩色阴影
  167. - **点击状态**:98%缩放 + 0.1s快速过渡 + 背景透明度变为15%
  168. - **禁用状态**:50%透明度,禁用所有交互和变换
  169. - **加载状态**:70%透明度 + 遮罩层效果
  170. **详细规范**:
  171. - **默认状态**:5%透明度彩色背景 + 100%彩色边框
  172. - **悬浮状态**:10%透明度彩色背景 + 80%透明度彩色边框 + `0 4px 12px rgba(color, 0.2)` 阴影
  173. - **点击状态**:15%透明度彩色背景 + 边框保持80%透明度
  174. #### 特殊状态
  175. - **圆形按钮**:宽高相等,50%圆角,主要用于图标按钮
  176. - **按钮组**:相邻按钮圆角归零,-1px右边距无缝连接
  177. - **阴影规范**:轮廓式按钮悬浮阴影统一为 `0 4px 12px rgba(color, 0.2)`
  178. #### 🎨 轮廓式按钮设计系统(2024年版本)
  179. **设计理念**:全面采用轮廓式(Outline)按钮设计,提供更加优雅、现代和一致的用户界面体验。
  180. **核心优势**:
  181. - ✅ **视觉轻量化**:减少视觉重量,避免界面过于厚重
  182. - ✅ **层次分明**:通过透明度变化清晰表达交互状态
  183. - ✅ **品牌一致性**:所有彩色按钮都保持品牌色彩的纯净表达
  184. - ✅ **可访问性优化**:高对比度的边框和文字确保良好的可读性
  185. **技术实现**:
  186. ```scss
  187. // 轮廓式按钮核心模式(适用于所有按钮,包括MessageBox)
  188. .el-button--[type] {
  189. border: 1px solid rgb(var(--art-[type])) !important;
  190. color: rgb(var(--art-[type])) !important;
  191. background: rgba(var(--art-[type]), 0.05) !important;
  192. &:hover {
  193. background: rgba(var(--art-[type]), 0.1) !important;
  194. border-color: rgba(var(--art-[type]), 0.8) !important;
  195. box-shadow: 0 4px 12px rgba(var(--art-[type]), 0.2) !important;
  196. }
  197. &:active {
  198. background: rgba(var(--art-[type]), 0.15) !important;
  199. }
  200. }
  201. // MessageBox 专用样式确保一致性
  202. .el-message-box .el-message-box__btns .el-button {
  203. // 继承全局轮廓式按钮样式,使用!important确保优先级
  204. }
  205. ```
  206. **适用范围**:
  207. - ✅ 全局所有 primary、success、warning、danger、info 按钮
  208. - ✅ 页面表单、表格操作按钮
  209. - ✅ 确认弹窗(MessageBox)中的所有按钮
  210. - ✅ 普通弹窗(Dialog)中的所有按钮
  211. - ✅ 导航和功能按钮
  212. **实施位置**:
  213. - 样式文件:`src/assets/styles/art-element-ui.scss`
  214. - 优先级:使用 `!important` 确保全局覆盖
  215. - 兼容性:与现有 Element Plus 组件完全兼容
  216. ### 输入框 (Input)
  217. - 边框:1px solid --border-color
  218. - 圆角:8px
  219. - 内边距:10px 12px
  220. - 聚焦状态:主色边框
  221. - 错误状态:红色边框
  222. ### 卡片 (Card)
  223. - 背景:白色
  224. - 圆角:10px
  225. - 阴影:shadow-card
  226. - 内边距:20px
  227. - 边框:可选 1px --border-card-color
  228. ### 左侧菜单 (Sidebar Menu)
  229. #### 基础规范
  230. - **菜单宽度**: 250px(展开) / 54px(收起)
  231. - **背景色**: 浅色主题白色 / 暗色主题深色
  232. - **圆角**: 4px (菜单项内边距)
  233. - **间距**: 外边距8px,内边距2px
  234. - **过渡动画**: 0.3s ease 流畅过渡
  235. #### 菜单项状态
  236. - **默认状态**:
  237. - 文字:`--art-text-gray-700`
  238. - 图标:`--art-text-gray-600`
  239. - 背景:透明
  240. - **悬浮状态**:
  241. - 文字:`--art-text-gray-800`
  242. - 图标:主题色 `rgb(var(--art-primary))`
  243. - 背景:8%主题色透明 `rgba(var(--art-primary), 0.08)`
  244. - **选中状态**:
  245. - 文字:主题色 `rgb(var(--art-primary))`
  246. - 图标:主题色 `rgb(var(--art-primary))`
  247. - 背景:10%主题色透明 `rgba(var(--art-primary), 0.1)`
  248. #### 嵌套子菜单
  249. - **背景透明化**: 子菜单项背景透明
  250. - **悬浮效果**: 6%主题色透明背景
  251. - **选中效果**: 10%主题色透明背景
  252. - **层级缩进**: 标准Element Plus缩进
  253. - **圆角统一**: 4px内边距圆角
  254. #### 暗色主题适配
  255. - **悬浮背景**: 15%主题色透明 `rgba(var(--art-primary), 0.15)`
  256. - **选中背景**: 20%主题色透明 `rgba(var(--art-primary), 0.2)`
  257. - **子菜单悬浮**: 12%主题色透明背景
  258. - **颜色继承**: 与浅色主题文字图标颜色保持一致
  259. #### 收起状态
  260. - **容器宽度**: 54px固定宽度
  261. - **菜单项高度**: 48px,确保统一高度
  262. - **图标规范**: 16x16px,美观合理
  263. - **完美居中**: 使用Flexbox确保水平垂直居中
  264. - **一级菜单特殊处理**: 使用`.el-menu > .el-menu-item`选择器确保优先级
  265. - **tooltip支持**: 兼容`.el-tooltip`和`.el-menu-tooltip__trigger`元素
  266. - **统一对齐**: 所有菜单项(一级、多级)完全一致的居中效果
  267. - **提示框**: Element Plus tooltip显示完整菜单名
  268. - **展开动画**: 0.28s流畅过渡动画
  269. ### 表格 (Table)
  270. - 表头背景:--gray-100
  271. - 斑马纹:--gray-50
  272. - 边框:1px --border-color
  273. - 悬浮行:--gray-100 背景
  274. ### 弹窗 (Modal/Dialog)
  275. - 背景:白色
  276. - 圆角:10px
  277. - 阴影:shadow-lg
  278. - 动画:scale + fade
  279. - 遮罩:rgba(0,0,0,0.5)
  280. #### 确认弹窗按钮样式规范
  281. **重要原则**:确认弹窗(MessageBox.confirm)中的按钮与全局轮廓式按钮规范保持完全一致,确保整个系统的设计统一性。
  282. **设计理念**:确认弹窗中的按钮采用轮廓式设计,与页面中的其他按钮保持一致的视觉风格,通过统一的轮廓式设计语言提供现代化、轻量化的用户体验。
  283. - **确定按钮(Primary)**:使用轮廓式主色设计
  284. - 背景:5%透明度主色 `rgba(var(--art-primary), 0.05)`
  285. - 边框:1px 主色边框 `rgb(var(--art-primary))`
  286. - 文字颜色:主色 `rgb(var(--art-primary))`
  287. - 悬浮效果:
  288. - 背景:10%透明度主色 `rgba(var(--art-primary), 0.1)`
  289. - 边框:80%透明度主色 `rgba(var(--art-primary), 0.8)`
  290. - 阴影:`0 4px 12px rgba(var(--art-primary), 0.2)`
  291. - 上移1px效果保持
  292. - 点击效果:
  293. - 背景:15%透明度主色 `rgba(var(--art-primary), 0.15)`
  294. - 98%缩放效果保持
  295. - **其他类型按钮**:使用对应色彩的轮廓式设计
  296. - **Success按钮**:轮廓式成功色设计,成功色边框和文字,5%透明度背景
  297. - **Warning按钮**:轮廓式警告色设计,警告色边框和文字,5%透明度背景
  298. - **Danger按钮**:轮廓式危险色设计,危险色边框和文字,5%透明度背景
  299. - **Info按钮**:轮廓式信息色设计,信息色边框和文字,5%透明度背景
  300. - 交互效果:与Primary按钮保持一致的轮廓式悬浮和点击效果
  301. - **取消按钮**:使用默认按钮样式(保持轻量化)
  302. - 背景:主背景色 `var(--art-main-bg-color)`
  303. - 边框:1px 灰色边框 `var(--art-border-color)`
  304. - 文字颜色:`var(--art-text-gray-700)`
  305. - 阴影:`0 1px 3px rgba(0, 0, 0, 0.1)`
  306. - **统一规范**:
  307. - 圆角:8px
  308. - 高度:32px
  309. - 内边距:0 16px
  310. - 字体权重:500
  311. - 过渡动画:`all 0.3s cubic-bezier(0.4, 0, 0.2, 1)`
  312. - 字母间距:0.02em
  313. **设计统一性说明**:
  314. - **全局按钮统一**:所有按钮(页面按钮和确认弹窗按钮)都采用轮廓式设计
  315. - **视觉一致性**:确保整个系统的按钮风格保持完全一致
  316. - **现代化体验**:通过统一的轮廓式设计提供现代化、轻量化的用户体验
  317. - **交互规范**:所有按钮都遵循相同的悬浮、点击、透明度变化规范
  318. **实现位置**:
  319. - 样式文件:`src/assets/styles/art-element-ui.scss`
  320. - 选择器:`.el-message-box .el-message-box__btns .el-button`
  321. - 优先级:使用 `!important` 确保样式优先级
  322. - 适用场景:confirm、alert、prompt等所有MessageBox弹窗
  323. - 设计原则:与全局轮廓式按钮规范保持完全一致
  324. #### MessageBox 按钮布局规范
  325. **按钮顺序规范**:确认弹窗(MessageBox)中的按钮顺序遵循国内用户习惯,确定按钮在左侧,取消按钮在右侧。
  326. **布局实现**:
  327. - **按钮容器**:使用 `flex-direction: row-reverse` 实现按钮顺序调整
  328. - **确定按钮**:`order: 2` 确保排在左侧(用户优先操作位置)
  329. - **取消按钮**:`order: 1` 排在右侧(次要操作位置)
  330. - **按钮间距**:使用 `gap: 12px` 确保按钮之间的合理间距
  331. **设计理念**:
  332. - **符合习惯**:遵循国内用户的操作习惯,确定操作在左,取消操作在右
  333. - **视觉引导**:确定按钮的主色调设计在左侧能够更好地引导用户操作
  334. - **一致性保证**:所有确认弹窗的按钮顺序保持完全一致
  335. **技术实现**:
  336. ```scss
  337. // MessageBox 按钮顺序调整
  338. .el-message-box .el-message-box__btns {
  339. display: flex !important;
  340. flex-direction: row-reverse !important;
  341. justify-content: flex-start !important;
  342. gap: 12px !important;
  343. }
  344. .el-message-box .el-message-box__btns .el-button.el-button--primary {
  345. order: 2 !important; // 确定按钮排在前面(左侧)
  346. }
  347. .el-message-box .el-message-box__btns .el-button.el-button--default,
  348. .el-message-box .el-message-box__btns .el-button:not([class*="el-button--"]) {
  349. order: 1 !important; // 取消按钮排在后面(右侧)
  350. }
  351. ```
  352. **应用场景**:
  353. - ✅ confirm 确认弹窗:确定在左,取消在右
  354. - ✅ alert 提示弹窗:确定按钮居左显示
  355. - ✅ prompt 输入弹窗:确定在左,取消在右
  356. - ✅ 所有自定义 MessageBox 弹窗
  357. **用户体验考虑**:
  358. - **操作优先级**:确定操作作为主要操作放在左侧,符合从左到右的阅读习惯
  359. - **降低误操作**:确定按钮的突出位置减少用户误点取消的情况
  360. - **一致性体验**:整个系统的确认弹窗都遵循相同的按钮顺序
  361. #### MessageBox 按钮统一性原则
  362. **核心要求**:MessageBox(确认弹窗)中的所有按钮必须与页面中的其他按钮保持完全一致的轮廓式设计。
  363. **统一性体现**:
  364. - ✅ **视觉风格**:相同的边框、背景、文字颜色规范
  365. - ✅ **交互效果**:相同的悬浮、点击、透明度变化效果
  366. - ✅ **尺寸规格**:相同的高度、圆角、内边距、字体权重
  367. - ✅ **颜色系统**:使用相同的色彩变量和透明度规范
  368. **实施保证**:
  369. ```scss
  370. // 确保MessageBox按钮与全局按钮完全一致
  371. .el-message-box .el-message-box__btns .el-button {
  372. // 所有样式属性都使用!important确保优先级
  373. // 严格遵循全局轮廓式按钮规范
  374. }
  375. ```
  376. **验收标准**:
  377. - MessageBox中的按钮与页面按钮在视觉上无任何差异
  378. - 所有交互状态的表现完全一致
  379. - 不同类型的按钮(primary、success、warning等)都遵循统一规范
  380. ## 9. 布局规范
  381. ### 栅格系统
  382. - 容器最大宽度:1200px
  383. - 栅格列数:24列
  384. - 间距:20px
  385. ### 页面布局
  386. - 顶栏高度:60px
  387. - 侧边栏宽度:240px (展开) / 80px (收起)
  388. - 内容区域:自适应
  389. - 底部高度:60px
  390. ### 响应式断点
  391. ```scss
  392. $device-phone: 500px; // 手机
  393. $device-ipad: 800px; // 平板
  394. $device-ipad-pro: 1180px; // 平板 Pro
  395. $device-notebook: 1600px; // 笔记本
  396. ```
  397. ## 10. 主题系统
  398. ### 主题切换
  399. - 支持浅色/暗色主题
  400. - 使用 CSS 变量实现
  401. - 平滑过渡动画
  402. - 本地存储偏好
  403. ### 颜色模式
  404. - 浅色模式:明亮、清晰
  405. - 暗色模式:柔和、护眼
  406. - 跟随系统:自动切换
  407. ## 11. 交互规范
  408. ### 悬浮效果 (Hover)
  409. - 按钮:背景变浅 + 轻微放大
  410. - 卡片:阴影加深
  411. - 图标:颜色变化 + 动画
  412. - 链接:颜色变化
  413. ### 点击效果 (Active)
  414. - 按钮:轻微缩小
  415. - 卡片:阴影减弱
  416. - 输入框:聚焦边框
  417. ### 加载状态
  418. - 骨架屏:灰色占位
  419. - 进度条:主色进度
  420. - 加载动画:旋转图标
  421. ## 12. 图标系统
  422. ### 图标规范
  423. - 尺寸:16px, 20px, 24px
  424. - 线条粗细:1.5px
  425. - 风格:线性图标
  426. - 颜色:继承文字色或主题色
  427. ### 图标用法
  428. - 按钮图标:16px
  429. - 菜单图标:20px
  430. - 页面图标:24px
  431. - 装饰图标:根据需要
  432. ## 13. 移动端适配
  433. ### 移动端规范
  434. - 最小点击区域:44px
  435. - 字体适当放大
  436. - 间距适当增加
  437. - 简化交互方式
  438. - 优化触摸体验
  439. ### 响应式布局
  440. - 移动端优先
  441. - 灵活的栅格系统
  442. - 可收起的侧边栏
  443. - 简化的导航方式
  444. ## 14. 可访问性 (Accessibility)
  445. ### 颜色对比度
  446. - 文字对比度:4.5:1 以上
  447. - 大文字对比度:3:1 以上
  448. - 状态指示:不仅依赖颜色
  449. ### 交互可访问性
  450. - 键盘导航支持
  451. - 屏幕阅读器支持
  452. - 焦点指示清晰
  453. - 错误信息明确
  454. ## 15. 实施原则
  455. ### 开发规范
  456. 1. 优先使用 CSS 变量
  457. 2. 统一使用 SCSS 预处理器
  458. 3. 组件化开发
  459. 4. 响应式设计
  460. 5. 性能优化
  461. ### 维护规范
  462. 1. 定期更新设计规范
  463. 2. 保持组件库的一致性
  464. 3. 及时修复视觉问题
  465. 4. 收集用户反馈
  466. ### 质量保证
  467. 1. 多设备测试
  468. 2. 多浏览器兼容
  469. 3. 性能监控
  470. 4. 用户体验评估
  471. ---
  472. ## 注意事项
  473. 1. **一致性优先**:确保整个系统的视觉一致性
  474. 2. **用户体验**:以用户体验为核心进行设计
  475. 3. **性能考虑**:优化动画和样式性能
  476. 4. **可维护性**:编写可维护的样式代码
  477. 5. **扩展性**:为未来的功能扩展预留空间
  478. ## 🚀 重大更新记录
  479. ### 2024年 - 全局轮廓式按钮系统
  480. **更新时间**:2024年
  481. **核心变更**:将整个系统的按钮设计从填充式改为轮廓式设计
  482. **影响范围**:
  483. - ✅ 全局所有 primary、success、warning、danger、info 按钮
  484. - ✅ 页面表单和表格中的操作按钮
  485. - ✅ 确认弹窗按钮(包括 confirm、alert、prompt)
  486. - ✅ 导航和功能按钮
  487. **设计理念**:
  488. - 提供更加轻量化、现代化的视觉体验
  489. - 保持品牌色彩的纯净表达
  490. - 通过透明度变化清晰表达交互状态
  491. - 提升界面的整体协调性和专业感
  492. **技术特点**:
  493. - 使用 `!important` 确保全局覆盖优先级
  494. - 与 Element Plus 组件完全兼容
  495. - 支持所有交互状态(hover、active、disabled、loading)
  496. - 统一的阴影和透明度规范
  497. **后续维护**:
  498. - 新增按钮类型应遵循轮廓式设计原则
  499. - 保持透明度和阴影规范的一致性
  500. - 确保在所有主题模式下的兼容性
  501. ### 2024年 - 确认弹窗按钮统一化设计
  502. **更新时间**:2024年
  503. **核心变更**:将确认弹窗(MessageBox)中的按钮与全局轮廓式按钮规范保持完全一致
  504. **影响范围**:
  505. - ✅ confirm 确认弹窗按钮
  506. - ✅ alert 提示弹窗按钮
  507. - ✅ prompt 输入弹窗按钮
  508. - ✅ 所有 MessageBox 类型的弹窗按钮
  509. **设计理念**:
  510. - **全局统一**:所有按钮都使用轮廓式设计,确保系统的视觉一致性
  511. - **现代化体验**:通过统一的轮廓式设计提供现代化、轻量化的用户体验
  512. - **交互一致性**:所有按钮的悬浮、点击效果保持完全一致
  513. - **维护简便**:统一的设计规范降低维护成本
  514. **技术特点**:
  515. - 确认按钮:轮廓式主色设计 + 主色文字
  516. - 其他类型按钮:对应色彩的轮廓式设计
  517. - 取消按钮:保持轻量化的默认样式
  518. - 最高优先级:使用 `!important` 确保样式覆盖
  519. **实施位置**:
  520. - 样式文件:`src/assets/styles/art-element-ui.scss`
  521. - 选择器:`.el-message-box .el-message-box__btns .el-button`
  522. ### 2024年 - MessageBox 按钮位置优化
  523. **更新时间**:2024年
  524. **核心变更**:调整确认弹窗(MessageBox)中的按钮顺序,确定按钮在左侧,取消按钮在右侧,符合国内用户操作习惯
  525. **影响范围**:
  526. - ✅ confirm 确认弹窗的按钮布局
  527. - ✅ alert 提示弹窗的按钮布局
  528. - ✅ prompt 输入弹窗的按钮布局
  529. - ✅ 所有自定义 MessageBox 弹窗的按钮布局
  530. **设计理念**:
  531. - **用户习惯优先**:遵循国内用户的操作习惯,主要操作(确定)在左侧
  532. - **视觉引导优化**:确定按钮的主色调设计在左侧能够更好地引导用户操作
  533. - **降低误操作**:确定按钮的突出位置减少用户误点取消的情况
  534. - **一致性保证**:整个系统的确认弹窗按钮顺序保持完全一致
  535. **技术实现**:
  536. - 使用 CSS Flexbox 的 `flex-direction: row-reverse` 调整按钮顺序
  537. - 通过 `order` 属性精确控制按钮位置
  538. - 使用 `gap` 属性确保按钮间距的一致性
  539. - 保持与轮廓式按钮样式的完美兼容
  540. **用户体验提升**:
  541. - 符合从左到右的阅读和操作习惯
  542. - 减少用户在确认操作时的认知负担
  543. - 提升整体操作的直观性和效率
  544. **实施位置**:
  545. - 文件:`src/assets/styles/art-element-ui.scss`
  546. - 选择器:`.el-message-box .el-message-box__btns`
  547. - 配合:`src/plugins/modal.ts` 中的按钮类名配置
  548. ## 16. 项目架构规范
  549. ### 目录结构标准
  550. ```
  551. src/
  552. ├── api/ # API接口定义
  553. │ ├── [module]/ # 模块化API
  554. │ │ ├── index.ts # API方法定义
  555. │ │ └── types.ts # 类型定义
  556. │ ├── types.ts # 通用类型
  557. │ └── login.ts # 登录相关API
  558. ├── assets/ # 静态资源
  559. │ ├── styles/ # 样式文件
  560. │ │ ├── art-variables.scss # 设计变量
  561. │ │ ├── art-element-ui.scss # 组件样式覆盖
  562. │ │ ├── art-dark.scss # 暗色主题
  563. │ │ └── index.scss # 样式入口
  564. │ └── images/ # 图片资源
  565. ├── components/ # 通用组件
  566. │ └── [ComponentName]/ # 组件目录(PascalCase)
  567. │ ├── index.vue # 组件主文件
  568. │ └── types.ts # 组件类型定义(可选)
  569. ├── views/ # 页面视图
  570. │ └── [module]/ # 模块化页面
  571. │ └── [feature]/ # 功能页面
  572. │ ├── index.vue # 主页面文件
  573. │ └── components/ # 页面专用组件(可选)
  574. ├── layout/ # 布局组件
  575. ├── router/ # 路由配置
  576. ├── store/ # 状态管理
  577. ├── utils/ # 工具函数
  578. ├── plugins/ # 插件配置
  579. ├── types/ # 全局类型定义
  580. └── main.ts # 应用入口
  581. ```
  582. ### 文件命名规范
  583. - **文件夹**:使用 kebab-case(小写+连字符)
  584. - **Vue组件文件**:使用 PascalCase 或 kebab-case
  585. - **TypeScript文件**:使用 camelCase
  586. - **样式文件**:使用 kebab-case
  587. - **常量文件**:使用 UPPER_SNAKE_CASE
  588. ### 模块组织原则
  589. 1. **按功能模块划分**:每个业务模块独立组织
  590. 2. **API与页面对应**:api目录结构与views保持一致
  591. 3. **类型定义集中**:每个模块都有对应的types.ts
  592. 4. **组件复用优先**:通用组件放在components目录
  593. ## 17. Vue组件开发规范
  594. ### 组件结构标准
  595. ```vue
  596. <template>
  597. <!-- 使用语义化的HTML结构 -->
  598. <div class="component-container">
  599. <!-- 组件内容 -->
  600. </div>
  601. </template>
  602. <script setup lang="ts" name="ComponentName">
  603. // 1. 引入依赖
  604. import { ref, reactive, computed, onMounted } from 'vue';
  605. import type { ComponentProps, ComponentEmits } from './types';
  606. // 2. 定义Props和Emits
  607. const props = defineProps<ComponentProps>();
  608. const emits = defineEmits<ComponentEmits>();
  609. // 3. 响应式数据
  610. const loading = ref(false);
  611. const formData = reactive({});
  612. // 4. 计算属性
  613. const computedValue = computed(() => {
  614. return /* 计算逻辑 */;
  615. });
  616. // 5. 方法定义
  617. const handleClick = () => {
  618. // 方法实现
  619. };
  620. // 6. 生命周期
  621. onMounted(() => {
  622. // 组件挂载后的逻辑
  623. });
  624. </script>
  625. <style lang="scss" scoped>
  626. .component-container {
  627. // 样式实现
  628. }
  629. </style>
  630. ```
  631. ### TypeScript类型定义规范
  632. ```typescript
  633. // types.ts
  634. export interface ComponentProps {
  635. title: string;
  636. visible: boolean;
  637. data?: any[];
  638. }
  639. export interface ComponentEmits {
  640. (e: 'update:visible', value: boolean): void;
  641. (e: 'confirm', data: any): void;
  642. }
  643. // 响应式数据类型
  644. export interface ComponentState {
  645. loading: boolean;
  646. formData: FormData;
  647. }
  648. ```
  649. ### 组件通信规范
  650. 1. **Props向下传递**:父组件向子组件传递数据
  651. 2. **Emits向上传递**:子组件向父组件传递事件
  652. 3. **v-model双向绑定**:表单组件使用v-model
  653. 4. **Provide/Inject**:跨级组件通信
  654. 5. **Pinia状态管理**:全局状态共享
  655. ## 18. 页面开发规范
  656. ### 列表页面标准模板
  657. ```vue
  658. <template>
  659. <div class="p-2 page-container">
  660. <!-- 搜索区域 -->
  661. <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
  662. :leave-active-class="proxy?.animate.searchAnimate.leave">
  663. <div v-show="showSearch" class="mb-[10px]">
  664. <el-card shadow="hover">
  665. <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="100px">
  666. <!-- 搜索表单项 -->
  667. <el-form-item>
  668. <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
  669. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  670. </el-form-item>
  671. </el-form>
  672. </el-card>
  673. </div>
  674. </transition>
  675. <!-- 表格区域 -->
  676. <el-card shadow="never" class="button-card table-card">
  677. <template #header>
  678. <el-row :gutter="10" class="mb8">
  679. <!-- 操作按钮 -->
  680. <el-col :span="1.5">
  681. <el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
  682. </el-col>
  683. <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
  684. </el-row>
  685. </template>
  686. <!-- 数据表格 -->
  687. <el-table v-loading="loading" border :data="dataList" :height="tableHeight">
  688. <el-table-column type="selection" width="55" align="center" />
  689. <!-- 数据列 -->
  690. <el-table-column label="操作" align="center" width="160">
  691. <template #default="scope">
  692. <!-- 操作按钮 -->
  693. </template>
  694. </el-table-column>
  695. </el-table>
  696. <!-- 分页组件 -->
  697. <pagination v-show="total > 0" :total="total"
  698. v-model:page="queryParams.pageNum"
  699. v-model:limit="queryParams.pageSize"
  700. @pagination="getList" />
  701. </el-card>
  702. <!-- 弹窗组件 -->
  703. <el-dialog :title="dialog.title" v-model="dialog.visible" width="800px" append-to-body>
  704. <!-- 弹窗内容 -->
  705. <template #footer>
  706. <div class="dialog-footer">
  707. <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
  708. <el-button @click="cancel">取 消</el-button>
  709. </div>
  710. </template>
  711. </el-dialog>
  712. </div>
  713. </template>
  714. ```
  715. ### 页面样式规范
  716. ```scss
  717. .page-container {
  718. height: calc(100vh - 85px);
  719. display: flex;
  720. flex-direction: column;
  721. overflow: hidden;
  722. box-sizing: border-box;
  723. padding: 8px 8px 0 8px !important;
  724. }
  725. .table-card {
  726. flex: 1;
  727. display: flex;
  728. flex-direction: column;
  729. overflow: hidden;
  730. }
  731. .table-card :deep(.el-card__body) {
  732. flex: 1;
  733. display: flex;
  734. flex-direction: column;
  735. padding: 20px 20px 0 20px;
  736. }
  737. ```
  738. ### 数据处理规范
  739. ```typescript
  740. // 页面数据结构
  741. const data = reactive<PageData<FormType, QueryType>>({
  742. form: { ...initFormData },
  743. queryParams: {
  744. pageNum: 1,
  745. pageSize: 10,
  746. // 查询参数
  747. },
  748. rules: {
  749. // 验证规则
  750. }
  751. });
  752. // 表格高度计算
  753. const tableHeight = computed(() => {
  754. const searchHeight = showSearch.value ? 120 : 0;
  755. const toolbarHeight = 50;
  756. const paginationHeight = 60;
  757. const otherHeight = 90;
  758. return windowHeight.value - searchHeight - toolbarHeight - paginationHeight - otherHeight;
  759. });
  760. ```
  761. ## 19. API开发规范
  762. ### API接口定义标准
  763. ```typescript
  764. // api/[module]/index.ts
  765. import request from '@/utils/request';
  766. import type { AxiosPromise } from 'axios';
  767. import type { DataVO, DataForm, DataQuery } from './types';
  768. /**
  769. * 查询数据列表
  770. * @param query 查询参数
  771. */
  772. export const listData = (query?: DataQuery): AxiosPromise<DataVO[]> => {
  773. return request({
  774. url: '/api/data/list',
  775. method: 'get',
  776. params: query
  777. });
  778. };
  779. /**
  780. * 查询数据详细信息
  781. * @param id 数据ID
  782. */
  783. export const getData = (id: string | number): AxiosPromise<DataVO> => {
  784. return request({
  785. url: `/api/data/${id}`,
  786. method: 'get'
  787. });
  788. };
  789. /**
  790. * 新增数据
  791. * @param data 数据信息
  792. */
  793. export const addData = (data: DataForm) => {
  794. return request({
  795. url: '/api/data',
  796. method: 'post',
  797. data: data
  798. });
  799. };
  800. /**
  801. * 修改数据
  802. * @param data 数据信息
  803. */
  804. export const updateData = (data: DataForm) => {
  805. return request({
  806. url: '/api/data',
  807. method: 'put',
  808. data: data
  809. });
  810. };
  811. /**
  812. * 删除数据
  813. * @param id 数据ID或ID数组
  814. */
  815. export const delData = (id: string | number | Array<string | number>) => {
  816. return request({
  817. url: `/api/data/${id}`,
  818. method: 'delete'
  819. });
  820. };
  821. ```
  822. ### API类型定义规范
  823. ```typescript
  824. // api/[module]/types.ts
  825. export interface DataVO {
  826. /** 主键ID */
  827. id: string | number;
  828. /** 数据名称 */
  829. name: string;
  830. /** 数据状态 */
  831. status: string;
  832. /** 创建时间 */
  833. createTime?: string;
  834. /** 更新时间 */
  835. updateTime?: string;
  836. }
  837. export interface DataForm extends BaseEntity {
  838. /** 主键ID */
  839. id?: string | number;
  840. /** 数据名称 */
  841. name?: string;
  842. /** 数据状态 */
  843. status?: string;
  844. }
  845. export interface DataQuery extends PageQuery {
  846. /** 数据名称 */
  847. name?: string;
  848. /** 数据状态 */
  849. status?: string;
  850. /** 日期范围参数 */
  851. params?: any;
  852. }
  853. ```
  854. ### 错误处理规范
  855. ```typescript
  856. // 统一错误处理已在request.ts中实现
  857. // 业务层只需要使用try-catch处理特殊情况
  858. const handleSubmit = async () => {
  859. try {
  860. await addData(formData);
  861. proxy?.$modal.msgSuccess('操作成功');
  862. getList();
  863. } catch (error) {
  864. // 特殊错误处理(可选)
  865. console.error('操作失败:', error);
  866. }
  867. };
  868. ```
  869. ## 20. 工具组件使用规范
  870. ### RightToolbar 工具栏
  871. ```vue
  872. <!-- 标准用法 -->
  873. <right-toolbar
  874. v-model:showSearch="showSearch"
  875. :columns="columns"
  876. @queryTable="getList">
  877. </right-toolbar>
  878. <!-- 列显隐控制 -->
  879. <script setup>
  880. const columns = ref([
  881. { key: 'name', label: '名称', visible: true },
  882. { key: 'status', label: '状态', visible: true },
  883. { key: 'createTime', label: '创建时间', visible: false }
  884. ]);
  885. </script>
  886. ```
  887. ### Pagination 分页组件
  888. ```vue
  889. <pagination
  890. v-show="total > 0"
  891. :total="total"
  892. v-model:page="queryParams.pageNum"
  893. v-model:limit="queryParams.pageSize"
  894. @pagination="getList" />
  895. ```
  896. ### DictTag 字典标签
  897. ```vue
  898. <dict-tag
  899. :options="dict_status"
  900. :value="row.status" />
  901. <script setup>
  902. const { dict_status } = toRefs<any>(proxy?.useDict('dict_status'));
  903. </script>
  904. ```
  905. ### ImageUpload 图片上传
  906. ```vue
  907. <image-upload v-model="form.image" />
  908. <!-- 图片预览 -->
  909. <image-preview
  910. :src="row.image"
  911. :width="50"
  912. :height="50" />
  913. ```
  914. ## 21. 样式开发规范
  915. ### SCSS变量使用
  916. ```scss
  917. // 使用设计变量
  918. .component {
  919. background-color: var(--art-main-bg-color);
  920. border: 1px solid var(--art-border-color);
  921. border-radius: var(--border-radius-md);
  922. padding: var(--space-lg);
  923. color: var(--art-text-gray-700);
  924. }
  925. // 响应式设计
  926. @media screen and (max-width: $device-phone) {
  927. .component {
  928. padding: var(--space-sm);
  929. }
  930. }
  931. ```
  932. ### 暗色主题适配
  933. ```scss
  934. // 组件支持暗色主题
  935. .component {
  936. background-color: var(--art-main-bg-color);
  937. // 暗色主题下自动适配
  938. html.dark & {
  939. border-color: var(--art-border-color);
  940. color: var(--art-text-gray-700);
  941. }
  942. }
  943. ```
  944. ### CSS类命名规范
  945. - **组件容器**:`.component-name-container`
  946. - **元素**:`.component-name__element`
  947. - **修饰符**:`.component-name--modifier`
  948. - **状态**:`.is-active`, `.is-disabled`, `.is-loading`
  949. - **工具类**:`.text-center`, `.mb-4`, `.p-2`
  950. ## 22. 权限控制规范
  951. ### 页面权限
  952. ```vue
  953. <template>
  954. <!-- 按钮权限控制 -->
  955. <el-button
  956. type="primary"
  957. @click="handleAdd"
  958. v-hasPermi="['system:user:add']">
  959. 新增
  960. </el-button>
  961. <!-- 路由权限在router中配置 -->
  962. </template>
  963. ```
  964. ### 路由权限配置
  965. ```typescript
  966. {
  967. path: '/user',
  968. component: Layout,
  969. meta: {
  970. title: '用户管理',
  971. icon: 'user',
  972. roles: ['admin', 'user'], // 角色权限
  973. permissions: ['system:user:view'] // 功能权限
  974. }
  975. }
  976. ```
  977. ## 23. 性能优化规范
  978. ### 组件懒加载
  979. ```typescript
  980. // 路由懒加载
  981. const UserManagement = () => import('@/views/system/user/index.vue');
  982. // 组件异步加载
  983. const LazyComponent = defineAsyncComponent(() => import('./LazyComponent.vue'));
  984. ```
  985. ### 列表优化
  986. ```vue
  987. <!-- 虚拟滚动(大数据量) -->
  988. <el-table-v2
  989. :columns="columns"
  990. :data="data"
  991. :width="800"
  992. :height="600"
  993. fixed />
  994. <!-- 分页加载 -->
  995. <pagination
  996. :total="total"
  997. v-model:page="queryParams.pageNum"
  998. v-model:limit="queryParams.pageSize" />
  999. ```
  1000. ### 图片优化
  1001. ```vue
  1002. <!-- 图片懒加载 -->
  1003. <el-image
  1004. :src="imageUrl"
  1005. lazy
  1006. loading="lazy"
  1007. :preview-src-list="[imageUrl]" />
  1008. <!-- 占位图 -->
  1009. <el-image
  1010. :src="imageUrl"
  1011. fit="cover"
  1012. loading="lazy">
  1013. <template #placeholder>
  1014. <div class="image-slot">加载中...</div>
  1015. </template>
  1016. <template #error>
  1017. <div class="image-slot">加载失败</div>
  1018. </template>
  1019. </el-image>
  1020. ```
  1021. ## 24. 国际化规范
  1022. ### 多语言配置
  1023. ```typescript
  1024. // lang/zh_CN.ts
  1025. export default {
  1026. common: {
  1027. add: '新增',
  1028. edit: '修改',
  1029. delete: '删除',
  1030. search: '搜索',
  1031. reset: '重置'
  1032. },
  1033. user: {
  1034. username: '用户名',
  1035. email: '邮箱',
  1036. status: '状态'
  1037. }
  1038. };
  1039. ```
  1040. ### 使用方式
  1041. ```vue
  1042. <template>
  1043. <el-button>{{ $t('common.add') }}</el-button>
  1044. <el-form-item :label="$t('user.username')">
  1045. <el-input v-model="form.username" />
  1046. </el-form-item>
  1047. </template>
  1048. <script setup>
  1049. const { t } = useI18n();
  1050. const buttonText = computed(() => t('common.add'));
  1051. </script>
  1052. ```
  1053. ## 25. 测试规范
  1054. ### 单元测试
  1055. ```typescript
  1056. // 组件测试
  1057. import { mount } from '@vue/test-utils';
  1058. import UserForm from '@/components/UserForm/index.vue';
  1059. describe('UserForm', () => {
  1060. test('should render correctly', () => {
  1061. const wrapper = mount(UserForm, {
  1062. props: {
  1063. visible: true,
  1064. data: {}
  1065. }
  1066. });
  1067. expect(wrapper.find('.user-form').exists()).toBe(true);
  1068. });
  1069. });
  1070. ```
  1071. ### E2E测试
  1072. ```typescript
  1073. // 页面流程测试
  1074. describe('User Management', () => {
  1075. test('should add user successfully', async () => {
  1076. await page.goto('/user');
  1077. await page.click('[data-test="add-button"]');
  1078. await page.fill('[data-test="username"]', 'testuser');
  1079. await page.click('[data-test="submit-button"]');
  1080. await expect(page.locator('.el-message')).toContainText('操作成功');
  1081. });
  1082. });
  1083. ```
  1084. ## 26. 构建和部署规范
  1085. ### 环境配置
  1086. ```typescript
  1087. // .env.development
  1088. VITE_APP_ENV = 'development'
  1089. VITE_APP_BASE_API = '/dev-api'
  1090. VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
  1091. // .env.production
  1092. VITE_APP_ENV = 'production'
  1093. VITE_APP_BASE_API = '/prod-api'
  1094. VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
  1095. ```
  1096. ### 构建优化
  1097. ```typescript
  1098. // vite.config.ts
  1099. export default defineConfig({
  1100. build: {
  1101. rollupOptions: {
  1102. output: {
  1103. chunkFileNames: 'js/[name]-[hash].js',
  1104. entryFileNames: 'js/[name]-[hash].js',
  1105. assetFileNames: 'assets/[name]-[hash].[ext]',
  1106. manualChunks: {
  1107. 'element-plus': ['element-plus'],
  1108. 'vue-vendor': ['vue', 'vue-router', 'pinia']
  1109. }
  1110. }
  1111. }
  1112. }
  1113. });
  1114. ```
  1115. ## 27. 代码质量保证
  1116. ### ESLint配置规范
  1117. ```typescript
  1118. // eslint.config.ts
  1119. export default [
  1120. {
  1121. rules: {
  1122. // Vue相关规则
  1123. 'vue/no-unused-vars': 'error',
  1124. 'vue/require-default-prop': 'off',
  1125. 'vue/multi-word-component-names': 'off',
  1126. // TypeScript相关规则
  1127. '@typescript-eslint/no-explicit-any': 'warn',
  1128. '@typescript-eslint/no-unused-vars': 'error',
  1129. // 通用规则
  1130. 'no-console': 'warn',
  1131. 'no-debugger': 'error'
  1132. }
  1133. }
  1134. ];
  1135. ```
  1136. ### 代码提交规范
  1137. ```bash
  1138. # 提交信息格式
  1139. git commit -m "feat(user): 新增用户管理功能"
  1140. # 提交类型
  1141. feat: 新功能
  1142. fix: 修复bug
  1143. docs: 文档更新
  1144. style: 代码格式调整
  1145. refactor: 重构代码
  1146. test: 测试相关
  1147. chore: 构建工具或辅助工具的变动
  1148. ```
  1149. ### 代码审查清单
  1150. - [ ] 代码符合项目规范
  1151. - [ ] 类型定义完整
  1152. - [ ] 组件可复用性良好
  1153. - [ ] 性能优化到位
  1154. - [ ] 无安全隐患
  1155. - [ ] 测试覆盖充分
  1156. - [ ] 文档更新及时
  1157. ---
  1158. 此规范基于 Art Design Pro 的优秀设计理念,结合现代 Web 设计趋势和 plus-ui 项目的实际实现,为 Plus UI 提供统一的设计语言和完整的开发标准。通过严格遵循此规范,可以确保项目的高质量、可维护性和团队协作效率。
  1159. ## 26. 代码调整记录规范
  1160. ### 📝 重要提醒:代码调整记录要求
  1161. **每次使用Cursor修改前端代码时,都必须在项目根目录的【代码调整记录.md】文件中记录调整信息。**
  1162. ### 记录格式标准
  1163. ### 记录要求
  1164. 1. **及时性**: 每次代码调整完成后立即记录
  1165. 2. **完整性**: 包含所有必要信息字段
  1166. 3. **准确性**: 详细描述实际的调整内容
  1167. 4. **可追溯性**: 便于后续查看和维护
  1168. ### Cursor AI使用提醒
  1169. 当您要求Cursor AI进行代码调整时,请提醒AI:
  1170. ```
  1171. 请在完成代码调整后,帮我在【代码调整记录.md】文件中记录本次调整的相关信息,
  1172. 包括调整时间、目的、涉及文件、具体内容等。
  1173. ```
  1174. ### 文件管理
  1175. - 记录文件位置: 项目根目录 `代码调整记录.md`
  1176. - 记录保留期: 建议保留至少6个月的调整记录
  1177. - 定期整理: 每月可将过期记录归档到 `docs/change-logs/` 目录
  1178. 这个记录制度有助于:
  1179. ✅ 追踪代码变更历史
  1180. ✅ 团队协作信息共享
  1181. ✅ 问题排查和回溯
  1182. ✅ 知识积累和经验总结
  1183. ✅ 项目维护和交接
  1184. ## 26. 代码调整记录规范
  1185. ### 📝 重要提醒:代码调整记录要求
  1186. **每次使用Cursor修改前端代码时,都必须在项目根目录的【代码调整记录.md】文件中记录调整信息。**
  1187. ### 记录格式标准
  1188. 每次调整后请按以下格式记录:
  1189. ```
  1190. ## 调整记录 - YYYY-MM-DD HH:mm:ss
  1191. **调整时间**: YYYY-MM-DD HH:mm:ss
  1192. **调整人**: [开发者姓名/Cursor AI辅助]
  1193. **调整目的**: [简述调整原因和目标]
  1194. **涉及文件**:
  1195. - src/views/module/file.vue
  1196. - src/api/module/file.ts
  1197. - src/components/ComponentName/index.vue
  1198. **调整内容详述**:
  1199. 1. 具体调整了哪些代码
  1200. 2. 修改了哪些功能
  1201. 3. 优化了哪些性能
  1202. 4. 修复了哪些问题
  1203. **技术细节**:
  1204. - 使用的技术栈: Vue 3.5.13 + TypeScript 5.8.3 + Element Plus 2.9.8
  1205. - 遵循的设计规范: Art Design Pro轮廓式按钮系统
  1206. - CSS变量使用: --art-*变量系统
  1207. - 其他重要技术决策
  1208. **测试验证**:
  1209. - [ ] 功能测试通过
  1210. - [ ] 样式规范检查通过
  1211. - [ ] TypeScript类型检查通过
  1212. - [ ] 响应式布局测试通过
  1213. - [ ] 暗色主题兼容性测试通过
  1214. **备注**: 其他需要说明的内容
  1215. ---
  1216. ```
  1217. ### 记录要求
  1218. 1. **及时性**: 每次代码调整完成后立即记录
  1219. 2. **完整性**: 包含所有必要信息字段
  1220. 3. **准确性**: 详细描述实际的调整内容
  1221. 4. **可追溯性**: 便于后续查看和维护
  1222. ### Cursor AI使用提醒
  1223. 当您要求Cursor AI进行代码调整时,请提醒AI:
  1224. "请在完成代码调整后,帮我在【代码调整记录.md】文件中记录本次调整的相关信息,包括调整时间、目的、涉及文件、具体内容等。"
  1225. ### 文件管理
  1226. - 记录文件位置: 项目根目录 `代码调整记录.md`
  1227. - 记录保留期: 建议保留至少6个月的调整记录
  1228. - 定期整理: 每月可将过期记录归档到 `docs/change-logs/` 目录
  1229. 这个记录制度有助于:
  1230. ✅ 追踪代码变更历史
  1231. ✅ 团队协作信息共享
  1232. ✅ 问题排查和回溯
  1233. ✅ 知识积累和经验总结
  1234. ✅ 项目维护和交接
  1235. ### ⚠️ 强制要求
  1236. **所有通过Cursor AI进行的代码调整都必须在【代码调整记录.md】中留下记录,这是项目管理的强制性要求。**