feat:初始化项目结构
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>contract-file</div>
|
||||
</template>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>contract-list</div>
|
||||
</template>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>contract-template</div>
|
||||
</template>
|
||||
@@ -0,0 +1,13 @@
|
||||
export default {
|
||||
'menu.business.project': '项目管理',
|
||||
'menu.business.space': '空间管理',
|
||||
'menu.business.house-view': '房源剖视',
|
||||
'menu.business.house-list': '房源列表',
|
||||
'menu.business.contract': '合同管理',
|
||||
'menu.business.contract-list': '合同列表',
|
||||
'menu.business.contract-file': '合同归档',
|
||||
'menu.business.contract-template': '合同模板',
|
||||
'menu.business.tenant': '租客管理',
|
||||
'menu.business.tenant-list': '租客列表',
|
||||
'menu.business.tenant.contacts': '租客联系人',
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>project</div>
|
||||
</template>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>house-list</div>
|
||||
</template>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>house-view</div>
|
||||
</template>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>tenant-contacts</div>
|
||||
</template>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>tenant-list</div>
|
||||
</template>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>monitor</div>
|
||||
</template>
|
||||
@@ -0,0 +1,48 @@
|
||||
export default {
|
||||
'menu.dashboard.monitor': 'Real-time Monitor',
|
||||
'monitor.title.chatPanel': 'Chat Window',
|
||||
'monitor.title.quickOperation': 'Quick Operation',
|
||||
'monitor.title.studioInfo': 'Studio Information',
|
||||
'monitor.title.studioPreview': 'Studio Preview',
|
||||
'monitor.chat.options.all': 'All',
|
||||
'monitor.chat.placeholder.searchCategory': 'Search Category',
|
||||
'monitor.chat.update': 'Update',
|
||||
'monitor.list.title.order': 'Order',
|
||||
'monitor.list.title.cover': 'Cover',
|
||||
'monitor.list.title.name': 'Name',
|
||||
'monitor.list.title.duration': 'Duration',
|
||||
'monitor.list.title.id': 'ID',
|
||||
'monitor.list.tip.rotations': 'Rotations ',
|
||||
'monitor.list.tip.rest': ', The program list is not visible to viewers',
|
||||
'monitor.list.tag.auditFailed': 'Audit Failed',
|
||||
'monitor.tab.title.liveMethod': 'Live Method',
|
||||
'monitor.tab.title.onlinePopulation': 'Online Population',
|
||||
'monitor.liveMethod.normal': 'Normal Live',
|
||||
'monitor.liveMethod.flowControl': 'Flow Control Live',
|
||||
'monitor.liveMethod.video': 'Video Live',
|
||||
'monitor.liveMethod.web': 'Web Live',
|
||||
'monitor.editCarousel': 'Edit',
|
||||
'monitor.startCarousel': 'Start',
|
||||
'monitor.quickOperation.changeClarity': 'Change the Clarity',
|
||||
'monitor.quickOperation.switchStream': 'Switch Stream',
|
||||
'monitor.quickOperation.removeClarity': 'Remove the Clarity',
|
||||
'monitor.quickOperation.pushFlowGasket': 'Push Flow Gasket',
|
||||
'monitor.studioInfo.label.studioTitle': 'Studio Title',
|
||||
'monitor.studioInfo.label.onlineNotification': 'Online Notification',
|
||||
'monitor.studioInfo.label.studioCategory': 'Studio Category',
|
||||
'monitor.studioInfo.placeholder.studioTitle': "'s Studio",
|
||||
'monitor.studioInfo.btn.fresh': 'Fresh',
|
||||
'monitor.studioStatus.title.studioStatus': 'Studio Status',
|
||||
'monitor.studioStatus.title.pictureInfo': 'Picture Information',
|
||||
'monitor.studioStatus.smooth': 'Smooth',
|
||||
'monitor.studioStatus.frameRate': 'Frame',
|
||||
'monitor.studioStatus.bitRate': 'Bit',
|
||||
'monitor.studioStatus.mainstream': 'Main',
|
||||
'monitor.studioStatus.hotStandby': 'Hot',
|
||||
'monitor.studioStatus.coldStandby': 'Cold',
|
||||
'monitor.studioStatus.line': 'Line',
|
||||
'monitor.studioStatus.play': 'Format',
|
||||
'monitor.studioStatus.pictureQuality': 'Quality',
|
||||
'monitor.studioPreview.studio': 'Studio',
|
||||
'monitor.studioPreview.watching': 'watching',
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
export default {
|
||||
'menu.dashboard.monitor': '实时监控',
|
||||
'monitor.title.chatPanel': '聊天窗口',
|
||||
'monitor.title.quickOperation': '快捷操作',
|
||||
'monitor.title.studioInfo': '直播信息',
|
||||
'monitor.title.studioPreview': '直播预览',
|
||||
'monitor.chat.options.all': '全部',
|
||||
'monitor.chat.placeholder.searchCategory': '搜索类目',
|
||||
'monitor.chat.update': '更新',
|
||||
'monitor.list.title.order': '序号',
|
||||
'monitor.list.title.cover': '封面',
|
||||
'monitor.list.title.name': '名称',
|
||||
'monitor.list.title.duration': '视频时长',
|
||||
'monitor.list.title.id': '视频Id',
|
||||
'monitor.list.tip.rotations': '轮播次数',
|
||||
'monitor.list.tip.rest': ',节目单观众不可见',
|
||||
'monitor.list.tag.auditFailed': '审核未通过',
|
||||
'monitor.tab.title.liveMethod': '直播方式',
|
||||
'monitor.tab.title.onlinePopulation': '在线人数',
|
||||
'monitor.liveMethod.normal': '普通直播',
|
||||
'monitor.liveMethod.flowControl': '控流直播',
|
||||
'monitor.liveMethod.video': '视频直播',
|
||||
'monitor.liveMethod.web': '网页开播',
|
||||
'monitor.editCarousel': '编辑轮播',
|
||||
'monitor.startCarousel': '开始轮播',
|
||||
'monitor.quickOperation.changeClarity': '切换清晰度',
|
||||
'monitor.quickOperation.switchStream': '主备流切换',
|
||||
'monitor.quickOperation.removeClarity': '摘除清晰度',
|
||||
'monitor.quickOperation.pushFlowGasket': '推流垫片',
|
||||
'monitor.studioInfo.label.studioTitle': '直播标题',
|
||||
'monitor.studioInfo.label.onlineNotification': '上线通知',
|
||||
'monitor.studioInfo.label.studioCategory': '直播类目',
|
||||
'monitor.studioInfo.placeholder.studioTitle': '的直播间',
|
||||
'monitor.studioInfo.btn.fresh': '更新',
|
||||
'monitor.studioStatus.title.studioStatus': '直播状态',
|
||||
'monitor.studioStatus.title.pictureInfo': '画面信息',
|
||||
'monitor.studioStatus.smooth': '流畅',
|
||||
'monitor.studioStatus.frameRate': '帧率',
|
||||
'monitor.studioStatus.bitRate': '码率',
|
||||
'monitor.studioStatus.mainstream': '主流',
|
||||
'monitor.studioStatus.hotStandby': '热备',
|
||||
'monitor.studioStatus.coldStandby': '冷备',
|
||||
'monitor.studioStatus.line': '线路',
|
||||
'monitor.studioStatus.play': '播放格式',
|
||||
'monitor.studioStatus.pictureQuality': '画质',
|
||||
'monitor.studioPreview.studio': '直播间',
|
||||
'monitor.studioPreview.watching': '在看',
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>workplace</div>
|
||||
</template>
|
||||
@@ -0,0 +1,38 @@
|
||||
export default {
|
||||
'menu.dashboard.workplace': 'Workplace',
|
||||
'workplace.welcome': 'Welcome!',
|
||||
'workplace.balance': 'Balance (CNY)',
|
||||
'workplace.order.pending': 'Pending',
|
||||
'workplace.order.pendingRenewal': 'Renewal Order',
|
||||
'workplace.onlineContent': 'Online Content',
|
||||
'workplace.putIn': 'Put In',
|
||||
'workplace.newDay': 'Daily Additional Comments',
|
||||
'workplace.newFromYesterday': 'New From Yesterday',
|
||||
'workplace.minute': 'Min',
|
||||
'workplace.docs': 'Documents',
|
||||
'workplace.docs.productOverview': 'Product Overview',
|
||||
'workplace.docs.userGuide': 'User Guide',
|
||||
'workplace.docs.workflow': 'Workflow',
|
||||
'workplace.docs.interfaceDocs': 'Interface Docs',
|
||||
//
|
||||
'workplace.contentManagement': 'Content Management',
|
||||
'workplace.contentStatistical': 'Content Statistical',
|
||||
'workplace.advanced': 'Advanced',
|
||||
'workplace.onlinePromotion': 'Online Promotion',
|
||||
'workplace.contentPutIn': 'Put In',
|
||||
'workplace.announcement': 'Announcement',
|
||||
'workplace.recently.visited': 'Recently Visited',
|
||||
'workplace.record.nodata': 'No data',
|
||||
'workplace.quick.operation': 'Quick Operation',
|
||||
'workplace.quickOperation.setup': 'Setup',
|
||||
'workplace.allProject': 'All',
|
||||
'workplace.loadMore': 'More',
|
||||
'workplace.viewMore': 'More',
|
||||
'workplace.contentData': 'Content Data',
|
||||
'workplace.popularContent': 'Popular Content',
|
||||
'workplace.popularContent.text': 'text',
|
||||
'workplace.popularContent.image': 'image',
|
||||
'workplace.popularContent.video': 'video',
|
||||
'workplace.categoriesPercent': 'Categories Percent',
|
||||
'workplace.pecs': 'pecs',
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
export default {
|
||||
'menu.dashboard.workplace': '工作台',
|
||||
'workplace.welcome': '欢迎回来!',
|
||||
'workplace.balance': '余额(元)',
|
||||
'workplace.order.pending': '待支付',
|
||||
'workplace.order.pendingRenewal': '待续费订单',
|
||||
'workplace.onlineContent': '线上总内容',
|
||||
'workplace.putIn': '投放中内容',
|
||||
'workplace.newDay': '日新增评论',
|
||||
'workplace.newFromYesterday': '较昨日新增',
|
||||
'workplace.minute': '分钟',
|
||||
'workplace.docs': '帮助文档',
|
||||
'workplace.docs.productOverview': '产品概要',
|
||||
'workplace.docs.userGuide': '使用指南',
|
||||
'workplace.docs.workflow': '接入流程',
|
||||
'workplace.docs.interfaceDocs': '接口文档',
|
||||
'workplace.contentManagement': '内容管理',
|
||||
'workplace.contentStatistical': '内容分析',
|
||||
'workplace.advanced': '高级管理',
|
||||
'workplace.onlinePromotion': '线上推广',
|
||||
'workplace.contentPutIn': '内容投放',
|
||||
'workplace.announcement': '公告',
|
||||
'workplace.recently.visited': '最近访问',
|
||||
'workplace.record.nodata': '暂无数据',
|
||||
'workplace.quick.operation': '快捷操作',
|
||||
'workplace.quickOperation.setup': '管理',
|
||||
'workplace.allProject': '所有项目',
|
||||
'workplace.loadMore': '加载更多',
|
||||
'workplace.viewMore': '查看更多',
|
||||
'workplace.contentData': '内容数据',
|
||||
'workplace.popularContent': '线上热门内容',
|
||||
'workplace.popularContent.text': '文本',
|
||||
'workplace.popularContent.image': '图片',
|
||||
'workplace.popularContent.video': '视频',
|
||||
'workplace.categoriesPercent': '内容类型占比',
|
||||
'workplace.pecs': '个',
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<Breadcrumb :items="['menu.exception', 'menu.exception.403']" />
|
||||
<div class="content">
|
||||
<a-result
|
||||
class="result"
|
||||
status="403"
|
||||
:subtitle="$t('exception.result.403.description')"
|
||||
/>
|
||||
<a-button key="back" type="primary">
|
||||
{{ $t('exception.result.403.back') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: '403',
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container {
|
||||
padding: 0 20px 20px 20px;
|
||||
height: calc(100% - 40px);
|
||||
:deep(.content) {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
background-color: var(--color-bg-1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
'menu.exception.403': '403',
|
||||
'exception.result.403.description':
|
||||
'Access to this resource on the server is denied.',
|
||||
'exception.result.403.back': 'Back',
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
'menu.exception.403': '403',
|
||||
'exception.result.403.description': '对不起,您没有访问该资源的权限',
|
||||
'exception.result.403.back': '返回',
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<Breadcrumb :items="['menu.exception', 'menu.exception.404']" />
|
||||
<div class="content">
|
||||
<a-result
|
||||
class="result"
|
||||
status="404"
|
||||
:subtitle="$t('exception.result.404.description')"
|
||||
>
|
||||
</a-result>
|
||||
<div class="operation-row">
|
||||
<a-button key="again" style="margin-right: 16px">
|
||||
{{ $t('exception.result.404.retry') }}
|
||||
</a-button>
|
||||
<a-button key="back" type="primary">
|
||||
{{ $t('exception.result.404.back') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: '404',
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container {
|
||||
padding: 0 20px 20px 20px;
|
||||
height: calc(100% - 40px);
|
||||
:deep(.content) {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
background-color: var(--color-bg-1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
'menu.exception.404': '404',
|
||||
'exception.result.404.description': 'Whoops, this page is gone.',
|
||||
'exception.result.404.retry': 'Retry',
|
||||
'exception.result.404.back': 'Back',
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
'menu.exception.404': '404',
|
||||
'exception.result.404.description': '抱歉,页面不见了~',
|
||||
'exception.result.404.retry': '重试',
|
||||
'exception.result.404.back': '返回',
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<Breadcrumb :items="['menu.exception', 'menu.exception.500']" />
|
||||
<div class="content">
|
||||
<a-result
|
||||
class="result"
|
||||
status="500"
|
||||
:subtitle="$t('exception.result.500.description')"
|
||||
/>
|
||||
<a-button key="back" type="primary">
|
||||
{{ $t('exception.result.500.back') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup></script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: '500',
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container {
|
||||
padding: 0 20px 20px 20px;
|
||||
height: calc(100% - 40px);
|
||||
:deep(.content) {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
background-color: var(--color-bg-1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
'menu.exception.500': '500',
|
||||
'exception.result.500.description': 'Internal server error',
|
||||
'exception.result.500.back': 'Back',
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
'menu.exception.500': '500',
|
||||
'exception.result.500.description': '抱歉,服务器出了点问题~',
|
||||
'exception.result.500.back': '返回',
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>bill</div>
|
||||
</template>
|
||||
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
'menu.finance.bill': '账单',
|
||||
'menu.finance.money': '金钱',
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>money</div>
|
||||
</template>
|
||||
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<div class="banner">
|
||||
<div class="banner-inner">
|
||||
<a-carousel class="carousel" animation-name="fade">
|
||||
<a-carousel-item v-for="item in carouselItem" :key="item.slogan">
|
||||
<div :key="item.slogan" class="carousel-item">
|
||||
<div class="carousel-title">{{ item.slogan }}</div>
|
||||
<div class="carousel-sub-title">{{ item.subSlogan }}</div>
|
||||
<img class="carousel-image" :src="item.image" />
|
||||
</div>
|
||||
</a-carousel-item>
|
||||
</a-carousel>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import bannerImage from '@/assets/images/login-banner.png';
|
||||
|
||||
const { t } = useI18n();
|
||||
const carouselItem = computed(() => [
|
||||
{
|
||||
slogan: t('login.banner.slogan1'),
|
||||
subSlogan: t('login.banner.subSlogan1'),
|
||||
image: bannerImage,
|
||||
},
|
||||
{
|
||||
slogan: t('login.banner.slogan2'),
|
||||
subSlogan: t('login.banner.subSlogan2'),
|
||||
image: bannerImage,
|
||||
},
|
||||
{
|
||||
slogan: t('login.banner.slogan3'),
|
||||
subSlogan: t('login.banner.subSlogan3'),
|
||||
image: bannerImage,
|
||||
},
|
||||
]);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&-inner {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.carousel {
|
||||
height: 100%;
|
||||
|
||||
&-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&-title {
|
||||
color: var(--color-fill-1);
|
||||
font-weight: 500;
|
||||
font-size: 20px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
&-sub-title {
|
||||
margin-top: 8px;
|
||||
color: var(--color-text-3);
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
&-image {
|
||||
width: 320px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<div class="login-form-wrapper">
|
||||
<div class="login-form-title">{{ $t('login.form.title') }}</div>
|
||||
<div class="login-form-sub-title">{{ $t('login.form.slogan') }}</div>
|
||||
<div class="login-form-error-msg">{{ errorMessage }}</div>
|
||||
<a-form
|
||||
ref="loginForm"
|
||||
:model="userInfo"
|
||||
class="login-form"
|
||||
layout="vertical"
|
||||
@submit="handleSubmit"
|
||||
>
|
||||
<a-form-item
|
||||
field="username"
|
||||
:rules="[{ required: true, message: $t('login.form.userName.errMsg') }]"
|
||||
:validate-trigger="['change', 'blur']"
|
||||
hide-label
|
||||
>
|
||||
<a-input
|
||||
v-model="userInfo.username"
|
||||
:placeholder="$t('login.form.userName.placeholder')"
|
||||
>
|
||||
<template #prefix>
|
||||
<icon-user />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="password"
|
||||
:rules="[{ required: true, message: $t('login.form.password.errMsg') }]"
|
||||
:validate-trigger="['change', 'blur']"
|
||||
hide-label
|
||||
>
|
||||
<a-input-password
|
||||
v-model="userInfo.password"
|
||||
:placeholder="$t('login.form.password.placeholder')"
|
||||
allow-clear
|
||||
>
|
||||
<template #prefix>
|
||||
<icon-lock />
|
||||
</template>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
<a-space :size="16" direction="vertical">
|
||||
<div class="login-form-password-actions">
|
||||
<a-checkbox
|
||||
checked="rememberPassword"
|
||||
:model-value="loginConfig.rememberPassword"
|
||||
@change="setRememberPassword as any"
|
||||
>
|
||||
{{ $t('login.form.rememberPassword') }}
|
||||
</a-checkbox>
|
||||
<a-link>{{ $t('login.form.forgetPassword') }}</a-link>
|
||||
</div>
|
||||
<a-button type="primary" html-type="submit" long :loading="loading">
|
||||
{{ $t('login.form.login') }}
|
||||
</a-button>
|
||||
<!-- <a-button type="text" long class="login-form-register-btn">
|
||||
{{ $t('login.form.register') }}
|
||||
</a-button> -->
|
||||
</a-space>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { ValidatedError } from '@arco-design/web-vue/es/form/interface';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { useUserStore } from '@/store';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import type { LoginData } from '@/api/user';
|
||||
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const errorMessage = ref('');
|
||||
const { loading, setLoading } = useLoading();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const loginConfig = useStorage('login-config', {
|
||||
rememberPassword: true,
|
||||
username: 'admin', // 演示默认值
|
||||
password: 'admin', // demo default value
|
||||
});
|
||||
const userInfo = reactive({
|
||||
username: loginConfig.value.username,
|
||||
password: loginConfig.value.password,
|
||||
});
|
||||
|
||||
const handleSubmit = async ({
|
||||
errors,
|
||||
values,
|
||||
}: {
|
||||
errors: Record<string, ValidatedError> | undefined;
|
||||
values: Record<string, any>;
|
||||
}) => {
|
||||
if (loading.value) return;
|
||||
if (!errors) {
|
||||
setLoading(true);
|
||||
try {
|
||||
await userStore.login(values as LoginData);
|
||||
const { redirect, ...othersQuery } = router.currentRoute.value.query;
|
||||
router.push({
|
||||
name: (redirect as string) || 'business',
|
||||
query: {
|
||||
...othersQuery,
|
||||
},
|
||||
});
|
||||
Message.success(t('login.form.login.success'));
|
||||
const { rememberPassword } = loginConfig.value;
|
||||
const { username, password } = values;
|
||||
// 实际生产环境需要进行加密存储。
|
||||
// The actual production environment requires encrypted storage.
|
||||
loginConfig.value.username = rememberPassword ? username : '';
|
||||
loginConfig.value.password = rememberPassword ? password : '';
|
||||
} catch (err) {
|
||||
errorMessage.value = (err as Error).message;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
const setRememberPassword = (value: boolean) => {
|
||||
loginConfig.value.rememberPassword = value;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.login-form {
|
||||
&-wrapper {
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
&-title {
|
||||
color: var(--color-text-1);
|
||||
font-weight: 500;
|
||||
font-size: 24px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-sub-title {
|
||||
color: var(--color-text-3);
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-error-msg {
|
||||
height: 32px;
|
||||
color: rgb(var(--red-6));
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
&-password-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&-register-btn {
|
||||
color: var(--color-text-3) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<!-- <div class="logo">
|
||||
<img
|
||||
alt="logo"
|
||||
src="//p3-armor.byteimg.com/tos-cn-i-49unhts6dw/dfdba5317c0c20ce20e64fac803d52bc.svg~tplv-49unhts6dw-image.image"
|
||||
/>
|
||||
<div class="logo-text">Arco Design Pro</div>
|
||||
</div> -->
|
||||
<!-- <LoginBanner /> -->
|
||||
<div class="content">
|
||||
<div class="content-inner">
|
||||
<LoginForm />
|
||||
</div>
|
||||
<div class="footer">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Footer from '@/components/footer/index.vue';
|
||||
// import LoginBanner from './components/banner.vue';
|
||||
import LoginForm from './components/login-form.vue';
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.container {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
.banner {
|
||||
width: 550px;
|
||||
background: linear-gradient(163.85deg, #1d2129 0%, #00308f 100%);
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.content-inner{
|
||||
background-color: #fff;
|
||||
padding: 60px 40px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
position: fixed;
|
||||
top: 24px;
|
||||
left: 22px;
|
||||
z-index: 1;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
&-text {
|
||||
margin-right: 4px;
|
||||
margin-left: 4px;
|
||||
color: var(--color-fill-1);
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less" scoped>
|
||||
// responsive
|
||||
@media (max-width: @screen-lg) {
|
||||
.container {
|
||||
.banner {
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,21 @@
|
||||
export default {
|
||||
'login.form.title': 'Login to Arco Design Pro',
|
||||
'login.form.userName.errMsg': 'Username cannot be empty',
|
||||
'login.form.password.errMsg': 'Password cannot be empty',
|
||||
'login.form.login.errMsg': 'Login error, refresh and try again',
|
||||
'login.form.login.success': 'welcome to use',
|
||||
'login.form.userName.placeholder': 'Username: admin',
|
||||
'login.form.password.placeholder': 'Password: admin',
|
||||
'login.form.rememberPassword': 'Remember password',
|
||||
'login.form.forgetPassword': 'Forgot password',
|
||||
'login.form.login': 'login',
|
||||
'login.form.register': 'register account',
|
||||
'login.banner.slogan1': 'Out-of-the-box high-quality template',
|
||||
'login.banner.subSlogan1':
|
||||
'Rich page templates, covering most typical business scenarios',
|
||||
'login.banner.slogan2': 'Built-in solutions to common problems',
|
||||
'login.banner.subSlogan2':
|
||||
'Internationalization, routing configuration, state management everything',
|
||||
'login.banner.slogan3': 'Access visualization enhancement tool AUX',
|
||||
'login.banner.subSlogan3': 'Realize flexible block development',
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
export default {
|
||||
'login.form.title': 'SaaS超级管理后台',
|
||||
'login.form.slogan': '管理您的租户和系统资源',
|
||||
'login.form.userName.errMsg': '用户名不能为空',
|
||||
'login.form.password.errMsg': '密码不能为空',
|
||||
'login.form.login.errMsg': '登录出错,轻刷新重试',
|
||||
'login.form.login.success': '欢迎使用',
|
||||
'login.form.userName.placeholder': '用户名:admin',
|
||||
'login.form.password.placeholder': '密码:admin',
|
||||
'login.form.rememberPassword': '记住密码',
|
||||
'login.form.forgetPassword': '忘记密码',
|
||||
'login.form.login': '登录',
|
||||
'login.form.register': '注册账号',
|
||||
'login.banner.slogan1': '开箱即用的高质量模板',
|
||||
'login.banner.subSlogan1': '丰富的的页面模板,覆盖大多数典型业务场景',
|
||||
'login.banner.slogan2': '内置了常见问题的解决方案',
|
||||
'login.banner.subSlogan2': '国际化,路由配置,状态管理应有尽有',
|
||||
'login.banner.slogan3': '接入可视化增强工具AUX',
|
||||
'login.banner.subSlogan3': '实现灵活的区块式开发',
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<div class="content">
|
||||
<a-result class="result" status="404" :subtitle="'not found'"> </a-result>
|
||||
<div class="operation-row">
|
||||
<a-button key="back" type="primary" @click="back"> back </a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const router = useRouter();
|
||||
const back = () => {
|
||||
// warning: Go to the node that has the permission
|
||||
router.push({ name: 'Workplace' });
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.content {
|
||||
// padding-top: 100px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-left: -95px;
|
||||
margin-top: -121px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>水电</div>
|
||||
</template>
|
||||
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
'menu.property.hydropower': '水电',
|
||||
'menu.property.reservation': '预约',
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>预约</div>
|
||||
</template>
|
||||
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
'menu.setting.user': '用户设置',
|
||||
'menu.setting.user-list': '用户列表',
|
||||
'menu.setting.role': '角色权限',
|
||||
'menu.setting.system': '系统配置',
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>帅哥kilo</div>
|
||||
</template>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>帅哥kilo</div>
|
||||
</template>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>帅哥kilo</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user