提交 a840f385 作者: 毛细亚

合并分支 'release' 到 'master'

Release

查看合并请求 !10
......@@ -15,7 +15,16 @@
ref="menuRef"
>
<el-menu-item v-for="item in menuList" :key="item.path" :index="item.path" class="mobile-menu-item">
{{ item.label }}
<!-- 任务列表菜单项显示红点 -->
<div v-if="item.path === '/taskList' && hasTaskRedDot" class="menu-item-with-badge">
<div class="task-badge">
<el-badge is-dot>
<span>{{ item.label }}</span>
</el-badge>
</div>
</div>
<!-- 普通菜单项 -->
<span v-else>{{ item.label }}</span>
</el-menu-item>
</el-menu>
......@@ -43,10 +52,11 @@
<script>
import bindUserList from '@/views/components/bindGameAccount/bindUserList.vue'
import { getToken } from '@/utils/auth'
import { mapState, mapMutations } from 'vuex'
import { mapState, mapMutations, mapActions } from 'vuex'
import Cookies from 'js-cookie'
import { getParams } from '@/utils/index'
import Debug from '@/components/debug.vue'
export default {
name: 'App',
components: {
......@@ -97,10 +107,11 @@ export default {
label: '快捷发送',
path: '/quickSendGame'
},
// {
// label: '任务列表',
// path: '/taskList'
// },
{
label: '任务列表',
path: '/taskList',
hasRedDot: false // 红点状态
},
// {
// label: '通讯录',
// path: '/addressBook'
......@@ -113,7 +124,12 @@ export default {
}
},
computed: {
...mapState('user', ['external_userid', 'token']),
...mapState('user', ['external_userid', 'token', 'userInfo']),
...mapState('game', ['taskData']),
// 计算任务列表是否需要显示红点
hasTaskRedDot() {
return this.taskData.user_task > 0 || this.taskData.account_task > 0
}
},
watch: {
'$route.path'(val) {
......@@ -125,6 +141,18 @@ export default {
}
console.log('路由变化:', val, '选中路径:', this.selectedPath)
},
// 监听用户信息变化,只在初始化时获取一次任务数据
userInfo: {
handler(newVal, oldVal) {
if (newVal && newVal.id && (!oldVal || !oldVal.id)) {
console.log('用户信息初始化完成,获取任务数据:', newVal)
// 只在用户信息第一次设置时获取任务数据
this.getTaskUnReadData()
}
},
deep: true,
immediate: true
},
// 监听 external_userid 的变化,确保界面及时更新
external_userid: {
handler(newVal) {
......@@ -181,6 +209,7 @@ export default {
methods: {
...mapMutations('user', ['set_userid', 'set_corp_id', 'set_token', 'set_cser_info', 'set_cser_id', 'set_cser_name', 'set_userInfo']),
...mapMutations('game', ['set_accountSelect']),
...mapActions('game', ['getTaskUnReadData']),
// 设置缓存
cacheCorp_id(corp_id) {
Cookies.set('corp_id', corp_id, { expires: 7 })
......@@ -205,23 +234,6 @@ export default {
handleSelect(key, keyPath) {
console.log('菜单选择:', key, keyPath, window.location.href)
},
initVuexValue(){
this.set_userid(Cookies.get('userid'))
this.set_corp_id(Cookies.get('corp_id'))
this.set_token(Cookies.get('token'))
this.set_cser_id(Cookies.get('cser_id'))
this.set_cser_name(Cookies.get('cser_name'))
const userinfo = {
cser_id:Cookies.get('cser_id'),
cser_name:Cookies.get('cser_name'),
username:Cookies.get('cser_name'),
id:Cookies.get('cser_id'),
}
this.set_userInfo(userinfo)
const cser_info = Cookies.get('cser_info')
console.log(Cookies.get('cser_id'),'cser_info',Cookies.get('cser_name'))
cser_info?this.set_cser_info(JSON.parse(cser_info)):this.set_cser_info({})
},
// 切换菜单展开收起状态
toggleMenu() {
this.isMenuExpanded = !this.isMenuExpanded
......@@ -366,4 +378,23 @@ export default {
body {
background: #f0f2f5;
}
/* 任务列表菜单项红点样式 */
.menu-item-with-badge {
display: inline-block;
}
.task-badge {
::v-deep .el-badge__content.is-dot {
top: 8px !important;
right: -5px !important;
}
}
/* 确保菜单项内容居中 */
.mobile-menu-item .menu-item-with-badge {
display: flex;
align-items: center;
justify-content: center;
}
</style>
......@@ -243,6 +243,14 @@ export function clearTaskUnReadData(data) {
data
})
}
// w账号绑定客户列表
export function memberBindExternalUser(data) {
return request({
url: returnApi('/cser_receipt/memberBindExternalUser'),
method: 'post',
data
})
}
// 删除共享信息
export function shareInfoDel(data) {
return request({
......
<template>
<el-drawer
:lock-scroll="true"
:title="title"
:visible="show"
:size="width"
:append-to-body="true"
@close="close"
>
<div class="layerConent">
<slot></slot>
<span class="dialog-footer rowFlex">
<el-button
class="btn"
type="primary"
size="small"
@click="submit"
>确 定</el-button>
<el-button
class="btn"
size="small"
@click="close"
>取 消</el-button>
</span>
</div>
</el-drawer>
</template>
<script type="text/javascript">
export default {
name: 'Layer',
props: ['show', 'width', 'title'],
data() {
return {
}
},
watch: {
show(newVal, oldVal) {
if (newVal) {
console.log('显示弹窗')
}
}
},
mounted() {
},
methods: {
close() {
this.$emit('update:show', false)
},
submit() {
this.$emit('confirm')
}
}
}
</script>
<style lang="scss" scoped>
// ::v-deep .el-drawer {
// height: 100%;
// overflow: 100%;
// overflow-x: hidden;
// over
// }
.layerConent{
width: 100%;
height: 100%;
overflow: auto;
padding-bottom: 100px;
padding-right: 20px;
}
.dialog-footer {
width: 100%;
height: auto;
position: absolute;
right: 0px;
bottom: 0px;
padding-right: 10px;
padding-top: 20px;
padding-bottom: 20px;
border-top: 1px solid rgba(0, 0, 0, 0.06);
justify-content: flex-end;
background: #fff;
.btn {
width: 84px;
height: 32px;
}
}
</style>
\ No newline at end of file
......@@ -83,6 +83,7 @@ function createScrollHandler(el, binding, vnode) {
// 调用加载函数
options.loadMore();
}
};
}
......
......@@ -11,7 +11,7 @@ import violationRecord from '../views/ViolationRecord.vue'
import taskRecord from '../views/taskRecord.vue'
import mailList from '@/views/mailList.vue'
import quickSendGame from '@/views/quickSendGame.vue'
// import taskList from '@/views/taskList.vue'
import taskList from '@/views/taskList.vue'
import Cookies from 'js-cookie'
import store from '@/store'
Vue.use(VueRouter)
......@@ -78,11 +78,11 @@ const routes = [
name: 'quickSendGame',
component: quickSendGame
},
// {
// path: '/taskList',
// name: 'taskList',
// component: taskList
// },
{
path: '/taskList',
name: 'taskList',
component: taskList
},
{
path: '/login',
name: 'login',
......
......@@ -2,6 +2,7 @@
// 管理公共的store
import { zyouBindMember } from '@/api/works'
import { getTaskTotal } from '@/api/game'
import Cookies from 'js-cookie'
// 从本地缓存获取accountSelect
......@@ -15,6 +16,13 @@ const state = {
chatUserInfo: {}, // 当前选中的用户的详情
viewLoading:false, // 查看用户详情的时候 加载状态
taskDetails: {}, // 任务详情
// 任务数据
taskData: {
user_task: 0,
account_task: 0,
operator_task: 0,
lastUpdateTime: null
},
}
const mutations = {
......@@ -38,6 +46,13 @@ const mutations = {
},
set_taskDetails(state, data) {
state.taskDetails = data
},
// 设置任务数据
set_taskData(state, data) {
state.taskData = {
...data,
lastUpdateTime: Date.now()
}
}
}
......@@ -62,6 +77,46 @@ const actions = {
})
})
},
// 获取任务数据
async getTaskUnReadData({ commit, rootState }) {
return new Promise( async (resolve, reject) => {
try {
// 确保用户信息存在
if (!rootState.user.userInfo || !rootState.user.userInfo.id) {
console.log('用户信息不存在,跳过任务数据获取')
return
}
const data = {
zw_user_id: rootState.user.userInfo.id
}
console.log('开始获取任务数据:', data)
const res = await getTaskTotal(data)
if (res.status_code === 1) {
// 使用真实的 API 响应数据
const responseData = res.data.data || {}
const taskData = {
user_task: responseData.user_num || 0,
account_task: responseData.member_num || 0,
operator_task: Number(responseData.user_num || 0) + Number(responseData.member_num || 0)
}
commit('set_taskData', taskData)
resolve(taskData)
return taskData
} else {
reject(res.msg)
console.error('获取任务数据失败:', res.msg)
}
} catch (error) {
reject(error)
console.error('获取任务数据异常:', error)
throw error
}
})
}
}
export default {
......
......@@ -76,7 +76,7 @@ const mutations = {
},
set_client_online_status(state, status) {
state.client_online_status = status
},
}
}
const actions = {
......
......@@ -3,10 +3,11 @@
<!-- <div class="detailsTitle rowFlex spaceBetween columnCenter">
<p>任务记录</p>
</div> -->
<div class="account-task-container-content" v-scroll="requestOrderList" v-loading="loading">
<div class="account-task-container-content" v-scroll="requestOrderList">
<!-- 运营任务 和 用户任务 -->
<div
class="orderDetailsScroll"
v-loading="loading"
>
<div v-if="orderList.length > 0">
<div
......@@ -35,34 +36,32 @@
</div>
</div>
</template>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">跟进客服</span>
<p class="text">{{ item.tracer_name }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex">
<span class="label">待维护日期</span>
<p class="text">{{ item.assignment_time }}</p>
</div>
</div>
<div class="editLayer">
<el-form
:model="webForm"
label-width="100px"
>
<el-form-item
label="跟进客服:"
>
<p class="text" style="margin-left: 10px;">{{ item.tracer_name || '--' }}</p>
</el-form-item>
<el-form-item
label="待维护日期:"
>
<p class="text" style="margin-left: 10px;">{{ item.assignment_time }}</p>
</el-form-item>
<!-- 新增异常原因筛选 当 plan_type==5 5:为大R异跟进异常时 新增异常原因筛选 -->
<el-form-item
v-if="taskInfo.plan_type && taskInfo.plan_type==5"
label="异常原因"
prop="abnormal_types"
label-width="100px"
>
<el-select
v-model="webForm.abnormal_types"
style="width: 90%"
placeholder="请选择"
multiple
style="margin-left: 10px;"
collapse-tags
>
<el-option
......@@ -77,12 +76,11 @@
<el-form-item
label="跟进结果:"
prop="trace_result"
label-width="100px"
>
<el-select
v-model="webForm.trace_result"
style="width: 90%"
placeholder="请选择"
style="margin-left: 10px;"
>
<el-option
v-for="item in traceList"
......@@ -95,15 +93,17 @@
<el-form-item
v-if="activeType == 'user_task'"
label="免打扰:"
label-width="80px"
prop="no_trouble"
style="margin-left: 10px;"
>
<div class="noDisturb">
<el-checkbox
v-model="webForm.no_trouble"
class="noDisturb rowFlex allCenter"
class="noDisturb rowFlex "
:true-label="1"
:false-label="0"
>免打扰(勾选后该用户不会再被分配任务)</el-checkbox>
</div>
</el-form-item>
</el-form>
</div>
......@@ -114,17 +114,17 @@
class="item rowFlex columnCenter spaceBetween"
>
<div
class="rowFlex spaceBetween"
class="rowFlex spaceBetween remarkItem"
style="width: 100%;"
>
<span
class="label"
style="width: 50px"
style="margin-left: 40px;color: #999999;"
>备注:</span>
<div class="text rowFlex remark flex1">
<div class="remarkTxext rowFlex remark flex1">
<textEditor
:remark.sync="remark.remark"
:domid="'taskRemark' + indexs"
style="width: 100%;"
:contenteditable="!Boolean(remark.id)"
@resultReamrk="resultReamrk"
/>
......@@ -167,6 +167,7 @@
</div>
<div
v-else-if="!loading && orderList.length == 0"
style="margin-top: 100px;"
class="noContent rowFlex allCenter"
>
<noContent />
......@@ -183,7 +184,7 @@
export default {
components: {
textEditor,
noContent
noContent,
},
data() {
return {
......@@ -259,13 +260,13 @@
total: 0
}
this.orderList = []
this.requestOrderList()
this.requestOrderList('msg')
}
}
},
mounted() {
// this.gameMemberView()
this.requestOrderList()
this.requestOrderList('msg')
this.searchcondition()
this.searchTrackList()
this.searchconditionError()
......@@ -405,7 +406,7 @@
no_trouble: 0
}
},
requestOrderList() {
requestOrderList(msg = '') {
if (this.accountSelect == '') {
this.$message.warning('暂无关联的账号,请先去关联账号!')
return false
......@@ -431,7 +432,7 @@
this.orderList.map((item) => {
!item.remarks || item.remarks.length === 0 ? (item.remarks = [{ remark: '' }]) : ''
})
if (res.status_code == 1) {
if (res.status_code == 1 && !msg) {
this.$message.success(res.msg)
}
},
......@@ -450,6 +451,9 @@
background: #fff;
position: relative;
overflow: hidden;
::v-deep .el-form-item__content{
line-height: 32px;
}
.detailsTitle {
width: 100%;
padding: 0 10px;
......@@ -481,7 +485,7 @@
color: #999999;
}
}
.item {
.taskItem {
width: 100%;
height: auto;
font-size: 14px;
......@@ -489,7 +493,6 @@
color: #333333;
transition: all 0.5s;
position: relative;
cursor: pointer;
div {
width: 100%;
margin-bottom: 5px;
......@@ -620,15 +623,13 @@
.money {
width: 100%;
height: auto;
padding-left: 10px;
.btns {
padding-right: 40px;
margin-right: 20px;
}
.btn {
background: #fff;
border-radius: 4px;
padding: 2px 5px;
margin-left: 10px;
font-size: 12px;
border: 1px solid rgba(0, 0, 0, 0.15);
color: #333333;
......@@ -711,7 +712,14 @@
font-size: 16px;
font-weight: 500;
}
.remarkTxext{
width: calc(100% - 120px);
margin-left: 10px;
}
.remarkItem{
margin-left: 40px;
position: relative;
}
::v-deep .el-collapse {
border: none;
}
......@@ -720,6 +728,7 @@
color: #333333;
font-size: 14px;
font-weight: 400;
padding: 0 5px;
/* 单行显示省略号 */
overflow: hidden;
text-overflow: ellipsis;
......@@ -733,17 +742,22 @@
padding: 10px;
}
.editLayer {
margin-left: -20px;
.noDisturb{
// 换行
white-space: wrap;
padding: 10px 0;
.noDisturb {
display: flex;
align-items: center;
margin-top: 4px;
}
::v-deep .el-form-item__label{
::v-deep .el-form-item__label {
font-weight: normal;
color: #999999;
padding-right: 8px;
}
::v-deep .el-form-item--small.el-form-item{
margin-bottom: 10px;
::v-deep .el-form-item {
margin-bottom: 14px;
}
::v-deep .el-select, ::v-deep .el-checkbox {
width: 100%;
}
}
}
......
......@@ -459,30 +459,18 @@ export default {
margin-left: 2px;
position: relative;
overflow: hidden;
.detailsTitle {
width: 100%;
padding: 0 10px;
height: 60px;
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
border-bottom: 1px solid #ebeef5;
border-left: 1px solid #ebeef5;
p {
color: #333333;
}
}
.account-task-container-content {
width: 100%;
height: calc(100% - 60px);
padding: 20px 10px;
padding-top: 0px;
height: 100%;
padding: 20px 10px 0;
.tabSelect {
width: 100%;
height: 60px;
border-bottom: 1px solid #ebeef5;
cursor: pointer;
.tabSelectItem {
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
......@@ -492,167 +480,37 @@ export default {
line-height: 47px;
cursor: pointer;
}
.tabSelectItemActive {
color: #409EFF;
border-bottom: 2px solid #409EFF;
}
}
.contentItem {
position: relative;
.title {
position: absolute;
left: 10px;
top: 14px;
font-size: 14px;
color: #999999;
}
}
.item {
width: 100%;
height: auto;
font-size: 14px;
font-weight: 400;
color: #333333;
transition: all 0.5s;
position: relative;
cursor: pointer;
div {
width: 100%;
margin-bottom: 5px;
}
.remark {
::v-deep .el-textarea__inner {
height: 80px;
}
}
.tableImage {
width: 40px;
height: 40px;
border-radius: 6px;
margin-right: 10px;
}
.label {
color: #999999;
}
.text {
color: #333333;
margin-left: 10px;
word-break: break-all;
max-width: 75%;
}
.icon {
display: none;
position: absolute;
right: 0;
top: 12px;
}
.dianFail {
display: inline-block;
width: 8px;
height: 8px;
background: #f45454;
border-radius: 5px;
}
.dian {
display: inline-block;
width: 8px;
height: 8px;
background: #409EFF;
border-radius: 5px;
}
.dian2 {
display: inline-block;
width: 8px;
height: 8px;
background: #ff9d02;
border-radius: 5px;
}
}
.orderMoney {
width: calc(100% + 40px);
height: 80px;
// margin-left: -20px;
padding: 10px 0;
.orderMoneyItem {
width: 50%;
text-align: center;
margin-top: 5px;
span {
font-size: 14px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
}
p {
font-size: 22px;
color: #409EFF;
}
}
}
.filterList {
margin-bottom: 10px;
.filterListInput {
width: 60%;
margin-left: 15px;
margin-bottom: 10px;
}
.filterListDate {
width: 150px;
margin-bottom: 10px;
}
::v-deep .search-item .item-label {
margin-right: 20px;
}
}
.orderDetailsScroll {
width: 100%;
height: calc(100% - 20px);
height: calc(100% - 80px);
overflow: auto;
overflow-x: hidden;
}
.orderDetails {
width: 100%;
height: auto;
margin-top: 20px;
position: relative;
.bridgeMain {
position: absolute;
top: 0px;
right: 0px;
width: 50px;
height: 50px;
.text {
font-size: 8px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #ff9d02;
transform: rotate(48deg);
z-index: 100;
position: absolute;
right: -6px;
top: 10px;
width: 50px;
text-align: center;
}
.bridge {
font-size: 50px;
position: absolute;
top: 0;
right: 0;
}
}
.orderDetailsTitle {
width: 100%;
background: #f9faff;
.money {
width: 100%;
height: auto;
padding-left: 10px;
.btns {
padding-right: 40px;
}
.btn {
background: #fff;
border-radius: 4px;
......@@ -663,20 +521,7 @@ export default {
color: #333333;
cursor: pointer;
}
.btnnot {
background: #ffdddd;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #f56c6c;
border: none;
}
.btnsuccess {
background: #e1fff0;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #409EFF;
border: none;
}
.sended {
padding: 0 8px;
height: 20px;
......@@ -688,6 +533,7 @@ export default {
font-weight: 400;
color: #409EFF;
}
.noSend {
padding: 0 8px;
height: 20px;
......@@ -700,6 +546,7 @@ export default {
color: #ffa81d;
}
}
.text {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
......@@ -707,53 +554,105 @@ export default {
color: #333333;
max-width: 200px;
overflow: hidden;
white-space: nowrap; /* 防止文字换行 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
white-space: nowrap;
text-overflow: ellipsis;
}
}
.orderDetailsList {
width: 100%;
height: auto;
background: #ffffff;
border: 1px solid #ebeef5;
position: relative;
.titleFix {
position: absolute;
left: 10px;
top: 20px;
}
}
.item {
width: 100%;
font-size: 14px;
font-weight: 400;
color: #333333;
position: relative;
.remark {
::v-deep .el-textarea__inner {
height: 80px;
}
}
.label {
color: #999999;
}
.text {
color: #333333;
margin-left: 10px;
word-break: break-all;
max-width: 75%;
}
}
}
.remarkHandle {
font-size: 20px;
color: #0ac358;
cursor: pointer;
margin-right: 5px;
position:absolute;
position: absolute;
right: 0;
top: 0;
}
::v-deep .el-tabs__item {
line-height: 26px;
font-size: 16px;
font-weight: 500;
}
.editLayer {
margin-left: -20px;
.noDisturb{
// 换行
white-space: wrap;
padding: 10px 0;
.noDisturb {
display: flex;
align-items: center;
flex-wrap: wrap;
}
::v-deep .el-form-item__label{
::v-deep .el-form-item__label {
font-weight: normal;
color: #999999;
padding-right: 8px;
}
::v-deep .el-form-item--small.el-form-item{
margin-bottom: 10px;
::v-deep .el-form-item {
margin-bottom: 14px;
}
::v-deep .el-select {
width: 100%;
max-width: 90%;
}
}
}
::v-deep .el-checkbox {
width: 100%;
}
}
::v-deep .el-collapse {
border: none;
}
::v-deep .el-collapse-item__header {
width: 100%;
color: #333333;
font-size: 14px;
font-weight: 400;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
::v-deep .el-collapse-item__arrow {
position: absolute;
right: 5px;
}
::v-deep .el-collapse-item__content {
padding: 10px;
}
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论