feat:优化

This commit is contained in:
wangzenghua 2025-02-13 07:06:39 +00:00
parent 511974f590
commit 7e12dbb545
31 changed files with 377 additions and 2952 deletions

View File

@ -25,6 +25,7 @@
"file-saver": "^2.0.5",
"js-base64": "^3.7.7",
"js-cookie": "^3.0.5",
"jsencrypt": "^3.3.2",
"jszip": "^3.10.1",
"jszip-utils": "^0.1.0",
"lib-flexible-computer": "^1.0.2",

View File

@ -1,33 +1,94 @@
import request from '@/utils/axios';
/**
* @Title: 登录
*/
export function Login(data, token) {
return request('/self/login', {
// 登录方法
export function Login(data) {
return request({
url: '/auth/login',
headers: {
isToken: false,
repeatSubmit: false,
},
method: 'POST',
data,
});
}
// 注册方法
export function register(data) {
return request({
url: '/auth/register',
headers: {
'Fairies-Captcha-Token': token,
isToken: false,
},
method: 'post',
data: data,
});
}
/**
* @Title: 登出
*/
export function LogOut() {
return request('/self/logout', {
method: 'POST',
// 刷新方法
export function refreshToken() {
return request({
url: '/auth/refresh',
method: 'post',
});
}
/**
* @Title: 验证码
*/
export function GetCaptcha() {
return request('/self/captcha', {
method: 'GET',
responseType: 'arraybuffer',
// 获取用户详细信息
export function getInfo() {
return request({
url: '/system/user/getInfo',
method: 'get',
});
}
// 退出方法
export function logout() {
return request({
url: '/auth/logout',
method: 'delete',
});
}
// 获取验证码
export function GetCodeImg() {
return request({
url: '/code',
headers: {
isToken: false,
},
method: 'get',
timeout: 20000,
});
}
// /**
// * @Title: 登录
// */
// export function Login(data, token) {
// return request('/self/login', {
// method: 'POST',
// data,
// headers: {
// 'Fairies-Captcha-Token': token,
// },
// });
// }
// /**
// * @Title: 登出
// */
// export function LogOut() {
// return request('/self/logout', {
// method: 'POST',
// });
// }
// /**
// * @Title: 验证码
// */
// export function GetCaptcha() {
// return request('/self/captcha', {
// method: 'GET',
// responseType: 'arraybuffer',
// });
// }

View File

@ -1,539 +0,0 @@
/* Logo 字体 */
@font-face {
font-family: "iconfont logo";
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
}
.logo {
font-family: "iconfont logo";
font-size: 160px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* tabs */
.nav-tabs {
position: relative;
}
.nav-tabs .nav-more {
position: absolute;
right: 0;
bottom: 0;
height: 42px;
line-height: 42px;
color: #666;
}
#tabs {
border-bottom: 1px solid #eee;
}
#tabs li {
cursor: pointer;
width: 100px;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 16px;
border-bottom: 2px solid transparent;
position: relative;
z-index: 1;
margin-bottom: -1px;
color: #666;
}
#tabs .active {
border-bottom-color: #f00;
color: #222;
}
.tab-container .content {
display: none;
}
/* 页面布局 */
.main {
padding: 30px 100px;
width: 960px;
margin: 0 auto;
}
.main .logo {
color: #333;
text-align: left;
margin-bottom: 30px;
line-height: 1;
height: 110px;
margin-top: -50px;
overflow: hidden;
*zoom: 1;
}
.main .logo a {
font-size: 160px;
color: #333;
}
.helps {
margin-top: 40px;
}
.helps pre {
padding: 20px;
margin: 10px 0;
border: solid 1px #e7e1cd;
background-color: #fffdef;
overflow: auto;
}
.icon_lists {
width: 100% !important;
overflow: hidden;
*zoom: 1;
}
.icon_lists li {
width: 100px;
margin-bottom: 10px;
margin-right: 20px;
text-align: center;
list-style: none !important;
cursor: default;
}
.icon_lists li .code-name {
line-height: 1.2;
}
.icon_lists .icon {
display: block;
height: 100px;
line-height: 100px;
font-size: 42px;
margin: 10px auto;
color: #333;
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
-moz-transition: font-size 0.25s linear, width 0.25s linear;
transition: font-size 0.25s linear, width 0.25s linear;
}
.icon_lists .icon:hover {
font-size: 100px;
}
.icon_lists .svg-icon {
/* 通过设置 font-size 来改变图标大小 */
width: 1em;
/* 图标和文字相邻时,垂直对齐 */
vertical-align: -0.15em;
/* 通过设置 color 来改变 SVG 的颜色/fill */
fill: currentColor;
/* path stroke 溢出 viewBox 部分在 IE 下会显示
normalize.css 中也包含这行 */
overflow: hidden;
}
.icon_lists li .name,
.icon_lists li .code-name {
color: #666;
}
/* markdown 样式 */
.markdown {
color: #666;
font-size: 14px;
line-height: 1.8;
}
.highlight {
line-height: 1.5;
}
.markdown img {
vertical-align: middle;
max-width: 100%;
}
.markdown h1 {
color: #404040;
font-weight: 500;
line-height: 40px;
margin-bottom: 24px;
}
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
color: #404040;
margin: 1.6em 0 0.6em 0;
font-weight: 500;
clear: both;
}
.markdown h1 {
font-size: 28px;
}
.markdown h2 {
font-size: 22px;
}
.markdown h3 {
font-size: 16px;
}
.markdown h4 {
font-size: 14px;
}
.markdown h5 {
font-size: 12px;
}
.markdown h6 {
font-size: 12px;
}
.markdown hr {
height: 1px;
border: 0;
background: #e9e9e9;
margin: 16px 0;
clear: both;
}
.markdown p {
margin: 1em 0;
}
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
width: 80%;
}
.markdown ul>li {
list-style: circle;
}
.markdown>ul li,
.markdown blockquote ul>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown>ul li p,
.markdown>ol li p {
margin: 0.6em 0;
}
.markdown ol>li {
list-style: decimal;
}
.markdown>ol li,
.markdown blockquote ol>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown code {
margin: 0 3px;
padding: 0 5px;
background: #eee;
border-radius: 3px;
}
.markdown strong,
.markdown b {
font-weight: 600;
}
.markdown>table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 95%;
margin-bottom: 24px;
}
.markdown>table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown>table th,
.markdown>table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown>table th {
background: #F7F7F7;
}
.markdown blockquote {
font-size: 90%;
color: #999;
border-left: 4px solid #e9e9e9;
padding-left: 0.8em;
margin: 1em 0;
}
.markdown blockquote p {
margin: 0;
}
.markdown .anchor {
opacity: 0;
transition: opacity 0.3s ease;
margin-left: 8px;
}
.markdown .waiting {
color: #ccc;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
opacity: 1;
display: inline-block;
}
.markdown>br,
.markdown>p>br {
clear: both;
}
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
/* 代码高亮 */
/* PrismJS 1.15.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +0,0 @@
@font-face {
font-family: "iconfont"; /* Project id 4709068 */
src: url('iconfont.woff2?t=1729754563434') format('woff2'),
url('iconfont.woff?t=1729754563434') format('woff'),
url('iconfont.ttf?t=1729754563434') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

File diff suppressed because one or more lines are too long

View File

@ -1,408 +0,0 @@
{
"id": "4709068",
"name": "sub-admin",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "react/vue项目后台管理平台",
"glyphs": [
{
"icon_id": "588769",
"name": "待付款",
"font_class": "pay",
"unicode": "e626",
"unicode_decimal": 58918
},
{
"icon_id": "653976",
"name": "已完成",
"font_class": "complete",
"unicode": "e60d",
"unicode_decimal": 58893
},
{
"icon_id": "1001767",
"name": "修改密码",
"font_class": "edit",
"unicode": "e618",
"unicode_decimal": 58904
},
{
"icon_id": "1068811",
"name": "待发货",
"font_class": "deliver",
"unicode": "e622",
"unicode_decimal": 58914
},
{
"icon_id": "1313074",
"name": "待收货",
"font_class": "receive",
"unicode": "e611",
"unicode_decimal": 58897
},
{
"icon_id": "2121739",
"name": "品牌",
"font_class": "brand",
"unicode": "e60f",
"unicode_decimal": 58895
},
{
"icon_id": "2846231",
"name": "商品规格",
"font_class": "sku",
"unicode": "e607",
"unicode_decimal": 58887
},
{
"icon_id": "3978297",
"name": "退出",
"font_class": "exit",
"unicode": "e641",
"unicode_decimal": 58945
},
{
"icon_id": "8295386",
"name": "商品类型",
"font_class": "type",
"unicode": "e87f",
"unicode_decimal": 59519
},
{
"icon_id": "8875707",
"name": "收货地址",
"font_class": "address",
"unicode": "e666",
"unicode_decimal": 58982
},
{
"icon_id": "12797032",
"name": "售后",
"font_class": "post-sale",
"unicode": "e63c",
"unicode_decimal": 58940
},
{
"icon_id": "21673621",
"name": "商品分类",
"font_class": "category",
"unicode": "e602",
"unicode_decimal": 58882
},
{
"icon_id": "3703028",
"name": "文章管理",
"font_class": "article",
"unicode": "e662",
"unicode_decimal": 58978
},
{
"icon_id": "1218184",
"name": "销售明细",
"font_class": "data4",
"unicode": "e60c",
"unicode_decimal": 58892
},
{
"icon_id": "2230090",
"name": "销售明细",
"font_class": "data5",
"unicode": "e6be",
"unicode_decimal": 59070
},
{
"icon_id": "6882983",
"name": "充值记录",
"font_class": "recharge-record",
"unicode": "e614",
"unicode_decimal": 58900
},
{
"icon_id": "34611004",
"name": "充值规则",
"font_class": "recharge-rule",
"unicode": "e628",
"unicode_decimal": 58920
},
{
"icon_id": "15562252",
"name": "用户画像",
"font_class": "user-profile",
"unicode": "e783",
"unicode_decimal": 59267
},
{
"icon_id": "18747445",
"name": "成就",
"font_class": "achieve",
"unicode": "e616",
"unicode_decimal": 58902
},
{
"icon_id": "33848542",
"name": "我的-段位",
"font_class": "activity-level",
"unicode": "e61a",
"unicode_decimal": 58906
},
{
"icon_id": "20406821",
"name": "皮肤",
"font_class": "skins",
"unicode": "e790",
"unicode_decimal": 59280
},
{
"icon_id": "2214847",
"name": "积分商城",
"font_class": "data1",
"unicode": "e996",
"unicode_decimal": 59798
},
{
"icon_id": "14233304",
"name": "价值投资",
"font_class": "data2",
"unicode": "e661",
"unicode_decimal": 58977
},
{
"icon_id": "23059951",
"name": "费用统计",
"font_class": "data3",
"unicode": "e632",
"unicode_decimal": 58930
},
{
"icon_id": "2199049",
"name": "数据报表",
"font_class": "data",
"unicode": "e64e",
"unicode_decimal": 58958
},
{
"icon_id": "36257316",
"name": "游戏管理",
"font_class": "game",
"unicode": "e6d0",
"unicode_decimal": 59088
},
{
"icon_id": "11913396",
"name": "banner",
"font_class": "banner",
"unicode": "e613",
"unicode_decimal": 58899
},
{
"icon_id": "35264323",
"name": "核销码核销",
"font_class": "verification",
"unicode": "e601",
"unicode_decimal": 58881
},
{
"icon_id": "6514128",
"name": "结算管理",
"font_class": "balance",
"unicode": "e6b9",
"unicode_decimal": 59065
},
{
"icon_id": "12025983",
"name": "退货退款",
"font_class": "refund",
"unicode": "e7af",
"unicode_decimal": 59311
},
{
"icon_id": "1207908",
"name": "wechat",
"font_class": "wechat",
"unicode": "e681",
"unicode_decimal": 59009
},
{
"icon_id": "27188513",
"name": "alipay",
"font_class": "alipay",
"unicode": "e61e",
"unicode_decimal": 58910
},
{
"icon_id": "11111017",
"name": "会员",
"font_class": "user",
"unicode": "e67f",
"unicode_decimal": 59007
},
{
"icon_id": "630079",
"name": "我的优惠券",
"font_class": "coupon",
"unicode": "e65a",
"unicode_decimal": 58970
},
{
"icon_id": "2046370",
"name": "会员等级",
"font_class": "level",
"unicode": "e7d8",
"unicode_decimal": 59352
},
{
"icon_id": "2569868",
"name": "活动",
"font_class": "activity",
"unicode": "e67b",
"unicode_decimal": 59003
},
{
"icon_id": "2681698",
"name": "门店",
"font_class": "shop",
"unicode": "e60a",
"unicode_decimal": 58890
},
{
"icon_id": "2811147",
"name": "会员",
"font_class": "member",
"unicode": "e640",
"unicode_decimal": 58944
},
{
"icon_id": "4560182",
"name": "会员充值",
"font_class": "recharge",
"unicode": "e799",
"unicode_decimal": 59289
},
{
"icon_id": "5880283",
"name": "营销",
"font_class": "marketing",
"unicode": "e765",
"unicode_decimal": 59237
},
{
"icon_id": "6982618",
"name": "商品规格",
"font_class": "goods-sku",
"unicode": "e6d7",
"unicode_decimal": 59095
},
{
"icon_id": "7307041",
"name": "商家入驻",
"font_class": "store",
"unicode": "e62b",
"unicode_decimal": 58923
},
{
"icon_id": "11639867",
"name": "小店商品库",
"font_class": "goods-store",
"unicode": "e6c6",
"unicode_decimal": 59078
},
{
"icon_id": "13872198",
"name": "商家",
"font_class": "storer",
"unicode": "e64a",
"unicode_decimal": 58954
},
{
"icon_id": "577335",
"name": "订单",
"font_class": "order",
"unicode": "e737",
"unicode_decimal": 59191
},
{
"icon_id": "736503",
"name": "权限",
"font_class": "permission",
"unicode": "e612",
"unicode_decimal": 58898
},
{
"icon_id": "1727271",
"name": "商品",
"font_class": "goods",
"unicode": "e889",
"unicode_decimal": 59529
},
{
"icon_id": "7587933",
"name": "菜单",
"font_class": "menu",
"unicode": "e60e",
"unicode_decimal": 58894
},
{
"icon_id": "12758820",
"name": "字典类型",
"font_class": "dict-type",
"unicode": "e652",
"unicode_decimal": 58962
},
{
"icon_id": "13768112",
"name": "字典",
"font_class": "dictionary",
"unicode": "e600",
"unicode_decimal": 58880
},
{
"icon_id": "37734141",
"name": "角色",
"font_class": "role",
"unicode": "e604",
"unicode_decimal": 58884
},
{
"icon_id": "1727563",
"name": "全屏",
"font_class": "fullscreen",
"unicode": "e8fa",
"unicode_decimal": 59642
},
{
"icon_id": "1727566",
"name": "退出全屏",
"font_class": "exit-fullscreen",
"unicode": "e8fb",
"unicode_decimal": 59643
},
{
"icon_id": "11641852",
"name": "表格",
"font_class": "table",
"unicode": "e615",
"unicode_decimal": 58901
},
{
"icon_id": "20104468",
"name": "测试",
"font_class": "test",
"unicode": "e610",
"unicode_decimal": 58896
},
{
"icon_id": "26686335",
"name": "中英文",
"font_class": "lang",
"unicode": "e649",
"unicode_decimal": 58953
},
{
"icon_id": "37702310",
"name": "文字大小",
"font_class": "size",
"unicode": "e660",
"unicode_decimal": 58976
}
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -35,7 +35,7 @@ const props = defineProps({
default: '提示:导入前请先下载模板填写信息,然后再导入!',
},
templateUrl: {
type: String,
type: [String, URL],
default: '',
},
// options: {

View File

@ -7,4 +7,16 @@ export const GenKey = (key, prefix = `${VITE_APP_NAME}_`) => {
export const CONSTANTS = {
PREFIX: `${VITE_APP_NAME}_`,
PRIMARY: '#409eff',
// 密钥对生成 http://web.chacuo.net/netrsakeypair
JS_PUBLICKEY:
'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==',
JS_PRIVATEKEY:
'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
'7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
'UP8iWi1Qw0Y=',
};

View File

@ -4,7 +4,7 @@ import App from './App.vue';
import router from './router';
import pinia from './store';
import ElementPlus from 'element-plus';
// import 'element-plus/dist/index.css';
import 'element-plus/dist/index.css';
import { registerGlobalMicroApps } from './micro';
import { registerElIcons } from './plugins/icon';
import './utils/permission';

View File

@ -2,6 +2,7 @@ import { initGlobalState } from 'qiankun';
import { reactive } from 'vue';
const initialState = reactive({
token: null,
user: {
name: 'admin',
},

View File

@ -10,13 +10,13 @@ export const leftApps = [
// title: '运营服务',
// icon: 'images/platform/icon-home.png',
// },
{
name: 'sub-admin',
entry: VITE_APP_SUB_ADMIN,
activeRule: '/sub-admin/',
title: '管理后台',
icon: 'images/platform/icon-admin.png',
},
// {
// name: 'sub-admin',
// entry: VITE_APP_SUB_ADMIN,
// activeRule: '/sub-admin/',
// title: '管理后台',
// icon: 'images/platform/icon-admin.png',
// },
// {
// name: 'sub-app',
// entry: VITE_APP_SUB_ADMIN,
@ -81,7 +81,7 @@ const apps = microApps.map((item) => {
container: '#app',
props: {
routerBase: item.activeRule,
getGlobalState: actions.getGlobalState,
globalState: actions.getGlobalState(),
},
};
});

View File

@ -1,64 +1,12 @@
import { defineStore } from 'pinia';
import { CONSTANTS } from '@/config';
export const useSettingStore = defineStore({
id: 'settingStore',
state: () => ({
// menu 是否收缩
isCollapse: true,
//
withoutAnimation: false,
device: 'desktop',
// 刷新当前页
isReload: true,
// 主题设置
themeConfig: {
// 显示设置
showSetting: false,
// 菜单展示模式 默认 vertical horizontal / vertical /columns
mode: 'vertical',
// tagsView 是否展示 默认展示
showTag: true,
// 页脚
footer: true,
// 深色模式 切换暗黑模式
isDark: false,
// 显示侧边栏Logo
showLogo: true,
// 主题颜色
primary: CONSTANTS.PRIMARY,
// element组件大小
globalComSize: 'default',
// 是否只保持一个子菜单的展开
uniqueOpened: true,
// 固定header
fixedHeader: true,
// 灰色模式
gray: false,
// 色弱模式
weak: false,
},
}),
getters: {},
actions: {
// 设置主题
setThemeConfig({ key, val }) {
this.themeConfig[key] = val;
},
// 切换 Collapse
setCollapse(value) {
this.isCollapse = value;
this.withoutAnimation = false;
},
// 关闭侧边栏
closeSideBar({ withoutAnimation }) {
this.isCollapse = false;
this.withoutAnimation = withoutAnimation;
},
toggleDevice(device) {
this.device = device;
},
// 刷新
setReload() {
this.isReload = false;
setTimeout(() => {

View File

@ -1,104 +0,0 @@
import { defineStore } from 'pinia';
import router from '@/router';
export const useTagsViewStore = defineStore({
id: 'tagsViewStore',
state: () => ({
activeTabsValue: '/home',
visitedViews: [],
cachedViews: [],
}),
getters: {},
actions: {
setTabsMenuValue(val) {
this.activeTabsValue = val;
},
addView(view) {
this.addVisitedView(view);
},
removeView(routes) {
return new Promise((resolve) => {
this.visitedViews = this.visitedViews.filter((item) => !routes.includes(item.path));
resolve(null);
});
},
addVisitedView(view) {
this.setTabsMenuValue(view.path);
if (this.visitedViews.some((v) => v.path === view.path)) return;
this.visitedViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name',
})
);
if (view.meta.keepAlive) {
this.cachedViews.push(view.name);
}
},
delView(activeTabPath) {
return new Promise((resolve) => {
this.delVisitedView(activeTabPath);
this.delCachedView(activeTabPath);
resolve({
visitedViews: [...this.visitedViews],
cachedViews: [...this.cachedViews],
});
});
},
toLastView(activeTabPath) {
const index = this.visitedViews.findIndex((item) => item.path === activeTabPath);
const nextTab = this.visitedViews[index + 1] || this.visitedViews[index - 1];
if (!nextTab) return;
router.push(nextTab.path);
this.addVisitedView(nextTab);
},
delVisitedView(path) {
return new Promise((resolve) => {
this.visitedViews = this.visitedViews.filter((v) => {
return v.path !== path || v.meta.affix;
});
this.cachedViews = this.cachedViews.filter((v) => {
return v.path !== path || v.meta.affix;
});
resolve([...this.visitedViews]);
});
},
delCachedView(view) {
return new Promise((resolve) => {
const index = this.cachedViews.indexOf(view.name);
index > -1 && this.cachedViews.splice(index, 1);
resolve([...this.cachedViews]);
});
},
clearVisitedView() {
this.delAllViews();
},
delAllViews() {
return new Promise((resolve) => {
this.visitedViews = this.visitedViews.filter((v) => v.meta.affix);
this.cachedViews = this.visitedViews.filter((v) => v.meta.affix);
resolve([...this.visitedViews]);
});
},
delOtherViews(path) {
this.visitedViews = this.visitedViews.filter((item) => {
return item.path === path || item.meta.affix;
});
this.cachedViews = this.visitedViews.filter((item) => {
return item.path === path || item.meta.affix;
});
},
goHome() {
this.activeTabsValue = '/home';
router.push({ path: '/home' });
},
updateVisitedView(view) {
for (let v of this.visitedViews) {
if (v.path === view.path) {
v = Object.assign(v, view);
break;
}
}
},
},
});

View File

@ -3,7 +3,7 @@ import { GenKey } from '@/config';
import { isEmpty, encode, decode } from '@/utils';
export const useUserStore = defineStore({
id: GenKey('USER_STATE'),
id: GenKey('user_store'),
state: () => ({
token: null,
userInfo: {},
@ -52,14 +52,14 @@ export const useUserStore = defineStore({
this.currentOrg = null;
this.orgList = [];
this.menus = [];
localStorage.removeItem(GenKey('USER_STATE'));
localStorage.removeItem(GenKey('user_store'));
},
clear() {
localStorage.removeItem(GenKey('USER_STATE'));
localStorage.removeItem(GenKey('user_store'));
},
},
persist: {
key: GenKey('USER_STATE'),
key: GenKey('user_store'),
storage: window.localStorage,
},
});

View File

@ -77,7 +77,8 @@ body {
width: 100%;
height: 100%;
font-size: 12px;
font-family: 'Source Han Sans CN, Source Han Sans CN-Regular', 'Helvetica Neue', Helvetica, Arial, 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif;
font-family: 'Source Han Sans CN, Source Han Sans CN-Regular', 'Helvetica Neue', Helvetica, Arial, 'PingFang SC', 'Hiragino Sans GB', 'Heiti SC',
'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif;
color: #323232;
// background: #000;

View File

@ -29,28 +29,28 @@ $color-types: (
primary: (
$color-primary,
#4db3ff,
#1d90e6
#1d90e6,
),
info: (
$color-info,
#73ccff,
#48ace6
#48ace6,
),
success: (
$color-success,
#42d885,
#11b95c
#11b95c,
),
warning: (
$color-warning,
#f9c855,
#dea726
#dea726,
),
danger: (
$color-danger,
#ff6d6d,
#e64242
)
#e64242,
),
);
@import "utils/utils";
@import 'utils/utils';

View File

@ -2,12 +2,13 @@
* @Descripttion:
* @Author: zenghua.wang
* @Date: 2022-02-23 21:12:37
* @LastEditors: wzh 1048523306@qq.com
* @LastEditTime: 2024-12-18 15:10:48
* @LastEditors: zenghua.wang
* @LastEditTime: 2025-02-13 14:46:34
*/
import axios from 'axios';
import { ElNotification } from 'element-plus';
import router from '@/router';
import { isEmpty } from '@/utils';
import { useUserStore } from '@/store/modules/user';
const { VITE_APP_BASE_API, VITE_APP_UPLOAD_API } = import.meta.env;
@ -45,14 +46,10 @@ const errorHandler = async (error) => {
*/
publicAxios.interceptors.request.use(async (config) => {
const UserStore = useUserStore();
config.baseURL = config?.isUpload ? VITE_APP_UPLOAD_API : config?.isLocal ? '' : VITE_APP_BASE_API;
if (UserStore.hasToken()) {
config.headers['fairies-auth-token'] = UserStore.token;
config.headers['authorization'] = config.headers['authorization'] ?? UserStore.token;
config.headers['cache-control'] = 'no-cache';
config.headers.Pragma = 'no-cache';
if (config?.isUpload) {
config.headers['Content-Type'] = config.uploadType;
}
}
if (config.method === 'POST' || config.method === 'DELETE') {
config.headers.Accept = 'application/json';
@ -89,6 +86,11 @@ publicAxios.interceptors.response.use((response) => {
if (config?.responseType) {
return response;
}
const token = response?.headers['authorization'];
if (!isEmpty(token)) {
const UserStore = useUserStore();
UserStore.setToken(token);
}
const result = formatResult(response);
if (result) {
return result;

View File

@ -19,9 +19,7 @@ import {
GraphicComponent,
} from 'echarts/components';
// TODO 如果想换成SVG渲染就导出SVGRenderer
// 并且放到 echarts.use 里,注释掉 CanvasRenderer
import { /*SVGRenderer*/ CanvasRenderer } from 'echarts/renderers';
import { CanvasRenderer } from 'echarts/renderers';
echarts.use([
LegendComponent,
@ -36,7 +34,6 @@ echarts.use([
PieChart,
MapChart,
RadarChart,
// TODO 因为要兼容Online图表自适应打印所以改成 CanvasRenderer可能会模糊
CanvasRenderer,
PictorialBarChart,
RadarComponent,

View File

@ -3,44 +3,13 @@
* @Author: zenghua.wang
* @Date: 2022-02-23 21:12:37
* @LastEditors: zenghua.wang
* @LastEditTime: 2025-02-10 14:47:12
* @LastEditTime: 2025-02-13 11:28:46
*/
import lodash from 'lodash';
import dayjs from 'dayjs';
import { Base64 } from 'js-base64';
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min';
import { CONSTANTS } from '@/config';
/**
* @Title 防抖指在一定时间内多次触发同一个事件只执行最后一次操作
* @param {*} fn
* @param {*} delay
* @returns
*/
export function debounce(fn, delay) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
/**
* @Title 节流指在一定时间内多次触发同一个事件只执行第一次操作
* @param {*} fn
* @param {*} delay
* @returns
*/
export function throttle(fn, delay) {
let timer = null;
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
}
};
}
/**
* @Title 判断是否 empty,返回ture
* @param {*} val:null 'null' undefined 'undefined' 0 '0' "" 返回true
@ -79,78 +48,6 @@ export const setPx = (val) => {
}
return val;
};
/**
* @Tilte 设置属性默认值
* @param {*} options
* @param {*} prop
* @param {*} defaultVal
* @returns
*/
export const setDefaultOption = (options, prop, defaultVal) => {
return options[prop] === undefined ? defaultVal : options.prop;
};
/**
* @Title 设置字典值
* @param {*} columns
* @param {*} key
* @param {*} data
* @returns
*/
export const setDicData = (columns, key, data = []) => {
if (isEmpty(data)) return;
const len = columns.length;
for (let i = 0; i < len; i++) {
if (columns[i]?.prop === key) {
columns[i]['dicData'] = data;
break;
}
}
};
/**
* @Title 求字段lable
* @param {*} tree
* @returns
*/
export const setDicLabel = (dicData, value) => {
let label = value;
if (isEmpty(dicData)) return label;
const len = dicData.length;
for (let i = 0; i < len; i++) {
if (dicData[i]?.value === value) {
label = dicData[i].label;
break;
}
}
return label;
};
/**
* @Title 数组交集
* @param {*} arr1
* @param {*} arr2
* @returns
*/
export const intersectionArray = (arr1 = [], arr2 = []) => {
return arr1.filter((item) => arr2.includes(item));
};
/**
* @Title 数组并集
* @param {*} arr1
* @param {*} arr2
* @returns
*/
export const unionArray = (arr1 = [], arr2 = []) => {
return Array.from(new Set([...arr1, ...arr2]));
};
/**
* @Title 数组差集
* @param {*} arr1
* @param {*} arr2
* @returns
*/
export const differenceArray = (arr1 = [], arr2 = []) => {
const s = new Set(arr2);
return arr1.filter((x) => !s.has(x));
};
/**
* @Title 加密
* @param {*} n
@ -195,6 +92,29 @@ export const decode = (e, flag = false) => {
}
return e;
};
/**
* @Title 加密
* @param {*} txt
* @returns
*/
export const encrypt = (txt) => {
const encryptor = new JSEncrypt();
encryptor.setPublicKey(CONSTANTS.JS_PUBLICKEY); // 设置公钥
return encryptor.encrypt(txt); // 对数据进行加密
};
/**
* @Title 解密
* @param {*} txt
* @returns
*/
export const decrypt = (txt) => {
const encryptor = new JSEncrypt();
encryptor.setPrivateKey(CONSTANTS.JS_PRIVATEKEY); // 设置私钥
return encryptor.decrypt(txt); // 对数据进行解密
};
/**
* @Title 图片转base64
* @param {*} file
@ -293,166 +213,3 @@ export const obj2Param = (json) => {
export const getAssetsFile = (url) => {
return new URL(`../assets/${url}`, import.meta.url);
};
/**
* @Title: 下载文件
* @param {void} url:
* @param {void} fileName:
* @param {void} fileType:
* @return {void}
*/
export const downloadFile = async (url, fileName, fileType) => {
let blob = null;
try {
switch (fileType) {
case 'image': {
const img = new Image();
img.crossOrigin = 'Anonymous';
img.src = url;
await new Promise((resolve, reject) => {
img.onload = resolve;
img.onerror = reject;
});
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
blob = await new Promise((resolve) => {
canvas.toBlob(resolve, 'image/jpeg');
});
break;
}
case 'blob': {
blob = new Blob([url]);
break;
}
}
if ('download' in document.createElement('a')) {
const elink = document.createElement('a');
elink.download = fileName;
elink.style.display = 'none';
elink.href = blob ? URL.createObjectURL(blob) : url;
document.body.appendChild(elink);
elink.click();
blob && URL.revokeObjectURL(elink.href);
document.body.removeChild(elink);
} else {
navigator.msSaveBlob(blob, fileName);
}
} catch (error) {
console.error('下载出错:', error);
}
};
/**
* @Title 模拟休眠
* @param {*} duration
* @returns
*/
export const sleep = (duration = 0) =>
new Promise((resolve) => {
setTimeout(resolve, duration);
});
/**
* @Title 创建id
* @param {*} prefix
* @returns
*/
export const createId = (prefix) => {
const val = Date.now() + Math.ceil(Math.random() * 99999);
return isEmpty(prefix) ? val : prefix + '-' + val;
};
/**
* @Title 生成数据
* @param {*} duration
* @returns
*/
export const mockData = (item = {}, len = 1) => {
const list = [];
for (let i = 0; i < len; i++) {
let temp = { ...item, id: createId() };
list.push(temp);
}
return list;
};
/**
* @Title 日期格式化
* @param {*} date
* @param {*} format
* @returns
*/
export const dateFormat = (datetime, formater = 'YYYY-MM-DD hh:mm:ss') => {
if (datetime instanceof Date || datetime) {
return dayjs(datetime).format(formater);
} else {
return null;
}
};
/**
* @Title 字符串转日期
* @param {*} str
* @returns
*/
export const toDate = (str) => {
return !isEmpty(str) ? dayjs(str) : dayjs();
};
/**
* @Title 字符串转日期
* @param {*} str
* @returns
*/
export const getDate = (num, type, formater = 'YYYY-MM-DD', start = true) => {
const date = dayjs().subtract(num, type);
return start ? date.startOf(type).format(formater) : date.endOf(type).format(formater);
};
/**
* @Title: 获取时间差
* @param start
* @param end
* @param type
* @returns
*/
export const getDiffTime = (start, end, type) => {
const startTime = dayjs(start);
const endTime = dayjs(end);
const duration = endTime.diff(startTime);
let diff = 0;
switch (type) {
case 'DD': {
diff = duration / (1000 * 60 * 60 * 24);
break;
}
case 'HH': {
diff = duration / (1000 * 60 * 60);
break;
}
case 'mm': {
diff = duration / (1000 * 60);
break;
}
}
return Math.round(diff);
};
/**
* @Title: 开始日期
* @param last
* @param type
* @param formater
* @returns
*/
export const startDate = (num, type = 'month', formater = 'YYYY-MM-DD HH:mm:ss') => {
if (num === 'now') return dayjs().format(formater);
if (typeof num === 'string') return dayjs(num).startOf(type).format(formater);
return num === 0 ? dayjs().startOf(type).format(formater) : dayjs().subtract(num, type).startOf(type).format(formater);
};
/**
* @Title: 结束日期
* @param num
* @param type
* @param formater
* @returns
*/
export const endDate = (num = 0, type = 'month', formater = 'YYYY-MM-DD HH:mm:ss') => {
if (num === 'now') return dayjs().format(formater);
if (typeof num === 'string') return dayjs(num).endOf(type).format(formater);
return num === 0 ? dayjs().endOf(type).format(formater) : dayjs().subtract(num, type).endOf(type).format(formater);
};

View File

@ -23,7 +23,7 @@ router.beforeEach(async (to, from, next) => {
}
const userStore = useUserStore();
const hasToken = true; //userStore.hasToken();
const hasToken = userStore.hasToken();
if (hasToken) {
if (to.path === '/login') {
@ -36,7 +36,6 @@ router.beforeEach(async (to, from, next) => {
accessRoutes.forEach((item) => router.addRoute(item));
next({ ...to, replace: true });
} else {
// 子应用跳转回主应用时判断#app是否还有渲染的子应用,如若没有则重新渲染主应用
if (from.path.includes('/sub') && !to.path.includes('/sub')) {
window.location.reload();
return;

View File

@ -1,3 +1,11 @@
/**
* @Description:
* @Author: zenghua.wang
* @Date: 2022-01-26 21:55:58
* @LastEditors: zenghua.wang
* @LastEditTime: 2024-04-14 11:03:08
*/
/**
* 路径匹配器
* @param {string} pattern

View File

@ -40,7 +40,7 @@ const gotoPage = (row) => {
// actions.setGlobalState({
// curentApp,
// });
console.log('===', actions.getGlobalState('user'));
// console.log('===', actions.getGlobalState('user'));
window.history.pushState({}, row.name, row.activeRule);
};
</script>
@ -50,8 +50,7 @@ const gotoPage = (row) => {
height: 100%;
background-image: url('@/assets/images/platform/bg.png');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
// background-position: center;
&-title {
width: 1200px;

View File

@ -1,5 +1,206 @@
<template>
<div>登录</div>
<div class="login">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
<h3 class="title">数字农业产业管理平台</h3>
<el-form-item prop="username">
<el-input v-model="loginForm.username" type="text" 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" 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 v-if="captchaEnabled" prop="code">
<el-input v-model="loginForm.code" 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" class="login-code-img" @click="getCode" />
</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 v-if="register" style="float: right">
<router-link class="link-type" :to="'/register'">立即注册</router-link>
</div> -->
</el-form-item>
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2025-2035 英壹集团 All Rights Reserved.</span>
</div>
</div>
</template>
<script setup></script>
<script>
import Cookies from 'js-cookie';
import { encrypt, decrypt } from '@/utils';
import { GetCodeImg, Login } from '@/apis/login';
import { useUserStore } from '@/store/modules/user';
import actions from '@/micro/actions';
const UserStore = useUserStore();
export default {
name: 'Login',
data() {
return {
codeUrl: '',
loginForm: {
username: 'admin',
password: 'admin123',
rememberMe: false,
code: '',
uuid: '',
},
loginRules: {
username: [{ required: true, trigger: 'blur', message: '请输入您的账号' }],
password: [{ required: true, trigger: 'blur', message: '请输入您的密码' }],
code: [{ required: true, trigger: 'change', message: '请输入验证码' }],
},
loading: false,
//
captchaEnabled: true,
//
register: true,
redirect: undefined,
};
},
watch: {
$route: {
handler: function (route) {
this.redirect = route.query && route.query.redirect;
},
immediate: true,
},
},
created() {
this.getCode();
this.getCookie();
},
methods: {
getCode() {
GetCodeImg().then((res) => {
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
if (this.captchaEnabled) {
this.codeUrl = 'data:image/gif;base64,' + res.img;
this.loginForm.uuid = res.uuid;
}
});
},
getCookie() {
const username = Cookies.get('username');
const password = Cookies.get('password');
const rememberMe = Cookies.get('rememberMe');
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
};
},
handleLogin() {
this.$refs.loginForm.validate((valid) => {
if (valid) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set('username', this.loginForm.username, { expires: 30 });
Cookies.set('password', encrypt(this.loginForm.password), { expires: 30 });
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
} else {
Cookies.remove('username');
Cookies.remove('password');
Cookies.remove('rememberMe');
}
Login(this.loginForm)
.then((res) => {
UserStore.setToken(res.data.access_token);
actions.setGlobalState({
token: res.data.access_token,
});
this.$router.push({ path: this.redirect || '/' }).catch(() => {});
})
.catch(() => {
this.loading = false;
if (this.captchaEnabled) {
this.getCode();
}
});
}
});
},
},
};
</script>
<style lang="scss" scoped>
.login {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
background-image: url('@/assets/images/platform/bg.png');
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;
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
}
}
.login-tip {
font-size: 13px;
text-align: center;
color: #bfbfbf;
}
.login-code {
width: 33%;
height: 38px;
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: 38px;
}
</style>

View File

@ -3862,6 +3862,11 @@ js-yaml@^4.1.0:
dependencies:
argparse "^2.0.1"
jsencrypt@^3.3.2:
version "3.3.2"
resolved "https://registry.npmmirror.com/jsencrypt/-/jsencrypt-3.3.2.tgz#b0f1a2278810c7ba1cb8957af11195354622df7c"
integrity sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A==
jsesc@^3.0.2:
version "3.1.0"
resolved "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d"

View File

@ -12,12 +12,12 @@
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled">
<el-form-item v-if="captchaEnabled" prop="code">
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter.native="handleLogin">
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img" />
<img :src="codeUrl" class="login-code-img" @click="getCode" />
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin: 0px 0px 25px 0px">记住密码</el-checkbox>
@ -26,15 +26,15 @@
<span v-if="!loading"> </span>
<span v-else> 中...</span>
</el-button>
<div style="float: right" v-if="register">
<div v-if="register" style="float: right">
<router-link class="link-type" :to="'/register'">立即注册</router-link>
</div>
</el-form-item>
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
<!-- <div class="el-login-footer">
<span>Copyright © 2025-2035 tari All Rights Reserved.</span>
</div>
</div> -->
</div>
</template>