提交 0e8febea 作者: 施汉文

feat: 7.4工作台功能同步,生命线、智能待办

上级 77693b65
......@@ -16,7 +16,7 @@
<title>企微侧边栏</title>
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,shrink-to-fit=no,user-scalable=no"> -->
<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
<script src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/icons_27278_172.5464f393968eda872f41eab2242bbbd7.es5.js"></script>
<script src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/svg_27278_173.e64d61edfe0d4824e2eeb0b7f478e568.js"></script>
</head>
<body>
<noscript>
......
......@@ -57,7 +57,7 @@
<!-- 绑定的 w 账号 -->
<bindUserList />
</div>
<div class="mobile-content">
<div class="mobile-content" v-if="accountSelect">
<router-view></router-view>
</div>
</div>
......@@ -126,6 +126,11 @@ export default {
hasRedDot: false, // 红点状态
},
{
label: "用户待办",
path: "/userToDo",
hasRedDot: false, // 红点状态
},
{
label: "微言助手",
path: "/aiChat",
},
......@@ -142,7 +147,7 @@ export default {
},
computed: {
...mapState("user", ["external_userid", "token", "userInfo"]),
...mapState("game", ["taskData"]),
...mapState("game", ["taskData", "accountSelect"]),
// 计算任务列表是否需要显示红点
hasTaskRedDot() {
return this.taskData.user_task > 0 || this.taskData.account_task > 0;
......@@ -204,7 +209,7 @@ export default {
// 页面刷新时从 Cookie 恢复 token 到 store
// Cookies.set(
// "token",
// "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOjQwOTAsImRhdGEiOnsiY3Nlcl9pZCI6NDA5MCwiY3Nlcl9uYW1lIjoi5q-b57uG5LqaIn0sImlhdCI6MTc2NTE3MjI0NywiZXhwIjoxNzY3NzY0MjQ3LCJuYmYiOjE3NjUxNzIyNDcsInN1YiI6InRva2Vu6K6k6K-BIiwianRpIjoiN2Q5NjYxNDVjNjgyZWU0Y2UyY2Y2MTc2ZjA0NTNlNGMifQ.QpEtYzoXK11RHwn8la-OMoS-BnlTyEEAa0lmlpYu2IQ"
// "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOjQwOTAsImRhdGEiOnsiY3Nlcl9pZCI6NDA5MCwiY3Nlcl9uYW1lIjoi5q-b57uG5LqaIn0sImlhdCI6MTc2ODU0Mjk0MiwiZXhwIjoxNzcxMTM0OTQyLCJuYmYiOjE3Njg1NDI5NDIsInN1YiI6InRva2Vu6K6k6K-BIiwianRpIjoiMjU0Zjg3OGQ3NzMyNWUyMzMyNDAwZTEwZWJkMjFkY2YifQ.3hHc6iQP-Xkz9Q5rMIOFENDdh5P-NSaRs4Y4ffbJcMg"
// );
// Cookies.set("corp_id", "wweaefe716636df3d1");
// Cookies.set("userid", "maoxiya");
......
......@@ -68,3 +68,19 @@ export function answerComment(data) {
data
})
}
// 会话生命线列表
export function sessionSummaryList(data) {
return request({
url: '/sidebar/client_session/sessionSummaryList',
method: 'post',
data
})
}
// 重新生成会话总结
export function regenerateSummary(data) {
return request({
url: '/sidebar/client_session/regenerateSummary',
method: 'post',
data
})
}
......@@ -316,3 +316,19 @@ export function corp_follow_up_task_index(data) {
data
})
}
// 【智能待办】工作台-我的
export function corpIntelligentTaskMineList(data) {
return request({
url: returnApi('/corp_intelligent_task/mineList'),
method: 'post',
data
})
}
// 【智能待办】工作台-完成、未完成
export function corpIntelligentTaskExternalList(data) {
return request({
url: returnApi('/corp_intelligent_task/externalList'),
method: 'post',
data
})
}
\ No newline at end of file
<template>
<div class="loading rowFlex allCenter">
<svg-icon icon-class="loading" class="loadingIcon" />
<p class="text">加载中</p>
</div>
</template>
<script>
export default {
name: 'loading',
data() {
return {
}
},
mounted() {},
methods: {}
<div class="loading rowFlex allCenter">
<!-- <svg-icon icon-class="loading" class="loadingIcon" /> -->
<i class="el-icon-loading loadingIcon text-primary"></i>
<p class="text">加载中</p>
</div>
</template>
<script>
export default {
name: "loading",
data() {
return {};
},
mounted() {},
methods: {},
};
</script>
<style lang="scss" scoped>
.loading {
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 0;
.loadingIcon {
font-size: 24px;
animation: rotage linear 1s infinite;
}
</script>
<style lang="scss" scoped>
.loading{
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 0;
.loadingIcon{
font-size: 24px;
animation: rotage linear 1s infinite;
}
.text{
color: #409EFF;
font-size: 14px;
margin-left: 5px;
}
.text {
color: #409eff;
font-size: 14px;
margin-left: 5px;
}
@keyframes rotage {
0%{
transform: rotate(0deg);
}
100%{
transform: rotate(360deg);
}
}
@keyframes rotage {
0% {
transform: rotate(0deg);
}
</style>
\ No newline at end of file
100% {
transform: rotate(360deg);
}
}
</style>
<template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
<svg v-else :class="svgClass" aria-hidden="true" :style="{ display: iconClass || svgName ? '' : 'none' }"
v-on="$listeners">
<use :xlink:href="iconName" />
</svg>
<div
v-if="isExternal"
:style="styleExternalIcon"
class="svg-external-icon svg-icon"
v-on="$listeners"
/>
<svg
v-else
:class="svgClass"
class="iconpark-icon"
aria-hidden="true"
:style="{ display: iconClass || svgName ? '' : 'none' }"
v-on="$listeners"
>
<use :xlink:href="iconName" />
</svg>
</template>
<script lang="jsx">
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
import { isExternal } from '@/utils/validate'
import { isExternal } from "@/utils/validate";
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
default: ''
},
svgName: {
type: String,
default: ''
},
className: {
type: String,
default: ''
}
name: "SvgIcon",
props: {
iconClass: {
type: String,
default: "",
},
computed: {
isExternal() {
return isExternal(this.iconClass)
},
iconName() {
if (this.svgName) {
return `#${this.svgName}`
}
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
}
}
}
}
svgName: {
type: String,
default: "",
},
className: {
type: String,
default: "",
},
},
computed: {
isExternal() {
return isExternal(this.iconClass);
},
iconName() {
if (this.svgName) {
return `#${this.svgName}`;
}
return `#icon-${this.iconClass}`;
},
svgClass() {
if (this.className) {
return "svg-icon " + this.className;
} else {
return "svg-icon";
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
"-webkit-mask": `url(${this.iconClass}) no-repeat 50% 50%`,
};
},
},
};
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
/* vertical-align: -0.15em; */
fill: currentColor;
overflow: hidden;
width: 1em;
height: 1em;
/* vertical-align: -0.15em; */
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover !important;
display: inline-block;
background-color: currentColor;
mask-size: cover !important;
display: inline-block;
}
</style>
import Vue from 'vue'
{/* <iconpark-icon name="icon-fuzhi"></iconpark-icon> */}
// {/* <iconpark-icon name="icon-fuzhi"></iconpark-icon> */}
const copy = {
// 当被绑定的元素插入到DOM中时
inserted: function(el, binding) {
// 创建复制图标元素
const copyIcon = document.createElement('iconpark-icon')
copyIcon.name='icon-fuzhi'
const copyIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
copyIcon.innerHTML = '<use href="#icon-fuzhi"></use>'
copyIcon.setAttribute('class', 'iconpark-icon')
copyIcon.style.cursor = 'pointer'
copyIcon.style.marginLeft = '8px'
copyIcon.style.fontSize = '16px'
copyIcon.style.height = '16px'
copyIcon.style.width = '16px'
copyIcon.title = '点击复制'
// 设置元素的position为relative,确保图标的absolute定位正确
......@@ -17,7 +19,7 @@ const copy = {
}
// 添加复制图标到元素后面
el.insertBefore(copyIcon, el.nextSibling)
el.appendChild(copyIcon)
// 复制功能实现
const clickHandler = async function(e) {
......@@ -100,4 +102,4 @@ const copy = {
}
}
export default copy
export default copy
\ No newline at end of file
......@@ -15,6 +15,7 @@ import taskList from '@/views/taskList.vue'
import aiChat from '@/views/components/aiChat/aiChat.vue'
import Cookies from 'js-cookie'
import store from '@/store'
import UserAgency from '@/views/userAgency/index.vue'
Vue.use(VueRouter)
import { getParams } from '@/utils/index'
const routes = [
......@@ -85,6 +86,11 @@ const routes = [
component: taskList
},
{
path: '/userToDo',
name: 'userToDo',
component: UserAgency
},
{
path: '/aiChat',
name: 'aiChat',
component: aiChat
......
......@@ -25,24 +25,40 @@
</div>
</template>
<script>
import AreaTransferApply from './components/ApplyRecords/AreaTransferApply.vue'
import errorHandle from './components/ApplyRecords/errorHandle.vue'
import TerminalTransfer from './components/ApplyRecords/TerminaTranfer.vue'
import report from './components/roleInfo/report.vue'
import AreaTransferApply from "./components/ApplyRecords/AreaTransferApply.vue";
import errorHandle from "./components/ApplyRecords/errorHandle.vue";
import TerminalTransfer from "./components/ApplyRecords/TerminaTranfer.vue";
import report from "./components/roleInfo/report.vue";
export default {
name: 'applyRecord',
name: "applyRecord",
components: {
AreaTransferApply,
errorHandle,
TerminalTransfer,
report
report,
},
data() {
return {
activeTab: 'report'
activeTab: "report",
};
},
created() {
const related_task_info = JSON.parse(
sessionStorage.getItem("related_task_info")
);
if (related_task_info) {
const type = {
6: "report",
12: "errorHandle",
14: "serve",
13: "terminal",
};
this.activeTab = type[related_task_info.related_task_type] || "report";
} else {
this.activeTab = "report";
}
}
}
},
};
</script>
<style lang="scss" scoped>
......@@ -75,4 +91,4 @@ export default {
line-height: 50px;
}
}
</style>
\ No newline at end of file
</style>
......@@ -2,99 +2,231 @@
<div class="terminaListArea" v-scroll="paperScroll">
<div class="addApply rowFlex spaceBetween">
<span></span>
<el-button type="primary" size="small" icon="el-icon-plus"
@click="showaddAreaTransfer = true, areaTransferItem = {}">新增转区申请</el-button>
<el-button
type="primary"
size="small"
icon="el-icon-plus"
@click="(showaddAreaTransfer = true), (areaTransferItem = {})"
>新增转区申请</el-button
>
</div>
<el-form ref="taskForm" :model="terminaForm" class="taskForm" label-position="top" label-width="85px">
<el-form
ref="taskForm"
:model="terminaForm"
class="taskForm"
label-position="top"
label-width="85px"
>
<el-form-item label="审批状态">
<el-select v-model="terminaForm.approval_status" style="width:95%;" clearable placeholder="请选择审批状态"
@change="filterChange">
<el-option v-for="item in approvalList" :key="item.value" :label="item.label" :value="item.value">
<el-select
v-model="terminaForm.approval_status"
style="width: 95%"
clearable
placeholder="请选择审批状态"
@change="filterChange"
>
<el-option
v-for="item in approvalList"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<selectDate :default-value="dateValue" :type="true" :no-clearable="true" style="width: 95%"
@result="createResult" />
<selectDate
:default-value="dateValue"
:type="true"
:no-clearable="true"
style="width: 95%"
@result="createResult"
/>
</el-form-item>
</el-form>
<div class="terminaListAreaList">
<!-- 举报申请 -->
<div class="scrollMain" v-if="terminaList.length > 0">
<div v-for="(item, index) in terminaList" :key="item.id || index" class="terminaContent"
@click="terminaProcess(item, index)">
<div class="terminaItem rowFlex spaceBetween columnCenter">
<i :class="item.showStep ? 'el-icon-arrow-down' : 'el-icon-arrow-right'" class="svgicon"></i>
<div
v-for="(item, index) in terminaList"
:key="item.id || index"
class="terminaContent"
@click="terminaProcess(item, index)"
>
<div class="terminaItem rowFlex spaceBetween columnCenter">
<i
:class="
item.showStep ? 'el-icon-arrow-down' : 'el-icon-arrow-right'
"
class="svgicon"
></i>
<div class="terminaItemLeft">
<p><span class="label">新区角色:</span><span class="value">{{ item.role_name }}({{ item.server_name }})</span>
<p>
<span class="label">新区角色:</span
><span class="value"
>{{ item.role_name }}({{ item.server_name }})</span
>
</p>
<p>
<span class="label">老区角色:</span
><span class="value"
>{{ item.old_role_name }} ({{ item.old_server_name }})
</span>
</p>
<p><span class="label">老区角色:</span><span class="value">{{ item.old_role_name }} ({{ item.old_server_name
}}) </span></p>
<p>
<span class="label">登记时间:</span><span class="value">{{ item.create_time || '' }}</span>
<span class="label">登记时间:</span
><span class="value">{{ item.create_time || "" }}</span>
</p>
</div>
<div class="terminaItemRight columnFlex columnCenter">
<el-button v-if="item.approval_status == 4 && item.related_request_id == 0" type="primary" size="mini"
style="margin-bottom:15px;" @click.stop="resubmitApproval(item)">重新提交</el-button>
<el-button
v-if="item.approval_status == 4 && item.related_request_id == 0"
type="primary"
size="mini"
style="margin-bottom: 15px"
@click.stop="resubmitApproval(item)"
>重新提交</el-button
>
<!-- 改成 svg-icon 图标 -->
<svg-icon v-if="item.approval_status == 1" icon-class="shenpi1" class="icon" />
<svg-icon v-else-if="item.approval_status == 2" icon-class="shenpi2" class="icon" />
<svg-icon v-else-if="item.approval_status == 3" icon-class="shenpi3" class="icon" />
<svg-icon v-else-if="item.approval_status == 4" icon-class="shenpi4" class="icon" />
<svg-icon v-else-if="item.approval_status == 5" icon-class="shenpi5" class="icon" />
<svg-icon
v-if="item.approval_status == 1"
icon-class="shenpi1"
class="icon"
/>
<svg-icon
v-else-if="item.approval_status == 2"
icon-class="shenpi2"
class="icon"
/>
<svg-icon
v-else-if="item.approval_status == 3"
icon-class="shenpi3"
class="icon"
/>
<svg-icon
v-else-if="item.approval_status == 4"
icon-class="shenpi4"
class="icon"
/>
<svg-icon
v-else-if="item.approval_status == 5"
icon-class="shenpi5"
class="icon"
/>
</div>
</div>
<!-- 审批进度 -->
<el-collapse-transition>
<div v-if="item.showStep" class="terminaProcessList">
<el-steps direction="vertical" :active="item.current" finish-status="success">
<el-step v-for="(items, indexs) in item.terminaProcessList" :key="'trans_item_' + indexs"
:title="items.node_name">
<el-steps
direction="vertical"
:active="item.current"
finish-status="success"
>
<el-step
v-for="(items, indexs) in item.terminaProcessList"
:key="'trans_item_' + indexs"
:title="items.node_name"
>
<template slot="description">
<div v-if="items" class="trans-follow-1 card-style">
<div class="follow-item">
<span class="follow-info-label label-font">
{{ items.node_sort !== '0' ? '审批人:' : '登记人:' }}
{{ items.node_sort !== "0" ? "审批人:" : "登记人:" }}
</span>
<span class="info-value value-font">
{{ Array.isArray(items.user_name) ? items.user_name[0] : items.user_name }}
{{
Array.isArray(items.user_name)
? items.user_name[0]
: items.user_name
}}
</span>
<el-tooltip v-if="Array.isArray(items.user_name) && items.user_name.length > 1" class="item"
effect="dark" :content="items.user_name.slice(1).join('、')" placement="top">
<el-tooltip
v-if="
Array.isArray(items.user_name) &&
items.user_name.length > 1
"
class="item"
effect="dark"
:content="items.user_name.slice(1).join('、')"
placement="top"
>
<span class="info-value value-font info-value-color">
{{ `+${items.user_name.length - 1}` }}
</span>
</el-tooltip>
</div>
<div v-if="items.node_sort !== '0' || items.node_name === '系统'" class="follow-item">
<div
v-if="
items.node_sort !== '0' || items.node_name === '系统'
"
class="follow-item"
>
<span class="follow-info-label label-font">
审批结果:
</span>
<span class="info-value value-font"
:class="items.current < indexs ? '' : switchStateTag(items.approval_result)">
{{ items.current < indexs ? '' : items.approval_result_text }} </span>
<span
class="info-value value-font"
:class="
items.current < indexs
? ''
: switchStateTag(items.approval_result)
"
>
{{
items.current < indexs
? ""
: items.approval_result_text
}}
</span>
</div>
<div class="follow-item">
<span class="follow-info-label label-font">
{{ items.node_sort !== '0' || items.node_name === '系统' ? '审批时间:' : '登记时间:' }}
{{
items.node_sort !== "0" ||
items.node_name === "系统"
? "审批时间:"
: "登记时间:"
}}
</span>
<span class="info-value value-font">
{{ items.node_sort === '0' ? items.create_time : items.update_time }}
{{
items.node_sort === "0"
? items.create_time
: items.update_time
}}
</span>
</div>
<div v-if="(items.node_sort !== '0' || items.node_name === '系统') && items.approval_result === '2'"
class="follow-item">
<div
v-if="
(items.node_sort !== '0' ||
items.node_name === '系统') &&
items.approval_result === '2'
"
class="follow-item"
>
<span class="follow-info-label label-font">
驳回原因:
</span>
<span class="info-value value-font" v-html="items.extra_attribution.approval_remark || ''">
<span
class="info-value value-font"
v-html="items.extra_attribution.approval_remark || ''"
>
</span>
</div>
<div
v-if="items.node_sort === item.terminaProcessList[item.terminaProcessList.length - 1].node_sort + '' && items.approval_result === '1' && items.node_sort !== '0'"
class="follow-item-remark follow-item">
v-if="
items.node_sort ===
item.terminaProcessList[
item.terminaProcessList.length - 1
].node_sort +
'' &&
items.approval_result === '1' &&
items.node_sort !== '0'
"
class="follow-item-remark follow-item"
>
<span class="follow-info-label label-font">
处理结果:
</span>
......@@ -102,18 +234,37 @@
{{ items.extra_attribution.banned_text }}
</span>
</div>
<div v-if="items.node_name !== '系统' && items.extra_attribution && items.extra_attribution.remark"
class="info-item-remark">
<div style="display: flex;">
<div
v-if="
items.node_name !== '系统' &&
items.extra_attribution &&
items.extra_attribution.remark
"
class="info-item-remark"
>
<div style="display: flex">
<span class="info-label remark-label">详情:</span>
<span class="preview-btn" @click.stop="previewRemark(items.extra_attribution.remark)">
<span
class="preview-btn"
@click.stop="
previewRemark(items.extra_attribution.remark)
"
>
<i class="el-icon-view"></i>
点击查看大图
</span>
</div>
<div class="remark-value"
v-html="formatImg(items.extra_attribution && items.extra_attribution.remark ? items.extra_attribution.remark : '')">
</div>
<div
class="remark-value"
v-html="
formatImg(
items.extra_attribution &&
items.extra_attribution.remark
? items.extra_attribution.remark
: ''
)
"
></div>
</div>
</div>
</template>
......@@ -125,66 +276,79 @@
</div>
<noContent v-else />
</div>
<el-dialog :visible.sync="dialogRemarkVisible" append-to-body title="查看大图" custom-class="remake-dialog">
<el-dialog
:visible.sync="dialogRemarkVisible"
append-to-body
title="查看大图"
custom-class="remake-dialog"
>
<div class="remake-box">
<div v-html="dialogRemake"></div>
</div>
</el-dialog>
<!-- 编辑误操作 -->
<AreaTransferDialog v-if="showaddAreaTransfer" :visible.sync="showaddAreaTransfer"
:area-transfer-item="areaTransferItem" @updateList="updateList" />
<AreaTransferDialog
v-if="showaddAreaTransfer"
:visible.sync="showaddAreaTransfer"
:area-transfer-item="areaTransferItem"
@updateList="updateList"
/>
</div>
</template>
<script>
import { searchcondition, transfer_server_request_list, transfer_server_request_process } from '@/api/game'
import { mapState } from 'vuex'
import { removeDp, formatNumber, debounce } from '@/utils/index'
import AreaTransferDialog from './AreaTransferDialog.vue'
import selectDate from '@/components/selectDate.vue'
import {
searchcondition,
transfer_server_request_list,
transfer_server_request_process,
} from "@/api/game";
import { mapState } from "vuex";
import { removeDp, formatNumber, debounce } from "@/utils/index";
import AreaTransferDialog from "./AreaTransferDialog.vue";
import selectDate from "@/components/selectDate.vue";
// 导入审批状态图标
import shenpi1 from '@/assets/icon/svg/shenpi1.svg'
import shenpi2 from '@/assets/icon/svg/shenpi2.svg'
import shenpi3 from '@/assets/icon/svg/shenpi3.svg'
import shenpi4 from '@/assets/icon/svg/shenpi4.svg'
import shenpi5 from '@/assets/icon/svg/shenpi5.svg'
import noContent from '@/components/noContent.vue'
import shenpi1 from "@/assets/icon/svg/shenpi1.svg";
import shenpi2 from "@/assets/icon/svg/shenpi2.svg";
import shenpi3 from "@/assets/icon/svg/shenpi3.svg";
import shenpi4 from "@/assets/icon/svg/shenpi4.svg";
import shenpi5 from "@/assets/icon/svg/shenpi5.svg";
import noContent from "@/components/noContent.vue";
export default {
name: 'AreaTransferApply',
name: "AreaTransferApply",
computed: {
...mapState('game', ['accountSelect']),
...mapState('user', ['userInfo'])
...mapState("game", ["accountSelect"]),
...mapState("user", ["userInfo"]),
},
components: {
AreaTransferDialog,
selectDate,
noContent
noContent,
},
data() {
return {
pickerOptions: {
disabledDate(time) {
const curDate = (new Date()).getTime()
const three = 90 * 24 * 3600 * 1000
const threeMonths = curDate - three
return time.getTime() > Date.now() || time.getTime() < threeMonths
}
const curDate = new Date().getTime();
const three = 90 * 24 * 3600 * 1000;
const threeMonths = curDate - three;
return time.getTime() > Date.now() || time.getTime() < threeMonths;
},
},
terminaForm: {
member_id: '',
create_time_start: '',
create_time_end: '',
approval_status: ''
member_id: "",
create_time_start: "",
create_time_end: "",
approval_status: "",
},
dateValue: [],
pageInfo: {
page: 1,
page_size: 20
page_size: 20,
},
terminaList: [],
isMoreRecord: false,
approvalList: [],
dialogRemarkVisible: false,
dialogRemake: '',
dialogRemake: "",
showaddAreaTransfer: false,
formatNumber: formatNumber,
// 审批状态图标
......@@ -192,173 +356,200 @@ export default {
shenpi2,
shenpi3,
shenpi4,
shenpi5
}
shenpi5,
};
},
watch: {
accountSelect(newVal, oldVal) {
console.log(newVal, 'newVal')
if (newVal && newVal !== '') {
console.log(newVal, "newVal");
if (newVal && newVal !== "") {
this.pageInfo = {
page: 0,
page_size: 20,
total: 0
}
this.isMoreRecord = true
this.filterChange()
total: 0,
};
this.isMoreRecord = true;
this.filterChange();
}
}
},
},
mounted() {
this.dateValue = [
this.$moment().subtract(6, 'days').format('YYYY-MM-DD HH:mm:ss'),
this.$moment().format('YYYY-MM-DD HH:mm:ss')
]
this.terminaForm.create_time_start = this.dateValue[0]
this.terminaForm.create_time_end = this.dateValue[1]
this.requstApprovalList()
this.filterChange()
this.$moment().subtract(6, "days").format("YYYY-MM-DD HH:mm:ss"),
this.$moment().format("YYYY-MM-DD HH:mm:ss"),
];
this.terminaForm.create_time_start = this.dateValue[0];
this.terminaForm.create_time_end = this.dateValue[1];
this.requstApprovalList();
this.filterChange();
},
methods: {
updateList() {
this.filterChange()
this.filterChange();
},
createResult: debounce(function (data) {
if (data && Array.isArray(data) && data.length === 2) {
this.terminaForm.create_time_start = data[0]
this.terminaForm.create_time_end = data[1]
this.dateValue = data
this.terminaForm.create_time_start = data[0];
this.terminaForm.create_time_end = data[1];
this.dateValue = data;
} else {
this.terminaForm.create_time_start = ''
this.terminaForm.create_time_end = ''
this.dateValue = []
this.terminaForm.create_time_start = "";
this.terminaForm.create_time_end = "";
this.dateValue = [];
}
this.filterChange()
this.filterChange();
}, 300),
filterChange() {
this.pageInfo.page = 1
this.terminaList = []
this.isMoreRecord = true
this.terminaIndex()
this.pageInfo.page = 1;
this.terminaList = [];
this.isMoreRecord = true;
this.terminaIndex();
},
resubmitApproval(item) {
this.showaddAreaTransfer = true
this.areaTransferItem = item
this.showaddAreaTransfer = true;
this.areaTransferItem = item;
},
async requstApprovalList() {
const data = {
type: 'dictionaries',
table_name: 'zs_refund_request',
field_name: 'approval_status'
}
const res = await searchcondition(data)
type: "dictionaries",
table_name: "zs_refund_request",
field_name: "approval_status",
};
const res = await searchcondition(data);
if (res.status_code === 1) {
this.approvalList = res.data.data
this.approvalList = res.data.data;
}
},
previewRemark(remark) {
this.dialogRemake = remark
this.dialogRemarkVisible = true
this.dialogRemake = remark;
this.dialogRemarkVisible = true;
},
async terminaProcess(item, index) {
item.showStep = !item.showStep
item.showStep = !item.showStep;
if (item.terminaProcessList.length === 0) {
try {
const res = await transfer_server_request_process({ id: item.id })
item.terminaProcessList = res.data.data
const res = await transfer_server_request_process({ id: item.id });
item.terminaProcessList = res.data.data;
res.data.data.map((items) => {
if (items.approval_result !== '0' && items.approval_result !== '2') {
item.current += 1
if (
items.approval_result !== "0" &&
items.approval_result !== "2"
) {
item.current += 1;
}
})
});
} catch (error) {
this.$message.error('获取审批进度失败')
console.error(error)
this.$message.error("获取审批进度失败");
console.error(error);
}
}
this.$forceUpdate()
this.$forceUpdate();
},
paperScroll() {
if (!this.isMoreRecord) {
console.log('没有更多数据了')
return false
console.log("没有更多数据了");
return false;
}
this.requestNextPage()
this.requestNextPage();
},
requestNextPage(pageInfo) {
this.pageInfo.page++
this.terminaIndex()
this.pageInfo.page++;
this.terminaIndex();
},
handleCurrentChange(val) {
this.pageInfo.page = val
this.pageInfo.page = val;
},
switchStateTag(status) {
switch (status) {
case '0':
return 'unhandle'
case '1':
return 'handled'
case '2':
return 'sendFail'
case "0":
return "unhandle";
case "1":
return "handled";
case "2":
return "sendFail";
default:
return ''
return "";
}
},
formatImg(html) {
if (html) {
return html.replaceAll(/<img/g, '<img style="max-width:100px;"')
return html.replaceAll(/<img/g, '<img style="max-width:100px;"');
}
return html
return html;
},
switchStateText(status) {
switch (status) {
case '0':
return '待审批'
case '1':
return '通过'
case '2':
return '驳回'
case "0":
return "待审批";
case "1":
return "通过";
case "2":
return "驳回";
}
},
async terminaIndex() {
if (this.accountSelect === '') {
this.$message.warning('暂无关联的账号,请先去关联账号!')
return false
if (this.accountSelect === "") {
this.$message.warning("暂无关联的账号,请先去关联账号!");
return false;
}
if (this.pageInfo.page === 1) {
this.terminaList = []
this.terminaList = [];
}
const { create_time_start, create_time_end, approval_status } = this.terminaForm
const data = {
approval_status,
create_time_start,
create_time_end,
member_id: this.accountSelect,
...this.pageInfo
const { create_time_start, create_time_end, approval_status } =
this.terminaForm;
// const data = {
// approval_status,
// create_time_start,
// create_time_end,
// member_id: this.accountSelect,
// ...this.pageInfo
// }
const related_task_info = JSON.parse(
sessionStorage.getItem("related_task_info")
);
let data;
if (related_task_info && related_task_info.related_task_type === 14) {
data = { ...this.pageInfo, id: related_task_info.related_task_id };
this.terminaForm.create_time_start = "";
this.terminaForm.create_time_end = "";
this.dateValue = [];
//展示一次后清除携带过来的id
this.$nextTick(() => {
sessionStorage.removeItem("related_task_info");
});
} else {
data = {
approval_status,
create_time_start,
create_time_end,
member_id: this.accountSelect,
...this.pageInfo,
};
}
const res = await transfer_server_request_list(data)
const res = await transfer_server_request_list(data);
if (this.pageInfo.page === 1) {
this.terminaList = res.data.data
this.terminaList = res.data.data;
} else {
this.terminaList = this.terminaList.concat(res.data.data)
this.terminaList = this.terminaList.concat(res.data.data);
}
if (this.terminaList.length > 0) {
this.terminaList.map((item) => {
item.showStep = false
item.current = 0
item.terminaProcessList = []
})
item.showStep = false;
item.current = 0;
item.terminaProcessList = [];
});
} else {
this.terminaList = []
this.terminaList = [];
}
if (res.data.data.length < 20) {
this.isMoreRecord = false
this.isMoreRecord = false;
} else {
this.isMoreRecord = true
this.isMoreRecord = true;
}
}
}
}
},
},
};
</script>
<style lang="scss" scoped>
......@@ -408,7 +599,7 @@ export default {
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #409EFF;
color: #409eff;
border: none;
}
......@@ -543,30 +734,30 @@ export default {
width: 1px;
}
::v-deep .el-step>.is-success {
color: #409EFF;
border-color: #409EFF;
::v-deep .el-step > .is-success {
color: #409eff;
border-color: #409eff;
.el-step__line {
background-color: #e5e6eb;
}
}
::v-deep .el-step__main>.is-success {
color: #409EFF;
::v-deep .el-step__main > .is-success {
color: #409eff;
}
::v-deep .el-step>.is-process {
color: #409EFF;
border-color: #409EFF;
::v-deep .el-step > .is-process {
color: #409eff;
border-color: #409eff;
.el-step__line {
background-color: #e5e6eb;
}
}
::v-deep .el-step__main>.is-process {
color: #409EFF;
::v-deep .el-step__main > .is-process {
color: #409eff;
}
.form-item-btn {
......@@ -587,7 +778,7 @@ export default {
.preview-btn {
cursor: pointer;
font-size: 14px;
color: #409EFF;
color: #409eff;
margin: 0 0 0 10px;
i {
......@@ -691,7 +882,7 @@ export default {
height: 80px;
}
&:hover>.preview-pic {
&:hover > .preview-pic {
z-index: 100;
}
}
......@@ -743,7 +934,7 @@ export default {
}
.info-value-color {
color: #409EFF;
color: #409eff;
margin-left: 5px;
}
}
......@@ -799,4 +990,4 @@ export default {
margin-bottom: 20px;
margin-top: 20px;
}
</style>
\ No newline at end of file
</style>
......@@ -2,82 +2,177 @@
<div class="terminaListContent" v-scroll="paperScroll">
<div class="addApply rowFlex spaceBetween">
<span></span>
<el-button type="primary" icon="el-icon-plus" size="small"
@click="(showaddAreaTransfer = true, areaTransferItem = {})">新增转端申请</el-button>
<el-button
type="primary"
icon="el-icon-plus"
size="small"
@click="(showaddAreaTransfer = true), (areaTransferItem = {})"
>新增转端申请</el-button
>
</div>
<el-form ref="taskForm" :model="terminaForm" label-position="top" class="terminaListForm" label-width="85px">
<el-form
ref="taskForm"
:model="terminaForm"
label-position="top"
class="terminaListForm"
label-width="85px"
>
<el-form-item label="审批状态">
<el-select v-model="terminaForm.approval_status" style="width:95%;" clearable placeholder="请选择审批状态"
@change="filterChange">
<el-option v-for="item in approvalList" :key="item.value" :label="item.label" :value="item.value">
<el-select
v-model="terminaForm.approval_status"
style="width: 95%"
clearable
placeholder="请选择审批状态"
@change="filterChange"
>
<el-option
v-for="item in approvalList"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<selectDate :default-value="dateValue" :type="true" style="width: 95%" @result="createResult" />
<selectDate
:default-value="dateValue"
:type="true"
style="width: 95%"
@result="createResult"
/>
</el-form-item>
</el-form>
<div class="terminaListContentList">
<!-- 举报申请 -->
<div v-if="terminaList.length > 0" class="scrollMain">
<div v-for="(item, index) in terminaList" :key="index" class="terminaContent"
@click="terminaProcess(item, index)">
<div class="terminaItem rowFlex spaceBetween columnCenter">
<div
v-for="(item, index) in terminaList"
:key="index"
class="terminaContent"
@click="terminaProcess(item, index)"
>
<div class="terminaItem spaceBetween columnCenter">
<div class="terminaItemLeft">
<p><span class="label">角色名称:</span><span class="value">{{ item.role_name }}</span></p>
<p>
<span class="label">累计充值:</span><span class="value">{{ formatNumber(item.recharge_total_amount) }}
</span>
<span class="label">角色名称:</span
><span class="value">{{ item.role_name }}</span>
</p>
<p>
<span class="label">登记时间:</span><span class="value">{{ item.create_time || '' }}</span>
<span class="label">累计充值:</span
><span class="value"
>{{ formatNumber(item.recharge_total_amount) }}</span
>
</p>
<p><span class="label">转端状态:</span><span class="value">{{ item.trans_check_status_text || '-' }}</span>
<p>
<span class="label">登记时间:</span
><span class="value">{{ item.create_time || "" }}</span>
</p>
<p>
<span class="label">转端状态:</span
><span class="value">{{
item.trans_check_status_text || "-"
}}</span>
</p>
</div>
<!-- 审批进度 -->
<el-collapse-transition>
<div v-if="item.showStep" class="terminaProcessList">
<el-steps direction="vertical" :active="item.current" finish-status="success">
<el-step v-for="(items, indexs) in item.terminaProcessList" :key="'trans_item_' + indexs"
:title="items.node_name">
<el-steps
direction="vertical"
:active="item.current"
finish-status="success"
>
<el-step
v-for="(items, indexs) in item.terminaProcessList"
:key="'trans_item_' + indexs"
:title="items.node_name"
>
<template slot="description">
<div v-if="items" class="trans-follow-1 card-style">
<div class="follow-item">
<span class="follow-info-label label-font">
{{ items.node_sort !== '0' ? '审批人:' : '登记人:' }}
{{
items.node_sort !== "0" ? "审批人:" : "登记人:"
}}
</span>
<span class="info-value value-font">
{{ Array.isArray(items.user_name) ? items.user_name[0] : items.user_name }}
{{
Array.isArray(items.user_name)
? items.user_name[0]
: items.user_name
}}
</span>
<el-tooltip v-if="Array.isArray(items.user_name) && items.user_name.length > 1" class="item"
effect="dark" :content="items.user_name.slice(1).join('、')" placement="top">
<span class="info-value value-font info-value-color">
<el-tooltip
v-if="
Array.isArray(items.user_name) &&
items.user_name.length > 1
"
class="item"
effect="dark"
:content="items.user_name.slice(1).join('、')"
placement="top"
>
<span
class="info-value value-font info-value-color"
>
{{ `+${items.user_name.length - 1}` }}
</span>
</el-tooltip>
</div>
<div v-if="items.node_sort !== '0' || items.node_name === '系统'" class="follow-item">
<div
v-if="
items.node_sort !== '0' ||
items.node_name === '系统'
"
class="follow-item"
>
<span class="follow-info-label label-font">
审批结果:
</span>
<span class="info-value value-font"
:class="items.current < indexs ? '' : switchStateTag(items.approval_result)">
{{ items.current < indexs ? '' : items.approval_result_text == '通过' ? '完成' :
items.approval_result_text }} </span>
<span
class="info-value value-font"
:class="
items.current < indexs
? ''
: switchStateTag(items.approval_result)
"
>
{{
items.current < indexs
? ""
: items.approval_result_text == "通过"
? "完成"
: items.approval_result_text
}}
</span>
</div>
<div class="follow-item">
<span class="follow-info-label label-font">
{{ items.node_sort !== '0' || items.node_name === '系统' ? '审批时间:' : '登记时间:' }}
{{
items.node_sort !== "0" ||
items.node_name === "系统"
? "审批时间:"
: "登记时间:"
}}
</span>
<span class="info-value value-font">
{{ items.node_sort === '0' ? items.create_time : items.update_time }}
{{
items.node_sort === "0"
? items.create_time
: items.update_time
}}
</span>
</div>
<div
v-if="(items.node_sort !== '0' || items.node_name === '系统') && items.approval_result === '2'"
class="follow-item">
v-if="
(items.node_sort !== '0' ||
items.node_name === '系统') &&
items.approval_result === '2'
"
class="follow-item"
>
<span class="follow-info-label label-font">
驳回原因:
</span>
......@@ -87,8 +182,17 @@
</div>
<div
v-if="items.node_sort === item.terminaProcessList[item.terminaProcessList.length - 1].node_sort + '' && items.approval_result === '1' && items.node_sort !== '0'"
class="follow-item-remark follow-item">
v-if="
items.node_sort ===
item.terminaProcessList[
item.terminaProcessList.length - 1
].node_sort +
'' &&
items.approval_result === '1' &&
items.node_sort !== '0'
"
class="follow-item-remark follow-item"
>
<span class="follow-info-label label-font">
处理结果:
</span>
......@@ -97,18 +201,36 @@
</span>
</div>
<div
v-if="items.node_name !== '系统' && items.extra_attribution && items.extra_attribution.remark"
class="info-item-remark">
<div style="display: flex;">
v-if="
items.node_name !== '系统' &&
items.extra_attribution &&
items.extra_attribution.remark
"
class="info-item-remark"
>
<div style="display: flex">
<span class="info-label remark-label">详情:</span>
<span class="preview-btn" @click.stop="previewRemark(items.extra_attribution.remark)">
<span
class="preview-btn"
@click.stop="
previewRemark(items.extra_attribution.remark)
"
>
<i class="el-icon-view"></i>
点击查看大图
</span>
</div>
<div class="remark-value"
v-html="formatImg(items.extra_attribution && items.extra_attribution.remark ? items.extra_attribution.remark : '')">
</div>
<div
class="remark-value"
v-html="
formatImg(
items.extra_attribution &&
items.extra_attribution.remark
? items.extra_attribution.remark
: ''
)
"
></div>
</div>
</div>
</template>
......@@ -123,66 +245,79 @@
<noContent />
</div>
</div>
<el-dialog :visible.sync="dialogRemarkVisible" append-to-body title="查看大图" custom-class="remake-dialog">
<el-dialog
:visible.sync="dialogRemarkVisible"
append-to-body
title="查看大图"
custom-class="remake-dialog"
>
<div class="remake-box">
<div v-html="dialogRemake"></div>
</div>
</el-dialog>
<!-- 编辑误操作 -->
<TerminalTransferDialog v-if="showaddAreaTransfer" :visible.sync="showaddAreaTransfer"
:area-transfer-item="areaTransferItem" @updateList="updateList" />
<TerminalTransferDialog
v-if="showaddAreaTransfer"
:visible.sync="showaddAreaTransfer"
:area-transfer-item="areaTransferItem"
@updateList="updateList"
/>
</div>
</template>
<script>
import { searchcondition, member_trans_request_list, member_trans_request_process } from '@/api/game'
import { mapState } from 'vuex'
import { removeDp, formatNumber, debounce } from '@/utils/index'
import TerminalTransferDialog from './TerminalTransferDialog.vue'
import selectDate from '@/components/selectDate.vue'
import {
searchcondition,
member_trans_request_list,
member_trans_request_process,
} from "@/api/game";
import { mapState } from "vuex";
import { removeDp, formatNumber, debounce } from "@/utils/index";
import TerminalTransferDialog from "./TerminalTransferDialog.vue";
import selectDate from "@/components/selectDate.vue";
// 导入审批状态图标
import shenpi1 from '@/assets/icon/svg/shenpi1.svg'
import shenpi2 from '@/assets/icon/svg/shenpi2.svg'
import shenpi4 from '@/assets/icon/svg/shenpi4.svg'
import shenpi5 from '@/assets/icon/svg/shenpi5.svg'
import shenpi6 from '@/assets/icon/svg/shenpi6.svg'
import noContent from '@/components/noContent.vue'
import shenpi1 from "@/assets/icon/svg/shenpi1.svg";
import shenpi2 from "@/assets/icon/svg/shenpi2.svg";
import shenpi4 from "@/assets/icon/svg/shenpi4.svg";
import shenpi5 from "@/assets/icon/svg/shenpi5.svg";
import shenpi6 from "@/assets/icon/svg/shenpi6.svg";
import noContent from "@/components/noContent.vue";
export default {
name: 'terminaTranfer',
name: "terminaTranfer",
computed: {
...mapState('game', ['accountSelect']),
...mapState('user', ['userInfo'])
...mapState("game", ["accountSelect"]),
...mapState("user", ["userInfo"]),
},
components: {
TerminalTransferDialog,
noContent,
selectDate
selectDate,
},
data() {
return {
pickerOptions: {
disabledDate(time) {
const curDate = (new Date()).getTime()
const three = 90 * 24 * 3600 * 1000
const threeMonths = curDate - three
return time.getTime() >= Date.now() || time.getTime() <= threeMonths
}
const curDate = new Date().getTime();
const three = 90 * 24 * 3600 * 1000;
const threeMonths = curDate - three;
return time.getTime() >= Date.now() || time.getTime() <= threeMonths;
},
},
terminaForm: {
member_id: '',
create_time_start: '',
create_time_end: '',
approval_status: ''
member_id: "",
create_time_start: "",
create_time_end: "",
approval_status: "",
},
dateValue: [],
pageInfo: {
page: 1,
page_size: 20
page_size: 20,
},
terminaList: [],
isMoreRecord: false,
approvalList: [],
dialogRemarkVisible: false,
dialogRemake: '',
dialogRemake: "",
showaddAreaTransfer: false,
formatNumber: formatNumber,
// 审批状态图标
......@@ -190,171 +325,198 @@ export default {
shenpi2,
shenpi4,
shenpi5,
shenpi6
}
shenpi6,
};
},
watch: {
accountSelect(newVal, oldVal) {
console.log(newVal, 'newVal')
if (newVal && newVal !== '') {
console.log(newVal, "newVal");
if (newVal && newVal !== "") {
this.pageInfo = {
page: 0,
page_size: 20,
total: 0
}
this.isMoreRecord = true
this.filterChange()
total: 0,
};
this.isMoreRecord = true;
this.filterChange();
}
}
},
},
mounted() {
this.dateValue = [
this.$moment().subtract(6, 'days').format('YYYY-MM-DD HH:mm:ss'),
this.$moment().format('YYYY-MM-DD HH:mm:ss')
]
this.terminaForm.create_time_start = this.dateValue[0]
this.terminaForm.create_time_end = this.dateValue[1]
this.requstApprovalList()
this.filterChange()
this.$moment().subtract(6, "days").format("YYYY-MM-DD HH:mm:ss"),
this.$moment().format("YYYY-MM-DD HH:mm:ss"),
];
this.terminaForm.create_time_start = this.dateValue[0];
this.terminaForm.create_time_end = this.dateValue[1];
this.requstApprovalList();
this.filterChange();
},
methods: {
updateList() {
this.filterChange()
this.filterChange();
},
resubmitApproval(item) {
this.showaddAreaTransfer = true
this.areaTransferItem = item
this.showaddAreaTransfer = true;
this.areaTransferItem = item;
},
createResult: debounce(function (data) {
if (data && Array.isArray(data) && data.length === 2) {
this.terminaForm.create_time_start = data[0]
this.terminaForm.create_time_end = data[1]
this.dateValue = data
this.terminaForm.create_time_start = data[0];
this.terminaForm.create_time_end = data[1];
this.dateValue = data;
} else {
this.terminaForm.create_time_start = ''
this.terminaForm.create_time_end = ''
this.dateValue = []
this.terminaForm.create_time_start = "";
this.terminaForm.create_time_end = "";
this.dateValue = [];
}
this.filterChange()
this.filterChange();
}, 300),
filterChange() {
this.pageInfo.page = 1
this.terminaList = []
this.isMoreRecord = true
this.terminaIndex()
this.pageInfo.page = 1;
this.terminaList = [];
this.isMoreRecord = true;
this.terminaIndex();
},
async requstApprovalList() {
const data = {
type: 'dictionaries',
table_name: 'zs_refund_request',
field_name: 'approval_status'
}
const res = await searchcondition(data)
type: "dictionaries",
table_name: "zs_refund_request",
field_name: "approval_status",
};
const res = await searchcondition(data);
if (res.status_code === 1) {
this.approvalList = res.data.data
this.approvalList = res.data.data;
}
},
previewRemark(remark) {
this.dialogRemake = remark
this.dialogRemarkVisible = true
this.dialogRemake = remark;
this.dialogRemarkVisible = true;
},
async terminaProcess(item, index) {
item.showStep = !item.showStep
item.showStep = !item.showStep;
if (item.terminaProcessList.length === 0) {
try {
const res = await member_trans_request_process({ id: item.id })
item.terminaProcessList = res.data.data
const res = await member_trans_request_process({ id: item.id });
item.terminaProcessList = res.data.data;
res.data.data.map((items) => {
if (items.approval_result !== '0' && items.approval_result !== '2') {
item.current += 1
if (
items.approval_result !== "0" &&
items.approval_result !== "2"
) {
item.current += 1;
}
})
});
} catch (error) {
this.$message.error('获取审批进度失败')
console.error('获取审批进度失败:', error)
this.$message.error("获取审批进度失败");
console.error("获取审批进度失败:", error);
}
}
this.$forceUpdate()
this.$forceUpdate();
},
paperScroll() {
if (!this.isMoreRecord) {
console.log('没有更多数据了')
return false
console.log("没有更多数据了");
return false;
}
this.requestNextPage()
this.requestNextPage();
},
requestNextPage(pageInfo) {
this.pageInfo.page++
this.terminaIndex()
this.pageInfo.page++;
this.terminaIndex();
},
handleCurrentChange(val) {
this.pageInfo.page = val
this.pageInfo.page = val;
},
switchStateTag(status) {
switch (status) {
case '0':
return 'unhandle'
case '1':
return 'handled'
case '2':
return 'sendFail'
case "0":
return "unhandle";
case "1":
return "handled";
case "2":
return "sendFail";
}
},
formatImg(html) {
if (html) {
return html.replaceAll(/<img/g, '<img style="max-width:100px;"')
return html.replaceAll(/<img/g, '<img style="max-width:100px;"');
}
return html
return html;
},
switchStateText(status) {
switch (status) {
case '0':
return '待审批'
case '1':
return '通过'
case '2':
return '驳回'
case "0":
return "待审批";
case "1":
return "通过";
case "2":
return "驳回";
}
},
async terminaIndex() {
if (this.accountSelect === '') {
this.$message.warning('暂无关联的账号,请先去关联账号!')
return false
if (this.accountSelect === "") {
this.$message.warning("暂无关联的账号,请先去关联账号!");
return false;
}
if (this.pageInfo.page === 1) {
this.terminaList = []
this.terminaList = [];
}
const { create_time_start, create_time_end, approval_status } = this.terminaForm
const data = {
approval_status,
create_time_start,
create_time_end,
member_id: this.accountSelect,
...this.pageInfo
const { create_time_start, create_time_end, approval_status } =
this.terminaForm;
// const data = {
// approval_status,
// create_time_start,
// create_time_end,
// member_id: this.accountSelect,
// ...this.pageInfo
// }
const related_task_info = JSON.parse(
sessionStorage.getItem("related_task_info")
);
let data = {};
if (related_task_info && related_task_info.related_task_type === 13) {
data = { ...this.pageInfo, id: related_task_info.related_task_id };
this.terminaForm.create_time_start = "";
this.terminaForm.create_time_end = "";
this.dateValue = [];
//展示一次后清除携带过来的id
this.$nextTick(() => {
sessionStorage.removeItem("related_task_info");
});
} else {
data = {
approval_status,
create_time_start,
create_time_end,
member_id: this.accountSelect,
...this.pageInfo,
};
}
const res = await member_trans_request_list(data)
const res = await member_trans_request_list(data);
if (this.pageInfo.page === 1) {
this.terminaList = res.data.data
this.terminaList = res.data.data;
} else {
this.terminaList = this.terminaList.concat(res.data.data)
this.terminaList = this.terminaList.concat(res.data.data);
}
if (this.terminaList.length > 0) {
this.terminaList.map((item) => {
item.showStep = false
item.current = 0
item.terminaProcessList = []
})
item.showStep = false;
item.current = 0;
item.terminaProcessList = [];
});
} else {
this.terminaList = []
this.terminaList = [];
}
if (res.data.data.length < 20) {
this.isMoreRecord = false
this.isMoreRecord = false;
} else {
this.isMoreRecord = true
this.isMoreRecord = true;
}
}
}
}
},
},
};
</script>
<style lang="scss" scoped>
......@@ -411,7 +573,7 @@ export default {
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #409EFF;
color: #409eff;
border: none;
}
......@@ -537,30 +699,30 @@ export default {
width: 1px;
}
::v-deep .el-step>.is-success {
color: #409EFF;
border-color: #409EFF;
::v-deep .el-step > .is-success {
color: #409eff;
border-color: #409eff;
.el-step__line {
background-color: #e5e6eb;
}
}
::v-deep .el-step__main>.is-success {
color: #409EFF;
::v-deep .el-step__main > .is-success {
color: #409eff;
}
::v-deep .el-step>.is-process {
color: #409EFF;
border-color: #409EFF;
::v-deep .el-step > .is-process {
color: #409eff;
border-color: #409eff;
.el-step__line {
background-color: #e5e6eb;
}
}
::v-deep .el-step__main>.is-process {
color: #409EFF;
::v-deep .el-step__main > .is-process {
color: #409eff;
}
.form-item-btn {
......@@ -581,7 +743,7 @@ export default {
.preview-btn {
cursor: pointer;
font-size: 14px;
color: #409EFF;
color: #409eff;
margin: 0 0 0 10px;
i {
......@@ -685,7 +847,7 @@ export default {
height: 80px;
}
&:hover>.preview-pic {
&:hover > .preview-pic {
z-index: 100;
}
}
......@@ -737,7 +899,7 @@ export default {
}
.info-value-color {
color: #409EFF;
color: #409eff;
margin-left: 5px;
}
}
......@@ -793,4 +955,4 @@ export default {
margin-bottom: 20px;
margin-top: 20px;
}
</style>
\ No newline at end of file
</style>
......@@ -3,23 +3,53 @@
<div class="detailsErrorHandleContent" v-scroll="requestOrderList">
<div class="addApply rowFlex spaceBetween">
<span></span>
<el-button type="primary" size="small" icon="el-icon-plus"
@click="showAddErrorHandle = true, info = null">新增误操作</el-button>
<el-button
type="primary"
size="small"
icon="el-icon-plus"
@click="(showAddErrorHandle = true), (info = null)"
>新增误操作</el-button
>
</div>
<el-form class="filterList" label-position="top" size="small">
<el-form-item label="角色名称" style="margin-bottom:15px;">
<searchSelect :account-change="accountChange" style="width:100%;" placeholder="请输入角色名称"
@result="selectResult" />
<el-form-item label="角色名称" style="margin-bottom: 15px">
<searchSelect
:account-change="accountChange"
style="width: 100%"
placeholder="请输入角色名称"
@result="selectResult"
/>
</el-form-item>
<el-form-item label="状态" style="margin-bottom:15px;">
<el-select v-model="pay_type" clearable placeholder="状态" style="width:100%;" @change="payTypeResult">
<el-option v-for="item in statusList" :key="item.value" :label="item.label" :value="item.value">
<el-form-item label="状态" style="margin-bottom: 15px">
<el-select
v-model="pay_type"
clearable
placeholder="状态"
style="width: 100%"
@change="payTypeResult"
>
<el-option
v-for="item in statusList"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="创建时间" style="margin-bottom:15px;">
<el-date-picker v-model="searchDate" type="daterange" clearable style="width:100%;" value-format="yyyy-MM-dd"
range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期" @change="dateResult"> </el-date-picker>
<el-form-item label="创建时间" style="margin-bottom: 15px">
<el-date-picker
v-model="searchDate"
type="daterange"
clearable
style="width: 100%"
value-format="yyyy-MM-dd"
range-separator="~"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="dateResult"
>
</el-date-picker>
</el-form-item>
</el-form>
<div class="list">
......@@ -27,14 +57,20 @@
<!-- 订单列表 -->
<div class="orderDetailsScroll">
<div v-if="orderList.length > 0" class="orderDetailsScrollContent">
<div v-for="(item, index) in orderList" :key="index" class="orderDetails">
<div
v-for="(item, index) in orderList"
:key="index"
class="orderDetails"
>
<div class="orderDetailsList">
<el-collapse v-model="collapseValue" @change="handleChange">
<el-collapse-item :name="item.order_id">
<template slot="title">
<div class="orderDetailsTitle">
<div class="money rowFlex spaceBetween">
<p class="text hidden">角色名称:{{ item.role_name }}</p>
<p class="text hidden">
角色名称:{{ item.role_name }}
</p>
</div>
</div>
</template>
......@@ -54,25 +90,53 @@
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex">
<span class="label">状态</span>
<p v-if="item.approval_status == 1" class="unhandle" style="margin-left:10px;">{{
item.approval_status_text }}</p>
<p v-else-if="item.approval_status == 2" style="margin-left:10px;" class="noSend">{{
item.approval_status_text }}</p>
<p v-else-if="item.approval_status == 3" style="margin-left:10px;" class="sended">{{
item.approval_status_text }}</p>
<p v-else-if="item.approval_status == 4" style="margin-left:10px;" class="sendFail">{{
item.approval_status_text }}
<p
v-if="item.approval_status == 1"
class="unhandle"
style="margin-left: 10px"
>
{{ item.approval_status_text }}
</p>
<p
v-else-if="item.approval_status == 2"
style="margin-left: 10px"
class="noSend"
>
{{ item.approval_status_text }}
</p>
<p
v-else-if="item.approval_status == 3"
style="margin-left: 10px"
class="sended"
>
{{ item.approval_status_text }}
</p>
<p
v-else-if="item.approval_status == 4"
style="margin-left: 10px"
class="sendFail"
>
{{ item.approval_status_text }}
</p>
<p
v-else-if="item.approval_status == 5"
style="margin-left: 10px"
class="handled"
>
{{ item.approval_status_text }}
</p>
<p v-else-if="item.approval_status == 5" style="margin-left:10px;" class="handled">{{
item.approval_status_text }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex">
<span class="label">补发道具</span>
<div v-if="item.reissue_prop.length" style="width:75%;">
<p v-for="(items, indexs) in item.reissue_prop" :key="indexs" class="text">{{ items.name }}{{
`(${items.num})` }}
<div v-if="item.reissue_prop.length" style="width: 75%">
<p
v-for="(items, indexs) in item.reissue_prop"
:key="indexs"
class="text"
>
{{ items.name }}{{ `(${items.num})` }}
</p>
</div>
</div>
......@@ -80,9 +144,13 @@
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex">
<span class="label">返回道具</span>
<div v-if="item.return_prop.length" style="width:75%;">
<p v-for="(items, indexs) in item.return_prop" :key="indexs" class="text">{{ items.name }}{{
`(${items.num})` }}
<div v-if="item.return_prop.length" style="width: 75%">
<p
v-for="(items, indexs) in item.return_prop"
:key="indexs"
class="text"
>
{{ items.name }}{{ `(${items.num})` }}
</p>
</div>
</div>
......@@ -97,146 +165,150 @@
</div>
</div>
</div>
</div>
<!-- 编辑误操作 -->
<addErrorHandle v-if="showAddErrorHandle" :show.sync="showAddErrorHandle" :info="info" title="玩家误操作" width="320px"
@updateList="updateList" />
<addErrorHandle
v-if="showAddErrorHandle"
:show.sync="showAddErrorHandle"
:info="info"
title="玩家误操作"
width="320px"
@updateList="updateList"
/>
</div>
</template>
<script>
import { mapMutations, mapActions, mapState } from 'vuex'
import searchSelect from '../order/searchUser.vue'
import { memberView, misoperationIndex, searchcondition } from '@/api/game'
import addErrorHandle from './addErrorHandle.vue'
import noContent from '@/components/noContent.vue'
import { mapMutations, mapActions, mapState } from "vuex";
import searchSelect from "../order/searchUser.vue";
import { memberView, misoperationIndex, searchcondition } from "@/api/game";
import addErrorHandle from "./addErrorHandle.vue";
import noContent from "@/components/noContent.vue";
export default {
name: 'errorHandle',
name: "errorHandle",
components: {
searchSelect,
addErrorHandle,
noContent
noContent,
},
data() {
return {
pay_type: 0,
info: {},
searchDate: [],
create_time_start: '',
create_time_end: '',
create_time_start: "",
create_time_end: "",
showAddErrorHandle: false,
isloadMore: true,
collapseValue: ['1'],
collapseValue: ["1"],
orderList: [],
gameUserInfo: {
recharge_total: 0,
today_amount: 0
today_amount: 0,
},
statusList: [],
role_id: '',
role_id: "",
accountChange: false,
pageInfo: {
page: 0,
page_size: 20,
total: 0
}
}
total: 0,
},
};
},
computed: {
...mapState('game', ['accountSelect']),
...mapState('user', ['userInfo'])
...mapState("game", ["accountSelect"]),
...mapState("user", ["userInfo"]),
},
watch: {
accountSelect(newVal, oldVal) {
if (newVal && newVal !== '') {
if (newVal && newVal !== "") {
this.pageInfo = {
page: 0,
page_size: 20,
total: 0
}
this.isloadMore = true
this.orderList = []
this.requestOrderList('msg')
total: 0,
};
this.isloadMore = true;
this.orderList = [];
this.requestOrderList("msg");
// this.gameMemberView()
this.accountChange = true
this.accountChange = true;
setTimeout(() => {
this.accountChange = false
}, 200)
this.accountChange = false;
}, 200);
}
}
},
},
mounted() {
this.requstStatusList()
this.requstStatusList();
// this.gameMemberView()
this.requestOrderList('msg')
this.requestOrderList("msg");
},
methods: {
async requstStatusList() {
const data = {
type: 'dictionaries',
table_name: 'zs_refund_request',
field_name: 'approval_status'
}
const res = await searchcondition(data)
type: "dictionaries",
table_name: "zs_refund_request",
field_name: "approval_status",
};
const res = await searchcondition(data);
if (res.status_code === 1) {
this.statusList = res.data.data
this.statusList.unshift({ label: '全部', value: 0 })
this.statusList = res.data.data;
this.statusList.unshift({ label: "全部", value: 0 });
}
},
dateResult(data) {
if (data) {
this.create_time_start = data[0]
this.create_time_end = data[1]
this.create_time_start = data[0];
this.create_time_end = data[1];
} else {
this.create_time_start = ''
this.create_time_end = ''
this.create_time_start = "";
this.create_time_end = "";
}
this.pageInfo = {
page: 0,
page_size: 20,
total: 0
}
this.isloadMore = true
this.orderList = []
this.requestOrderList()
total: 0,
};
this.isloadMore = true;
this.orderList = [];
this.requestOrderList();
},
updateList() {
this.pageInfo = {
page: 0,
page_size: 20,
total: 0
}
this.isloadMore = true
this.orderList = []
this.requestOrderList()
total: 0,
};
this.isloadMore = true;
this.orderList = [];
this.requestOrderList();
},
editErrorHanle(item) {
this.showAddErrorHandle = true
this.info = item
this.showAddErrorHandle = true;
this.info = item;
},
payTypeResult() {
this.isloadMore = true
this.isloadMore = true;
this.pageInfo = {
page: 0,
page_size: 20,
total: 0
}
this.isloadMore = true
this.orderList = []
this.requestOrderList()
total: 0,
};
this.isloadMore = true;
this.orderList = [];
this.requestOrderList();
},
selectResult(value) {
this.pageInfo = {
page: 0,
page_size: 20,
total: 0
}
this.isloadMore = true
this.orderList = []
this.role_id = value
this.requestOrderList()
total: 0,
};
this.isloadMore = true;
this.orderList = [];
this.role_id = value;
this.requestOrderList();
},
// onConfirm() {
// const data = {
......@@ -264,41 +336,60 @@ export default {
// })
// },
handleChange(val) {
console.log(val)
console.log(val);
},
requestOrderList(msg) {
if (this.accountSelect == '') {
this.$message.warning('暂无关联的账号,请先去关联账号!')
return false
if (this.accountSelect == "") {
this.$message.warning("暂无关联的账号,请先去关联账号!");
return false;
}
if (!this.isloadMore) {
console.log('没有更多数据了')
return false
}
this.pageInfo.page += 1
const data = {
role_id: this.role_id,
member_id: this.accountSelect,
create_time_start: this.create_time_start,
create_time_end: this.create_time_end,
approval_status: this.pay_type,
...this.pageInfo
}
misoperationIndex(data).then(res => {
console.log("没有更多数据了");
return false;
}
this.pageInfo.page += 1;
// const data = {
// role_id: this.role_id,
// member_id: this.accountSelect,
// create_time_start: this.create_time_start,
// create_time_end: this.create_time_end,
// approval_status: this.pay_type,
// ...this.pageInfo
// }
const related_task_info = JSON.parse(
sessionStorage.getItem("related_task_info")
);
const data = related_task_info
? { ...this.pageInfo, id: related_task_info.related_task_id }
: {
role_id: this.role_id,
member_id: this.accountSelect,
create_time_start: this.create_time_start,
create_time_end: this.create_time_end,
approval_status: this.pay_type,
...this.pageInfo,
};
//展示一次后清除携带过来的id
this.$nextTick(() => {
sessionStorage.removeItem("related_task_info");
});
misoperationIndex(data).then((res) => {
if (res.data.data && res.data.data.length < 20) {
this.isloadMore = false
this.isloadMore = false;
}
this.orderList = this.orderList.concat(res.data.data)
this.orderList.map(item => {
!item.remarks || item.remarks.length === 0 ? item.remarks = [{ remark: '' }] : ''
})
this.orderList = this.orderList.concat(res.data.data);
this.orderList.map((item) => {
!item.remarks || item.remarks.length === 0
? (item.remarks = [{ remark: "" }])
: "";
});
if (res.status_code == 1 && !msg) {
// this.$message.success(res.msg)
}
})
}
}
}
});
},
},
};
</script>
<style lang="scss" scoped>
.detailsErrorHandle {
......@@ -334,7 +425,7 @@ export default {
.tabSelect {
width: 100%;
height: 60px;
border-bottom: 1px solid #EBEEF5;
border-bottom: 1px solid #ebeef5;
cursor: pointer;
.tabSelectItem {
......@@ -348,8 +439,8 @@ export default {
}
.tabSelectItemActive {
color: #409EFF;
border-bottom: 2px solid #409EFF;
color: #409eff;
border-bottom: 2px solid #409eff;
}
}
......@@ -421,7 +512,7 @@ export default {
display: inline-block;
width: 8px;
height: 8px;
background: #F45454;
background: #f45454;
border-radius: 5px;
}
......@@ -429,7 +520,7 @@ export default {
display: inline-block;
width: 8px;
height: 8px;
background: #409EFF;
background: #409eff;
border-radius: 5px;
}
......@@ -437,7 +528,7 @@ export default {
display: inline-block;
width: 8px;
height: 8px;
background: #FF9D02;
background: #ff9d02;
border-radius: 5px;
}
}
......@@ -462,7 +553,7 @@ export default {
p {
font-size: 22px;
color: #409EFF;
color: #409eff;
}
}
}
......@@ -511,7 +602,7 @@ export default {
font-size: 8px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FF9D02;
color: #ff9d02;
transform: rotate(48deg);
z-index: 100;
position: absolute;
......@@ -531,7 +622,7 @@ export default {
.orderDetailsTitle {
width: 100%;
background: #F9FAFF;
background: #f9faff;
.money {
width: 100%;
......@@ -554,18 +645,18 @@ export default {
}
.btnnot {
background: #FFDDDD;
background: #ffdddd;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #F56C6C;
color: #f56c6c;
border: none;
}
.btnsuccess {
background: #E1FFF0;
background: #e1fff0;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #409EFF;
color: #409eff;
border: none;
}
......@@ -573,24 +664,24 @@ export default {
padding: 0 8px;
height: 20px;
line-height: 20px;
background: #E1FFF0;
background: #e1fff0;
border-radius: 4px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #409EFF;
color: #409eff;
}
.noSend {
padding: 0 8px;
height: 20px;
line-height: 20px;
background: #FFFAE0;
background: #fffae0;
border-radius: 4px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FFA81D;
color: #ffa81d;
}
}
......@@ -611,8 +702,8 @@ export default {
.orderDetailsList {
width: 100%;
height: auto;
background: #FFFFFF;
border: 1px solid #EBEEF5;
background: #ffffff;
border: 1px solid #ebeef5;
position: relative;
.titleFix {
......@@ -623,7 +714,6 @@ export default {
}
}
}
}
::v-deep .el-tabs__item {
......@@ -639,6 +729,5 @@ export default {
height: 100%;
font-size: 300px;
}
}
</style>
\ No newline at end of file
</style>
......@@ -33,10 +33,10 @@
@click="previewVideo(item)"
>
<div class="flex items-center">
<iconpark-icon
name="xiaoxicaozuo-chakan"
class="mr-[4px] text-[14px]"
></iconpark-icon>
<svg-icon
svgName="xiaoxicaozuo-chakan"
class="mr-[4px] h-[14px] w-[14px] text-[14px]"
></svg-icon>
预览
</div>
</el-button>
......@@ -44,10 +44,10 @@
@click="sendVideo(item)"
class="h-[24px] ml-[8px] cursor-pointer hover:bg-[#E7F1FD] text-[12px] w-[58px] p-0 flex justify-center items-center rounded-full bg-[#F7F8FA] text-[#267EF0]"
>
<iconpark-icon
name="icon-fasonghuashu"
class="text-[14px] mr-[4px]"
></iconpark-icon>
<svg-icon
svgName="icon-fasonghuashu"
class="text-[14px] w-[14px] h-[14px] mr-[4px]"
></svg-icon>
<span> 发送</span>
</div>
</div>
......
<template>
<div
class="p-[16px] h-full overflow-y-auto"
ref="conversationLifeline"
@scroll="handleScroll"
>
<div
class="flex justify-between"
v-for="(v, index) in sessionSummaryList"
:key="v._id"
>
<div class="flex flex-col py-[4px] min-w-[24px] shrink-0 items-center">
<div class="bg-primary h-[12px] w-[12px] rounded-full"></div>
<div class="pt-[10px] flex-1">
<div class="w-[1px] h-full bg-[#D6D9E0]"></div>
</div>
</div>
<div class="text-[#323335] text-[14px] flex-1">
<div class="leading-[20px] text-[12px] text-[#C9CDD4]">
{{ v.allot_time }}{{ v.close_time }}
</div>
<div
class="py-[8px] px-[12px] rounded-[8px] border-[1px] border-solid border-[#E5E6EB]"
>
<div class="flex items-center justify-between">
<span class="font-medium">会话总结</span>
<span class="text-[#86909C] text-[14px]"
>客服:{{ v.zq_user_name }}</span
>
</div>
<div class="px-[12px] py-[8px] rounded-[4px] bg-[#F7F8FA] mt-[4px]">
{{ v.session_summary }}
</div>
<div class="pt-[8px]">
<span class="font-medium">会话分析</span>
</div>
<div class="px-[12px] py-[8px] rounded-[4px] bg-[#F7F8FA] mt-[4px]">
{{ v.session_analysis }}
</div>
<div class="flex flex-wrap gap-[8px] mt-[8px]">
<div
v-for="(tag, tagIndex) in v.session_summary_label_str?.split(',')"
:key="tagIndex"
class="px-[6px] leading-[22px] rounded-[4px] bg-[#F5F5F5] text-[#131920] text-[13px]"
>
{{ tag }}
</div>
</div>
</div>
<div class="flex justify-end">
<el-button
type="text"
icon="el-icon-redo"
:loading="v.loading"
@click="getRegenerateSummary(v)"
>重新生成</el-button
>
</div>
</div>
</div>
<div
v-if="sessionSummaryList.length === 0 && !loading"
class="text-center py-8 text-[#C9CDD4]"
>
暂无会话总结
</div>
<div v-if="loading" class="text-center py-4 text-[#C9CDD4]">加载中...</div>
</div>
</template>
<script>
import { sessionSummaryList, regenerateSummary } from "@/api/aiChat";
import { mapState } from "vuex";
export default {
name: "ConversationLifeline",
data() {
return {
sessionSummaryList: [],
loading: false,
page: 1,
pageSize: 10,
total: 0,
isLastPage: false,
};
},
computed: {
...mapState("game", ["chatUserInfo"]),
...mapState("user", ["corp_id"]),
},
mounted() {
this.getSessionSummaryList();
},
methods: {
/**
* 获取会话总结列表
* @param {boolean} isLoadMore - 是否为加载更多
*/
async getSessionSummaryList(isLoadMore = false) {
// 如果已经是最后一页,则不再加载
if (isLoadMore && this.isLastPage) {
return;
}
try {
this.loading = true;
// 如果是加载更多,则页码+1
const currentPage = isLoadMore ? this.page + 1 : 1;
// 获取企业ID和外部用户ID
const corpId = this.corp_id;
const externalUserId = this.chatUserInfo.external_userid;
const params = {
corp_id: corpId,
external_userid: externalUserId,
page: currentPage,
page_size: this.pageSize,
};
const res = await sessionSummaryList(params);
if (res.status_code === 1) {
const newData = res.data.data.map((item) => ({
...item,
loading: false,
}));
const totalCount = res.data.page_info.total;
// 合并数据
if (isLoadMore) {
this.sessionSummaryList = [...this.sessionSummaryList, ...newData];
this.page = currentPage;
} else {
this.sessionSummaryList = newData;
this.page = 1;
}
this.total = totalCount;
// 判断是否为最后一页
this.isLastPage = this.sessionSummaryList.length >= this.total;
console.log("会话总结列表数据:", res.data);
return this.sessionSummaryList;
} else {
this.$message({
message: res.data.msg,
type: "error",
});
return [];
}
} catch (error) {
console.error("获取会话总结列表失败:", error);
this.$message({
message: "获取会话总结列表失败",
type: "error",
});
return [];
} finally {
this.loading = false;
}
},
/**
* 滚动到底部触发分页
*/
handleScroll() {
const container = this.$refs.conversationLifeline;
if (!container || this.loading || this.isLastPage) return;
// 滚动到底部的判断条件
const scrollTop = container.scrollTop;
const scrollHeight = container.scrollHeight;
const clientHeight = container.clientHeight;
// 当距离底部20px时触发加载更多
if (scrollHeight - scrollTop - clientHeight < 20) {
this.getSessionSummaryList(true);
}
},
// 重新生成会话总结
async getRegenerateSummary(data) {
data.loading = true;
try {
await regenerateSummary({ session_id: data.session_id });
this.$message({
message: "重新生成成功",
type: "success",
});
// 重新加载数据
this.getSessionSummaryList();
} catch (error) {
console.error("重新生成会话总结失败:", error);
} finally {
data.loading = false;
}
},
},
};
</script>
<template>
<div class="quickSendGame columnFlex">
<div class="content search-form">
<el-tabs v-model="activeName">
<el-tab-pane label="AI微言" name="aiChat">
<aiArgenChat v-if="activeName === 'aiChat'" />
</el-tab-pane>
<el-tab-pane label="AI 跟进记录" name="aiFollow">
<summaryList v-if="activeName === 'aiFollow'" />
</el-tab-pane>
<el-tab-pane label="跟进任务记录" name="aiFollowTask">
<followTask v-if="activeName === 'aiFollowTask'" />
</el-tab-pane>
</el-tabs>
</div>
<div class="quickSendGame columnFlex">
<div class="content search-form">
<el-tabs v-model="activeName">
<el-tab-pane label="AI微言" name="aiChat">
<aiArgenChat v-if="activeName === 'aiChat'" />
</el-tab-pane>
<el-tab-pane label="AI 跟进记录" name="aiFollow">
<summaryList v-if="activeName === 'aiFollow'" />
</el-tab-pane>
<el-tab-pane label="跟进任务记录" name="aiFollowTask">
<followTask v-if="activeName === 'aiFollowTask'" />
</el-tab-pane>
<el-tab-pane label="会话生命线" name="ConversationLifeline">
<ConversationLifeline v-if="activeName === 'ConversationLifeline'" />
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script>
import aiArgenChat from './aiArgenChat.vue'
import summaryList from './summaryList.vue'
import followTask from './followTask.vue'
import { mapActions } from 'vuex'
import aiArgenChat from "./aiArgenChat.vue";
import summaryList from "./summaryList.vue";
import followTask from "./followTask.vue";
import ConversationLifeline from "./ConversationLifeline.vue";
import { mapActions } from "vuex";
export default {
name: 'quickSendGame',
components: {
aiArgenChat,
summaryList,
followTask,
name: "quickSendGame",
components: {
aiArgenChat,
summaryList,
followTask,
ConversationLifeline,
},
data() {
return {
activeName: "aiChat",
};
},
created() {},
mounted() {
// this.initializeWecom()
},
methods: {
...mapActions("user", ["initWecom"]),
async initializeWecom() {
try {
console.log("🚀 开始初始化企业微信 SDK");
const result = await this.initWecom();
console.log("✅ 企业微信 SDK 初始化成功", result);
} catch (error) {
console.error("❌ 企业微信 SDK 初始化失败:", error);
}
},
data() {
return {
activeName: 'aiChat'
}
},
created() {
},
mounted() {
// this.initializeWecom()
},
methods: {
...mapActions('user', ['initWecom']),
async initializeWecom() {
try {
console.log('🚀 开始初始化企业微信 SDK')
const result = await this.initWecom()
console.log('✅ 企业微信 SDK 初始化成功', result)
} catch (error) {
console.error('❌ 企业微信 SDK 初始化失败:', error)
}
},
}
}
},
};
</script>
<style lang="scss" scoped>
.quickSendGame {
::v-deep .el-tabs__nav-next,
::v-deep .el-tabs__nav-prev {
line-height: 50px;
}
::v-deep .el-tabs__nav-next,
::v-deep .el-tabs__nav-prev {
line-height: 50px;
}
width: 100%;
height: 100%;
background: #fff;
::v-deep .el-tabs__item {
padding: 0 15px;
}
.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;
}
}
.content {
width: 100%;
height: calc(100% - 10px);
width: 100%;
height: 100%;
background: #fff;
::v-deep .el-tabs__header {
margin: 0 0 20px;
}
}
::v-deep .el-tabs__item {
padding: 0 15px;
}
::v-deep .el-tabs--border-card .is-active {
border: none !important;
}
::v-deep .is-active {
border: none;
.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;
}
}
.inputContent {
width: 100%;
.content {
width: 100%;
height: calc(100% - 10px);
::v-deep .el-input {
width: 80%;
}
::v-deep .el-tabs__header {
margin: 0 0 20px;
}
}
::v-deep .el-tabs,
.el-tabs__content,
.el-tab-pane {
width: 100%;
height: 100%;
}
::v-deep .el-tabs--border-card .is-active {
border: none !important;
}
::v-deep .el-tabs__content {
width: 100%;
height: calc(100% - 50px);
}
::v-deep .is-active {
border: none;
}
::v-deep .el-tab-pane {
width: 100%;
height: 100%;
}
.inputContent {
width: 100%;
.scrollList {
width: 100%;
height: calc(100% - 40px);
overflow: auto;
::v-deep .el-input {
width: 80%;
}
}
.draggable {
position: relative;
transition: all 0.3s;
::v-deep .el-tabs,
.el-tabs__content,
.el-tab-pane {
width: 100%;
height: 100%;
}
.icon {
position: absolute;
left: 10px;
top: 15px;
z-index: 10;
}
}
::v-deep .el-tabs__content {
width: 100%;
height: calc(100% - 50px);
}
::v-deep .el-icon-circle-close {
color: #fff;
}
::v-deep .el-tab-pane {
width: 100%;
height: 100%;
}
.bate {
width: 42px;
height: 20px;
background: linear-gradient(135deg, #6ee7e9 0%, #9ff2cd 47%, #e3fdb2 100%);
border-radius: 10px;
padding: 0px 10px 3px 10px;
.scrollList {
width: 100%;
height: calc(100% - 40px);
overflow: auto;
}
.draggable {
position: relative;
transition: all 0.3s;
.icon {
position: absolute;
left: 10px;
top: 15px;
z-index: 10;
}
}
::v-deep .el-icon-circle-close {
color: #fff;
}
.bate {
width: 42px;
height: 20px;
background: linear-gradient(135deg, #6ee7e9 0%, #9ff2cd 47%, #e3fdb2 100%);
border-radius: 10px;
padding: 0px 10px 3px 10px;
}
}
</style>
\ No newline at end of file
</style>
......@@ -163,7 +163,7 @@
<div v-if="items" class="trans-follow-1 card-style">
<div class="follow-item">
<span class="follow-info-label label-font">
{{ items.node_sort !== '0' ? '审批人:' : '登记人:' }}
{{ items.node_sort !== "0" ? "审批人:" : "登记人:" }}
</span>
<span class="info-value value-font">
{{
......@@ -207,7 +207,7 @@
>
{{
items.current < indexs
? ''
? ""
: items.approval_result_text
}}
</span>
......@@ -215,15 +215,15 @@
<div class="follow-item">
<span class="follow-info-label label-font">
{{
items.node_sort !== '0' ||
items.node_name === '系统'
? '审批时间:'
: '登记时间:'
items.node_sort !== "0" ||
items.node_name === "系统"
? "审批时间:"
: "登记时间:"
}}
</span>
<span class="info-value value-font">
{{
items.node_sort === '0'
items.node_sort === "0"
? items.create_time
: items.update_time
}}
......@@ -338,27 +338,27 @@ import {
reportIndex,
reportCancel,
reportProcess,
} from '@/api/game';
import { mapState, mapMutations } from 'vuex';
import { removeDp, formatNumber, debounce } from '@/utils/index';
import resubmitReport from './layer/report.vue';
import approvalTask from './layer/approvalTask.vue';
} from "@/api/game";
import { mapState, mapMutations } from "vuex";
import { removeDp, formatNumber, debounce } from "@/utils/index";
import resubmitReport from "./layer/report.vue";
import approvalTask from "./layer/approvalTask.vue";
// 导入审批状态图标
import shenpi1 from '@/assets/icon/svg/shenpi1.svg';
import shenpi2 from '@/assets/icon/svg/shenpi2.svg';
import shenpi3 from '@/assets/icon/svg/shenpi3.svg';
import shenpi4 from '@/assets/icon/svg/shenpi4.svg';
import shenpi5 from '@/assets/icon/svg/shenpi5.svg';
import noContent from '@/components/noContent.vue';
import shenpi1 from "@/assets/icon/svg/shenpi1.svg";
import shenpi2 from "@/assets/icon/svg/shenpi2.svg";
import shenpi3 from "@/assets/icon/svg/shenpi3.svg";
import shenpi4 from "@/assets/icon/svg/shenpi4.svg";
import shenpi5 from "@/assets/icon/svg/shenpi5.svg";
import noContent from "@/components/noContent.vue";
export default {
name: 'report',
name: "report",
computed: {
...mapState('game', ['accountSelect']),
...mapState('user', ['cser_id', 'cser_name']),
...mapState("game", ["accountSelect"]),
...mapState("user", ["cser_id", "cser_name"]),
},
watch: {
accountSelect(newVal, oldVal) {
if (newVal && newVal !== '' && newVal !== oldVal) {
if (newVal && newVal !== "" && newVal !== oldVal) {
this.filterChange();
}
},
......@@ -377,18 +377,18 @@ export default {
shenpi4,
shenpi5,
reportForm: {
customer_id: '',
member_id: '',
role_id: '',
username: '',
role_name: '',
customer_id: "",
member_id: "",
role_id: "",
username: "",
role_name: "",
register_type: 1,
approval_status: '',
approval_status: "",
},
isApproval: false,
register_type_list: [
{ value: 2, label: '玩家登记' },
{ value: 1, label: '客服登记' },
{ value: 2, label: "玩家登记" },
{ value: 1, label: "客服登记" },
],
reportInfo: {},
pageInfo: {
......@@ -400,7 +400,7 @@ export default {
isMoreRecord: false,
approvalList: [],
dialogRemarkVisible: false,
dialogRemake: '',
dialogRemake: "",
formatNumber: formatNumber,
taskTypeList: [],
};
......@@ -428,9 +428,9 @@ export default {
},
async requstApprovalList() {
const data = {
type: 'dictionaries',
table_name: 'zs_refund_request',
field_name: 'approval_status',
type: "dictionaries",
table_name: "zs_refund_request",
field_name: "approval_status",
};
const res = await searchcondition(data);
if (res.status_code === 1) {
......@@ -439,9 +439,9 @@ export default {
},
async request_register_type() {
const data = {
type: 'dictionaries',
table_name: 'zs_report_request',
field_name: 'register_type',
type: "dictionaries",
table_name: "zs_report_request",
field_name: "register_type",
};
const res = await searchcondition(data);
if (res.status_code === 1) {
......@@ -453,13 +453,13 @@ export default {
this.dialogRemarkVisible = true;
},
async reportProcess(item, index) {
console.log(item.current, 'item');
console.log(item.current, "item");
item.showStep = !item.showStep;
if (item.reportProcessList.length === 0) {
const res = await reportProcess({ id: item.id });
item.reportProcessList = res.data.data;
res.data.data.map((items) => {
if (items.approval_result !== '0' && items.approval_result !== '2') {
if (items.approval_result !== "0" && items.approval_result !== "2") {
item.current += 1;
}
});
......@@ -469,9 +469,9 @@ export default {
this.$forceUpdate();
},
paperScroll() {
console.log('开始滚动了');
console.log("开始滚动了");
if (!this.isMoreRecord) {
console.log('没有更多数据了');
console.log("没有更多数据了");
return false;
}
this.requestNextPage();
......@@ -485,12 +485,12 @@ export default {
},
switchStateTag(status) {
switch (status) {
case '0':
return 'unhandle';
case '1':
return 'handled';
case '2':
return 'sendFail';
case "0":
return "unhandle";
case "1":
return "handled";
case "2":
return "sendFail";
}
},
formatImg(html) {
......@@ -501,19 +501,19 @@ export default {
},
switchStateText(status) {
switch (status) {
case '0':
return '待审批';
case '1':
return '通过';
case '2':
return '驳回';
case "0":
return "待审批";
case "1":
return "通过";
case "2":
return "驳回";
}
},
handleReport(item) {
this.$confirm('确定要撤销该申请么?', '确认提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
this.$confirm("确定要撤销该申请么?", "确认提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
console.log(1231);
......@@ -525,8 +525,8 @@ export default {
reportCancel(data).then((res) => {
if (res.status_code === 1) {
this.$message({
type: 'success',
message: '撤销成功!',
type: "success",
message: "撤销成功!",
});
this.filterChange();
}
......@@ -534,15 +534,15 @@ export default {
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消',
type: "info",
message: "已取消",
});
});
},
// 举报列表
async reportIndex() {
if (this.accountSelect === '') {
this.$message.warning('暂无关联的账号,请先去关联账号!');
if (this.accountSelect === "") {
this.$message.warning("暂无关联的账号,请先去关联账号!");
return false;
}
if (this.pageInfo.page == 1) {
......@@ -551,20 +551,34 @@ export default {
const { username, role_name, approval_status, register_type } =
this.reportForm;
// const { id } = this.userInfo
const data = {
username,
role_name,
approval_status,
// customer_id: id,
member_id: this.accountSelect,
register_type,
...this.pageInfo,
};
const related_task_info = JSON.parse(
sessionStorage.getItem("related_task_info")
);
let data;
if (related_task_info && related_task_info.related_task_type === 6) {
data = { ...this.pageInfo, id: related_task_info.related_task_id };
this.reportForm.register_type = "";
//展示一次后清除携带过来的id
this.$nextTick(() => {
sessionStorage.removeItem("related_task_info");
});
} else {
data = {
username,
role_name,
approval_status,
// customer_id: id,
member_id: this.accountSelect,
register_type,
...this.pageInfo,
};
}
const res = await reportIndex(data);
if (this.pageInfo.page == 1) {
this.reportList = res.data.data;
} else {
this.reportList = removeDp(this.reportList, res.data.data, 'id');
this.reportList = removeDp(this.reportList, res.data.data, "id");
}
if (this.reportList.length > 0) {
this.reportList.map((item) => {
......
<template>
<div class="flex flex-col h-full">
<div
class="py-[19px] px-[16px] text-[14px] text-[#86909C] space-x-[24px] border-b-[1px] border-solid border-[#F2F3F5]"
>
<span
v-for="value in tabList"
:key="value.value"
@click="handleTabClick(value.value)"
class="cursor-pointer"
:class="{ '!text-[#323335] font-medium': activeTab === value.value }"
>{{ value.name }}</span
>
</div>
<div class="flex-1 overflow-y-auto" @scroll="handleScroll">
<div
class="p-[16px] space-y-[6px] border-b-[1px] border-solid border-[#F2F3F5]"
v-for="(value, index) in list"
:key="value.id || index"
>
<div class="flex space-x-[16px] text-[#323335]">
<div
class="w-[56px] text-[#86909C]"
:class="{ 'user-agency': value.status === 0 }"
>
<el-tag :type="['success', 'info'][value.status]">
{{ value.status_text }}
</el-tag>
</div>
<div
class="truncate flex-1 flex items-center text-[16px] font-medium"
>
{{ value.name }}
</div>
</div>
<div class="flex space-x-[16px] text-[#323335]">
<div class="w-[56px] text-[#86909C]">待办详情</div>
<div class="flex-1 relative" :ref="(el) => (detailRefs[index] = el)">
<div
class="text-[14px] break-words transition-all duration-300"
:class="{ 'max-h-[22px] overflow-hidden': !value.showMore }"
v-show="!value.showMore"
>
{{ value.detail }}
</div>
<div class="text-[14px] break-words" v-show="value.showMore">
{{ value.detail }}
</div>
<div
v-if="value.shouldShowMore"
class="bg-white absolute bottom-0 right-0 cursor-pointer flex items-center pl-[16px]"
@click="toggleShowMore(index)"
>
{{ value.showMore ? "收起" : "展开" }}
<svg-icon
svgName="icon-zhankai"
class="w-[12px] h-[12px]"
:class="{ 'rotate-180': value.showMore }"
></svg-icon>
</div>
</div>
</div>
<div class="flex space-x-[16px] text-[#323335]">
<div class="w-[56px] text-[#86909C]">创建时间</div>
<div class="flex-1 flex items-center text-[14px] break-words">
{{ value.created_at }}
</div>
</div>
<div class="flex space-x-[16px] text-[#323335]">
<div class="w-[56px] text-[#86909C]">归属客服</div>
<div class="flex-1 flex items-center text-[14px] break-words">
{{ value.cser_name }}
</div>
</div>
<div class="flex space-x-[16px] text-[#323335]">
<div class="w-[56px] text-[#86909C]">来源会话</div>
<div class="flex-1 flex items-center text-[14px] break-words">
2025-12-22 14:21:12至2025-12-22 15:21:12
</div>
</div>
<div class="flex space-x-[16px] text-[#323335]">
<div class="w-[56px] text-[#86909C]">关联工单</div>
<div class="flex-1 flex items-center text-[14px] break-words">
玩家申诉(通过)<el-button
v-if="value.related_task_id"
type="text"
class="!py-0"
@click="handleClick(value)"
>工单详情</el-button
>
</div>
</div>
<div
class="flex space-x-[16px] text-[#323335]"
v-if="value.related_task_type"
>
<div class="w-[56px] text-[#86909C]">待办类型</div>
<div
class="flex-1 flex items-center text-[14px] break-words flex-wrap gap-[6px]"
>
<div class="px-[6px] bg-[#F2F3F5] rounded-[4px] shrink-0">
{{ related_task_type_text[value.related_task_type] }}
</div>
</div>
</div>
<div class="flex space-x-[16px] text-[#323335]">
<div class="w-[56px] text-[#86909C]">完成会话</div>
<div
class="flex-1 flex items-center text-[14px] break-words flex-wrap gap-[6px]"
>
2025-12-22 14:21:12至2025-12-22 15:21:12
</div>
</div>
</div>
<div v-if="loading" class="relative flex justify-center py-[20px]">
<loading />
</div>
</div>
</div>
</template>
<script>
import { mapMutations, mapState } from "vuex";
import {
corpIntelligentTaskExternalList,
corpIntelligentTaskMineList,
} from "@/api/works";
import loading from "@/components/loading";
export default {
name: "UserAgency",
components: {
loading,
},
data() {
return {
activeTab: 0,
related_task_type_text: {
6: "举报申请",
12: "玩家误操作",
14: "转区申请",
13: "玩家转端",
},
tabList: [
{
name: "未完成",
value: 0,
},
{
name: "已完成",
value: 1,
},
{
name: "我的待办",
value: 2,
},
],
detailRefs: [],
show: false,
page_info: {
page: 1,
page_size: 10,
total: 0,
},
list: [],
loading: false,
};
},
computed: {
...mapState("game", ["chatUserInfo"]),
},
methods: {
handleClick(v) {
sessionStorage.setItem(
"related_task_info",
JSON.stringify({
related_task_id: v.related_task_id,
related_task_type: v.related_task_type,
})
);
// 跳转到申请记录
this.$router.push({
path: "/applyRecord",
});
},
handleTabClick(value) {
if (this.activeTab === value) return;
this.activeTab = value;
this.page_info.page = 1;
this.list = [];
this.getList(value);
},
handleScroll(e) {
const { scrollTop, scrollHeight, clientHeight } = e.target;
// 当滚动到底部100px以内时加载更多
if (scrollHeight - scrollTop - clientHeight < 100 && !this.loading) {
// 检查是否还有更多数据可以加载
if (this.list.length < this.page_info.total) {
this.loadMore();
}
}
},
loadMore() {
this.page_info.page++;
this.getList(this.activeTab);
},
toggleShowMore(index) {
this.$set(this.list[index], "showMore", !this.list[index].showMore);
},
checkTextOverflow() {
this.$nextTick(() => {
this.detailRefs.forEach((ref, index) => {
if (ref) {
// 创建一个临时元素来测量文本高度
const tempEl = document.createElement("div");
tempEl.className = "text-[14px] break-words";
tempEl.style.position = "absolute";
tempEl.style.visibility = "hidden";
tempEl.style.width = "100%";
tempEl.style.whiteSpace = "normal";
tempEl.innerHTML = this.list[index].detail;
ref.appendChild(tempEl);
// 计算一行文字的高度(假设行高为1.5倍字体大小)
const lineHeight = parseInt(
window.getComputedStyle(tempEl).lineHeight
);
const fontHeight = parseInt(
window.getComputedStyle(tempEl).fontSize
);
const expectedLineHeight = lineHeight || fontHeight * 1.5;
// 测量文本总高度
const totalHeight = tempEl.offsetHeight;
// 如果内容高度大于一行高度,则显示展开收起按钮
const shouldShowMore = totalHeight > expectedLineHeight;
this.$set(this.list[index], "shouldShowMore", shouldShowMore);
// 移除临时元素
ref.removeChild(tempEl);
}
});
});
},
async getList(value = 0) {
// 如果正在加载或者已经是最后一页,则不发起请求
if (
this.loading ||
(this.list.length >= this.page_info.total && this.page_info.total > 0)
) {
return;
}
this.loading = true;
const params = {
status: value,
page: this.page_info.page,
page_size: this.page_info.page_size,
external_userid: this.chatUserInfo.external_userid,
};
let api;
try {
if (value !== 2) {
api = corpIntelligentTaskExternalList;
} else {
delete params.external_userid;
delete params.status;
api = corpIntelligentTaskMineList;
}
const res = await api(params);
const newList = res.data.data.map((item) => ({
...item,
showMore: false,
shouldShowMore: false,
}));
// 如果是第一页则替换列表,否则合并列表
if (this.page_info.page === 1) {
this.list = newList;
} else {
this.list = [...this.list, ...newList];
}
this.page_info.total = res.data.page_info.total;
// 检查文字是否溢出
this.checkTextOverflow();
} catch (error) {
console.error("获取数据失败:", error);
this.$message({
message: "获取数据失败",
type: "error",
});
} finally {
this.loading = false;
}
},
},
mounted() {
this.getList();
},
};
</script>
<style scoped lang="scss">
.user-agency {
.el-tag.el-tag--success {
color: #3491fa;
background-color: #e8f7ff;
border-color: #c3e7fe;
}
}
</style>
......@@ -11,7 +11,11 @@ module.exports = {
purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
darkMode: false,
theme: {
extend: {}
extend: {
colors: {
primary: '#409EFF',
}
}
},
variants: {
extend: {}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论