1、電商管理系統
本系統前端頁面基于Vue和ElemrntUI,后端為node.js撰寫,主要應用于當下市場所流行的電商模式,通過科技的手段,使傳統的商戶交易模式變為更為高效率的電商交易模式,面向全國各地更多的客戶,
專案原始碼https://download.csdn.net/download/Zyw907155124/64631613
https://download.csdn.net/download/Zyw907155124/64631613
2、專案演示
(1)登錄頁面
(2)主頁

(3)用戶管理

管理員可進入:實作模糊搜索、多條件分頁、添加用戶、編輯用戶資訊、洗掉、分配用戶角色等功能,
(4)權限管理
分為1、角色串列;2、權限串列,

角色串列:可通過樹狀結構,查看、添加、修改、洗掉不同層級的權限可訪問的選單項,

權限串列:可查詢上級選單所對應的下級選單,
(5)商品管理
分為:1、商品分類;2、商品串列;3、分類引數
商品分類:


可實作 查看、編輯不同層級的商品分類名稱以及父子級關系,
商品串列:

可實作商品的多條件搜索分頁,以及對具體商品的添加、修改和洗掉操作
本系統對于商品的添加進行了嚴格的校驗和細致的劃分,

對于商品的每一資訊都進行了嚴格的校驗,且未完成前一個步驟的情況下,無法直接跳過去進行下一個步驟的操作,


可上傳商品的圖片,

分類引數:負責查看、修改、洗掉商品分類的動態引數和靜態屬性


(6)訂單管理

可實作查看訂單的詳情、修改訂單付款狀態、修改訂單地址等功能,
(7)資料統計

通過可視化工具實作不同地區用戶的來源數量,
3、原始碼
(1)登錄頁面
<template>
<div class="login_container">
<img src="../assets/img/bizhi2.png" style="width: 100%;height: 850px">
<!-- 登錄盒子 -->
<div class="login_box">
<!-- 頭像 -->
<div class="avatar_box">
<img src="../assets/img/沃爾瑪.jpg" alt="">
</div>
<!-- 登錄表單 -->
<el-form :model="loginForm" ref="LoginFormRef" :rules="loginFormRules" label-width="0px" class="login_form">
<!-- 用戶名 -->
<el-form-item prop="username">
<el-input v-model="loginForm.username" prefix-icon="iconfont icon-user" ></el-input>
</el-form-item>
<!-- 密碼 -->
<el-form-item prop="password">
<el-input type="password" v-model="loginForm.password" prefix-icon="iconfont icon-3702mima"></el-input>
</el-form-item>
<!-- 按鈕 -->
<el-form-item class="btns">
<el-button type="primary" @click="login">登錄</el-button>
<el-button type="info" @click="resetLoginForm">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
export default {
data() {
return {
//資料系結
loginForm: {
username: 'admin',
password: '123456'
},
//表單驗證規則
loginFormRules: {
username: [
{ required: true, message: '請輸入登錄名', trigger: 'blur' },
{
min: 3,
max: 10,
message: '登錄名長度在 3 到 10 個字符',
trigger: 'blur'
}
],
password: [
{ required: true, message: '請輸入密碼', trigger: 'blur' },
{
min: 6,
max: 15,
message: '密碼長度在 6 到 15 個字符',
trigger: 'blur'
}
]
}
}
},
//添加行為,
methods: {
//添加表單重置方法
resetLoginForm() {
//this=>當前組件物件,其中的屬性$refs包含了設定的表單ref
console.log(this)
this.loginForm.username = '';
this.loginForm.password = '';
// this.$refs.LoginFormRef.resetFields()
},
login() {
//點擊登錄的時候先呼叫validate方法驗證表單內容是否有誤
this.$refs.LoginFormRef.validate(async valid => {
console.log(this.loginFormRules)
//如果valid引數為true則驗證通過
if (!valid) {
return
}
//發送請求進行登錄
const { data: res } = await this.$http.post('login', this.loginForm)
// console.log(res);
if (res.meta.status !== 200) {
return this.$message.error('登錄失敗:' + res.meta.msg) //console.log("登錄失敗:"+res.meta.msg)
}
this.$message.success('登錄成功')
console.log(res)
//保存token
window.sessionStorage.setItem('token', res.data.token)
// 導航至/home
this.$router.push('/home')
})
}
}
}
</script>
<style lang="less" scoped>
.login_container {
background-color: #2b5b6b;
height: 100%;
}
.login_box {
width: 450px;
height: 300px;
background: #fff;
border-radius: 3px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
.avatar_box {
height: 130px;
width: 130px;
border: 1px solid #eee;
border-radius: 50%;
padding: 10px;
box-shadow: 0 0 10px #ddd;
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
img {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #eee;
}
}
}
.login_form {
position: absolute;
bottom: 0;
width: 100%;
padding: 0 20px;
box-sizing: border-box;
}
.btns {
display: flex;
justify-content: flex-end;
}
</style>
(2)主頁
<template>
<el-container class="home-container" >
<!-- 頭部區域 -->
<el-header >
<div>
<!-- logo -->
<!-- <a href="Home.vue"><img src="../assets/logo.png" alt=""></a>-->
<a href="/welcome"><img src="../assets/img/jdd.jpg" alt="" style="width: 200px;height: 20%;padding-left: 0" ></a>
<!-- 頂部標題 -->
<!-- <span>電商后臺管理系統</span>-->
<img src="../assets/img/apple.jpg" style="width: 1350px">
</div>
<el-button type="info" @click="logout"> 退出 </el-button>
</el-header>
<!-- 頁面主體區域 -->
<el-container>
<!-- 側邊欄 -->
<el-aside width="200px">
<!-- 側邊欄選單 -->
<el-menu
background-color="#333744"
text-color="#fff"
active-text-color="#ffd04b" router
unique-opened
:default-active="activePath"
>
<!-- 一級選單 -->
<el-submenu v-for="item in menuList" :key="item.id" :index="item.id+''">
<!-- 一級選單模板 -->
<template slot="title">
<!-- 圖示 -->
<i :class="item.psIcon"></i>
<!-- 文本 -->
<span>{{item.authName}}</span>
</template>
<!-- 二級子選單 -->
<el-menu-item :index="'/'+subItem.path" v-for="subItem in item.children" :key="subItem.id">
<!-- 二級選單模板 -->
<template slot="title">
<!-- 圖示 -->
<i class="el-icon-location"></i>
<!-- 文本 -->
<span>{{subItem.authName}}</span>
</template>
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<!-- 主體結構 -->
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
data() {
return {
// 左側選單資料
menuList: null,
// 被激活的鏈接地址
activePath: ''
}
},
created() {
// 在created階段請求左側選單資料
this.getMenuList()
this.activePath = window.sessionStorage.getItem('activePath')
},
methods: {
logout() {
window.sessionStorage.clear()
this.$router.push('/login')
},
async getMenuList() {
// 發送請求獲取左側選單資料
const { data: res } = await this.$http.get('menus')
if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
this.menuList = res.data
console.log(this.menuList)
}
}
}
</script>
<style lang="less" scoped>
.home-container {
height: 100%;
}
.el-header {
background-color: #373d41;
display: flex;
justify-content: space-between;
padding-left: 0;
align-items: center;
color: #fff;
font-size: 20px;
> div {
display: flex;
align-items: center;
span {
margin-left: 15px;
}
}
}
.el-aside {
background-color: #333744;
.el-menu {
border-right: none;
}
}
.el-main {
background-color: #eaedf1;
}
.iconfont {
margin-right: 10px;
}
.toggle-button {
background-color: #4a5064;
font-size: 10px;
line-height: 24px;
color: #fff;
text-align: center;
letter-spacing: 0.2em;
cursor: pointer;
}
</style>
<template>
<el-carousel :interval="4000" type="card" height="500px" >
<el-carousel-item v-for="item in urls" :key="item">
<img :src="item" >
</el-carousel-item>
</el-carousel>
</template>
<script>
export default {
data() {
return {
urls: [
'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg',
'https://2oa-file.oss-cn-beijing.aliyuncs.com/t/2021-11-29/7954995fda494741af1e62d0f067ba68-car.jpg'
],
currentDate: new Date()
}
}
}
</script>
<style scoped>
.el-carousel__item h3 {
color: #475669;
font-size: 14px;
opacity: 0.75;
line-height: 200px;
margin: 0;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n+1) {
background-color: #d3dce6;
}
.time {
font-size: 13px;
color: #999;
}
.bottom {
margin-top: 13px;
line-height: 12px;
}
.button {
padding: 0;
float: right;
}
.image {
width: 100%;
display: block;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both
}
</style>
(3)用戶管理
<template>
<div>
<!-- 面包屑導航 -->
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/home' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item>用戶管理</el-breadcrumb-item>
<el-breadcrumb-item>用戶串列</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片視圖區域 -->
<el-card>
<!-- 搜索與添加區域 -->
<el-row :gutter="20">
<el-col :span="7">
<el-input placeholder="請輸入內容" v-model="queryInfo.query" clearable @clear="getUserList">
<el-button slot="append" icon="el-icon-search" @click="serch"></el-button>
</el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="add()">添加用戶</el-button>
</el-col>
<el-dialog :title=title :visible.sync="dialogFormVisible">
<el-form :model="users" ref="LoginFormRef" :rules="loginFormRules">
<el-form-item label="用戶名稱" prop="username">
<el-input v-model="users.username" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="用戶密碼" prop="password" v-if="users.id == null">
<el-input v-model="users.password" autocomplete="off" v-if="users.id == null"></el-input>
</el-form-item>
<el-form-item label="郵箱" prop="email">
<el-input v-model="users.email" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="手機號" prop="mobile">
<el-input v-model="users.mobile" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="update(users.id)">確 定</el-button>
</div>
</el-dialog>
</el-row>
</el-card>
<!-- 用戶串列區域 -->
<el-table :data="userlist" border stripe>
<el-table-column type="index"></el-table-column>
<el-table-column label="姓名" prop="username"></el-table-column>
<el-table-column label="郵箱" prop="email"></el-table-column>
<el-table-column label="電話" prop="mobile"></el-table-column>
<el-table-column label="角色" prop="role_name"></el-table-column>
<el-table-column label="狀態">
<template slot-scope="scope">
<el-switch v-model="scope.row.mg_state" @change="userStateChanged(scope.row)"></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" width="180px">
<template slot-scope="scope">
<!-- 修改按鈕 -->
<el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(scope.row.id)"></el-button>
<!-- 洗掉按鈕 -->
<el-button type="danger" icon="el-icon-delete" size="mini" @click="removeUserById(scope.row.id)"></el-button>
<!-- 分配角色按鈕 -->
<el-tooltip effect="dark" content="分配角色" placement="top" :enterable="false">
<el-button type="warning" icon="el-icon-setting" size="mini" @click="setRole(scope.row)"></el-button>
</el-tooltip>
<template>
<el-dialog :title="title" :visible.sync="duoxuan">
<el-select v-model="rid" autocomplete="off">
<el-option
v-for="role in rolelist"
:key="role.id"
:label="role.roleName"
:value="role.id">
</el-option>
</el-select>
<el-button type="primary" @click="setR(rid)">確 定</el-button>
</el-dialog>
</template>
</template>
</el-table-column>
</el-table>
<!-- 分頁導航區域
@size-change(pagesize改變時觸發)
@current-change(頁碼發生改變時觸發)
:current-page(設定當前頁碼)
:page-size(設定每頁的資料條數)
:total(設定總頁數) -->
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="queryInfo.pagenum" :page-sizes="[1, 2, 5, 10]" :page-size="queryInfo.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</div>
</template>
<script>
export default {
data () {
return {
// 獲取查詢用戶資訊的引數
title:'',
sea:false,
duoxuan:false,
users: {
id: '',
username: '',
password: '',
email: '',
mobile: ''
},
rid:'',
rolelist:[],
visible: false,
formLabelWidth: '120px',
dialogFormVisible: false,
form2:{
email:'',mobile:''
},
queryInfo: {
query: '',
pagenum: 1,
pagesize: 2
},
//表單驗證規則
loginFormRules: {
username: [
{required: true, message: '請輸入登錄名', trigger: 'blur'},
{
min: 3,
max: 10,
message: '登錄名長度在 3 到 10 個字符',
trigger: 'blur'
}
],
password: [
{required: true, message: '請輸入密碼', trigger: 'blur'},
{
min: 6,
max: 15,
message: '密碼長度在 6 到 15 個字符',
trigger: 'blur'
}
],
email: [
// {required: true, message: '請輸入郵箱', triggger: 'blur'},
{
pattern: /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
message: "正確的郵箱格式為xxx@xx.com",
trigger: 'blur'
}
],
mobile: [
// {required: true, message: "請輸入手機號碼", trigger: "blur"},
{
pattern: /^1[356789]\d{9}$/,
message: "請填寫11位正確的手機號碼",
trigger: "blur"
}]
},
// 保存請求回來的用戶串列資料
userlist: [],
total: 0,
options: [{}],
value: ''
}
},
created () {
this.getUserList()
},
methods: {
serch(){
if (this.queryInfo.query.trim()!=""){
this.sea = true;
}
this.queryInfo.pagenum = 1;
this.getUserList();
},
async getUserList() {
const { data: res } = await this.$http.get('users', {
params: this.queryInfo
})
if (res.meta.status !== 200) {
return this.$message.error('獲取用戶串列失敗!')
}
this.userlist = res.data.users
this.total = res.data.total
console.log(res)
},
async setRole(row){
this.duoxuan = true;
this.id = row.id;
this.rid = row.roleId;
const { data: res } = await this.$http.get('roles/')
if (res.meta.status !== 200) {
return this.$message.error('獲取角色串列失敗!')
}
this.rolelist = res.data;
},
setR(rid){
console.log("rid="+rid);
console.log("this.id="+this.id);
console.log("users/:"+this.id+"/"+rid);
this.$http.put("users/"+this.id+"/"+rid);
this.getUserList();
this.id = '';
this.duoxuan = false;
},
handleSizeChange(newSize) {
//pagesize改變時觸發,當pagesize發生改變的時候,我們應該
//以最新的pagesize來請求資料并展示資料
// console.log(newSize)
// this.search?this.queryInfo.pagesize=1:this.queryInfo.pagesize = newSize;
this.queryInfo.pagesize = newSize;
//重新按照pagesize發送請求,請求最新的資料
this.getUserList();
},
handleCurrentChange( current ) {
//頁碼發生改變時觸發當current發生改變的時候,我們應該
//以最新的current頁碼來請求資料并展示資料
// console.log(current)
if (!this.search){
this.queryInfo.pagenum = current;
}
//重新按照pagenum發送請求,請求最新的資料
this.getUserList();
},
async userStateChanged(row) {
//發送請求進行狀態修改
const { data: res } = await this.$http.put(
`users/${row.id}/state/${row.mg_state}`
)
//如果回傳狀態為例外狀態則報錯并回傳
if (res.meta.status !== 200) {
row.mg_state = !row.mg_state
return this.$message.error('修改狀態失敗')
}
this.$message.success('更新狀態成功')
},
//添加
add() {
this.users = {};
this.title = "添加";
this.dialogFormVisible = true;
},
// 修改
async showEditDialog(id) {
//找出需要修改的資料的資訊
const {data: res} = await this.$http.get("users/" + id);
if (res.meta.status !== 200) {
return this.$message.error('查詢失敗')
}
this.$message.success('查詢成功');
this.users = res.data;
console.log(this.users);
this.title = "修改";
this.dialogFormVisible = true;
},
//添加/修改
async update(id) {
this.$refs.LoginFormRef.validate(async valid => {
console.log(this.loginFormRules);
//如果valid引數為true則驗證通過
if (!valid) {
return
}
if (id != null) {
const {data: res} = await this.$http.put(`users/${id}`, this.users);
if (res.meta.status !== 200) {
return this.$message.error('修改失敗')
}
this.$message.success('修改成功');
} else {
const {data: res} = await this.$http.post("users", this.users);
if (res.meta.status !== 201) {
return this.$message.error('添加失敗')
} else {
this.$message.success('添加成功');
}
}
this.users = '';
this.dialogFormVisible = false;
this.getUserList()
})
},
removeUserById(id){
this.$confirm('此操作將永久洗掉該檔案, 是否繼續?', '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$http.delete("users/"+id).then(() => {
this.queryInfo.pagenum = this.userlist.length === 1 ? this.queryInfo.pagenum - 1 : this.queryInfo.pagenum;
this.queryInfo.pagenum = this.queryInfo.pagenum < 1 ? 1 : this.queryInfo.pagenum;
this.getUserList();
}),
this.$message({
type: 'success',
message: '洗掉成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消洗掉'
});
});
},
//獲取角色串列
}
}
</script>
<style scoped>
</style>
(4)權限管理
1、角色串列;
<template>
<div>
<!-- 面包屑導航區域 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item>權限管理</el-breadcrumb-item>
<el-breadcrumb-item>角色串列</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片視圖 -->
<el-card>
<!-- 添加角色按鈕區域 -->
<el-row>
<el-col>
<el-button type="primary" @click="res()">添加角色</el-button>
<el-dialog :visible.sync="dialogFormVisible">
<el-form :model="role1" >
<el-form-item label="角色名稱" prop="roleName">
<el-input v-model="role1.roleName" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="角色描述" prop="roleDesc">
<el-input v-model="role1.roleDesc" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="insert()">確 定</el-button>
</div>
</el-dialog>
</el-col>
</el-row>
<!-- 角色串列區域 -->
<el-table :data="roleList" border stripe>
<!-- 展開列 -->
<el-table-column type="expand">
<template slot-scope="scope">
<el-row :class="['bdbottom', i1 === 0 ? 'bdtop' : '', 'vcenter']" v-for="(item1, i1) in scope.row.children" :key="item1.id">
<!-- 渲染一級權限 -->
<el-col :span="5">
<el-tag closable >{{item1.authName}}</el-tag>
<i class="el-icon-caret-right" @close="removeRightById(scope.row, item1.id)"></i>
</el-col>
<!-- 渲染二級和三級權限 -->
<el-col :span="19">
<!-- 通過 for 回圈 嵌套渲染二級權限 -->
<el-row :class="[i2 === 0 ? '' : 'bdtop', 'vcenter']" v-for="(item2, i2) in item1.children" :key="item2.id">
<el-col :span="6">
<el-tag type="success" closable>{{item2.authName}}</el-tag>
<i class="el-icon-caret-right" @close="removeRightById(scope.row, item2.id)"></i>
</el-col>
<el-col :span="18">
<el-tag closable type="warning" v-for="item3 in item2.children" :key="item3.id">{{item3.authName}}</el-tag>
<i class="el-icon-caret-right" @close="removeRightById(scope.row, item3.id)"></i>
</el-col>
</el-row>
</el-col>
</el-row>
</template>
</el-table-column>
<el-table-column label="角色名稱" prop="roleName"></el-table-column>
<el-table-column label="角色描述" prop="roleDesc"></el-table-column>
<el-table-column label="操作" width="300px">
<template slot-scope="scope">
<el-button size="mini" type="primary" icon="el-icon-edit" @click="selectById(scope.row.id)" >編輯</el-button>
<el-dialog :visible.sync="dialogFormVisible2">
<el-form :model="role" ref="LoginFormRef">
<el-form-item label="角色名稱" prop="roleName">
<el-input v-model="role.roleName" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="角色描述" prop="roleDesc">
<el-input v-model="role.roleDesc" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible2 = false">取 消</el-button>
<el-button type="primary" @click="upda(scope.row.id)">確 定</el-button>
</div>
</el-dialog>
<el-button size="mini" type="danger" icon="el-icon-delete" @click="delRole(scope.row.id)">洗掉</el-button>
<el-button size="mini" type="warning" icon="el-icon-setting" @click="showSetRightDialog(scope.row)">分配權限</el-button>
<!-- 分配權限對話框 -->
<el-dialog title="分配權限" :visible.sync="setRightDialogVisible" width="50%" @close="setRightDialogClose">
<!-- 樹形組件
show-checkbox:顯示復選框
node-key:設定選中節點對應的值
default-expand-all:是否默認展開所有節點
:default-checked-keys 設定默認選中項的陣列
ref:設定參考 -->
<el-tree :data="rightsList" :props="treeProps" show-checkbox node-key="id" default-expand-all :default-checked-keys="defKeys" ref="treeRef"></el-tree>
<span slot="footer" class="dialog-footer">
<el-button @click="setRightDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="allotRights">確 定</el-button>
</span>
</el-dialog>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
// 角色串列資料
roleList: [],
// 控制分配權限對話框的顯示
setRightDialogVisible: false,
// 權限樹資料
rightsList: [],
// 樹形控制元件的屬性系結物件
treeProps: {
// 通過label設定樹形節點文本展示authName
label: 'authName',
// 設定通過children屬性展示子節點資訊
children: 'children'
},
// 設定樹形控制元件中默認選中的內容
defKeys: [],
// 保存正在操作的角色id
roleId: '',
role1:{
roleName:'',roleDesc:''
},
role:{
id:'',roleName:'',roleDesc:''
},
dialogFormVisible:false,
dialogFormVisible2:false
}
},
created() {
this.getRoleList()
},
methods: {
async getRoleList() {
const { data: res } = await this.$http.get('roles')
// 如果回傳狀態為例外狀態則報錯并回傳
if (res.meta.status !== 200) { return this.$message.error('獲取角色串列失敗') }
// 如果回傳狀態正常,將請求的資料保存在data中
// this.roleList = res.data
console.log(res.data)
this.roleList = res.data
},
async removeRightById(role, rightId) {
// 彈窗提示用戶是否要洗掉
const confirmResult = await this.$messagebox.confirm(
'請問是否要洗掉該權限',
'洗掉提示',
{
confirmButtonText: '確認洗掉',
cancelButtonText: '取消',
type: 'warning'
}
).catch(err => err)
// 如果用戶點擊確認,則confirmResult 為'confirm'
// 如果用戶點擊取消, 則confirmResult獲取的就是catch的錯誤訊息'cancel'
if (confirmResult !== 'confirm') {
return this.$message.info('已經取消洗掉')
}
// 用戶點擊了確定表示真的要洗掉
// 當發送delete請求之后,回傳的資料就是最新的角色權限資訊
const { data: res } = await this.$http.delete(
`roles/${role.id}/rights/${rightId}`
)
if (res.meta.status !== 200) { return this.$message.error('洗掉角色權限失敗') }
// 無需再重新加載所有權限
// 只需要對現有的角色權限進行更新即可
role.children = res.data
// this.getRoleList();
},
async showSetRightDialog(role) {
// 將role.id保存起來以供保存權限時使用
this.roleId = role.id
// 獲取所有權限的資料
const { data: res } = await this.$http.get('rights/tree')
// 如果回傳狀態為例外狀態則報錯并回傳
if (res.meta.status !== 200) return this.$message.error('獲取權限樹失敗')
// 如果回傳狀態正常,將請求的資料保存在data中
this.rightsList = res.data
// 呼叫getLeafKeys進行遞回,將三級權限添加到陣列中
this.getLeafKeys(role, this.defKeys)
// 當點擊分配權限按鈕時,展示對應的對話框
this.setRightDialogVisible = true
console.log(this.defKeys)
},
getLeafKeys(node, arr) {
// 該函式會獲取到當前角色的所有三級權限id并添加到defKeys中
// 如果當前節點不包含children屬性,則表示node為三級權限
if (!node.children) {
return arr.push(node.id)
}
// 遞回呼叫
node.children.forEach(item => this.getLeafKeys(item, arr))
},
setRightDialogClose() {
// 當用戶關閉樹形權限對話框的時候,清除掉所有選中狀態
this.defKeys = []
},
async allotRights() {
// 當用戶在樹形權限對話框中點擊確定,將用戶選擇的
// 權限發送請求進行更新
// 獲取所有選中及半選的內容
const keys = [
...this.$refs.treeRef.getCheckedKeys(),
...this.$refs.treeRef.getHalfCheckedKeys()
]
// 將陣列轉換為 , 拼接的字串
const idStr = keys.join(',')
// 發送請求完成更新
const { data: res } = await this.$http.post(
`roles/${this.roleId}/rights`,
{ rids: idStr }
)
if (res.meta.status !== 200) { return this.$message.error('分配權限失敗') }
this.$message.success('分配權限成功')
this.getRoleList()
// 關閉對話框
this.setRightDialogVisible = false
},
res(){
this.role1 = {};
this.dialogFormVisible = true;
},
//新增
async insert(){
//新增
console.log("新增");
const {data: res} = await this.$http.post(`roles`, this.role1);
if (res.meta.status !== 201) {
return this.$message.error('添加失敗')
} else {
this.$message.success('添加成功');
}
this.role1 = '';
this.dialogFormVisible = false;
this.getRoleList();
},
async selectById(id){
const {data: res} = await this.$http.get(`roles/`+id, this.role);
if (res.meta.status !== 200) {
return this.$message.error('查詢失敗')
}
this.$message.success('查詢成功');
this.role.id = res.data.id;
this.role.roleName = res.data.roleName;
this.role.roleDesc = res.data.roleDesc;
console.log(this.role);
this.dialogFormVisible2 = true;
},
//修改
async upda(id){
console.log("id="+id);
const {data: res} = await this.$http.put(`roles/${id}`,this.role);
if (res.meta.status !== 200) {
return this.$message.error('修改失敗')
} else {
this.$message.success('修改成功');
}
this.role = {};
this.dialogFormVisible2 = false;
this.getRoleList();
},
delRole(id){
this.$confirm('此操作將永久洗掉該檔案, 是否繼續?', '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
console.log("id="+id);
this.$http.delete(`roles/${id}`).then(() => {
this.getRoleList();
})
}),this.$message({
type: 'success',
message: '洗掉成功!'
}).catch(() => {
this.$message({
type: 'info',
message: '已取消洗掉'
});
});
}
}
}
</script>
<style lang="less" scoped>
.el-tag {
margin: 7px;
}
.bdtop {
border-top: 1px solid #eee;
}
.bdbottom {
border-bottom: 1px solid #eee;
}
.vcenter {
display: flex;
align-items: center;
}
</style>
2、權限串列,
<template>
<div>
<!-- 面包屑導航區域 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item>權限管理</el-breadcrumb-item>
<el-breadcrumb-item>權限串列</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片視圖 -->
<el-card>
<!-- <tree-table :data="quanxianList" :columns="columns" :selection-type="false"-->
<!-- :expand-type="false" show-index index-text="#" :show-row-hover="false">-->
<!-- <template slot="level" scope="scope">-->
<!-- <el-tag type="primary" effect="plain" size="mini" v-if="scope.row.children!=null && scope.row.pid==0">一級</el-tag>-->
<!-- <el-tag type="success" effect="plain" size="mini" v-else-if="scope.row.children!=null && scope.row.pid!=0">二級</el-tag>-->
<!-- <el-tag type="warning" effect="plain" size="mini" v-else>三級</el-tag>-->
<!-- </template>-->
<!-- </tree-table>-->
<!-- 角色串列區域-->
<el-table :data="quanxianList" border stripe>
<!-- 展開列 -->
<el-table-column type="expand">
<!-- <el-table-column label="" prop="authName"></el-table-column>-->
<template slot-scope="scope">
<el-row :class="['bdbottom', i1 === 0 ? 'bdtop' : '', 'vcenter']" v-for="(item1, i1) in scope.row.children" :key="item1.id">
<!-- 渲染一級權限 -->
<el-col :span="5">
<el-tag >{{item1.authName}}</el-tag>
<i class="el-icon-caret-right"></i>
</el-col>
<!-- 渲染二級和三級權限 -->
<el-col :span="19">
<!-- 通過 for 回圈 嵌套渲染二級權限 -->
<el-row :class="[i2 === 0 ? '' : 'bdtop', 'vcenter']" v-for="(item2, i2) in item1.children" :key="item2.id">
<el-col :span="6">
<el-tag type="success" >{{item2.authName}}</el-tag>
<i class="el-icon-caret-right"></i>
</el-col>
<el-col :span="18">
<el-row :class="[i2 === 0 ? '' : 'bdtop', 'vcenter']" v-for="(item3, i2) in item1.children" :key="item3.id">
<el-tag type="warning">
{{item3.authName}}
</el-tag>
<i class="el-icon-caret-right"></i>
</el-row>
</el-col>
</el-row>
</el-col>
</el-row>
</template>
</el-table-column>
<!-- 角色串列區域 -->
<!-- 添加展開列 -->
<!-- <el-table-column label="權限ID" prop="id"></el-table-column>-->
<el-table-column label="權限說明" prop="authName"></el-table-column>
<el-table-column label="權限層級" prop="level"></el-table-column>
<el-table-column label="權限父ID" prop="pid"></el-table-column>
<el-table-column label="對應訪問路徑" prop="path"></el-table-column>
</el-table>
</el-card>
</div>
</template>
<script>
export default {
data () {
return {
// quanxianList: [],
quanxianList: {
// 通過label設定樹形節點文本展示authName
label: 'authName',
// 設定通過children屬性展示子節點資訊
children: 'children'
},
menus:{
id:'',authName:'',path:'',children:''
}
}
},
created () {
this.getRoleList()
},
methods: {
async getRoleList () {
const { data: res } = await this.$http.get('rights/tree')
// 如果回傳狀態為例外狀態則報錯并回傳
if (res.meta.status !== 200) {
return this.$message.error('獲取角色串列失敗')
}
console.log(res.data)
// 如果回傳狀態正常,將請求的資料保存在data中
this.quanxianList = res.data
},
async getLeftList () {
const { data: res } = await this.$http.get('menus')
// 如果回傳狀態為例外狀態則報錯并回傳
if (res.meta.status !== 200) {
return this.$message.error('獲取選單串列失敗')
}
console.log(res.data)
// 如果回傳狀態正常,將請求的資料保存在data中
this.menus = res.data
}
}
}
</script>
(5)商品管理
1、商品分類;
<template>
<div>
<!-- 面包屑導航 -->
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/home' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item>商品管理</el-breadcrumb-item>
<el-breadcrumb-item>商品分類</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片視圖區域 -->
<el-card>
<!-- 添加分類按鈕區域 -->
<el-row>
<el-col>
<el-button type="primary" @click="showAddCateDialog">添加分類</el-button>
</el-col>
</el-row>
<!-- 添加分類對話框 -->
<el-dialog title="添加分類" :visible.sync="addCateDialogVisible" width="50%" @close="addCateDialogClosed">
<!-- 添加分類表單 -->
<el-form :model="addCateForm" :rules="addCateFormRules" ref="addCateFormRef" label-width="100px">
<el-form-item label="分類名稱" prop="cat_name">
<el-input v-model="addCateForm.cat_name"></el-input>
</el-form-item>
<el-form-item label="父級分類" prop="cat_pid" v-if="this.pid==''">
<!-- expandTrigger='hover'(滑鼠懸停觸發級聯) v-model(設定級聯選單系結資料) :options(指定級聯選單資料源) :props(用來配置資料顯示的規則)
clearable(提供“X”號完成洗掉文本功能) change-on-select(是否可以選中任意一級的選單) -->
<el-cascader expandTrigger='hover' v-model="selectedKeys" :options="parentCateList" :props="cascaderProps" @change="parentCateChange" clearable change-on-select></el-cascader>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="res">取 消</el-button>
<el-button type="primary" @click="addCate">確 定</el-button>
</span>
</el-dialog>
<!-- 分類表格 -->
<!-- 分類表格
:data(設定資料源) :columns(設定表格中列配置資訊) :selection-type(是否有復選框)
:expand-type(是否展開資料) show-index(是否設定索引列) index-text(設定索引列頭)
border(是否添加縱向邊框) :show-row-hover(是否滑鼠懸停高亮) -->
<tree-table :data="cateList" :columns="columns" :selection-type="false"
:expand-type="false" show-index index-text="#" border :show-row-hover="false">
<!-- 排序 -->
<template slot="order" slot-scope="scope">
<el-tag size="mini" v-if="scope.row.cat_level===0">一級</el-tag>
<el-tag size="mini" type="success" v-else-if="scope.row.cat_level===1">二級</el-tag>
<el-tag size="mini" type="warning" v-else>三級</el-tag>
</template>
<!-- 操作 -->
<template slot="opt" slot-scope="scope">
<el-button size="mini" type="primary" icon="el-icon-edit" @click="bj(scope.row.cat_id)">編輯</el-button>
<el-button size="mini" type="danger" icon="el-icon-delete" @click="del(scope.row.cat_id)">洗掉</el-button>
</template>
</tree-table>
<!-- 分頁 -->
<!-- 分頁 -->
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="queryInfo.pagenum" :page-sizes="[3, 5, 10, 15]" :page-size="queryInfo.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
// 商品分類資料串列
cateList: [],
columns: [
{label:'分類名稱',prop:'cat_name'},
{label:'排序',prop:'',type:'template',template:'order'},
{label:'操作',prop:'',type:'template',template:'opt'}
],
// 查詢分類資料的條件
queryInfo: {
type: 3,
pagenum: 1,
pagesize: 5
},
pid:'',
// 保存總資料條數
total: 0,
//用來顯示或隱藏添加分類對話框
addCateDialogVisible: false,
dialogFormVisible2: false,
//添加分類的表單資料物件
addCateForm:{
//分類名稱
cat_name:'',
//添加分類的父級id,0則表示父級為0.添加一級分類
cat_pid:0,
//添加分類的等級,0則表示添加一級分類
cat_level:0
},
//保存1,2級父級分類的串列
parentCateList:[],
//添加分類校驗規則
addCateFormRules:{
//驗證規則
cat_name:[ {required:true , message:'請輸入分類名稱',trigger:'blur'} ]
},
//配置級聯選單中資料如何展示
cascaderProps:{
value:'cat_id',
label:'cat_name',
children:'children',
expandTrigger:'hover'
},
//系結用戶選擇的分類值
selectedKeys:[]
}
},
created() {
this.getCateList()
},
methods: {
async getCateList() {
// 獲取商品分類資料
const { data: res } = await this.$http.get('categories', {
params: this.queryInfo
})
if (res.meta.status !== 200) {
return this.$message.error('獲取商品串列資料失敗')
}
// 將資料串列賦值給cateList
this.cateList = res.data.result
// 保存總資料條數
this.total = res.data.total
// console.log(res.data);
},
handleSizeChange(newSize){
//當pagesize發生改變時觸發
this.queryInfo.pagesize = newSize;
this.getCateList();
},
handleCurrentChange(newPage){
//當pagenum發生改變時觸發
this.queryInfo.pagenum = newPage;
this.getCateList();
},
showAddCateDialog() {
//呼叫getParentCateList獲取分類串列
this.getParentCateList()
//顯示添加分類對話框
this.addCateDialogVisible = true;
},
res(){
this.addCateForm.cat_name = '';
this.addCateDialogVisible = false;
this.pid = '';
},
async getParentCateList(){
//獲取父級分類資料串列
const { data: res } = await this.$http.get('categories', {
params: {type:2}
})
if (res.meta.status !== 200) {
return this.$message.error('獲取商品分類串列資料失敗')
}
this.parentCateList = res.data
},
parentCateChange(){
//級聯選單中選擇項發生變化時觸發
console.log(this.selectedKeys)
//如果用戶選擇了父級分類
if(this.selectedKeys.length > 0){
//則將陣列中的最后一項設定為父級分類
this.addCateForm.cat_pid = this.selectedKeys[this.selectedKeys.length - 1]
//level也要跟著發生變化
this.addCateForm.cat_level = this.selectedKeys.length
return
}else{
this.addCateForm.cat_pid = 0
this.addCateForm.cat_level = 0
return
}
},
addCateDialogClosed(){
//當關閉添加分類對話框時,重置表單
//this.$refs.addCateFormRef.resetFields()
this.selectedKeys = [];
this.addCateForm.cat_pid = 0
this.addCateForm.cat_level = 0
},
async addCate() {
console.log('pid='+this.pid);
if (this.pid==''){
console.log('添加');
//點擊確定,完成添加分類
console.log('cat_name='+this.addCateForm.cat_name)
console.log('cat_pid='+this.addCateForm.cat_pid)
this.$refs.addCateFormRef.validate(async valid => {
if (!valid) return
//發送請求完成添加分類
const {data: res} = await this.$http.post(
'categories',
this.addCateForm
)
if (res.meta.status !== 201) {
return this.$message.error('添加分類失敗')
}
this.$message.success('添加分類成功')
this.getCateList()
this.addCateDialogVisible = false;
this.addCateForm = {};
});
}else {
//編輯
console.log('編輯');
const {data: res} = await this.$http.put('categories/'+this.pid, this.addCateForm);
if (res.meta.status !== 200) {
return this.$message.error('編輯分類失敗')
}else {
this.$message.success('編輯分類成功')
}
this.getCateList();
this.addCateDialogVisible = false;
this.addCateForm = {};
this.pid = '';
}
},
async bj(id){
this.pid = id;
console.log("id="+id);
this.addCateDialogVisible= true;
const {data: res} = await this.$http.get('categories/'+this.pid);
this.addCateForm = res.data;
},
del(id){
this.$confirm('此操作將永久洗掉該檔案, 是否繼續?', '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
console.log("id="+id);
this.$http.delete("categories/"+id).then(() => {
this.queryInfo.pagenum = this.cateList.length === 1 ? this.queryInfo.pagenum - 1 : this.queryInfo.pagenum;
this.queryInfo.pagenum = this.queryInfo.pagenum < 1 ? 1 : this.queryInfo.pagenum;
this.getCateList();
}),
this.$message({
type: 'success',
message: '洗掉成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消洗掉'
});
});
},
}
}
</script>
<style scoped>
</style>
2、商品串列;
<template>
<div>
<!-- 面包屑導航 -->
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/home' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item>商品管理</el-breadcrumb-item>
<el-breadcrumb-item>商品串列</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片視圖區域 -->
<el-card>
<!-- 搜索欄 -->
<el-row :gutter="20">
<el-col :span="8">
<el-input placeholder="請輸入內容" v-model="queryInfo.query" clearable>
<el-button slot="append" icon="el-icon-search" @click="sea()"/>
</el-input>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="goAddPage">添加商品</el-button>
</el-col>
</el-row>
<!-- 表格區域 -->
<el-table :data="goodsList" border stripe>
<el-table-column type="index"/>
<el-table-column label="商品名稱" prop="goods_name"/>
<el-table-column label="商品價格(元)" prop="goods_price" width="95px"/>
<el-table-column label="商品重量" prop="goods_weight" width="95px"/>
<el-table-column label="創建時間" prop="add_time" width="140px">
<template slot-scope="scope">
{{scope.row.add_time | dateFormat}}
</template>
</el-table-column>
<el-table-column label="操作" width="125px">
<template slot-scope="scope">
<el-button size="mini" type="primary" icon="el-icon-edit" @click="update(scope.row.goods_id)"/>
<el-button size="mini" type="danger" icon="el-icon-delete" @click="del(scope.row.goods_id)"/>
</template>
</el-table-column>
</el-table>
<!-- 分頁 -->
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="queryInfo.pagenum" :page-sizes="[3, 5, 10, 15]"
:page-size="queryInfo.pagesize" layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
<el-dialog title="修改商品" :visible.sync="dialogFormVisible" width="60%">
<el-scrollbar style="height: 400px">
<el-form :model="good" ref="updateGoodsForm">
<el-form-item label="商品名稱" :label-width="formLabelWidth" prop="goods_name">
<el-input v-model="good.goods_name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="商品價格" :label-width="formLabelWidth" prop="goods_price">
<el-input v-model="good.goods_price" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="商品重量" :label-width="formLabelWidth" prop="goods_weight">
<el-input v-model="good.goods_weight" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="商品數量" :label-width="formLabelWidth" prop="goods_number">
<el-input v-model="good.goods_number" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="商品介紹" :label-width="formLabelWidth" prop="goods_introduce">
<quill-editor v-model="good.goods_introduce" autocomplete="off"></quill-editor>
</el-form-item>
</el-form>
</el-scrollbar>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="updateGood()">確 定</el-button>
</div>
</el-dialog>
</el-card>
</div>
</template>
<script>
export default {
name: "goods",
data() {
return {
dialogFormVisible: false,
formLabelWidth: '120px',
sear: false,
good: {
},
//查詢引數
queryInfo: {
query: '',
pagenum: 1,
pagesize: 10
},
//保存商品串列資訊
goodsList: [],
//總資料條數
total: 0,
}
},
created() {
this.getGoodsList()
},
methods: {
sea() {
if (this.queryInfo.query.trim() !== '') {
this.sear = true;
}
this.queryInfo.pagenum = 1;
this.getGoodsList();
},
async getGoodsList() {
// 根據分頁獲取對應的商品串列
const {data: res} = await this.$http.get('goods', {
params: this.queryInfo
});
if (res.meta.status !== 200) {
return this.$message.error('獲取商品串列失敗')
}
console.log(res.data);
this.$message.success('獲取商品串列成功');
this.goodsList = res.data.goods;
this.total = res.data.total
},
handleSizeChange(newSize) {
//當頁號發生改變時,更改pagesize,重新請求
this.queryInfo.pagesize = newSize;
this.getGoodsList();
},
handleCurrentChange(newPage) {
//當頁碼發生改變時,更改pagesize,重新請求
if (!this.sear) {
this.queryInfo.query = '';
}
this.queryInfo.pagenum = newPage;
this.getGoodsList();
},
goAddPage() {
this.$router.push('/goods/add')
},
async update(id) {
const {data: res} = await this.$http.get("goods/" + id);
if (res.meta.status !== 200) {
return this.$message.error('查詢商品失敗')
}
this.$message.success('查詢商品成功');
this.good = res.data;
console.log(this.good);
this.dialogFormVisible = true;
},
async updateGood() {
const {data: res} = await this.$http.put(`goods/${this.good.goods_id}`, this.good);
console.log(res);
if (res.meta.status !== 200) {
return this.$message.error('修改商品失敗')
}
this.$message.success('修改商品成功');
// 關閉對話框
this.dialogFormVisible = false;
this.getGoodsList()
},
async del(id) {
const {data: res} = await this.$http.delete(`goods/${id}`);
if (res.meta.status !== 200) {
return this.$message.error('洗掉商品失敗')
}
this.$message.success('洗掉商品成功');
this.getGoodsList();
}
}
}
</script>
<style scoped>
</style>
添加商品
<template>
<div>
<h3>添加商品</h3>
<!-- 面包屑導航 -->
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/home' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item>商品管理</el-breadcrumb-item>
<el-breadcrumb-item>添加商品</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片視圖區域 -->
<el-card>
<!-- 訊息提示 -->
<el-alert title="添加商品資訊" type="info" center show-icon :closable="false">
</el-alert>
<!-- 步驟條組件 -->
<!-- align-center(居中效果) -->
<el-steps :space="200" :active="activeIndex - 0" finish-status="success" align-center>
<el-step title="基本資訊"></el-step>
<el-step title="商品引數"></el-step>
<el-step title="商品屬性"></el-step>
<el-step title="商品圖片"></el-step>
<el-step title="商品內容"></el-step>
<el-step title="完成"></el-step>
</el-steps>
<!-- tab欄區域:el-tab-pane必須是el-tabs的子節點
:tab-position="'left'"(設定tab欄為左右結構tab欄) -->
<!-- 表單:label-position="top"(設定label在文本框上方) -->
<el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="100px" label-position="top">
<el-tabs v-model="activeIndex" :tab-position="'left'" :before-leave="beforeTabLeave" @tab-click="tabClicked">
<el-tab-pane label="基本資訊" name="0">
<el-form-item label="商品名稱" prop="goods_name">
<el-input v-model="addForm.goods_name"></el-input>
</el-form-item>
<el-form-item label="商品價格" prop="goods_price">
<el-input v-model="addForm.goods_price" type="number"></el-input>
</el-form-item>
<el-form-item label="商品重量" prop="goods_weight">
<el-input v-model="addForm.goods_weight" type="number"></el-input>
</el-form-item>
<el-form-item label="商品數量" prop="goods_number">
<el-input v-model="addForm.goods_number" type="number"></el-input>
</el-form-item>
<el-form-item label="商品分類" prop="goods_cat">
<!-- 選擇商品分類的級聯選擇框 -->
<el-cascader expandTrigger='hover' v-model="addForm.goods_cat" :options="cateList" :props="cateProps" @change="handleChange" clearable></el-cascader>
</el-form-item>
</el-tab-pane>
<el-tab-pane label="商品引數" name="1">
<!-- 渲染表單item項 -->
<el-form-item :label="item.attr_name" :key="item.attr_id" v-for="item in manyTableData">
<!-- 使用陣列渲染復選框組 -->
<el-checkbox-group v-model="item.attr_vals">
<el-checkbox border :label="val" v-for="(val,i) in item.attr_vals" :key="i"></el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-tab-pane>
<el-tab-pane label="商品屬性" name="2">
<!-- 回圈生成靜態屬性 -->
<el-form-item :label="item.attr_name" v-for="item in onlyTableData" :key="item.attr_id">
<el-input v-model="item.attr_vals"></el-input>
</el-form-item>
</el-tab-pane>
<!-- //在頁面中添加upload組件,并設定對應的事件和屬性-->
<el-tab-pane label="商品圖片" name="3">
<!-- 商品圖片上傳
action:指定圖片上傳api介面
:on-preview : 當點擊圖片時會觸發該事件進行預覽操作,處理圖片預覽
:on-remove : 當用戶點擊圖片右上角的X號時觸發執行
:on-success:當用戶點擊上傳圖片并成功上傳時觸發
list-type :設定預覽圖片的方式
:headers :設定上傳圖片的請求頭 -->
<el-upload :action="uploadURL" :on-preview="handlePreview" :on-remove="handleRemove" :on-success="handleSuccess" list-type="picture" :headers="headerObj">
<el-button size="small" type="primary">點擊上傳</el-button>
</el-upload>
</el-tab-pane>
<!-- 富文本編輯器組件 -->
<el-tab-pane label="商品內容" name="4">
<!-- 富文本編輯器組件 -->
<quill-editor v-model="addForm.goods_introduce"></quill-editor>
<!-- 添加商品按鈕 -->
<el-button type="primary" class="btnAdd" @click="add">添加商品</el-button>
</el-tab-pane>
</el-tabs>
</el-form>
</el-card>
<!-- //在el-card卡片視圖下面添加對話框用來預覽圖片-->
<!-- 預覽圖片對話框 -->
<el-dialog title="圖片預覽" :visible.sync="previewVisible" width="50%">
<img :src="previewPath" class="previewImg" />
</el-dialog>
</div>
</template>
<script>
var _ = require('lodash');
export default {
data() {
return {
//保存步驟條激活項索引
activeIndex: '0',
//添加商品的表單資料物件
addForm: {
goods_name: '',
goods_price: 0,
goods_weight: 0,
goods_number: 0,
goods_cat: [],
//上傳圖片陣列
pics: [],
//商品的詳情介紹
goods_introduce:'',
attrs: []
},
//上傳圖片的url地址
uploadURL: 'http://127.0.0.1:8888/api/private/v1/upload',
//圖片上傳組件的headers請求頭物件
headerObj: { Authorization: window.sessionStorage.getItem('token') },
//保存預覽圖片的url地址
previewPath: '',
//控制預覽圖片對話框的顯示和隱藏
previewVisible:false,
//動態引數串列
manyTableData: [],
//靜態屬性串列
onlyTableData:[],
//驗證規則
addFormRules: {
goods_name: [
{ required: true, message: '請輸入商品名稱', trigger: 'blur' }
],
goods_price: [
{ required: true, message: '請輸入商品價格', trigger: 'blur' }
],
goods_weight: [
{ required: true, message: '請輸入商品重量', trigger: 'blur' }
],
goods_number: [
{ required: true, message: '請輸入商品數量', trigger: 'blur' }
],
goods_cat: [
{ required: true, message: '請選擇商品分類', trigger: 'blur' }
]
},
//用來保存分類資料
cateList: [],
//配置級聯選單中資料如何展示
cateProps: {
value: 'cat_id',
label: 'cat_name',
children: 'children'
}
}
},
created() {
this.getCateList()
},
methods: {
async getCateList() {
const { data: res } = await this.$http.get('categories')
if (res.meta.status !== 200) {
return this.$message.error('獲取商品分類資料失敗')
}
this.cateList = res.data
},
handleChange(){
//如果用戶選擇的不是三級分類,該次選擇無效,因為必須選擇三級分類
if(this.addForm.goods_cat.length !== 3){
this.addForm.goods_cat = []
return
}
},
beforeTabLeave (activeName, oldActiveName) {
// 在tab欄切換之前觸發,兩個形參為切換前,后的tab欄name
if (oldActiveName === '0') {
// 在第一個標簽頁的時候
if (this.addForm.goods_cat.length !== 3) {
this.$message.error('請選擇商品的分類')
return false
} else if (this.addForm.goods_name.trim() === '') {
this.$message.error('請輸入商品名稱')
return false
} else if (this.addForm.goods_price === '0') {
this.$message.error('請輸入商品價格')
return false
} else if (this.addForm.goods_weight === '0') {
this.$message.error('請輸入商品重量')
return false
} else if (this.addForm.goods_number === '0') {
this.$message.error('請輸入商品數量')
return false
}
}
},
// 獲取商品引數和屬性
async tabClicked () {
if (this.addForm.goods_cat.length === 3) {
// 當用戶點擊切換tab欄時觸發
if (this.activeIndex === '1') {
// 發送請求獲取動態引數
const { data: res } = await this.$http.get('categories/' + this.addForm.goods_cat[2] + '/attributes',
{ params: { sel: 'many' } }
)
if (res.meta.status !== 200) {
return this.$message.error('獲取動態引數串列失敗')
}
// 將attr_vals字串轉換為陣列
res.data.forEach(item => {
item.attr_vals =
item.attr_vals.length === 0 ? [] : item.attr_vals.split(' ')
})
this.manyTableData = res.data
} else if (this.activeIndex === '2') {
// 發送請求獲取靜態屬性
const { data: res } = await this.$http.get('categories/' + this.addForm.goods_cat[2] + '/attributes',
{ params: { sel: 'only' } }
)
if (res.meta.status !== 200) {
return this.$message.error('獲取靜態屬性串列失敗')
}
this.onlyTableData = res.data
}
}
},
handlePreview(file) {
//當用戶點擊圖片進行預覽時執行,處理圖片預覽
//形參file就是用戶預覽的那個檔案
this.previewPath = file.response.data.url
//顯示預覽圖片對話框
this.previewVisible = true
},
handleRemove(file) {
//當用戶點擊X號洗掉時執行
//形參file就是用戶點擊洗掉的檔案
//獲取用戶點擊洗掉的那個圖片的臨時路徑
const filePath = file.response.data.tmp_path
//使用findIndex來查找符合條件的索引
const index = this.addForm.pics.findIndex(item => item.pic === filePath)
//移除索引對應的圖片
this.addForm.pics.splice(index, 1)
},
handleSuccess(response) {
//當上傳成功時觸發執行
//形參response就是上傳成功之后服務器回傳的結果
//將服務器回傳的臨時路徑保存到addForm表單的pics陣列中
this.addForm.pics.push({ pic: response.data.tmp_path })
},
//撰寫點擊事件完成商品添加
add(){
this.$refs.addFormRef.validate(async valid=>{
if(!valid) return this.$message.error("請填寫必要的表單項!")
//將addForm進行深拷貝,避免goods_cat陣列轉換字串之后導致級聯選擇器報錯
const form = _.cloneDeep(this.addForm)
//將goods_cat從陣列轉換為"1,2,3"字串形式
form.goods_cat = form.goods_cat.join(",")
//處理attrs陣列,陣列中需要包含商品的動態引數和靜態屬性
//將manyTableData(動態引數)處理添加到attrs
this.manyTableData.forEach(item=>{
form.attrs.push({ attr_id:item.attr_id, attr_value:item.attr_vals.join(" ") })
})
//將onlyTableData(靜態屬性)處理添加到attrs
this.onlyTableData.forEach(item=>{
form.attrs.push({ attr_id:item.attr_id, attr_value:item.attr_vals })
})
//發送請求完成商品的添加,商品名稱必須是唯一的
const {data:res} = await this.$http.post('goods',form)
if(res.meta.status !== 201){
return this.$message.error('添加商品失敗')
}
this.$message.success('添加商品成功')
//編程式導航跳轉到商品串列
this.$router.push('/goods')
})
},
}
}
</script>
<style scoped>
.el-checkbox {
margin: 0 10px 0 0 !important;
}
.previewImg {
width: 100%;
}
.btnAdd {
margin-top: 15px;
}
.el-checkbox {
margin: 0 10px 0 0 !important;
}
.previewImg {
width: 100%;
}
.btnAdd {
margin-top: 15px;
}
</style>
3、分類引數
<template>
<div>
<!-- 面包屑導航 -->
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/home' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item>商品管理</el-breadcrumb-item>
<el-breadcrumb-item>分類引數</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片視圖區域 -->
<el-card>
<!-- 警告區域 :closable="false"(是否展示“X”號) show-icon(顯示圖示) -->
<el-alert title="注意:只允許為第三級分類設定相關引數" type="warning" :closable="false" show-icon>
</el-alert>
<!-- 選擇商品分類區域 -->
<el-row class="cat_opt">
<el-col>
<span>選擇商品分類:</span>
<!-- 選擇商品分類的級聯選擇框 -->
<el-cascader expandTrigger='hover' v-model="selectedCateKeys" :options="cateList" :props="cateProps" @change="handleChange" clearable></el-cascader>
</el-col>
<el-col>
<!-- tab頁簽區域 -->
<el-tabs v-model="activeName" @tab-click="handleTabClick">
<!-- 添加動態引數的面板 將標簽頁改為many -->
<el-tab-pane label="動態引數" name="many">
<el-button size="mini" type="primary" :disabled="isButtonDisabled" @click="add()">添加引數</el-button>
<!-- 添加分類對話框 -->
<el-dialog title="添加動態引數" :visible.sync="addCateDialogVisible" width="50%" @close="addCateDialogClosed">
<!-- 添加分類表單 -->
<el-form :model="param" label-width="100px">
<el-form-item label="引數名稱" prop="attr_name">
<el-input v-model="param.attr_name"></el-input>
</el-form-item>
<el-form-item label="[only,many]" prop="attr_sel" v-show="false">
<el-input v-model="param.attr_sel">many</el-input>
</el-form-item>
<el-form-item label="引數詳情" prop="attr_vals">
<el-input v-model="param.attr_vals"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="res">取 消</el-button>
<el-button type="primary" @click="addMany">確 定</el-button>
</span>
</el-dialog>
<!-- 動態引數表格 -->
<el-table :data="manyTableData" border stripe>
<!-- 展開行 -->
<el-table-column type="expand">
<template slot-scope="scope">
<!-- 回圈渲染Tag標簽 -->
<el-tag v-for="(item,i) in scope.row.attr_vals" :key="i" closable @close="handleClose(i,scope.row)">{{item}}</el-tag>
<!-- 輸入的文本框 -->
<el-input class="input-new-tag" v-if="scope.row.inputVisible" v-model="scope.row.inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(scope.row)" @blur="handleInputConfirm(scope.row)"></el-input>
<!-- 添加按鈕 -->
<el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button>
</template>
</el-table-column>
<!-- 索引列 -->
<el-table-column type="index"></el-table-column>
<el-table-column label="引數名稱" prop="attr_name"></el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button size="mini" type="primary" icon="el-icon-edit" @click="bj(scope.row.attr_id)">編輯</el-button>
<el-button size="mini" type="danger" icon="el-icon-delete" @click="del(scope.row.attr_id)">洗掉</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<!-- 添加靜態屬性的面板 將標簽頁改為only -->
<el-tab-pane label="靜態屬性" name="only">
<el-button size="mini" type="primary" :disabled="isButtonDisabled" @click="oponly">添加屬性</el-button>
<el-dialog title="添加靜態屬性" :visible.sync="addCateDialogVisible2" width="50%" @close="addCateDialogClosed">
<!-- 添加分類表單 -->
<el-form :model="param" label-width="100px">
<el-form-item label="引數名稱" prop="attr_name">
<el-input v-model="param.attr_name"></el-input>
</el-form-item>
<el-form-item label="[only,many]" prop="attr_sel" v-show="false">
<el-input v-model="param.attr_sel" >only</el-input>
</el-form-item>
<el-form-item label="引數詳情" prop="attr_vals">
<el-input v-model="param.attr_vals"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="res">取 消</el-button>
<el-button type="primary" @click="addonly">確 定</el-button>
</span>
</el-dialog>
<!-- 靜態屬性表格 -->
<el-table :data="onlyTableData" border stripe>
<!-- 索引列 -->
<el-table-column type="index"></el-table-column>
<el-table-column label="屬性名稱" prop="attr_name"></el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button size="mini" type="primary" icon="el-icon-edit" @click="bj2(scope.row.attr_id)">編輯</el-button>
<el-button size="mini" type="danger" icon="el-icon-delete" @click="del(scope.row.attr_id)">洗掉</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
addCateDialogVisible:false,
addCateDialogVisible2:false,
//分類串列
cateList: [],
//用戶在級聯下拉選單中選中的分類id
selectedCateKeys: [],
//配置級聯選單中資料如何展示
cateProps: {
value: 'cat_id',
label: 'cat_name',
children: 'children'
},
pid:'',
param:{
attr_name:'',attr_sel:'',attr_vals:''
},
//tab頁簽激活顯示的頁簽項
activeName: 'many',
//用來保存動態引數資料
manyTableData: [],
//用來保存靜態屬性資料
onlyTableData: []
}
},
created() {
this.getCateList()
},
methods: {
add(){
this.pid = '';
this.addCateDialogVisible = true;
},
oponly(){
this.pid = '';
this.addCateDialogVisible2 = true;
},
res(){
this.param = {};
this.addCateDialogVisible = false;
this.addCateDialogVisible2 = false;
this.pid = '';
},
async addMany(){
console.log("cateId="+this.cateId);
console.log("this.pid"+this.pid);
if (this.pid==''){
console.log("新增動態");
this.param.attr_sel = "many";
const { data: res } = await this.$http.post(`categories/${this.cateId}/attributes`,this.param);
if (res.meta.status !== 201) {
return this.$message.error('創建動態引數失敗')
}
this.$message.success('創建動態引數成功');
}else {
console.log("編輯動態");
const { data: res } = await this.$http.put(`categories/${this.cateId}/attributes/${this.pid}`,this.param);
if (res.meta.status !== 200) {
return this.$message.error('編輯動態引數失敗')
}
this.$message.success('編輯動態引數成功');
}
this.handleChange();
this.param = {};
this.addCateDialogVisible = false;
},
async addonly(){
console.log("cateId="+this.cateId);
console.log("this.pid"+this.pid);
if (this.pid==''){
console.log("新增靜態");
this.param.attr_sel = "only";
const { data: res } = await this.$http.post(`categories/${this.cateId}/attributes`,this.param);
if (res.meta.status !== 201) {
return this.$message.error('新增靜態失敗')
}
this.$message.success('新增靜態成功');
}else {
console.log("編輯靜態");
const { data: res } = await this.$http.put(`categories/${this.cateId}/attributes/${this.pid}`,this.param);
if (res.meta.status !== 200) {
return this.$message.error('編輯靜態引數失敗')
}
this.$message.success('編輯靜態引數成功');
}
this.handleChange();
this.param = {};
this.addCateDialogVisible2 = false;
},
async bj(id){
console.log("id="+id);
this.pid = id;
this.addCateDialogVisible = true;
const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes/${id}`);
this.param = res.data;
if (res.meta.status !== 200) {
return this.$message.error('查詢分類失敗')
}else {
this.$message.success('查詢分類成功')
}
},
async bj2(id){
console.log("id="+id);
this.pid = id;
this.addCateDialogVisible2 = true;
const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes/${id}`);
this.param = res.data;
if (res.meta.status !== 200) {
return this.$message.error('查詢分類失敗')
}else {
this.$message.success('查詢分類成功')
}
},
del(id){
this.$confirm('此操作將永久洗掉該檔案, 是否繼續?', '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
console.log("id="+id);
console.log(`categories/${this.cateId}/attributes/${id}`)
this.$http.delete(`categories/${this.cateId}/attributes/${id}`).then(() => {
this.handleChange();
}),
this.$message({
type: 'success',
message: '洗掉成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消洗掉'
});
});
},
async getCateList(){
//獲取所有的商品分類串列
const { data: res } = await this.$http.get('categories')
if (res.meta.status !== 200) {
return this.$message.error('獲取分類資料失敗')
}
//將資料串列賦值給cateList
this.cateList = res.data
// //保存總資料條數
// this.total = res.data.total
// console.log(res.data);
},
// 修改原handleChange方法
async handleChange() {
// 證明選中的不是三級分類
if (this.selectedCateKeys.length !== 3) {
this.selectedCateKeys = []
this.manyTableData = []
this.onlyTableData = []
return
}
// 證明選中的是三級分類
console.log(this.selectedCateKeys)
// 根據所選分類的Id,和當前所處的面板,獲取對應的引數
const { data: res } = await this.$http.get(
`categories/${this.cateId}/attributes`,
{
params: { sel: this.activeName }
}
)
if (res.meta.status !== 200) {
return this.$message.error('獲取引數串列失敗!')
}
// 處理文本框中的值
res.data.forEach(item => {
item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : []
// 控制文本框的顯示與隱藏
item.inputVisible = false
// 文本框中輸入的值
item.inputValue = ''
})
console.log(res.data)
if (this.activeName === 'many') {
this.manyTableData = res.data
} else {
this.onlyTableData = res.data
}
},
handleTabClick() {
console.log(this.activeName)
this.handleChange()
},
// 展示輸入框
showInput(row){
//用戶點擊添加按鈕時觸發
row.inputVisible = true
//$nextTick:在頁面上元素被重新渲染之后,呼叫回呼函式的代碼
this.$nextTick.then(()=>{
//讓文本框自動獲得焦點
this.$refs.saveTagInput.$refs.input.focus()
})
},
handleInputConfirm(row){
//當用戶在文本框中按下enter鍵或者焦點離開時都會觸發執行
//判斷用戶在文本框中輸入的內容是否合法
if(row.inputValue.trim().length===0){
row.inputValue = ''
row.inputVisible = false
return
}
// row.inputVisible = false
//如果用戶輸入了真實合法的資料,需要保存起來
row.attr_vals.push(row.inputValue.trim())
row.inputValue = ''
row.inputVisible = false
this.saveAttrVals(row)
},
handleClose(index,row){
//洗掉對應索引的引數可選項
row.attr_vals.splice(index,1)
//呼叫函式,完成保存可選項的操作
this.saveAttrVals(row)
},
async saveAttrVals(row){
//封裝函式,完成保存可選項的操作
//發起請求,保存引數細項
const {data:res} = await this.$http.put(`categories/${this.cateId}/attributes/${row.attr_id}`,
{attr_name:row.attr_name,attr_sel:row.attr_sel,attr_vals:row.attr_vals.join(' ')})
if (res.meta.status !== 200) {
return this.$message.error('修改引數項失敗')
}
this.$message.success('修改引數項成功')
}
},
computed: {
//添加計算屬性用來獲取按鈕禁用與否
isButtonDisabled() {
return this.selectedCateKeys.length !== 3
},
//獲取選中的三級分類id
cateId() {
if (this.selectedCateKeys.length === 3) {
return this.selectedCateKeys[this.selectedCateKeys.length - 1]
}
return null
},
}
}
</script>
(6)訂單管理
<template>
<div>
<h3>訂單串列</h3>
<!-- 面包屑導航 -->
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/home' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item>訂單管理</el-breadcrumb-item>
<el-breadcrumb-item>訂單串列</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片視圖區域 -->
<el-card>
<!-- 搜索欄 -->
<el-row :gutter="20">
<el-col :span="8">
<el-input placeholder="請輸入內容" v-model="queryInfo.query" clearable>
<el-button slot="append" icon="el-icon-search" @click="getOrderList"></el-button>
</el-input>
</el-col>
</el-row>
<!-- 訂單表格 -->
<el-table :data="orderList" border stripe>
<el-table-column type="index"></el-table-column>
<el-table-column label="訂單編號" prop="order_number"></el-table-column>
<el-table-column label="訂單價格" prop="order_price"></el-table-column>
<el-table-column label="是否付款" prop="pay_status">
<template slot-scope="scope">
<el-tag type="success" v-if="scope.row.pay_status === '1'">已付款</el-tag>
<el-tag type="danger" v-else>未付款</el-tag>
</template>
</el-table-column>
<el-table-column label="是否發貨" prop="is_send"></el-table-column>
<el-table-column label="下單時間" prop="create_time">
<template slot-scope="scope">
{{scope.row.create_time | dateFormat}}
</template>
</el-table-column>
<el-table-column label="操作" width="125px">
<template slot-scope="scope">
<!-- 給修改地址按鈕添加點擊事件 -->
<el-button size="mini" type="primary" icon="el-icon-edit" @click="showEditAddress(scope.row.order_id)" ></el-button>
<!-- 給查看物流添加點擊事件 -->
<el-button size="mini" type="success" icon="el-icon-location" @click="showProgress(scope.row.order_id)"></el-button>
</template>
</el-table-column>
</el-table>
<!-- 分頁 -->
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="queryInfo.pagenum" :page-sizes="[3, 5, 10, 15]" :page-size="queryInfo.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</el-card>
<!-- 修改地址對話框 -->
<el-dialog title="修改識訓地址" :visible.sync="addressVisible" width="50%" @close="addressDialogClosed">
<!-- 添加表單 -->
<el-form :model="addressForm" :rules="addressFormRules" ref="addressFormRef" label-width="100px">
<el-form-item label="省市區縣" prop="address1">
<el-cascader :options="cityData" v-model="addressForm.address1"></el-cascader>
</el-form-item>
<el-form-item label="詳細地址" prop="address2">
<el-input v-model="addressForm.address2"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addressVisible = false">取 消</el-button>
<el-button type="primary" @click="addressVisible = false">確 定</el-button>
</span>
</el-dialog>
<!-- 物流資訊進度對話框 -->
<el-dialog title="物流進度" :visible.sync="progressVisible" width="50%">
<!-- 時間線組件 -->
<el-timeline>
<el-timeline-item v-for="(activity, index) in progressInfo"
:key="index" :timestamp="activity.time">
{{activity.context}}
</el-timeline-item>
</el-timeline>
</el-dialog>
</div>
</template>
<script>
import cityData from './citydata.js'
export default {
data() {
return {
//查詢條件
queryInfo: {
query: '',
pagenum: 1,
pagesize: 10
},
//訂單串列資料
orderList: [],
//資料總條數
total: 0,
//控制修改地址對話框的顯示和隱藏
addressVisible:false,
//修改識訓地址的表單
addressForm: {
address1: [],
address2: ''
},
//控制物流進度對話框的顯示和隱藏
progressVisible: false,
//保存物流資訊
progressInfo: [],
addressFormRules:{
address1:[{ required: true, message: '請選擇省市區縣', trigger: 'blur' }],
address2:[{ required: true, message: '請輸入詳細地址', trigger: 'blur' }],
},
//將匯入的cityData資料保存起來
cityData:cityData
}
},
created() {
this.getOrderList()
},
methods: {
async getOrderList() {
console.log("query="+this.queryInfo.query)
const { data: res } = await this.$http.get('orders', {
params: this.queryInfo
})
if (res.meta.status !== 200) {
return this.$message.error('獲取訂單串列資料失敗!')
}
this.total = res.data.total
this.orderList = res.data.goods
},
handleSizeChange(newSize){
this.queryInfo.pagesize = newSize
this.getOrderList()
},
handleCurrentChange(newPage){
this.queryInfo.pagenum = newPage
this.getOrderList()
},
async showEditAddress(id) {
//當用戶點擊修改識訓地址按鈕時觸發
this.addressVisible = true;
console.log("id="+id);
const { data: res } = await this.$http.get('orders/'+id);
this.addressForm = res.data;
},
addressDialogClosed(){
this.$refs.addressFormRef.resetFields()
},
async showProgress(id) {
//發送請求獲取物流資料
console.log(id)
const { data: res } = await this.$http.get('/kuaidi/'+id);
if (res.meta.status !== 200) {
return this.$message.error('獲取物流進度失敗!')
}
this.progressInfo = res.data
//顯示對話框
this.progressVisible = true
},
}
}
</script>
<style lang="less" scoped>
.el-cascader{
width: 100%;
}
</style>
(7)資料統計
<template>
<div>
<!-- 面包屑導航區域 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item>資料統計</el-breadcrumb-item>
<el-breadcrumb-item>資料報表</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片視圖區域 -->
<el-card>
<!-- 2. 為ECharts準備一個具備大小(寬高)的Dom -->
<div id="main" style="width: 750px;height:400px;"></div>
</el-card>
</div>
</template>
<script>
// 1. 匯入 echarts
import echarts from 'echarts'
import _ from 'lodash'
export default {
data() {
return {
// 需要合并的資料
options: {
title: {
text: '用戶來源'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#E9EEF3'
}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
boundaryGap: false
}
],
yAxis: [
{
type: 'value'
}
]
}
}
},
created() {},
// 此時,頁面上的元素,已經被渲染完畢了!
async mounted() {
// 3. 基于準備好的dom,初始化echarts實體
var myChart = echarts.init(document.getElementById('main'))
const { data: res } = await this.$http.get('reports/type/1')
if (res.meta.status !== 200) {
return this.$message.error('獲取折線圖資料失敗!')
}
// 4. 準備資料和配置項
const result = _.merge(res.data, this.options)
console.log("result="+result);
// 5. 展示資料
myChart.setOption(result)
},
methods: {}
}
</script>
<style lang="less" scoped>
</style>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/384299.html
標籤:其他
