From a0131b5ef8895b07bac97c74601cad11e291887a Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期三, 25 三月 2026 14:00:03 +0800
Subject: [PATCH] 销售看板
---
src/views/index.vue | 2067 ++++++++++++++++++++++++++++++++--------------------------
1 files changed, 1,124 insertions(+), 943 deletions(-)
diff --git a/src/views/index.vue b/src/views/index.vue
index 068e01d..73650ba 100644
--- a/src/views/index.vue
+++ b/src/views/index.vue
@@ -1,943 +1,1124 @@
-<template>
- <div class="app-container home">
- <el-row :gutter="20">
- <el-col :sm="24" :lg="24">
- <blockquote class="text-warning" style="font-size: 14px">
- 棰嗗彇闃块噷浜戦�氱敤浜戜骇鍝�1888浼樻儬鍒�
- <br />
- <el-link
- href="https://www.aliyun.com/minisite/goods?userCode=brki8iof"
- type="primary"
- target="_blank"
- >https://www.aliyun.com/minisite/goods?userCode=brki8iof</el-link
- >
- <br />
- 棰嗗彇鑵捐浜戦�氱敤浜戜骇鍝�2860浼樻儬鍒�
- <br />
- <el-link
- href="https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console"
- type="primary"
- target="_blank"
- >https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console</el-link
- >
- <br />
- 闃块噷浜戞湇鍔″櫒鎶樻墸鍖�
- <el-link href="http://aly.ruoyi.vip" type="primary" target="_blank"
- >>鈽涒槢鐐规垜杩涘叆鈽氣槡</el-link
- >
- 鑵捐浜戞湇鍔″櫒绉掓潃鍖�
- <el-link href="http://txy.ruoyi.vip" type="primary" target="_blank"
- >>鈽涒槢鐐规垜杩涘叆鈽氣槡</el-link
- ><br />
- <h4 class="text-danger">
- 浜戜骇鍝侀�氱敤绾㈠寘锛屽彲鍙犲姞瀹樼綉甯歌浼樻儬浣跨敤銆�(浠呴檺鏂扮敤鎴�)
- </h4>
- </blockquote>
-
- <hr />
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :sm="24" :lg="12" style="padding-left: 20px">
- <h2>鑻ヤ緷鍚庡彴绠$悊妗嗘灦</h2>
- <p>
- 涓�鐩存兂鍋氫竴娆惧悗鍙扮鐞嗙郴缁燂紝鐪嬩簡寰堝浼樼鐨勫紑婧愰」鐩絾鏄彂鐜版病鏈夊悎閫傝嚜宸辩殑銆備簬鏄埄鐢ㄧ┖闂蹭紤鎭椂闂村紑濮嬭嚜宸卞啓涓�濂楀悗鍙扮郴缁熴�傚姝ゆ湁浜嗚嫢渚濈鐞嗙郴缁燂紝濂瑰彲浠ョ敤浜庢墍鏈夌殑Web搴旂敤绋嬪簭锛屽缃戠珯绠$悊鍚庡彴锛岀綉绔欎細鍛樹腑蹇冿紝CMS锛孋RM锛孫A绛夌瓑锛屽綋鐒讹紝鎮ㄤ篃鍙互瀵瑰ス杩涜娣卞害瀹氬埗锛屼互鍋氬嚭鏇村己绯荤粺銆傛墍鏈夊墠绔悗鍙颁唬鐮佸皝瑁呰繃鍚庡崄鍒嗙簿绠�鏄撲笂鎵嬶紝鍑洪敊姒傜巼浣庛�傚悓鏃舵敮鎸佺Щ鍔ㄥ鎴风璁块棶銆傜郴缁熶細闄嗙画鏇存柊涓�浜涘疄鐢ㄥ姛鑳姐��
- </p>
- <p>
- <b>褰撳墠鐗堟湰:</b> <span>v{{ version }}</span>
- </p>
- <p>
- <el-tag type="danger">¥鍏嶈垂寮�婧�</el-tag>
- </p>
- <p>
- <el-button
- type="primary"
- icon="Cloudy"
- plain
- @click="goTarget('https://gitee.com/y_project/RuoYi-Vue')"
- >璁块棶鐮佷簯</el-button
- >
- <el-button
- icon="HomeFilled"
- plain
- @click="goTarget('http://ruoyi.vip')"
- >璁块棶涓婚〉</el-button
- >
- </p>
- </el-col>
-
- <el-col :sm="24" :lg="12" style="padding-left: 50px">
- <el-row>
- <el-col :span="12">
- <h2>鎶�鏈�夊瀷</h2>
- </el-col>
- </el-row>
- <el-row>
- <el-col :span="6">
- <h4>鍚庣鎶�鏈�</h4>
- <ul>
- <li>SpringBoot</li>
- <li>Spring Security</li>
- <li>JWT</li>
- <li>MyBatis</li>
- <li>Druid</li>
- <li>Fastjson</li>
- <li>...</li>
- </ul>
- </el-col>
- <el-col :span="6">
- <h4>鍓嶇鎶�鏈�</h4>
- <ul>
- <li>Vue</li>
- <li>Vuex</li>
- <li>Element-ui</li>
- <li>Axios</li>
- <li>Sass</li>
- <li>Quill</li>
- <li>...</li>
- </ul>
- </el-col>
- </el-row>
- </el-col>
- </el-row>
- <el-divider />
- <el-row :gutter="20">
- <el-col :xs="24" :sm="24" :md="12" :lg="8">
- <el-card class="update-log">
- <template v-slot:header>
- <div class="clearfix">
- <span>鑱旂郴淇℃伅</span>
- </div>
- </template>
- <div class="body">
- <p>
- <i class="el-icon-s-promotion"></i> 瀹樼綉锛�<el-link
- href="http://www.ruoyi.vip"
- target="_blank"
- >http://www.ruoyi.vip</el-link
- >
- </p>
- <p>
- <i class="el-icon-user-solid"></i> QQ缇わ細<s>婊�937441</s> <s>婊�887144332</s>
- <s>婊�180251782</s> <s>婊�104180207</s> <s>婊�186866453</s> <s>婊�201396349</s>
- <s>婊�101456076</s> <s>婊�101539465</s> <s>婊�264312783</s> <s>婊�167385320</s>
- <s>婊�104748341</s> <s>婊�160110482</s> <a href="https://jq.qq.com/?_wv=1027&k=Xnbinl0U" target="_blank">
- 170801498</a
- >
- </p>
- <p>
- <i class="el-icon-chat-dot-round"></i> 寰俊锛�<a
- href="javascript:;"
- >/ *鑻ヤ緷</a
- >
- </p>
- <p>
- <i class="el-icon-money"></i> 鏀粯瀹濓細<a
- href="javascript:;"
- class="鏀粯瀹濅俊鎭�"
- >/ *鑻ヤ緷</a
- >
- </p>
- </div>
- </el-card>
- </el-col>
- <el-col :xs="24" :sm="24" :md="12" :lg="8">
- <el-card class="update-log">
- <template v-slot:header>
- <div class="clearfix">
- <span>鏇存柊鏃ュ織</span>
- </div>
- </template>
- <el-collapse accordion>
- <el-collapse-item title="v3.8.4 - 2022-09-26">
- <ol>
- <li>鏁版嵁閫昏緫鍒犻櫎涓嶈繘琛屽敮涓�楠岃瘉</li>
- <li>Excel娉ㄨВ鏀寔瀵煎嚭瀵硅薄鐨勫瓙鍒楄〃鏂规硶</li>
- <li>Excel娉ㄨВ鏀寔鑷畾涔夐殣钘忓睘鎬у垪</li>
- <li>Excel娉ㄨВ鏀寔backgroundColor灞炴�ц缃儗鏅壊</li>
- <li>鏀寔閰嶇疆瀵嗙爜鏈�澶ч敊璇鏁�/閿佸畾鏃堕棿</li>
- <li>鐧诲綍鏃ュ織鏂板瑙i攣璐︽埛鍔熻兘</li>
- <li>閫氱敤涓嬭浇鏂规硶鏂板config閰嶇疆閫夐」</li>
- <li>鏀寔澶氭潈闄愬瓧绗﹀尮閰嶈鑹叉暟鎹潈闄�</li>
- <li>椤甸潰鍐呭祵iframe鍒囨崲tab涓嶅埛鏂版暟鎹�</li>
- <li>鎿嶄綔鏃ュ織璁板綍鏀寔鎺掗櫎鏁忔劅灞炴�у瓧娈�</li>
- <li>淇澶氭枃浠朵笂浼犳姤閿欏嚭鐜扮殑寮傚父闂</li>
- <li>淇鍥剧墖棰勮缁勪欢src灞炴�т负null鍊兼帶鍒跺彴鎶ラ敊闂</li>
- <li>鍗囩骇oshi鍒版渶鏂扮増鏈�6.2.2</li>
- <li>鍗囩骇fastjson鍒版渶鏂扮増2.0.14</li>
- <li>鍗囩骇pagehelper鍒版渶鏂扮増1.4.3</li>
- <li>鍗囩骇core-js鍒版渶鏂扮増鏈�3.25.2</li>
- <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.10</li>
- <li>浼樺寲浠诲姟杩囨湡涓嶆墽琛岃皟搴�</li>
- <li>浼樺寲瀛楀吀鏁版嵁浣跨敤store瀛樺彇</li>
- <li>浼樺寲淇敼璧勬枡澶村儚琚鐩栫殑闂</li>
- <li>浼樺寲淇敼鐢ㄦ埛鐧诲綍璐﹀彿閲嶅楠岃瘉</li>
- <li>浼樺寲浠g爜鐢熸垚鍚屾鍚庡�糔ULL闂</li>
- <li>浼樺寲瀹氭椂浠诲姟鏀寔鎵ц鐖剁被鏂规硶</li>
- <li>浼樺寲鐢ㄦ埛涓汉淇℃伅鎺ュ彛闃叉淇敼閮ㄩ棬</li>
- <li>浼樺寲甯冨眬璁剧疆浣跨敤el-drawer鎶藉眽鏄剧ず</li>
- <li>浼樺寲娌℃湁鏉冮檺鐨勭敤鎴风紪杈戦儴闂ㄧ己灏戞暟鎹�</li>
- <li>浼樺寲鏃ュ織娉ㄨВ璁板綍闄愬埗璇锋眰鍦板潃鐨勯暱搴�</li>
- <li>浼樺寲excel/scale灞炴�у鍑哄崟鍏冩牸鏁板�肩被鍨�</li>
- <li>浼樺寲鏃ュ織鎿嶄綔涓噸缃寜閽椂閲嶅鏌ヨ鐨勯棶棰�</li>
- <li>浼樺寲澶氫釜鐩稿悓瑙掕壊鏁版嵁瀵艰嚧鏉冮檺SQL閲嶅闂</li>
- <li>浼樺寲琛ㄦ牸涓婂彸渚у伐鍏锋潯锛堟悳绱㈡寜閽樉闅�&鍙充晶鏍峰紡鍑稿嚭锛�</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v3.8.3 - 2022-06-27">
- <ol>
- <li>鏂板缂撳瓨鍒楄〃鑿滃崟鍔熻兘</li>
- <li>浠g爜鐢熸垚鏍戣〃鏂板(灞曞紑/鎶樺彔)</li>
- <li>Excel娉ㄨВ鏀寔color瀛椾綋棰滆壊</li>
- <li>鏂板Anonymous鍖垮悕璁块棶涓嶉壌鏉冩敞瑙�</li>
- <li>鐢ㄦ埛澶村儚涓婁紶闄愬埗鍙兘涓哄浘鐗囨牸寮�</li>
- <li>鎺ュ彛浣跨敤娉涘瀷浣垮叾鐪嬪埌鍝嶅簲灞炴�у瓧娈�</li>
- <li>妫�鏌ュ畾鏃朵换鍔ean鎵�鍦ㄥ寘鍚嶆槸鍚︿负鐧藉悕鍗曢厤缃�</li>
- <li>娣诲姞椤电openPage鏀寔浼犻�掑弬鏁�</li>
- <li>鐢ㄦ埛缂撳瓨淇℃伅娣诲姞閮ㄩ棬ancestors绁栫骇鍒楄〃</li>
- <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.8</li>
- <li>鍗囩骇oshi鍒版渶鏂扮増鏈�6.1.6</li>
- <li>鍗囩骇druid鍒版渶鏂扮増鏈�1.2.11</li>
- <li>鍗囩骇fastjson鍒版渶鏂扮増2.0.8</li>
- <li>鍗囩骇spring-boot鍒版渶鏂扮増鏈�2.5.14</li>
- <li>闄嶇骇jsencrypt鐗堟湰鍏煎IE娴忚鍣�</li>
- <li>鍒犻櫎澶氫綑鐨剆alt瀛楁</li>
- <li>鏂板鑾峰彇涓嶅甫鍚庣紑鏂囦欢鍚嶇О鏂规硶</li>
- <li>鏂板鑾峰彇閰嶇疆鏂囦欢涓殑灞炴�у�兼柟娉�</li>
- <li>鏂板鍐呭缂栫爜/瑙g爜鏂逛究鎻掍欢闆嗘垚浣跨敤</li>
- <li>瀛楀吀绫诲瀷蹇呴』浠ュ瓧姣嶅紑澶达紝涓斿彧鑳戒负锛堝皬鍐欏瓧姣嶏紝鏁板瓧锛屼笅婊戠嚎锛�</li>
- <li>浼樺寲璁剧疆鍒嗛〉鍙傛暟榛樿鍊�</li>
- <li>浼樺寲瀵圭┖瀛楃涓插弬鏁板鐞嗙殑杩囨护</li>
- <li>浼樺寲鏄剧ず椤哄簭orderNum绫诲瀷涓烘暣鍨�</li>
- <li>浼樺寲琛ㄥ崟鏋勫缓鎸夐挳涓嶆樉绀烘鍒欐牎楠�</li>
- <li>浼樺寲瀛楀吀鏁版嵁鍥炴樉鏍峰紡涓嬫媺妗嗘樉绀哄��</li>
- <li>浼樺寲R鍝嶅簲鎴愬姛鐘舵�佺爜涓庡叏灞�淇濇寔涓�鑷�</li>
- <li>浼樺寲druid寮�鍚痺all杩囨护鍣ㄥ嚭鐜扮殑寮傚父闂</li>
- <li>浼樺寲鐢ㄦ埛绠$悊宸︿晶鏍戝瀷缁勪欢澧炲姞閫変腑楂樹寒淇濇寔</li>
- <li>浼樺寲鏂板鐢ㄦ埛涓庤鑹蹭俊鎭�&鐢ㄦ埛涓庡矖浣嶄俊鎭�昏緫</li>
- <li>浼樺寲榛樿涓嶅惎鐢ㄥ帇缂╂枃浠剁紦瀛橀槻姝ode_modules杩囧ぇ</li>
- <li>淇瀛楀吀鏁版嵁鏄剧ず涓嶅叏闂</li>
- <li>淇鎿嶄綔鏃ュ織鏌ヨ绫诲瀷鏉′欢涓�0鏃朵細鏌ュ埌鎵�鏈夋暟鎹�</li>
- <li>淇Excel娉ㄨВprompt/combo鍚屾椂浣跨敤涓嶇敓鏁堥棶棰�</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v3.8.2 - 2022-04-01">
- <ol>
- <li>鍓嶇鏀寔璁剧疆鏄惁闇�瑕侀槻姝㈡暟鎹噸澶嶆彁浜�</li>
- <li>寮�鍚疶opNav娌℃湁瀛愯彍鍗曟儏鍐甸殣钘忎晶杈规爮</li>
- <li>渚ц竟鏍忚彍鍗曞悕绉拌繃闀挎偓鍋滄樉绀烘爣棰�</li>
- <li>鐢ㄦ埛璁块棶鎺у埗鏃舵牎楠屾暟鎹潈闄愶紝闃叉瓒婃潈</li>
- <li>瀵煎嚭Excel鏃跺睆钄藉叕寮忥紝闃叉CSV娉ㄥ叆椋庨櫓</li>
- <li>缁勪欢ImagePreview鏀寔澶氬浘棰勮鏄剧ず</li>
- <li>缁勪欢ImageUpload鏀寔澶氬浘鍚屾椂閫夋嫨涓婁紶</li>
- <li>缁勪欢FileUpload鏀寔澶氭枃浠跺悓鏃堕�夋嫨涓婁紶</li>
- <li>鏈嶅姟鐩戞帶鏂板杩愯鍙傛暟淇℃伅鏄剧ず</li>
- <li>瀹氭椂浠诲姟鐩爣瀛楃涓茶繃婊ょ壒娈婂瓧绗�</li>
- <li>瀹氭椂浠诲姟鐩爣瀛楃涓查獙璇佸寘鍚嶇櫧鍚嶅崟</li>
- <li>浠g爜鐢熸垚鍒楄〃鍥剧墖鏀寔棰勮</li>
- <li>浠g爜鐢熸垚缂栬緫淇敼鎵撳紑鏂伴〉绛�</li>
- <li>浠g爜鐢熸垚鏂板Java绫诲瀷Boolean</li>
- <li>浠g爜鐢熸垚瀛愯〃鏀寔鏃ユ湡/瀛楀吀閰嶇疆</li>
- <li>浠g爜鐢熸垚鍚屾淇濈暀蹇呭~/绫诲瀷閫夐」</li>
- <li>鍗囩骇oshi鍒版渶鏂扮増鏈�6.1.2</li>
- <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.80</li>
- <li>鍗囩骇pagehelper鍒版渶鏂扮増1.4.1</li>
- <li>鍗囩骇spring-boot鍒版渶鏂扮増鏈�2.5.11</li>
- <li>鍗囩骇spring-boot-mybatis鍒版渶鏂扮増2.2.2</li>
- <li>娣诲姞閬楁紡鐨勫垎椤靛弬鏁板悎鐞嗗寲灞炴��</li>
- <li>淇敼npm鍗冲皢杩囨湡鐨勬敞鍐屾簮鍦板潃</li>
- <li>淇鍒嗛〉缁勪欢璇锋眰涓ゆ闂</li>
- <li>淇閫氱敤鏂囦欢涓嬭浇鎺ュ彛璺ㄥ煙闂</li>
- <li>淇Xss娉ㄨВ瀛楁鍊间负绌烘椂鐨勫紓甯搁棶棰�</li>
- <li>淇閫夐」鍗$偣鍑诲彸閿埛鏂颁涪澶卞弬鏁伴棶棰�</li>
- <li>淇琛ㄥ崟娓呴櫎鍏冪礌浣嶇疆鏈瀭鐩村眳涓棶棰�</li>
- <li>淇鏈嶅姟鐩戞帶涓繍琛屽弬鏁版樉绀烘潯浠堕敊璇�</li>
- <li>淇瀵煎叆Excel鏃跺瓧鍏稿瓧娈电被鍨嬩负Long杞箟涓虹┖闂</li>
- <li>淇鐧诲綍瓒呮椂鍒锋柊椤甸潰璺宠浆鐧诲綍椤甸潰杩樻彁绀洪噸鏂扮櫥褰曢棶棰�</li>
- <li>浼樺寲鍔犺浇瀛楀吀缂撳瓨鏁版嵁</li>
- <li>浼樺寲IP鍦板潃鑾峰彇鍒板涓殑闂</li>
- <li>浼樺寲浠诲姟闃熷垪婊℃椂浠诲姟鎷掔粷绛栫暐</li>
- <li>浼樺寲鏂囦欢涓婁紶鍏煎Weblogic鐜</li>
- <li>浼樺寲瀹氭椂浠诲姟榛樿淇濆瓨鍒板唴瀛樹腑鎵ц</li>
- <li>浼樺寲閮ㄩ棬淇敼缂╂斁鍚庡嚭鐜扮殑閿欎綅闂</li>
- <li>浼樺寲Excel鏍煎紡鍖栦笉鍚岀被鍨嬬殑鏃ユ湡瀵硅薄</li>
- <li>浼樺寲鑿滃崟琛ㄥ叧閿瓧瀵艰嚧鐨勬彃浠舵姤閿欓棶棰�</li>
- <li>浼樺寲Oracle鐢ㄦ埛澶村儚鍒椾负绌烘椂涓嶆樉绀洪棶棰�</li>
- <li>浼樺寲椤甸潰鑻ユ湭鍖归厤鍒板瓧鍏告爣绛惧垯杩斿洖鍘熷瓧鍏稿��</li>
- <li>浼樺寲淇鐧诲綍澶辨晥鍚庡娆¤姹傛彁绀哄娆″脊绐楅棶棰�</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v3.8.1 - 2022-01-01">
- <ol>
- <li>鏂板Vue3鍓嶇浠g爜鐢熸垚妯℃澘</li>
- <li>鏂板鍥剧墖棰勮缁勪欢</li>
- <li>鏂板鍘嬬缉鎻掍欢瀹炵幇鎵撳寘Gzip</li>
- <li>鑷畾涔墄ss鏍¢獙娉ㄨВ瀹炵幇</li>
- <li>鑷畾涔夋枃瀛楀鍒跺壀璐存寚浠�</li>
- <li>浠g爜鐢熸垚棰勮鏀寔澶嶅埗鍐呭</li>
- <li>璺敱鏀寔鍗曠嫭閰嶇疆鑿滃崟鎴栬鑹叉潈闄�</li>
- <li>鐢ㄦ埛绠$悊閮ㄩ棬鏌ヨ閫夋嫨鑺傜偣鍚庡垎椤靛弬鏁板垵濮�</li>
- <li>淇鐢ㄦ埛鍒嗛厤瑙掕壊灞炴�ч敊璇�</li>
- <li>淇鎵撳寘鍚庡瓧浣撳浘鏍囧伓鐜扮殑涔辩爜闂</li>
- <li>淇鑿滃崟绠$悊閲嶇疆琛ㄥ崟鍑虹幇鐨勯敊璇�</li>
- <li>淇鐗堟湰宸紓瀵艰嚧鐨勬噿鍔犺浇鎶ラ敊闂</li>
- <li>淇Cron缁勪欢涓懆鍥炴樉闂</li>
- <li>淇瀹氭椂浠诲姟澶氬弬鏁伴�楀彿鍒嗛殧鐨勯棶棰�</li>
- <li>淇鏍规嵁ID鏌ヨ鍒楄〃鍙兘鍑虹幇鐨勪富閿孩鍑洪棶棰�</li>
- <li>淇tomcat閰嶇疆鍙傛暟宸茶繃鏈熼棶棰�</li>
- <li>鍗囩骇clipboard鍒版渶鏂扮増鏈�2.0.8</li>
- <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.8.6</li>
- <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.79</li>
- <li>鍗囩骇spring-boot鍒版渶鏂扮増鏈�2.5.8</li>
- <li>鍗囩骇log4j2鍒�2.17.1锛岄槻姝㈡紡娲為闄�</li>
- <li>浼樺寲涓嬭浇瑙f瀽blob寮傚父鎻愮ず</li>
- <li>浼樺寲浠g爜鐢熸垚瀛楀吀缁勯噸澶嶉棶棰�</li>
- <li>浼樺寲鏌ヨ鐢ㄦ埛鐨勮鑹茬粍&宀椾綅缁勪唬鐮�</li>
- <li>浼樺寲瀹氭椂浠诲姟cron琛ㄨ揪寮忓皬鏃惰缃�24</li>
- <li>浼樺寲鐢ㄦ埛瀵煎叆鎻愮ず婧㈠嚭鍒欐樉绀烘粴鍔ㄦ潯</li>
- <li>浼樺寲闃查噸澶嶆彁浜ゆ爣璇嗙粍鍚堜负(key+url+header)</li>
- <li>浼樺寲鍒嗛〉鏂规硶璁剧疆鎴愰�氱敤鏂逛究鐏垫椿璋冪敤</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v3.8.0 - 2021-12-01">
- <ol>
- <li>鏂板閰嶅骞跺悓姝ョ殑Vue3鍓嶇鐗堟湰</li>
- <li>鏂板閫氱敤鏂规硶绠�鍖栨ā鎬�/缂撳瓨/涓嬭浇/鏉冮檺/椤电浣跨敤</li>
- <li>浼樺寲瀵煎嚭鏁版嵁/浣跨敤閫氱敤涓嬭浇鏂规硶</li>
- <li>Excel娉ㄨВ鏀寔鑷畾涔夋暟鎹鐞嗗櫒</li>
- <li>Excel娉ㄨВ鏀寔瀵煎叆瀵煎嚭鏍囬淇℃伅</li>
- <li>Excel瀵煎叆鏀寔@Excels娉ㄨВ</li>
- <li>鏂板缁勪欢data-dict锛岀畝鍖栨暟鎹瓧鍏镐娇鐢�</li>
- <li>鏂板Jaxb渚濊禆锛岄槻姝dk8浠ヤ笂鍑虹幇鐨勫吋瀹归敊璇�</li>
- <li>鐢熶骇鐜浣跨敤璺敱鎳掑姞杞芥彁鍗囬〉闈㈠搷搴旈�熷害</li>
- <li>淇浜旂骇浠ヤ笂鑿滃崟鍑虹幇鐨�404闂</li>
- <li>闃查噸鎻愪氦娉ㄨВ鏀寔閰嶇疆闂撮殧鏃堕棿/鎻愮ず娑堟伅</li>
- <li>鏃ュ織娉ㄨВ鏂板鏄惁淇濆瓨鍝嶅簲鍙傛暟</li>
- <li>浠诲姟灞忚斀杩濊瀛楃&鍙傛暟蹇界暐鍙屽紩鍙蜂腑鐨勯�楀彿</li>
- <li>鍗囩骇SpringBoot鍒版渶鏂扮増鏈�2.5.6</li>
- <li>鍗囩骇pagehelper鍒版渶鏂扮増1.4.0</li>
- <li>鍗囩骇spring-boot-mybatis鍒版渶鏂扮増2.2.0</li>
- <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.8.2</li>
- <li>鍗囩骇druid鍒版渶鏂扮増1.2.8</li>
- <li>鍗囩骇velocity鍒版渶鏂扮増鏈�2.3</li>
- <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.78</li>
- <li>鍗囩骇axios鍒版渶鏂扮増鏈�0.24.0</li>
- <li>鍗囩骇dart-sass鍒扮増鏈�1.32.13</li>
- <li>鍗囩骇core-js鍒版渶鏂扮増鏈�3.19.1</li>
- <li>鍗囩骇jsencrypt鍒版渶鏂扮増鏈�3.2.1</li>
- <li>鍗囩骇js-cookie鍒版渶鏂扮増鏈�3.0.1</li>
- <li>鍗囩骇file-saver鍒版渶鏂扮増鏈�2.0.5</li>
- <li>鍗囩骇sass-loader鍒版渶鏂扮増鏈�10.1.1</li>
- <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.6</li>
- <li>鏂板sendGet鏃犲弬璇锋眰鏂规硶</li>
- <li>绂佺敤el-tag缁勪欢鐨勬笎鍙樺姩鐢�</li>
- <li>浠g爜鐢熸垚鐐瑰嚮棰勮閲嶇疆婵�娲籺ab</li>
- <li>AjaxResult閲嶅啓put鏂规硶锛屼互鏂逛究閾惧紡璋冪敤</li>
- <li>浼樺寲鐧诲綍/楠岃瘉鐮佽姹俬eaders涓嶈缃畉oken</li>
- <li>浼樺寲鐢ㄦ埛涓汉淇℃伅鎺ュ彛闃叉淇敼鐢ㄦ埛鍚�</li>
- <li>浼樺寲Cron琛ㄨ揪寮忕敓鎴愬櫒鍏抽棴鏃堕攢姣侀伩鍏嶇紦瀛�</li>
- <li>浼樺寲娉ㄥ唽鎴愬姛鎻愮ず娑堟伅绫诲瀷success</li>
- <li>浼樺寲aop璇硶锛屼娇鐢╯pring鑷姩娉ㄥ叆娉ㄨВ</li>
- <li>浼樺寲璁板綍鐧诲綍淇℃伅锛岀Щ闄や笉蹇呰鐨勪慨鏀�</li>
- <li>浼樺寲mybatis鍏ㄥ眬榛樿鐨勬墽琛屽櫒</li>
- <li>浼樺寲Excel瀵煎叆鍥剧墖鍙兘鍑虹幇鐨勫紓甯�</li>
- <li>淇浠g爜鐢熸垚妯℃澘涓诲瓙琛ㄥ垹闄ょ己灏戜簨鍔�</li>
- <li>淇鏃ュ織璁板綍鍙兘鍑虹幇鐨勮浆鎹㈠紓甯�</li>
- <li>淇浠g爜鐢熸垚澶嶉�夋瀛楀吀閬楁紡闂</li>
- <li>淇鍏抽棴xss鍔熻兘瀵艰嚧鍙噸澶嶈RepeatableFilter澶辨晥</li>
- <li>淇瀛楃涓叉棤娉曡鍙嶈浆涔夐棶棰�</li>
- <li>淇鍚庣涓诲瓙琛ㄤ唬鐮佹ā鏉挎柟娉曞悕鐢熸垚閿欒闂</li>
- <li>淇xss杩囨护鍚庢牸寮忓嚭鐜扮殑寮傚父</li>
- <li>淇swagger娌℃湁鎸囧畾dataTypeClass瀵艰嚧鍚姩鍑虹幇warn鏃ュ織</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v3.7.0 - 2021-09-13">
- <ol>
- <li>鍙傛暟绠$悊鏀寔閰嶇疆楠岃瘉鐮佸紑鍏�</li>
- <li>鏂板鏄惁寮�鍚敤鎴锋敞鍐屽姛鑳�</li>
- <li>瀹氭椂浠诲姟鏀寔鍦ㄧ嚎鐢熸垚cron琛ㄨ揪寮�</li>
- <li>鑿滃崟绠$悊鏀寔閰嶇疆璺敱鍙傛暟</li>
- <li>鏀寔鑷畾涔夋敞瑙e疄鐜版帴鍙i檺娴�</li>
- <li>Excel娉ㄨВ鏀寔Image鍥剧墖瀵煎叆</li>
- <li>鑷畾涔夊脊灞傛孩鍑烘粴鍔ㄦ牱寮�</li>
- <li>鑷畾涔夊彲鎷栧姩寮圭獥瀹藉害鎸囦护</li>
- <li>鑷畾涔夊彲鎷栧姩寮圭獥楂樺害鎸囦护</li>
- <li>淇浠绘剰璐︽埛瓒婃潈闂</li>
- <li>淇敼鏃舵鏌ョ敤鎴锋暟鎹潈闄愯寖鍥�</li>
- <li>淇淇濆瓨閰嶇疆涓婚棰滆壊澶辨晥闂</li>
- <li>鏂板鏆楄壊鑿滃崟椋庢牸涓婚</li>
- <li>鑿滃崟&閮ㄩ棬鏂板灞曞紑/鎶樺彔鍔熻兘</li>
- <li>椤电鏂板鍏抽棴宸︿晶&娣诲姞鍥炬爣</li>
- <li>椤堕儴鑿滃崟鎺掗櫎闅愯棌鐨勯粯璁よ矾鐢�</li>
- <li>椤堕儴鑿滃崟鍚屾绯荤粺涓婚鏍峰紡</li>
- <li>璺宠浆璺敱楂樹寒鐩稿搴旂殑鑿滃崟鏍�</li>
- <li>浠g爜鐢熸垚涓诲瓙琛ㄥ閫夎鏁版嵁</li>
- <li>鏃ユ湡鑼冨洿鏀寔娣诲姞澶氱粍</li>
- <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.5</li>
- <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.8.0</li>
- <li>鍗囩骇commons.io鍒版渶鏂扮増鏈瑅2.11.0</li>
- <li>瀹氭椂浠诲姟灞忚斀ldap杩滅▼璋冪敤</li>
- <li>瀹氭椂浠诲姟灞忚斀http(s)杩滅▼璋冪敤</li>
- <li>琛ュ厖瀹氭椂浠诲姟琛ㄥ瓧娈垫敞閲�</li>
- <li>瀹氭椂浠诲姟瀵规鏌ュ紓甯歌繘琛屼簨鍔″洖婊�</li>
- <li>鍚敤鐖堕儴闂ㄧ姸鎬佹帓闄ら《绾ц妭鐐�</li>
- <li>瀵屾枃鏈柊澧炰笂浼犳枃浠跺ぇ灏忛檺鍒�</li>
- <li>榛樿棣栭〉浣跨敤keep-alive缂撳瓨</li>
- <li>淇敼浠g爜鐢熸垚瀛楀吀鍥炴樉鏍峰紡</li>
- <li>鑷畾涔夊垎椤靛悎鐞嗗寲浼犲叆鍙傛暟</li>
- <li>淇瀛楀吀缁勪欢鍊间负鏁村舰涓嶆樉绀洪棶棰�</li>
- <li>淇瀹氭椂浠诲姟鏃ュ織鎵ц鐘舵�佹樉绀�</li>
- <li>瑙掕壊&鑿滃崟鏂板瀛楁灞炴�ф彁绀轰俊鎭�</li>
- <li>淇瑙掕壊鍒嗛厤鐢ㄦ埛椤甸潰鍙傛暟绫诲瀷閿欒鎻愰啋</li>
- <li>浼樺寲甯冨眬璁剧疆鍔ㄧ敾鐗规晥</li>
- <li>浼樺寲寮傚父澶勭悊淇℃伅</li>
- <li>浼樺寲閿欒token瀵艰嚧鐨勮В鏋愬紓甯�</li>
- <li>瀵嗙爜妗嗘柊澧炴樉绀哄垏鎹㈠瘑鐮佸浘鏍�</li>
- <li>瀹氭椂浠诲姟鏂板鏇村鎿嶄綔</li>
- <li>鏇村鎿嶄綔鎸夐挳娣诲姞鏉冮檺鎺у埗</li>
- <li>瀵煎叆鐢ㄦ埛鏍峰紡浼樺寲</li>
- <li>鎻愬彇閫氱敤鏂规硶鍒板熀绫绘帶鍒跺櫒</li>
- <li>浼樺寲浣跨敤鏉冮檺宸ュ叿鑾峰彇鐢ㄦ埛淇℃伅</li>
- <li>浼樺寲鐢ㄦ埛涓嶈兘鍒犻櫎鑷繁</li>
- <li>浼樺寲XSS璺ㄧ珯鑴氭湰杩囨护</li>
- <li>浼樺寲浠g爜鐢熸垚妯℃澘</li>
- <li>楠岃瘉鐮侀粯璁�20s瓒呮椂</li>
- <li>BLOB涓嬭浇鏃舵竻闄RL瀵硅薄寮曠敤</li>
- <li>浠g爜鐢熸垚瀵煎叆琛ㄦ寜鍒涘缓鏃堕棿鎺掑簭</li>
- <li>淇浠g爜鐢熸垚椤甸潰鏁版嵁缂栬緫淇濆瓨涔嬪悗鎬绘槸璺宠浆绗竴椤电殑闂</li>
- <li>淇甯afari娴忚鍣ㄦ棤娉曟牸寮忓寲utc鏃ユ湡鏍煎紡yyyy-MM-dd'T'HH:mm:ss.SSS闂</li>
- <li>澶氬浘涓婁紶缁勪欢绉婚櫎澶氫綑鐨刟pi鍦板潃&楠岃瘉澶辫触瀵艰嚧鍥剧墖鍒犻櫎闂&鏃犳硶鍒犻櫎鐩稿簲鍥剧墖淇</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v3.6.0 - 2021-07-12">
- <ol>
- <li>瑙掕壊绠$悊鏂板鍒嗛厤鐢ㄦ埛鍔熻兘</li>
- <li>鐢ㄦ埛绠$悊鏂板鍒嗛厤瑙掕壊鍔熻兘</li>
- <li>鏃ュ織鍒楄〃鏀寔鎺掑簭鎿嶄綔</li>
- <li>浼樺寲鍙傛暟&瀛楀吀缂撳瓨鎿嶄綔</li>
- <li>绯荤粺甯冨眬閰嶇疆鏀寔鍔ㄦ�佹爣棰樺紑鍏�</li>
- <li>鑿滃崟璺敱閰嶇疆鏀寔鍐呴摼璁块棶</li>
- <li>榛樿璁块棶鍚庣棣栭〉鏂板鎻愮ず璇�</li>
- <li>瀵屾枃鏈粯璁や笂浼犺繑鍥瀠rl绫诲瀷</li>
- <li>鏂板鑷畾涔夊脊绐楁嫋鎷芥寚浠�</li>
- <li>鍏ㄥ眬娉ㄥ唽甯哥敤閫氱敤缁勪欢</li>
- <li>鍏ㄥ眬鎸傝浇瀛楀吀鏍囩缁勪欢</li>
- <li>ImageUpload缁勪欢鏀寔澶氬浘鐗囦笂浼�</li>
- <li>FileUpload缁勪欢鏀寔澶氭枃浠朵笂浼�</li>
- <li>鏂囦欢涓婁紶缁勪欢娣诲姞鏁伴噺闄愬埗灞炴��</li>
- <li>瀵屾枃鏈紪杈戠粍浠舵坊鍔犵被鍨嬪睘鎬�</li>
- <li>瀵屾枃鏈粍浠跺伐鍏锋爮閰嶇疆瑙嗛</li>
- <li>灏佽閫氱敤iframe缁勪欢</li>
- <li>闄愬埗瓒呯骇绠$悊鍛樹笉鍏佽鎿嶄綔</li>
- <li>鐢ㄦ埛淇℃伅闀垮害鏍¢獙闄愬埗</li>
- <li>鍒嗛〉缁勪欢鏂板pagerCount灞炴��</li>
- <li>娣诲姞bat鑴氭湰鎵ц搴旂敤</li>
- <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.7.4</li>
- <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.2</li>
- <li>鍗囩骇pagehelper鍒版渶鏂扮増1.3.1</li>
- <li>鍗囩骇commons.io鍒版渶鏂扮増鏈瑅2.10.0</li>
- <li>鍗囩骇commons.fileupload鍒版渶鏂扮増鏈瑅1.4</li>
- <li>鍗囩骇swagger鍒版渶鏂扮増鏈瑅3.0.0</li>
- <li>淇鍏抽棴confirm鎻愮ず妗嗘帶鍒跺彴鎶ラ敊闂</li>
- <li>淇瀛樺湪鐨凷QL娉ㄥ叆婕忔礊闂</li>
- <li>瀹氭椂浠诲姟灞忚斀rmi杩滅▼璋冪敤</li>
- <li>淇鐢ㄦ埛鎼滅储鍒嗛〉鍙橀噺閿欒</li>
- <li>淇瀵煎嚭瑙掕壊鏁版嵁鑼冨洿缈昏瘧缂哄皯浠呮湰浜�</li>
- <li>淇琛ㄥ崟鏋勫缓閫夋嫨涓嬫媺閫夋嫨鎺у埗鍙版姤閿欓棶棰�</li>
- <li>浼樺寲鍥剧墖宸ュ叿绫昏鍙栨枃浠�</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v3.5.0 - 2021-05-25">
- <ol>
- <li>鏂板鑿滃崟瀵艰埅鏄剧ず椋庢牸TopNav锛坒alse涓哄乏渚у鑸彍鍗曪紝true涓洪《閮ㄥ鑸彍鍗曪級</li>
- <li>甯冨眬璁剧疆鏀寔淇濆瓨&閲嶇疆閰嶇疆</li>
- <li>淇鏍戣〃鏁版嵁鏄剧ず涓嶅叏&鍔犺浇鎱㈤棶棰�</li>
- <li>鏂板IE娴忚鍣ㄧ増鏈繃浣庢彁绀洪〉闈�</li>
- <li>鐢ㄦ埛鐧诲綍鍚庤褰曟渶鍚庣櫥褰旾P&鏃堕棿</li>
- <li>椤甸潰瀵煎嚭鎸夐挳鐐瑰嚮涔嬪悗娣诲姞閬僵</li>
- <li>瀵屾枃鏈紪杈戝櫒鏀寔鑷畾涔変笂浼犲湴鍧�</li>
- <li>瀵屾枃鏈紪杈戠粍浠舵柊澧瀝eadOnly灞炴��</li>
- <li>椤电TagsView鏂板鍏抽棴鍙充晶鍔熻兘</li>
- <li>鏄鹃殣鍒楃粍浠跺姞杞藉垵濮嬮粯璁ら殣钘忓垪</li>
- <li>鍏抽棴澶村儚涓婁紶绐楀彛杩樺師榛樿鍥剧墖</li>
- <li>涓汉淇℃伅娣诲姞鎵嬫満&閭閲嶅楠岃瘉</li>
- <li>浠g爜鐢熸垚妯℃澘瀵煎嚭鎸夐挳鐐瑰嚮鍚庢坊鍔犻伄缃�</li>
- <li>浠g爜鐢熸垚妯℃澘鏍戣〃鎿嶄綔鍒楁坊鍔犳柊澧炴寜閽�</li>
- <li>浠g爜鐢熸垚妯℃澘淇涓诲瓙琛ㄥ瓧娈甸噸鍚嶉棶棰�</li>
- <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.76</li>
- <li>鍗囩骇druid鍒版渶鏂扮増鏈瑅1.2.6</li>
- <li>鍗囩骇mybatis鍒版渶鏂扮増3.5.6 闃绘杩滅▼浠g爜鎵ц婕忔礊</li>
- <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.6.0</li>
- <li>velocity鍓旈櫎commons-collections鐗堟湰锛岄槻姝�3.2.1鐗堟湰鐨勫弽搴忓垪鍖栨紡娲�</li>
- <li>鏁版嵁鐩戞帶椤甸粯璁よ处鎴峰瘑鐮侀槻姝㈣秺鏉冭闂�</li>
- <li>淇firefox涓嬭〃鍗曟瀯寤烘嫋鎷戒細鏂版墦鍗′竴涓�夐」鍗�</li>
- <li>淇鍚庣瀵煎叆琛ㄦ潈闄愭爣璇�</li>
- <li>淇鍓嶇鎿嶄綔鏃ュ織&鐧诲綍鏃ュ織鏉冮檺鏍囪瘑</li>
- <li>璁剧疆Redis閰嶇疆HashKey搴忓垪鍖�</li>
- <li>鍒犻櫎鎿嶄綔鏃ュ織璁板綍淇℃伅</li>
- <li>涓婁紶濯掍綋绫诲瀷娣诲姞瑙嗛鏍煎紡</li>
- <li>淇璇锋眰褰㈠弬鏈紶鍊艰褰曟棩蹇楀紓甯搁棶棰�</li>
- <li>浼樺寲xss鏍¢獙json璇锋眰鏉′欢</li>
- <li>鏍戠骇缁撴瀯鏇存柊瀛愯妭鐐逛娇鐢╮eplaceFirst</li>
- <li>浼樺寲ExcelUtil绌哄�煎鐞�</li>
- <li>鏃ュ織璁板綍杩囨护BindingResult瀵硅薄锛岄槻姝㈠紓甯�</li>
- <li>淇敼涓婚鍚巑ini绫诲瀷鎸夐挳鏃犳晥闂</li>
- <li>浼樺寲閫氱敤涓嬭浇瀹屾垚鍚庡垹闄よ妭鐐�</li>
- <li>閫氱敤Controller娣诲姞鍝嶅簲杩斿洖娑堟伅</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v3.4.0 - 2021-02-22">
- <ol>
- <li>浠g爜鐢熸垚妯℃澘鏀寔涓诲瓙琛�</li>
- <li>琛ㄦ牸鍙充晶宸ュ叿鏍忕粍浠舵敮鎸佹樉闅愬垪</li>
- <li>鍥剧墖缁勪欢娣诲姞棰勮&绉婚櫎鍔熻兘</li>
- <li>Excel娉ㄨВ鏀寔Image鍥剧墖瀵煎嚭</li>
- <li>鎿嶄綔鎸夐挳缁勮皟鏁翠负鏈寸礌鎸夐挳鏍峰紡</li>
- <li>浠g爜鐢熸垚鏀寔鏂囦欢涓婁紶缁勪欢</li>
- <li>浠g爜鐢熸垚鏃ユ湡鎺т欢鍖哄垎鑼冨洿</li>
- <li>浠g爜鐢熸垚鏁版嵁搴撴枃鏈被鍨嬬敓鎴愯〃鍗曟枃鏈煙</li>
- <li>鐢ㄦ埛鎵嬫満閭&鑿滃崟缁勪欢淇敼鍏佽绌哄瓧绗︿覆</li>
- <li>鍗囩骇SpringBoot鍒版渶鏂扮増鏈�2.2.13 鎻愬崌鍚姩閫熷害</li>
- <li>鍗囩骇druid鍒版渶鏂扮増鏈瑅1.2.4</li>
- <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.75</li>
- <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.0</li>
- <li>淇IE11娴忚鍣ㄦ姤閿欓棶棰�</li>
- <li>浼樺寲澶氱骇鑿滃崟涔嬮棿鍒囨崲鏃犳硶缂撳瓨鐨勯棶棰�</li>
- <li>淇鍥涚骇鑿滃崟鏃犳硶鏄剧ず闂</li>
- <li>淇渚ц竟鏍忛潤鎬佽矾鐢变涪澶遍棶棰�</li>
- <li>淇瑙掕壊绠$悊-缂栬緫瑙掕壊-鍔熻兘鏉冮檺鏄剧ず寮傚父</li>
- <li>閰嶇疆鏂囦欢鏂板redis鏁版嵁搴撶储寮曞睘鎬�</li>
- <li>鏉冮檺宸ュ叿绫诲鍔燼dmin鍒ゆ柇</li>
- <li>瑙掕壊闈炶嚜瀹氫箟鏉冮檺鑼冨洿娓呯┖閫夋嫨鍊�</li>
- <li>淇瀵煎叆鏁版嵁涓鸿礋娴偣鏁版椂涓㈠け绮惧害闂</li>
- <li>绉婚櫎path-to-regexp姝e垯鍖归厤鎻掍欢</li>
- <li>淇鐢熸垚鏍戣〃浠g爜寮傚父</li>
- <li>淇敼ip瀛楁闀垮害闃叉ipv6鍦板潃闀垮害涓嶅</li>
- <li>闃叉get璇锋眰鍙傛暟鍊间负false鎴�0绛夌壒娈婂�间細瀵艰嚧鏃犳硶姝g‘鐨勪紶鍙�</li>
- <li>鐧诲綍鍚巔ush娣诲姞catch闃叉鍑虹幇妫�鏌ラ敊璇�</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v3.3.0 - 2020-12-14">
- <ol>
- <li>鏂板缂撳瓨鐩戞帶鍔熻兘</li>
- <li>鏀寔涓婚椋庢牸閰嶇疆</li>
- <li>淇澶氱骇鑿滃崟涔嬮棿鍒囨崲鏃犳硶缂撳瓨鐨勯棶棰�</li>
- <li>澶氱骇鑿滃崟鑷姩閰嶇疆缁勪欢</li>
- <li>浠g爜鐢熸垚棰勮鏀寔楂樹寒鏄剧ず</li>
- <li>鏀寔Get璇锋眰鏄犲皠Params鍙傛暟</li>
- <li>鍒犻櫎鐢ㄦ埛鍜岃鑹茶В缁戝叧鑱�</li>
- <li>鍘婚櫎鐢ㄦ埛鎵嬫満閭閮ㄩ棬蹇呭~楠岃瘉</li>
- <li>Excel鏀寔娉ㄨВalign瀵归綈鏂瑰紡</li>
- <li>Excel鏀寔瀵煎叆Boolean鍨嬫暟鎹�</li>
- <li>浼樺寲澶村儚鏍峰紡锛岄紶鏍囩Щ鍏ユ偓鍋滈伄缃�</li>
- <li>浠g爜鐢熸垚棰勮鎻愪緵婊氬姩鏈哄埗</li>
- <li>浠g爜鐢熸垚鍒犻櫎澶氫綑鐨勬暟瀛梖loat绫诲瀷</li>
- <li>淇杞崲瀛楃涓茬殑鐩爣瀛楃闆嗗睘鎬�</li>
- <li>鍥炴樉鏁版嵁瀛楀吀闃叉绌哄�兼姤閿�</li>
- <li>鏃ュ織璁板綍澧炲姞杩囨护澶氭枃浠跺満鏅�</li>
- <li>淇敼缂撳瓨Set鏂规硶鍙兘瀵艰嚧宓屽鐨勯棶棰�</li>
- <li>绉婚櫎鍓嶇涓�浜涘浣欑殑渚濊禆</li>
- <li>闃叉瀹夊叏鎵弿YUI鍑虹幇鐨勯闄╂彁绀�</li>
- <li>淇敼node-sass涓篸art-sass</li>
- <li>鍗囩骇SpringBoot鍒版渶鏂扮増鏈�2.1.18</li>
- <li>鍗囩骇poi鍒版渶鏂扮増鏈�4.1.2</li>
- <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.3.6</li>
- <li>鍗囩骇bitwalker鍒版渶鏂扮増鏈�1.21</li>
- <li>鍗囩骇axios鍒版渶鏂扮増鏈�0.21.0</li>
- <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.14.1</li>
- <li>鍗囩骇vue鍒版渶鏂扮増鏈�2.6.12</li>
- <li>鍗囩骇vuex鍒版渶鏂扮増鏈�3.6.0</li>
- <li>鍗囩骇vue-cli鍒扮増鏈�4.5.9</li>
- <li>鍗囩骇vue-router鍒版渶鏂扮増鏈�3.4.9</li>
- <li>鍗囩骇vue-cli鍒版渶鏂扮増鏈�4.4.6</li>
- <li>鍗囩骇vue-cropper鍒版渶鏂扮増鏈�0.5.5</li>
- <li>鍗囩骇clipboard鍒版渶鏂扮増鏈�2.0.6</li>
- <li>鍗囩骇core-js鍒版渶鏂扮増鏈�3.8.1</li>
- <li>鍗囩骇echarts鍒版渶鏂扮増鏈�4.9.0</li>
- <li>鍗囩骇file-saver鍒版渶鏂扮増鏈�2.0.4</li>
- <li>鍗囩骇fuse.js鍒版渶鏂扮増鏈�6.4.3</li>
- <li>鍗囩骇js-beautify鍒版渶鏂扮増鏈�1.13.0</li>
- <li>鍗囩骇js-cookie鍒版渶鏂扮増鏈�2.2.1</li>
- <li>鍗囩骇path-to-regexp鍒版渶鏂扮増鏈�6.2.0</li>
- <li>鍗囩骇quill鍒版渶鏂扮増鏈�1.3.7</li>
- <li>鍗囩骇screenfull鍒版渶鏂扮増鏈�5.0.2</li>
- <li>鍗囩骇sortablejs鍒版渶鏂扮増鏈�1.10.2</li>
- <li>鍗囩骇vuedraggable鍒版渶鏂扮増鏈�2.24.3</li>
- <li>鍗囩骇chalk鍒版渶鏂扮増鏈�4.1.0</li>
- <li>鍗囩骇eslint鍒版渶鏂扮増鏈�7.15.0</li>
- <li>鍗囩骇eslint-plugin-vue鍒版渶鏂扮増鏈�7.2.0</li>
- <li>鍗囩骇lint-staged鍒版渶鏂扮増鏈�10.5.3</li>
- <li>鍗囩骇runjs鍒版渶鏂扮増鏈�4.4.2</li>
- <li>鍗囩骇sass-loader鍒版渶鏂扮増鏈�10.1.0</li>
- <li>鍗囩骇script-ext-html-webpack-plugin鍒版渶鏂扮増鏈�2.1.5</li>
- <li>鍗囩骇svg-sprite-loader鍒版渶鏂扮増鏈�5.1.1</li>
- <li>鍗囩骇vue-template-compiler鍒版渶鏂扮増鏈�2.6.12</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v3.2.1 - 2020-11-18">
- <ol>
- <li>闃绘浠绘剰鏂囦欢涓嬭浇婕忔礊</li>
- <li>浠g爜鐢熸垚鏀寔涓婁紶鎺т欢</li>
- <li>鏂板鍥剧墖涓婁紶缁勪欢</li>
- <li>璋冩暣榛樿棣栭〉</li>
- <li>鍗囩骇druid鍒版渶鏂扮増鏈瑅1.2.2</li>
- <li>mapperLocations閰嶇疆鏀寔鍒嗛殧绗�</li>
- <li>鏉冮檺淇℃伅璋冩暣</li>
- <li>璋冩暣sql榛樿鏃堕棿</li>
- <li>瑙e喅浠g爜鐢熸垚娌℃湁bit绫诲瀷鐨勯棶棰�</li>
- <li>鍗囩骇pagehelper鍒版渶鏂扮増1.3.0</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v3.2.0 - 2020-10-10">
- <ol>
- <li>鍗囩骇springboot鐗堟湰鍒�2.1.17 鎻愬崌瀹夊叏鎬�</li>
- <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.2.5</li>
- <li>鍗囩骇druid鍒版渶鏂扮増鏈瑅1.2.1</li>
- <li>鍗囩骇jjwt鍒扮増鏈�0.9.1</li>
- <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.74</li>
- <li>淇敼sass涓簄ode-sass锛岄伩鍏峞l-icon鍥炬爣涔辩爜</li>
- <li>浠g爜鐢熸垚鏀寔鍚屾鏁版嵁搴�</li>
- <li>浠g爜鐢熸垚鏀寔瀵屾枃鏈帶浠�</li>
- <li>浠g爜鐢熸垚椤甸潰鏃朵笉蹇界暐remark灞炴��</li>
- <li>浠g爜鐢熸垚娣诲姞select蹇呭~閫夐」</li>
- <li>Excel瀵煎嚭绫诲瀷NUMERIC鏀寔绮惧害娴偣绫诲瀷</li>
- <li>Excel瀵煎嚭targetAttr浼樺寲鑾峰彇鍊硷紝闃叉get鏂规硶涓嶈鑼�</li>
- <li>Excel娉ㄨВ鏀寔鑷姩缁熻鏁版嵁鎬诲拰</li>
- <li>Excel娉ㄨВ鏀寔璁剧疆BigDecimal绮惧害&鑸嶅叆瑙勫垯</li>
- <li>鑿滃崟&鏁版嵁鏉冮檺鏂板锛堝睍寮�/鎶樺彔 鍏ㄩ��/鍏ㄤ笉閫� 鐖跺瓙鑱斿姩锛�</li>
- <li>鍏佽鐢ㄦ埛鍒嗛厤鍒伴儴闂ㄧ埗鑺傜偣</li>
- <li>鑿滃崟鏂板鏄惁缂撳瓨keep-alive</li>
- <li>琛ㄦ牸鎿嶄綔鍒楅棿璺濊皟鏁�</li>
- <li>闄愬埗绯荤粺鍐呯疆鍙傛暟涓嶅厑璁稿垹闄�</li>
- <li>瀵屾枃鏈粍浠朵紭鍖栵紝鏀寔鑷畾涔夐珮搴�&鍥剧墖鍐茬獊闂</li>
- <li>瀵屾枃鏈伐鍏锋爮鏍峰紡瀵归綈</li>
- <li>瀵煎叆excel鏁村舰鍊兼牎楠屼紭鍖�</li>
- <li>淇椤电鍏抽棴鎵�鏈夋椂鍥哄畾鏍囩璺敱涓嶅埛鏂伴棶棰�</li>
- <li>琛ㄥ崟鏋勫缓甯冨眬鍨嬬粍浠舵柊澧炴寜閽�</li>
- <li>宸︿晶鑿滃崟鏂囧瓧杩囬暱鏄剧ず鐪佺暐鍙�</li>
- <li>淇鏍硅妭鐐逛负瀛愰儴闂ㄦ椂锛屾爲鐘剁粨鏋勬樉绀洪棶棰�</li>
- <li>淇璋冪敤鐩爣瀛楃涓叉渶澶ч暱搴�</li>
- <li>淇鑿滃崟鎻愮ず淇℃伅閿欒</li>
- <li>淇瀹氭椂浠诲姟鎵ц涓�娆℃潈闄愭爣璇�</li>
- <li>淇鏁版嵁搴撳瓧绗︿覆绫诲瀷nvarchar</li>
- <li>浼樺寲閫掑綊瀛愯妭鐐�</li>
- <li>浼樺寲鏁版嵁鏉冮檺鍒ゆ柇</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
-
- <el-collapse-item title="v3.1.0 - 2020-08-13">
- <ol>
- <li>琛ㄦ牸宸ュ叿鏍忓彸渚ф坊鍔犲埛鏂�&鏄鹃殣鏌ヨ缁勪欢</li>
- <li>鍚庣鏀寔CORS璺ㄥ煙璇锋眰</li>
- <li>浠g爜鐢熸垚鏀寔閫夋嫨涓婄骇鑿滃崟</li>
- <li>浠g爜鐢熸垚鏀寔鑷畾涔夎矾寰�</li>
- <li>浠g爜鐢熸垚鏀寔澶嶉�夋</li>
- <li>Excel瀵煎嚭瀵煎叆鏀寔dictType瀛楀吀绫诲瀷</li>
- <li>Excel鏀寔鍒嗗壊瀛楃涓茬粍鍐呭</li>
- <li>楠岃瘉鐮佺被鍨嬫敮鎸侊紙鏁扮粍璁$畻銆佸瓧绗﹂獙璇侊級</li>
- <li>鍗囩骇vue-cli鐗堟湰鍒�4.4.4</li>
- <li>淇敼 node-sass 涓� dart-sass</li>
- <li>琛ㄥ崟绫诲瀷涓篒nteger/Long璁剧疆鏁村舰榛樿鍊�</li>
- <li>浠g爜鐢熸垚鍣ㄩ粯璁apper璺緞涓庨粯璁apperScan璺緞涓嶄竴鑷�</li>
- <li>浼樺寲闃查噸澶嶆彁浜ゆ嫤鎴櫒</li>
- <li>浼樺寲涓婄骇鑿滃崟涓嶈兘閫夋嫨鑷繁</li>
- <li>淇瑙掕壊鐨勬潈闄愬垎閰嶅悗锛屾湭瀹炴椂鐢熸晥闂</li>
- <li>淇鍦ㄧ嚎鐢ㄦ埛鏃ュ織璁板綍绫诲瀷</li>
- <li>淇瀵屾枃鏈┖鏍煎拰缂╄繘淇濆瓨鍚庝笉鐢熸晥闂</li>
- <li>淇鍦ㄧ嚎鐢ㄦ埛鍒ゆ柇閫昏緫</li>
- <li>鍞竴闄愬埗鏉′欢鍙繑鍥炲崟鏉℃暟鎹�</li>
- <li>娣诲姞鑾峰彇褰撳墠鐨勭幆澧冮厤缃柟娉�</li>
- <li>瓒呮椂鐧诲綍鍚庨〉闈㈣烦杞埌棣栭〉</li>
- <li>鍏ㄥ眬寮傚父鐘舵�佹眽鍖栨嫤鎴鐞�</li>
- <li>HTML杩囨护鍣ㄦ敼涓哄皢html杞箟</li>
- <li>妫�鏌ュ瓧绗︽敮鎸佸皬鏁扮偣&闄嶇骇鏀规垚寮傚父鎻愰啋</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
-
- <el-collapse-item title="v3.0.0 - 2020-07-20">
- <ol>
- <li>鍗曞簲鐢ㄨ皟鏁翠负澶氭ā鍧楅」鐩�</li>
- <li>鍗囩骇element-ui鐗堟湰鍒�2.13.2</li>
- <li>鍒犻櫎babel锛屾彁楂樼紪璇戦�熷害銆�</li>
- <li>鏂板鑿滃崟榛樿涓荤被鐩�</li>
- <li>缂栫爜鏂囦欢鍚嶄慨鏀逛负uuid鏂瑰紡</li>
- <li>瀹氭椂浠诲姟cron琛ㄨ揪寮忛獙璇�</li>
- <li>瑙掕壊鏉冮檺淇敼鏃跺凡鏈夋潈闄愭湭鑷姩鍕鹃�夊紓甯镐慨澶�</li>
- <li>闃叉鍒囨崲鏉冮檺鐢ㄦ埛鍚庣櫥褰曞嚭鐜�404</li>
- <li>Excel鏀寔sort瀵煎嚭鎺掑簭</li>
- <li>鍒涘缓鐢ㄦ埛涓嶅厑璁搁�夋嫨瓒呯骇绠$悊鍛樿鑹�</li>
- <li>淇浠g爜鐢熸垚瀵煎叆琛ㄧ粨鏋勫嚭鐜板紓甯搁〉闈笉鎻愰啋闂</li>
- <li>淇浠g爜鐢熸垚鐐瑰嚮澶氭琛ㄤ慨鏀规暟鎹笉鍙樺寲鐨勯棶棰�</li>
- <li>淇澶村儚涓婁紶鎴愬姛浜屾鎵撳紑鏃犳硶鏀瑰彉瑁佸壀妗嗗ぇ灏忓拰浣嶇疆闂</li>
- <li>淇甯冨眬涓簊mall鑰卪ini鐢ㄦ埛琛ㄥ崟鏄剧ず閿欎綅闂</li>
- <li>淇鐑儴缃插鑷寸殑寮烘崲寮傚父闂</li>
- <li>淇敼鐢ㄦ埛绠$悊澶嶉�夋瀹藉害锛岄槻姝㈤儴鍒嗘祻瑙堝櫒鍑虹幇鐪佺暐鍙�</li>
- <li>IpUtils宸ュ叿锛屾竻闄ss鐗规畩瀛楃锛岄槻姝ff娉ㄥ叆鏀诲嚮</li>
- <li>鐢熸垚domain 濡傛灉鏄诞鐐瑰瀷 缁熶竴鐢˙igDecimal</li>
- <li>瀹氭椂浠诲姟璋冩暣label-width锛岄槻姝㈤儴缃插嚭鐜伴敊浣�</li>
- <li>璋冩暣琛ㄥご鍥哄畾鍒楅粯璁ゆ牱寮�</li>
- <li>浠g爜鐢熸垚妯℃澘璋冩暣锛屽瓧娈典负String骞朵笖蹇呭~鍒欏姞绌轰覆鏉′欢</li>
- <li>浠g爜鐢熸垚瀛楀吀Integer/Long浣跨敤parseInt</li>
- <li>
- 淇dict_sort涓嶅彲update涓�0鐨勯棶棰�&鏌ヨ杩斿洖澧炲姞dict_sort鍗囧簭鎺掑簭
- </li>
- <li>淇宀椾綅瀵煎嚭鏉冮檺娉ㄨВ</li>
- <li>绂佹鍔犲瘑瀵嗘枃杩斿洖鍓嶇</li>
- <li>淇浠g爜鐢熸垚椤甸潰涓殑鏌ヨ鏉′欢鍒涘缓鏃堕棿鏈敓鏁堢殑闂</li>
- <li>淇棣栭〉鎼滅储鑿滃崟澶栭摼鏃犳硶鐐瑰嚮璺宠浆闂</li>
- <li>淇鑿滃崟绠$悊閫夋嫨鍥炬爣锛宐ackspace鍒犻櫎鏃朵笉杩囨护鏁版嵁</li>
- <li>鐢ㄦ埛绠$悊閮ㄩ棬鍒嗘敮鑺傜偣涓嶅彲妫�鏌�&鏄剧ず璁℃暟</li>
- <li>鏁版嵁鑼冨洿杩囨护灞炴�ц皟鏁�</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
-
- <el-collapse-item title="v2.3.0 - 2020-06-01">
- <ol>
- <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.70 淇楂樺嵄瀹夊叏婕忔礊</li>
- <li>dev鍚姩榛樿鎵撳紑娴忚鍣�</li>
- <li>vue-cli浣跨敤榛樿source-map</li>
- <li>slidebar eslint鎶ラ敊浼樺寲</li>
- <li>褰搕ags-view婊氬姩鍏抽棴鍙抽敭鑿滃崟</li>
- <li>瀛楀吀绠$悊娣诲姞缂撳瓨璇诲彇</li>
- <li>鍙傛暟绠$悊鏀寔缂撳瓨鎿嶄綔</li>
- <li>鏀寔涓�绾ц彍鍗曪紙鍜屼富椤靛悓绾э級鍦╩ain鍖哄煙鏄剧ず</li>
- <li>闄愬埗澶栭摼鍦板潃蹇呴』浠ttp(s)寮�澶�</li>
- <li>tagview & sidebar 涓婚棰滆壊涓巈lement ui(鍏ㄥ眬)鍚屾</li>
- <li>淇敼鏁版嵁婧愮被鍨嬩紭鍏堢骇锛屽厛鏍规嵁鏂规硶锛屽啀鏍规嵁绫�</li>
- <li>鏀寔鏄惁闇�瑕佽缃畉oken灞炴�э紝鑷畾涔夎繑鍥炵爜娑堟伅銆�</li>
- <li>swagger璇锋眰鍓嶇紑鍔犲叆閰嶇疆銆�</li>
- <li>鐧诲綍鍦扮偣璁剧疆鍐呭杩囬暱鍒欓殣钘忔樉绀�</li>
- <li>淇瀹氭椂浠诲姟鎵ц涓�娆℃寜閽悗涓嶆彁绀烘秷鎭棶棰�</li>
- <li>淇敼涓婄骇閮ㄩ棬锛堥�夋嫨椤规帓闄ゆ湰韬拰涓嬬骇锛�</li>
- <li>閫氱敤http鍙戦�佹柟娉曞鍔犲弬鏁� contentType 缂栫爜绫诲瀷</li>
- <li>鏇存崲IP鍦板潃鏌ヨ鎺ュ彛</li>
- <li>淇椤电鍙橀噺undefined</li>
- <li>娣诲姞鏍¢獙閮ㄩ棬鍖呭惈鏈仠鐢ㄧ殑瀛愰儴闂�</li>
- <li>淇敼瀹氭椂浠诲姟璇︽儏涓嬫鎵ц鏃堕棿鏃ユ湡鏄剧ず閿欒</li>
- <li>瑙掕壊绠$悊鏌ヨ璁剧疆榛樿鎺掑簭瀛楁</li>
- <li>swagger娣诲姞enable鍙傛暟鎺у埗鏄惁鍚敤</li>
- <li>鍙json绫诲瀷璇锋眰鏋勫缓鍙噸澶嶈鍙杋nputStream鐨剅equest</li>
- <li>淇敼浠g爜鐢熸垚瀛楀吀瀛楁int绫诲瀷娌℃湁鑷姩閫変腑闂</li>
- <li>vuex鐢ㄦ埛鍚嶅彇鍊间慨姝�</li>
- <li>琛ㄦ牸鏍戞ā鏉垮幓鎺夊浣欑殑)</li>
- <li>浠g爜鐢熸垚搴忓彿淇</li>
- <li>鍏ㄥ睆鎯呭喌涓嬩笉璋冩暣涓婂杈硅窛</li>
- <li>浠g爜鐢熸垚Date瀛楁娣诲姞榛樿鏍煎紡</li>
- <li>鐢ㄦ埛绠$悊瑙掕壊閫夋嫨鏉冮檺鎺у埗</li>
- <li>淇璺敱鎳掑姞杞芥姤閿欓棶棰�</li>
- <li>妯℃澘sql.vm娣诲姞鑿滃崟鐘舵��</li>
- <li>璁剧疆鐢ㄦ埛鍚嶇О涓嶈兘淇敼</li>
- <li>dialog娣诲姞append-to-body灞炴�э紝闃叉ie閬僵</li>
- <li>鑿滃崟鍖哄垎鐘舵�佸拰鏄剧ず闅愯棌鍔熻兘</li>
- <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.68 淇瀹夊叏鍔犲浐</li>
- <li>淇浠g爜鐢熸垚濡傛灉閫夋嫨瀛楀吀绫诲瀷缂哄け閫楀彿闂</li>
- <li>鐧诲綍璇锋眰params鏇存崲涓篸ata锛岄槻姝㈡毚闇瞮rl</li>
- <li>鏃ュ織杩斿洖鏃堕棿鏍煎紡澶勭悊</li>
- <li>娣诲姞handle鎺у埗鍏佽鎷栧姩鐨勫厓绱�</li>
- <li>甯冨眬璁剧疆鐐瑰嚮鎵╁ぇ鑼冨洿</li>
- <li>浠g爜鐢熸垚鍒楀睘鎬ф帓搴忔煡璇�</li>
- <li>浠g爜鐢熸垚鍒楁敮鎸佹嫋鍔ㄦ帓搴�</li>
- <li>淇鏃堕棿鏍煎紡涓嶆敮鎸乮os闂</li>
- <li>琛ㄥ崟鏋勫缓娣诲姞鐖剁骇class锛岄槻姝㈠啿绐�</li>
- <li>瀹氭椂浠诲姟骞跺彂灞炴�т慨姝�</li>
- <li>瑙掕壊绂佺敤&鑿滃崟闅愯棌涓嶆煡璇㈡潈闄�</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
-
- <el-collapse-item title="v2.2.0 - 2020-03-18">
- <ol>
- <li>绯荤粺鐩戞帶鏂板瀹氭椂浠诲姟鍔熻兘</li>
- <li>娣诲姞涓�涓墦鍖匴eb宸ョ▼bat</li>
- <li>淇椤电榧犳爣婊氳疆鎸変笅鐨勬椂鍊欙紝鍙互鍏抽棴涓嶅彲鍏抽棴鐨則ag</li>
- <li>淇鐐瑰嚮閫�鍑虹櫥褰曟湁鏃朵細鏃犳彁绀洪棶棰�</li>
- <li>淇闃查噸澶嶆彁浜ゆ敞瑙f棤鏁堥棶棰�</li>
- <li>淇閫氱煡鍏憡鎵归噺鍒犻櫎寮傚父闂</li>
- <li>娣诲姞鑿滃崟鏃惰矾鐢卞湴鍧�蹇呭~闄愬埗</li>
- <li>浠g爜鐢熸垚瀛楁鎻忚堪鍙紪杈�</li>
- <li>淇鐢ㄦ埛淇敼涓汉淇℃伅瀵艰嚧缂撳瓨涓嶈繃鏈熼棶棰�</li>
- <li>涓汉淇℃伅鍒涘缓鏃堕棿鑾峰彇姝g‘灞炴�у��</li>
- <li>鎿嶄綔鏃ュ織璇︾粏鏄剧ず姝g‘绫诲瀷</li>
- <li>瀵煎叆琛ㄥ崟鍑昏鏁版嵁鏃堕�変腑瀵瑰簲鐨勫閫夋</li>
- <li>鎵归噺鏇挎崲琛ㄥ墠缂�閫昏緫璋冩暣</li>
- <li>鍥哄畾閲嶅畾鍚戣矾寰勮〃杈惧紡</li>
- <li>鍗囩骇element-ui鐗堟湰鍒�2.13.0</li>
- <li>鎿嶄綔鏃ュ織鎺掑簭璋冩暣</li>
- <li>淇charts鍒囨崲渚ц竟鏍忔垨鑰呯缉鏀剧獥鍙f樉绀篵ug</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
-
- <el-collapse-item title="v2.1.0 - 2020-02-24">
- <ol>
- <li>鏂板琛ㄥ崟鏋勫缓</li>
- <li>浠g爜鐢熸垚鏀寔鏍戣〃缁撴瀯</li>
- <li>鏂板鐢ㄦ埛瀵煎叆</li>
- <li>淇鍔ㄦ�佸姞杞借矾鐢遍〉闈㈠埛鏂伴棶棰�</li>
- <li>淇鍦板潃寮�鍏虫棤鏁堥棶棰�</li>
- <li>姹夊寲閿欒鎻愮ず椤甸潰</li>
- <li>浠g爜鐢熸垚宸茬煡闂淇敼</li>
- <li>淇澶氭暟鎹簮涓嬮厤缃叧闂嚭鐜板紓甯稿鐞�</li>
- <li>娣诲姞HTML杩囨护鍣紝鐢ㄤ簬鍘婚櫎XSS婕忔礊闅愭偅</li>
- <li>淇涓婁紶澶村儚鎺у埗鍙板嚭鐜板紓甯�</li>
- <li>淇敼鐢ㄦ埛绠$悊鍒嗛〉涓嶆纭殑闂</li>
- <li>淇楠岃瘉鐮佽褰曟彁绀洪敊璇�</li>
- <li>淇request.js缂哄皯Message寮曠敤</li>
- <li>淇琛ㄦ牸鏃堕棿涓虹┖鍑虹幇鐨勫紓甯�</li>
- <li>娣诲姞Jackson鏃ユ湡鍙嶅簭鍒楀寲鏃跺尯閰嶇疆</li>
- <li>璋冩暣鏍规嵁鐢ㄦ埛鏉冮檺鍔犺浇鑿滃崟鏁版嵁鏍戝舰缁撴瀯</li>
- <li>璋冩暣鎴愬姛鐧诲綍涓嶆仮澶嶆寜閽紝闃叉澶氭鐐瑰嚮</li>
- <li>淇敼鐢ㄦ埛涓汉璧勬枡鍚屾缂撳瓨淇℃伅</li>
- <li>淇椤甸潰鍚屾椂鍑虹幇el-upload鍜孍ditor涓嶆樉绀哄鐞�</li>
- <li>淇鍦ㄨ鑹茬鐞嗛〉淇敼鑿滃崟鏉冮檺鍋跺皵鏈�変腑闂</li>
- <li>閰嶇疆鏂囦欢鏂板redis瀵嗙爜灞炴��</li>
- <li>璁剧疆mybatis鍏ㄥ眬鐨勯厤缃枃浠�</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
-
- <el-collapse-item title="v2.0.0 - 2019-12-02">
- <ol>
- <li>鏂板浠g爜鐢熸垚</li>
- <li>鏂板@RepeatSubmit娉ㄨВ锛岄槻姝㈤噸澶嶆彁浜�</li>
- <li>鏂板鑿滃崟涓荤洰褰曟坊鍔�/鍒犻櫎鎿嶄綔</li>
- <li>鏃ュ織璁板綍杩囨护鐗规畩瀵硅薄锛岄槻姝㈣浆鎹㈠紓甯�</li>
- <li>淇敼浠g爜鐢熸垚璺敱鑴氭湰閿欒</li>
- <li>鐢ㄦ埛涓婁紶澶村儚瀹炴椂鍚屾缂撳瓨锛屾棤闇�閲嶆柊鐧诲綍</li>
- <li>璋冩暣鍒囨崲椤电鍚庝笉閲嶆柊鍔犺浇鏁版嵁</li>
- <li>娣诲姞jsencrypt瀹炵幇鍙傛暟鐨勫墠绔姞瀵�</li>
- <li>绯荤粺閫�鍑哄垹闄ょ敤鎴风紦瀛樿褰�</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v1.1.0 - 2019-11-11">
- <ol>
- <li>鏂板鍦ㄧ嚎鐢ㄦ埛绠$悊</li>
- <li>鏂板鎸夐挳缁勫姛鑳藉疄鐜帮紙鎵归噺鍒犻櫎銆佸鍑恒�佹竻绌猴級</li>
- <li>鏂板鏌ヨ鏉′欢閲嶇疆鎸夐挳</li>
- <li>鏂板Swagger鍏ㄥ眬Token閰嶇疆</li>
- <li>鏂板鍚庣鍙傛暟鏍¢獙</li>
- <li>淇瀛楀吀绠$悊椤甸潰鐨勬棩鏈熸煡璇㈠紓甯�</li>
- <li>淇敼鏃堕棿鍑芥暟鍛藉悕闃叉鍐茬獊</li>
- <li>鍘婚櫎鑿滃崟涓婄骇鏍¢獙锛岄粯璁や负椤剁骇</li>
- <li>淇鐢ㄦ埛瀵嗙爜鏃犳硶淇敼闂</li>
- <li>淇鑿滃崟绫诲瀷涓烘寜閽椂涓嶆樉绀烘潈闄愭爣璇�</li>
- <li>鍏朵粬缁嗚妭浼樺寲</li>
- </ol>
- </el-collapse-item>
- <el-collapse-item title="v1.0.0 - 2019-10-08">
- <ol>
- <li>鑻ヤ緷鍓嶅悗绔垎绂荤郴缁熸寮忓彂甯�</li>
- </ol>
- </el-collapse-item>
- </el-collapse>
- </el-card>
- </el-col>
- <el-col :xs="24" :sm="24" :md="12" :lg="8">
- <el-card class="update-log">
- <template v-slot:header>
- <div class="clearfix">
- <span>鎹愯禒鏀寔</span>
- </div>
- </template>
- <div class="body">
- <img
- src="https://oscimg.oschina.net/oscnet/up-d6695f82666e5018f715c41cb7ee60d3b73.png"
- alt="donate"
- style="width:100%"
- />
- <span style="display: inline-block; height: 30px; line-height: 30px"
- >浣犲彲浠ヨ浣滆�呭枬鏉挅鍟¤〃绀洪紦鍔�</span
- >
- </div>
- </el-card>
- </el-col>
- </el-row>
- </div>
-</template>
-
-<script setup name="Index">
-const version = ref('3.8.4')
-
-function goTarget(url) {
- window.open(url, '__blank')
-}
-</script>
-
-<style scoped lang="scss">
-.home {
- blockquote {
- padding: 10px 20px;
- margin: 0 0 20px;
- font-size: 17.5px;
- border-left: 5px solid #eee;
- }
- hr {
- margin-top: 20px;
- margin-bottom: 20px;
- border: 0;
- border-top: 1px solid #eee;
- }
- .col-item {
- margin-bottom: 20px;
- }
-
- ul {
- padding: 0;
- margin: 0;
- }
-
- font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
- font-size: 13px;
- color: #676a6c;
- overflow-x: hidden;
-
- ul {
- list-style-type: none;
- }
-
- h4 {
- margin-top: 0px;
- }
-
- h2 {
- margin-top: 10px;
- font-size: 26px;
- font-weight: 100;
- }
-
- p {
- margin-top: 10px;
-
- b {
- font-weight: 700;
- }
- }
-
- .update-log {
- ol {
- display: block;
- list-style-type: decimal;
- margin-block-start: 1em;
- margin-block-end: 1em;
- margin-inline-start: 0;
- margin-inline-end: 0;
- padding-inline-start: 40px;
- }
- }
-}
-</style>
-
+<template>
+ <div class="home-page">
+ <div class="top-bar">
+ <div class="user-box">
+ <img :src="userStore.avatar" class="avatar" alt="" />
+ <div>
+ <div class="hello">{{ userStore.roleName || "绯荤粺绠$悊鍛�" }}锛屼綘濂�</div>
+ <div class="sub">鐧诲綍鏃堕棿锛歿{ userStore.currentLoginTime }}</div>
+ </div>
+ </div>
+ <div class="top-actions">
+ <span class="refresh-time">鏁版嵁鏇存柊鏃堕棿锛歿{ lastUpdatedAt || "-" }}</span>
+ <el-button size="small" type="primary" plain @click="refreshDashboardData">鍒锋柊鏁版嵁</el-button>
+ <el-button size="small" plain @click="configDialogVisible = true">棣栭〉閰嶇疆</el-button>
+ </div>
+ </div>
+
+ <div class="content-grid">
+ <div class="left-col">
+ <section class="section-card">
+ <div class="section-title-row">
+ <div class="section-title">蹇嵎鎿嶄綔</div>
+ <el-button size="small" type="primary" link @click="openShortcutDialog">娣诲姞蹇嵎鍏ュ彛</el-button>
+ </div>
+ <div class="quick-grid">
+ <el-button
+ v-for="item in shortcuts"
+ :key="`${item.label}-${item.path}`"
+ :type="item.invalid ? 'danger' : 'default'"
+ @click="goTo(item.path)"
+ >
+ {{ item.label }}
+ </el-button>
+ </div>
+ </section>
+
+ <section class="section-card">
+ <div class="section-title">閲嶇偣寰呭姙</div>
+ <div class="todo-row" v-for="todo in todos" :key="todo.title">
+ <el-tag size="small" :type="todo.type">{{ todo.level }}</el-tag>
+ <span>{{ todo.title }}</span>
+ </div>
+ </section>
+
+ <section class="section-card">
+ <div class="section-title">缁忚惀鍏虫敞</div>
+ <div class="focus-row" v-for="item in businessFocus" :key="item.name">
+ <span class="focus-name">{{ item.name }}</span>
+ <span class="focus-value">{{ item.value }}</span>
+ </div>
+ </section>
+
+ <section class="section-card flex-fill-card">
+ <div class="section-title-row">
+ <div class="section-title">浠婃棩寰呭鐞�</div>
+ <el-radio-group v-model="pendingFilter" size="small">
+ <el-radio-button label="all">鍏ㄩ儴</el-radio-button>
+ <el-radio-button label="mine">鎴戠殑</el-radio-button>
+ <el-radio-button label="high">楂樹紭鍏�</el-radio-button>
+ </el-radio-group>
+ </div>
+ <div class="task-row" v-for="task in filteredPendingTasks" :key="task.id">
+ <div class="task-left">
+ <el-tag size="small" :type="task.type">{{ task.level }}</el-tag>
+ <span class="task-title">{{ task.title }}</span>
+ </div>
+ <el-button link type="primary" @click="goTo(task.path)">鍘诲鐞�</el-button>
+ </div>
+ <el-empty v-if="filteredPendingTasks.length === 0" description="鏆傛棤寰呭鐞嗕簨椤�" :image-size="80" />
+ </section>
+ </div>
+
+ <div class="right-col">
+ <section class="section-card" v-if="isSectionVisible('trendCards')">
+ <div class="section-title">鏈�杩�7澶╁叧閿寚鏍囪秼鍔�</div>
+ <div class="trend-cards">
+ <div class="trend-card clickable" v-for="card in recentTrendCards" :key="card.key" @click="handleTrendCardClick(card)">
+ <div class="trend-head">
+ <span class="trend-label">{{ card.label }}</span>
+ <span class="trend-rate" :class="trendClass(card.change)">
+ {{ card.change > 0 ? "+" : "" }}{{ card.change.toFixed(1) }}%
+ </span>
+ </div>
+ <div class="trend-value">{{ card.latest }} {{ card.unit }}</div>
+ <div class="sparkline">
+ <span
+ v-for="(v, idx) in card.values"
+ :key="`${card.key}-${idx}`"
+ class="sparkline-bar"
+ :style="{ height: `${calcBarHeight(v, card.values)}%` }"
+ />
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <section class="section-card" v-if="isSectionVisible('planTrend')">
+ <div class="section-title-row">
+ <div class="section-title">璁″垝涓庣敓浜ц秼鍔�</div>
+ <el-radio-group v-model="chartRangePlan" size="small" @change="loadPlanTrend">
+ <el-radio-button :label="1">鏃�</el-radio-button>
+ <el-radio-button :label="2">鍛�</el-radio-button>
+ <el-radio-button :label="3">鏈�</el-radio-button>
+ </el-radio-group>
+ </div>
+ <Echarts
+ :chartStyle="chartStyle"
+ :legend="planLegend"
+ :grid="grid"
+ :tooltip="lineTooltip"
+ :xAxis="planXAxis"
+ :yAxis="valueYAxis"
+ :series="planSeries"
+ style="height: 300px"
+ />
+ </section>
+
+ <div class="row-two" v-if="isSectionVisible('qualityChart') || isSectionVisible('costChart')">
+ <section class="section-card" v-if="isSectionVisible('qualityChart')">
+ <div class="section-title-row">
+ <div class="section-title">璐ㄦ寮傚父鍒嗗竷</div>
+ <el-radio-group v-model="chartRangeQuality" size="small" @change="loadQualityData">
+ <el-radio-button :label="1">鍛�</el-radio-button>
+ <el-radio-button :label="2">鏈�</el-radio-button>
+ <el-radio-button :label="3">瀛e害</el-radio-button>
+ </el-radio-group>
+ </div>
+ <Echarts
+ :chartStyle="chartStyle"
+ :grid="grid"
+ :tooltip="barTooltip"
+ :xAxis="qualityXAxis"
+ :yAxis="valueYAxis"
+ :series="qualitySeries"
+ style="height: 260px"
+ />
+ </section>
+ <section class="section-card" v-if="isSectionVisible('costChart')">
+ <div class="section-title">鑳借�椾笌鎴愭湰缁撴瀯</div>
+ <Echarts
+ :chartStyle="chartStyle"
+ :legend="costLegend"
+ :tooltip="pieTooltip"
+ :series="costSeries"
+ style="height: 260px"
+ />
+ </section>
+ </div>
+
+ <section class="section-card" v-if="isSectionVisible('warningCenter')">
+ <div class="section-title">寮傚父棰勮涓績</div>
+ <div class="warning-row" v-for="item in warningList" :key="item.id">
+ <div class="warning-left">
+ <el-tag size="small" :type="item.levelType">{{ item.levelText }}</el-tag>
+ <span class="warning-title">{{ item.title }}</span>
+ </div>
+ <el-button link type="danger" @click="goTo(item.path)">澶勭悊</el-button>
+ </div>
+ <el-empty v-if="warningList.length === 0" description="鏆傛棤寮傚父棰勮" :image-size="80" />
+ </section>
+
+ <section class="section-card mini-table-wrap" v-if="isSectionVisible('planTable')">
+ <div class="section-title">鐢熶骇璁″垝鎵ц鏄庣粏</div>
+ <el-table :data="planTable" size="small" stripe>
+ <el-table-column prop="planNo" label="璁″垝鍗曞彿" min-width="150" />
+ <el-table-column prop="product" label="浜у搧" min-width="120" />
+ <el-table-column prop="qty" label="璁″垝閲�" min-width="90" />
+ <el-table-column prop="issued" label="宸蹭笅鍙�" min-width="90" />
+ <el-table-column prop="status" label="鐘舵��" min-width="100" />
+ <el-table-column label="鎿嶄綔" min-width="120">
+ <template #default="{ row }">
+ <el-button link type="primary" @click="goTo(routePathMap.plan)">鏌ョ湅</el-button>
+ <el-button
+ v-if="row.status !== '宸插畬鎴�'"
+ link
+ type="success"
+ @click="goTo(routePathMap.dispatch)"
+ >
+ 涓嬪彂
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </section>
+ </div>
+ </div>
+
+ <el-dialog v-model="shortcutDialogVisible" title="娣诲姞蹇嵎鍏ュ彛锛堟渶澶�6涓級" width="680px">
+ <div class="shortcut-form-row">
+ <el-tree-select
+ v-model="selectedPagePath"
+ placeholder="璇烽�夋嫨椤甸潰锛堢洰褰曚笉鍙�夛級"
+ filterable
+ clearable
+ check-strictly
+ node-key="value"
+ :data="menuTreeOptions"
+ :props="{ label: 'label', value: 'value', children: 'children', disabled: 'disabled' }"
+ style="grid-column: span 2"
+ />
+ <el-button type="success" @click="addShortcutBySelect">閫夋嫨娣诲姞</el-button>
+ </div>
+ <el-table :data="shortcuts" size="small" border>
+ <el-table-column prop="label" label="鍚嶇О" min-width="220" />
+ <el-table-column label="鐘舵��" min-width="80">
+ <template #default="{ row }">
+ <el-tag size="small" :type="row.invalid ? 'danger' : 'success'">{{ row.invalid ? "鏃犳晥" : "鏈夋晥" }}</el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" min-width="90" align="center">
+ <template #default="{ $index }">
+ <el-button link type="danger" @click="removeShortcut($index)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-dialog>
+
+ <el-dialog v-model="configDialogVisible" title="棣栭〉妯″潡閰嶇疆" width="520px">
+ <el-checkbox-group v-model="enabledSectionKeys" class="config-check-group">
+ <el-checkbox v-for="item in sectionConfigOptions" :key="item.key" :label="item.key">
+ {{ item.label }}
+ </el-checkbox>
+ </el-checkbox-group>
+ <template #footer>
+ <el-button @click="configDialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="saveSectionConfig">淇濆瓨</el-button>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { computed, onMounted, reactive, ref } from "vue";
+import { useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import Echarts from "@/components/Echarts/echarts.vue";
+import useUserStore from "@/store/modules/user.js";
+import usePermissionStore from "@/store/modules/permission";
+import {
+ expenseCompositionAnalysis,
+ getProgressStatistics,
+ homeTodos,
+ orderCount,
+ processDataProductionStatistics,
+ qualityInspectionStatistics,
+ nonComplianceWarning,
+} from "@/api/viewIndex.js";
+
+const router = useRouter();
+const userStore = useUserStore();
+const permissionStore = usePermissionStore();
+
+const SHORTCUT_STORAGE_KEY = "home-shortcuts-v1";
+
+const defaultShortcuts = [
+ { label: "涓荤敓浜ц鍒�", path: "/productionManagement/productionPlan" },
+ { label: "鐢熶骇璁㈠崟", path: "/productionManagement/productionOrder" },
+ { label: "鐢熶骇鎶ュ伐", path: "/productionManagement/productionReporting" },
+ { label: "杩囩▼妫�", path: "/qualityManagement/processInspection" },
+ { label: "鐢熶骇鑳借��", path: "/energyManagement/productionEnergyConsumption" },
+ { label: "鐢熶骇鎴愭湰", path: "/costAccounting/productionCostAccounting" },
+ { label: "鏍囧噯vs瀹為檯", path: "/costAccounting/stdVsActCostAnalysis" },
+ { label: "鍐崇瓥鍒嗘瀽", path: "/reportAnalysis/dataDashboard" },
+];
+
+const isRouteValid = (path) => {
+ if (!path || !path.startsWith("/")) return false;
+ const resolved = router.resolve(path);
+ return resolved.matched && resolved.matched.length > 0;
+};
+
+const withValidFlag = (list) =>
+ list.map((item) => ({
+ ...item,
+ invalid: !isRouteValid(item.path),
+ }));
+
+const pageOptions = router
+ .getRoutes()
+ .filter((route) => {
+ const hasTitle = Boolean(route.meta?.title);
+ const validPath = route.path && route.path.startsWith("/") && !route.path.includes(":");
+ const isVisibleMenu = !route.meta?.hidden && route.path !== "/index";
+ const notSpecial =
+ !route.path.includes("redirect") &&
+ route.path !== "/login" &&
+ route.path !== "/register" &&
+ route.path !== "/401" &&
+ !route.path.includes(":pathMatch");
+ return hasTitle && validPath && isVisibleMenu && notSpecial;
+ })
+ .map((route) => ({
+ title: route.meta.title,
+ path: route.path,
+ }))
+ .sort((a, b) => a.path.localeCompare(b.path));
+
+const normalizePath = (path) => String(path || "").replace(/\/+/g, "/");
+const joinPath = (parentPath, childPath) => {
+ if (!childPath) return normalizePath(parentPath || "/");
+ if (String(childPath).startsWith("/")) return normalizePath(childPath);
+ return normalizePath(`${parentPath || ""}/${childPath}`);
+};
+
+const buildMenuTreeOptions = (routes = [], parentPath = "") => {
+ const result = [];
+ routes.forEach((route) => {
+ if (!route || route.hidden) return;
+ const fullPath = joinPath(parentPath, route.path);
+ const children = buildMenuTreeOptions(route.children || [], fullPath);
+ const title = route.meta?.title;
+ if (!title && children.length > 0) {
+ result.push(...children);
+ return;
+ }
+ if (!title) return;
+ result.push({
+ label: title,
+ value: fullPath,
+ disabled: children.length > 0,
+ children,
+ });
+ });
+ return result;
+};
+
+const menuTreeOptions = computed(() => buildMenuTreeOptions(permissionStore.sidebarRouters || []));
+const selectableMenuMap = computed(() => {
+ const map = new Map();
+ const walk = (list = []) => {
+ list.forEach((item) => {
+ if (!item.disabled) map.set(item.value, item.label);
+ if (item.children?.length) walk(item.children);
+ });
+ };
+ walk(menuTreeOptions.value);
+ return map;
+});
+
+const keywordMap = {
+ "涓荤敓浜ц鍒�": ["鐢熶骇璁″垝", "productionPlan"],
+ "鐢熶骇璁㈠崟": ["鐢熶骇璁㈠崟", "productionOrder"],
+ "鐢熶骇鎶ュ伐": ["鎶ュ伐", "productionReporting"],
+ "杩囩▼妫�": ["杩囩▼妫�", "processInspection"],
+ "鐢熶骇鑳借��": ["鐢熶骇鑳借��", "productionEnergyConsumption"],
+ "鐢熶骇鎴愭湰": ["鐢熶骇鎴愭湰", "productionCostAccounting"],
+ "鏍囧噯vs瀹為檯": ["鏍囧噯", "瀹為檯", "stdVsActCostAnalysis"],
+ "鍐崇瓥鍒嗘瀽": ["鍐崇瓥", "鐪嬫澘", "dataDashboard"],
+};
+
+const findRouteByKeywords = (keywords = []) => {
+ const lowerKeywords = keywords.map((k) => String(k).toLowerCase());
+ return pageOptions.find((item) => {
+ const title = String(item.title || "").toLowerCase();
+ const path = String(item.path || "").toLowerCase();
+ return lowerKeywords.some((k) => title.includes(k) || path.includes(k));
+ });
+};
+
+const getPathByKeywords = (keywords = []) => findRouteByKeywords(keywords)?.path || "";
+
+const getRecommendedShortcuts = () => {
+ const list = defaultShortcuts
+ .map((item) => {
+ const matched = findRouteByKeywords(keywordMap[item.label] || [item.label]);
+ return matched ? { label: item.label, path: matched.path } : null;
+ })
+ .filter(Boolean);
+ return list.length > 0 ? list : defaultShortcuts;
+};
+
+const tryRepairSavedShortcut = (item) => {
+ const matched = findRouteByKeywords(keywordMap[item.label] || [item.label]);
+ if (matched) return { label: item.label, path: matched.path };
+ return item;
+};
+
+const getSavedShortcuts = () => {
+ const recommended = getRecommendedShortcuts();
+ try {
+ const saved = localStorage.getItem(SHORTCUT_STORAGE_KEY);
+ if (!saved) return recommended;
+ const parsed = JSON.parse(saved);
+ if (!Array.isArray(parsed) || parsed.length === 0) return recommended;
+ return parsed.map((item) => tryRepairSavedShortcut(item));
+ } catch (error) {
+ return recommended;
+ }
+};
+
+const shortcuts = reactive(withValidFlag(getSavedShortcuts().slice(0, 6)));
+const shortcutDialogVisible = ref(false);
+const configDialogVisible = ref(false);
+const selectedPagePath = ref("");
+const lastUpdatedAt = ref("");
+const pendingFilter = ref("all");
+const chartRangePlan = ref(3);
+const chartRangeQuality = ref(2);
+
+const routePathMap = {
+ plan: getPathByKeywords(["鐢熶骇璁″垝", "productionPlan"]),
+ order: getPathByKeywords(["鐢熶骇璁㈠崟", "productionOrder"]),
+ processInspection: getPathByKeywords(["杩囩▼妫�", "processInspection"]),
+ meter: getPathByKeywords(["鎶勮〃", "meterCollection", "鑳借��"]),
+ dispatch: getPathByKeywords(["鐢熶骇璋冨害", "productionDispatching"]),
+};
+
+const persistShortcuts = () => {
+ localStorage.setItem(
+ SHORTCUT_STORAGE_KEY,
+ JSON.stringify(shortcuts.slice(0, 6).map(({ label, path }) => ({ label, path })))
+ );
+};
+
+const todos = reactive([]);
+
+const businessFocus = reactive([
+ { name: "鐢熶骇璁㈠崟鎬绘暟", value: "-" },
+ { name: "宸插畬鎴愯鍗曟暟", value: "-" },
+ { name: "鏈畬鎴愯鍗曟暟", value: "-" },
+ { name: "閮ㄥ垎瀹屾垚璁㈠崟鏁�", value: "-" },
+ { name: "璐ㄦ鎬绘暟", value: "-" },
+ { name: "杩囩▼妫�鎬绘暟", value: "-" },
+]);
+
+const pendingTasks = reactive([]);
+const warningList = reactive([]);
+const SECTION_CONFIG_KEY = "home-sections-v1";
+const sectionConfigOptions = [
+ { key: "trendCards", label: "鏈�杩�7澶╄秼鍔垮崱" },
+ { key: "planTrend", label: "璁″垝涓庣敓浜ц秼鍔垮浘" },
+ { key: "qualityChart", label: "璐ㄦ寮傚父鍒嗗竷鍥�" },
+ { key: "costChart", label: "鑳借�椾笌鎴愭湰缁撴瀯鍥�" },
+ { key: "warningCenter", label: "寮傚父棰勮涓績" },
+ { key: "planTable", label: "鐢熶骇璁″垝鎵ц鏄庣粏琛�" },
+];
+const enabledSectionKeys = ref(sectionConfigOptions.map((i) => i.key));
+
+const chartStyle = { width: "100%", height: "100%" };
+const grid = { left: "3%", right: "4%", bottom: "3%", containLabel: true };
+const lineTooltip = { trigger: "axis" };
+const barTooltip = { trigger: "axis", axisPointer: { type: "shadow" } };
+const pieTooltip = { trigger: "item" };
+
+const valueYAxis = [{ type: "value" }];
+const planXAxis = [{ type: "category", data: [] }];
+const qualityXAxis = [{ type: "category", data: [] }];
+
+const planLegend = { show: true, data: ["璁″垝閲�", "涓嬪彂閲�", "瀹屾垚閲�"] };
+const costLegend = {
+ show: true,
+ orient: "vertical",
+ right: 10,
+ top: "center",
+ data: ["鑳借�楁垚鏈�", "鐢熶骇鎴愭湰", "璐ㄩ噺鎹熷け鎴愭湰", "鍏朵粬鎴愭湰"],
+};
+
+const planSeries = reactive([
+ { name: "璁″垝閲�", type: "line", smooth: true, data: [] },
+ { name: "涓嬪彂閲�", type: "line", smooth: true, data: [] },
+ { name: "瀹屾垚閲�", type: "line", smooth: true, data: [] },
+]);
+
+const qualitySeries = reactive([
+ {
+ name: "寮傚父鏁�",
+ type: "bar",
+ barWidth: 26,
+ itemStyle: { color: "#e67e22", borderRadius: [6, 6, 0, 0] },
+ data: [],
+ },
+]);
+
+const costSeries = reactive([
+ {
+ type: "pie",
+ radius: ["45%", "68%"],
+ center: ["35%", "50%"],
+ label: { formatter: "{b}: {d}%" },
+ data: [],
+ },
+]);
+
+const planTable = reactive([]);
+const recentTrendCards = reactive([
+ { key: "planIssued", label: "璁″垝涓嬪彂閲�", unit: "鍗�", values: [0, 0, 0, 0, 0, 0, 0], latest: 0, change: 0 },
+ { key: "qualityRaw", label: "鏉ユ枡妫�鏁伴噺", unit: "鏉�", values: [0, 0, 0, 0, 0, 0, 0], latest: 0, change: 0 },
+ { key: "qualityProcess", label: "杩囩▼妫�鏁伴噺", unit: "鏉�", values: [0, 0, 0, 0, 0, 0, 0], latest: 0, change: 0 },
+ { key: "qualityFactory", label: "鎴愬搧妫�鏁伴噺", unit: "鏉�", values: [0, 0, 0, 0, 0, 0, 0], latest: 0, change: 0 },
+]);
+
+const toNumber = (value) => {
+ const num = Number(value);
+ return Number.isFinite(num) ? num : 0;
+};
+
+const pickFirstNumber = (obj, keys = []) => {
+ for (const key of keys) {
+ if (obj && obj[key] !== undefined && obj[key] !== null) return toNumber(obj[key]);
+ }
+ return 0;
+};
+
+const updateArray = (target, list) => {
+ target.splice(0, target.length, ...list);
+};
+
+const toFixedOne = (num) => Number(num || 0).toFixed(1);
+
+const normalizeSeven = (list = []) => {
+ const nums = list.map((i) => toNumber(i));
+ if (nums.length >= 7) return nums.slice(-7);
+ return [...Array(7 - nums.length).fill(0), ...nums];
+};
+
+const calcTrend = (list = []) => {
+ if (!Array.isArray(list) || list.length === 0) return { latest: 0, change: 0 };
+ const first = toNumber(list[0]);
+ const latest = toNumber(list[list.length - 1]);
+ if (first === 0) return { latest, change: latest > 0 ? 100 : 0 };
+ return { latest, change: ((latest - first) / first) * 100 };
+};
+
+const setTrendCard = (key, values) => {
+ const target = recentTrendCards.find((i) => i.key === key);
+ if (!target) return;
+ const series = normalizeSeven(values);
+ const { latest, change } = calcTrend(series);
+ target.values = series;
+ target.latest = latest;
+ target.change = Number(toFixedOne(change));
+};
+
+const trendClass = (change) => (change > 0 ? "up" : change < 0 ? "down" : "flat");
+
+const calcBarHeight = (value, list) => {
+ const max = Math.max(...list, 1);
+ return Math.max(18, Math.round((toNumber(value) / max) * 100));
+};
+
+const filteredPendingTasks = computed(() => {
+ if (pendingFilter.value === "high") return pendingTasks.filter((i) => i.level === "楂�");
+ if (pendingFilter.value === "mine") {
+ const currentUserName = String(userStore?.name || "").toLowerCase();
+ const currentUserId = String(userStore?.userId || "");
+ return pendingTasks.filter((i) => {
+ const ownerName = String(i.ownerName || "").toLowerCase();
+ const ownerId = String(i.ownerId || "");
+ return (currentUserName && ownerName && ownerName.includes(currentUserName)) || (currentUserId && ownerId === currentUserId);
+ });
+ }
+ return pendingTasks;
+});
+
+const isSectionVisible = (key) => enabledSectionKeys.value.includes(key);
+
+const goTo = (path) => {
+ if (!isRouteValid(path)) {
+ ElMessage.warning("褰撳墠鑿滃崟鏈厤缃椤甸潰鎴栨棤璁块棶鏉冮檺");
+ return;
+ }
+ router.push(path);
+};
+
+const handleTrendCardClick = (card) => {
+ const mapping = {
+ planIssued: routePathMap.plan || routePathMap.order,
+ qualityRaw: routePathMap.processInspection,
+ qualityProcess: routePathMap.processInspection,
+ qualityFactory: routePathMap.processInspection,
+ };
+ const target = mapping[card.key];
+ if (!target) {
+ ElMessage.warning("鏈厤缃彲璺宠浆椤甸潰");
+ return;
+ }
+ const query =
+ card.key === "planIssued"
+ ? { dateType: String(chartRangePlan.value), source: "homeTrend" }
+ : { dateType: String(chartRangeQuality.value), source: "homeTrend" };
+ router.push({ path: target, query });
+};
+
+const openShortcutDialog = () => {
+ shortcutDialogVisible.value = true;
+};
+
+const addShortcutBySelect = () => {
+ if (shortcuts.length >= 6) {
+ ElMessage.warning("蹇嵎鍏ュ彛鏈�澶氬彧鑳芥坊鍔�6涓�");
+ return;
+ }
+ if (!selectedPagePath.value) {
+ ElMessage.warning("璇峰厛閫夋嫨椤甸潰");
+ return;
+ }
+ if (shortcuts.some((item) => item.path === selectedPagePath.value)) {
+ ElMessage.warning("璇ュ揩鎹峰叆鍙e凡瀛樺湪");
+ return;
+ }
+ const label = selectableMenuMap.value.get(selectedPagePath.value);
+ if (!label) {
+ ElMessage.warning("璇烽�夋嫨鍙坊鍔犵殑椤甸潰锛岀洰褰曡妭鐐逛笉鍙��");
+ return;
+ }
+ shortcuts.push({
+ label,
+ path: selectedPagePath.value,
+ invalid: !isRouteValid(selectedPagePath.value),
+ });
+ persistShortcuts();
+ selectedPagePath.value = "";
+};
+
+const removeShortcut = (index) => {
+ shortcuts.splice(index, 1);
+ persistShortcuts();
+ ElMessage.success("宸插垹闄ゅ揩鎹峰叆鍙�");
+};
+
+const loadHomeTodos = async () => {
+ try {
+ const res = await homeTodos();
+ const list = Array.isArray(res?.data) ? res.data : [];
+ const mapped = list.slice(0, 4).map((item, idx) => {
+ const text = item?.approveReason || item?.approveTypeName || `寰呭鐞嗕簨椤� ${idx + 1}`;
+ const levelType = idx === 0 ? "danger" : idx <= 2 ? "warning" : "success";
+ const level = idx === 0 ? "楂�" : idx <= 2 ? "涓�" : "浣�";
+ return { level, title: text, type: levelType };
+ });
+ updateArray(todos, mapped);
+ const pendingMapped = list.slice(0, 4).map((item, idx) => {
+ const title = item?.approveReason || item?.approveTypeName || `寰呭鐞嗕簨椤� ${idx + 1}`;
+ const path = inferTodoPath(item);
+ return {
+ id: item?.id || `${idx}-${title}`,
+ title,
+ level: idx === 0 ? "楂�" : idx <= 2 ? "涓�" : "浣�",
+ type: idx === 0 ? "danger" : idx <= 2 ? "warning" : "success",
+ path,
+ ownerId: item?.approveUserId || item?.userId || "",
+ ownerName: item?.approveUserName || item?.userName || "",
+ };
+ });
+ updateArray(pendingTasks, pendingMapped);
+ } catch (error) {
+ console.error("homeTodos鎺ュ彛鑾峰彇澶辫触:", error);
+ }
+};
+
+const loadOrderAndProgress = async () => {
+ try {
+ const [orderRes, progressRes] = await Promise.allSettled([orderCount(), getProgressStatistics()]);
+
+ if (orderRes.status === "fulfilled") {
+ const items = Array.isArray(orderRes.value?.data) ? orderRes.value.data : [];
+ const byName = Object.fromEntries(
+ items.map((i) => [String(i?.name || "").replace(/\s/g, ""), i?.value])
+ );
+ businessFocus[0].value = `${pickFirstNumber(byName, ["鐢熶骇璁㈠崟鏁�", "鐢熶骇璁㈠崟鎬绘暟", "鎬昏鍗曟暟"]) || 0} 鍗昤;
+ businessFocus[1].value = `${pickFirstNumber(byName, ["宸插畬鎴愯鍗曟暟"]) || 0} 鍗昤;
+ businessFocus[2].value = `${pickFirstNumber(byName, ["寰呯敓浜ц鍗曟暟", "鏈畬鎴愯鍗曟暟"]) || 0} 鍗昤;
+ businessFocus[3].value = `${pickFirstNumber(byName, ["閮ㄥ垎瀹屾垚璁㈠崟鏁�"]) || 0} 鍗昤;
+ }
+
+ if (progressRes.status === "fulfilled") {
+ const p = progressRes.value?.data || {};
+ const detail = Array.isArray(p.completedOrderDetails) ? p.completedOrderDetails : [];
+ const rows = detail.slice(0, 6).map((item, index) => {
+ const qty = pickFirstNumber(item, ["quantity", "planQuantity"]);
+ const done = pickFirstNumber(item, ["completeQuantity", "completedQuantity"]);
+ return {
+ planNo: item.npsNo || item.productionPlanNo || `NO-${index + 1}`,
+ product: item.productCategory || item.productName || "-",
+ qty,
+ issued: done,
+ status: qty > 0 && done >= qty ? "宸插畬鎴�" : done > 0 ? "鎵ц涓�" : "寰呬笅鍙�",
+ };
+ });
+ updateArray(planTable, rows);
+ setTrendCard(
+ "planIssued",
+ detail.slice(-7).map((i) => pickFirstNumber(i, ["completeQuantity", "completedQuantity", "issueNum"]))
+ );
+
+ }
+ } catch (error) {
+ console.error("orderCount/getProgressStatistics鎺ュ彛鑾峰彇澶辫触:", error);
+ }
+};
+
+const inferTodoPath = (todo) => {
+ const text = `${todo?.approveTypeName || ""}${todo?.approveReason || ""}`.toLowerCase();
+ if (text.includes("璁″垝")) return routePathMap.plan || routePathMap.order;
+ if (text.includes("璁㈠崟")) return routePathMap.order || routePathMap.plan;
+ if (text.includes("杩囩▼妫�") || text.includes("璐ㄦ")) return routePathMap.processInspection || routePathMap.plan;
+ if (text.includes("鑳借��") || text.includes("鎶勮〃")) return routePathMap.meter || routePathMap.plan;
+ return routePathMap.plan || routePathMap.order || "";
+};
+
+const loadPlanTrend = async () => {
+ try {
+ const res = await processDataProductionStatistics({ type: chartRangePlan.value });
+ const list = Array.isArray(res?.data) ? res.data : [];
+ planXAxis[0].data = list.map((i, index) => i.processName || `宸ュ簭${index + 1}`);
+ planSeries[0].data = list.map((i) => pickFirstNumber(i, ["totalInput", "input", "planNum"]));
+ planSeries[1].data = list.map((i) => pickFirstNumber(i, ["totalOutput", "output", "issueNum"]));
+ planSeries[2].data = list.map((i) => pickFirstNumber(i, ["totalScrap", "scrap", "completeNum"]));
+ } catch (error) {
+ console.error("processDataProductionStatistics鎺ュ彛鑾峰彇澶辫触:", error);
+ }
+};
+
+const loadQualityData = async () => {
+ try {
+ const res = await qualityInspectionStatistics({ type: chartRangeQuality.value });
+ const data = res?.data || {};
+ const items = Array.isArray(data.item) ? data.item : [];
+ if (items.length > 0) {
+ qualityXAxis[0].data = items.map((i) => i.date || i.name || "-");
+ qualitySeries[0].data = items.map((i) =>
+ pickFirstNumber(i, ["supplierNum", "processNum", "factoryNum", "totalNum"])
+ );
+ setTrendCard("qualityRaw", items.map((i) => pickFirstNumber(i, ["supplierNum"])));
+ setTrendCard("qualityProcess", items.map((i) => pickFirstNumber(i, ["processNum"])));
+ setTrendCard("qualityFactory", items.map((i) => pickFirstNumber(i, ["factoryNum"])));
+ } else {
+ qualityXAxis[0].data = ["鏉ユ枡妫�", "杩囩▼妫�", "鎴愬搧妫�"];
+ qualitySeries[0].data = [
+ pickFirstNumber(data, ["supplierNum"]),
+ pickFirstNumber(data, ["processNum"]),
+ pickFirstNumber(data, ["factoryNum"]),
+ ];
+ setTrendCard("qualityRaw", [pickFirstNumber(data, ["supplierNum"])]);
+ setTrendCard("qualityProcess", [pickFirstNumber(data, ["processNum"])]);
+ setTrendCard("qualityFactory", [pickFirstNumber(data, ["factoryNum"])]);
+ }
+ businessFocus[4].value = `${pickFirstNumber(data, ["supplierNum", "totalNum"])} 鏉;
+ businessFocus[5].value = `${pickFirstNumber(data, ["processNum"])} 鏉;
+ } catch (error) {
+ console.error("qualityInspectionStatistics鎺ュ彛鑾峰彇澶辫触:", error);
+ }
+};
+
+const loadWarningCenter = async () => {
+ try {
+ const res = await nonComplianceWarning();
+ const list = Array.isArray(res?.data) ? res.data : [];
+ const mapped = list.slice(0, 6).map((item, idx) => {
+ const levelNum = toNumber(item.level ?? item.warningLevel ?? 2);
+ const levelType = levelNum >= 3 ? "danger" : levelNum === 2 ? "warning" : "info";
+ const levelText = levelNum >= 3 ? "楂�" : levelNum === 2 ? "涓�" : "浣�";
+ const title = item.name || item.title || item.paramName || `寮傚父棰勮 ${idx + 1}`;
+ const text = `${title}${item.processName || ""}${item.orderNo || ""}`.toLowerCase();
+ const path = text.includes("璐ㄦ")
+ ? routePathMap.processInspection
+ : text.includes("璁㈠崟")
+ ? routePathMap.order
+ : routePathMap.processInspection || routePathMap.order || routePathMap.plan;
+ return { id: item.id || `${idx}-${title}`, levelType, levelText, title, path };
+ });
+ updateArray(warningList, mapped);
+ } catch (error) {
+ console.error("nonComplianceWarning鎺ュ彛鑾峰彇澶辫触:", error);
+ updateArray(warningList, []);
+ }
+};
+
+const initSectionConfig = () => {
+ try {
+ const raw = localStorage.getItem(SECTION_CONFIG_KEY);
+ if (!raw) return;
+ const parsed = JSON.parse(raw);
+ if (Array.isArray(parsed) && parsed.length > 0) {
+ enabledSectionKeys.value = parsed.filter((k) => sectionConfigOptions.some((i) => i.key === k));
+ }
+ } catch (error) {
+ console.error("璇诲彇棣栭〉閰嶇疆澶辫触:", error);
+ }
+};
+
+const saveSectionConfig = () => {
+ if (enabledSectionKeys.value.length === 0) {
+ ElMessage.warning("鑷冲皯淇濈暀涓�涓ā鍧�");
+ return;
+ }
+ localStorage.setItem(SECTION_CONFIG_KEY, JSON.stringify(enabledSectionKeys.value));
+ configDialogVisible.value = false;
+ ElMessage.success("棣栭〉閰嶇疆宸蹭繚瀛�");
+};
+
+const loadCostComposition = async () => {
+ try {
+ const res = await expenseCompositionAnalysis({ type: 1 });
+ const list = Array.isArray(res?.data) ? res.data : [];
+ const mapped = list.map((i) => ({
+ name: i.name || "鏈懡鍚�",
+ value: pickFirstNumber(i, ["value", "amount", "cost"]),
+ }));
+ costSeries[0].data = mapped;
+ } catch (error) {
+ console.error("expenseCompositionAnalysis鎺ュ彛鑾峰彇澶辫触:", error);
+ }
+};
+
+const refreshDashboardData = () => {
+ loadHomeTodos();
+ loadOrderAndProgress();
+ loadPlanTrend();
+ loadQualityData();
+ loadCostComposition();
+ loadWarningCenter();
+ lastUpdatedAt.value = new Date().toLocaleString();
+};
+
+onMounted(() => {
+ initSectionConfig();
+ refreshDashboardData();
+});
+</script>
+
+<style scoped>
+.home-page {
+ min-height: 100vh;
+ background: #f5f7fb;
+ padding: 20px;
+}
+
+.top-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 16px;
+ background: #fff;
+ border-radius: 12px;
+ padding: 16px;
+ margin-bottom: 16px;
+}
+
+.top-actions {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.refresh-time {
+ font-size: 12px;
+ color: #7b8794;
+}
+
+.user-box {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.avatar {
+ width: 54px;
+ height: 54px;
+ border-radius: 50%;
+ object-fit: cover;
+}
+
+.hello {
+ font-size: 18px;
+ font-weight: 700;
+ color: #1f2d3d;
+}
+
+.sub {
+ margin-top: 4px;
+ color: #6b7785;
+ font-size: 13px;
+}
+
+.content-grid {
+ display: grid;
+ grid-template-columns: 320px 1fr;
+ gap: 16px;
+ align-items: stretch;
+}
+
+.left-col,
+.right-col {
+ display: flex;
+ flex-direction: column;
+}
+
+.section-card {
+ background: #fff;
+ border-radius: 12px;
+ padding: 16px;
+ margin-bottom: 16px;
+ box-shadow: 0 2px 10px rgba(20, 35, 90, 0.06);
+}
+
+.flex-fill-card {
+ flex: 1;
+}
+
+.section-title {
+ position: relative;
+ padding-left: 10px;
+ margin-bottom: 14px;
+ font-size: 16px;
+ font-weight: 700;
+ color: #243447;
+}
+
+.section-title-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.section-title::before {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 4px;
+ width: 4px;
+ height: 16px;
+ border-radius: 2px;
+ background: #409eff;
+}
+
+.quick-grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 10px;
+}
+
+.quick-grid :deep(.el-button) {
+ margin-left: 0;
+}
+
+.shortcut-form-row {
+ display: grid;
+ grid-template-columns: 1fr 1.5fr auto;
+ gap: 10px;
+ margin-bottom: 12px;
+}
+
+.todo-row {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ margin-bottom: 10px;
+ font-size: 13px;
+ color: #3b4a5b;
+}
+
+.focus-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 0;
+ border-bottom: 1px dashed #e8edf5;
+}
+
+.focus-row:last-child {
+ border-bottom: none;
+}
+
+.focus-name {
+ font-size: 13px;
+ color: #516174;
+}
+
+.focus-value {
+ font-weight: 700;
+ color: #1f2d3d;
+}
+
+.task-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 10px;
+ padding: 8px 0;
+ border-bottom: 1px dashed #e8edf5;
+}
+
+.task-row:last-child {
+ border-bottom: none;
+}
+
+.task-left {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.task-title {
+ font-size: 13px;
+ color: #3d4d5f;
+}
+
+.row-two {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 16px;
+}
+
+.trend-cards {
+ display: grid;
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+ gap: 12px;
+}
+
+.trend-card {
+ border: 1px solid #e8edf5;
+ border-radius: 10px;
+ padding: 12px;
+}
+
+.trend-card.clickable {
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+
+.trend-card.clickable:hover {
+ border-color: #8eb8ff;
+ background: #f6f9ff;
+}
+
+.trend-head {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.trend-label {
+ font-size: 13px;
+ color: #5f6b7a;
+}
+
+.trend-rate {
+ font-size: 12px;
+ font-weight: 700;
+}
+
+.trend-rate.up {
+ color: #67c23a;
+}
+
+.trend-rate.down {
+ color: #f56c6c;
+}
+
+.trend-rate.flat {
+ color: #909399;
+}
+
+.trend-value {
+ margin-top: 6px;
+ font-size: 20px;
+ color: #1f2d3d;
+ font-weight: 700;
+}
+
+.sparkline {
+ margin-top: 10px;
+ height: 48px;
+ display: flex;
+ align-items: flex-end;
+ gap: 4px;
+}
+
+.sparkline-bar {
+ flex: 1;
+ min-height: 6px;
+ border-radius: 3px 3px 0 0;
+ background: linear-gradient(180deg, #82b1ff 0%, #409eff 100%);
+}
+
+.warning-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 10px;
+ padding: 8px 0;
+ border-bottom: 1px dashed #e8edf5;
+}
+
+.warning-row:last-child {
+ border-bottom: none;
+}
+
+.warning-left {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.warning-title {
+ font-size: 13px;
+ color: #3d4d5f;
+}
+
+.config-check-group {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 10px 16px;
+}
+
+.mini-table-wrap :deep(.el-table th) {
+ background: #f8fbff;
+}
+
+@media (max-width: 1100px) {
+ .content-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .row-two {
+ grid-template-columns: 1fr;
+ }
+
+ .trend-cards {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+}
+</style>
\ No newline at end of file
--
Gitblit v1.9.3