travel/admin/src/layout/components/Navbar.vue

566 lines
15 KiB
Vue

<template>
<div class="navbar">
<hamburger
id="hamburger-container"
:is-active="sidebar.opened"
class="hamburger-container"
@toggleClick="toggleSideBar"
/>
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
<div class="right-menu">
<template v-if="device !== 'mobile'">
<!-- <search id="header-search" class="right-menu-item" /> -->
<!-- <screenfull id="screenfull" class="right-menu-item hover-effect" />
<el-tooltip content="Global Size" effect="dark" placement="bottom">
<size-select id="size-select" class="right-menu-item hover-effect" />
</el-tooltip> -->
</template>
<!-- <div class="right-menu-item hover-effect">
<el-button @click="drawer = true">QA常见问题</el-button>
</div>-->
<div v-if="appointment_num" class="right-menu-item hover-effect">
<el-button style="color: red" @click="handleAppointemnet()"
>预约待处理({{ appointment_num }})</el-button
>
</div>
<div v-if="$store.getters.is_anchor" class="right-menu-item hover-effect">
<el-button @click="dialogWorks = true"
>排班{{ $store.getters.name }}</el-button
>
</div>
<div class="right-menu-item hover-effect">
<el-button
:style="{
backgroundColor: !workstatus ? '#409EFF' : '#fff',
color: workstatus ? '#979797' : '#fff',
}"
@click="startWorks"
>{{ workstatus ? "上班" : "上班中" }}</el-button
>
<el-button
:style="{
backgroundColor: workstatus ? '#409EFF' : '#fff',
color: workstatus ? '#fff' : '#979797',
}"
@click="endWorks"
>{{ workstatus ? "下班中" : "下班" }}</el-button
>
</div>
<el-dropdown
class="avatar-container right-menu-item hover-effect"
trigger="click"
>
<div class="avatar-wrapper">
<img
:src="avatar + '?imageView2/1/w/80/h/80'"
class="user-avatar"
alt=""
/>
<i
class="el-icon-camera"
style="position: absolute"
@click.stop="showAvatar = true"
/>
<i class="el-icon-caret-bottom" />
</div>
<el-dropdown-menu slot="dropdown">
<!-- <router-link to="/profile/index">
<el-dropdown-item>Profile</el-dropdown-item>
</router-link> -->
<router-link to="/">
<el-dropdown-item>系统面板</el-dropdown-item>
</router-link>
<div @click="dialogPWD = true">
<el-dropdown-item>修改密码</el-dropdown-item>
</div>
<el-dropdown-item divided @click.native="logout">
<span style="display: block">退出登录</span>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<el-dialog title="提示" :visible.sync="showAvatar" width="30%" center>
<el-upload
class="avatar-uploader"
action="/admin/index/avatar"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img v-if="imageUrl" :src="imageUrl" class="avatar" alt="" />
<i v-else class="el-icon-plus avatar-uploader-icon" />
</el-upload>
</el-dialog>
<el-dialog
title="修改密码"
:show-close="isPassword"
:close-on-press-escape="isPassword"
:close-on-click-modal="isPassword"
:visible.sync="dialogPWD"
>
<el-form ref="formName" :rules="rules" :model="form">
<el-form-item label="旧密码" prop="oldpwd">
<el-input v-model="form.oldpwd" autocomplete="off" />
</el-form-item>
<el-form-item label="新密码" prop="pwd">
<el-input v-model="form.pwd" autocomplete="off" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button v-if="isPassword" @click="dialogPWD = false"
>取 消</el-button
>
<el-button type="primary" @click="pwd">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="排班" width="90%" :visible.sync="dialogWorks">
<el-form :rules="rules">
<el-row style="margin-bottom: 10px">
<el-col :span="24">
<el-date-picker
v-model="times[0]"
placeholder="选择开始时间"
default-time="07:00:00"
type="datetime"
/>
</el-col>
</el-row>
<el-row style="margin-bottom: 10px">
<el-col :span="24">
<el-date-picker
v-model="times[1]"
placeholder="选择结束时间"
default-time="07:59:59"
type="datetime"
/>
</el-col>
</el-row>
<el-row style="margin-bottom: 10px">
<el-col :span="24">
<el-checkbox-group v-model="os">
<el-checkbox
v-for="(v, i, k) in $store.getters.oss"
:key="k"
:label="i"
>{{ v }}</el-checkbox
>
</el-checkbox-group>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogWorks = false">取 消</el-button>
<el-button type="primary" @click="saveWork">确 定</el-button>
</div>
</el-dialog>
<el-drawer
:with-header="false"
:visible.sync="drawer"
size="800px"
direction="rtl"
:modal="false"
>
<div v-clickoutside="handleClose" class="drawer">
<el-button v-if="QaShow" type="success" @click="drawer = false"
>关 闭</el-button
>
<el-button v-if="!QaShow" type="success" @click="QaShow = true"
>返 回</el-button
>
<div v-if="QaShow" class="mod">
<el-button
v-for="item in getQaCityList"
:key="item.city_id"
style="width: 150px"
size="medium"
type="primary"
@click="clickQaList(item)"
>
{{ item.city_name }}
</el-button>
</div>
<div v-if="QaInfo && !QaShow" class="ver">
<div v-for="getQaList in getQaLists">
<div class="ver_title">{{ getQaList.title }}</div>
<div class="ver_content">{{ getQaList.content }}</div>
</div>
</div>
</div>
</el-drawer>
</div>
</template>
<script>
import { mapGetters } from "vuex";
import Breadcrumb from "@/components/Breadcrumb";
import Hamburger from "@/components/Hamburger";
import Screenfull from "@/components/Screenfull";
import SizeSelect from "@/components/SizeSelect";
import Search from "@/components/HeaderSearch";
import { color } from "echarts/lib/export";
import sidebar from "@/layout/components/Sidebar/index.vue";
import avatar from "element-ui/packages/avatar";
import { getQaCityList, getQaList } from "@/api/qa";
import clickoutside from "element-ui/src/utils/clickoutside";
import { Local } from "@/utils/storage";
export default {
directives: { clickoutside },
components: {
Breadcrumb,
Hamburger,
Screenfull,
SizeSelect,
// eslint-disable-next-line vue/no-unused-Wangeditor
Search,
},
props: {
appointment_num: {
type: Number,
default: 0,
},
},
computed: {
avatar() {
return avatar;
},
sidebar() {
return sidebar;
},
...mapGetters(["sidebar", "avatar", "device"]),
},
// eslint-disable-next-line vue/order-in-Wangeditor
data() {
var validatePassword = (rule, password, callback) => {
const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,16}$/;
if (!passwordRegex.test(password)) {
callback(new Error("新密码要求包含字母和数字并且长度在8到16位"));
} else {
callback();
}
};
return {
workstatus: false,
drawer: false,
showAvatar: false,
dialogPWD: false,
dialogWorks: false,
centerDialogVisible: false,
imageUrl: false,
QaShow: true,
os: [],
isPassword: true,
getQaCityList: [],
getQaLists: [],
times: [],
form: {
oldpwd: "",
pwd: "",
},
QaInfo: {
title: "",
content: "",
},
rules: {
oldpwd: [
{ required: true, message: "请输入旧密码", trigger: "blur" },
{
min: 6,
max: 20,
message: "长度在 6 到 20 个字符",
trigger: "blur",
},
],
pwd: [
{ required: true, validator: validatePassword, trigger: "blur" },
// {
// min: 6,
// max: 20,
// message: "长度在 6 到 20 个字符",
// trigger: "blur",
// },
],
},
};
},
created() {
this.getworkstatus();
getQaCityList().then((res) => {
this.getQaCityList = res.data;
});
},
mounted() {
if (Local.get("userInfo").change_passwd) {
this.dialogPWD = true;
this.isPassword = false;
}
},
methods: {
color,
toggleSideBar() {
this.$store.dispatch("app/toggleSideBar");
},
handleClose() {
this.drawer = false;
this.QaShow = true;
},
clickQaList(data) {
getQaList(data.city_id).then((res) => {
this.getQaLists = res.data;
});
console.log(JSON.stringify(this.getQaLists));
if (!this.getQaLists) {
return this.$message({
message: "暂无QA问题",
type: "warning",
duration: 1500,
});
}
this.QaShow = false;
},
async logout() {
await this.$store.dispatch("user/logout");
this.$router.push(`/login?redirect=${this.$route.fullPath}`);
},
handleAvatarSuccess(res, file) {
this.imageUrl = URL.createObjectURL(file.raw);
},
pwd() {
this.$refs["formName"].validate((valid) => {
if (valid) {
this.$axios
.post("/admin/admin/pwd", this.form)
.then((res) => {
this.dialogPWD = false;
this.isPassword = true;
this.form = {};
Local.remove("userInfo");
})
.catch((err) => {
console.log(err);
});
} else {
return false;
}
});
},
saveWork() {
this.$axios
.post("/admin/work/save2", { times: this.times, os: this.os })
.then((res) => {
console.log(res);
this.$message({
showClose: true,
message: "添加成功",
});
this.dialogWorks = false;
})
.catch((err) => {
console.log(err);
});
},
startWorks() {
this.$axios
.post("/admin/admin/editInfo", { is_order: 1 })
.then((res) => {
console.log(res);
this.$message({
showClose: true,
message: "上班成功",
});
this.getworkstatus();
})
.catch((err) => {
console.log(err);
});
},
endWorks() {
this.$axios
.post("/admin/admin/editInfo", { is_order: 0 })
.then((res) => {
console.log(res);
this.$message({
showClose: true,
message: "下班成功",
});
this.getworkstatus();
})
.catch((err) => {
console.log(err);
});
},
getworkstatus() {
this.$axios
.post("/admin/work/getworkstatus", { id: this.id })
.then((res) => {
console.log(res);
this.workstatus = res.data;
})
.catch((err) => {
console.log(err);
});
},
handleAppointemnet() {
this.$router.push({
path: "/order/index/",
query: { appointment_status: "1", refresh: Date.now() },
});
},
beforeAvatarUpload(file) {
/*const isJPG = file.type === 'image/jpeg'
const isLt2M = file.size / 1024 / 1024 < 2
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!')
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!')
}
return isJPG && isLt2M*/
},
},
};
</script>
<style lang="scss" scoped>
.drawer {
padding: 20px 0 0 20px;
width: 100%;
height: 100vh;
}
.mod {
margin-top: 50px;
}
.ver {
margin-top: 30px;
color: #6c6f71;
&_title {
font-size: 16px;
font-weight: bold;
margin-bottom: 12px;
}
&_content {
line-height: 26px;
font-size: 15px;
padding-bottom: 10px;
margin: 0 40px 26px 0;
border-bottom: 1px dashed #d3dcdc;
}
}
.navbar {
height: 50px;
overflow: hidden;
position: relative;
background: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.hamburger-container {
line-height: 46px;
height: 100%;
float: left;
cursor: pointer;
transition: background 0.3s;
-webkit-tap-highlight-color: transparent;
&:hover {
background: rgba(0, 0, 0, 0.025);
}
}
.breadcrumb-container {
float: left;
}
.errLog-container {
display: inline-block;
vertical-align: top;
}
.right-menu {
float: right;
height: 100%;
line-height: 50px;
&:focus {
outline: none;
}
.right-menu-item {
display: inline-block;
padding: 0 8px;
height: 100%;
font-size: 18px;
color: #5a5e66;
vertical-align: text-bottom;
&.hover-effect {
cursor: pointer;
transition: background 0.3s;
&:hover {
background: rgba(0, 0, 0, 0.025);
}
}
}
.avatar-container {
margin-right: 30px;
.avatar-wrapper {
margin-top: 5px;
position: relative;
.user-avatar {
cursor: pointer;
width: 40px;
height: 40px;
border-radius: 10px;
}
.el-icon-caret-bottom {
cursor: pointer;
position: absolute;
right: -20px;
top: 25px;
font-size: 12px;
}
}
}
}
}
.avatar-uploader .el-upload {
border: 1px solid #131313;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
border: 1px solid #979797;
border-radius: 15px;
font-size: 28px;
color: #8c939d;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
}
.avatar {
width: 100px;
height: 100px;
display: block;
border: 1px solid #979797;
border-radius: 15px;
}
</style>