【原创】Vue项目中各种功能的实现
已完成:
- 后台的管理功能:
这里用的组件是 element-UI ====> NavMenu
◆首先是排版 :
1 <div class="manage-page fillcontain"> 2 <el-row style="height: 100%;"> 3 <el-col :span="width" style="height: 100%;background-color: #324057;overflow-y:scroll"> 4 <el-menu :default-active="defaultPath" ref='homeMenu' :default-openeds='arr' style="min-height: 100%;" text-color="#ffffff" unique-opened router @select='selectRouter' @close='closeMenu'> 5 <el-submenu index="1"> 6 <template slot="title"> 7 <i class="el-icon-star-on"></i> 8 <span>实时管理</span> 9 <span class="red-dots dot-little" v-show="applyNum>0 || btext.bool || storageSpace"></span> 10 </template> 11 <el-submenu index="1-1"> 12 <template slot="title"> 13 <i class="el-icon-bell"></i> 14 <span>实时</span> 15 </template> 16 <el-menu-item index="/realTimeStatus">实时状况</el-menu-item> 17 <el-menu-item index="/baseData">基础数据</el-menu-item> 18 <el-menu-item index="/GPURealTime">GPU实时统计</el-menu-item> 19 </el-submenu> 20 <el-submenu index="1-2" v-if="is_administrator"> 21 <template slot="title"> 22 <i class="el-icon-time"></i> 23 <span>主机部署</span> 24 </template> 25 <el-menu-item index="/hostScan">主机扫描</el-menu-item> 26 </el-submenu> 27 <el-submenu index="1-3"> 28 <template slot="title"> 29 <i class="el-icon-plus"></i> 30 <span>设备管理</span> 31 <span class="red-dots dot-little" v-show="btext.bool || storageSpace"></span> 32 </template> 33 <el-menu-item index="/deviceList">设备列表</el-menu-item> 34 <el-menu-item index="/hostList">主机列表 35 <span class="red-dots " v-show="btext.bool">{{btext.num}}</span> 36 </el-menu-item> 37 <el-menu-item index="/modelList">模板列表</el-menu-item> 38 <el-menu-item index="/spaceList">存储空间列表 39 <span class="red-dots" v-show="storageSpace>0">{{storageSpace}}</span> 40 </el-menu-item> 41 <el-menu-item index="/priceList">价格列表</el-menu-item> 42 <el-menu-item index="/networkAgent">网络代理列表</el-menu-item> 43 </el-submenu> 44 <el-submenu index="1-4"> 45 <template slot="title"> 46 <i class="el-icon-goods"></i> 47 <span>市场管理</span> 48 <span class="red-dots dot-little" v-show="workerOrderApply>0"></span> 49 </template> 50 <el-menu-item index="/serviceList">服务列表</el-menu-item> 51 <el-menu-item index="/workOrderList">工单列表 52 <span class="red-dots" v-show="workerOrderApply>0">{{workerOrderApply}}</span> 53 </el-menu-item> 54 <el-menu-item index="/createWorkOrder">创建工单</el-menu-item> 55 <el-menu-item index="/AISoundCode">AI 源码列表</el-menu-item> 56 </el-submenu> 57 <el-submenu index="1-5"> 58 <template slot="title"> 59 <i class="el-icon-printer"></i> 60 <span>财务管理</span> 61 <span class="red-dots dot-little" v-show="billingApply>0"></span> 62 </template> 63 <el-menu-item index="/invoiceProcessing">发票管理 64 <span class="red-dots" v-show="billingApply>0">{{billingApply}}</span> 65 </el-menu-item> 66 <el-menu-item index="/rechargeInfo">收入管理</el-menu-item> 67 <el-menu-item index="/expenditure">支出管理</el-menu-item> 68 <el-menu-item index="/systemPresented">系统赠送</el-menu-item> 69 </el-submenu> 70 <el-submenu index="1-6"> 71 <template slot="title"> 72 <i class="el-icon-user-solid"></i> 73 <span>用户管理</span> 74 </template> 75 <el-menu-item index="/userInfo">用户列表</el-menu-item> 76 <el-menu-item index="/wxUserList">微信用户列表</el-menu-item> 77 </el-submenu> 78 <el-submenu index="1-7"> 79 <template slot="title"> 80 <i class="el-icon-share"></i> 81 <span>推广管理</span> 82 <span class="red-dots dot-little" v-show="(ambassadorApply>0 || withdrawApply>0)"></span> 83 </template> 84 <el-menu-item index="/recommendApply">推广申请 85 <span class="red-dots" v-show="ambassadorApply>0">{{ambassadorApply}}</span> 86 </el-menu-item> 87 <el-menu-item index="/withdrawApply">提现申请 88 <span class="red-dots" v-show="withdrawApply>0">{{withdrawApply}}</span> 89 </el-menu-item> 90 <el-menu-item index="/recommendList">推广信息列表</el-menu-item> 91 </el-submenu> 92 <el-submenu index="1-8"> 93 <template slot="title"> 94 <i class="el-icon-edit"></i> 95 <span>活动管理</span> 96 </template> 97 <el-menu-item index="/discountList">折扣列表</el-menu-item> 98 <el-menu-item index="/activityList">活动列表</el-menu-item> 99 </el-submenu> 100 <el-submenu index="1-9"> 101 <template slot="title"> 102 <i class="el-icon-news"></i> 103 <span>公告管理</span> 104 </template> 105 <el-menu-item index="/notice">公告列表</el-menu-item> 106 </el-submenu> 107 <el-submenu index="1-10" v-if="is_administrator"> 108 <template slot="title"> 109 <i class="el-icon-setting"></i> 110 <span>权限管理</span> 111 </template> 112 <el-menu-item index="/userRole">角色列表</el-menu-item> 113 <el-menu-item index="/permission">权限列表</el-menu-item> 114 <el-menu-item index="/role">角色管理</el-menu-item> 115 </el-submenu> 116 </el-submenu> 117 <el-submenu index="2"> 118 <template slot="title"> 119 <i class="el-icon-document"></i> 120 <span>统计分析</span> 121 </template> 122 <el-submenu index="2-1"> 123 <template slot="title"> 124 <i class="el-icon-document"></i> 125 <span>设备使用情况</span> 126 </template> 127 <el-menu-item index="/equipData">GPU 租用总量总计</el-menu-item> 128 <el-menu-item index="/GPUAvailability">GPU 利用率统计</el-menu-item> 129 <el-menu-item index="/GPUUsed">GPU 使用分时统计</el-menu-item> 130 <el-menu-item index="/GPURent">GPU 租用采样统计</el-menu-item> 131 <el-menu-item index="/GPUUtilizationHeap">GPU 利用率堆积图</el-menu-item> 132 <el-menu-item index="/GPURentBenefit">GPU 租用效益统计</el-menu-item> 133 <!-- <el-menu-item index="/occupancyAnalysis">租用量分析</el-menu-item> 134 <el-menu-item index="/rentalFeeAnalysis">租赁费分析</el-menu-item> --> 135 <!-- <el-menu-item index="/rentalBenefitAnalysis">租用效益分析</el-menu-item> --> 136 </el-submenu> 137 <el-submenu index="2-2"> 138 <template slot="title"> 139 <i class="el-icon-document"></i> 140 <span>用户基本情况</span> 141 </template> 142 <el-menu-item index="/userGrow">用户增长统计</el-menu-item> 143 <el-menu-item index="/userRegister">用户注册时间分布</el-menu-item> 144 <el-menu-item index="/userInformat">用户活跃量统计</el-menu-item> 145 <el-menu-item index="/useTime">使用时长统计</el-menu-item> 146 <el-menu-item index="/userAttribute">用户属性统计</el-menu-item> 147 <el-menu-item index="/visitor">用户排行榜</el-menu-item> 148 <el-menu-item index="/visitStatistics">网站访问统计</el-menu-item> 149 </el-submenu> 150 <el-submenu index="2-7"> 151 <template slot="title"> 152 <i class="el-icon-pie-chart"></i> 153 <span>用户分布统计</span> 154 </template> 155 <el-menu-item index="/provinceStatistics">省份人数分布</el-menu-item> 156 <el-menu-item index="/cityStatistics">城市人数分布</el-menu-item> 157 <el-menu-item index="/schoolStatistics">学校人数分布</el-menu-item> 158 </el-submenu> 159 <el-submenu index="2-3"> 160 <template slot="title"> 161 <i class="el-icon-document"></i> 162 <span>用户 GPU 利用率</span> 163 </template> 164 <el-menu-item index="/rankingList">用户 GPU 利用率排行榜</el-menu-item> 165 </el-submenu> 166 <el-submenu index="2-4"> 167 <template slot="title"> 168 <i class="el-icon-document"></i> 169 <span>用户消费情况</span> 170 </template> 171 <el-menu-item index="/userExpense">消费类型统计</el-menu-item> 172 <el-menu-item index="/mainframeLease">主机租赁统计</el-menu-item> 173 <el-menu-item index="/incrementService">增值服务统计</el-menu-item> 174 <el-menu-item index="/ticketsUsed">消费券使用记录</el-menu-item> 175 <el-menu-item index="/codeList">AI 源码用户购买列表</el-menu-item> 176 </el-submenu> 177 <el-submenu index="2-5"> 178 <template slot="title"> 179 <i class="el-icon-document"></i> 180 <span>用户充值情况</span> 181 </template> 182 <el-menu-item index="/userRecharge">用户充值额统计</el-menu-item> 183 <el-menu-item index="/userRechargeType">用户充值渠道统计</el-menu-item> 184 </el-submenu> 185 <el-submenu index="2-6"> 186 <template slot="title"> 187 <i class="el-icon-document"></i> 188 <span>公司收支分析</span> 189 </template> 190 <el-menu-item index="/comparative">收支对比</el-menu-item> 191 <el-menu-item index="/income">收入统计</el-menu-item> 192 <el-menu-item index="/expenditureTow">支出统计</el-menu-item> 193 </el-submenu> 194 </el-submenu> 195 <el-submenu index='3'> 196 <template slot="title"> 197 <i class="el-icon-s-promotion"></i> 198 <span>直达</span> 199 </template> 200 <!-- <el-menu-item index="/nonstop">快捷方式设置</el-menu-item> --> 201 <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> 202 </el-submenu> 203 </el-menu> 204 </el-col> 205 <el-col :span="(24-width)" style="height: 100%"> 206 <head-top v-on:changeMenu='openAMenu'></head-top> 207 <div class="content"> 208 <keep-alive> 209 <router-view></router-view> 210 </keep-alive> 211 <div class="scrollbar"></div> 212 </div> 213 </el-col> 214 </el-row> 215 </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(206, 43, 43); }
如何实现小红点的判断:
1 <template slot="title"> 2 <i class="el-icon-plus"></i> 3 <span>设备管理</span> 4 <span class="red-dots dot-little" v-show="btext.bool || storageSpace"></span> 5 </template>
路由跳转
1 <el-menu-item index="/userExpense">消费类型统计</el-menu-item> 2 <el-menu-item index="/mainframeLease">主机租赁统计</el-menu-item> 3 <el-menu-item index="/incrementService">增值服务统计</el-menu-item> 4 <el-menu-item index="/ticketsUsed">消费券使用记录</el-menu-item> 5 <el-menu-item index="/codeList">AI 源码用户购买列表</el-menu-item>
- 顶部导航栏功能的实现(后台)
排版代码:
1 <template> 2 <div class="header-container"> 3 <el-breadcrumb separator="/"> 4 <el-breadcrumb-item :to="{ path: '/manage' }">首页</el-breadcrumb-item> 5 <el-breadcrumb-item v-for="item in $route.meta" :key="item.index"> 6 <span :class="{'is-link':item.index!==undefined}" @click="openMenu(item.index)">{{item.name}}</span> 7 </el-breadcrumb-item> 8 </el-breadcrumb> 9 <div class="userInfo-box"> 10 <template v-if="canAdd!==null"> 11 <el-button class="addNonstop" size="small" type="primary" @click="setShortcut('post')" v-if="canAdd===1">添加直达</el-button> 12 <el-button class="addNonstop" size="small" type="warning" @click="setShortcut('delete')" v-if="canAdd===0">取消直达</el-button> 13 </template> 14 <img src='../assets/default.jpg' class="avator"> 15 <ul class="userInfo"> 16 <li>{{username}}</li> 17 <li>|</li> 18 <li @click="loginOut">退出</li> 19 </ul> 20 </div> 21 </div> 22 </template>
子组件向父组件传路由值
1 <el-breadcrumb-item v-for="item in $route.meta" :key="item.index"> 2 <span :class="{'is-link':item.index!==undefined}" @click="openMenu(item.index)">{{item.name}}</span> 3 </el-breadcrumb-item>
1 openMenu(index){ 2 if(index){ 3 this.$emit('changeMenu',index); //$emit 绑定一个自定义事件event,当这个这个语句被执行到的时候,就会将参数arg传递给父组件,父组件通过@event监听并接收参数 4 } 5 }
父组件获取路由值
1 <head-top v-on:changeMenu='openTheMenu'></head-top>
//打开指定菜单 openTheMenu(index) { this.$refs["homeMenu"].open(index); }
- 订单查询功能(后台)
整个页面:
1 <script> 2 import Utils from "@/utils/utils"; 3 import { createNamespacedHelpers } from 'vuex' 4 const { mapState, mapActions } = createNamespacedHelpers('financial') 5 export default { 6 data() { 7 return { 8 showPagination: false, 9 pickerBeginDateBefore: { 10 disabledDate: time => { 11 if (this.end_date) { 12 return ( 13 time.getTime() > this.end_date || time.getTime() > Date.now() 14 ); 15 } 16 } 17 }, 18 pickerBeginDateAfter: { 19 disabledDate: time => { 20 if (this.begin_date) { 21 return ( 22 time.getTime() < this.begin_date || time.getTime() > Date.now() 23 ); 24 } 25 } 26 }, 27 origin_list: [ 28 "全部", 29 "后台-淘宝-易学智能", 30 "后台-淘宝-GPU远程租用", 31 "平台-支付宝", 32 "后台-淘宝充值", 33 "后台-银行公账-深圳兴导", 34 '后台-银行公账-湖南兴导', 35 "后台-淘宝-国科机房", 36 '平台-微信' 37 ], 38 time_list: [ 39 { name: "本日", val: "today" }, 40 { name: "本周", val: "this_week" }, 41 { name: "本月", val: "this_month" }, 42 { name: "上月", val: "last_month" }, 43 { name: "日期范围", val: "date_range" } 44 ], 45 add_list: [{ 46 name:"全部", 47 id:0 48 },{ 49 name:"充值", 50 id:1 51 },{ 52 name:"快递费", 53 id:5 54 },{ 55 name:"增值服务", 56 id:6 57 }], 58 origin: 0, 59 add_type: 0, 60 time_type: "today", 61 begin_date: new Date(2018,10,15), 62 end_date: new Date(), 63 total_data: { 64 total: 0 65 }, 66 table_loading: false, 67 page_size: 20, 68 order_by: null, 69 order: null, 70 input:null, 71 order_number:null 72 }; 73 }, 74 watch: { 75 $route(to, from) { 76 if (to.path === "/rechargeInfo" && from.path !== "/userDetails") { 77 this.total_data = {}; 78 this.origin=0; 79 this.add_type=0; 80 this.time_type="today"; 81 this.begin_date=new Date(2018,10,15); 82 this.end_date=new Date(); 83 this.showPagination = false; 84 this.order = null; 85 this.order_by = null; 86 this.search(1); 87 } 88 } 89 }, 90 created() { 91 this.search(1); 92 }, 93 methods: { 94 ...mapActions(["rechargeListAPI", "downloadRechargeAPI"]), 95 //分页 96 changePage(value) { 97 this.search(value); 98 this.$refs['pageTwo'].internalCurrentPage = this.$refs['pageOne'].internalCurrentPage;//绑定页数 99 }, 100 changePageTwo(value){ 101 this.search(value); 102 this.$refs['pageOne'].internalCurrentPage = this.$refs['pageTwo'].internalCurrentPage; 103 }, 104 //排序 105 sortMethod(){ 106 this.order_by = 'add_time'; 107 this.order = this.order === 'desc'? 'asc': 'desc'; 108 this.showPagination=false; 109 this.search(1); 110 }, 111 //进入用户详情 112 searchOne(id) { 113 this.$router.push({ path: "userDetails?id=" + id, replace: true }); 114 }, 115 //查询充值明细 116 search(page) { 117 if (!Utils.checkToken(this)) return; 118 if(this.time_type==='date_range'&&(!this.begin_date||!this.end_date)){ 119 return this.$message.error('请选择时间!'); 120 } 121 this.table_loading = true; 122 this.rechargeListAPI({ 123 origin: this.origin, 124 time_type: this.time_type, 125 add_type: this.add_type, 126 begin_date: Utils.formatDate(this.begin_date, "yyyy-MM-dd"), 127 end_date: Utils.formatDate(this.end_date, "yyyy-MM-dd"), 128 page: page, 129 page_size: this.page_size, 130 order_by: this.order_by, 131 order: this.order, 132 order_number:this.order_number 133 }).then( 134 ({body}) => { 135 this.total_data = body; 136 this.table_loading = false; 137 this.showPagination = true; 138 }, 139 err => { 140 this.table_loading = false; 141 this.showPagination = true; 142 this.$message.error(err.msg); 143 } 144 ); 145 }, 146 //下载明细单 147 download(page) { 148 if (!Utils.checkToken(this)) return; 149 const loading = this.$loading(); 150 this.downloadRechargeAPI({ 151 origin: this.origin, 152 time_type: this.time_type, 153 add_type: this.add_type, 154 begin_date: Utils.formatDate(this.begin_date, "yyyy-MM-dd"), 155 end_date: Utils.formatDate(this.end_date, "yyyy-MM-dd"), 156 order: this.order, 157 order_by: this.order_by, 158 }).then( 159 res => { 160 loading.close(); 161 const blob = res.data; 162 const fileName = decodeURI(res.headers.map["content-disposition"][0].split(";")[1].split("=")[1]) || '易学智能-充值明细单.xlsx'; 163 if ("download" in document.createElement("a")) { 164 // 非IE下载 165 const elink = document.createElement("a"); 166 elink.download = fileName; 167 elink.style.display = "none"; 168 elink.href = URL.createObjectURL(blob); 169 document.body.appendChild(elink); 170 elink.click(); 171 URL.revokeObjectURL(elink.href); // 释放URL 对象 172 document.body.removeChild(elink); 173 } else { 174 // IE10+下载 175 navigator.msSaveBlob(blob, fileName); 176 } 177 }, 178 err => { 179 loading.close(); 180 this.$message.error(err.msg); 181 } 182 ); 183 }, 184 //订单号获得焦点事件 //zcg 185 focus(){ 186 this.time_type ='date_range' 187 this.search(1); 188 }, 189 //订单号change事件 190 changeInput(value){ 191 this.order_number =value 192 this.search(1); 193 } 194 } 195 }; 196 </script> 197 <template> 198 <div> 199 <p class="title title-primary">充值明细查询</p> 200 <el-form label-width="100px" label-position="left"> 201 <el-form-item label="来源:"> 202 <el-radio-group v-model="origin" @change="showPagination=false,search(1)"> 203 <el-radio v-for='(item,index) in origin_list' :key="index" :label="index">{{item}}</el-radio> 204 </el-radio-group> 205 </el-form-item> 206 <el-form-item label="充值类型:"> 207 <el-radio-group v-model="add_type" @change="showPagination=false,search(1)"> 208 <el-radio v-for='(item,index) in add_list' :key="index" :label="item.id">{{item.name}}</el-radio> 209 </el-radio-group> 210 </el-form-item> 211 <el-form-item label="时间类型:"> 212 <el-radio-group v-model="time_type" @change="showPagination=false,search(1)"> 213 <el-radio v-for='(item,index) in time_list' :key="index" :label="item.val">{{item.name}}</el-radio> 214 </el-radio-group> 215 </el-form-item> 216 <el-form-item label="起始日期:" v-show="time_type==='date_range'"> 217 <el-date-picker v-model="begin_date" type="date" placeholder="开始时间" format="yyyy-MM-dd" :picker-options="pickerBeginDateBefore"> 218 </el-date-picker> 219 <el-date-picker v-model="end_date" type="date" placeholder="结束时间" format="yyyy-MM-dd" :picker-options="pickerBeginDateAfter"> 220 </el-date-picker> 221 <el-button type="primary" @click="showPagination=false,search(1)">查询记录</el-button> 222 </el-form-item> 223 <el-form-item label="订单号:" class="nav-btns nav-input"> 224 <el-input placeholder="输入订单号" clearable v-model="input" @focus="focus" @input="changeInput"></el-input> 225 </el-form-item> 226 <el-form-item> 227 <el-button type="warning" @click="download">全部下载</el-button> 228 </el-form-item> 229 </el-form> 230 <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> 231 <el-table :data="total_data.data" v-loading="table_loading"> 232 <el-table-column label="序号" type="index" width="100px"> 233 </el-table-column> 234 <el-table-column label="用户名" prop="user_name"> 235 <template slot-scope="scope"> 236 <span @click="searchOne(scope.row.uid)" class="font-jump">{{scope.row.user_name}}</span> 237 </template> 238 </el-table-column> 239 <el-table-column label="充值时间" prop="add_time"> 240 <template slot="header" slot-scope="scope"> 241 <span @click="sortMethod('add_time')">充值时间 242 <i class="el-icon-sort" v-if="order_by!='add_time'"></i> 243 <template v-else> 244 <i class="el-icon-sort-down" v-if="order =='desc'"></i> 245 <i class="el-icon-sort-up" v-else></i> 246 </template> 247 </span> 248 </template> 249 </el-table-column> 250 <el-table-column label="订单号"> 251 <template slot-scope="scope"> 252 <p>{{scope.row.order_number?scope.row.order_number:'无'}}</p> 253 </template> 254 </el-table-column> 255 <el-table-column label="来源" prop="origin"> 256 </el-table-column> 257 <el-table-column label="备注"> 258 <template slot-scope="scope"> 259 <p>{{scope.row.comment?scope.row.comment:'无'}}</p> 260 </template> 261 </el-table-column> 262 <el-table-column label="充值金额(元)" prop="receipt_amount"> 263 </el-table-column> 264 <el-table-column label="操作人" prop="admin_username"> 265 </el-table-column> 266 </el-table> 267 <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> 268 </div> 269 </template>
排版:
1 <el-form-item label="订单号:" class="nav-btns nav-input"> 2 <el-input placeholder="输入订单号" clearable v-model="input" @focus="focus" @input="changeInput"></el-input> 3 </el-form-item> 4 <el-form-item> 5 <el-button type="warning" @click="download">全部下载</el-button> 6 </el-form-item
功能的实现:
1 1 focus(){ 2 2 this.time_type ='date_range' 3 3 this.search(1); 4 4 }, 5 5 //订单号change事件 6 6 changeInput(value){ 7 7 this.order_number =value 8 8 this.search(1); 9 9 } 10 10 }
查询时间:
1 search(page) { 2 if (!Utils.checkToken(this)) return; 3 if(this.time_type==='date_range'&&(!this.begin_date||!this.end_date)){ 4 return this.$message.error('请选择时间!'); 5 } 6 this.table_loading = true; 7 this.rechargeListAPI({ 8 origin: this.origin, 9 time_type: this.time_type, 10 add_type: this.add_type, 11 begin_date: Utils.formatDate(this.begin_date, "yyyy-MM-dd"), 12 end_date: Utils.formatDate(this.end_date, "yyyy-MM-dd"), 13 page: page, 14 page_size: this.page_size, 15 order_by: this.order_by, 16 order: this.order, 17 order_number:this.order_number 18 }).then( 19 ({body}) => { 20 this.total_data = body; 21 this.table_loading = false; 22 this.showPagination = true; 23 }, 24 err => { 25 this.table_loading = false; 26 this.showPagination = true; 27 this.$message.error(err.msg); 28 } 29 ); 30 },
下载明细文件:
1 download(page) { 2 if (!Utils.checkToken(this)) return; 3 const loading = this.$loading(); 4 this.downloadRechargeAPI({ 5 origin: this.origin, 6 time_type: this.time_type, 7 add_type: this.add_type, 8 begin_date: Utils.formatDate(this.begin_date, "yyyy-MM-dd"), 9 end_date: Utils.formatDate(this.end_date, "yyyy-MM-dd"), 10 order: this.order, 11 order_by: this.order_by, 12 }).then( 13 res => { 14 loading.close(); 15 const blob = res.data; 16 const fileName = decodeURI(res.headers.map["content-disposition"][0].split(";")[1].split("=")[1]) || '易学智能-充值明细单.xlsx'; 17 if ("download" in document.createElement("a")) { 18 // 非IE下载 19 const elink = document.createElement("a"); 20 elink.download = fileName; 21 elink.style.display = "none"; 22 elink.href = URL.createObjectURL(blob); 23 document.body.appendChild(elink); 24 elink.click(); 25 URL.revokeObjectURL(elink.href); // 释放URL 对象 26 document.body.removeChild(elink); 27 } else { 28 // IE10+下载 29 navigator.msSaveBlob(blob, fileName); 30 } 31 }, 32 err => { 33 loading.close(); 34 this.$message.error(err.msg); 35 } 36 ); 37 },
1 const state = { 2 billingList:{}, 3 billingOrders:{} 4 } 5 6 const actions = { 7 /* 发票管理 */ 8 //开票待处理、已开票、已拒绝列表 9 async billingInfoAPI({dispatch,commit},query) { 10 return await dispatch('callingInterface',{ 11 request_method:'get', 12 API_url:'gpu_admin/finance/bill/apply_list', 13 query:{ 14 params:query 15 }, 16 callback:({body})=>{ 17 commit('setState',{ 18 childName:'financial', 19 name:'billingList', 20 val:body 21 },{root:true}) 22 } 23 },{root:true}) 24 }, 25 //开票相关订单信息 26 async billingOrdersInfoAPI({dispatch,commit},query) { 27 return await dispatch('callingInterface',{ 28 request_method:'get', 29 API_url:'gpu_admin/finance/bill/order_list', 30 query:{ 31 params:query 32 }, 33 callback:({body})=>{ 34 commit('setState',{ 35 childName:'financial', 36 name:'billingOrders', 37 val:body 38 },{root:true}) 39 } 40 },{root:true}) 41 }, 42 //开票完成信息提交 43 async billingCompleteAPI({dispatch},query) { 44 return await dispatch('callingInterface',{ 45 request_method:'post', 46 API_url:'gpu_admin/finance/bill/dealt', 47 query:query 48 },{root:true}) 49 }, 50 //发票数据总计 51 async billingAmountAPI({dispatch}) { 52 return await dispatch('callingInterface',{ 53 request_method:'get', 54 API_url:'gpu_admin/finance/billinfo' 55 },{root:true}) 56 }, 57 58 /* 充值明细 */ 59 //充值明细记录 60 async rechargeListAPI({dispatch},query) { 61 return await dispatch('callingInterface',{ 62 request_method:'get', 63 API_url:'gpu_admin/finance/recharge_list', 64 query:{ 65 params:query 66 } 67 },{root:true}) 68 }, 69 //下载充值明细 70 async downloadRechargeAPI({dispatch},query) { 71 return await dispatch('callingInterface',{ 72 request_method:'get', 73 API_url:'gpu_admin/finance/recharge_list_excel', 74 query:{ 75 headers:{'Content-Type':'application/ms-excel'}, 76 responseType:'blob', 77 params:query, 78 } 79 },{root:true}) 80 }, 81 82 /* 系统赠送 */ 83 //系统赠送明细记录 84 async presentedListAPI({dispatch},query) { 85 return await dispatch('callingInterface',{ 86 request_method:'get', 87 API_url:'gpu_admin/finance/syspresented_list', 88 query:{ 89 params:query 90 } 91 },{root:true}) 92 }, 93 //下载系统赠送明细 94 async downloadPresentedAPI({dispatch},query) { 95 return await dispatch('callingInterface',{ 96 request_method:'get', 97 API_url:'gpu_admin/finance/syspresented_list_excel', 98 query:{ 99 headers:{'Content-Type':'application/ms-excel'}, 100 responseType:'blob', 101 params:query 102 } 103 },{root:true}) 104 }, 105 //支出信息 106 async expenditureAPI({dispatch},query) { 107 return await dispatch('callingInterface',{ 108 request_method:'get', 109 API_url:'gpu_admin/and_payments/expenditure', 110 query:{ 111 params:query 112 }, 113 flag : true 114 },{root:true}) 115 }, 116 //添加支出 117 async expenditureAddAPI({dispatch},query) { 118 return await dispatch('callingInterface',{ 119 request_method:'post', 120 API_url:'gpu_admin/and_payments/expenditure', 121 query:query 122 },{root:true}) 123 }, 124 //用户名列表 125 async usernamelistAPI({dispatch},query) { 126 return await dispatch('callingInterface',{ 127 request_method:'get', 128 API_url:'gpu_admin/usernamelist', 129 query:{ 130 params:query 131 } 132 },{root:true}) 133 }, 134 //用户充值记录 135 async add_money_logAPI({dispatch},query) { 136 return await dispatch('callingInterface',{ 137 request_method:'get', 138 API_url:'gpu_admin/and_payments/add_money_log', 139 query:{ 140 params:query 141 } 142 },{root:true}) 143 }, 144 145 146 //财务管理 147 148 //收入信息 -充值信息 149 async incomeAPI({dispatch},query) { 150 return await dispatch('callingInterface',{ 151 request_method:'get', 152 API_url:'gpu_admin/finance/income', 153 query:{ 154 params:query 155 } 156 },{root:true}) 157 }, 158 159 //收入信息 -充值信息 160 async incomegraphAPI({dispatch},query) { 161 return await dispatch('callingInterface',{ 162 request_method:'get', 163 API_url:'gpu_admin/finance/incomegraph', 164 query:{ 165 params:query 166 } 167 },{root:true}) 168 }, 169 170 //收入每日/周/月信息 171 async incomedetailAPI({dispatch},query) { 172 return await dispatch('callingInterface',{ 173 request_method:'get', 174 API_url:'gpu_admin/finance/incomedetail', 175 query:{ 176 params:query 177 } 178 },{root:true}) 179 }, 180 181 } 182 183 export default{ 184 namespaced:true, 185 state, 186 actions 187 }
调用接口JS代码:
1 callingInterface({},{request_method,API_url,query,flag,callback}){ 2 //请求地址+API 3 const url = localhost + API_url; 4 //是否开启emulateJSON 5 const is_flag = flag!==undefined ? flag : false; 6 //回调函数,处理提交mutaion修改state的操作 7 const callMethod = callback!==undefined ? callback : (()=>{}); 8 console.log('请求传入参数query:', query) 9 10 return new Promise((resolve, reject) => { 11 Vue.http[request_method](url, query ,{ 12 emulateJSON: is_flag 13 }).then(res => { 14 resolve(res); 15 callMethod(res); 16 console.log('请求成功:', res); 17 }, err => { 18 console.log('请求失败:', err) 19 reject(err.body) 20 }) 21 }) 22 },
点击按钮查询不同的数据(利用v-model的双向绑定原理和v-on:change事件)
1 <el-form-item label="来源:"> 2 <el-radio-group v-model="origin" @change="showPagination=false,search(1)"> 3 <el-radio v-for='(item,index) in origin_list' :key="index" :label="index">{{item}}</el-radio> 4 </el-radio-group> 5 </el-form-item> 6 <el-form-item label="充值类型:"> 7 <el-radio-group v-model="add_type" @change="showPagination=false,search(1)"> 8 <el-radio v-for='(item,index) in add_list' :key="index" :label="item.id">{{item.name}}</el-radio> 9 </el-radio-group> 10 </el-form-item> 11 <el-form-item label="时间类型:"> 12 <el-radio-group v-model="time_type" @change="showPagination=false,search(1)"> 13 <el-radio v-for='(item,index) in time_list' :key="index" :label="item.val">{{item.name}}</el-radio> 14 </el-radio-group> 15 </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 }
详情页面的获取信息功能:
1 getUserDetails(){ 2 this.uid = this.$route.query.id;// 根据路由ID的不同,返回不同的数据 3 this.getUserInfo(); 4 this.getExtraInfo(); 5 this.getExpenseInfo(); 6 },
getUserInfo:
1 getUserInfo() { 2 if (!Utils.checkToken(this)) return; 3 this.pageLoading = true; 4 this.userInfoDetailsAPI({//通过API接口获取数据 5 uid: this.uid 6 }).then( 7 ({body}) => { 8 this.pageLoading = false; 9 this.sendData = Object.assign(this.sendData,{user_name:body.user_name,balance:body.balance}) 10 this.userInfo = body; 11 }, 12 err => { 13 this.pageLoading = false; 14 this.$message.error(err.msg); 15 } 16 ); 17 }
监听:
1 watch: { 2 $route(to, from) { 3 if (to.path === "/userDetails") { 4 this.showPagination = false; 5 this.record_type= 'expenseRecord'; 6 this.record_son_type= 0; 7 this.pageInfo={ 8 page:1, 9 page_size:10 10 }; 11 this.date= [Utils.formatDate(new Date("2018/11/15"), "yyyy-MM-dd"), Utils.formatDate(new Date(), "yyyy-MM-dd")]; 12 this.userInfo = {} 13 this.extraInfo = {} 14 this.expenseInfo = {} 15 this.sendData = {} 16 this.getUserDetails(); 17 } 18 }
生命周期钩子函数:
1 created() { 2 this.getUserDetails(); 3 },
- 点击显示订单详情
利用饿了么组件(不同之处:利用计算属性来获得数据)
1 <el-dialog title="订单信息" :visible.sync="openOrderInfo" width="1000px" center :close-on-click-modal='false'> 2 <el-table :data="billingOrders.data" border> 3 <el-table-column label="序号" type="index" width="100px"> 4 </el-table-column> 5 <el-table-column label="可开票金额(元)" prop="available_bill"> 6 </el-table-column> 7 <el-table-column label="实收金额(元)" prop="receipt_amount"> 8 </el-table-column> 9 <el-table-column label="充值来源" prop="origin"> 10 </el-table-column> 11 <el-table-column label="订单号" prop="order_number"> 12 </el-table-column> 13 <el-table-column label="订单类型" prop="order_type"> 14 </el-table-column> 15 <el-table-column label="充值时间" prop="add_time"> 16 </el-table-column> 17 </el-table> 18 </el-dialog>
数据获取(使用了命名空间):
1 import { createNamespacedHelpers } from 'vuex' 2 const { mapState, mapActions } = createNamespacedHelpers('financial') 3 4 computed:{ 5 ...mapState(['billingList','billingOrders']) 6 }
命名空间获取billingOrders值:(命名空间:将模块的空间名称字符串作为第一个参数传递给上述函数,这样所有绑定都会自动将该模块作为上下文。)
命名空间: 默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
1 async billingOrdersInfoAPI({dispatch,commit},query) { 2 return await dispatch('callingInterface',{ 3 request_method:'get', 4 API_url:'gpu_admin/finance/bill/order_list', 5 query:{ 6 params:query 7 }, 8 callback:({body})=>{ 9 commit('setState',{//到setstate去设置state的值 10 childName:'financial',//字符串,为了setState可以[""] 11 name:'billingOrders',//字符串,为了setState可以[""] 12 val:body 13 },{root:true}) 14 } 15 },{root:true}) 16 },
提交到setState:(mutations.js文件)
1 const mutations = { 2 //设置state的值 3 setState(state,{name,val,childName}){ 4 if(childName!==undefined){ 5 state[childName][name] = val 6 }else{ 7 state[name] = val 8 } 9 } 10 } 11 12 export default{ 13 mutations 14 }
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true
的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。例如:
billingOrders来源:(接口获取)
1 async billingOrdersInfoAPI({dispatch,commit},query) { 2 return await dispatch('callingInterface',{ 3 request_method:'get', 4 API_url:'gpu_admin/finance/bill/order_list', 5 query:{ 6 params:query 7 }, 8 callback:({body})=>{ 9 commit('setState',{ 10 childName:'financial', 11 name:'billingOrders',//回调函数 12 val:body 13 },{root:true}) 14 } 15 },{root:true}) 16 },
命名来源:(Store下的index.js文件):
1 import Vue from 'vue' 2 import Vuex from 'vuex' 3 4 import fooActions from './actions' 5 import fooMutations from './mutations' 6 import login from './modules/login' 7 import realTimeData from './modules/real_time_data' 8 import deploy from './modules/deploy' 9 import device from './modules/device' 10 import financial from './modules/financial' 11 import userInfo from './modules/user_info' 12 import recommend from './modules/recommend' 13 import activity from './modules/activity' 14 import userLimit from './modules/user_limit' 15 import recharge from './modules/recharge' 16 import statistics from './modules/statistics' 17 import equipUsageInfo from './modules/equip_usage_info' 18 import userExpenseData from './modules/user_expense_data' 19 import market from './modules/market' 20 import GPUUseRatio from './modules/GPU_use_ratio' 21 import expenses from "./modules/expenses" 22 import userDistribution from "./modules/user_distribution" 23 // import createLogger from '../../../src/plugins/logger' 24 25 Vue.use(Vuex) 26 const debug = process.env.NODE_ENV !== 'production' 27 28 const state = { 29 applyData:{}, 30 urlList:[] 31 } 32 33 export default new Vuex.Store({ 34 state:state, 35 actions:fooActions.actions, 36 mutations:fooMutations.mutations, 37 modules:{ 38 login, 39 realTimeData, 40 deploy, 41 device, 42 financial, 43 userInfo, 44 recommend, 45 activity, 46 userLimit, 47 recharge, 48 statistics, 49 equipUsageInfo, 50 userExpenseData, 51 market, 52 GPUUseRatio, 53 expenses, 54 userDistribution 55 }, 56 strict: debug, 57 // plugins: debug ? [createLogger()] : [] 58 })
若需要在全局命名空间内分发 action 或提交 mutation,将 { root: true }
作为第三参数传给 dispatch
或 commit
即可。
{ root: true }
作为第三参数传给 dispatch
或 commit
即可。 未用命名空间:
1 import { mapActions,mapState } from "vuex" 2 computed: { 3 ...mapState({ 4 deploy_status:state=>state.deploy.deploy_status, 5 status_color:state=>state.deploy.status_color 6 }), 7 8 methods: { 9 ...mapActions({ 10 deployListAPI:'deploy/deployListAPI', 11 deployServerAPI:'deploy/deployServerAPI' 12 }),
回调接口;
1 callingInterface({},{request_method,API_url,query,flag,callback}){ 2 //请求地址+API 3 const url = localhost + API_url; 4 //是否开启emulateJSON 5 const is_flag = flag!==undefined ? flag : false; 6 //回调函数,处理提交mutaion修改state的操作 7 const callMethod = callback!==undefined ? callback : (()=>{}); 8 console.log('请求传入参数query:', query) 9 10 return new Promise((resolve, reject) => { 11 Vue.http[request_method](url, query ,{ 12 emulateJSON: is_flag 13 }).then(res => { 14 resolve(res); 15 callMethod(res); //如果传了callback,就有意义,如果没传callback 就是(){} 空函数,执行了也没效果 16 console.log('请求成功:', res); 17 }, err => { 18 console.log('请求失败:', err) 19 reject(err.body) 20 }) 21 }) 22 }
- 画图: =====>见另一篇博文 Echarts配置
- 点击按钮触发申请处理表
模板代码:
1 <el-table-column label="操作" v-if="status==='apply'" key="t2" width="120"> 2 <template slot-scope="scope"> // scope 是v-bind绑定数据(:data)后的固定写法
3 <el-button @click="openForm(scope.row)" type="primary" size="small">处理</el-button> 4 </template> 5 </el-table-column>
点击事件代码:
1 //打开处理申请的弹框 2 openForm(row){ 3 this.formData = Object.assign({ 4 order:null//目标 5 },{ 6 id:row.e_id, 7 clearing:row.e_money, 8 }) 9 this.openUpdate = true; 10 },
点击后:
模板代码:
1 <el-dialog title="申请处理" :visible.sync="openUpdate" width="400px" center @closed='clearData' :close-on-click-modal='false'>
//model ====> 表单数据对象 2 <el-form :model="formData" :rules="deal_rules" ref='dealForm' label-width="100px" v-if="formData!==null"> 3 <el-form-item label="提现订单号" prop="order"> 4 <el-input v-model="formData.order"></el-input> 5 </el-form-item> 6 <el-form-item label="提现金额" prop="clearing"> 7 <el-input v-model="formData.clearing"></el-input> 8 </el-form-item> 9 </el-form> 10 <span slot="footer" class="dialog-footer"> 11 <el-button @click="openUpdate = false">取 消</el-button> 12 <el-button type="primary" @click="submitData('dealForm')">确 定</el-button> 13 </span> 14 </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===1000){ this.$message.success(body.msg) this.getApplyInfo(this.page); }else{ this.$message.error(body.msg) } },err=>{ loading.close(); this.$message.error(err.msg) }) } }) }
- 权限:
- 切换角色类型:
1 <el-radio-group v-model="record_type"> 2 <el-radio-button :label="item" v-for="(item,index) in role_list" :key='index'></el-radio-button> 3 </el-radio-group>
监听双向绑定额数据:
1 watch:{ 2 //切换角色类型 3 record_type(newVal,oldVal){ 4 this.showPagination = false; 5 this.getUserRoleList(1); 6 } 7 }
监听数据这里不是函数,而是一个固定写法,第一个参数是new值,第二个参数是old值(而且这里不用this)
- 直达功能
添加直达
模板代码:
1 <template v-if="canAdd!==null"> 2 <el-button class="addNonstop" size="small" type="primary" @click="setShortcut('post')" v-if="canAdd===1">添加直达</el-button> 3 <el-button class="addNonstop" size="small" type="warning" @click="setShortcut('delete')" v-if="canAdd===0">取消直达</el-button> 4 </template>
直达功能代码:
1 setShortcut(method){ 2 if(!Utils.checkToken(this))return; 3 const name = this.$route.meta[2].name? this.$route.meta[2].name: this.$route.meta[1].name; 4 let query; 5 if(method==='delete'){ 6 query = { 7 method:method, 8 data:{ 9 body:{ 10 nav_name:name, 11 nav_url:this.$route.path 12 } 13 } 14 } 15 }else{ 16 query = { 17 method:method, 18 data:{ 19 nav_name:name, 20 nav_url:this.$route.path 21 } 22 } 23 } 24 this.updateShortcutAPI(query).then( 25 res => { 26 this.$message.success(res.body.msg); 27 this.shortcutListAPI() 28 }, 29 err => { 30 this.$message.error(err.msg); 31 } 32 ); 33 }
$route为当前router跳转对象里面可以获取name、path、query、params等
$router为VueRouter实例,想要导航到不同URL,则使用$router.push方法
- 点击曲线获得数据
1 const This = this; 2 let mChart_line1 = This.$echarts.init(document.getElementById("mChart_line")); 3 mChart_line1.getZr().off("click"); // ZRender 一个轻量级的Canvas类库 4 mChart_line1.getZr().on("click", params => { 5 const pointInPixel = [params.offsetX, params.offsetY]; 6 if (mChart_line1.containPixel({ seriesIndex: [0] }, pointInPixel)) { 7 //判断给定的点是否在指定的坐标系或者系列上 8 let xIndex = mChart_line1.convertFromPixel({ seriesIndex: 0 }, [ 9 //转换像素坐标值到逻辑坐标系上的点 10 params.offsetX, 11 params.offsetY 12 ])[0]; /*事件处理代码书写位置*/ 13 This.day = 14 This.date_type === "month" 15 ? This.total_data.date[xIndex] + "-01" 16 : This.total_data.date[xIndex]; 17 This.showPagination = false; 18 this.getData() 19 } 20 });
- 两种查询方式调同一个方法里面的接口: (一个传值,一个不传值) //即使是不同的地方点击事件,里面的参数也会保存。
1 getInvoiceList(page){ 2 if(!Utils.checkToken(this))return; 3 if (this.begin_date === null || this.end_date === null) { 4 this.$message.error("请选择时间!"); 5 return; 6 } 7 this.table_loading = true; 8 this.billingInfoAPI({ 9 begin_date: Utils.formatDate(this.begin_date, "yyyy-MM-dd"), 10 end_date: Utils.formatDate(this.end_date, "yyyy-MM-dd"), 11 status: this.status, 12 page: page, 13 page_size: this.page_size, 14 keyword:this.keyword 15 }).then(res=>{ 16 this.table_loading = false; 17 this.showPagination = true; 18 },err=>{ 19 this.table_loading = false; 20 this.showPagination = true; 21 this.$message.error(err.msg); 22 }) 23 },
invoiceQuery() { this.showPagination = false; this.getInvoiceList(1); }
遍历数据的三种写法:
1.v-for
1 <el-form-item label="来源:"> 2 <el-radio-group v-model="origin" @change="showPagination=false,search(1)"> 3 <el-radio v-for='(item,index) in origin_list' :key="index" :label="index">{{item}}</el-radio> 4 </el-radio-group> 5 </el-form-item>
2.element 模板 利用v-bind绑定数据, 然后传个prop属性作为值。
1 <el-table border :data="userData" v-loading='tableLoadingOne'> 2 <el-table-column label="用户总数" prop="user_total_num"></el-table-column> 3 <el-table-column label="总充值次数" prop="add_money_num"></el-table-column> 4 <el-table-column label="充值总额(元)" prop="add_money_total"></el-table-column> 5 <el-table-column label="总使用次数" prop="rent_num"></el-table-column> 6 <el-table-column label="消费总额(易学币)" prop="cunsumption_money_total"></el-table-column> 7 </el-table>
- 2-1 如果需要对获取的值做个判断,可以在这个里面嵌套个 <template slot-scope = 'scope'> </template> 再用插值表达式判断
3.element表单组件,利用v-bind:model绑定数据,然后利用v-model双向绑定机制输出。
1 <el-form :model="editData" ref="editForm" :rules="rules" v-if="editData!==null" class="recharge-form" label-width="100px"> 2 <el-form-item label="策略编号" prop="policy_reference"> 3 <el-select v-model="editData.policy_reference" placeholder="请选择策略" :disabled="editTitle==='修改折扣'"> 4 <el-option v-for="(item,index) in idList" :key="index" :label="item" :value="item"></el-option> 5 </el-select> 6 </el-form-item>
7 </el-form>
- 通过JS适配移动端WEB页面
1 function adaptation() {//通过JS适配移动端 2 (function(doc, win) { 3 var docEl = doc.documentElement, 4 recalc = function() { 5 var clientWidth = docEl.clientWidth; 6 if (!clientWidth) return; 7 //&&!navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i) 8 if (clientWidth >= 640) { 9 docEl.style.fontSize = '100px'; 10 } else { 11 docEl.style.fontSize = 100 * (clientWidth / 640) + 'px'; 12 } 13 }; 14 // if (!doc.addEventListener) return; 15 // doc.addEventListener('DOMContentLoaded', recalc, false); 16 recalc(); 17 })(document, window); 18 }
待完成 :
- 聊天室(前台)
- 直播 (前台)
- 支付功能(前台)