¶Ô±ÈÐÂÎļþ |
| | |
| | | # 页颿 é¢ |
| | | VITE_APP_TITLE = è¥ä¾ç®¡çç³»ç» |
| | | |
| | | # å¼åç¯å¢é
ç½® |
| | | VITE_APP_ENV = 'development' |
| | | |
| | | # è¥ä¾ç®¡çç³»ç»/å¼åç¯å¢ |
| | | VITE_APP_BASE_API = '/dev-api' |
¶Ô±ÈÐÂÎļþ |
| | |
| | | # 页颿 é¢ |
| | | VITE_APP_TITLE = è¥ä¾ç®¡çç³»ç» |
| | | |
| | | # ç产ç¯å¢é
ç½® |
| | | VITE_APP_ENV = 'production' |
| | | |
| | | # è¥ä¾ç®¡çç³»ç»/ç产ç¯å¢ |
| | | VITE_APP_BASE_API = '/prod-api' |
| | | |
| | | # æ¯å¦å¨æå
æ¶å¼å¯åç¼©ï¼æ¯æ gzip å brotli |
| | | VITE_BUILD_COMPRESS = gzip |
¶Ô±ÈÐÂÎļþ |
| | |
| | | # 页颿 é¢ |
| | | VITE_APP_TITLE = è¥ä¾ç®¡çç³»ç» |
| | | |
| | | # ç产ç¯å¢é
ç½® |
| | | VITE_APP_ENV = 'staging' |
| | | |
| | | # è¥ä¾ç®¡çç³»ç»/ç产ç¯å¢ |
| | | VITE_APP_BASE_API = '/stage-api' |
| | | |
| | | # æ¯å¦å¨æå
æ¶å¼å¯åç¼©ï¼æ¯æ gzip å brotli |
| | | VITE_BUILD_COMPRESS = gzip |
¶Ô±ÈÐÂÎļþ |
| | |
| | | custom: http://doc.ruoyi.vip/ruoyi-vue/other/donate.html |
¶Ô±ÈÐÂÎļþ |
| | |
| | | .DS_Store |
| | | node_modules/ |
| | | dist/ |
| | | npm-debug.log* |
| | | yarn-debug.log* |
| | | yarn-error.log* |
| | | **/*.log |
| | | |
| | | tests/**/coverage/ |
| | | tests/e2e/reports |
| | | selenium-debug.log |
| | | |
| | | # Editor directories and files |
| | | .idea |
| | | .vscode |
| | | *.suo |
| | | *.ntvs* |
| | | *.njsproj |
| | | *.sln |
| | | *.local |
| | | |
| | | package-lock.json |
| | | yarn.lock |
¶Ô±ÈÐÂÎļþ |
| | |
| | | The MIT License (MIT) |
| | | |
| | | Copyright (c) 2018 RuoYi |
| | | |
| | | Permission is hereby granted, free of charge, to any person obtaining a copy of |
| | | this software and associated documentation files (the "Software"), to deal in |
| | | the Software without restriction, including without limitation the rights to |
| | | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
| | | the Software, and to permit persons to whom the Software is furnished to do so, |
| | | subject to the following conditions: |
| | | |
| | | The above copyright notice and this permission notice shall be included in all |
| | | copies or substantial portions of the Software. |
| | | |
| | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
| | | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
| | | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
| | | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| | | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
¶Ô±ÈÐÂÎļþ |
| | |
| | | @echo off |
| | | echo. |
| | | echo [ä¿¡æ¯] æå
Webå·¥ç¨ï¼çædistæä»¶ã |
| | | echo. |
| | | |
| | | %~d0 |
| | | cd %~dp0 |
| | | |
| | | cd .. |
| | | yarn build:prod |
| | | |
| | | pause |
¶Ô±ÈÐÂÎļþ |
| | |
| | | @echo off |
| | | echo. |
| | | echo [ä¿¡æ¯] å®è£
Webå·¥ç¨ï¼çænode_modulesæä»¶ã |
| | | echo. |
| | | |
| | | %~d0 |
| | | cd %~dp0 |
| | | |
| | | cd .. |
| | | yarn --registry=https://registry.npmmirror.com |
| | | |
| | | pause |
¶Ô±ÈÐÂÎļþ |
| | |
| | | @echo off |
| | | echo. |
| | | echo [ä¿¡æ¯] ä½¿ç¨ Vite å½ä»¤è¿è¡ Web å·¥ç¨ã |
| | | echo. |
| | | |
| | | %~d0 |
| | | cd %~dp0 |
| | | |
| | | cd .. |
| | | yarn dev |
| | | |
| | | pause |
¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | <!DOCTYPE html> |
| | | <html lang="zh-CN"> |
| | | <head> |
| | | <meta charset="UTF-8" /> |
| | | <title>请å级æ¨çæµè§å¨</title> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" > |
| | | <meta name="renderer" content="webkit"> |
| | | <base target="_blank" /> |
| | | <style type="text/css"> |
| | | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0} |
| | | a{text-decoration:none;color:#0072c6;}a:hover{text-decoration:none;color:#004d8c;} |
| | | body{width:960px;margin:0 auto;padding:10px;font-size:14px;line-height:24px;color:#454545;font-family:'Microsoft YaHei UI','Microsoft YaHei',DengXian,SimSun,'Segoe UI',Tahoma,Helvetica,sans-serif;overflow-y:scroll} |
| | | h1{font-size:40px;line-height:80px;font-weight:100;margin-bottom:10px;} |
| | | h2{font-size:20px;line-height:25px;font-weight:100;margin:10px 0;} |
| | | em{color:red} |
| | | p{margin-bottom:10px;} |
| | | hr{margin:20px 0;border:0;border-top:1px solid #dadada} |
| | | span{display:block;font-size:12px;line-height:12px;} |
| | | .clean{clear:both;} |
| | | .browser{padding:10px 10px;} |
| | | .browser li{width:auto;padding:0 80px;margin-top:30px;height:34px;line-height:22px;float:left;list-style:none;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAADMCAYAAAAWCXEwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKTWlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVN3WJP3Fj7f92UPVkLY8LGXbIEAIiOsCMgQWaIQkgBhhBASQMWFiApWFBURnEhVxILVCkidiOKgKLhnQYqIWotVXDjuH9yntX167+3t+9f7vOec5/zOec8PgBESJpHmomoAOVKFPDrYH49PSMTJvYACFUjgBCAQ5svCZwXFAADwA3l4fnSwP/wBr28AAgBw1S4kEsfh/4O6UCZXACCRAOAiEucLAZBSAMguVMgUAMgYALBTs2QKAJQAAGx5fEIiAKoNAOz0ST4FANipk9wXANiiHKkIAI0BAJkoRyQCQLsAYFWBUiwCwMIAoKxAIi4EwK4BgFm2MkcCgL0FAHaOWJAPQGAAgJlCLMwAIDgCAEMeE80DIEwDoDDSv+CpX3CFuEgBAMDLlc2XS9IzFLiV0Bp38vDg4iHiwmyxQmEXKRBmCeQinJebIxNI5wNMzgwAABr50cH+OD+Q5+bk4eZm52zv9MWi/mvwbyI+IfHf/ryMAgQAEE7P79pf5eXWA3DHAbB1v2upWwDaVgBo3/ldM9sJoFoK0Hr5i3k4/EAenqFQyDwdHAoLC+0lYqG9MOOLPv8z4W/gi372/EAe/tt68ABxmkCZrcCjg/1xYW52rlKO58sEQjFu9+cj/seFf/2OKdHiNLFcLBWK8ViJuFAiTcd5uVKRRCHJleIS6X8y8R+W/QmTdw0ArIZPwE62B7XLbMB+7gECiw5Y0nYAQH7zLYwaC5EAEGc0Mnn3AACTv/mPQCsBAM2XpOMAALzoGFyolBdMxggAAESggSqwQQcMwRSswA6cwR28wBcCYQZEQAwkwDwQQgbkgBwKoRiWQRlUwDrYBLWwAxqgEZrhELTBMTgN5+ASXIHrcBcGYBiewhi8hgkEQcgIE2EhOogRYo7YIs4IF5mOBCJhSDSSgKQg6YgUUSLFyHKkAqlCapFdSCPyLXIUOY1cQPqQ28ggMor8irxHMZSBslED1AJ1QLmoHxqKxqBz0XQ0D12AlqJr0Rq0Hj2AtqKn0UvodXQAfYqOY4DRMQ5mjNlhXIyHRWCJWBomxxZj5Vg1Vo81Yx1YN3YVG8CeYe8IJAKLgBPsCF6EEMJsgpCQR1hMWEOoJewjtBK6CFcJg4Qxwicik6hPtCV6EvnEeGI6sZBYRqwm7iEeIZ4lXicOE1+TSCQOyZLkTgohJZAySQtJa0jbSC2kU6Q+0hBpnEwm65Btyd7kCLKArCCXkbeQD5BPkvvJw+S3FDrFiOJMCaIkUqSUEko1ZT/lBKWfMkKZoKpRzame1AiqiDqfWkltoHZQL1OHqRM0dZolzZsWQ8ukLaPV0JppZ2n3aC/pdLoJ3YMeRZfQl9Jr6Afp5+mD9HcMDYYNg8dIYigZaxl7GacYtxkvmUymBdOXmchUMNcyG5lnmA+Yb1VYKvYqfBWRyhKVOpVWlX6V56pUVXNVP9V5qgtUq1UPq15WfaZGVbNQ46kJ1Bar1akdVbupNq7OUndSj1DPUV+jvl/9gvpjDbKGhUaghkijVGO3xhmNIRbGMmXxWELWclYD6yxrmE1iW7L57Ex2Bfsbdi97TFNDc6pmrGaRZp3mcc0BDsax4PA52ZxKziHODc57LQMtPy2x1mqtZq1+rTfaetq+2mLtcu0W7eva73VwnUCdLJ31Om0693UJuja6UbqFutt1z+o+02PreekJ9cr1Dund0Uf1bfSj9Rfq79bv0R83MDQINpAZbDE4Y/DMkGPoa5hpuNHwhOGoEctoupHEaKPRSaMnuCbuh2fjNXgXPmasbxxirDTeZdxrPGFiaTLbpMSkxeS+Kc2Ua5pmutG003TMzMgs3KzYrMnsjjnVnGueYb7ZvNv8jYWlRZzFSos2i8eW2pZ8ywWWTZb3rJhWPlZ5VvVW16xJ1lzrLOtt1ldsUBtXmwybOpvLtqitm63Edptt3xTiFI8p0in1U27aMez87ArsmuwG7Tn2YfYl9m32zx3MHBId1jt0O3xydHXMdmxwvOuk4TTDqcSpw+lXZxtnoXOd8zUXpkuQyxKXdpcXU22niqdun3rLleUa7rrStdP1o5u7m9yt2W3U3cw9xX2r+00umxvJXcM970H08PdY4nHM452nm6fC85DnL152Xlle+70eT7OcJp7WMG3I28Rb4L3Le2A6Pj1l+s7pAz7GPgKfep+Hvqa+It89viN+1n6Zfgf8nvs7+sv9j/i/4XnyFvFOBWABwQHlAb2BGoGzA2sDHwSZBKUHNQWNBbsGLww+FUIMCQ1ZH3KTb8AX8hv5YzPcZyya0RXKCJ0VWhv6MMwmTB7WEY6GzwjfEH5vpvlM6cy2CIjgR2yIuB9pGZkX+X0UKSoyqi7qUbRTdHF09yzWrORZ+2e9jvGPqYy5O9tqtnJ2Z6xqbFJsY+ybuIC4qriBeIf4RfGXEnQTJAntieTE2MQ9ieNzAudsmjOc5JpUlnRjruXcorkX5unOy553PFk1WZB8OIWYEpeyP+WDIEJQLxhP5aduTR0T8oSbhU9FvqKNolGxt7hKPJLmnVaV9jjdO31D+miGT0Z1xjMJT1IreZEZkrkj801WRNberM/ZcdktOZSclJyjUg1plrQr1zC3KLdPZisrkw3keeZtyhuTh8r35CP5c/PbFWyFTNGjtFKuUA4WTC+oK3hbGFt4uEi9SFrUM99m/ur5IwuCFny9kLBQuLCz2Lh4WfHgIr9FuxYji1MXdy4xXVK6ZHhp8NJ9y2jLspb9UOJYUlXyannc8o5Sg9KlpUMrglc0lamUycturvRauWMVYZVkVe9ql9VbVn8qF5VfrHCsqK74sEa45uJXTl/VfPV5bdra3kq3yu3rSOuk626s91m/r0q9akHV0IbwDa0b8Y3lG19tSt50oXpq9Y7NtM3KzQM1YTXtW8y2rNvyoTaj9nqdf13LVv2tq7e+2Sba1r/dd3vzDoMdFTve75TsvLUreFdrvUV99W7S7oLdjxpiG7q/5n7duEd3T8Wej3ulewf2Re/ranRvbNyvv7+yCW1SNo0eSDpw5ZuAb9qb7Zp3tXBaKg7CQeXBJ9+mfHvjUOihzsPcw83fmX+39QjrSHkr0jq/dawto22gPaG97+iMo50dXh1Hvrf/fu8x42N1xzWPV56gnSg98fnkgpPjp2Snnp1OPz3Umdx590z8mWtdUV29Z0PPnj8XdO5Mt1/3yfPe549d8Lxw9CL3Ytslt0utPa49R35w/eFIr1tv62X3y+1XPK509E3rO9Hv03/6asDVc9f41y5dn3m978bsG7duJt0cuCW69fh29u0XdwruTNxdeo94r/y+2v3qB/oP6n+0/rFlwG3g+GDAYM/DWQ/vDgmHnv6U/9OH4dJHzEfVI0YjjY+dHx8bDRq98mTOk+GnsqcTz8p+Vv9563Or59/94vtLz1j82PAL+YvPv655qfNy76uprzrHI8cfvM55PfGm/K3O233vuO+638e9H5ko/ED+UPPR+mPHp9BP9z7nfP78L/eE8/sl0p8zAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAC7ESURBVHja5Lx5dFRV1rBfgHwYRQQVtB26ZWhtabtfeUGxGxFbUGZF8RMHGkVbRkekVYiKisicVhE0gEwBokgDAhEMMSSQkAECwcxkrlRSqVTqJqnxzs/vj5t7qUyAvr9e37fWV2vtleSm6p6n9t5nn733OVU2RaUaEP5PiqJSbeMXPBTA5/Xhzk9Vnd9vo3HFx21E2LYJX9IRgh6npvyCe9uaqS4K4C3IpXHFx9S99CTuJ8Z0KLVjRlA7ZgTuJ8ZgXxmJL+kIlwAkXBQk6HFq9pWRVA8fSvXwodYgdS892a6EA1UNvouqwXdR99KTeAtyfz2IL+kI1cOHYh9wqwVwKWJqpXbMCOv19gG3Imzb1JF2OgZxfr/NukH4jcNVfyEAE8IU+4BbKet1PfaVke3BtA/i/H6b8aIBt7a4mWmaC0nr55vmqRp8F5V33Mm5LhHtwbQF8SUdsSDCb1I1+K42g1xIWgOYYh9wK+e6RCBs29QxSIWus37aJM51iWjx4so77mwD1d5AHQ1eecedlN9yuyVlva6nrNf14Q7cEmRn4W7u3T2E9ME3UX7L7W1uZg5Weced1s3sA2613ql5LXzQjuRclwjcT4wxTXQeRHC7GLdnHPeensiCVwa3e0PznZk3EbZtwluQa0kofz8NcVNxr++Ce30XnNuv61Bcu7viXt8Fvyu7JYipjfGHxzD+8Bh2j+7fAiZcC+Y0zPDIbCyD6DyV6DyVeDcIQR2C39J4oieNJ3oSOnkVcnZ35Ozu6MVdDHF0N6S4C43OqJYg/0ydzb27hzDx0FjuPT2R+asfa6OVsl7X40s6QoWus/CQk6fWZPHChhxe3lbMCxtyrN9TyxSQSwidvMoC0XK6tRGybPjSRmOuNUKVo4Zxe8YxIu4+Jh4ay/jDY7j39MQWWjnXJYLGFR9Toes8tSaLiavTrIHDxfxfapkCwW8hy9YuhCmhk1fR1FRnaCS1NM4yy8RDYy2tjIkZRXq/HtYsCnqc2sJDTkYsTrU00J6YkEJQR7M/eEGY0MmrcOenqjZA2JmyzTJLuJiOe65LBHUvPUmGR2bE4lQmrk7jqTVZHcrE1WkMWpRIdJ4KnpUXBCHLRl3e16EWIOEaMU00/vAY9na/gsYVH/NdgYe+8w9bMBeSQYsSWXjICcFvL2ga+dhlFwcJ10rjio/ZklprgbSWiavTWvzdd/5hXt5W/OtATC201sq9u4eQ+PVijmSW0nf+YQYtSmTQosR2gUYsTmXQokT6zj9saeRCpmkJ0hxD2gOZeGgsI+Lu45+ps7FXlFmDmDDtSd/5h+k7/zCpZQpa9cwOQciyIR+77LyzFhXlMyZmFOP2jLP8orVWRsTdR2ppHFtSa+k6ZZM1WHvSdcomwyxySceayO4OWTY88TdirygzUkWf18eL2//RQiutYcwYE/Q4tagDOUQ8uo6uUzbRZ3qMJV2nbCLi0XU8tSbrolNXzu6OfOyylgEN4NOkaO5acw/j9ozr0ET37h5imehIZimPL91rAfSZHsOQBfuISS7E7vaTETeX0MmrOoQInbwK+dhlNKWsahni0zPSuGvNPW1M1BrI1NrOwt0WkCn2ijJSS+MYt2ccuQk3oxd36RCi8URPY+HLT1VbgGiSzPsx71laCddMe2Yygf6ZOtuScXvG0XfJn/n8YL+LQnjibyQ34WZ8Xl/bfKSoKL+FVi4EYwKZcu/uIQzaPoExMaPQcrq1ADFX33AI1+6u1OV9HVI6ShU/TYqm75I/dwjTHtDEQ2MZt2ccg7ZPaGGScIDWEBlxc42UoSMQ00StYdoDCgcbtH0Cbx+8p40ZTIBwiFM7RmB3+y+exZvT2YRpDdR6ZoVrw1xRWwN44m/Euf06A6Ki7NLrmnDNmH7TEdSg7RP4/GA/yLK1GdwEKNzSk1M7RlDlqPl1JefOlG2MXTGmXaAxMaMsB/XE34h4tH+7ANlrB7T2iV8OAlDlqOH9mPcsIBPKlF3R16Ad7GwlxoVberYAKCrKv1ghfmkg5sPldLIzZVsLqLErxpC9doAlp3aMICNurlGyVpRdSAu/HqS1Q58rd1JUlI87P1UtKsrHXlGG3e1HCOoov+x2wiX3RxT+o49L1IgutXxVUCfDIxNfLraQDI+M3e3/NdCXbhohqBNfLrIsVzZqmoT6dmXG0SBLTrmJLxd/CVRLECXcDGFaSC1TmHE0yKg4B0P2uxiy38WoOAePHaptAfHYoVqG7HcxcGc5o+IcfFfgsbQUPoYoSa213BbE78oGucTSwpJTbobFFjNgbQHdvi6g8/Z6Om+vZ8h+VxsQE7T/97UMWFvA+Og0UvIryfDIZBQ4CeXvt8a5IAhAY/RImlJWUaHrPHaolhuXFXHN+8e58qNcbomq5P6t3xG973WePLzPgnnsUG0LiP7f1zJwZzk3LisyctfSOFxOJ4lfLzYToQubxu/KpmpWBFWzInguOokrP8ql7/zDRMxLpFfUabasHwlZNnITbmbgznI6b6+3Bu7/fa2lrW5fF9Ar6jQD1hYwLLaYx5fupdi+EiGok748koa4qa010xKkKWUV2UM7kd6vB7tH9yfpnUFkLzQiZOGWnmgHO9N4oie9ok5bA4YPbkqvqNNc8/5xIuYl8tSaLOLLRXambENXF+PxNJD0ziAanVHhYaEliH1lJD/1iqD0qSsIzu2M/N550TZ3QjvYmS3rR1qDtwdhgpgwnabGMj46zRjQsxJdXYw7P1X1pY0GuaRjkMKxPah5qxuV8y6nct7l1LzVDfdyo6miHexM+ou9mblwKfdv/Y77t37HNe8fbwMQDhIxL5FOU2PZklqLJjUYdU7wWxBuN+ricBAF0KQG6pcNovZpw0fCQao/MEBcu7tSOLYHjnu7EZzbmeDczqyfNokrP8ptMXi4XDnzAJ0n72TIgn1oUoMB4VlpgIjj24I0payi9KkrqHj+Ssth2wM5c38f8p68D2nbHKRtc3h86d42A/eZHsOVMw9Y0nXKJmxDvyS1NA70z8Gz0qh5hNvbzpr6ZYMofzyiBUwLkOVdjfR/eVcao0dSl/d1aHx0GhHzEi0TXDnzAJ2mxtJpaixdp2yypM/0GLrcs5D3Y94ztNDsK7qjuxmzDBBz2rYGqZoVQc1b3dr4yfppk+g8eWeLd91aAxGPrqPbyKV0G7mUiEfXMWdz+nmQ0Jsgn1AbT/SkMXrkeZC6vK9DpU9d0S5I5bzLqf6gq6UV7WBn5q9+zDJBuEQ8us4SE6LLPQvpcs9CjmSW4ndlo1XPNBxWLiE34WbSX+wNapEBEsrfT/njERSO7WGBmDA1b3Wj9KkrSO/Xg1WjBjJl/CT+8sQ8a0BT/eGDhwN0uWchXe94ia07YkE+oSLc3gxyQt2yfiSrRg0E+YRqgRSO7UHh2B4UT7ragqmcdznFk67mp14ROO7txpTxk7AN/bLFgN1GLsU29EvrejiACdG59xQjKgu3GzVP9UwIvcmCVwYb102NmBHVBDFNVDUrgjP39yF98E0E5xox5Dcj5lsDhwOYQObg4dK59xR2RV8D4njEo/0NIEd3dkVfgy9t9HkfMTWSO6pXG63kjupF8aSrqXj+SoJzO1M573KmjJ/Eb0bM5y9PzGPBK4Mp3GKUEFvWj+Q3I+a3AOjcewp/eWKesUQ0T1mz2att7oSU9+F5EE2SqXvpSbKHdrIGNmHCoapmRVgh33LezZ3QNncyloGDnVnwyuA2IFvWj0Q+dplREzu6Wy0r9/KubVvg9pWRpPfrwZn7+1haMSHCxdSM/J4RWWufjiC9Xw/m9PgtN9w0uo1JbrhpNI0njAXTrAIbT/TEvb4LjdEj2641vqQjpPfrQfrgm1qYKHxKlz51BbmjerFj4G2WtAYwtWDKglcGG2ZoXrldu43AWDUrAmnbnLaRVZMayHvyPn7qZThoa38pfeoKap+OIDi3M6tGDeSGm0a3GTT82g03jeaGm0bj3H4d8rHLrN0I93LDpDsG3kb68si2a425hfZTrwjSB9/UBiZcM+YM6ghoyvhJpL/Ym+yFhknc67tYQVF+z3gjc3r8Fuf32zpOFTMeHXpRGDNfMYF2j+7PqlEDWTVqIOkv9rZ8SNvcCff6LlTOu9yK1Okv9mZOj9+S8ehQNKmBDhs17vxU9adeES1gwoHKH49oFyhcwhfKynmXWzOu4vkryR7aieyhnQjl7+84QzNNJGzbxN7uV1gw7WmntYZaLw2mmNdrn44ge2gnztzfx9od7zBnDa9t0pdHtgsTDhRustaaCndwEyLj0aG481PVS9r3FSUJj6eBrConMZHvnodpntrh2gkHCgcLl/TBN7G3+xXGLMlIo0LXjU7ixeoaUZIQ3C7OlTtJya8kJvJddgy8DctvWgGFaylcHPd2Y2/3K5jT47esGjWQrTtiyapy4nI6jUrvUmpfUytFRfmkZ6SxdUcs66dNYsfA2ywNtQBrJeb/dgy8jZjId/kx4YgF4fP6Ln1L3uyhhWvnSGYpOw6lEBP5LuunTWLDAw+x4YGHrAi74YGHWD9tEuunTSIm8l227ohtAyBK0i8/pNDagTVJxuf1YXf7OVfuJKvKMF16RhrpGWkcySwlJb+SrCqn1awRgjqaJP9nO0b/Zxo1v+ahS0ZqKJ9QCX5rJMyhN42aRj6h/udB5BKjiAp+i64uNrJ2M0Vs3rUiy4aU92G42X49iCYZDZjUMoX4ctFIcILfGgVU6E0LwEyCxKP98aWNxpc2GvFof+RjlyHlfdjxWnOxh93tJya5kIWHnDx2qJbnopP4NCmaYvtKC0LL6WYkQps70RA3laaUVbjzU1V7RRn2ijK8BbkWUJsM7VIAog7k8MyuPKtD1AJA/9zQQpYN9/oubFk/kpkLl7J4a0KbtrdZa/vSRrfMWS8GcSSzlGd25TH5VIjptTpR9T5SS+OMsrHZD3RHd7SDnTm1YwSzY2KsTtL46DSei07iSGZpm/tKeR8a5gnf0+vI8zfE5zAstpjptTrvifBJeeZ5LTQDkGXDtbsr0fte59mjDmaWaUyv1ZlZpvH3XJlRcQ6Grj5OTHJhy/t7VhrpwMVAog7kMCrOwcs+nZWaccak2L7S0oLpC6d2jGDJiUyWN8E6FVZqsLwJ5ruwYO5O9jFoUSIb4nPOT+/gtxf3kZjkQobFFreAaHRGGZoQbm+hhWd25fHsUQevHilgbo7bAmoNM2S/i6Grj3Mks9Tolcgn1Hb39MzHuXInw9edZrJd4z3xPISuLrYgCrf0ZOuOWKLzVFLLFDIKmlfr5EJmHMxhfoWvDczkUyELxl5RduFUUZNkIvdm8+BpkZd9eocQPyYc6XDnocpRQ+TebObmuFmptdTK5FMhBqwt4K1vMi4cWTMKnIyKczDZrvFJeWaHEBdrbVc5aphxMIflTR1rJaPA2TFI1IEc7k72tZwdYRCLtyZc6h4MMcmF7WrlwRSRAWsLiNyb3T6Iz+vjmV15jIpztIHwxN/I7JgY4svFS47CHk9DG62Y5hm4s5zx0Wntb0CnlikMiy3m06ToFpFSO9iZnSnbeGZXHkcyS8kocF6SHMksZc7m9AuaJyW/si3IltRaZsfEGNM09KZVs2bEzWV5EyzLlXn1SEG7MuNgTruy5JS73dlzd7IvPMi1BIlJLmRnyjbLJFawar7ZHi5NdrSS9jRyd7KPXlGnzQDXyjSlcYY2mk1SuKUnS05kslI7f9M9/HKgdaoh74nn/cR02NV7M9t2A9A/t/qf2uZOvB/zHvNdxk3Mm0bV+36VzK8wxHTWVutPmEbkE6q1hjQ3/yefCvGeeB7k1SPGlLsUeeubDOtnezJnczpvfZPBuXJnGEjzAqSri9FyulG4pSf3b/3OCvErNQNmxsEczpU70ST5kuWXJc9yiZXemQ3du5N9TK/VedmnW1qZm+M+v3r+gpTS42nA42nA5XRa4vE0hFd8zSDBb63cInvtAAYtSuTuZB+T7ZoFYy7tz+zK6+igQZtHRoGTyL3ZLab4M7vyGB+dxpAF+1i8NaEliLmWyNndsa+MZPi60/T/vpaJhTKT7ZqllZWaoZW3vsnA42m4IMS5cifPRScxN8fNeyK87NOZXqszsdDITa55/3i4dgVb0OPUTG2IR/vjzk9Vt6Qau5R3J/uYWCi3MJEJM2dzOkcyS80Q3WKrPia50IIIX2cmnwrxYIpIr6jTPBed1Mo0apFgpv0NcVMR3C5ESWLO5nS6fV3Ag6fFdmHmV/iYcTCHyL3ZRB3IsSRybzbP7MpjfoWvXYj+39cyZME+c7aEgTQ36smy0RA31dostrv9DF193IIJ9xcTxgSam+O2xAQwg9fMMo2JhTIPnjYgBi1KbC+RPq8REyR8iT9X7rRgWptpvssYLBwqHGB6rc7fc2ULYsh+F4MWJbLjUErH09c8ytcaxNTMCxtyGLC2oIUDT6/VO5TJdkMLJsTAneUMWpTYNotvE0eaj3rKxy6zun2t69mdKdt4fOley4lN35ls11pIOIC51D8XnWQu9xcGUQCteibyscuM5n31TKNqD5fm1H9DfA7PRScxdPVxhsUWMyy22Dq4MGS/i2GxxQxfd9oC2HEopb1WVcdtCU2Sqcv7OmTWpGbRLOV9SCh/P0GPUwvPvDIKnMQkFxK5N5s5m9N5LjqJ56KTeOubDFbvzSQlv7LN1P5FxzZ8Xp918v8SWk5WsWStLbr0a5oLHRdY/+GjPP8vtq7+0yCiJOHz+hDcLlxOJ2bzxeV0Irhdlk/9x0B8Xh9VjhoEt6s5rZTaFU1qQHC7qHLU/PpZ05EGqhw1uJxO0CVESSIlv5KoAznM2ZxufTJgzuZ0og7kkJJfaR1mcjmdVDlqflkc6ahSs1eUWdMzJrmQQYsSrYMJNy4raiHmYQWzD2IC2SvKLpa/dAzi8/qsc6cZBU6GLNjHlTMPcEtUJVMSdd45qRGdp7KxDOvDPu+c1JhxNMgtUZVcOfMAQxbss0K7vaLsQqbq+GCtCbEhPodOU2O58qNcZhwNsrMK4t0Xlp1VMONokCs/yqXT1FgrE7sATPvbJK0hblxWxDsnNWugvc7zcqFry3JlbomqbANzSdskpk9kFDjpOmWTpQnzne6sMgbbWWWYY8kpN0tOuYnOU1v8z9TcOyc1blxWRNcpmwwz6dLFjxr7vD5rY+eO13YSMS+Rh/co1iAby4wBluXKLDnl5rsCD1lVxk7FdwUelpxysyxXbvHcjWUwYb9CxLxE7nhtp7X10spELUHMMiHqQA6dJ+9k8KYaJh1u6ZRLTrnZklrb+hS3lURtSa1lySm39fyNZTAlUWfwpho6T95p1rqtS5LzICapJsmWNkbEBpiSqLMs1/gY3DsntfAuT4tDlkrYtci92bxzUmNjmaG9KYk6I2IDbbTStsBqjhma1EBKfiVdp2xiwNoCHt6jMOmwxjsnNev46KWUkaIksfCQk2W5Mu+c1Jh0WGPCfoUBawvoOmWT1d4Miy3nQczIuXpvJp2mxjJ4Uw0T9hsg09KM6fhcdBIxyYWXJM9FJzHjaJBpaTDpsAEzeFMNnabGGhVec+RtA1LlqAFd4vGley0Q8wZTEnWmpWGdWX3sUC3PHnW0K+b/n0qoZ1oaTEszfCQc5PGle0GXwv0k7PxI87S9EMjMMo35rvMdILPDbErrzlA4iOmw4SBh0/iXgUxLg8mnQvw9V2Zmmdau/D1XtpoxpiYe3qPw8B6FW6IqreOCvwpkWhqMinMwaFEi46PTfrFMXG38HLr6OHe8ttPykXZNYzrr4q0JdJoay4C1BS2cdfCmGuZsTrd6Hv/T5ozZJ7no9L1xWZE1fU0bD193unXx3GESFZNcyIb4nDazaUN8Dh6PkTy1O307CmgT9itM2K9YWnkuOumi26wTV6dZR43NXOXKj3LpPHknEY+us0DaDWiWnwCr92bSdcomBm+q4eE9ShsThTXh2jRn5mxOZ/CmmjYzZkRsgE5TY40Q33bhu/iiF66VcJjh604TuTfbUnnk3myGrzttQZgzZtJhzQrvfabHWGNccNELnz2tfSUcJjxADVhbwIC1BdYsMyOp+fyH9yhWGnAks/TS0gDTV4qK8q2NxU5TY7klqrIFTDhQ6+gZ/hwzdoSbpKgo/9LPj5hnR8yUwEwVw810MRkRG7BSRXPpLyrKv/RUsT2YI5mlLZLnEbEBK1q2lhGxASt5vuO1nZY5ioryL5TJX7icENwuioryjV1rr4+oAzkMWbDvouXEkAX7iDqQg8/rQ5MaLgZxaQWWJslWSWkWWBkFzl9UYP2PvgjFPNrj8/osM/2YcIQfE46QnpFmfL7K7SLocWpBj1Mz6+D0jLQWzzPb3b/6aI8SVnCbvXTTVOZxno6kqCjfKlPNUH4pIP9XPGz/N319UFnrf2iKLGi6LmggqCBoIOi6JuiqIqCrgqIrgqyrgoYu6JpiiK4LKgigCpquCCEdQdVVAU0VdP2iMGW29tplmtbcQNQ1QEXXNDQdQGsWHZBbvdQsKkTQfaiaBJrc/PyLPpQ2zqqbL9U10GV0TUbTZUCyQAoaJPaVinx5RmbVKZnVWRpf56r8WKlQFww2Q4bf8VdMXwsEtfkdGb97xSAb8yRG7df4zYYQ3deEsK2WsK1UsK1U6LIqxJWfKQzcEODVw0GS7KbG1F8Pout6C7WuL5Dpv1PBtlLEFgWXfyHTY61Ery91rvkiwLWfB7h6jcxV/5LoskLF9gl0+tjLI7FesuuxzKnrHeqneQdL143Bjacj6wqg4ZFUph8JYvusCdsXIldvhGvXi/T+SuS6dQrXrZO4fp3Ib76UuH5NiD6fi1z/mcgNnwa5epWMbbHG1StEvsoSjbeoq2i60h6MYNN1XTAhNF1vdlBoVFSG7/Nh+1Ti2o1Brl8v03uDyDVfN3DDVz5u+FKh15cKvdbp9FoHvT5X6PW5wjVr4LrPda6NkugTJdL1EwXbIpkVx5sdGaXZ8S9gGgNIJ6ipPHgghO3TED23h+ixTafXZpmb1ofos0ml+9dw1VcaV3wapMvKIF1WSVz+qULPzxV6faZw9Wc613yq0Xt1iN9Ehei+WMG2QObz03JHDtxsGk07P2XRmZ/hx7ZG5rqtMjdubqTHFonrNov8doPMZRvA9pmPqz8X+MNWhb/tkrg/VuGWaJXLPmmk85Imen6m0+sz6BMlcsNqP9etVujysU63jwIcrwy1N6UFm6Zrgma4KKBxrE7lyq999PnaT58dcMNWjV5bFa7d6sP2lcj/+szP6/FNHK2SqQtpSKqIKItUN2psyJH52yYXtkV+uq9UuP5fMj1XqVy9WuWGFSE6LQgxbHMQv6kVXW92B12wKZouSEjGNNMVJvwgYdugcGOsym+2q/TZqnD9dh3bVz5u3h4guVJtnpJa808zkJlBMMS7SQG6vB/gimUKvVdK9Fmu0nu5zLXLZGzvaWzLDhggmoysqwYIKoKqG+rKqVO5douP62JUfvutxg2xCn1iZTpv0rgpRuF0XQAIgRJElSUURUWWZWRZRpFlgrIKeIEg7yaC7X2FXkslei+XDVkmY1sQ4pFNDaA3hwcdNF0XbGjNZwNQWXZaxrZV5XexMjftFLnpW4ne34rYNvjZUywBQUJqEEkMoEk6oqIgySqipCCKEt6Qis8fRNEaAB+TtijYInV6Lwtx7VKRPstkIj5S6PGBRGFtwFCgApquCDYFTQANXZeZkiARsVPnlu9kfhcr0/cbiYivA4w94DM0oet4VQVJUQiJGiFRIiTKBEMSAX+QhoBIvU/C1SQCfpIKGrl8kZerFitcu0Tkuk9ErlsiYXtDYuMpYyobE0gVbIouC6DiDsgMiwtx406Z/rs0+u6WGPCNSI8tIZbnSoCCEvITkBRkWSMUkAgEJbz+EE2+IA3eAPUNjTR6fNTWSni9PuoFN/d8KtBpkcg1n3jp82GQ3h/6sc33seAHb/P6pYOmCTY0VQCNEkHhrgMhfrdL5k/fafT/XqT/boU+sRI/2r0AhESFYFDCF1TwBSWa/CE8TQHcjQFcDX6cdQGq63w43PWU1AoEmup4emMjtvl+enzop/d7Aa57N4Btvo/Z37jCHBzBpuqaAHDOHWDo/iD99in8+XuZO/er/H6fxsB/h0irDgGqoYGAhOAL0eALUd/oo87TRK2nCUddI3anQKXTTUl1DUVVNXga6nh2mwvb6066L3Bz3btOekU2YXtd5MVNDmuVVtEFm6brAmiUu4OMPODnjv0idx+UGHpQ4q6DEnf928+h0iCg0egN0OgXqW8MUCd4cXm81LgbqHIJlDs9lFd5KK90U1hWQ3GlgLOqlrs/rsQ2q45rFjq57q0yukc6sL3iYc62akBDR0fRNcGmq5oAQYSAyuQEibsPhnjgkMYD8T4ePOTnv/ZrfJrtBTWE4A3ibvRTJ3hx1jdRXddApbOeMoebEruL3Ao3p8vqOVVSR1JuDZkFtbywvgDb0zl0eqmanm+Wct2bFdhmlvP2Po/hH6qIrmiCTdNUAVVElTVeyfTz10My435UGHNE5JGfJIYf1ZiV4kFo8uILBKirD+LwBHC43Dhq6ymurqfAUU9ORS05RSU0NHmQVRW/JCMqOho6354U6DEri04z8+nxWim2fxSx8ZgLEAlJCqoiCzZZUwVZVECDjUVNDD8s8sRRlSmJOs8mwbPHZJ466iO2yI8aDNJU56a8tpGqaicOZx2FVfWcLa8lq7CMBn8IHfAGZQKSik/SQAoBOjEZtdiezqTTS/l0fzmPrFIBNB9CUCcoSYJN0TTBKymgS5TXBXn8pwCTj8lMT1WZmarx+nGR2Rk680+GOFleh9/bgMtZR3V1HYWVLvJKajiTV0pVjRsV8IVEgrLaLApeERSCAAx5/xS2+48zZvlZAmKIQFMTHq+PppAi2DRdFQIyyKIfRImoMz6ePO7lpUyJl08r/PN0iMjTEh9kS6zNEUgp92GvaaDAXstZh4DLG0JoChAMyviDMn5Jxi/K+EISIVnFr0h4JWPZ33a8mNteSCI6vhpZbMDhaqChyYfHHxRsmhYURBECoRDoMvkukVfTFN7IlHk7W+aDXIlVOSHW5ob4qhi2F4v8WNLIiSov5wLgkVVERSUYMqa2LyTjF1UCkkpQ1vGLImJAxCsai2SdKFJQ6aG0ooqK+gBuVxOCTxBsuq4IkqQSFCVCkgyqzg8lXt5J9/H+WViVJ7G+KMSOEoVdJSp77DJxdRrH3Rq5goLDJyMERRqCIt6QbPiHqBAQFSRJJSCrhGSZJklDUs/nIefsNRRXe3DWefE0NjUf21BURFEiGDRWVH9I5Nu8Rt7Pk/lXocbWIpFvKzT2VSr8YJdIcEqk1Svke2TsPhV3SMYTEmkISngDCr6QTFBSCUkqQUnFL2kEJUNLflFF1aGuyUepow6HuxG34DdyVkVRkCQFUVLxBWR0ScEfFPmuuIG1hTIxpSr/rpA46FBIqJHJdGmcqVPJa1Co9MrUBiTcQQlPQKYhoNAUUvCJCn5JJSApBCTZEr8oEVJU/IpKiaOOmnov9Q1+QyOqqiErGqKiIYk6/mAATQ4QalRItPvZU+EnvkrmxxqJRJdIVp1KTr1GQaNChVei2idTE9BwBRTqAzKeoEyjKNMkKvglhaCkNAMZogAeX4DS6npcDQE8jYHmM0aajqLqyLJOSNbwSTJev0woEKCxyU9OdZCEkgAJ1UGSBYWsBo3cRihq0qj0KVT5ZBwBjdqQRn1IRhBVGiWVRlklqOiIikZQ1hAV4ytjJE2n0ummqt6LU/AjNAYEm64jaBqoqo6iaEiKhiirBESVhkAQr9eH0ChSUu3nVGkdGY4mUmt8ZLoC5DWoFDUplHpVKnw6VT6ZWn+IuqCEJ6TQEFINzUgSflXFJ8nUe304XALVdQ3UNwaob/TT5A0ZILoO4TCyrBKSZHxBGcEfxNPgpdETwO32U+ZoIKesnrPlHrLtbn6urCfPXk+B3U2R3cO5qgbOVTVQUilwrkKgtEqguLKe4sp6yhwNlNg9VLkEhKYgjd4QTX6RYFA+X2Dpuo6maaiqiqqqKIqGKKn4QwrekERjIIC70YenMUBjk0S9EKK23our3ovb48Xj8SI0BfD4ROq9IdyNQeoa/Lg8AZxuPzV1PuobRASfguAN0egP4Q1KBEMykqwKNkAxMnpDNM1oSxhQGrKiI6oqTapIkyTiDYUIiDLBkEwoICOGjHghKxqKqqCoEooqEVJFgkqIkBIiKIsEpBB+MYA/FMAXkgiICiHRmK2KoilWo6bZRIKu61bjRdd1QdEQVBVBkzRBlVRBFhVBVTRBUXRBknVB1hAUECQQNF0XUHVB13RB0XRBVDRBUjRBUTVBUlRBlBRBlGQhJGuCJOuCouiCpuqCqqpl/7Eemqor5HnS2Ja/hPezpvCP1PuYlfo3vvo5EnfA0baH9qs+CKZpBIIh7DUuyuw1lNprqHDU4mnwoqoamq5xyn2YVTkv8cKJO3n+TH+eTB7Ao/H9eSr+TnbmrfyfgdiddZzKKaK0yklhuYN6oWVfvabay+6Tu3gzaSJPpPZm9E9XMmnvH1n60wKSanZypuEg35WuZlrCMLb9vPSXgzicdWTkFLX7vya5Dq/spk62s8v1AW+cu53ns29kSd6z/Fi9mZ/L8tpqVFfZeHYxBe7MSwdJy85v8Xd1oJwDFRtZlTeTD88+wcKsMSzMGsv8rL8wNbMnc7LuJN6xg6AcsF6TW1xBkzfQct9P8pDrSkfT1QuDKKrKz8UV1t+V3kKi89/m1YyhvHlyMPOz/ouFZ4fwYe59fJAzjLfO3s66wuep8p7jbF0iUTkzOe76/rzZ6jxUVteGtch06gL2C4PIikJFtcv6e3/ZeuamDOHNU//NivwxfFY8jnXlE/iyYiKflz/Eh4WD2Gv/CL/YQIJjI2+dvJvXTt7FtJS+LPt5OvVBY383KEoUlFaGzSz5wqb5ubC0WSsyG3PfZUbKnXzw8wOsKX6EdWUT+NI+nq8cY1nrGMnikjuJd0Xhld1sr3iTt37+IyuLHmZN0WMszxnPzLSBvJnxMMWNPxv7vUITLrdw8VlzMswnNud+xD+O3cGy3LF8ce5R1pZN4IuKsXzlGM0X1SP4uPJ2jgpraJAcfFb+CJHnbuOz8pF8UT6OL0om8nnRJFblPcrLaXfxxolROHzGd2idq7xIHBEavTQFQwAcLNvMP5Lu5JOcsawpmsRnJROIKnuYtVWjWVP9Vz6q7McRz0pUTSa2Zh6LSgeytOJPfGa/j3UVY1lTMoFPz01kdcEjLM95hNmp/8UHmU+j6MYnlrJyz3UMknHW0IbDW8rLyfexIGs4nxU8zqqi8Xx07gGiKkfyheN+ltnvJEFYGdYOFWlUqjniWcGK8iFElQ1jTek4Pi2awOqCR1iZ9wgfnx3Hs4l9+aHc+BqH2voGRFFqC+JpaEKSjOR2Y84iZqX8majcx1ieN57Xc+/hvXPD+aziAZaX30VGY0yH0/1s00E+KR7KquL7+ezceFbnT2BFzkSW5Uzg7VP38UbKQ3hCdc1aKWoLktHsG06/nbnJ9/H+6VGsyJnIC9l38kreMNaUPsKSkkHsdy26aABMcK3lw4L/5l9FY1mdP56lOeP55Ox4Psh+mOeT7+BAyUZj17O8qiWIKMkUlNoBOFQaw4zkQSw+M5bZp+7in7mPsKnkFVade4DPSsfTJNVeFCSk+lhbPIVl+Q+wMnccS8+OY/GZsXxwZjTTj9/OkqwXACi3O/H5A+dBKhy1lFQac33t2bf5R/KdvJnxFxadnkSyYzuf5j3BssIR/Kt4DBvLp/NF2dOsqXiSNRVPsKbyCeNnxZN8XjaFz4ufJrr4Bf5V8Agr8h5iWc5YPs4ey4enR/P+6YeYnfZn3kh9CAUfqgz2Gtd5kLOFpZTYjUMHH516jmlJA3jjxHCO2XexteBtFpwZyqqC0awo+huLCv7Eu4W38V7x73mvtD/vl/Xl/bJ+vFfye94tuo2F+X/g3dw/szT/b6zIHcMnZ0fz0ZmHWXT6ISKzRvJq5mBeSh5MSeNZyzyyrBggWTlFlNsNssiMKYz9oQe7i/9FmmM/r6bezZKfx7Is5yGW5f+NFYUjWHXuflaXDmN12V+JKhtGVNkwVpX9lZXFw1lRNILl+Q/ySc6DfHRmFIuyRhF5ciRvZ/6NNzPvZ3baIJ5N+AM/1xsfXcg9V47XH2wLMidpFE/9eAcVQg7Lsp7j9fShfHTmIT4+M4rIrKG8ljGAeSf78eaZfszP7sc/z/bln9n9mH+mH29m9eO1jP7MPfF7ZibfxvSE3zP1UD+eiruVxw/cxIT9fRj+764Mje3M6bqjAOQVl+MPhgyQvHPllFQapnkhfgRf5y7haNV3PJvwe945+QDvnnyAf2bcQ0zR22S7fySzbj+Z7n2cdO/jZP1eTtbvI9O9j8y6fWS49pHm3Edq9T6OV+0luXIPRyt2k1C+i/jybzhYupUfSrfjV40wX1zhQNN0A8RR66bEbjjr5p+Xc9IRz9snJvJ88h94O/N+3s64j1dS7mJLXuT/v0e/vT6qa93nnVXXdXLOlRtJi6qSWLmL8Yd682rGvcxLG8qbJ4byRuoQXj56L+UNuRcdoDHk5kDJNvaXbuZA2Rb2l21hX9nX7C3byNaCKJKr4pqnbw3+QLBlQDttxn4dPsh4hseP3sjcjP/m5dRBvJYymNdTBjMtvh8rT865KMja0wsZvqsr4/f3ZNyBnjx88CpGxV3BiAM2bt5iY8PPKwz/KKlsG1lDooTgCRJAYPKR/jyb2pcZaQOZdfyPzDn+J145/l/MSfojU364lW05yzuE2F30FU/80JcZSQN5+fifmH38Tmam3MGM1Dt4LOE6pv90DyHFCGLZ+SXtL3pn88rJCR5hbPy1TEq6jqnJv2XGsduZdfwPzD52By8n/5FZSX9g8sGbeDflGU7VHMUTqKMhVM/Z2hMsSZ/JY3G38I/E25l77I/MOv4HZhy/nRkptzE1+Rbu+beNhMrvjLEKSi+cj0T+8AaPZfTi2eQ/8Gj89fz96C3MSB7AjOTfMzPpNmYn3c7MowN4/IdrmXKoPy8l3MtLP/2Fpw7fxiMHr+HFxH7MTrqNmUm/56XkAbyY3I/pyb/jr/tsRJ542hqnOGydaRdkxv6J/DXBxvflX/Fd0Rru2W3jmYTrmZnUnxlJ/ZhxtB+zjg5g1tH+vJBwM1Pjr+fZ+Ot5PuFmZiX2Y9ZR43kvJfXlpeR+PJ90M3/da2Nm4gME5MZ2c5F2QV5OeYA/7rZxrOYgANE/f8S933ViTFxXZiX1ZfbRvsxK7MusxFuZnXgrs8JkZuKtzEi8lZlHf8espL48Gd+Lu3fbeDVpLA1BY+kvc7T7ZTktQUQlyLQjg/nzv20cyo+zrsdX7OKR/bcybLeNp368hpd+uok5ib9lbuKtzfI75ib+jtmJv2PGT7fwfMJveOj7zty/O4JPs+YjKsYUdTc04Wloav/YRusLz/04lAeTIsgsPENewfnc0is1EH32Qx47MICH913F+O//F+O/t/H4wW7877gIHtnfhXHfd2Hs91cyZl9v3k19lgLPaev15TV1NDR6Oz4/0vrC26ceYVhcL45X/GB4d2Eljf7Q+cJI9pHqiGPVqVeZd+wRZicOZ0bCvbyS9DAfpD3PnnNfUuO3ny9NVI2T+eVI8oVPGrUB2ZsfzX1HehJTtMK6FgyJZOYW0+gXf1EIz8wro9LhvKTn2lrugkMoFOS5n/7C0APXYK8tb3GepMrh5HB8Cmknz5JbXEpBSQVlFbVU2N0UlVWRW1RK1s95/JCQzMkzPyPLMpqm4ff7CQQChEIhJElCURQ0TcPsVOm6fn6tCT+oUOkq4bGE27n/qzv4KeMIwVCQQCBAbV0ttXW1VFRWkJ19lrS0DJKSj5F4NInk5OOcPHmK/Px8amtrcbvd1NTU4HQ6cbvdNDU1WTCyLKOqaguYDmvfgNzE4bIYdpWv4UT5EezuMkQl9B877PT/DQC7cLwx8LR3hQAAAABJRU5ErkJggg==) no-repeat;padding-left:40px} |
| | | .browser .browser-firefox{background-position:0 -34px} |
| | | .browser .browser-ie{background-position:0 -68px;margin-left:0px} |
| | | .browser .browser-360{background-position:0 -170px;margin-left: -27px} |
| | | </style> |
| | | </head> |
| | | <body style="margin-top:50px"> |
| | | <h1>请å级æ¨çæµè§å¨ï¼ä»¥ä¾¿æä»¬æ´å¥½çä¸ºæ¨æä¾æå¡ï¼</h1> |
| | | <p>æ¨æ£å¨ä½¿ç¨ Internet Explorer çæ©æçæ¬ï¼IE11以ä¸çæ¬æä½¿ç¨è¯¥å
æ ¸çæµè§å¨ï¼ãè¿æå³çå¨å级æµè§å¨åï¼æ¨å°æ æ³è®¿é®æ¤ç½ç«ã</p> |
| | | <hr> |
| | | <h2>请注æï¼å¾®è½¯å
¬å¸å¯¹Windows XP å Internet Explorer æ©æçæ¬çæ¯æå·²ç»ç»æ</h2> |
| | | <p>èª 2016 å¹´ 1 æ 12 æ¥èµ·ï¼Microsoft ä¸å为 IE 11 以ä¸çæ¬æä¾ç¸åºæ¯æåæ´æ°ã没æå
³é®çæµè§å¨å®å
¨æ´æ°ï¼æ¨ççµèå¯è½æåæå®³ç
æ¯ãé´è°è½¯ä»¶åå
¶ä»æ¶æè½¯ä»¶çæ»å»ï¼å®ä»¬å¯ä»¥çªåææå®³æ¨çä¸å¡æ°æ®åä¿¡æ¯ã请åé
<a href="https://www.microsoft.com/zh-cn/WindowsForBusiness/End-of-IE-support">微软对 Internet Explorer æ©æçæ¬çæ¯æå°äº 2016 å¹´ 1 æ 12 æ¥ç»æç说æ</a> ã</p> |
| | | <hr> |
| | | <h2>æ¨å¯ä»¥éæ©æ´å
è¿çæµè§å¨</h2> |
| | | <p>æ¨è使ç¨ä»¥ä¸æµè§å¨çææ°çæ¬ã妿æ¨ççµèå·²æä»¥ä¸æµè§å¨çææ°çæ¬åç´æ¥ä½¿ç¨è¯¥æµè§å¨è®¿é®å³å¯ã</p> |
| | | <ul class="browser"> |
| | | <li class="browser-chrome"><a href="https://www.google.cn/chrome/browser/desktop/index.html?hl=zh-CN&standalone=1"> è°·ææµè§å¨<span>Google Chrome</span></a></li> |
| | | <li class="browser-firefox"><a href="https://www.mozilla.org/zh-CN/firefox/new/"> ç«çæµè§å¨<span>Mozilla Firefox</span></a></li> |
| | | <li class="browser-ie"><a href="https://windows.microsoft.com/zh-cn/internet-explorer/download-ie"> IE 11 æµè§å¨<span>Internet Explorer</span></a></li> |
| | | <li class="browser-360"><a href="http://se.360.cn/"> 360å®å
¨æµè§å¨<span>360 Chrome</span></a></li> |
| | | <div class="clean"></div> |
| | | </ul> |
| | | <hr> |
| | | </body> |
| | | </html> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <!DOCTYPE html> |
| | | <html> |
| | | |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
| | | <meta name="renderer" content="webkit"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> |
| | | <link rel="icon" href="/favicon.ico"> |
| | | <title>è¥ä¾ç®¡çç³»ç»</title> |
| | | <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]--> |
| | | <style> |
| | | html, |
| | | body, |
| | | #app { |
| | | height: 100%; |
| | | margin: 0px; |
| | | padding: 0px; |
| | | } |
| | | |
| | | .chromeframe { |
| | | margin: 0.2em 0; |
| | | background: #ccc; |
| | | color: #000; |
| | | padding: 0.2em 0; |
| | | } |
| | | |
| | | #loader-wrapper { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | z-index: 999999; |
| | | } |
| | | |
| | | #loader { |
| | | display: block; |
| | | position: relative; |
| | | left: 50%; |
| | | top: 50%; |
| | | width: 150px; |
| | | height: 150px; |
| | | margin: -75px 0 0 -75px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -webkit-animation: spin 2s linear infinite; |
| | | -ms-animation: spin 2s linear infinite; |
| | | -moz-animation: spin 2s linear infinite; |
| | | -o-animation: spin 2s linear infinite; |
| | | animation: spin 2s linear infinite; |
| | | z-index: 1001; |
| | | } |
| | | |
| | | #loader:before { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 5px; |
| | | left: 5px; |
| | | right: 5px; |
| | | bottom: 5px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -webkit-animation: spin 3s linear infinite; |
| | | -moz-animation: spin 3s linear infinite; |
| | | -o-animation: spin 3s linear infinite; |
| | | -ms-animation: spin 3s linear infinite; |
| | | animation: spin 3s linear infinite; |
| | | } |
| | | |
| | | #loader:after { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 15px; |
| | | left: 15px; |
| | | right: 15px; |
| | | bottom: 15px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -moz-animation: spin 1.5s linear infinite; |
| | | -o-animation: spin 1.5s linear infinite; |
| | | -ms-animation: spin 1.5s linear infinite; |
| | | -webkit-animation: spin 1.5s linear infinite; |
| | | animation: spin 1.5s linear infinite; |
| | | } |
| | | |
| | | |
| | | @-webkit-keyframes spin { |
| | | 0% { |
| | | -webkit-transform: rotate(0deg); |
| | | -ms-transform: rotate(0deg); |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | 100% { |
| | | -webkit-transform: rotate(360deg); |
| | | -ms-transform: rotate(360deg); |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | @keyframes spin { |
| | | 0% { |
| | | -webkit-transform: rotate(0deg); |
| | | -ms-transform: rotate(0deg); |
| | | transform: rotate(0deg); |
| | | } |
| | | |
| | | 100% { |
| | | -webkit-transform: rotate(360deg); |
| | | -ms-transform: rotate(360deg); |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | |
| | | #loader-wrapper .loader-section { |
| | | position: fixed; |
| | | top: 0; |
| | | width: 51%; |
| | | height: 100%; |
| | | background: #7171C6; |
| | | z-index: 1000; |
| | | -webkit-transform: translateX(0); |
| | | -ms-transform: translateX(0); |
| | | transform: translateX(0); |
| | | } |
| | | |
| | | #loader-wrapper .loader-section.section-left { |
| | | left: 0; |
| | | } |
| | | |
| | | #loader-wrapper .loader-section.section-right { |
| | | right: 0; |
| | | } |
| | | |
| | | |
| | | .loaded #loader-wrapper .loader-section.section-left { |
| | | -webkit-transform: translateX(-100%); |
| | | -ms-transform: translateX(-100%); |
| | | transform: translateX(-100%); |
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | } |
| | | |
| | | .loaded #loader-wrapper .loader-section.section-right { |
| | | -webkit-transform: translateX(100%); |
| | | -ms-transform: translateX(100%); |
| | | transform: translateX(100%); |
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | } |
| | | |
| | | .loaded #loader { |
| | | opacity: 0; |
| | | -webkit-transition: all 0.3s ease-out; |
| | | transition: all 0.3s ease-out; |
| | | } |
| | | |
| | | .loaded #loader-wrapper { |
| | | visibility: hidden; |
| | | -webkit-transform: translateY(-100%); |
| | | -ms-transform: translateY(-100%); |
| | | transform: translateY(-100%); |
| | | -webkit-transition: all 0.3s 1s ease-out; |
| | | transition: all 0.3s 1s ease-out; |
| | | } |
| | | |
| | | .no-js #loader-wrapper { |
| | | display: none; |
| | | } |
| | | |
| | | .no-js h1 { |
| | | color: #222222; |
| | | } |
| | | |
| | | #loader-wrapper .load_title { |
| | | font-family: 'Open Sans'; |
| | | color: #FFF; |
| | | font-size: 19px; |
| | | width: 100%; |
| | | text-align: center; |
| | | z-index: 9999999999999; |
| | | position: absolute; |
| | | top: 60%; |
| | | opacity: 1; |
| | | line-height: 30px; |
| | | } |
| | | |
| | | #loader-wrapper .load_title span { |
| | | font-weight: normal; |
| | | font-style: italic; |
| | | font-size: 13px; |
| | | color: #FFF; |
| | | opacity: 0.5; |
| | | } |
| | | </style> |
| | | </head> |
| | | |
| | | <body> |
| | | <div id="app"> |
| | | <div id="loader-wrapper"> |
| | | <div id="loader"></div> |
| | | <div class="loader-section section-left"></div> |
| | | <div class="loader-section section-right"></div> |
| | | <div class="load_title">æ£å¨å 载系ç»èµæºï¼è¯·èå¿çå¾
</div> |
| | | </div> |
| | | </div> |
| | | <script type="module" src="/src/main.js"></script> |
| | | </body> |
| | | |
| | | </html> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "name": "ruoyi", |
| | | "version": "3.8.9", |
| | | "description": "è¥ä¾ç®¡çç³»ç»", |
| | | "author": "è¥ä¾", |
| | | "license": "MIT", |
| | | "type": "module", |
| | | "scripts": { |
| | | "dev": "vite", |
| | | "build:prod": "vite build", |
| | | "build:stage": "vite build --mode staging", |
| | | "preview": "vite preview" |
| | | }, |
| | | "repository": { |
| | | "type": "git", |
| | | "url": "https://gitee.com/y_project/RuoYi-Vue.git" |
| | | }, |
| | | "dependencies": { |
| | | "@element-plus/icons-vue": "2.3.1", |
| | | "@vueup/vue-quill": "1.2.0", |
| | | "@vueuse/core": "10.11.0", |
| | | "axios": "0.28.1", |
| | | "clipboard": "2.0.11", |
| | | "echarts": "5.5.1", |
| | | "element-plus": "2.7.6", |
| | | "file-saver": "2.0.5", |
| | | "fuse.js": "6.6.2", |
| | | "js-beautify": "1.14.11", |
| | | "js-cookie": "3.0.5", |
| | | "jsencrypt": "3.3.2", |
| | | "nprogress": "0.2.0", |
| | | "pinia": "2.1.7", |
| | | "splitpanes": "3.1.5", |
| | | "vue": "3.4.31", |
| | | "vue-cropper": "1.1.1", |
| | | "vue-router": "4.4.0", |
| | | "vuedraggable": "4.1.0" |
| | | }, |
| | | "devDependencies": { |
| | | "@vitejs/plugin-vue": "5.0.5", |
| | | "sass": "1.77.5", |
| | | "unplugin-auto-import": "0.17.6", |
| | | "unplugin-vue-setup-extend-plus": "1.0.1", |
| | | "vite": "5.3.2", |
| | | "vite-plugin-compression": "0.5.1", |
| | | "vite-plugin-svg-icons": "2.0.1" |
| | | }, |
| | | "overrides": { |
| | | "quill": "2.0.2" |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <router-view /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | import { handleThemeStyle } from '@/utils/theme' |
| | | |
| | | onMounted(() => { |
| | | nextTick(() => { |
| | | // åå§å䏻颿 ·å¼ |
| | | handleThemeStyle(useSettingsStore().theme) |
| | | }) |
| | | }) |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // ç»å½æ¹æ³ |
| | | export function login(username, password, code, uuid) { |
| | | const data = { |
| | | username, |
| | | password, |
| | | code, |
| | | uuid |
| | | } |
| | | return request({ |
| | | url: '/login', |
| | | headers: { |
| | | isToken: false, |
| | | repeatSubmit: false |
| | | }, |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // æ³¨åæ¹æ³ |
| | | export function register(data) { |
| | | return request({ |
| | | url: '/register', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // è·åç¨æ·è¯¦ç»ä¿¡æ¯ |
| | | export function getInfo() { |
| | | return request({ |
| | | url: '/getInfo', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // éåºæ¹æ³ |
| | | export function logout() { |
| | | return request({ |
| | | url: '/logout', |
| | | method: 'post' |
| | | }) |
| | | } |
| | | |
| | | // è·åéªè¯ç |
| | | export function getCodeImg() { |
| | | return request({ |
| | | url: '/captchaImage', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'get', |
| | | timeout: 20000 |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // è·åè·¯ç± |
| | | export const getRouters = () => { |
| | | return request({ |
| | | url: '/getRouters', |
| | | method: 'get' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢ç¼åè¯¦ç» |
| | | export function getCache() { |
| | | return request({ |
| | | url: '/monitor/cache', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢ç¼ååç§°å表 |
| | | export function listCacheName() { |
| | | return request({ |
| | | url: '/monitor/cache/getNames', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢ç¼åé®åå表 |
| | | export function listCacheKey(cacheName) { |
| | | return request({ |
| | | url: '/monitor/cache/getKeys/' + cacheName, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢ç¼åå
容 |
| | | export function getCacheValue(cacheName, cacheKey) { |
| | | return request({ |
| | | url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ¸
çæå®åç§°ç¼å |
| | | export function clearCacheName(cacheName) { |
| | | return request({ |
| | | url: '/monitor/cache/clearCacheName/' + cacheName, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // æ¸
çæå®é®åç¼å |
| | | export function clearCacheKey(cacheKey) { |
| | | return request({ |
| | | url: '/monitor/cache/clearCacheKey/' + cacheKey, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // æ¸
çå
¨é¨ç¼å |
| | | export function clearCacheAll() { |
| | | return request({ |
| | | url: '/monitor/cache/clearCacheAll', |
| | | method: 'delete' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢å®æ¶ä»»å¡è°åº¦å表 |
| | | export function listJob(query) { |
| | | return request({ |
| | | url: '/monitor/job/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢å®æ¶ä»»å¡è°åº¦è¯¦ç» |
| | | export function getJob(jobId) { |
| | | return request({ |
| | | url: '/monitor/job/' + jobId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢å®æ¶ä»»å¡è°åº¦ |
| | | export function addJob(data) { |
| | | return request({ |
| | | url: '/monitor/job', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹å®æ¶ä»»å¡è°åº¦ |
| | | export function updateJob(data) { |
| | | return request({ |
| | | url: '/monitor/job', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤å®æ¶ä»»å¡è°åº¦ |
| | | export function delJob(jobId) { |
| | | return request({ |
| | | url: '/monitor/job/' + jobId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // ä»»å¡ç¶æä¿®æ¹ |
| | | export function changeJobStatus(jobId, status) { |
| | | const data = { |
| | | jobId, |
| | | status |
| | | } |
| | | return request({ |
| | | url: '/monitor/job/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | |
| | | // 宿¶ä»»å¡ç«å³æ§è¡ä¸æ¬¡ |
| | | export function runJob(jobId, jobGroup) { |
| | | const data = { |
| | | jobId, |
| | | jobGroup |
| | | } |
| | | return request({ |
| | | url: '/monitor/job/run', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢è°åº¦æ¥å¿å表 |
| | | export function listJobLog(query) { |
| | | return request({ |
| | | url: '/monitor/jobLog/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // å é¤è°åº¦æ¥å¿ |
| | | export function delJobLog(jobLogId) { |
| | | return request({ |
| | | url: '/monitor/jobLog/' + jobLogId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // æ¸
空è°åº¦æ¥å¿ |
| | | export function cleanJobLog() { |
| | | return request({ |
| | | url: '/monitor/jobLog/clean', |
| | | method: 'delete' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢ç»å½æ¥å¿å表 |
| | | export function list(query) { |
| | | return request({ |
| | | url: '/monitor/logininfor/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // å é¤ç»å½æ¥å¿ |
| | | export function delLogininfor(infoId) { |
| | | return request({ |
| | | url: '/monitor/logininfor/' + infoId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // è§£éç¨æ·ç»å½ç¶æ |
| | | export function unlockLogininfor(userName) { |
| | | return request({ |
| | | url: '/monitor/logininfor/unlock/' + userName, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ¸
空ç»å½æ¥å¿ |
| | | export function cleanLogininfor() { |
| | | return request({ |
| | | url: '/monitor/logininfor/clean', |
| | | method: 'delete' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢å¨çº¿ç¨æ·å表 |
| | | export function list(query) { |
| | | return request({ |
| | | url: '/monitor/online/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 强éç¨æ· |
| | | export function forceLogout(tokenId) { |
| | | return request({ |
| | | url: '/monitor/online/' + tokenId, |
| | | method: 'delete' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢æä½æ¥å¿å表 |
| | | export function list(query) { |
| | | return request({ |
| | | url: '/monitor/operlog/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // å 餿使¥å¿ |
| | | export function delOperlog(operId) { |
| | | return request({ |
| | | url: '/monitor/operlog/' + operId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // æ¸
空æä½æ¥å¿ |
| | | export function cleanOperlog() { |
| | | return request({ |
| | | url: '/monitor/operlog/clean', |
| | | method: 'delete' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // è·åæå¡ä¿¡æ¯ |
| | | export function getServer() { |
| | | return request({ |
| | | url: '/monitor/server', |
| | | method: 'get' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢åæ°å表 |
| | | export function listConfig(query) { |
| | | return request({ |
| | | url: '/system/config/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢åæ°è¯¦ç» |
| | | export function getConfig(configId) { |
| | | return request({ |
| | | url: '/system/config/' + configId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ ¹æ®åæ°é®åæ¥è¯¢åæ°å¼ |
| | | export function getConfigKey(configKey) { |
| | | return request({ |
| | | url: '/system/config/configKey/' + configKey, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢åæ°é
ç½® |
| | | export function addConfig(data) { |
| | | return request({ |
| | | url: '/system/config', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹åæ°é
ç½® |
| | | export function updateConfig(data) { |
| | | return request({ |
| | | url: '/system/config', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤åæ°é
ç½® |
| | | export function delConfig(configId) { |
| | | return request({ |
| | | url: '/system/config/' + configId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // å·æ°åæ°ç¼å |
| | | export function refreshCache() { |
| | | return request({ |
| | | url: '/system/config/refreshCache', |
| | | method: 'delete' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢é¨é¨å表 |
| | | export function listDept(query) { |
| | | return request({ |
| | | url: '/system/dept/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢é¨é¨åè¡¨ï¼æé¤èç¹ï¼ |
| | | export function listDeptExcludeChild(deptId) { |
| | | return request({ |
| | | url: '/system/dept/list/exclude/' + deptId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢é¨é¨è¯¦ç» |
| | | export function getDept(deptId) { |
| | | return request({ |
| | | url: '/system/dept/' + deptId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢é¨é¨ |
| | | export function addDept(data) { |
| | | return request({ |
| | | url: '/system/dept', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹é¨é¨ |
| | | export function updateDept(data) { |
| | | return request({ |
| | | url: '/system/dept', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤é¨é¨ |
| | | export function delDept(deptId) { |
| | | return request({ |
| | | url: '/system/dept/' + deptId, |
| | | method: 'delete' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢åå
¸æ°æ®å表 |
| | | export function listData(query) { |
| | | return request({ |
| | | url: '/system/dict/data/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢åå
¸æ°æ®è¯¦ç» |
| | | export function getData(dictCode) { |
| | | return request({ |
| | | url: '/system/dict/data/' + dictCode, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ ¹æ®åå
¸ç±»åæ¥è¯¢åå
¸æ°æ®ä¿¡æ¯ |
| | | export function getDicts(dictType) { |
| | | return request({ |
| | | url: '/system/dict/data/type/' + dictType, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢åå
¸æ°æ® |
| | | export function addData(data) { |
| | | return request({ |
| | | url: '/system/dict/data', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹åå
¸æ°æ® |
| | | export function updateData(data) { |
| | | return request({ |
| | | url: '/system/dict/data', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤åå
¸æ°æ® |
| | | export function delData(dictCode) { |
| | | return request({ |
| | | url: '/system/dict/data/' + dictCode, |
| | | method: 'delete' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢åå
¸ç±»åå表 |
| | | export function listType(query) { |
| | | return request({ |
| | | url: '/system/dict/type/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢åå
¸ç±»åè¯¦ç» |
| | | export function getType(dictId) { |
| | | return request({ |
| | | url: '/system/dict/type/' + dictId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢åå
¸ç±»å |
| | | export function addType(data) { |
| | | return request({ |
| | | url: '/system/dict/type', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹åå
¸ç±»å |
| | | export function updateType(data) { |
| | | return request({ |
| | | url: '/system/dict/type', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤åå
¸ç±»å |
| | | export function delType(dictId) { |
| | | return request({ |
| | | url: '/system/dict/type/' + dictId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // å·æ°åå
¸ç¼å |
| | | export function refreshCache() { |
| | | return request({ |
| | | url: '/system/dict/type/refreshCache', |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // è·ååå
¸éæ©æ¡å表 |
| | | export function optionselect() { |
| | | return request({ |
| | | url: '/system/dict/type/optionselect', |
| | | method: 'get' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢èåå表 |
| | | export function listMenu(query) { |
| | | return request({ |
| | | url: '/system/menu/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢èåè¯¦ç» |
| | | export function getMenu(menuId) { |
| | | return request({ |
| | | url: '/system/menu/' + menuId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢èå䏿æ ç»æ |
| | | export function treeselect() { |
| | | return request({ |
| | | url: '/system/menu/treeselect', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ ¹æ®è§è²IDæ¥è¯¢èå䏿æ ç»æ |
| | | export function roleMenuTreeselect(roleId) { |
| | | return request({ |
| | | url: '/system/menu/roleMenuTreeselect/' + roleId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢èå |
| | | export function addMenu(data) { |
| | | return request({ |
| | | url: '/system/menu', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹èå |
| | | export function updateMenu(data) { |
| | | return request({ |
| | | url: '/system/menu', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤èå |
| | | export function delMenu(menuId) { |
| | | return request({ |
| | | url: '/system/menu/' + menuId, |
| | | method: 'delete' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢å
¬åå表 |
| | | export function listNotice(query) { |
| | | return request({ |
| | | url: '/system/notice/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢å
¬åè¯¦ç» |
| | | export function getNotice(noticeId) { |
| | | return request({ |
| | | url: '/system/notice/' + noticeId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢å
Œ |
| | | export function addNotice(data) { |
| | | return request({ |
| | | url: '/system/notice', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹å
Œ |
| | | export function updateNotice(data) { |
| | | return request({ |
| | | url: '/system/notice', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤å
Œ |
| | | export function delNotice(noticeId) { |
| | | return request({ |
| | | url: '/system/notice/' + noticeId, |
| | | method: 'delete' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢å²ä½å表 |
| | | export function listPost(query) { |
| | | return request({ |
| | | url: '/system/post/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢å²ä½è¯¦ç» |
| | | export function getPost(postId) { |
| | | return request({ |
| | | url: '/system/post/' + postId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢å²ä½ |
| | | export function addPost(data) { |
| | | return request({ |
| | | url: '/system/post', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹å²ä½ |
| | | export function updatePost(data) { |
| | | return request({ |
| | | url: '/system/post', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤å²ä½ |
| | | export function delPost(postId) { |
| | | return request({ |
| | | url: '/system/post/' + postId, |
| | | method: 'delete' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢è§è²å表 |
| | | export function listRole(query) { |
| | | return request({ |
| | | url: '/system/role/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢è§è²è¯¦ç» |
| | | export function getRole(roleId) { |
| | | return request({ |
| | | url: '/system/role/' + roleId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢è§è² |
| | | export function addRole(data) { |
| | | return request({ |
| | | url: '/system/role', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹è§è² |
| | | export function updateRole(data) { |
| | | return request({ |
| | | url: '/system/role', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // è§è²æ°æ®æé |
| | | export function dataScope(data) { |
| | | return request({ |
| | | url: '/system/role/dataScope', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // è§è²ç¶æä¿®æ¹ |
| | | export function changeRoleStatus(roleId, status) { |
| | | const data = { |
| | | roleId, |
| | | status |
| | | } |
| | | return request({ |
| | | url: '/system/role/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤è§è² |
| | | export function delRole(roleId) { |
| | | return request({ |
| | | url: '/system/role/' + roleId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢è§è²å·²ææç¨æ·å表 |
| | | export function allocatedUserList(query) { |
| | | return request({ |
| | | url: '/system/role/authUser/allocatedList', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢è§è²æªææç¨æ·å表 |
| | | export function unallocatedUserList(query) { |
| | | return request({ |
| | | url: '/system/role/authUser/unallocatedList', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // åæ¶ç¨æ·ææè§è² |
| | | export function authUserCancel(data) { |
| | | return request({ |
| | | url: '/system/role/authUser/cancel', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // æ¹éåæ¶ç¨æ·ææè§è² |
| | | export function authUserCancelAll(data) { |
| | | return request({ |
| | | url: '/system/role/authUser/cancelAll', |
| | | method: 'put', |
| | | params: data |
| | | }) |
| | | } |
| | | |
| | | // ææç¨æ·éæ© |
| | | export function authUserSelectAll(data) { |
| | | return request({ |
| | | url: '/system/role/authUser/selectAll', |
| | | method: 'put', |
| | | params: data |
| | | }) |
| | | } |
| | | |
| | | // æ ¹æ®è§è²IDæ¥è¯¢é¨é¨æ ç»æ |
| | | export function deptTreeSelect(roleId) { |
| | | return request({ |
| | | url: '/system/role/deptTree/' + roleId, |
| | | method: 'get' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | import { parseStrEmpty } from "@/utils/ruoyi"; |
| | | |
| | | // æ¥è¯¢ç¨æ·å表 |
| | | export function listUser(query) { |
| | | return request({ |
| | | url: '/system/user/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢ç¨æ·è¯¦ç» |
| | | export function getUser(userId) { |
| | | return request({ |
| | | url: '/system/user/' + parseStrEmpty(userId), |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // æ°å¢ç¨æ· |
| | | export function addUser(data) { |
| | | return request({ |
| | | url: '/system/user', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹ç¨æ· |
| | | export function updateUser(data) { |
| | | return request({ |
| | | url: '/system/user', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // å é¤ç¨æ· |
| | | export function delUser(userId) { |
| | | return request({ |
| | | url: '/system/user/' + userId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // ç¨æ·å¯ç éç½® |
| | | export function resetUserPwd(userId, password) { |
| | | const data = { |
| | | userId, |
| | | password |
| | | } |
| | | return request({ |
| | | url: '/system/user/resetPwd', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ç¨æ·ç¶æä¿®æ¹ |
| | | export function changeUserStatus(userId, status) { |
| | | const data = { |
| | | userId, |
| | | status |
| | | } |
| | | return request({ |
| | | url: '/system/user/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢ç¨æ·ä¸ªäººä¿¡æ¯ |
| | | export function getUserProfile() { |
| | | return request({ |
| | | url: '/system/user/profile', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹ç¨æ·ä¸ªäººä¿¡æ¯ |
| | | export function updateUserProfile(data) { |
| | | return request({ |
| | | url: '/system/user/profile', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ç¨æ·å¯ç éç½® |
| | | export function updateUserPwd(oldPassword, newPassword) { |
| | | const data = { |
| | | oldPassword, |
| | | newPassword |
| | | } |
| | | return request({ |
| | | url: '/system/user/profile/updatePwd', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // ç¨æ·å¤´åä¸ä¼ |
| | | export function uploadAvatar(data) { |
| | | return request({ |
| | | url: '/system/user/profile/avatar', |
| | | method: 'post', |
| | | headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢ææè§è² |
| | | export function getAuthRole(userId) { |
| | | return request({ |
| | | url: '/system/user/authRole/' + userId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ä¿åææè§è² |
| | | export function updateAuthRole(data) { |
| | | return request({ |
| | | url: '/system/user/authRole', |
| | | method: 'put', |
| | | params: data |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢é¨é¨ä¸ææ ç»æ |
| | | export function deptTreeSelect() { |
| | | return request({ |
| | | url: '/system/user/deptTree', |
| | | method: 'get' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // æ¥è¯¢çæè¡¨æ°æ® |
| | | export function listTable(query) { |
| | | return request({ |
| | | url: '/tool/gen/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | // æ¥è¯¢dbæ°æ®åºå表 |
| | | export function listDbTable(query) { |
| | | return request({ |
| | | url: '/tool/gen/db/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // æ¥è¯¢è¡¨è¯¦ç»ä¿¡æ¯ |
| | | export function getGenTable(tableId) { |
| | | return request({ |
| | | url: '/tool/gen/' + tableId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // ä¿®æ¹ä»£ç çæä¿¡æ¯ |
| | | export function updateGenTable(data) { |
| | | return request({ |
| | | url: '/tool/gen', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 导å
¥è¡¨ |
| | | export function importTable(data) { |
| | | return request({ |
| | | url: '/tool/gen/importTable', |
| | | method: 'post', |
| | | params: data |
| | | }) |
| | | } |
| | | |
| | | // å建表 |
| | | export function createTable(data) { |
| | | return request({ |
| | | url: '/tool/gen/createTable', |
| | | method: 'post', |
| | | params: data |
| | | }) |
| | | } |
| | | |
| | | // é¢è§çæä»£ç |
| | | export function previewTable(tableId) { |
| | | return request({ |
| | | url: '/tool/gen/preview/' + tableId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // å é¤è¡¨æ°æ® |
| | | export function delTable(tableId) { |
| | | return request({ |
| | | url: '/tool/gen/' + tableId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // çæä»£ç ï¼èªå®ä¹è·¯å¾ï¼ |
| | | export function genCode(tableName) { |
| | | return request({ |
| | | url: '/tool/gen/genCode/' + tableName, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // åæ¥æ°æ®åº |
| | | export function synchDb(tableName) { |
| | | return request({ |
| | | url: '/tool/gen/synchDb/' + tableName, |
| | | method: 'get' |
| | | }) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M121.718 73.272v9.953c3.957-7.584 6.199-16.05 6.199-24.995C127.917 26.079 99.273 0 63.958 0 28.644 0 0 26.079 0 58.23c0 .403.028.806.028 1.21l22.97-25.953h13.34l-19.76 27.187h6.42V53.77l13.728-19.477v49.361H22.998V73.272H2.158c5.951 20.284 23.608 36.208 45.998 41.399-1.44 3.3-5.618 11.263-12.565 12.674-8.607 1.764 23.358.428 46.163-13.178 17.519-4.611 31.938-15.849 39.77-30.513h-13.506V73.272H85.02V59.464l22.998-25.977h13.008l-19.429 27.187h6.421v-7.433l13.727-19.402v39.433h-.027zm-78.24 2.822a10.516 10.516 0 0 1-.996-4.535V44.548c0-1.613.332-3.124.996-4.535a11.66 11.66 0 0 1 2.713-3.68c1.134-1.032 2.49-1.864 4.04-2.468 1.55-.605 3.21-.908 4.982-.908h11.292c1.77 0 3.431.303 4.981.908 1.522.604 2.85 1.41 3.986 2.418l-12.26 16.303v-2.898a1.96 1.96 0 0 0-.665-1.512c-.443-.403-.996-.604-1.66-.604-.665 0-1.218.201-1.661.604a1.96 1.96 0 0 0-.664 1.512v9.071L44.364 77.606a10.556 10.556 0 0 1-.886-1.512zm35.73-4.535c0 1.613-.332 3.124-.997 4.535a11.66 11.66 0 0 1-2.712 3.68c-1.134 1.032-2.49 1.864-4.04 2.469-1.55.604-3.21.907-4.982.907H55.185c-1.77 0-3.431-.303-4.981-.907-1.55-.605-2.906-1.437-4.041-2.47a12.49 12.49 0 0 1-1.384-1.512l13.727-18.217v6.375c0 .605.222 1.109.665 1.512.442.403.996.604 1.66.604.664 0 1.218-.201 1.66-.604a1.96 1.96 0 0 0 .665-1.512V53.87L75.97 36.838c.913.932 1.66 1.99 2.214 3.175.664 1.41.996 2.922.996 4.535v27.011h.028z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M127.88 73.143c0 1.412-.506 2.635-1.518 3.669-1.011 1.033-2.209 1.55-3.592 1.55h-17.887c0 9.296-1.783 17.178-5.35 23.645l16.609 17.044c1.011 1.034 1.517 2.257 1.517 3.67 0 1.412-.506 2.635-1.517 3.668-.958 1.033-2.155 1.55-3.593 1.55-1.438 0-2.635-.517-3.593-1.55l-15.811-16.063a15.49 15.49 0 0 1-1.196 1.06c-.532.434-1.65 1.208-3.353 2.322a50.104 50.104 0 0 1-5.192 2.974c-1.758.87-3.94 1.658-6.546 2.364-2.607.706-5.189 1.06-7.748 1.06V47.044H58.89v73.062c-2.716 0-5.417-.367-8.106-1.102-2.688-.734-5.003-1.631-6.945-2.692a66.769 66.769 0 0 1-5.268-3.179c-1.571-1.057-2.73-1.94-3.476-2.65L33.9 109.34l-14.611 16.877c-1.066 1.14-2.344 1.711-3.833 1.711-1.277 0-2.422-.434-3.434-1.304-1.012-.978-1.557-2.187-1.635-3.627-.079-1.44.333-2.705 1.236-3.794l16.129-18.51c-3.087-6.197-4.63-13.644-4.63-22.342H5.235c-1.383 0-2.58-.517-3.592-1.55S.125 74.545.125 73.132c0-1.412.506-2.635 1.518-3.668 1.012-1.034 2.21-1.55 3.592-1.55h17.887V43.939L9.308 29.833c-1.012-1.033-1.517-2.256-1.517-3.669 0-1.412.505-2.635 1.517-3.668 1.012-1.034 2.21-1.55 3.593-1.55s2.58.516 3.593 1.55l13.813 14.106h67.396l13.814-14.106c1.012-1.034 2.21-1.55 3.592-1.55 1.384 0 2.581.516 3.593 1.55 1.012 1.033 1.518 2.256 1.518 3.668 0 1.413-.506 2.636-1.518 3.67l-13.814 14.105v23.975h17.887c1.383 0 2.58.516 3.593 1.55 1.011 1.033 1.517 2.256 1.517 3.668l-.005.01zM89.552 26.175H38.448c0-7.23 2.489-13.386 7.466-18.469C50.892 2.623 56.92.082 64 .082c7.08 0 13.108 2.541 18.086 7.624 4.977 5.083 7.466 11.24 7.466 18.469z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1568899741379" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2054" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M960 591.424V368.96c0-0.288 0.16-0.512 0.16-0.768S960 367.68 960 367.424V192a32 32 0 0 0-32-32H96a32 32 0 0 0-32 32v175.424c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768v222.464c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768V864a32 32 0 0 0 32 32h832a32 32 0 0 0 32-32v-271.04c0-0.288 0.16-0.512 0.16-0.768S960 591.68 960 591.424z m-560-31.232v-160H608v160h-208z m208 64V832h-208v-207.808H608z m-480-224h208v160H128v-160z m544 0h224v160h-224v-160zM896 224v112.192H128V224h768zM128 624.192h208V832H128v-207.808zM672 832v-207.808h224V832h-224z" p-id="2055"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1588670460195" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1314" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M230.4 307.712c13.824 0 25.088-11.264 25.088-25.088 0-100.352 81.92-182.272 182.272-182.272s182.272 81.408 182.272 182.272c0 13.824 11.264 25.088 25.088 25.088s25.088-11.264 24.576-25.088c0-127.488-103.936-231.936-231.936-231.936S205.824 154.624 205.824 282.624c-0.512 14.336 10.752 25.088 24.576 25.088z m564.736 234.496c-11.264 0-21.504 2.048-31.232 6.144 0-44.544-40.448-81.92-88.064-81.92-14.848 0-28.16 3.584-39.936 10.24-13.824-28.16-44.544-48.128-78.848-48.128-12.288 0-24.576 2.56-35.328 7.68V284.16c0-45.568-37.888-81.92-84.48-81.92s-84.48 36.864-84.48 81.92v348.672l-69.12-112.64c-18.432-28.16-58.368-36.864-91.136-19.968-26.624 14.336-46.592 47.104-30.208 88.064 3.072 8.192 76.8 205.312 171.52 311.296 0 0 28.16 24.576 43.008 58.88 4.096 9.728 13.312 15.36 22.528 15.36 3.072 0 6.656-0.512 9.728-2.048 12.288-5.12 18.432-19.968 12.8-32.256-19.456-44.544-53.76-74.752-53.76-74.752C281.6 768 209.408 573.44 208.384 570.88c-5.12-12.8-2.56-20.992 7.168-26.112 9.216-4.608 21.504-4.608 26.112 2.56l113.152 184.32c4.096 8.704 12.8 14.336 22.528 14.336 13.824 0 25.088-10.752 25.088-25.088V284.16c0-17.92 15.36-32.256 34.816-32.256s34.816 14.336 34.816 32.256v284.16c0 13.824 10.24 25.088 24.576 25.088 13.824 0 25.088-11.264 25.088-25.088v-57.344c0-17.92 15.36-32.768 34.816-32.768 19.968 0 37.376 15.36 37.376 32.768v95.232c0 7.168 3.072 13.312 7.68 17.92 4.608 4.608 10.752 7.168 17.92 7.168 13.824 0 24.576-11.264 24.576-25.088V547.84c0-18.432 13.824-32.256 32.256-32.256 20.48 0 38.912 15.36 38.912 32.256v95.232c0 13.824 11.264 25.088 25.088 25.088s24.576-11.264 25.088-25.088v-18.944c0-18.944 12.8-32.256 30.72-32.256 18.432 0 22.528 18.944 22.528 31.744 0 1.024-11.776 99.84-50.688 173.056-30.72 58.368-45.056 112.128-51.2 146.944-2.56 13.312 6.656 26.112 19.968 28.672 1.536 0 3.072 0.512 4.608 0.512 11.776 0 22.016-8.192 24.064-20.48 5.632-31.232 18.432-79.36 46.08-132.608 43.52-81.92 55.808-186.88 56.32-193.536-0.512-50.688-29.696-83.968-72.704-83.968z"></path></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1576153230908" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="971" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M772.87036133 734.06115723c-43.34106445 0-80.00793458 27.93273926-93.76831055 66.57714843H475.90991211c-56.60705567 0-102.66723633-46.06018067-102.66723633-102.66723633V600.82446289h305.859375c13.76037598 38.64440918 50.42724609 66.57714844 93.76831055 66.57714844 55.12390137 0 99.94812012-44.82421875 99.94812012-99.94812012S827.9942627 467.50537109 772.87036133 467.50537109c-43.34106445 0-80.00793458 27.93273926-93.76831055 66.57714844H373.24267578V401.01062011h321.92687989c55.12390137 0 99.94812012-44.82421875 99.94812011-99.94812011V190.07312011C795.11767578 134.94921875 750.29345703 90.125 695.16955567 90.125H251.12963867C196.0057373 90.125 151.18151855 134.94921875 151.18151855 190.07312011V301.0625c0 55.12390137 44.82421875 99.94812012 99.94812012 99.94812012h55.53588867v296.96044921c0 93.35632325 75.97045898 169.32678223 169.32678224 169.32678223h203.19213866c13.76037598 38.64440918 50.42724609 66.57714844 93.76831055 66.57714844 55.12390137 0 99.94812012-44.82421875 99.94812012-99.94812012s-44.90661622-99.86572266-100.03051758-99.86572265z m0-199.89624024c18.37463379 0 33.28857422 14.91394043 33.28857422 33.28857423s-14.91394043 33.28857422-33.28857422 33.28857421-33.28857422-14.91394043-33.28857422-33.28857421 14.91394043-33.28857422 33.28857422-33.28857422zM217.75866699 301.0625V190.07312011c0-18.37463379 14.91394043-33.28857422 33.28857423-33.28857421h444.03991698c18.37463379 0 33.28857422 14.91394043 33.28857422 33.28857422V301.0625c0 18.37463379-14.91394043 33.28857422-33.28857422 33.28857422H251.12963867c-18.37463379 0-33.37097168-14.91394043-33.37097168-33.28857422z m555.11169434 566.23535156c-18.37463379 0-33.28857422-14.91394043-33.28857422-33.28857422 0-18.37463379 14.91394043-33.28857422 33.28857422-33.28857422s33.28857422 14.91394043 33.28857422 33.28857422c0.08239747 18.29223633-14.91394043 33.28857422-33.28857422 33.28857422z" p-id="972"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h36.571V128H0V54.857zM91.429 27.43H128V128H91.429V27.429zM45.714 0h36.572v128H45.714V0z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575982282951" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="902" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M828.40625 90.125H195.59375C137.375 90.125 90.125 137.375 90.125 195.59375v632.8125c0 58.21875 47.25 105.46875 105.46875 105.46875h632.8125c58.21875 0 105.46875-47.25 105.46875-105.46875V195.59375c0-58.21875-47.25-105.46875-105.46875-105.46875z m52.734375 738.28125c0 29.16-23.57015625 52.734375-52.734375 52.734375H195.59375c-29.109375 0-52.734375-23.574375-52.734375-52.734375V195.59375c0-29.109375 23.625-52.734375 52.734375-52.734375h632.8125c29.16 0 52.734375 23.625 52.734375 52.734375v632.8125z" p-id="903"></path><path d="M421.52890625 709.55984375a36.28125 36.28125 0 0 1-27.55265625-12.66890625L205.17453125 476.613125a36.28546875 36.28546875 0 0 1 55.10109375-47.22890625l164.986875 192.4846875 342.16171875-298.48078125a36.2896875 36.2896875 0 0 1 47.70984375 54.68765625L445.3859375 700.6203125a36.3234375 36.3234375 0 0 1-23.85703125 8.93953125z" p-id="904"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.857 118.857h64V73.143H89.143c-1.902 0-3.52-.668-4.855-2.002-1.335-1.335-2.002-2.954-2.002-4.855V36.57H54.857v82.286zM73.143 16v-4.571a2.2 2.2 0 0 0-.677-1.61 2.198 2.198 0 0 0-1.609-.676H20.571c-.621 0-1.158.225-1.609.676a2.198 2.198 0 0 0-.676 1.61V16a2.2 2.2 0 0 0 .676 1.61c.451.45.988.676 1.61.676h50.285c.622 0 1.158-.226 1.61-.677.45-.45.676-.987.676-1.609zm18.286 48h21.357L91.43 42.642V64zM128 73.143v48c0 1.902-.667 3.52-2.002 4.855-1.335 1.335-2.953 2.002-4.855 2.002H52.57c-1.901 0-3.52-.667-4.854-2.002-1.335-1.335-2.003-2.953-2.003-4.855v-11.429H6.857c-1.902 0-3.52-.667-4.855-2.002C.667 106.377 0 104.759 0 102.857v-96c0-1.902.667-3.52 2.002-4.855C3.337.667 4.955 0 6.857 0h77.714c1.902 0 3.52.667 4.855 2.002 1.335 1.335 2.003 2.953 2.003 4.855V30.29c1 .622 1.856 1.29 2.569 2.003l29.147 29.147c1.335 1.335 2.478 3.145 3.429 5.43.95 2.287 1.426 4.383 1.426 6.291v-.018z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1546567861908" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2422" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M318.577778 819.2L17.066667 512l301.511111-307.2 45.511111 45.511111L96.711111 512l267.377778 261.688889zM705.422222 819.2l-45.511111-45.511111L927.288889 512l-267.377778-261.688889 45.511111-45.511111L1006.933333 512zM540.785778 221.866667l55.751111 11.150222L483.157333 802.133333l-55.751111-11.093333z" p-id="2423"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577252187056" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2508" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M747.59340925 691.12859384c11.51396329 0.25305413 22.43746719-0.21087818 40.74171707-1.51832482 29.35428085-2.10878421 35.84933734-2.36183835 46.47761114-0.8856895 24.71495444 3.37405491 41.12129828 21.76265671 32.47528161 47.95376084-85.57447632 258.19957947-442.00123984 249.76444099-628.67084683 50.73735554-153.47733892-159.33976008-153.09775772-414.41833795 0.92786545-573.42069196 159.71934128-162.67163983 424.03439521-166.59397897 565.78689185 0.63263534 80.38686649 94.81095318 108.34934958 169.16669549 89.11723508 230.57450162-15.01454608 47.99593598-50.61082928 77.68762207-119.77896259 114.63352789-4.89237973 2.65706845-29.35428085 15.52065436-35.84933652 19.02123633-46.94154346 25.30541465-63.51659033 41.20565021-62.20914449 58.45550757 2.95229856 39.13904114 24.16667102 52.7196135 70.98168823 53.81618115z m44.41100207 50.10472101c-19.82257471 1.43397372-32.05352527 1.940082-45.63409763 1.6448519-70.34905207-1.60267593-115.98314969-30.91478165-121.38163769-101.64341492-3.45840683-46.05585397 24.7571304-73.13264758 89.24376132-107.96976837 6.7902866-3.66928501 31.37871396-16.57504688 36.06021551-19.06341229 57.69634516-30.83042972 85.15271997-53.73183005 94.76877722-84.47790866 12.77923398-40.78389304-9.10994898-98.94417051-79.24812286-181.6507002-121.17075953-142.97559219-350.14258521-139.60153647-489.2380134 2.06660824-134.49827774 138.84237405-134.79350784 362.12048163-0.42175717 501.637667 158.53842169 168.99799328 451.9968783 181.18676788 534.57688175-11.80919339-4.68150156 0.2952301-10.71262573 0.67481131-18.72600705 1.26527069z" p-id="2509"></path><path d="M346.03865637 637.18588562a78.82636652 78.82636652 0 0 0 78.32025825-79.29029883c0-43.69401562-35.005823-79.29029883-78.32025825-79.29029882a78.82636652 78.82636652 0 0 0-78.36243338 79.29029882c0 43.69401562 35.005823 79.29029883 78.36243338 79.29029883z m0-51.7495729a27.07679361 27.07679361 0 0 1-26.5706845-27.54072593c0-15.30977536 11.97789643-27.54072593 26.5706845-27.54072592 14.55061295 0 26.57068533 12.23095057 26.57068533 27.54072592a27.07679361 27.07679361 0 0 1-26.57068533 27.54072593zM475.7289063 807.11174353a78.82636652 78.82636652 0 0 0 78.3624334-79.29029882c0-43.69401562-34.96364785-79.29029883-78.32025825-79.29029883a78.82636652 78.82636652 0 0 0-78.32025742 79.29029883c0 43.69401562 34.96364785 79.29029883 78.32025742 79.29029882z m0-51.74957208a27.07679361 27.07679361 0 0 1-26.57068532-27.54072674c0-15.30977536 12.06224753-27.54072593 26.57068532-27.54072593 14.59278892 0 26.57068533 12.23095057 26.57068453 27.54072593a27.07679361 27.07679361 0 0 1-26.57068453 27.54072674zM601.24376214 377.21492718a78.82636652 78.82636652 0 0 0 78.32025742-79.29029883c0-43.69401562-34.96364785-79.29029883-78.32025742-79.29029882a78.82636652 78.82636652 0 0 0-78.32025823 79.29029883c0 43.69401562 34.96364785 79.29029883 78.32025824 79.29029883z m1e-8-51.74957208a27.07679361 27.07679361 0 0 1-26.57068534-27.54072675c0-15.30977536 11.97789643-27.54072593 26.57068534-27.54072591 14.55061295 0 26.57068533 12.23095057 26.57068451 27.54072592a27.07679361 27.07679361 0 0 1-26.57068451 27.54072674zM378.80916809 433.85687983a78.82636652 78.82636652 0 0 0 78.32025824-79.29029883c0-43.69401562-34.96364785-79.29029883-78.32025824-79.29029802a78.82636652 78.82636652 0 0 0-78.32025742 79.29029802c0 43.69401562 34.96364785 79.29029883 78.32025742 79.29029883z m0-51.74957209a27.07679361 27.07679361 0 0 1-26.57068451-27.54072674c0-15.30977536 11.97789643-27.54072593 26.57068451-27.54072593 14.55061295 0 26.57068533 12.23095057 26.57068533 27.54072593a27.07679361 27.07679361 0 0 1-26.57068533 27.54072674z" p-id="2510"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575804206892" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3145" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M826.56 470.016c-32.896 0-64.384 12.288-89.984 35.52l0-104.96c0-62.208-50.496-112.832-112.64-113.088L623.936 287.04 519.552 287.104C541.824 262.72 554.56 230.72 554.56 197.12c0-73.536-59.904-133.44-133.504-133.44-73.472 0-133.376 59.904-133.376 133.44 0 32.896 12.224 64.256 35.52 89.984L175.232 287.104l0 0.576C113.728 288.704 64 338.88 64 400.576l0.32 0 0.32 116.48C60.864 544.896 70.592 577.728 100.8 588.48c12.736 4.608 37.632 7.488 60.864-25.28 12.992-18.368 34.24-29.248 56.64-29.248 38.336 0 69.504 31.104 69.504 69.312 0 38.4-31.168 69.504-69.504 69.504-22.656 0-44.032-11.264-57.344-30.4C138.688 610.112 112.576 615.36 102.464 619.136c-29.824 10.752-39.104 43.776-38.144 67.392l0 160.384L64 846.912C64 909.248 114.752 960 177.216 960l446.272 0c62.4 0 113.152-50.752 113.152-113.152l0-145.024c24.384 22.272 56.384 35.008 89.984 35.008 73.536 0 133.44-59.904 133.44-133.504C960 529.92 900.096 470.016 826.56 470.016zM826.56 672.896c-22.72 0-44.032-11.264-57.344-30.4-22.272-32.384-48.448-27.136-58.56-23.36-29.824 10.752-39.04 43.776-38.08 67.392l0 160.384c0 27.136-22.016 49.152-49.152 49.152L177.216 896.064C150.08 896 128 873.984 128 846.848l0.32 0 0-145.024c24.384 22.272 56.384 35.008 89.984 35.008 73.6 0 133.504-59.904 133.504-133.504 0-73.472-59.904-133.376-133.504-133.376-32.896 0-64.32 12.288-89.984 35.52l0-104.96L128 400.512c0-27.072 22.08-49.152 49.216-49.152L177.216 351.04 334.656 350.72c3.776 0.512 7.616 0.832 11.52 0.832 24.896 0 50.752-10.816 60.032-37.056 4.544-12.736 7.424-37.568-25.344-60.736C362.624 240.768 351.68 219.52 351.68 197.12c0-38.272 31.104-69.44 69.376-69.44 38.336 0 69.504 31.168 69.504 69.44 0 22.72-11.264 44.032-30.528 57.472C427.968 276.736 433.088 302.784 436.8 313.024c10.752 29.888 43.072 39.232 67.392 38.08l119.232 0 0 0.384c27.136 0 49.152 22.08 49.152 49.152l0.256 116.48c-3.776 27.84 6.016 60.736 36.224 71.488 12.736 4.608 37.632 7.488 60.8-25.28 13.056-18.368 34.24-29.248 56.704-29.248C864.832 534.016 896 565.12 896 603.392 896 641.728 864.832 672.896 826.56 672.896z" p-id="3146"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="100" xmlns="http://www.w3.org/2000/svg"><path d="M27.429 63.638c0-2.508-.893-4.65-2.679-6.424-1.786-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.465 2.662-1.785 1.774-2.678 3.916-2.678 6.424 0 2.508.893 4.65 2.678 6.424 1.786 1.775 3.94 2.662 6.465 2.662 2.524 0 4.678-.887 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm13.714-31.801c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM71.714 65.98l7.215-27.116c.285-1.23.107-2.378-.536-3.443-.643-1.064-1.56-1.762-2.75-2.094-1.19-.33-2.333-.177-3.429.462-1.095.639-1.81 1.573-2.143 2.804l-7.214 27.116c-2.857.237-5.405 1.266-7.643 3.088-2.238 1.822-3.738 4.152-4.5 6.992-.952 3.644-.476 7.098 1.429 10.364 1.905 3.265 4.69 5.37 8.357 6.317 3.667.947 7.143.474 10.429-1.42 3.285-1.892 5.404-4.66 6.357-8.305.762-2.84.619-5.607-.429-8.305-1.047-2.697-2.762-4.85-5.143-6.46zm47.143-2.342c0-2.508-.893-4.65-2.678-6.424-1.786-1.775-3.94-2.662-6.465-2.662-2.524 0-4.678.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.786 1.775 3.94 2.662 6.464 2.662 2.524 0 4.679-.887 6.465-2.662 1.785-1.775 2.678-3.916 2.678-6.424zm-45.714-45.43c0-2.509-.893-4.65-2.679-6.425C68.68 10.01 66.524 9.122 64 9.122c-2.524 0-4.679.887-6.464 2.661-1.786 1.775-2.679 3.916-2.679 6.425 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm32 13.629c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM128 63.638c0 12.351-3.357 23.78-10.071 34.286-.905 1.372-2.19 2.058-3.858 2.058H13.93c-1.667 0-2.953-.686-3.858-2.058C3.357 87.465 0 76.037 0 63.638c0-8.613 1.69-16.847 5.071-24.703C8.452 31.08 13 24.312 18.714 18.634c5.715-5.68 12.524-10.199 20.429-13.559C47.048 1.715 55.333.035 64 .035c8.667 0 16.952 1.68 24.857 5.04 7.905 3.36 14.714 7.88 20.429 13.559 5.714 5.678 10.262 12.446 13.643 20.301 3.38 7.856 5.071 16.09 5.071 24.703z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1579774833889" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1376" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M887.466667 192.853333h-100.693334V119.466667c0-10.24-6.826667-17.066667-17.066666-17.066667s-17.066667 6.826667-17.066667 17.066667v73.386666H303.786667V119.466667c0-10.24-6.826667-17.066667-17.066667-17.066667s-17.066667 6.826667-17.066667 17.066667v73.386666H168.96c-46.08 0-85.333333 37.546667-85.333333 85.333334V836.266667c0 46.08 37.546667 85.333333 85.333333 85.333333H887.466667c46.08 0 85.333333-37.546667 85.333333-85.333333V278.186667c0-47.786667-37.546667-85.333333-85.333333-85.333334z m-718.506667 34.133334h100.693333v66.56c0 10.24 6.826667 17.066667 17.066667 17.066666s17.066667-6.826667 17.066667-17.066666v-66.56h450.56v66.56c0 10.24 6.826667 17.066667 17.066666 17.066666s17.066667-6.826667 17.066667-17.066666v-66.56H887.466667c27.306667 0 51.2 22.186667 51.2 51.2v88.746666H117.76v-88.746666c0-29.013333 22.186667-51.2 51.2-51.2zM887.466667 887.466667H168.96c-27.306667 0-51.2-22.186667-51.2-51.2V401.066667H938.666667V836.266667c0 27.306667-22.186667 51.2-51.2 51.2z" p-id="1377"></path><path d="M858.453333 493.226667H327.68c-10.24 0-17.066667 6.826667-17.066667 17.066666v114.346667h-116.053333c-10.24 0-17.066667 6.826667-17.066667 17.066667v133.12c0 10.24 6.826667 17.066667 17.066667 17.066666H460.8c10.24 0 17.066667-6.826667 17.066667-17.066666v-114.346667h380.586666c10.24 0 17.066667-6.826667 17.066667-17.066667v-133.12c0-10.24-6.826667-17.066667-17.066667-17.066666z m-413.013333 34.133333v97.28h-98.986667v-97.28h98.986667z m-230.4 131.413333h98.986667v98.986667h-98.986667v-98.986667z m131.413333 97.28v-97.28h98.986667v97.28h-98.986667z m133.12-228.693333h97.28v98.986667h-97.28v-98.986667z m131.413334 0h98.986666v98.986667h-98.986666v-98.986667z m230.4 97.28h-98.986667v-98.986667h98.986667v98.986667z" p-id="1378"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577186573535" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1068" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M479.85714249 608.42857168h64.28571502c19.28571417 0 32.14285751-12.85714249 32.14285664-32.14285751s-12.85714249-32.14285751-32.14285664-32.14285664h-64.28571504c-19.28571417 0-32.14285751 12.85714249-32.14285664 32.14285662s12.85714249 32.14285751 32.14285664 32.14285753z m-2e-8 122.14285665h64.28571504c19.28571417 0 32.14285751-12.85714249 32.14285664-32.14285665s-12.85714249-32.14285751-32.14285664-32.14285751h-64.28571504c-19.28571417 0-32.14285751 12.85714249-32.14285664 32.14285751s12.85714249 32.14285751 32.14285664 32.14285664z m353.57142921-559.28571416h-128.57142921v-32.14285664c0-19.28571417-12.85714249-32.14285751-32.14285664-32.14285753s-32.14285751 12.85714249-32.14285751 32.14285753v32.14285664h-257.14285665v-32.14285664c0-19.28571417-12.85714249-32.14285751-32.14285752-32.14285753s-32.14285751 12.85714249-32.14285664 32.14285753v32.14285664h-128.57142919c-70.71428585 0-128.57142832 57.85714249-128.57142832 122.14285751v501.42857081c0 70.71428585 57.85714249 128.57142832 128.57142832 122.14285751h642.85714335c70.71428585 0 128.57142832-57.85714249 128.57142833-122.14285751v-501.42857081c0-70.71428585-57.85714249-122.14285753-128.57142833-122.14285751z m64.28571415 623.57142832c0 32.14285751-32.14285751 64.28571415-64.28571416 64.28571504h-642.85714335c-32.14285751 0-64.28571415-25.71428583-64.28571417-64.28571504v-372.85714249h771.42857168v372.85714249z m0-437.14285664h-771.42857168v-64.28571417c0-32.14285751 32.14285751-64.28571415 64.28571417-64.28571415h128.57142919v32.14285664c0 19.28571417 12.85714249 32.14285751 32.14285664 32.14285751s32.14285751-12.85714249 32.14285753-32.14285751v-32.14285664h257.14285665v32.14285664c0 19.28571417 12.85714249 32.14285751 32.1428575 32.14285751s32.14285751-12.85714249 32.14285664-32.14285751v-32.14285664h128.57142921c32.14285751 0 64.28571415 25.71428583 64.28571415 64.28571415v64.28571417z m-610.71428583 372.85714247h64.28571415c19.28571417 0 32.14285751-12.85714249 32.14285753-32.14285664s-12.85714249-32.14285751-32.14285753-32.14285751h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285751 32.14285751s12.85714249 32.14285751 32.14285751 32.14285665z m385.71428583-122.14285664h64.28571417c19.28571417 0 32.14285751-12.85714249 32.14285751-32.14285751s-12.85714249-32.14285751-32.14285751-32.14285664h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285753 32.14285664s12.85714249 32.14285751 32.14285753 32.14285751z m-385.71428583 0h64.28571415c19.28571417 0 32.14285751-12.85714249 32.14285753-32.14285751s-12.85714249-32.14285751-32.14285753-32.14285664h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285751 32.14285664s12.85714249 32.14285751 32.14285751 32.14285751z m385.71428583 122.14285665h64.28571417c19.28571417 0 32.14285751-12.85714249 32.14285751-32.14285665s-12.85714249-32.14285751-32.14285751-32.14285751h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285753 32.14285751s12.85714249 32.14285751 32.14285753 32.14285665z" p-id="1069"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566035680909" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3601" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M1002.0848 744.672l-33.568 10.368c0.96 7.264 2.144 14.304 2.144 21.76 0 7.328-1.184 14.432-2.368 21.568l33.792 10.56c7.936 2.24 14.496 7.616 18.336 14.752 3.84 7.328 4.672 15.808 1.952 23.552-5.376 16-23.168 24.672-39.936 19.68l-34.176-10.624c-7.136 12.8-15.776 24.672-26.208 35.2l20.8 27.488a28.96 28.96 0 0 1 5.824 22.816 29.696 29.696 0 0 1-12.704 19.616 32.544 32.544 0 0 1-44.416-6.752l-20.8-27.552c-13.696 6.56-28.192 11.2-43.008 13.888v33.632c0 16.736-14.112 30.432-31.648 30.432-17.6 0-31.872-13.696-31.872-30.432v-33.632a167.616 167.616 0 0 1-42.88-13.888l-20.928 27.552c-10.72 13.76-30.08 16.64-44.288 6.752a29.632 29.632 0 0 1-12.704-19.616 29.28 29.28 0 0 1 5.696-22.816l20.896-27.808a166.72 166.72 0 0 1-27.008-34.688l-33.376 10.432c-16.8 5.184-34.56-3.552-39.936-19.616a29.824 29.824 0 0 1 20.224-38.24l33.472-10.432c-0.8-7.264-2.016-14.304-2.016-21.824 0-7.36 1.184-14.496 2.304-21.632l-33.792-10.368c-16.672-5.376-25.632-22.496-20.224-38.432 5.376-16 23.136-24.672 39.936-19.68l34.016 10.752c7.328-12.672 15.84-24.8 26.336-35.328l-20.8-27.552a29.44 29.44 0 0 1 6.944-42.432 32.704 32.704 0 0 1 44.384 6.752l20.832 27.616c13.696-6.432 28.224-11.2 43.104-13.952v-33.568c0-16.736 14.048-30.432 31.648-30.432 17.536 0 31.808 13.568 31.808 30.432v33.504c15.072 2.688 29.344 7.808 42.848 14.016l20.992-27.616a32.48 32.48 0 0 1 44.224-6.752 29.568 29.568 0 0 1 7.136 42.432l-21.024 27.808c10.432 10.432 19.872 21.888 27.04 34.752l33.376-10.432c16.768-5.12 34.56 3.68 39.936 19.68 5.536 15.936-3.712 33.056-20.32 38.304z m-206.016-74.432c-61.344 0-111.136 47.808-111.136 106.56 0 58.88 49.792 106.496 111.136 106.496 61.312 0 111.104-47.616 111.104-106.496 0-58.752-49.792-106.56-111.104-106.56z" p-id="3602"></path><path d="M802.7888 57.152h-76.448c0-22.08-21.024-38.24-42.848-38.24H39.3968a39.68 39.68 0 0 0-39.36 40.032v795.616s41.888 120.192 110.752 120.192H673.2848a227.488 227.488 0 0 1-107.04-97.44H117.6368s-40.608-13.696-40.608-41.248l470.304-0.256 1.664 3.36a227.68 227.68 0 0 1-12.64-73.632c0-60.576 24-118.624 66.88-161.44a228.352 228.352 0 0 1 123.552-63.392l-3.2 0.288 2.144-424.672h38.208l0.576 421.024c27.04 0 52.672 4.8 76.64 13.344V101.536c0.032 0-6.304-44.384-38.368-44.384zM149.7648 514.336H72.3888v-77.408H149.7648v77.408z m0-144.32H72.3888v-77.44H149.7648v77.44z m0-137.248H72.3888v-77.44H149.7648v77.44z m501.856 281.568H206.0848v-77.408h445.536v77.408z m0-144.32H206.0848v-77.44h445.536v77.44z m0-137.248H206.0848v-77.44h445.536v77.44z" p-id="3603"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M71.984 44.815H115.9L71.984 9.642v35.173zM16.094.05h63.875l47.906 38.37v76.74c0 3.392-1.682 6.645-4.677 9.044-2.995 2.399-7.056 3.746-11.292 3.746H16.094c-4.236 0-8.297-1.347-11.292-3.746-2.995-2.399-4.677-5.652-4.677-9.044V12.84C.125 5.742 7.23.05 16.094.05zm71.86 102.32V89.58h-71.86v12.79h71.86zm23.952-25.58V64H16.094v12.79h95.812z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1569915748289" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3062" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M768.35456 416a256 256 0 1 0-512 0 192 192 0 1 0 0 384v64a256 256 0 0 1-58.88-505.216 320.128 320.128 0 0 1 629.76 0A256.128 256.128 0 0 1 768.35456 864v-64a192 192 0 0 0 0-384z m-512 384h64v64H256.35456v-64z m448 0h64v64h-64v-64z" fill="#333333" p-id="3063"></path><path d="M539.04256 845.248V512.192a32.448 32.448 0 0 0-32-32.192c-17.664 0-32 14.912-32 32.192v333.056l-36.096-36.096a32.192 32.192 0 0 0-45.056 0.192 31.616 31.616 0 0 0-0.192 45.056l90.88 90.944a31.36 31.36 0 0 0 22.528 9.088 30.08 30.08 0 0 0 22.4-9.088l90.88-90.88a32.192 32.192 0 0 0-0.192-45.12 31.616 31.616 0 0 0-45.056-0.192l-36.096 36.096z" fill="#333333" p-id="3064"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M73.137 29.08h-9.209 29.7L63.886.093 34.373 29.08h20.49v27.035H27.238v17.948h27.625v27.133h18.274V74.063h27.41V56.115h-27.41V29.08zm-9.245 98.827l27.518-26.711H36.59l27.302 26.71zM.042 64.982l27.196 27.029V38.167L.042 64.982zm100.505-26.815V92.01l27.41-27.029-27.41-26.815z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036347051" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5853" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M832 128H192a64.19 64.19 0 0 0-64 64v640a64.19 64.19 0 0 0 64 64h640a64.19 64.19 0 0 0 64-64V192a64.19 64.19 0 0 0-64-64z m0 703.89l-0.11 0.11H192.11l-0.11-0.11V768h640zM832 544H720L605.6 696.54 442.18 435.07 333.25 544H192v-64h114.75l147.07-147.07L610.4 583.46 688 480h144z m0-288H192v-63.89l0.11-0.11h639.78l0.11 0.11z" p-id="5854"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M106.133 67.2a4.797 4.797 0 0 0-4.8 4.8c0 .187.014.36.027.533h-.027V118.4H9.6V26.667h50.133c2.654 0 4.8-2.147 4.8-4.8 0-2.654-2.146-4.8-4.8-4.8H9.6a9.594 9.594 0 0 0-9.6 9.6V118.4c0 5.307 4.293 9.6 9.6 9.6h91.733c5.307 0 9.6-4.293 9.6-9.6V72.533h-.026c.013-.173.026-.346.026-.533 0-2.653-2.146-4.8-4.8-4.8z"/><path d="M125.16 13.373L114.587 2.8c-3.747-3.747-9.854-3.72-13.6.027l-52.96 52.96a4.264 4.264 0 0 0-.907 1.36L33.813 88.533c-.746 1.76-.226 3.534.907 4.68 1.133 1.147 2.92 1.667 4.693.92l31.4-13.293c.507-.213.96-.52 1.36-.907l52.96-52.96c3.747-3.746 3.774-9.853.027-13.6zM66.107 72.4l-18.32 7.76 7.76-18.32L92.72 24.667l10.56 10.56L66.107 72.4zm52.226-52.227l-8.266 8.267-10.56-10.56 8.266-8.267.027-.026 10.56 10.56-.027.026z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M88.883 119.565c-7.284 0-19.434 2.495-21.333 8.25v.127c-4.232.13-5.222 0-7.108 0-1.895-5.76-14.045-8.256-21.333-8.256H0V0h42.523c9.179 0 17.109 5.47 21.47 13.551C68.352 5.475 76.295 0 85.478 0H128v119.57l-39.113-.005h-.004zM60.442 24.763c0-9.651-8.978-16.507-17.777-16.507H7.108V111.43H39.11c7.054-.14 18.177.082 21.333 6.12v-4.628c-.134-5.722-.004-13.522 0-13.832V27.413l.004-2.655-.004.005zm60.442-16.517h-35.55c-8.802 0-17.78 6.856-17.78 16.493v74.259c.004.32.138 8.115 0 13.813v4.627c3.155-6.022 14.279-6.26 21.333-6.114h32V8.25l-.003-.005z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="96" xmlns="http://www.w3.org/2000/svg"><path d="M64.125 56.975L120.188.912A12.476 12.476 0 0 0 115.5 0h-103c-1.588 0-3.113.3-4.513.838l56.138 56.137z"/><path d="M64.125 68.287l-62.3-62.3A12.42 12.42 0 0 0 0 12.5v71C0 90.4 5.6 96 12.5 96h103c6.9 0 12.5-5.6 12.5-12.5v-71a12.47 12.47 0 0 0-1.737-6.35L64.125 68.287z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1746590936918" class="icon" viewBox="0 0 1194 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5378" xmlns:xlink="http://www.w3.org/1999/xlink" width="233.203125" height="200"><path d="M1151.9144 325.11999969V89.12a57.04000031 57.04000031 0 0 0-28.8-49.44 58.15999969 58.15999969 0 0 0-57.76000031 0 57.04000031 57.04000031 0 0 0-28.8 49.44v235.99999969c0.24 84.31999969-33.6 152.56000031-94.08 212.00000062-60.07999969 59.83999969-141.84 80.64-227.04 80.4H225.91440031L388.07439969 457.11999969a56.80000031 56.80000031 0 0 0 12.40000031-62.16 57.76000031 57.76000031 0 0 0-94.00000031-18.63999938L48.8744 631.20000031a56.88 56.88 0 0 0 0 80.79999938l264.96 262.56a58.08 58.08 0 0 0 96.55999969-25.59999938 56.80000031 56.80000031 0 0 0-14.95999969-55.2L232.07439969 731.67999969h483.44000062c116.56000031 0 226.15999969-32.08000031 308.64-113.76 82.15999969-80.80000031 128.23999969-178.15999969 127.83999938-292.87999969" p-id="5379"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.208 16.576v8.384h38.72v5.376h-38.72v8.704h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.512h38.72v5.376h-38.72v11.136H128v-94.72H78.208zM0 114.368L72.128 128V0L0 13.632v100.736z"/><path d="M28.672 82.56h-11.2l14.784-23.488-14.08-22.592h11.52l8.192 14.976 8.448-14.976h11.136l-14.08 22.208L58.368 82.56H46.656l-8.768-15.68z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M49.217 41.329l-.136-35.24c-.06-2.715-2.302-4.345-5.022-4.405h-3.65c-2.712-.06-4.866 2.303-4.806 5.016l.152 19.164-24.151-23.79a6.698 6.698 0 0 0-9.499 0 6.76 6.76 0 0 0 0 9.526l23.93 23.713-18.345.074c-2.712-.069-5.228 1.813-5.64 5.02v3.462c.069 2.721 2.31 4.97 5.022 5.03l35.028-.207c.052.005.087.025.133.025l2.457.054a4.626 4.626 0 0 0 3.436-1.38c.88-.874 1.205-2.096 1.169-3.462l-.262-2.465c0-.048.182-.081.182-.136h.002zm52.523 51.212l18.32-.073c2.713.06 5.224-1.609 5.64-4.815v-3.462c-.068-2.722-2.317-4.97-5.021-5.04l-34.58.21c-.053 0-.086-.021-.138-.021l-2.451-.06a4.64 4.64 0 0 0-3.445 1.381c-.885.868-1.201 2.094-1.174 3.46l.27 2.46c.005.06-.177.095-.177.141l.141 34.697c.069 2.713 2.31 4.338 5.022 4.397l3.45.006c2.705.062 4.867-2.31 4.8-5.026l-.153-18.752 24.151 23.946a6.69 6.69 0 0 0 9.494 0 6.747 6.747 0 0 0 0-9.523L101.74 92.54v.001zM48.125 80.662a4.636 4.636 0 0 0-3.437-1.382l-2.457.06c-.05 0-.082.022-.137.022l-35.025-.21c-2.712.07-4.957 2.318-5.022 5.04v3.462c.409 3.206 2.925 4.874 5.633 4.814l18.554.06-24.132 23.928c-2.62 2.626-2.62 6.89 0 9.524a6.694 6.694 0 0 0 9.496 0l24.155-23.79-.155 18.866c-.06 2.722 2.094 5.093 4.801 5.025h3.65c2.72-.069 4.962-1.685 5.022-4.406l.141-34.956c0-.05-.182-.082-.182-.136l.262-2.46c.03-1.366-.286-2.592-1.166-3.46h-.001zM80.08 47.397a4.62 4.62 0 0 0 3.443 1.374l2.45-.054c.055 0 .088-.02.143-.028l35.08.21c2.712-.062 4.953-2.312 5.021-5.033l.009-3.463c-.417-3.211-2.937-5.084-5.64-5.025l-18.615-.073 23.917-23.715c2.63-2.623 2.63-6.879.008-9.513a6.691 6.691 0 0 0-9.494 0L92.251 26.016l.155-19.312c.065-2.713-2.097-5.085-4.802-5.025h-3.45c-2.713.069-4.954 1.693-5.022 4.406l-.139 35.247c0 .054.18.088.18.136l-.267 2.465c-.028 1.366.288 2.588 1.174 3.463v.001z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.068 23.784c-1.02 0-1.877-.32-2.572-.96a8.588 8.588 0 0 1-1.738-2.237 11.524 11.524 0 0 1-1.042-2.621c-.232-.895-.348-1.641-.348-2.238V0h.278c.834 0 1.622.085 2.363.256.742.17 1.645.575 2.711 1.214 1.066.64 2.363 1.535 3.892 2.686 1.53 1.15 3.453 2.664 5.77 4.54 2.502 2.045 4.494 3.771 5.977 5.178 1.483 1.406 2.618 2.6 3.406 3.58.787.98 1.274 1.812 1.46 2.494.185.682.277 1.278.277 1.79v2.046H84.068zM127.3 84.01c.278.682.464 1.535.556 2.558.093 1.023-.37 2.003-1.39 2.94-.463.427-.88.832-1.25 1.215-.372.384-.696.704-.974.96a6.69 6.69 0 0 1-.973.767l-11.816-10.741a44.331 44.331 0 0 0 1.877-1.535 31.028 31.028 0 0 1 1.737-1.406c1.112-.938 2.317-1.343 3.615-1.215 1.297.128 2.363.405 3.197.83.927.427 1.923 1.173 2.989 2.239 1.065 1.065 1.876 2.195 2.432 3.388zM78.23 95.902c2.038 0 3.752-.511 5.143-1.534l-26.969 25.83H18.037c-1.761 0-3.684-.47-5.77-1.407a24.549 24.549 0 0 1-5.838-3.709 21.373 21.373 0 0 1-4.518-5.306c-1.204-2.003-1.807-4.07-1.807-6.202V16.495c0-1.79.44-3.665 1.32-5.626A18.41 18.41 0 0 1 5.04 5.562a21.798 21.798 0 0 1 5.213-3.964C12.198.533 14.237 0 16.37 0h53.24v15.984c0 1.62.278 3.367.834 5.242a16.704 16.704 0 0 0 2.572 5.179c1.159 1.577 2.665 2.898 4.518 3.964 1.853 1.066 4.078 1.598 6.673 1.598h20.295v42.325L85.458 92.45c1.02-1.364 1.529-2.856 1.529-4.476 0-2.216-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1c-2.409 0-4.448.789-6.116 2.366-1.668 1.577-2.502 3.474-2.502 5.69 0 2.217.834 4.092 2.502 5.626 1.668 1.535 3.707 2.302 6.117 2.302h52.13zM26.1 47.951c-2.41 0-4.449.789-6.117 2.366-1.668 1.577-2.502 3.473-2.502 5.69 0 2.216.834 4.092 2.502 5.626 1.668 1.534 3.707 2.302 6.117 2.302h52.13c2.409 0 4.47-.768 6.185-2.302 1.715-1.534 2.572-3.41 2.572-5.626 0-2.217-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1zm52.407 64.063l1.807-1.663 3.476-3.196a479.75 479.75 0 0 0 4.587-4.284 500.757 500.757 0 0 1 5.004-4.667c3.985-3.666 8.48-7.758 13.485-12.276l11.677 10.741-13.485 12.404-5.004 4.603-4.587 4.22a179.46 179.46 0 0 0-3.267 3.068c-.88.853-1.367 1.322-1.46 1.407-.463.341-.973.703-1.529 1.087-.556.383-1.112.703-1.668.959-.556.256-1.413.575-2.572.959a83.5 83.5 0 0 1-3.545 1.087 72.2 72.2 0 0 1-3.475.895c-1.112.256-1.946.426-2.502.511-1.112.17-1.854.043-2.224-.383-.371-.426-.464-1.151-.278-2.174.092-.511.278-1.279.556-2.302.278-1.023.602-2.067.973-3.132l1.042-3.005c.325-.938.58-1.577.765-1.918a10.157 10.157 0 0 1 2.224-2.941z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M38.47 52L52 38.462l-23.648-23.67L43.209 0H.035L0 43.137l14.757-14.865L38.47 52zm74.773 47.726L89.526 76 76 89.536l23.648 23.672L84.795 128h43.174L128 84.863l-14.757 14.863zM89.538 52l23.668-23.648L128 43.207V.038L84.866 0 99.73 14.76 76 38.472 89.538 52zM38.46 76L14.792 99.651 0 84.794v43.173l43.137.033-14.865-14.757L52 89.53 38.46 76z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1581238998885" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4187" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M511.542857 14.057143C228.914286 13.942857 0 242.742857 0 525.142857 0 748.457143 143.2 938.285714 342.628571 1008c26.857143 6.742857 22.742857-12.342857 22.742858-25.371429v-88.571428c-155.085714 18.171429-161.371429-84.457143-171.771429-101.6C172.571429 756.571429 122.857143 747.428571 137.714286 730.285714c35.314286-18.171429 71.314286 4.571429 113.028571 66.171429 30.171429 44.685714 89.028571 37.142857 118.857143 29.714286 6.514286-26.857143 20.457143-50.857143 39.657143-69.485715-160.685714-28.8-227.657143-126.857143-227.657143-243.428571 0-56.571429 18.628571-108.571429 55.2-150.514286-23.314286-69.142857 2.171429-128.342857 5.6-137.142857 66.4-5.942857 135.428571 47.542857 140.8 51.771429 37.714286-10.171429 80.8-15.542857 129.028571-15.542858 48.457143 0 91.657143 5.6 129.714286 15.885715 12.914286-9.828571 76.914286-55.771429 138.628572-50.171429 3.314286 8.8 28.228571 66.628571 6.285714 134.857143 37.028571 42.057143 55.885714 94.514286 55.885714 151.2 0 116.8-67.428571 214.971429-228.571428 243.314286a145.714286 145.714286 0 0 1 43.542857 104v128.571428c0.914286 10.285714 0 20.457143 17.142857 20.457143 202.4-68.228571 348.114286-259.428571 348.114286-484.685714 0-282.514286-229.028571-511.2-511.428572-511.2z" p-id="4188"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.482 70.131l36.204 16.18 69.932-65.485-61.38 70.594 46.435 18.735c1.119.425 2.397-.17 2.797-1.363v-.085L127.998.047 1.322 65.874c-1.12.597-1.519 1.959-1.04 3.151.32.511.72.937 1.2 1.107zm44.676 57.821L64.22 107.26l-18.062-7.834v28.527z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.147.062a13 13 0 0 1 4.94.945c1.55.63 2.907 1.526 4.069 2.688a13.148 13.148 0 0 1 2.761 4.069c.678 1.55 1.017 3.245 1.017 5.086v102.3c0 3.681-1.187 6.733-3.56 9.155-2.373 2.422-5.352 3.633-8.937 3.633H12.992c-3.875 0-7-1.26-9.373-3.779-2.373-2.518-3.56-5.667-3.56-9.445V12.704c0-3.39 1.163-6.345 3.488-8.863C5.872 1.32 8.972.062 12.847.062h102.3zM81.434 109.047c1.744 0 3.003-.412 3.778-1.235.775-.824 1.163-1.914 1.163-3.27 0-1.26-.388-2.325-1.163-3.197-.775-.872-2.034-1.307-3.778-1.307H72.57c.097-.194.145-.485.145-.872V27.09h9.01c1.743 0 2.954-.436 3.633-1.308.678-.872 1.017-1.938 1.017-3.197 0-1.26-.34-2.325-1.017-3.197-.679-.872-1.89-1.308-3.633-1.308H46.268c-1.743 0-2.954.436-3.632 1.308-.678.872-1.018 1.938-1.018 3.197 0 1.26.34 2.325 1.018 3.197.678.872 1.889 1.308 3.632 1.308h8.138v72.075c0 .193.024.339.073.436.048.096.072.242.072.436H46.56c-1.744 0-3.003.435-3.778 1.307-.775.872-1.163 1.938-1.163 3.197 0 1.356.388 2.446 1.163 3.27.775.823 2.034 1.235 3.778 1.235h34.875z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575802859706" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3102" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M896 224H128c-35.2 0-64 28.8-64 64v448c0 35.2 28.8 64 64 64h768c35.2 0 64-28.8 64-64V288c0-35.2-28.8-64-64-64z m0 480c0 19.2-12.8 32-32 32H160c-19.2 0-32-12.8-32-32V320c0-19.2 12.8-32 32-32h704c19.2 0 32 12.8 32 32v384z" p-id="3103"></path><path d="M224 352c-19.2 0-32 12.8-32 32v256c0 16 12.8 32 32 32s32-12.8 32-32V384c0-16-12.8-32-32-32z" p-id="3104"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M83.287 103.01c-1.57-3.84-6.778-10.414-15.447-19.548-2.327-2.444-2.182-4.306-1.338-9.862v-.64c.553-3.81 1.513-6.05 14.313-8.087 6.516-1.018 8.203 1.57 10.589 5.178l.785 1.193a12.625 12.625 0 0 0 6.43 5.207c1.134.524 2.53 1.164 4.421 2.24 4.596 2.53 4.596 5.41 4.596 11.753v.727a26.91 26.91 0 0 1-5.178 17.454 59.055 59.055 0 0 1-19.025 11.026c3.49-6.546.814-14.313 0-16.553l-.146-.087zM64 5.12a58.502 58.502 0 0 1 25.484 5.818 54.313 54.313 0 0 0-12.859 10.327c-.93 1.28-1.716 2.473-2.472 3.579-2.444 3.694-3.637 5.352-5.818 5.614a25.105 25.105 0 0 1-4.219 0c-4.276-.29-10.094-.64-11.956 4.422-1.193 3.23-1.396 11.956 2.444 16.495.66 1.077.778 2.4.32 3.578a7.01 7.01 0 0 1-2.066 3.229 18.938 18.938 0 0 1-2.909-2.91 18.91 18.91 0 0 0-8.32-6.603c-1.25-.349-2.647-.64-3.985-.93-3.782-.786-8.03-1.688-9.019-3.812a14.895 14.895 0 0 1-.727-5.818 21.935 21.935 0 0 0-1.396-9.25 8.873 8.873 0 0 0-5.557-4.946A58.705 58.705 0 0 1 64 5.12zM0 64c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036191400" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5472" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M934.912 1016.832H192c-14.336 0-25.6-11.264-25.6-25.6v-189.44c0-14.336 11.264-25.6 25.6-25.6s25.6 11.264 25.6 25.6v163.84h691.712V64H217.6v148.48c0 14.336-11.264 25.6-25.6 25.6s-25.6-11.264-25.6-25.6v-174.08c0-14.336 11.264-25.6 25.6-25.6h742.912c14.336 0 25.6 11.264 25.6 25.6v952.832c0 14.336-11.264 25.6-25.6 25.6z" p-id="5473"></path><path d="M232.96 371.2h-117.76c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h117.76c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6zM232.96 540.16h-117.76c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h117.76c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6zM232.96 698.88h-117.76c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h117.76c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6zM574.464 762.88c-134.144 0-243.2-109.056-243.2-243.2S440.32 276.48 574.464 276.48s243.2 109.056 243.2 243.2-109.056 243.2-243.2 243.2z m0-435.2c-105.984 0-192 86.016-192 192S468.48 711.68 574.464 711.68s192-86.016 192-192S680.448 327.68 574.464 327.68z" p-id="5474"></path><path d="M663.04 545.28h-87.04c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h87.04c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6z" p-id="5475"></path><path d="M576 545.28c-14.336 0-25.6-11.264-25.6-25.6v-87.04c0-14.336 11.264-25.6 25.6-25.6s25.6 11.264 25.6 25.6v87.04c0 14.336-11.264 25.6-25.6 25.6z" p-id="5476"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.742 36.8c2.398 7.2 5.595 12.8 11.19 18.4 4.795-4.8 7.992-11.2 10.39-18.4h-21.58zm-52.748 40h20.78l-10.39-28-10.39 28z"/><path d="M111.916 0H16.009C7.218 0 .025 7.2.025 16v96c0 8.8 7.193 16 15.984 16h95.907c8.791 0 15.984-7.2 15.984-16V16c0-8.8-6.394-16-15.984-16zM72.754 103.2c-1.598 1.6-3.197 1.6-4.795 1.6-.8 0-2.398 0-3.197-.8-.8-.8-1.599 0-1.599-.8s-.799-1.6-1.598-3.2c-.8-1.6-.8-2.4-1.599-4l-3.196-8.8H28.797L25.6 96c-1.598 3.2-2.398 5.6-3.197 7.2-.8 1.6-2.398 1.6-4.795 1.6-1.599 0-3.197-.8-4.796-1.6-1.598-1.6-2.397-2.4-2.397-4 0-.8 0-1.6.799-3.2.8-1.6.8-2.4 1.598-4l17.583-44.8c.8-1.6.8-3.2 1.599-4.8.799-1.6 1.598-3.2 2.397-4 .8-.8 1.599-2.4 3.197-3.2 1.599-.8 3.197-.8 4.796-.8 1.598 0 3.196 0 4.795.8 1.598.8 2.398 1.6 3.197 3.2.799.8 1.598 2.4 2.397 4 .8 1.6 1.599 3.2 2.398 5.6l17.583 44c1.598 3.2 2.398 5.6 2.398 7.2-.8.8-1.599 2.4-2.398 4zM116.711 72c-8.791-3.2-15.185-7.2-20.78-12-5.594 5.6-12.787 9.6-21.579 12l-2.397-4c8.791-2.4 15.984-5.6 21.579-11.2C87.939 51.2 83.144 44 81.545 36h-7.992v-3.2h21.58c-1.6-2.4-3.198-5.6-4.796-8l2.397-.8c1.599 2.4 3.997 5.6 5.595 8.8h19.98v4h-7.992c-2.397 8-6.393 15.2-11.189 20 5.595 4.8 11.988 8.8 20.78 11.2l-3.197 4z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.585 12.087c0 6.616 3.974 11.98 8.877 11.98 4.902 0 8.877-5.364 8.877-11.98 0-6.616-3.975-11.98-8.877-11.98-4.903 0-8.877 5.364-8.877 11.98zM125.86.107H35.613c-1.268 0-2.114 1.426-2.114 2.852v18.255c0 1.712 1.057 2.853 2.114 2.853h90.247c1.268 0 2.114-1.426 2.114-2.853V2.96c0-1.711-1.057-2.852-2.114-2.852zM.106 62.86c0 6.615 3.974 11.979 8.876 11.979 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zM124.17 50.88H33.921c-1.268 0-2.114 1.425-2.114 2.851v18.256c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852V53.73c0-1.426-.846-2.852-2.114-2.852zM.106 115.913c0 6.616 3.974 11.98 8.876 11.98 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zm124.064-11.98H33.921c-1.268 0-2.114 1.426-2.114 2.853v18.255c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852v-18.255c0-1.427-.846-2.853-2.114-2.853z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M119.88 49.674h-7.987V39.52C111.893 17.738 90.45.08 63.996.08 37.543.08 16.1 17.738 16.1 39.52v10.154H8.113c-4.408 0-7.987 2.94-7.987 6.577v65.13c0 3.637 3.57 6.577 7.987 6.577H119.88c4.407 0 7.987-2.94 7.987-6.577v-65.13c-.008-3.636-3.58-6.577-7.987-6.577zm-23.953 0H32.065V39.52c0-14.524 14.301-26.295 31.931-26.295 17.63 0 31.932 11.777 31.932 26.295v10.153z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566035943711" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4805" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M208.736 566.336H64.384v59.328h144.352v-59.328z m0-336.096H165.44V74.592c0-7.968 4.896-14.848 10.464-14.848h502.016V0.448H175.936c-38.72 1.248-69.248 34.368-68.192 74.144v155.648H64.384V289.6h144.352V230.24z m0 168.096H64.384v59.328h144.352v-59.328z m714.656 76.576h-57.76v474.496c0 7.936-4.896 14.848-10.464 14.848H175.936c-5.568 0-10.464-6.912-10.464-14.848v-155.68h43.296v-59.296H64.384v59.296h43.328v155.68c-1.024 39.776 29.472 72.896 68.192 74.144h679.232c38.72-1.184 69.248-34.368 68.256-74.144V474.912z m14.944-290.336l-83.072-85.312a71.264 71.264 0 0 0-52.544-21.728 71.52 71.52 0 0 0-51.616 23.872L386.528 507.264a30.496 30.496 0 0 0-6.176 10.72L308.16 740.512a30.016 30.016 0 0 0 6.976 30.24c7.712 7.968 19.2 10.752 29.568 7.2l216.544-74.112a28.736 28.736 0 0 0 12.128-7.936L940.448 287.456a75.552 75.552 0 0 0-2.112-102.88z m-557.12 518.272l39.104-120.64 78.336 80.416-117.44 40.224z m170.048-70.016l-103.552-106.016 200.16-222.4 103.52 106.304-200.128 222.112zM897.952 247.072l-0.256 0.224-107.136 119.168-103.52-106.528 106.432-118.624a14.144 14.144 0 0 1 10.304-4.736 13.44 13.44 0 0 1 10.464 4.288l83.264 85.696c5.472 5.6 5.664 14.72 0.448 20.512z" p-id="4806"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036016814" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5261" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M896 128h-85.333333a42.666667 42.666667 0 0 0 0 85.333333h42.666666v640H170.666667V213.333333h42.666666a42.666667 42.666667 0 0 0 0-85.333333H128a42.666667 42.666667 0 0 0-42.666667 42.666667v725.333333a42.666667 42.666667 0 0 0 42.666667 42.666667h768a42.666667 42.666667 0 0 0 42.666667-42.666667V170.666667a42.666667 42.666667 0 0 0-42.666667-42.666667z" p-id="5262"></path><path d="M341.333333 298.666667a42.666667 42.666667 0 0 0 42.666667-42.666667V128a42.666667 42.666667 0 0 0-85.333333 0v128a42.666667 42.666667 0 0 0 42.666666 42.666667zM512 298.666667a42.666667 42.666667 0 0 0 42.666667-42.666667V128a42.666667 42.666667 0 0 0-85.333334 0v128a42.666667 42.666667 0 0 0 42.666667 42.666667zM682.666667 298.666667a42.666667 42.666667 0 0 0 42.666666-42.666667V128a42.666667 42.666667 0 0 0-85.333333 0v128a42.666667 42.666667 0 0 0 42.666667 42.666667zM341.333333 768a42.666667 42.666667 0 0 0 42.666667-42.666667 128 128 0 0 1 256 0 42.666667 42.666667 0 0 0 85.333333 0 213.333333 213.333333 0 0 0-107.52-184.32A128 128 0 0 0 640 469.333333a128 128 0 0 0-256 0 128 128 0 0 0 22.186667 71.68A213.333333 213.333333 0 0 0 298.666667 725.333333a42.666667 42.666667 0 0 0 42.666666 42.666667z m128-298.666667a42.666667 42.666667 0 1 1 42.666667 42.666667 42.666667 42.666667 0 0 1-42.666667-42.666667z" p-id="5263"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 20.967v59.59c0 11.59 8.537 20.966 19.075 20.966h28.613l1 26.477L76.8 101.523h32.125c10.538 0 19.075-9.377 19.075-20.966v-59.59C128 9.377 119.463 0 108.925 0h-89.85C8.538 0 0 9.377 0 20.967zm82.325 33.1c0-5.524 4.013-9.935 9.037-9.935 5.026 0 9.038 4.41 9.038 9.934 0 5.524-4.025 9.934-9.038 9.934-5.024 0-9.037-4.41-9.037-9.934zm-27.613 0c0-5.524 4.013-9.935 9.038-9.935s9.037 4.41 9.037 9.934c0 5.524-4.025 9.934-9.037 9.934-5.025 0-9.038-4.41-9.038-9.934zm-27.1 0c0-5.524 4.013-9.935 9.038-9.935s9.038 4.41 9.038 9.934c0 5.524-4.026 9.934-9.05 9.934-5.013 0-9.025-4.41-9.025-9.934z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.122 127.892v-28.68H7.513V87.274h46.609v-12.4H7.513v-12.86h38.003L.099 0h22.6l32.556 45.07c3.617 5.144 6.44 9.611 8.487 13.385 1.788-3.05 4.89-7.779 9.301-14.186L103.93 0h24.01L82.385 62.013h38.34v12.862h-46.41v12.4h46.41v11.937h-46.41v28.68H54.123z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1543827393750" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4695" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: rbicon; src: url("chrome-extension://dipiagiiohfljcicegpgffpbnjmgjcnf/fonts/rbicon.woff2") format("woff2"); font-weight: normal; font-style: normal; } |
| | | </style></defs><path d="M64 64V640H896V64H64zM0 0h960v704H0V0z" p-id="4696"></path><path d="M192 896H768v64H192zM448 640H512v256h-64z" p-id="4697"></path><path d="M479.232 561.604267l309.9904-348.330667-47.803733-42.5472-259.566934 291.669333L303.957333 240.008533 163.208533 438.6048l52.224 37.009067 91.6224-129.28z" p-id="4698"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1733303018722" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1447" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M368.832 67.2c51.328-16.384 89.216 34.112 75.712 76.416a346.816 346.816 0 0 0 435.84 435.84c42.304-13.44 92.8 24.384 76.48 75.712A467.968 467.968 0 1 1 368.832 67.2z m-35.776 122.688a368.832 368.832 0 1 0 501.056 501.056 445.952 445.952 0 0 1-501.056-501.056z" p-id="1448"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1746760911144" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12537" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M395.21211 182.914448c0 62.669318 49.541323 113.472378 110.642936 113.472378 61.093427 0 110.652146-50.80306 110.65214601-113.472378 0-62.685691-49.559742-113.487727-110.65214601-113.487727C444.75241 69.426721 395.21211 120.22978 395.21211 182.914448zM395.21211 523.34693101c0 62.668295 49.541323 113.487727 110.642936 113.48772699 61.093427 0 110.652146-50.820456 110.652146-113.487727 0-62.669318-49.559742-113.472378-110.652146-113.472378C444.75241 409.874553 395.21211 460.67761301 395.21211 523.34693101zM395.21211 841.084529c0 62.686714 49.541323 113.488751 110.642936 113.488751 61.093427 0 110.652146-50.80203599 110.65214601-113.488751 0-62.669318-49.559742-113.471354-110.65214601-113.471354C444.75241 727.614198 395.21211 778.416234 395.21211 841.084529z" p-id="12538"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575802851180" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2867" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M279.272727 791.272727h512a46.545455 46.545455 0 0 1 0 93.090909H279.272727a46.545455 46.545455 0 0 1 0-93.090909z m33.838546-617.984V651.636364H193.722182V395.170909c0-37.003636-0.884364-59.298909-2.653091-66.746182a24.948364 24.948364 0 0 0-14.615273-16.989091c-8.005818-3.863273-25.786182-5.771636-53.341091-5.771636h-11.822545v-55.854545c57.716364-12.381091 101.562182-37.888 131.490909-76.520728h70.283636z m303.709091 396.8V651.636364H354.164364v-68.235637c77.777455-127.255273 124.043636-206.010182 138.705454-236.218182 14.661818-30.254545 22.016-53.853091 22.016-70.74909 0-13.032727-2.234182-22.714182-6.656-29.137455-4.421818-6.376727-11.170909-9.588364-20.247273-9.588364a22.248727 22.248727 0 0 0-20.200727 10.612364c-4.468364 7.121455-6.656 21.178182-6.656 42.263273v45.521454H354.164364v-17.454545c0-26.763636 1.396364-47.941818 4.142545-63.348364 2.746182-15.499636 9.541818-30.72 20.386909-45.661091 10.798545-14.987636 24.901818-26.298182 42.216727-33.978182 17.361455-7.68 38.167273-11.543273 62.37091-11.543272 47.476364 0 83.316364 11.776 107.706181 35.328 24.296727 23.552 36.445091 53.341091 36.445091 89.367272 0 27.368727-6.842182 56.32-20.48 86.853819-13.730909 30.533818-54.039273 95.325091-121.018182 194.420363h130.885819z m270.615272-189.393454c18.152727 6.097455 31.650909 16.104727 40.494546 29.975272 8.843636 13.917091 13.312 46.452364 13.312 97.652364 0 38.027636-4.328727 67.490909-13.032727 88.529455-8.657455 20.945455-23.598545 36.910545-44.869819 47.848727-21.271273 10.938182-48.593455 16.384-81.873454 16.384-37.794909 0-67.490909-6.330182-89.088-19.083636-21.550545-12.660364-35.746909-28.253091-42.542546-46.638546-6.795636-18.432-10.193455-50.362182-10.193454-95.883636v-37.841455h119.389091v77.730909c0 20.666182 1.210182 33.838545 3.723636 39.424 2.420364 5.585455 7.912727 8.424727 16.337455 8.424728 9.309091 0 15.36-3.537455 18.338909-10.612364 2.932364-7.121455 4.421818-25.6 4.421818-55.575273v-33.047273c0-18.338909-2.048-31.744-6.190546-40.215272a30.72 30.72 0 0 0-18.338909-16.709818c-8.052364-2.653091-23.738182-4.189091-46.964363-4.561455V357.050182c28.392727 0 45.893818-1.070545 52.596363-3.258182a22.946909 22.946909 0 0 0 14.475637-14.149818c2.932364-7.307636 4.421818-18.711273 4.421818-34.257455v-26.624c0-16.756364-1.722182-27.741091-5.12-33.047272-3.490909-5.352727-8.843636-8.005818-16.151273-8.005819-8.285091 0-13.963636 2.792727-16.989091 8.378182-3.025455 5.632-4.561455 17.640727-4.561454 35.933091v39.284364h-119.389091v-40.773818c0-45.661091 10.472727-76.567273 31.325091-92.625455 20.898909-16.058182 54.085818-24.064 99.607272-24.064 56.878545 0 95.511273 11.170909 115.805091 33.373091 20.293818 22.248727 30.394182 53.201455 30.394182 92.765091 0 26.810182-3.630545 46.173091-10.891636 58.088727-7.307636 11.915636-20.107636 22.807273-38.446546 32.628364z" p-id="2868"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1568899557259" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="535" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M356.246145 681.56286c-68.156286-41.949414-107.246583-103.84102-107.246583-169.805384 0-65.966411 39.090297-127.860063 107.246583-169.809477 12.046361-7.414877 15.800871-23.190165 8.385994-35.236526-7.413853-12.046361-23.191188-15.801894-35.236526-8.387018-39.640836 24.399713-72.539106 56.044434-95.137801 91.515297-23.86657 37.461193-36.481889 79.620385-36.481889 121.917724 0 42.297338 12.615319 84.454484 36.481889 121.914654 22.598694 35.469839 55.496965 67.11456 95.137801 91.51325 4.185322 2.576685 8.821923 3.804652 13.400195 3.804652 8.598842 0 16.998139-4.329609 21.836331-12.190647C372.047016 704.752002 368.291482 688.976714 356.246145 681.56286zM263.943926 754.580874c-92.603071-61.111846-145.713686-149.623739-145.713686-242.840794 0-93.195565 53.094242-181.682899 145.667637-242.774279 11.805884-7.79043 15.061021-23.677259 7.269567-35.483142-7.79043-11.805884-23.677259-15.062044-35.483142-7.269567C128.487861 296.954249 67.006602 401.024489 67.006602 511.74008c0 110.73708 61.496609 214.830857 168.721703 285.593504 4.343935 2.867304 9.240455 4.238534 14.08274 4.238534 8.317433 0 16.476253-4.046153 21.400403-11.507078C279.003923 778.258133 275.748786 762.372328 263.943926 754.580874zM788.660552 226.213092c-11.80486-7.791453-27.692712-4.536316-35.483142 7.269567-7.79043 11.805884-4.536316 27.692712 7.269567 35.483142 92.575442 61.092403 145.670707 149.579737 145.670707 242.774279 0 93.216032-53.111638 181.727924-145.715733 242.840794-11.805884 7.79043-15.059997 23.678282-7.269567 35.484166 4.925173 7.461949 13.081946 11.507078 21.400403 11.507078 4.841262 0 9.739828-1.37123 14.083763-4.238534 107.22714-70.761624 168.724773-174.857447 168.724773-285.593504C957.341323 401.025513 895.860063 296.955272 788.660552 226.213092zM790.090111 633.67213c23.865547-37.459147 36.480866-79.617315 36.480866-121.914654 0-42.298362-12.615319-84.45653-36.480866-121.917724-22.598694-35.470863-55.496965-67.115584-95.139847-91.515297-12.047384-7.413853-27.821649-3.659343-35.236526 8.387018-7.414877 12.045337-3.659343 27.821649 8.385994 35.236526 68.156286 41.949414 107.247606 103.842043 107.247606 169.809477 0 65.964364-39.090297 127.85597-107.247606 169.804361-12.045337 7.414877-15.800871 23.190165-8.385994 35.237549 4.838192 7.861038 13.236466 12.190647 21.835308 12.190647 4.579295 0 9.215896-1.227967 13.400195-3.804652C734.591099 700.786691 767.490394 669.142993 790.090111 633.67213zM567.129086 518.274914c24.12342-17.150612 39.887452-45.305859 39.887452-77.07133 0-52.128241-42.452881-94.538143-94.634334-94.538143-52.18043 0-94.633311 42.408879-94.633311 94.538143 0 31.695886 15.696494 59.797921 39.730886 76.958766-49.875944 21.128203-84.917018 70.234621-84.917018 127.301338 0 2.366907 0.061398 4.762467 0.182149 7.119141l1.249457 24.296359 276.373515 0 1.238201-24.308639c0.119727-2.358721 0.181125-4.750187 0.181125-7.106862C651.786185 588.497255 616.865861 539.465538 567.129086 518.274914zM512.381182 397.889079c23.937179 0 43.411719 19.430538 43.411719 43.314505 0 23.882943-19.47454 43.313481-43.411719 43.313481-23.936155 0-43.409672-19.430538-43.409672-43.313481C468.971509 417.320641 488.445026 397.889079 512.381182 397.889079zM426.08884 625.656573c9.119705-38.542828 44.254923-67.337641 86.085634-67.337641s76.966952 28.794813 86.085634 67.337641L426.08884 625.656573z" p-id="536"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575802846045" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2750" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M868.593046 403.832442c-30.081109-28.844955-70.037123-44.753273-112.624057-44.753273L265.949606 359.079168c-42.554188 0-82.510202 15.908318-112.469538 44.690852-30.236652 28.782533-46.857191 67.222007-46.857191 108.198258l0 294.079782c0 40.977273 16.619516 79.414701 46.702672 108.136859 29.959336 28.844955 70.069869 44.814672 112.624057 44.814672l490.019383 0c42.585911 0 82.696444-15.969717 112.624057-44.814672 30.082132-28.844955 46.579875-67.222007 46.579875-108.136859L915.172921 511.968278C915.171897 471.053426 898.675178 432.677397 868.593046 403.832442zM841.821309 806.049083c0 22.098297-8.882298 42.772152-25.099654 58.306964-16.154935 15.661701-37.81935 24.203238-60.752666 24.203238L265.949606 888.559285c-22.934339 0-44.567032-8.54256-60.877509-24.264637-16.186657-15.474436-25.067932-36.148291-25.067932-58.246589L180.004165 511.968278c0-22.035876 8.881274-42.772152 25.192775-58.307987 16.186657-15.536858 37.81935-24.139793 60.753689-24.139793l490.019383 0c22.933315 0 44.597731 8.602935 60.752666 24.139793 16.21838 15.535835 25.099654 36.272112 25.099654 58.307987L841.822332 806.049083zM510.974136 135.440715c114.914216 0 208.318536 89.75214 208.318536 200.055338l73.350588 0c0-149.113109-126.366036-270.496667-281.669124-270.496667-155.333788 0-281.699824 121.383558-281.699824 270.496667l73.350588 0C302.623877 225.193879 396.059919 135.440715 510.974136 135.440715zM474.299865 747.244792l73.350588 0L547.650453 629.576859l-73.350588 0L474.299865 747.244792z" p-id="2751"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><path d="M869.073 277.307H657.111V65.344l211.962 211.963zm-238.232 26.27V65.344l-476.498-.054v416.957h714.73v-178.67H630.841zm-335.836 360.57c-5.07-3.064-10.944-5.133-17.61-6.201-6.67-1.064-13.603-1.6-20.81-1.6h-48.821v85.641h48.822c7.206 0 14.14-.532 20.81-1.6 6.665-1.065 12.54-3.133 17.609-6.202 5.064-3.063 9.134-7.406 12.208-13.007 3.065-5.602 4.6-12.937 4.6-22.011 0-9.07-1.535-16.408-4.6-22.01-3.074-5.603-7.144-9.94-12.208-13.01zM35.82 541.805v416.904h952.358V541.805H35.821zm331.421 191.179c-3.6 11.071-9.343 20.879-17.209 29.413-7.874 8.542-18.078 15.408-30.617 20.61-12.544 5.206-27.747 7.807-45.621 7.807h-66.036v102.45h-62.831V607.517h128.867c17.874 0 33.077 2.6 45.62 7.802 12.541 5.207 22.745 12.076 30.618 20.615 7.866 8.538 13.604 18.277 17.21 29.212 3.6 10.943 5.401 22.278 5.401 34.018 0 11.477-1.8 22.752-5.402 33.819zM644.9 806.417c-5.343 17.61-13.408 32.818-24.212 45.627-10.807 12.803-24.283 22.879-40.423 30.213-16.146 7.343-35.155 11.007-57.03 11.007h-123.26V607.518h123.26c18.41 0 35.552 2.941 51.428 8.808 15.873 5.869 29.618 14.671 41.22 26.412 11.608 11.744 20.674 26.411 27.217 44.02 6.535 17.61 9.803 38.288 9.803 62.035 0 20.81-2.67 40.02-8.003 57.624zm245.362-146.07h-138.07v66.03h119.66v48.829h-119.66v118.058h-62.83V607.518h200.9v52.829h-.001zm-318.2 25.611c-6.402-8.266-14.877-14.604-25.412-19.01-10.544-4.402-23.551-6.602-39.019-6.602h-44.825v180.088h56.029c9.07 0 17.872-1.463 26.415-4.401 8.535-2.932 16.14-7.802 22.812-14.609 6.665-6.8 12.007-15.667 16.007-26.61 4.003-10.94 6.003-24.275 6.003-40.021 0-14.408-1.4-27.416-4.202-39.019-2.8-11.607-7.406-21.542-13.808-29.816zm0 0"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M104.185 95.254c8.161 7.574 13.145 17.441 13.145 28.28 0 1.508-.098 2.998-.285 4.466h-10.784c.238-1.465.403-2.948.403-4.465 0-8.983-4.36-17.115-11.419-23.216C86 104.66 75.355 107.162 64 107.162c-11.344 0-21.98-2.495-31.22-6.83-7.064 6.099-11.444 14.218-11.444 23.203 0 1.517.165 3 .403 4.465H10.955a35.444 35.444 0 0 1-.285-4.465c0-10.838 4.974-20.713 13.127-28.291C9.294 85.42.003 70.417.003 53.58.003 23.99 28.656.001 64 .001s63.997 23.988 63.997 53.58c0 16.842-9.299 31.85-23.812 41.673zM64 36.867c-29.454 0-53.33-10.077-53.33 15.342 0 25.418 23.876 46.023 53.33 46.023 29.454 0 53.33-20.605 53.33-46.023 0-25.419-23.876-15.342-53.33-15.342zm24.888 25.644c-3.927 0-7.111-2.665-7.111-5.953 0-3.288 3.184-5.954 7.11-5.954 3.928 0 7.111 2.666 7.111 5.954s-3.183 5.953-7.11 5.953zm-3.556 16.372c0 4.11-9.55 7.442-21.332 7.442-11.781 0-21.332-3.332-21.332-7.442 0-1.06.656-2.064 1.8-2.976 3.295 2.626 10.79 4.465 19.532 4.465 8.743 0 16.237-1.84 19.531-4.465 1.145.912 1.801 1.916 1.801 2.976zm-46.22-16.372c-3.927 0-7.11-2.665-7.11-5.953 0-3.288 3.183-5.954 7.11-5.954 3.927 0 7.111 2.666 7.111 5.954s-3.184 5.953-7.11 5.953z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M95.648 118.762c0 5.035-3.563 9.121-7.979 9.121H7.98c-4.416 0-7.979-4.086-7.979-9.121C0 100.519 15.408 83.47 31.152 76.75c-9.099-6.43-15.216-17.863-15.216-30.987v-9.128c0-20.16 14.293-36.518 31.893-36.518s31.894 16.358 31.894 36.518v9.122c0 13.137-6.123 24.556-15.216 30.993 15.738 6.726 31.141 23.769 31.141 42.012z"/><path d="M106.032 118.252h15.867c3.376 0 6.101-3.125 6.101-6.972 0-13.957-11.787-26.984-23.819-32.123 6.955-4.919 11.638-13.66 11.638-23.704v-6.985c0-15.416-10.928-27.926-24.39-27.926-1.674 0-3.306.193-4.89.561 1.936 4.713 3.018 9.974 3.018 15.526v9.121c0 13.137-3.056 23.111-11.066 30.993 14.842 4.41 27.312 23.42 27.541 41.509z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1567417214476" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2266" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M761.503029 2.90619 242.121921 2.90619c-32.405037 0-58.932204 26.060539-58.932204 58.527998l0 902.302287c0 32.156374 26.217105 58.216913 58.932204 58.216913l519.381108 0c32.344662 0 58.591443-26.060539 58.591443-58.216913L820.094472 61.123103C820.094472 28.966729 793.847691 2.90619 761.503029 2.90619M452.878996 61.123103l98.147344 0c6.780427 0 12.31549 5.536087 12.31549 12.253068 0 6.748704-5.535063 12.253068-12.31549 12.253068l-98.147344 0c-6.779404 0-12.345166-5.504364-12.345166-12.253068C440.532807 66.659189 446.099592 61.123103 452.878996 61.123103M501.641583 980.593398c-29.636994 0-53.987588-23.946388-53.987588-53.677527 0-29.356608 24.039509-53.614082 53.987588-53.614082 29.91738 0 53.987588 23.883967 53.987588 53.614082C555.629171 956.647009 531.559986 980.593398 501.641583 980.593398M766.35657 803.142893c0 16.23373-13.186324 29.107945-29.233811 29.107945l-470.618521 0c-16.35755 0-29.325909-13.186324-29.325909-29.107945L237.178329 163.500794c0-16.232706 13.279445-29.138644 29.325909-29.138644l470.246037 0c16.420995 0 29.357632 13.1853 29.357632 29.138644l0 639.642099L766.35657 803.142893zM766.35657 803.142893" p-id="2267"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566035724641" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3998" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M136.4 434.3h77.7c21.5 0 38.9-17.4 38.9-38.9s-17.4-38.9-38.9-38.9h-77.7c-21.5 0-38.9 17.4-38.9 38.9s17.4 38.9 38.9 38.9zM252.9 628.6c0-21.5-17.4-38.9-38.9-38.9h-77.7c-21.5 0-38.9 17.4-38.9 38.9s17.4 38.9 38.9 38.9H214c21.5-0.1 38.9-17.5 38.9-38.9z" p-id="3999"></path><path d="M874.7 97.5H227c-28.6 0-51.8 23.2-51.8 51.8v194.3h38.9c28.6 0 51.8 23.2 51.8 51.8 0 28.6-23.2 51.8-51.8 51.8h-38.9v129.5h38.9c28.6 0 51.8 23.2 51.8 51.8 0 28.6-23.2 51.8-51.8 51.8h-38.9v194.3c0 28.6 23.2 51.8 51.8 51.8h647.7c28.6 0 51.8-23.2 51.8-51.8V149.3c0-28.6-23.2-51.8-51.8-51.8z m-311.3 723c-15.6 0-146.7-71.6-146.7-91 0-19.4 102-368.6 102-368.6l-83.6-104s-12.3-23.1 24.6-23.1h208.9c36.9 0 18.4 23.1 18.4 23.1l-79 104s102 351.3 102 368.6c0.1 17.3-131 91-146.6 91z m169.2-253.6l-27.9 40.2-74.5-240 103.4 171.7c4.6 7.9 4.2 20.6-1 28.1z" p-id="4000"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M18.448 57.545l-.244-.744-.198-.968-.132-.53v-2.181l.236-.859.24-.908.317-.953.428-1.06.561-1.103.794-1.104v-.773l.077-.724.123-.984.34-1.106.313-1.194.25-.548.289-.511.371-.569.405-.423v-2.73l.234-1.407.236-1.633.42-1.955.577-2.035.43-1.118.426-1.217.468-1.135.559-1.216.57-1.332.655-1.247.737-1.331.929-1.33.43-.762.457-.624.995-1.406 1.025-1.403 1.163-1.444 1.246-1.405 1.352-1.384 1.41-1.423 1.708-1.536 1.083-.934 1.322-1.008 1.34-.89 1.448-.855 1.392-.76 1.57-.63 1.667-.775 1.657-.532 1.653-.552 1.787-.548 1.785-.417 1.876-.347L59.128.68l1.879-.245 1.876-.252 2.002-.106h5.912l1.97.243 1.981.231 2.019.207 1.874.441 1.979.413 1.857.475 2.035.53 1.862.646 1.782.738 1.904.78 1.736.853 1.689.95 1.655 1.044 1.425.971.662.548.693.401 1.323 1.1 1.115 1.064 1.112 1.1 1.083 1.214.894 1.178 1.064 1.217.74 1.306.752 1.162.798 1.352.661 1.175 1.113 2.489.546 1.286.428 1.192.428 1.294.384 1.217.267 1.047.347 1.231.607 2.198.388 1.924.253 1.861.217 1.497.342 2.28.077.362.274.41.737 1.18.473.8.42.832.534.892.472 1.07.307 1.093.334 1.2.252 1.232.115.605.106.746v.648l-.106.643v.8l-.192.774-.35 1.5-.403.76-.299.852v.213l.142.264.4.623 1.746 2.53 1.377 1.9.66 1.267.889 1.389.774 1.52.893 1.627.894 1.828 1.006 2.069.567 1.268.518 1.239.447 1.307.44 1.175.336 1.235.342 1.16.432 2.261.343 2.31.235 2.05v2.891l-.158 1.025-.226 1.768-.308 1.59-.48 1.44-.18.588-.336.707-.28.493-.375.607-.33.383-.42.494-.375.4-.401.34-.48.207-.432.207-.355.114h-.543l-.346-.114-.66-.32-.302-.212-.317-.223-.347-.304-.35-.342-.579-.63-.684-.89-.539-.917-.538-.734-.526-.855-.741-1.517-.833-1.579-.098-.055h-.138l-.338.247-.196.415-.326.516-.567 1.533-.856 2.182-1.096 2.626-.824 1.308-.864 1.366-1.027 1.536-1.09 1.503-.557.68-.676.743-1.555 1.497.136.135.21.214.777.446 3.235 1.524 1.41.779 1.347.756 1.332.953 1.187.982.574.443.432.511.445.593.367.643.198.533.242.64.105.554.115.647-.115.433v.44l-.105.454-.242.415-.092.325-.22.394-.587.784-.543.627-.42.47-.35.348-.893.638-1.01.556-1.077.532-1.155.511-1.287.495-.693.207-.608.167-1.496.342-1.545.325-1.552.323-1.689.27-1.74.072-1.785.21h-5.539l-1.998-.114-1.86-.168-2.005-.27-1.99-.209-2.095-.286-2.03-.495-1.981-.374-1.968-.552-2.019-.707-1.98-.585-1.044-.342-.927-.323-.586-.223-.582-.12h-1.647l-1.904-.131-.962-.096-1.24-.135-.795.705-1.085.665-1.471.701-1.628.875-.99.475-1.033.376-2.281.914-1.24.305-1.3.343-1.803.344-1.13.086-1.193.1-1.246.135-1.45.053h-5.926l-3.346-.053-3.25-.321-1.644-.23-1.589-.23-1.546-.227-1.547-.305-1.442-.456-1.434-.325-1.294-.51-1.223-.474-1.142-.533-.99-.583-.984-.71-.336-.343-.44-.415-.334-.362-.3-.417-.278-.415-.215-.42-.311-.89-.109-.46-.138-.51v-.473l.138-.533v-.53l.109-.53v-1.069l.052-.564.259-.647.215-.646.39-.779.286-.3.236-.348.615-.738.49-.38.464-.266.428-.338.676-.21.543-.324.676-.341.77-.227.775-.231.897-.192.85-.11 1.008-.13 1.093-.081.284-.092h.063l.137-.115v-.13l-.2-.266-.58-.27-1.45-1.231-.975-.761-1.127-.967-1.136-1.082-1.181-1.382-1.36-1.558-.508-.843-.672-.87-.58-1.007-.522-1.1-.704-1.047-.459-1.194-.547-1.192-.546-1.33-.397-1.273-.378-1.575-.112-.057h-.115l-.059-.113h-.14l-.23.113-.114.057-.158.264-.057.321-.119.286-.206.477-.664 1.157-.345.701-.546.612-.58.736-.641.816-.677.724-.795.701-.734.658-.814.524-.89.546-.855.325-1.008.247-.99.095h-.233l-.228-.095-.18-.384-.29-.188-.38-.912-.237-.493-.255-.707-.21-.734-.113-.724-.313-1.648-.12-.972v-3.185l.12-2.379.196-1.214.23-1.252.21-1.347.374-1.254.42-1.443.431-1.407.578-1.448.545-1.38.754-1.4.699-1.52.855-1.425 1.006-1.538 1.023-1.382 1.069-1.538.891-1.071 1.142-1.227 1.202-1.237.56-.59.678-.662.985-.836 1.012-.853 1.647-1.446 1.242-.889z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1581238842264" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1409" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M512 0C229.233778 0 0 229.233778 0 512s229.233778 512 512 512 512-229.233778 512-512A512 512 0 0 0 512 0z m0 938.666667C276.366222 938.666667 85.333333 747.633778 85.333333 512 85.333333 276.366222 276.366222 85.333333 512 85.333333c235.633778 0 426.666667 191.032889 426.666667 426.666667a426.666667 426.666667 0 0 1-426.666667 426.666667z m0-717.653334a170.666667 170.666667 0 0 0-170.666667 170.666667 42.666667 42.666667 0 0 0 85.333334 0 85.333333 85.333333 0 1 1 85.333333 85.333333 42.666667 42.666667 0 0 0-42.666667 42.666667v111.36a42.666667 42.666667 0 0 0 85.333334 0v-74.24A170.666667 170.666667 0 0 0 512 221.013333z m-42.666667 542.293334a42.666667 42.666667 0 1 0 85.333334 0 42.666667 42.666667 0 0 0-85.333334 0z" p-id="1410"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575966775973" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="879" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M507.39346659 71.84873358c241.53533667 0 437.39770766 195.85422109 437.39770767 437.37442191 0 241.53766571-195.86237099 437.38955776-437.39770767 437.38955776-241.50040803 0-437.34997219-195.85189205-437.34997219-437.38955776C70.0434944 267.70295467 265.89189347 71.84873358 507.39346659 71.84873358L507.39346659 71.84873358zM507.39346659 282.81899805c-125.00686734 0-226.37039389 101.38914133-226.37039388 226.41813048 0 125.01268821 101.36352768 226.39717262 226.37039388 226.39717262 125.04295993 0 226.42395136-101.38448441 226.42395136-226.39717262C733.81625401 384.20813938 632.43642653 282.81899805 507.39346659 282.81899805L507.39346659 282.81899805zM507.39346659 120.78172615c-214.46664192 0-388.42047261 173.95150279-388.4204726 388.44026539 0 214.51204949 173.95499463 388.46122325 388.4204726 388.46122325 214.52369237 0 388.46005817-173.94800981 388.46005818-388.46122325C895.85236082 294.73322894 721.91715897 120.78172615 507.39346659 120.78172615z" p-id="880"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577246781606" class="icon" viewBox="0 0 1069 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1098" xmlns:xlink="http://www.w3.org/1999/xlink" width="84.5595703125" height="81"><defs><style type="text/css"></style></defs><path d="M633.72929961 378.02038203l9.49872568 18.68789795 20.78025469 2.79745225 206.61592412 27.33248408a11.46496817 11.46496817 0 0 1 6.6095543 19.47324902l-147.2675168 147.35350284-14.89299345 14.89299345 3.8006376 20.68280244 37.84585956 204.89044571a11.46496817 11.46496817 0 0 1-16.4808914 12.2961788L554.68980898 751.84713388l-18.68789794-9.49299345-18.48726123 9.99171915-183.23885392 99.34968163a11.46496817 11.46496817 0 0 1-16.78471347-11.8662416l32.5433127-205.79617881 3.29617793-20.78598692-15.19108243-14.49172002-151.03375839-143.48407587a11.46496817 11.46496817 0 0 1 6.09936328-19.63949062l205.79617881-32.63503185 20.78598691-3.2961788L428.87898125 380.72038203 518.59235674 192.64331182a11.46496817 11.46496817 0 0 1 20.56815264-0.26369385l94.56879023 185.63503183zM496.64840732 85.52038203l-121.75796162 254.98089229L95.76433145 384.76178369A34.3949045 34.3949045 0 0 0 77.46050938 443.66879023l204.87324901 194.66369385-44.16879023 279.1146498a34.3949045 34.3949045 0 0 0 50.36560489 35.61592325l248.4-134.67898038 251.84522285 128.27579591a34.3949045 34.3949045 0 0 0 49.43694287-36.89426777l-51.30573223-277.85350284 199.73120977-199.90891758a34.3949045 34.3949045 0 0 0-19.82866201-58.40827998l-280.11783428-37.03184736L558.32993633 84.71210205a34.3949045 34.3949045 0 0 0-61.68152901 0.80254775z" p-id="1099"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1656035183065" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3395" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); } |
| | | </style></defs><path d="M958.88 730.06H65.12c-18.28 0-33.12-14.82-33.12-33.12V68.91c0-18.29 14.83-33.12 33.12-33.12h893.77c18.28 0 33.12 14.82 33.12 33.12v628.03c-0.01 18.3-14.84 33.12-33.13 33.12zM98.23 663.83h827.53v-561.8H98.23v561.8z" p-id="3396"></path><path d="M512 954.55c-18.28 0-33.12-14.82-33.12-33.12V733.92c0-18.29 14.83-33.12 33.12-33.12s33.12 14.82 33.12 33.12v187.51c0 18.3-14.84 33.12-33.12 33.12z" p-id="3397"></path><path d="M762.01 988.21H261.99c-18.28 0-33.12-14.82-33.12-33.12 0-18.29 14.83-33.12 33.12-33.12h500.03c18.28 0 33.12 14.82 33.12 33.12-0.01 18.29-14.84 33.12-33.13 33.12zM514.74 578.55c-21.63 0-43.31-3.87-64.21-11.65-45.95-17.13-82.49-51.13-102.86-95.74-5.07-11.08-0.19-24.19 10.89-29.26 11.08-5.09 24.19-0.18 29.26 10.91 15.5 33.88 43.25 59.7 78.14 72.71 34.93 12.99 72.79 11.64 106.66-3.85 33.22-15.17 58.8-42.26 72.03-76.3 4.42-11.37 17.21-17.01 28.57-12.58 11.36 4.42 16.99 17.22 12.57 28.58-17.42 44.82-51.1 80.5-94.82 100.47-24.34 11.12-50.25 16.71-76.23 16.71z" p-id="3398"></path><path d="M325.27 528.78c-1.66 0-3.34-0.18-5.02-0.57-11.88-2.77-19.28-14.63-16.49-26.51l18.84-81c1.34-5.82 5-10.84 10.13-13.92 5.09-3.09 11.3-3.96 17.03-2.41l80.51 21.43c11.79 3.14 18.8 15.23 15.67 27.02-3.15 11.79-15.42 18.75-27.02 15.65l-58.49-15.57-13.69 58.81c-2.37 10.2-11.45 17.07-21.47 17.07zM360.8 351.01c-2.65 0-5.37-0.49-8-1.51-11.36-4.41-16.99-17.21-12.59-28.57 17.4-44.79 51.06-80.47 94.8-100.48 92.15-42.06 201.25-1.39 243.31 90.68 5.07 11.08 0.19 24.19-10.89 29.26-11.13 5.07-24.19 0.17-29.26-10.91-31.97-69.91-114.9-100.82-184.79-68.86-33.22 15.19-58.8 42.28-71.99 76.29-3.41 8.74-11.75 14.1-20.59 14.1z" p-id="3399"></path><path d="M684.68 376.74c-1.47 0-2.95-0.15-4.42-0.44l-81.61-16.68c-11.94-2.45-19.64-14.11-17.21-26.06 2.44-11.96 14.1-19.64 26.04-17.22l59.29 12.12 10.23-59.5c2.05-12 13.52-20.19 25.48-18.01 12.03 2.06 20.09 13.48 18.02 25.5l-14.08 81.96a22.089 22.089 0 0 1-9.29 14.49c-3.7 2.51-8.03 3.84-12.45 3.84z" p-id="3400"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1605865043777" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="856" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M1023.786667 611.84c-0.426667 9.770667-13.354667 20.693333-39.893334 34.56-54.613333 28.458667-337.749333 144.896-397.994666 176.298667-60.288 31.402667-93.738667 31.104-141.354667 8.32-47.616-22.741333-348.842667-144.469333-403.114667-170.368-27.093333-12.970667-40.917333-23.893333-41.386666-34.218667v103.509333c0 10.325333 14.250667 21.290667 41.386666 34.261334 54.272 25.941333 355.541333 147.626667 403.114667 170.368 47.616 22.784 81.066667 23.082667 141.354667-8.362667 60.245333-31.402667 343.338667-147.797333 397.994666-176.298667 27.776-14.464 40.106667-25.728 40.106667-35.925333v-102.058667l-0.213333-0.085333z m0-168.746667c-0.512 9.770667-13.397333 20.650667-39.893334 34.517334-54.613333 28.458667-337.749333 144.896-397.994666 176.298666-60.288 31.402667-93.738667 31.104-141.354667 8.362667-47.616-22.741333-348.842667-144.469333-403.114667-170.410667-27.093333-12.928-40.917333-23.893333-41.386666-34.176v103.509334c0 10.325333 14.250667 21.248 41.386666 34.218666 54.272 25.941333 355.498667 147.626667 403.114667 170.368 47.616 22.784 81.066667 23.082667 141.354667-8.32 60.245333-31.402667 343.338667-147.84 397.994666-176.298666 27.776-14.506667 40.106667-25.770667 40.106667-35.968v-102.058667l-0.256-0.042667z m0-175.018666c0.469333-10.410667-13.141333-19.541333-40.533334-29.610667-53.248-19.498667-334.634667-131.498667-388.522666-151.253333-53.888-19.712-75.818667-18.901333-139.093334 3.84C392.234667 113.706667 92.629333 231.253333 39.338667 252.074667c-26.666667 10.496-39.68 20.181333-39.253334 30.506666V386.133333c0 10.325333 14.250667 21.248 41.386667 34.218667 54.272 25.941333 355.498667 147.669333 403.114667 170.410667 47.616 22.741333 81.066667 23.04 141.354666-8.362667 60.245333-31.402667 343.338667-147.84 397.994667-176.298667 27.776-14.506667 40.106667-25.770667 40.106667-35.968V268.074667h-0.341334zM366.677333 366.08l237.269334-36.437333-71.68 105.088-165.546667-68.650667z m524.8-94.634667l-140.330666 55.466667-15.232 5.973333-140.245334-55.466666 155.392-61.44 140.373334 55.466666z m-411.989333-101.674666l-22.954667-42.325334 71.594667 27.989334 67.498667-22.101334-18.261334 43.733334 68.778667 25.770666-88.704 9.216-19.882667 47.786667-32.085333-53.290667-102.4-9.216 76.416-27.562666z m-176.768 59.733333c70.058667 0 126.805333 21.973333 126.805333 49.109333s-56.746667 49.152-126.805333 49.152-126.848-22.058667-126.848-49.152c0-27.136 56.789333-49.152 126.848-49.152z" p-id="857"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1579339929870" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1182" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M152 854.856875h325.7146875V237.715625H134.856875v600q0 6.99375 5.0746875 12.0684375T152 854.856875z m737.143125-17.1421875v-600H546.284375v617.1421875H872q6.99375 0 12.0684375-5.07375t5.0746875-12.0684375z m68.5715625-651.429375V837.715625q0 35.3821875-25.16625 60.5484375T872 923.4284375H152q-35.383125 0-60.5484375-25.1653125T66.284375 837.7146875V186.284375q0-35.3821875 25.16625-60.5484375T152 100.5715625h720q35.383125 0 60.5484375 25.1653125t25.16625 60.5484375z" p-id="1183"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M124.884 109.812L94.256 79.166c-.357-.357-.757-.629-1.129-.914a50.366 50.366 0 0 0 8.186-27.59C101.327 22.689 78.656 0 50.67 0 22.685 0 0 22.688 0 50.663c0 27.989 22.685 50.663 50.656 50.663 10.186 0 19.643-3.03 27.6-8.201.286.385.557.771.9 1.114l30.628 30.632a10.633 10.633 0 0 0 7.543 3.129c2.728 0 5.457-1.043 7.543-3.115 4.171-4.157 4.171-10.915.014-15.073M50.671 85.338C31.557 85.338 16 69.78 16 50.663c0-19.102 15.557-34.661 34.67-34.661 19.115 0 34.657 15.559 34.657 34.675 0 19.102-15.557 34.661-34.656 34.661"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575803481213" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="804" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M62 511.97954521C62 263.86590869 263.90681826 62 511.97954521 62s449.97954521 201.825 449.97954521 449.97954521c0 248.19545479-201.90681826 449.97954521-449.97954521 449.97954521C263.90681826 962 62 760.175 62 511.97954521M901.98636348 511.97954521c0-215.24318174-175.00909131-390.41590869-390.00681827-390.41590869-215.03863652 0-389.96590869 175.17272695-389.96590868 390.41590869 0 215.28409131 175.00909131 390.45681826 389.96590868 390.45681826C727.01818174 902.47727305 901.98636348 727.30454521 901.98636348 511.97954521M264.17272695 430.28409131c0-5.76818174 2.12727305-11.51590869 6.64772696-15.87272696 8.71363652-8.75454521 22.88863652-8.75454521 31.725 0l209.4340913 208.22727305L721.45454521 414.53409131c8.75454521-8.71363652 22.97045479-8.71363652 31.90909132 0 8.71363652 8.75454521 8.71363652 22.88863652 0 31.60227304L511.97954521 685.74090869 270.71818174 446.01363653C266.27954521 441.77954521 264.17272695 436.05227305 264.17272695 430.28409131" p-id="805"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1547360688278" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M890 120H134a70 70 0 0 0-70 70v500a70 70 0 0 0 70 70h756a70 70 0 0 0 70-70V190a70 70 0 0 0-70-70z m-10 520a40 40 0 0 1-40 40H712V448a40 40 0 0 0-80 0v232h-80V368a40 40 0 0 0-80 0v312h-80V512a40 40 0 0 0-80 0v168H184a40 40 0 0 1-40-40V240a40 40 0 0 1 40-40h656a40 40 0 0 1 40 40zM696 824H328a40 40 0 0 0 0 80h368a40 40 0 0 0 0-80z" p-id="6718"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M42.913 101.36c1.642 0 3.198.332 4.667.996a12.28 12.28 0 0 1 3.89 2.772c1.123 1.184 1.987 2.582 2.592 4.193.605 1.612.908 3.318.908 5.118 0 1.8-.303 3.507-.908 5.118-.605 1.611-1.469 3.01-2.593 4.194a13.3 13.3 0 0 1-3.889 2.843 10.582 10.582 0 0 1-4.667 1.066c-1.729 0-3.306-.355-4.732-1.066a13.604 13.604 0 0 1-3.825-2.843c-1.123-1.185-1.988-2.583-2.593-4.194a14.437 14.437 0 0 1-.907-5.118c0-1.8.302-3.506.907-5.118.605-1.61 1.47-3.009 2.593-4.193a12.515 12.515 0 0 1 3.825-2.772c1.426-.664 3.003-.996 4.732-.996zm53.932.285c1.643 0 3.22.331 4.733.995a11.386 11.386 0 0 1 3.889 2.772c1.08 1.185 1.945 2.583 2.593 4.194.648 1.61.972 3.317.972 5.118 0 1.8-.324 3.506-.972 5.117-.648 1.611-1.513 3.01-2.593 4.194a12.253 12.253 0 0 1-3.89 2.843 11 11 0 0 1-4.732 1.066 10.58 10.58 0 0 1-4.667-1.066 12.478 12.478 0 0 1-3.824-2.843c-1.08-1.185-1.945-2.583-2.593-4.194a13.581 13.581 0 0 1-.973-5.117c0-1.801.325-3.507.973-5.118.648-1.611 1.512-3.01 2.593-4.194a11.559 11.559 0 0 1 3.824-2.772 11.212 11.212 0 0 1 4.667-.995zm21.781-80.747c2.42 0 4.3.355 5.64 1.066 1.34.71 2.29 1.587 2.852 2.63a6.427 6.427 0 0 1 .778 3.34c-.044 1.185-.195 2.204-.454 3.057-.26.853-.8 2.606-1.62 5.26a589.268 589.268 0 0 1-2.788 8.743 1236.373 1236.373 0 0 0-3.047 9.453c-.994 3.128-1.75 5.592-2.269 7.393-1.123 3.79-2.55 6.42-4.278 7.89-1.728 1.469-3.846 2.203-6.352 2.203H39.023l1.945 12.795h65.342c4.148 0 6.223 1.943 6.223 5.828 0 1.896-.41 3.53-1.232 4.905-.821 1.374-2.442 2.061-4.862 2.061H38.505c-1.729 0-3.176-.426-4.343-1.28-1.167-.852-2.14-1.966-2.917-3.34a21.277 21.277 0 0 1-1.88-4.478 44.128 44.128 0 0 1-1.102-4.55c-.087-.568-.324-1.942-.713-4.122-.39-2.18-.865-4.904-1.426-8.174l-1.88-10.947c-.692-4.027-1.383-8.079-2.075-12.154-1.642-9.572-3.5-20.234-5.574-31.986H6.87c-1.296 0-2.377-.356-3.24-1.067a9.024 9.024 0 0 1-2.14-2.558 10.416 10.416 0 0 1-1.167-3.2C.108 8.53 0 7.488 0 6.54c0-1.896.583-3.46 1.75-4.69C2.917.615 4.494 0 6.482 0h13.095c1.728 0 3.111.284 4.148.853 1.037.569 1.858 1.28 2.463 2.132a8.548 8.548 0 0 1 1.297 2.701c.26.948.475 1.754.648 2.417.173.758.346 1.825.519 3.199.173 1.374.345 2.772.518 4.193.26 1.706.519 3.507.778 5.403h88.678z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h54.796v18.286H36.531V128H18.265V73.143H0V54.857zm127.857-36.571H91.935V128H72.456V18.286H36.534V0h91.326l-.003 18.286z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M31.652 93.206h33.401c1.44 2.418 3.077 4.663 4.93 6.692h-38.33v-6.692zm0-10.586h28.914a44.8 44.8 0 0 1-1.264-6.688h-27.65v6.688zm0-17.27H59.39c.288-2.286.714-4.532 1.34-6.687H31.65v6.687h.003zm53.913 44.84v5.85c0 2.798-2.095 5.075-4.667 5.075h-70.07c-2.576 0-4.663-2.277-4.663-5.075V31.26l23.22-20.96v22.25H17.16v6.688h18.39V6.688h45.348c2.576 0 4.667 2.277 4.667 5.066v20.009c1.987-.675 4.053-1.128 6.17-1.445v-18.56C91.738 5.28 86.874 0 80.902 0H31.15L0 28.118v87.917c0 6.48 4.859 11.759 10.832 11.759h70.07c5.974 0 10.837-5.27 10.837-11.759v-4.41c-2.117-.312-4.183-.765-6.17-1.435h-.004zM23.279 58.667h-7.96v6.688h7.96v-6.688zm-7.956 41.23h7.96v-6.691h-7.96v6.692zm7.956-23.96h-7.96v6.687h7.96v-6.688zm89.718-15.042l-4.896-4.07-12.447 17.613-11.19-9.305-3.762 5.311 16.091 13.38 16.204-22.929zM128 70.978c0-18.632-13.97-33.782-31.147-33.782-17.168 0-31.135 15.155-31.135 33.782 0 18.628 13.97 33.783 31.135 33.783 17.172 0 31.143-15.15 31.143-33.783H128zm-6.17 0c0 14.933-11.203 27.1-24.981 27.1-13.77 0-24.987-12.158-24.987-27.1 0-14.941 11.195-27.099 24.987-27.099 13.778 0 24.982 12.158 24.982 27.1z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577185310368" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1238" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M951.453125 476.84375H523.671875a131.8359375 131.8359375 0 0 0-254.1796875 0H72.546875v70.3125h196.9453125a131.8359375 131.8359375 0 0 0 254.1796875 0H951.453125z" p-id="1239"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M70.66 4.328l14.01 29.693c1.088 2.29 3.177 3.882 5.603 4.25l31.347 4.76c6.087.926 8.528 8.756 4.117 13.247L103.05 79.395c-1.75 1.78-2.544 4.352-2.132 6.867l5.352 32.641c1.043 6.337-5.33 11.182-10.778 8.19l-28.039-15.409a7.13 7.13 0 0 0-6.91 0l-28.039 15.41c-5.448 2.99-11.821-1.854-10.777-8.19l5.352-32.642c.415-2.515-.387-5.088-2.136-6.867L2.264 56.278C-2.146 51.787.286 43.957 6.38 43.031l31.343-4.76c2.419-.368 4.51-1.96 5.595-4.25L57.334 4.328c2.728-5.77 10.605-5.77 13.325 0z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1733303115132" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12397" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 890.432c18.432 0 33.408 14.976 33.408 33.408v66.752a33.408 33.408 0 0 1-66.816 0v-66.752c0-18.432 14.976-33.408 33.408-33.408z m-267.52-110.848a33.408 33.408 0 0 1 0 47.232l-47.296 47.232a33.408 33.408 0 0 1-47.232-47.232l47.232-47.232a33.408 33.408 0 0 1 47.232 0z m582.336 0l47.232 47.232a33.408 33.408 0 0 1-47.232 47.232l-47.232-47.232a33.408 33.408 0 1 1 47.232-47.232zM512 200.32a311.68 311.68 0 1 1 0 623.296 311.68 311.68 0 0 1 0-623.36z m0 66.752a244.864 244.864 0 1 0 0 489.728 244.864 244.864 0 0 0 0-489.728zM100.16 478.592a33.408 33.408 0 1 1 0 66.816H33.408a33.408 33.408 0 0 1 0-66.816h66.752z m890.432 0a33.408 33.408 0 0 1 0 66.816h-66.752a33.408 33.408 0 1 1 0-66.816h66.752zM197.184 149.952l47.232 47.232a33.408 33.408 0 1 1-47.232 47.232l-47.232-47.232a33.408 33.408 0 0 1 47.232-47.232z m676.864 0a33.408 33.408 0 0 1 0 47.232l-47.232 47.232a33.408 33.408 0 1 1-47.232-47.232l47.232-47.232a33.408 33.408 0 0 1 47.232 0zM512 0c18.432 0 33.408 14.976 33.408 33.408v66.752a33.408 33.408 0 1 1-66.816 0V33.408C478.592 14.976 493.568 0 512 0z" p-id="12398"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036776944" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6463" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M64 223.995345h168.001164v47.997673c0 26.428509 18.878836 47.997673 41.984 47.997673h140.036654c23.095855 0 41.984-21.569164 41.984-47.997673v-47.997673h504.003491a32.004655 32.004655 0 0 0 0-64.009309H455.996509V111.988364c0-26.428509-18.878836-47.997673-41.984-47.997673H273.985164c-23.095855 0-41.984 21.569164-41.984 47.997673v47.997672H64a32.004655 32.004655 0 0 0 0 64.009309zM288.004655 128h111.997672V256H288.004655V128zM960 479.995345H791.998836v-47.997672c0-26.372655-18.878836-47.997673-41.984-47.997673H609.978182c-23.095855 0-41.984 21.634327-41.984 47.997673v47.997672H64a32.004655 32.004655 0 0 0 0 64.00931h504.003491v47.997672c0 26.363345 18.878836 47.997673 41.984 47.997673h140.036654c23.095855 0 41.984-21.634327 41.984-47.997673v-47.997672h168.001164a32.004655 32.004655 0 1 0-0.009309-64.00931zM735.995345 576H623.997673v-128h111.997672v128zM960 800.293236v-0.288581H455.996509v-47.997673c0-26.363345-18.878836-47.997673-41.984-47.997673H274.050327c-23.105164 0-41.984 21.634327-41.984 47.997673v47.997673H64v0.288581a32.004655 32.004655 0 0 0 0 64.009309c0.986764 0 1.917673-0.195491 2.885818-0.288581h165.115346v47.997672c0 26.363345 18.878836 47.997673 41.984 47.997673h140.036654c23.095855 0 41.984-21.634327 41.984-47.997673v-47.997672h501.108364c0.968145 0.093091 1.899055 0.288582 2.895127 0.288581a32.004655 32.004655 0 1 0-0.009309-64.009309zM400.002327 896H288.004655V768h111.997672v128z" fill="" p-id="6464"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1576042673958" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1110" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M692 792H332c-150 0-270-120-270-270s120-270 270-270h360c150 0 270 120 270 270 0 147-120 270-270 270zM332 312c-117 0-210 93-210 210s93 210 210 210h360c117 0 210-93 210-210s-93-210-210-210H332z" p-id="1111"></path><path d="M341 522m-150 0a150 150 0 1 0 300 0 150 150 0 1 0-300 0Z" p-id="1112"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1543827724451" class="icon" style="" viewBox="0 0 1084 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10233" xmlns:xlink="http://www.w3.org/1999/xlink" width="211.71875" height="200"><defs><style type="text/css">@font-face { font-family: rbicon; src: url("chrome-extension://dipiagiiohfljcicegpgffpbnjmgjcnf/fonts/rbicon.woff2") format("woff2"); font-weight: normal; font-style: normal; } |
| | | </style></defs><path d="M1080.09609 434.500756c-4.216302-23.731757-26.9241-47.945376-50.595623-53.185637l-17.648235-4.095836a175.940257 175.940257 0 0 1-101.612877-80.832531 177.807476 177.807476 0 0 1-18.732427-129.801867l5.541425-16.684509c7.10748-23.129428-2.108151-54.992624-20.599646-70.833873 0 0-16.624276-14.094495-63.244529-41.199293-46.800951-26.984332-66.858502-34.513443-66.858502-34.513443-22.76803-8.372371-54.631227-0.361397-71.255503 17.407304l-12.287509 13.251234a173.470708 173.470708 0 0 1-120.465769 48.065842A174.13327 174.13327 0 0 1 421.329029 33.590675L409.583617 20.761071C393.140039 2.99237 361.096144-4.898138 338.267881 3.353767c0 0-20.358715 7.529111-67.099434 34.513443-46.800951 27.34573-63.244529 41.440225-63.244529 41.440225-18.431263 15.66055-27.646894 47.222582-20.539413 70.592941l5.059562 16.865207a178.048407 178.048407 0 0 1-18.672194 129.621169 174.916297 174.916297 0 0 1-102.275439 81.073463l-17.045906 3.854904c-23.310126 5.42096-46.258856 29.333415-50.595623 53.185637 0 0-3.854905 21.382674-3.854905 75.712737 0 54.330062 3.854905 75.712736 3.854905 75.712736 4.216302 23.972688 26.9241 47.945376 50.595623 53.185637l16.624276 3.854905a174.253736 174.253736 0 0 1 102.395904 81.314394c23.310126 40.837896 28.911785 87.337683 18.732427 129.801867l-4.81863 16.443578c-7.10748 23.129428 2.108151 54.992624 20.599646 70.833872 0 0 16.624276 14.094495 63.244529 41.199293 46.800951 27.104798 66.918735 34.513443 66.918735 34.513443 22.707798 8.372371 54.631227 0.361397 71.255503-17.407303l11.624947-12.588673a175.096996 175.096996 0 0 1 242.256662 0.120465l11.624947 12.648906c16.383345 17.708468 48.427239 25.598976 71.255503 17.347071 0 0 20.358715-7.529111 67.159666-34.513443 46.740719-27.104798 63.124063-41.199293 63.124064-41.199293 18.491496-15.600317 27.707127-47.463513 20.599646-70.833873l-5.059562-17.106139a176.723284 176.723284 0 0 1 18.672194-129.139305 176.060722 176.060722 0 0 1 102.395904-81.314394l16.68451-3.854905c23.310126-5.42096 46.258856-29.333415 50.595623-53.185637 0 0 3.854905-21.382674 3.854904-75.712737-0.240932-54.330062-4.095836-75.833202-4.095836-75.833202z m-537.819428 293.334149c-119.261112 0-216.175824-97.336342-216.175824-217.621412a216.657687 216.657687 0 0 1 216.236057-217.320249c119.200879 0 216.115591 97.276109 216.11559 217.56118-0.240932 120.044139-96.974945 217.320248-216.175823 217.320249z" p-id="10234"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.921.052H49.08c-1.865 0-3.198 1.599-3.198 3.464v6.661c0 1.865 1.6 3.464 3.198 3.464h29.84c1.865 0 3.198-1.599 3.198-3.464V3.516C82.385 1.65 80.786.052 78.92.052zm45.563 0H94.642c-1.865 0-3.464 1.599-3.464 3.464v6.661c0 1.865 1.599 3.464 3.464 3.464h29.842c1.865-.266 3.464-1.599 3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464zm0 22.382H40.02c-1.866 0-3.464-1.599-3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464H3.516C1.65.052.052 1.651.052 3.516V124.75c0 1.598 1.599 3.197 3.464 3.197h120.968c1.865 0 3.464-1.599 3.464-3.464V25.898c0-1.865-1.599-3.464-3.464-3.464z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575802855098" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2984" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M896 160H128c-35.2 0-64 28.8-64 64v576c0 35.2 28.8 64 64 64h768c35.2 0 64-28.8 64-64V224c0-35.2-28.8-64-64-64z m0 608c0 16-12.8 32-32 32H160c-19.2 0-32-12.8-32-32V256c0-16 12.8-32 32-32h704c19.2 0 32 12.8 32 32v512z" p-id="2985"></path><path d="M224 288c-19.2 0-32 12.8-32 32v256c0 16 12.8 32 32 32s32-12.8 32-32V320c0-16-12.8-32-32-32z m608 480c19.2 0 32-12.8 32-32V608L704 768h128z" p-id="2986"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M125.5 36.984L95.336 2.83C93.735 1.018 91.565 0 89.3 0c-2.263 0-4.433 1.018-6.033 2.83l-3.786 4.286c-1.6 1.812-3.77 2.83-6.032 2.831H54.553c-2.263 0-4.434-1.018-6.033-2.83L44.734 2.83C43.134 1.018 40.964 0 38.701 0c-2.263 0-4.434 1.018-6.034 2.83L2.5 36.984C.9 38.796 0 41.254 0 43.815c0 2.562.899 5.02 2.5 6.831L14.565 64.31c2.178 2.468 5.367 3.403 8.33 2.444 1.35-.435 2.709.592 2.709 2.18v49.407c0 5.313 3.84 9.66 8.532 9.66h59.726c4.693 0 8.532-4.347 8.532-9.66V68.934c0-1.59 1.36-2.616 2.71-2.181 2.962.96 6.15.024 8.329-2.444L125.5 50.646c1.6-1.811 2.499-4.269 2.499-6.83 0-2.563-.899-5.02-2.5-6.832z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1579774825624" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1248" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M498.595712 482.290351 345.420077 482.290351l0 57.307194 210.477712 0L555.897789 274.196942l-57.301054 0L498.596735 482.290351zM498.595712 482.290351" p-id="1249"></path><path d="M577.685002 644.98478l379.879913 0 0 57.302077L577.685002 702.286858 577.685002 644.98478 577.685002 644.98478zM577.685002 644.98478" p-id="1250"></path><path d="M577.685002 773.764795l379.879913 0 0 57.307194L577.685002 831.071989 577.685002 773.764795 577.685002 773.764795zM577.685002 773.764795" p-id="1251"></path><path d="M577.685002 902.549927l379.879913 0 0 57.307194L577.685002 959.857121 577.685002 902.549927 577.685002 902.549927zM577.685002 902.549927" p-id="1252"></path><path d="M102.523001 382.290823c4.450359 2.615571 9.470699 3.954055 14.530948 3.954055 2.969635 0 5.952572-0.461511 8.836249-1.394766l190.809767-61.886489c15.052834-4.882194 23.297612-21.040199 18.415418-36.08894-4.882194-15.052834-21.040199-23.297612-36.093033-18.415418L175.676092 308.458257c15.994276-26.115797 35.170011-50.537 57.370639-72.743768 73.767074-73.767074 171.845857-114.388237 276.16783-114.388237 104.32095 0 202.39564 40.622186 276.16169 114.388237s114.393353 171.845857 114.393353 276.16783c0 26.427906-2.615571 52.449559-7.709589 77.780481l58.302871 0c4.464685-25.499767 6.708795-51.470255 6.708795-77.780481 0-60.449767-11.845793-119.102608-35.204803-174.336584-22.559808-53.334719-54.850236-101.226472-95.968725-142.349055-41.122583-41.122583-89.017406-73.408917-142.348032-95.968725C628.317169 75.866898 569.659211 64.021106 509.215584 64.021106c-60.448744 0-119.106702 11.845793-174.336584 35.207873-53.334719 22.559808-101.230566 54.846142-142.349055 95.968725-23.980157 23.980157-44.934398 50.278103-62.727647 78.601172l-20.738323-105.655342c-3.043313-15.527648-18.105357-25.642007-33.631982-22.599717-15.527648 3.048429-25.64303 18.105357-22.599717 33.637098l36.102243 183.932126C90.51348 371.153158 95.460142 378.13313 102.523001 382.290823L102.523001 382.290823zM102.523001 382.290823" p-id="1253"></path><path d="M126.020158 587.9416 67.768453 587.9416c5.759167 33.679054 15.368012 66.544579 28.789697 98.278327 22.559808 53.333696 54.850236 101.225449 95.971795 142.348032 41.122583 41.122583 89.014336 73.408917 142.349055 95.968725 54.112432 22.88829 111.517863 34.71157 170.668031 35.18229L505.547031 902.395408c-102.94972-0.941442-199.594851-41.445948-272.499277-114.349351C177.545672 732.543975 140.810003 663.275355 126.020158 587.9416L126.020158 587.9416zM126.020158 587.9416" p-id="1254"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577099827399" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1008" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M520 559h204c17.673 0 32 14.327 32 32 0 17.673-14.327 32-32 32H488c-17.673 0-32-14.327-32-32 0-0.167 0.001-0.334 0.004-0.5a32.65 32.65 0 0 1-0.004-0.5V277c0-17.673 14.327-32 32-32 17.673 0 32 14.327 32 32v282z m-8 401C264.576 960 64 759.424 64 512S264.576 64 512 64s448 200.576 448 448-200.576 448-448 448z m0-64c212.077 0 384-171.923 384-384S724.077 128 512 128 128 299.923 128 512s171.923 384 384 384z" p-id="1009"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1553828490559" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1684" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M898.831744 900.517641 103.816972 900.517641c-36.002982 0-65.363683-29.286-65.363683-65.313541l0-554.949184c0-36.041868 29.361725-65.326844 65.363683-65.326844l795.015795 0c36.002982 0 65.198931 29.284977 65.198931 65.326844l0 554.949184C964.030675 871.231641 934.834726 900.517641 898.831744 900.517641L898.831744 900.517641zM103.816972 255.593236c-13.576203 0-24.711821 11.085476-24.711821 24.662703l0 554.949184c0 13.576203 11.136641 24.662703 24.711821 24.662703l795.015795 0c13.577227 0 24.547069-11.086499 24.547069-24.662703l0-554.949184c0-13.577227-10.970866-24.662703-24.547069-24.662703L103.816972 255.593236 103.816972 255.593236zM664.346245 251.774257c-11.161201 0-20.332071-9.080819-20.332071-20.332071l0-101.278661c0-13.576203-11.047614-24.623817-24.699542-24.623817L383.181611 105.539708c-13.576203 0-24.712845 11.04659-24.712845 24.623817l0 101.278661c0 11.252275-9.041934 20.332071-20.332071 20.332071-11.20111 0-20.319791-9.080819-20.319791-20.332071l0-101.278661c0-35.989679 29.323862-65.275679 65.364707-65.275679l236.133022 0c36.06745 0 65.402569 29.284977 65.402569 65.275679l0 101.278661C684.717202 242.694461 675.636383 251.774257 664.346245 251.774257L664.346245 251.774257zM413.233044 521.725502 75.694471 521.725502c-11.163247 0-20.333094-9.117658-20.333094-20.35663 0-11.252275 9.169847-20.332071 20.333094-20.332071l337.538573 0c11.277858 0 20.319791 9.080819 20.319791 20.332071C433.552835 512.607844 424.510902 521.725502 413.233044 521.725502L413.233044 521.725502zM912.894018 521.725502 575.367725 521.725502c-11.213389 0-20.332071-9.117658-20.332071-20.35663 0-11.252275 9.118682-20.332071 20.332071-20.332071l337.526293 0c11.290137 0 20.332071 9.080819 20.332071 20.332071C933.226089 512.607844 924.184155 521.725502 912.894018 521.725502L912.894018 521.725502zM557.56322 634.217552 445.085496 634.217552c-11.213389 0-20.332071-9.079796-20.332071-20.331048l0-168.763658c0-11.251252 9.118682-20.332071 20.332071-20.332071l112.478747 0c11.290137 0 20.370956 9.080819 20.370956 20.332071l0 168.763658C577.934177 625.137757 568.853357 634.217552 557.56322 634.217552L557.56322 634.217552zM465.417567 593.514525l71.827909 0L537.245476 465.454918l-71.827909 0L465.417567 593.514525 465.417567 593.514525z" p-id="1685"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M44.8 0h79.543C126.78 0 128 1.422 128 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H44.8c-2.438 0-3.657-1.422-3.657-4.267V4.267C41.143 1.422 42.362 0 44.8 0zm22.857 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 80 64 78.578 64 75.733V52.267C64 49.422 65.219 48 67.657 48zm0 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 128 64 126.578 64 123.733v-23.466C64 97.422 65.219 96 67.657 96zM50.286 68.267c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V32h6.4c2.02 0 3.658-1.91 3.658-4.267V4.267C27.429 1.91 25.79 0 23.77 0H3.657C1.637 0 0 1.91 0 4.267v23.466C0 30.09 1.637 32 3.657 32h6.4v80c0 2.356 1.638 4.267 3.657 4.267h36.572c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V68.267h32.915z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577540289643" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7922" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M530.944 458.24l4.8 3.456 122.176 106.816a32 32 0 0 1-37.44 51.584l-4.672-3.392L546.56 556.16v280.704a32 32 0 0 1-26.24 31.488l-5.76 0.512a32 32 0 0 1-31.424-26.24l-0.512-5.76-0.064-280.704-69.12 60.48a32 32 0 0 1-40.96 0.896l-4.16-3.968a32 32 0 0 1-0.96-40.96l4.032-4.16 122.176-106.816a32 32 0 0 1 37.312-3.456zM497.92 128c128.128 0 239.168 82.304 275.52 199.04 123.968 11.264 221.312 113.088 221.312 237.44 0 128.128-103.68 232.96-234.88 238.272h-5.888l-35.52 0.192a32 32 0 0 1-0.192-64l35.264-0.128 4.672-0.064c96.384-3.84 172.544-80.896 172.544-174.272 0-96.128-80.512-174.464-179.584-174.464h-1.984a32 32 0 0 1-32-25.28C695.872 264.96 604.736 192 497.92 192 381.824 192 285.44 277.76 274.816 388.48a32 32 0 0 1-28.352 28.8c-83.968 9.152-147.84 78.208-147.84 159.552l0.192 7.936c3.84 85.76 77.056 154.112 166.592 154.112h45.632a32 32 0 0 1 0 64h-45.632C142.016 802.944 40.32 708.032 34.88 586.88l-0.192-9.28c0-106.88 76.352-197.184 179.968-219.904C239.488 226.112 357.76 128 497.856 128z" p-id="7923"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1569580729849" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1939" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M513.3 958.5c-142.2 0-397.9-222.1-401.6-440.5V268c1.7-39.6 31.7-72.3 71.1-77.3 49-4.6 97.1-16.5 142.7-35.3 47.8-14 91.9-38.3 129.4-71.1 30.3-24.4 72.9-26.3 105.3-4.6 39.9 30.7 83.8 55.9 130.5 74.6 48.6 14.7 98.2 25.9 148.4 33.7 38.5 7.6 67.1 40.3 69.5 79.5 3.3 84.9 2.5 169.9-2.6 254.7-33.7 281.6-253.7 436.4-392.7 436.3z m-0.1-813.7c-7.2-0.2-14.3 2-20 6.4-39.7 35.2-86.8 61.1-137.7 75.7-46.8 19.2-96.2 31-146.6 35.2-11 3.2-18.8 13-19.5 24.4v230.1c3.5 180.3 223.3 361 323.9 361s287.3-120.2 317.6-360.5c7.3-142.7 0-228.6 0-229.6-1.3-13.3-11-24.3-24-27.3-49.6-7.7-98.6-19-146.5-33.7-46.3-19.5-89.7-45.3-129-76.7-5.8-3.8-12.7-5.5-19.5-4.9l1.3-0.1z" fill="#C6CCDA" p-id="1940"></path><path d="M750.1 428L490.7 673.2c-11.7 11.1-29.5 12.9-43.1 4.2l-6.8-5.8-141.2-149.4c-9.3-9.3-12.7-22.9-9-35.5 3.8-12.6 14.1-22.1 27-24.8 12.9-2.7 26.1 1.9 34.6 11.9L469 597.5l233.7-221c14.6-12.8 36.8-11.6 49.9 2.7 13.2 14.2 11.5 35.3-2.5 48.8" fill="#C6CCDA" p-id="1941"></path></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="110" xmlns="http://www.w3.org/2000/svg"><path d="M86.635 33.334c1.467 0 2.917.113 4.358.283C87.078 14.392 67.58.111 45.321.111 20.44.111.055 17.987.055 40.687c0 13.104 6.781 23.863 18.115 32.209l-4.527 14.352 15.82-8.364c5.666 1.182 10.207 2.395 15.858 2.395 1.42 0 2.829-.073 4.227-.189-.886-3.19-1.398-6.53-1.398-9.996 0-20.845 16.98-37.76 38.485-37.76zm-24.34-12.936c3.407 0 5.665 2.363 5.665 5.954 0 3.576-2.258 5.97-5.666 5.97-3.392 0-6.795-2.395-6.795-5.97 0-3.591 3.403-5.954 6.795-5.954zM30.616 32.323c-3.393 0-6.818-2.395-6.818-5.971 0-3.591 3.425-5.954 6.818-5.954 3.392 0 5.65 2.363 5.65 5.954 0 3.576-2.258 5.97-5.65 5.97z"/><path d="M127.945 70.52c0-19.075-18.108-34.623-38.448-34.623-21.537 0-38.5 15.548-38.5 34.623 0 19.108 16.963 34.622 38.5 34.622 4.508 0 9.058-1.2 13.584-2.395l12.414 7.167-3.404-11.923c9.087-7.184 15.854-16.712 15.854-27.471zm-50.928-5.97c-2.254 0-4.53-2.362-4.53-4.773 0-2.378 2.276-4.771 4.53-4.771 3.422 0 5.665 2.393 5.665 4.771 0 2.41-2.243 4.773-5.665 4.773zm24.897 0c-2.24 0-4.498-2.362-4.498-4.773 0-2.378 2.258-4.771 4.498-4.771 3.392 0 5.665 2.393 5.665 4.771 0 2.41-2.273 4.773-5.665 4.773z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.527 116.793c.178.008.348.024.527.024h40.233c4.711-.005 8.53-3.677 8.534-8.21V18.895c-.004-4.532-3.823-8.204-8.534-8.209H79.054c-.179 0-.353.016-.527.024V0L0 10.082v107.406l78.527 10.342v-11.037zm0-101.362c.174-.024.348-.052.527-.052h40.233c2.018 0 3.659 1.578 3.659 3.52v89.713c-.003 1.942-1.64 3.517-3.659 3.519H79.054c-.179 0-.353-.028-.527-.052V15.431zM30.262 75.757l-18.721-.46V72.37l11.3-16.673v-.148l-10.266.164v-4.51l17.504-.44v3.264L18.696 70.76v.144l11.566.176v4.678zm9.419.231l-5.823-.144V50.671l5.823-.144v25.461zm22.255-11.632c-2.168 1.922-5.353 2.76-9.02 2.736-.702.004-1.402-.04-2.097-.131v9.303l-5.997-.148V50.743c1.852-.352 4.473-.647 8.218-.743 3.838-.096 6.608.539 8.48 1.913 1.807 1.306 3.032 3.5 3.032 6.112s-.926 4.833-2.612 6.331h-.004zM53.36 54.45c-.856-.01-1.71.083-2.541.275v7.682c.523.116 1.167.152 2.06.152 3.301-.004 5.36-1.614 5.36-4.314 0-2.425-1.772-3.843-4.875-3.791l-.004-.004zm39.847-37.066h9.564v3.795h-9.564v-3.795zm-9.568 5.68h9.564v3.8h-9.564v-3.8zm9.568 6.216h9.564v3.799h-9.564V29.28zm0 12h9.564v3.794h-9.564V41.28zm-9.568-6.096h9.564v3.795h-9.564v-3.795zm9.472 47.064c2.512 0 4.921-.96 6.697-2.67 1.776-1.708 2.773-4.026 2.772-6.442l-1.748-15.263c0-5.033-2.492-9.112-7.725-9.112-5.232 0-7.72 4.079-7.72 9.112l-1.752 15.263c-.001 2.417.996 4.735 2.773 6.444 1.777 1.71 4.187 2.669 6.7 2.668h.003zm-3.135-16.75h6.27v12.743h-6.27V65.5z"/></svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1" |
| | | xmlns="http://www.w3.org/2000/svg" |
| | | xmlns:xlink="http://www.w3.org/1999/xlink"> |
| | | <defs> |
| | | <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox" id="filter-1"> |
| | | <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> |
| | | <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> |
| | | <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix> |
| | | <feMerge> |
| | | <feMergeNode in="shadowMatrixOuter1"></feMergeNode> |
| | | <feMergeNode in="SourceGraphic"></feMergeNode> |
| | | </feMerge> |
| | | </filter> |
| | | <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect> |
| | | <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4"> |
| | | <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> |
| | | <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> |
| | | <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix> |
| | | </filter> |
| | | </defs> |
| | | <g id="é
ç½®é¢æ¿" width="48" height="40" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> |
| | | <g id="setting-copy-2" width="48" height="40" transform="translate(-1190.000000, -136.000000)"> |
| | | <g id="Group-8" width="48" height="40" transform="translate(1167.000000, 0.000000)"> |
| | | <g id="Group-5-Copy-5" filter="url(#filter-1)" transform="translate(25.000000, 137.000000)"> |
| | | <mask id="mask-3" fill="white"> |
| | | <use xlink:href="#path-2"></use> |
| | | </mask> |
| | | <g id="Rectangle-18"> |
| | | <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use> |
| | | <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use> |
| | | </g> |
| | | <rect id="Rectangle-11" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="48" height="10"></rect> |
| | | <rect id="Rectangle-18" fill="#303648" mask="url(#mask-3)" x="0" y="0" width="16" height="40"></rect> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | </svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1" |
| | | xmlns="http://www.w3.org/2000/svg" |
| | | xmlns:xlink="http://www.w3.org/1999/xlink"> |
| | | <defs> |
| | | <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox" id="filter-1"> |
| | | <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> |
| | | <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> |
| | | <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix> |
| | | <feMerge> |
| | | <feMergeNode in="shadowMatrixOuter1"></feMergeNode> |
| | | <feMergeNode in="SourceGraphic"></feMergeNode> |
| | | </feMerge> |
| | | </filter> |
| | | <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect> |
| | | <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4"> |
| | | <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> |
| | | <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> |
| | | <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix> |
| | | </filter> |
| | | </defs> |
| | | <g id="é
ç½®é¢æ¿" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> |
| | | <g id="setting-copy-2" transform="translate(-1254.000000, -136.000000)"> |
| | | <g id="Group-8" transform="translate(1167.000000, 0.000000)"> |
| | | <g id="Group-5" filter="url(#filter-1)" transform="translate(89.000000, 137.000000)"> |
| | | <mask id="mask-3" fill="white"> |
| | | <use xlink:href="#path-2"></use> |
| | | </mask> |
| | | <g id="Rectangle-18"> |
| | | <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use> |
| | | <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use> |
| | | </g> |
| | | <rect id="Rectangle-18" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="16" height="40"></rect> |
| | | <rect id="Rectangle-11" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="48" height="10"></rect> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | </svg> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | @import './variables.module.scss'; |
| | | |
| | | @mixin colorBtn($color) { |
| | | background: $color; |
| | | |
| | | &:hover { |
| | | color: $color; |
| | | |
| | | &:before, |
| | | &:after { |
| | | background: $color; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .blue-btn { |
| | | @include colorBtn($blue) |
| | | } |
| | | |
| | | .light-blue-btn { |
| | | @include colorBtn($light-blue) |
| | | } |
| | | |
| | | .red-btn { |
| | | @include colorBtn($red) |
| | | } |
| | | |
| | | .pink-btn { |
| | | @include colorBtn($pink) |
| | | } |
| | | |
| | | .green-btn { |
| | | @include colorBtn($green) |
| | | } |
| | | |
| | | .tiffany-btn { |
| | | @include colorBtn($tiffany) |
| | | } |
| | | |
| | | .yellow-btn { |
| | | @include colorBtn($yellow) |
| | | } |
| | | |
| | | .pan-btn { |
| | | font-size: 14px; |
| | | color: #fff; |
| | | padding: 14px 36px; |
| | | border-radius: 8px; |
| | | border: none; |
| | | outline: none; |
| | | transition: 600ms ease all; |
| | | position: relative; |
| | | display: inline-block; |
| | | |
| | | &:hover { |
| | | background: #fff; |
| | | |
| | | &:before, |
| | | &:after { |
| | | width: 100%; |
| | | transition: 600ms ease all; |
| | | } |
| | | } |
| | | |
| | | &:before, |
| | | &:after { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | height: 2px; |
| | | width: 0; |
| | | transition: 400ms ease all; |
| | | } |
| | | |
| | | &::after { |
| | | right: inherit; |
| | | top: inherit; |
| | | left: 0; |
| | | bottom: 0; |
| | | } |
| | | } |
| | | |
| | | .custom-button { |
| | | display: inline-block; |
| | | line-height: 1; |
| | | white-space: nowrap; |
| | | cursor: pointer; |
| | | background: #fff; |
| | | color: #fff; |
| | | -webkit-appearance: none; |
| | | text-align: center; |
| | | box-sizing: border-box; |
| | | outline: 0; |
| | | margin: 0; |
| | | padding: 10px 15px; |
| | | font-size: 14px; |
| | | border-radius: 4px; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | // cover some element-ui styles |
| | | |
| | | .el-breadcrumb__inner, |
| | | .el-breadcrumb__inner a { |
| | | font-weight: 400 !important; |
| | | } |
| | | |
| | | .el-upload { |
| | | input[type="file"] { |
| | | display: none !important; |
| | | } |
| | | } |
| | | |
| | | .el-upload__input { |
| | | display: none; |
| | | } |
| | | |
| | | .cell { |
| | | .el-tag { |
| | | margin-right: 0px; |
| | | } |
| | | } |
| | | |
| | | .small-padding { |
| | | .cell { |
| | | padding-left: 5px; |
| | | padding-right: 5px; |
| | | } |
| | | } |
| | | |
| | | .fixed-width { |
| | | .el-button--mini { |
| | | padding: 7px 10px; |
| | | width: 60px; |
| | | } |
| | | } |
| | | |
| | | .status-col { |
| | | .cell { |
| | | padding: 0 10px; |
| | | text-align: center; |
| | | |
| | | .el-tag { |
| | | margin-right: 0px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // to fixed https://github.com/ElemeFE/element/issues/2461 |
| | | .el-dialog { |
| | | transform: none; |
| | | left: 0; |
| | | position: relative; |
| | | margin: 0 auto; |
| | | } |
| | | |
| | | // refine element ui upload |
| | | .upload-container { |
| | | .el-upload { |
| | | width: 100%; |
| | | |
| | | .el-upload-dragger { |
| | | width: 100%; |
| | | height: 200px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // dropdown |
| | | .el-dropdown-menu { |
| | | a { |
| | | display: block |
| | | } |
| | | } |
| | | |
| | | // fix date-picker ui bug in filter-item |
| | | .el-range-editor.el-input__inner { |
| | | display: inline-flex !important; |
| | | } |
| | | |
| | | // to fix el-date-picker css style |
| | | .el-range-separator { |
| | | box-sizing: content-box; |
| | | } |
| | | |
| | | .el-menu--collapse |
| | | > div |
| | | > .el-submenu |
| | | > .el-submenu__title |
| | | .el-submenu__icon-arrow { |
| | | display: none; |
| | | } |
| | | |
| | | .el-dropdown .el-dropdown-link{ |
| | | color: var(--el-color-primary) !important; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | @import './variables.module.scss'; |
| | | @import './mixin.scss'; |
| | | @import './transition.scss'; |
| | | @import './element-ui.scss'; |
| | | @import './sidebar.scss'; |
| | | @import './btn.scss'; |
| | | @import './ruoyi.scss'; |
| | | |
| | | body { |
| | | height: 100%; |
| | | margin: 0; |
| | | -moz-osx-font-smoothing: grayscale; |
| | | -webkit-font-smoothing: antialiased; |
| | | text-rendering: optimizeLegibility; |
| | | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; |
| | | } |
| | | |
| | | label { |
| | | font-weight: 700; |
| | | } |
| | | |
| | | html { |
| | | height: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | #app { |
| | | height: 100%; |
| | | } |
| | | |
| | | *, |
| | | *:before, |
| | | *:after { |
| | | box-sizing: inherit; |
| | | } |
| | | |
| | | .no-padding { |
| | | padding: 0px !important; |
| | | } |
| | | |
| | | .padding-content { |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | a:focus, |
| | | a:active { |
| | | outline: none; |
| | | } |
| | | |
| | | a, |
| | | a:focus, |
| | | a:hover { |
| | | cursor: pointer; |
| | | color: inherit; |
| | | text-decoration: none; |
| | | } |
| | | |
| | | div:focus { |
| | | outline: none; |
| | | } |
| | | |
| | | .fr { |
| | | float: right; |
| | | } |
| | | |
| | | .fl { |
| | | float: left; |
| | | } |
| | | |
| | | .pr-5 { |
| | | padding-right: 5px; |
| | | } |
| | | |
| | | .pl-5 { |
| | | padding-left: 5px; |
| | | } |
| | | |
| | | .block { |
| | | display: block; |
| | | } |
| | | |
| | | .pointer { |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .inlineBlock { |
| | | display: block; |
| | | } |
| | | |
| | | .clearfix { |
| | | &:after { |
| | | visibility: hidden; |
| | | display: block; |
| | | font-size: 0; |
| | | content: " "; |
| | | clear: both; |
| | | height: 0; |
| | | } |
| | | } |
| | | |
| | | aside { |
| | | background: #eef1f6; |
| | | padding: 8px 24px; |
| | | margin-bottom: 20px; |
| | | border-radius: 2px; |
| | | display: block; |
| | | line-height: 32px; |
| | | font-size: 16px; |
| | | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; |
| | | color: #2c3e50; |
| | | -webkit-font-smoothing: antialiased; |
| | | -moz-osx-font-smoothing: grayscale; |
| | | |
| | | a { |
| | | color: #337ab7; |
| | | cursor: pointer; |
| | | |
| | | &:hover { |
| | | color: rgb(32, 160, 255); |
| | | } |
| | | } |
| | | } |
| | | |
| | | //main-containerå
¨å±æ ·å¼ |
| | | .app-container { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .components-container { |
| | | margin: 30px 50px; |
| | | position: relative; |
| | | } |
| | | |
| | | .text-center { |
| | | text-align: center |
| | | } |
| | | |
| | | .sub-navbar { |
| | | height: 50px; |
| | | line-height: 50px; |
| | | position: relative; |
| | | width: 100%; |
| | | text-align: right; |
| | | padding-right: 20px; |
| | | transition: 600ms ease position; |
| | | background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); |
| | | |
| | | .subtitle { |
| | | font-size: 20px; |
| | | color: #fff; |
| | | } |
| | | |
| | | &.draft { |
| | | background: #d0d0d0; |
| | | } |
| | | |
| | | &.deleted { |
| | | background: #d0d0d0; |
| | | } |
| | | } |
| | | |
| | | .link-type, |
| | | .link-type:focus { |
| | | color: #337ab7; |
| | | cursor: pointer; |
| | | |
| | | &:hover { |
| | | color: rgb(32, 160, 255); |
| | | } |
| | | } |
| | | |
| | | .filter-container { |
| | | padding-bottom: 10px; |
| | | |
| | | .filter-item { |
| | | display: inline-block; |
| | | vertical-align: middle; |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | @mixin clearfix { |
| | | &:after { |
| | | content: ""; |
| | | display: table; |
| | | clear: both; |
| | | } |
| | | } |
| | | |
| | | @mixin scrollBar { |
| | | &::-webkit-scrollbar-track-piece { |
| | | background: #d3dce6; |
| | | } |
| | | |
| | | &::-webkit-scrollbar { |
| | | width: 6px; |
| | | } |
| | | |
| | | &::-webkit-scrollbar-thumb { |
| | | background: #99a9bf; |
| | | border-radius: 20px; |
| | | } |
| | | } |
| | | |
| | | @mixin relative { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | @mixin pct($pct) { |
| | | width: #{$pct}; |
| | | position: relative; |
| | | margin: 0 auto; |
| | | } |
| | | |
| | | @mixin triangle($width, $height, $color, $direction) { |
| | | $width: $width/2; |
| | | $color-border-style: $height solid $color; |
| | | $transparent-border-style: $width solid transparent; |
| | | height: 0; |
| | | width: 0; |
| | | |
| | | @if $direction==up { |
| | | border-bottom: $color-border-style; |
| | | border-left: $transparent-border-style; |
| | | border-right: $transparent-border-style; |
| | | } |
| | | |
| | | @else if $direction==right { |
| | | border-left: $color-border-style; |
| | | border-top: $transparent-border-style; |
| | | border-bottom: $transparent-border-style; |
| | | } |
| | | |
| | | @else if $direction==down { |
| | | border-top: $color-border-style; |
| | | border-left: $transparent-border-style; |
| | | border-right: $transparent-border-style; |
| | | } |
| | | |
| | | @else if $direction==left { |
| | | border-right: $color-border-style; |
| | | border-top: $transparent-border-style; |
| | | border-bottom: $transparent-border-style; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * éç¨cssæ ·å¼å¸å±å¤ç |
| | | * Copyright (c) 2019 ruoyi |
| | | */ |
| | | |
| | | /** åºç¡éç¨ **/ |
| | | .pt5 { |
| | | padding-top: 5px; |
| | | } |
| | | .pr5 { |
| | | padding-right: 5px; |
| | | } |
| | | .pb5 { |
| | | padding-bottom: 5px; |
| | | } |
| | | .mt5 { |
| | | margin-top: 5px; |
| | | } |
| | | .mr5 { |
| | | margin-right: 5px; |
| | | } |
| | | .mb5 { |
| | | margin-bottom: 5px; |
| | | } |
| | | .mb8 { |
| | | margin-bottom: 8px; |
| | | } |
| | | .ml5 { |
| | | margin-left: 5px; |
| | | } |
| | | .mt10 { |
| | | margin-top: 10px; |
| | | } |
| | | .mr10 { |
| | | margin-right: 10px; |
| | | } |
| | | .mb10 { |
| | | margin-bottom: 10px; |
| | | } |
| | | .ml10 { |
| | | margin-left: 10px; |
| | | } |
| | | .mt20 { |
| | | margin-top: 20px; |
| | | } |
| | | .mr20 { |
| | | margin-right: 20px; |
| | | } |
| | | .mb20 { |
| | | margin-bottom: 20px; |
| | | } |
| | | .ml20 { |
| | | margin-left: 20px; |
| | | } |
| | | |
| | | .h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { |
| | | font-family: inherit; |
| | | font-weight: 500; |
| | | line-height: 1.1; |
| | | color: inherit; |
| | | } |
| | | |
| | | .el-form .el-form-item__label { |
| | | font-weight: 700; |
| | | } |
| | | .el-dialog:not(.is-fullscreen) { |
| | | margin-top: 6vh !important; |
| | | } |
| | | |
| | | .el-dialog.scrollbar .el-dialog__body { |
| | | overflow: auto; |
| | | overflow-x: hidden; |
| | | max-height: 70vh; |
| | | padding: 10px 20px 0; |
| | | } |
| | | |
| | | .el-table { |
| | | .el-table__header-wrapper, .el-table__fixed-header-wrapper { |
| | | th { |
| | | word-break: break-word; |
| | | background-color: #f8f8f9 !important; |
| | | color: #515a6e; |
| | | height: 40px !important; |
| | | font-size: 13px; |
| | | } |
| | | } |
| | | .el-table__body-wrapper { |
| | | .el-button [class*="el-icon-"] + span { |
| | | margin-left: 1px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** 表åå¸å± **/ |
| | | .form-header { |
| | | font-size:15px; |
| | | color:#6379bb; |
| | | border-bottom:1px solid #ddd; |
| | | margin:8px 10px 25px 10px; |
| | | padding-bottom:5px |
| | | } |
| | | |
| | | /** è¡¨æ ¼å¸å± **/ |
| | | .pagination-container { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | margin-top: 20px; |
| | | background-color: transparent !important; |
| | | } |
| | | |
| | | /* å¼¹çªä¸çåé¡µå¨ */ |
| | | .el-dialog .pagination-container { |
| | | position: static !important; |
| | | margin: 10px 0 0 0; |
| | | padding: 0 !important; |
| | | |
| | | .el-pagination { |
| | | position: static; |
| | | } |
| | | } |
| | | |
| | | /* ç§»å¨ç«¯éé
*/ |
| | | @media (max-width: 768px) { |
| | | .pagination-container { |
| | | .el-pagination { |
| | | > .el-pagination__jump { |
| | | display: none !important; |
| | | } |
| | | > .el-pagination__sizes { |
| | | display: none !important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* tree border */ |
| | | .tree-border { |
| | | margin-top: 5px; |
| | | border: 1px solid var(--el-border-color-light, #e5e6e7); |
| | | background: var(--el-bg-color, #FFFFFF) none; |
| | | border-radius:4px; |
| | | width: 100%; |
| | | } |
| | | |
| | | .el-table .fixed-width .el-button--small { |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | width: inherit; |
| | | } |
| | | |
| | | /** è¡¨æ ¼æ´å¤æä½ä¸ææ ·å¼ */ |
| | | .el-table .el-dropdown-link { |
| | | cursor: pointer; |
| | | color: #409EFF; |
| | | margin-left: 10px; |
| | | } |
| | | |
| | | .el-table .el-dropdown, .el-icon-arrow-down { |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .el-tree-node__content > .el-checkbox { |
| | | margin-right: 8px; |
| | | } |
| | | |
| | | .list-group-striped > .list-group-item { |
| | | border-left: 0; |
| | | border-right: 0; |
| | | border-radius: 0; |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | } |
| | | |
| | | .list-group { |
| | | padding-left: 0px; |
| | | list-style: none; |
| | | } |
| | | |
| | | .list-group-item { |
| | | border-bottom: 1px solid #e7eaec; |
| | | border-top: 1px solid #e7eaec; |
| | | margin-bottom: -1px; |
| | | padding: 11px 0px; |
| | | font-size: 13px; |
| | | } |
| | | |
| | | .pull-right { |
| | | float: right !important; |
| | | } |
| | | |
| | | .el-card__header { |
| | | padding: 14px 15px 7px !important; |
| | | min-height: 40px; |
| | | } |
| | | |
| | | .el-card__body { |
| | | padding: 15px 20px 20px 20px !important; |
| | | } |
| | | |
| | | .card-box { |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | /* button color */ |
| | | .el-button--cyan.is-active, |
| | | .el-button--cyan:active { |
| | | background: #20B2AA; |
| | | border-color: #20B2AA; |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | .el-button--cyan:focus, |
| | | .el-button--cyan:hover { |
| | | background: #48D1CC; |
| | | border-color: #48D1CC; |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | .el-button--cyan { |
| | | background-color: #20B2AA; |
| | | border-color: #20B2AA; |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | /* text color */ |
| | | .text-navy { |
| | | color: #1ab394; |
| | | } |
| | | |
| | | .text-primary { |
| | | color: inherit; |
| | | } |
| | | |
| | | .text-success { |
| | | color: #1c84c6; |
| | | } |
| | | |
| | | .text-info { |
| | | color: #23c6c8; |
| | | } |
| | | |
| | | .text-warning { |
| | | color: #f8ac59; |
| | | } |
| | | |
| | | .text-danger { |
| | | color: #ed5565; |
| | | } |
| | | |
| | | .text-muted { |
| | | color: #888888; |
| | | } |
| | | |
| | | /* image */ |
| | | .img-circle { |
| | | border-radius: 50%; |
| | | } |
| | | |
| | | .img-lg { |
| | | width: 120px; |
| | | height: 120px; |
| | | } |
| | | |
| | | .avatar-upload-preview { |
| | | position: absolute; |
| | | top: 50%; |
| | | transform: translate(50%, -50%); |
| | | width: 200px; |
| | | height: 200px; |
| | | border-radius: 50%; |
| | | box-shadow: 0 0 4px #ccc; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | /* ææ½åæ ·å¼ */ |
| | | .sortable-ghost{ |
| | | opacity: .8; |
| | | color: #fff!important; |
| | | background: #42b983!important; |
| | | } |
| | | |
| | | /* è¡¨æ ¼å³ä¾§å·¥å
·æ æ ·å¼ */ |
| | | .top-right-btn { |
| | | margin-left: auto; |
| | | } |
| | | |
| | | /* åå²é¢æ¿æ ·å¼ */ |
| | | .splitpanes.default-theme .splitpanes__pane { |
| | | background-color: var(--splitpanes-default-bg) !important; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | #app { |
| | | |
| | | .main-container { |
| | | min-height: 100%; |
| | | transition: margin-left .28s; |
| | | margin-left: $base-sidebar-width; |
| | | position: relative; |
| | | } |
| | | |
| | | .sidebarHide { |
| | | margin-left: 0!important; |
| | | } |
| | | |
| | | .sidebar-container { |
| | | -webkit-transition: width .28s; |
| | | transition: width 0.28s; |
| | | width: $base-sidebar-width !important; |
| | | background-color: $base-menu-background; |
| | | height: 100%; |
| | | position: fixed; |
| | | font-size: 0px; |
| | | top: 50px; |
| | | bottom: 0; |
| | | left: 0; |
| | | z-index: 1001; |
| | | overflow: hidden; |
| | | -webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35); |
| | | box-shadow: none; |
| | | |
| | | // reset element-ui css |
| | | .horizontal-collapse-transition { |
| | | transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; |
| | | } |
| | | |
| | | .scrollbar-wrapper { |
| | | overflow-x: hidden !important; |
| | | } |
| | | |
| | | .el-scrollbar__bar.is-vertical { |
| | | right: 0px; |
| | | } |
| | | |
| | | .el-scrollbar { |
| | | height: 100%; |
| | | } |
| | | |
| | | &.has-logo { |
| | | .el-scrollbar { |
| | | height: calc(100% - 50px); |
| | | } |
| | | } |
| | | |
| | | .is-horizontal { |
| | | display: none; |
| | | } |
| | | |
| | | a { |
| | | display: inline-block; |
| | | width: 100%; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .svg-icon { |
| | | margin-right: 16px; |
| | | } |
| | | |
| | | .el-menu { |
| | | border: none; |
| | | height: 100%; |
| | | width: 100% !important; |
| | | } |
| | | |
| | | .el-menu-item, .menu-title { |
| | | overflow: hidden !important; |
| | | text-overflow: ellipsis !important; |
| | | white-space: nowrap !important; |
| | | } |
| | | |
| | | .el-menu-item .el-menu-tooltip__trigger { |
| | | display: inline-block !important; |
| | | } |
| | | |
| | | // menu hover |
| | | .sub-menu-title-noDropdown, |
| | | .el-sub-menu__title { |
| | | &:hover { |
| | | background-color: #ffffff !important; |
| | | } |
| | | } |
| | | |
| | | & .theme-dark .is-active > .el-sub-menu__title { |
| | | color: $base-menu-color-active !important; |
| | | } |
| | | |
| | | & .nest-menu .el-sub-menu>.el-sub-menu__title, |
| | | & .el-sub-menu .el-menu-item { |
| | | min-width: $base-sidebar-width !important; |
| | | |
| | | &:hover { |
| | | background-color: #ffffff !important; |
| | | } |
| | | } |
| | | |
| | | & .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title, |
| | | & .theme-dark .el-sub-menu .el-menu-item { |
| | | background-color: $base-sub-menu-background; |
| | | |
| | | &:hover { |
| | | background-color: #ffffff !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .hideSidebar { |
| | | .sidebar-container { |
| | | width: 54px !important; |
| | | } |
| | | |
| | | .main-container { |
| | | margin-left: 54px; |
| | | } |
| | | |
| | | .sub-menu-title-noDropdown { |
| | | padding: 0 !important; |
| | | position: relative; |
| | | |
| | | .el-tooltip { |
| | | padding: 0 !important; |
| | | |
| | | .svg-icon { |
| | | margin-left: 20px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-sub-menu { |
| | | overflow: hidden; |
| | | |
| | | &>.el-sub-menu__title { |
| | | padding: 0 !important; |
| | | |
| | | .svg-icon { |
| | | margin-left: 20px; |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | .el-menu--collapse { |
| | | .el-sub-menu { |
| | | &>.el-sub-menu__title { |
| | | &>span { |
| | | height: 0; |
| | | width: 0; |
| | | overflow: hidden; |
| | | visibility: hidden; |
| | | display: inline-block; |
| | | } |
| | | &>i { |
| | | height: 0; |
| | | width: 0; |
| | | overflow: hidden; |
| | | visibility: hidden; |
| | | display: inline-block; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-menu--collapse .el-menu .el-sub-menu { |
| | | min-width: $base-sidebar-width !important; |
| | | } |
| | | |
| | | // mobile responsive |
| | | .mobile { |
| | | .main-container { |
| | | margin-left: 0px; |
| | | } |
| | | |
| | | .sidebar-container { |
| | | transition: transform .28s; |
| | | width: $base-sidebar-width !important; |
| | | } |
| | | |
| | | &.hideSidebar { |
| | | .sidebar-container { |
| | | pointer-events: none; |
| | | transition-duration: 0.3s; |
| | | transform: translate3d(-$base-sidebar-width, 0, 0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | .withoutAnimation { |
| | | |
| | | .main-container, |
| | | .sidebar-container { |
| | | transition: none; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // when menu collapsed |
| | | .el-menu--vertical { |
| | | &>.el-menu { |
| | | .svg-icon { |
| | | margin-right: 16px; |
| | | } |
| | | } |
| | | |
| | | .nest-menu .el-sub-menu>.el-sub-menu__title, |
| | | .el-menu-item { |
| | | &:hover { |
| | | // you can use $sub-menuHover |
| | | background-color: #ffffff !important; |
| | | } |
| | | } |
| | | |
| | | // the scroll bar appears when the sub-menu is too long |
| | | >.el-menu--popup { |
| | | max-height: 100vh; |
| | | overflow-y: auto; |
| | | |
| | | &::-webkit-scrollbar-track-piece { |
| | | background: #d3dce6; |
| | | } |
| | | |
| | | &::-webkit-scrollbar { |
| | | width: 6px; |
| | | } |
| | | |
| | | &::-webkit-scrollbar-thumb { |
| | | background: #99a9bf; |
| | | border-radius: 20px; |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | // global transition css |
| | | |
| | | /* fade */ |
| | | .fade-enter-active, |
| | | .fade-leave-active { |
| | | transition: opacity 0.28s; |
| | | } |
| | | |
| | | .fade-enter, |
| | | .fade-leave-active { |
| | | opacity: 0; |
| | | } |
| | | |
| | | /* fade-transform */ |
| | | .fade-transform--move, |
| | | .fade-transform-leave-active, |
| | | .fade-transform-enter-active { |
| | | transition: all .5s; |
| | | } |
| | | |
| | | .fade-transform-enter { |
| | | opacity: 0; |
| | | transform: translateX(-30px); |
| | | } |
| | | |
| | | .fade-transform-leave-to { |
| | | opacity: 0; |
| | | transform: translateX(30px); |
| | | } |
| | | |
| | | /* breadcrumb transition */ |
| | | .breadcrumb-enter-active, |
| | | .breadcrumb-leave-active { |
| | | transition: all .5s; |
| | | } |
| | | |
| | | .breadcrumb-enter, |
| | | .breadcrumb-leave-active { |
| | | opacity: 0; |
| | | transform: translateX(20px); |
| | | } |
| | | |
| | | .breadcrumb-move { |
| | | transition: all .5s; |
| | | } |
| | | |
| | | .breadcrumb-leave-active { |
| | | position: absolute; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | // base color |
| | | $blue: #324157; |
| | | $light-blue: #333c46; |
| | | $red: #C03639; |
| | | $pink: #E65D6E; |
| | | $green: #30B08F; |
| | | $tiffany: #4AB7BD; |
| | | $yellow: #FEC171; |
| | | $panGreen: #30B08F; |
| | | |
| | | // é»è®¤ä¸»é¢åé |
| | | $menuText: #ffffff; |
| | | $menuActiveText: #165DFF; |
| | | $menuBg: #165DFF; |
| | | $menuHover: #ffffff; |
| | | |
| | | // æµ
è²ä¸»é¢theme-light |
| | | $menuLightBg: #165DFF; |
| | | $menuLightHover: #ffffff; |
| | | $menuLightText: #ffffff; |
| | | $menuLightActiveText: #165DFF; |
| | | |
| | | // åºç¡åé |
| | | $base-sidebar-width: 200px; |
| | | $sideBarWidth: 200px; |
| | | |
| | | // èåæè²åé |
| | | $base-menu-color: #bfcbd9; |
| | | $base-menu-color-active: #f4f4f5; |
| | | $base-menu-background: #165DFF; |
| | | $base-sub-menu-background: #1f2d3d; |
| | | $base-sub-menu-hover: #001528; |
| | | |
| | | // ç»ä»¶åé |
| | | $--color-primary: #165DFF; |
| | | $--color-success: #67C23A; |
| | | $--color-warning: #E6A23C; |
| | | $--color-danger: #F56C6C; |
| | | $--color-info: #909399; |
| | | |
| | | :export { |
| | | menuText: $menuText; |
| | | menuActiveText: $menuActiveText; |
| | | menuBg: $menuBg; |
| | | menuHover: $menuHover; |
| | | menuLightBg: $menuLightBg; |
| | | menuLightHover: $menuLightHover; |
| | | menuLightText: $menuLightText; |
| | | menuLightActiveText: $menuLightActiveText; |
| | | sideBarWidth: $sideBarWidth; |
| | | // 导åºåºç¡é¢è² |
| | | blue: $blue; |
| | | lightBlue: $light-blue; |
| | | red: $red; |
| | | pink: $pink; |
| | | green: $green; |
| | | tiffany: $tiffany; |
| | | yellow: $yellow; |
| | | panGreen: $panGreen; |
| | | // 导åºç»ä»¶é¢è² |
| | | colorPrimary: $--color-primary; |
| | | colorSuccess: $--color-success; |
| | | colorWarning: $--color-warning; |
| | | colorDanger: $--color-danger; |
| | | colorInfo: $--color-info; |
| | | } |
| | | |
| | | // CSSåéå®ä¹ |
| | | :root { |
| | | /* äº®è²æ¨¡å¼åé */ |
| | | --sidebar-bg: #{$menuBg}; |
| | | --sidebar-text: #{$menuText}; |
| | | --menu-hover: #{$menuHover}; |
| | | |
| | | --navbar-bg: #ffffff; |
| | | --navbar-text: #303133; |
| | | |
| | | /* splitpanes default-theme åé */ |
| | | --splitpanes-default-bg: #ffffff; |
| | | |
| | | } |
| | | |
| | | // æé»æ¨¡å¼åé |
| | | html.dark { |
| | | /* é»è®¤éç¨ */ |
| | | --el-bg-color: #141414; |
| | | --el-bg-color-overlay: #1d1e1f; |
| | | --el-text-color-primary: #ffffff; |
| | | --el-text-color-regular: #d0d0d0; |
| | | --el-border-color: #434343; |
| | | --el-border-color-light: #434343; |
| | | |
| | | /* ä¾§è¾¹æ */ |
| | | --sidebar-bg: #141414; |
| | | --sidebar-text: #ffffff; |
| | | --menu-hover: #2d2d2d; |
| | | --menu-active-text: #{$menuActiveText}; |
| | | |
| | | /* é¡¶é¨å¯¼èªæ */ |
| | | --navbar-bg: #141414; |
| | | --navbar-text: #ffffff; |
| | | --navbar-hover: #141414; |
| | | |
| | | /* æ ç¾æ */ |
| | | --tags-bg: #141414; |
| | | --tags-item-bg: #1d1e1f; |
| | | --tags-item-border: #303030; |
| | | --tags-item-text: #d0d0d0; |
| | | --tags-item-hover: #2d2d2d; |
| | | --tags-close-hover: #64666a; |
| | | |
| | | /* splitpanes ç»ä»¶æé»æ¨¡å¼åé */ |
| | | --splitpanes-bg: #141414; |
| | | --splitpanes-border: #303030; |
| | | --splitpanes-splitter-bg: #1d1e1f; |
| | | --splitpanes-splitter-hover-bg: #2d2d2d; |
| | | |
| | | /* blockquote æé»æ¨¡å¼åé */ |
| | | --blockquote-bg: #1d1e1f; |
| | | --blockquote-border: #303030; |
| | | --blockquote-text: #d0d0d0; |
| | | |
| | | /* Cron æ¶é´è¡¨è¾¾å¼ 模å¼åé */ |
| | | --cron-border: #303030; |
| | | |
| | | /* splitpanes default-theme æé»æ¨¡å¼åé */ |
| | | --splitpanes-default-bg: #141414; |
| | | |
| | | /* ä¾§è¾¹æ èåè¦ç */ |
| | | .sidebar-container { |
| | | .el-menu-item, .menu-title { |
| | | color: var(--el-text-color-regular); |
| | | } |
| | | & .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title, |
| | | & .theme-dark .el-sub-menu .el-menu-item { |
| | | background-color: var(--el-bg-color) !important; |
| | | } |
| | | } |
| | | |
| | | /* 顶鍿 æ èåè¦ç */ |
| | | .el-menu--horizontal { |
| | | .el-menu-item { |
| | | &:not(.is-disabled) { |
| | | &:hover, |
| | | &:focus { |
| | | background-color: var(--navbar-hover) !important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* åå²çªæ ¼è¦ç */ |
| | | .splitpanes { |
| | | background-color: var(--splitpanes-bg); |
| | | |
| | | .splitpanes__pane { |
| | | background-color: var(--splitpanes-bg); |
| | | border-color: var(--splitpanes-border); |
| | | } |
| | | |
| | | .splitpanes__splitter { |
| | | background-color: var(--splitpanes-splitter-bg); |
| | | border-color: var(--splitpanes-border); |
| | | |
| | | &:hover { |
| | | background-color: var(--splitpanes-splitter-hover-bg); |
| | | } |
| | | |
| | | &:before, |
| | | &:after { |
| | | background-color: var(--splitpanes-border); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* è¡¨æ ¼æ ·å¼è¦ç */ |
| | | .el-table { |
| | | --el-table-header-bg-color: var(--el-bg-color-overlay) !important; |
| | | --el-table-header-text-color: var(--el-text-color-regular) !important; |
| | | --el-table-border-color: var(--el-border-color-light) !important; |
| | | --el-table-row-hover-bg-color: var(--el-bg-color-overlay) !important; |
| | | |
| | | .el-table__header-wrapper, .el-table__fixed-header-wrapper { |
| | | th { |
| | | background-color: var(--el-bg-color-overlay, #f8f8f9) !important; |
| | | color: var(--el-text-color-regular, #515a6e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* æ ç»ä»¶é«äº®æ ·å¼è¦ç */ |
| | | .el-tree { |
| | | .el-tree-node.is-current > .el-tree-node__content { |
| | | background-color: var(--el-bg-color-overlay) !important; |
| | | color: var(--el-color-primary); |
| | | } |
| | | |
| | | .el-tree-node__content:hover { |
| | | background-color: var(--el-bg-color-overlay); |
| | | } |
| | | } |
| | | |
| | | /* 䏿èåæ ·å¼è¦ç */ |
| | | .el-dropdown-menu__item:not(.is-disabled):focus, .el-dropdown-menu__item:not(.is-disabled):hover{ |
| | | background-color: var(--navbar-hover) !important; |
| | | } |
| | | |
| | | /* blockquoteæ ·å¼è¦ç */ |
| | | blockquote { |
| | | background-color: var(--blockquote-bg) !important; |
| | | border-left-color: var(--blockquote-border) !important; |
| | | color: var(--blockquote-text) !important; |
| | | } |
| | | |
| | | /* æ¶é´è¡¨è¾¾å¼æ 颿 ·å¼è¦ç */ |
| | | .popup-result .title { |
| | | background: var(--cron-border); |
| | | } |
| | | |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-breadcrumb class="app-breadcrumb" separator="/"> |
| | | <transition-group name="breadcrumb"> |
| | | <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path"> |
| | | <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span> |
| | | <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a> |
| | | </el-breadcrumb-item> |
| | | </transition-group> |
| | | </el-breadcrumb> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import usePermissionStore from '@/store/modules/permission' |
| | | |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | const permissionStore = usePermissionStore() |
| | | const levelList = ref([]) |
| | | |
| | | function getBreadcrumb() { |
| | | // only show routes with meta.title |
| | | let matched = [] |
| | | const pathNum = findPathNum(route.path) |
| | | // multi-level menu |
| | | if (pathNum > 2) { |
| | | const reg = /\/\w+/gi |
| | | const pathList = route.path.match(reg).map((item, index) => { |
| | | if (index !== 0) item = item.slice(1) |
| | | return item |
| | | }) |
| | | getMatched(pathList, permissionStore.defaultRoutes, matched) |
| | | } else { |
| | | matched = route.matched.filter((item) => item.meta && item.meta.title) |
| | | } |
| | | // 夿æ¯å¦ä¸ºé¦é¡µ |
| | | if (!isDashboard(matched[0])) { |
| | | matched = [{ path: "/index", meta: { title: "é¦é¡µ" } }].concat(matched) |
| | | } |
| | | levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) |
| | | } |
| | | function findPathNum(str, char = "/") { |
| | | let index = str.indexOf(char) |
| | | let num = 0 |
| | | while (index !== -1) { |
| | | num++ |
| | | index = str.indexOf(char, index + 1) |
| | | } |
| | | return num |
| | | } |
| | | function getMatched(pathList, routeList, matched) { |
| | | let data = routeList.find(item => item.path == pathList[0] || (item.name += '').toLowerCase() == pathList[0]) |
| | | if (data) { |
| | | matched.push(data) |
| | | if (data.children && pathList.length) { |
| | | pathList.shift() |
| | | getMatched(pathList, data.children, matched) |
| | | } |
| | | } |
| | | } |
| | | function isDashboard(route) { |
| | | const name = route && route.name |
| | | if (!name) { |
| | | return false |
| | | } |
| | | return name.trim() === 'Index' |
| | | } |
| | | function handleLink(item) { |
| | | const { redirect, path } = item |
| | | if (redirect) { |
| | | router.push(redirect) |
| | | return |
| | | } |
| | | router.push(path) |
| | | } |
| | | |
| | | watchEffect(() => { |
| | | // if you go to the redirect page, do not update the breadcrumbs |
| | | if (route.path.startsWith('/redirect/')) { |
| | | return |
| | | } |
| | | getBreadcrumb() |
| | | }) |
| | | getBreadcrumb() |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | .app-breadcrumb.el-breadcrumb { |
| | | display: inline-block; |
| | | font-size: 14px; |
| | | line-height: 50px; |
| | | margin-left: 8px; |
| | | |
| | | .no-redirect { |
| | | color: #97a8be; |
| | | cursor: text; |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-form> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="1"> |
| | | æ¥ï¼å
许çéé
符[, - * ? / L W] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="2"> |
| | | ä¸æå® |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="3"> |
| | | å¨æä» |
| | | <el-input-number v-model='cycle01' :min="1" :max="30" /> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="31" /> æ¥ |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="4"> |
| | | ä» |
| | | <el-input-number v-model='average01' :min="1" :max="30" /> å·å¼å§ï¼æ¯ |
| | | <el-input-number v-model='average02' :min="1" :max="31 - average01" /> æ¥æ§è¡ä¸æ¬¡ |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="5"> |
| | | æ¯æ |
| | | <el-input-number v-model='workday' :min="1" :max="31" /> å·æè¿çé£ä¸ªå·¥ä½æ¥ |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="6"> |
| | | æ¬ææåä¸å¤© |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="7"> |
| | | æå® |
| | | <el-select clearable v-model="checkboxList" placeholder="å¯å¤é" multiple :multiple-limit="10"> |
| | | <el-option v-for="item in 31" :key="item" :label="item" :value="item" /> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | <script setup> |
| | | const emit = defineEmits(['update']) |
| | | const props = defineProps({ |
| | | cron: { |
| | | type: Object, |
| | | default: { |
| | | second: "*", |
| | | min: "*", |
| | | hour: "*", |
| | | day: "*", |
| | | month: "*", |
| | | week: "?", |
| | | year: "", |
| | | } |
| | | }, |
| | | check: { |
| | | type: Function, |
| | | default: () => { |
| | | } |
| | | } |
| | | }) |
| | | const radioValue = ref(1) |
| | | const cycle01 = ref(1) |
| | | const cycle02 = ref(2) |
| | | const average01 = ref(1) |
| | | const average02 = ref(1) |
| | | const workday = ref(1) |
| | | const checkboxList = ref([]) |
| | | const checkCopy = ref([1]) |
| | | const cycleTotal = computed(() => { |
| | | cycle01.value = props.check(cycle01.value, 1, 30) |
| | | cycle02.value = props.check(cycle02.value, cycle01.value + 1, 31) |
| | | return cycle01.value + '-' + cycle02.value |
| | | }) |
| | | const averageTotal = computed(() => { |
| | | average01.value = props.check(average01.value, 1, 30) |
| | | average02.value = props.check(average02.value, 1, 31 - average01.value) |
| | | return average01.value + '/' + average02.value |
| | | }) |
| | | const workdayTotal = computed(() => { |
| | | workday.value = props.check(workday.value, 1, 31) |
| | | return workday.value + 'W' |
| | | }) |
| | | const checkboxString = computed(() => { |
| | | return checkboxList.value.join(',') |
| | | }) |
| | | watch(() => props.cron.day, value => changeRadioValue(value)) |
| | | watch([radioValue, cycleTotal, averageTotal, workdayTotal, checkboxString], () => onRadioChange()) |
| | | function changeRadioValue(value) { |
| | | if (value === "*") { |
| | | radioValue.value = 1 |
| | | } else if (value === "?") { |
| | | radioValue.value = 2 |
| | | } else if (value.indexOf("-") > -1) { |
| | | const indexArr = value.split('-') |
| | | cycle01.value = Number(indexArr[0]) |
| | | cycle02.value = Number(indexArr[1]) |
| | | radioValue.value = 3 |
| | | } else if (value.indexOf("/") > -1) { |
| | | const indexArr = value.split('/') |
| | | average01.value = Number(indexArr[0]) |
| | | average02.value = Number(indexArr[1]) |
| | | radioValue.value = 4 |
| | | } else if (value.indexOf("W") > -1) { |
| | | const indexArr = value.split("W") |
| | | workday.value = Number(indexArr[0]) |
| | | radioValue.value = 5 |
| | | } else if (value === "L") { |
| | | radioValue.value = 6 |
| | | } else { |
| | | checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))] |
| | | radioValue.value = 7 |
| | | } |
| | | } |
| | | // åéæé®å¼ååæ¶ |
| | | function onRadioChange() { |
| | | if (radioValue.value === 2 && props.cron.week === '?') { |
| | | emit('update', 'week', '*', 'day') |
| | | } |
| | | if (radioValue.value !== 2 && props.cron.week !== '?') { |
| | | emit('update', 'week', '?', 'day') |
| | | } |
| | | switch (radioValue.value) { |
| | | case 1: |
| | | emit('update', 'day', '*', 'day') |
| | | break |
| | | case 2: |
| | | emit('update', 'day', '?', 'day') |
| | | break |
| | | case 3: |
| | | emit('update', 'day', cycleTotal.value, 'day') |
| | | break |
| | | case 4: |
| | | emit('update', 'day', averageTotal.value, 'day') |
| | | break |
| | | case 5: |
| | | emit('update', 'day', workdayTotal.value, 'day') |
| | | break |
| | | case 6: |
| | | emit('update', 'day', 'L', 'day') |
| | | break |
| | | case 7: |
| | | if (checkboxList.value.length === 0) { |
| | | checkboxList.value.push(checkCopy.value[0]) |
| | | } else { |
| | | checkCopy.value = checkboxList.value |
| | | } |
| | | emit('update', 'day', checkboxString.value, 'day') |
| | | break |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .el-input-number--small, .el-select, .el-select--small { |
| | | margin: 0 0.2rem; |
| | | } |
| | | .el-select, .el-select--small { |
| | | width: 18.8rem; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-form> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="1"> |
| | | å°æ¶ï¼å
许çéé
符[, - * /] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="2"> |
| | | å¨æä» |
| | | <el-input-number v-model='cycle01' :min="0" :max="22" /> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="23" /> æ¶ |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="3"> |
| | | ä» |
| | | <el-input-number v-model='average01' :min="0" :max="22" /> æ¶å¼å§ï¼æ¯ |
| | | <el-input-number v-model='average02' :min="1" :max="23 - average01" /> å°æ¶æ§è¡ä¸æ¬¡ |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="4"> |
| | | æå® |
| | | <el-select clearable v-model="checkboxList" placeholder="å¯å¤é" multiple :multiple-limit="10"> |
| | | <el-option v-for="item in 24" :key="item" :label="item - 1" :value="item - 1" /> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const emit = defineEmits(['update']) |
| | | const props = defineProps({ |
| | | cron: { |
| | | type: Object, |
| | | default: { |
| | | second: "*", |
| | | min: "*", |
| | | hour: "*", |
| | | day: "*", |
| | | month: "*", |
| | | week: "?", |
| | | year: "", |
| | | } |
| | | }, |
| | | check: { |
| | | type: Function, |
| | | default: () => { |
| | | } |
| | | } |
| | | }) |
| | | const radioValue = ref(1) |
| | | const cycle01 = ref(0) |
| | | const cycle02 = ref(1) |
| | | const average01 = ref(0) |
| | | const average02 = ref(1) |
| | | const checkboxList = ref([]) |
| | | const checkCopy = ref([0]) |
| | | const cycleTotal = computed(() => { |
| | | cycle01.value = props.check(cycle01.value, 0, 22) |
| | | cycle02.value = props.check(cycle02.value, cycle01.value + 1, 23) |
| | | return cycle01.value + '-' + cycle02.value |
| | | }) |
| | | const averageTotal = computed(() => { |
| | | average01.value = props.check(average01.value, 0, 22) |
| | | average02.value = props.check(average02.value, 1, 23 - average01.value) |
| | | return average01.value + '/' + average02.value |
| | | }) |
| | | const checkboxString = computed(() => { |
| | | return checkboxList.value.join(',') |
| | | }) |
| | | watch(() => props.cron.hour, value => changeRadioValue(value)) |
| | | watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange()) |
| | | function changeRadioValue(value) { |
| | | if (props.cron.min === '*') { |
| | | emit('update', 'min', '0', 'hour') |
| | | } |
| | | if (props.cron.second === '*') { |
| | | emit('update', 'second', '0', 'hour') |
| | | } |
| | | if (value === '*') { |
| | | radioValue.value = 1 |
| | | } else if (value.indexOf('-') > -1) { |
| | | const indexArr = value.split('-') |
| | | cycle01.value = Number(indexArr[0]) |
| | | cycle02.value = Number(indexArr[1]) |
| | | radioValue.value = 2 |
| | | } else if (value.indexOf('/') > -1) { |
| | | const indexArr = value.split('/') |
| | | average01.value = Number(indexArr[0]) |
| | | average02.value = Number(indexArr[1]) |
| | | radioValue.value = 3 |
| | | } else { |
| | | checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))] |
| | | radioValue.value = 4 |
| | | } |
| | | } |
| | | function onRadioChange() { |
| | | switch (radioValue.value) { |
| | | case 1: |
| | | emit('update', 'hour', '*', 'hour') |
| | | break |
| | | case 2: |
| | | emit('update', 'hour', cycleTotal.value, 'hour') |
| | | break |
| | | case 3: |
| | | emit('update', 'hour', averageTotal.value, 'hour') |
| | | break |
| | | case 4: |
| | | if (checkboxList.value.length === 0) { |
| | | checkboxList.value.push(checkCopy.value[0]) |
| | | } else { |
| | | checkCopy.value = checkboxList.value |
| | | } |
| | | emit('update', 'hour', checkboxString.value, 'hour') |
| | | break |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .el-input-number--small, .el-select, .el-select--small { |
| | | margin: 0 0.2rem; |
| | | } |
| | | .el-select, .el-select--small { |
| | | width: 18.8rem; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-tabs type="border-card"> |
| | | <el-tab-pane label="ç§" v-if="shouldHide('second')"> |
| | | <CrontabSecond |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronsecond" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="åé" v-if="shouldHide('min')"> |
| | | <CrontabMin |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronmin" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="å°æ¶" v-if="shouldHide('hour')"> |
| | | <CrontabHour |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronhour" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="æ¥" v-if="shouldHide('day')"> |
| | | <CrontabDay |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronday" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="æ" v-if="shouldHide('month')"> |
| | | <CrontabMonth |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronmonth" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="å¨" v-if="shouldHide('week')"> |
| | | <CrontabWeek |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronweek" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="å¹´" v-if="shouldHide('year')"> |
| | | <CrontabYear |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronyear" |
| | | /> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <div class="popup-main"> |
| | | <div class="popup-result"> |
| | | <p class="title">æ¶é´è¡¨è¾¾å¼</p> |
| | | <table> |
| | | <thead> |
| | | <th v-for="item of tabTitles" :key="item">{{item}}</th> |
| | | <th>Cron 表达å¼</th> |
| | | </thead> |
| | | <tbody> |
| | | <td> |
| | | <span v-if="crontabValueObj.second.length < 10">{{crontabValueObj.second}}</span> |
| | | <el-tooltip v-else :content="crontabValueObj.second" placement="top"><span>{{crontabValueObj.second}}</span></el-tooltip> |
| | | </td> |
| | | <td> |
| | | <span v-if="crontabValueObj.min.length < 10">{{crontabValueObj.min}}</span> |
| | | <el-tooltip v-else :content="crontabValueObj.min" placement="top"><span>{{crontabValueObj.min}}</span></el-tooltip> |
| | | </td> |
| | | <td> |
| | | <span v-if="crontabValueObj.hour.length < 10">{{crontabValueObj.hour}}</span> |
| | | <el-tooltip v-else :content="crontabValueObj.hour" placement="top"><span>{{crontabValueObj.hour}}</span></el-tooltip> |
| | | </td> |
| | | <td> |
| | | <span v-if="crontabValueObj.day.length < 10">{{crontabValueObj.day}}</span> |
| | | <el-tooltip v-else :content="crontabValueObj.day" placement="top"><span>{{crontabValueObj.day}}</span></el-tooltip> |
| | | </td> |
| | | <td> |
| | | <span v-if="crontabValueObj.month.length < 10">{{crontabValueObj.month}}</span> |
| | | <el-tooltip v-else :content="crontabValueObj.month" placement="top"><span>{{crontabValueObj.month}}</span></el-tooltip> |
| | | </td> |
| | | <td> |
| | | <span v-if="crontabValueObj.week.length < 10">{{crontabValueObj.week}}</span> |
| | | <el-tooltip v-else :content="crontabValueObj.week" placement="top"><span>{{crontabValueObj.week}}</span></el-tooltip> |
| | | </td> |
| | | <td> |
| | | <span v-if="crontabValueObj.year.length < 10">{{crontabValueObj.year}}</span> |
| | | <el-tooltip v-else :content="crontabValueObj.year" placement="top"><span>{{crontabValueObj.year}}</span></el-tooltip> |
| | | </td> |
| | | <td class="result"> |
| | | <span v-if="crontabValueString.length < 90">{{crontabValueString}}</span> |
| | | <el-tooltip v-else :content="crontabValueString" placement="top"><span>{{crontabValueString}}</span></el-tooltip> |
| | | </td> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | <CrontabResult :ex="crontabValueString"></CrontabResult> |
| | | |
| | | <div class="pop_btn"> |
| | | <el-button type="primary" @click="submitFill">ç¡®å®</el-button> |
| | | <el-button type="warning" @click="clearCron">éç½®</el-button> |
| | | <el-button @click="hidePopup">åæ¶</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import CrontabSecond from "./second.vue" |
| | | import CrontabMin from "./min.vue" |
| | | import CrontabHour from "./hour.vue" |
| | | import CrontabDay from "./day.vue" |
| | | import CrontabMonth from "./month.vue" |
| | | import CrontabWeek from "./week.vue" |
| | | import CrontabYear from "./year.vue" |
| | | import CrontabResult from "./result.vue" |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits(['hide', 'fill']) |
| | | const props = defineProps({ |
| | | hideComponent: { |
| | | type: Array, |
| | | default: () => [], |
| | | }, |
| | | expression: { |
| | | type: String, |
| | | default: "" |
| | | } |
| | | }) |
| | | const tabTitles = ref(["ç§", "åé", "å°æ¶", "æ¥", "æ", "å¨", "å¹´"]) |
| | | const tabActive = ref(0) |
| | | const hideComponent = ref([]) |
| | | const expression = ref('') |
| | | const crontabValueObj = ref({ |
| | | second: "*", |
| | | min: "*", |
| | | hour: "*", |
| | | day: "*", |
| | | month: "*", |
| | | week: "?", |
| | | year: "", |
| | | }) |
| | | const crontabValueString = computed(() => { |
| | | const obj = crontabValueObj.value |
| | | return obj.second |
| | | + " " |
| | | + obj.min |
| | | + " " |
| | | + obj.hour |
| | | + " " |
| | | + obj.day |
| | | + " " |
| | | + obj.month |
| | | + " " |
| | | + obj.week |
| | | + (obj.year === "" ? "" : " " + obj.year) |
| | | }) |
| | | watch(expression, () => resolveExp()) |
| | | function shouldHide(key) { |
| | | return !(hideComponent.value && hideComponent.value.includes(key)) |
| | | } |
| | | function resolveExp() { |
| | | // åè§£æ è¡¨è¾¾å¼ |
| | | if (expression.value) { |
| | | const arr = expression.value.split(/\s+/) |
| | | if (arr.length >= 6) { |
| | | //6 ä½ä»¥ä¸æ¯åæ³è¡¨è¾¾å¼ |
| | | let obj = { |
| | | second: arr[0], |
| | | min: arr[1], |
| | | hour: arr[2], |
| | | day: arr[3], |
| | | month: arr[4], |
| | | week: arr[5], |
| | | year: arr[6] ? arr[6] : "" |
| | | } |
| | | crontabValueObj.value = { |
| | | ...obj, |
| | | } |
| | | } |
| | | } else { |
| | | // 没æä¼ å
¥çè¡¨è¾¾å¼ åè¿å |
| | | clearCron() |
| | | } |
| | | } |
| | | // tabåæ¢å¼ |
| | | function tabCheck(index) { |
| | | tabActive.value = index |
| | | } |
| | | // ç±åç»ä»¶è§¦åï¼æ´æ¹è¡¨è¾¾å¼ç»æçåæ®µå¼ |
| | | function updateCrontabValue(name, value, from) { |
| | | crontabValueObj.value[name] = value |
| | | } |
| | | // 表åé项çåç»ä»¶æ ¡éªæ°åæ ¼å¼ï¼éè¿-propsä¼ éï¼ |
| | | function checkNumber(value, minLimit, maxLimit) { |
| | | // æ£æ¥å¿
é¡»ä¸ºæ´æ° |
| | | value = Math.floor(value) |
| | | if (value < minLimit) { |
| | | value = minLimit |
| | | } else if (value > maxLimit) { |
| | | value = maxLimit |
| | | } |
| | | return value |
| | | } |
| | | // éèå¼¹çª |
| | | function hidePopup() { |
| | | emit("hide") |
| | | } |
| | | // å¡«å
è¡¨è¾¾å¼ |
| | | function submitFill() { |
| | | emit("fill", crontabValueString.value) |
| | | hidePopup() |
| | | } |
| | | function clearCron() { |
| | | // è¿å鿩项 |
| | | crontabValueObj.value = { |
| | | second: "*", |
| | | min: "*", |
| | | hour: "*", |
| | | day: "*", |
| | | month: "*", |
| | | week: "?", |
| | | year: "", |
| | | } |
| | | } |
| | | onMounted(() => { |
| | | expression.value = props.expression |
| | | hideComponent.value = props.hideComponent |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .pop_btn { |
| | | text-align: center; |
| | | margin-top: 20px; |
| | | } |
| | | .popup-main { |
| | | position: relative; |
| | | margin: 10px auto; |
| | | border-radius: 5px; |
| | | font-size: 12px; |
| | | overflow: hidden; |
| | | } |
| | | .popup-title { |
| | | overflow: hidden; |
| | | line-height: 34px; |
| | | padding-top: 6px; |
| | | background: #f2f2f2; |
| | | } |
| | | .popup-result { |
| | | box-sizing: border-box; |
| | | line-height: 24px; |
| | | margin: 25px auto; |
| | | padding: 15px 10px 10px; |
| | | border: 1px solid #ccc; |
| | | position: relative; |
| | | } |
| | | .popup-result .title { |
| | | position: absolute; |
| | | top: -28px; |
| | | left: 50%; |
| | | width: 140px; |
| | | font-size: 14px; |
| | | margin-left: -70px; |
| | | text-align: center; |
| | | line-height: 30px; |
| | | background: #fff; |
| | | } |
| | | .popup-result table { |
| | | text-align: center; |
| | | width: 100%; |
| | | margin: 0 auto; |
| | | } |
| | | .popup-result table td:not(.result) { |
| | | width: 3.5rem; |
| | | min-width: 3.5rem; |
| | | max-width: 3.5rem; |
| | | } |
| | | .popup-result table span { |
| | | display: block; |
| | | width: 100%; |
| | | font-family: arial; |
| | | line-height: 30px; |
| | | height: 30px; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | border: 1px solid #e8e8e8; |
| | | } |
| | | .popup-result-scroll { |
| | | font-size: 12px; |
| | | line-height: 24px; |
| | | height: 10em; |
| | | overflow-y: auto; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-form> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="1"> |
| | | åéï¼å
许çéé
符[, - * /] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="2"> |
| | | å¨æä» |
| | | <el-input-number v-model='cycle01' :min="0" :max="58" /> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="59" /> åé |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="3"> |
| | | ä» |
| | | <el-input-number v-model='average01' :min="0" :max="58" /> åéå¼å§ï¼ æ¯ |
| | | <el-input-number v-model='average02' :min="1" :max="59 - average01" /> åéæ§è¡ä¸æ¬¡ |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="4"> |
| | | æå® |
| | | <el-select clearable v-model="checkboxList" placeholder="å¯å¤é" multiple :multiple-limit="10"> |
| | | <el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" /> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | <script setup> |
| | | const emit = defineEmits(['update']) |
| | | const props = defineProps({ |
| | | cron: { |
| | | type: Object, |
| | | default: { |
| | | second: "*", |
| | | min: "*", |
| | | hour: "*", |
| | | day: "*", |
| | | month: "*", |
| | | week: "?", |
| | | year: "", |
| | | } |
| | | }, |
| | | check: { |
| | | type: Function, |
| | | default: () => { |
| | | } |
| | | } |
| | | }) |
| | | const radioValue = ref(1) |
| | | const cycle01 = ref(0) |
| | | const cycle02 = ref(1) |
| | | const average01 = ref(0) |
| | | const average02 = ref(1) |
| | | const checkboxList = ref([]) |
| | | const checkCopy = ref([0]) |
| | | const cycleTotal = computed(() => { |
| | | cycle01.value = props.check(cycle01.value, 0, 58) |
| | | cycle02.value = props.check(cycle02.value, cycle01.value + 1, 59) |
| | | return cycle01.value + '-' + cycle02.value |
| | | }) |
| | | const averageTotal = computed(() => { |
| | | average01.value = props.check(average01.value, 0, 58) |
| | | average02.value = props.check(average02.value, 1, 59 - average01.value) |
| | | return average01.value + '/' + average02.value |
| | | }) |
| | | const checkboxString = computed(() => { |
| | | return checkboxList.value.join(',') |
| | | }) |
| | | watch(() => props.cron.min, value => changeRadioValue(value)) |
| | | watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange()) |
| | | function changeRadioValue(value) { |
| | | if (value === '*') { |
| | | radioValue.value = 1 |
| | | } else if (value.indexOf('-') > -1) { |
| | | const indexArr = value.split('-') |
| | | cycle01.value = Number(indexArr[0]) |
| | | cycle02.value = Number(indexArr[1]) |
| | | radioValue.value = 2 |
| | | } else if (value.indexOf('/') > -1) { |
| | | const indexArr = value.split('/') |
| | | average01.value = Number(indexArr[0]) |
| | | average02.value = Number(indexArr[1]) |
| | | radioValue.value = 3 |
| | | } else { |
| | | checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))] |
| | | radioValue.value = 4 |
| | | } |
| | | } |
| | | function onRadioChange() { |
| | | switch (radioValue.value) { |
| | | case 1: |
| | | emit('update', 'min', '*', 'min') |
| | | break |
| | | case 2: |
| | | emit('update', 'min', cycleTotal.value, 'min') |
| | | break |
| | | case 3: |
| | | emit('update', 'min', averageTotal.value, 'min') |
| | | break |
| | | case 4: |
| | | if (checkboxList.value.length === 0) { |
| | | checkboxList.value.push(checkCopy.value[0]) |
| | | } else { |
| | | checkCopy.value = checkboxList.value |
| | | } |
| | | emit('update', 'min', checkboxString.value, 'min') |
| | | break |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .el-input-number--small, .el-select, .el-select--small { |
| | | margin: 0 0.2rem; |
| | | } |
| | | .el-select, .el-select--small { |
| | | width: 19.8rem; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-form> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="1"> |
| | | æï¼å
许çéé
符[, - * /] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="2"> |
| | | å¨æä» |
| | | <el-input-number v-model='cycle01' :min="1" :max="11" /> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="12" /> æ |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="3"> |
| | | ä» |
| | | <el-input-number v-model='average01' :min="1" :max="11" /> æå¼å§ï¼æ¯ |
| | | <el-input-number v-model='average02' :min="1" :max="12 - average01" /> æææ§è¡ä¸æ¬¡ |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="4"> |
| | | æå® |
| | | <el-select clearable v-model="checkboxList" placeholder="å¯å¤é" multiple :multiple-limit="8"> |
| | | <el-option v-for="item in monthList" :key="item.key" :label="item.value" :value="item.key" /> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const emit = defineEmits(['update']) |
| | | const props = defineProps({ |
| | | cron: { |
| | | type: Object, |
| | | default: { |
| | | second: "*", |
| | | min: "*", |
| | | hour: "*", |
| | | day: "*", |
| | | month: "*", |
| | | week: "?", |
| | | year: "", |
| | | } |
| | | }, |
| | | check: { |
| | | type: Function, |
| | | default: () => { |
| | | } |
| | | } |
| | | }) |
| | | const radioValue = ref(1) |
| | | const cycle01 = ref(1) |
| | | const cycle02 = ref(2) |
| | | const average01 = ref(1) |
| | | const average02 = ref(1) |
| | | const checkboxList = ref([]) |
| | | const checkCopy = ref([1]) |
| | | const monthList = ref([ |
| | | {key: 1, value: '䏿'}, |
| | | {key: 2, value: 'äºæ'}, |
| | | {key: 3, value: '䏿'}, |
| | | {key: 4, value: 'åæ'}, |
| | | {key: 5, value: 'äºæ'}, |
| | | {key: 6, value: 'å
æ'}, |
| | | {key: 7, value: '䏿'}, |
| | | {key: 8, value: 'å
«æ'}, |
| | | {key: 9, value: '乿'}, |
| | | {key: 10, value: 'åæ'}, |
| | | {key: 11, value: 'å䏿'}, |
| | | {key: 12, value: 'åäºæ'} |
| | | ]) |
| | | const cycleTotal = computed(() => { |
| | | cycle01.value = props.check(cycle01.value, 1, 11) |
| | | cycle02.value = props.check(cycle02.value, cycle01.value + 1, 12) |
| | | return cycle01.value + '-' + cycle02.value |
| | | }) |
| | | const averageTotal = computed(() => { |
| | | average01.value = props.check(average01.value, 1, 11) |
| | | average02.value = props.check(average02.value, 1, 12 - average01.value) |
| | | return average01.value + '/' + average02.value |
| | | }) |
| | | const checkboxString = computed(() => { |
| | | return checkboxList.value.join(',') |
| | | }) |
| | | watch(() => props.cron.month, value => changeRadioValue(value)) |
| | | watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange()) |
| | | function changeRadioValue(value) { |
| | | if (value === '*') { |
| | | radioValue.value = 1 |
| | | } else if (value.indexOf('-') > -1) { |
| | | const indexArr = value.split('-') |
| | | cycle01.value = Number(indexArr[0]) |
| | | cycle02.value = Number(indexArr[1]) |
| | | radioValue.value = 2 |
| | | } else if (value.indexOf('/') > -1) { |
| | | const indexArr = value.split('/') |
| | | average01.value = Number(indexArr[0]) |
| | | average02.value = Number(indexArr[1]) |
| | | radioValue.value = 3 |
| | | } else { |
| | | checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))] |
| | | radioValue.value = 4 |
| | | } |
| | | } |
| | | function onRadioChange() { |
| | | switch (radioValue.value) { |
| | | case 1: |
| | | emit('update', 'month', '*', 'month') |
| | | break |
| | | case 2: |
| | | emit('update', 'month', cycleTotal.value, 'month') |
| | | break |
| | | case 3: |
| | | emit('update', 'month', averageTotal.value, 'month') |
| | | break |
| | | case 4: |
| | | if (checkboxList.value.length === 0) { |
| | | checkboxList.value.push(checkCopy.value[0]) |
| | | } else { |
| | | checkCopy.value = checkboxList.value |
| | | } |
| | | emit('update', 'month', checkboxString.value, 'month') |
| | | break |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .el-input-number--small, .el-select, .el-select--small { |
| | | margin: 0 0.2rem; |
| | | } |
| | | .el-select, .el-select--small { |
| | | width: 18.8rem; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="popup-result"> |
| | | <p class="title">æè¿5次è¿è¡æ¶é´</p> |
| | | <ul class="popup-result-scroll"> |
| | | <template v-if='isShow'> |
| | | <li v-for='item in resultList' :key="item">{{item}}</li> |
| | | </template> |
| | | <li v-else>计ç®ç»æä¸...</li> |
| | | </ul> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const props = defineProps({ |
| | | ex: { |
| | | type: String, |
| | | default: '' |
| | | } |
| | | }) |
| | | const dayRule = ref('') |
| | | const dayRuleSup = ref('') |
| | | const dateArr = ref([]) |
| | | const resultList = ref([]) |
| | | const isShow = ref(false) |
| | | watch(() => props.ex, () => expressionChange()) |
| | | // 表达å¼å¼ååæ¶ï¼å¼å§å»è®¡ç®ç»æ |
| | | function expressionChange() { |
| | | // 计ç®å¼å§-éèç»æ |
| | | isShow.value = false |
| | | // è·åè§åæ°ç»[0ç§ã1åã2æ¶ã3æ¥ã4æã5ææã6å¹´] |
| | | let ruleArr = props.ex.split(' ') |
| | | // ç¨äºè®°å½è¿å
¥å¾ªç¯çæ¬¡æ° |
| | | let nums = 0 |
| | | // ç¨äºææ¶åç¬¦å·æ¶é´è§åç»æçæ°ç» |
| | | let resultArr = [] |
| | | // è·åå½åæ¶é´ç²¾ç¡®è³[å¹´ãæãæ¥ãæ¶ãåãç§] |
| | | let nTime = new Date() |
| | | let nYear = nTime.getFullYear() |
| | | let nMonth = nTime.getMonth() + 1 |
| | | let nDay = nTime.getDate() |
| | | let nHour = nTime.getHours() |
| | | let nMin = nTime.getMinutes() |
| | | let nSecond = nTime.getSeconds() |
| | | // æ ¹æ®è§åè·åå°è¿100å¹´å¯è½å¹´æ°ç»ãææ°ç»çç |
| | | getSecondArr(ruleArr[0]) |
| | | getMinArr(ruleArr[1]) |
| | | getHourArr(ruleArr[2]) |
| | | getDayArr(ruleArr[3]) |
| | | getMonthArr(ruleArr[4]) |
| | | getWeekArr(ruleArr[5]) |
| | | getYearArr(ruleArr[6], nYear) |
| | | // å°è·åå°çæ°ç»èµå¼-æ¹ä¾¿ä½¿ç¨ |
| | | let sDate = dateArr.value[0] |
| | | let mDate = dateArr.value[1] |
| | | let hDate = dateArr.value[2] |
| | | let DDate = dateArr.value[3] |
| | | let MDate = dateArr.value[4] |
| | | let YDate = dateArr.value[5] |
| | | // è·åå½åæ¶é´å¨æ°ç»ä¸çç´¢å¼ |
| | | let sIdx = getIndex(sDate, nSecond) |
| | | let mIdx = getIndex(mDate, nMin) |
| | | let hIdx = getIndex(hDate, nHour) |
| | | let DIdx = getIndex(DDate, nDay) |
| | | let MIdx = getIndex(MDate, nMonth) |
| | | let YIdx = getIndex(YDate, nYear) |
| | | // éç½®ææ¥æ¶åç§ç彿°(åé¢ç¨çæ¯è¾å¤) |
| | | const resetSecond = function () { |
| | | sIdx = 0 |
| | | nSecond = sDate[sIdx] |
| | | } |
| | | const resetMin = function () { |
| | | mIdx = 0 |
| | | nMin = mDate[mIdx] |
| | | resetSecond() |
| | | } |
| | | const resetHour = function () { |
| | | hIdx = 0 |
| | | nHour = hDate[hIdx] |
| | | resetMin() |
| | | } |
| | | const resetDay = function () { |
| | | DIdx = 0 |
| | | nDay = DDate[DIdx] |
| | | resetHour() |
| | | } |
| | | const resetMonth = function () { |
| | | MIdx = 0 |
| | | nMonth = MDate[MIdx] |
| | | resetDay() |
| | | } |
| | | // 妿å½å年份ä¸ä¸ºæ°ç»ä¸å½åå¼ |
| | | if (nYear !== YDate[YIdx]) { |
| | | resetMonth() |
| | | } |
| | | // 妿å½åæä»½ä¸ä¸ºæ°ç»ä¸å½åå¼ |
| | | if (nMonth !== MDate[MIdx]) { |
| | | resetDay() |
| | | } |
| | | // 妿å½åâæ¥âä¸ä¸ºæ°ç»ä¸å½åå¼ |
| | | if (nDay !== DDate[DIdx]) { |
| | | resetHour() |
| | | } |
| | | // 妿å½åâæ¶âä¸ä¸ºæ°ç»ä¸å½åå¼ |
| | | if (nHour !== hDate[hIdx]) { |
| | | resetMin() |
| | | } |
| | | // 妿å½åâåâä¸ä¸ºæ°ç»ä¸å½åå¼ |
| | | if (nMin !== mDate[mIdx]) { |
| | | resetSecond() |
| | | } |
| | | // 循ç¯å¹´ä»½æ°ç» |
| | | goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) { |
| | | let YY = YDate[Yi] |
| | | // 妿å°è¾¾æå¤§å¼æ¶ |
| | | if (nMonth > MDate[MDate.length - 1]) { |
| | | resetMonth() |
| | | continue |
| | | } |
| | | // å¾ªç¯æä»½æ°ç» |
| | | goMonth: for (let Mi = MIdx; Mi < MDate.length; Mi++) { |
| | | // èµå¼ãæ¹ä¾¿åé¢è¿ç® |
| | | let MM = MDate[Mi]; |
| | | MM = MM < 10 ? '0' + MM : MM |
| | | // 妿å°è¾¾æå¤§å¼æ¶ |
| | | if (nDay > DDate[DDate.length - 1]) { |
| | | resetDay() |
| | | if (Mi === MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue |
| | | } |
| | | // å¾ªç¯æ¥ææ°ç» |
| | | goDay: for (let Di = DIdx; Di < DDate.length; Di++) { |
| | | // èµå¼ãæ¹ä¾¿åé¢è¿ç® |
| | | let DD = DDate[Di] |
| | | let thisDD = DD < 10 ? '0' + DD : DD |
| | | // 妿å°è¾¾æå¤§å¼æ¶ |
| | | if (nHour > hDate[hDate.length - 1]) { |
| | | resetHour() |
| | | if (Di === DDate.length - 1) { |
| | | resetDay() |
| | | if (Mi === MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue goMonth |
| | | } |
| | | continue |
| | | } |
| | | // å¤ææ¥æçåæ³æ§ï¼ä¸åæ³çè¯ä¹æ¯è·³åºå½åå¾ªç¯ |
| | | if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && dayRule.value !== 'workDay' && dayRule.value !== 'lastWeek' && dayRule.value !== 'lastDay') { |
| | | resetDay() |
| | | continue goMonth |
| | | } |
| | | // å¦ææ¥æè§å䏿弿¶ |
| | | if (dayRule.value === 'lastDay') { |
| | | // 妿䏿¯åæ³æ¥æåéè¦å°åå°æ¥æè°å°åæ³æ¥æå³ææ«æåä¸å¤© |
| | | if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | DD-- |
| | | thisDD = DD < 10 ? '0' + DD : DD |
| | | } |
| | | } |
| | | } else if (dayRule.value === 'workDay') { |
| | | // æ ¡éªå¹¶è°æ´å¦ææ¯2æ30å·è¿ç§æ¥æä¼ è¿æ¥æ¶éè°æ´è³æ£å¸¸æåº |
| | | if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | DD-- |
| | | thisDD = DD < 10 ? '0' + DD : DD |
| | | } |
| | | } |
| | | // è·åè¾¾å°æ¡ä»¶çæ¥ææ¯ææX |
| | | let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week') |
| | | // å½æææ¥æ¶ |
| | | if (thisWeek === 1) { |
| | | // å
æ¾ä¸ä¸ä¸ªæ¥ï¼å¹¶å¤ææ¯å¦ä¸ºæåº |
| | | DD++ |
| | | thisDD = DD < 10 ? '0' + DD : DD |
| | | // 夿ä¸ä¸æ¥å·²ç»ä¸æ¯åæ³æ¥æ |
| | | if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | DD -= 3 |
| | | } |
| | | } else if (thisWeek === 7) { |
| | | // 彿æ6æ¶åªé夿䏿¯1å·å°±å¯è¿è¡æä½ |
| | | if (dayRuleSup.value !== 1) { |
| | | DD-- |
| | | } else { |
| | | DD += 2 |
| | | } |
| | | } |
| | | } else if (dayRule.value === 'weekDay') { |
| | | // 妿æå®äºæ¯ææå |
| | | // è·åå½åæ¥ææ¯å±äºææå |
| | | let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week') |
| | | // æ ¡éªå½åæææ¯å¦å¨æææ± ï¼dayRuleSupï¼ä¸ |
| | | if (dayRuleSup.value.indexOf(thisWeek) < 0) { |
| | | // 妿å°è¾¾æå¤§å¼æ¶ |
| | | if (Di === DDate.length - 1) { |
| | | resetDay() |
| | | if (Mi === MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue goMonth |
| | | } |
| | | continue |
| | | } |
| | | } else if (dayRule.value === 'assWeek') { |
| | | // 妿æå®äºæ¯ç¬¬å å¨çææå |
| | | // è·åæ¯æ1å·æ¯å±äºææå |
| | | let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week') |
| | | if (dayRuleSup.value[1] >= thisWeek) { |
| | | DD = (dayRuleSup.value[0] - 1) * 7 + dayRuleSup.value[1] - thisWeek + 1 |
| | | } else { |
| | | DD = dayRuleSup.value[0] * 7 + dayRuleSup.value[1] - thisWeek + 1 |
| | | } |
| | | } else if (dayRule.value === 'lastWeek') { |
| | | // 妿æå®äºæ¯ææåä¸ä¸ªææå |
| | | // æ ¡éªå¹¶è°æ´å¦ææ¯2æ30å·è¿ç§æ¥æä¼ è¿æ¥æ¶éè°æ´è³æ£å¸¸æåº |
| | | if (checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | while (DD > 0 && checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | DD-- |
| | | thisDD = DD < 10 ? '0' + DD : DD |
| | | } |
| | | } |
| | | // è·åææ«æåä¸å¤©æ¯ææå |
| | | let thisWeek = formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week') |
| | | // æ¾å°è¦æ±ä¸æè¿çé£ä¸ªææå |
| | | if (dayRuleSup.value < thisWeek) { |
| | | DD -= thisWeek - dayRuleSup.value |
| | | } else if (dayRuleSup.value > thisWeek) { |
| | | DD -= 7 - (dayRuleSup.value - thisWeek) |
| | | } |
| | | } |
| | | // 夿æ¶é´å¼æ¯å¦å°äº10ç½®æ¢æâ05âè¿ç§æ ¼å¼ |
| | | DD = DD < 10 ? '0' + DD : DD |
| | | // 循ç¯âæ¶âæ°ç» |
| | | goHour: for (let hi = hIdx; hi < hDate.length; hi++) { |
| | | let hh = hDate[hi] < 10 ? '0' + hDate[hi] : hDate[hi] |
| | | // 妿å°è¾¾æå¤§å¼æ¶ |
| | | if (nMin > mDate[mDate.length - 1]) { |
| | | resetMin() |
| | | if (hi === hDate.length - 1) { |
| | | resetHour() |
| | | if (Di === DDate.length - 1) { |
| | | resetDay() |
| | | if (Mi === MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue goMonth |
| | | } |
| | | continue goDay |
| | | } |
| | | continue |
| | | } |
| | | // 循ç¯"å"æ°ç» |
| | | goMin: for (let mi = mIdx; mi < mDate.length; mi++) { |
| | | let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi] |
| | | // 妿å°è¾¾æå¤§å¼æ¶ |
| | | if (nSecond > sDate[sDate.length - 1]) { |
| | | resetSecond() |
| | | if (mi === mDate.length - 1) { |
| | | resetMin() |
| | | if (hi === hDate.length - 1) { |
| | | resetHour() |
| | | if (Di === DDate.length - 1) { |
| | | resetDay() |
| | | if (Mi === MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue goMonth |
| | | } |
| | | continue goDay |
| | | } |
| | | continue goHour |
| | | } |
| | | continue |
| | | } |
| | | // 循ç¯"ç§"æ°ç» |
| | | goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) { |
| | | let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si] |
| | | // æ·»å å½åæ¶é´ï¼æ¶é´åæ³æ§å¨æ¥æå¾ªç¯æ¶å·²ç»å¤æï¼ |
| | | if (MM !== '00' && DD !== '00') { |
| | | resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss) |
| | | nums++ |
| | | } |
| | | // å¦ææ¡æ°æ»¡äºå°±éåºå¾ªç¯ |
| | | if (nums === 5) break goYear |
| | | // 妿å°è¾¾æå¤§å¼æ¶ |
| | | if (si === sDate.length - 1) { |
| | | resetSecond() |
| | | if (mi === mDate.length - 1) { |
| | | resetMin() |
| | | if (hi === hDate.length - 1) { |
| | | resetHour() |
| | | if (Di === DDate.length - 1) { |
| | | resetDay() |
| | | if (Mi === MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue goMonth |
| | | } |
| | | continue goDay |
| | | } |
| | | continue goHour |
| | | } |
| | | continue goMin |
| | | } |
| | | } //goSecond |
| | | } //goMin |
| | | }//goHour |
| | | }//goDay |
| | | }//goMonth |
| | | } |
| | | // 夿100å¹´å
çç»ææ¡æ° |
| | | if (resultArr.length === 0) { |
| | | resultList.value = ['没æè¾¾å°æ¡ä»¶çç»æï¼'] |
| | | } else { |
| | | resultList.value = resultArr |
| | | if (resultArr.length !== 5) { |
| | | resultList.value.push('æè¿100å¹´å
åªæä¸é¢' + resultArr.length + 'æ¡ç»æï¼') |
| | | } |
| | | } |
| | | // 计ç®å®æ-æ¾ç¤ºç»æ |
| | | isShow.value = true |
| | | } |
| | | // ç¨äºè®¡ç®æä½æ°å卿°ç»ä¸çç´¢å¼ |
| | | function getIndex(arr, value) { |
| | | if (value <= arr[0] || value > arr[arr.length - 1]) { |
| | | return 0 |
| | | } else { |
| | | for (let i = 0; i < arr.length - 1; i++) { |
| | | if (value > arr[i] && value <= arr[i + 1]) { |
| | | return i + 1 |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // è·å"å¹´"æ°ç» |
| | | function getYearArr(rule, year) { |
| | | dateArr.value[5] = getOrderArr(year, year + 100) |
| | | if (rule !== undefined) { |
| | | if (rule.indexOf('-') >= 0) { |
| | | dateArr.value[5] = getCycleArr(rule, year + 100, false) |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | dateArr.value[5] = getAverageArr(rule, year + 100) |
| | | } else if (rule !== '*') { |
| | | dateArr.value[5] = getAssignArr(rule) |
| | | } |
| | | } |
| | | } |
| | | // è·å"æ"æ°ç» |
| | | function getMonthArr(rule) { |
| | | dateArr.value[4] = getOrderArr(1, 12) |
| | | if (rule.indexOf('-') >= 0) { |
| | | dateArr.value[4] = getCycleArr(rule, 12, false) |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | dateArr.value[4] = getAverageArr(rule, 12) |
| | | } else if (rule !== '*') { |
| | | dateArr.value[4] = getAssignArr(rule) |
| | | } |
| | | } |
| | | // è·å"æ¥"æ°ç»-主è¦ä¸ºæ¥æè§å |
| | | function getWeekArr(rule) { |
| | | // åªæå½æ¥æè§åç两个å¼å为ââæ¶åè¡¨è¾¾æ¥ææ¯æé项ç |
| | | if (dayRule.value === '' && dayRuleSup.value === '') { |
| | | if (rule.indexOf('-') >= 0) { |
| | | dayRule.value = 'weekDay' |
| | | dayRuleSup.value = getCycleArr(rule, 7, false) |
| | | } else if (rule.indexOf('#') >= 0) { |
| | | dayRule.value = 'assWeek' |
| | | let matchRule = rule.match(/[0-9]{1}/g) |
| | | dayRuleSup.value = [Number(matchRule[1]), Number(matchRule[0])] |
| | | dateArr.value[3] = [1] |
| | | if (dayRuleSup.value[1] === 7) { |
| | | dayRuleSup.value[1] = 0 |
| | | } |
| | | } else if (rule.indexOf('L') >= 0) { |
| | | dayRule.value = 'lastWeek' |
| | | dayRuleSup.value = Number(rule.match(/[0-9]{1,2}/g)[0]) |
| | | dateArr.value[3] = [31] |
| | | if (dayRuleSup.value === 7) { |
| | | dayRuleSup.value = 0 |
| | | } |
| | | } else if (rule !== '*' && rule !== '?') { |
| | | dayRule.value = 'weekDay' |
| | | dayRuleSup.value = getAssignArr(rule) |
| | | } |
| | | } |
| | | } |
| | | // è·å"æ¥"æ°ç»-å°éä¸ºæ¥æè§å |
| | | function getDayArr(rule) { |
| | | dateArr.value[3] = getOrderArr(1, 31) |
| | | dayRule.value = '' |
| | | dayRuleSup.value = '' |
| | | if (rule.indexOf('-') >= 0) { |
| | | dateArr.value[3] = getCycleArr(rule, 31, false) |
| | | dayRuleSup.value = 'null' |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | dateArr.value[3] = getAverageArr(rule, 31) |
| | | dayRuleSup.value = 'null' |
| | | } else if (rule.indexOf('W') >= 0) { |
| | | dayRule.value = 'workDay' |
| | | dayRuleSup.value = Number(rule.match(/[0-9]{1,2}/g)[0]) |
| | | dateArr.value[3] = [dayRuleSup.value] |
| | | } else if (rule.indexOf('L') >= 0) { |
| | | dayRule.value = 'lastDay' |
| | | dayRuleSup.value = 'null' |
| | | dateArr.value[3] = [31] |
| | | } else if (rule !== '*' && rule !== '?') { |
| | | dateArr.value[3] = getAssignArr(rule) |
| | | dayRuleSup.value = 'null' |
| | | } else if (rule === '*') { |
| | | dayRuleSup.value = 'null' |
| | | } |
| | | } |
| | | // è·å"æ¶"æ°ç» |
| | | function getHourArr(rule) { |
| | | dateArr.value[2] = getOrderArr(0, 23) |
| | | if (rule.indexOf('-') >= 0) { |
| | | dateArr.value[2] = getCycleArr(rule, 24, true) |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | dateArr.value[2] = getAverageArr(rule, 23) |
| | | } else if (rule !== '*') { |
| | | dateArr.value[2] = getAssignArr(rule) |
| | | } |
| | | } |
| | | // è·å"å"æ°ç» |
| | | function getMinArr(rule) { |
| | | dateArr.value[1] = getOrderArr(0, 59) |
| | | if (rule.indexOf('-') >= 0) { |
| | | dateArr.value[1] = getCycleArr(rule, 60, true) |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | dateArr.value[1] = getAverageArr(rule, 59) |
| | | } else if (rule !== '*') { |
| | | dateArr.value[1] = getAssignArr(rule) |
| | | } |
| | | } |
| | | // è·å"ç§"æ°ç» |
| | | function getSecondArr(rule) { |
| | | dateArr.value[0] = getOrderArr(0, 59) |
| | | if (rule.indexOf('-') >= 0) { |
| | | dateArr.value[0] = getCycleArr(rule, 60, true) |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | dateArr.value[0] = getAverageArr(rule, 59) |
| | | } else if (rule !== '*') { |
| | | dateArr.value[0] = getAssignArr(rule) |
| | | } |
| | | } |
| | | // æ ¹æ®ä¼ è¿æ¥çmin-maxè¿åä¸ä¸ªé¡ºåºçæ°ç» |
| | | function getOrderArr(min, max) { |
| | | let arr = [] |
| | | for (let i = min; i <= max; i++) { |
| | | arr.push(i) |
| | | } |
| | | return arr |
| | | } |
| | | // æ ¹æ®è§å䏿å®çé¶æ£å¼è¿åä¸ä¸ªæ°ç» |
| | | function getAssignArr(rule) { |
| | | let arr = [] |
| | | let assiginArr = rule.split(',') |
| | | for (let i = 0; i < assiginArr.length; i++) { |
| | | arr[i] = Number(assiginArr[i]) |
| | | } |
| | | arr.sort(compare) |
| | | return arr |
| | | } |
| | | // æ ¹æ®ä¸å®ç®æ¯è§å计ç®è¿åä¸ä¸ªæ°ç» |
| | | function getAverageArr(rule, limit) { |
| | | let arr = [] |
| | | let agArr = rule.split('/') |
| | | let min = Number(agArr[0]) |
| | | let step = Number(agArr[1]) |
| | | while (min <= limit) { |
| | | arr.push(min) |
| | | min += step |
| | | } |
| | | return arr |
| | | } |
| | | // æ ¹æ®è§åè¿åä¸ä¸ªå
·æå¨ææ§çæ°ç» |
| | | function getCycleArr(rule, limit, status) { |
| | | // status--表示æ¯å¦ä»0å¼å§ï¼åä»1å¼å§ï¼ |
| | | let arr = [] |
| | | let cycleArr = rule.split('-') |
| | | let min = Number(cycleArr[0]) |
| | | let max = Number(cycleArr[1]) |
| | | if (min > max) { |
| | | max += limit |
| | | } |
| | | for (let i = min; i <= max; i++) { |
| | | let add = 0 |
| | | if (status === false && i % limit === 0) { |
| | | add = limit |
| | | } |
| | | arr.push(Math.round(i % limit + add)) |
| | | } |
| | | arr.sort(compare) |
| | | return arr |
| | | } |
| | | // æ¯è¾æ°å大å°ï¼ç¨äºArray.sortï¼ |
| | | function compare(value1, value2) { |
| | | if (value2 - value1 > 0) { |
| | | return -1 |
| | | } else { |
| | | return 1 |
| | | } |
| | | } |
| | | // æ ¼å¼åæ¥ææ ¼å¼å¦ï¼2017-9-19 18:04:33 |
| | | function formatDate(value, type) { |
| | | // è®¡ç®æ¥æç¸å
³å¼ |
| | | let time = typeof value == 'number' ? new Date(value) : value |
| | | let Y = time.getFullYear() |
| | | let M = time.getMonth() + 1 |
| | | let D = time.getDate() |
| | | let h = time.getHours() |
| | | let m = time.getMinutes() |
| | | let s = time.getSeconds() |
| | | let week = time.getDay() |
| | | // å¦æä¼ éäºtypeçè¯ |
| | | if (type === undefined) { |
| | | return Y + '-' + (M < 10 ? '0' + M : M) + '-' + (D < 10 ? '0' + D : D) + ' ' + (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s) |
| | | } else if (type === 'week') { |
| | | // å¨quartzä¸ 1ä¸ºæææ¥ |
| | | return week + 1 |
| | | } |
| | | } |
| | | // æ£æ¥æ¥ææ¯å¦åå¨ |
| | | function checkDate(value) { |
| | | let time = new Date(value) |
| | | let format = formatDate(time) |
| | | return value === format |
| | | } |
| | | onMounted(() => { |
| | | expressionChange() |
| | | }) |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-form> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="1"> |
| | | ç§ï¼å
许çéé
符[, - * /] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="2"> |
| | | å¨æä» |
| | | <el-input-number v-model='cycle01' :min="0" :max="58" /> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 + 1" :max="59" /> ç§ |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="3"> |
| | | ä» |
| | | <el-input-number v-model='average01' :min="0" :max="58" /> ç§å¼å§ï¼æ¯ |
| | | <el-input-number v-model='average02' :min="1" :max="59 - average01" /> ç§æ§è¡ä¸æ¬¡ |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="4"> |
| | | æå® |
| | | <el-select clearable v-model="checkboxList" placeholder="å¯å¤é" multiple :multiple-limit="10"> |
| | | <el-option v-for="item in 60" :key="item" :label="item - 1" :value="item - 1" /> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const emit = defineEmits(['update']) |
| | | const props = defineProps({ |
| | | cron: { |
| | | type: Object, |
| | | default: { |
| | | second: "*", |
| | | min: "*", |
| | | hour: "*", |
| | | day: "*", |
| | | month: "*", |
| | | week: "?", |
| | | year: "", |
| | | } |
| | | }, |
| | | check: { |
| | | type: Function, |
| | | default: () => { |
| | | } |
| | | } |
| | | }) |
| | | const radioValue = ref(1) |
| | | const cycle01 = ref(0) |
| | | const cycle02 = ref(1) |
| | | const average01 = ref(0) |
| | | const average02 = ref(1) |
| | | const checkboxList = ref([]) |
| | | const checkCopy = ref([0]) |
| | | const cycleTotal = computed(() => { |
| | | cycle01.value = props.check(cycle01.value, 0, 58) |
| | | cycle02.value = props.check(cycle02.value, cycle01.value + 1, 59) |
| | | return cycle01.value + '-' + cycle02.value |
| | | }) |
| | | const averageTotal = computed(() => { |
| | | average01.value = props.check(average01.value, 0, 58) |
| | | average02.value = props.check(average02.value, 1, 59 - average01.value) |
| | | return average01.value + '/' + average02.value |
| | | }) |
| | | const checkboxString = computed(() => { |
| | | return checkboxList.value.join(',') |
| | | }) |
| | | watch(() => props.cron.second, value => changeRadioValue(value)) |
| | | watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange()) |
| | | function changeRadioValue(value) { |
| | | if (value === '*') { |
| | | radioValue.value = 1 |
| | | } else if (value.indexOf('-') > -1) { |
| | | const indexArr = value.split('-') |
| | | cycle01.value = Number(indexArr[0]) |
| | | cycle02.value = Number(indexArr[1]) |
| | | radioValue.value = 2 |
| | | } else if (value.indexOf('/') > -1) { |
| | | const indexArr = value.split('/') |
| | | average01.value = Number(indexArr[0]) |
| | | average02.value = Number(indexArr[1]) |
| | | radioValue.value = 3 |
| | | } else { |
| | | checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))] |
| | | radioValue.value = 4 |
| | | } |
| | | } |
| | | // åéæé®å¼ååæ¶ |
| | | function onRadioChange() { |
| | | switch (radioValue.value) { |
| | | case 1: |
| | | emit('update', 'second', '*', 'second') |
| | | break |
| | | case 2: |
| | | emit('update', 'second', cycleTotal.value, 'second') |
| | | break |
| | | case 3: |
| | | emit('update', 'second', averageTotal.value, 'second') |
| | | break |
| | | case 4: |
| | | if (checkboxList.value.length === 0) { |
| | | checkboxList.value.push(checkCopy.value[0]) |
| | | } else { |
| | | checkCopy.value = checkboxList.value |
| | | } |
| | | emit('update', 'second', checkboxString.value, 'second') |
| | | break |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .el-input-number--small, .el-select, .el-select--small { |
| | | margin: 0 0.2rem; |
| | | } |
| | | .el-select, .el-select--small { |
| | | width: 18.8rem; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-form> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="1"> |
| | | å¨ï¼å
许çéé
符[, - * ? / L #] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="2"> |
| | | ä¸æå® |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="3"> |
| | | å¨æä» |
| | | <el-select clearable v-model="cycle01"> |
| | | <el-option |
| | | v-for="(item,index) of weekList" |
| | | :key="index" |
| | | :label="item.value" |
| | | :value="item.key" |
| | | :disabled="item.key === 7" |
| | | >{{item.value}}</el-option> |
| | | </el-select> |
| | | - |
| | | <el-select clearable v-model="cycle02"> |
| | | <el-option |
| | | v-for="(item,index) of weekList" |
| | | :key="index" |
| | | :label="item.value" |
| | | :value="item.key" |
| | | :disabled="item.key <= cycle01" |
| | | >{{item.value}}</el-option> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="4"> |
| | | 第 |
| | | <el-input-number v-model='average01' :min="1" :max="4" /> å¨ç |
| | | <el-select clearable v-model="average02"> |
| | | <el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" /> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="5"> |
| | | æ¬ææåä¸ä¸ª |
| | | <el-select clearable v-model="weekday"> |
| | | <el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" /> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :value="6"> |
| | | æå® |
| | | <el-select class="multiselect" clearable v-model="checkboxList" placeholder="å¯å¤é" multiple :multiple-limit="6"> |
| | | <el-option v-for="item in weekList" :key="item.key" :label="item.value" :value="item.key" /> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const emit = defineEmits(['update']) |
| | | const props = defineProps({ |
| | | cron: { |
| | | type: Object, |
| | | default: { |
| | | second: "*", |
| | | min: "*", |
| | | hour: "*", |
| | | day: "*", |
| | | month: "*", |
| | | week: "?", |
| | | year: "" |
| | | } |
| | | }, |
| | | check: { |
| | | type: Function, |
| | | default: () => { |
| | | } |
| | | } |
| | | }) |
| | | const radioValue = ref(2) |
| | | const cycle01 = ref(2) |
| | | const cycle02 = ref(3) |
| | | const average01 = ref(1) |
| | | const average02 = ref(2) |
| | | const weekday = ref(2) |
| | | const checkboxList = ref([]) |
| | | const checkCopy = ref([2]) |
| | | const weekList = ref([ |
| | | {key: 1, value: 'æææ¥'}, |
| | | {key: 2, value: 'ææä¸'}, |
| | | {key: 3, value: 'ææäº'}, |
| | | {key: 4, value: 'ææä¸'}, |
| | | {key: 5, value: 'ææå'}, |
| | | {key: 6, value: 'ææäº'}, |
| | | {key: 7, value: 'ææå
'} |
| | | ]) |
| | | const cycleTotal = computed(() => { |
| | | cycle01.value = props.check(cycle01.value, 1, 6) |
| | | cycle02.value = props.check(cycle02.value, cycle01.value + 1, 7) |
| | | return cycle01.value + '-' + cycle02.value |
| | | }) |
| | | const averageTotal = computed(() => { |
| | | average01.value = props.check(average01.value, 1, 4) |
| | | average02.value = props.check(average02.value, 1, 7) |
| | | return average02.value + '#' + average01.value |
| | | }) |
| | | const weekdayTotal = computed(() => { |
| | | weekday.value = props.check(weekday.value, 1, 7) |
| | | return weekday.value + 'L' |
| | | }) |
| | | const checkboxString = computed(() => { |
| | | return checkboxList.value.join(',') |
| | | }) |
| | | watch(() => props.cron.week, value => changeRadioValue(value)) |
| | | watch([radioValue, cycleTotal, averageTotal, weekdayTotal, checkboxString], () => onRadioChange()) |
| | | function changeRadioValue(value) { |
| | | if (value === "*") { |
| | | radioValue.value = 1 |
| | | } else if (value === "?") { |
| | | radioValue.value = 2 |
| | | } else if (value.indexOf("-") > -1) { |
| | | const indexArr = value.split('-') |
| | | cycle01.value = Number(indexArr[0]) |
| | | cycle02.value = Number(indexArr[1]) |
| | | radioValue.value = 3 |
| | | } else if (value.indexOf("#") > -1) { |
| | | const indexArr = value.split('#') |
| | | average01.value = Number(indexArr[1]) |
| | | average02.value = Number(indexArr[0]) |
| | | radioValue.value = 4 |
| | | } else if (value.indexOf("L") > -1) { |
| | | const indexArr = value.split("L") |
| | | weekday.value = Number(indexArr[0]) |
| | | radioValue.value = 5 |
| | | } else { |
| | | checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))] |
| | | radioValue.value = 6 |
| | | } |
| | | } |
| | | function onRadioChange() { |
| | | if (radioValue.value === 2 && props.cron.day === '?') { |
| | | emit('update', 'day', '*', 'week') |
| | | } |
| | | if (radioValue.value !== 2 && props.cron.day !== '?') { |
| | | emit('update', 'day', '?', 'week') |
| | | } |
| | | switch (radioValue.value) { |
| | | case 1: |
| | | emit('update', 'week', '*', 'week') |
| | | break |
| | | case 2: |
| | | emit('update', 'week', '?', 'week') |
| | | break |
| | | case 3: |
| | | emit('update', 'week', cycleTotal.value, 'week') |
| | | break |
| | | case 4: |
| | | emit('update', 'week', averageTotal.value, 'week') |
| | | break |
| | | case 5: |
| | | emit('update', 'week', weekdayTotal.value, 'week') |
| | | break |
| | | case 6: |
| | | if (checkboxList.value.length === 0) { |
| | | checkboxList.value.push(checkCopy.value[0]) |
| | | } else { |
| | | checkCopy.value = checkboxList.value |
| | | } |
| | | emit('update', 'week', checkboxString.value, 'week') |
| | | break |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .el-input-number--small, .el-select, .el-select--small { |
| | | margin: 0 0.5rem; |
| | | } |
| | | .el-select, .el-select--small { |
| | | width: 8rem; |
| | | } |
| | | .el-select.multiselect, .el-select--small.multiselect { |
| | | width: 17.8rem; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-form> |
| | | <el-form-item> |
| | | <el-radio :value="1" v-model='radioValue'> |
| | | ä¸å¡«ï¼å
许çéé
符[, - * /] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio :value="2" v-model='radioValue'> |
| | | æ¯å¹´ |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio :value="3" v-model='radioValue'> |
| | | å¨æä» |
| | | <el-input-number v-model='cycle01' :min='fullYear' :max="2098"/> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : fullYear + 1" :max="2099"/> |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio :value="4" v-model='radioValue'> |
| | | ä» |
| | | <el-input-number v-model='average01' :min='fullYear' :max="2098"/> å¹´å¼å§ï¼æ¯ |
| | | <el-input-number v-model='average02' :min="1" :max="2099 - average01 || fullYear"/> å¹´æ§è¡ä¸æ¬¡ |
| | | </el-radio> |
| | | |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio :value="5" v-model='radioValue'> |
| | | æå® |
| | | <el-select clearable v-model="checkboxList" placeholder="å¯å¤é" multiple :multiple-limit="8"> |
| | | <el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" /> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const emit = defineEmits(['update']) |
| | | const props = defineProps({ |
| | | cron: { |
| | | type: Object, |
| | | default: { |
| | | second: "*", |
| | | min: "*", |
| | | hour: "*", |
| | | day: "*", |
| | | month: "*", |
| | | week: "?", |
| | | year: "" |
| | | } |
| | | }, |
| | | check: { |
| | | type: Function, |
| | | default: () => { |
| | | } |
| | | } |
| | | }) |
| | | |
| | | const fullYear = Number(new Date().getFullYear()) |
| | | const maxFullYear = fullYear + 10 |
| | | const radioValue = ref(1) |
| | | const cycle01 = ref(fullYear) |
| | | const cycle02 = ref(fullYear + 1) |
| | | const average01 = ref(fullYear) |
| | | const average02 = ref(1) |
| | | const checkboxList = ref([]) |
| | | const checkCopy = ref([fullYear]) |
| | | |
| | | const cycleTotal = computed(() => { |
| | | cycle01.value = props.check(cycle01.value, fullYear, maxFullYear - 1) |
| | | cycle02.value = props.check(cycle02.value, cycle01.value + 1, maxFullYear) |
| | | return cycle01.value + '-' + cycle02.value |
| | | }) |
| | | const averageTotal = computed(() => { |
| | | average01.value = props.check(average01.value, fullYear, maxFullYear - 1) |
| | | average02.value = props.check(average02.value, 1, 10) |
| | | return average01.value + '/' + average02.value |
| | | }) |
| | | const checkboxString = computed(() => { |
| | | return checkboxList.value.join(',') |
| | | }) |
| | | watch(() => props.cron.year, value => changeRadioValue(value)) |
| | | watch([radioValue, cycleTotal, averageTotal, checkboxString], () => onRadioChange()) |
| | | function changeRadioValue(value) { |
| | | if (value === '') { |
| | | radioValue.value = 1 |
| | | } else if (value === "*") { |
| | | radioValue.value = 2 |
| | | } else if (value.indexOf("-") > -1) { |
| | | const indexArr = value.split('-') |
| | | cycle01.value = Number(indexArr[0]) |
| | | cycle02.value = Number(indexArr[1]) |
| | | radioValue.value = 3 |
| | | } else if (value.indexOf("/") > -1) { |
| | | const indexArr = value.split('/') |
| | | average01.value = Number(indexArr[0]) |
| | | average02.value = Number(indexArr[1]) |
| | | radioValue.value = 4 |
| | | } else { |
| | | checkboxList.value = [...new Set(value.split(',').map(item => Number(item)))] |
| | | radioValue.value = 5 |
| | | } |
| | | } |
| | | function onRadioChange() { |
| | | switch (radioValue.value) { |
| | | case 1: |
| | | emit('update', 'year', '', 'year') |
| | | break |
| | | case 2: |
| | | emit('update', 'year', '*', 'year') |
| | | break |
| | | case 3: |
| | | emit('update', 'year', cycleTotal.value, 'year') |
| | | break |
| | | case 4: |
| | | emit('update', 'year', averageTotal.value, 'year') |
| | | break |
| | | case 5: |
| | | if (checkboxList.value.length === 0) { |
| | | checkboxList.value.push(checkCopy.value[0]) |
| | | } else { |
| | | checkCopy.value = checkboxList.value |
| | | } |
| | | emit('update', 'year', checkboxString.value, 'year') |
| | | break |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .el-input-number--small, .el-select, .el-select--small { |
| | | margin: 0 0.2rem; |
| | | } |
| | | .el-select, .el-select--small { |
| | | width: 18.8rem; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <template v-for="(item, index) in options"> |
| | | <template v-if="values.includes(item.value)"> |
| | | <span |
| | | v-if="(item.elTagType == 'default' || item.elTagType == '') && (item.elTagClass == '' || item.elTagClass == null)" |
| | | :key="item.value" |
| | | :index="index" |
| | | :class="item.elTagClass" |
| | | >{{ item.label + " " }}</span> |
| | | <el-tag |
| | | v-else |
| | | :disable-transitions="true" |
| | | :key="item.value + ''" |
| | | :index="index" |
| | | :type="item.elTagType" |
| | | :class="item.elTagClass" |
| | | >{{ item.label + " " }}</el-tag> |
| | | </template> |
| | | </template> |
| | | <template v-if="unmatch && showValue"> |
| | | {{ unmatchArray | handleArray }} |
| | | </template> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | // è®°å½æªå¹é
ç项 |
| | | const unmatchArray = ref([]) |
| | | |
| | | const props = defineProps({ |
| | | // æ°æ® |
| | | options: { |
| | | type: Array, |
| | | default: null, |
| | | }, |
| | | // å½åçå¼ |
| | | value: [Number, String, Array], |
| | | // 彿ªæ¾å°å¹é
çæ°æ®æ¶ï¼æ¾ç¤ºvalue |
| | | showValue: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | separator: { |
| | | type: String, |
| | | default: ",", |
| | | } |
| | | }) |
| | | |
| | | const values = computed(() => { |
| | | if (props.value === null || typeof props.value === 'undefined' || props.value === '') return [] |
| | | return Array.isArray(props.value) ? props.value.map(item => '' + item) : String(props.value).split(props.separator) |
| | | }) |
| | | |
| | | const unmatch = computed(() => { |
| | | unmatchArray.value = [] |
| | | // 没ævalue䏿¾ç¤º |
| | | if (props.value === null || typeof props.value === 'undefined' || props.value === '' || !Array.isArray(props.options) || props.options.length === 0) return false |
| | | // ä¼ å
¥å¼ä¸ºæ°ç» |
| | | let unmatch = false // æ·»å ä¸ä¸ªæ å¿æ¥å¤ææ¯å¦ææªå¹é
项 |
| | | values.value.forEach(item => { |
| | | if (!props.options.some(v => v.value === item)) { |
| | | unmatchArray.value.push(item) |
| | | unmatch = true // å¦æææªå¹é
项ï¼å°æ å¿è®¾ç½®ä¸ºtrue |
| | | } |
| | | }) |
| | | return unmatch // è¿åæ å¿çå¼ |
| | | }) |
| | | |
| | | function handleArray(array) { |
| | | if (array.length === 0) return "" |
| | | return array.reduce((pre, cur) => { |
| | | return pre + " " + cur |
| | | }) |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .el-tag + .el-tag { |
| | | margin-left: 10px; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-upload |
| | | :action="uploadUrl" |
| | | :before-upload="handleBeforeUpload" |
| | | :on-success="handleUploadSuccess" |
| | | :on-error="handleUploadError" |
| | | name="file" |
| | | :show-file-list="false" |
| | | :headers="headers" |
| | | class="editor-img-uploader" |
| | | v-if="type == 'url'" |
| | | > |
| | | <i ref="uploadRef" class="editor-img-uploader"></i> |
| | | </el-upload> |
| | | </div> |
| | | <div class="editor"> |
| | | <quill-editor |
| | | ref="quillEditorRef" |
| | | v-model:content="content" |
| | | contentType="html" |
| | | @textChange="(e) => $emit('update:modelValue', content)" |
| | | :options="options" |
| | | :style="styles" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import axios from 'axios' |
| | | import { QuillEditor } from "@vueup/vue-quill" |
| | | import "@vueup/vue-quill/dist/vue-quill.snow.css" |
| | | import { getToken } from "@/utils/auth" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | const quillEditorRef = ref() |
| | | const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload") // ä¸ä¼ çå¾çæå¡å¨å°å |
| | | const headers = ref({ |
| | | Authorization: "Bearer " + getToken() |
| | | }) |
| | | |
| | | const props = defineProps({ |
| | | /* ç¼è¾å¨çå
容 */ |
| | | modelValue: { |
| | | type: String, |
| | | }, |
| | | /* é«åº¦ */ |
| | | height: { |
| | | type: Number, |
| | | default: null, |
| | | }, |
| | | /* æå°é«åº¦ */ |
| | | minHeight: { |
| | | type: Number, |
| | | default: null, |
| | | }, |
| | | /* åªè¯» */ |
| | | readOnly: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | /* ä¸ä¼ æä»¶å¤§å°éå¶(MB) */ |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | /* ç±»åï¼base64æ ¼å¼ãurlæ ¼å¼ï¼ */ |
| | | type: { |
| | | type: String, |
| | | default: "url", |
| | | } |
| | | }) |
| | | |
| | | const options = ref({ |
| | | theme: "snow", |
| | | bounds: document.body, |
| | | debug: "warn", |
| | | modules: { |
| | | // å·¥å
·æ é
ç½® |
| | | toolbar: [ |
| | | ["bold", "italic", "underline", "strike"], // å ç² æä½ ä¸å线 å é¤çº¿ |
| | | ["blockquote", "code-block"], // å¼ç¨ 代ç å |
| | | [{ list: "ordered" }, { list: "bullet" }], // æåºãæ åºå表 |
| | | [{ indent: "-1" }, { indent: "+1" }], // ç¼©è¿ |
| | | [{ size: ["small", false, "large", "huge"] }], // åä½å¤§å° |
| | | [{ header: [1, 2, 3, 4, 5, 6, false] }], // æ é¢ |
| | | [{ color: [] }, { background: [] }], // åä½é¢è²ãåä½èæ¯é¢è² |
| | | [{ align: [] }], // 坹齿¹å¼ |
| | | ["clean"], // æ¸
é¤ææ¬æ ¼å¼ |
| | | ["link", "image", "video"] // 龿¥ãå¾çãè§é¢ |
| | | ], |
| | | }, |
| | | placeholder: "请è¾å
¥å
容", |
| | | readOnly: props.readOnly |
| | | }) |
| | | |
| | | const styles = computed(() => { |
| | | let style = {} |
| | | if (props.minHeight) { |
| | | style.minHeight = `${props.minHeight}px` |
| | | } |
| | | if (props.height) { |
| | | style.height = `${props.height}px` |
| | | } |
| | | return style |
| | | }) |
| | | |
| | | const content = ref("") |
| | | watch(() => props.modelValue, (v) => { |
| | | if (v !== content.value) { |
| | | content.value = v == undefined ? "<p></p>" : v |
| | | } |
| | | }, { immediate: true }) |
| | | |
| | | // å¦æè®¾ç½®äºä¸ä¼ å°ååèªå®ä¹å¾çä¸ä¼ äºä»¶ |
| | | onMounted(() => { |
| | | if (props.type == 'url') { |
| | | let quill = quillEditorRef.value.getQuill() |
| | | let toolbar = quill.getModule("toolbar") |
| | | toolbar.addHandler("image", (value) => { |
| | | if (value) { |
| | | proxy.$refs.uploadRef.click() |
| | | } else { |
| | | quill.format("image", false) |
| | | } |
| | | }) |
| | | quill.root.addEventListener('paste', handlePasteCapture, true) |
| | | } |
| | | }) |
| | | |
| | | // ä¸ä¼ åæ ¡æ£æ ¼å¼åå¤§å° |
| | | function handleBeforeUpload(file) { |
| | | const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"] |
| | | const isJPG = type.includes(file.type) |
| | | //æ£éªæä»¶æ ¼å¼ |
| | | if (!isJPG) { |
| | | proxy.$modal.msgError(`å¾çæ ¼å¼é误!`) |
| | | return false |
| | | } |
| | | // æ ¡æ£æä»¶å¤§å° |
| | | if (props.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < props.fileSize |
| | | if (!isLt) { |
| | | proxy.$modal.msgError(`ä¸ä¼ æä»¶å¤§å°ä¸è½è¶
è¿ ${props.fileSize} MB!`) |
| | | return false |
| | | } |
| | | } |
| | | return true |
| | | } |
| | | |
| | | // ä¸ä¼ æåå¤ç |
| | | function handleUploadSuccess(res, file) { |
| | | // 妿ä¸ä¼ æå |
| | | if (res.code == 200) { |
| | | // è·å坿æ¬å®ä¾ |
| | | let quill = toRaw(quillEditorRef.value).getQuill() |
| | | // è·åå
æ ä½ç½® |
| | | let length = quill.selection.savedRange.index |
| | | // æå
¥å¾çï¼res.url为æå¡å¨è¿åçå¾ç龿¥å°å |
| | | quill.insertEmbed(length, "image", import.meta.env.VITE_APP_BASE_API + res.fileName) |
| | | // è°æ´å
æ å°æå |
| | | quill.setSelection(length + 1) |
| | | } else { |
| | | proxy.$modal.msgError("å¾çæå
¥å¤±è´¥") |
| | | } |
| | | } |
| | | |
| | | // ä¸ä¼ 失败å¤ç |
| | | function handleUploadError() { |
| | | proxy.$modal.msgError("å¾çæå
¥å¤±è´¥") |
| | | } |
| | | |
| | | // å¤å¶ç²è´´å¾çå¤ç |
| | | function handlePasteCapture(e) { |
| | | const clipboard = e.clipboardData || window.clipboardData |
| | | if (clipboard && clipboard.items) { |
| | | for (let i = 0; i < clipboard.items.length; i++) { |
| | | const item = clipboard.items[i] |
| | | if (item.type.indexOf('image') !== -1) { |
| | | e.preventDefault() |
| | | const file = item.getAsFile() |
| | | insertImage(file) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | function insertImage(file) { |
| | | const formData = new FormData() |
| | | formData.append("file", file) |
| | | axios.post(uploadUrl.value, formData, { headers: { "Content-Type": "multipart/form-data", Authorization: headers.value.Authorization } }).then(res => { |
| | | handleUploadSuccess(res.data) |
| | | }) |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | .editor-img-uploader { |
| | | display: none; |
| | | } |
| | | .editor, .ql-toolbar { |
| | | white-space: pre-wrap !important; |
| | | line-height: normal !important; |
| | | } |
| | | .quill-img { |
| | | display: none; |
| | | } |
| | | .ql-snow .ql-tooltip[data-mode="link"]::before { |
| | | content: "请è¾å
¥é¾æ¥å°å:"; |
| | | } |
| | | .ql-snow .ql-tooltip.ql-editing a.ql-action::after { |
| | | border-right: 0px; |
| | | content: "ä¿å"; |
| | | padding-right: 0px; |
| | | } |
| | | .ql-snow .ql-tooltip[data-mode="video"]::before { |
| | | content: "请è¾å
¥è§é¢å°å:"; |
| | | } |
| | | .ql-snow .ql-picker.ql-size .ql-picker-label::before, |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item::before { |
| | | content: "14px"; |
| | | } |
| | | .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before, |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before { |
| | | content: "10px"; |
| | | } |
| | | .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before, |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before { |
| | | content: "18px"; |
| | | } |
| | | .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before, |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before { |
| | | content: "32px"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item::before { |
| | | content: "ææ¬"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { |
| | | content: "æ é¢1"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { |
| | | content: "æ é¢2"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { |
| | | content: "æ é¢3"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { |
| | | content: "æ é¢4"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { |
| | | content: "æ é¢5"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { |
| | | content: "æ é¢6"; |
| | | } |
| | | .ql-snow .ql-picker.ql-font .ql-picker-label::before, |
| | | .ql-snow .ql-picker.ql-font .ql-picker-item::before { |
| | | content: "æ ååä½"; |
| | | } |
| | | .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before, |
| | | .ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before { |
| | | content: "衬线åä½"; |
| | | } |
| | | .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before, |
| | | .ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before { |
| | | content: "ç宽åä½"; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="upload-file"> |
| | | <el-upload |
| | | multiple |
| | | :action="uploadFileUrl" |
| | | :before-upload="handleBeforeUpload" |
| | | :file-list="fileList" |
| | | :data="data" |
| | | :limit="limit" |
| | | :on-error="handleUploadError" |
| | | :on-exceed="handleExceed" |
| | | :on-success="handleUploadSuccess" |
| | | :show-file-list="false" |
| | | :headers="headers" |
| | | class="upload-file-uploader" |
| | | ref="fileUpload" |
| | | v-if="!disabled" |
| | | > |
| | | <!-- ä¸ä¼ æé® --> |
| | | <el-button type="primary">éåæä»¶</el-button> |
| | | </el-upload> |
| | | <!-- ä¸ä¼ æç¤º --> |
| | | <div class="el-upload__tip" v-if="showTip && !disabled"> |
| | | 请ä¸ä¼ |
| | | <template v-if="fileSize"> 大å°ä¸è¶
è¿ <b style="color: #f56c6c">{{ fileSize }}MB</b> </template> |
| | | <template v-if="fileType"> æ ¼å¼ä¸º <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template> |
| | | çæä»¶ |
| | | </div> |
| | | <!-- æä»¶å表 --> |
| | | <transition-group ref="uploadFileList" class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul"> |
| | | <li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList"> |
| | | <el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank"> |
| | | <span class="el-icon-document"> {{ getFileName(file.name) }} </span> |
| | | </el-link> |
| | | <div class="ele-upload-list__item-content-action"> |
| | | <el-link :underline="false" @click="handleDelete(index)" type="danger" v-if="!disabled"> å é¤</el-link> |
| | | </div> |
| | | </li> |
| | | </transition-group> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getToken } from "@/utils/auth" |
| | | import Sortable from 'sortablejs' |
| | | |
| | | const props = defineProps({ |
| | | modelValue: [String, Object, Array], |
| | | // ä¸ä¼ æ¥å£å°å |
| | | action: { |
| | | type: String, |
| | | default: "/common/upload" |
| | | }, |
| | | // ä¸ä¼ æºå¸¦çåæ° |
| | | data: { |
| | | type: Object |
| | | }, |
| | | // æ°ééå¶ |
| | | limit: { |
| | | type: Number, |
| | | default: 5 |
| | | }, |
| | | // 大å°éå¶(MB) |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5 |
| | | }, |
| | | // æä»¶ç±»å, ä¾å¦['png', 'jpg', 'jpeg'] |
| | | fileType: { |
| | | type: Array, |
| | | default: () => ["doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "pdf"] |
| | | }, |
| | | // æ¯å¦æ¾ç¤ºæç¤º |
| | | isShowTip: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // ç¦ç¨ç»ä»¶ï¼ä»
æ¥çæä»¶ï¼ |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // æå¨æåº |
| | | drag: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }) |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits() |
| | | const number = ref(0) |
| | | const uploadList = ref([]) |
| | | const baseUrl = import.meta.env.VITE_APP_BASE_API |
| | | const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + props.action) // ä¸ä¼ æä»¶æå¡å¨å°å |
| | | const headers = ref({ Authorization: "Bearer " + getToken() }) |
| | | const fileList = ref([]) |
| | | const showTip = computed( |
| | | () => props.isShowTip && (props.fileType || props.fileSize) |
| | | ) |
| | | |
| | | watch(() => props.modelValue, val => { |
| | | if (val) { |
| | | let temp = 1 |
| | | // é¦å
å°å¼è½¬ä¸ºæ°ç» |
| | | const list = Array.isArray(val) ? val : props.modelValue.split(',') |
| | | // ç¶åå°æ°ç»è½¬ä¸ºå¯¹è±¡æ°ç» |
| | | fileList.value = list.map(item => { |
| | | if (typeof item === "string") { |
| | | item = { name: item, url: item } |
| | | } |
| | | item.uid = item.uid || new Date().getTime() + temp++ |
| | | return item |
| | | }) |
| | | } else { |
| | | fileList.value = [] |
| | | return [] |
| | | } |
| | | },{ deep: true, immediate: true }) |
| | | |
| | | // ä¸ä¼ åæ ¡æ£æ ¼å¼åå¤§å° |
| | | function handleBeforeUpload(file) { |
| | | // æ ¡æ£æä»¶ç±»å |
| | | if (props.fileType.length) { |
| | | const fileName = file.name.split('.') |
| | | const fileExt = fileName[fileName.length - 1] |
| | | const isTypeOk = props.fileType.indexOf(fileExt) >= 0 |
| | | if (!isTypeOk) { |
| | | proxy.$modal.msgError(`æä»¶æ ¼å¼ä¸æ£ç¡®ï¼è¯·ä¸ä¼ ${props.fileType.join("/")}æ ¼å¼æä»¶!`) |
| | | return false |
| | | } |
| | | } |
| | | // æ ¡æ£æä»¶åæ¯å¦å
å«ç¹æ®å符 |
| | | if (file.name.includes(',')) { |
| | | proxy.$modal.msgError('æä»¶å䏿£ç¡®ï¼ä¸è½å
å«è±æéå·!') |
| | | return false |
| | | } |
| | | // æ ¡æ£æä»¶å¤§å° |
| | | if (props.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < props.fileSize |
| | | if (!isLt) { |
| | | proxy.$modal.msgError(`ä¸ä¼ æä»¶å¤§å°ä¸è½è¶
è¿ ${props.fileSize} MB!`) |
| | | return false |
| | | } |
| | | } |
| | | proxy.$modal.loading("æ£å¨ä¸ä¼ æä»¶ï¼è¯·ç¨å...") |
| | | number.value++ |
| | | return true |
| | | } |
| | | |
| | | // æä»¶ä¸ªæ°è¶
åº |
| | | function handleExceed() { |
| | | proxy.$modal.msgError(`ä¸ä¼ æä»¶æ°éä¸è½è¶
è¿ ${props.limit} 个!`) |
| | | } |
| | | |
| | | // ä¸ä¼ 失败 |
| | | function handleUploadError(err) { |
| | | proxy.$modal.msgError("ä¸ä¼ æä»¶å¤±è´¥") |
| | | proxy.$modal.closeLoading() |
| | | } |
| | | |
| | | // ä¸ä¼ æååè° |
| | | function handleUploadSuccess(res, file) { |
| | | if (res.code === 200) { |
| | | uploadList.value.push({ name: res.fileName, url: res.fileName }) |
| | | uploadedSuccessfully() |
| | | } else { |
| | | number.value-- |
| | | proxy.$modal.closeLoading() |
| | | proxy.$modal.msgError(res.msg) |
| | | proxy.$refs.fileUpload.handleRemove(file) |
| | | uploadedSuccessfully() |
| | | } |
| | | } |
| | | |
| | | // å 餿件 |
| | | function handleDelete(index) { |
| | | fileList.value.splice(index, 1) |
| | | emit("update:modelValue", listToString(fileList.value)) |
| | | } |
| | | |
| | | // ä¸ä¼ ç»æå¤ç |
| | | function uploadedSuccessfully() { |
| | | if (number.value > 0 && uploadList.value.length === number.value) { |
| | | fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value) |
| | | uploadList.value = [] |
| | | number.value = 0 |
| | | emit("update:modelValue", listToString(fileList.value)) |
| | | proxy.$modal.closeLoading() |
| | | } |
| | | } |
| | | |
| | | // è·åæä»¶åç§° |
| | | function getFileName(name) { |
| | | // 妿æ¯urlé£ä¹åæåçåå 妿䏿¯ç´æ¥è¿å |
| | | if (name.lastIndexOf("/") > -1) { |
| | | return name.slice(name.lastIndexOf("/") + 1) |
| | | } else { |
| | | return name |
| | | } |
| | | } |
| | | |
| | | // 对象转ææå®å符串åé |
| | | function listToString(list, separator) { |
| | | let strs = "" |
| | | separator = separator || "," |
| | | for (let i in list) { |
| | | if (list[i].url) { |
| | | strs += list[i].url + separator |
| | | } |
| | | } |
| | | return strs != '' ? strs.substr(0, strs.length - 1) : '' |
| | | } |
| | | |
| | | // åå§åææ½æåº |
| | | onMounted(() => { |
| | | if (props.drag && !props.disabled) { |
| | | nextTick(() => { |
| | | const element = proxy.$refs.uploadFileList?.$el || proxy.$refs.uploadFileList |
| | | Sortable.create(element, { |
| | | ghostClass: 'file-upload-darg', |
| | | onEnd: (evt) => { |
| | | const movedItem = fileList.value.splice(evt.oldIndex, 1)[0] |
| | | fileList.value.splice(evt.newIndex, 0, movedItem) |
| | | emit('update:modelValue', listToString(fileList.value)) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | }) |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | .file-upload-darg { |
| | | opacity: 0.5; |
| | | background: #c8ebfb; |
| | | } |
| | | .upload-file-uploader { |
| | | margin-bottom: 5px; |
| | | } |
| | | .upload-file-list .el-upload-list__item { |
| | | border: 1px solid #e4e7ed; |
| | | line-height: 2; |
| | | margin-bottom: 10px; |
| | | position: relative; |
| | | transition: none !important; |
| | | } |
| | | .upload-file-list .ele-upload-list__item-content { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | color: inherit; |
| | | } |
| | | .ele-upload-list__item-content-action .el-link { |
| | | margin-right: 10px; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div style="padding: 0 15px;" @click="toggleClick"> |
| | | <svg |
| | | :class="{'is-active':isActive}" |
| | | class="hamburger" |
| | | viewBox="0 0 1024 1024" |
| | | xmlns="http://www.w3.org/2000/svg" |
| | | width="64" |
| | | height="64" |
| | | fill="currentColor" |
| | | > |
| | | <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" /> |
| | | </svg> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | defineProps({ |
| | | isActive: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }) |
| | | |
| | | const emit = defineEmits() |
| | | const toggleClick = () => { |
| | | emit('toggleClick') |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .hamburger { |
| | | display: inline-block; |
| | | vertical-align: middle; |
| | | width: 20px; |
| | | height: 20px; |
| | | } |
| | | |
| | | .hamburger.is-active { |
| | | transform: rotate(180deg); |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="header-search"> |
| | | <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" /> |
| | | <el-dialog |
| | | v-model="show" |
| | | width="600" |
| | | @close="close" |
| | | :show-close="false" |
| | | append-to-body |
| | | > |
| | | <el-input |
| | | v-model="search" |
| | | ref="headerSearchSelectRef" |
| | | size="large" |
| | | @input="querySearch" |
| | | prefix-icon="Search" |
| | | placeholder="èåæç´¢ï¼æ¯ææ é¢ãURLæ¨¡ç³æ¥è¯¢" |
| | | clearable |
| | | @keyup.enter="selectActiveResult" |
| | | @keydown.up.prevent="navigateResult('up')" |
| | | @keydown.down.prevent="navigateResult('down')" |
| | | > |
| | | </el-input> |
| | | |
| | | <div class="result-wrap"> |
| | | <el-scrollbar> |
| | | <div class="search-item" tabindex="1" v-for="(item, index) in options" :key="item.path" :style="activeStyle(index)" @mouseenter="activeIndex = index" @mouseleave="activeIndex = -1"> |
| | | <div class="left"> |
| | | <svg-icon class="menu-icon" :icon-class="item.icon" /> |
| | | </div> |
| | | <div class="search-info" @click="change(item)"> |
| | | <div class="menu-title"> |
| | | {{ item.title.join(" / ") }} |
| | | </div> |
| | | <div class="menu-path"> |
| | | {{ item.path }} |
| | | </div> |
| | | </div> |
| | | <svg-icon icon-class="enter" v-show="index === activeIndex"/> |
| | | </div> |
| | | </el-scrollbar> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import Fuse from 'fuse.js' |
| | | import { getNormalPath } from '@/utils/ruoyi' |
| | | import { isHttp } from '@/utils/validate' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | import usePermissionStore from '@/store/modules/permission' |
| | | |
| | | const search = ref('') |
| | | const options = ref([]) |
| | | const searchPool = ref([]) |
| | | const activeIndex = ref(-1) |
| | | const show = ref(false) |
| | | const fuse = ref(undefined) |
| | | const headerSearchSelectRef = ref(null) |
| | | const router = useRouter() |
| | | const theme = computed(() => useSettingsStore().theme) |
| | | const routes = computed(() => usePermissionStore().defaultRoutes) |
| | | |
| | | function click() { |
| | | show.value = !show.value |
| | | if (show.value) { |
| | | headerSearchSelectRef.value && headerSearchSelectRef.value.focus() |
| | | options.value = searchPool.value |
| | | } |
| | | } |
| | | |
| | | function close() { |
| | | headerSearchSelectRef.value && headerSearchSelectRef.value.blur() |
| | | search.value = '' |
| | | options.value = [] |
| | | show.value = false |
| | | activeIndex.value = -1 |
| | | } |
| | | |
| | | function change(val) { |
| | | const path = val.path |
| | | const query = val.query |
| | | if (isHttp(path)) { |
| | | // http(s):// è·¯å¾æ°çªå£æå¼ |
| | | const pindex = path.indexOf("http") |
| | | window.open(path.substr(pindex, path.length), "_blank") |
| | | } else { |
| | | if (query) { |
| | | router.push({ path: path, query: JSON.parse(query) }) |
| | | } else { |
| | | router.push(path) |
| | | } |
| | | } |
| | | |
| | | search.value = '' |
| | | options.value = [] |
| | | nextTick(() => { |
| | | show.value = false |
| | | }) |
| | | } |
| | | |
| | | function initFuse(list) { |
| | | fuse.value = new Fuse(list, { |
| | | shouldSort: true, |
| | | threshold: 0.4, |
| | | location: 0, |
| | | distance: 100, |
| | | minMatchCharLength: 1, |
| | | keys: [{ |
| | | name: 'title', |
| | | weight: 0.7 |
| | | }, { |
| | | name: 'path', |
| | | weight: 0.3 |
| | | }] |
| | | }) |
| | | } |
| | | |
| | | // Filter out the routes that can be displayed in the sidebar |
| | | // And generate the internationalized title |
| | | function generateRoutes(routes, basePath = '', prefixTitle = []) { |
| | | let res = [] |
| | | |
| | | for (const r of routes) { |
| | | // skip hidden router |
| | | if (r.hidden) { continue } |
| | | const p = r.path.length > 0 && r.path[0] === '/' ? r.path : '/' + r.path |
| | | const data = { |
| | | path: !isHttp(r.path) ? getNormalPath(basePath + p) : r.path, |
| | | title: [...prefixTitle], |
| | | icon: '' |
| | | } |
| | | |
| | | if (r.meta && r.meta.title) { |
| | | data.title = [...data.title, r.meta.title] |
| | | data.icon = r.meta.icon |
| | | if (r.redirect !== "noRedirect") { |
| | | // only push the routes with title |
| | | // special case: need to exclude parent router without redirect |
| | | res.push(data) |
| | | } |
| | | } |
| | | if (r.query) { |
| | | data.query = r.query |
| | | } |
| | | |
| | | // recursive child routes |
| | | if (r.children) { |
| | | const tempRoutes = generateRoutes(r.children, data.path, data.title) |
| | | if (tempRoutes.length >= 1) { |
| | | res = [...res, ...tempRoutes] |
| | | } |
| | | } |
| | | } |
| | | return res |
| | | } |
| | | |
| | | function querySearch(query) { |
| | | activeIndex.value = -1 |
| | | if (query !== '') { |
| | | options.value = fuse.value.search(query).map((item) => item.item) ?? searchPool.value |
| | | } else { |
| | | options.value = searchPool.value |
| | | } |
| | | } |
| | | |
| | | function activeStyle(index) { |
| | | if (index !== activeIndex.value) return {} |
| | | return { |
| | | "background-color": theme.value, |
| | | "color": "#fff" |
| | | } |
| | | } |
| | | |
| | | function navigateResult(direction) { |
| | | if (direction === "up") { |
| | | activeIndex.value = activeIndex.value <= 0 ? options.value.length - 1 : activeIndex.value - 1 |
| | | } else if (direction === "down") { |
| | | activeIndex.value = activeIndex.value >= options.value.length - 1 ? 0 : activeIndex.value + 1 |
| | | } |
| | | } |
| | | |
| | | function selectActiveResult() { |
| | | if (options.value.length > 0 && activeIndex.value >= 0) { |
| | | change(options.value[activeIndex.value]) |
| | | } |
| | | } |
| | | |
| | | onMounted(() => { |
| | | searchPool.value = generateRoutes(routes.value) |
| | | }) |
| | | |
| | | watch(searchPool, (list) => { |
| | | initFuse(list) |
| | | }) |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | .header-search { |
| | | .search-icon { |
| | | cursor: pointer; |
| | | font-size: 18px; |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | |
| | | .result-wrap { |
| | | height: 280px; |
| | | margin: 6px 0; |
| | | |
| | | .search-item { |
| | | display: flex; |
| | | height: 48px; |
| | | align-items: center; |
| | | padding-right: 10px; |
| | | |
| | | .left { |
| | | width: 60px; |
| | | text-align: center; |
| | | |
| | | .menu-icon { |
| | | width: 18px; |
| | | height: 18px; |
| | | } |
| | | } |
| | | |
| | | .search-info { |
| | | padding-left: 5px; |
| | | margin-top: 10px; |
| | | width: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: flex-start; |
| | | flex: 1; |
| | | |
| | | .menu-title, |
| | | .menu-path { |
| | | height: 20px; |
| | | } |
| | | .menu-path { |
| | | color: #ccc; |
| | | font-size: 10px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .search-item:hover { |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="icon-body"> |
| | | <el-input |
| | | v-model="iconName" |
| | | class="icon-search" |
| | | clearable |
| | | placeholder="请è¾å
¥å¾æ åç§°" |
| | | @clear="filterIcons" |
| | | @input="filterIcons" |
| | | > |
| | | <template #suffix><i class="el-icon-search el-input__icon" /></template> |
| | | </el-input> |
| | | <div class="icon-list"> |
| | | <div class="list-container"> |
| | | <div v-for="(item, index) in iconList" class="icon-item-wrapper" :key="index" @click="selectedIcon(item)"> |
| | | <div :class="['icon-item', { active: activeIcon === item }]"> |
| | | <svg-icon :icon-class="item" class-name="icon" style="height: 25px;width: 16px;"/> |
| | | <span>{{ item }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import icons from './requireIcons' |
| | | |
| | | const props = defineProps({ |
| | | activeIcon: { |
| | | type: String |
| | | } |
| | | }) |
| | | |
| | | const iconName = ref('') |
| | | const iconList = ref(icons) |
| | | const emit = defineEmits(['selected']) |
| | | |
| | | function filterIcons() { |
| | | iconList.value = icons |
| | | if (iconName.value) { |
| | | iconList.value = icons.filter(item => item.indexOf(iconName.value) !== -1) |
| | | } |
| | | } |
| | | |
| | | function selectedIcon(name) { |
| | | emit('selected', name) |
| | | document.body.click() |
| | | } |
| | | |
| | | function reset() { |
| | | iconName.value = '' |
| | | iconList.value = icons |
| | | } |
| | | |
| | | defineExpose({ |
| | | reset |
| | | }) |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | .icon-body { |
| | | width: 100%; |
| | | padding: 10px; |
| | | .icon-search { |
| | | position: relative; |
| | | margin-bottom: 5px; |
| | | } |
| | | .icon-list { |
| | | height: 200px; |
| | | overflow: auto; |
| | | .list-container { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | .icon-item-wrapper { |
| | | width: calc(100% / 3); |
| | | height: 25px; |
| | | line-height: 25px; |
| | | cursor: pointer; |
| | | display: flex; |
| | | .icon-item { |
| | | display: flex; |
| | | max-width: 100%; |
| | | height: 100%; |
| | | padding: 0 5px; |
| | | &:hover { |
| | | background: #ececec; |
| | | border-radius: 5px; |
| | | } |
| | | .icon { |
| | | flex-shrink: 0; |
| | | } |
| | | span { |
| | | display: inline-block; |
| | | vertical-align: -0.15em; |
| | | fill: currentColor; |
| | | padding-left: 2px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | .icon-item.active { |
| | | background: #ececec; |
| | | border-radius: 5px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | let icons = [] |
| | | const modules = import.meta.glob('./../../assets/icons/svg/*.svg') |
| | | for (const path in modules) { |
| | | const p = path.split('assets/icons/svg/')[1].split('.svg')[0] |
| | | icons.push(p) |
| | | } |
| | | |
| | | export default icons |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-image |
| | | :src="`${realSrc}`" |
| | | fit="cover" |
| | | :style="`width:${realWidth};height:${realHeight};`" |
| | | :preview-src-list="realSrcList" |
| | | preview-teleported |
| | | > |
| | | <template #error> |
| | | <div class="image-slot"> |
| | | <el-icon><picture-filled /></el-icon> |
| | | </div> |
| | | </template> |
| | | </el-image> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { isExternal } from "@/utils/validate" |
| | | |
| | | const props = defineProps({ |
| | | src: { |
| | | type: String, |
| | | default: "" |
| | | }, |
| | | width: { |
| | | type: [Number, String], |
| | | default: "" |
| | | }, |
| | | height: { |
| | | type: [Number, String], |
| | | default: "" |
| | | } |
| | | }) |
| | | |
| | | const realSrc = computed(() => { |
| | | if (!props.src) { |
| | | return |
| | | } |
| | | let real_src = props.src.split(",")[0] |
| | | if (isExternal(real_src)) { |
| | | return real_src |
| | | } |
| | | return import.meta.env.VITE_APP_BASE_API + real_src |
| | | }) |
| | | |
| | | const realSrcList = computed(() => { |
| | | if (!props.src) { |
| | | return |
| | | } |
| | | let real_src_list = props.src.split(",") |
| | | let srcList = [] |
| | | real_src_list.forEach(item => { |
| | | if (isExternal(item)) { |
| | | return srcList.push(item) |
| | | } |
| | | return srcList.push(import.meta.env.VITE_APP_BASE_API + item) |
| | | }) |
| | | return srcList |
| | | }) |
| | | |
| | | const realWidth = computed(() => |
| | | typeof props.width == "string" ? props.width : `${props.width}px` |
| | | ) |
| | | |
| | | const realHeight = computed(() => |
| | | typeof props.height == "string" ? props.height : `${props.height}px` |
| | | ) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .el-image { |
| | | border-radius: 5px; |
| | | background-color: #ebeef5; |
| | | box-shadow: 0 0 5px 1px #ccc; |
| | | :deep(.el-image__inner) { |
| | | transition: all 0.3s; |
| | | cursor: pointer; |
| | | &:hover { |
| | | transform: scale(1.2); |
| | | } |
| | | } |
| | | :deep(.image-slot) { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | width: 100%; |
| | | height: 100%; |
| | | color: #909399; |
| | | font-size: 30px; |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="component-upload-image"> |
| | | <el-upload |
| | | multiple |
| | | :disabled="disabled" |
| | | :action="uploadImgUrl" |
| | | list-type="picture-card" |
| | | :on-success="handleUploadSuccess" |
| | | :before-upload="handleBeforeUpload" |
| | | :data="data" |
| | | :limit="limit" |
| | | :on-error="handleUploadError" |
| | | :on-exceed="handleExceed" |
| | | ref="imageUpload" |
| | | :before-remove="handleDelete" |
| | | :show-file-list="true" |
| | | :headers="headers" |
| | | :file-list="fileList" |
| | | :on-preview="handlePictureCardPreview" |
| | | :class="{ hide: fileList.length >= limit }" |
| | | > |
| | | <el-icon class="avatar-uploader-icon"><plus /></el-icon> |
| | | </el-upload> |
| | | <!-- ä¸ä¼ æç¤º --> |
| | | <div class="el-upload__tip" v-if="showTip && !disabled"> |
| | | 请ä¸ä¼ |
| | | <template v-if="fileSize"> |
| | | 大å°ä¸è¶
è¿ <b style="color: #f56c6c">{{ fileSize }}MB</b> |
| | | </template> |
| | | <template v-if="fileType"> |
| | | æ ¼å¼ä¸º <b style="color: #f56c6c">{{ fileType.join("/") }}</b> |
| | | </template> |
| | | çæä»¶ |
| | | </div> |
| | | |
| | | <el-dialog |
| | | v-model="dialogVisible" |
| | | title="é¢è§" |
| | | width="800px" |
| | | append-to-body |
| | | > |
| | | <img |
| | | :src="dialogImageUrl" |
| | | style="display: block; max-width: 100%; margin: 0 auto" |
| | | /> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getToken } from "@/utils/auth" |
| | | import { isExternal } from "@/utils/validate" |
| | | import Sortable from 'sortablejs' |
| | | |
| | | const props = defineProps({ |
| | | modelValue: [String, Object, Array], |
| | | // ä¸ä¼ æ¥å£å°å |
| | | action: { |
| | | type: String, |
| | | default: "/common/upload" |
| | | }, |
| | | // ä¸ä¼ æºå¸¦çåæ° |
| | | data: { |
| | | type: Object |
| | | }, |
| | | // å¾çæ°ééå¶ |
| | | limit: { |
| | | type: Number, |
| | | default: 5 |
| | | }, |
| | | // 大å°éå¶(MB) |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5 |
| | | }, |
| | | // æä»¶ç±»å, ä¾å¦['png', 'jpg', 'jpeg'] |
| | | fileType: { |
| | | type: Array, |
| | | default: () => ["png", "jpg", "jpeg"] |
| | | }, |
| | | // æ¯å¦æ¾ç¤ºæç¤º |
| | | isShowTip: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // ç¦ç¨ç»ä»¶ï¼ä»
æ¥çå¾çï¼ |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // æå¨æåº |
| | | drag: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }) |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const emit = defineEmits() |
| | | const number = ref(0) |
| | | const uploadList = ref([]) |
| | | const dialogImageUrl = ref("") |
| | | const dialogVisible = ref(false) |
| | | const baseUrl = import.meta.env.VITE_APP_BASE_API |
| | | const uploadImgUrl = ref(import.meta.env.VITE_APP_BASE_API + props.action) // ä¸ä¼ çå¾çæå¡å¨å°å |
| | | const headers = ref({ Authorization: "Bearer " + getToken() }) |
| | | const fileList = ref([]) |
| | | const showTip = computed( |
| | | () => props.isShowTip && (props.fileType || props.fileSize) |
| | | ) |
| | | |
| | | watch(() => props.modelValue, val => { |
| | | if (val) { |
| | | // é¦å
å°å¼è½¬ä¸ºæ°ç» |
| | | const list = Array.isArray(val) ? val : props.modelValue.split(",") |
| | | // ç¶åå°æ°ç»è½¬ä¸ºå¯¹è±¡æ°ç» |
| | | fileList.value = list.map(item => { |
| | | if (typeof item === "string") { |
| | | if (item.indexOf(baseUrl) === -1 && !isExternal(item)) { |
| | | item = { name: baseUrl + item, url: baseUrl + item } |
| | | } else { |
| | | item = { name: item, url: item } |
| | | } |
| | | } |
| | | return item |
| | | }) |
| | | } else { |
| | | fileList.value = [] |
| | | return [] |
| | | } |
| | | },{ deep: true, immediate: true }) |
| | | |
| | | // ä¸ä¼ åloadingå è½½ |
| | | function handleBeforeUpload(file) { |
| | | let isImg = false |
| | | if (props.fileType.length) { |
| | | let fileExtension = "" |
| | | if (file.name.lastIndexOf(".") > -1) { |
| | | fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1) |
| | | } |
| | | isImg = props.fileType.some(type => { |
| | | if (file.type.indexOf(type) > -1) return true |
| | | if (fileExtension && fileExtension.indexOf(type) > -1) return true |
| | | return false |
| | | }) |
| | | } else { |
| | | isImg = file.type.indexOf("image") > -1 |
| | | } |
| | | if (!isImg) { |
| | | proxy.$modal.msgError(`æä»¶æ ¼å¼ä¸æ£ç¡®ï¼è¯·ä¸ä¼ ${props.fileType.join("/")}å¾çæ ¼å¼æä»¶!`) |
| | | return false |
| | | } |
| | | if (file.name.includes(',')) { |
| | | proxy.$modal.msgError('æä»¶å䏿£ç¡®ï¼ä¸è½å
å«è±æéå·!') |
| | | return false |
| | | } |
| | | if (props.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < props.fileSize |
| | | if (!isLt) { |
| | | proxy.$modal.msgError(`ä¸ä¼ 头åå¾ç大å°ä¸è½è¶
è¿ ${props.fileSize} MB!`) |
| | | return false |
| | | } |
| | | } |
| | | proxy.$modal.loading("æ£å¨ä¸ä¼ å¾çï¼è¯·ç¨å...") |
| | | number.value++ |
| | | } |
| | | |
| | | // æä»¶ä¸ªæ°è¶
åº |
| | | function handleExceed() { |
| | | proxy.$modal.msgError(`ä¸ä¼ æä»¶æ°éä¸è½è¶
è¿ ${props.limit} 个!`) |
| | | } |
| | | |
| | | // ä¸ä¼ æååè° |
| | | function handleUploadSuccess(res, file) { |
| | | if (res.code === 200) { |
| | | uploadList.value.push({ name: res.fileName, url: res.fileName }) |
| | | uploadedSuccessfully() |
| | | } else { |
| | | number.value-- |
| | | proxy.$modal.closeLoading() |
| | | proxy.$modal.msgError(res.msg) |
| | | proxy.$refs.imageUpload.handleRemove(file) |
| | | uploadedSuccessfully() |
| | | } |
| | | } |
| | | |
| | | // å é¤å¾ç |
| | | function handleDelete(file) { |
| | | const findex = fileList.value.map(f => f.name).indexOf(file.name) |
| | | if (findex > -1 && uploadList.value.length === number.value) { |
| | | fileList.value.splice(findex, 1) |
| | | emit("update:modelValue", listToString(fileList.value)) |
| | | return false |
| | | } |
| | | } |
| | | |
| | | // ä¸ä¼ ç»æå¤ç |
| | | function uploadedSuccessfully() { |
| | | if (number.value > 0 && uploadList.value.length === number.value) { |
| | | fileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value) |
| | | uploadList.value = [] |
| | | number.value = 0 |
| | | emit("update:modelValue", listToString(fileList.value)) |
| | | proxy.$modal.closeLoading() |
| | | } |
| | | } |
| | | |
| | | // ä¸ä¼ 失败 |
| | | function handleUploadError() { |
| | | proxy.$modal.msgError("ä¸ä¼ å¾ç失败") |
| | | proxy.$modal.closeLoading() |
| | | } |
| | | |
| | | // é¢è§ |
| | | function handlePictureCardPreview(file) { |
| | | dialogImageUrl.value = file.url |
| | | dialogVisible.value = true |
| | | } |
| | | |
| | | // 对象转ææå®å符串åé |
| | | function listToString(list, separator) { |
| | | let strs = "" |
| | | separator = separator || "," |
| | | for (let i in list) { |
| | | if (undefined !== list[i].url && list[i].url.indexOf("blob:") !== 0) { |
| | | strs += list[i].url.replace(baseUrl, "") + separator |
| | | } |
| | | } |
| | | return strs != "" ? strs.substr(0, strs.length - 1) : "" |
| | | } |
| | | |
| | | // åå§åææ½æåº |
| | | onMounted(() => { |
| | | if (props.drag && !props.disabled) { |
| | | nextTick(() => { |
| | | const element = proxy.$refs.imageUpload?.$el?.querySelector('.el-upload-list') |
| | | Sortable.create(element, { |
| | | onEnd: (evt) => { |
| | | const movedItem = fileList.value.splice(evt.oldIndex, 1)[0] |
| | | fileList.value.splice(evt.newIndex, 0, movedItem) |
| | | emit('update:modelValue', listToString(fileList.value)) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | // .el-upload--picture-card æ§å¶å å·é¨å |
| | | :deep(.hide .el-upload--picture-card) { |
| | | display: none; |
| | | } |
| | | |
| | | :deep(.el-upload.el-upload--picture-card.is-disabled) { |
| | | display: none !important; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div :class="{ 'hidden': hidden }" class="pagination-container"> |
| | | <el-pagination |
| | | :background="background" |
| | | v-model:current-page="currentPage" |
| | | v-model:page-size="pageSize" |
| | | :layout="layout" |
| | | :page-sizes="pageSizes" |
| | | :pager-count="pagerCount" |
| | | :total="total" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { scrollTo } from '@/utils/scroll-to' |
| | | |
| | | const props = defineProps({ |
| | | total: { |
| | | required: true, |
| | | type: Number |
| | | }, |
| | | page: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | limit: { |
| | | type: Number, |
| | | default: 20 |
| | | }, |
| | | pageSizes: { |
| | | type: Array, |
| | | default() { |
| | | return [10, 20, 30, 50] |
| | | } |
| | | }, |
| | | // ç§»å¨ç«¯é¡µç æé®çæ°é端é»è®¤å¼5 |
| | | pagerCount: { |
| | | type: Number, |
| | | default: document.body.clientWidth < 992 ? 5 : 7 |
| | | }, |
| | | layout: { |
| | | type: String, |
| | | default: 'total, sizes, prev, pager, next, jumper' |
| | | }, |
| | | background: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | autoScroll: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | hidden: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }) |
| | | |
| | | const emit = defineEmits() |
| | | const currentPage = computed({ |
| | | get() { |
| | | return props.page |
| | | }, |
| | | set(val) { |
| | | emit('update:page', val) |
| | | } |
| | | }) |
| | | const pageSize = computed({ |
| | | get() { |
| | | return props.limit |
| | | }, |
| | | set(val){ |
| | | emit('update:limit', val) |
| | | } |
| | | }) |
| | | |
| | | function handleSizeChange(val) { |
| | | if (currentPage.value * val > props.total) { |
| | | currentPage.value = 1 |
| | | } |
| | | emit('pagination', { page: currentPage.value, limit: val }) |
| | | if (props.autoScroll) { |
| | | scrollTo(0, 800) |
| | | } |
| | | } |
| | | |
| | | function handleCurrentChange(val) { |
| | | emit('pagination', { page: val, limit: pageSize.value }) |
| | | if (props.autoScroll) { |
| | | scrollTo(0, 800) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .pagination-container { |
| | | background: #fff; |
| | | } |
| | | .pagination-container.hidden { |
| | | display: none; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template > |
| | | <router-view /> |
| | | </template> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="top-right-btn" :style="style"> |
| | | <el-row> |
| | | <el-tooltip class="item" effect="dark" :content="showSearch ? 'éèæç´¢' : 'æ¾ç¤ºæç´¢'" placement="top" v-if="search"> |
| | | <el-button circle icon="Search" @click="toggleSearch()" /> |
| | | </el-tooltip> |
| | | <el-tooltip class="item" effect="dark" content="å·æ°" placement="top"> |
| | | <el-button circle icon="Refresh" @click="refresh()" /> |
| | | </el-tooltip> |
| | | <el-tooltip class="item" effect="dark" content="æ¾éå" placement="top" v-if="columns"> |
| | | <el-button circle icon="Menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/> |
| | | <el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'"> |
| | | <el-button circle icon="Menu" /> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <!-- å
¨é/åé æé® --> |
| | | <el-dropdown-item> |
| | | <el-checkbox :indeterminate="isIndeterminate" v-model="isChecked" @change="toggleCheckAll"> åå±ç¤º </el-checkbox> |
| | | </el-dropdown-item> |
| | | <div class="check-line"></div> |
| | | <template v-for="item in columns" :key="item.key"> |
| | | <el-dropdown-item> |
| | | <el-checkbox v-model="item.visible" @change="checkboxChange($event, item.label)" :label="item.label" /> |
| | | </el-dropdown-item> |
| | | </template> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </el-tooltip> |
| | | </el-row> |
| | | <el-dialog :title="title" v-model="open" append-to-body> |
| | | <el-transfer |
| | | :titles="['æ¾ç¤º', 'éè']" |
| | | v-model="value" |
| | | :data="columns" |
| | | @change="dataChange" |
| | | ></el-transfer> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const props = defineProps({ |
| | | /* æ¯å¦æ¾ç¤ºæ£ç´¢æ¡ä»¶ */ |
| | | showSearch: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | /* æ¾éåä¿¡æ¯ */ |
| | | columns: { |
| | | type: Array |
| | | }, |
| | | /* æ¯å¦æ¾ç¤ºæ£ç´¢å¾æ */ |
| | | search: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | /* æ¾éåç±»åï¼transferç©¿æ¢æ¡ãcheckboxå¤éæ¡ï¼ */ |
| | | showColumnsType: { |
| | | type: String, |
| | | default: "checkbox" |
| | | }, |
| | | /* å³å¤è¾¹è· */ |
| | | gutter: { |
| | | type: Number, |
| | | default: 10 |
| | | }, |
| | | }) |
| | | |
| | | const emits = defineEmits(['update:showSearch', 'queryTable']) |
| | | |
| | | // æ¾éæ°æ® |
| | | const value = ref([]) |
| | | // å¼¹åºå±æ é¢ |
| | | const title = ref("æ¾ç¤º/éè") |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå± |
| | | const open = ref(false) |
| | | |
| | | const style = computed(() => { |
| | | const ret = {} |
| | | if (props.gutter) { |
| | | ret.marginRight = `${props.gutter / 2}px` |
| | | } |
| | | return ret |
| | | }) |
| | | |
| | | // æ¯å¦å
¨é/åé ç¶æ |
| | | const isChecked = computed({ |
| | | get: () => props.columns.every(col => col.visible), |
| | | set: () => {} |
| | | }) |
| | | const isIndeterminate = computed(() => props.columns.some((col) => col.visible) && !isChecked.value) |
| | | |
| | | // æç´¢ |
| | | function toggleSearch() { |
| | | emits("update:showSearch", !props.showSearch) |
| | | } |
| | | |
| | | // å·æ° |
| | | function refresh() { |
| | | emits("queryTable") |
| | | } |
| | | |
| | | // å³ä¾§å表å
ç´ åå |
| | | function dataChange(data) { |
| | | for (let item in props.columns) { |
| | | const key = props.columns[item].key |
| | | props.columns[item].visible = !data.includes(key) |
| | | } |
| | | } |
| | | |
| | | // æå¼æ¾éådialog |
| | | function showColumn() { |
| | | open.value = true |
| | | } |
| | | |
| | | if (props.showColumnsType == 'transfer') { |
| | | // æ¾éååå§é»è®¤éèå |
| | | for (let item in props.columns) { |
| | | if (props.columns[item].visible === false) { |
| | | value.value.push(parseInt(item)) |
| | | } |
| | | } |
| | | } |
| | | |
| | | // åå¾é |
| | | function checkboxChange(event, label) { |
| | | props.columns.filter(item => item.label == label)[0].visible = event |
| | | } |
| | | |
| | | // 忢å
¨é/åé |
| | | function toggleCheckAll() { |
| | | const newValue = !isChecked.value |
| | | props.columns.forEach((col) => (col.visible = newValue)) |
| | | } |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | :deep(.el-transfer__button) { |
| | | border-radius: 50%; |
| | | display: block; |
| | | margin-left: 0px; |
| | | } |
| | | :deep(.el-transfer__button:first-child) { |
| | | margin-bottom: 10px; |
| | | } |
| | | :deep(.el-dropdown-menu__item) { |
| | | line-height: 30px; |
| | | padding: 0 17px; |
| | | } |
| | | .check-line { |
| | | width: 90%; |
| | | height: 1px; |
| | | background-color: #ccc; |
| | | margin: 3px auto; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <svg-icon icon-class="question" @click="goto" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const url = ref('http://doc.ruoyi.vip/ruoyi-vue') |
| | | |
| | | function goto() { |
| | | window.open(url.value) |
| | | } |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <svg-icon icon-class="github" @click="goto" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const url = ref('https://gitee.com/y_project/RuoYi-Vue') |
| | | |
| | | function goto() { |
| | | window.open(url.value) |
| | | } |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'" @click="toggle" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useFullscreen } from '@vueuse/core' |
| | | |
| | | const { isFullscreen, enter, exit, toggle } = useFullscreen() |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | .screenfull-svg { |
| | | display: inline-block; |
| | | cursor: pointer; |
| | | fill: #5a5e66; |
| | | width: 20px; |
| | | height: 20px; |
| | | vertical-align: 10px; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dropdown trigger="click" @command="handleSetSize"> |
| | | <div class="size-icon--style"> |
| | | <svg-icon class-name="size-icon" icon-class="size" /> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size === item.value" :command="item.value"> |
| | | {{ item.label }} |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import useAppStore from "@/store/modules/app" |
| | | |
| | | const appStore = useAppStore() |
| | | const size = computed(() => appStore.size) |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | const { proxy } = getCurrentInstance() |
| | | const sizeOptions = ref([ |
| | | { label: "è¾å¤§", value: "large" }, |
| | | { label: "é»è®¤", value: "default" }, |
| | | { label: "ç¨å°", value: "small" }, |
| | | ]) |
| | | |
| | | function handleSetSize(size) { |
| | | proxy.$modal.loading("æ£å¨è®¾ç½®å¸å±å¤§å°ï¼è¯·ç¨å...") |
| | | appStore.setSize(size) |
| | | setTimeout("window.location.reload()", 1000) |
| | | } |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | .size-icon--style { |
| | | font-size: 18px; |
| | | line-height: 50px; |
| | | padding-right: 7px; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <svg :class="svgClass" aria-hidden="true"> |
| | | <use :xlink:href="iconName" :fill="color" /> |
| | | </svg> |
| | | </template> |
| | | |
| | | <script> |
| | | export default defineComponent({ |
| | | props: { |
| | | iconClass: { |
| | | type: String, |
| | | required: true |
| | | }, |
| | | className: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | color: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | }, |
| | | setup(props) { |
| | | return { |
| | | iconName: computed(() => `#icon-${props.iconClass}`), |
| | | svgClass: computed(() => { |
| | | if (props.className) { |
| | | return `svg-icon ${props.className}` |
| | | } |
| | | return 'svg-icon' |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | </script> |
| | | |
| | | <style scope lang="scss"> |
| | | .sub-el-icon, |
| | | .nav-icon { |
| | | display: inline-block; |
| | | font-size: 15px; |
| | | margin-right: 12px; |
| | | position: relative; |
| | | } |
| | | |
| | | .svg-icon { |
| | | width: 1em; |
| | | height: 1em; |
| | | position: relative; |
| | | fill: currentColor; |
| | | vertical-align: -2px; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import * as components from '@element-plus/icons-vue' |
| | | |
| | | export default { |
| | | install: (app) => { |
| | | for (const key in components) { |
| | | const componentConfig = components[key] |
| | | app.component(componentConfig.name, componentConfig) |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-menu |
| | | :default-active="activeMenu" |
| | | mode="horizontal" |
| | | @select="handleSelect" |
| | | :ellipsis="false" |
| | | > |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"> |
| | | <svg-icon |
| | | v-if="item.meta && item.meta.icon && item.meta.icon !== '#'" |
| | | :icon-class="item.meta.icon"/> |
| | | {{ item.meta.title }} |
| | | </el-menu-item> |
| | | </template> |
| | | |
| | | <!-- é¡¶é¨èåè¶
åºæ°éæå --> |
| | | <el-sub-menu :style="{'--theme': theme}" index="more" v-if="topMenus.length > visibleNumber"> |
| | | <template #title>æ´å¤èå</template> |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item |
| | | :index="item.path" |
| | | :key="index" |
| | | v-if="index >= visibleNumber"> |
| | | <svg-icon |
| | | v-if="item.meta && item.meta.icon && item.meta.icon !== '#'" |
| | | :icon-class="item.meta.icon"/> |
| | | {{ item.meta.title }} |
| | | </el-menu-item> |
| | | </template> |
| | | </el-sub-menu> |
| | | </el-menu> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { constantRoutes } from "@/router" |
| | | import { isHttp } from '@/utils/validate' |
| | | import useAppStore from '@/store/modules/app' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | import usePermissionStore from '@/store/modules/permission' |
| | | |
| | | // 顶鍿 åå§æ° |
| | | const visibleNumber = ref(null) |
| | | // å½åæ¿æ´»èåç index |
| | | const currentIndex = ref(null) |
| | | // éèä¾§è¾¹æ è·¯ç± |
| | | const hideList = ['/index', '/user/profile'] |
| | | |
| | | const appStore = useAppStore() |
| | | const settingsStore = useSettingsStore() |
| | | const permissionStore = usePermissionStore() |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | |
| | | // 主é¢é¢è² |
| | | const theme = computed(() => settingsStore.theme) |
| | | // ææçè·¯ç±ä¿¡æ¯ |
| | | const routers = computed(() => permissionStore.topbarRouters) |
| | | |
| | | // 顶鍿¾ç¤ºèå |
| | | const topMenus = computed(() => { |
| | | let topMenus = [] |
| | | routers.value.map((menu) => { |
| | | if (menu.hidden !== true) { |
| | | // å
¼å®¹é¡¶é¨æ ä¸çº§èåå
é¨è·³è½¬ |
| | | if (menu.path === '/' && menu.children) { |
| | | topMenus.push(menu.children[0]) |
| | | } else { |
| | | topMenus.push(menu) |
| | | } |
| | | } |
| | | }) |
| | | return topMenus |
| | | }) |
| | | |
| | | // 设置åè·¯ç± |
| | | const childrenMenus = computed(() => { |
| | | let childrenMenus = [] |
| | | routers.value.map((router) => { |
| | | for (let item in router.children) { |
| | | if (router.children[item].parentPath === undefined) { |
| | | if(router.path === "/") { |
| | | router.children[item].path = "/" + router.children[item].path |
| | | } else { |
| | | if(!isHttp(router.children[item].path)) { |
| | | router.children[item].path = router.path + "/" + router.children[item].path |
| | | } |
| | | } |
| | | router.children[item].parentPath = router.path |
| | | } |
| | | childrenMenus.push(router.children[item]) |
| | | } |
| | | }) |
| | | return constantRoutes.concat(childrenMenus) |
| | | }) |
| | | |
| | | // é»è®¤æ¿æ´»çèå |
| | | const activeMenu = computed(() => { |
| | | const path = route.path |
| | | let activePath = path |
| | | if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) { |
| | | const tmpPath = path.substring(1, path.length) |
| | | if (!route.meta.link) { |
| | | activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/")) |
| | | appStore.toggleSideBarHide(false) |
| | | } |
| | | } else if(!route.children) { |
| | | activePath = path |
| | | appStore.toggleSideBarHide(true) |
| | | } |
| | | activeRoutes(activePath) |
| | | return activePath |
| | | }) |
| | | |
| | | function setVisibleNumber() { |
| | | const width = document.body.getBoundingClientRect().width / 3 |
| | | visibleNumber.value = parseInt(width / 85) |
| | | } |
| | | |
| | | function handleSelect(key, keyPath) { |
| | | currentIndex.value = key |
| | | const route = routers.value.find(item => item.path === key) |
| | | if (isHttp(key)) { |
| | | // http(s):// è·¯å¾æ°çªå£æå¼ |
| | | window.open(key, "_blank") |
| | | } else if (!route || !route.children) { |
| | | // 没æåè·¯ç±è·¯å¾å
é¨æå¼ |
| | | const routeMenu = childrenMenus.value.find(item => item.path === key) |
| | | if (routeMenu && routeMenu.query) { |
| | | let query = JSON.parse(routeMenu.query) |
| | | router.push({ path: key, query: query }) |
| | | } else { |
| | | router.push({ path: key }) |
| | | } |
| | | appStore.toggleSideBarHide(true) |
| | | } else { |
| | | // æ¾ç¤ºå·¦ä¾§èå¨èå |
| | | activeRoutes(key) |
| | | appStore.toggleSideBarHide(false) |
| | | } |
| | | } |
| | | |
| | | function activeRoutes(key) { |
| | | let routes = [] |
| | | if (childrenMenus.value && childrenMenus.value.length > 0) { |
| | | childrenMenus.value.map((item) => { |
| | | if (key == item.parentPath || (key == "index" && "" == item.path)) { |
| | | routes.push(item) |
| | | } |
| | | }) |
| | | } |
| | | if(routes.length > 0) { |
| | | permissionStore.setSidebarRouters(routes) |
| | | } else { |
| | | appStore.toggleSideBarHide(true) |
| | | } |
| | | return routes |
| | | } |
| | | |
| | | onMounted(() => { |
| | | window.addEventListener('resize', setVisibleNumber) |
| | | }) |
| | | |
| | | onBeforeUnmount(() => { |
| | | window.removeEventListener('resize', setVisibleNumber) |
| | | }) |
| | | |
| | | onMounted(() => { |
| | | setVisibleNumber() |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .topmenu-container.el-menu--horizontal > .el-menu-item { |
| | | float: left; |
| | | height: 50px !important; |
| | | line-height: 50px !important; |
| | | color: #999093 !important; |
| | | padding: 0 5px !important; |
| | | margin: 0 10px !important; |
| | | } |
| | | |
| | | .topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-sub-menu.is-active .el-submenu__title { |
| | | border-bottom: 2px solid #{'var(--theme)'} !important; |
| | | color: #303133; |
| | | } |
| | | |
| | | /* sub-menu item */ |
| | | .topmenu-container.el-menu--horizontal > .el-sub-menu .el-sub-menu__title { |
| | | float: left; |
| | | height: 50px !important; |
| | | line-height: 50px !important; |
| | | color: #999093 !important; |
| | | padding: 0 5px !important; |
| | | margin: 0 10px !important; |
| | | } |
| | | |
| | | /* èæ¯è²éè */ |
| | | .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover { |
| | | background-color: #ffffff; |
| | | } |
| | | |
| | | /* 徿 å³é´è· */ |
| | | .topmenu-container .svg-icon { |
| | | margin-right: 4px; |
| | | } |
| | | |
| | | /* topmenu more arrow */ |
| | | .topmenu-container .el-sub-menu .el-sub-menu__icon-arrow { |
| | | position: static; |
| | | vertical-align: middle; |
| | | margin-left: 8px; |
| | | margin-top: 0px; |
| | | } |
| | | |
| | | |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div v-loading="loading" :style="'height:' + height"> |
| | | <iframe |
| | | :src="url" |
| | | frameborder="no" |
| | | style="width: 100%; height: 100%" |
| | | scrolling="auto" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const props = defineProps({ |
| | | src: { |
| | | type: String, |
| | | required: true |
| | | } |
| | | }) |
| | | |
| | | const height = ref(document.documentElement.clientHeight - 94.5 + "px;") |
| | | const loading = ref(true) |
| | | const url = computed(() => props.src) |
| | | |
| | | onMounted(() => { |
| | | setTimeout(() => { |
| | | loading.value = false |
| | | }, 300) |
| | | window.onresize = function temp() { |
| | | height.value = document.documentElement.clientHeight - 94.5 + "px;" |
| | | } |
| | | }) |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * v-copyText å¤å¶ææ¬å
容 |
| | | * Copyright (c) 2022 ruoyi |
| | | */ |
| | | export default { |
| | | beforeMount(el, { value, arg }) { |
| | | if (arg === "callback") { |
| | | el.$copyCallback = value |
| | | } else { |
| | | el.$copyValue = value |
| | | const handler = () => { |
| | | copyTextToClipboard(el.$copyValue) |
| | | if (el.$copyCallback) { |
| | | el.$copyCallback(el.$copyValue) |
| | | } |
| | | } |
| | | el.addEventListener("click", handler) |
| | | el.$destroyCopy = () => el.removeEventListener("click", handler) |
| | | } |
| | | } |
| | | } |
| | | |
| | | function copyTextToClipboard(input, { target = document.body } = {}) { |
| | | const element = document.createElement('textarea') |
| | | const previouslyFocusedElement = document.activeElement |
| | | |
| | | element.value = input |
| | | |
| | | // Prevent keyboard from showing on mobile |
| | | element.setAttribute('readonly', '') |
| | | |
| | | element.style.contain = 'strict' |
| | | element.style.position = 'absolute' |
| | | element.style.left = '-9999px' |
| | | element.style.fontSize = '12pt' // Prevent zooming on iOS |
| | | |
| | | const selection = document.getSelection() |
| | | const originalRange = selection.rangeCount > 0 && selection.getRangeAt(0) |
| | | |
| | | target.append(element) |
| | | element.select() |
| | | |
| | | // Explicit selection workaround for iOS |
| | | element.selectionStart = 0 |
| | | element.selectionEnd = input.length |
| | | |
| | | let isSuccess = false |
| | | try { |
| | | isSuccess = document.execCommand('copy') |
| | | } catch { } |
| | | |
| | | element.remove() |
| | | |
| | | if (originalRange) { |
| | | selection.removeAllRanges() |
| | | selection.addRange(originalRange) |
| | | } |
| | | |
| | | // Get the focus back on the previously focused element, if any |
| | | if (previouslyFocusedElement) { |
| | | previouslyFocusedElement.focus() |
| | | } |
| | | |
| | | return isSuccess |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import hasRole from './permission/hasRole' |
| | | import hasPermi from './permission/hasPermi' |
| | | import copyText from './common/copyText' |
| | | |
| | | export default function directive(app){ |
| | | app.directive('hasRole', hasRole) |
| | | app.directive('hasPermi', hasPermi) |
| | | app.directive('copyText', copyText) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * v-hasPermi æä½æéå¤ç |
| | | * Copyright (c) 2019 ruoyi |
| | | */ |
| | | import useUserStore from '@/store/modules/user' |
| | | |
| | | export default { |
| | | mounted(el, binding, vnode) { |
| | | const { value } = binding |
| | | const all_permission = "*:*:*" |
| | | const permissions = useUserStore().permissions |
| | | |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const permissionFlag = value |
| | | |
| | | const hasPermissions = permissions.some(permission => { |
| | | return all_permission === permission || permissionFlag.includes(permission) |
| | | }) |
| | | |
| | | if (!hasPermissions) { |
| | | el.parentNode && el.parentNode.removeChild(el) |
| | | } |
| | | } else { |
| | | throw new Error(`请设置æä½æéæ ç¾å¼`) |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * v-hasRole è§è²æéå¤ç |
| | | * Copyright (c) 2019 ruoyi |
| | | */ |
| | | import useUserStore from '@/store/modules/user' |
| | | |
| | | export default { |
| | | mounted(el, binding, vnode) { |
| | | const { value } = binding |
| | | const super_admin = "admin" |
| | | const roles = useUserStore().roles |
| | | |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const roleFlag = value |
| | | |
| | | const hasRole = roles.some(role => { |
| | | return super_admin === role || roleFlag.includes(role) |
| | | }) |
| | | |
| | | if (!hasRole) { |
| | | el.parentNode && el.parentNode.removeChild(el) |
| | | } |
| | | } else { |
| | | throw new Error(`请设置è§è²æéæ ç¾å¼`) |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <section class="app-main"> |
| | | <router-view v-slot="{ Component, route }"> |
| | | <transition name="fade-transform" mode="out-in"> |
| | | <keep-alive :include="tagsViewStore.cachedViews"> |
| | | <component v-if="!route.meta.link" :is="Component" :key="route.path"/> |
| | | </keep-alive> |
| | | </transition> |
| | | </router-view> |
| | | <iframe-toggle /> |
| | | </section> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import iframeToggle from "./IframeToggle/index" |
| | | import useTagsViewStore from '@/store/modules/tagsView' |
| | | |
| | | const route = useRoute() |
| | | const tagsViewStore = useTagsViewStore() |
| | | |
| | | onMounted(() => { |
| | | addIframe() |
| | | }) |
| | | |
| | | watchEffect(() => { |
| | | addIframe() |
| | | }) |
| | | |
| | | function addIframe() { |
| | | if (route.meta.link) { |
| | | useTagsViewStore().addIframeView(route) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .app-main { |
| | | /* 50= navbar 50 */ |
| | | min-height: calc(100vh - 50px); |
| | | width: 100%; |
| | | position: relative; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .fixed-header + .app-main { |
| | | padding-top: 50px; |
| | | } |
| | | |
| | | .hasTagsView { |
| | | .app-main { |
| | | /* 84 = navbar + tags-view = 50 + 34 */ |
| | | min-height: calc(100vh - 84px); |
| | | } |
| | | |
| | | .fixed-header + .app-main { |
| | | padding-top: 84px; |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | <style lang="scss"> |
| | | // fix css style bug in open el-dialog |
| | | .el-popup-parent--hidden { |
| | | .fixed-header { |
| | | padding-right: 6px; |
| | | } |
| | | } |
| | | |
| | | ::-webkit-scrollbar { |
| | | width: 6px; |
| | | height: 6px; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-track { |
| | | background-color: #f1f1f1; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-thumb { |
| | | background-color: #c0c0c0; |
| | | border-radius: 3px; |
| | | } |
| | | </style> |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <inner-link |
| | | v-for="(item, index) in tagsViewStore.iframeViews" |
| | | :key="item.path" |
| | | :iframeId="'iframe' + index" |
| | | v-show="route.path === item.path" |
| | | :src="iframeUrl(item.meta.link, item.query)" |
| | | ></inner-link> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import InnerLink from "../InnerLink/index" |
| | | import useTagsViewStore from "@/store/modules/tagsView" |
| | | |
| | | const route = useRoute() |
| | | const tagsViewStore = useTagsViewStore() |
| | | |
| | | function iframeUrl(url, query) { |
| | | if (Object.keys(query).length > 0) { |
| | | let params = Object.keys(query).map((key) => key + "=" + query[key]).join("&") |
| | | return url + "?" + params |
| | | } |
| | | return url |
| | | } |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div :style="'height:' + height" v-loading="loading" element-loading-text="æ£å¨å 载页é¢ï¼è¯·ç¨åï¼"> |
| | | <iframe |
| | | :id="iframeId" |
| | | style="width: 100%; height: 100%" |
| | | :src="src" |
| | | ref="iframeRef" |
| | | frameborder="no" |
| | | ></iframe> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | const props = defineProps({ |
| | | src: { |
| | | type: String, |
| | | default: "/" |
| | | }, |
| | | iframeId: { |
| | | type: String |
| | | } |
| | | }) |
| | | |
| | | const loading = ref(true) |
| | | const height = ref(document.documentElement.clientHeight - 94.5 + 'px') |
| | | const iframeRef = ref(null) |
| | | |
| | | onMounted(() => { |
| | | if (iframeRef.value) { |
| | | iframeRef.value.onload = () => { |
| | | loading.value = false |
| | | } |
| | | } |
| | | }) |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="navbar"> |
| | | <!-- <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />--> |
| | | <!-- <breadcrumb v-if="!settingsStore.topNav" id="breadcrumb-container" class="breadcrumb-container" />--> |
| | | <!-- <top-nav v-if="settingsStore.topNav" id="topmenu-container" class="topmenu-container" />--> |
| | | <div class="logo"> |
| | | <img src="@/assets/logo/logo.png" alt=""/> |
| | | </div> |
| | | <div class="right-menu"> |
| | | <template v-if="appStore.device !== 'mobile'"> |
| | | <header-search id="header-search" class="right-menu-item" /> |
| | | <screenfull id="screenfull" class="right-menu-item hover-effect" /> |
| | | </template> |
| | | <el-dropdown @command="handleCommand" class="avatar-container right-menu-item hover-effect" trigger="hover"> |
| | | <div class="avatar-wrapper"> |
| | | <img :src="userStore.avatar" class="user-avatar" /> |
| | | <span class="user-nickname"> {{ userStore.nickName }} </span> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <router-link to="/user/profile"> |
| | | <el-dropdown-item>个人ä¸å¿</el-dropdown-item> |
| | | </router-link> |
| | | <el-dropdown-item divided command="logout"> |
| | | <span>éåºç»å½</span> |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | <!-- <div class="right-menu-item hover-effect setting" @click="setLayout" v-if="settingsStore.showSettings">--> |
| | | <!-- <svg-icon icon-class="more-up" />--> |
| | | <!-- </div>--> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ElMessageBox } from 'element-plus' |
| | | import Breadcrumb from '@/components/Breadcrumb' |
| | | import TopNav from '@/components/TopNav' |
| | | import Hamburger from '@/components/Hamburger' |
| | | import Screenfull from '@/components/Screenfull' |
| | | import SizeSelect from '@/components/SizeSelect' |
| | | import HeaderSearch from '@/components/HeaderSearch' |
| | | import RuoYiGit from '@/components/RuoYi/Git' |
| | | import RuoYiDoc from '@/components/RuoYi/Doc' |
| | | import useAppStore from '@/store/modules/app' |
| | | import useUserStore from '@/store/modules/user' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | |
| | | const appStore = useAppStore() |
| | | const userStore = useUserStore() |
| | | const settingsStore = useSettingsStore() |
| | | |
| | | function toggleSideBar() { |
| | | appStore.toggleSideBar() |
| | | } |
| | | |
| | | function handleCommand(command) { |
| | | switch (command) { |
| | | case "setLayout": |
| | | setLayout() |
| | | break |
| | | case "logout": |
| | | logout() |
| | | break |
| | | default: |
| | | break |
| | | } |
| | | } |
| | | |
| | | function logout() { |
| | | ElMessageBox.confirm('ç¡®å®æ³¨éå¹¶éåºç³»ç»åï¼', 'æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | userStore.logOut().then(() => { |
| | | location.href = '/index' |
| | | }) |
| | | }).catch(() => { }) |
| | | } |
| | | |
| | | const emits = defineEmits(['setLayout']) |
| | | function setLayout() { |
| | | emits('setLayout') |
| | | } |
| | | |
| | | function toggleTheme() { |
| | | settingsStore.toggleTheme() |
| | | } |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | .navbar { |
| | | height: 50px; |
| | | overflow: hidden; |
| | | position: fixed; /* å°å¤´é¨åºå® */ |
| | | top: 0; /* å¨é¡¶é¨åºå® */ |
| | | width: 100%; /* 宽度100%ï¼è¦çæ´ä¸ªè§å£ */ |
| | | //background-color: #f8f9fa; /* è®¾ç½®èæ¯é¢è²ï¼ä»¥ä¾¿æ´ææ¾å°çå°ææ */ |
| | | z-index: 1000; /* ç¡®ä¿å¤´é¨å¨å
¶ä»å
容ä¹ä¸ */ |
| | | background: var(--navbar-bg); |
| | | box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); |
| | | display: flex; |
| | | justify-content: space-between; |
| | | padding: 0 20px; |
| | | |
| | | .logo { |
| | | height: 50px; |
| | | line-height: 50px; |
| | | img { |
| | | cursor: pointer; |
| | | width: 146px; |
| | | height: 46px; |
| | | } |
| | | } |
| | | |
| | | .breadcrumb-container { |
| | | float: left; |
| | | } |
| | | |
| | | .topmenu-container { |
| | | position: absolute; |
| | | left: 50px; |
| | | } |
| | | |
| | | .errLog-container { |
| | | display: inline-block; |
| | | vertical-align: top; |
| | | } |
| | | |
| | | .right-menu { |
| | | float: right; |
| | | height: 100%; |
| | | line-height: 50px; |
| | | display: flex; |
| | | |
| | | &:focus { |
| | | outline: none; |
| | | } |
| | | |
| | | .right-menu-item { |
| | | display: inline-block; |
| | | padding: 0 8px; |
| | | height: 100%; |
| | | font-size: 18px; |
| | | color: #5a5e66; |
| | | vertical-align: text-bottom; |
| | | |
| | | &.hover-effect { |
| | | cursor: pointer; |
| | | transition: background 0.3s; |
| | | |
| | | &:hover { |
| | | background: rgba(0, 0, 0, 0.025); |
| | | } |
| | | } |
| | | |
| | | &.theme-switch-wrapper { |
| | | display: flex; |
| | | align-items: center; |
| | | |
| | | svg { |
| | | transition: transform 0.3s; |
| | | |
| | | &:hover { |
| | | transform: scale(1.15); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .avatar-container { |
| | | margin-right: 0px; |
| | | padding-right: 0px; |
| | | |
| | | .avatar-wrapper { |
| | | margin-top: 10px; |
| | | right: 5px; |
| | | position: relative; |
| | | |
| | | .user-avatar { |
| | | cursor: pointer; |
| | | width: 30px; |
| | | height: 30px; |
| | | border-radius: 50%; |
| | | } |
| | | |
| | | .user-nickname{ |
| | | position: relative; |
| | | left: 5px; |
| | | bottom: 10px; |
| | | font-size: 14px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | i { |
| | | cursor: pointer; |
| | | position: absolute; |
| | | right: -20px; |
| | | top: 25px; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-drawer v-model="showSettings" :withHeader="false" direction="rtl" size="300px"> |
| | | <div class="setting-drawer-title"> |
| | | <h3 class="drawer-title">主é¢é£æ ¼è®¾ç½®</h3> |
| | | </div> |
| | | <div class="setting-drawer-block-checbox"> |
| | | <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')"> |
| | | <img src="@/assets/images/dark.svg" alt="dark" /> |
| | | <div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;"> |
| | | <i aria-label="徿 : check" class="anticon anticon-check"> |
| | | <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class> |
| | | <path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" /> |
| | | </svg> |
| | | </i> |
| | | </div> |
| | | </div> |
| | | <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')"> |
| | | <img src="@/assets/images/light.svg" alt="light" /> |
| | | <div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;"> |
| | | <i aria-label="徿 : check" class="anticon anticon-check"> |
| | | <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class> |
| | | <path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" /> |
| | | </svg> |
| | | </i> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="drawer-item"> |
| | | <span>主é¢é¢è²</span> |
| | | <span class="comp-style"> |
| | | <el-color-picker v-model="theme" :predefine="predefineColors" @change="themeChange"/> |
| | | </span> |
| | | </div> |
| | | <el-divider /> |
| | | |
| | | <h3 class="drawer-title">ç³»ç»å¸å±é
ç½®</h3> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>å¼å¯ TopNav</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="settingsStore.topNav" @change="topNavChange" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>å¼å¯ Tags-Views</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="settingsStore.tagsView" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>åºå® Header</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="settingsStore.fixedHeader" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>æ¾ç¤º Logo</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="settingsStore.sidebarLogo" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>卿æ é¢</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="settingsStore.dynamicTitle" @change="dynamicTitleChange" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | |
| | | <el-divider /> |
| | | |
| | | <el-button type="primary" plain icon="DocumentAdd" @click="saveSetting">ä¿åé
ç½®</el-button> |
| | | <el-button plain icon="Refresh" @click="resetSetting">éç½®é
ç½®</el-button> |
| | | </el-drawer> |
| | | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import useAppStore from '@/store/modules/app' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | import usePermissionStore from '@/store/modules/permission' |
| | | import { handleThemeStyle } from '@/utils/theme' |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const appStore = useAppStore() |
| | | const settingsStore = useSettingsStore() |
| | | const permissionStore = usePermissionStore() |
| | | const showSettings = ref(false) |
| | | const theme = ref(settingsStore.theme) |
| | | const sideTheme = ref(settingsStore.sideTheme) |
| | | const storeSettings = computed(() => settingsStore) |
| | | const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"]) |
| | | |
| | | /** æ¯å¦éè¦topnav */ |
| | | function topNavChange(val) { |
| | | if (!val) { |
| | | appStore.toggleSideBarHide(false) |
| | | permissionStore.setSidebarRouters(permissionStore.defaultRoutes) |
| | | } |
| | | } |
| | | |
| | | /** æ¯å¦éè¦dynamicTitle */ |
| | | function dynamicTitleChange() { |
| | | useSettingsStore().setTitle(useSettingsStore().title) |
| | | } |
| | | |
| | | function themeChange(val) { |
| | | settingsStore.theme = val |
| | | handleThemeStyle(val) |
| | | } |
| | | |
| | | function handleTheme(val) { |
| | | settingsStore.sideTheme = val |
| | | sideTheme.value = val |
| | | } |
| | | |
| | | function saveSetting() { |
| | | proxy.$modal.loading("æ£å¨ä¿åå°æ¬å°ï¼è¯·ç¨å...") |
| | | let layoutSetting = { |
| | | "topNav": storeSettings.value.topNav, |
| | | "tagsView": storeSettings.value.tagsView, |
| | | "fixedHeader": storeSettings.value.fixedHeader, |
| | | "sidebarLogo": storeSettings.value.sidebarLogo, |
| | | "dynamicTitle": storeSettings.value.dynamicTitle, |
| | | "sideTheme": storeSettings.value.sideTheme, |
| | | "theme": storeSettings.value.theme |
| | | } |
| | | localStorage.setItem("layout-setting", JSON.stringify(layoutSetting)) |
| | | setTimeout(proxy.$modal.closeLoading(), 1000) |
| | | } |
| | | |
| | | function resetSetting() { |
| | | proxy.$modal.loading("æ£å¨æ¸
é¤è®¾ç½®ç¼åå¹¶å·æ°ï¼è¯·ç¨å...") |
| | | localStorage.removeItem("layout-setting") |
| | | setTimeout("window.location.reload()", 1000) |
| | | } |
| | | |
| | | function openSetting() { |
| | | showSettings.value = true |
| | | } |
| | | |
| | | defineExpose({ |
| | | openSetting |
| | | }) |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | .setting-drawer-title { |
| | | margin-bottom: 12px; |
| | | color: var(--el-text-color-primary, rgba(0, 0, 0, 0.85)); |
| | | line-height: 22px; |
| | | font-weight: bold; |
| | | |
| | | .drawer-title { |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | |
| | | .setting-drawer-block-checbox { |
| | | display: flex; |
| | | justify-content: flex-start; |
| | | align-items: center; |
| | | margin-top: 10px; |
| | | margin-bottom: 20px; |
| | | |
| | | .setting-drawer-block-checbox-item { |
| | | position: relative; |
| | | margin-right: 16px; |
| | | border-radius: 2px; |
| | | cursor: pointer; |
| | | |
| | | img { |
| | | width: 48px; |
| | | height: 48px; |
| | | } |
| | | |
| | | .setting-drawer-block-checbox-selectIcon { |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | padding-top: 15px; |
| | | padding-left: 24px; |
| | | color: #1890ff; |
| | | font-weight: 700; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .drawer-item { |
| | | color: var(--el-text-color-regular, rgba(0, 0, 0, 0.65)); |
| | | padding: 12px 0; |
| | | font-size: 14px; |
| | | |
| | | .comp-style { |
| | | float: right; |
| | | margin: -3px 8px 0px 0px; |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <component :is="type" v-bind="linkProps()"> |
| | | <slot /> |
| | | </component> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { isExternal } from '@/utils/validate' |
| | | |
| | | const props = defineProps({ |
| | | to: { |
| | | type: [String, Object], |
| | | required: true |
| | | } |
| | | }) |
| | | |
| | | const isExt = computed(() => { |
| | | return isExternal(props.to) |
| | | }) |
| | | |
| | | const type = computed(() => { |
| | | if (isExt.value) { |
| | | return 'a' |
| | | } |
| | | return 'router-link' |
| | | }) |
| | | |
| | | function linkProps() { |
| | | if (isExt.value) { |
| | | return { |
| | | href: props.to, |
| | | target: '_blank', |
| | | rel: 'noopener' |
| | | } |
| | | } |
| | | return { |
| | | to: props.to |
| | | } |
| | | } |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="sidebar-logo-container" :class="{ 'collapse': collapse }"> |
| | | <transition name="sidebarLogoFade"> |
| | | <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/"> |
| | | <img v-if="logo" :src="logo" class="sidebar-logo" /> |
| | | <h1 v-else class="sidebar-title">{{ title }}</h1> |
| | | </router-link> |
| | | <router-link v-else key="expand" class="sidebar-logo-link" to="/"> |
| | | <img v-if="logo" :src="logo" class="sidebar-logo" /> |
| | | <h1 class="sidebar-title">{{ title }}</h1> |
| | | </router-link> |
| | | </transition> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import logo from '@/assets/logo/logo.png' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | import variables from '@/assets/styles/variables.module.scss' |
| | | |
| | | defineProps({ |
| | | collapse: { |
| | | type: Boolean, |
| | | required: true |
| | | } |
| | | }) |
| | | |
| | | const title = import.meta.env.VITE_APP_TITLE |
| | | const settingsStore = useSettingsStore() |
| | | const sideTheme = computed(() => settingsStore.sideTheme) |
| | | |
| | | // è·åLogoèæ¯è² |
| | | const getLogoBackground = computed(() => { |
| | | if (settingsStore.isDark) { |
| | | return 'var(--sidebar-bg)' |
| | | } |
| | | return sideTheme.value === 'theme-dark' ? variables.menuBg : variables.menuLightBg |
| | | }) |
| | | |
| | | // è·åLogoæåé¢è² |
| | | const getLogoTextColor = computed(() => { |
| | | if (settingsStore.isDark) { |
| | | return 'var(--sidebar-text)' |
| | | } |
| | | return sideTheme.value === 'theme-dark' ? '#fff' : variables.menuLightText |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/assets/styles/variables.module.scss'; |
| | | |
| | | .sidebarLogoFade-enter-active { |
| | | transition: opacity 1.5s; |
| | | } |
| | | |
| | | .sidebarLogoFade-enter, |
| | | .sidebarLogoFade-leave-to { |
| | | opacity: 0; |
| | | } |
| | | |
| | | .sidebar-logo-container { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 50px; |
| | | line-height: 50px; |
| | | background: v-bind(getLogoBackground); |
| | | text-align: center; |
| | | overflow: hidden; |
| | | |
| | | & .sidebar-logo-link { |
| | | height: 100%; |
| | | width: 100%; |
| | | |
| | | & .sidebar-logo { |
| | | width: 32px; |
| | | height: 32px; |
| | | vertical-align: middle; |
| | | margin-right: 12px; |
| | | } |
| | | |
| | | & .sidebar-title { |
| | | display: inline-block; |
| | | margin: 0; |
| | | color: v-bind(getLogoTextColor); |
| | | font-weight: 600; |
| | | line-height: 50px; |
| | | font-size: 14px; |
| | | font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif; |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | |
| | | &.collapse { |
| | | .sidebar-logo { |
| | | margin-right: 0px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div v-if="!item.hidden"> |
| | | <template v-if="hasOneShowingChild(item.children, item) && (!onlyOneChild.children || onlyOneChild.noShowingChildren) && !item.alwaysShow"> |
| | | <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)"> |
| | | <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{ 'submenu-title-noDropdown': !isNest }"> |
| | | <svg-icon :icon-class="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"/> |
| | | <template #title><span class="menu-title" :title="hasTitle(onlyOneChild.meta.title)">{{ onlyOneChild.meta.title }}</span></template> |
| | | </el-menu-item> |
| | | </app-link> |
| | | </template> |
| | | |
| | | <el-sub-menu v-else ref="subMenu" :index="resolvePath(item.path)" teleported> |
| | | <template v-if="item.meta" #title> |
| | | <svg-icon :icon-class="item.meta && item.meta.icon" /> |
| | | <span class="menu-title" :title="hasTitle(item.meta.title)">{{ item.meta.title }}</span> |
| | | </template> |
| | | |
| | | <sidebar-item |
| | | v-for="(child, index) in item.children" |
| | | :key="child.path + index" |
| | | :is-nest="true" |
| | | :item="child" |
| | | :base-path="resolvePath(child.path)" |
| | | class="nest-menu" |
| | | /> |
| | | </el-sub-menu> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { isExternal } from '@/utils/validate' |
| | | import AppLink from './Link' |
| | | import { getNormalPath } from '@/utils/ruoyi' |
| | | |
| | | const props = defineProps({ |
| | | // route object |
| | | item: { |
| | | type: Object, |
| | | required: true |
| | | }, |
| | | isNest: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | basePath: { |
| | | type: String, |
| | | default: '' |
| | | } |
| | | }) |
| | | |
| | | const onlyOneChild = ref({}) |
| | | |
| | | function hasOneShowingChild(children = [], parent) { |
| | | if (!children) { |
| | | children = [] |
| | | } |
| | | const showingChildren = children.filter(item => { |
| | | if (item.hidden) { |
| | | return false |
| | | } |
| | | onlyOneChild.value = item |
| | | return true |
| | | }) |
| | | |
| | | // When there is only one child router, the child router is displayed by default |
| | | if (showingChildren.length === 1) { |
| | | return true |
| | | } |
| | | |
| | | // Show parent if there are no child router to display |
| | | if (showingChildren.length === 0) { |
| | | onlyOneChild.value = { ...parent, path: '', noShowingChildren: true } |
| | | return true |
| | | } |
| | | |
| | | return false |
| | | } |
| | | |
| | | function resolvePath(routePath, routeQuery) { |
| | | if (isExternal(routePath)) { |
| | | return routePath |
| | | } |
| | | if (isExternal(props.basePath)) { |
| | | return props.basePath |
| | | } |
| | | if (routeQuery) { |
| | | let query = JSON.parse(routeQuery) |
| | | return { path: getNormalPath(props.basePath + '/' + routePath), query: query } |
| | | } |
| | | return getNormalPath(props.basePath + '/' + routePath) |
| | | } |
| | | |
| | | function hasTitle(title){ |
| | | if (title.length > 5) { |
| | | return title |
| | | } else { |
| | | return "" |
| | | } |
| | | } |
| | | </script> |
| | | <style scoped> |
| | | |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div :class="{ 'has-logo': showLogo }" class="sidebar-container"> |
| | | <!-- <logo v-if="showLogo" :collapse="isCollapse" />--> |
| | | <el-scrollbar wrap-class="scrollbar-wrapper"> |
| | | <el-menu |
| | | :default-active="activeMenu" |
| | | :collapse="true" |
| | | :background-color="getMenuBackground" |
| | | :text-color="getMenuTextColor" |
| | | :unique-opened="true" |
| | | :active-text-color="theme" |
| | | :collapse-transition="false" |
| | | mode="vertical" |
| | | :class="sideTheme" |
| | | > |
| | | <sidebar-item |
| | | v-for="(route, index) in sidebarRouters" |
| | | :key="route.path + index" |
| | | :item="route" |
| | | :base-path="route.path" |
| | | /> |
| | | </el-menu> |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import Logo from './Logo' |
| | | import SidebarItem from './SidebarItem' |
| | | import variables from '@/assets/styles/variables.module.scss' |
| | | import useAppStore from '@/store/modules/app' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | import usePermissionStore from '@/store/modules/permission' |
| | | |
| | | const route = useRoute() |
| | | const appStore = useAppStore() |
| | | const settingsStore = useSettingsStore() |
| | | const permissionStore = usePermissionStore() |
| | | |
| | | const sidebarRouters = computed(() => permissionStore.sidebarRouters) |
| | | const showLogo = computed(() => settingsStore.sidebarLogo) |
| | | const sideTheme = computed(() => settingsStore.sideTheme) |
| | | const theme = computed(() => settingsStore.theme) |
| | | const isCollapse = computed(() => !appStore.sidebar.opened) |
| | | |
| | | // è·åèåèæ¯è² |
| | | const getMenuBackground = computed(() => { |
| | | if (settingsStore.isDark) { |
| | | return 'var(--sidebar-bg)' |
| | | } |
| | | return sideTheme.value === 'theme-dark' ? variables.menuBg : variables.menuLightBg |
| | | }) |
| | | |
| | | // è·åèåæåé¢è² |
| | | const getMenuTextColor = computed(() => { |
| | | if (settingsStore.isDark) { |
| | | return 'var(--sidebar-text)' |
| | | } |
| | | return sideTheme.value === 'theme-dark' ? variables.menuText : variables.menuLightText |
| | | }) |
| | | |
| | | const activeMenu = computed(() => { |
| | | const { meta, path } = route |
| | | if (meta.activeMenu) { |
| | | return meta.activeMenu |
| | | } |
| | | return path |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .sidebar-container { |
| | | background-color: v-bind(getMenuBackground); |
| | | |
| | | .scrollbar-wrapper { |
| | | background-color: v-bind(getMenuBackground); |
| | | } |
| | | |
| | | .el-menu { |
| | | border: none; |
| | | height: 100%; |
| | | width: 100% !important; |
| | | |
| | | .el-menu-item, .el-sub-menu__title { |
| | | &:hover { |
| | | background-color: var(--menu-hover, rgba(0, 0, 0, 0.06)) !important; |
| | | } |
| | | } |
| | | |
| | | .el-menu-item { |
| | | color: v-bind(getMenuTextColor); |
| | | |
| | | &.is-active { |
| | | color: var(--menu-active-text, #409eff); |
| | | background-color: var(--menu-hover, rgba(0, 0, 0, 0.06)) !important; |
| | | } |
| | | } |
| | | |
| | | .el-sub-menu__title { |
| | | color: v-bind(getMenuTextColor); |
| | | } |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-scrollbar |
| | | ref="scrollContainer" |
| | | :vertical="false" |
| | | class="scroll-container" |
| | | @wheel.prevent="handleScroll" |
| | | > |
| | | <slot /> |
| | | </el-scrollbar> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import useTagsViewStore from '@/store/modules/tagsView' |
| | | |
| | | const tagAndTagSpacing = ref(4) |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | const scrollWrapper = computed(() => proxy.$refs.scrollContainer.$refs.wrapRef) |
| | | |
| | | onMounted(() => { |
| | | scrollWrapper.value.addEventListener('scroll', emitScroll, true) |
| | | }) |
| | | |
| | | onBeforeUnmount(() => { |
| | | scrollWrapper.value.removeEventListener('scroll', emitScroll) |
| | | }) |
| | | |
| | | function handleScroll(e) { |
| | | const eventDelta = e.wheelDelta || -e.deltaY * 40 |
| | | const $scrollWrapper = scrollWrapper.value |
| | | $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4 |
| | | } |
| | | |
| | | const emits = defineEmits() |
| | | const emitScroll = () => { |
| | | emits('scroll') |
| | | } |
| | | |
| | | const tagsViewStore = useTagsViewStore() |
| | | const visitedViews = computed(() => tagsViewStore.visitedViews) |
| | | |
| | | function moveToTarget(currentTag) { |
| | | const $container = proxy.$refs.scrollContainer.$el |
| | | const $containerWidth = $container.offsetWidth |
| | | const $scrollWrapper = scrollWrapper.value |
| | | |
| | | let firstTag = null |
| | | let lastTag = null |
| | | |
| | | // find first tag and last tag |
| | | if (visitedViews.value.length > 0) { |
| | | firstTag = visitedViews.value[0] |
| | | lastTag = visitedViews.value[visitedViews.value.length - 1] |
| | | } |
| | | |
| | | if (firstTag === currentTag) { |
| | | $scrollWrapper.scrollLeft = 0 |
| | | } else if (lastTag === currentTag) { |
| | | $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth |
| | | } else { |
| | | const tagListDom = document.getElementsByClassName('tags-view-item') |
| | | const currentIndex = visitedViews.value.findIndex(item => item === currentTag) |
| | | let prevTag = null |
| | | let nextTag = null |
| | | for (const k in tagListDom) { |
| | | if (k !== 'length' && Object.hasOwnProperty.call(tagListDom, k)) { |
| | | if (tagListDom[k].dataset.path === visitedViews.value[currentIndex - 1].path) { |
| | | prevTag = tagListDom[k] |
| | | } |
| | | if (tagListDom[k].dataset.path === visitedViews.value[currentIndex + 1].path) { |
| | | nextTag = tagListDom[k] |
| | | } |
| | | } |
| | | } |
| | | |
| | | // the tag's offsetLeft after of nextTag |
| | | const afterNextTagOffsetLeft = nextTag.offsetLeft + nextTag.offsetWidth + tagAndTagSpacing.value |
| | | |
| | | // the tag's offsetLeft before of prevTag |
| | | const beforePrevTagOffsetLeft = prevTag.offsetLeft - tagAndTagSpacing.value |
| | | if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { |
| | | $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth |
| | | } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) { |
| | | $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft |
| | | } |
| | | } |
| | | } |
| | | |
| | | defineExpose({ |
| | | moveToTarget, |
| | | }) |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | .scroll-container { |
| | | white-space: nowrap; |
| | | position: relative; |
| | | overflow: hidden; |
| | | width: 100%; |
| | | :deep(.el-scrollbar__bar) { |
| | | bottom: 0px; |
| | | } |
| | | :deep(.el-scrollbar__wrap) { |
| | | height: 39px; |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div id="tags-view-container" class="tags-view-container"> |
| | | <scroll-pane ref="scrollPaneRef" class="tags-view-wrapper" @scroll="handleScroll"> |
| | | <router-link |
| | | v-for="tag in visitedViews" |
| | | :key="tag.path" |
| | | :data-path="tag.path" |
| | | :class="isActive(tag) ? 'active' : ''" |
| | | :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }" |
| | | class="tags-view-item" |
| | | :style="activeStyle(tag)" |
| | | @click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''" |
| | | @contextmenu.prevent="openMenu(tag, $event)" |
| | | > |
| | | {{ tag.title }} |
| | | <span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)"> |
| | | <close class="el-icon-close" style="width: 1em; height: 1em;vertical-align: middle;" /> |
| | | </span> |
| | | </router-link> |
| | | </scroll-pane> |
| | | <ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu"> |
| | | <li @click="refreshSelectedTag(selectedTag)"> |
| | | <refresh-right style="width: 1em; height: 1em;" /> å·æ°é¡µé¢ |
| | | </li> |
| | | <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"> |
| | | <close style="width: 1em; height: 1em;" /> å
³éå½å |
| | | </li> |
| | | <li @click="closeOthersTags"> |
| | | <circle-close style="width: 1em; height: 1em;" /> å
³éå
¶ä» |
| | | </li> |
| | | <li v-if="!isFirstView()" @click="closeLeftTags"> |
| | | <back style="width: 1em; height: 1em;" /> å
³é左侧 |
| | | </li> |
| | | <li v-if="!isLastView()" @click="closeRightTags"> |
| | | <right style="width: 1em; height: 1em;" /> å
³éå³ä¾§ |
| | | </li> |
| | | <li @click="closeAllTags(selectedTag)"> |
| | | <circle-close style="width: 1em; height: 1em;" /> å
¨é¨å
³é |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import ScrollPane from './ScrollPane' |
| | | import { getNormalPath } from '@/utils/ruoyi' |
| | | import useTagsViewStore from '@/store/modules/tagsView' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | import usePermissionStore from '@/store/modules/permission' |
| | | |
| | | const visible = ref(false) |
| | | const top = ref(0) |
| | | const left = ref(0) |
| | | const selectedTag = ref({}) |
| | | const affixTags = ref([]) |
| | | const scrollPaneRef = ref(null) |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | |
| | | const visitedViews = computed(() => useTagsViewStore().visitedViews) |
| | | const routes = computed(() => usePermissionStore().routes) |
| | | const theme = computed(() => useSettingsStore().theme) |
| | | |
| | | watch(route, () => { |
| | | addTags() |
| | | moveToCurrentTag() |
| | | }) |
| | | |
| | | watch(visible, (value) => { |
| | | if (value) { |
| | | document.body.addEventListener('click', closeMenu) |
| | | } else { |
| | | document.body.removeEventListener('click', closeMenu) |
| | | } |
| | | }) |
| | | |
| | | onMounted(() => { |
| | | initTags() |
| | | addTags() |
| | | }) |
| | | |
| | | function isActive(r) { |
| | | return r.path === route.path |
| | | } |
| | | |
| | | function activeStyle(tag) { |
| | | if (!isActive(tag)) return {} |
| | | return { |
| | | "background-color": theme.value, |
| | | "border-color": theme.value |
| | | } |
| | | } |
| | | |
| | | function isAffix(tag) { |
| | | return tag.meta && tag.meta.affix |
| | | } |
| | | |
| | | function isFirstView() { |
| | | try { |
| | | return selectedTag.value.fullPath === '/index' || selectedTag.value.fullPath === visitedViews.value[1].fullPath |
| | | } catch (err) { |
| | | return false |
| | | } |
| | | } |
| | | |
| | | function isLastView() { |
| | | try { |
| | | return selectedTag.value.fullPath === visitedViews.value[visitedViews.value.length - 1].fullPath |
| | | } catch (err) { |
| | | return false |
| | | } |
| | | } |
| | | |
| | | function filterAffixTags(routes, basePath = '') { |
| | | let tags = [] |
| | | routes.forEach(route => { |
| | | if (route.meta && route.meta.affix) { |
| | | const tagPath = getNormalPath(basePath + '/' + route.path) |
| | | tags.push({ |
| | | fullPath: tagPath, |
| | | path: tagPath, |
| | | name: route.name, |
| | | meta: { ...route.meta } |
| | | }) |
| | | } |
| | | if (route.children) { |
| | | const tempTags = filterAffixTags(route.children, route.path) |
| | | if (tempTags.length >= 1) { |
| | | tags = [...tags, ...tempTags] |
| | | } |
| | | } |
| | | }) |
| | | return tags |
| | | } |
| | | |
| | | function initTags() { |
| | | const res = filterAffixTags(routes.value) |
| | | affixTags.value = res |
| | | for (const tag of res) { |
| | | // Must have tag name |
| | | if (tag.name) { |
| | | useTagsViewStore().addVisitedView(tag) |
| | | } |
| | | } |
| | | } |
| | | |
| | | function addTags() { |
| | | const { name } = route |
| | | if (name) { |
| | | useTagsViewStore().addView(route) |
| | | } |
| | | } |
| | | |
| | | function moveToCurrentTag() { |
| | | nextTick(() => { |
| | | for (const r of visitedViews.value) { |
| | | if (r.path === route.path) { |
| | | scrollPaneRef.value.moveToTarget(r) |
| | | // when query is different then update |
| | | if (r.fullPath !== route.fullPath) { |
| | | useTagsViewStore().updateVisitedView(route) |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | function refreshSelectedTag(view) { |
| | | proxy.$tab.refreshPage(view) |
| | | if (route.meta.link) { |
| | | useTagsViewStore().delIframeView(route) |
| | | } |
| | | } |
| | | |
| | | function closeSelectedTag(view) { |
| | | proxy.$tab.closePage(view).then(({ visitedViews }) => { |
| | | if (isActive(view)) { |
| | | toLastView(visitedViews, view) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | function closeRightTags() { |
| | | proxy.$tab.closeRightPage(selectedTag.value).then(visitedViews => { |
| | | if (!visitedViews.find(i => i.fullPath === route.fullPath)) { |
| | | toLastView(visitedViews) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | function closeLeftTags() { |
| | | proxy.$tab.closeLeftPage(selectedTag.value).then(visitedViews => { |
| | | if (!visitedViews.find(i => i.fullPath === route.fullPath)) { |
| | | toLastView(visitedViews) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | function closeOthersTags() { |
| | | router.push(selectedTag.value).catch(() => { }) |
| | | proxy.$tab.closeOtherPage(selectedTag.value).then(() => { |
| | | moveToCurrentTag() |
| | | }) |
| | | } |
| | | |
| | | function closeAllTags(view) { |
| | | proxy.$tab.closeAllPage().then(({ visitedViews }) => { |
| | | if (affixTags.value.some(tag => tag.path === route.path)) { |
| | | return |
| | | } |
| | | toLastView(visitedViews, view) |
| | | }) |
| | | } |
| | | |
| | | function toLastView(visitedViews, view) { |
| | | const latestView = visitedViews.slice(-1)[0] |
| | | if (latestView) { |
| | | router.push(latestView.fullPath) |
| | | } else { |
| | | // now the default is to redirect to the home page if there is no tags-view, |
| | | // you can adjust it according to your needs. |
| | | if (view.name === 'Dashboard') { |
| | | // to reload home page |
| | | router.replace({ path: '/redirect' + view.fullPath }) |
| | | } else { |
| | | router.push('/') |
| | | } |
| | | } |
| | | } |
| | | |
| | | function openMenu(tag, e) { |
| | | const menuMinWidth = 105 |
| | | const offsetLeft = proxy.$el.getBoundingClientRect().left // container margin left |
| | | const offsetWidth = proxy.$el.offsetWidth // container width |
| | | const maxLeft = offsetWidth - menuMinWidth // left boundary |
| | | const l = e.clientX - offsetLeft + 15 // 15: margin right |
| | | |
| | | if (l > maxLeft) { |
| | | left.value = maxLeft |
| | | } else { |
| | | left.value = l |
| | | } |
| | | |
| | | top.value = e.clientY |
| | | visible.value = true |
| | | selectedTag.value = tag |
| | | } |
| | | |
| | | function closeMenu() { |
| | | visible.value = false |
| | | } |
| | | |
| | | function handleScroll() { |
| | | closeMenu() |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .tags-view-container { |
| | | height: 30px; |
| | | width: 100%; |
| | | position: fixed; /* å°å¤´é¨åºå® */ |
| | | top: 50px; /* å¨é¡¶é¨åºå® */ |
| | | z-index: 1000; /* ç¡®ä¿å¤´é¨å¨å
¶ä»å
容ä¹ä¸ */ |
| | | background: #fff; |
| | | box-shadow: none; |
| | | |
| | | .tags-view-wrapper { |
| | | .tags-view-item { |
| | | display: inline-block; |
| | | position: relative; |
| | | cursor: pointer; |
| | | height: 26px; |
| | | line-height: 26px; |
| | | border: 1px solid var(--tags-item-border, #d8dce5); |
| | | color: var(--tags-item-text, #495060); |
| | | background: var(--tags-item-bg, #fff); |
| | | padding: 0 8px; |
| | | font-size: 12px; |
| | | margin-left: 5px; |
| | | margin-top: 4px; |
| | | |
| | | &:first-of-type { |
| | | margin-left: 15px; |
| | | } |
| | | |
| | | &:last-of-type { |
| | | margin-right: 15px; |
| | | } |
| | | |
| | | &.active { |
| | | background-color: #42b983; |
| | | color: #fff; |
| | | border-color: #42b983; |
| | | |
| | | &::before { |
| | | content: ''; |
| | | background: #fff; |
| | | display: inline-block; |
| | | width: 8px; |
| | | height: 8px; |
| | | border-radius: 50%; |
| | | position: relative; |
| | | margin-right: 5px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .contextmenu { |
| | | margin: 0; |
| | | background: var(--el-bg-color-overlay, #fff); |
| | | z-index: 3000; |
| | | position: absolute; |
| | | list-style-type: none; |
| | | padding: 5px 0; |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | font-weight: 400; |
| | | color: var(--tags-item-text, #333); |
| | | box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3); |
| | | border: 1px solid var(--el-border-color-light, #e4e7ed); |
| | | |
| | | li { |
| | | margin: 0; |
| | | padding: 7px 16px; |
| | | cursor: pointer; |
| | | |
| | | &:hover { |
| | | background: var(--tags-item-hover, #eee); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | <style lang="scss"> |
| | | //reset element css of el-icon-close |
| | | .tags-view-wrapper { |
| | | .tags-view-item { |
| | | .el-icon-close { |
| | | width: 16px; |
| | | height: 16px; |
| | | vertical-align: 2px; |
| | | border-radius: 50%; |
| | | text-align: center; |
| | | transition: all .3s cubic-bezier(.645, .045, .355, 1); |
| | | transform-origin: 100% 50%; |
| | | |
| | | &:before { |
| | | transform: scale(.6); |
| | | display: inline-block; |
| | | vertical-align: -3px; |
| | | } |
| | | |
| | | &:hover { |
| | | background-color: var(--tags-close-hover, #b4bccc); |
| | | color: #fff; |
| | | width: 12px !important; |
| | | height: 12px !important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export { default as AppMain } from './AppMain' |
| | | export { default as Navbar } from './Navbar' |
| | | export { default as Settings } from './Settings' |
| | | export { default as TagsView } from './TagsView/index.vue' |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }"> |
| | | <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside"/> |
| | | <navbar @setLayout="setLayout" /> |
| | | <sidebar v-if="!sidebar.hide" class="sidebar-container" /> |
| | | <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container"> |
| | | <div :class="{ 'fixed-header': fixedHeader }"> |
| | | <tags-view v-if="needTagsView" /> |
| | | </div> |
| | | <app-main /> |
| | | <settings ref="settingRef" /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useWindowSize } from '@vueuse/core' |
| | | import Sidebar from './components/Sidebar/index.vue' |
| | | import { AppMain, Navbar, Settings, TagsView } from './components' |
| | | import useAppStore from '@/store/modules/app' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | |
| | | const settingsStore = useSettingsStore() |
| | | const theme = computed(() => settingsStore.theme) |
| | | const sideTheme = computed(() => settingsStore.sideTheme) |
| | | const sidebar = computed(() => useAppStore().sidebar) |
| | | const device = computed(() => useAppStore().device) |
| | | const needTagsView = computed(() => settingsStore.tagsView) |
| | | const fixedHeader = computed(() => settingsStore.fixedHeader) |
| | | |
| | | const classObj = computed(() => ({ |
| | | hideSidebar: !sidebar.value.opened, |
| | | openSidebar: sidebar.value.opened, |
| | | withoutAnimation: sidebar.value.withoutAnimation, |
| | | mobile: device.value === 'mobile' |
| | | })) |
| | | |
| | | const { width, height } = useWindowSize() |
| | | const WIDTH = 992 // refer to Bootstrap's responsive design |
| | | |
| | | watch(() => device.value, () => { |
| | | if (device.value === 'mobile' && sidebar.value.opened) { |
| | | useAppStore().closeSideBar({ withoutAnimation: false }) |
| | | } |
| | | }) |
| | | |
| | | watchEffect(() => { |
| | | if (width.value - 1 < WIDTH) { |
| | | useAppStore().toggleDevice('mobile') |
| | | useAppStore().closeSideBar({ withoutAnimation: true }) |
| | | } else { |
| | | useAppStore().toggleDevice('desktop') |
| | | } |
| | | }) |
| | | |
| | | function handleClickOutside() { |
| | | useAppStore().closeSideBar({ withoutAnimation: false }) |
| | | } |
| | | |
| | | const settingRef = ref(null) |
| | | function setLayout() { |
| | | settingRef.value.openSetting() |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import "@/assets/styles/mixin.scss"; |
| | | @import "@/assets/styles/variables.module.scss"; |
| | | |
| | | .app-wrapper { |
| | | @include clearfix; |
| | | position: relative; |
| | | height: 100%; |
| | | width: 100%; |
| | | |
| | | &.mobile.openSidebar { |
| | | position: fixed; |
| | | top: 0; |
| | | } |
| | | } |
| | | |
| | | .drawer-bg { |
| | | background: #000; |
| | | opacity: 0.3; |
| | | width: 100%; |
| | | top: 0; |
| | | height: 100%; |
| | | position: absolute; |
| | | z-index: 999; |
| | | } |
| | | |
| | | .fixed-header { |
| | | position: fixed; |
| | | top: 0; |
| | | right: 0; |
| | | z-index: 9; |
| | | width: calc(100% - #{$base-sidebar-width}); |
| | | transition: width 0.28s; |
| | | } |
| | | |
| | | .hideSidebar .fixed-header { |
| | | width: calc(100% - 54px); |
| | | } |
| | | |
| | | .sidebarHide .fixed-header { |
| | | width: 100%; |
| | | } |
| | | |
| | | .mobile .fixed-header { |
| | | width: 100%; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { createApp } from 'vue' |
| | | |
| | | import Cookies from 'js-cookie' |
| | | |
| | | import ElementPlus from 'element-plus' |
| | | import 'element-plus/dist/index.css' |
| | | import 'element-plus/theme-chalk/dark/css-vars.css' |
| | | import locale from 'element-plus/es/locale/lang/zh-cn' |
| | | |
| | | import '@/assets/styles/index.scss' // global css |
| | | |
| | | import App from './App' |
| | | import store from './store' |
| | | import router from './router' |
| | | import directive from './directive' // directive |
| | | |
| | | // 注åæä»¤ |
| | | import plugins from './plugins' // plugins |
| | | import { download } from '@/utils/request' |
| | | |
| | | // svg徿 |
| | | import 'virtual:svg-icons-register' |
| | | import SvgIcon from '@/components/SvgIcon' |
| | | import elementIcons from '@/components/SvgIcon/svgicon' |
| | | |
| | | import './permission' // permission control |
| | | |
| | | import { useDict } from '@/utils/dict' |
| | | import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi' |
| | | |
| | | // å页ç»ä»¶ |
| | | import Pagination from '@/components/Pagination' |
| | | // èªå®ä¹è¡¨æ ¼å·¥å
·ç»ä»¶ |
| | | import RightToolbar from '@/components/RightToolbar' |
| | | // 坿æ¬ç»ä»¶ |
| | | import Editor from "@/components/Editor" |
| | | // æä»¶ä¸ä¼ ç»ä»¶ |
| | | import FileUpload from "@/components/FileUpload" |
| | | // å¾çä¸ä¼ ç»ä»¶ |
| | | import ImageUpload from "@/components/ImageUpload" |
| | | // å¾çé¢è§ç»ä»¶ |
| | | import ImagePreview from "@/components/ImagePreview" |
| | | // åå
¸æ ç¾ç»ä»¶ |
| | | import DictTag from '@/components/DictTag' |
| | | |
| | | const app = createApp(App) |
| | | |
| | | // å
¨å±æ¹æ³æè½½ |
| | | app.config.globalProperties.useDict = useDict |
| | | app.config.globalProperties.download = download |
| | | app.config.globalProperties.parseTime = parseTime |
| | | app.config.globalProperties.resetForm = resetForm |
| | | app.config.globalProperties.handleTree = handleTree |
| | | app.config.globalProperties.addDateRange = addDateRange |
| | | app.config.globalProperties.selectDictLabel = selectDictLabel |
| | | app.config.globalProperties.selectDictLabels = selectDictLabels |
| | | |
| | | // å
¨å±ç»ä»¶æè½½ |
| | | app.component('DictTag', DictTag) |
| | | app.component('Pagination', Pagination) |
| | | app.component('FileUpload', FileUpload) |
| | | app.component('ImageUpload', ImageUpload) |
| | | app.component('ImagePreview', ImagePreview) |
| | | app.component('RightToolbar', RightToolbar) |
| | | app.component('Editor', Editor) |
| | | |
| | | app.use(router) |
| | | app.use(store) |
| | | app.use(plugins) |
| | | app.use(elementIcons) |
| | | app.component('svg-icon', SvgIcon) |
| | | |
| | | directive(app) |
| | | |
| | | // 使ç¨element-plus å¹¶ä¸è®¾ç½®å
¨å±çå¤§å° |
| | | app.use(ElementPlus, { |
| | | locale: locale, |
| | | // æ¯æ largeãdefaultãsmall |
| | | size: Cookies.get('size') || 'default' |
| | | }) |
| | | |
| | | app.mount('#app') |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import router from './router' |
| | | import { ElMessage } from 'element-plus' |
| | | import NProgress from 'nprogress' |
| | | import 'nprogress/nprogress.css' |
| | | import { getToken } from '@/utils/auth' |
| | | import { isHttp, isPathMatch } from '@/utils/validate' |
| | | import { isRelogin } from '@/utils/request' |
| | | import useUserStore from '@/store/modules/user' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | import usePermissionStore from '@/store/modules/permission' |
| | | |
| | | NProgress.configure({ showSpinner: false }) |
| | | |
| | | const whiteList = ['/login', '/register'] |
| | | |
| | | const isWhiteList = (path) => { |
| | | return whiteList.some(pattern => isPathMatch(pattern, path)) |
| | | } |
| | | |
| | | router.beforeEach((to, from, next) => { |
| | | NProgress.start() |
| | | if (getToken()) { |
| | | to.meta.title && useSettingsStore().setTitle(to.meta.title) |
| | | /* has token*/ |
| | | if (to.path === '/login') { |
| | | next({ path: '/' }) |
| | | NProgress.done() |
| | | } else if (isWhiteList(to.path)) { |
| | | next() |
| | | } else { |
| | | if (useUserStore().roles.length === 0) { |
| | | isRelogin.show = true |
| | | // 夿å½åç¨æ·æ¯å¦å·²æåå®user_infoä¿¡æ¯ |
| | | useUserStore().getInfo().then(() => { |
| | | isRelogin.show = false |
| | | usePermissionStore().generateRoutes().then(accessRoutes => { |
| | | // æ ¹æ®rolesæéçæå¯è®¿é®çè·¯ç±è¡¨ |
| | | accessRoutes.forEach(route => { |
| | | if (!isHttp(route.path)) { |
| | | router.addRoute(route) // å¨ææ·»å å¯è®¿é®è·¯ç±è¡¨ |
| | | } |
| | | }) |
| | | next({ ...to, replace: true }) // hackæ¹æ³ ç¡®ä¿addRoutes已宿 |
| | | }) |
| | | }).catch(err => { |
| | | useUserStore().logOut().then(() => { |
| | | ElMessage.error(err) |
| | | next({ path: '/' }) |
| | | }) |
| | | }) |
| | | } else { |
| | | next() |
| | | } |
| | | } |
| | | } else { |
| | | // 没ætoken |
| | | if (isWhiteList(to.path)) { |
| | | // å¨å
ç»å½ç½ååï¼ç´æ¥è¿å
¥ |
| | | next() |
| | | } else { |
| | | next(`/login?redirect=${to.fullPath}`) // å¦åå
¨é¨éå®åå°ç»å½é¡µ |
| | | NProgress.done() |
| | | } |
| | | } |
| | | }) |
| | | |
| | | router.afterEach(() => { |
| | | NProgress.done() |
| | | }) |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import useUserStore from '@/store/modules/user' |
| | | |
| | | function authPermission(permission) { |
| | | const all_permission = "*:*:*" |
| | | const permissions = useUserStore().permissions |
| | | if (permission && permission.length > 0) { |
| | | return permissions.some(v => { |
| | | return all_permission === v || v === permission |
| | | }) |
| | | } else { |
| | | return false |
| | | } |
| | | } |
| | | |
| | | function authRole(role) { |
| | | const super_admin = "admin" |
| | | const roles = useUserStore().roles |
| | | if (role && role.length > 0) { |
| | | return roles.some(v => { |
| | | return super_admin === v || v === role |
| | | }) |
| | | } else { |
| | | return false |
| | | } |
| | | } |
| | | |
| | | export default { |
| | | // éªè¯ç¨æ·æ¯å¦å
·å¤ææé |
| | | hasPermi(permission) { |
| | | return authPermission(permission) |
| | | }, |
| | | // éªè¯ç¨æ·æ¯å¦å«ææå®æéï¼åªéå
å«å
¶ä¸ä¸ä¸ª |
| | | hasPermiOr(permissions) { |
| | | return permissions.some(item => { |
| | | return authPermission(item) |
| | | }) |
| | | }, |
| | | // éªè¯ç¨æ·æ¯å¦å«ææå®æéï¼å¿
é¡»å
¨é¨æ¥æ |
| | | hasPermiAnd(permissions) { |
| | | return permissions.every(item => { |
| | | return authPermission(item) |
| | | }) |
| | | }, |
| | | // éªè¯ç¨æ·æ¯å¦å
·å¤æè§è² |
| | | hasRole(role) { |
| | | return authRole(role) |
| | | }, |
| | | // éªè¯ç¨æ·æ¯å¦å«ææå®è§è²ï¼åªéå
å«å
¶ä¸ä¸ä¸ª |
| | | hasRoleOr(roles) { |
| | | return roles.some(item => { |
| | | return authRole(item) |
| | | }) |
| | | }, |
| | | // éªè¯ç¨æ·æ¯å¦å«ææå®è§è²ï¼å¿
é¡»å
¨é¨æ¥æ |
| | | hasRoleAnd(roles) { |
| | | return roles.every(item => { |
| | | return authRole(item) |
| | | }) |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | const sessionCache = { |
| | | set (key, value) { |
| | | if (!sessionStorage) { |
| | | return |
| | | } |
| | | if (key != null && value != null) { |
| | | sessionStorage.setItem(key, value) |
| | | } |
| | | }, |
| | | get (key) { |
| | | if (!sessionStorage) { |
| | | return null |
| | | } |
| | | if (key == null) { |
| | | return null |
| | | } |
| | | return sessionStorage.getItem(key) |
| | | }, |
| | | setJSON (key, jsonValue) { |
| | | if (jsonValue != null) { |
| | | this.set(key, JSON.stringify(jsonValue)) |
| | | } |
| | | }, |
| | | getJSON (key) { |
| | | const value = this.get(key) |
| | | if (value != null) { |
| | | return JSON.parse(value) |
| | | } |
| | | return null |
| | | }, |
| | | remove (key) { |
| | | sessionStorage.removeItem(key) |
| | | } |
| | | } |
| | | const localCache = { |
| | | set (key, value) { |
| | | if (!localStorage) { |
| | | return |
| | | } |
| | | if (key != null && value != null) { |
| | | localStorage.setItem(key, value) |
| | | } |
| | | }, |
| | | get (key) { |
| | | if (!localStorage) { |
| | | return null |
| | | } |
| | | if (key == null) { |
| | | return null |
| | | } |
| | | return localStorage.getItem(key) |
| | | }, |
| | | setJSON (key, jsonValue) { |
| | | if (jsonValue != null) { |
| | | this.set(key, JSON.stringify(jsonValue)) |
| | | } |
| | | }, |
| | | getJSON (key) { |
| | | const value = this.get(key) |
| | | if (value != null) { |
| | | return JSON.parse(value) |
| | | } |
| | | return null |
| | | }, |
| | | remove (key) { |
| | | localStorage.removeItem(key) |
| | | } |
| | | } |
| | | |
| | | export default { |
| | | /** |
| | | * ä¼è¯çº§ç¼å |
| | | */ |
| | | session: sessionCache, |
| | | /** |
| | | * æ¬å°ç¼å |
| | | */ |
| | | local: localCache |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import axios from 'axios' |
| | | import { ElLoading, ElMessage } from 'element-plus' |
| | | import { saveAs } from 'file-saver' |
| | | import { getToken } from '@/utils/auth' |
| | | import errorCode from '@/utils/errorCode' |
| | | import { blobValidate } from '@/utils/ruoyi' |
| | | |
| | | const baseURL = import.meta.env.VITE_APP_BASE_API |
| | | let downloadLoadingInstance |
| | | |
| | | export default { |
| | | name(name, isDelete = true) { |
| | | var url = baseURL + "/common/download?fileName=" + encodeURIComponent(name) + "&delete=" + isDelete |
| | | axios({ |
| | | method: 'get', |
| | | url: url, |
| | | responseType: 'blob', |
| | | headers: { 'Authorization': 'Bearer ' + getToken() } |
| | | }).then((res) => { |
| | | const isBlob = blobValidate(res.data) |
| | | if (isBlob) { |
| | | const blob = new Blob([res.data]) |
| | | this.saveAs(blob, decodeURIComponent(res.headers['download-filename'])) |
| | | } else { |
| | | this.printErrMsg(res.data) |
| | | } |
| | | }) |
| | | }, |
| | | resource(resource) { |
| | | var url = baseURL + "/common/download/resource?resource=" + encodeURIComponent(resource) |
| | | axios({ |
| | | method: 'get', |
| | | url: url, |
| | | responseType: 'blob', |
| | | headers: { 'Authorization': 'Bearer ' + getToken() } |
| | | }).then((res) => { |
| | | const isBlob = blobValidate(res.data) |
| | | if (isBlob) { |
| | | const blob = new Blob([res.data]) |
| | | this.saveAs(blob, decodeURIComponent(res.headers['download-filename'])) |
| | | } else { |
| | | this.printErrMsg(res.data) |
| | | } |
| | | }) |
| | | }, |
| | | zip(url, name) { |
| | | var url = baseURL + url |
| | | downloadLoadingInstance = ElLoading.service({ text: "æ£å¨ä¸è½½æ°æ®ï¼è¯·ç¨å", background: "rgba(0, 0, 0, 0.7)", }) |
| | | axios({ |
| | | method: 'get', |
| | | url: url, |
| | | responseType: 'blob', |
| | | headers: { 'Authorization': 'Bearer ' + getToken() } |
| | | }).then((res) => { |
| | | const isBlob = blobValidate(res.data) |
| | | if (isBlob) { |
| | | const blob = new Blob([res.data], { type: 'application/zip' }) |
| | | this.saveAs(blob, name) |
| | | } else { |
| | | this.printErrMsg(res.data) |
| | | } |
| | | downloadLoadingInstance.close() |
| | | }).catch((r) => { |
| | | console.error(r) |
| | | ElMessage.error('ä¸è½½æä»¶åºç°é误ï¼è¯·è系管çåï¼') |
| | | downloadLoadingInstance.close() |
| | | }) |
| | | }, |
| | | saveAs(text, name, opts) { |
| | | saveAs(text, name, opts) |
| | | }, |
| | | async printErrMsg(data) { |
| | | const resText = await data.text() |
| | | const rspObj = JSON.parse(resText) |
| | | const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] |
| | | ElMessage.error(errMsg) |
| | | } |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import tab from './tab' |
| | | import auth from './auth' |
| | | import cache from './cache' |
| | | import modal from './modal' |
| | | import download from './download' |
| | | |
| | | export default function installPlugins(app){ |
| | | // é¡µç¾æä½ |
| | | app.config.globalProperties.$tab = tab |
| | | // 认è¯å¯¹è±¡ |
| | | app.config.globalProperties.$auth = auth |
| | | // ç¼å对象 |
| | | app.config.globalProperties.$cache = cache |
| | | // æ¨¡ææ¡å¯¹è±¡ |
| | | app.config.globalProperties.$modal = modal |
| | | // ä¸è½½æä»¶ |
| | | app.config.globalProperties.$download = download |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { ElMessage, ElMessageBox, ElNotification, ElLoading } from 'element-plus' |
| | | |
| | | let loadingInstance |
| | | |
| | | export default { |
| | | // æ¶æ¯æç¤º |
| | | msg(content) { |
| | | ElMessage.info(content) |
| | | }, |
| | | // éè¯¯æ¶æ¯ |
| | | msgError(content) { |
| | | ElMessage.error(content) |
| | | }, |
| | | // æåæ¶æ¯ |
| | | msgSuccess(content) { |
| | | ElMessage.success(content) |
| | | }, |
| | | // è¦åæ¶æ¯ |
| | | msgWarning(content) { |
| | | ElMessage.warning(content) |
| | | }, |
| | | // å¼¹åºæç¤º |
| | | alert(content) { |
| | | ElMessageBox.alert(content, "ç³»ç»æç¤º") |
| | | }, |
| | | // é误æç¤º |
| | | alertError(content) { |
| | | ElMessageBox.alert(content, "ç³»ç»æç¤º", { type: 'error' }) |
| | | }, |
| | | // æåæç¤º |
| | | alertSuccess(content) { |
| | | ElMessageBox.alert(content, "ç³»ç»æç¤º", { type: 'success' }) |
| | | }, |
| | | // è¦åæç¤º |
| | | alertWarning(content) { |
| | | ElMessageBox.alert(content, "ç³»ç»æç¤º", { type: 'warning' }) |
| | | }, |
| | | // éç¥æç¤º |
| | | notify(content) { |
| | | ElNotification.info(content) |
| | | }, |
| | | // é误éç¥ |
| | | notifyError(content) { |
| | | ElNotification.error(content) |
| | | }, |
| | | // æåéç¥ |
| | | notifySuccess(content) { |
| | | ElNotification.success(content) |
| | | }, |
| | | // è¦åéç¥ |
| | | notifyWarning(content) { |
| | | ElNotification.warning(content) |
| | | }, |
| | | // 确认çªä½ |
| | | confirm(content) { |
| | | return ElMessageBox.confirm(content, "ç³»ç»æç¤º", { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: "warning", |
| | | }) |
| | | }, |
| | | // æäº¤å
容 |
| | | prompt(content) { |
| | | return ElMessageBox.prompt(content, "ç³»ç»æç¤º", { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | type: "warning", |
| | | }) |
| | | }, |
| | | // æå¼é®ç½©å± |
| | | loading(content) { |
| | | loadingInstance = ElLoading.service({ |
| | | lock: true, |
| | | text: content, |
| | | background: "rgba(0, 0, 0, 0.7)", |
| | | }) |
| | | }, |
| | | // å
³éé®ç½©å± |
| | | closeLoading() { |
| | | loadingInstance.close() |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import useTagsViewStore from '@/store/modules/tagsView' |
| | | import router from '@/router' |
| | | |
| | | export default { |
| | | // å·æ°å½åtabé¡µç¾ |
| | | refreshPage(obj) { |
| | | const { path, query, matched } = router.currentRoute.value |
| | | if (obj === undefined) { |
| | | matched.forEach((m) => { |
| | | if (m.components && m.components.default && m.components.default.name) { |
| | | if (!['Layout', 'ParentView'].includes(m.components.default.name)) { |
| | | obj = { name: m.components.default.name, path: path, query: query } |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | return useTagsViewStore().delCachedView(obj).then(() => { |
| | | const { path, query } = obj |
| | | router.replace({ |
| | | path: '/redirect' + path, |
| | | query: query |
| | | }) |
| | | }) |
| | | }, |
| | | // å
³éå½åtab页ç¾ï¼æå¼æ°é¡µç¾ |
| | | closeOpenPage(obj) { |
| | | useTagsViewStore().delView(router.currentRoute.value) |
| | | if (obj !== undefined) { |
| | | return router.push(obj) |
| | | } |
| | | }, |
| | | // å
³éæå®tabé¡µç¾ |
| | | closePage(obj) { |
| | | if (obj === undefined) { |
| | | return useTagsViewStore().delView(router.currentRoute.value).then(({ visitedViews }) => { |
| | | const latestView = visitedViews.slice(-1)[0] |
| | | if (latestView) { |
| | | return router.push(latestView.fullPath) |
| | | } |
| | | return router.push('/') |
| | | }) |
| | | } |
| | | return useTagsViewStore().delView(obj) |
| | | }, |
| | | // å
³éæætabé¡µç¾ |
| | | closeAllPage() { |
| | | return useTagsViewStore().delAllViews() |
| | | }, |
| | | // å
³é左侧tabé¡µç¾ |
| | | closeLeftPage(obj) { |
| | | return useTagsViewStore().delLeftTags(obj || router.currentRoute.value) |
| | | }, |
| | | // å
³éå³ä¾§tabé¡µç¾ |
| | | closeRightPage(obj) { |
| | | return useTagsViewStore().delRightTags(obj || router.currentRoute.value) |
| | | }, |
| | | // å
³éå
¶ä»tabé¡µç¾ |
| | | closeOtherPage(obj) { |
| | | return useTagsViewStore().delOthersViews(obj || router.currentRoute.value) |
| | | }, |
| | | // æå¼tabé¡µç¾ |
| | | openPage(title, url, params) { |
| | | const obj = { path: url, meta: { title: title } } |
| | | useTagsViewStore().addView(obj) |
| | | return router.push({ path: url, query: params }) |
| | | }, |
| | | // ä¿®æ¹tabé¡µç¾ |
| | | updatePage(obj) { |
| | | return useTagsViewStore().updateVisitedView(obj) |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { createWebHistory, createRouter } from 'vue-router' |
| | | /* Layout */ |
| | | import Layout from '@/layout' |
| | | |
| | | /** |
| | | * Note: è·¯ç±é
置项 |
| | | * |
| | | * hidden: true // å½è®¾ç½® true çæ¶å该路ç±ä¸ä¼åä¾§è¾¹æ åºç° å¦401ï¼loginç页é¢ï¼æè
å¦ä¸äºç¼è¾é¡µé¢/edit/1 |
| | | * alwaysShow: true // å½ä½ ä¸ä¸ªè·¯ç±ä¸é¢ç children 声æçè·¯ç±å¤§äº1个æ¶ï¼èªå¨ä¼åæåµå¥ç模å¼--å¦ç»ä»¶é¡µé¢ |
| | | * // åªæä¸ä¸ªæ¶ï¼ä¼å°é£ä¸ªåè·¯ç±å½åæ ¹è·¯ç±æ¾ç¤ºå¨ä¾§è¾¹æ --å¦å¼å¯¼é¡µé¢ |
| | | * // è¥ä½ æ³ä¸ç®¡è·¯ç±ä¸é¢ç children 声æç个æ°é½æ¾ç¤ºä½ çæ ¹è·¯ç± |
| | | * // ä½ å¯ä»¥è®¾ç½® alwaysShow: trueï¼è¿æ ·å®å°±ä¼å¿½ç¥ä¹åå®ä¹çè§åï¼ä¸ç´æ¾ç¤ºæ ¹è·¯ç± |
| | | * redirect: noRedirect // å½è®¾ç½® noRedirect çæ¶å该路ç±å¨é¢å
å±å¯¼èªä¸ä¸å¯è¢«ç¹å» |
| | | * name:'router-name' // 设å®è·¯ç±çååï¼ä¸å®è¦å¡«åä¸ç¶ä½¿ç¨<keep-alive>æ¶ä¼åºç°åç§é®é¢ |
| | | * query: '{"id": 1, "name": "ry"}' // 访é®è·¯ç±çé»è®¤ä¼ éåæ° |
| | | * roles: ['admin', 'common'] // 访é®è·¯ç±çè§è²æé |
| | | * permissions: ['a:a:a', 'b:b:b'] // 访é®è·¯ç±çèåæé |
| | | * meta : { |
| | | noCache: true // å¦æè®¾ç½®ä¸ºtrueï¼åä¸ä¼è¢« <keep-alive> ç¼å(é»è®¤ false) |
| | | title: 'title' // 设置该路ç±å¨ä¾§è¾¹æ åé¢å
å±ä¸å±ç¤ºçåå |
| | | icon: 'svg-name' // 设置该路ç±ç徿 ï¼å¯¹åºè·¯å¾src/assets/icons/svg |
| | | breadcrumb: false // å¦æè®¾ç½®ä¸ºfalseï¼åä¸ä¼å¨breadcrumbé¢å
å±ä¸æ¾ç¤º |
| | | activeMenu: '/system/user' // å½è·¯ç±è®¾ç½®äºè¯¥å±æ§ï¼åä¼é«äº®ç¸å¯¹åºçä¾§è¾¹æ ã |
| | | } |
| | | */ |
| | | |
| | | // å
Œ
±è·¯ç± |
| | | export const constantRoutes = [ |
| | | { |
| | | path: '/redirect', |
| | | component: Layout, |
| | | hidden: true, |
| | | children: [ |
| | | { |
| | | path: '/redirect/:path(.*)', |
| | | component: () => import('@/views/redirect/index.vue') |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/login', |
| | | component: () => import('@/views/login'), |
| | | hidden: true |
| | | }, |
| | | { |
| | | path: '/register', |
| | | component: () => import('@/views/register'), |
| | | hidden: true |
| | | }, |
| | | { |
| | | path: "/:pathMatch(.*)*", |
| | | component: () => import('@/views/error/404'), |
| | | hidden: true |
| | | }, |
| | | { |
| | | path: '/401', |
| | | component: () => import('@/views/error/401'), |
| | | hidden: true |
| | | }, |
| | | { |
| | | path: '', |
| | | component: Layout, |
| | | redirect: '/index', |
| | | children: [ |
| | | { |
| | | path: '/index', |
| | | component: () => import('@/views/index'), |
| | | name: 'Index', |
| | | meta: { title: 'é¦é¡µ', icon: 'dashboard', affix: true } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/user', |
| | | component: Layout, |
| | | hidden: true, |
| | | redirect: 'noredirect', |
| | | children: [ |
| | | { |
| | | path: 'profile', |
| | | component: () => import('@/views/system/user/profile/index'), |
| | | name: 'Profile', |
| | | meta: { title: '个人ä¸å¿', icon: 'user' } |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | |
| | | // å¨æè·¯ç±ï¼åºäºç¨æ·æé卿å»å è½½ |
| | | export const dynamicRoutes = [ |
| | | { |
| | | path: '/system/user-auth', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:user:edit'], |
| | | children: [ |
| | | { |
| | | path: 'role/:userId(\\d+)', |
| | | component: () => import('@/views/system/user/authRole'), |
| | | name: 'AuthRole', |
| | | meta: { title: 'åé
è§è²', activeMenu: '/system/user' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/system/role-auth', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:role:edit'], |
| | | children: [ |
| | | { |
| | | path: 'user/:roleId(\\d+)', |
| | | component: () => import('@/views/system/role/authUser'), |
| | | name: 'AuthUser', |
| | | meta: { title: 'åé
ç¨æ·', activeMenu: '/system/role' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/system/dict-data', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:dict:list'], |
| | | children: [ |
| | | { |
| | | path: 'index/:dictId(\\d+)', |
| | | component: () => import('@/views/system/dict/data'), |
| | | name: 'Data', |
| | | meta: { title: 'åå
¸æ°æ®', activeMenu: '/system/dict' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/monitor/job-log', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['monitor:job:list'], |
| | | children: [ |
| | | { |
| | | path: 'index/:jobId(\\d+)', |
| | | component: () => import('@/views/monitor/job/log'), |
| | | name: 'JobLog', |
| | | meta: { title: 'è°åº¦æ¥å¿', activeMenu: '/monitor/job' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/tool/gen-edit', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['tool:gen:edit'], |
| | | children: [ |
| | | { |
| | | path: 'index/:tableId(\\d+)', |
| | | component: () => import('@/views/tool/gen/editTable'), |
| | | name: 'GenEdit', |
| | | meta: { title: 'ä¿®æ¹çæé
ç½®', activeMenu: '/tool/gen' } |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | |
| | | const router = createRouter({ |
| | | history: createWebHistory(), |
| | | routes: constantRoutes, |
| | | scrollBehavior(to, from, savedPosition) { |
| | | if (savedPosition) { |
| | | return savedPosition |
| | | } |
| | | return { top: 0 } |
| | | }, |
| | | }) |
| | | |
| | | export default router |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export default { |
| | | /** |
| | | * ç½é¡µæ é¢ |
| | | */ |
| | | title: import.meta.env.VITE_APP_TITLE, |
| | | |
| | | /** |
| | | * ä¾§è¾¹æ ä¸»é¢ æ·±è²ä¸»é¢theme-darkï¼æµ
è²ä¸»é¢theme-light |
| | | */ |
| | | sideTheme: 'theme-light', |
| | | |
| | | /** |
| | | * æ¯å¦ç³»ç»å¸å±é
ç½® |
| | | */ |
| | | showSettings: true, |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºé¡¶é¨å¯¼èª |
| | | */ |
| | | topNav: false, |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤º tagsView |
| | | */ |
| | | tagsView: true, |
| | | |
| | | /** |
| | | * æ¯å¦åºå®å¤´é¨ |
| | | */ |
| | | fixedHeader: true, |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºlogo |
| | | */ |
| | | sidebarLogo: false, |
| | | |
| | | /** |
| | | * æ¯å¦æ¾ç¤ºå¨ææ é¢ |
| | | */ |
| | | dynamicTitle: false, |
| | | |
| | | /** |
| | | * @type {string | array} 'production' | ['production', 'development'] |
| | | * @description Need show err logs component. |
| | | * The default is only used in the production env |
| | | * If you want to also use it in dev, you can pass ['production', 'development'] |
| | | */ |
| | | errorLog: 'production' |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | const store = createPinia() |
| | | |
| | | export default store |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import Cookies from 'js-cookie' |
| | | |
| | | const useAppStore = defineStore( |
| | | 'app', |
| | | { |
| | | state: () => ({ |
| | | sidebar: { |
| | | opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, |
| | | withoutAnimation: false, |
| | | hide: false |
| | | }, |
| | | device: 'desktop', |
| | | size: Cookies.get('size') || 'default' |
| | | }), |
| | | actions: { |
| | | toggleSideBar(withoutAnimation) { |
| | | return true |
| | | }, |
| | | closeSideBar({ withoutAnimation }) { |
| | | Cookies.set('sidebarStatus', 0) |
| | | this.sidebar.opened = false |
| | | this.sidebar.withoutAnimation = withoutAnimation |
| | | }, |
| | | toggleDevice(device) { |
| | | this.device = device |
| | | }, |
| | | setSize(size) { |
| | | this.size = size |
| | | Cookies.set('size', size) |
| | | }, |
| | | toggleSideBarHide(status) { |
| | | this.sidebar.hide = status |
| | | } |
| | | } |
| | | }) |
| | | |
| | | export default useAppStore |
¶Ô±ÈÐÂÎļþ |
| | |
| | | const useDictStore = defineStore( |
| | | 'dict', |
| | | { |
| | | state: () => ({ |
| | | dict: new Array() |
| | | }), |
| | | actions: { |
| | | // è·ååå
¸ |
| | | getDict(_key) { |
| | | if (_key == null && _key == "") { |
| | | return null |
| | | } |
| | | try { |
| | | for (let i = 0; i < this.dict.length; i++) { |
| | | if (this.dict[i].key == _key) { |
| | | return this.dict[i].value |
| | | } |
| | | } |
| | | } catch (e) { |
| | | return null |
| | | } |
| | | }, |
| | | // 设置åå
¸ |
| | | setDict(_key, value) { |
| | | if (_key !== null && _key !== "") { |
| | | this.dict.push({ |
| | | key: _key, |
| | | value: value |
| | | }) |
| | | } |
| | | }, |
| | | // å é¤åå
¸ |
| | | removeDict(_key) { |
| | | var bln = false |
| | | try { |
| | | for (let i = 0; i < this.dict.length; i++) { |
| | | if (this.dict[i].key == _key) { |
| | | this.dict.splice(i, 1) |
| | | return true |
| | | } |
| | | } |
| | | } catch (e) { |
| | | bln = false |
| | | } |
| | | return bln |
| | | }, |
| | | // æ¸
空åå
¸ |
| | | cleanDict() { |
| | | this.dict = new Array() |
| | | }, |
| | | // åå§åå
¸ |
| | | initDict() { |
| | | } |
| | | } |
| | | }) |
| | | |
| | | export default useDictStore |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import auth from '@/plugins/auth' |
| | | import router, { constantRoutes, dynamicRoutes } from '@/router' |
| | | import { getRouters } from '@/api/menu' |
| | | import Layout from '@/layout/index' |
| | | import ParentView from '@/components/ParentView' |
| | | import InnerLink from '@/layout/components/InnerLink' |
| | | |
| | | // å¹é
viewsé颿æç.vueæä»¶ |
| | | const modules = import.meta.glob('./../../views/**/*.vue') |
| | | |
| | | const usePermissionStore = defineStore( |
| | | 'permission', |
| | | { |
| | | state: () => ({ |
| | | routes: [], |
| | | addRoutes: [], |
| | | defaultRoutes: [], |
| | | topbarRouters: [], |
| | | sidebarRouters: [] |
| | | }), |
| | | actions: { |
| | | setRoutes(routes) { |
| | | this.addRoutes = routes |
| | | this.routes = constantRoutes.concat(routes) |
| | | }, |
| | | setDefaultRoutes(routes) { |
| | | this.defaultRoutes = constantRoutes.concat(routes) |
| | | }, |
| | | setTopbarRoutes(routes) { |
| | | this.topbarRouters = routes |
| | | }, |
| | | setSidebarRouters(routes) { |
| | | this.sidebarRouters = routes |
| | | }, |
| | | generateRoutes(roles) { |
| | | return new Promise(resolve => { |
| | | // åå端请æ±è·¯ç±æ°æ® |
| | | getRouters().then(res => { |
| | | const sdata = JSON.parse(JSON.stringify(res.data)) |
| | | const rdata = JSON.parse(JSON.stringify(res.data)) |
| | | const defaultData = JSON.parse(JSON.stringify(res.data)) |
| | | const sidebarRoutes = filterAsyncRouter(sdata) |
| | | const rewriteRoutes = filterAsyncRouter(rdata, false, true) |
| | | const defaultRoutes = filterAsyncRouter(defaultData) |
| | | const asyncRoutes = filterDynamicRoutes(dynamicRoutes) |
| | | asyncRoutes.forEach(route => { router.addRoute(route) }) |
| | | this.setRoutes(rewriteRoutes) |
| | | this.setSidebarRouters(constantRoutes.concat(sidebarRoutes)) |
| | | this.setDefaultRoutes(sidebarRoutes) |
| | | this.setTopbarRoutes(defaultRoutes) |
| | | resolve(rewriteRoutes) |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | // éååå°ä¼ æ¥çè·¯ç±å符串ï¼è½¬æ¢ä¸ºç»ä»¶å¯¹è±¡ |
| | | function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) { |
| | | return asyncRouterMap.filter(route => { |
| | | if (type && route.children) { |
| | | route.children = filterChildren(route.children) |
| | | } |
| | | if (route.component) { |
| | | // Layout ParentView ç»ä»¶ç¹æ®å¤ç |
| | | if (route.component === 'Layout') { |
| | | route.component = Layout |
| | | } else if (route.component === 'ParentView') { |
| | | route.component = ParentView |
| | | } else if (route.component === 'InnerLink') { |
| | | route.component = InnerLink |
| | | } else { |
| | | route.component = loadView(route.component) |
| | | } |
| | | } |
| | | if (route.children != null && route.children && route.children.length) { |
| | | route.children = filterAsyncRouter(route.children, route, type) |
| | | } else { |
| | | delete route['children'] |
| | | delete route['redirect'] |
| | | } |
| | | return true |
| | | }) |
| | | } |
| | | |
| | | function filterChildren(childrenMap, lastRouter = false) { |
| | | var children = [] |
| | | childrenMap.forEach(el => { |
| | | el.path = lastRouter ? lastRouter.path + '/' + el.path : el.path |
| | | if (el.children && el.children.length && el.component === 'ParentView') { |
| | | children = children.concat(filterChildren(el.children, el)) |
| | | } else { |
| | | children.push(el) |
| | | } |
| | | }) |
| | | return children |
| | | } |
| | | |
| | | // å¨æè·¯ç±éåï¼éªè¯æ¯å¦å
·å¤æé |
| | | export function filterDynamicRoutes(routes) { |
| | | const res = [] |
| | | routes.forEach(route => { |
| | | if (route.permissions) { |
| | | if (auth.hasPermiOr(route.permissions)) { |
| | | res.push(route) |
| | | } |
| | | } else if (route.roles) { |
| | | if (auth.hasRoleOr(route.roles)) { |
| | | res.push(route) |
| | | } |
| | | } |
| | | }) |
| | | return res |
| | | } |
| | | |
| | | export const loadView = (view) => { |
| | | let res |
| | | for (const path in modules) { |
| | | const dir = path.split('views/')[1].split('.vue')[0] |
| | | if (dir === view) { |
| | | res = () => modules[path]() |
| | | } |
| | | } |
| | | return res |
| | | } |
| | | |
| | | export default usePermissionStore |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import defaultSettings from '@/settings' |
| | | import { useDark, useToggle } from '@vueuse/core' |
| | | import { useDynamicTitle } from '@/utils/dynamicTitle' |
| | | |
| | | const isDark = useDark() |
| | | const toggleDark = useToggle(isDark) |
| | | |
| | | const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings |
| | | |
| | | const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' |
| | | |
| | | const useSettingsStore = defineStore( |
| | | 'settings', |
| | | { |
| | | state: () => ({ |
| | | title: '', |
| | | theme: storageSetting.theme || '#409EFF', |
| | | sideTheme: storageSetting.sideTheme || sideTheme, |
| | | showSettings: showSettings, |
| | | topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, |
| | | tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, |
| | | fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, |
| | | sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo, |
| | | dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle, |
| | | isDark: isDark.value |
| | | }), |
| | | actions: { |
| | | // ä¿®æ¹å¸å±è®¾ç½® |
| | | changeSetting(data) { |
| | | const { key, value } = data |
| | | if (this.hasOwnProperty(key)) { |
| | | this[key] = value |
| | | } |
| | | }, |
| | | // 设置ç½é¡µæ é¢ |
| | | setTitle(title) { |
| | | this.title = title |
| | | useDynamicTitle() |
| | | }, |
| | | // 忢æé»æ¨¡å¼ |
| | | toggleTheme() { |
| | | this.isDark = !this.isDark |
| | | toggleDark() |
| | | } |
| | | } |
| | | }) |
| | | |
| | | export default useSettingsStore |
¶Ô±ÈÐÂÎļþ |
| | |
| | | const useTagsViewStore = defineStore( |
| | | 'tags-view', |
| | | { |
| | | state: () => ({ |
| | | visitedViews: [], |
| | | cachedViews: [], |
| | | iframeViews: [] |
| | | }), |
| | | actions: { |
| | | addView(view) { |
| | | this.addVisitedView(view) |
| | | this.addCachedView(view) |
| | | }, |
| | | addIframeView(view) { |
| | | if (this.iframeViews.some(v => v.path === view.path)) return |
| | | this.iframeViews.push( |
| | | Object.assign({}, view, { |
| | | title: view.meta.title || 'no-name' |
| | | }) |
| | | ) |
| | | }, |
| | | addVisitedView(view) { |
| | | if (this.visitedViews.some(v => v.path === view.path)) return |
| | | this.visitedViews.push( |
| | | Object.assign({}, view, { |
| | | title: view.meta.title || 'no-name' |
| | | }) |
| | | ) |
| | | }, |
| | | addCachedView(view) { |
| | | if (this.cachedViews.includes(view.name)) return |
| | | if (!view.meta.noCache) { |
| | | this.cachedViews.push(view.name) |
| | | } |
| | | }, |
| | | delView(view) { |
| | | return new Promise(resolve => { |
| | | this.delVisitedView(view) |
| | | this.delCachedView(view) |
| | | resolve({ |
| | | visitedViews: [...this.visitedViews], |
| | | cachedViews: [...this.cachedViews] |
| | | }) |
| | | }) |
| | | }, |
| | | delVisitedView(view) { |
| | | return new Promise(resolve => { |
| | | for (const [i, v] of this.visitedViews.entries()) { |
| | | if (v.path === view.path) { |
| | | this.visitedViews.splice(i, 1) |
| | | break |
| | | } |
| | | } |
| | | this.iframeViews = this.iframeViews.filter(item => item.path !== view.path) |
| | | resolve([...this.visitedViews]) |
| | | }) |
| | | }, |
| | | delIframeView(view) { |
| | | return new Promise(resolve => { |
| | | this.iframeViews = this.iframeViews.filter(item => item.path !== view.path) |
| | | resolve([...this.iframeViews]) |
| | | }) |
| | | }, |
| | | delCachedView(view) { |
| | | return new Promise(resolve => { |
| | | const index = this.cachedViews.indexOf(view.name) |
| | | index > -1 && this.cachedViews.splice(index, 1) |
| | | resolve([...this.cachedViews]) |
| | | }) |
| | | }, |
| | | delOthersViews(view) { |
| | | return new Promise(resolve => { |
| | | this.delOthersVisitedViews(view) |
| | | this.delOthersCachedViews(view) |
| | | resolve({ |
| | | visitedViews: [...this.visitedViews], |
| | | cachedViews: [...this.cachedViews] |
| | | }) |
| | | }) |
| | | }, |
| | | delOthersVisitedViews(view) { |
| | | return new Promise(resolve => { |
| | | this.visitedViews = this.visitedViews.filter(v => { |
| | | return v.meta.affix || v.path === view.path |
| | | }) |
| | | this.iframeViews = this.iframeViews.filter(item => item.path === view.path) |
| | | resolve([...this.visitedViews]) |
| | | }) |
| | | }, |
| | | delOthersCachedViews(view) { |
| | | return new Promise(resolve => { |
| | | const index = this.cachedViews.indexOf(view.name) |
| | | if (index > -1) { |
| | | this.cachedViews = this.cachedViews.slice(index, index + 1) |
| | | } else { |
| | | this.cachedViews = [] |
| | | } |
| | | resolve([...this.cachedViews]) |
| | | }) |
| | | }, |
| | | delAllViews(view) { |
| | | return new Promise(resolve => { |
| | | this.delAllVisitedViews(view) |
| | | this.delAllCachedViews(view) |
| | | resolve({ |
| | | visitedViews: [...this.visitedViews], |
| | | cachedViews: [...this.cachedViews] |
| | | }) |
| | | }) |
| | | }, |
| | | delAllVisitedViews(view) { |
| | | return new Promise(resolve => { |
| | | const affixTags = this.visitedViews.filter(tag => tag.meta.affix) |
| | | this.visitedViews = affixTags |
| | | this.iframeViews = [] |
| | | resolve([...this.visitedViews]) |
| | | }) |
| | | }, |
| | | delAllCachedViews(view) { |
| | | return new Promise(resolve => { |
| | | this.cachedViews = [] |
| | | resolve([...this.cachedViews]) |
| | | }) |
| | | }, |
| | | updateVisitedView(view) { |
| | | for (let v of this.visitedViews) { |
| | | if (v.path === view.path) { |
| | | v = Object.assign(v, view) |
| | | break |
| | | } |
| | | } |
| | | }, |
| | | delRightTags(view) { |
| | | return new Promise(resolve => { |
| | | const index = this.visitedViews.findIndex(v => v.path === view.path) |
| | | if (index === -1) { |
| | | return |
| | | } |
| | | this.visitedViews = this.visitedViews.filter((item, idx) => { |
| | | if (idx <= index || (item.meta && item.meta.affix)) { |
| | | return true |
| | | } |
| | | const i = this.cachedViews.indexOf(item.name) |
| | | if (i > -1) { |
| | | this.cachedViews.splice(i, 1) |
| | | } |
| | | if(item.meta.link) { |
| | | const fi = this.iframeViews.findIndex(v => v.path === item.path) |
| | | this.iframeViews.splice(fi, 1) |
| | | } |
| | | return false |
| | | }) |
| | | resolve([...this.visitedViews]) |
| | | }) |
| | | }, |
| | | delLeftTags(view) { |
| | | return new Promise(resolve => { |
| | | const index = this.visitedViews.findIndex(v => v.path === view.path) |
| | | if (index === -1) { |
| | | return |
| | | } |
| | | this.visitedViews = this.visitedViews.filter((item, idx) => { |
| | | if (idx >= index || (item.meta && item.meta.affix)) { |
| | | return true |
| | | } |
| | | const i = this.cachedViews.indexOf(item.name) |
| | | if (i > -1) { |
| | | this.cachedViews.splice(i, 1) |
| | | } |
| | | if(item.meta.link) { |
| | | const fi = this.iframeViews.findIndex(v => v.path === item.path) |
| | | this.iframeViews.splice(fi, 1) |
| | | } |
| | | return false |
| | | }) |
| | | resolve([...this.visitedViews]) |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | export default useTagsViewStore |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { login, logout, getInfo } from '@/api/login' |
| | | import { getToken, setToken, removeToken } from '@/utils/auth' |
| | | import { isHttp, isEmpty } from "@/utils/validate" |
| | | import defAva from '@/assets/images/profile.jpg' |
| | | |
| | | const useUserStore = defineStore( |
| | | 'user', |
| | | { |
| | | state: () => ({ |
| | | token: getToken(), |
| | | id: '', |
| | | name: '', |
| | | nickName: '', |
| | | avatar: '', |
| | | roles: [], |
| | | permissions: [] |
| | | }), |
| | | actions: { |
| | | // ç»å½ |
| | | login(userInfo) { |
| | | const username = userInfo.username.trim() |
| | | const password = userInfo.password |
| | | const code = userInfo.code |
| | | const uuid = userInfo.uuid |
| | | return new Promise((resolve, reject) => { |
| | | login(username, password, code, uuid).then(res => { |
| | | setToken(res.token) |
| | | this.token = res.token |
| | | resolve() |
| | | }).catch(error => { |
| | | reject(error) |
| | | }) |
| | | }) |
| | | }, |
| | | // è·åç¨æ·ä¿¡æ¯ |
| | | getInfo() { |
| | | return new Promise((resolve, reject) => { |
| | | getInfo().then(res => { |
| | | const user = res.user |
| | | let avatar = user.avatar || "" |
| | | if (!isHttp(avatar)) { |
| | | avatar = (isEmpty(avatar)) ? defAva : import.meta.env.VITE_APP_BASE_API + avatar |
| | | } |
| | | if (res.roles && res.roles.length > 0) { // éªè¯è¿åçrolesæ¯å¦æ¯ä¸ä¸ªé空æ°ç» |
| | | this.roles = res.roles |
| | | this.permissions = res.permissions |
| | | } else { |
| | | this.roles = ['ROLE_DEFAULT'] |
| | | } |
| | | this.id = user.userId |
| | | this.name = user.userName |
| | | this.nickName = user.nickName |
| | | this.avatar = avatar |
| | | resolve(res) |
| | | }).catch(error => { |
| | | reject(error) |
| | | }) |
| | | }) |
| | | }, |
| | | // éåºç³»ç» |
| | | logOut() { |
| | | return new Promise((resolve, reject) => { |
| | | logout(this.token).then(() => { |
| | | this.token = '' |
| | | this.roles = [] |
| | | this.permissions = [] |
| | | removeToken() |
| | | resolve() |
| | | }).catch(error => { |
| | | reject(error) |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | export default useUserStore |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import Cookies from 'js-cookie' |
| | | |
| | | const TokenKey = 'Admin-Token' |
| | | |
| | | export function getToken() { |
| | | return Cookies.get(TokenKey) |
| | | } |
| | | |
| | | export function setToken(token) { |
| | | return Cookies.set(TokenKey, token) |
| | | } |
| | | |
| | | export function removeToken() { |
| | | return Cookies.remove(TokenKey) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import useDictStore from '@/store/modules/dict' |
| | | import { getDicts } from '@/api/system/dict/data' |
| | | |
| | | /** |
| | | * è·ååå
¸æ°æ® |
| | | */ |
| | | export function useDict(...args) { |
| | | const res = ref({}) |
| | | return (() => { |
| | | args.forEach((dictType, index) => { |
| | | res.value[dictType] = [] |
| | | const dicts = useDictStore().getDict(dictType) |
| | | if (dicts) { |
| | | res.value[dictType] = dicts |
| | | } else { |
| | | getDicts(dictType).then(resp => { |
| | | res.value[dictType] = resp.data.map(p => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass })) |
| | | useDictStore().setDict(dictType, res.value[dictType]) |
| | | }) |
| | | } |
| | | }) |
| | | return toRefs(res.value) |
| | | })() |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import defaultSettings from '@/settings' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | |
| | | /** |
| | | * å¨æä¿®æ¹æ é¢ |
| | | */ |
| | | export function useDynamicTitle() { |
| | | const settingsStore = useSettingsStore() |
| | | if (settingsStore.dynamicTitle) { |
| | | document.title = settingsStore.title + ' - ' + defaultSettings.title |
| | | } else { |
| | | document.title = defaultSettings.title |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export default { |
| | | '401': '认è¯å¤±è´¥ï¼æ æ³è®¿é®ç³»ç»èµæº', |
| | | '403': 'å½åæä½æ²¡ææé', |
| | | '404': '访é®èµæºä¸åå¨', |
| | | 'default': 'ç³»ç»æªç¥é误ï¼è¯·åé¦ç»ç®¡çå' |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export const formConf = { |
| | | formRef: 'formRef', |
| | | formModel: 'formData', |
| | | size: 'default', |
| | | labelPosition: 'right', |
| | | labelWidth: 100, |
| | | formRules: 'rules', |
| | | gutter: 15, |
| | | disabled: false, |
| | | span: 24, |
| | | formBtns: true, |
| | | } |
| | | |
| | | export const inputComponents = [ |
| | | { |
| | | label: 'åè¡ææ¬', |
| | | tag: 'el-input', |
| | | tagIcon: 'input', |
| | | type: 'text', |
| | | placeholder: '请è¾å
¥', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | prepend: '', |
| | | append: '', |
| | | 'prefix-icon': '', |
| | | 'suffix-icon': '', |
| | | maxlength: null, |
| | | 'show-word-limit': false, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/input', |
| | | }, |
| | | { |
| | | label: 'å¤è¡ææ¬', |
| | | tag: 'el-input', |
| | | tagIcon: 'textarea', |
| | | type: 'textarea', |
| | | placeholder: '请è¾å
¥', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | autosize: { |
| | | minRows: 4, |
| | | maxRows: 4, |
| | | }, |
| | | style: { width: '100%' }, |
| | | maxlength: null, |
| | | 'show-word-limit': false, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/input', |
| | | }, |
| | | { |
| | | label: 'å¯ç ', |
| | | tag: 'el-input', |
| | | tagIcon: 'password', |
| | | type: 'password', |
| | | placeholder: '请è¾å
¥', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | 'show-password': true, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | prepend: '', |
| | | append: '', |
| | | 'prefix-icon': '', |
| | | 'suffix-icon': '', |
| | | maxlength: null, |
| | | 'show-word-limit': false, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/input', |
| | | }, |
| | | { |
| | | label: '计æ°å¨', |
| | | tag: 'el-input-number', |
| | | tagIcon: 'number', |
| | | placeholder: '', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | min: undefined, |
| | | max: undefined, |
| | | step: undefined, |
| | | 'step-strictly': false, |
| | | precision: undefined, |
| | | 'controls-position': '', |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/input-number', |
| | | }, |
| | | ] |
| | | |
| | | export const selectComponents = [ |
| | | { |
| | | label: '䏿鿩', |
| | | tag: 'el-select', |
| | | tagIcon: 'select', |
| | | placeholder: 'è¯·éæ©', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | disabled: false, |
| | | required: true, |
| | | filterable: false, |
| | | multiple: false, |
| | | options: [ |
| | | { |
| | | label: 'é项ä¸', |
| | | value: 1, |
| | | }, |
| | | { |
| | | label: 'é项äº', |
| | | value: 2, |
| | | }, |
| | | ], |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/select', |
| | | }, |
| | | { |
| | | label: '级èéæ©', |
| | | tag: 'el-cascader', |
| | | tagIcon: 'cascader', |
| | | placeholder: 'è¯·éæ©', |
| | | defaultValue: [], |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | props: { |
| | | props: { |
| | | multiple: false, |
| | | }, |
| | | }, |
| | | 'show-all-levels': true, |
| | | disabled: false, |
| | | clearable: true, |
| | | filterable: false, |
| | | required: true, |
| | | options: [ |
| | | { |
| | | id: 1, |
| | | value: 1, |
| | | label: 'é项1', |
| | | children: [ |
| | | { |
| | | id: 2, |
| | | value: 2, |
| | | label: 'é项1-1', |
| | | }, |
| | | ], |
| | | }, |
| | | ], |
| | | dataType: 'dynamic', |
| | | labelKey: 'label', |
| | | valueKey: 'value', |
| | | childrenKey: 'children', |
| | | separator: '/', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/cascader', |
| | | }, |
| | | { |
| | | label: 'åéæ¡ç»', |
| | | tag: 'el-radio-group', |
| | | tagIcon: 'radio', |
| | | defaultValue: 0, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | optionType: 'default', |
| | | border: false, |
| | | size: 'default', |
| | | disabled: false, |
| | | required: true, |
| | | options: [ |
| | | { |
| | | label: 'é项ä¸', |
| | | value: 1, |
| | | }, |
| | | { |
| | | label: 'é项äº', |
| | | value: 2, |
| | | }, |
| | | ], |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/radio', |
| | | }, |
| | | { |
| | | label: 'å¤éæ¡ç»', |
| | | tag: 'el-checkbox-group', |
| | | tagIcon: 'checkbox', |
| | | defaultValue: [], |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | optionType: 'default', |
| | | border: false, |
| | | size: 'default', |
| | | disabled: false, |
| | | required: true, |
| | | options: [ |
| | | { |
| | | label: 'é项ä¸', |
| | | value: 1, |
| | | }, |
| | | { |
| | | label: 'é项äº', |
| | | value: 2, |
| | | }, |
| | | ], |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/checkbox', |
| | | }, |
| | | { |
| | | label: 'å¼å
³', |
| | | tag: 'el-switch', |
| | | tagIcon: 'switch', |
| | | defaultValue: false, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | disabled: false, |
| | | required: true, |
| | | 'active-text': '', |
| | | 'inactive-text': '', |
| | | 'active-color': null, |
| | | 'inactive-color': null, |
| | | 'active-value': true, |
| | | 'inactive-value': false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/switch', |
| | | }, |
| | | { |
| | | label: 'æ»å', |
| | | tag: 'el-slider', |
| | | tagIcon: 'slider', |
| | | defaultValue: null, |
| | | span: 24, |
| | | labelWidth: null, |
| | | disabled: false, |
| | | required: true, |
| | | min: 0, |
| | | max: 100, |
| | | step: 1, |
| | | 'show-stops': false, |
| | | range: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/slider', |
| | | }, |
| | | { |
| | | label: 'æ¶é´éæ©', |
| | | tag: 'el-time-picker', |
| | | tagIcon: 'time', |
| | | placeholder: 'è¯·éæ©', |
| | | defaultValue: '', |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | format: 'HH:mm:ss', |
| | | 'value-format': 'HH:mm:ss', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/time-picker', |
| | | }, |
| | | { |
| | | label: 'æ¶é´èå´', |
| | | tag: 'el-time-picker', |
| | | tagIcon: 'time-range', |
| | | defaultValue: null, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | 'is-range': true, |
| | | 'range-separator': 'è³', |
| | | 'start-placeholder': 'å¼å§æ¶é´', |
| | | 'end-placeholder': 'ç»ææ¶é´', |
| | | format: 'HH:mm:ss', |
| | | 'value-format': 'HH:mm:ss', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/time-picker', |
| | | }, |
| | | { |
| | | label: 'æ¥æéæ©', |
| | | tag: 'el-date-picker', |
| | | tagIcon: 'date', |
| | | placeholder: 'è¯·éæ©', |
| | | defaultValue: null, |
| | | type: 'date', |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | format: 'YYYY-MM-DD', |
| | | 'value-format': 'YYYY-MM-DD', |
| | | readonly: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/date-picker', |
| | | }, |
| | | { |
| | | label: 'æ¥æèå´', |
| | | tag: 'el-date-picker', |
| | | tagIcon: 'date-range', |
| | | defaultValue: null, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | type: 'daterange', |
| | | 'range-separator': 'è³', |
| | | 'start-placeholder': 'å¼å§æ¥æ', |
| | | 'end-placeholder': 'ç»ææ¥æ', |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | format: 'YYYY-MM-DD', |
| | | 'value-format': 'YYYY-MM-DD', |
| | | readonly: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/date-picker', |
| | | }, |
| | | { |
| | | label: 'è¯å', |
| | | tag: 'el-rate', |
| | | tagIcon: 'rate', |
| | | defaultValue: 0, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | max: 5, |
| | | 'allow-half': false, |
| | | 'show-text': false, |
| | | 'show-score': false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/rate', |
| | | }, |
| | | { |
| | | label: 'é¢è²éæ©', |
| | | tag: 'el-color-picker', |
| | | tagIcon: 'color', |
| | | defaultValue: null, |
| | | labelWidth: null, |
| | | 'show-alpha': false, |
| | | 'color-format': '', |
| | | disabled: false, |
| | | required: true, |
| | | size: 'default', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/color-picker', |
| | | }, |
| | | { |
| | | label: 'ä¸ä¼ ', |
| | | tag: 'el-upload', |
| | | tagIcon: 'upload', |
| | | action: 'https://jsonplaceholder.typicode.com/posts/', |
| | | defaultValue: null, |
| | | labelWidth: null, |
| | | disabled: false, |
| | | required: true, |
| | | accept: '', |
| | | name: 'file', |
| | | 'auto-upload': true, |
| | | showTip: false, |
| | | buttonText: 'ç¹å»ä¸ä¼ ', |
| | | fileSize: 2, |
| | | sizeUnit: 'MB', |
| | | 'list-type': 'text', |
| | | multiple: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element-plus.org/zh-CN/component/upload', |
| | | tip: 'åªè½ä¸ä¼ ä¸è¶
è¿ 2MB çæä»¶', |
| | | style: { width: '100%' }, |
| | | }, |
| | | ] |
| | | |
| | | export const layoutComponents = [ |
| | | { |
| | | layout: 'rowFormItem', |
| | | tagIcon: 'row', |
| | | type: 'default', |
| | | justify: 'start', |
| | | align: 'top', |
| | | label: 'è¡å®¹å¨', |
| | | layoutTree: true, |
| | | children: [], |
| | | document: 'https://element-plus.org/zh-CN/component/layout', |
| | | }, |
| | | { |
| | | layout: 'colFormItem', |
| | | label: 'æé®', |
| | | changeTag: true, |
| | | labelWidth: null, |
| | | tag: 'el-button', |
| | | tagIcon: 'button', |
| | | span: 24, |
| | | default: 'ä¸»è¦æé®', |
| | | type: 'primary', |
| | | icon: 'Search', |
| | | size: 'default', |
| | | disabled: false, |
| | | document: 'https://element-plus.org/zh-CN/component/button', |
| | | }, |
| | | ] |
| | | |
| | | // ç»ä»¶ruleçè§¦åæ¹å¼ï¼æ è§¦åæ¹å¼çç»ä»¶ä¸çærule |
| | | export const trigger = { |
| | | 'el-input': 'blur', |
| | | 'el-input-number': 'blur', |
| | | 'el-select': 'change', |
| | | 'el-radio-group': 'change', |
| | | 'el-checkbox-group': 'change', |
| | | 'el-cascader': 'change', |
| | | 'el-time-picker': 'change', |
| | | 'el-date-picker': 'change', |
| | | 'el-rate': 'change', |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | const styles = { |
| | | 'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}', |
| | | 'el-upload': '.el-upload__tip{line-height: 1.2;}' |
| | | } |
| | | |
| | | function addCss(cssList, el) { |
| | | const css = styles[el.tag] |
| | | css && cssList.indexOf(css) === -1 && cssList.push(css) |
| | | if (el.children) { |
| | | el.children.forEach(el2 => addCss(cssList, el2)) |
| | | } |
| | | } |
| | | |
| | | export function makeUpCss(conf) { |
| | | const cssList = [] |
| | | conf.fields.forEach(el => addCss(cssList, el)) |
| | | return cssList.join('\n') |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export default [ |
| | | { |
| | | layout: 'colFormItem', |
| | | tagIcon: 'input', |
| | | label: 'ææºå·', |
| | | vModel: 'mobile', |
| | | formId: 6, |
| | | tag: 'el-input', |
| | | placeholder: '请è¾å
¥ææºå·', |
| | | defaultValue: '', |
| | | span: 24, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | prepend: '', |
| | | append: '', |
| | | 'prefix-icon': 'Cellphone', |
| | | 'suffix-icon': '', |
| | | maxlength: 11, |
| | | 'show-word-limit': true, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | changeTag: true, |
| | | regList: [{ |
| | | pattern: '/^1(3|4|5|7|8|9)\\d{9}$/', |
| | | message: 'ææºå·æ ¼å¼é误' |
| | | }] |
| | | } |
| | | ] |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* eslint-disable max-len */ |
| | | import { trigger } from './config' |
| | | |
| | | let confGlobal |
| | | let someSpanIsNot24 |
| | | |
| | | export function dialogWrapper(str) { |
| | | return `<el-dialog v-model="dialogVisible" @open="onOpen" @close="onClose" title="Dialog Titile"> |
| | | ${str} |
| | | <template #footer> |
| | | <el-button @click="close">åæ¶</el-button> |
| | | <el-button type="primary" @click="handelConfirm">ç¡®å®</el-button> |
| | | </template> |
| | | </el-dialog>` |
| | | } |
| | | |
| | | export function vueTemplate(str) { |
| | | return `<template> |
| | | <div class="app-container"> |
| | | ${str} |
| | | </div> |
| | | </template>` |
| | | } |
| | | |
| | | export function vueScript(str) { |
| | | return `<script setup> |
| | | ${str} |
| | | </script>` |
| | | } |
| | | |
| | | export function cssStyle(cssStr) { |
| | | return `<style> |
| | | ${cssStr} |
| | | </style>` |
| | | } |
| | | |
| | | function buildFormTemplate(conf, child, type) { |
| | | let labelPosition = '' |
| | | if (conf.labelPosition !== 'right') { |
| | | labelPosition = `label-position="${conf.labelPosition}"` |
| | | } |
| | | const disabled = conf.disabled ? `:disabled="${conf.disabled}"` : '' |
| | | let str = `<el-form ref="${conf.formRef}" :model="${conf.formModel}" :rules="${conf.formRules}" size="${conf.size}" ${disabled} label-width="${conf.labelWidth}px" ${labelPosition}> |
| | | ${child} |
| | | ${buildFromBtns(conf, type)} |
| | | </el-form>` |
| | | if (someSpanIsNot24) { |
| | | str = `<el-row :gutter="${conf.gutter}"> |
| | | ${str} |
| | | </el-row>` |
| | | } |
| | | return str |
| | | } |
| | | |
| | | function buildFromBtns(conf, type) { |
| | | let str = '' |
| | | if (conf.formBtns && type === 'file') { |
| | | str = `<el-form-item> |
| | | <el-button type="primary" @click="submitForm">æäº¤</el-button> |
| | | <el-button @click="resetForm">éç½®</el-button> |
| | | </el-form-item>` |
| | | if (someSpanIsNot24) { |
| | | str = `<el-col :span="24"> |
| | | ${str} |
| | | </el-col>` |
| | | } |
| | | } |
| | | return str |
| | | } |
| | | |
| | | // spanä¸ä¸º24çç¨el-colå
裹 |
| | | function colWrapper(element, str) { |
| | | if (someSpanIsNot24 || element.span !== 24) { |
| | | return `<el-col :span="${element.span}"> |
| | | ${str} |
| | | </el-col>` |
| | | } |
| | | return str |
| | | } |
| | | |
| | | const layouts = { |
| | | colFormItem(element) { |
| | | let labelWidth = '' |
| | | if (element.labelWidth && element.labelWidth !== confGlobal.labelWidth) { |
| | | labelWidth = `label-width="${element.labelWidth}px"` |
| | | } |
| | | const required = !trigger[element.tag] && element.required ? 'required' : '' |
| | | const tagDom = tags[element.tag] ? tags[element.tag](element) : null |
| | | let str = `<el-form-item ${labelWidth} label="${element.label}" prop="${element.vModel}" ${required}> |
| | | ${tagDom} |
| | | </el-form-item>` |
| | | str = colWrapper(element, str) |
| | | return str |
| | | }, |
| | | rowFormItem(element) { |
| | | const type = element.type === 'default' ? '' : `type="${element.type}"` |
| | | const justify = element.type === 'default' ? '' : `justify="${element.justify}"` |
| | | const align = element.type === 'default' ? '' : `align="${element.align}"` |
| | | const gutter = element.gutter ? `gutter="${element.gutter}"` : '' |
| | | const children = element.children.map(el => layouts[el.layout](el)) |
| | | let str = `<el-row ${type} ${justify} ${align} ${gutter}> |
| | | ${children.join('\n')} |
| | | </el-row>` |
| | | str = colWrapper(element, str) |
| | | return str |
| | | } |
| | | } |
| | | |
| | | const tags = { |
| | | 'el-button': el => { |
| | | const { |
| | | tag, disabled |
| | | } = attrBuilder(el) |
| | | const type = el.type ? `type="${el.type}"` : '' |
| | | const icon = el.icon ? `icon="${el.icon}"` : '' |
| | | const size = el.size ? `size="${el.size}"` : '' |
| | | let child = buildElButtonChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${type} ${icon} ${size} ${disabled}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-input': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : '' |
| | | const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : '' |
| | | const readonly = el.readonly ? 'readonly' : '' |
| | | const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : '' |
| | | const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : '' |
| | | const showPassword = el['show-password'] ? 'show-password' : '' |
| | | const type = el.type ? `type="${el.type}"` : '' |
| | | const autosize = el.autosize && el.autosize.minRows |
| | | ? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"` |
| | | : '' |
| | | let child = buildElInputChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-input-number': el => { |
| | | const { disabled, vModel, placeholder } = attrBuilder(el) |
| | | const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : '' |
| | | const min = el.min ? `:min='${el.min}'` : '' |
| | | const max = el.max ? `:max='${el.max}'` : '' |
| | | const step = el.step ? `:step='${el.step}'` : '' |
| | | const stepStrictly = el['step-strictly'] ? 'step-strictly' : '' |
| | | const precision = el.precision ? `:precision='${el.precision}'` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-select': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const filterable = el.filterable ? 'filterable' : '' |
| | | const multiple = el.multiple ? 'multiple' : '' |
| | | let child = buildElSelectChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-radio-group': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const size = `size="${el.size}"` |
| | | let child = buildElRadioGroupChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${vModel} ${size} ${disabled}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-checkbox-group': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const size = `size="${el.size}"` |
| | | const min = el.min ? `:min="${el.min}"` : '' |
| | | const max = el.max ? `:max="${el.max}"` : '' |
| | | let child = buildElCheckboxGroupChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-switch': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : '' |
| | | const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : '' |
| | | const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : '' |
| | | const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : '' |
| | | const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : '' |
| | | const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-cascader': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const options = el.options ? `:options="${el.vModel}Options"` : '' |
| | | const props = el.props ? `:props="${el.vModel}Props"` : '' |
| | | const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"' |
| | | const filterable = el.filterable ? 'filterable' : '' |
| | | const separator = el.separator === '/' ? '' : `separator="${el.separator}"` |
| | | |
| | | return `<${el.tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-slider': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const min = el.min ? `:min='${el.min}'` : '' |
| | | const max = el.max ? `:max='${el.max}'` : '' |
| | | const step = el.step ? `:step='${el.step}'` : '' |
| | | const range = el.range ? 'range' : '' |
| | | const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : '' |
| | | |
| | | return `<${el.tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-time-picker': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' |
| | | const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' |
| | | const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' |
| | | const isRange = el['is-range'] ? 'is-range' : '' |
| | | const format = el.format ? `format="${el.format}"` : '' |
| | | const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' |
| | | const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-date-picker': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' |
| | | const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' |
| | | const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' |
| | | const format = el.format ? `format="${el.format}"` : '' |
| | | const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' |
| | | const type = el.type === 'date' ? '' : `type="${el.type}"` |
| | | const readonly = el.readonly ? 'readonly' : '' |
| | | |
| | | return `<${el.tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-rate': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const max = el.max ? `:max='${el.max}'` : '' |
| | | const allowHalf = el['allow-half'] ? 'allow-half' : '' |
| | | const showText = el['show-text'] ? 'show-text' : '' |
| | | const showScore = el['show-score'] ? 'show-score' : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${allowHalf} ${showText} ${showScore} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-color-picker': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const size = `size="${el.size}"` |
| | | const showAlpha = el['show-alpha'] ? 'show-alpha' : '' |
| | | const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-upload': el => { |
| | | const disabled = el.disabled ? ':disabled=\'true\'' : '' |
| | | const action = el.action ? `:action="${el.vModel}Action"` : '' |
| | | const multiple = el.multiple ? 'multiple' : '' |
| | | const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : '' |
| | | const accept = el.accept ? `accept="${el.accept}"` : '' |
| | | const name = el.name !== 'file' ? `name="${el.name}"` : '' |
| | | const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : '' |
| | | const beforeUpload = `:before-upload="${el.vModel}BeforeUpload"` |
| | | const fileList = `:file-list="${el.vModel}fileList"` |
| | | const ref = `ref="${el.vModel}"` |
| | | let child = buildElUploadChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // æ¢è¡ |
| | | return `<${el.tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}</${el.tag}>` |
| | | } |
| | | } |
| | | |
| | | function attrBuilder(el) { |
| | | return { |
| | | vModel: `v-model="${confGlobal.formModel}.${el.vModel}"`, |
| | | clearable: el.clearable ? 'clearable' : '', |
| | | placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '', |
| | | width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '', |
| | | disabled: el.disabled ? ':disabled=\'true\'' : '' |
| | | } |
| | | } |
| | | |
| | | // el-buttin å级 |
| | | function buildElButtonChild(conf) { |
| | | const children = [] |
| | | if (conf.default) { |
| | | children.push(conf.default) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | // el-input innerHTML |
| | | function buildElInputChild(conf) { |
| | | const children = [] |
| | | if (conf.prepend) { |
| | | children.push(`<template slot="prepend">${conf.prepend}</template>`) |
| | | } |
| | | if (conf.append) { |
| | | children.push(`<template slot="append">${conf.append}</template>`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElSelectChild(conf) { |
| | | const children = [] |
| | | if (conf.options && conf.options.length) { |
| | | children.push(`<el-option v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled"></el-option>`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElRadioGroupChild(conf) { |
| | | const children = [] |
| | | if (conf.options && conf.options.length) { |
| | | const tag = conf.optionType === 'button' ? 'el-radio-button' : 'el-radio' |
| | | const border = conf.border ? 'border' : '' |
| | | children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :value="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElCheckboxGroupChild(conf) { |
| | | const children = [] |
| | | if (conf.options && conf.options.length) { |
| | | const tag = conf.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox' |
| | | const border = conf.border ? 'border' : '' |
| | | children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :value="item.label" :disabled="item.disabled" ${border} />`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElUploadChild(conf) { |
| | | const list = [] |
| | | if (conf['list-type'] === 'picture-card') list.push('<i class="el-icon-plus"></i>') |
| | | else list.push(`<el-button size="small" type="primary" icon="el-icon-upload">${conf.buttonText}</el-button>`) |
| | | if (conf.showTip) list.push(`<div slot="tip" class="el-upload__tip">åªè½ä¸ä¼ ä¸è¶
è¿ ${conf.fileSize}${conf.sizeUnit} ç${conf.accept}æä»¶</div>`) |
| | | return list.join('\n') |
| | | } |
| | | |
| | | export function makeUpHtml(conf, type) { |
| | | const htmlList = [] |
| | | confGlobal = conf |
| | | someSpanIsNot24 = conf.fields.some(item => item.span !== 24) |
| | | conf.fields.forEach(el => { |
| | | htmlList.push(layouts[el.layout](el)) |
| | | }) |
| | | const htmlStr = htmlList.join('\n') |
| | | |
| | | let temp = buildFormTemplate(conf, htmlStr, type) |
| | | if (type === 'dialog') { |
| | | temp = dialogWrapper(temp) |
| | | } |
| | | confGlobal = null |
| | | return temp |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | ["platform-eleme","eleme","delete-solid","delete","s-tools","setting","user-solid","user","phone","phone-outline","more","more-outline","star-on","star-off","s-goods","goods","warning","warning-outline","question","info","remove","circle-plus","success","error","zoom-in","zoom-out","remove-outline","circle-plus-outline","circle-check","circle-close","s-help","help","minus","plus","check","close","picture","picture-outline","picture-outline-round","upload","upload2","download","camera-solid","camera","video-camera-solid","video-camera","message-solid","bell","s-cooperation","s-order","s-platform","s-fold","s-unfold","s-operation","s-promotion","s-home","s-release","s-ticket","s-management","s-open","s-shop","s-marketing","s-flag","s-comment","s-finance","s-claim","s-custom","s-opportunity","s-data","s-check","s-grid","menu","share","d-caret","caret-left","caret-right","caret-bottom","caret-top","bottom-left","bottom-right","back","right","bottom","top","top-left","top-right","arrow-left","arrow-right","arrow-down","arrow-up","d-arrow-left","d-arrow-right","video-pause","video-play","refresh","refresh-right","refresh-left","finished","sort","sort-up","sort-down","rank","loading","view","c-scale-to-original","date","edit","edit-outline","folder","folder-opened","folder-add","folder-remove","folder-delete","folder-checked","tickets","document-remove","document-delete","document-copy","document-checked","document","document-add","printer","paperclip","takeaway-box","search","monitor","attract","mobile","scissors","umbrella","headset","brush","mouse","coordinate","magic-stick","reading","data-line","data-board","pie-chart","data-analysis","collection-tag","film","suitcase","suitcase-1","receiving","collection","files","notebook-1","notebook-2","toilet-paper","office-building","school","table-lamp","house","no-smoking","smoking","shopping-cart-full","shopping-cart-1","shopping-cart-2","shopping-bag-1","shopping-bag-2","sold-out","sell","present","box","bank-card","money","coin","wallet","discount","price-tag","news","guide","male","female","thumb","cpu","link","connection","open","turn-off","set-up","chat-round","chat-line-round","chat-square","chat-dot-round","chat-dot-square","chat-line-square","message","postcard","position","turn-off-microphone","microphone","close-notification","bangzhu","time","odometer","crop","aim","switch-button","full-screen","copy-document","mic","stopwatch","medal-1","medal","trophy","trophy-1","first-aid-kit","discover","place","location","location-outline","location-information","add-location","delete-location","map-location","alarm-clock","timer","watch-1","watch","lock","unlock","key","service","mobile-phone","bicycle","truck","ship","basketball","football","soccer","baseball","wind-power","light-rain","lightning","heavy-rain","sunrise","sunrise-1","sunset","sunny","cloudy","partly-cloudy","cloudy-and-sunny","moon","moon-night","dish","dish-1","food","chicken","fork-spoon","knife-fork","burger","tableware","sugar","dessert","ice-cream","hot-water","water-cup","coffee-cup","cold-drink","goblet","goblet-full","goblet-square","goblet-square-full","refrigerator","grape","watermelon","cherry","apple","pear","orange","coffee","ice-tea","ice-drink","milk-tea","potato-strips","lollipop","ice-cream-square","ice-cream-round"] |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { titleCase } from '@/utils/index' |
| | | import { trigger } from './config' |
| | | // æä»¶å¤§å°è®¾ç½® |
| | | const units = { |
| | | KB: '1024', |
| | | MB: '1024 / 1024', |
| | | GB: '1024 / 1024 / 1024', |
| | | } |
| | | /** |
| | | * @name: çæjséè¦çæ°æ® |
| | | * @description: çæjséè¦çæ°æ® |
| | | * @param {*} conf |
| | | * @param {*} type å¼¹çªæè¡¨å |
| | | * @return {*} |
| | | */ |
| | | export function makeUpJs(conf, type) { |
| | | conf = JSON.parse(JSON.stringify(conf)) |
| | | const dataList = [] |
| | | const ruleList = [] |
| | | const optionsList = [] |
| | | const propsList = [] |
| | | const methodList = [] |
| | | const uploadVarList = [] |
| | | |
| | | conf.fields.forEach((el) => { |
| | | buildAttributes( |
| | | el, |
| | | dataList, |
| | | ruleList, |
| | | optionsList, |
| | | methodList, |
| | | propsList, |
| | | uploadVarList |
| | | ) |
| | | }) |
| | | |
| | | const script = buildexport( |
| | | conf, |
| | | type, |
| | | dataList.join('\n'), |
| | | ruleList.join('\n'), |
| | | optionsList.join('\n'), |
| | | uploadVarList.join('\n'), |
| | | propsList.join('\n'), |
| | | methodList.join('\n') |
| | | ) |
| | | |
| | | return script |
| | | } |
| | | /** |
| | | * @name: çæåæ° |
| | | * @description: çæåæ°ï¼å
æ¬è¡¨åæ°æ®è¡¨åéªè¯æ°æ®ï¼å¤ééé¡¹æ°æ®ï¼ä¸ä¼ æ°æ®ç |
| | | * @return {*} |
| | | */ |
| | | function buildAttributes( |
| | | el, |
| | | dataList, |
| | | ruleList, |
| | | optionsList, |
| | | methodList, |
| | | propsList, |
| | | uploadVarList |
| | | ){ |
| | | buildData(el, dataList) |
| | | buildRules(el, ruleList) |
| | | |
| | | if (el.options && el.options.length) { |
| | | buildOptions(el, optionsList) |
| | | if (el.dataType === 'dynamic') { |
| | | const model = `${el.vModel}Options` |
| | | const options = titleCase(model) |
| | | buildOptionMethod(`get${options}`, model, methodList) |
| | | } |
| | | } |
| | | |
| | | if (el.props && el.props.props) { |
| | | buildProps(el, propsList) |
| | | } |
| | | |
| | | if (el.action && el.tag === 'el-upload') { |
| | | uploadVarList.push( |
| | | ` |
| | | // ä¸ä¼ 请æ±è·¯å¾ |
| | | const ${el.vModel}Action = ref('${el.action}') |
| | | // ä¸ä¼ æä»¶å表 |
| | | const ${el.vModel}fileList = ref([])` |
| | | ) |
| | | methodList.push(buildBeforeUpload(el)) |
| | | if (!el['auto-upload']) { |
| | | methodList.push(buildSubmitUpload(el)) |
| | | } |
| | | } |
| | | |
| | | if (el.children) { |
| | | el.children.forEach((el2) => { |
| | | buildAttributes( |
| | | el2, |
| | | dataList, |
| | | ruleList, |
| | | optionsList, |
| | | methodList, |
| | | propsList, |
| | | uploadVarList |
| | | ) |
| | | }) |
| | | } |
| | | } |
| | | /** |
| | | * @name: çæè¡¨åæ°æ®formData |
| | | * @description: çæè¡¨åæ°æ®formData |
| | | * @param {*} conf |
| | | * @param {*} dataList æ°æ®å表 |
| | | * @return {*} |
| | | */ |
| | | function buildData(conf, dataList) { |
| | | if (conf.vModel === undefined) return |
| | | let defaultValue |
| | | if (typeof conf.defaultValue === 'string' && !conf.multiple) { |
| | | defaultValue = `'${conf.defaultValue}'` |
| | | } else { |
| | | defaultValue = `${JSON.stringify(conf.defaultValue)}` |
| | | } |
| | | dataList.push(`${conf.vModel}: ${defaultValue},`) |
| | | } |
| | | /** |
| | | * @name: çæè¡¨åéªè¯æ°æ®rule |
| | | * @description: çæè¡¨åéªè¯æ°æ®rule |
| | | * @param {*} conf |
| | | * @param {*} ruleList éªè¯æ°æ®å表 |
| | | * @return {*} |
| | | */ |
| | | function buildRules(conf, ruleList) { |
| | | if (conf.vModel === undefined) return |
| | | const rules = [] |
| | | if (trigger[conf.tag]) { |
| | | if (conf.required) { |
| | | const type = Array.isArray(conf.defaultValue) ? "type: 'array'," : '' |
| | | let message = Array.isArray(conf.defaultValue) |
| | | ? `请è³å°éæ©ä¸ä¸ª${conf.vModel}` |
| | | : conf.placeholder |
| | | if (message === undefined) message = `${conf.label}ä¸è½ä¸ºç©º` |
| | | rules.push( |
| | | `{ required: true, ${type} message: '${message}', trigger: '${ |
| | | trigger[conf.tag] |
| | | }' }` |
| | | ) |
| | | } |
| | | if (conf.regList && Array.isArray(conf.regList)) { |
| | | conf.regList.forEach((item) => { |
| | | if (item.pattern) { |
| | | rules.push( |
| | | `{ pattern: new RegExp(${item.pattern}), message: '${ |
| | | item.message |
| | | }', trigger: '${trigger[conf.tag]}' }` |
| | | ) |
| | | } |
| | | }) |
| | | } |
| | | ruleList.push(`${conf.vModel}: [${rules.join(',')}],`) |
| | | } |
| | | } |
| | | /** |
| | | * @name: çæéé¡¹æ°æ® |
| | | * @description: çæéé¡¹æ°æ®ï¼åéå¤é䏿ç |
| | | * @param {*} conf |
| | | * @param {*} optionsList éé¡¹æ°æ®å表 |
| | | * @return {*} |
| | | */ |
| | | function buildOptions(conf, optionsList) { |
| | | if (conf.vModel === undefined) return |
| | | if (conf.dataType === 'dynamic') { |
| | | conf.options = [] |
| | | } |
| | | const str = `const ${conf.vModel}Options = ref(${JSON.stringify(conf.options)})` |
| | | optionsList.push(str) |
| | | } |
| | | /** |
| | | * @name: çææ¹æ³ |
| | | * @description: çææ¹æ³ |
| | | * @param {*} methodName æ¹æ³å |
| | | * @param {*} model |
| | | * @param {*} methodList æ¹æ³å表 |
| | | * @return {*} |
| | | */ |
| | | function buildOptionMethod(methodName, model, methodList) { |
| | | const str = `function ${methodName}() { |
| | | // TODO å起请æ±è·åæ°æ® |
| | | ${model}.value |
| | | }` |
| | | methodList.push(str) |
| | | } |
| | | /** |
| | | * @name: çæè¡¨åç»ä»¶éè¦çprops设置 |
| | | * @description: çæè¡¨åç»ä»¶éè¦çprops设置ï¼å¦ï¼çº§èç»ä»¶ |
| | | * @param {*} conf |
| | | * @param {*} propsList |
| | | * @return {*} |
| | | */ |
| | | function buildProps(conf, propsList) { |
| | | if (conf.dataType === 'dynamic') { |
| | | conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey) |
| | | conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey) |
| | | conf.childrenKey !== 'children' && |
| | | (conf.props.props.children = conf.childrenKey) |
| | | } |
| | | const str = ` |
| | | // props设置 |
| | | const ${conf.vModel}Props = ref(${JSON.stringify(conf.props.props)})` |
| | | propsList.push(str) |
| | | } |
| | | /** |
| | | * @name: çæä¸ä¼ ç»ä»¶çç¸å
³å
容 |
| | | * @description: çæä¸ä¼ ç»ä»¶çç¸å
³å
容 |
| | | * @param {*} conf |
| | | * @return {*} |
| | | */ |
| | | function buildBeforeUpload(conf) { |
| | | const unitNum = units[conf.sizeUnit] |
| | | let rightSizeCode = '' |
| | | let acceptCode = '' |
| | | const returnList = [] |
| | | if (conf.fileSize) { |
| | | rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize} |
| | | if(!isRightSize){ |
| | | proxy.$modal.msgError('æä»¶å¤§å°è¶
è¿ ${conf.fileSize}${conf.sizeUnit}') |
| | | }` |
| | | returnList.push('isRightSize') |
| | | } |
| | | if (conf.accept) { |
| | | acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type) |
| | | if(!isAccept){ |
| | | proxy.$modal.msgError('åºè¯¥éæ©${conf.accept}ç±»åçæä»¶') |
| | | }` |
| | | returnList.push('isAccept') |
| | | } |
| | | const str = ` |
| | | /** |
| | | * @name: ä¸ä¼ ä¹åçæä»¶å¤æ |
| | | * @description: ä¸ä¼ ä¹åçæä»¶å¤æï¼å¤ææä»¶å¤§å°æä»¶ç±»åç |
| | | * @param {*} file |
| | | * @return {*} |
| | | */ |
| | | function ${conf.vModel}BeforeUpload(file) { |
| | | ${rightSizeCode} |
| | | ${acceptCode} |
| | | return ${returnList.join('&&')} |
| | | }` |
| | | return returnList.length ? str : '' |
| | | } |
| | | /** |
| | | * @name: çææäº¤è¡¨åæ¹æ³ |
| | | * @description: çææäº¤è¡¨åæ¹æ³ |
| | | * @param {Object} conf vModel 表åref |
| | | * @return {*} |
| | | */ |
| | | function buildSubmitUpload(conf) { |
| | | const str = `function submitUpload() { |
| | | this.$refs['${conf.vModel}'].submit() |
| | | }` |
| | | return str |
| | | } |
| | | /** |
| | | * @name: ç»è£
js代ç |
| | | * @description: ç»è£
jsä»£ç æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function buildexport( |
| | | conf, |
| | | type, |
| | | data, |
| | | rules, |
| | | selectOptions, |
| | | uploadVar, |
| | | props, |
| | | methods |
| | | ) { |
| | | let str = ` |
| | | const { proxy } = getCurrentInstance() |
| | | const ${conf.formRef} = ref() |
| | | const data = reactive({ |
| | | ${conf.formModel}: { |
| | | ${data} |
| | | }, |
| | | ${conf.formRules}: { |
| | | ${rules} |
| | | } |
| | | }) |
| | | |
| | | const {${conf.formModel}, ${conf.formRules}} = toRefs(data) |
| | | |
| | | ${selectOptions} |
| | | |
| | | ${uploadVar} |
| | | |
| | | ${props} |
| | | |
| | | ${methods} |
| | | ` |
| | | |
| | | if(type === 'dialog') { |
| | | str += ` |
| | | // å¼¹çªè®¾ç½® |
| | | const dialogVisible = defineModel() |
| | | // å¼¹çªç¡®è®¤åè° |
| | | const emit = defineEmits(['confirm']) |
| | | /** |
| | | * @name: å¼¹çªæå¼åæ§è¡ |
| | | * @description: å¼¹çªæå¼åæ§è¡æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function onOpen(){ |
| | | |
| | | } |
| | | /** |
| | | * @name: å¼¹çªå
³éæ¶æ§è¡ |
| | | * @description: å¼¹çªå
³éæ¹æ³ï¼é置表å |
| | | * @return {*} |
| | | */ |
| | | function onClose(){ |
| | | ${conf.formRef}.value.resetFields() |
| | | } |
| | | /** |
| | | * @name: å¼¹çªåæ¶ |
| | | * @description: å¼¹çªåæ¶æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function close(){ |
| | | dialogVisible.value = false |
| | | } |
| | | /** |
| | | * @name: å¼¹çªè¡¨åæäº¤ |
| | | * @description: å¼¹çªè¡¨åæäº¤æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function handelConfirm(){ |
| | | ${conf.formRef}.value.validate((valid) => { |
| | | if (!valid) return |
| | | // TODO æäº¤è¡¨å |
| | | |
| | | close() |
| | | // åè°ç¶çº§ç»ä»¶ |
| | | emit('confirm') |
| | | }) |
| | | } |
| | | ` |
| | | } else { |
| | | str += ` |
| | | /** |
| | | * @name: 表åæäº¤ |
| | | * @description: 表åæäº¤æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function submitForm() { |
| | | ${conf.formRef}.value.validate((valid) => { |
| | | if (!valid) return |
| | | // TODO æäº¤è¡¨å |
| | | }) |
| | | } |
| | | /** |
| | | * @name: 表åéç½® |
| | | * @description: 表åéç½®æ¹æ³ |
| | | * @return {*} |
| | | */ |
| | | function resetForm() { |
| | | ${conf.formRef}.value.resetFields() |
| | | } |
| | | ` |
| | | } |
| | | return str |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { defineComponent, h } from 'vue' |
| | | import { makeMap } from '@/utils/index' |
| | | |
| | | const isAttr = makeMap( |
| | | 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,' + |
| | | 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,' + |
| | | 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,' + |
| | | 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,' + |
| | | 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,' + |
| | | 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,' + |
| | | 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,' + |
| | | 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,' + |
| | | 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,' + |
| | | 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,' + |
| | | 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,' + |
| | | 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,' + |
| | | 'target,title,type,usemap,value,width,wrap' + 'prefix-icon' |
| | | ) |
| | | const isNotProps = makeMap( |
| | | 'layout,prepend,regList,tag,document,changeTag,defaultValue' |
| | | ) |
| | | |
| | | function useVModel(props, emit) { |
| | | return { |
| | | modelValue: props.defaultValue, |
| | | 'onUpdate:modelValue': (val) => emit('update:modelValue', val), |
| | | } |
| | | } |
| | | const componentChild = { |
| | | 'el-button': { |
| | | default(h, conf, key) { |
| | | return conf[key] |
| | | }, |
| | | }, |
| | | 'el-select': { |
| | | options(h, conf, key) { |
| | | return conf.options.map(item => h(resolveComponent('el-option'), { |
| | | label: item.label, |
| | | value: item.value, |
| | | })) |
| | | } |
| | | }, |
| | | 'el-radio-group': { |
| | | options(h, conf, key) { |
| | | return conf.optionType === 'button' ? conf.options.map(item => h(resolveComponent('el-checkbox-button'), { |
| | | label: item.value, |
| | | }, () => item.label)) : conf.options.map(item => h(resolveComponent('el-radio'), { |
| | | label: item.value, |
| | | border: conf.border, |
| | | }, () => item.label)) |
| | | } |
| | | }, |
| | | 'el-checkbox-group': { |
| | | options(h, conf, key) { |
| | | return conf.optionType === 'button' ? conf.options.map(item => h(resolveComponent('el-checkbox-button'), { |
| | | label: item.value, |
| | | }, () => item.label)) : conf.options.map(item => h(resolveComponent('el-checkbox'), { |
| | | label: item.value, |
| | | border: conf.border, |
| | | }, () => item.label)) |
| | | } |
| | | }, |
| | | 'el-upload': { |
| | | 'list-type': (h, conf, key) => { |
| | | const option = {} |
| | | // if (conf.showTip) { |
| | | // tip = h('div', { |
| | | // class: "el-upload__tip" |
| | | // }, () => 'åªè½ä¸ä¼ ä¸è¶
è¿' + conf.fileSize + conf.sizeUnit + 'ç' + conf.accept + 'æä»¶') |
| | | // } |
| | | if (conf['list-type'] === 'picture-card') { |
| | | return h(resolveComponent('el-icon'), option, () => h(resolveComponent('Plus'))) |
| | | } else { |
| | | // option.size = "small" |
| | | option.type = "primary" |
| | | option.icon = "Upload" |
| | | return h(resolveComponent('el-button'), option, () => conf.buttonText) |
| | | } |
| | | }, |
| | | |
| | | } |
| | | } |
| | | const componentSlot = { |
| | | 'el-upload': { |
| | | 'tip': (h, conf, key) => { |
| | | if (conf.showTip) { |
| | | return () => h('div', { |
| | | class: "el-upload__tip" |
| | | }, 'åªè½ä¸ä¼ ä¸è¶
è¿' + conf.fileSize + conf.sizeUnit + 'ç' + conf.accept + 'æä»¶') |
| | | } |
| | | }, |
| | | } |
| | | } |
| | | export default defineComponent({ |
| | | |
| | | // ä½¿ç¨ render 彿° |
| | | render() { |
| | | const dataObject = { |
| | | attrs: {}, |
| | | props: {}, |
| | | on: {}, |
| | | style: {} |
| | | } |
| | | const confClone = JSON.parse(JSON.stringify(this.conf)) |
| | | const children = [] |
| | | const slot = {} |
| | | const childObjs = componentChild[confClone.tag] |
| | | if (childObjs) { |
| | | Object.keys(childObjs).forEach(key => { |
| | | const childFunc = childObjs[key] |
| | | if (confClone[key]) { |
| | | children.push(childFunc(h, confClone, key)) |
| | | } |
| | | }) |
| | | } |
| | | const slotObjs = componentSlot[confClone.tag] |
| | | if (slotObjs) { |
| | | Object.keys(slotObjs).forEach(key => { |
| | | const childFunc = slotObjs[key] |
| | | if (confClone[key]) { |
| | | slot[key] = childFunc(h, confClone, key) |
| | | } |
| | | }) |
| | | } |
| | | Object.keys(confClone).forEach(key => { |
| | | const val = confClone[key] |
| | | if (dataObject[key]) { |
| | | dataObject[key] = val |
| | | } else if (isAttr(key)) { |
| | | dataObject.attrs[key] = val |
| | | } else if (!isNotProps(key)) { |
| | | dataObject.props[key] = val |
| | | } |
| | | }) |
| | | if(children.length > 0){ |
| | | slot.default = () => children |
| | | } |
| | | |
| | | return h(resolveComponent(this.conf.tag), |
| | | { |
| | | modelValue: this.$attrs.modelValue, |
| | | ...dataObject.props, |
| | | ...dataObject.attrs, |
| | | style: { |
| | | ...dataObject.style |
| | | }, |
| | | } |
| | | , slot ?? null) |
| | | }, |
| | | props: { |
| | | conf: { |
| | | type: Object, |
| | | required: true, |
| | | }, |
| | | } |
| | | }) |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { parseTime } from './ruoyi' |
| | | |
| | | /** |
| | | * è¡¨æ ¼æ¶é´æ ¼å¼å |
| | | */ |
| | | export function formatDate(cellValue) { |
| | | if (cellValue == null || cellValue == "") return "" |
| | | var date = new Date(cellValue) |
| | | var year = date.getFullYear() |
| | | var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 |
| | | var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() |
| | | var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() |
| | | var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() |
| | | var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() |
| | | return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds |
| | | } |
| | | |
| | | /** |
| | | * @param {number} time |
| | | * @param {string} option |
| | | * @returns {string} |
| | | */ |
| | | export function formatTime(time, option) { |
| | | if (('' + time).length === 10) { |
| | | time = parseInt(time) * 1000 |
| | | } else { |
| | | time = +time |
| | | } |
| | | const d = new Date(time) |
| | | const now = Date.now() |
| | | |
| | | const diff = (now - d) / 1000 |
| | | |
| | | if (diff < 30) { |
| | | return 'åå' |
| | | } else if (diff < 3600) { |
| | | // less 1 hour |
| | | return Math.ceil(diff / 60) + 'åéå' |
| | | } else if (diff < 3600 * 24) { |
| | | return Math.ceil(diff / 3600) + 'å°æ¶å' |
| | | } else if (diff < 3600 * 24 * 2) { |
| | | return '1天å' |
| | | } |
| | | if (option) { |
| | | return parseTime(time, option) |
| | | } else { |
| | | return ( |
| | | d.getMonth() + |
| | | 1 + |
| | | 'æ' + |
| | | d.getDate() + |
| | | 'æ¥' + |
| | | d.getHours() + |
| | | 'æ¶' + |
| | | d.getMinutes() + |
| | | 'å' |
| | | ) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @param {string} url |
| | | * @returns {Object} |
| | | */ |
| | | export function getQueryObject(url) { |
| | | url = url == null ? window.location.href : url |
| | | const search = url.substring(url.lastIndexOf('?') + 1) |
| | | const obj = {} |
| | | const reg = /([^?&=]+)=([^?&=]*)/g |
| | | search.replace(reg, (rs, $1, $2) => { |
| | | const name = decodeURIComponent($1) |
| | | let val = decodeURIComponent($2) |
| | | val = String(val) |
| | | obj[name] = val |
| | | return rs |
| | | }) |
| | | return obj |
| | | } |
| | | |
| | | /** |
| | | * @param {string} input value |
| | | * @returns {number} output value |
| | | */ |
| | | export function byteLength(str) { |
| | | // returns the byte length of an utf8 string |
| | | let s = str.length |
| | | for (var i = str.length - 1; i >= 0; i--) { |
| | | const code = str.charCodeAt(i) |
| | | if (code > 0x7f && code <= 0x7ff) s++ |
| | | else if (code > 0x7ff && code <= 0xffff) s += 2 |
| | | if (code >= 0xDC00 && code <= 0xDFFF) i-- |
| | | } |
| | | return s |
| | | } |
| | | |
| | | /** |
| | | * @param {Array} actual |
| | | * @returns {Array} |
| | | */ |
| | | export function cleanArray(actual) { |
| | | const newArray = [] |
| | | for (let i = 0; i < actual.length; i++) { |
| | | if (actual[i]) { |
| | | newArray.push(actual[i]) |
| | | } |
| | | } |
| | | return newArray |
| | | } |
| | | |
| | | /** |
| | | * @param {Object} json |
| | | * @returns {Array} |
| | | */ |
| | | export function param(json) { |
| | | if (!json) return '' |
| | | return cleanArray( |
| | | Object.keys(json).map(key => { |
| | | if (json[key] === undefined) return '' |
| | | return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]) |
| | | }) |
| | | ).join('&') |
| | | } |
| | | |
| | | /** |
| | | * @param {string} url |
| | | * @returns {Object} |
| | | */ |
| | | export function param2Obj(url) { |
| | | const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') |
| | | if (!search) { |
| | | return {} |
| | | } |
| | | const obj = {} |
| | | const searchArr = search.split('&') |
| | | searchArr.forEach(v => { |
| | | const index = v.indexOf('=') |
| | | if (index !== -1) { |
| | | const name = v.substring(0, index) |
| | | const val = v.substring(index + 1, v.length) |
| | | obj[name] = val |
| | | } |
| | | }) |
| | | return obj |
| | | } |
| | | |
| | | /** |
| | | * @param {string} val |
| | | * @returns {string} |
| | | */ |
| | | export function html2Text(val) { |
| | | const div = document.createElement('div') |
| | | div.innerHTML = val |
| | | return div.textContent || div.innerText |
| | | } |
| | | |
| | | /** |
| | | * Merges two objects, giving the last one precedence |
| | | * @param {Object} target |
| | | * @param {(Object|Array)} source |
| | | * @returns {Object} |
| | | */ |
| | | export function objectMerge(target, source) { |
| | | if (typeof target !== 'object') { |
| | | target = {} |
| | | } |
| | | if (Array.isArray(source)) { |
| | | return source.slice() |
| | | } |
| | | Object.keys(source).forEach(property => { |
| | | const sourceProperty = source[property] |
| | | if (typeof sourceProperty === 'object') { |
| | | target[property] = objectMerge(target[property], sourceProperty) |
| | | } else { |
| | | target[property] = sourceProperty |
| | | } |
| | | }) |
| | | return target |
| | | } |
| | | |
| | | /** |
| | | * @param {HTMLElement} element |
| | | * @param {string} className |
| | | */ |
| | | export function toggleClass(element, className) { |
| | | if (!element || !className) { |
| | | return |
| | | } |
| | | let classString = element.className |
| | | const nameIndex = classString.indexOf(className) |
| | | if (nameIndex === -1) { |
| | | classString += '' + className |
| | | } else { |
| | | classString = |
| | | classString.substr(0, nameIndex) + |
| | | classString.substr(nameIndex + className.length) |
| | | } |
| | | element.className = classString |
| | | } |
| | | |
| | | /** |
| | | * @param {string} type |
| | | * @returns {Date} |
| | | */ |
| | | export function getTime(type) { |
| | | if (type === 'start') { |
| | | return new Date().getTime() - 3600 * 1000 * 24 * 90 |
| | | } else { |
| | | return new Date(new Date().toDateString()) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @param {Function} func |
| | | * @param {number} wait |
| | | * @param {boolean} immediate |
| | | * @return {*} |
| | | */ |
| | | export function debounce(func, wait, immediate) { |
| | | let timeout, args, context, timestamp, result |
| | | |
| | | const later = function() { |
| | | // æ®ä¸ä¸æ¬¡è§¦åæ¶é´é´é |
| | | const last = +new Date() - timestamp |
| | | |
| | | // 䏿¬¡è¢«å
è£
彿°è¢«è°ç¨æ¶é´é´é last å°äºè®¾å®æ¶é´é´é wait |
| | | if (last < wait && last > 0) { |
| | | timeout = setTimeout(later, wait - last) |
| | | } else { |
| | | timeout = null |
| | | // å¦æè®¾å®ä¸ºimmediate===trueï¼å 为å¼å§è¾¹çå·²ç»è°ç¨è¿äºæ¤å¤æ éè°ç¨ |
| | | if (!immediate) { |
| | | result = func.apply(context, args) |
| | | if (!timeout) context = args = null |
| | | } |
| | | } |
| | | } |
| | | |
| | | return function(...args) { |
| | | context = this |
| | | timestamp = +new Date() |
| | | const callNow = immediate && !timeout |
| | | // 妿延æ¶ä¸åå¨ï¼éæ°è®¾å®å»¶æ¶ |
| | | if (!timeout) timeout = setTimeout(later, wait) |
| | | if (callNow) { |
| | | result = func.apply(context, args) |
| | | context = args = null |
| | | } |
| | | |
| | | return result |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * This is just a simple version of deep copy |
| | | * Has a lot of edge cases bug |
| | | * If you want to use a perfect deep copy, use lodash's _.cloneDeep |
| | | * @param {Object} source |
| | | * @returns {Object} |
| | | */ |
| | | export function deepClone(source) { |
| | | if (!source && typeof source !== 'object') { |
| | | throw new Error('error arguments', 'deepClone') |
| | | } |
| | | const targetObj = source.constructor === Array ? [] : {} |
| | | Object.keys(source).forEach(keys => { |
| | | if (source[keys] && typeof source[keys] === 'object') { |
| | | targetObj[keys] = deepClone(source[keys]) |
| | | } else { |
| | | targetObj[keys] = source[keys] |
| | | } |
| | | }) |
| | | return targetObj |
| | | } |
| | | |
| | | /** |
| | | * @param {Array} arr |
| | | * @returns {Array} |
| | | */ |
| | | export function uniqueArr(arr) { |
| | | return Array.from(new Set(arr)) |
| | | } |
| | | |
| | | /** |
| | | * @returns {string} |
| | | */ |
| | | export function createUniqueString() { |
| | | const timestamp = +new Date() + '' |
| | | const randomNum = parseInt((1 + Math.random()) * 65536) + '' |
| | | return (+(randomNum + timestamp)).toString(32) |
| | | } |
| | | |
| | | /** |
| | | * Check if an element has a class |
| | | * @param {HTMLElement} elm |
| | | * @param {string} cls |
| | | * @returns {boolean} |
| | | */ |
| | | export function hasClass(ele, cls) { |
| | | return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) |
| | | } |
| | | |
| | | /** |
| | | * Add class to element |
| | | * @param {HTMLElement} elm |
| | | * @param {string} cls |
| | | */ |
| | | export function addClass(ele, cls) { |
| | | if (!hasClass(ele, cls)) ele.className += ' ' + cls |
| | | } |
| | | |
| | | /** |
| | | * Remove class from element |
| | | * @param {HTMLElement} elm |
| | | * @param {string} cls |
| | | */ |
| | | export function removeClass(ele, cls) { |
| | | if (hasClass(ele, cls)) { |
| | | const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)') |
| | | ele.className = ele.className.replace(reg, ' ') |
| | | } |
| | | } |
| | | |
| | | export function makeMap(str, expectsLowerCase) { |
| | | const map = Object.create(null) |
| | | const list = str.split(',') |
| | | for (let i = 0; i < list.length; i++) { |
| | | map[list[i]] = true |
| | | } |
| | | return expectsLowerCase |
| | | ? val => map[val.toLowerCase()] |
| | | : val => map[val] |
| | | } |
| | | |
| | | export const exportDefault = 'export default ' |
| | | |
| | | export const beautifierConf = { |
| | | html: { |
| | | indent_size: '2', |
| | | indent_char: ' ', |
| | | max_preserve_newlines: '-1', |
| | | preserve_newlines: false, |
| | | keep_array_indentation: false, |
| | | break_chained_methods: false, |
| | | indent_scripts: 'separate', |
| | | brace_style: 'end-expand', |
| | | space_before_conditional: true, |
| | | unescape_strings: false, |
| | | jslint_happy: false, |
| | | end_with_newline: true, |
| | | wrap_line_length: '110', |
| | | indent_inner_html: true, |
| | | comma_first: false, |
| | | e4x: true, |
| | | indent_empty_lines: true |
| | | }, |
| | | js: { |
| | | indent_size: '2', |
| | | indent_char: ' ', |
| | | max_preserve_newlines: '-1', |
| | | preserve_newlines: false, |
| | | keep_array_indentation: false, |
| | | break_chained_methods: false, |
| | | indent_scripts: 'normal', |
| | | brace_style: 'end-expand', |
| | | space_before_conditional: true, |
| | | unescape_strings: false, |
| | | jslint_happy: true, |
| | | end_with_newline: true, |
| | | wrap_line_length: '110', |
| | | indent_inner_html: true, |
| | | comma_first: false, |
| | | e4x: true, |
| | | indent_empty_lines: true |
| | | } |
| | | } |
| | | |
| | | // é¦åæ¯å¤§å° |
| | | export function titleCase(str) { |
| | | return str.replace(/( |^)[a-z]/g, L => L.toUpperCase()) |
| | | } |
| | | |
| | | // ä¸å转驼峰 |
| | | export function camelCase(str) { |
| | | return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase()) |
| | | } |
| | | |
| | | export function isNumberStr(str) { |
| | | return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import JSEncrypt from 'jsencrypt/bin/jsencrypt.min' |
| | | |
| | | // å¯é¥å¯¹çæ http://web.chacuo.net/netrsakeypair |
| | | |
| | | const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + |
| | | 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==' |
| | | |
| | | const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' + |
| | | '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' + |
| | | 'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' + |
| | | 'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' + |
| | | 'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' + |
| | | 'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' + |
| | | 'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' + |
| | | 'UP8iWi1Qw0Y=' |
| | | |
| | | // å å¯ |
| | | export function encrypt(txt) { |
| | | const encryptor = new JSEncrypt() |
| | | encryptor.setPublicKey(publicKey) // 设置å
¬é¥ |
| | | return encryptor.encrypt(txt) // å¯¹æ°æ®è¿è¡å å¯ |
| | | } |
| | | |
| | | // è§£å¯ |
| | | export function decrypt(txt) { |
| | | const encryptor = new JSEncrypt() |
| | | encryptor.setPrivateKey(privateKey) // 设置ç§é¥ |
| | | return encryptor.decrypt(txt) // å¯¹æ°æ®è¿è¡è§£å¯ |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import useUserStore from '@/store/modules/user' |
| | | |
| | | /** |
| | | * å符æéæ ¡éª |
| | | * @param {Array} value æ ¡éªå¼ |
| | | * @returns {Boolean} |
| | | */ |
| | | export function checkPermi(value) { |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const permissions = useUserStore().permissions |
| | | const permissionDatas = value |
| | | const all_permission = "*:*:*" |
| | | |
| | | const hasPermission = permissions.some(permission => { |
| | | return all_permission === permission || permissionDatas.includes(permission) |
| | | }) |
| | | |
| | | if (!hasPermission) { |
| | | return false |
| | | } |
| | | return true |
| | | } else { |
| | | console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`) |
| | | return false |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è§è²æéæ ¡éª |
| | | * @param {Array} value æ ¡éªå¼ |
| | | * @returns {Boolean} |
| | | */ |
| | | export function checkRole(value) { |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const roles = useUserStore().roles |
| | | const permissionRoles = value |
| | | const super_admin = "admin" |
| | | |
| | | const hasRole = roles.some(role => { |
| | | return super_admin === role || permissionRoles.includes(role) |
| | | }) |
| | | |
| | | if (!hasRole) { |
| | | return false |
| | | } |
| | | return true |
| | | } else { |
| | | console.error(`need roles! Like checkRole="['admin','editor']"`) |
| | | return false |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import axios from 'axios' |
| | | import { ElNotification , ElMessageBox, ElMessage, ElLoading } from 'element-plus' |
| | | import { getToken } from '@/utils/auth' |
| | | import errorCode from '@/utils/errorCode' |
| | | import { tansParams, blobValidate } from '@/utils/ruoyi' |
| | | import cache from '@/plugins/cache' |
| | | import { saveAs } from 'file-saver' |
| | | import useUserStore from '@/store/modules/user' |
| | | |
| | | let downloadLoadingInstance |
| | | // æ¯å¦æ¾ç¤ºéæ°ç»å½ |
| | | export let isRelogin = { show: false } |
| | | |
| | | axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' |
| | | // å建axioså®ä¾ |
| | | const service = axios.create({ |
| | | // axiosä¸è¯·æ±é
ç½®æbaseURLé项ï¼è¡¨ç¤ºè¯·æ±URLå
Œ
±é¨å |
| | | baseURL: import.meta.env.VITE_APP_BASE_API, |
| | | // è¶
æ¶ |
| | | timeout: 10000 |
| | | }) |
| | | |
| | | // requestæ¦æªå¨ |
| | | service.interceptors.request.use(config => { |
| | | // æ¯å¦éè¦è®¾ç½® token |
| | | const isToken = (config.headers || {}).isToken === false |
| | | // æ¯å¦éè¦é²æ¢æ°æ®éå¤æäº¤ |
| | | const isRepeatSubmit = (config.headers || {}).repeatSubmit === false |
| | | if (getToken() && !isToken) { |
| | | config.headers['Authorization'] = 'Bearer ' + getToken() // 让æ¯ä¸ªè¯·æ±æºå¸¦èªå®ä¹token è¯·æ ¹æ®å®é
æ
åµèªè¡ä¿®æ¹ |
| | | } |
| | | // getè¯·æ±æ å°paramsåæ° |
| | | if (config.method === 'get' && config.params) { |
| | | let url = config.url + '?' + tansParams(config.params) |
| | | url = url.slice(0, -1) |
| | | config.params = {} |
| | | config.url = url |
| | | } |
| | | if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { |
| | | const requestObj = { |
| | | url: config.url, |
| | | data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, |
| | | time: new Date().getTime() |
| | | } |
| | | const requestSize = Object.keys(JSON.stringify(requestObj)).length // è¯·æ±æ°æ®å¤§å° |
| | | const limitSize = 5 * 1024 * 1024 // éå¶åæ¾æ°æ®5M |
| | | if (requestSize >= limitSize) { |
| | | console.warn(`[${config.url}]: ` + 'è¯·æ±æ°æ®å¤§å°è¶
åºå
许ç5Méå¶ï¼æ æ³è¿è¡é²éå¤æäº¤éªè¯ã') |
| | | return config |
| | | } |
| | | const sessionObj = cache.session.getJSON('sessionObj') |
| | | if (sessionObj === undefined || sessionObj === null || sessionObj === '') { |
| | | cache.session.setJSON('sessionObj', requestObj) |
| | | } else { |
| | | const s_url = sessionObj.url // 请æ±å°å |
| | | const s_data = sessionObj.data // è¯·æ±æ°æ® |
| | | const s_time = sessionObj.time // è¯·æ±æ¶é´ |
| | | const interval = 1000 // é´éæ¶é´(ms)ï¼å°äºæ¤æ¶é´è§ä¸ºéå¤æäº¤ |
| | | if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { |
| | | const message = 'æ°æ®æ£å¨å¤çï¼è¯·å¿éå¤æäº¤' |
| | | console.warn(`[${s_url}]: ` + message) |
| | | return Promise.reject(new Error(message)) |
| | | } else { |
| | | cache.session.setJSON('sessionObj', requestObj) |
| | | } |
| | | } |
| | | } |
| | | return config |
| | | }, error => { |
| | | console.log(error) |
| | | Promise.reject(error) |
| | | }) |
| | | |
| | | // ååºæ¦æªå¨ |
| | | service.interceptors.response.use(res => { |
| | | // æªè®¾ç½®ç¶æç åé»è®¤æåç¶æ |
| | | const code = res.data.code || 200 |
| | | // è·åéè¯¯ä¿¡æ¯ |
| | | const msg = errorCode[code] || res.data.msg || errorCode['default'] |
| | | // äºè¿å¶æ°æ®åç´æ¥è¿å |
| | | if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { |
| | | return res.data |
| | | } |
| | | if (code === 401) { |
| | | if (!isRelogin.show) { |
| | | isRelogin.show = true |
| | | ElMessageBox.confirm('ç»å½ç¶æå·²è¿æï¼æ¨å¯ä»¥ç»§ç»çå¨è¯¥é¡µé¢ï¼æè
éæ°ç»å½', 'ç³»ç»æç¤º', { confirmButtonText: 'éæ°ç»å½', cancelButtonText: 'åæ¶', type: 'warning' }).then(() => { |
| | | isRelogin.show = false |
| | | useUserStore().logOut().then(() => { |
| | | location.href = '/index' |
| | | }) |
| | | }).catch(() => { |
| | | isRelogin.show = false |
| | | }) |
| | | } |
| | | return Promise.reject('æ æçä¼è¯ï¼æè
ä¼è¯å·²è¿æï¼è¯·éæ°ç»å½ã') |
| | | } else if (code === 500) { |
| | | ElMessage({ message: msg, type: 'error' }) |
| | | return Promise.reject(new Error(msg)) |
| | | } else if (code === 601) { |
| | | ElMessage({ message: msg, type: 'warning' }) |
| | | return Promise.reject(new Error(msg)) |
| | | } else if (code !== 200) { |
| | | ElNotification.error({ title: msg }) |
| | | return Promise.reject('error') |
| | | } else { |
| | | return Promise.resolve(res.data) |
| | | } |
| | | }, |
| | | error => { |
| | | console.log('err' + error) |
| | | let { message } = error |
| | | if (message == "Network Error") { |
| | | message = "å端æ¥å£è¿æ¥å¼å¸¸" |
| | | } else if (message.includes("timeout")) { |
| | | message = "ç³»ç»æ¥å£è¯·æ±è¶
æ¶" |
| | | } else if (message.includes("Request failed with status code")) { |
| | | message = "ç³»ç»æ¥å£" + message.substr(message.length - 3) + "å¼å¸¸" |
| | | } |
| | | ElMessage({ message: message, type: 'error', duration: 5 * 1000 }) |
| | | return Promise.reject(error) |
| | | } |
| | | ) |
| | | |
| | | // éç¨ä¸è½½æ¹æ³ |
| | | export function download(url, params, filename, config) { |
| | | downloadLoadingInstance = ElLoading.service({ text: "æ£å¨ä¸è½½æ°æ®ï¼è¯·ç¨å", background: "rgba(0, 0, 0, 0.7)", }) |
| | | return service.post(url, params, { |
| | | transformRequest: [(params) => { return tansParams(params) }], |
| | | headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, |
| | | responseType: 'blob', |
| | | ...config |
| | | }).then(async (data) => { |
| | | const isBlob = blobValidate(data) |
| | | if (isBlob) { |
| | | const blob = new Blob([data]) |
| | | saveAs(blob, filename) |
| | | } else { |
| | | const resText = await data.text() |
| | | const rspObj = JSON.parse(resText) |
| | | const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] |
| | | ElMessage.error(errMsg) |
| | | } |
| | | downloadLoadingInstance.close() |
| | | }).catch((r) => { |
| | | console.error(r) |
| | | ElMessage.error('ä¸è½½æä»¶åºç°é误ï¼è¯·è系管çåï¼') |
| | | downloadLoadingInstance.close() |
| | | }) |
| | | } |
| | | |
| | | export default service |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * éç¨jsæ¹æ³å°è£
å¤ç |
| | | * Copyright (c) 2019 ruoyi |
| | | */ |
| | | |
| | | // æ¥ææ ¼å¼å |
| | | export function parseTime(time, pattern) { |
| | | if (arguments.length === 0 || !time) { |
| | | return null |
| | | } |
| | | const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}' |
| | | let date |
| | | if (typeof time === 'object') { |
| | | date = time |
| | | } else { |
| | | if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { |
| | | time = parseInt(time) |
| | | } else if (typeof time === 'string') { |
| | | time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '') |
| | | } |
| | | if ((typeof time === 'number') && (time.toString().length === 10)) { |
| | | time = time * 1000 |
| | | } |
| | | date = new Date(time) |
| | | } |
| | | const formatObj = { |
| | | y: date.getFullYear(), |
| | | m: date.getMonth() + 1, |
| | | d: date.getDate(), |
| | | h: date.getHours(), |
| | | i: date.getMinutes(), |
| | | s: date.getSeconds(), |
| | | a: date.getDay() |
| | | } |
| | | const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { |
| | | let value = formatObj[key] |
| | | // Note: getDay() returns 0 on Sunday |
| | | if (key === 'a') { return ['æ¥', 'ä¸', 'äº', 'ä¸', 'å', 'äº', 'å
'][value] } |
| | | if (result.length > 0 && value < 10) { |
| | | value = '0' + value |
| | | } |
| | | return value || 0 |
| | | }) |
| | | return time_str |
| | | } |
| | | |
| | | // 表åéç½® |
| | | export function resetForm(refName) { |
| | | if (this.$refs[refName]) { |
| | | this.$refs[refName].resetFields() |
| | | } |
| | | } |
| | | |
| | | // æ·»å æ¥æèå´ |
| | | export function addDateRange(params, dateRange, propName) { |
| | | let search = params |
| | | search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {} |
| | | dateRange = Array.isArray(dateRange) ? dateRange : [] |
| | | if (typeof (propName) === 'undefined') { |
| | | search.params['beginTime'] = dateRange[0] |
| | | search.params['endTime'] = dateRange[1] |
| | | } else { |
| | | search.params['begin' + propName] = dateRange[0] |
| | | search.params['end' + propName] = dateRange[1] |
| | | } |
| | | return search |
| | | } |
| | | |
| | | // åæ¾æ°æ®åå
¸ |
| | | export function selectDictLabel(datas, value) { |
| | | if (value === undefined) { |
| | | return "" |
| | | } |
| | | var actions = [] |
| | | Object.keys(datas).some((key) => { |
| | | if (datas[key].value == ('' + value)) { |
| | | actions.push(datas[key].label) |
| | | return true |
| | | } |
| | | }) |
| | | if (actions.length === 0) { |
| | | actions.push(value) |
| | | } |
| | | return actions.join('') |
| | | } |
| | | |
| | | // åæ¾æ°æ®åå
¸ï¼åç¬¦ä¸²ãæ°ç»ï¼ |
| | | export function selectDictLabels(datas, value, separator) { |
| | | if (value === undefined || value.length ===0) { |
| | | return "" |
| | | } |
| | | if (Array.isArray(value)) { |
| | | value = value.join(",") |
| | | } |
| | | var actions = [] |
| | | var currentSeparator = undefined === separator ? "," : separator |
| | | var temp = value.split(currentSeparator) |
| | | Object.keys(value.split(currentSeparator)).some((val) => { |
| | | var match = false |
| | | Object.keys(datas).some((key) => { |
| | | if (datas[key].value == ('' + temp[val])) { |
| | | actions.push(datas[key].label + currentSeparator) |
| | | match = true |
| | | } |
| | | }) |
| | | if (!match) { |
| | | actions.push(temp[val] + currentSeparator) |
| | | } |
| | | }) |
| | | return actions.join('').substring(0, actions.join('').length - 1) |
| | | } |
| | | |
| | | // åç¬¦ä¸²æ ¼å¼å(%s ) |
| | | export function sprintf(str) { |
| | | var args = arguments, flag = true, i = 1 |
| | | str = str.replace(/%s/g, function () { |
| | | var arg = args[i++] |
| | | if (typeof arg === 'undefined') { |
| | | flag = false |
| | | return '' |
| | | } |
| | | return arg |
| | | }) |
| | | return flag ? str : '' |
| | | } |
| | | |
| | | // 转æ¢å符串ï¼undefined,nullç转å为"" |
| | | export function parseStrEmpty(str) { |
| | | if (!str || str == "undefined" || str == "null") { |
| | | return "" |
| | | } |
| | | return str |
| | | } |
| | | |
| | | // æ°æ®åå¹¶ |
| | | export function mergeRecursive(source, target) { |
| | | for (var p in target) { |
| | | try { |
| | | if (target[p].constructor == Object) { |
| | | source[p] = mergeRecursive(source[p], target[p]) |
| | | } else { |
| | | source[p] = target[p] |
| | | } |
| | | } catch (e) { |
| | | source[p] = target[p] |
| | | } |
| | | } |
| | | return source |
| | | } |
| | | |
| | | /** |
| | | * æé æ åç»ææ°æ® |
| | | * @param {*} data æ°æ®æº |
| | | * @param {*} id idåæ®µ é»è®¤ 'id' |
| | | * @param {*} parentId ç¶èç¹å段 é»è®¤ 'parentId' |
| | | * @param {*} children å©åèç¹å段 é»è®¤ 'children' |
| | | */ |
| | | export function handleTree(data, id, parentId, children) { |
| | | let config = { |
| | | id: id || 'id', |
| | | parentId: parentId || 'parentId', |
| | | childrenList: children || 'children' |
| | | } |
| | | |
| | | var childrenListMap = {} |
| | | var tree = [] |
| | | for (let d of data) { |
| | | let id = d[config.id] |
| | | childrenListMap[id] = d |
| | | if (!d[config.childrenList]) { |
| | | d[config.childrenList] = [] |
| | | } |
| | | } |
| | | |
| | | for (let d of data) { |
| | | let parentId = d[config.parentId] |
| | | let parentObj = childrenListMap[parentId] |
| | | if (!parentObj) { |
| | | tree.push(d) |
| | | } else { |
| | | parentObj[config.childrenList].push(d) |
| | | } |
| | | } |
| | | return tree |
| | | } |
| | | |
| | | /** |
| | | * åæ°å¤ç |
| | | * @param {*} params åæ° |
| | | */ |
| | | export function tansParams(params) { |
| | | let result = '' |
| | | for (const propName of Object.keys(params)) { |
| | | const value = params[propName] |
| | | var part = encodeURIComponent(propName) + "=" |
| | | if (value !== null && value !== "" && typeof (value) !== "undefined") { |
| | | if (typeof value === 'object') { |
| | | for (const key of Object.keys(value)) { |
| | | if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') { |
| | | let params = propName + '[' + key + ']' |
| | | var subPart = encodeURIComponent(params) + "=" |
| | | result += subPart + encodeURIComponent(value[key]) + "&" |
| | | } |
| | | } |
| | | } else { |
| | | result += part + encodeURIComponent(value) + "&" |
| | | } |
| | | } |
| | | } |
| | | return result |
| | | } |
| | | |
| | | // è¿å项ç®è·¯å¾ |
| | | export function getNormalPath(p) { |
| | | if (p.length === 0 || !p || p == 'undefined') { |
| | | return p |
| | | } |
| | | let res = p.replace('//', '/') |
| | | if (res[res.length - 1] === '/') { |
| | | return res.slice(0, res.length - 1) |
| | | } |
| | | return res |
| | | } |
| | | |
| | | // éªè¯æ¯å¦ä¸ºblobæ ¼å¼ |
| | | export function blobValidate(data) { |
| | | return data.type !== 'application/json' |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | Math.easeInOutQuad = function(t, b, c, d) { |
| | | t /= d / 2 |
| | | if (t < 1) { |
| | | return c / 2 * t * t + b |
| | | } |
| | | t-- |
| | | return -c / 2 * (t * (t - 2) - 1) + b |
| | | } |
| | | |
| | | // requestAnimationFrame for Smart Animating http://goo.gl/sx5sts |
| | | var requestAnimFrame = (function() { |
| | | return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } |
| | | })() |
| | | |
| | | /** |
| | | * Because it's so fucking difficult to detect the scrolling element, just move them all |
| | | * @param {number} amount |
| | | */ |
| | | function move(amount) { |
| | | document.documentElement.scrollTop = amount |
| | | document.body.parentNode.scrollTop = amount |
| | | document.body.scrollTop = amount |
| | | } |
| | | |
| | | function position() { |
| | | return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop |
| | | } |
| | | |
| | | /** |
| | | * @param {number} to |
| | | * @param {number} duration |
| | | * @param {Function} callback |
| | | */ |
| | | export function scrollTo(to, duration, callback) { |
| | | const start = position() |
| | | const change = to - start |
| | | const increment = 20 |
| | | let currentTime = 0 |
| | | duration = (typeof (duration) === 'undefined') ? 500 : duration |
| | | var animateScroll = function() { |
| | | // increment the time |
| | | currentTime += increment |
| | | // find the value with the quadratic in-out easing function |
| | | var val = Math.easeInOutQuad(currentTime, start, change, duration) |
| | | // move the document.body |
| | | move(val) |
| | | // do the animation unless its over |
| | | if (currentTime < duration) { |
| | | requestAnimFrame(animateScroll) |
| | | } else { |
| | | if (callback && typeof (callback) === 'function') { |
| | | // the animation is done so lets callback |
| | | callback() |
| | | } |
| | | } |
| | | } |
| | | animateScroll() |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | // å¤ç䏻颿 ·å¼ |
| | | export function handleThemeStyle(theme) { |
| | | document.documentElement.style.setProperty('--el-color-primary', theme) |
| | | for (let i = 1; i <= 9; i++) { |
| | | document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(theme, i / 10)}`) |
| | | } |
| | | for (let i = 1; i <= 9; i++) { |
| | | document.documentElement.style.setProperty(`--el-color-primary-dark-${i}`, `${getDarkColor(theme, i / 10)}`) |
| | | } |
| | | } |
| | | |
| | | // hexé¢è²è½¬rgbé¢è² |
| | | export function hexToRgb(str) { |
| | | str = str.replace('#', '') |
| | | let hexs = str.match(/../g) |
| | | for (let i = 0; i < 3; i++) { |
| | | hexs[i] = parseInt(hexs[i], 16) |
| | | } |
| | | return hexs |
| | | } |
| | | |
| | | // rgbé¢è²è½¬Hexé¢è² |
| | | export function rgbToHex(r, g, b) { |
| | | let hexs = [r.toString(16), g.toString(16), b.toString(16)] |
| | | for (let i = 0; i < 3; i++) { |
| | | if (hexs[i].length == 1) { |
| | | hexs[i] = `0${hexs[i]}` |
| | | } |
| | | } |
| | | return `#${hexs.join('')}` |
| | | } |
| | | |
| | | // åæµ
é¢è²å¼ |
| | | export function getLightColor(color, level) { |
| | | let rgb = hexToRgb(color) |
| | | for (let i = 0; i < 3; i++) { |
| | | rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]) |
| | | } |
| | | return rgbToHex(rgb[0], rgb[1], rgb[2]) |
| | | } |
| | | |
| | | // åæ·±é¢è²å¼ |
| | | export function getDarkColor(color, level) { |
| | | let rgb = hexToRgb(color) |
| | | for (let i = 0; i < 3; i++) { |
| | | rgb[i] = Math.floor(rgb[i] * (1 - level)) |
| | | } |
| | | return rgbToHex(rgb[0], rgb[1], rgb[2]) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * è·¯å¾å¹é
å¨ |
| | | * @param {string} pattern |
| | | * @param {string} path |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isPathMatch(pattern, path) { |
| | | const regexPattern = pattern.replace(/\//g, '\\/').replace(/\*\*/g, '.*').replace(/\*/g, '[^\\/]*') |
| | | const regex = new RegExp(`^${regexPattern}$`) |
| | | return regex.test(path) |
| | | } |
| | | |
| | | /** |
| | | * 夿valueå符串æ¯å¦ä¸ºç©º |
| | | * @param {string} value |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isEmpty(value) { |
| | | if (value == null || value == "" || value == undefined || value == "undefined") { |
| | | return true |
| | | } |
| | | return false |
| | | } |
| | | |
| | | /** |
| | | * 夿urlæ¯å¦æ¯httpæhttps |
| | | * @param {string} url |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isHttp(url) { |
| | | return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1 |
| | | } |
| | | |
| | | /** |
| | | * 夿pathæ¯å¦ä¸ºå¤é¾ |
| | | * @param {string} path |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isExternal(path) { |
| | | return /^(https?:|mailto:|tel:)/.test(path) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} str |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validUsername(str) { |
| | | const valid_map = ['admin', 'editor'] |
| | | return valid_map.indexOf(str.trim()) >= 0 |
| | | } |
| | | |
| | | /** |
| | | * @param {string} url |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validURL(url) { |
| | | const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ |
| | | return reg.test(url) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} str |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validLowerCase(str) { |
| | | const reg = /^[a-z]+$/ |
| | | return reg.test(str) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} str |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validUpperCase(str) { |
| | | const reg = /^[A-Z]+$/ |
| | | return reg.test(str) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} str |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validAlphabets(str) { |
| | | const reg = /^[A-Za-z]+$/ |
| | | return reg.test(str) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} email |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validEmail(email) { |
| | | const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ |
| | | return reg.test(email) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} str |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isString(str) { |
| | | return typeof str === 'string' || str instanceof String |
| | | } |
| | | |
| | | /** |
| | | * @param {Array} arg |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isArray(arg) { |
| | | if (typeof Array.isArray === 'undefined') { |
| | | return Object.prototype.toString.call(arg) === '[object Array]' |
| | | } |
| | | return Array.isArray(arg) |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="errPage-container"> |
| | | <el-button icon="arrow-left" class="pan-back-btn" @click="back"> |
| | | è¿å |
| | | </el-button> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <h1 class="text-jumbo text-ginormous"> |
| | | 401é误! |
| | | </h1> |
| | | <h2>æ¨æ²¡æè®¿é®æéï¼</h2> |
| | | <h6>对ä¸èµ·ï¼æ¨æ²¡æè®¿é®æéï¼è¯·ä¸è¦è¿è¡éæ³æä½ï¼æ¨å¯ä»¥è¿å主页é¢</h6> |
| | | <ul class="list-unstyled"> |
| | | <li class="link-type"> |
| | | <router-link to="/"> |
| | | åé¦é¡µ |
| | | </router-link> |
| | | </li> |
| | | </ul> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream."> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import errImage from "@/assets/401_images/401.gif" |
| | | |
| | | let { proxy } = getCurrentInstance() |
| | | |
| | | const errGif = ref(errImage + "?" + +new Date()) |
| | | |
| | | function back() { |
| | | if (proxy.$route.query.noGoBack) { |
| | | proxy.$router.push({ path: "/" }) |
| | | } else { |
| | | proxy.$router.go(-1) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .errPage-container { |
| | | width: 800px; |
| | | max-width: 100%; |
| | | margin: 100px auto; |
| | | .pan-back-btn { |
| | | background: #008489; |
| | | color: #fff; |
| | | border: none !important; |
| | | } |
| | | .pan-gif { |
| | | margin: 0 auto; |
| | | display: block; |
| | | } |
| | | .pan-img { |
| | | display: block; |
| | | margin: 0 auto; |
| | | width: 100%; |
| | | } |
| | | .text-jumbo { |
| | | font-size: 60px; |
| | | font-weight: 700; |
| | | color: #484848; |
| | | } |
| | | .list-unstyled { |
| | | font-size: 14px; |
| | | li { |
| | | padding-bottom: 5px; |
| | | } |
| | | a { |
| | | color: #008489; |
| | | text-decoration: none; |
| | | &:hover { |
| | | text-decoration: underline; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="wscn-http404-container"> |
| | | <div class="wscn-http404"> |
| | | <div class="pic-404"> |
| | | <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404"> |
| | | <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404"> |
| | | <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404"> |
| | | <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404"> |
| | | </div> |
| | | <div class="bullshit"> |
| | | <div class="bullshit__oops"> |
| | | 404é误! |
| | | </div> |
| | | <div class="bullshit__headline"> |
| | | {{ message }} |
| | | </div> |
| | | <div class="bullshit__info"> |
| | | 对ä¸èµ·ï¼æ¨æ£å¨å¯»æ¾ç页é¢ä¸åå¨ãå°è¯æ£æ¥URLçé误ï¼ç¶åææµè§å¨ä¸çå·æ°æé®æå°è¯å¨æä»¬çåºç¨ç¨åºä¸æ¾å°å
¶ä»å
容ã |
| | | </div> |
| | | <router-link to="/index" class="bullshit__return-home"> |
| | | è¿åé¦é¡µ |
| | | </router-link> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | let message = computed(() => { |
| | | return 'æ¾ä¸å°ç½é¡µï¼' |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .wscn-http404-container{ |
| | | transform: translate(-50%,-50%); |
| | | position: absolute; |
| | | top: 40%; |
| | | left: 50%; |
| | | } |
| | | .wscn-http404 { |
| | | position: relative; |
| | | width: 1200px; |
| | | padding: 0 50px; |
| | | overflow: hidden; |
| | | .pic-404 { |
| | | position: relative; |
| | | float: left; |
| | | width: 600px; |
| | | overflow: hidden; |
| | | &__parent { |
| | | width: 100%; |
| | | } |
| | | &__child { |
| | | position: absolute; |
| | | &.left { |
| | | width: 80px; |
| | | top: 17px; |
| | | left: 220px; |
| | | opacity: 0; |
| | | animation-name: cloudLeft; |
| | | animation-duration: 2s; |
| | | animation-timing-function: linear; |
| | | animation-fill-mode: forwards; |
| | | animation-delay: 1s; |
| | | } |
| | | &.mid { |
| | | width: 46px; |
| | | top: 10px; |
| | | left: 420px; |
| | | opacity: 0; |
| | | animation-name: cloudMid; |
| | | animation-duration: 2s; |
| | | animation-timing-function: linear; |
| | | animation-fill-mode: forwards; |
| | | animation-delay: 1.2s; |
| | | } |
| | | &.right { |
| | | width: 62px; |
| | | top: 100px; |
| | | left: 500px; |
| | | opacity: 0; |
| | | animation-name: cloudRight; |
| | | animation-duration: 2s; |
| | | animation-timing-function: linear; |
| | | animation-fill-mode: forwards; |
| | | animation-delay: 1s; |
| | | } |
| | | @keyframes cloudLeft { |
| | | 0% { |
| | | top: 17px; |
| | | left: 220px; |
| | | opacity: 0; |
| | | } |
| | | 20% { |
| | | top: 33px; |
| | | left: 188px; |
| | | opacity: 1; |
| | | } |
| | | 80% { |
| | | top: 81px; |
| | | left: 92px; |
| | | opacity: 1; |
| | | } |
| | | 100% { |
| | | top: 97px; |
| | | left: 60px; |
| | | opacity: 0; |
| | | } |
| | | } |
| | | @keyframes cloudMid { |
| | | 0% { |
| | | top: 10px; |
| | | left: 420px; |
| | | opacity: 0; |
| | | } |
| | | 20% { |
| | | top: 40px; |
| | | left: 360px; |
| | | opacity: 1; |
| | | } |
| | | 70% { |
| | | top: 130px; |
| | | left: 180px; |
| | | opacity: 1; |
| | | } |
| | | 100% { |
| | | top: 160px; |
| | | left: 120px; |
| | | opacity: 0; |
| | | } |
| | | } |
| | | @keyframes cloudRight { |
| | | 0% { |
| | | top: 100px; |
| | | left: 500px; |
| | | opacity: 0; |
| | | } |
| | | 20% { |
| | | top: 120px; |
| | | left: 460px; |
| | | opacity: 1; |
| | | } |
| | | 80% { |
| | | top: 180px; |
| | | left: 340px; |
| | | opacity: 1; |
| | | } |
| | | 100% { |
| | | top: 200px; |
| | | left: 300px; |
| | | opacity: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .bullshit { |
| | | position: relative; |
| | | float: left; |
| | | width: 300px; |
| | | padding: 30px 0; |
| | | overflow: hidden; |
| | | &__oops { |
| | | font-size: 32px; |
| | | font-weight: bold; |
| | | line-height: 40px; |
| | | color: #1482f0; |
| | | opacity: 0; |
| | | margin-bottom: 20px; |
| | | animation-name: slideUp; |
| | | animation-duration: 0.5s; |
| | | animation-fill-mode: forwards; |
| | | } |
| | | &__headline { |
| | | font-size: 20px; |
| | | line-height: 24px; |
| | | color: #222; |
| | | font-weight: bold; |
| | | opacity: 0; |
| | | margin-bottom: 10px; |
| | | animation-name: slideUp; |
| | | animation-duration: 0.5s; |
| | | animation-delay: 0.1s; |
| | | animation-fill-mode: forwards; |
| | | } |
| | | &__info { |
| | | font-size: 13px; |
| | | line-height: 21px; |
| | | color: grey; |
| | | opacity: 0; |
| | | margin-bottom: 30px; |
| | | animation-name: slideUp; |
| | | animation-duration: 0.5s; |
| | | animation-delay: 0.2s; |
| | | animation-fill-mode: forwards; |
| | | } |
| | | &__return-home { |
| | | display: block; |
| | | float: left; |
| | | width: 110px; |
| | | height: 36px; |
| | | background: #1482f0; |
| | | border-radius: 100px; |
| | | text-align: center; |
| | | color: #ffffff; |
| | | opacity: 0; |
| | | font-size: 14px; |
| | | line-height: 36px; |
| | | cursor: pointer; |
| | | animation-name: slideUp; |
| | | animation-duration: 0.5s; |
| | | animation-delay: 0.3s; |
| | | animation-fill-mode: forwards; |
| | | } |
| | | @keyframes slideUp { |
| | | 0% { |
| | | transform: translateY(60px); |
| | | opacity: 0; |
| | | } |
| | | 100% { |
| | | transform: translateY(0); |
| | | opacity: 1; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container home"> |
| | | <el-row :gutter="20"> |
| | | <el-col :sm="24" :lg="12" style="padding-left: 20px"> |
| | | <h2>è¥ä¾åå°ç®¡çæ¡æ¶</h2> |
| | | <p> |
| | | ä¸ç´æ³å䏿¬¾åå°ç®¡çç³»ç»ï¼çäºå¾å¤ä¼ç§ç弿ºé¡¹ç®ä½æ¯åç°æ²¡æåéèªå·±çãäºæ¯å©ç¨ç©ºé²ä¼æ¯æ¶é´å¼å§èªå·±åä¸å¥åå°ç³»ç»ã妿¤æäºè¥ä¾ç®¡çç³»ç»ï¼å¥¹å¯ä»¥ç¨äºææçWebåºç¨ç¨åºï¼å¦ç½ç«ç®¡çåå°ï¼ç½ç«ä¼åä¸å¿ï¼CMSï¼CRMï¼OAççï¼å½ç¶ï¼æ¨ä¹å¯ä»¥å¯¹å¥¹è¿è¡æ·±åº¦å®å¶ï¼ä»¥ååºæ´å¼ºç³»ç»ãææå端åå°ä»£ç å°è£
è¿åååç²¾ç®æä¸æï¼åºéæ¦çä½ãåæ¶æ¯æç§»å¨å®¢æ·ç«¯è®¿é®ãç³»ç»ä¼éç»æ´æ°ä¸äºå®ç¨åè½ã |
| | | </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> <s> 满170801498 </s> <s> 满108482800 </s> |
| | | <s> 满101046199 </s> <s> 满136919097 </s> <s> 满143961921 </s> <s> 满174951577 </s> |
| | | <s> 满161281055 </s> <s> 满138988063 </s> <s> 满151450850 </s> <s> 满224622315 </s> |
| | | <s> 满287842588 </s> <s> 满187944233 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G6r5KGCaa3pqdbUSXNIgYloyb8e0_L0D&authKey=4w8tF1eGW7%2FedWn%2FHAypQksdrML%2BDHolQSx7094Agm7Luakj9EbfPnSTxSi2T1LQ&noverify=0&group_code=228578329" target="_blank">228578329</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.9 - 2024-12-30"> |
| | | <ol> |
| | | <li>ç¨æ·ç®¡çæ¯æåæ æå¨</li> |
| | | <li>ä¿®æ¹ä¸»é¢æ ·å¼æ¬å°è¯»å</li> |
| | | <li>ç¨æ·å¤´åhttp(s)龿¥æ¯æ</li> |
| | | <li>ç¨æ·ç®¡çè¿æ»¤æå·²ç¦ç¨é¨é¨</li> |
| | | <li>æ¯æèªå®ä¹æ¾ç¤ºExcel屿§å</li> |
| | | <li>æä½æ¥å¿è®°å½DELETE请æ±åæ°</li> |
| | | <li>ç½å忝æå¯¹éé
符路å¾å¹é
</li> |
| | | <li>æ ¡æ£æä»¶åæ¯å¦å
å«ç¹æ®å符</li> |
| | | <li>代ç çæå建表å±è½è¿è§çå符</li> |
| | | <li>èåé¢å
å±å¯¼èªæ¯æå¤å±çº§æ¾ç¤º</li> |
| | | <li>Excelæ³¨è§£æ¯æwrapTextæ¯å¦å
许å
容æ¢è¡</li> |
| | | <li>代ç çææ°å¢é
ç½®æ¯å¦å
许æä»¶è¦çå°æ¬å°</li> |
| | | <li>ä¿®å¤è§è²ç¦ç¨æéä¸å¤±æé®é¢</li> |
| | | <li>ä¿®å¤ä»£ç çæä¸çº§èåæ¾ç¤ºé®é¢</li> |
| | | <li>ä¿®å¤å¯¼åºåå表对象åªè½å¨æåçé®é¢</li> |
| | | <li>ä¿®å¤TopNavæ æ³æ£ç¡®è·åactiveçé®é¢</li> |
| | | <li>ä¿®å¤é»è®¤å
³éTags-Viewså
é¾é¡µé¢æä¸å¼</li> |
| | | <li>å级oshiå°ææ°çæ¬6.6.5</li> |
| | | <li>å级tomcatå°ææ°çæ¬9.0.96</li> |
| | | <li>å级fastjsonå°ææ°ç2.0.53</li> |
| | | <li>å级logbackå°ææ°çæ¬1.2.13</li> |
| | | <li>å级spring-frameworkå°ææ°çæ¬5.3.39</li> |
| | | <li>å级quillå°ææ°çæ¬2.0.2</li> |
| | | <li>å级axioså°ææ°çæ¬0.28.1</li> |
| | | <li>ä¼å身份è¯è±ææ£å</li> |
| | | <li>ä¼åæéæ´æ°å忥ç¼å</li> |
| | | <li>ä¼åæ¥è¯¢æ¶é´èå´æ¥ææ ¼å¼</li> |
| | | <li>ä¼ååæ°é®å¼æ´æ¢ä¸ºå¤è¡ææ¬</li> |
| | | <li>ä¼å导å
¥å¸¦æ 颿件å
³éæ¸
ç</li> |
| | | <li>ä¼åä¸ä¼ å¾ç带ååä¸å¢å åç¼</li> |
| | | <li>ä¼åç¹æ®å符å¯ç ä¿®æ¹å¤±è´¥é®é¢</li> |
| | | <li>ä¼åæ ç¨æ·ç¼å·ä¸æ ¡éªæ°æ®æé</li> |
| | | <li>ä¼åTopNavå
é¾èåç¹å»æ²¡æé«äº®</li> |
| | | <li>ä¼åèå管ç忢Miniå¸å±éä¹±é®é¢</li> |
| | | <li>å
¶ä»ç»èä¼å</li> |
| | | </ol> |
| | | </el-collapse-item> |
| | | <el-collapse-item title="v3.8.8 - 2024-06-30"> |
| | | <ol> |
| | | <li>èåç®¡çæ°å¢è·¯ç±åç§°</li> |
| | | <li>æ°å¢æ°æ®è±æè¿æ»¤æ³¨è§£</li> |
| | | <li>ç¨æ·å¯ç æ°å¢éæ³å符éªè¯</li> |
| | | <li>éå¶ç¨æ·æä½æ°æ®æéèå´</li> |
| | | <li>代ç çææ°å¢åå»ºè¡¨ç»æåè½</li> |
| | | <li>宿¶ä»»å¡ç½ååé
ç½®èå´ç¼©å°</li> |
| | | <li>ä¼å代ç çæä¸»å表å
³èæ¥è¯¢æ¹å¼</li> |
| | | <li>Excel注解æ°å¢å±æ§comboReadDict</li> |
| | | <li>Excel注解ColumnTypeç±»åæ°å¢ææ¬</li> |
| | | <li>æ°å¢å½é
åèµæºæä»¶é
ç½®</li> |
| | | <li>å级oshiå°ææ°çæ¬6.6.1</li> |
| | | <li>å级druidå°ææ°çæ¬1.2.23</li> |
| | | <li>å级core-jså°ææ°çæ¬3.37.1</li> |
| | | <li>æ´æ°HttpUtilsä¸çUser-Agent</li> |
| | | <li>æ´æ°compressionPluginå°6.1.2以å
¼å®¹node18+</li> |
| | | <li>å级spring-securityå°å®å
¨çæ¬ï¼é²æ¢æ¼æ´é£é©</li> |
| | | <li>å级spring-frameworkå°å®å
¨çæ¬ï¼é²æ¢æ¼æ´é£é©</li> |
| | | <li>ä¼åèªå®ä¹XSS注解å¹é
æ¹å¼</li> |
| | | <li>ä¼åç¼åçæ§é®åå表æåºæ¾ç¤º</li> |
| | | <li>ä¼å宿¶ä»»å¡æ¥å¿é»è®¤ææ¶é´æåº</li> |
| | | <li>ä¼åé»è®¤æä»¶å¤§å°è¶
è¿2Gæ æçé®é¢</li> |
| | | <li>ä¼åæ¥è¡¨ç¹æ®å符使ç¨åææ è¿è¡è½¬ä¹</li> |
| | | <li>ä¼å宿¶ä»»å¡cron表达å¼å°æ¶é
ç½®æ¾ç¤ºé误é®é¢</li> |
| | | <li>ä¼åå¤ä¸ªèªå®æ°æ®æé使ç¨inæ¥è¯¢,é¿å
夿¬¡æ¼æ¥</li> |
| | | <li>ä¼å导å
¥Excelæ¶è®¾ç½®dictType屿§é夿¥ç¼åé®é¢</li> |
| | | <li>å
¶ä»ç»èä¼å</li> |
| | | </ol> |
| | | </el-collapse-item> |
| | | <el-collapse-item title="v3.8.7 - 2023-12-08"> |
| | | <ol> |
| | | <li>æä½æ¥å¿è®°å½é¨é¨åç§°</li> |
| | | <li>å
¨å±æ°æ®åå¨ç¨æ·ç¼å·</li> |
| | | <li>æ°å¢ç¼ç¨å¼å¤æèµæºè®¿é®æé</li> |
| | | <li>æä½æ¥å¿å表æ°å¢IPå°åæ¥è¯¢</li> |
| | | <li>宿¶ä»»å¡æ°å¢é¡µå»é¤ç¶æé项</li> |
| | | <li>代ç çææ¯æéæ©å端模æ¿ç±»å</li> |
| | | <li>æ¾éåç»ä»¶æ¯æå¤éæ¡å¼¹åºç±»å</li> |
| | | <li>éç¨æåºå±æ§orderByåæ°éå¶é¿åº¦</li> |
| | | <li>Excelèªå®ä¹æ°æ®å¤çå¨å¢å åå
æ ¼/å·¥ä½ç°¿å¯¹è±¡</li> |
| | | <li>å级oshiå°ææ°çæ¬6.4.8</li> |
| | | <li>å级druidå°ææ°çæ¬1.2.20</li> |
| | | <li>å级fastjsonå°ææ°ç2.0.43</li> |
| | | <li>å级pagehelperå°ææ°ç1.4.7</li> |
| | | <li>å级commons.ioå°ææ°çæ¬2.13.0</li> |
| | | <li>å级element-uiå°ææ°çæ¬2.15.14</li> |
| | | <li>ä¿®å¤äºçº§è·¯ç±ç¼åæ æé®é¢</li> |
| | | <li>ä¿®å¤å¤é¾å¸¦ç«¯å£åºç°çå¼å¸¸</li> |
| | | <li>ä¿®å¤æ 模æ¿ç¶çº§ç¼ç åéé误</li> |
| | | <li>ä¿®å¤åå
¸è¡¨è¯¦æ
é¡µé¢æç´¢é®é¢</li> |
| | | <li>ä¿®å¤å
é¾iframe没æä¼ éåæ°é®é¢</li> |
| | | <li>ä¿®å¤èªå®ä¹åå
¸æ ·å¼ä¸çæçé®é¢</li> |
| | | <li>ä¿®å¤åå
¸ç¼åå 餿¹æ³åæ°é误é®é¢</li> |
| | | <li>ä¿®å¤Excel导å
¥æ°æ®ä¸´æ¶æä»¶æ æ³å é¤é®é¢</li> |
| | | <li>ä¿®å¤æªç»å½å¸¦åæ°è®¿é®æåå忰䏢失é®é¢</li> |
| | | <li>ä¿®å¤HeaderSearchç»ä»¶è·³è½¬query忰䏢失é®é¢</li> |
| | | <li>ä¿®å¤ä»£ç çæå¯¼å
¥åå¿
填项䏿°æ®åºä¸å¹é
é®é¢</li> |
| | | <li>ä¿®å¤Excels导å
¥æ¶æ æ³è·åå°dictTypeåå
¸å¼é®é¢</li> |
| | | <li>ä¼åä¸è½½zipæ¹æ³æ°å¢é®ç½©å±</li> |
| | | <li>ä¼å头åä¸ä¼ åæ°æ°å¢æä»¶åç§°</li> |
| | | <li>ä¼ååå
¸æ ç¾æ¯æèªå®ä¹åé符</li> |
| | | <li>ä¼åèå管çç±»å为æé®ç¶æå¯é</li> |
| | | <li>ä¼åå端é²éå¤æäº¤æ°æ®å¤§å°éå¶</li> |
| | | <li>ä¼åTopNavèåæ²¡æå¾æ svg䏿¾ç¤º</li> |
| | | <li>ä¼åæ°åéé¢å¤§å转æ¢ç²¾åº¦ä¸¢å¤±é®é¢</li> |
| | | <li>ä¼å坿æ¬Editorç»ä»¶æ£éªå¾çæ ¼å¼</li> |
| | | <li>ä¼å页ç¾å¨Firefoxæµè§å¨è¢«é®æ¡çé®é¢</li> |
| | | <li>ä¼å个人ä¸å¿/åºæ¬èµæä¿®æ¹æ¶æ°æ®æ¾ç¤ºé®é¢</li> |
| | | <li>ä¼åç¼åçæ§å¾è¡¨æ¯æè·éå±å¹å¤§å°èªéåºè°æ´</li> |
| | | <li>å
¶ä»ç»èä¼å</li> |
| | | </ol> |
| | | </el-collapse-item> |
| | | <el-collapse-item title="v3.8.6 - 2023-06-30"> |
| | | <ol> |
| | | <li>æ¯æç»å½IPé»ååéå¶</li> |
| | | <li>æ°å¢çæ§é¡µé¢å¾æ æ¾ç¤º</li> |
| | | <li>æä½æ¥å¿æ°å¢æ¶èæ¶é´å±æ§</li> |
| | | <li>å±è½å®æ¶ä»»å¡beanè¿è§çå符</li> |
| | | <li>æ¥å¿ç®¡ç使ç¨ç´¢å¼æåæ¥è¯¢æ§è½</li> |
| | | <li>æ¥å¿æ³¨è§£æ¯ææé¤æå®ç请æ±åæ°</li> |
| | | <li>æ¯æèªå®ä¹éè屿§åè¿æ»¤å对象</li> |
| | | <li>å级oshiå°ææ°çæ¬6.4.3</li> |
| | | <li>å级druidå°ææ°çæ¬1.2.16</li> |
| | | <li>å级fastjsonå°ææ°ç2.0.34</li> |
| | | <li>å级spring-bootå°ææ°çæ¬2.5.15</li> |
| | | <li>å级element-uiå°ææ°çæ¬2.15.13</li> |
| | | <li>ç§»é¤apache/commons-fileuploadä¾èµ</li> |
| | | <li>ä¿®å¤é¡µé¢åæ¢æ¶å¸å±éä¹±çé®é¢</li> |
| | | <li>ä¿®å¤å¿å注解Anonymous空æéé®é¢</li> |
| | | <li>ä¿®å¤è·¯ç±è·³è½¬è¢«é»æ¢æ¶å
é¨äº§çæ¥éä¿¡æ¯é®é¢</li> |
| | | <li>ä¿®å¤isMatchedIpçåæ°å¤æäº§ç空æéçé®é¢</li> |
| | | <li>ä¿®å¤ç¨æ·å¤è§è²æ°æ®æéå¯è½åºç°æéæ¬åçæ
åµ</li> |
| | | <li>ä¿®å¤å¼å¯TopNavåä¸çº§èåè·¯ç±åæ°è®¾ç½®æ æé®é¢</li> |
| | | <li>ä¿®å¤DictTagç»ä»¶value没æå¹é
ç弿¶åå±ç¤ºvalue</li> |
| | | <li>ä¼åæä»¶ä¸è½½åºç°çå¼å¸¸</li> |
| | | <li>ä¼å鿩徿 ç»ä»¶é«äº®åæ¾</li> |
| | | <li>ä¼åå¼¹çªåå¯¼èªæ åç§»çé®é¢</li> |
| | | <li>ä¼åä¿®æ¹å¯ç æ¥å¿å卿æé®é¢</li> |
| | | <li>ä¼åé¡µç¾æ å
³éå
¶ä»åºç°çå¼å¸¸é®é¢</li> |
| | | <li>ä¼å页ç¾å
³é左侧é项æé¤é¦é¡µé项</li> |
| | | <li>ä¼åå
³éå½åtab页跳转æå³ä¾§tab页</li> |
| | | <li>ä¼åç¼åå表æ¸
é¤æä½æç¤ºä¸åçé®é¢</li> |
| | | <li>ä¼åå符æªä½¿ç¨ä¸å线ä¸è¿è¡é©¼å³°å¼å¤ç</li> |
| | | <li>ä¼åç¨æ·å¯¼å
¥æ´æ°æ¶éè·åç¨æ·ç¼å·é®é¢</li> |
| | | <li>ä¼åä¾§è¾¹æ ç平尿 é¢ä¸VUE_APP_TITLEä¿æåæ¥</li> |
| | | <li>ä¼å导åºExcelæ¶è®¾ç½®dictType屿§é夿¥ç¼åé®é¢</li> |
| | | <li>è¿æ¥æ± Druidæ¯ææ°çé
ç½®connectTimeoutåsocketTimeout</li> |
| | | <li>å
¶ä»ç»èä¼å</li> |
| | | </ol> |
| | | </el-collapse-item> |
| | | <el-collapse-item title="v3.8.5 - 2023-01-01"> |
| | | <ol> |
| | | <li>宿¶ä»»å¡è¿è§çå符</li> |
| | | <li>éç½®æ¶åæ¶é¨é¨éä¸</li> |
| | | <li>æ°å¢è¿åè¦åæ¶æ¯æç¤º</li> |
| | | <li>忽ç¥ä¸å¿
è¦ç屿§æ°æ®è¿å</li> |
| | | <li>ä¿®æ¹åæ°é®åæ¶ç§»é¤åç¼åé
ç½®</li> |
| | | <li>导å
¥æ´æ°ç¨æ·æ°æ®åæ ¡éªæ°æ®æé</li> |
| | | <li>å
¼å®¹Excel䏿æ¡å
容è¿å¤æ æ³æ¾ç¤ºçé®é¢</li> |
| | | <li>å级echartså°ææ°çæ¬5.4.0</li> |
| | | <li>å级core-jså°ææ°çæ¬3.25.3</li> |
| | | <li>å级oshiå°ææ°çæ¬6.4.0</li> |
| | | <li>å级kaptchaå°ææ°ç2.3.3</li> |
| | | <li>å级druidå°ææ°çæ¬1.2.15</li> |
| | | <li>å级fastjsonå°ææ°ç2.0.20</li> |
| | | <li>å级pagehelperå°ææ°ç1.4.6</li> |
| | | <li>ä¼åå¼¹çªå
容è¿å¤å±ç¤ºä¸å
¨é®é¢</li> |
| | | <li>ä¼åswagger-uiéæèµæºä½¿ç¨ç¼å</li> |
| | | <li>å¼å¯TopNav没æåèåéèä¾§è¾¹æ </li> |
| | | <li>å é¤fuseæ æé项maxPatternLength</li> |
| | | <li>ä¼å导åºå¯¹è±¡çåå表为空ä¼åºç°[]é®é¢</li> |
| | | <li>ä¼åç¼è¾å¤´åæ¶éæé¨åä¼åæé»è²é®é¢</li> |
| | | <li>ä¼åå°å±å¹ä¸ä¿®æ¹å¤´åçé¢å¸å±éä½çé®é¢</li> |
| | | <li>ä¿®å¤ä»£ç çæå¾é屿§æ æé®é¢</li> |
| | | <li>ä¿®å¤æä»¶ä¸ä¼ ç»ä»¶æ ¼å¼éªè¯é®é¢</li> |
| | | <li>ä¿®å¤åæ¾æ°æ®åå
¸æ°ç»å¼å¸¸é®é¢</li> |
| | | <li>ä¿®å¤sheetè¶
åºæå¤§è¡æ°å¼å¸¸é®é¢</li> |
| | | <li>ä¿®å¤Log注解GET请æ±è®°å½ä¸å°åæ°é®é¢</li> |
| | | <li>ä¿®å¤è°åº¦æ¥å¿ç¹å»å¤æ¬¡æ°æ®ä¸ååçé®é¢</li> |
| | | <li>ä¿®å¤ä¸»é¢é¢è²å¨Drawerç»ä»¶ä¸ä¼å è½½é®é¢</li> |
| | | <li>ä¿®å¤æä»¶åå
å«ç¹æ®å符çæä»¶æ æ³ä¸è½½é®é¢</li> |
| | | <li>ä¿®å¤table䏿´å¤æé®åæ¢ä¸»é¢è²æªçæä¿®å¤é®é¢</li> |
| | | <li>ä¿®å¤æäºç¹æ§çç¯å¢çæä»£ç åä¹±ç TXTæä»¶é®é¢</li> |
| | | <li>ä¿®å¤ä»£ç çæå¾ç/æä»¶/åéæ¶éæ©å¿
å¡«æ æ³æ ¡éªé®é¢</li> |
| | | <li>ä¿®å¤æäºç¹æ§çæ
åµç¨æ·ç¼è¾å¯¹è¯æ¡ä¸è§è²åé¨é¨æ æ³ä¿®æ¹é®é¢</li> |
| | | <li>å
¶ä»ç»èä¼å</li> |
| | | </ol> |
| | | </el-collapse-item> |
| | | <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>ç»å½æ¥å¿æ°å¢è§£éè´¦æ·åè½</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>ä¼å代ç çæåæ¥åå¼NULLé®é¢</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>代ç çææ 表æ°å¢(å±å¼/æå )</li> |
| | | <li>Excelæ³¨è§£æ¯æcoloråä½é¢è²</li> |
| | | <li>æ°å¢Anonymouså¿å访é®ä¸é´ææ³¨è§£</li> |
| | | <li>ç¨æ·å¤´åä¸ä¼ éå¶åªè½ä¸ºå¾çæ ¼å¼</li> |
| | | <li>æ¥å£ä½¿ç¨æ³å使å
¶çå°ååºå±æ§å段</li> |
| | | <li>æ£æ¥å®æ¶ä»»å¡beanæå¨å
忝å¦ä¸ºç½ååé
ç½®</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>å é¤å¤ä½çsaltåæ®µ</li> |
| | | <li>æ°å¢è·åä¸å¸¦åç¼æä»¶åç§°æ¹æ³</li> |
| | | <li>æ°å¢è·åé
ç½®æä»¶ä¸ç屿§å¼æ¹æ³</li> |
| | | <li>æ°å¢å
容ç¼ç /è§£ç æ¹ä¾¿æä»¶éæä½¿ç¨</li> |
| | | <li>åå
¸ç±»åå¿
须以忝å¼å¤´ï¼ä¸åªè½ä¸ºï¼å°ååæ¯ï¼æ°åï¼ä¸æ»çº¿ï¼</li> |
| | | <li>ä¼å设置å页忰é»è®¤å¼</li> |
| | | <li>ä¼å对空åç¬¦ä¸²åæ°å¤ççè¿æ»¤</li> |
| | | <li>ä¼åæ¾ç¤ºé¡ºåºorderNumç±»å为æ´å</li> |
| | | <li>ä¼å表åæå»ºæé®ä¸æ¾ç¤ºæ£åæ ¡éª</li> |
| | | <li>ä¼ååå
¸æ°æ®åæ¾æ ·å¼ä¸ææ¡æ¾ç¤ºå¼</li> |
| | | <li>ä¼åRååºæåç¶æç ä¸å
¨å±ä¿æä¸è´</li> |
| | | <li>ä¼ådruidå¼å¯wallè¿æ»¤å¨åºç°çå¼å¸¸é®é¢</li> |
| | | <li>ä¼åç¨æ·ç®¡ç左侧æ åç»ä»¶å¢å éä¸é«äº®ä¿æ</li> |
| | | <li>ä¼åæ°å¢ç¨æ·ä¸è§è²ä¿¡æ¯&ç¨æ·ä¸å²ä½ä¿¡æ¯é»è¾</li> |
| | | <li>ä¼åé»è®¤ä¸å¯ç¨å缩æä»¶ç¼å鲿¢node_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>å¼å¯TopNav没æåèåæ
åµéèä¾§è¾¹æ </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>代ç çæå表å¾çæ¯æé¢è§</li> |
| | | <li>代ç çæç¼è¾ä¿®æ¹æå¼æ°é¡µç¾</li> |
| | | <li>代ç çææ°å¢Javaç±»åBoolean</li> |
| | | <li>代ç çæåè¡¨æ¯ææ¥æ/åå
¸é
ç½®</li> |
| | | <li>代ç çæåæ¥ä¿çå¿
å¡«/ç±»åé项</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å端代ç çææ¨¡æ¿</li> |
| | | <li>æ°å¢å¾çé¢è§ç»ä»¶</li> |
| | | <li>æ°å¢å缩æä»¶å®ç°æå
Gzip</li> |
| | | <li>èªå®ä¹xssæ ¡éªæ³¨è§£å®ç°</li> |
| | | <li>èªå®ä¹æåå¤å¶åªè´´æä»¤</li> |
| | | <li>代ç çæé¢è§æ¯æå¤å¶å
容</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å°ææ°çæ¬v5.8.6</li> |
| | | <li>å级fastjsonå°ææ°ç1.2.79</li> |
| | | <li>å级spring-bootå°ææ°çæ¬2.5.8</li> |
| | | <li>å级log4j2å°2.17.1ï¼é²æ¢æ¼æ´é£é©</li> |
| | | <li>ä¼åä¸è½½è§£æblobå¼å¸¸æç¤º</li> |
| | | <li>ä¼å代ç çæåå
¸ç»éå¤é®é¢</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ä¾èµï¼é²æ¢jdk8以ä¸åºç°çå
¼å®¹é误</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å°ææ°çæ¬v5.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>代ç çæç¹å»é¢è§éç½®æ¿æ´»tab</li> |
| | | <li>AjaxResultéåputæ¹æ³ï¼ä»¥æ¹ä¾¿é¾å¼è°ç¨</li> |
| | | <li>ä¼åç»å½/éªè¯ç 请æ±headersä¸è®¾ç½®token</li> |
| | | <li>ä¼åç¨æ·ä¸ªäººä¿¡æ¯æ¥å£é²æ¢ä¿®æ¹ç¨æ·å</li> |
| | | <li>ä¼åCron表达å¼çæå¨å
³éæ¶éæ¯é¿å
ç¼å</li> |
| | | <li>ä¼å注åæåæç¤ºæ¶æ¯ç±»åsuccess</li> |
| | | <li>ä¼åaopè¯æ³ï¼ä½¿ç¨springèªå¨æ³¨å
¥æ³¨è§£</li> |
| | | <li>ä¼åè®°å½ç»å½ä¿¡æ¯ï¼ç§»é¤ä¸å¿
è¦çä¿®æ¹</li> |
| | | <li>ä¼åmybatiså
¨å±é»è®¤çæ§è¡å¨</li> |
| | | <li>ä¼åExcel导å
¥å¾çå¯è½åºç°çå¼å¸¸</li> |
| | | <li>ä¿®å¤ä»£ç çææ¨¡æ¿ä¸»å表å é¤ç¼ºå°äºå¡</li> |
| | | <li>ä¿®å¤æ¥å¿è®°å½å¯è½åºç°ç转æ¢å¼å¸¸</li> |
| | | <li>ä¿®å¤ä»£ç çæå¤éæ¡åå
¸éæ¼é®é¢</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>æ¯æèªå®ä¹æ³¨è§£å®ç°æ¥å£éæµ</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>代ç çæä¸»å表å¤éè¡æ°æ®</li> |
| | | <li>æ¥æèå´æ¯ææ·»å å¤ç»</li> |
| | | <li>å级element-uiå°ææ°çæ¬2.15.5</li> |
| | | <li>å级oshiå°ææ°çæ¬v5.8.0</li> |
| | | <li>å级commons.ioå°ææ°çæ¬v2.11.0</li> |
| | | <li>宿¶ä»»å¡å±è½ldapè¿ç¨è°ç¨</li> |
| | | <li>宿¶ä»»å¡å±è½http(s)è¿ç¨è°ç¨</li> |
| | | <li>è¡¥å
宿¶ä»»å¡è¡¨å段注é</li> |
| | | <li>宿¶ä»»å¡å¯¹æ£æ¥å¼å¸¸è¿è¡äºå¡åæ»</li> |
| | | <li>å¯ç¨ç¶é¨é¨ç¶ææé¤é¡¶çº§èç¹</li> |
| | | <li>å¯ææ¬æ°å¢ä¸ä¼ æä»¶å¤§å°éå¶</li> |
| | | <li>é»è®¤é¦é¡µä½¿ç¨keep-aliveç¼å</li> |
| | | <li>ä¿®æ¹ä»£ç çæåå
¸åæ¾æ ·å¼</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>ä¼å代ç çææ¨¡æ¿</li> |
| | | <li>éªè¯ç é»è®¤20sè¶
æ¶</li> |
| | | <li>BLOBä¸è½½æ¶æ¸
é¤URL对象å¼ç¨</li> |
| | | <li>代ç çæå¯¼å
¥è¡¨æå建æ¶é´æåº</li> |
| | | <li>ä¿®å¤ä»£ç çæé¡µé¢æ°æ®ç¼è¾ä¿åä¹åæ»æ¯è·³è½¬ç¬¬ä¸é¡µçé®é¢</li> |
| | | <li>ä¿®å¤å¸¦safariæµè§å¨æ æ³æ ¼å¼åutcæ¥ææ ¼å¼yyyy-MM-dd'T'HH:mm:ss.SSSé®é¢</li> |
| | | <li>å¤å¾ä¸ä¼ ç»ä»¶ç§»é¤å¤ä½çapiå°å&éªè¯å¤±è´¥å¯¼è´å¾çå é¤é®é¢&æ æ³å é¤ç¸åºå¾çä¿®å¤</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>坿æ¬é»è®¤ä¸ä¼ è¿åurlç±»å</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å°ææ°çæ¬v5.7.4</li> |
| | | <li>å级element-uiå°ææ°çæ¬2.15.2</li> |
| | | <li>å级pagehelperå°ææ°ç1.3.1</li> |
| | | <li>å级commons.ioå°ææ°çæ¬v2.10.0</li> |
| | | <li>å级commons.fileuploadå°ææ°çæ¬v1.4</li> |
| | | <li>å级swaggerå°ææ°çæ¬v3.0.0</li> |
| | | <li>ä¿®å¤å
³éconfirmæç¤ºæ¡æ§å¶å°æ¥éé®é¢</li> |
| | | <li>ä¿®å¤åå¨çSQL注å
¥æ¼æ´é®é¢</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ï¼false为左侧导èªèåï¼true为顶é¨å¯¼èªèåï¼</li> |
| | | <li>å¸å±è®¾ç½®æ¯æä¿å&éç½®é
ç½®</li> |
| | | <li>ä¿®å¤æ è¡¨æ°æ®æ¾ç¤ºä¸å
¨&å è½½æ
¢é®é¢</li> |
| | | <li>æ°å¢IEæµè§å¨çæ¬è¿ä½æç¤ºé¡µé¢</li> |
| | | <li>ç¨æ·ç»å½åè®°å½æåç»å½IP&æ¶é´</li> |
| | | <li>页é¢å¯¼åºæé®ç¹å»ä¹åæ·»å é®ç½©</li> |
| | | <li>坿æ¬ç¼è¾å¨æ¯æèªå®ä¹ä¸ä¼ å°å</li> |
| | | <li>坿æ¬ç¼è¾ç»ä»¶æ°å¢readOnly屿§</li> |
| | | <li>页ç¾TagsViewæ°å¢å
³éå³ä¾§åè½</li> |
| | | <li>æ¾éåç»ä»¶å è½½åå§é»è®¤éèå</li> |
| | | <li>å
³é头åä¸ä¼ çªå£è¿åé»è®¤å¾ç</li> |
| | | <li>ä¸ªäººä¿¡æ¯æ·»å ææº&é®ç®±éå¤éªè¯</li> |
| | | <li>代ç çææ¨¡æ¿å¯¼åºæé®ç¹å»åæ·»å é®ç½©</li> |
| | | <li>代ç çææ¨¡æ¿æ 表æä½åæ·»å æ°å¢æé®</li> |
| | | <li>代ç çææ¨¡æ¿ä¿®å¤ä¸»åè¡¨åæ®µéåé®é¢</li> |
| | | <li>å级fastjsonå°ææ°ç1.2.76</li> |
| | | <li>å级druidå°ææ°çæ¬v1.2.6</li> |
| | | <li>å级mybatiså°ææ°ç3.5.6 黿¢è¿ç¨ä»£ç æ§è¡æ¼æ´</li> |
| | | <li>å级oshiå°ææ°çæ¬v5.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>æ çº§ç»ææ´æ°åèç¹ä½¿ç¨replaceFirst</li> |
| | | <li>ä¼åExcelUtil空å¼å¤ç</li> |
| | | <li>æ¥å¿è®°å½è¿æ»¤BindingResult对象ï¼é²æ¢å¼å¸¸</li> |
| | | <li>ä¿®æ¹ä¸»é¢åminiç±»åæé®æ æé®é¢</li> |
| | | <li>ä¼åéç¨ä¸è½½å®æåå é¤èç¹</li> |
| | | <li>éç¨Controlleræ·»å ååºè¿åæ¶æ¯</li> |
| | | <li>å
¶ä»ç»èä¼å</li> |
| | | </ol> |
| | | </el-collapse-item> |
| | | <el-collapse-item title="v3.4.0 - 2021-02-22"> |
| | | <ol> |
| | | <li>代ç çææ¨¡æ¿æ¯æä¸»å表</li> |
| | | <li>è¡¨æ ¼å³ä¾§å·¥å
·æ ç»ä»¶æ¯ææ¾éå</li> |
| | | <li>å¾çç»ä»¶æ·»å é¢è§&ç§»é¤åè½</li> |
| | | <li>Excelæ³¨è§£æ¯æImageå¾ç导åº</li> |
| | | <li>æä½æé®ç»è°æ´ä¸ºæ´ç´ æé®æ ·å¼</li> |
| | | <li>代ç çææ¯ææä»¶ä¸ä¼ ç»ä»¶</li> |
| | | <li>代ç çææ¥ææ§ä»¶åºåèå´</li> |
| | | <li>代ç çææ°æ®åºææ¬ç±»åçæè¡¨åææ¬å</li> |
| | | <li>ç¨æ·ææºé®ç®±&èåç»ä»¶ä¿®æ¹å
许空å符串</li> |
| | | <li>å级SpringBootå°ææ°çæ¬2.2.13 æåå¯å¨é度</li> |
| | | <li>å级druidå°ææ°çæ¬v1.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>æéå·¥å
·ç±»å¢å admin夿</li> |
| | | <li>è§è²éèªå®ä¹æéèå´æ¸
ç©ºéæ©å¼</li> |
| | | <li>ä¿®å¤å¯¼å
¥æ°æ®ä¸ºè´æµ®ç¹æ°æ¶ä¸¢å¤±ç²¾åº¦é®é¢</li> |
| | | <li>ç§»é¤path-to-regexpæ£åå¹é
æä»¶</li> |
| | | <li>ä¿®å¤çææ è¡¨ä»£ç å¼å¸¸</li> |
| | | <li>ä¿®æ¹ipåæ®µé¿åº¦é²æ¢ipv6å°åé¿åº¦ä¸å¤</li> |
| | | <li>鲿¢get请æ±åæ°å¼ä¸ºfalseæ0çç¹æ®å¼ä¼å¯¼è´æ æ³æ£ç¡®çä¼ å</li> |
| | | <li>ç»å½åpushæ·»å 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>代ç çæé¢è§æ¯æé«äº®æ¾ç¤º</li> |
| | | <li>æ¯æGetè¯·æ±æ å°Paramsåæ°</li> |
| | | <li>å é¤ç¨æ·åè§è²è§£ç»å
³è</li> |
| | | <li>å»é¤ç¨æ·ææºé®ç®±é¨é¨å¿
å¡«éªè¯</li> |
| | | <li>Excelæ¯ææ³¨è§£align坹齿¹å¼</li> |
| | | <li>Excelæ¯æå¯¼å
¥Booleanåæ°æ®</li> |
| | | <li>ä¼åå¤´åæ ·å¼ï¼é¼ æ ç§»å
¥æ¬åé®ç½©</li> |
| | | <li>代ç çæé¢è§æä¾æ»å¨æºå¶</li> |
| | | <li>代ç çæå é¤å¤ä½çæ°åfloatç±»å</li> |
| | | <li>ä¿®æ£è½¬æ¢å符串çç®æ å符é屿§</li> |
| | | <li>åæ¾æ°æ®åå
¸é²æ¢ç©ºå¼æ¥é</li> |
| | | <li>æ¥å¿è®°å½å¢å è¿æ»¤å¤æä»¶åºæ¯</li> |
| | | <li>ä¿®æ¹ç¼åSetæ¹æ³å¯è½å¯¼è´åµå¥çé®é¢</li> |
| | | <li>ç§»é¤å端ä¸äºå¤ä½çä¾èµ</li> |
| | | <li>鲿¢å®å
¨æ«æYUIåºç°çé£é©æç¤º</li> |
| | | <li>ä¿®æ¹node-sass为dart-sass</li> |
| | | <li>å级SpringBootå°ææ°çæ¬2.1.18</li> |
| | | <li>å级poiå°ææ°çæ¬4.1.2</li> |
| | | <li>å级oshiå°ææ°çæ¬v5.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>代ç çææ¯æä¸ä¼ æ§ä»¶</li> |
| | | <li>æ°å¢å¾çä¸ä¼ ç»ä»¶</li> |
| | | <li>è°æ´é»è®¤é¦é¡µ</li> |
| | | <li>å级druidå°ææ°çæ¬v1.2.2</li> |
| | | <li>mapperLocationsé
ç½®æ¯æåé符</li> |
| | | <li>æéä¿¡æ¯è°æ´</li> |
| | | <li>è°æ´sqlé»è®¤æ¶é´</li> |
| | | <li>è§£å³ä»£ç çææ²¡æ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å°ææ°çæ¬v5.2.5</li> |
| | | <li>å级druidå°ææ°çæ¬v1.2.1</li> |
| | | <li>å级jjwtå°çæ¬0.9.1</li> |
| | | <li>å级fastjsonå°ææ°ç1.2.74</li> |
| | | <li>ä¿®æ¹sass为node-sassï¼é¿å
el-icon徿 ä¹±ç </li> |
| | | <li>代ç çææ¯æåæ¥æ°æ®åº</li> |
| | | <li>代ç çææ¯æå¯ææ¬æ§ä»¶</li> |
| | | <li>代ç çæé¡µé¢æ¶ä¸å¿½ç¥remark屿§</li> |
| | | <li>代ç çææ·»å 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>代ç çææ¯æéæ©ä¸çº§èå</li> |
| | | <li>代ç çææ¯æèªå®ä¹è·¯å¾</li> |
| | | <li>代ç çææ¯æå¤éæ¡</li> |
| | | <li>Excel导åºå¯¼å
¥æ¯ædictTypeåå
¸ç±»å</li> |
| | | <li>Excelæ¯æåå²å符串ç»å
容</li> |
| | | <li>éªè¯ç ç±»åæ¯æï¼æ°ç»è®¡ç®ãå符éªè¯ï¼</li> |
| | | <li>å级vue-cliçæ¬å°4.4.4</li> |
| | | <li>ä¿®æ¹ node-sass 为 dart-sass</li> |
| | | <li>表åç±»å为Integer/Long设置æ´å½¢é»è®¤å¼</li> |
| | | <li>代ç çæå¨é»è®¤mapperè·¯å¾ä¸é»è®¤mapperScanè·¯å¾ä¸ä¸è´</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>ä¿®å¤ä»£ç çæå¯¼å
¥è¡¨ç»æåºç°å¼å¸¸é¡µé¢ä¸æéé®é¢</li> |
| | | <li>ä¿®å¤ä»£ç çæç¹å»å¤æ¬¡è¡¨ä¿®æ¹æ°æ®ä¸ååçé®é¢</li> |
| | | <li>ä¿®å¤å¤´åä¸ä¼ æåäºæ¬¡æå¼æ æ³æ¹åè£åªæ¡å¤§å°åä½ç½®é®é¢</li> |
| | | <li>ä¿®å¤å¸å±ä¸ºsmallè
miniç¨æ·è¡¨åæ¾ç¤ºéä½é®é¢</li> |
| | | <li>ä¿®å¤çé¨ç½²å¯¼è´ç强æ¢å¼å¸¸é®é¢</li> |
| | | <li>ä¿®æ¹ç¨æ·ç®¡çå¤éæ¡å®½åº¦ï¼é²æ¢é¨åæµè§å¨åºç°çç¥å·</li> |
| | | <li>IpUtilså·¥å
·ï¼æ¸
é¤Xssç¹æ®å符ï¼é²æ¢Xff注å
¥æ»å»</li> |
| | | <li>çædomain å¦ææ¯æµ®ç¹å ç»ä¸ç¨BigDecimal</li> |
| | | <li>宿¶ä»»å¡è°æ´label-widthï¼é²æ¢é¨ç½²åºç°éä½</li> |
| | | <li>è°æ´è¡¨å¤´åºå®åé»è®¤æ ·å¼</li> |
| | | <li>代ç çææ¨¡æ¿è°æ´ï¼å段为Stringå¹¶ä¸å¿
å¡«åå 空串æ¡ä»¶</li> |
| | | <li>代ç çæåå
¸Integer/Long使ç¨parseInt</li> |
| | | <li> |
| | | ä¿®å¤dict_sortä¸å¯update为0çé®é¢&æ¥è¯¢è¿åå¢å dict_sortååºæåº |
| | | </li> |
| | | <li>ä¿®æ£å²ä½å¯¼åºæé注解</li> |
| | | <li>ç¦æ¢å å¯å¯æè¿åå端</li> |
| | | <li>ä¿®å¤ä»£ç çæé¡µé¢ä¸çæ¥è¯¢æ¡ä»¶å建æ¶é´æªçæçé®é¢</li> |
| | | <li>ä¿®å¤é¦é¡µæç´¢èåå¤é¾æ æ³ç¹å»è·³è½¬é®é¢</li> |
| | | <li>ä¿®å¤èå管ç鿩徿 ï¼backspaceå 餿¶ä¸è¿æ»¤æ°æ®</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>å½tags-viewæ»å¨å
³éå³é®èå</li> |
| | | <li>åå
¸ç®¡çæ·»å ç¼å读å</li> |
| | | <li>åæ°ç®¡çæ¯æç¼åæä½</li> |
| | | <li>æ¯æä¸çº§èåï¼å主页å级ï¼å¨mainåºåæ¾ç¤º</li> |
| | | <li>éå¶å¤é¾å°åå¿
须以http(s)å¼å¤´</li> |
| | | <li>tagview & sidebar 主é¢é¢è²ä¸element ui(å
¨å±)忥</li> |
| | | <li>ä¿®æ¹æ°æ®æºç±»åä¼å
级ï¼å
æ ¹æ®æ¹æ³ï¼åæ ¹æ®ç±»</li> |
| | | <li>æ¯ææ¯å¦éè¦è®¾ç½®token屿§ï¼èªå®ä¹è¿åç æ¶æ¯ã</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ç±»åè¯·æ±æå»ºå¯éå¤è¯»åinputStreamçrequest</li> |
| | | <li>ä¿®æ¹ä»£ç çæåå
¸å段intç±»åæ²¡æèªå¨éä¸é®é¢</li> |
| | | <li>vuexç¨æ·ååå¼ä¿®æ£</li> |
| | | <li>è¡¨æ ¼æ æ¨¡æ¿å»æå¤ä½ç)</li> |
| | | <li>代ç çæåºå·ä¿®æ£</li> |
| | | <li>å
¨å±æ
åµä¸ä¸è°æ´ä¸å¤è¾¹è·</li> |
| | | <li>代ç çæ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>ä¿®å¤ä»£ç çæå¦æéæ©åå
¸ç±»å缺失éå·é®é¢</li> |
| | | <li>ç»å½è¯·æ±paramsæ´æ¢ä¸ºdataï¼é²æ¢æ´é²url</li> |
| | | <li>æ¥å¿è¿åæ¶é´æ ¼å¼å¤ç</li> |
| | | <li>æ·»å handleæ§å¶å
许æå¨çå
ç´ </li> |
| | | <li>å¸å±è®¾ç½®ç¹å»æ©å¤§èå´</li> |
| | | <li>代ç çæå屿§æåºæ¥è¯¢</li> |
| | | <li>代ç çæåæ¯ææå¨æåº</li> |
| | | <li>ä¿®å¤æ¶é´æ ¼å¼ä¸æ¯æiosé®é¢</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>æ·»å ä¸ä¸ªæå
Webå·¥ç¨bat</li> |
| | | <li>ä¿®å¤é¡µç¾é¼ æ æ»è½®æä¸çæ¶åï¼å¯ä»¥å
³éä¸å¯å
³éçtag</li> |
| | | <li>ä¿®å¤ç¹å»éåºç»å½ææ¶ä¼æ æç¤ºé®é¢</li> |
| | | <li>ä¿®å¤é²éå¤æäº¤æ³¨è§£æ æé®é¢</li> |
| | | <li>ä¿®å¤éç¥å
¬åæ¹éå é¤å¼å¸¸é®é¢</li> |
| | | <li>æ·»å èåæ¶è·¯ç±å°åå¿
å¡«éå¶</li> |
| | | <li>代ç çæå段æè¿°å¯ç¼è¾</li> |
| | | <li>ä¿®å¤ç¨æ·ä¿®æ¹ä¸ªäººä¿¡æ¯å¯¼è´ç¼åä¸è¿æé®é¢</li> |
| | | <li>个人信æ¯å建æ¶é´è·åæ£ç¡®å±æ§å¼</li> |
| | | <li>æä½æ¥å¿è¯¦ç»æ¾ç¤ºæ£ç¡®ç±»å</li> |
| | | <li>导å
¥è¡¨åå»è¡æ°æ®æ¶éä¸å¯¹åºçå¤éæ¡</li> |
| | | <li>æ¹éæ¿æ¢è¡¨åç¼é»è¾è°æ´</li> |
| | | <li>åºå®éå®åè·¯å¾è¡¨è¾¾å¼</li> |
| | | <li>å级element-uiçæ¬å°2.13.0</li> |
| | | <li>æä½æ¥å¿æåºè°æ´</li> |
| | | <li>ä¿®å¤chartsåæ¢ä¾§è¾¹æ æè
缩æ¾çªå£æ¾ç¤ºbug</li> |
| | | <li>å
¶ä»ç»èä¼å</li> |
| | | </ol> |
| | | </el-collapse-item> |
| | | |
| | | <el-collapse-item title="v2.1.0 - 2020-02-24"> |
| | | <ol> |
| | | <li>æ°å¢è¡¨åæå»º</li> |
| | | <li>代ç çææ¯ææ è¡¨ç»æ</li> |
| | | <li>æ°å¢ç¨æ·å¯¼å
¥</li> |
| | | <li>ä¿®å¤å¨æå 载路ç±é¡µé¢å·æ°é®é¢</li> |
| | | <li>ä¿®å¤å°åå¼å
³æ æé®é¢</li> |
| | | <li>æ±åé误æç¤ºé¡µé¢</li> |
| | | <li>代ç çæå·²ç¥é®é¢ä¿®æ¹</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åEditor䏿¾ç¤ºå¤ç</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>æ°å¢ä»£ç çæ</li> |
| | | <li>æ°å¢@RepeatSubmit注解ï¼é²æ¢éå¤æäº¤</li> |
| | | <li>æ°å¢èå主ç®å½æ·»å /å 餿ä½</li> |
| | | <li>æ¥å¿è®°å½è¿æ»¤ç¹æ®å¯¹è±¡ï¼é²æ¢è½¬æ¢å¼å¸¸</li> |
| | | <li>ä¿®æ¹ä»£ç çæè·¯ç±èæ¬é误</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="@/assets/images/pay.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.9') |
| | | |
| | | 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="login"> |
| | | <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form"> |
| | | <h3 class="title">{{ title }}</h3> |
| | | <el-form-item prop="username"> |
| | | <el-input |
| | | v-model="loginForm.username" |
| | | type="text" |
| | | size="large" |
| | | auto-complete="off" |
| | | placeholder="è´¦å·" |
| | | > |
| | | <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="password"> |
| | | <el-input |
| | | v-model="loginForm.password" |
| | | type="password" |
| | | size="large" |
| | | auto-complete="off" |
| | | placeholder="å¯ç " |
| | | @keyup.enter="handleLogin" |
| | | > |
| | | <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="code" v-if="captchaEnabled"> |
| | | <el-input |
| | | v-model="loginForm.code" |
| | | size="large" |
| | | auto-complete="off" |
| | | placeholder="éªè¯ç " |
| | | style="width: 63%" |
| | | @keyup.enter="handleLogin" |
| | | > |
| | | <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | <div class="login-code"> |
| | | <img :src="codeUrl" @click="getCode" class="login-code-img"/> |
| | | </div> |
| | | </el-form-item> |
| | | <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">è®°ä½å¯ç </el-checkbox> |
| | | <el-form-item style="width:100%;"> |
| | | <el-button |
| | | :loading="loading" |
| | | size="large" |
| | | type="primary" |
| | | style="width:100%;" |
| | | @click.prevent="handleLogin" |
| | | > |
| | | <span v-if="!loading">ç» å½</span> |
| | | <span v-else>ç» å½ ä¸...</span> |
| | | </el-button> |
| | | <div style="float: right;" v-if="register"> |
| | | <router-link class="link-type" :to="'/register'">ç«å³æ³¨å</router-link> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- åºé¨ --> |
| | | <div class="el-login-footer"> |
| | | <span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getCodeImg } from "@/api/login" |
| | | import Cookies from "js-cookie" |
| | | import { encrypt, decrypt } from "@/utils/jsencrypt" |
| | | import useUserStore from '@/store/modules/user' |
| | | |
| | | const title = import.meta.env.VITE_APP_TITLE |
| | | const userStore = useUserStore() |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | const loginForm = ref({ |
| | | username: "admin", |
| | | password: "admin123", |
| | | rememberMe: false, |
| | | code: "", |
| | | uuid: "" |
| | | }) |
| | | |
| | | const loginRules = { |
| | | username: [{ required: true, trigger: "blur", message: "请è¾å
¥æ¨çè´¦å·" }], |
| | | password: [{ required: true, trigger: "blur", message: "请è¾å
¥æ¨çå¯ç " }], |
| | | code: [{ required: true, trigger: "change", message: "请è¾å
¥éªè¯ç " }] |
| | | } |
| | | |
| | | const codeUrl = ref("") |
| | | const loading = ref(false) |
| | | // éªè¯ç å¼å
³ |
| | | const captchaEnabled = ref(true) |
| | | // 注åå¼å
³ |
| | | const register = ref(false) |
| | | const redirect = ref(undefined) |
| | | |
| | | watch(route, (newRoute) => { |
| | | redirect.value = newRoute.query && newRoute.query.redirect |
| | | }, { immediate: true }) |
| | | |
| | | function handleLogin() { |
| | | proxy.$refs.loginRef.validate(valid => { |
| | | if (valid) { |
| | | loading.value = true |
| | | // å¾éäºéè¦è®°ä½å¯ç è®¾ç½®å¨ cookie ä¸è®¾ç½®è®°ä½ç¨æ·ååå¯ç |
| | | if (loginForm.value.rememberMe) { |
| | | Cookies.set("username", loginForm.value.username, { expires: 30 }) |
| | | Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 }) |
| | | Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 }) |
| | | } else { |
| | | // å¦åç§»é¤ |
| | | Cookies.remove("username") |
| | | Cookies.remove("password") |
| | | Cookies.remove("rememberMe") |
| | | } |
| | | // è°ç¨actionçç»å½æ¹æ³ |
| | | userStore.login(loginForm.value).then(() => { |
| | | const query = route.query |
| | | const otherQueryParams = Object.keys(query).reduce((acc, cur) => { |
| | | if (cur !== "redirect") { |
| | | acc[cur] = query[cur] |
| | | } |
| | | return acc |
| | | }, {}) |
| | | router.push({ path: redirect.value || "/", query: otherQueryParams }) |
| | | }).catch(() => { |
| | | loading.value = false |
| | | // éæ°è·åéªè¯ç |
| | | if (captchaEnabled.value) { |
| | | getCode() |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | function getCode() { |
| | | getCodeImg().then(res => { |
| | | captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled |
| | | if (captchaEnabled.value) { |
| | | codeUrl.value = "data:image/gif;base64," + res.img |
| | | loginForm.value.uuid = res.uuid |
| | | } |
| | | }) |
| | | } |
| | | |
| | | function getCookie() { |
| | | const username = Cookies.get("username") |
| | | const password = Cookies.get("password") |
| | | const rememberMe = Cookies.get("rememberMe") |
| | | loginForm.value = { |
| | | username: username === undefined ? loginForm.value.username : username, |
| | | password: password === undefined ? loginForm.value.password : decrypt(password), |
| | | rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) |
| | | } |
| | | } |
| | | |
| | | getCode() |
| | | getCookie() |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | .login { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | height: 100%; |
| | | background-image: url("../assets/images/login-background.jpg"); |
| | | background-size: cover; |
| | | } |
| | | .title { |
| | | margin: 0px auto 30px auto; |
| | | text-align: center; |
| | | color: #707070; |
| | | } |
| | | |
| | | .login-form { |
| | | border-radius: 6px; |
| | | background: #ffffff; |
| | | width: 400px; |
| | | padding: 25px 25px 5px 25px; |
| | | z-index: 1; |
| | | .el-input { |
| | | height: 40px; |
| | | input { |
| | | height: 40px; |
| | | } |
| | | } |
| | | .input-icon { |
| | | height: 39px; |
| | | width: 14px; |
| | | margin-left: 0px; |
| | | } |
| | | } |
| | | .login-tip { |
| | | font-size: 13px; |
| | | text-align: center; |
| | | color: #bfbfbf; |
| | | } |
| | | .login-code { |
| | | width: 33%; |
| | | height: 40px; |
| | | float: right; |
| | | img { |
| | | cursor: pointer; |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | .el-login-footer { |
| | | height: 40px; |
| | | line-height: 40px; |
| | | position: fixed; |
| | | bottom: 0; |
| | | width: 100%; |
| | | text-align: center; |
| | | color: #fff; |
| | | font-family: Arial; |
| | | font-size: 12px; |
| | | letter-spacing: 1px; |
| | | } |
| | | .login-code-img { |
| | | height: 40px; |
| | | padding-left: 12px; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="24" class="card-box"> |
| | | <el-card> |
| | | <template #header><Monitor style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">åºæ¬ä¿¡æ¯</span></template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%"> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">Redisçæ¬</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.redis_version }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">è¿è¡æ¨¡å¼</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.redis_mode == "standalone" ? "åæº" : "é群" }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">端å£</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.tcp_port }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">客æ·ç«¯æ°</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.connected_clients }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">è¿è¡æ¶é´(天)</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.uptime_in_days }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">使ç¨å
å</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.used_memory_human }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">使ç¨CPU</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">å
åé
ç½®</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.maxmemory_human }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">AOFæ¯å¦å¼å¯</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.aof_enabled == "0" ? "å¦" : "æ¯" }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">RDBæ¯å¦æå</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">Keyæ°é</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.dbSize">{{ cache.dbSize }} </div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">ç½ç»å
¥å£/åºå£</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <template #header><PieChart style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">å½ä»¤ç»è®¡</span></template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <div ref="commandstats" style="height: 420px" /> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <template #header><Odometer style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">å
åä¿¡æ¯</span></template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <div ref="usedmemory" style="height: 420px" /> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Cache"> |
| | | import { getCache } from '@/api/monitor/cache' |
| | | import * as echarts from 'echarts' |
| | | |
| | | const cache = ref([]) |
| | | const commandstats = ref(null) |
| | | const usedmemory = ref(null) |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | function getList() { |
| | | proxy.$modal.loading("æ£å¨å è½½ç¼åçæ§æ°æ®ï¼è¯·ç¨åï¼") |
| | | getCache().then(response => { |
| | | proxy.$modal.closeLoading() |
| | | cache.value = response.data |
| | | |
| | | const commandstatsIntance = echarts.init(commandstats.value, "macarons") |
| | | commandstatsIntance.setOption({ |
| | | tooltip: { |
| | | trigger: "item", |
| | | formatter: "{a} <br/>{b} : {c} ({d}%)" |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "å½ä»¤", |
| | | type: "pie", |
| | | roseType: "radius", |
| | | radius: [15, 95], |
| | | center: ["50%", "38%"], |
| | | data: response.data.commandStats, |
| | | animationEasing: "cubicInOut", |
| | | animationDuration: 1000 |
| | | } |
| | | ] |
| | | }) |
| | | const usedmemoryInstance = echarts.init(usedmemory.value, "macarons") |
| | | usedmemoryInstance.setOption({ |
| | | tooltip: { |
| | | formatter: "{b} <br/>{a} : " + cache.value.info.used_memory_human |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "å³°å¼", |
| | | type: "gauge", |
| | | min: 0, |
| | | max: 1000, |
| | | detail: { |
| | | formatter: cache.value.info.used_memory_human |
| | | }, |
| | | data: [ |
| | | { |
| | | value: parseFloat(cache.value.info.used_memory_human), |
| | | name: "å
åæ¶è" |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | }) |
| | | window.addEventListener("resize", () => { |
| | | commandstatsIntance.resize() |
| | | usedmemoryInstance.resize() |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="8"> |
| | | <el-card style="height: calc(100vh - 125px)"> |
| | | <template #header> |
| | | <Collection style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">ç¼åå表</span> |
| | | <el-button |
| | | style="float: right; padding: 3px 0" |
| | | link |
| | | type="primary" |
| | | icon="Refresh" |
| | | @click="refreshCacheNames()" |
| | | ></el-button> |
| | | </template> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="cacheNames" |
| | | :height="tableHeight" |
| | | highlight-current-row |
| | | @row-click="getCacheKeys" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column |
| | | label="åºå·" |
| | | width="60" |
| | | type="index" |
| | | ></el-table-column> |
| | | |
| | | <el-table-column |
| | | label="ç¼ååç§°" |
| | | align="center" |
| | | prop="cacheName" |
| | | :show-overflow-tooltip="true" |
| | | :formatter="nameFormatter" |
| | | ></el-table-column> |
| | | |
| | | <el-table-column |
| | | label="夿³¨" |
| | | align="center" |
| | | prop="remark" |
| | | :show-overflow-tooltip="true" |
| | | /> |
| | | <el-table-column |
| | | label="æä½" |
| | | width="60" |
| | | align="center" |
| | | class-name="small-padding fixed-width" |
| | | > |
| | | <template #default="scope"> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | icon="Delete" |
| | | @click="handleClearCacheName(scope.row)" |
| | | ></el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <el-card style="height: calc(100vh - 125px)"> |
| | | <template #header> |
| | | <Key style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">é®åå表</span> |
| | | <el-button |
| | | style="float: right; padding: 3px 0" |
| | | link |
| | | type="primary" |
| | | icon="Refresh" |
| | | @click="refreshCacheKeys()" |
| | | ></el-button> |
| | | </template> |
| | | <el-table |
| | | v-loading="subLoading" |
| | | :data="cacheKeys" |
| | | :height="tableHeight" |
| | | highlight-current-row |
| | | @row-click="handleCacheValue" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column |
| | | label="åºå·" |
| | | width="60" |
| | | type="index" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | label="ç¼åé®å" |
| | | align="center" |
| | | :show-overflow-tooltip="true" |
| | | :formatter="keyFormatter" |
| | | > |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="æä½" |
| | | width="60" |
| | | align="center" |
| | | class-name="small-padding fixed-width" |
| | | > |
| | | <template #default="scope"> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | icon="Delete" |
| | | @click="handleClearCacheKey(scope.row)" |
| | | ></el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <el-card :bordered="false" style="height: calc(100vh - 125px)"> |
| | | <template #header> |
| | | <Document style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">ç¼åå
容</span> |
| | | <el-button |
| | | style="float: right; padding: 3px 0" |
| | | link |
| | | type="primary" |
| | | icon="Refresh" |
| | | @click="handleClearCacheAll()" |
| | | >æ¸
çå
¨é¨</el-button |
| | | > |
| | | </template> |
| | | <el-form :model="cacheForm"> |
| | | <el-row :gutter="32"> |
| | | <el-col :offset="1" :span="22"> |
| | | <el-form-item label="ç¼ååç§°:" prop="cacheName"> |
| | | <el-input v-model="cacheForm.cacheName" :readOnly="true" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :offset="1" :span="22"> |
| | | <el-form-item label="ç¼åé®å:" prop="cacheKey"> |
| | | <el-input v-model="cacheForm.cacheKey" :readOnly="true" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :offset="1" :span="22"> |
| | | <el-form-item label="ç¼åå
容:" prop="cacheValue"> |
| | | <el-input |
| | | v-model="cacheForm.cacheValue" |
| | | type="textarea" |
| | | :rows="8" |
| | | :readOnly="true" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="CacheList"> |
| | | import { listCacheName, listCacheKey, getCacheValue, clearCacheName, clearCacheKey, clearCacheAll } from "@/api/monitor/cache" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | const cacheNames = ref([]) |
| | | const cacheKeys = ref([]) |
| | | const cacheForm = ref({}) |
| | | const loading = ref(true) |
| | | const subLoading = ref(false) |
| | | const nowCacheName = ref("") |
| | | const tableHeight = ref(window.innerHeight - 200) |
| | | |
| | | /** æ¥è¯¢ç¼ååç§°å表 */ |
| | | function getCacheNames() { |
| | | loading.value = true |
| | | listCacheName().then(response => { |
| | | cacheNames.value = response.data |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** å·æ°ç¼ååç§°å表 */ |
| | | function refreshCacheNames() { |
| | | getCacheNames() |
| | | proxy.$modal.msgSuccess("å·æ°ç¼åå表æå") |
| | | } |
| | | |
| | | /** æ¸
çæå®åç§°ç¼å */ |
| | | function handleClearCacheName(row) { |
| | | clearCacheName(row.cacheName).then(response => { |
| | | proxy.$modal.msgSuccess("æ¸
çç¼ååç§°[" + row.cacheName + "]æå") |
| | | getCacheKeys() |
| | | }) |
| | | } |
| | | |
| | | /** æ¥è¯¢ç¼åé®åå表 */ |
| | | function getCacheKeys(row) { |
| | | const cacheName = row !== undefined ? row.cacheName : nowCacheName.value |
| | | if (cacheName === "") { |
| | | return |
| | | } |
| | | subLoading.value = true |
| | | listCacheKey(cacheName).then(response => { |
| | | cacheKeys.value = response.data |
| | | subLoading.value = false |
| | | nowCacheName.value = cacheName |
| | | }) |
| | | } |
| | | |
| | | /** å·æ°ç¼åé®åå表 */ |
| | | function refreshCacheKeys() { |
| | | getCacheKeys() |
| | | proxy.$modal.msgSuccess("å·æ°é®åå表æå") |
| | | } |
| | | |
| | | /** æ¸
çæå®é®åç¼å */ |
| | | function handleClearCacheKey(cacheKey) { |
| | | clearCacheKey(cacheKey).then(response => { |
| | | proxy.$modal.msgSuccess("æ¸
çç¼åé®å[" + cacheKey + "]æå") |
| | | getCacheKeys() |
| | | }) |
| | | } |
| | | |
| | | /** å表åç¼å»é¤ */ |
| | | function nameFormatter(row) { |
| | | return row.cacheName.replace(":", "") |
| | | } |
| | | |
| | | /** é®ååç¼å»é¤ */ |
| | | function keyFormatter(cacheKey) { |
| | | return cacheKey.replace(nowCacheName.value, "") |
| | | } |
| | | |
| | | /** æ¥è¯¢ç¼åå
å®¹è¯¦ç» */ |
| | | function handleCacheValue(cacheKey) { |
| | | getCacheValue(nowCacheName.value, cacheKey).then(response => { |
| | | cacheForm.value = response.data |
| | | }) |
| | | } |
| | | |
| | | /** æ¸
çå
¨é¨ç¼å */ |
| | | function handleClearCacheAll() { |
| | | clearCacheAll().then(response => { |
| | | proxy.$modal.msgSuccess("æ¸
çå
¨é¨ç¼åæå") |
| | | }) |
| | | } |
| | | |
| | | getCacheNames() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <i-frame v-model:src="url"></i-frame> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import iFrame from '@/components/iFrame' |
| | | |
| | | import { ref } from 'vue' |
| | | |
| | | const url = ref(import.meta.env.VITE_APP_BASE_API + '/druid/login.html') |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch"> |
| | | <el-form-item label="ä»»å¡åç§°" prop="jobName"> |
| | | <el-input |
| | | v-model="queryParams.jobName" |
| | | placeholder="请è¾å
¥ä»»å¡åç§°" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ä»»å¡ç»å" prop="jobGroup"> |
| | | <el-select v-model="queryParams.jobGroup" placeholder="è¯·éæ©ä»»å¡ç»å" clearable style="width: 200px"> |
| | | <el-option |
| | | v-for="dict in sys_job_group" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ä»»å¡ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="è¯·éæ©ä»»å¡ç¶æ" clearable style="width: 200px"> |
| | | <el-option |
| | | v-for="dict in sys_job_status" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | v-hasPermi="['monitor:job:add']" |
| | | >æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="Edit" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['monitor:job:edit']" |
| | | >ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['monitor:job:remove']" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Download" |
| | | @click="handleExport" |
| | | v-hasPermi="['monitor:job:export']" |
| | | >导åº</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="info" |
| | | plain |
| | | icon="Operation" |
| | | @click="handleJobLog" |
| | | v-hasPermi="['monitor:job:query']" |
| | | >æ¥å¿</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="ä»»å¡ç¼å·" width="100" align="center" prop="jobId" /> |
| | | <el-table-column label="ä»»å¡åç§°" align="center" prop="jobName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ä»»å¡ç»å" align="center" prop="jobGroup"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_job_group" :value="scope.row.jobGroup" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="è°ç¨ç®æ å符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="cronæ§è¡è¡¨è¾¾å¼" align="center" prop="cronExpression" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç¶æ" align="center"> |
| | | <template #default="scope"> |
| | | <el-switch |
| | | v-model="scope.row.status" |
| | | active-value="0" |
| | | inactive-value="1" |
| | | @change="handleStatusChange(scope.row)" |
| | | ></el-switch> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="200" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['monitor:job:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['monitor:job:remove']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="æ§è¡ä¸æ¬¡" placement="top"> |
| | | <el-button link type="primary" icon="CaretRight" @click="handleRun(scope.row)" v-hasPermi="['monitor:job:changeStatus']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="ä»»å¡è¯¦ç»" placement="top"> |
| | | <el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['monitor:job:query']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="è°åº¦æ¥å¿" placement="top"> |
| | | <el-button link type="primary" icon="Operation" @click="handleJobLog(scope.row)" v-hasPermi="['monitor:job:query']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- æ·»å æä¿®æ¹å®æ¶ä»»å¡å¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="820px" append-to-body> |
| | | <el-form ref="jobRef" :model="form" :rules="rules" label-width="120px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä»»å¡åç§°" prop="jobName"> |
| | | <el-input v-model="form.jobName" placeholder="请è¾å
¥ä»»å¡åç§°" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä»»å¡åç»" prop="jobGroup"> |
| | | <el-select v-model="form.jobGroup" placeholder="è¯·éæ©"> |
| | | <el-option |
| | | v-for="dict in sys_job_group" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item prop="invokeTarget"> |
| | | <template #label> |
| | | <span> |
| | | è°ç¨æ¹æ³ |
| | | <el-tooltip placement="top"> |
| | | <template #content> |
| | | <div> |
| | | Beanè°ç¨ç¤ºä¾ï¼ryTask.ryParams('ry') |
| | | <br />Classç±»è°ç¨ç¤ºä¾ï¼com.ruoyi.quartz.task.RyTask.ryParams('ry') |
| | | <br />åæ°è¯´æï¼æ¯æå符串ï¼å¸å°ç±»åï¼é¿æ´åï¼æµ®ç¹åï¼æ´å |
| | | </div> |
| | | </template> |
| | | <el-icon><question-filled /></el-icon> |
| | | </el-tooltip> |
| | | </span> |
| | | </template> |
| | | <el-input v-model="form.invokeTarget" placeholder="请è¾å
¥è°ç¨ç®æ å符串" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="cron表达å¼" prop="cronExpression"> |
| | | <el-input v-model="form.cronExpression" placeholder="请è¾å
¥cronæ§è¡è¡¨è¾¾å¼"> |
| | | <template #append> |
| | | <el-button type="primary" @click="handleShowCron"> |
| | | çæè¡¨è¾¾å¼ |
| | | <i class="el-icon-time el-icon--right"></i> |
| | | </el-button> |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24" v-if="form.jobId !== undefined"> |
| | | <el-form-item label="ç¶æ"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in sys_job_status" |
| | | :key="dict.value" |
| | | :value="dict.value" |
| | | >{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ§è¡çç¥" prop="misfirePolicy"> |
| | | <el-radio-group v-model="form.misfirePolicy"> |
| | | <el-radio-button value="1">ç«å³æ§è¡</el-radio-button> |
| | | <el-radio-button value="2">æ§è¡ä¸æ¬¡</el-radio-button> |
| | | <el-radio-button value="3">æ¾å¼æ§è¡</el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¯å¦å¹¶å" prop="concurrent"> |
| | | <el-radio-group v-model="form.concurrent"> |
| | | <el-radio-button value="0">å
许</el-radio-button> |
| | | <el-radio-button value="1">ç¦æ¢</el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <el-dialog title="Cron表达å¼çæå¨" v-model="openCron" append-to-body destroy-on-close> |
| | | <crontab ref="crontabRef" @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab> |
| | | </el-dialog> |
| | | |
| | | <!-- 任塿¥å¿è¯¦ç» --> |
| | | <el-dialog title="ä»»å¡è¯¦ç»" v-model="openView" width="700px" append-to-body> |
| | | <el-form :model="form" label-width="120px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä»»å¡ç¼å·ï¼">{{ form.jobId }}</el-form-item> |
| | | <el-form-item label="ä»»å¡åç§°ï¼">{{ form.jobName }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä»»å¡åç»ï¼">{{ jobGroupFormat(form) }}</el-form-item> |
| | | <el-form-item label="å建æ¶é´ï¼">{{ form.createTime }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="cron表达å¼ï¼">{{ form.cronExpression }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="䏿¬¡æ§è¡æ¶é´ï¼">{{ parseTime(form.nextValidTime) }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="è°ç¨ç®æ æ¹æ³ï¼">{{ form.invokeTarget }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä»»å¡ç¶æï¼"> |
| | | <div v-if="form.status == 0">æ£å¸¸</div> |
| | | <div v-else-if="form.status == 1">æå</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¯å¦å¹¶åï¼"> |
| | | <div v-if="form.concurrent == 0">å
许</div> |
| | | <div v-else-if="form.concurrent == 1">ç¦æ¢</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ§è¡çç¥ï¼"> |
| | | <div v-if="form.misfirePolicy == 0">é»è®¤çç¥</div> |
| | | <div v-else-if="form.misfirePolicy == 1">ç«å³æ§è¡</div> |
| | | <div v-else-if="form.misfirePolicy == 2">æ§è¡ä¸æ¬¡</div> |
| | | <div v-else-if="form.misfirePolicy == 3">æ¾å¼æ§è¡</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="openView = false">å
³ é</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Job"> |
| | | import Crontab from '@/components/Crontab' |
| | | import { listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus } from "@/api/monitor/job" |
| | | |
| | | const router = useRouter() |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_job_group, sys_job_status } = proxy.useDict("sys_job_group", "sys_job_status") |
| | | |
| | | const jobList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const single = ref(true) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const title = ref("") |
| | | const openView = ref(false) |
| | | const openCron = ref(false) |
| | | const expression = ref("") |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | jobName: undefined, |
| | | jobGroup: undefined, |
| | | status: undefined |
| | | }, |
| | | rules: { |
| | | jobName: [{ required: true, message: "ä»»å¡åç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | invokeTarget: [{ required: true, message: "è°ç¨ç®æ å符串ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | cronExpression: [{ required: true, message: "cronæ§è¡è¡¨è¾¾å¼ä¸è½ä¸ºç©º", trigger: "change" }] |
| | | } |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢å®æ¶ä»»å¡å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | listJob(queryParams.value).then(response => { |
| | | jobList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** ä»»å¡ç»ååå
¸ç¿»è¯ */ |
| | | function jobGroupFormat(row, column) { |
| | | return proxy.selectDictLabel(sys_job_group.value, row.jobGroup) |
| | | } |
| | | |
| | | /** åæ¶æé® */ |
| | | function cancel() { |
| | | open.value = false |
| | | reset() |
| | | } |
| | | |
| | | /** 表åéç½® */ |
| | | function reset() { |
| | | form.value = { |
| | | jobId: undefined, |
| | | jobName: undefined, |
| | | jobGroup: undefined, |
| | | invokeTarget: undefined, |
| | | cronExpression: undefined, |
| | | misfirePolicy: 1, |
| | | concurrent: 1, |
| | | status: "0" |
| | | } |
| | | proxy.resetForm("jobRef") |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | // å¤éæ¡é䏿°æ® |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.jobId) |
| | | single.value = selection.length != 1 |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | // æ´å¤æä½è§¦å |
| | | function handleCommand(command, row) { |
| | | switch (command) { |
| | | case "handleRun": |
| | | handleRun(row) |
| | | break |
| | | case "handleView": |
| | | handleView(row) |
| | | break |
| | | case "handleJobLog": |
| | | handleJobLog(row) |
| | | break |
| | | default: |
| | | break |
| | | } |
| | | } |
| | | |
| | | // ä»»å¡ç¶æä¿®æ¹ |
| | | function handleStatusChange(row) { |
| | | let text = row.status === "0" ? "å¯ç¨" : "åç¨" |
| | | proxy.$modal.confirm('确认è¦"' + text + '""' + row.jobName + '"ä»»å¡å?').then(function () { |
| | | return changeJobStatus(row.jobId, row.status) |
| | | }).then(() => { |
| | | proxy.$modal.msgSuccess(text + "æå") |
| | | }).catch(function () { |
| | | row.status = row.status === "0" ? "1" : "0" |
| | | }) |
| | | } |
| | | |
| | | /* ç«å³æ§è¡ä¸æ¬¡ */ |
| | | function handleRun(row) { |
| | | proxy.$modal.confirm('确认è¦ç«å³æ§è¡ä¸æ¬¡"' + row.jobName + '"ä»»å¡å?').then(function () { |
| | | return runJob(row.jobId, row.jobGroup) |
| | | }).then(() => { |
| | | proxy.$modal.msgSuccess("æ§è¡æå")}) |
| | | .catch(() => {}) |
| | | } |
| | | |
| | | /** ä»»å¡è¯¦ç»ä¿¡æ¯ */ |
| | | function handleView(row) { |
| | | getJob(row.jobId).then(response => { |
| | | form.value = response.data |
| | | openView.value = true |
| | | }) |
| | | } |
| | | |
| | | /** cronè¡¨è¾¾å¼æé®æä½ */ |
| | | function handleShowCron() { |
| | | expression.value = form.value.cronExpression |
| | | openCron.value = true |
| | | } |
| | | |
| | | /** ç¡®å®ååä¼ å¼ */ |
| | | function crontabFill(value) { |
| | | form.value.cronExpression = value |
| | | } |
| | | |
| | | /** 任塿¥å¿å表æ¥è¯¢ */ |
| | | function handleJobLog(row) { |
| | | const jobId = row.jobId || 0 |
| | | router.push('/monitor/job-log/index/' + jobId) |
| | | } |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | function handleAdd() { |
| | | reset() |
| | | open.value = true |
| | | title.value = "æ·»å ä»»å¡" |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | function handleUpdate(row) { |
| | | reset() |
| | | const jobId = row.jobId || ids.value |
| | | getJob(jobId).then(response => { |
| | | form.value = response.data |
| | | open.value = true |
| | | title.value = "ä¿®æ¹ä»»å¡" |
| | | }) |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["jobRef"].validate(valid => { |
| | | if (valid) { |
| | | if (form.value.jobId != undefined) { |
| | | updateJob(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } else { |
| | | addJob(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | const jobIds = row.jobId || ids.value |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å®æ¶ä»»å¡ç¼å·ä¸º"' + jobIds + '"çæ°æ®é¡¹?').then(function () { |
| | | return delJob(jobIds) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | function handleExport() { |
| | | proxy.download("monitor/job/export", { |
| | | ...queryParams.value, |
| | | }, `job_${new Date().getTime()}.xlsx`) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="ä»»å¡åç§°" prop="jobName"> |
| | | <el-input |
| | | v-model="queryParams.jobName" |
| | | placeholder="请è¾å
¥ä»»å¡åç§°" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ä»»å¡ç»å" prop="jobGroup"> |
| | | <el-select |
| | | v-model="queryParams.jobGroup" |
| | | placeholder="è¯·éæ©ä»»å¡ç»å" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in sys_job_group" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æ§è¡ç¶æ" prop="status"> |
| | | <el-select |
| | | v-model="queryParams.status" |
| | | placeholder="è¯·éæ©æ§è¡ç¶æ" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in sys_common_status" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æ§è¡æ¶é´" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['monitor:job:remove']" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | @click="handleClean" |
| | | v-hasPermi="['monitor:job:remove']" |
| | | >æ¸
空</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Download" |
| | | @click="handleExport" |
| | | v-hasPermi="['monitor:job:export']" |
| | | >导åº</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Close" |
| | | @click="handleClose" |
| | | >å
³é</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="jobLogList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="æ¥å¿ç¼å·" width="80" align="center" prop="jobLogId" /> |
| | | <el-table-column label="ä»»å¡åç§°" align="center" prop="jobName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ä»»å¡ç»å" align="center" prop="jobGroup" :show-overflow-tooltip="true"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_job_group" :value="scope.row.jobGroup" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="è°ç¨ç®æ å符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æ¥å¿ä¿¡æ¯" align="center" prop="jobMessage" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æ§è¡ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_common_status" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æ§è¡æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['monitor:job:query']">详ç»</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- è°åº¦æ¥å¿è¯¦ç» --> |
| | | <el-dialog title="è°åº¦æ¥å¿è¯¦ç»" v-model="open" width="700px" append-to-body> |
| | | <el-form :model="form" label-width="100px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥å¿åºå·ï¼">{{ form.jobLogId }}</el-form-item> |
| | | <el-form-item label="ä»»å¡åç§°ï¼">{{ form.jobName }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä»»å¡åç»ï¼">{{ form.jobGroup }}</el-form-item> |
| | | <el-form-item label="æ§è¡æ¶é´ï¼">{{ form.createTime }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="è°ç¨æ¹æ³ï¼">{{ form.invokeTarget }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æ¥å¿ä¿¡æ¯ï¼">{{ form.jobMessage }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æ§è¡ç¶æï¼"> |
| | | <div v-if="form.status == 0">æ£å¸¸</div> |
| | | <div v-else-if="form.status == 1">失败</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å¼å¸¸ä¿¡æ¯ï¼" v-if="form.status == 1">{{ form.exceptionInfo }}</el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="open = false">å
³ é</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="JobLog"> |
| | | import { getJob } from "@/api/monitor/job" |
| | | import { listJobLog, delJobLog, cleanJobLog } from "@/api/monitor/jobLog" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_common_status, sys_job_group } = proxy.useDict("sys_common_status", "sys_job_group") |
| | | |
| | | const jobLogList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const dateRange = ref([]) |
| | | const route = useRoute() |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | dictName: undefined, |
| | | dictType: undefined, |
| | | status: undefined |
| | | } |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢è°åº¦æ¥å¿å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | listJobLog(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => { |
| | | jobLogList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | // è¿åæé® |
| | | function handleClose() { |
| | | const obj = { path: "/monitor/job" } |
| | | proxy.$tab.closeOpenPage(obj) |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | dateRange.value = [] |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | // å¤éæ¡é䏿°æ® |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.jobLogId) |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | /** è¯¦ç»æé®æä½ */ |
| | | function handleView(row) { |
| | | open.value = true |
| | | form.value = row |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤è°åº¦æ¥å¿ç¼å·ä¸º"' + ids.value + '"çæ°æ®é¡¹?').then(function () { |
| | | return delJobLog(ids.value) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** æ¸
空æé®æä½ */ |
| | | function handleClean() { |
| | | proxy.$modal.confirm("æ¯å¦ç¡®è®¤æ¸
空ææè°åº¦æ¥å¿æ°æ®é¡¹?").then(function () { |
| | | return cleanJobLog() |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("æ¸
空æå") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | function handleExport() { |
| | | proxy.download("monitor/jobLog/export", { |
| | | ...queryParams.value, |
| | | }, `job_log_${new Date().getTime()}.xlsx`) |
| | | } |
| | | |
| | | (() => { |
| | | const jobId = route.params && route.params.jobId |
| | | if (jobId !== undefined && jobId != 0) { |
| | | getJob(jobId).then(response => { |
| | | queryParams.value.jobName = response.data.jobName |
| | | queryParams.value.jobGroup = response.data.jobGroup |
| | | getList() |
| | | }) |
| | | } else { |
| | | getList() |
| | | } |
| | | })() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="ç»å½å°å" prop="ipaddr"> |
| | | <el-input |
| | | v-model="queryParams.ipaddr" |
| | | placeholder="请è¾å
¥ç»å½å°å" |
| | | clearable |
| | | style="width: 240px;" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¨æ·åç§°" prop="userName"> |
| | | <el-input |
| | | v-model="queryParams.userName" |
| | | placeholder="请è¾å
¥ç¨æ·åç§°" |
| | | clearable |
| | | style="width: 240px;" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select |
| | | v-model="queryParams.status" |
| | | placeholder="ç»å½ç¶æ" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in sys_common_status" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç»å½æ¶é´" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['monitor:logininfor:remove']" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | @click="handleClean" |
| | | v-hasPermi="['monitor:logininfor:remove']" |
| | | >æ¸
空</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Unlock" |
| | | :disabled="single" |
| | | @click="handleUnlock" |
| | | v-hasPermi="['monitor:logininfor:unlock']" |
| | | >è§£é</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Download" |
| | | @click="handleExport" |
| | | v-hasPermi="['monitor:logininfor:export']" |
| | | >导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table ref="logininforRef" v-loading="loading" :data="logininforList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="访é®ç¼å·" align="center" prop="infoId" /> |
| | | <el-table-column label="ç¨æ·åç§°" align="center" prop="userName" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" /> |
| | | <el-table-column label="å°å" align="center" prop="ipaddr" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½å°ç¹" align="center" prop="loginLocation" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç³»ç»" align="center" prop="os" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æµè§å¨" align="center" prop="browser" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_common_status" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æè¿°" align="center" prop="msg" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="è®¿é®æ¶é´" align="center" prop="loginTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.loginTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Logininfor"> |
| | | import { list, delLogininfor, cleanLogininfor, unlockLogininfor } from "@/api/monitor/logininfor" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_common_status } = proxy.useDict("sys_common_status") |
| | | |
| | | const logininforList = ref([]) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const single = ref(true) |
| | | const multiple = ref(true) |
| | | const selectName = ref("") |
| | | const total = ref(0) |
| | | const dateRange = ref([]) |
| | | const defaultSort = ref({ prop: "loginTime", order: "descending" }) |
| | | |
| | | // æ¥è¯¢åæ° |
| | | const queryParams = ref({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | ipaddr: undefined, |
| | | userName: undefined, |
| | | status: undefined, |
| | | orderByColumn: undefined, |
| | | isAsc: undefined |
| | | }) |
| | | |
| | | /** æ¥è¯¢ç»å½æ¥å¿å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | list(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => { |
| | | logininforList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | dateRange.value = [] |
| | | proxy.resetForm("queryRef") |
| | | queryParams.value.pageNum = 1 |
| | | proxy.$refs["logininforRef"].sort(defaultSort.value.prop, defaultSort.value.order) |
| | | } |
| | | |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.infoId) |
| | | multiple.value = !selection.length |
| | | single.value = selection.length != 1 |
| | | selectName.value = selection.map(item => item.userName) |
| | | } |
| | | |
| | | /** æåºè§¦åäºä»¶ */ |
| | | function handleSortChange(column, prop, order) { |
| | | queryParams.value.orderByColumn = column.prop |
| | | queryParams.value.isAsc = column.order |
| | | getList() |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | const infoIds = row.infoId || ids.value |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤è®¿é®ç¼å·ä¸º"' + infoIds + '"çæ°æ®é¡¹?').then(function () { |
| | | return delLogininfor(infoIds) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** æ¸
空æé®æä½ */ |
| | | function handleClean() { |
| | | proxy.$modal.confirm("æ¯å¦ç¡®è®¤æ¸
空ææç»å½æ¥å¿æ°æ®é¡¹?").then(function () { |
| | | return cleanLogininfor() |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("æ¸
空æå") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** è§£éæé®æä½ */ |
| | | function handleUnlock() { |
| | | const username = selectName.value |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤è§£éç¨æ·"' + username + '"æ°æ®é¡¹?').then(function () { |
| | | return unlockLogininfor(username) |
| | | }).then(() => { |
| | | proxy.$modal.msgSuccess("ç¨æ·" + username + "è§£éæå") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | function handleExport() { |
| | | proxy.download("monitor/logininfor/export", { |
| | | ...queryParams.value, |
| | | }, `logininfor_${new Date().getTime()}.xlsx`) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true"> |
| | | <el-form-item label="ç»å½å°å" prop="ipaddr"> |
| | | <el-input |
| | | v-model="queryParams.ipaddr" |
| | | placeholder="请è¾å
¥ç»å½å°å" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¨æ·åç§°" prop="userName"> |
| | | <el-input |
| | | v-model="queryParams.userName" |
| | | placeholder="请è¾å
¥ç¨æ·åç§°" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="onlineList.slice((pageNum - 1) * pageSize, pageNum * pageSize)" |
| | | style="width: 100%;" |
| | | > |
| | | <el-table-column label="åºå·" width="50" type="index" align="center"> |
| | | <template #default="scope"> |
| | | <span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ä¼è¯ç¼å·" align="center" prop="tokenId" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½åç§°" align="center" prop="userName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æå±é¨é¨" align="center" prop="deptName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="主æº" align="center" prop="ipaddr" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½å°ç¹" align="center" prop="loginLocation" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç³»ç»" align="center" prop="os" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æµè§å¨" align="center" prop="browser" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç»å½æ¶é´" align="center" prop="loginTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.loginTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="Delete" @click="handleForceLogout(scope.row)" v-hasPermi="['monitor:online:forceLogout']">强é</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="pageNum" v-model:limit="pageSize" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Online"> |
| | | import { forceLogout, list as initData } from "@/api/monitor/online" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | const onlineList = ref([]) |
| | | const loading = ref(true) |
| | | const total = ref(0) |
| | | const pageNum = ref(1) |
| | | const pageSize = ref(10) |
| | | |
| | | const queryParams = ref({ |
| | | ipaddr: undefined, |
| | | userName: undefined |
| | | }) |
| | | |
| | | /** æ¥è¯¢ç»å½æ¥å¿å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | initData(queryParams.value).then(response => { |
| | | onlineList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | pageNum.value = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | /** 强éæé®æä½ */ |
| | | function handleForceLogout(row) { |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å¼ºéå称为"' + row.userName + '"çç¨æ·?').then(function () { |
| | | return forceLogout(row.tokenId) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="æä½å°å" prop="operIp"> |
| | | <el-input |
| | | v-model="queryParams.operIp" |
| | | placeholder="请è¾å
¥æä½å°å" |
| | | clearable |
| | | style="width: 240px;" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç³»ç»æ¨¡å" prop="title"> |
| | | <el-input |
| | | v-model="queryParams.title" |
| | | placeholder="请è¾å
¥ç³»ç»æ¨¡å" |
| | | clearable |
| | | style="width: 240px;" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="æä½äººå" prop="operName"> |
| | | <el-input |
| | | v-model="queryParams.operName" |
| | | placeholder="请è¾å
¥æä½äººå" |
| | | clearable |
| | | style="width: 240px;" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç±»å" prop="businessType"> |
| | | <el-select |
| | | v-model="queryParams.businessType" |
| | | placeholder="æä½ç±»å" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in sys_oper_type" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select |
| | | v-model="queryParams.status" |
| | | placeholder="æä½ç¶æ" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in sys_common_status" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æä½æ¶é´" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['monitor:operlog:remove']" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | @click="handleClean" |
| | | v-hasPermi="['monitor:operlog:remove']" |
| | | >æ¸
空</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Download" |
| | | @click="handleExport" |
| | | v-hasPermi="['monitor:operlog:export']" |
| | | >导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table ref="operlogRef" v-loading="loading" :data="operlogList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange"> |
| | | <el-table-column type="selection" width="50" align="center" /> |
| | | <el-table-column label="æ¥å¿ç¼å·" align="center" prop="operId" /> |
| | | <el-table-column label="ç³»ç»æ¨¡å" align="center" prop="title" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç±»å" align="center" prop="businessType"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_oper_type" :value="scope.row.businessType" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½äººå" align="center" width="110" prop="operName" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" /> |
| | | <el-table-column label="æä½å°å" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="æä½ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_common_status" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½æ¥æ" align="center" prop="operTime" width="180" sortable="custom" :sort-orders="['descending', 'ascending']"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.operTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æ¶èæ¶é´" align="center" prop="costTime" width="110" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']"> |
| | | <template #default="scope"> |
| | | <span>{{ scope.row.costTime }}毫ç§</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="View" @click="handleView(scope.row, scope.index)" v-hasPermi="['monitor:operlog:query']">详ç»</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- æä½æ¥å¿è¯¦ç» --> |
| | | <el-dialog title="æä½æ¥å¿è¯¦ç»" v-model="open" width="800px" append-to-body> |
| | | <el-form :model="form" label-width="100px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æä½æ¨¡åï¼">{{ form.title }} / {{ typeFormat(form) }}</el-form-item> |
| | | <el-form-item |
| | | label="ç»å½ä¿¡æ¯ï¼" |
| | | >{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="请æ±å°åï¼">{{ form.operUrl }}</el-form-item> |
| | | <el-form-item label="è¯·æ±æ¹å¼ï¼">{{ form.requestMethod }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="æä½æ¹æ³ï¼">{{ form.method }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="请æ±åæ°ï¼">{{ form.operParam }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="è¿ååæ°ï¼">{{ form.jsonResult }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="æä½ç¶æï¼"> |
| | | <div v-if="form.status === 0">æ£å¸¸</div> |
| | | <div v-else-if="form.status === 1">失败</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="æ¶èæ¶é´ï¼">{{ form.costTime }}毫ç§</el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="æä½æ¶é´ï¼">{{ parseTime(form.operTime) }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å¼å¸¸ä¿¡æ¯ï¼" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="open = false">å
³ é</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Operlog"> |
| | | import { list, delOperlog, cleanOperlog } from "@/api/monitor/operlog" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_oper_type, sys_common_status } = proxy.useDict("sys_oper_type", "sys_common_status") |
| | | |
| | | const operlogList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const single = ref(true) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const title = ref("") |
| | | const dateRange = ref([]) |
| | | const defaultSort = ref({ prop: "operTime", order: "descending" }) |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | operIp: undefined, |
| | | title: undefined, |
| | | operName: undefined, |
| | | businessType: undefined, |
| | | status: undefined |
| | | } |
| | | }) |
| | | |
| | | const { queryParams, form } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢ç»å½æ¥å¿ */ |
| | | function getList() { |
| | | loading.value = true |
| | | list(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => { |
| | | operlogList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** æä½æ¥å¿ç±»ååå
¸ç¿»è¯ */ |
| | | function typeFormat(row, column) { |
| | | return proxy.selectDictLabel(sys_oper_type.value, row.businessType) |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | dateRange.value = [] |
| | | proxy.resetForm("queryRef") |
| | | queryParams.value.pageNum = 1 |
| | | proxy.$refs["operlogRef"].sort(defaultSort.value.prop, defaultSort.value.order) |
| | | } |
| | | |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.operId) |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | /** æåºè§¦åäºä»¶ */ |
| | | function handleSortChange(column, prop, order) { |
| | | queryParams.value.orderByColumn = column.prop |
| | | queryParams.value.isAsc = column.order |
| | | getList() |
| | | } |
| | | |
| | | /** è¯¦ç»æé®æä½ */ |
| | | function handleView(row) { |
| | | open.value = true |
| | | form.value = row |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | const operIds = row.operId || ids.value |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å 餿¥å¿ç¼å·ä¸º"' + operIds + '"çæ°æ®é¡¹?').then(function () { |
| | | return delOperlog(operIds) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** æ¸
空æé®æä½ */ |
| | | function handleClean() { |
| | | proxy.$modal.confirm("æ¯å¦ç¡®è®¤æ¸
ç©ºæææä½æ¥å¿æ°æ®é¡¹?").then(function () { |
| | | return cleanOperlog() |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("æ¸
空æå") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | function handleExport() { |
| | | proxy.download("monitor/operlog/export",{ |
| | | ...queryParams.value, |
| | | }, `config_${new Date().getTime()}.xlsx`) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <template #header><Cpu style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">CPU</span></template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%;"> |
| | | <thead> |
| | | <tr> |
| | | <th class="el-table__cell is-leaf"><div class="cell">屿§</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">å¼</div></th> |
| | | </tr> |
| | | </thead> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">æ ¸å¿æ°</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.cpuNum }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">ç¨æ·ä½¿ç¨ç</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.used }}%</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">ç³»ç»ä½¿ç¨ç</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.sys }}%</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">å½å空é²ç</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.free }}%</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <template #header><Tickets style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">å
å</span></template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%;"> |
| | | <thead> |
| | | <tr> |
| | | <th class="el-table__cell is-leaf"><div class="cell">屿§</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">å
å</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">JVM</div></th> |
| | | </tr> |
| | | </thead> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">æ»å
å</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.total }}G</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.total }}M</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">å·²ç¨å
å</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.used}}G</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.used}}M</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">å©ä½å
å</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.free }}G</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.free }}M</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">使ç¨ç</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem" :class="{'text-danger': server.mem.usage > 80}">{{ server.mem.usage }}%</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm" :class="{'text-danger': server.jvm.usage > 80}">{{ server.jvm.usage }}%</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="24" class="card-box"> |
| | | <el-card> |
| | | <template #header><Monitor style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">æå¡å¨ä¿¡æ¯</span></template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%;"> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">æå¡å¨åç§°</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.computerName }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">æä½ç³»ç»</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.osName }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">æå¡å¨IP</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.computerIp }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">ç³»ç»æ¶æ</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.osArch }}</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="24" class="card-box"> |
| | | <el-card> |
| | | <template #header><CoffeeCup style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">Javaèææºä¿¡æ¯</span></template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%;table-layout:fixed;"> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">Javaåç§°</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.name }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">Javaçæ¬</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.version }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">å¯å¨æ¶é´</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.startTime }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">è¿è¡æ¶é¿</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.runTime }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td colspan="1" class="el-table__cell is-leaf"><div class="cell">å®è£
è·¯å¾</div></td> |
| | | <td colspan="3" class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.home }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td colspan="1" class="el-table__cell is-leaf"><div class="cell">项ç®è·¯å¾</div></td> |
| | | <td colspan="3" class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.userDir }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td colspan="1" class="el-table__cell is-leaf"><div class="cell">è¿è¡åæ°</div></td> |
| | | <td colspan="3" class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.inputArgs }}</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="24" class="card-box"> |
| | | <el-card> |
| | | <template #header><MessageBox style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">ç£çç¶æ</span></template> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%;"> |
| | | <thead> |
| | | <tr> |
| | | <th class="el-table__cell el-table__cell is-leaf"><div class="cell">ç符路å¾</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">æä»¶ç³»ç»</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">ç符类å</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">æ»å¤§å°</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">å¯ç¨å¤§å°</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">å·²ç¨å¤§å°</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">å·²ç¨ç¾åæ¯</div></th> |
| | | </tr> |
| | | </thead> |
| | | <tbody v-if="server.sysFiles"> |
| | | <tr v-for="(sysFile, index) in server.sysFiles" :key="index"> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.dirName }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.sysTypeName }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.typeName }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.total }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.free }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.used }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" :class="{'text-danger': sysFile.usage > 80}">{{ sysFile.usage }}%</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getServer } from '@/api/monitor/server' |
| | | |
| | | const server = ref([]) |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | function getList() { |
| | | proxy.$modal.loading("æ£å¨å è½½æå¡çæ§æ°æ®ï¼è¯·ç¨åï¼") |
| | | getServer().then(response => { |
| | | server.value = response.data |
| | | proxy.$modal.closeLoading() |
| | | }) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div></div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { useRoute, useRouter } from 'vue-router' |
| | | |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | const { params, query } = route |
| | | const { path } = params |
| | | |
| | | router.replace({ path: '/' + path, query }) |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="register"> |
| | | <el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form"> |
| | | <h3 class="title">{{ title }}</h3> |
| | | <el-form-item prop="username"> |
| | | <el-input |
| | | v-model="registerForm.username" |
| | | type="text" |
| | | size="large" |
| | | auto-complete="off" |
| | | placeholder="è´¦å·" |
| | | > |
| | | <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="password"> |
| | | <el-input |
| | | v-model="registerForm.password" |
| | | type="password" |
| | | size="large" |
| | | auto-complete="off" |
| | | placeholder="å¯ç " |
| | | @keyup.enter="handleRegister" |
| | | > |
| | | <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="confirmPassword"> |
| | | <el-input |
| | | v-model="registerForm.confirmPassword" |
| | | type="password" |
| | | size="large" |
| | | auto-complete="off" |
| | | placeholder="确认å¯ç " |
| | | @keyup.enter="handleRegister" |
| | | > |
| | | <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="code" v-if="captchaEnabled"> |
| | | <el-input |
| | | size="large" |
| | | v-model="registerForm.code" |
| | | auto-complete="off" |
| | | placeholder="éªè¯ç " |
| | | style="width: 63%" |
| | | @keyup.enter="handleRegister" |
| | | > |
| | | <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template> |
| | | </el-input> |
| | | <div class="register-code"> |
| | | <img :src="codeUrl" @click="getCode" class="register-code-img"/> |
| | | </div> |
| | | </el-form-item> |
| | | <el-form-item style="width:100%;"> |
| | | <el-button |
| | | :loading="loading" |
| | | size="large" |
| | | type="primary" |
| | | style="width:100%;" |
| | | @click.prevent="handleRegister" |
| | | > |
| | | <span v-if="!loading">注 å</span> |
| | | <span v-else>注 å ä¸...</span> |
| | | </el-button> |
| | | <div style="float: right;"> |
| | | <router-link class="link-type" :to="'/login'">使ç¨å·²æè´¦æ·ç»å½</router-link> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- åºé¨ --> |
| | | <div class="el-register-footer"> |
| | | <span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ElMessageBox } from "element-plus" |
| | | import { getCodeImg, register } from "@/api/login" |
| | | |
| | | const title = import.meta.env.VITE_APP_TITLE |
| | | const router = useRouter() |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | const registerForm = ref({ |
| | | username: "", |
| | | password: "", |
| | | confirmPassword: "", |
| | | code: "", |
| | | uuid: "" |
| | | }) |
| | | |
| | | const equalToPassword = (rule, value, callback) => { |
| | | if (registerForm.value.password !== value) { |
| | | callback(new Error("两次è¾å
¥çå¯ç ä¸ä¸è´")) |
| | | } else { |
| | | callback() |
| | | } |
| | | } |
| | | |
| | | const registerRules = { |
| | | username: [ |
| | | { required: true, trigger: "blur", message: "请è¾å
¥æ¨çè´¦å·" }, |
| | | { min: 2, max: 20, message: "ç¨æ·è´¦å·é¿åº¦å¿
é¡»ä»äº 2 å 20 ä¹é´", trigger: "blur" } |
| | | ], |
| | | password: [ |
| | | { required: true, trigger: "blur", message: "请è¾å
¥æ¨çå¯ç " }, |
| | | { min: 5, max: 20, message: "ç¨æ·å¯ç é¿åº¦å¿
é¡»ä»äº 5 å 20 ä¹é´", trigger: "blur" }, |
| | | { pattern: /^[^<>"'|\\]+$/, message: "ä¸è½å
å«éæ³å符ï¼< > \" ' \\\ |", trigger: "blur" } |
| | | ], |
| | | confirmPassword: [ |
| | | { required: true, trigger: "blur", message: "è¯·åæ¬¡è¾å
¥æ¨çå¯ç " }, |
| | | { required: true, validator: equalToPassword, trigger: "blur" } |
| | | ], |
| | | code: [{ required: true, trigger: "change", message: "请è¾å
¥éªè¯ç " }] |
| | | } |
| | | |
| | | const codeUrl = ref("") |
| | | const loading = ref(false) |
| | | const captchaEnabled = ref(true) |
| | | |
| | | function handleRegister() { |
| | | proxy.$refs.registerRef.validate(valid => { |
| | | if (valid) { |
| | | loading.value = true |
| | | register(registerForm.value).then(res => { |
| | | const username = registerForm.value.username |
| | | ElMessageBox.alert("<font color='red'>æåä½ ï¼æ¨çè´¦å· " + username + " 注åæåï¼</font>", "ç³»ç»æç¤º", { |
| | | dangerouslyUseHTMLString: true, |
| | | type: "success", |
| | | }).then(() => { |
| | | router.push("/login") |
| | | }).catch(() => {}) |
| | | }).catch(() => { |
| | | loading.value = false |
| | | if (captchaEnabled) { |
| | | getCode() |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | function getCode() { |
| | | getCodeImg().then(res => { |
| | | captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled |
| | | if (captchaEnabled.value) { |
| | | codeUrl.value = "data:image/gif;base64," + res.img |
| | | registerForm.value.uuid = res.uuid |
| | | } |
| | | }) |
| | | } |
| | | |
| | | getCode() |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | .register { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | height: 100%; |
| | | background-image: url("../assets/images/login-background.jpg"); |
| | | background-size: cover; |
| | | } |
| | | .title { |
| | | margin: 0px auto 30px auto; |
| | | text-align: center; |
| | | color: #707070; |
| | | } |
| | | |
| | | .register-form { |
| | | border-radius: 6px; |
| | | background: #ffffff; |
| | | width: 400px; |
| | | padding: 25px 25px 5px 25px; |
| | | .el-input { |
| | | height: 40px; |
| | | input { |
| | | height: 40px; |
| | | } |
| | | } |
| | | .input-icon { |
| | | height: 39px; |
| | | width: 14px; |
| | | margin-left: 0px; |
| | | } |
| | | } |
| | | .register-tip { |
| | | font-size: 13px; |
| | | text-align: center; |
| | | color: #bfbfbf; |
| | | } |
| | | .register-code { |
| | | width: 33%; |
| | | height: 40px; |
| | | float: right; |
| | | img { |
| | | cursor: pointer; |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | .el-register-footer { |
| | | height: 40px; |
| | | line-height: 40px; |
| | | position: fixed; |
| | | bottom: 0; |
| | | width: 100%; |
| | | text-align: center; |
| | | color: #fff; |
| | | font-family: Arial; |
| | | font-size: 12px; |
| | | letter-spacing: 1px; |
| | | } |
| | | .register-code-img { |
| | | height: 40px; |
| | | padding-left: 12px; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="åæ°åç§°" prop="configName"> |
| | | <el-input |
| | | v-model="queryParams.configName" |
| | | placeholder="请è¾å
¥åæ°åç§°" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°é®å" prop="configKey"> |
| | | <el-input |
| | | v-model="queryParams.configKey" |
| | | placeholder="请è¾å
¥åæ°é®å" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç³»ç»å
ç½®" prop="configType"> |
| | | <el-select v-model="queryParams.configType" placeholder="ç³»ç»å
ç½®" clearable style="width: 240px"> |
| | | <el-option |
| | | v-for="dict in sys_yes_no" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´" style="width: 308px;"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:config:add']" |
| | | >æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="Edit" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['system:config:edit']" |
| | | >ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['system:config:remove']" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Download" |
| | | @click="handleExport" |
| | | v-hasPermi="['system:config:export']" |
| | | >导åº</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Refresh" |
| | | @click="handleRefreshCache" |
| | | v-hasPermi="['system:config:remove']" |
| | | >å·æ°ç¼å</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="忰䏻é®" align="center" prop="configId" /> |
| | | <el-table-column label="åæ°åç§°" align="center" prop="configName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="åæ°é®å" align="center" prop="configKey" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="åæ°é®å¼" align="center" prop="configValue" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç³»ç»å
ç½®" align="center" prop="configType"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_yes_no" :value="scope.row.configType" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="夿³¨" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="150" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:config:edit']" >ä¿®æ¹</el-button> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:config:remove']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- æ·»å æä¿®æ¹åæ°é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="500px" append-to-body> |
| | | <el-form ref="configRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="åæ°åç§°" prop="configName"> |
| | | <el-input v-model="form.configName" placeholder="请è¾å
¥åæ°åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°é®å" prop="configKey"> |
| | | <el-input v-model="form.configKey" placeholder="请è¾å
¥åæ°é®å" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ°é®å¼" prop="configValue"> |
| | | <el-input v-model="form.configValue" type="textarea" placeholder="请è¾å
¥åæ°é®å¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç³»ç»å
ç½®" prop="configType"> |
| | | <el-radio-group v-model="form.configType"> |
| | | <el-radio |
| | | v-for="dict in sys_yes_no" |
| | | :key="dict.value" |
| | | :value="dict.value" |
| | | >{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Config"> |
| | | import { listConfig, getConfig, delConfig, addConfig, updateConfig, refreshCache } from "@/api/system/config" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_yes_no } = proxy.useDict("sys_yes_no") |
| | | |
| | | const configList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const single = ref(true) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const title = ref("") |
| | | const dateRange = ref([]) |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | configName: undefined, |
| | | configKey: undefined, |
| | | configType: undefined |
| | | }, |
| | | rules: { |
| | | configName: [{ required: true, message: "åæ°åç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | configKey: [{ required: true, message: "åæ°é®åä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | configValue: [{ required: true, message: "åæ°é®å¼ä¸è½ä¸ºç©º", trigger: "blur" }] |
| | | } |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢åæ°å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | listConfig(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => { |
| | | configList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** åæ¶æé® */ |
| | | function cancel() { |
| | | open.value = false |
| | | reset() |
| | | } |
| | | |
| | | /** 表åéç½® */ |
| | | function reset() { |
| | | form.value = { |
| | | configId: undefined, |
| | | configName: undefined, |
| | | configKey: undefined, |
| | | configValue: undefined, |
| | | configType: "Y", |
| | | remark: undefined |
| | | } |
| | | proxy.resetForm("configRef") |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | dateRange.value = [] |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.configId) |
| | | single.value = selection.length != 1 |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | function handleAdd() { |
| | | reset() |
| | | open.value = true |
| | | title.value = "æ·»å åæ°" |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | function handleUpdate(row) { |
| | | reset() |
| | | const configId = row.configId || ids.value |
| | | getConfig(configId).then(response => { |
| | | form.value = response.data |
| | | open.value = true |
| | | title.value = "ä¿®æ¹åæ°" |
| | | }) |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["configRef"].validate(valid => { |
| | | if (valid) { |
| | | if (form.value.configId != undefined) { |
| | | updateConfig(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } else { |
| | | addConfig(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | const configIds = row.configId || ids.value |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤åæ°ç¼å·ä¸º"' + configIds + '"çæ°æ®é¡¹ï¼').then(function () { |
| | | return delConfig(configIds) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | function handleExport() { |
| | | proxy.download("system/config/export", { |
| | | ...queryParams.value |
| | | }, `config_${new Date().getTime()}.xlsx`) |
| | | } |
| | | |
| | | /** å·æ°ç¼åæé®æä½ */ |
| | | function handleRefreshCache() { |
| | | refreshCache().then(() => { |
| | | proxy.$modal.msgSuccess("å·æ°ç¼åæå") |
| | | }) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch"> |
| | | <el-form-item label="é¨é¨åç§°" prop="deptName"> |
| | | <el-input |
| | | v-model="queryParams.deptName" |
| | | placeholder="请è¾å
¥é¨é¨åç§°" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="é¨é¨ç¶æ" clearable style="width: 200px"> |
| | | <el-option |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:dept:add']" |
| | | >æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="info" |
| | | plain |
| | | icon="Sort" |
| | | @click="toggleExpandAll" |
| | | >å±å¼/æå </el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table |
| | | v-if="refreshTable" |
| | | v-loading="loading" |
| | | :data="deptList" |
| | | row-key="deptId" |
| | | :default-expand-all="isExpandAll" |
| | | :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" |
| | | > |
| | | <el-table-column prop="deptName" label="é¨é¨åç§°" width="260"></el-table-column> |
| | | <el-table-column prop="orderNum" label="æåº" width="200"></el-table-column> |
| | | <el-table-column prop="status" label="ç¶æ" width="100"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="200"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dept:edit']">ä¿®æ¹</el-button> |
| | | <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:dept:add']">æ°å¢</el-button> |
| | | <el-button v-if="scope.row.parentId != 0" link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dept:remove']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- æ·»å æä¿®æ¹é¨é¨å¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="600px" append-to-body> |
| | | <el-form ref="deptRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-row> |
| | | <el-col :span="24" v-if="form.parentId !== 0"> |
| | | <el-form-item label="ä¸çº§é¨é¨" prop="parentId"> |
| | | <el-tree-select |
| | | v-model="form.parentId" |
| | | :data="deptOptions" |
| | | :props="{ value: 'deptId', label: 'deptName', children: 'children' }" |
| | | value-key="deptId" |
| | | placeholder="éæ©ä¸çº§é¨é¨" |
| | | check-strictly |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¨é¨åç§°" prop="deptName"> |
| | | <el-input v-model="form.deptName" placeholder="请è¾å
¥é¨é¨åç§°" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¾ç¤ºæåº" prop="orderNum"> |
| | | <el-input-number v-model="form.orderNum" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è´è´£äºº" prop="leader"> |
| | | <el-input v-model="form.leader" placeholder="请è¾å
¥è´è´£äºº" maxlength="20" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èç³»çµè¯" prop="phone"> |
| | | <el-input v-model="form.phone" placeholder="请è¾å
¥èç³»çµè¯" maxlength="11" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é®ç®±" prop="email"> |
| | | <el-input v-model="form.email" placeholder="请è¾å
¥é®ç®±" maxlength="50" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¨é¨ç¶æ"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :value="dict.value" |
| | | >{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Dept"> |
| | | import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_normal_disable } = proxy.useDict("sys_normal_disable") |
| | | |
| | | const deptList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const title = ref("") |
| | | const deptOptions = ref([]) |
| | | const isExpandAll = ref(true) |
| | | const refreshTable = ref(true) |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | deptName: undefined, |
| | | status: undefined |
| | | }, |
| | | rules: { |
| | | parentId: [{ required: true, message: "ä¸çº§é¨é¨ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | deptName: [{ required: true, message: "é¨é¨åç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | orderNum: [{ required: true, message: "æ¾ç¤ºæåºä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | email: [{ type: "email", message: "请è¾å
¥æ£ç¡®çé®ç®±å°å", trigger: ["blur", "change"] }], |
| | | phone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请è¾å
¥æ£ç¡®çææºå·ç ", trigger: "blur" }] |
| | | }, |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢é¨é¨å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | listDept(queryParams.value).then(response => { |
| | | deptList.value = proxy.handleTree(response.data, "deptId") |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** åæ¶æé® */ |
| | | function cancel() { |
| | | open.value = false |
| | | reset() |
| | | } |
| | | |
| | | /** 表åéç½® */ |
| | | function reset() { |
| | | form.value = { |
| | | deptId: undefined, |
| | | parentId: undefined, |
| | | deptName: undefined, |
| | | orderNum: 0, |
| | | leader: undefined, |
| | | phone: undefined, |
| | | email: undefined, |
| | | status: "0" |
| | | } |
| | | proxy.resetForm("deptRef") |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | function handleAdd(row) { |
| | | reset() |
| | | listDept().then(response => { |
| | | deptOptions.value = proxy.handleTree(response.data, "deptId") |
| | | }) |
| | | if (row != undefined) { |
| | | form.value.parentId = row.deptId |
| | | } |
| | | open.value = true |
| | | title.value = "æ·»å é¨é¨" |
| | | } |
| | | |
| | | /** å±å¼/æå æä½ */ |
| | | function toggleExpandAll() { |
| | | refreshTable.value = false |
| | | isExpandAll.value = !isExpandAll.value |
| | | nextTick(() => { |
| | | refreshTable.value = true |
| | | }) |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | function handleUpdate(row) { |
| | | reset() |
| | | listDeptExcludeChild(row.deptId).then(response => { |
| | | deptOptions.value = proxy.handleTree(response.data, "deptId") |
| | | }) |
| | | getDept(row.deptId).then(response => { |
| | | form.value = response.data |
| | | open.value = true |
| | | title.value = "ä¿®æ¹é¨é¨" |
| | | }) |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["deptRef"].validate(valid => { |
| | | if (valid) { |
| | | if (form.value.deptId != undefined) { |
| | | updateDept(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } else { |
| | | addDept(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å称为"' + row.deptName + '"çæ°æ®é¡¹?').then(function() { |
| | | return delDept(row.deptId) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch"> |
| | | <el-form-item label="åå
¸åç§°" prop="dictType"> |
| | | <el-select v-model="queryParams.dictType" style="width: 200px"> |
| | | <el-option |
| | | v-for="item in typeOptions" |
| | | :key="item.dictId" |
| | | :label="item.dictName" |
| | | :value="item.dictType" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="åå
¸æ ç¾" prop="dictLabel"> |
| | | <el-input |
| | | v-model="queryParams.dictLabel" |
| | | placeholder="请è¾å
¥åå
¸æ ç¾" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="æ°æ®ç¶æ" clearable style="width: 200px"> |
| | | <el-option |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:dict:add']" |
| | | >æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="Edit" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['system:dict:edit']" |
| | | >ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['system:dict:remove']" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Download" |
| | | @click="handleExport" |
| | | v-hasPermi="['system:dict:export']" |
| | | >导åº</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Close" |
| | | @click="handleClose" |
| | | >å
³é</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="åå
¸ç¼ç " align="center" prop="dictCode" /> |
| | | <el-table-column label="åå
¸æ ç¾" align="center" prop="dictLabel"> |
| | | <template #default="scope"> |
| | | <span v-if="(scope.row.listClass == '' || scope.row.listClass == 'default') && (scope.row.cssClass == '' || scope.row.cssClass == null)">{{ scope.row.dictLabel }}</span> |
| | | <el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass" :class="scope.row.cssClass">{{ scope.row.dictLabel }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="åå
¸é®å¼" align="center" prop="dictValue" /> |
| | | <el-table-column label="åå
¸æåº" align="center" prop="dictSort" /> |
| | | <el-table-column label="ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="夿³¨" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="160" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']">ä¿®æ¹</el-button> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict:remove']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- æ·»å æä¿®æ¹åæ°é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="500px" append-to-body> |
| | | <el-form ref="dataRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="åå
¸ç±»å"> |
| | | <el-input v-model="form.dictType" :disabled="true" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ°æ®æ ç¾" prop="dictLabel"> |
| | | <el-input v-model="form.dictLabel" placeholder="请è¾å
¥æ°æ®æ ç¾" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ°æ®é®å¼" prop="dictValue"> |
| | | <el-input v-model="form.dictValue" placeholder="请è¾å
¥æ°æ®é®å¼" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ ·å¼å±æ§" prop="cssClass"> |
| | | <el-input v-model="form.cssClass" placeholder="请è¾å
¥æ ·å¼å±æ§" /> |
| | | </el-form-item> |
| | | <el-form-item label="æ¾ç¤ºæåº" prop="dictSort"> |
| | | <el-input-number v-model="form.dictSort" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | <el-form-item label="åæ¾æ ·å¼" prop="listClass"> |
| | | <el-select v-model="form.listClass"> |
| | | <el-option |
| | | v-for="item in listClassOptions" |
| | | :key="item.value" |
| | | :label="item.label + '(' + item.value + ')'" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :value="dict.value" |
| | | >{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Data"> |
| | | import useDictStore from '@/store/modules/dict' |
| | | import { optionselect as getDictOptionselect, getType } from "@/api/system/dict/type" |
| | | import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_normal_disable } = proxy.useDict("sys_normal_disable") |
| | | |
| | | const dataList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const single = ref(true) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const title = ref("") |
| | | const defaultDictType = ref("") |
| | | const typeOptions = ref([]) |
| | | const route = useRoute() |
| | | // æ°æ®æ ç¾åæ¾æ ·å¼ |
| | | const listClassOptions = ref([ |
| | | { value: "default", label: "é»è®¤" }, |
| | | { value: "primary", label: "主è¦" }, |
| | | { value: "success", label: "æå" }, |
| | | { value: "info", label: "ä¿¡æ¯" }, |
| | | { value: "warning", label: "è¦å" }, |
| | | { value: "danger", label: "å±é©" } |
| | | ]) |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | dictType: undefined, |
| | | dictLabel: undefined, |
| | | status: undefined |
| | | }, |
| | | rules: { |
| | | dictLabel: [{ required: true, message: "æ°æ®æ ç¾ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | dictValue: [{ required: true, message: "æ°æ®é®å¼ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | dictSort: [{ required: true, message: "æ°æ®é¡ºåºä¸è½ä¸ºç©º", trigger: "blur" }] |
| | | } |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢åå
¸ç±»åè¯¦ç» */ |
| | | function getTypes(dictId) { |
| | | getType(dictId).then(response => { |
| | | queryParams.value.dictType = response.data.dictType |
| | | defaultDictType.value = response.data.dictType |
| | | getList() |
| | | }) |
| | | } |
| | | |
| | | /** æ¥è¯¢åå
¸ç±»åå表 */ |
| | | function getTypeList() { |
| | | getDictOptionselect().then(response => { |
| | | typeOptions.value = response.data |
| | | }) |
| | | } |
| | | |
| | | /** æ¥è¯¢åå
¸æ°æ®å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | listData(queryParams.value).then(response => { |
| | | dataList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** åæ¶æé® */ |
| | | function cancel() { |
| | | open.value = false |
| | | reset() |
| | | } |
| | | |
| | | /** 表åéç½® */ |
| | | function reset() { |
| | | form.value = { |
| | | dictCode: undefined, |
| | | dictLabel: undefined, |
| | | dictValue: undefined, |
| | | cssClass: undefined, |
| | | listClass: "default", |
| | | dictSort: 0, |
| | | status: "0", |
| | | remark: undefined |
| | | } |
| | | proxy.resetForm("dataRef") |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** è¿åæé®æä½ */ |
| | | function handleClose() { |
| | | const obj = { path: "/system/dict" } |
| | | proxy.$tab.closeOpenPage(obj) |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryRef") |
| | | queryParams.value.dictType = defaultDictType.value |
| | | handleQuery() |
| | | } |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | function handleAdd() { |
| | | reset() |
| | | open.value = true |
| | | title.value = "æ·»å åå
¸æ°æ®" |
| | | form.value.dictType = queryParams.value.dictType |
| | | } |
| | | |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.dictCode) |
| | | single.value = selection.length != 1 |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | function handleUpdate(row) { |
| | | reset() |
| | | const dictCode = row.dictCode || ids.value |
| | | getData(dictCode).then(response => { |
| | | form.value = response.data |
| | | open.value = true |
| | | title.value = "ä¿®æ¹åå
¸æ°æ®" |
| | | }) |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["dataRef"].validate(valid => { |
| | | if (valid) { |
| | | if (form.value.dictCode != undefined) { |
| | | updateData(form.value).then(response => { |
| | | useDictStore().removeDict(queryParams.value.dictType) |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } else { |
| | | addData(form.value).then(response => { |
| | | useDictStore().removeDict(queryParams.value.dictType) |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | const dictCodes = row.dictCode || ids.value |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤åå
¸ç¼ç 为"' + dictCodes + '"çæ°æ®é¡¹ï¼').then(function() { |
| | | return delData(dictCodes) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | useDictStore().removeDict(queryParams.value.dictType) |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | function handleExport() { |
| | | proxy.download("system/dict/data/export", { |
| | | ...queryParams.value |
| | | }, `dict_data_${new Date().getTime()}.xlsx`) |
| | | } |
| | | |
| | | getTypes(route.params && route.params.dictId) |
| | | getTypeList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="åå
¸åç§°" prop="dictName"> |
| | | <el-input |
| | | v-model="queryParams.dictName" |
| | | placeholder="请è¾å
¥åå
¸åç§°" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="åå
¸ç±»å" prop="dictType"> |
| | | <el-input |
| | | v-model="queryParams.dictType" |
| | | placeholder="请è¾å
¥åå
¸ç±»å" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select |
| | | v-model="queryParams.status" |
| | | placeholder="åå
¸ç¶æ" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:dict:add']" |
| | | >æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="Edit" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['system:dict:edit']" |
| | | >ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['system:dict:remove']" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Download" |
| | | @click="handleExport" |
| | | v-hasPermi="['system:dict:export']" |
| | | >导åº</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Refresh" |
| | | @click="handleRefreshCache" |
| | | v-hasPermi="['system:dict:remove']" |
| | | >å·æ°ç¼å</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="åå
¸ç¼å·" align="center" prop="dictId" /> |
| | | <el-table-column label="åå
¸åç§°" align="center" prop="dictName" :show-overflow-tooltip="true"/> |
| | | <el-table-column label="åå
¸ç±»å" align="center" :show-overflow-tooltip="true"> |
| | | <template #default="scope"> |
| | | <router-link :to="'/system/dict-data/index/' + scope.row.dictId" class="link-type"> |
| | | <span>{{ scope.row.dictType }}</span> |
| | | </router-link> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="夿³¨" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="160" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']">ä¿®æ¹</el-button> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict:remove']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- æ·»å æä¿®æ¹åæ°é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="500px" append-to-body> |
| | | <el-form ref="dictRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="åå
¸åç§°" prop="dictName"> |
| | | <el-input v-model="form.dictName" placeholder="请è¾å
¥åå
¸åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="åå
¸ç±»å" prop="dictType"> |
| | | <el-input v-model="form.dictType" placeholder="请è¾å
¥åå
¸ç±»å" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :value="dict.value" |
| | | >{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Dict"> |
| | | import useDictStore from '@/store/modules/dict' |
| | | import { listType, getType, delType, addType, updateType, refreshCache } from "@/api/system/dict/type" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_normal_disable } = proxy.useDict("sys_normal_disable") |
| | | |
| | | const typeList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const single = ref(true) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const title = ref("") |
| | | const dateRange = ref([]) |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | dictName: undefined, |
| | | dictType: undefined, |
| | | status: undefined |
| | | }, |
| | | rules: { |
| | | dictName: [{ required: true, message: "åå
¸åç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | dictType: [{ required: true, message: "åå
¸ç±»åä¸è½ä¸ºç©º", trigger: "blur" }] |
| | | }, |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢åå
¸ç±»åå表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | listType(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => { |
| | | typeList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** åæ¶æé® */ |
| | | function cancel() { |
| | | open.value = false |
| | | reset() |
| | | } |
| | | |
| | | /** 表åéç½® */ |
| | | function reset() { |
| | | form.value = { |
| | | dictId: undefined, |
| | | dictName: undefined, |
| | | dictType: undefined, |
| | | status: "0", |
| | | remark: undefined |
| | | } |
| | | proxy.resetForm("dictRef") |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | dateRange.value = [] |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | function handleAdd() { |
| | | reset() |
| | | open.value = true |
| | | title.value = "æ·»å åå
¸ç±»å" |
| | | } |
| | | |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.dictId) |
| | | single.value = selection.length != 1 |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | function handleUpdate(row) { |
| | | reset() |
| | | const dictId = row.dictId || ids.value |
| | | getType(dictId).then(response => { |
| | | form.value = response.data |
| | | open.value = true |
| | | title.value = "ä¿®æ¹åå
¸ç±»å" |
| | | }) |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["dictRef"].validate(valid => { |
| | | if (valid) { |
| | | if (form.value.dictId != undefined) { |
| | | updateType(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } else { |
| | | addType(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | const dictIds = row.dictId || ids.value |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤åå
¸ç¼å·ä¸º"' + dictIds + '"çæ°æ®é¡¹ï¼').then(function() { |
| | | return delType(dictIds) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | function handleExport() { |
| | | proxy.download("system/dict/type/export", { |
| | | ...queryParams.value |
| | | }, `dict_${new Date().getTime()}.xlsx`) |
| | | } |
| | | |
| | | /** å·æ°ç¼åæé®æä½ */ |
| | | function handleRefreshCache() { |
| | | refreshCache().then(() => { |
| | | proxy.$modal.msgSuccess("å·æ°æå") |
| | | useDictStore().cleanDict() |
| | | }) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch"> |
| | | <el-form-item label="èååç§°" prop="menuName"> |
| | | <el-input |
| | | v-model="queryParams.menuName" |
| | | placeholder="请è¾å
¥èååç§°" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="èåç¶æ" clearable style="width: 200px"> |
| | | <el-option |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:menu:add']" |
| | | >æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="info" |
| | | plain |
| | | icon="Sort" |
| | | @click="toggleExpandAll" |
| | | >å±å¼/æå </el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table |
| | | v-if="refreshTable" |
| | | v-loading="loading" |
| | | :data="menuList" |
| | | row-key="menuId" |
| | | :default-expand-all="isExpandAll" |
| | | :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" |
| | | > |
| | | <el-table-column prop="menuName" label="èååç§°" :show-overflow-tooltip="true" width="160"></el-table-column> |
| | | <el-table-column prop="icon" label="徿 " align="center" width="100"> |
| | | <template #default="scope"> |
| | | <svg-icon :icon-class="scope.row.icon" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="orderNum" label="æåº" width="60"></el-table-column> |
| | | <el-table-column prop="perms" label="æéæ è¯" :show-overflow-tooltip="true"></el-table-column> |
| | | <el-table-column prop="component" label="ç»ä»¶è·¯å¾" :show-overflow-tooltip="true"></el-table-column> |
| | | <el-table-column prop="status" label="ç¶æ" width="80"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" width="160" prop="createTime"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="210" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:menu:edit']">ä¿®æ¹</el-button> |
| | | <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:menu:add']">æ°å¢</el-button> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:menu:remove']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- æ·»å æä¿®æ¹èåå¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="680px" append-to-body> |
| | | <el-form ref="menuRef" :model="form" :rules="rules" label-width="100px"> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ä¸çº§èå"> |
| | | <el-tree-select |
| | | v-model="form.parentId" |
| | | :data="menuOptions" |
| | | :props="{ value: 'menuId', label: 'menuName', children: 'children' }" |
| | | value-key="menuId" |
| | | placeholder="éæ©ä¸çº§èå" |
| | | check-strictly |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="èåç±»å" prop="menuType"> |
| | | <el-radio-group v-model="form.menuType"> |
| | | <el-radio value="M">ç®å½</el-radio> |
| | | <el-radio value="C">èå</el-radio> |
| | | <el-radio value="F">æé®</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType != 'F'"> |
| | | <el-form-item label="èå徿 " prop="icon"> |
| | | <el-popover |
| | | placement="bottom-start" |
| | | :width="540" |
| | | trigger="click" |
| | | > |
| | | <template #reference> |
| | | <el-input v-model="form.icon" placeholder="ç¹å»éæ©å¾æ " @blur="showSelectIcon" readonly> |
| | | <template #prefix> |
| | | <svg-icon |
| | | v-if="form.icon" |
| | | :icon-class="form.icon" |
| | | class="el-input__icon" |
| | | style="height: 32px;width: 16px;" |
| | | /> |
| | | <el-icon v-else style="height: 32px;width: 16px;"><search /></el-icon> |
| | | </template> |
| | | </el-input> |
| | | </template> |
| | | <icon-select ref="iconSelectRef" @selected="selected" :active-icon="form.icon" /> |
| | | </el-popover> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¾ç¤ºæåº" prop="orderNum"> |
| | | <el-input-number v-model="form.orderNum" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="èååç§°" prop="menuName"> |
| | | <el-input v-model="form.menuName" placeholder="请è¾å
¥èååç§°" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType == 'C'"> |
| | | <el-form-item prop="routeName"> |
| | | <template #label> |
| | | <span> |
| | | <el-tooltip content="é»è®¤ä¸å¡«ååè·¯ç±å°åç¸åï¼å¦å°å为ï¼`user`ï¼åå称为`User`ï¼æ³¨æï¼å 为routerä¼å é¤åç§°ç¸åè·¯ç±ï¼ä¸ºé¿å
ååçå²çªï¼ç¹æ®æ
åµä¸è¯·èªå®ä¹ï¼ä¿è¯å¯ä¸æ§ï¼" placement="top"> |
| | | <el-icon><question-filled /></el-icon> |
| | | </el-tooltip> |
| | | è·¯ç±åç§° |
| | | </span> |
| | | </template> |
| | | <el-input v-model="form.routeName" placeholder="请è¾å
¥è·¯ç±åç§°" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType != 'F'"> |
| | | <el-form-item> |
| | | <template #label> |
| | | <span> |
| | | <el-tooltip content="éæ©æ¯å¤é¾åè·¯ç±å°åéè¦ä»¥`http(s)://`å¼å¤´" placement="top"> |
| | | <el-icon><question-filled /></el-icon> |
| | | </el-tooltip>æ¯å¦å¤é¾ |
| | | </span> |
| | | </template> |
| | | <el-radio-group v-model="form.isFrame"> |
| | | <el-radio value="0">æ¯</el-radio> |
| | | <el-radio value="1">å¦</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType != 'F'"> |
| | | <el-form-item prop="path"> |
| | | <template #label> |
| | | <span> |
| | | <el-tooltip content="访é®çè·¯ç±å°åï¼å¦ï¼`user`ï¼å¦å¤ç½å°åéå
é¾è®¿é®å以`http(s)://`å¼å¤´" placement="top"> |
| | | <el-icon><question-filled /></el-icon> |
| | | </el-tooltip> |
| | | è·¯ç±å°å |
| | | </span> |
| | | </template> |
| | | <el-input v-model="form.path" placeholder="请è¾å
¥è·¯ç±å°å" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType == 'C'"> |
| | | <el-form-item prop="component"> |
| | | <template #label> |
| | | <span> |
| | | <el-tooltip content="访é®çç»ä»¶è·¯å¾ï¼å¦ï¼`system/user/index`ï¼é»è®¤å¨`views`ç®å½ä¸" placement="top"> |
| | | <el-icon><question-filled /></el-icon> |
| | | </el-tooltip> |
| | | ç»ä»¶è·¯å¾ |
| | | </span> |
| | | </template> |
| | | <el-input v-model="form.component" placeholder="请è¾å
¥ç»ä»¶è·¯å¾" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType != 'M'"> |
| | | <el-form-item> |
| | | <el-input v-model="form.perms" placeholder="请è¾å
¥æéæ è¯" maxlength="100" /> |
| | | <template #label> |
| | | <span> |
| | | <el-tooltip content="æ§å¶å¨ä¸å®ä¹çæéå符ï¼å¦ï¼@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top"> |
| | | <el-icon><question-filled /></el-icon> |
| | | </el-tooltip> |
| | | æéå符 |
| | | </span> |
| | | </template> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType == 'C'"> |
| | | <el-form-item> |
| | | <el-input v-model="form.query" placeholder="请è¾å
¥è·¯ç±åæ°" maxlength="255" /> |
| | | <template #label> |
| | | <span> |
| | | <el-tooltip content='访é®è·¯ç±çé»è®¤ä¼ éåæ°ï¼å¦ï¼`{"id": 1, "name": "ry"}`' placement="top"> |
| | | <el-icon><question-filled /></el-icon> |
| | | </el-tooltip> |
| | | è·¯ç±åæ° |
| | | </span> |
| | | </template> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType == 'C'"> |
| | | <el-form-item> |
| | | <template #label> |
| | | <span> |
| | | <el-tooltip content="éæ©æ¯åä¼è¢«`keep-alive`ç¼åï¼éè¦å¹é
ç»ä»¶ç`name`åå°åä¿æä¸è´" placement="top"> |
| | | <el-icon><question-filled /></el-icon> |
| | | </el-tooltip> |
| | | æ¯å¦ç¼å |
| | | </span> |
| | | </template> |
| | | <el-radio-group v-model="form.isCache"> |
| | | <el-radio value="0">ç¼å</el-radio> |
| | | <el-radio value="1">ä¸ç¼å</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType != 'F'"> |
| | | <el-form-item> |
| | | <template #label> |
| | | <span> |
| | | <el-tooltip content="éæ©éèåè·¯ç±å°ä¸ä¼åºç°å¨ä¾§è¾¹æ ï¼ä½ä»ç¶å¯ä»¥è®¿é®" placement="top"> |
| | | <el-icon><question-filled /></el-icon> |
| | | </el-tooltip> |
| | | æ¾ç¤ºç¶æ |
| | | </span> |
| | | </template> |
| | | <el-radio-group v-model="form.visible"> |
| | | <el-radio |
| | | v-for="dict in sys_show_hide" |
| | | :key="dict.value" |
| | | :value="dict.value" |
| | | >{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item> |
| | | <template #label> |
| | | <span> |
| | | <el-tooltip content="éæ©åç¨åè·¯ç±å°ä¸ä¼åºç°å¨ä¾§è¾¹æ ï¼ä¹ä¸è½è¢«è®¿é®" placement="top"> |
| | | <el-icon><question-filled /></el-icon> |
| | | </el-tooltip> |
| | | èåç¶æ |
| | | </span> |
| | | </template> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :value="dict.value" |
| | | >{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Menu"> |
| | | import { addMenu, delMenu, getMenu, listMenu, updateMenu } from "@/api/system/menu" |
| | | import SvgIcon from "@/components/SvgIcon" |
| | | import IconSelect from "@/components/IconSelect" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_show_hide, sys_normal_disable } = proxy.useDict("sys_show_hide", "sys_normal_disable") |
| | | |
| | | const menuList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const title = ref("") |
| | | const menuOptions = ref([]) |
| | | const isExpandAll = ref(false) |
| | | const refreshTable = ref(true) |
| | | const iconSelectRef = ref(null) |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | menuName: undefined, |
| | | visible: undefined |
| | | }, |
| | | rules: { |
| | | menuName: [{ required: true, message: "èååç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | orderNum: [{ required: true, message: "èå顺åºä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | path: [{ required: true, message: "è·¯ç±å°åä¸è½ä¸ºç©º", trigger: "blur" }] |
| | | }, |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢èåå表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | listMenu(queryParams.value).then(response => { |
| | | menuList.value = proxy.handleTree(response.data, "menuId") |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** æ¥è¯¢èå䏿æ ç»æ */ |
| | | function getTreeselect() { |
| | | menuOptions.value = [] |
| | | listMenu().then(response => { |
| | | const menu = { menuId: 0, menuName: "主类ç®", children: [] } |
| | | menu.children = proxy.handleTree(response.data, "menuId") |
| | | menuOptions.value.push(menu) |
| | | }) |
| | | } |
| | | |
| | | /** åæ¶æé® */ |
| | | function cancel() { |
| | | open.value = false |
| | | reset() |
| | | } |
| | | |
| | | /** 表åéç½® */ |
| | | function reset() { |
| | | form.value = { |
| | | menuId: undefined, |
| | | parentId: 0, |
| | | menuName: undefined, |
| | | icon: undefined, |
| | | menuType: "M", |
| | | orderNum: undefined, |
| | | isFrame: "1", |
| | | isCache: "0", |
| | | visible: "0", |
| | | status: "0" |
| | | } |
| | | proxy.resetForm("menuRef") |
| | | } |
| | | |
| | | /** å±ç¤ºä¸æå¾æ */ |
| | | function showSelectIcon() { |
| | | iconSelectRef.value.reset() |
| | | } |
| | | |
| | | /** 鿩徿 */ |
| | | function selected(name) { |
| | | form.value.icon = name |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | function handleAdd(row) { |
| | | reset() |
| | | getTreeselect() |
| | | if (row != null && row.menuId) { |
| | | form.value.parentId = row.menuId |
| | | } else { |
| | | form.value.parentId = 0 |
| | | } |
| | | open.value = true |
| | | title.value = "æ·»å èå" |
| | | } |
| | | |
| | | /** å±å¼/æå æä½ */ |
| | | function toggleExpandAll() { |
| | | refreshTable.value = false |
| | | isExpandAll.value = !isExpandAll.value |
| | | nextTick(() => { |
| | | refreshTable.value = true |
| | | }) |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | async function handleUpdate(row) { |
| | | reset() |
| | | await getTreeselect() |
| | | getMenu(row.menuId).then(response => { |
| | | form.value = response.data |
| | | open.value = true |
| | | title.value = "ä¿®æ¹èå" |
| | | }) |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["menuRef"].validate(valid => { |
| | | if (valid) { |
| | | if (form.value.menuId != undefined) { |
| | | updateMenu(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } else { |
| | | addMenu(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å称为"' + row.menuName + '"çæ°æ®é¡¹?').then(function() { |
| | | return delMenu(row.menuId) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch"> |
| | | <el-form-item label="å
¬åæ é¢" prop="noticeTitle"> |
| | | <el-input |
| | | v-model="queryParams.noticeTitle" |
| | | placeholder="请è¾å
¥å
¬åæ é¢" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="æä½äººå" prop="createBy"> |
| | | <el-input |
| | | v-model="queryParams.createBy" |
| | | placeholder="请è¾å
¥æä½äººå" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç±»å" prop="noticeType"> |
| | | <el-select v-model="queryParams.noticeType" placeholder="å
¬åç±»å" clearable style="width: 200px"> |
| | | <el-option |
| | | v-for="dict in sys_notice_type" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:notice:add']" |
| | | >æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="Edit" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['system:notice:edit']" |
| | | >ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['system:notice:remove']" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="åºå·" align="center" prop="noticeId" width="100" /> |
| | | <el-table-column |
| | | label="å
¬åæ é¢" |
| | | align="center" |
| | | prop="noticeTitle" |
| | | :show-overflow-tooltip="true" |
| | | /> |
| | | <el-table-column label="å
¬åç±»å" align="center" prop="noticeType" width="100"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_notice_type" :value="scope.row.noticeType" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¶æ" align="center" prop="status" width="100"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_notice_status" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建è
" align="center" prop="createBy" width="100" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="100"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:notice:edit']">ä¿®æ¹</el-button> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:notice:remove']" >å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- æ·»å æä¿®æ¹å
¬åå¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="780px" append-to-body> |
| | | <el-form ref="noticeRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬åæ é¢" prop="noticeTitle"> |
| | | <el-input v-model="form.noticeTitle" placeholder="请è¾å
¥å
¬åæ é¢" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å
¬åç±»å" prop="noticeType"> |
| | | <el-select v-model="form.noticeType" placeholder="è¯·éæ©"> |
| | | <el-option |
| | | v-for="dict in sys_notice_type" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="ç¶æ"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in sys_notice_status" |
| | | :key="dict.value" |
| | | :value="dict.value" |
| | | >{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å
容"> |
| | | <editor v-model="form.noticeContent" :min-height="192"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Notice"> |
| | | import { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api/system/notice" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_notice_status, sys_notice_type } = proxy.useDict("sys_notice_status", "sys_notice_type") |
| | | |
| | | const noticeList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const single = ref(true) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const title = ref("") |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | noticeTitle: undefined, |
| | | createBy: undefined, |
| | | status: undefined |
| | | }, |
| | | rules: { |
| | | noticeTitle: [{ required: true, message: "å
¬åæ é¢ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | noticeType: [{ required: true, message: "å
¬åç±»åä¸è½ä¸ºç©º", trigger: "change" }] |
| | | }, |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢å
¬åå表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | listNotice(queryParams.value).then(response => { |
| | | noticeList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** åæ¶æé® */ |
| | | function cancel() { |
| | | open.value = false |
| | | reset() |
| | | } |
| | | |
| | | /** 表åéç½® */ |
| | | function reset() { |
| | | form.value = { |
| | | noticeId: undefined, |
| | | noticeTitle: undefined, |
| | | noticeType: undefined, |
| | | noticeContent: undefined, |
| | | status: "0" |
| | | } |
| | | proxy.resetForm("noticeRef") |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.noticeId) |
| | | single.value = selection.length != 1 |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | function handleAdd() { |
| | | reset() |
| | | open.value = true |
| | | title.value = "æ·»å å
Œ" |
| | | } |
| | | |
| | | /**ä¿®æ¹æé®æä½ */ |
| | | function handleUpdate(row) { |
| | | reset() |
| | | const noticeId = row.noticeId || ids.value |
| | | getNotice(noticeId).then(response => { |
| | | form.value = response.data |
| | | open.value = true |
| | | title.value = "ä¿®æ¹å
Œ" |
| | | }) |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["noticeRef"].validate(valid => { |
| | | if (valid) { |
| | | if (form.value.noticeId != undefined) { |
| | | updateNotice(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } else { |
| | | addNotice(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | const noticeIds = row.noticeId || ids.value |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å
¬åç¼å·ä¸º"' + noticeIds + '"çæ°æ®é¡¹ï¼').then(function() { |
| | | return delNotice(noticeIds) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch"> |
| | | <el-form-item label="å²ä½ç¼ç " prop="postCode"> |
| | | <el-input |
| | | v-model="queryParams.postCode" |
| | | placeholder="请è¾å
¥å²ä½ç¼ç " |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="å²ä½åç§°" prop="postName"> |
| | | <el-input |
| | | v-model="queryParams.postName" |
| | | placeholder="请è¾å
¥å²ä½åç§°" |
| | | clearable |
| | | style="width: 200px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="å²ä½ç¶æ" clearable style="width: 200px"> |
| | | <el-option |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:post:add']" |
| | | >æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="Edit" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['system:post:edit']" |
| | | >ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['system:post:remove']" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Download" |
| | | @click="handleExport" |
| | | v-hasPermi="['system:post:export']" |
| | | >导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="å²ä½ç¼å·" align="center" prop="postId" /> |
| | | <el-table-column label="å²ä½ç¼ç " align="center" prop="postCode" /> |
| | | <el-table-column label="å²ä½åç§°" align="center" prop="postName" /> |
| | | <el-table-column label="å²ä½æåº" align="center" prop="postSort" /> |
| | | <el-table-column label="ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" width="180" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:post:edit']">ä¿®æ¹</el-button> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:post:remove']">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- æ·»å æä¿®æ¹å²ä½å¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="500px" append-to-body> |
| | | <el-form ref="postRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="å²ä½åç§°" prop="postName"> |
| | | <el-input v-model="form.postName" placeholder="请è¾å
¥å²ä½åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="å²ä½ç¼ç " prop="postCode"> |
| | | <el-input v-model="form.postCode" placeholder="请è¾å
¥ç¼ç åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="å²ä½é¡ºåº" prop="postSort"> |
| | | <el-input-number v-model="form.postSort" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | <el-form-item label="å²ä½ç¶æ" prop="status"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :value="dict.value" |
| | | >{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Post"> |
| | | import { listPost, addPost, delPost, getPost, updatePost } from "@/api/system/post" |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_normal_disable } = proxy.useDict("sys_normal_disable") |
| | | |
| | | const postList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const single = ref(true) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const title = ref("") |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | postCode: undefined, |
| | | postName: undefined, |
| | | status: undefined |
| | | }, |
| | | rules: { |
| | | postName: [{ required: true, message: "å²ä½åç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | postCode: [{ required: true, message: "å²ä½ç¼ç ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | postSort: [{ required: true, message: "å²ä½é¡ºåºä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | } |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢å²ä½å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | listPost(queryParams.value).then(response => { |
| | | postList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** åæ¶æé® */ |
| | | function cancel() { |
| | | open.value = false |
| | | reset() |
| | | } |
| | | |
| | | /** 表åéç½® */ |
| | | function reset() { |
| | | form.value = { |
| | | postId: undefined, |
| | | postCode: undefined, |
| | | postName: undefined, |
| | | postSort: 0, |
| | | status: "0", |
| | | remark: undefined |
| | | } |
| | | proxy.resetForm("postRef") |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.postId) |
| | | single.value = selection.length != 1 |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | function handleAdd() { |
| | | reset() |
| | | open.value = true |
| | | title.value = "æ·»å å²ä½" |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | function handleUpdate(row) { |
| | | reset() |
| | | const postId = row.postId || ids.value |
| | | getPost(postId).then(response => { |
| | | form.value = response.data |
| | | open.value = true |
| | | title.value = "ä¿®æ¹å²ä½" |
| | | }) |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["postRef"].validate(valid => { |
| | | if (valid) { |
| | | if (form.value.postId != undefined) { |
| | | updatePost(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } else { |
| | | addPost(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | const postIds = row.postId || ids.value |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å²ä½ç¼å·ä¸º"' + postIds + '"çæ°æ®é¡¹ï¼').then(function() { |
| | | return delPost(postIds) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | function handleExport() { |
| | | proxy.download("system/post/export", { |
| | | ...queryParams.value |
| | | }, `post_${new Date().getTime()}.xlsx`) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" v-show="showSearch" :inline="true"> |
| | | <el-form-item label="ç¨æ·åç§°" prop="userName"> |
| | | <el-input |
| | | v-model="queryParams.userName" |
| | | placeholder="请è¾å
¥ç¨æ·åç§°" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ææºå·ç " prop="phonenumber"> |
| | | <el-input |
| | | v-model="queryParams.phonenumber" |
| | | placeholder="请è¾å
¥ææºå·ç " |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="openSelectUser" |
| | | v-hasPermi="['system:role:add']" |
| | | >æ·»å ç¨æ·</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="CircleClose" |
| | | :disabled="multiple" |
| | | @click="cancelAuthUserAll" |
| | | v-hasPermi="['system:role:remove']" |
| | | >æ¹éåæ¶ææ</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Close" |
| | | @click="handleClose" |
| | | >å
³é</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="ç¨æ·åç§°" prop="userName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç¨æ·æµç§°" prop="nickName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="é®ç®±" prop="email" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ææº" prop="phonenumber" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" icon="CircleClose" @click="cancelAuthUser(scope.row)" v-hasPermi="['system:role:remove']">åæ¶ææ</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | <select-user ref="selectRef" :roleId="queryParams.roleId" @ok="handleQuery" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="AuthUser"> |
| | | import selectUser from "./selectUser" |
| | | import { allocatedUserList, authUserCancel, authUserCancelAll } from "@/api/system/role" |
| | | |
| | | const route = useRoute() |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_normal_disable } = proxy.useDict("sys_normal_disable") |
| | | |
| | | const userList = ref([]) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const userIds = ref([]) |
| | | |
| | | const queryParams = reactive({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | roleId: route.params.roleId, |
| | | userName: undefined, |
| | | phonenumber: undefined, |
| | | }) |
| | | |
| | | /** æ¥è¯¢ææç¨æ·å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | allocatedUserList(queryParams).then(response => { |
| | | userList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** è¿åæé® */ |
| | | function handleClose() { |
| | | const obj = { path: "/system/role" } |
| | | proxy.$tab.closeOpenPage(obj) |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | function handleSelectionChange(selection) { |
| | | userIds.value = selection.map(item => item.userId) |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | /** æå¼ææç¨æ·è¡¨å¼¹çª */ |
| | | function openSelectUser() { |
| | | proxy.$refs["selectRef"].show() |
| | | } |
| | | |
| | | /** åæ¶æææé®æä½ */ |
| | | function cancelAuthUser(row) { |
| | | proxy.$modal.confirm('确认è¦åæ¶è¯¥ç¨æ·"' + row.userName + '"è§è²åï¼').then(function () { |
| | | return authUserCancel({ userId: row.userId, roleId: queryParams.roleId }) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("åæ¶æææå") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** æ¹éåæ¶æææé®æä½ */ |
| | | function cancelAuthUserAll(row) { |
| | | const roleId = queryParams.roleId |
| | | const uIds = userIds.value.join(",") |
| | | proxy.$modal.confirm("æ¯å¦åæ¶éä¸ç¨æ·æææ°æ®é¡¹?").then(function () { |
| | | return authUserCancelAll({ roleId: roleId, userIds: uIds }) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("åæ¶æææå") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" v-show="showSearch" :inline="true" label-width="68px"> |
| | | <el-form-item label="è§è²åç§°" prop="roleName"> |
| | | <el-input |
| | | v-model="queryParams.roleName" |
| | | placeholder="请è¾å
¥è§è²åç§°" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="æéå符" prop="roleKey"> |
| | | <el-input |
| | | v-model="queryParams.roleKey" |
| | | placeholder="请è¾å
¥æéå符" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select |
| | | v-model="queryParams.status" |
| | | placeholder="è§è²ç¶æ" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´" style="width: 308px"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | value-format="YYYY-MM-DD" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="å¼å§æ¥æ" |
| | | end-placeholder="ç»ææ¥æ" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="Plus" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:role:add']" |
| | | >æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="Edit" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['system:role:edit']" |
| | | >ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="Delete" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['system:role:remove']" |
| | | >å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="Download" |
| | | @click="handleExport" |
| | | v-hasPermi="['system:role:export']" |
| | | >导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <!-- è¡¨æ ¼æ°æ® --> |
| | | <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="è§è²ç¼å·" prop="roleId" width="120" /> |
| | | <el-table-column label="è§è²åç§°" prop="roleName" :show-overflow-tooltip="true" width="150" /> |
| | | <el-table-column label="æéå符" prop="roleKey" :show-overflow-tooltip="true" width="150" /> |
| | | <el-table-column label="æ¾ç¤ºé¡ºåº" prop="roleSort" width="100" /> |
| | | <el-table-column label="ç¶æ" align="center" width="100"> |
| | | <template #default="scope"> |
| | | <el-switch |
| | | v-model="scope.row.status" |
| | | active-value="0" |
| | | inactive-value="1" |
| | | @change="handleStatusChange(scope.row)" |
| | | ></el-switch> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top" v-if="scope.row.roleId !== 1"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:role:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top" v-if="scope.row.roleId !== 1"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:role:remove']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="æ°æ®æé" placement="top" v-if="scope.row.roleId !== 1"> |
| | | <el-button link type="primary" icon="CircleCheck" @click="handleDataScope(scope.row)" v-hasPermi="['system:role:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="åé
ç¨æ·" placement="top" v-if="scope.row.roleId !== 1"> |
| | | <el-button link type="primary" icon="User" @click="handleAuthUser(scope.row)" v-hasPermi="['system:role:edit']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- æ·»å æä¿®æ¹è§è²é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="500px" append-to-body> |
| | | <el-form ref="roleRef" :model="form" :rules="rules" label-width="100px"> |
| | | <el-form-item label="è§è²åç§°" prop="roleName"> |
| | | <el-input v-model="form.roleName" placeholder="请è¾å
¥è§è²åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item prop="roleKey"> |
| | | <template #label> |
| | | <span> |
| | | <el-tooltip content="æ§å¶å¨ä¸å®ä¹çæéå符ï¼å¦ï¼@PreAuthorize(`@ss.hasRole('admin')`)" placement="top"> |
| | | <el-icon><question-filled /></el-icon> |
| | | </el-tooltip> |
| | | æéå符 |
| | | </span> |
| | | </template> |
| | | <el-input v-model="form.roleKey" placeholder="请è¾å
¥æéå符" /> |
| | | </el-form-item> |
| | | <el-form-item label="è§è²é¡ºåº" prop="roleSort"> |
| | | <el-input-number v-model="form.roleSort" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in sys_normal_disable" |
| | | :key="dict.value" |
| | | :value="dict.value" |
| | | >{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="èåæé"> |
| | | <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">å±å¼/æå </el-checkbox> |
| | | <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">å
¨é/å
¨ä¸é</el-checkbox> |
| | | <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">ç¶åèå¨</el-checkbox> |
| | | <el-tree |
| | | class="tree-border" |
| | | :data="menuOptions" |
| | | show-checkbox |
| | | ref="menuRef" |
| | | node-key="id" |
| | | :check-strictly="!form.menuCheckStrictly" |
| | | empty-text="å è½½ä¸ï¼è¯·ç¨å" |
| | | :props="{ label: 'label', children: 'children' }" |
| | | ></el-tree> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- åé
è§è²æ°æ®æéå¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="openDataScope" width="500px" append-to-body> |
| | | <el-form :model="form" label-width="80px"> |
| | | <el-form-item label="è§è²åç§°"> |
| | | <el-input v-model="form.roleName" :disabled="true" /> |
| | | </el-form-item> |
| | | <el-form-item label="æéå符"> |
| | | <el-input v-model="form.roleKey" :disabled="true" /> |
| | | </el-form-item> |
| | | <el-form-item label="æéèå´"> |
| | | <el-select v-model="form.dataScope" @change="dataScopeSelectChange"> |
| | | <el-option |
| | | v-for="item in dataScopeOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æ°æ®æé" v-show="form.dataScope == 2"> |
| | | <el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">å±å¼/æå </el-checkbox> |
| | | <el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">å
¨é/å
¨ä¸é</el-checkbox> |
| | | <el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">ç¶åèå¨</el-checkbox> |
| | | <el-tree |
| | | class="tree-border" |
| | | :data="deptOptions" |
| | | show-checkbox |
| | | default-expand-all |
| | | ref="deptRef" |
| | | node-key="id" |
| | | :check-strictly="!form.deptCheckStrictly" |
| | | empty-text="å è½½ä¸ï¼è¯·ç¨å" |
| | | :props="{ label: 'label', children: 'children' }" |
| | | ></el-tree> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitDataScope">ç¡® å®</el-button> |
| | | <el-button @click="cancelDataScope">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Role"> |
| | | import { addRole, changeRoleStatus, dataScope, delRole, getRole, listRole, updateRole, deptTreeSelect } from "@/api/system/role" |
| | | import { roleMenuTreeselect, treeselect as menuTreeselect } from "@/api/system/menu" |
| | | |
| | | const router = useRouter() |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_normal_disable } = proxy.useDict("sys_normal_disable") |
| | | |
| | | const roleList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const single = ref(true) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const title = ref("") |
| | | const dateRange = ref([]) |
| | | const menuOptions = ref([]) |
| | | const menuExpand = ref(false) |
| | | const menuNodeAll = ref(false) |
| | | const deptExpand = ref(true) |
| | | const deptNodeAll = ref(false) |
| | | const deptOptions = ref([]) |
| | | const openDataScope = ref(false) |
| | | const menuRef = ref(null) |
| | | const deptRef = ref(null) |
| | | |
| | | /** æ°æ®èå´é项*/ |
| | | const dataScopeOptions = ref([ |
| | | { value: "1", label: "å
¨é¨æ°æ®æé" }, |
| | | { value: "2", label: "èªå®æ°æ®æé" }, |
| | | { value: "3", label: "æ¬é¨é¨æ°æ®æé" }, |
| | | { value: "4", label: "æ¬é¨é¨å以䏿°æ®æé" }, |
| | | { value: "5", label: "ä»
æ¬äººæ°æ®æé" } |
| | | ]) |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | roleName: undefined, |
| | | roleKey: undefined, |
| | | status: undefined |
| | | }, |
| | | rules: { |
| | | roleName: [{ required: true, message: "è§è²åç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | roleKey: [{ required: true, message: "æéå符ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | roleSort: [{ required: true, message: "è§è²é¡ºåºä¸è½ä¸ºç©º", trigger: "blur" }] |
| | | }, |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs(data) |
| | | |
| | | /** æ¥è¯¢è§è²å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | listRole(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => { |
| | | roleList.value = response.rows |
| | | total.value = response.total |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | dateRange.value = [] |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | const roleIds = row.roleId || ids.value |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤è§è²ç¼å·ä¸º"' + roleIds + '"çæ°æ®é¡¹?').then(function () { |
| | | return delRole(roleIds) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | function handleExport() { |
| | | proxy.download("system/role/export", { |
| | | ...queryParams.value, |
| | | }, `role_${new Date().getTime()}.xlsx`) |
| | | } |
| | | |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.roleId) |
| | | single.value = selection.length != 1 |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | /** è§è²ç¶æä¿®æ¹ */ |
| | | function handleStatusChange(row) { |
| | | let text = row.status === "0" ? "å¯ç¨" : "åç¨" |
| | | proxy.$modal.confirm('确认è¦"' + text + '""' + row.roleName + '"è§è²å?').then(function () { |
| | | return changeRoleStatus(row.roleId, row.status) |
| | | }).then(() => { |
| | | proxy.$modal.msgSuccess(text + "æå") |
| | | }).catch(function () { |
| | | row.status = row.status === "0" ? "1" : "0" |
| | | }) |
| | | } |
| | | |
| | | /** æ´å¤æä½ */ |
| | | function handleCommand(command, row) { |
| | | switch (command) { |
| | | case "handleDataScope": |
| | | handleDataScope(row) |
| | | break |
| | | case "handleAuthUser": |
| | | handleAuthUser(row) |
| | | break |
| | | default: |
| | | break |
| | | } |
| | | } |
| | | |
| | | /** åé
ç¨æ· */ |
| | | function handleAuthUser(row) { |
| | | router.push("/system/role-auth/user/" + row.roleId) |
| | | } |
| | | |
| | | /** æ¥è¯¢èåæ ç»æ */ |
| | | function getMenuTreeselect() { |
| | | menuTreeselect().then(response => { |
| | | menuOptions.value = response.data |
| | | }) |
| | | } |
| | | |
| | | /** ææé¨é¨èç¹æ°æ® */ |
| | | function getDeptAllCheckedKeys() { |
| | | // ç®å被éä¸çé¨é¨èç¹ |
| | | let checkedKeys = deptRef.value.getCheckedKeys() |
| | | // åéä¸çé¨é¨èç¹ |
| | | let halfCheckedKeys = deptRef.value.getHalfCheckedKeys() |
| | | checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys) |
| | | return checkedKeys |
| | | } |
| | | |
| | | /** éç½®æ°å¢ç表å以åå
¶ä»æ°æ® */ |
| | | function reset() { |
| | | if (menuRef.value != undefined) { |
| | | menuRef.value.setCheckedKeys([]) |
| | | } |
| | | menuExpand.value = false |
| | | menuNodeAll.value = false |
| | | deptExpand.value = true |
| | | deptNodeAll.value = false |
| | | form.value = { |
| | | roleId: undefined, |
| | | roleName: undefined, |
| | | roleKey: undefined, |
| | | roleSort: 0, |
| | | status: "0", |
| | | menuIds: [], |
| | | deptIds: [], |
| | | menuCheckStrictly: true, |
| | | deptCheckStrictly: true, |
| | | remark: undefined |
| | | } |
| | | proxy.resetForm("roleRef") |
| | | } |
| | | |
| | | /** æ·»å è§è² */ |
| | | function handleAdd() { |
| | | reset() |
| | | getMenuTreeselect() |
| | | open.value = true |
| | | title.value = "æ·»å è§è²" |
| | | } |
| | | |
| | | /** ä¿®æ¹è§è² */ |
| | | function handleUpdate(row) { |
| | | reset() |
| | | const roleId = row.roleId || ids.value |
| | | const roleMenu = getRoleMenuTreeselect(roleId) |
| | | getRole(roleId).then(response => { |
| | | form.value = response.data |
| | | form.value.roleSort = Number(form.value.roleSort) |
| | | open.value = true |
| | | nextTick(() => { |
| | | roleMenu.then((res) => { |
| | | let checkedKeys = res.checkedKeys |
| | | checkedKeys.forEach((v) => { |
| | | nextTick(() => { |
| | | menuRef.value.setChecked(v, true, false) |
| | | }) |
| | | }) |
| | | }) |
| | | }) |
| | | }) |
| | | title.value = "ä¿®æ¹è§è²" |
| | | } |
| | | |
| | | /** æ ¹æ®è§è²IDæ¥è¯¢èåæ ç»æ */ |
| | | function getRoleMenuTreeselect(roleId) { |
| | | return roleMenuTreeselect(roleId).then(response => { |
| | | menuOptions.value = response.menus |
| | | return response |
| | | }) |
| | | } |
| | | |
| | | /** æ ¹æ®è§è²IDæ¥è¯¢é¨é¨æ ç»æ */ |
| | | function getDeptTree(roleId) { |
| | | return deptTreeSelect(roleId).then(response => { |
| | | deptOptions.value = response.depts |
| | | return response |
| | | }) |
| | | } |
| | | |
| | | /** æ æéï¼å±å¼/æå ï¼*/ |
| | | function handleCheckedTreeExpand(value, type) { |
| | | if (type == "menu") { |
| | | let treeList = menuOptions.value |
| | | for (let i = 0; i < treeList.length; i++) { |
| | | menuRef.value.store.nodesMap[treeList[i].id].expanded = value |
| | | } |
| | | } else if (type == "dept") { |
| | | let treeList = deptOptions.value |
| | | for (let i = 0; i < treeList.length; i++) { |
| | | deptRef.value.store.nodesMap[treeList[i].id].expanded = value |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** æ æéï¼å
¨é/å
¨ä¸éï¼ */ |
| | | function handleCheckedTreeNodeAll(value, type) { |
| | | if (type == "menu") { |
| | | menuRef.value.setCheckedNodes(value ? menuOptions.value : []) |
| | | } else if (type == "dept") { |
| | | deptRef.value.setCheckedNodes(value ? deptOptions.value : []) |
| | | } |
| | | } |
| | | |
| | | /** æ æéï¼ç¶åèå¨ï¼ */ |
| | | function handleCheckedTreeConnect(value, type) { |
| | | if (type == "menu") { |
| | | form.value.menuCheckStrictly = value ? true : false |
| | | } else if (type == "dept") { |
| | | form.value.deptCheckStrictly = value ? true : false |
| | | } |
| | | } |
| | | |
| | | /** ææèåèç¹æ°æ® */ |
| | | function getMenuAllCheckedKeys() { |
| | | // ç®å被éä¸çèåèç¹ |
| | | let checkedKeys = menuRef.value.getCheckedKeys() |
| | | // åéä¸çèåèç¹ |
| | | let halfCheckedKeys = menuRef.value.getHalfCheckedKeys() |
| | | checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys) |
| | | return checkedKeys |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["roleRef"].validate(valid => { |
| | | if (valid) { |
| | | if (form.value.roleId != undefined) { |
| | | form.value.menuIds = getMenuAllCheckedKeys() |
| | | updateRole(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } else { |
| | | form.value.menuIds = getMenuAllCheckedKeys() |
| | | addRole(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | /** åæ¶æé® */ |
| | | function cancel() { |
| | | open.value = false |
| | | reset() |
| | | } |
| | | |
| | | /** éæ©è§è²æéèå´è§¦å */ |
| | | function dataScopeSelectChange(value) { |
| | | if (value !== "2") { |
| | | deptRef.value.setCheckedKeys([]) |
| | | } |
| | | } |
| | | |
| | | /** åé
æ°æ®æéæä½ */ |
| | | function handleDataScope(row) { |
| | | reset() |
| | | const deptTreeSelect = getDeptTree(row.roleId) |
| | | getRole(row.roleId).then(response => { |
| | | form.value = response.data |
| | | openDataScope.value = true |
| | | nextTick(() => { |
| | | deptTreeSelect.then(res => { |
| | | nextTick(() => { |
| | | if (deptRef.value) { |
| | | deptRef.value.setCheckedKeys(res.checkedKeys) |
| | | } |
| | | }) |
| | | }) |
| | | }) |
| | | }) |
| | | title.value = "åé
æ°æ®æé" |
| | | } |
| | | |
| | | /** æäº¤æé®ï¼æ°æ®æéï¼ */ |
| | | function submitDataScope() { |
| | | if (form.value.roleId != undefined) { |
| | | form.value.deptIds = getDeptAllCheckedKeys() |
| | | dataScope(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | openDataScope.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | /** åæ¶æé®ï¼æ°æ®æéï¼*/ |
| | | function cancelDataScope() { |
| | | openDataScope.value = false |
| | | reset() |
| | | } |
| | | |
| | | getList() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <!-- ææç¨æ· --> |
| | | <el-dialog title="éæ©ç¨æ·" v-model="visible" width="800px" top="5vh" append-to-body> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true"> |
| | | <el-form-item label="ç¨æ·åç§°" prop="userName"> |
| | | <el-input |
| | | v-model="queryParams.userName" |
| | | placeholder="请è¾å
¥ç¨æ·åç§°" |
| | | clearable |
| | | style="width: 180px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="ææºå·ç " prop="phonenumber"> |
| | | <el-input |
| | | v-model="queryParams.phonenumber" |
| | | placeholder="请è¾å
¥ææºå·ç " |
| | | clearable |
| | | style="width: 180px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-row> |
| | | <el-table @row-click="clickRow" ref="refTable" :data="userList" @selection-change="handleSelectionChange" height="260px"> |
| | | <el-table-column type="selection" width="55"></el-table-column> |
| | | <el-table-column label="ç¨æ·åç§°" prop="userName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç¨æ·æµç§°" prop="nickName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="é®ç®±" prop="email" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ææº" prop="phonenumber" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç¶æ" align="center" prop="status"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="sys_normal_disable" :value="scope.row.status" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | </el-row> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSelectUser">ç¡® å®</el-button> |
| | | <el-button @click="visible = false">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup name="SelectUser"> |
| | | import { authUserSelectAll, unallocatedUserList } from "@/api/system/role" |
| | | |
| | | const props = defineProps({ |
| | | roleId: { |
| | | type: [Number, String] |
| | | } |
| | | }) |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_normal_disable } = proxy.useDict("sys_normal_disable") |
| | | |
| | | const userList = ref([]) |
| | | const visible = ref(false) |
| | | const total = ref(0) |
| | | const userIds = ref([]) |
| | | |
| | | const queryParams = reactive({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | roleId: undefined, |
| | | userName: undefined, |
| | | phonenumber: undefined |
| | | }) |
| | | |
| | | // æ¾ç¤ºå¼¹æ¡ |
| | | function show() { |
| | | queryParams.roleId = props.roleId |
| | | getList() |
| | | visible.value = true |
| | | } |
| | | |
| | | /**éæ©è¡ */ |
| | | function clickRow(row) { |
| | | proxy.$refs["refTable"].toggleRowSelection(row) |
| | | } |
| | | |
| | | // å¤éæ¡é䏿°æ® |
| | | function handleSelectionChange(selection) { |
| | | userIds.value = selection.map(item => item.userId) |
| | | } |
| | | |
| | | // æ¥è¯¢è¡¨æ°æ® |
| | | function getList() { |
| | | unallocatedUserList(queryParams).then(res => { |
| | | userList.value = res.rows |
| | | total.value = res.total |
| | | }) |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | proxy.resetForm("queryRef") |
| | | handleQuery() |
| | | } |
| | | |
| | | const emit = defineEmits(["ok"]) |
| | | /** éæ©ææç¨æ·æä½ */ |
| | | function handleSelectUser() { |
| | | const roleId = queryParams.roleId |
| | | const uIds = userIds.value.join(",") |
| | | if (uIds == "") { |
| | | proxy.$modal.msgError("è¯·éæ©è¦åé
çç¨æ·") |
| | | return |
| | | } |
| | | authUserSelectAll({ roleId: roleId, userIds: uIds }).then(res => { |
| | | proxy.$modal.msgSuccess(res.msg) |
| | | visible.value = false |
| | | emit("ok") |
| | | }) |
| | | } |
| | | |
| | | defineExpose({ |
| | | show, |
| | | }) |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <h4 class="form-header h4">åºæ¬ä¿¡æ¯</h4> |
| | | <el-form :model="form" label-width="80px"> |
| | | <el-row> |
| | | <el-col :span="8" :offset="2"> |
| | | <el-form-item label="ç¨æ·æµç§°" prop="nickName"> |
| | | <el-input v-model="form.nickName" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8" :offset="2"> |
| | | <el-form-item label="ç»å½è´¦å·" prop="userName"> |
| | | <el-input v-model="form.userName" disabled /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <h4 class="form-header h4">è§è²ä¿¡æ¯</h4> |
| | | <el-table v-loading="loading" :row-key="getRowKey" @row-click="clickRow" ref="roleRef" @selection-change="handleSelectionChange" :data="roles.slice((pageNum - 1) * pageSize, pageNum * pageSize)"> |
| | | <el-table-column label="åºå·" width="55" type="index" align="center"> |
| | | <template #default="scope"> |
| | | <span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column type="selection" :reserve-selection="true" :selectable="checkSelectable" width="55"></el-table-column> |
| | | <el-table-column label="è§è²ç¼å·" align="center" prop="roleId" /> |
| | | <el-table-column label="è§è²åç§°" align="center" prop="roleName" /> |
| | | <el-table-column label="æéå符" align="center" prop="roleKey" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="pageNum" v-model:limit="pageSize" /> |
| | | |
| | | <el-form label-width="100px"> |
| | | <div style="text-align: center;margin-left:-120px;margin-top:30px;"> |
| | | <el-button type="primary" @click="submitForm()">æäº¤</el-button> |
| | | <el-button @click="close()">è¿å</el-button> |
| | | </div> |
| | | </el-form> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="AuthRole"> |
| | | import { getAuthRole, updateAuthRole } from "@/api/system/user" |
| | | |
| | | const route = useRoute() |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | | const loading = ref(true) |
| | | const total = ref(0) |
| | | const pageNum = ref(1) |
| | | const pageSize = ref(10) |
| | | const roleIds = ref([]) |
| | | const roles = ref([]) |
| | | const form = ref({ |
| | | nickName: undefined, |
| | | userName: undefined, |
| | | userId: undefined |
| | | }) |
| | | |
| | | /** åå»éä¸è¡æ°æ® */ |
| | | function clickRow(row) { |
| | | if (checkSelectable(row)) { |
| | | proxy.$refs["roleRef"].toggleRowSelection(row) |
| | | } |
| | | } |
| | | |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | function handleSelectionChange(selection) { |
| | | roleIds.value = selection.map(item => item.roleId) |
| | | } |
| | | |
| | | /** ä¿åéä¸çæ°æ®ç¼å· */ |
| | | function getRowKey(row) { |
| | | return row.roleId |
| | | } |
| | | |
| | | // æ£æ¥è§è²ç¶æ |
| | | function checkSelectable(row) { |
| | | return row.status === "0" ? true : false |
| | | } |
| | | |
| | | /** å
³éæé® */ |
| | | function close() { |
| | | const obj = { path: "/system/user" } |
| | | proxy.$tab.closeOpenPage(obj) |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | const userId = form.value.userId |
| | | const rIds = roleIds.value.join(",") |
| | | updateAuthRole({ userId: userId, roleIds: rIds }).then(response => { |
| | | proxy.$modal.msgSuccess("æææå") |
| | | close() |
| | | }) |
| | | } |
| | | |
| | | (() => { |
| | | const userId = route.params && route.params.userId |
| | | if (userId) { |
| | | loading.value = true |
| | | getAuthRole(userId).then(response => { |
| | | form.value = response.user |
| | | roles.value = response.roles |
| | | total.value = roles.value.length |
| | | nextTick(() => { |
| | | roles.value.forEach(row => { |
| | | if (row.flag) { |
| | | proxy.$refs["roleRef"].toggleRowSelection(row) |
| | | } |
| | | }) |
| | | }) |
| | | loading.value = false |
| | | }) |
| | | } |
| | | })() |
| | | </script> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-row :gutter="20"> |
| | | <splitpanes :horizontal="appStore.device === 'mobile'" class="default-theme"> |
| | | <!--é¨é¨æ°æ®--> |
| | | <pane size="16"> |
| | | <el-col> |
| | | <div class="head-container"> |
| | | <el-input v-model="deptName" placeholder="请è¾å
¥é¨é¨åç§°" clearable prefix-icon="Search" style="margin-bottom: 20px" /> |
| | | </div> |
| | | <div class="head-container"> |
| | | <el-tree :data="deptOptions" :props="{ label: 'label', children: 'children' }" :expand-on-click-node="false" :filter-node-method="filterNode" ref="deptTreeRef" node-key="id" highlight-current default-expand-all @node-click="handleNodeClick" /> |
| | | </div> |
| | | </el-col> |
| | | </pane> |
| | | <!--ç¨æ·æ°æ®--> |
| | | <pane size="84"> |
| | | <el-col> |
| | | <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="ç¨æ·åç§°" prop="userName"> |
| | | <el-input v-model="queryParams.userName" placeholder="请è¾å
¥ç¨æ·åç§°" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ææºå·ç " prop="phonenumber"> |
| | | <el-input v-model="queryParams.phonenumber" placeholder="请è¾å
¥ææºå·ç " clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="ç¨æ·ç¶æ" clearable style="width: 240px"> |
| | | <el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="å建æ¶é´" style="width: 308px"> |
| | | <el-date-picker v-model="dateRange" value-format="YYYY-MM-DD" type="daterange" range-separator="-" start-placeholder="å¼å§æ¥æ" end-placeholder="ç»ææ¥æ"></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:user:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['system:user:edit']">ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:user:remove']">å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="info" plain icon="Upload" @click="handleImport" v-hasPermi="['system:user:import']">导å
¥</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:user:export']">导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="50" align="center" /> |
| | | <el-table-column label="ç¨æ·ç¼å·" align="center" key="userId" prop="userId" v-if="columns[0].visible" /> |
| | | <el-table-column label="ç¨æ·åç§°" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ç¨æ·æµç§°" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="é¨é¨" align="center" key="deptName" prop="dept.deptName" v-if="columns[3].visible" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="ææºå·ç " align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" /> |
| | | <el-table-column label="ç¶æ" align="center" key="status" v-if="columns[5].visible"> |
| | | <template #default="scope"> |
| | | <el-switch |
| | | v-model="scope.row.status" |
| | | active-value="0" |
| | | inactive-value="1" |
| | | @change="handleStatusChange(scope.row)" |
| | | ></el-switch> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" v-if="columns[6].visible" width="160"> |
| | | <template #default="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="150" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top" v-if="scope.row.userId !== 1"> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:user:edit']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top" v-if="scope.row.userId !== 1"> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:user:remove']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="éç½®å¯ç " placement="top" v-if="scope.row.userId !== 1"> |
| | | <el-button link type="primary" icon="Key" @click="handleResetPwd(scope.row)" v-hasPermi="['system:user:resetPwd']"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="åé
è§è²" placement="top" v-if="scope.row.userId !== 1"> |
| | | <el-button link type="primary" icon="CircleCheck" @click="handleAuthRole(scope.row)" v-hasPermi="['system:user:edit']"></el-button> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-col> |
| | | </pane> |
| | | </splitpanes> |
| | | </el-row> |
| | | |
| | | <!-- æ·»å æä¿®æ¹ç¨æ·é
ç½®å¯¹è¯æ¡ --> |
| | | <el-dialog :title="title" v-model="open" width="600px" append-to-body> |
| | | <el-form :model="form" :rules="rules" ref="userRef" label-width="80px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¨æ·æµç§°" prop="nickName"> |
| | | <el-input v-model="form.nickName" placeholder="请è¾å
¥ç¨æ·æµç§°" maxlength="30" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å½å±é¨é¨" prop="deptId"> |
| | | <el-tree-select v-model="form.deptId" :data="enabledDeptOptions" :props="{ value: 'id', label: 'label', children: 'children' }" value-key="id" placeholder="è¯·éæ©å½å±é¨é¨" check-strictly /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ææºå·ç " prop="phonenumber"> |
| | | <el-input v-model="form.phonenumber" placeholder="请è¾å
¥ææºå·ç " maxlength="11" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é®ç®±" prop="email"> |
| | | <el-input v-model="form.email" placeholder="请è¾å
¥é®ç®±" maxlength="50" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item v-if="form.userId == undefined" label="ç¨æ·åç§°" prop="userName"> |
| | | <el-input v-model="form.userName" placeholder="请è¾å
¥ç¨æ·åç§°" maxlength="30" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item v-if="form.userId == undefined" label="ç¨æ·å¯ç " prop="password"> |
| | | <el-input v-model="form.password" placeholder="请è¾å
¥ç¨æ·å¯ç " type="password" maxlength="20" show-password /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¨æ·æ§å«"> |
| | | <el-select v-model="form.sex" placeholder="è¯·éæ©"> |
| | | <el-option v-for="dict in sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¶æ"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å²ä½"> |
| | | <el-select v-model="form.postIds" multiple placeholder="è¯·éæ©"> |
| | | <el-option v-for="item in postOptions" :key="item.postId" :label="item.postName" :value="item.postId" :disabled="item.status == 1"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è§è²"> |
| | | <el-select v-model="form.roleIds" multiple placeholder="è¯·éæ©"> |
| | | <el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="夿³¨"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请è¾å
¥å
容"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- ç¨æ·å¯¼å
¥å¯¹è¯æ¡ --> |
| | | <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body> |
| | | <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag> |
| | | <el-icon class="el-icon--upload"><upload-filled /></el-icon> |
| | | <div class="el-upload__text">å°æä»¶æå°æ¤å¤ï¼æ<em>ç¹å»ä¸ä¼ </em></div> |
| | | <template #tip> |
| | | <div class="el-upload__tip text-center"> |
| | | <div class="el-upload__tip"> |
| | | <el-checkbox v-model="upload.updateSupport" />æ¯å¦æ´æ°å·²ç»åå¨çç¨æ·æ°æ® |
| | | </div> |
| | | <span>ä»
å
许导å
¥xlsãxlsxæ ¼å¼æä»¶ã</span> |
| | | <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">ä¸è½½æ¨¡æ¿</el-link> |
| | | </div> |
| | | </template> |
| | | </el-upload> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitFileForm">ç¡® å®</el-button> |
| | | <el-button @click="upload.open = false">å æ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="User"> |
| | | import { getToken } from "@/utils/auth" |
| | | import useAppStore from '@/store/modules/app' |
| | | import { changeUserStatus, listUser, resetUserPwd, delUser, getUser, updateUser, addUser, deptTreeSelect } from "@/api/system/user" |
| | | import { Splitpanes, Pane } from "splitpanes" |
| | | import "splitpanes/dist/splitpanes.css" |
| | | |
| | | const router = useRouter() |
| | | const appStore = useAppStore() |
| | | const { proxy } = getCurrentInstance() |
| | | const { sys_normal_disable, sys_user_sex } = proxy.useDict("sys_normal_disable", "sys_user_sex") |
| | | |
| | | const userList = ref([]) |
| | | const open = ref(false) |
| | | const loading = ref(true) |
| | | const showSearch = ref(true) |
| | | const ids = ref([]) |
| | | const single = ref(true) |
| | | const multiple = ref(true) |
| | | const total = ref(0) |
| | | const title = ref("") |
| | | const dateRange = ref([]) |
| | | const deptName = ref("") |
| | | const deptOptions = ref(undefined) |
| | | const enabledDeptOptions = ref(undefined) |
| | | const initPassword = ref(undefined) |
| | | const postOptions = ref([]) |
| | | const roleOptions = ref([]) |
| | | /*** ç¨æ·å¯¼å
¥åæ° */ |
| | | const upload = reactive({ |
| | | // æ¯å¦æ¾ç¤ºå¼¹åºå±ï¼ç¨æ·å¯¼å
¥ï¼ |
| | | open: false, |
| | | // å¼¹åºå±æ é¢ï¼ç¨æ·å¯¼å
¥ï¼ |
| | | title: "", |
| | | // æ¯å¦ç¦ç¨ä¸ä¼ |
| | | isUploading: false, |
| | | // æ¯å¦æ´æ°å·²ç»åå¨çç¨æ·æ°æ® |
| | | updateSupport: 0, |
| | | // 设置ä¸ä¼ ç请æ±å¤´é¨ |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | // ä¸ä¼ çå°å |
| | | url: import.meta.env.VITE_APP_BASE_API + "/system/user/importData" |
| | | }) |
| | | // åæ¾éä¿¡æ¯ |
| | | const columns = ref([ |
| | | { key: 0, label: `ç¨æ·ç¼å·`, visible: true }, |
| | | { key: 1, label: `ç¨æ·åç§°`, visible: true }, |
| | | { key: 2, label: `ç¨æ·æµç§°`, visible: true }, |
| | | { key: 3, label: `é¨é¨`, visible: true }, |
| | | { key: 4, label: `ææºå·ç `, visible: true }, |
| | | { key: 5, label: `ç¶æ`, visible: true }, |
| | | { key: 6, label: `å建æ¶é´`, visible: true } |
| | | ]) |
| | | |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | userName: undefined, |
| | | phonenumber: undefined, |
| | | status: undefined, |
| | | deptId: undefined |
| | | }, |
| | | rules: { |
| | | userName: [{ required: true, message: "ç¨æ·åç§°ä¸è½ä¸ºç©º", trigger: "blur" }, { min: 2, max: 20, message: "ç¨æ·åç§°é¿åº¦å¿
é¡»ä»äº 2 å 20 ä¹é´", trigger: "blur" }], |
| | | nickName: [{ required: true, message: "ç¨æ·æµç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | password: [{ required: true, message: "ç¨æ·å¯ç ä¸è½ä¸ºç©º", trigger: "blur" }, { min: 5, max: 20, message: "ç¨æ·å¯ç é¿åº¦å¿
é¡»ä»äº 5 å 20 ä¹é´", trigger: "blur" }, { pattern: /^[^<>"'|\\]+$/, message: "ä¸è½å
å«éæ³å符ï¼< > \" ' \\\ |", trigger: "blur" }], |
| | | email: [{ type: "email", message: "请è¾å
¥æ£ç¡®çé®ç®±å°å", trigger: ["blur", "change"] }], |
| | | phonenumber: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请è¾å
¥æ£ç¡®çææºå·ç ", trigger: "blur" }] |
| | | } |
| | | }) |
| | | |
| | | const { queryParams, form, rules } = toRefs(data) |
| | | |
| | | /** éè¿æ¡ä»¶è¿æ»¤èç¹ */ |
| | | const filterNode = (value, data) => { |
| | | if (!value) return true |
| | | return data.label.indexOf(value) !== -1 |
| | | } |
| | | |
| | | /** æ ¹æ®åç§°çéé¨é¨æ */ |
| | | watch(deptName, val => { |
| | | proxy.$refs["deptTreeRef"].filter(val) |
| | | }) |
| | | |
| | | /** æ¥è¯¢ç¨æ·å表 */ |
| | | function getList() { |
| | | loading.value = true |
| | | listUser(proxy.addDateRange(queryParams.value, dateRange.value)).then(res => { |
| | | loading.value = false |
| | | userList.value = res.rows |
| | | total.value = res.total |
| | | }) |
| | | } |
| | | |
| | | /** æ¥è¯¢é¨é¨ä¸ææ ç»æ */ |
| | | function getDeptTree() { |
| | | deptTreeSelect().then(response => { |
| | | deptOptions.value = response.data |
| | | enabledDeptOptions.value = filterDisabledDept(JSON.parse(JSON.stringify(response.data))) |
| | | }) |
| | | } |
| | | |
| | | /** è¿æ»¤ç¦ç¨çé¨é¨ */ |
| | | function filterDisabledDept(deptList) { |
| | | return deptList.filter(dept => { |
| | | if (dept.disabled) { |
| | | return false |
| | | } |
| | | if (dept.children && dept.children.length) { |
| | | dept.children = filterDisabledDept(dept.children) |
| | | } |
| | | return true |
| | | }) |
| | | } |
| | | |
| | | /** èç¹åå»äºä»¶ */ |
| | | function handleNodeClick(data) { |
| | | queryParams.value.deptId = data.id |
| | | handleQuery() |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | | queryParams.value.pageNum = 1 |
| | | getList() |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | function resetQuery() { |
| | | dateRange.value = [] |
| | | proxy.resetForm("queryRef") |
| | | queryParams.value.deptId = undefined |
| | | proxy.$refs.deptTreeRef.setCurrentKey(null) |
| | | handleQuery() |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | function handleDelete(row) { |
| | | const userIds = row.userId || ids.value |
| | | proxy.$modal.confirm('æ¯å¦ç¡®è®¤å é¤ç¨æ·ç¼å·ä¸º"' + userIds + '"çæ°æ®é¡¹ï¼').then(function () { |
| | | return delUser(userIds) |
| | | }).then(() => { |
| | | getList() |
| | | proxy.$modal.msgSuccess("å 餿å") |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | function handleExport() { |
| | | proxy.download("system/user/export", { |
| | | ...queryParams.value, |
| | | },`user_${new Date().getTime()}.xlsx`) |
| | | } |
| | | |
| | | /** ç¨æ·ç¶æä¿®æ¹ */ |
| | | function handleStatusChange(row) { |
| | | let text = row.status === "0" ? "å¯ç¨" : "åç¨" |
| | | proxy.$modal.confirm('确认è¦"' + text + '""' + row.userName + '"ç¨æ·å?').then(function () { |
| | | return changeUserStatus(row.userId, row.status) |
| | | }).then(() => { |
| | | proxy.$modal.msgSuccess(text + "æå") |
| | | }).catch(function () { |
| | | row.status = row.status === "0" ? "1" : "0" |
| | | }) |
| | | } |
| | | |
| | | /** æ´å¤æä½ */ |
| | | function handleCommand(command, row) { |
| | | switch (command) { |
| | | case "handleResetPwd": |
| | | handleResetPwd(row) |
| | | break |
| | | case "handleAuthRole": |
| | | handleAuthRole(row) |
| | | break |
| | | default: |
| | | break |
| | | } |
| | | } |
| | | |
| | | /** 跳转è§è²åé
*/ |
| | | function handleAuthRole(row) { |
| | | const userId = row.userId |
| | | router.push("/system/user-auth/role/" + userId) |
| | | } |
| | | |
| | | /** éç½®å¯ç æé®æä½ */ |
| | | function handleResetPwd(row) { |
| | | proxy.$prompt('请è¾å
¥"' + row.userName + '"çæ°å¯ç ', "æç¤º", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | closeOnClickModal: false, |
| | | inputPattern: /^.{5,20}$/, |
| | | inputErrorMessage: "ç¨æ·å¯ç é¿åº¦å¿
é¡»ä»äº 5 å 20 ä¹é´", |
| | | inputValidator: (value) => { |
| | | if (/<|>|"|'|\||\\/.test(value)) { |
| | | return "ä¸è½å
å«éæ³å符ï¼< > \" ' \\\ |" |
| | | } |
| | | }, |
| | | }).then(({ value }) => { |
| | | resetUserPwd(row.userId, value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æåï¼æ°å¯ç æ¯ï¼" + value) |
| | | }) |
| | | }).catch(() => {}) |
| | | } |
| | | |
| | | /** éæ©æ¡æ° */ |
| | | function handleSelectionChange(selection) { |
| | | ids.value = selection.map(item => item.userId) |
| | | single.value = selection.length != 1 |
| | | multiple.value = !selection.length |
| | | } |
| | | |
| | | /** 导å
¥æé®æä½ */ |
| | | function handleImport() { |
| | | upload.title = "ç¨æ·å¯¼å
¥" |
| | | upload.open = true |
| | | } |
| | | |
| | | /** ä¸è½½æ¨¡æ¿æä½ */ |
| | | function importTemplate() { |
| | | proxy.download("system/user/importTemplate", { |
| | | }, `user_template_${new Date().getTime()}.xlsx`) |
| | | } |
| | | |
| | | /**æä»¶ä¸ä¼ ä¸å¤ç */ |
| | | const handleFileUploadProgress = (event, file, fileList) => { |
| | | upload.isUploading = true |
| | | } |
| | | |
| | | /** æä»¶ä¸ä¼ æåå¤ç */ |
| | | const handleFileSuccess = (response, file, fileList) => { |
| | | upload.open = false |
| | | upload.isUploading = false |
| | | proxy.$refs["uploadRef"].handleRemove(file) |
| | | proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导å
¥ç»æ", { dangerouslyUseHTMLString: true }) |
| | | getList() |
| | | } |
| | | |
| | | /** æäº¤ä¸ä¼ æä»¶ */ |
| | | function submitFileForm() { |
| | | proxy.$refs["uploadRef"].submit() |
| | | } |
| | | |
| | | /** éç½®æä½è¡¨å */ |
| | | function reset() { |
| | | form.value = { |
| | | userId: undefined, |
| | | deptId: undefined, |
| | | userName: undefined, |
| | | nickName: undefined, |
| | | password: undefined, |
| | | phonenumber: undefined, |
| | | email: undefined, |
| | | sex: undefined, |
| | | status: "0", |
| | | remark: undefined, |
| | | postIds: [], |
| | | roleIds: [] |
| | | } |
| | | proxy.resetForm("userRef") |
| | | } |
| | | |
| | | /** åæ¶æé® */ |
| | | function cancel() { |
| | | open.value = false |
| | | reset() |
| | | } |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | function handleAdd() { |
| | | reset() |
| | | getUser().then(response => { |
| | | postOptions.value = response.posts |
| | | roleOptions.value = response.roles |
| | | open.value = true |
| | | title.value = "æ·»å ç¨æ·" |
| | | form.value.password = initPassword.value |
| | | }) |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | function handleUpdate(row) { |
| | | reset() |
| | | const userId = row.userId || ids.value |
| | | getUser(userId).then(response => { |
| | | form.value = response.data |
| | | postOptions.value = response.posts |
| | | roleOptions.value = response.roles |
| | | form.value.postIds = response.postIds |
| | | form.value.roleIds = response.roleIds |
| | | open.value = true |
| | | title.value = "ä¿®æ¹ç¨æ·" |
| | | form.password = "" |
| | | }) |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | function submitForm() { |
| | | proxy.$refs["userRef"].validate(valid => { |
| | | if (valid) { |
| | | if (form.value.userId != undefined) { |
| | | updateUser(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("ä¿®æ¹æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } else { |
| | | addUser(form.value).then(response => { |
| | | proxy.$modal.msgSuccess("æ°å¢æå") |
| | | open.value = false |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | getDeptTree() |
| | | getList() |
| | | </script> |
src/views/system/user/profile/index.vue
src/views/system/user/profile/resetPwd.vue
src/views/system/user/profile/userAvatar.vue
src/views/system/user/profile/userInfo.vue
src/views/tool/build/CodeTypeDialog.vue
src/views/tool/build/DraggableItem.vue
src/views/tool/build/IconsDialog.vue
src/views/tool/build/RightPanel.vue
src/views/tool/build/TreeNodeDialog.vue
src/views/tool/build/index.vue
src/views/tool/gen/basicInfoForm.vue
src/views/tool/gen/createTable.vue
src/views/tool/gen/editTable.vue
src/views/tool/gen/genInfoForm.vue
src/views/tool/gen/importTable.vue
src/views/tool/gen/index.vue
src/views/tool/swagger/index.vue
vite.config.js
vite/plugins/auto-import.js
vite/plugins/compression.js
vite/plugins/index.js
vite/plugins/setup-extend.js
vite/plugins/svg-icon.js |