food/src/views/layout/components/headbar.vue
szdot 8e5a6428e3 【类 型】:feat
【原  因】:增加了机型管理里面 添加和更新 功能
【过  程】:新增表单页面组件,实现添加与编辑逻辑,支持 shop_id、机型类型、载重等字段的录入和更新
【影  响】:
2025-06-19 03:14:39 +08:00

402 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<!-- menu缩进按钮 -->
<div class="w-50px h-50px fc l" id="menuTabB" @click="handleCollapse">
<i class="iconfont f-s-26" :class="isCollapse ? 'icon-a-yousuojin3x' : 'icon-a-zuosuojin3x'"></i>
</div>
<!-- 面包屑 -->
<Breadcrumb class="l l-h-50 m-l-5" />
<!-- 头像 -->
<div class="right-menu m-r-5">
<el-dropdown class="avatar-container" trigger="click" @command="handleCommand">
<div class="avatar-wrapper">
<img v-if="avatar && (
avatar.includes('.jpg') ||
avatar.includes('.gif') ||
avatar.includes('.png')
)" :src="avatar + '?imageView2/1/w/80/h/80'" class="user-avatar" />
<el-avatar v-else size="medium" icon="el-icon-user-solid"></el-avatar>
<i class="el-icon-caret-bottom"></i>
</div>
<el-dropdown-menu slot="dropdown" class="user-dropdown">
<!-- 自定义语言设置为右侧弹出 -->
<el-dropdown-item>
<el-popover placement="right-start" width="150" trigger="hover" v-model="languagePopoverVisible">
<el-radio-group v-model="currentLang" @change="changeLang">
<el-radio label="zh-CN">简体中文</el-radio>
<!-- 其他语言可继续添加 -->
<!-- <el-radio label="en" class="m-t-10">English</el-radio> -->
</el-radio-group>
<span slot="reference" class="mainFontColor f-s-16"><i class="iconfont icon-zhongyingwen m-r-10"></i>语言设置</span>
</el-popover>
</el-dropdown-item>
<el-dropdown-item class="mainFontColor f-s-16" command="go-setting"><i class="iconfont icon-shezhi m-r-10"></i>设置</el-dropdown-item>
<el-dropdown-item class="mainFontColor f-s-16" divided command="logout"><i class="iconfont icon-logout m-r-10"></i>退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<!-- 页面刷新 -->
<div class="l-h-50 p-r-15 r">
<el-button size="small" icon="iconfont icon-shuaxin" @click="refreshPage" circle></el-button>
</div>
<!-- 订单信息按钮 -->
<el-badge :hidden="pendingCount + processingCount + shippedCount + requestedCount == 0
? true
: false
" :value="pendingCount + processingCount + shippedCount + requestedCount" class="navbarBadge l-h-50 p-r-15 r">
<el-button :type="pendingCount + processingCount + shippedCount + requestedCount !== 0
? 'primary'
: ''
" @click="drawer = true" size="small" :icon="orderIcon" circle></el-button>
</el-badge>
<el-drawer :custom-class="$store.state.app.isWideScreen ? 'el-drawer-small' : 'el-drawer-large'"
:visible.sync="drawer" :size="$store.state.app.isWideScreen ? '90%' : '60%'" :append-to-body="true"
:modal-append-to-body="false" :direction="$store.state.app.isWideScreen ? 'btt' : 'rtl'">
<template slot="title">
<div>
<i class="l f-s-18 iconfont icon-jinjidingdan m-r-5 l-h-18"></i>
<h3>待处理订单</h3>
</div>
</template>
<el-button-group class="m-l-20 m-b-15">
<SelectionShopId v-model="shop_id" />
</el-button-group>
<el-tabs type="border-card">
<el-tab-pane>
<template slot="label">
<span>未接单</span>
<el-badge :hidden="pendingCount == 0 ? true : false" :value="pendingCount">
</el-badge>
</template>
<QuestTabs :list="pendingList" type="未接单" />
</el-tab-pane>
<el-tab-pane>
<template slot="label">
<span>已接单</span>
<el-badge :hidden="processingCount == 0 ? true : false" :value="processingCount">
</el-badge>
</template>
<QuestTabs :list="processingList" type="已接单" />
</el-tab-pane>
<el-tab-pane>
<template slot="label">
<span>已发货</span>
<el-badge :hidden="shippedCount == 0 ? true : false" :value="shippedCount">
</el-badge>
</template>
<QuestTabs :list="shippedList" type="已发货" @close-drawer="drawer = false" />
</el-tab-pane>
<el-tab-pane>
<template slot="label">
<span>退款申请中</span>
<el-badge :hidden="requestedCount == 0 ? true : false" :value="requestedCount">
</el-badge>
</template>
<QuestTabs :list="requestedList" type="退款申请中" />
</el-tab-pane>
</el-tabs>
</el-drawer>
<!-- mqtt状态灯 -->
<div class="l-h-50 p-r-15 r">
<el-button size="small" :type="mqttState === true ? 'success' : 'danger'" :icon="mqttState === true
? 'iconfont icon-yaokong2'
: 'iconfont icon-yaokong2-copy'
" circle @click="
mqttState === true
? $message.success('指令服务器链接正常')
: $message.error('未链接到指令服务器')
"></el-button>
</div>
</div>
</template>
<script>
import Breadcrumb from '@/components/Breadcrumb'
import QuestTabs from '@/components/QuestTabs'
import SelectionShopId from '@/components/SelectionShopId'
import { speakText } from '@/utils/index'
export default {
name: 'Headbar',
data () {
return {
shop_id: this.$store.state.user.shop_id, // 商铺id(默认为本店) 过滤条件
drawer: false,
getQuestInterval: null, // 用于销毁时间轴
animationTrumpet: true, // 喇叭动画
currentLang: 'zh-CN',
languagePopoverVisible: false // 控制语言弹出框可见
}
},
components: {
Breadcrumb,
QuestTabs,
SelectionShopId
},
computed: {
/**
* @description: 侧边栏显隐
*/
isCollapse () {
return this.$store.state.app.isCollapse
},
/**
* @description: mqtt服务器连接状态
*/
mqttState () {
return this.$store.state.app.mqttState
},
/**
* @description: 用户头像地址
*/
avatar () {
return this.$store.state.settings.photoPath + this.$store.state.user.photo
},
/**
* @description: 获取 已付款 和已退款但是发货状态为 已发货 订单列表
*/
paidOrderList () {
return this.$store.state.paidOrderList.filter(
(item) => item.shop_id === this.shop_id
)
},
/**
* @description: 过滤 未接单 并且没有申请退款的 订单
*/
pendingList () {
return this.paidOrderList.filter(
(item) =>
item.main_status === '已付款' &&
item.shipment_status === '未接单' &&
item.refund_status !== '申请中'
)
},
/**
* @description: 未接单 总数
*/
pendingCount () {
return this.pendingList.length
},
/**
* @description: 过滤 已接单 并且没有申请退款的 订单
*/
processingList () {
return this.paidOrderList.filter(
(item) =>
item.main_status === '已付款' &&
item.shipment_status === '已接单' &&
item.refund_status !== '申请中'
)
},
/**
* @description: 已接单 总数
*/
processingCount () {
return this.processingList.length
},
/**
* @description: 过滤 已发货 并且没有申请退款的 订单
*/
shippedList () {
return this.paidOrderList.filter(
(item) =>
item.shipment_status === '已发货'
)
},
/**
* @description: 已发货 总数
*/
shippedCount () {
return this.shippedList.length
},
/**
* @description: 过滤 退款申请中 订单
*/
requestedList () {
return this.paidOrderList.filter(
(item) => item.refund_status === '申请中'
)
},
/**
* @description: 退款申请中 总数
*/
requestedCount () {
return this.requestedList.length
},
/**
* @description: 面包条 订单图标动画
* @return {*} 图标样式
*/
orderIcon () {
if (
this.pendingCount +
this.processingCount +
this.shippedCount +
this.requestedCount ===
0
) {
return 'iconfont icon-meiyoudingdan-01'
} else {
if (this.animationTrumpet) {
return 'iconfont icon-tongzhi'
} else {
return 'iconfont icon-jinjidingdan'
}
}
}
},
methods: {
speakText,
/**
* @description: 切换侧边栏 显隐
*/
handleCollapse () {
this.$store.commit('app/setCollapse')
},
/**
* @description: 计算订单数量 订单变化播放声音 显示在图标右上角小红圈内
*/
computeQuestList () { },
/**
* @description: 刷新当前页面
*/
refreshPage () {
/* init 数据接口 */
this.$store.commit('app/setIsMobile') // 获取客户端平台类型
this.$store.dispatch('fetchPlaneClassList')// 获取机型列表
this.$store.dispatch('fetchAirList') // 获取飞机列表
this.$store.dispatch('fetchShopList') // 获取商铺列表
this.$store.dispatch('fetchAdminList') // 获取管理员列表
this.$store.dispatch('fetchSiteList') // 获取站点列表
this.$store.dispatch('fetchRouteList') // 获取航线列表
this.$store.dispatch('fetchNoflyData', this.$store.state.user.shop_id)// 获取禁飞区数据 注意这里要有shopid 总管理员再操作其他商铺飞机时 要刷新此缓存 需要对应商铺的禁飞区数据
this.$store.dispatch('fetchCategoryList') // 获取分类列表(小程序)
this.$store.dispatch('fetchPaidOrderList') // 获取订单列表
this.$store.dispatch('fetchMessageList')// 获取管理员公告列表 并弹出公告框
},
/**
* @description: 登出
*/
logout () {
this.$store
.dispatch('user/destroyUserAsync')
.then(this.$router.push('/login'))
},
handleCommand (command) {
if (command === 'go-setting') {
this.$router.push('/home/set')
} else if (command === 'logout') {
this.logout()
}
},
changeLang (lang) {
this.currentLang = lang
// 如果用 vue-i18n
// this.$i18n.locale = lang;
localStorage.setItem('lang', lang)
this.$message.success(`语言切换为:${lang === 'zh-CN' ? '简体中文' : lang}`)
this.languagePopoverVisible = false // 切换后关闭子菜单
}
},
watch: {
paidOrderList: {
handler (newVal, oldVal) {
// 面包条订单图标跳动
if (this.getQuestInterval !== null) {
clearInterval(this.getQuestInterval)
}
if (newVal.length > 0) {
// 订单更新时 订单数大于0 面包条订单图标跳动
this.getQuestInterval = setInterval(() => {
this.animationTrumpet = !this.animationTrumpet // 面包条订单图标跳动
}, 500)
}
// 播报新的订单
if (newVal.length > oldVal.length) {
this.speakText('有新的订单')
}
},
deep: true
},
requestedCount: {
handler (newVal, oldVal) {
// 播报退款订单
if (newVal.length > oldVal.length) {
this.speakText('有订单申请退款')
}
}
}
},
created () { }
}
</script>
<style lang="scss" scoped>
@import '@/styles/theme.scss';
#menuTabB:hover {
background-color: $white-color;
cursor: pointer;
}
.el-dropdown-menu {
span {
color: $maintext-color;
}
}
.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;
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;
}
}
}
}
</style>