已完成:

  • 后台的管理功能:

这里用的组件是 element-UI  ====> NavMenu

◆首先是排版 :

 <div class="manage-page fillcontain">
<el-row style="height: 100%;">
<el-col :span="width" style="height: 100%;background-color: #324057;overflow-y:scroll">
<el-menu :default-active="defaultPath" ref='homeMenu' :default-openeds='arr' style="min-height: 100%;" text-color="#ffffff" unique-opened router @select='selectRouter' @close='closeMenu'>
<el-submenu index="">
<template slot="title">
<i class="el-icon-star-on"></i>
<span>实时管理</span>
<span class="red-dots dot-little" v-show="applyNum>0 || btext.bool || storageSpace"></span>
</template>
<el-submenu index="1-1">
<template slot="title">
<i class="el-icon-bell"></i>
<span>实时</span>
</template>
<el-menu-item index="/realTimeStatus">实时状况</el-menu-item>
<el-menu-item index="/baseData">基础数据</el-menu-item>
<el-menu-item index="/GPURealTime">GPU实时统计</el-menu-item>
</el-submenu>
<el-submenu index="1-2" v-if="is_administrator">
<template slot="title">
<i class="el-icon-time"></i>
<span>主机部署</span>
</template>
<el-menu-item index="/hostScan">主机扫描</el-menu-item>
</el-submenu>
<el-submenu index="1-3">
<template slot="title">
<i class="el-icon-plus"></i>
<span>设备管理</span>
<span class="red-dots dot-little" v-show="btext.bool || storageSpace"></span>
</template>
<el-menu-item index="/deviceList">设备列表</el-menu-item>
<el-menu-item index="/hostList">主机列表
<span class="red-dots " v-show="btext.bool">{{btext.num}}</span>
</el-menu-item>
<el-menu-item index="/modelList">模板列表</el-menu-item>
<el-menu-item index="/spaceList">存储空间列表
<span class="red-dots" v-show="storageSpace>0">{{storageSpace}}</span>
</el-menu-item>
<el-menu-item index="/priceList">价格列表</el-menu-item>
<el-menu-item index="/networkAgent">网络代理列表</el-menu-item>
</el-submenu>
<el-submenu index="1-4">
<template slot="title">
<i class="el-icon-goods"></i>
<span>市场管理</span>
<span class="red-dots dot-little" v-show="workerOrderApply>0"></span>
</template>
<el-menu-item index="/serviceList">服务列表</el-menu-item>
<el-menu-item index="/workOrderList">工单列表
<span class="red-dots" v-show="workerOrderApply>0">{{workerOrderApply}}</span>
</el-menu-item>
<el-menu-item index="/createWorkOrder">创建工单</el-menu-item>
<el-menu-item index="/AISoundCode">AI 源码列表</el-menu-item>
</el-submenu>
<el-submenu index="1-5">
<template slot="title">
<i class="el-icon-printer"></i>
<span>财务管理</span>
<span class="red-dots dot-little" v-show="billingApply>0"></span>
</template>
<el-menu-item index="/invoiceProcessing">发票管理
<span class="red-dots" v-show="billingApply>0">{{billingApply}}</span>
</el-menu-item>
<el-menu-item index="/rechargeInfo">收入管理</el-menu-item>
<el-menu-item index="/expenditure">支出管理</el-menu-item>
<el-menu-item index="/systemPresented">系统赠送</el-menu-item>
</el-submenu>
<el-submenu index="1-6">
<template slot="title">
<i class="el-icon-user-solid"></i>
<span>用户管理</span>
</template>
<el-menu-item index="/userInfo">用户列表</el-menu-item>
<el-menu-item index="/wxUserList">微信用户列表</el-menu-item>
</el-submenu>
<el-submenu index="1-7">
<template slot="title">
<i class="el-icon-share"></i>
<span>推广管理</span>
<span class="red-dots dot-little" v-show="(ambassadorApply>0 || withdrawApply>0)"></span>
</template>
<el-menu-item index="/recommendApply">推广申请
<span class="red-dots" v-show="ambassadorApply>0">{{ambassadorApply}}</span>
</el-menu-item>
<el-menu-item index="/withdrawApply">提现申请
<span class="red-dots" v-show="withdrawApply>0">{{withdrawApply}}</span>
</el-menu-item>
<el-menu-item index="/recommendList">推广信息列表</el-menu-item>
</el-submenu>
<el-submenu index="1-8">
<template slot="title">
<i class="el-icon-edit"></i>
<span>活动管理</span>
</template>
<el-menu-item index="/discountList">折扣列表</el-menu-item>
<el-menu-item index="/activityList">活动列表</el-menu-item>
</el-submenu>
<el-submenu index="1-9">
<template slot="title">
<i class="el-icon-news"></i>
<span>公告管理</span>
</template>
<el-menu-item index="/notice">公告列表</el-menu-item>
</el-submenu>
<el-submenu index="1-10" v-if="is_administrator">
<template slot="title">
<i class="el-icon-setting"></i>
<span>权限管理</span>
</template>
<el-menu-item index="/userRole">角色列表</el-menu-item>
<el-menu-item index="/permission">权限列表</el-menu-item>
<el-menu-item index="/role">角色管理</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="">
<template slot="title">
<i class="el-icon-document"></i>
<span>统计分析</span>
</template>
<el-submenu index="2-1">
<template slot="title">
<i class="el-icon-document"></i>
<span>设备使用情况</span>
</template>
<el-menu-item index="/equipData">GPU 租用总量总计</el-menu-item>
<el-menu-item index="/GPUAvailability">GPU 利用率统计</el-menu-item>
<el-menu-item index="/GPUUsed">GPU 使用分时统计</el-menu-item>
<el-menu-item index="/GPURent">GPU 租用采样统计</el-menu-item>
<el-menu-item index="/GPUUtilizationHeap">GPU 利用率堆积图</el-menu-item>
<el-menu-item index="/GPURentBenefit">GPU 租用效益统计</el-menu-item>
<!-- <el-menu-item index="/occupancyAnalysis">租用量分析</el-menu-item>
<el-menu-item index="/rentalFeeAnalysis">租赁费分析</el-menu-item> -->
<!-- <el-menu-item index="/rentalBenefitAnalysis">租用效益分析</el-menu-item> -->
</el-submenu>
<el-submenu index="2-2">
<template slot="title">
<i class="el-icon-document"></i>
<span>用户基本情况</span>
</template>
<el-menu-item index="/userGrow">用户增长统计</el-menu-item>
<el-menu-item index="/userRegister">用户注册时间分布</el-menu-item>
<el-menu-item index="/userInformat">用户活跃量统计</el-menu-item>
<el-menu-item index="/useTime">使用时长统计</el-menu-item>
<el-menu-item index="/userAttribute">用户属性统计</el-menu-item>
<el-menu-item index="/visitor">用户排行榜</el-menu-item>
<el-menu-item index="/visitStatistics">网站访问统计</el-menu-item>
</el-submenu>
<el-submenu index="2-7">
<template slot="title">
<i class="el-icon-pie-chart"></i>
<span>用户分布统计</span>
</template>
<el-menu-item index="/provinceStatistics">省份人数分布</el-menu-item>
<el-menu-item index="/cityStatistics">城市人数分布</el-menu-item>
<el-menu-item index="/schoolStatistics">学校人数分布</el-menu-item>
</el-submenu>
<el-submenu index="2-3">
<template slot="title">
<i class="el-icon-document"></i>
<span>用户 GPU 利用率</span>
</template>
<el-menu-item index="/rankingList">用户 GPU 利用率排行榜</el-menu-item>
</el-submenu>
<el-submenu index="2-4">
<template slot="title">
<i class="el-icon-document"></i>
<span>用户消费情况</span>
</template>
<el-menu-item index="/userExpense">消费类型统计</el-menu-item>
<el-menu-item index="/mainframeLease">主机租赁统计</el-menu-item>
<el-menu-item index="/incrementService">增值服务统计</el-menu-item>
<el-menu-item index="/ticketsUsed">消费券使用记录</el-menu-item>
<el-menu-item index="/codeList">AI 源码用户购买列表</el-menu-item>
</el-submenu>
<el-submenu index="2-5">
<template slot="title">
<i class="el-icon-document"></i>
<span>用户充值情况</span>
</template>
<el-menu-item index="/userRecharge">用户充值额统计</el-menu-item>
<el-menu-item index="/userRechargeType">用户充值渠道统计</el-menu-item>
</el-submenu>
<el-submenu index="2-6">
<template slot="title">
<i class="el-icon-document"></i>
<span>公司收支分析</span>
</template>
<el-menu-item index="/comparative">收支对比</el-menu-item>
<el-menu-item index="/income">收入统计</el-menu-item>
<el-menu-item index="/expenditureTow">支出统计</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index=''>
<template slot="title">
<i class="el-icon-s-promotion"></i>
<span>直达</span>
</template>
<!-- <el-menu-item index="/nonstop">快捷方式设置</el-menu-item> -->
<el-menu-item v-for='(item,index) in urlList' :index="`3-${index}`" :route="{path:item.nav_url,query:{copy:1}}" :key="index">{{item.nav_name}}</el-menu-item>
</el-submenu>
</el-menu>
</el-col>
<el-col :span="(24-width)" style="height: 100%">
<head-top v-on:changeMenu='openAMenu'></head-top>
<div class="content">
<keep-alive>
<router-view></router-view>
</keep-alive>
<div class="scrollbar"></div>
</div>
</el-col>
</el-row>
</div>

排版

◆消息提示:

小红点样式

.red-dots {
display: inline-block;
color: white;
vertical-align: middle;
margin-left: 5px;
margin-top: -2px;
width: 22px;
height: 22px;
line-height: 22px;
text-align: center;
border-radius: 15px;
font-size: 10px;
background-color: rgb(, , );
}

如何实现小红点的判断:

 <template slot="title">
<i class="el-icon-plus"></i>
<span>设备管理</span>
<span class="red-dots dot-little" v-show="btext.bool || storageSpace"></span>
</template>

路由跳转

 <el-menu-item index="/userExpense">消费类型统计</el-menu-item>
<el-menu-item index="/mainframeLease">主机租赁统计</el-menu-item>
<el-menu-item index="/incrementService">增值服务统计</el-menu-item>
<el-menu-item index="/ticketsUsed">消费券使用记录</el-menu-item>
<el-menu-item index="/codeList">AI 源码用户购买列表</el-menu-item>

路由跳转

  • 顶部导航栏功能的实现(后台)

排版代码:

 <template>
<div class="header-container">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/manage' }">首页</el-breadcrumb-item>
<el-breadcrumb-item v-for="item in $route.meta" :key="item.index">
<span :class="{'is-link':item.index!==undefined}" @click="openMenu(item.index)">{{item.name}}</span>
</el-breadcrumb-item>
</el-breadcrumb>
<div class="userInfo-box">
<template v-if="canAdd!==null">
<el-button class="addNonstop" size="small" type="primary" @click="setShortcut('post')" v-if="canAdd===1">添加直达</el-button>
<el-button class="addNonstop" size="small" type="warning" @click="setShortcut('delete')" v-if="canAdd===0">取消直达</el-button>
</template>
<img src='../assets/default.jpg' class="avator">
<ul class="userInfo">
<li>{{username}}</li>
<li>|</li>
<li @click="loginOut">退出</li>
</ul>
</div>
</div>
</template>

排版代码

子组件向父组件传路由值

 <el-breadcrumb-item v-for="item in $route.meta" :key="item.index">
<span :class="{'is-link':item.index!==undefined}" @click="openMenu(item.index)">{{item.name}}</span>
</el-breadcrumb-item>
 openMenu(index){
if(index){
this.$emit('changeMenu',index); //$emit 绑定一个自定义事件event,当这个这个语句被执行到的时候,就会将参数arg传递给父组件,父组件通过@event监听并接收参数
}
}

父组件获取路由值

 <head-top v-on:changeMenu='openTheMenu'></head-top>
//打开指定菜单
openTheMenu(index) {
this.$refs["homeMenu"].open(index);
}
  • 订单查询功能(后台)

整个页面:

 <script>
import Utils from "@/utils/utils";
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('financial')
export default {
data() {
return {
showPagination: false,
pickerBeginDateBefore: {
disabledDate: time => {
if (this.end_date) {
return (
time.getTime() > this.end_date || time.getTime() > Date.now()
);
}
}
},
pickerBeginDateAfter: {
disabledDate: time => {
if (this.begin_date) {
return (
time.getTime() < this.begin_date || time.getTime() > Date.now()
);
}
}
},
origin_list: [
"全部",
"后台-淘宝-易学智能",
"后台-淘宝-GPU远程租用",
"平台-支付宝",
"后台-淘宝充值",
"后台-银行公账-深圳兴导",
'后台-银行公账-湖南兴导',
"后台-淘宝-国科机房",
'平台-微信'
],
time_list: [
{ name: "本日", val: "today" },
{ name: "本周", val: "this_week" },
{ name: "本月", val: "this_month" },
{ name: "上月", val: "last_month" },
{ name: "日期范围", val: "date_range" }
],
add_list: [{
name:"全部",
id:0
},{
name:"充值",
id:1
},{
name:"快递费",
id:5
},{
name:"增值服务",
id:6
}],
origin: 0,
add_type: 0,
time_type: "today",
begin_date: new Date(2018,10,15),
end_date: new Date(),
total_data: {
total: 0
},
table_loading: false,
page_size: 20,
order_by: null,
order: null,
input:null,
order_number:null
};
},
watch: {
$route(to, from) {
if (to.path === "/rechargeInfo" && from.path !== "/userDetails") {
this.total_data = {};
this.origin=0;
this.add_type=0;
this.time_type="today";
this.begin_date=new Date(2018,10,15);
this.end_date=new Date();
this.showPagination = false;
this.order = null;
this.order_by = null;
this.search(1);
}
}
},
created() {
this.search(1);
},
methods: {
...mapActions(["rechargeListAPI", "downloadRechargeAPI"]),
//分页
changePage(value) {
this.search(value);
this.$refs['pageTwo'].internalCurrentPage = this.$refs['pageOne'].internalCurrentPage;//绑定页数
},
changePageTwo(value){
this.search(value);
this.$refs['pageOne'].internalCurrentPage = this.$refs['pageTwo'].internalCurrentPage;
},
//排序
sortMethod(){
this.order_by = 'add_time';
this.order = this.order === 'desc'? 'asc': 'desc';
this.showPagination=false;
this.search(1);
},
//进入用户详情
searchOne(id) {
this.$router.push({ path: "userDetails?id=" + id, replace: true });
},
//查询充值明细
search(page) {
if (!Utils.checkToken(this)) return;
if(this.time_type==='date_range'&&(!this.begin_date||!this.end_date)){
return this.$message.error('请选择时间!');
}
this.table_loading = true;
this.rechargeListAPI({
origin: this.origin,
time_type: this.time_type,
add_type: this.add_type,
begin_date: Utils.formatDate(this.begin_date, "yyyy-MM-dd"),
end_date: Utils.formatDate(this.end_date, "yyyy-MM-dd"),
page: page,
page_size: this.page_size,
order_by: this.order_by,
order: this.order,
order_number:this.order_number
}).then(
({body}) => {
this.total_data = body;
this.table_loading = false;
this.showPagination = true;
},
err => {
this.table_loading = false;
this.showPagination = true;
this.$message.error(err.msg);
}
);
},
//下载明细单
download(page) {
if (!Utils.checkToken(this)) return;
const loading = this.$loading();
this.downloadRechargeAPI({
origin: this.origin,
time_type: this.time_type,
add_type: this.add_type,
begin_date: Utils.formatDate(this.begin_date, "yyyy-MM-dd"),
end_date: Utils.formatDate(this.end_date, "yyyy-MM-dd"),
order: this.order,
order_by: this.order_by,
}).then(
res => {
loading.close();
const blob = res.data;
const fileName = decodeURI(res.headers.map["content-disposition"][0].split(";")[1].split("=")[1]) || '易学智能-充值明细单.xlsx';
if ("download" in document.createElement("a")) {
// 非IE下载
const elink = document.createElement("a");
elink.download = fileName;
elink.style.display = "none";
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
} else {
// IE10+下载
navigator.msSaveBlob(blob, fileName);
}
},
err => {
loading.close();
this.$message.error(err.msg);
}
);
},
//订单号获得焦点事件 //zcg
focus(){
this.time_type ='date_range'
this.search(1);
},
//订单号change事件
changeInput(value){
this.order_number =value
this.search(1);
}
}
};
</script>
<template>
<div>
<p class="title title-primary">充值明细查询</p>
<el-form label-width="100px" label-position="left">
<el-form-item label="来源:">
<el-radio-group v-model="origin" @change="showPagination=false,search(1)">
<el-radio v-for='(item,index) in origin_list' :key="index" :label="index">{{item}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="充值类型:">
<el-radio-group v-model="add_type" @change="showPagination=false,search(1)">
<el-radio v-for='(item,index) in add_list' :key="index" :label="item.id">{{item.name}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="时间类型:">
<el-radio-group v-model="time_type" @change="showPagination=false,search(1)">
<el-radio v-for='(item,index) in time_list' :key="index" :label="item.val">{{item.name}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="起始日期:" v-show="time_type==='date_range'">
<el-date-picker v-model="begin_date" type="date" placeholder="开始时间" format="yyyy-MM-dd" :picker-options="pickerBeginDateBefore">
</el-date-picker>
<el-date-picker v-model="end_date" type="date" placeholder="结束时间" format="yyyy-MM-dd" :picker-options="pickerBeginDateAfter">
</el-date-picker>
<el-button type="primary" @click="showPagination=false,search(1)">查询记录</el-button>
</el-form-item>
<el-form-item label="订单号:" class="nav-btns nav-input">
<el-input placeholder="输入订单号" clearable v-model="input" @focus="focus" @input="changeInput"></el-input>
</el-form-item>
<el-form-item>
<el-button type="warning" @click="download">全部下载</el-button>
</el-form-item>
</el-form>
<el-pagination ref='pageOne' v-if="showPagination" :page-size="page_size" background layout="total,prev, pager, next" :total='total_data.total' @current-change="changePage"></el-pagination>
<el-table :data="total_data.data" v-loading="table_loading">
<el-table-column label="序号" type="index" width="100px">
</el-table-column>
<el-table-column label="用户名" prop="user_name">
<template slot-scope="scope">
<span @click="searchOne(scope.row.uid)" class="font-jump">{{scope.row.user_name}}</span>
</template>
</el-table-column>
<el-table-column label="充值时间" prop="add_time">
<template slot="header" slot-scope="scope">
<span @click="sortMethod('add_time')">充值时间
<i class="el-icon-sort" v-if="order_by!='add_time'"></i>
<template v-else>
<i class="el-icon-sort-down" v-if="order =='desc'"></i>
<i class="el-icon-sort-up" v-else></i>
</template>
</span>
</template>
</el-table-column>
<el-table-column label="订单号">
<template slot-scope="scope">
<p>{{scope.row.order_number?scope.row.order_number:'无'}}</p>
</template>
</el-table-column>
<el-table-column label="来源" prop="origin">
</el-table-column>
<el-table-column label="备注">
<template slot-scope="scope">
<p>{{scope.row.comment?scope.row.comment:'无'}}</p>
</template>
</el-table-column>
<el-table-column label="充值金额(元)" prop="receipt_amount">
</el-table-column>
<el-table-column label="操作人" prop="admin_username">
</el-table-column>
</el-table>
<el-pagination ref='pageTwo' v-if="showPagination" :page-size="page_size" background layout="total,prev, pager, next" :total='total_data.total' @current-change="changePageTwo"></el-pagination>
</div>
</template>

整个查询页面

排版:

  <el-form-item  label="订单号:" class="nav-btns nav-input">
<el-input placeholder="输入订单号" clearable v-model="input" @focus="focus" @input="changeInput"></el-input>
</el-form-item>
<el-form-item>
<el-button type="warning" @click="download">全部下载</el-button>
</el-form-item

功能的实现:

 1 focus(){
2 this.time_type ='date_range'
3 this.search(1);
4 },
5 //订单号change事件
6 changeInput(value){
7 this.order_number =value
8 this.search(1);
9 }
10 }

查询时间:

 search(page) {
if (!Utils.checkToken(this)) return;
if(this.time_type==='date_range'&&(!this.begin_date||!this.end_date)){
return this.$message.error('请选择时间!');
}
this.table_loading = true;
this.rechargeListAPI({
origin: this.origin,
time_type: this.time_type,
add_type: this.add_type,
begin_date: Utils.formatDate(this.begin_date, "yyyy-MM-dd"),
end_date: Utils.formatDate(this.end_date, "yyyy-MM-dd"),
page: page,
page_size: this.page_size,
order_by: this.order_by,
order: this.order,
order_number:this.order_number
}).then(
({body}) => {
this.total_data = body;
this.table_loading = false;
this.showPagination = true;
},
err => {
this.table_loading = false;
this.showPagination = true;
this.$message.error(err.msg);
}
);
},

下载明细文件:

 download(page) {
if (!Utils.checkToken(this)) return;
const loading = this.$loading();
this.downloadRechargeAPI({
origin: this.origin,
time_type: this.time_type,
add_type: this.add_type,
begin_date: Utils.formatDate(this.begin_date, "yyyy-MM-dd"),
end_date: Utils.formatDate(this.end_date, "yyyy-MM-dd"),
order: this.order,
order_by: this.order_by,
}).then(
res => {
loading.close();
const blob = res.data;
const fileName = decodeURI(res.headers.map["content-disposition"][0].split(";")[1].split("=")[1]) || '易学智能-充值明细单.xlsx';
if ("download" in document.createElement("a")) {
// 非IE下载
const elink = document.createElement("a");
elink.download = fileName;
elink.style.display = "none";
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
} else {
// IE10+下载
navigator.msSaveBlob(blob, fileName);
}
},
err => {
loading.close();
this.$message.error(err.msg);
}
);
},
 const state = {
billingList:{},
billingOrders:{}
} const actions = {
/* 发票管理 */
//开票待处理、已开票、已拒绝列表
async billingInfoAPI({dispatch,commit},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/bill/apply_list',
query:{
params:query
},
callback:({body})=>{
commit('setState',{
childName:'financial',
name:'billingList',
val:body
},{root:true})
}
},{root:true})
},
//开票相关订单信息
async billingOrdersInfoAPI({dispatch,commit},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/bill/order_list',
query:{
params:query
},
callback:({body})=>{
commit('setState',{
childName:'financial',
name:'billingOrders',
val:body
},{root:true})
}
},{root:true})
},
//开票完成信息提交
async billingCompleteAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'post',
API_url:'gpu_admin/finance/bill/dealt',
query:query
},{root:true})
},
//发票数据总计
async billingAmountAPI({dispatch}) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/billinfo'
},{root:true})
}, /* 充值明细 */
//充值明细记录
async rechargeListAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/recharge_list',
query:{
params:query
}
},{root:true})
},
//下载充值明细
async downloadRechargeAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/recharge_list_excel',
query:{
headers:{'Content-Type':'application/ms-excel'},
responseType:'blob',
params:query,
}
},{root:true})
}, /* 系统赠送 */
//系统赠送明细记录
async presentedListAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/syspresented_list',
query:{
params:query
}
},{root:true})
},
//下载系统赠送明细
async downloadPresentedAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/syspresented_list_excel',
query:{
headers:{'Content-Type':'application/ms-excel'},
responseType:'blob',
params:query
}
},{root:true})
},
//支出信息
async expenditureAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/and_payments/expenditure',
query:{
params:query
},
flag : true
},{root:true})
},
//添加支出
async expenditureAddAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'post',
API_url:'gpu_admin/and_payments/expenditure',
query:query
},{root:true})
},
//用户名列表
async usernamelistAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/usernamelist',
query:{
params:query
}
},{root:true})
},
//用户充值记录
async add_money_logAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/and_payments/add_money_log',
query:{
params:query
}
},{root:true})
}, //财务管理 //收入信息 -充值信息
async incomeAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/income',
query:{
params:query
}
},{root:true})
}, //收入信息 -充值信息
async incomegraphAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/incomegraph',
query:{
params:query
}
},{root:true})
}, //收入每日/周/月信息
async incomedetailAPI({dispatch},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/incomedetail',
query:{
params:query
}
},{root:true})
}, } export default{
namespaced:true,
state,
actions
}

财政接口代码

调用接口JS代码:

 callingInterface({},{request_method,API_url,query,flag,callback}){
//请求地址+API
const url = localhost + API_url;
//是否开启emulateJSON
const is_flag = flag!==undefined ? flag : false;
//回调函数,处理提交mutaion修改state的操作
const callMethod = callback!==undefined ? callback : (()=>{});
console.log('请求传入参数query:', query) return new Promise((resolve, reject) => {
Vue.http[request_method](url, query ,{
emulateJSON: is_flag
}).then(res => {
resolve(res);
callMethod(res);
console.log('请求成功:', res);
}, err => {
console.log('请求失败:', err)
reject(err.body)
})
})
},

点击按钮查询不同的数据(利用v-model的双向绑定原理和v-on:change事件)

 <el-form-item label="来源:">
<el-radio-group v-model="origin" @change="showPagination=false,search(1)">
<el-radio v-for='(item,index) in origin_list' :key="index" :label="index">{{item}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="充值类型:">
<el-radio-group v-model="add_type" @change="showPagination=false,search(1)">
<el-radio v-for='(item,index) in add_list' :key="index" :label="item.id">{{item.name}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="时间类型:">
<el-radio-group v-model="time_type" @change="showPagination=false,search(1)">
<el-radio v-for='(item,index) in time_list' :key="index" :label="item.val">{{item.name}}</el-radio>
</el-radio-group>
</el-form-item>

 根据路由传值完成不同的详情页面:

在其他页面传值后跳转到详情页面

点击用户名 触发事件:

<el-table-column label="用户名">
<template slot-scope="scope">
<span @click="searchOne(scope.row.uid)" class="font-jump">{{scope.row.username}}</span> //点击触发查询事件
</template>
</el-table-column>

查询事件:

searchOne(id) {
this.$router.push({path:'userDetails?id='+id,replace:true});//路由就变成了详情页并且带id
}

详情页面的获取信息功能:

 getUserDetails(){
this.uid = this.$route.query.id;// 根据路由ID的不同,返回不同的数据
this.getUserInfo();
this.getExtraInfo();
this.getExpenseInfo();
},

getUserInfo:

  getUserInfo() {
if (!Utils.checkToken(this)) return;
this.pageLoading = true;
this.userInfoDetailsAPI({//通过API接口获取数据
uid: this.uid
}).then(
({body}) => {
this.pageLoading = false;
this.sendData = Object.assign(this.sendData,{user_name:body.user_name,balance:body.balance})
this.userInfo = body;
},
err => {
this.pageLoading = false;
this.$message.error(err.msg);
}
);
}

监听:

 watch: {
$route(to, from) {
if (to.path === "/userDetails") {
this.showPagination = false;
this.record_type= 'expenseRecord';
this.record_son_type= ;
this.pageInfo={
page:,
page_size:
};
this.date= [Utils.formatDate(new Date("2018/11/15"), "yyyy-MM-dd"), Utils.formatDate(new Date(), "yyyy-MM-dd")];
this.userInfo = {}
this.extraInfo = {}
this.expenseInfo = {}
this.sendData = {}
this.getUserDetails();
}
}

生命周期钩子函数:

 created() {
this.getUserDetails();
},
  • 点击显示订单详情

利用饿了么组件(不同之处:利用计算属性来获得数据)

 <el-dialog title="订单信息" :visible.sync="openOrderInfo" width="1000px" center :close-on-click-modal='false'>
<el-table :data="billingOrders.data" border>
<el-table-column label="序号" type="index" width="100px">
</el-table-column>
<el-table-column label="可开票金额(元)" prop="available_bill">
</el-table-column>
<el-table-column label="实收金额(元)" prop="receipt_amount">
</el-table-column>
<el-table-column label="充值来源" prop="origin">
</el-table-column>
<el-table-column label="订单号" prop="order_number">
</el-table-column>
<el-table-column label="订单类型" prop="order_type">
</el-table-column>
<el-table-column label="充值时间" prop="add_time">
</el-table-column>
</el-table>
</el-dialog>

数据获取(使用了命名空间):

  import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('financial') computed:{
...mapState(['billingList','billingOrders'])
}

命名空间获取billingOrders值:(命名空间:将模块的空间名称字符串作为第一个参数传递给上述函数,这样所有绑定都会自动将该模块作为上下文。)

命名空间: 默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。

 async billingOrdersInfoAPI({dispatch,commit},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/bill/order_list',
query:{
params:query
},
callback:({body})=>{
commit('setState',{//到setstate去设置state的值
childName:'financial',//字符串,为了setState可以[""]
name:'billingOrders',//字符串,为了setState可以[""]
val:body
},{root:true})
}
},{root:true})
},

提交到setState:(mutations.js文件)

 const mutations = {
//设置state的值
setState(state,{name,val,childName}){
if(childName!==undefined){
state[childName][name] = val
}else{
state[name] = val
}
}
} export default{
mutations
}

如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。例如:

billingOrders来源:(接口获取)

 async billingOrdersInfoAPI({dispatch,commit},query) {
return await dispatch('callingInterface',{
request_method:'get',
API_url:'gpu_admin/finance/bill/order_list',
query:{
params:query
},
callback:({body})=>{
commit('setState',{
childName:'financial',
name:'billingOrders',//回调函数
val:body
},{root:true})
}
},{root:true})
},

命名来源:(Store下的index.js文件):

 import Vue from 'vue'
import Vuex from 'vuex' import fooActions from './actions'
import fooMutations from './mutations'
import login from './modules/login'
import realTimeData from './modules/real_time_data'
import deploy from './modules/deploy'
import device from './modules/device'
import financial from './modules/financial'
import userInfo from './modules/user_info'
import recommend from './modules/recommend'
import activity from './modules/activity'
import userLimit from './modules/user_limit'
import recharge from './modules/recharge'
import statistics from './modules/statistics'
import equipUsageInfo from './modules/equip_usage_info'
import userExpenseData from './modules/user_expense_data'
import market from './modules/market'
import GPUUseRatio from './modules/GPU_use_ratio'
import expenses from "./modules/expenses"
import userDistribution from "./modules/user_distribution"
// import createLogger from '../../../src/plugins/logger' Vue.use(Vuex)
const debug = process.env.NODE_ENV !== 'production' const state = {
applyData:{},
urlList:[]
} export default new Vuex.Store({
state:state,
actions:fooActions.actions,
mutations:fooMutations.mutations,
modules:{
login,
realTimeData,
deploy,
device,
financial,
userInfo,
recommend,
activity,
userLimit,
recharge,
statistics,
equipUsageInfo,
userExpenseData,
market,
GPUUseRatio,
expenses,
userDistribution
},
strict: debug,
// plugins: debug ? [createLogger()] : []
})

Store文件夹下的index.js文件

若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。

{root:true}    =====> 若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true } 作为第三参数传给 dispatch 或 commit 即可。  

未用命名空间:

 import { mapActions,mapState } from "vuex"
computed: {
...mapState({
deploy_status:state=>state.deploy.deploy_status,
status_color:state=>state.deploy.status_color
}), methods: {
...mapActions({
deployListAPI:'deploy/deployListAPI',
deployServerAPI:'deploy/deployServerAPI'
}),

回调接口;

 callingInterface({},{request_method,API_url,query,flag,callback}){
//请求地址+API
const url = localhost + API_url;
//是否开启emulateJSON
const is_flag = flag!==undefined ? flag : false;
//回调函数,处理提交mutaion修改state的操作
const callMethod = callback!==undefined ? callback : (()=>{});
console.log('请求传入参数query:', query) return new Promise((resolve, reject) => {
Vue.http[request_method](url, query ,{
emulateJSON: is_flag
}).then(res => {
resolve(res);
callMethod(res); //如果传了callback,就有意义,如果没传callback 就是(){} 空函数,执行了也没效果
console.log('请求成功:', res);
}, err => {
console.log('请求失败:', err)
reject(err.body)
})
})
}
  • 画图:  =====>见另一篇博文 Echarts配置
  • 点击按钮触发申请处理表

模板代码:

 <el-table-column label="操作" v-if="status==='apply'" key="t2" width="">
<template slot-scope="scope"> // scope 是v-bind绑定数据(:data)后的固定写法

           <el-button @click="openForm(scope.row)" type="primary" size="small">处理</el-button>
</template>
</el-table-column>

点击事件代码:

 //打开处理申请的弹框
openForm(row){
this.formData = Object.assign({
order:null//目标
},{
id:row.e_id,
clearing:row.e_money,
})
this.openUpdate = true;
},

点击后:

模板代码:

 <el-dialog title="申请处理" :visible.sync="openUpdate" width="400px" center @closed='clearData' :close-on-click-modal='false'>
        //model ====> 表单数据对象
<el-form :model="formData" :rules="deal_rules" ref='dealForm' label-width="100px" v-if="formData!==null">
<el-form-item label="提现订单号" prop="order">
<el-input v-model="formData.order"></el-input>
</el-form-item>
<el-form-item label="提现金额" prop="clearing">
<el-input v-model="formData.clearing"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="openUpdate = false">取 消</el-button>
<el-button type="primary" @click="submitData('dealForm')">确 定</el-button>
</span>
</el-dialog>

提交申请:

submitData(name){
if(!Utils.checkToken(this))return;
this.$refs[name].validate(valid=>{
if(valid){
let loading = this.$loading();
this.withdrawHandleAPI({
id:this.formData.id,
clearing:this.formData.clearing,
order:this.formData.order,
}).then(({body})=>{
loading.close();
this.openUpdate = false;
if(body.code===){
this.$message.success(body.msg)
this.getApplyInfo(this.page);
}else{
this.$message.error(body.msg)
}
},err=>{
loading.close();
this.$message.error(err.msg)
})
}
})
}
  • 权限:

  • 切换角色类型:

 <el-radio-group v-model="record_type">
<el-radio-button :label="item" v-for="(item,index) in role_list" :key='index'></el-radio-button>
</el-radio-group>

监听双向绑定额数据:

 watch:{
//切换角色类型
record_type(newVal,oldVal){
this.showPagination = false;
this.getUserRoleList();
}
}

监听数据这里不是函数,而是一个固定写法,第一个参数是new值,第二个参数是old值(而且这里不用this)

  • 直达功能

添加直达

模板代码:

 <template v-if="canAdd!==null">
<el-button class="addNonstop" size="small" type="primary" @click="setShortcut('post')" v-if="canAdd===1">添加直达</el-button>
<el-button class="addNonstop" size="small" type="warning" @click="setShortcut('delete')" v-if="canAdd===0">取消直达</el-button>
</template>

直达功能代码:

 setShortcut(method){
if(!Utils.checkToken(this))return;
const name = this.$route.meta[].name? this.$route.meta[].name: this.$route.meta[].name;
let query;
if(method==='delete'){
query = {
method:method,
data:{
body:{
nav_name:name,
nav_url:this.$route.path
}
}
}
}else{
query = {
method:method,
data:{
nav_name:name,
nav_url:this.$route.path
}
}
}
this.updateShortcutAPI(query).then(
res => {
this.$message.success(res.body.msg);
this.shortcutListAPI()
},
err => {
this.$message.error(err.msg);
}
);
}

直达功能

$route为当前router跳转对象里面可以获取name、path、query、params等

$router为VueRouter实例,想要导航到不同URL,则使用$router.push方法

  • 点击曲线获得数据
       const This = this;
let mChart_line1 = This.$echarts.init(document.getElementById("mChart_line"));
mChart_line1.getZr().off("click"); // ZRender 一个轻量级的Canvas类库
mChart_line1.getZr().on("click", params => {
const pointInPixel = [params.offsetX, params.offsetY];
if (mChart_line1.containPixel({ seriesIndex: [] }, pointInPixel)) {
//判断给定的点是否在指定的坐标系或者系列上
let xIndex = mChart_line1.convertFromPixel({ seriesIndex: }, [
//转换像素坐标值到逻辑坐标系上的点
params.offsetX,
params.offsetY
])[]; /*事件处理代码书写位置*/
This.day =
This.date_type === "month"
? This.total_data.date[xIndex] + "-01"
: This.total_data.date[xIndex];
This.showPagination = false;
this.getData()
}
});
  • 两种查询方式调同一个方法里面的接口: (一个传值,一个不传值) //即使是不同的地方点击事件,里面的参数也会保存。
 getInvoiceList(page){
if(!Utils.checkToken(this))return;
if (this.begin_date === null || this.end_date === null) {
this.$message.error("请选择时间!");
return;
}
this.table_loading = true;
this.billingInfoAPI({
begin_date: Utils.formatDate(this.begin_date, "yyyy-MM-dd"),
end_date: Utils.formatDate(this.end_date, "yyyy-MM-dd"),
status: this.status,
page: page,
page_size: this.page_size,
keyword:this.keyword
}).then(res=>{
this.table_loading = false;
this.showPagination = true;
},err=>{
this.table_loading = false;
this.showPagination = true;
this.$message.error(err.msg);
})
},

传值的

  invoiceQuery() {
this.showPagination = false;
this.getInvoiceList();
}

不传值的

遍历数据的三种写法:

1.v-for

 <el-form-item label="来源:">
<el-radio-group v-model="origin" @change="showPagination=false,search(1)">
<el-radio v-for='(item,index) in origin_list' :key="index" :label="index">{{item}}</el-radio>
</el-radio-group>
</el-form-item>

2.element 模板  利用v-bind绑定数据, 然后传个prop属性作为值。

 <el-table border :data="userData" v-loading='tableLoadingOne'>
<el-table-column label="用户总数" prop="user_total_num"></el-table-column>
<el-table-column label="总充值次数" prop="add_money_num"></el-table-column>
<el-table-column label="充值总额(元)" prop="add_money_total"></el-table-column>
<el-table-column label="总使用次数" prop="rent_num"></el-table-column>
<el-table-column label="消费总额(易学币)" prop="cunsumption_money_total"></el-table-column>
</el-table>
  • 2-1  如果需要对获取的值做个判断,可以在这个里面嵌套个 <template slot-scope = 'scope'> </template>  再用插值表达式判断

3.element表单组件,利用v-bind:model绑定数据,然后利用v-model双向绑定机制输出。

 <el-form :model="editData" ref="editForm" :rules="rules" v-if="editData!==null" class="recharge-form" label-width="100px">
<el-form-item label="策略编号" prop="policy_reference">
<el-select v-model="editData.policy_reference" placeholder="请选择策略" :disabled="editTitle==='修改折扣'">
  <el-option v-for="(item,index) in idList" :key="index" :label="item" :value="item"></el-option>
   </el-select>
          </el-form-item>
</el-form>
 
  • 通过JS适配移动端WEB页面
 function adaptation() {//通过JS适配移动端
(function(doc, win) {
var docEl = doc.documentElement,
recalc = function() {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
//&&!navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)
if (clientWidth >= ) {
docEl.style.fontSize = '100px';
} else {
docEl.style.fontSize = * (clientWidth / ) + 'px';
}
};
// if (!doc.addEventListener) return;
// doc.addEventListener('DOMContentLoaded', recalc, false);
recalc();
})(document, window);
}

待完成 :

  • 聊天室(前台)
  • 直播 (前台)
  • 支付功能(前台)

【原创】Vue项目中各种功能的实现的更多相关文章

  1. 在vue项目中使用codemirror插件实现代码编辑器功能(代码高亮显示及自动提示

    在vue项目中使用codemirror插件实现代码编辑器功能(代码高亮显示及自动提示) 1.使用npm安装依赖 npm install --save codemirror; 2.在页面中放入如下代码 ...

  2. Vue项目中添加锁屏功能

    0. 直接上 预览链接 Vue项目中添加锁屏功能 1. 实现思路 ( 1 ) 设置锁屏密码 ( 2 ) 密码存localStorage (本项目已经封装h5的sessionStorage和localS ...

  3. 浅谈 Axios 在 Vue 项目中的使用

    介绍 Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中. 特性 它主要有如下特性: 浏览器端发起XMLHttpRequests请求 Node端发起http ...

  4. scss/less语法以及在vue项目中的使用(转载)

    1.scss与less都是css的预处理器,首先我们的明白为什么要用scss与less,因为css只是一种标记语言,其中并没有函数变量之类的,所以当写复杂的样式时必然存在局限性,不灵活,而scss与l ...

  5. 转:如何在Vue项目中使用vw实现移动端适配

    https://www.w3cplus.com/mobile/vw-layout-in-vue.html 有关于移动端的适配布局一直以来都是众说纷纭,对应的解决方案也是有很多种.在<使用Flex ...

  6. 在Vue项目中使用vw实现移动端适配

    有关于移动端的适配布局一直以来都是众说纷纭,对应的解决方案也是有很多种.在<使用Flexible实现手淘H5页面的终端适配>提出了Flexible的布局方案,随着viewport单位越来越 ...

  7. 如何在Vue项目中使用vw实现移动端适配(转)

    有关于移动端的适配布局一直以来都是众说纷纭,对应的解决方案也是有很多种.在<使用Flexible实现手淘H5页面的终端适配>提出了Flexible的布局方案,随着viewport单位越来越 ...

  8. vue 项目中命名方法

    命名 命名的方法通常有以下几类: 命名法说明 1).camel命名法,形如thisIsAnApple 2).pascal命名法,形如ThisIsAnApple 3).下划线命名法,形如this_is_ ...

  9. Vue项目中使用vw实现移动端适配

    我们在vue移动端项目中的适配一般都采用rem,但是rem也不是能兼容所有的终端. 随着viewport单位越来越受到众多浏览器的支持,下面将简单介绍怎么实现vw的兼容问题,用vw代替rem 当我们采 ...

随机推荐

  1. 日本語 IME输入法(Microsoft 输入法)切换问题

    平假名 与 片假名之间的切换 按住 Ctrl + Caps Lock(平假名) 按住 Alt + Caps Lock(片假名) 另外:语言之间的切换 Alt + Shift 键 / Windows + ...

  2. Bet(The 2016 ACM-ICPC Asia China-Final Contest 思路题)

    题目: The Codejamon game is on fire! Fans across the world are predicting and betting on which team wi ...

  3. 猎豹CEO傅盛:与周鸿祎、雷军、马化腾、马云的的相爱相杀

    百度百科:傅盛,男,1978年3月6日出生在江西景德镇,毕业于山东工商学院信息管理与信息系统专业. 2003年加入3721公司.2005年加入奇虎360,带领团队打造了安全类软件360安全卫士.200 ...

  4. Shell中的循环语句实例

    1.for循环语句实例1.1 最基本的for循环 #!/bin/bash for x in one two three four do     echo number $x done 注:" ...

  5. C. Star sky 二维前缀和

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  6. Thread的方法join()使用

    join()的作用:Waits for this thread to die.等待线程对象销毁.在Thread源码中可以看到join源码是使用了wait()方法来实现等待功能. 因为join()内部使 ...

  7. 武大OJ 613. Count in Sama’s triangle

    Description Today, the math teacher taught Alice Hui Yang’s triangle. However, the teacher came up w ...

  8. 利用Clojure统计代码文件数量和代码行数

    ;; 引入clojure的io包 (use '[clojure.java.io]) ;; 遍历目录将所有符合要求的文件做为列表返回 (defn walk [dirpath pattern] (doal ...

  9. 条款50: 提高对C++的认识

    class Base { public: virtual void f(int x); }; class Derived: public Base { public: virtual void f(d ...

  10. ssh连接断开后 shell进程退出

    问题描述:当SSH远程连接到服务器上,然后运行一个服务 ./catalina.sh start,然后把终端开闭(切断SSH连接)之后,发现该服务中断,导致网页无法访问.   解决方法:使用nohup命 ...