Browse Source

更新

master
j1ack 2 years ago
parent
commit
b8285b4b59
  1. 76
      src/App.vue
  2. 14
      src/api/form.js
  3. BIN
      src/assets/images/Group1171275385.png
  4. BIN
      src/assets/images/Group1171275386.png
  5. BIN
      src/assets/images/Group1171275387.png
  6. BIN
      src/assets/images/b1.png
  7. BIN
      src/assets/images/b2.png
  8. BIN
      src/assets/images/b3.png
  9. BIN
      src/assets/images/login-background.jpg
  10. BIN
      src/assets/images/logo.png
  11. BIN
      src/assets/images/profile.jpg
  12. BIN
      src/assets/images/screen.png
  13. BIN
      src/assets/images/search.png
  14. BIN
      src/assets/logo/logo.png
  15. 1
      src/assets/styles/element-ui.scss
  16. 2
      src/assets/styles/element-variables.scss
  17. 2
      src/assets/styles/ruoyi.scss
  18. 7
      src/assets/styles/sidebar.scss
  19. 10
      src/assets/styles/variables.scss
  20. 17
      src/components/Breadcrumb/index.vue
  21. 1
      src/components/Hamburger/index.vue
  22. 30
      src/components/HeaderSearch/index.vue
  23. 32
      src/components/Screenfull/index.vue
  24. 59
      src/layout/components/Navbar.vue
  25. 2
      src/layout/components/Settings/index.vue
  26. 14
      src/layout/components/Sidebar/Logo.vue
  27. 621
      src/layout/components/TagsView/index.vue
  28. 2
      src/router/index.js
  29. 5
      src/store/modules/user.js
  30. 44
      src/utils/ruoyi.js
  31. 101
      src/views/dashboard/PanelGroup.vue
  32. 243
      src/views/dashboard/PieChartCreate.vue
  33. 98
      src/views/index_v1.vue
  34. 105
      src/views/login.vue
  35. 23
      src/views/otc/OtcStoreBondConfig/index.vue
  36. 33
      src/views/otc/otcAppealOrder/index.vue
  37. 51
      src/views/otc/otcStore/index.vue
  38. 4
      src/views/otc/otcStore/pkCouponScopeRangeStoreList.vue
  39. 2
      src/views/otc/otcStoreDaiFuOrder/index.vue
  40. 37
      src/views/otc/otcStorePledge/index.vue
  41. 2
      src/views/otc/otcStoreRechargeOrder/index.vue
  42. 2
      src/views/register.vue
  43. 12
      src/views/system/role/index.vue
  44. 1
      vue.config.js

76
src/App.vue

@ -26,3 +26,79 @@ export default {
display: none;
}
</style>
<style>
.el-submenu.is-opened > .el-submenu__title .el-submenu__icon-arrow {
color: #fff;
}
.el-menu-item{
/* padding-left: 50px !important; */
position: relative;
}
.el-menu-item.is-active{
color: #fff !important;
background-color: #FFFFFF1A !important;
}
.el-menu-item.is-active::before{
content: '';
position: absolute;
height: 100%;
width: 8px;
position: absolute;
right: 0;
top: 0;
background: #09BA7A;
}
/* .el-menu-item .svg-icon{
display: none;
} */
.flex{
display: flex;
align-items: center;
}
.flex-between{
display: flex;
align-items: center;
justify-content: space-between;
}
.m-b-10{
margin-bottom: 10px;
}
.m-b-16{
margin-bottom: 16px;
}
.m-b-28{
margin-bottom: 28px;
}
.center{
display: table;
margin: 0 auto;
}
.search_con{
background: rgba(255, 255, 255, 1);
border-radius: 8px;
padding: 16px;
}
.bg-white{
background: rgba(255, 255, 255, 1);
}
.bg{
padding: 16px;
border-radius: 8px;
}
.el-table{
border: 1px solid rgba(223, 230, 236, 1)
}
.el-table th.el-table__cell.is-leaf, .el-table td.el-table__cell {
border-bottom: 1px solid #dfe6ec;
border-right: 1px solid #dfe6ec;
}
.el-table th.el-table__cell > .cell {
color: rgba(154, 169, 188, 1);
}
.el-table .el-table__header-wrapper th, .el-table .el-table__fixed-header-wrapper th {
background-color: #F3F6F8;
}
</style>

14
src/api/form.js

@ -276,3 +276,17 @@ export const paymentDaiFuRecord = {
})
},
}
/**
* 首页数据
*/
export const payGetMerchantTotalInfo = {
// 首页数据
getMerchantTotalInfo: (query) => {
return request({
url: '/order/RechargeRecord/getMerchantTotalInfo',
method: 'get',
params: query,
})
},
}

BIN
src/assets/images/Group1171275385.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
src/assets/images/Group1171275386.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
src/assets/images/Group1171275387.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
src/assets/images/b1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

BIN
src/assets/images/b2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

BIN
src/assets/images/b3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

BIN
src/assets/images/login-background.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 509 KiB

After

Width:  |  Height:  |  Size: 5.9 MiB

BIN
src/assets/images/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
src/assets/images/profile.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
src/assets/images/screen.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/assets/images/search.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
src/assets/logo/logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

1
src/assets/styles/element-ui.scss

@ -3,6 +3,7 @@
.el-breadcrumb__inner,
.el-breadcrumb__inner a {
font-weight: 400 !important;
color: #B8C4D2;
}
.el-upload {

2
src/assets/styles/element-variables.scss

@ -4,7 +4,7 @@
**/
/* theme color */
$--color-primary: #1890ff;
$--color-primary: #08BA7A;
$--color-success: #13ce66;
$--color-warning: #ffba00;
$--color-danger: #ff4949;

2
src/assets/styles/ruoyi.scss

@ -145,7 +145,7 @@
}
.el-table .el-dropdown, .el-icon-arrow-down {
font-size: 12px;
font-size: 14px;
}
.el-tree-node__content > .el-checkbox {

7
src/assets/styles/sidebar.scss

@ -1,10 +1,11 @@
#app {
.main-container {
height: 100%;
// height: 100%;
transition: margin-left .28s;
margin-left: $base-sidebar-width;
position: relative;
background: #F3F6F8;
}
.sidebarHide {
@ -96,10 +97,10 @@
background-color: rgba(0, 0, 0, 0.06) !important;
}
}
& .theme-dark .nest-menu .el-submenu>.el-submenu__title,
& .theme-dark .el-submenu .el-menu-item {
background-color: $base-sub-menu-background !important;
background-color: $base-sub-menu-background;
&:hover {
background-color: $base-sub-menu-hover !important;

10
src/assets/styles/variables.scss

@ -9,17 +9,17 @@ $yellow:#FEC171;
$panGreen: #30B08F;
// 默认菜单主题风格
$base-menu-color:#bfcbd9;
$base-menu-color:#B8C4D2;
$base-menu-color-active:#f4f4f5;
$base-menu-background:#304156;
$base-menu-background:#2C3130;
$base-logo-title-color: #ffffff;
$base-menu-light-color:rgba(0,0,0,.70);
$base-menu-light-background:#ffffff;
$base-logo-light-title-color: #001529;
$base-sub-menu-background:#1f2d3d;
$base-sub-menu-hover:#001528;
$base-sub-menu-background:#2C3130;
$base-sub-menu-hover:#414544;
// 自定义暗色菜单风格
/**
@ -36,7 +36,7 @@ $base-sub-menu-background:#000c17;
$base-sub-menu-hover:#001528;
*/
$base-sidebar-width: 200px;
$base-sidebar-width: 202px;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass

17
src/components/Breadcrumb/index.vue

@ -1,8 +1,9 @@
<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>
<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"
:class="index == levelList.length - 1 ? 'text-white' : ''">{{ item.meta.title }}</span>
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
</el-breadcrumb-item>
</transition-group>
@ -35,7 +36,7 @@ export default {
const first = matched[0]
if (!this.isDashboard(first)) {
matched = [{ path: '/index', meta: { title: '首页' }}].concat(matched)
matched = [{ path: '/index', meta: { title: '首页' } }].concat(matched)
}
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
@ -60,14 +61,18 @@ export default {
</script>
<style lang="scss" scoped>
.text-white {
color: #fff !important;
}
.app-breadcrumb.el-breadcrumb {
display: inline-block;
font-size: 14px;
font-size: 16px;
line-height: 50px;
margin-left: 8px;
font-weight: 500;
.no-redirect {
color: #97a8be;
color: #B8C4D2;
cursor: text;
}
}

1
src/components/Hamburger/index.vue

@ -36,6 +36,7 @@ export default {
vertical-align: middle;
width: 20px;
height: 20px;
fill: #999999;
}
.hamburger.is-active {

30
src/components/HeaderSearch/index.vue

@ -1,18 +1,12 @@
<template>
<div :class="{'show':show}" class="header-search">
<svg-icon class-name="search-icon" icon-class="search" @click.stop="click" />
<el-select
ref="headerSearchSelect"
v-model="search"
:remote-method="querySearch"
filterable
default-first-option
remote
placeholder="Search"
class="header-search-select"
@change="change"
>
<el-option v-for="option in options" :key="option.item.path" :value="option.item" :label="option.item.title.join(' > ')" />
<div :class="{ 'show': show }" class="header-search">
<!-- <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" /> -->
<!-- <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" /> -->
<img src="../../assets/images/search.png" class="search" alt="" srcset="" @click.stop="click">
<el-select ref="headerSearchSelect" v-model="search" :remote-method="querySearch" filterable default-first-option
remote placeholder="Search" class="header-search-select" @change="change">
<el-option v-for="option in options" :key="option.item.path" :value="option.item"
:label="option.item.title.join(' > ')" />
</el-select>
</div>
</template>
@ -71,7 +65,7 @@ export default {
},
change(val) {
const path = val.path;
if(this.ishttp(val.path)) {
if (this.ishttp(val.path)) {
// http(s)://
const pindex = path.indexOf("http");
window.open(path.substr(pindex, path.length), "_blank");
@ -149,6 +143,12 @@ export default {
</script>
<style lang="scss" scoped>
.search {
width: 26px;
height: 26px;
vertical-align: middle;
}
.header-search {
font-size: 0 !important;

32
src/components/Screenfull/index.vue

@ -1,6 +1,7 @@
<template>
<div>
<svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" @click="click" />
<div class="screen-con">
<!-- <svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" @click="click" /> -->
<img src="../../assets/images/screen.png" alt="" srcset="" class="screen" @click="click">
</div>
</template>
@ -46,12 +47,33 @@ export default {
</script>
<style scoped>
.screen {
width: 26px;
height: 26px;
vertical-align: middle;
margin-right: 20px;
}
.screen-con {
position: relative;
}
.screen-con::before {
content: '';
width: 1px;
height: 22px;
background: #6D7170;
position: absolute;
right: 10px;
top: 15%;
}
.screenfull-svg {
display: inline-block;
cursor: pointer;
fill: #5a5e66;;
fill: #5a5e66;
;
width: 20px;
height: 20px;
vertical-align: 10px;
}
</style>
}</style>

59
src/layout/components/Navbar.vue

@ -8,35 +8,22 @@
<div class="right-menu">
<template v-if="device!=='mobile'">
<search id="header-search" class="right-menu-item" />
<el-tooltip content="源码地址" effect="dark" placement="bottom">
<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
</el-tooltip>
<el-tooltip content="文档地址" effect="dark" placement="bottom">
<ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
</el-tooltip>
<screenfull id="screenfull" class="right-menu-item hover-effect" />
<el-tooltip content="布局大小" effect="dark" placement="bottom">
<size-select id="size-select" class="right-menu-item hover-effect" />
</el-tooltip>
</template>
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper">
<div class="avatar-wrapper flex">
<img :src="avatar" class="user-avatar">
<span class="nickName">{{ user.nickName }}</span>
<i class="el-icon-caret-bottom" />
</div>
<el-dropdown-menu slot="dropdown">
<router-link to="/user/profile">
<el-dropdown-item>个人中心</el-dropdown-item>
</router-link>
<el-dropdown-item @click.native="setting = true">
<!-- <el-dropdown-item @click.native="setting = true">
<span>布局设置</span>
</el-dropdown-item>
</el-dropdown-item> -->
<el-dropdown-item divided @click.native="logout">
<span>退出登录</span>
</el-dropdown-item>
@ -56,6 +43,7 @@ import SizeSelect from '@/components/SizeSelect'
import Search from '@/components/HeaderSearch'
import RuoYiGit from '@/components/RuoYi/Git'
import RuoYiDoc from '@/components/RuoYi/Doc'
import { getUserProfile } from "@/api/system/user";
export default {
components: {
@ -91,7 +79,20 @@ export default {
}
}
},
data() {
return {
user: {},
};
},
created() {
this.getUser();
},
methods: {
getUser() {
getUserProfile().then(response => {
this.user = response.data;
});
},
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
},
@ -111,13 +112,17 @@ export default {
</script>
<style lang="scss" scoped>
.nickName{
color: #fff;
margin-left: 6px;
}
.navbar {
height: 50px;
height: 70px;
overflow: hidden;
position: relative;
background: #fff;
background: #2C3130;
box-shadow: 0 1px 4px rgba(0,21,41,.08);
padding: 10px 0;
.hamburger-container {
line-height: 46px;
height: 100%;
@ -147,20 +152,21 @@ export default {
.right-menu {
float: right;
height: 100%;
line-height: 50px;
// height: 100%;
line-height: 100%;
display: flex;
align-items: center;
&:focus {
outline: none;
}
.right-menu-item {
display: inline-block;
padding: 0 8px;
padding: 0 14px;
height: 100%;
font-size: 18px;
color: #5a5e66;
vertical-align: text-bottom;
// vertical-align: text-bottom;
&.hover-effect {
cursor: pointer;
@ -190,8 +196,9 @@ export default {
cursor: pointer;
position: absolute;
right: -20px;
top: 25px;
top: 15px;
font-size: 12px;
color: #fff;
}
}
}

2
src/layout/components/Settings/index.vue

@ -226,7 +226,7 @@ export default {
height: 100%;
padding-top: 15px;
padding-left: 24px;
color: #1890ff;
color: #08BA7A;
font-weight: 700;
font-size: 14px;
}

14
src/layout/components/Sidebar/Logo.vue

@ -55,8 +55,8 @@ export default {
.sidebar-logo-container {
position: relative;
width: 100%;
height: 50px;
line-height: 50px;
height: 90px;
line-height: 70px;
background: #2b2f3a;
text-align: center;
overflow: hidden;
@ -66,19 +66,19 @@ export default {
width: 100%;
& .sidebar-logo {
width: 32px;
height: 32px;
width: 28px;
height: 28px;
vertical-align: middle;
margin-right: 12px;
margin-right: 16px;
}
& .sidebar-title {
display: inline-block;
margin: 0;
color: #fff;
font-weight: 600;
font-weight: 500;
line-height: 50px;
font-size: 14px;
font-size: 24px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle;
}

621
src/layout/components/TagsView/index.vue

@ -1,31 +1,32 @@
<template>
<div id="tags-view-container" class="tags-view-container">
<scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">
<router-link
v-for="tag in visitedViews"
ref="tag"
:key="tag.path"
:class="isActive(tag)?'active':''"
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
tag="span"
class="tags-view-item"
:style="activeStyle(tag)"
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
@contextmenu.prevent.native="openMenu(tag,$event)"
>
{{ tag.title }}
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
</router-link>
</scroll-pane>
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
<li @click="refreshSelectedTag(selectedTag)"><i class="el-icon-refresh-right"></i> 刷新页面</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><i class="el-icon-close"></i> 关闭当前</li>
<li @click="closeOthersTags"><i class="el-icon-circle-close"></i> 关闭其他</li>
<li v-if="!isFirstView()" @click="closeLeftTags"><i class="el-icon-back"></i> 关闭左侧</li>
<li v-if="!isLastView()" @click="closeRightTags"><i class="el-icon-right"></i> 关闭右侧</li>
<li @click="closeAllTags(selectedTag)"><i class="el-icon-circle-close"></i> 全部关闭</li>
</ul>
</div>
<!-- id="tags-view-container" class="tags-view-container" -->
<div>
<!-- <scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll">
<router-link
v-for="tag in visitedViews"
ref="tag"
:key="tag.path"
:class="isActive(tag)?'active':''"
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
tag="span"
class="tags-view-item"
:style="activeStyle(tag)"
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
@contextmenu.prevent.native="openMenu(tag,$event)"
>
{{ tag.title }}
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
</router-link>
</scroll-pane>
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
<li @click="refreshSelectedTag(selectedTag)"><i class="el-icon-refresh-right"></i> 刷新页面</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><i class="el-icon-close"></i> 关闭当前</li>
<li @click="closeOthersTags"><i class="el-icon-circle-close"></i> 关闭其他</li>
<li v-if="!isFirstView()" @click="closeLeftTags"><i class="el-icon-back"></i> 关闭左侧</li>
<li v-if="!isLastView()" @click="closeRightTags"><i class="el-icon-right"></i> 关闭右侧</li>
<li @click="closeAllTags(selectedTag)"><i class="el-icon-circle-close"></i> 全部关闭</li>
</ul> -->
</div>
</template>
<script>
@ -33,300 +34,302 @@ import ScrollPane from './ScrollPane'
import path from 'path'
export default {
components: { ScrollPane },
data() {
return {
visible: false,
top: 0,
left: 0,
selectedTag: {},
affixTags: []
}
},
computed: {
visitedViews() {
return this.$store.state.tagsView.visitedViews
},
routes() {
return this.$store.state.permission.routes
},
theme() {
return this.$store.state.settings.theme;
}
},
watch: {
$route() {
this.addTags()
this.moveToCurrentTag()
},
visible(value) {
if (value) {
document.body.addEventListener('click', this.closeMenu)
} else {
document.body.removeEventListener('click', this.closeMenu)
}
}
},
mounted() {
this.initTags()
this.addTags()
},
methods: {
isActive(route) {
return route.path === this.$route.path
},
activeStyle(tag) {
if (!this.isActive(tag)) return {};
return {
"background-color": this.theme,
"border-color": this.theme
};
},
isAffix(tag) {
return tag.meta && tag.meta.affix
},
isFirstView() {
try {
return this.selectedTag.fullPath === '/index' || this.selectedTag.fullPath === this.visitedViews[1].fullPath
} catch (err) {
return false
}
},
isLastView() {
try {
return this.selectedTag.fullPath === this.visitedViews[this.visitedViews.length - 1].fullPath
} catch (err) {
return false
}
},
filterAffixTags(routes, basePath = '/') {
let tags = []
routes.forEach(route => {
if (route.meta && route.meta.affix) {
const tagPath = path.resolve(basePath, route.path)
tags.push({
fullPath: tagPath,
path: tagPath,
name: route.name,
meta: { ...route.meta }
})
}
if (route.children) {
const tempTags = this.filterAffixTags(route.children, route.path)
if (tempTags.length >= 1) {
tags = [...tags, ...tempTags]
}
}
})
return tags
},
initTags() {
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
for (const tag of affixTags) {
// Must have tag name
if (tag.name) {
this.$store.dispatch('tagsView/addVisitedView', tag)
}
}
},
addTags() {
const { name } = this.$route
if (name) {
this.$store.dispatch('tagsView/addView', this.$route)
if (this.$route.meta.link) {
this.$store.dispatch('tagsView/addIframeView', this.$route)
}
}
return false
},
moveToCurrentTag() {
const tags = this.$refs.tag
this.$nextTick(() => {
for (const tag of tags) {
if (tag.to.path === this.$route.path) {
this.$refs.scrollPane.moveToTarget(tag)
// when query is different then update
if (tag.to.fullPath !== this.$route.fullPath) {
this.$store.dispatch('tagsView/updateVisitedView', this.$route)
}
break
}
}
})
},
refreshSelectedTag(view) {
this.$tab.refreshPage(view);
if (this.$route.meta.link) {
this.$store.dispatch('tagsView/delIframeView', this.$route)
}
},
closeSelectedTag(view) {
this.$tab.closePage(view).then(({ visitedViews }) => {
if (this.isActive(view)) {
this.toLastView(visitedViews, view)
}
})
},
closeRightTags() {
this.$tab.closeRightPage(this.selectedTag).then(visitedViews => {
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
this.toLastView(visitedViews)
}
})
},
closeLeftTags() {
this.$tab.closeLeftPage(this.selectedTag).then(visitedViews => {
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
this.toLastView(visitedViews)
}
})
},
closeOthersTags() {
this.$router.push(this.selectedTag.fullPath).catch(()=>{});
this.$tab.closeOtherPage(this.selectedTag).then(() => {
this.moveToCurrentTag()
})
},
closeAllTags(view) {
this.$tab.closeAllPage().then(({ visitedViews }) => {
if (this.affixTags.some(tag => tag.path === this.$route.path)) {
return
}
this.toLastView(visitedViews, view)
})
},
toLastView(visitedViews, view) {
const latestView = visitedViews.slice(-1)[0]
if (latestView) {
this.$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
this.$router.replace({ path: '/redirect' + view.fullPath })
} else {
this.$router.push('/')
}
}
},
openMenu(tag, e) {
const menuMinWidth = 105
const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
const offsetWidth = this.$el.offsetWidth // container width
const maxLeft = offsetWidth - menuMinWidth // left boundary
const left = e.clientX - offsetLeft + 15 // 15: margin right
components: { ScrollPane },
data() {
return {
visible: false,
top: 0,
left: 0,
selectedTag: {},
affixTags: []
}
},
computed: {
visitedViews() {
return this.$store.state.tagsView.visitedViews
},
routes() {
return this.$store.state.permission.routes
},
theme() {
return this.$store.state.settings.theme;
}
},
watch: {
$route() {
this.addTags()
this.moveToCurrentTag()
},
visible(value) {
if (value) {
document.body.addEventListener('click', this.closeMenu)
} else {
document.body.removeEventListener('click', this.closeMenu)
}
}
},
mounted() {
this.initTags()
this.addTags()
},
methods: {
isActive(route) {
return route.path === this.$route.path
},
activeStyle(tag) {
if (!this.isActive(tag)) return {};
return {
"background-color": this.theme,
"border-color": this.theme
};
},
isAffix(tag) {
return tag.meta && tag.meta.affix
},
isFirstView() {
try {
return this.selectedTag.fullPath === '/index' || this.selectedTag.fullPath === this.visitedViews[1].fullPath
} catch (err) {
return false
}
},
isLastView() {
try {
return this.selectedTag.fullPath === this.visitedViews[this.visitedViews.length - 1].fullPath
} catch (err) {
return false
}
},
filterAffixTags(routes, basePath = '/') {
let tags = []
routes.forEach(route => {
if (route.meta && route.meta.affix) {
const tagPath = path.resolve(basePath, route.path)
tags.push({
fullPath: tagPath,
path: tagPath,
name: route.name,
meta: { ...route.meta }
})
}
if (route.children) {
const tempTags = this.filterAffixTags(route.children, route.path)
if (tempTags.length >= 1) {
tags = [...tags, ...tempTags]
}
}
})
return tags
},
initTags() {
const affixTags = this.affixTags = this.filterAffixTags(this.routes)
for (const tag of affixTags) {
// Must have tag name
if (tag.name) {
this.$store.dispatch('tagsView/addVisitedView', tag)
}
}
},
addTags() {
const { name } = this.$route
if (name) {
this.$store.dispatch('tagsView/addView', this.$route)
if (this.$route.meta.link) {
this.$store.dispatch('tagsView/addIframeView', this.$route)
}
}
return false
},
moveToCurrentTag() {
const tags = this.$refs.tag
if (tags) {
this.$nextTick(() => {
for (const tag of tags) {
if (tag.to.path === this.$route.path) {
this.$refs.scrollPane.moveToTarget(tag)
// when query is different then update
if (tag.to.fullPath !== this.$route.fullPath) {
this.$store.dispatch('tagsView/updateVisitedView', this.$route)
}
break
}
}
})
}
},
refreshSelectedTag(view) {
this.$tab.refreshPage(view);
if (this.$route.meta.link) {
this.$store.dispatch('tagsView/delIframeView', this.$route)
}
},
closeSelectedTag(view) {
this.$tab.closePage(view).then(({ visitedViews }) => {
if (this.isActive(view)) {
this.toLastView(visitedViews, view)
}
})
},
closeRightTags() {
this.$tab.closeRightPage(this.selectedTag).then(visitedViews => {
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
this.toLastView(visitedViews)
}
})
},
closeLeftTags() {
this.$tab.closeLeftPage(this.selectedTag).then(visitedViews => {
if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) {
this.toLastView(visitedViews)
}
})
},
closeOthersTags() {
this.$router.push(this.selectedTag).catch(()=>{});
this.$tab.closeOtherPage(this.selectedTag).then(() => {
this.moveToCurrentTag()
})
},
closeAllTags(view) {
this.$tab.closeAllPage().then(({ visitedViews }) => {
if (this.affixTags.some(tag => tag.path === this.$route.path)) {
return
}
this.toLastView(visitedViews, view)
})
},
toLastView(visitedViews, view) {
const latestView = visitedViews.slice(-1)[0]
if (latestView) {
this.$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
this.$router.replace({ path: '/redirect' + view.fullPath })
} else {
this.$router.push('/')
}
}
},
openMenu(tag, e) {
const menuMinWidth = 105
const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
const offsetWidth = this.$el.offsetWidth // container width
const maxLeft = offsetWidth - menuMinWidth // left boundary
const left = e.clientX - offsetLeft + 15 // 15: margin right
if (left > maxLeft) {
this.left = maxLeft
} else {
this.left = left
}
if (left > maxLeft) {
this.left = maxLeft
} else {
this.left = left
}
this.top = e.clientY
this.visible = true
this.selectedTag = tag
},
closeMenu() {
this.visible = false
},
handleScroll() {
this.closeMenu()
}
}
this.top = e.clientY
this.visible = true
this.selectedTag = tag
},
closeMenu() {
this.visible = false
},
handleScroll() {
this.closeMenu()
}
}
}
</script>
<style lang="scss" scoped>
.tags-view-container {
height: 34px;
width: 100%;
background: #fff;
border-bottom: 1px solid #d8dce5;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
.tags-view-wrapper {
.tags-view-item {
display: inline-block;
position: relative;
cursor: pointer;
height: 26px;
line-height: 26px;
border: 1px solid #d8dce5;
color: #495060;
background: #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: 2px;
}
}
}
}
.contextmenu {
margin: 0;
background: #fff;
z-index: 3000;
position: absolute;
list-style-type: none;
padding: 5px 0;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
color: #333;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
li {
margin: 0;
padding: 7px 16px;
cursor: pointer;
&:hover {
background: #eee;
}
}
}
height: 34px;
width: 100%;
background: #fff;
border-bottom: 1px solid #d8dce5;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
.tags-view-wrapper {
.tags-view-item {
display: inline-block;
position: relative;
cursor: pointer;
height: 26px;
line-height: 26px;
border: 1px solid #d8dce5;
color: #495060;
background: #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: 2px;
}
}
}
}
.contextmenu {
margin: 0;
background: #fff;
z-index: 3000;
position: absolute;
list-style-type: none;
padding: 5px 0;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
color: #333;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
li {
margin: 0;
padding: 7px 16px;
cursor: pointer;
&:hover {
background: #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: #b4bccc;
color: #fff;
}
}
}
.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: #b4bccc;
color: #fff;
}
}
}
}
</style>

2
src/router/index.js

@ -68,7 +68,7 @@ export const constantRoutes = [
children: [
{
path: 'index',
component: () => import('@/views/index'),
component: () => import('@/views/index_v1'),
name: 'Index',
meta: { title: '首页', icon: 'dashboard', affix: true }
}

5
src/store/modules/user.js

@ -51,7 +51,10 @@ const user = {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const user = res.user
const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
const avatar = (user.avatar == "" || user.avatar == null) ? require("../../assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
console.log(user.avatar,1111)
console.log(process.env.VUE_APP_BASE_API,1111)
if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', res.roles)
commit('SET_PERMISSIONS', res.permissions)

44
src/utils/ruoyi.js

@ -71,46 +71,14 @@ export function addDateRange(params, dateRange, propName) {
// 添加日期范围
export function addSESDateRange(params, dateRange, propName) {
var search = params
var search = params;
search.beginTime = null
search.endTime = null
search.updateBeginTime = null
search.updateEndTime = null
if (propName) {
if (dateRange[0]) {
if (dateRange[0][0] && dateRange[0][1]) {
search.beginTime = dateRange[0][0]
search.endTime = dateRange[0][1]
} else if (!dateRange[0][0]) {
search.beginTime = undefined
search.endTime = undefined
}
}
if (dateRange[1]) {
if (dateRange[1][0] && dateRange[1][1]) {
search.updateBeginTime = dateRange[1][0]
search.updateEndTime = dateRange[1][1]
} else if (!dateRange[1][0]) {
search.updateBeginTime = undefined
search.updateEndTime = undefined
}
}
search.endTime = null;
if (null != dateRange && '' != dateRange) {
search.beginTime = dateRange[0];
search.endTime = dateRange[1];
}
if (!propName) {
if (null != dateRange && '' != dateRange) {
// search.beginTime = dateRange[0];
// search.endTime = dateRange[1];
if (dateRange[0] && dateRange[1]) {
search.beginTime = dateRange[0]
search.endTime = dateRange[1]
} else if (!dateRange[0]) {
search.beginTime = undefined
search.endTime = undefined
}
}
}
return search
return search;
}
// 通用下载方法

101
src/views/dashboard/PanelGroup.vue

@ -1,54 +1,43 @@
<template>
<el-row :gutter="40" class="panel-group">
<el-row :gutter="40" class="panel-group flex-between">
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('newVisitis')">
<div class="card-panel-icon-wrapper icon-people">
<svg-icon icon-class="peoples" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
访客
<div class="item-title m-b-10">成交订单</div>
<div class="item-time">{{chartData.beginTime}}~{{chartData.endTime}}</div>
<div class="flex-between">
<div style="font-size:46px;font-weight:500;color: #333;">
<count-to :start-val="0" :end-val="chartData.paymentSuccessOrderNum" :duration="3600" class="card-panel-num" />
<span style="font-size:14px;color:rgba(125, 140, 161, 1)"></span>
</div>
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
<img src="../../assets/images/Group1171275385.png" alt="" srcset="" style="width:86px;height:86px">
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('messages')">
<div class="card-panel-icon-wrapper icon-message">
<svg-icon icon-class="message" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
消息
<div class="item-title m-b-10">成交金额</div>
<div class="item-time">{{chartData.beginTime}}~{{chartData.endTime}}</div>
<div class="flex-between">
<div style="font-size:46px;font-weight:500;color: #333;">
<count-to :start-val="0" :end-val="chartData.collectionSuccessPrice" :duration="3600" class="card-panel-num" />
<span style="font-size:14px;color:rgba(125, 140, 161, 1)">万元</span>
</div>
<count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
<img src="../../assets/images/Group1171275386.png" alt="" srcset="" style="width:86px;height:86px">
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('purchases')">
<div class="card-panel-icon-wrapper icon-money">
<svg-icon icon-class="money" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
金额
</div>
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
订单
<div class="item-title m-b-10">获取收益</div>
<div class="item-time">{{chartData.beginTime}}~{{chartData.endTime}}</div>
<div class="flex-between">
<div style="font-size:46px;font-weight:500;color: #333;">
<count-to :start-val="0" :end-val="chartData.collectionSuccessPrice" :duration="3600" class="card-panel-num" />
<span style="font-size:14px;color:rgba(125, 140, 161, 1)">万元</span>
</div>
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" />
<img src="../../assets/images/Group1171275387.png" alt="" srcset="" style="width:86px;height:86px">
</div>
</div>
</el-col>
@ -62,6 +51,12 @@ export default {
components: {
CountTo
},
props: {
chartData: {
type: Object,
required: true,
},
},
methods: {
handleSetLineChartData(type) {
this.$emit('handleSetLineChartData', type)
@ -71,23 +66,39 @@ export default {
</script>
<style lang="scss" scoped>
.item-title {
font-size: 18px;
font-weight: 500;
color: rgba(51, 51, 51, 1);
}
.item-time {
font-size: 16px;
font-weight: 400;
margin-bottom: 20px;
}
.panel-group {
margin-top: 18px;
.card-panel-col {
margin-bottom: 32px;
width: 32%;
padding: 0 !important;
}
.card-panel {
height: 108px;
padding: 28px 26px 34px 24px;
border-radius: 16px;
cursor: pointer;
font-size: 12px;
position: relative;
overflow: hidden;
color: #666;
background: #fff;
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
border-color: rgba(0, 0, 0, .05);
box-shadow: 0px 13px 28px 0px rgba(9, 186, 122, 0.04);
&:hover {
.card-panel-icon-wrapper {
@ -160,6 +171,22 @@ export default {
}
}
.card-panel-col:nth-child(1) .card-panel{
background-image: url('../../assets/images/b1.png');
background-repeat: no-repeat;
background-size: cover;
}
.card-panel-col:nth-child(2) .card-panel{
background-image: url('../../assets/images/b2.png');
background-repeat: no-repeat;
background-size: cover;
}
.card-panel-col:nth-child(3) .card-panel{
background-image: url('../../assets/images/b3.png');
background-repeat: no-repeat;
background-size: cover;
}
@media (max-width:550px) {
.card-panel-description {
display: none;

243
src/views/dashboard/PieChartCreate.vue

@ -0,0 +1,243 @@
<template>
<!-- <div :class="className" :style="{height:height,width:width}" /> -->
<el-row :gutter="40" class="panel-group flex-between">
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col" v-for="item, index in 4" :key="index">
<div class="card-panel">
<div class="flex-between m-b-28">
<span class="t1">
代收成功订单
</span>
<span class="t2">
总订单3698
</span>
</div>
<div class="pieCon1 center" id="myChart1" style="width:150px;height:150px;margin-bottom: 15px;"></div>
<div class="center">
<count-to :start-val="0" :end-val="3256" :duration="3600" class="card-panel-num" />
<span style="font-size:14px;color:rgba(125, 140, 161, 1)"></span>
</div>
</div>
</el-col>
</el-row>
</template>
<script>
import CountTo from 'vue-count-to'
import * as echarts from 'echarts';
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
components: {
CountTo
},
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null,
myChart: '',
opinionData2: [
{ value: 86, name: '代收成功订单', itemStyle: 'red' },
]
}
},
mounted() {
this.$nextTick(() => {
// this.initChart()
this.drawLine()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
drawLine() {
this.myChart = echarts.init(document.getElementById('myChart1'))
this.myChart.setOption({
title: {
text: '95.08%',
textStyle: {
color: '#333',
fontSize: 16
},
itemGap: 10, //
left: 'center',
top: 'center'
},
angleAxis: {
max: 100, //
clockwise: true, //
// 线
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitLine: {
show: false
}
},
radiusAxis: {
type: 'category',
// 线
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitLine: {
show: false
}
},
polar: {
center: ['50%', '50%'],
radius: ['60%', '100%'] //
},
series: [
{
type: 'bar',
silent:'true',
data: [{
name: '作文得分',
value: 68,
itemStyle: {
normal: {
color: {
//
colorStops: [
{
offset: 0,
color: "#46F2BC" // 0%
},
{
offset: 0.5,
color: "#2ED383" // 0%
},
{
offset: 0.7,
color: "#2ED383" // 0%
},
{
offset: 1,
color: "#46F2BC" // 100%
}
]
},
},
},
}],
coordinateSystem: 'polar',
roundCap: true,
barWidth: 15,
barGap: '-100%', //
z: 2,
},
{ //
type: 'bar',
silent:'true',
data: [{
value: 100,
itemStyle: {
color: '#ECF1F8',
shadowColor: '#EAFBF4',
shadowBlur: 10,
shadowOffsetY: 2
}
}],
coordinateSystem: 'polar',
roundCap: true,
barWidth: 225,
barGap: '-100%', //
z: 1
}]
})
},
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
bottom: '10',
data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts']
},
series: [
{
name: 'WEEKLY WRITE ARTICLES',
type: 'pie',
roseType: 'radius',
radius: [15, 95],
center: ['50%', '38%'],
data: [
{ value: 320, name: 'Industries' },
{ value: 240, name: 'Technology' },
{ value: 149, name: 'Forex' },
{ value: 100, name: 'Gold' },
{ value: 59, name: 'Forecasts' }
],
animationEasing: 'cubicInOut',
animationDuration: 2600
}
]
})
}
}
}
</script>
<style scoped>
.card-panel-num {
font-size: 32px;
}
.card-panel {
border-radius: 16px;
width: 100%;
background: rgba(255, 255, 255, 1);
padding: 20px 16px 26px 16px;
}
.t1 {
color: rgba(51, 51, 51, 1);
font-size: 14px;
font-weight: 500;
}
.t2 {
color: rgba(125, 140, 161, 1);
font-family: PingFang TC;
font-size: 13px;
font-weight: 400;
}
</style>

98
src/views/index_v1.vue

@ -1,31 +1,32 @@
<template>
<div class="dashboard-editor-container">
<div class="flex-between">
<div class="title">
OTC当日数据统计
</div>
<div class="flex">
<span class="title" style="margin-right:10px">时间</span>
<el-date-picker v-model="dateRange" size="small" style="width: 355px;height: 38px;margin-right:16px"
value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange" range-separator="-" start-placeholder="开始日期"
end-placeholder="结束日期" :unlink-panels="true" :default-time="['00:00:00', '23:59:59']"></el-date-picker>
<el-button type="primary" icon="" size="medium" @click="handleQuery">搜索</el-button>
</div>
</div>
<panel-group :chart-data="info" />
<div class="flex-between m-b-28">
<div class="title">
Payment当日数据统计
</div>
</div>
<pie-chart-create />
<panel-group @handleSetLineChartData="handleSetLineChartData" />
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
<line-chart :chart-data="lineChartData" />
</el-row>
<el-row :gutter="32">
<el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper">
<raddar-chart />
</div>
</el-col>
<el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper">
<pie-chart />
</div>
</el-col>
<el-col :xs="24" :sm="24" :lg="8">
<div class="chart-wrapper">
<bar-chart />
</div>
</el-col>
</el-row>
</div>
</template>
@ -34,7 +35,9 @@ import PanelGroup from './dashboard/PanelGroup'
import LineChart from './dashboard/LineChart'
import RaddarChart from './dashboard/RaddarChart'
import PieChart from './dashboard/PieChart'
import PieChartCreate from './dashboard/PieChartCreate'
import BarChart from './dashboard/BarChart'
import { payGetMerchantTotalInfo } from "@/api/form";
const lineChartData = {
newVisitis: {
@ -62,14 +65,48 @@ export default {
LineChart,
RaddarChart,
PieChart,
BarChart
BarChart,
PieChartCreate
},
data() {
return {
lineChartData: lineChartData.newVisitis
lineChartData: lineChartData.newVisitis,
dateRange: [],
queryParams: {},
info: {},
}
},
created() {
this.addDate()
this.getData()
},
methods: {
addDate() {
let nowDate = new Date();
let date = {
year: nowDate.getFullYear(),
month: nowDate.getMonth() + 1,
date: nowDate.getDate(),
}
if (date.date <= 9) {
this.dateRange[0] = date.year + '-' + 0 + date.month + '-' + 0 + date.date + ' ' + '00:00:00';
this.dateRange[1] = date.year + '-' + 0 + date.month + '-' + 0 + date.date + ' ' + '23:59:59';
} else {
this.dateRange[0] = date.year + '-' + 0 + date.month + '-' + date.date + ' ' + '00:00:00';
this.dateRange[1] = date.year + '-' + 0 + date.month + '-' + date.date + ' ' + '23:59:59';
}
},
getData() {
payGetMerchantTotalInfo.getMerchantTotalInfo(this.addSESDateRange(this.queryParams, this.dateRange)).then(response => {
this.info = response.data
this.info.beginTime=this.dateRange[0]
this.info.endTime=this.dateRange[1]
});
},
/** 搜索按钮操作 */
handleQuery() {
},
handleSetLineChartData(type) {
this.lineChartData = lineChartData[type]
}
@ -78,9 +115,14 @@ export default {
</script>
<style lang="scss" scoped>
.title {
font-size: 16px;
color: #333;
font-weight: 500;
}
.dashboard-editor-container {
padding: 32px;
background-color: rgb(240, 242, 245);
position: relative;
.chart-wrapper {

105
src/views/login.vue

@ -1,50 +1,29 @@
<template>
<div class="login">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
<h3 class="title">若依后台管理系统</h3>
<img src="../assets/images/logo.png" alt="" srcset="" class="logo">
<h3 class="title">bitcopay后台管理系统</h3>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
type="text"
auto-complete="off"
placeholder="账号"
>
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码"
@keyup.enter.native="handleLogin" show-password>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled">
<el-input
v-model="loginForm.code"
auto-complete="off"
placeholder="谷歌验证码"
@keyup.enter.native="handleLogin"
<el-input v-model="loginForm.code" auto-complete="off" placeholder="谷歌验证码" @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"/>-->
<!-- </div>-->
<!-- <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="medium"
type="primary"
style="width:100%;"
@click.native.prevent="handleLogin"
>
<el-button :loading="loading" size="medium" type="primary" style="width:100%;"
@click.native.prevent="handleLogin">
<span v-if="!loading"> </span>
<span v-else> 中...</span>
</el-button>
@ -53,10 +32,6 @@
</div>
</el-form-item>
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span>
</div>
</div>
</template>
@ -96,7 +71,7 @@ export default {
},
watch: {
$route: {
handler: function(route) {
handler: function (route) {
this.redirect = route.query && route.query.redirect;
},
immediate: true
@ -140,7 +115,7 @@ export default {
Cookies.remove('rememberMe');
}
this.$store.dispatch("Login", this.loginForm).then(() => {
this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
this.$router.push({ path: this.redirect || "/" }).catch(() => { });
}).catch(() => {
this.loading = false;
if (this.captchaEnabled) {
@ -153,7 +128,34 @@ export default {
}
};
</script>
<style scoped>
.login .el-input__inner {
border-radius: 10px;
border: 1px solid #525252;
background-color: #212121 !important;
color: #949494;
}
.login .el-input__inner::placeholder{
color:#949494;
}
.login .el-checkbox__input.is-checked .el-checkbox__inner {
background-color: #08BA7A;
border-color: #08BA7A;
}
.login .el-checkbox__input.is-checked + .el-checkbox__label{
color: #08BA7A;
}
.login .el-form-item__content{
line-height: 50px;
}
.login .el-button{
height: 50px;
background: #08BA7A !important;
border-color: #08BA7A;
border-radius: 10px;
}
</style>
<style rel="stylesheet/scss" lang="scss">
.login {
display: flex;
@ -163,43 +165,59 @@ export default {
background-image: url("../assets/images/login-background.jpg");
background-size: cover;
}
.title {
margin: 0px auto 30px auto;
text-align: center;
color: #707070;
color: #fff;
font-size: 28px;
font-weight: 500;
}
.login-form {
border-radius: 6px;
background: #ffffff;
width: 400px;
padding: 25px 25px 5px 25px;
.logo {
width: 78px;
height: 78px;
display: table;
margin: 0 auto;
margin-bottom: 34px;
}
.el-input {
height: 38px;
height: 50px;
input {
height: 38px;
height: 50px;
}
}
.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;
@ -212,6 +230,7 @@ export default {
font-size: 12px;
letter-spacing: 1px;
}
.login-code-img {
height: 38px;
}

23
src/views/otc/OtcStoreBondConfig/index.vue

@ -1,12 +1,13 @@
<template>
div<template>
<div class="app-container">
<div class="search_con m-b-28">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="质押币种" prop="pledgeCoin">
<el-input
v-model="queryParams.pledgeCoin"
placeholder="请输入质押币种"
clearable
size="small"
size="medium"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
@ -30,7 +31,7 @@
<!-- />-->
<!-- </el-form-item>-->
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择数据状态Y有效N无效" clearable size="small">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="medium">
<el-option
v-for="dict in statusOptions"
:key="dict.dictValue"
@ -49,12 +50,14 @@
<!-- />-->
<!-- </el-form-item>-->
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
<el-button type="primary" size="medium" @click="handleQuery">搜索</el-button>
<el-button size="medium" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</div>
<el-row :gutter="10" class="mb8">
<div class="bg bg-white">
<el-row :gutter="10" class="m-b-16">
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="primary"-->
@ -89,10 +92,8 @@
<!-- </el-col>-->
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
type="primary"
size="medium"
@click="handleExport"
v-hasPermi="['otc:OtcStoreBondConfig:export']"
>导出</el-button>
@ -136,6 +137,8 @@
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 添加或修改承兑商质押金费率配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>

33
src/views/otc/otcAppealOrder/index.vue

@ -1,5 +1,7 @@
<template>
<div class="app-container">
<div class="search_con m-b-28">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="订单号" prop="otcOrderNo">
@ -7,12 +9,12 @@
v-model="queryParams.otcOrderNo"
placeholder="请输入订单号"
clearable
size="small"
size="medium"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="申诉状态" prop="appealStatus">
<el-select v-model="queryParams.appealStatus" placeholder="请选择申诉状态" clearable size="small">
<el-select size="medium" v-model="queryParams.appealStatus" placeholder="请选择申诉状态" clearable>
<el-option
v-for="dict in appealStatusOptions"
:key="dict.dictValue"
@ -34,28 +36,27 @@
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
<el-button type="primary" size="medium" @click="handleQuery">搜索</el-button>
<el-button size="medium" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</div>
<el-row :gutter="10" class="mb8">
<div class="bg bg-white">
<el-row :gutter="10" class="m-b-16">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
size="medium"
@click="handleAdd"
v-hasPermi="['otc:otcAppealOrder:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
type="primary"
size="medium"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['otc:otcAppealOrder:edit']"
@ -74,10 +75,8 @@
<!-- </el-col>-->
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
type="primary"
size="medium"
@click="handleExport"
v-hasPermi="['otc:otcAppealOrder:export']"
>导出</el-button>
@ -146,6 +145,8 @@
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 添加或修改OTC申诉订单对话框 -->
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>

51
src/views/otc/otcStore/index.vue

@ -1,6 +1,8 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="106px"
<div class="search_con m-b-28">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="96px"
class="flex form" style="position: relative">
<el-form-item label="商户名称" prop="username">
<el-input size="medium" v-model="queryParams.username" placeholder="请输入商户名称"
@ -12,26 +14,29 @@
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker v-model="dateRange" size="small" style="width: 340px" value-format="yyyy-MM-dd HH:mm:ss"
<el-date-picker v-model="dateRange" size="medium" style="width: 340px" value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
:unlink-panels="true" :default-time="['00:00:00', '23:59:59']"></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="" size="medium" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="medium" @click="resetQuery">重置</el-button>
<el-button size="medium" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
</div>
<div class="bg bg-white">
<el-row :gutter="10" class="m-b-16">
<el-col :span="1.5">
<el-button type="primary" plain icon="" size="medium" @click="handleAdd('', 'add')">新增商户</el-button>
<el-button type="primary" icon="" size="medium" @click="handleAdd('', 'add')">新增商户</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<div class="bg">
<el-table stripe :data="infoList" v-loading="loading">
<el-table :data="infoList" v-loading="loading">
<el-table-column label="商户名称" align="center" prop="username" />
<el-table-column label="商户编号" align="center" prop="merchantNo" />
<el-table-column :label="'余额'" align="center" prop="balance">
@ -74,37 +79,37 @@
min-width="200">
<template slot-scope="scope">
<el-button size="small" type="text" @click="handleDeleteMer(scope.row)"
style="color: #006eff">商户删除</el-button>
<!-- <el-button size="small" type="text" @click="handleView(scope.row)" style="color: #006eff"
style=" ">商户删除</el-button>
<!-- <el-button size="small" type="text" @click="handleView(scope.row)" style=" "
v-hasPermi="['system:merchantChannel:getChannel']">通道</el-button> -->
<el-button size="small" type="text" @click="handleWithdraw(scope.row)"
style="color: #006eff">提现</el-button>
style=" ">提现</el-button>
<el-button size="small" type="text" @click="handlePassword(scope.row, 'loginPassword')"
style="color: #006eff">登录密码</el-button>
style=" ">登录密码</el-button>
<el-button size="small" type="text" @click="handlePassword(scope.row, 'payPassword')"
style="color: #006eff">支付密码</el-button>
style=" ">支付密码</el-button>
<el-button size="small" type="text" @click="handleBalance(scope.row)"
style="color: #006eff">余额</el-button>
style=" ">余额</el-button>
<el-button size="small" type="text" @click="handleUpdate(scope.row)"
style="color: #006eff">编辑</el-button>
style=" ">编辑</el-button>
<el-button size="small" type="text" @click="handleControl(scope.row)"
style="color: #006eff">风控</el-button>
style=" ">风控</el-button>
<el-button size="small" type="text" @click="handleUpdateRate(scope.row)"
style="color: #006eff">费率</el-button>
style=" ">费率</el-button>
<el-button size="small" type="text" @click="handleAdd(scope.row, 'next')"
style="color: #006eff">添加下级</el-button>
style=" ">添加下级</el-button>
<!-- <el-button size="small" type="text" @click="handleMD5(scope.row)" style="color: #006eff">MD5</el-button>
<el-button size="small" type="text" @click="handleKey(scope.row)" style="color: #006eff">谷歌密钥</el-button>
<!-- <el-button size="small" type="text" @click="handleMD5(scope.row)" style=" ">MD5</el-button>
<el-button size="small" type="text" @click="handleKey(scope.row)" style=" ">谷歌密钥</el-button>
<el-button size="small" type="text" @click="handleIp(scope.row, 'login')"
style="color: #006eff">登录IP</el-button>
style=" ">登录IP</el-button>
<el-button size="small" type="text" @click="handleIp(scope.row, 'pay')"
style="color: #006eff">支付IP</el-button> -->
style=" ">支付IP</el-button> -->
</template>
</el-table-column>
</el-table>

4
src/views/otc/otcStore/pkCouponScopeRangeStoreList.vue

@ -12,7 +12,7 @@
</div>
</el-form-item>
</el-form>
<el-table stripe v-loading="loading" :data="infoList">
<el-table v-loading="loading" :data="infoList">
<el-table-column label="通道名称" align="center" prop="dataStatus">
<template slot-scope="scope">
{{ scope.row.platformChannel.channelName }}
@ -45,7 +45,7 @@
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" min-width="200">
<template slot-scope="scope">
<el-button size="small" type="text" @click="handleUpdate(scope.row)" style="color: #006eff">费率</el-button>
<el-button size="small" type="text" @click="handleUpdate(scope.row)" style=" ">费率</el-button>
<el-button size="small" type="text" @click="handleDelete(scope.row)" style="color: red">删除</el-button>
</template>
</el-table-column>

2
src/views/otc/otcStoreDaiFuOrder/index.vue

@ -55,7 +55,7 @@
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table stripe :data="infoList" v-loading="loading" :row-class-name="tableRowClassName">
<el-table :data="infoList" v-loading="loading" :row-class-name="tableRowClassName">
<el-table-column label="平台订单号" align="center" prop="noOrder" />

37
src/views/otc/otcStorePledge/index.vue

@ -1,12 +1,13 @@
<template>
<div class="app-container">
<div class="search_con m-b-28">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="商家名称" prop="storeName">
<el-input
v-model="queryParams.storeName"
placeholder="请输入商家名称"
clearable
size="small"
size="medium"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
@ -15,7 +16,7 @@
v-model="queryParams.storeAccount"
placeholder="请输入商家账号"
clearable
size="small"
size="medium"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
@ -24,12 +25,12 @@
v-model="queryParams.coin"
placeholder="请输入质押币种"
clearable
size="small"
size="medium"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="medium">
<el-option
v-for="dict in statusOptions"
:key="dict.dictValue"
@ -40,12 +41,14 @@
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
<el-button type="primary" size="medium" @click="handleQuery">搜索</el-button>
<el-button size="medium" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</div>
<el-row :gutter="10" class="mb8">
<div class="bg bg-white">
<el-row :gutter="10" class="m-b-16">
<!-- <el-col :span="1.5">
<el-button
type="primary"
@ -58,10 +61,8 @@
</el-col> -->
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
type="primary"
size="medium"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['otc:otcStorePledge:edit']"
@ -69,10 +70,8 @@
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
type="primary"
size="medium"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['otc:otcStorePledge:remove']"
@ -80,10 +79,8 @@
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
type="primary"
size="medium"
@click="handleExport"
v-hasPermi="['otc:otcStorePledge:export']"
>导出</el-button>
@ -128,6 +125,8 @@
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 添加或修改商户质押资产对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>

2
src/views/otc/otcStoreRechargeOrder/index.vue

@ -94,7 +94,7 @@
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="small" type="text" style="color: #006EFF;" v-if="scope.row.orderStatus == 1"
<el-button size="small" type="text" style=" ;" v-if="scope.row.orderStatus == 1"
@click="handleOrder(scope.row)">手工处理</el-button>
</template>
</el-table-column>

2
src/views/register.vue

@ -145,7 +145,7 @@ export default {
};
</script>
<style rel="stylesheet/scss" lang="scss">
<style rel="stylesheet/scss" lang="scss" scoped>
.register {
display: flex;
justify-content: center;

12
src/views/system/role/index.vue

@ -1,6 +1,7 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
<div class="search_con m-b-28">
<el-form :model="queryParams" ref="queryForm" size="medium" :inline="true" v-show="showSearch">
<el-form-item label="角色名称" prop="roleName">
<el-input
v-model="queryParams.roleName"
@ -46,12 +47,14 @@
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
<el-button type="primary" size="medium" @click="handleQuery">搜索</el-button>
<el-button size="medium" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</div>
<el-row :gutter="10" class="mb8">
<div class="bg bg-white">
<el-row :gutter="10" class="m-b-16">
<el-col :span="1.5">
<el-button
type="primary"
@ -154,6 +157,7 @@
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 添加或修改角色配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>

1
vue.config.js

@ -33,6 +33,7 @@ module.exports = {
port: port,
open: true,
proxy: {
// http://bitcopay-admin.weirui0755.com/stage-api/swagger-ui.html#!/2183025143208052054035746213333164929702/getMerchantTotalInfoUsingGET 接口文档地址
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
// target: `http://bitcopay-admin.weirui0755.com/stage-api`,

Loading…
Cancel
Save