提交 f0207f9f 作者: 毛细亚

Merge branch '1.1' into 1.2

<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="favicon.ico">
<title>company_app</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 defer src="static/js/chunk-vendors.js"></script><script defer src="static/js/app.js"></script></head>
<body>
<noscript>
<strong>We're sorry but company_app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
</body>
</html>
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9"/><title>company_app</title><script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script><script defer="defer" src="static/js/chunk-vendors.fc0c503d.js"></script><script defer="defer" src="static/js/app.24843ee7.js"></script><link href="static/css/chunk-vendors.8e901099.css" rel="stylesheet"><link href="static/css/app.ea202361.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but company_app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
\ No newline at end of file
......@@ -5,6 +5,13 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- HTTP 1.1 -->
<meta http-equiv="pragma" content="no-cache">
<!-- HTTP 1.0 -->
<meta http-equiv="cache-control" content="no-cache">
<!-- Prevent caching at the proxy server -->
<meta http-equiv="expires" content="0">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" />
<title><%= htmlWebpackPlugin.options.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>
......
# v-scroll 下拉加载更多指令
## 功能概述
`v-scroll` 是一个用于实现无限滚动加载的 Vue 自定义指令。当用户滚动到页面底部或接近底部时,自动触发加载更多数据的函数,适用于列表分页加载场景。
## 特性
- 自动检测滚动容器(支持窗口和自定义滚动容器)
- 使用节流控制滚动事件触发频率,提高性能
- 支持自定义触发距离
- 支持禁用功能
- 支持移动端触摸事件
- 自动处理内容不足一屏的情况
## 参数说明
### 指令值
- **类型**`Function`
- **必填**:是
- **说明**:滚动到底部时触发的加载更多函数
### 指令参数
- **语法**`v-scroll:distance`
- **类型**`Number`
- **默认值**`30`(单位:px)
- **说明**:距离底部多少像素时触发加载更多函数
### 修饰符
- **disabled**:禁用滚动加载功能
- **语法**`v-scroll.disabled`
- **说明**:设置后将不会触发加载更多函数
## 使用方法
### 基本用法
```vue
<template>
<div v-scroll="loadMore" class="list-container">
<div v-for="(item, index) in list" :key="index" class="list-item">
{{ item.title }}
</div>
<div v-if="loading" class="loading">加载中...</div>
<div v-if="noMore" class="no-more">没有更多数据</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [],
page: 1,
pageSize: 10,
loading: false,
noMore: false
}
},
mounted() {
// 初始加载第一页数据
this.getList()
},
methods: {
// 加载更多函数,将作为 v-scroll 指令的值
loadMore() {
// 如果正在加载或没有更多数据,则不执行
if (this.loading || this.noMore) return
this.page++
this.getList()
},
async getList() {
this.loading = true
try {
const res = await this.fetchData(this.page, this.pageSize)
if (res.data && res.data.length > 0) {
this.list = [...this.list, ...res.data]
} else {
this.noMore = true
}
} catch (error) {
console.error('加载数据失败', error)
} finally {
this.loading = false
}
},
fetchData(page, pageSize) {
// 实际项目中替换为真实 API 调用
return this.$api.getList({ page, pageSize })
}
}
}
</script>
<style scoped>
.list-container {
height: 500px; /* 设置容器高度以启用滚动 */
overflow-y: auto;
max-width: 360px; /* 适配企业微信侧边栏 */
margin: 0 auto;
}
</style>
```
### 自定义触发距离
通过参数设置距离底部多少像素时触发加载:
```html
<!-- 距离底部 50px 时触发加载更多 -->
<div v-scroll:50="loadMore" class="list-container">
<!-- 列表内容 -->
</div>
```
### 禁用滚动加载
使用 disabled 修饰符禁用滚动加载功能:
```html
<!-- 禁用滚动加载功能 -->
<div v-scroll.disabled="loadMore" class="list-container">
<!-- 列表内容 -->
</div>
```
### 动态控制启用/禁用
结合 Vue 的条件表达式动态控制滚动加载:
```html
<!-- 根据 isLoading 状态动态启用/禁用 -->
<div v-scroll:30="isLoading ? null : loadMore" class="list-container">
<!-- 列表内容 -->
</div>
<!-- 或使用对象语法 -->
<div v-scroll="{ loadMore: loadMoreFn, disabled: isLoading }" class="list-container">
<!-- 列表内容 -->
</div>
```
## 注意事项
1. **滚动容器设置**
- 确保滚动容器有固定高度或最大高度,并设置 `overflow-y: auto``overflow-y: scroll`
- 指令会自动检测最近的滚动容器,如果没有找到,则使用 window 作为滚动容器
2. **性能优化**
- 指令内部已使用节流函数控制滚动事件触发频率,默认为 200ms
- 大数据列表建议使用虚拟滚动结合本指令使用
3. **移动端适配**
- 已支持触摸事件,在移动端也能正常工作
- 在企业微信环境中,最大宽度建议设置为 360px
4. **加载状态处理**
- 在 loadMore 函数中应该有加载状态控制,防止重复触发
- 推荐使用 loading 和 noMore 两个状态分别控制加载中和无更多数据
5. **初始内容不足一屏**
- 指令会在初始化时检查一次是否需要加载更多,处理内容不足一屏的情况
- 初始检查会延迟 50ms 执行,确保 DOM 渲染完成
## 示例场景
### 商品列表无限加载
```vue
<template>
<div class="product-list" v-scroll="loadMoreProducts">
<product-card
v-for="product in products"
:key="product.id"
:product="product"
/>
<div v-if="loading" class="loading-indicator">
<i class="el-icon-loading"></i> 加载中...
</div>
<div v-if="noMore && !loading" class="no-more">
没有更多商品了
</div>
</div>
</template>
```
### 聊天记录上拉加载历史消息
```vue
<template>
<div class="chat-container" v-scroll:50="loadHistoryMessages">
<div class="message-list">
<message-item
v-for="msg in messages"
:key="msg.id"
:message="msg"
/>
</div>
</div>
</template>
```
## 技术实现
该指令基于以下核心实现:
1. 使用 `throttle` 节流函数控制滚动事件触发频率
2. 自动检测并绑定最近的滚动容器
3. 精确计算滚动位置,支持 window 和自定义容器两种情况
4. 完整支持 Vue 指令生命周期(inserted, update, unbind)
\ No newline at end of file
<template>
<div class="scroll-demo">
<h2 class="demo-title">下拉加载更多示例</h2>
<!-- 使用v-scroll指令的列表容器 -->
<div
v-scroll="loadMore"
class="list-container"
ref="listContainer"
>
<!-- 列表项 -->
<div
v-for="(item, index) in list"
:key="index"
class="list-item"
>
<div class="item-avatar">
<img :src="item.avatar" alt="头像">
</div>
<div class="item-content">
<div class="item-title">{{item.title}}</div>
<div class="item-desc">{{item.desc}}</div>
</div>
</div>
<!-- 加载状态 -->
<div v-if="loading" class="loading-status">
<i class="el-icon-loading"></i> 加载中...
</div>
<!-- 无更多数据提示 -->
<div v-if="noMore && !loading" class="no-more">
— 没有更多数据了 —
</div>
</div>
<!-- 控制面板 -->
<div class="control-panel">
<el-switch
v-model="disabled"
active-text="禁用加载"
inactive-text="启用加载"
/>
<el-button
@click="resetList"
type="primary"
size="small"
>
重置列表
</el-button>
</div>
</div>
</template>
<script>
export default {
name: 'ScrollDemo',
data() {
return {
list: [],
page: 1,
pageSize: 10,
loading: false,
noMore: false,
disabled: false
}
},
computed: {
// 根据disabled状态动态计算加载函数
loadMoreHandler() {
return this.disabled ? null : this.loadMore
}
},
mounted() {
// 初始加载第一页数据
this.getList()
},
methods: {
// 加载更多数据
loadMore() {
// 如果正在加载、已禁用或没有更多数据,则不执行
if (this.loading || this.disabled || this.noMore) return
this.page++
this.getList()
},
// 获取列表数据
async getList() {
this.loading = true
try {
// 模拟API请求延迟
await this.sleep(800)
// 模拟API请求返回数据
const res = await this.mockApi(this.page, this.pageSize)
if (res.data && res.data.length > 0) {
// 追加新数据到列表
this.list = [...this.list, ...res.data]
} else {
// 设置无更多数据标记
this.noMore = true
}
} catch (error) {
console.error('加载数据失败', error)
this.$message.error('加载失败,请重试')
} finally {
this.loading = false
}
},
// 重置列表
resetList() {
this.list = []
this.page = 1
this.noMore = false
this.getList()
},
// 模拟API请求
mockApi(page, pageSize) {
return new Promise(resolve => {
// 假设只有5页数据
const hasMore = page <= 5
const data = hasMore
? Array(pageSize).fill().map((_, i) => ({
id: (page - 1) * pageSize + i + 1,
title: `用户${(page - 1) * pageSize + i + 1}`,
desc: `这是第${page}页的第${i + 1}条数据,总第${(page - 1) * pageSize + i + 1}条`,
avatar: `https://randomuser.me/api/portraits/men/${((page - 1) * pageSize + i) % 100}.jpg`
}))
: []
resolve({ data, total: 50 })
})
},
// 辅助方法:延时
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
}
}
</script>
<style scoped>
.scroll-demo {
max-width: 360px;
margin: 0 auto;
padding: 10px;
}
.demo-title {
text-align: center;
margin-bottom: 15px;
font-size: 18px;
}
.list-container {
height: 70vh;
overflow-y: auto;
border: 1px solid #ebeef5;
border-radius: 4px;
background-color: #fff;
}
.list-item {
display: flex;
padding: 12px 15px;
border-bottom: 1px solid #f0f0f0;
}
.item-avatar {
width: 40px;
height: 40px;
margin-right: 12px;
}
.item-avatar img {
width: 100%;
height: 100%;
border-radius: 50%;
object-fit: cover;
}
.item-content {
flex: 1;
}
.item-title {
font-size: 16px;
font-weight: 500;
margin-bottom: 4px;
}
.item-desc {
font-size: 13px;
color: #606266;
}
.loading-status, .no-more {
text-align: center;
padding: 15px;
color: #909399;
font-size: 14px;
}
.control-panel {
margin-top: 15px;
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #f5f7fa;
border-radius: 4px;
}
</style>
\ No newline at end of file
// 表格吸顶
import scroll from './scroll'
const install = function(Vue) {
Vue.directive('scroll', scroll)
}
if (window.Vue) {
window.scroll = scroll
Vue.use(install); // eslint-disable-line
}
scroll.install = install
export default scroll
/*
* 我想封装这样的下拉加载更多的功能指令
* 1. 当页面滚动到底部或者接近底部的时候 触发接口请求请求下一页的数据
* 2.触发的时候 引入 debounce 防抖函数
*/
import { throttle } from '@/utils/index';
const InfiniteScroll = {
name: 'infinite-scroll',
inserted(el, binding, vnode) {
const options = parseOptions(el, binding);
el.__infinite_scroll_options = options;
// 使用节流控制滚动事件触发频率
const scrollHandler = createScrollHandler(el, binding, vnode);
el.__infinite_scroll_handler = throttle(scrollHandler, 200);
// 绑定滚动事件
el.__infinite_scroll_container = bindEvents(el, el.__infinite_scroll_handler);
// 初始检查一次(处理内容不足一屏的情况)
setTimeout(() => {
el.__infinite_scroll_handler();
}, 50);
},
update(el, binding) {
// 更新配置
el.__infinite_scroll_options = parseOptions(el, binding);
},
unbind(el) {
// 解绑事件
if (el.__infinite_scroll_container && el.__infinite_scroll_handler) {
unbindEvents(el, el.__infinite_scroll_container, el.__infinite_scroll_handler);
}
// 清理引用
delete el.__infinite_scroll_container;
delete el.__infinite_scroll_handler;
delete el.__infinite_scroll_options;
}
};
// 解析配置选项
function parseOptions(el, binding) {
return {
// 距离底部多远触发加载,默认30px
distance: binding.arg ? parseInt(binding.arg) : 30,
// 是否禁用
disabled: binding.modifiers.disabled,
// 加载函数
loadMore: binding.value
};
}
// 创建滚动处理函数
function createScrollHandler(el, binding, vnode) {
return function() {
const options = el.__infinite_scroll_options;
// 检查是否禁用
if (options.disabled) return;
const scrollContainer = el.__infinite_scroll_container;
const isBottom = isScrollBottom(scrollContainer, el, options.distance);
if (isBottom) {
// 调用加载函数
options.loadMore();
}
};
}
// 绑定事件
function bindEvents(el, handler) {
const scrollContainer = getScrollContainer(el);
scrollContainer.addEventListener('scroll', handler);
// 移动端支持
if ('ontouchend' in document) {
scrollContainer.addEventListener('touchend', handler);
}
return scrollContainer;
}
// 解绑事件
function unbindEvents(el, container, handler) {
container.removeEventListener('scroll', handler);
if ('ontouchend' in document) {
container.removeEventListener('touchend', handler);
}
}
// 获取滚动容器
function getScrollContainer(el) {
let container = el;
while (container && container !== document.body) {
const { overflowY } = window.getComputedStyle(container);
if (['auto', 'scroll', 'overlay'].includes(overflowY)) {
return container;
}
container = container.parentNode;
}
// 默认返回window
return window;
}
// 判断是否滚动到底部
function isScrollBottom(scrollContainer, el, distance = 30) {
// window情况
if (scrollContainer === window) {
return (
Math.ceil(window.innerHeight + window.pageYOffset) >=
document.documentElement.scrollHeight - distance
);
}
// DOM元素情况
return (
Math.ceil(scrollContainer.scrollTop + scrollContainer.clientHeight) >=
scrollContainer.scrollHeight - distance
);
}
export default InfiniteScroll;
\ No newline at end of file
......@@ -20,21 +20,22 @@ import globalComponent from '@/components/register.js'
import loadmore from '@/directive/loadmore/index.js' // 加载更多
import clickagain from './directive/clickagain'
import permission from '@/directive/permission/index.js' // 权限判断指令
Vue.use(globalComponent).use(permission).use(clickagain).use(loadmore)
import scroll from '@/directive/scroll' // 下拉加载更多指令
Vue.use(globalComponent).use(permission).use(clickagain).use(loadmore).use(scroll)
// 导入 VConsole 清理工具
import '@/utils/vconsoleCleanup'
// 开发环境下初始化 stagewise 工具栏
if (process.env.NODE_ENV === 'development') {
import('@stagewise/toolbar').then(({ initToolbar }) => {
const stagewiseConfig = {
plugins: []
};
initToolbar(stagewiseConfig);
}).catch(err => {
console.error('Failed to initialize stagewise toolbar:', err);
});
}
// if (process.env.NODE_ENV === 'development') {
// import('@stagewise/toolbar').then(({ initToolbar }) => {
// const stagewiseConfig = {
// plugins: []
// };
// initToolbar(stagewiseConfig);
// }).catch(err => {
// console.error('Failed to initialize stagewise toolbar:', err);
// });
// }
// 开发环境不收集日志
if (process.env.NODE_ENV !== 'development') {
......
......@@ -16,6 +16,7 @@ const state = {
gameUserInfo:{},
send_game_log: null, // 转游发送渠道新增日志发送信息
chatUserInfo: {}, // 当前选中的用户的详情
viewLoading:false, // 查看用户详情的时候 加载状态
}
const mutations = {
......@@ -39,6 +40,9 @@ const mutations = {
},
set_send_game_log(state, data) {
state.send_game_log = data
},
set_viewLoading(state, data) {
state.viewLoading = data
}
}
......
......@@ -86,6 +86,22 @@ div:focus {
height: 1px;
background-color: #e4e7ed;
}
.el-tabs{
height:100%;
}
.el-tabs__content{
height: 100%;
}
.el-tab-pane{
height: 100%;
}
.el-tabs .el-tabs__header{
margin: 0;
// height: 60px;
}
.el-tabs__nav-next, .el-tabs__nav-prev{
line-height: 50px;
}
/* 统一下拉框高度 */
.el-select-dropdown__item {
......
......@@ -259,15 +259,15 @@ export default {
<style lang="scss" scoped>
.violationRecord {
width: 100%;
height: calc(100vh - 170px);
height: 100%;
background: #fff;
overflow-y: auto;
overflow-x: hidden;
.violationRecordContent {
width: 100%;
padding: 20px;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
height: auto;
}
.contentItem {
......
<template>
<div class="addressBook-content">
通讯录
</div>
</template>
<script>
export default {
name: 'AddressBook',
}
</script>
<style lang="scss" scoped>
.addressBook-content{
width: 100%;
height: 100%;
background: #fff;
}
</style>
\ No newline at end of file
<template>
<div class="terminaListArea">
<div class="terminaListArea" v-scroll="paperScroll">
<div class="addApply rowFlex spaceBetween">
<span></span>
<el-button
......@@ -44,10 +44,7 @@
</el-form-item>
</el-form>
<div
v-infinite-scroll="paperScroll"
:infinite-scroll-disabled="!isMoreRecord"
:infinite-scroll-immediate="false"
class="mailListScroll"
class="terminaListAreaList"
>
<!-- 举报申请 -->
<div class="scrollMain" v-if="terminaList.length > 0">
......@@ -377,6 +374,10 @@ export default {
this.$forceUpdate()
},
paperScroll() {
if (!this.isMoreRecord) {
console.log('没有更多数据了')
return false
}
this.requestNextPage()
},
requestNextPage(pageInfo) {
......@@ -457,6 +458,7 @@ export default {
width: 100%;
height: 100%;
overflow: auto;
overflow-x: hidden;
::v-deep .el-form-item__label{
font-weight: 400;
}
......@@ -516,12 +518,8 @@ export default {
}
}
.mailListScroll {
.terminaListAreaList {
width: 100%;
height: calc(100% - 220px);
overflow-y: auto;
overflow-x: hidden;
.scrollMain {
width: 100%;
height: auto;
......
<template>
<div class="detailsErrorHandle columnFlex">
<div class="detailsErrorHandleContent">
<div class="detailsErrorHandleContent" v-scroll="requestOrderList">
<div class="addApply rowFlex spaceBetween">
<span></span>
<el-button
......@@ -32,7 +32,7 @@
<div class="list">
<!-- 过滤条件 -->
<!-- 订单列表 -->
<div v-infinite-scroll="requestOrderList" :infinite-scroll-disabled="!isloadMore" class="orderDetailsScroll">
<div class="orderDetailsScroll">
<div v-if="orderList.length>0" class="orderDetailsScrollContent">
<div v-for="(item,index) in orderList" :key="index" class="orderDetails">
<div class="orderDetailsList">
......@@ -302,7 +302,6 @@ export default {
background: #fff;
margin-left: 2px;
position: relative;
overflow: hidden;
.detailsTitle {
width: 100%;
padding: 0 vw(20);
......@@ -321,6 +320,8 @@ export default {
width: 100%;
height:100%;
padding: 20px 10px;
overflow: auto;
overflow-x: hidden;
.tabSelect{
width: 100%;
height: 60px;
......@@ -342,8 +343,7 @@ export default {
}
.list{
width: 100%;
height: calc(100% - 90px);
overflow: auto;
height: auto;
}
.contentItem{
position: relative;
......@@ -456,9 +456,6 @@ export default {
}
.orderDetailsScroll{
width: 100%;
height: calc(100% - 20px);
overflow: auto;
overflow-x: hidden;
.orderDetailsScrollContent{
margin-bottom: 50px;
}
......
......@@ -74,7 +74,8 @@ export default {
...mapMutations('game', [
'set_accountSelect',
'set_chatUserInfo',
'set_gameUserInfo'
'set_gameUserInfo',
'set_viewLoading'
]),
...mapActions('game', ['gameBindUser']),
handleChange(value) {
......@@ -89,17 +90,19 @@ export default {
},
gameMemberView(item) {
if (this.accountSelect && this.accountSelect !== '') {
this.set_viewLoading(true)
const data = { member_id: this.accountSelect, need_channel: 1, need_roleInfo: 1, need_banned: 1 }
memberView(data).then((res) => {
this.set_viewLoading(false)
if (res.status_code === 1) {
this.set_gameUserInfo(res.data)
} else {
this.set_gameUserInfo({})
}
}, (err) => {
this.set_viewLoading(false)
this.set_gameUserInfo({})
})
}
},
addNewUser() {
......
......@@ -95,7 +95,7 @@ import Clipboard from 'clipboard'
<style lang="scss" scoped>
.wx-gift-container {
height: calc(100vh - 230px);
height: 100%;
width: 100%;
background-color: #fff;
......
<template>
<div class="detailsRefund columnFlex">
<div class="content refundContent">
<div class="refundContent" v-scroll="requestOrderList">
<div class="filter-container">
<el-form class="filter-form" label-position="top" label-width="auto">
<el-form class="filter-form" label-position="top" label-width="auto" :class="{ 'collapsed-form': isCollapsed }">
<div class="filter-header">
<span class="filter-title">筛选条件</span>
<i
:class="isCollapsed ? 'el-icon-arrow-down' : 'el-icon-arrow-up'"
class="collapse-icon"
@click="toggleCollapse"
></i>
</div>
<el-form-item label="订单号:">
<el-input
v-model="requestData.order_id"
......@@ -49,10 +57,7 @@
</div>
<!-- 订单列表 -->
<div
v-infinite-scroll="requestOrderList"
v-loading="loading"
class="detailsRefundScroll"
:infinite-scroll-disabled="!isloadMore"
>
<div v-if="orderList.length > 0">
<div v-for="(item, index) in orderList" :key="index" class="orderDetails">
......@@ -276,7 +281,8 @@
page: 0,
page_size: 20,
total: 0
}
},
isCollapsed: false
}
},
computed: {
......@@ -461,7 +467,10 @@
this.loading = false
}
)
}, 1000)
}, 1000),
toggleCollapse() {
this.isCollapsed = !this.isCollapsed
}
}
}
</script>
......@@ -470,9 +479,6 @@
width: 100%;
height: 100%;
background: #fff;
position: relative;
overflow: hidden;
.detailsTitle {
width: 100%;
padding: 0 vw(20);
......@@ -489,11 +495,11 @@
}
}
.content {
.refundContent {
width: 100%;
height: 100%;
padding-top: 20px;
overflow: auto;
overflow-x: hidden;
.tabSelect {
width: 100%;
height: 60px;
......@@ -631,9 +637,7 @@
}
.detailsRefundScroll {
width: 100%;
height: calc(100% - 250px);
overflow: auto;
overflow-x: hidden;
height: auto;
padding-right: 10px;
border-radius: 5px;
}
......@@ -784,6 +788,76 @@
}
}
.filter-container {
margin-bottom: 10px;
.filter-form {
border: 1px solid #EBEEF5;
border-radius: 4px;
padding: 10px;
transition: all 0.3s;
.filter-header {
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px dashed #EBEEF5;
}
.filter-title {
font-size: 14px;
font-weight: 500;
color: #606266;
}
.collapse-icon {
cursor: pointer;
color: #409EFF;
font-size: 16px;
padding: 5px;
transition: all 0.3s;
}
&.collapsed-form {
.el-form-item {
display: none;
}
.filter-header {
margin-bottom: 0;
padding-bottom: 0;
border-bottom: none;
}
}
.el-form-item {
margin-bottom: 15px;
width: 100%;
margin-right: 2%;
display: inline-block;
vertical-align: top;
&:nth-child(2n) {
margin-right: 0;
}
}
::v-deep .el-form-item__label {
padding: 0;
line-height: 24px;
font-size: 14px;
color: #606266;
}
::v-deep .el-form-item__content {
line-height: 36px;
}
.searchInput {
width: 100%;
}
}
}
::v-deep .el-tabs__item {
line-height: 26px;
font-size: 16px;
......
......@@ -693,11 +693,11 @@ export default {
// const list = [
// {
// msgtype: 'text',
// text: { content: `账号:${username} \n密码:${res.data.encryptPassword}`, key: res.data.key, iv: res.data.iv }
// text: { content: `账号:${username} \n密码:${res.data.password}`, key: res.data.key, iv: res.data.iv }
// }
// ]
// this.set_sendSkillMessage(list)
this.sendChatMessage(`账号:${username} \n密码:${res.data.encryptPassword}`, 'text')
this.sendChatMessage(`账号:${username} \n密码:${res.data.password}`, 'text')
this.markTransScene(type)
this.sendGameLog(item)
})
......@@ -740,13 +740,13 @@ export default {
{
msgtype: 'text',
text: {
content: `${str}${item.url} \n账号:${username} \n密码:${res.data.encryptPassword}`,
content: `${str}${item.url} \n账号:${username} \n密码:${res.data.password}`,
key: res.data.key, iv: res.data.iv
}
}
]
// this.set_sendSkillMessage(list)
this.sendChatMessage(`${str}${item.url} \n账号:${username} \n密码:${res.data.encryptPassword}`, 'text')
this.sendChatMessage(`${str}${item.url} \n账号:${username} \n密码:${res.data.password}`, 'text')
this.markTransScene(type)
item.type = 1
this.sendGameLog(item)
......@@ -941,14 +941,14 @@ export default {
channel_key: item.channel_key
},
text: {
content: `${str}${item.game_url} \n账号:${username} \n密码:${res.data.encryptPassword}`,
content: `${str}${item.game_url} \n账号:${username} \n密码:${res.data.password}`,
key: res.data.key, iv: res.data.iv
}
}
]
// 这里需要特殊处理,因为有taskInfo参数
// this.set_sendSkillMessage(list)
this.sendChatMessage(`${str}${item.game_url} \n账号:${username} \n密码:${res.data.encryptPassword}`, 'text')
this.sendChatMessage(`${str}${item.game_url} \n账号:${username} \n密码:${res.data.password}`, 'text')
item.type = 3
this.sendGameLog(item)
})
......
......@@ -211,11 +211,11 @@ export default {
const list = [
{
msgtype: 'text',
text: { content: `账号:${username} \n密码:${res.data.encryptPassword}`, key: res.data.key, iv: res.data.iv }
text: { content: `账号:${username} \n密码:${res.data.password}`, key: res.data.key, iv: res.data.iv }
}
]
// this.set_sendSkillMessage(list)
this.sendChatMessage(`账号:${username} \n密码:${res.data.encryptPassword}`, 'text')
this.sendChatMessage(`账号:${username} \n密码:${res.data.password}`, 'text')
this.close()
})
.catch((err) => {
......@@ -252,14 +252,14 @@ export default {
{
msgtype: 'text',
text: {
content: `${str}${this.webForm.channel_id.game_url} \n账号:${username} \n密码:${res.data.encryptPassword}`,
content: `${str}${this.webForm.channel_id.game_url} \n账号:${username} \n密码:${res.data.password}`,
key: res.data.key,
iv: res.data.iv
}
}
]
// this.set_sendSkillMessage(list)
this.sendChatMessage(`${str}${this.webForm.channel_id.game_url} \n账号:${username} \n密码:${res.data.encryptPassword}`, 'text')
this.sendChatMessage(`${str}${this.webForm.channel_id.game_url} \n账号:${username} \n密码:${res.data.password}`, 'text')
this.close()
})
.catch((err) => {
......
......@@ -170,11 +170,11 @@ export default {
// const list = [
// {
// msgtype: 'text',
// text: { content: `账号:${username} \n密码:${res.data.encryptPassword}`, key: res.data.key, iv: res.data.iv }
// text: { content: `账号:${username} \n密码:${res.data.password}`, key: res.data.key, iv: res.data.iv }
// }
// ]
// this.set_sendSkillMessage(list)
this.sendChatMessage(`账号:${username} \n密码:${res.data.encryptPassword}`, 'text')
this.sendChatMessage(`账号:${username} \n密码:${res.data.password}`, 'text')
this.close()
})
.catch((err) => {
......@@ -211,13 +211,13 @@ export default {
// {
// msgtype: 'text',
// text: {
// content: `${str}${this.webForm.channel_id.game_url} \n账号:${username} \n密码:${res.data.encryptPassword}`,
// content: `${str}${this.webForm.channel_id.game_url} \n账号:${username} \n密码:${res.data.password}`,
// key: res.data.key, iv: res.data.iv
// }
// }
// ]
// this.set_sendSkillMessage(list)
this.sendChatMessage(`${str}${this.webForm.channel_id.game_url} \n账号:${username} \n密码:${res.data.encryptPassword}`, 'text')
this.sendChatMessage(`${str}${this.webForm.channel_id.game_url} \n账号:${username} \n密码:${res.data.password}`, 'text')
this.close()
})
.catch((err) => {
......
......@@ -277,7 +277,7 @@
}
const username = this.bindGameUserList.find(item => item.member_id == this.accountSelect).username
passwardEncryption({ member_id: this.accountSelect }).then(res => {
this.sendChatMessage(`${str}${item.url} \n账号:${username} \n密码:${res.data.encryptPassword}`, 'text')
this.sendChatMessage(`${str}${item.url} \n账号:${username} \n密码:${res.data.password}`, 'text')
}).catch(err => {
this.sendChatMessage(`${str}${item.url} \n账号:${username}`, 'text')
console.log(err)
......
......@@ -84,7 +84,7 @@
v-infinite-scroll="paperScroll"
:infinite-scroll-disabled="!isMoreRecord"
:infinite-scroll-immediate="false"
class="mailListScroll"
class="approvalScroll"
>
<!-- 举报申请 -->
<div class="scrollMain" v-if="reportList.length > 0">
......@@ -512,9 +512,9 @@
<style lang="scss" scoped>
.approval-role-list {
width: 100%;
height: calc(100vh - 200px);
overflow: auto;
height: 100%;
padding-top: 10px;
overflow: auto;
.taskForm {
::v-deep .el-form-item {
margin-bottom: 10px;
......@@ -567,12 +567,9 @@
}
}
.mailListScroll {
.approvalScroll {
width: 100%;
overflow-y: auto;
overflow-x: hidden;
display: flex;
flex: 1;
height: auto;
.scrollMain {
width: 100%;
height: auto;
......
......@@ -517,8 +517,8 @@
.reportList {
width: 100%;
height: 100%;
overflow: auto;
overflow-y: auto;
overflow-x: hidden;
.taskForm {
::v-deep .el-form-item {
margin-bottom: 10px;
......@@ -573,15 +573,11 @@
.mailListScroll {
width: 100%;
height: calc(100% - 250px);
overflow-y: auto;
overflow-x: hidden;
height: auto;
.scrollMain {
width: 100%;
height: auto;
margin-bottom: 40px;
.reportContent {
width: calc(100% - 10px);
}
......
......@@ -196,6 +196,7 @@
height: 100%;
background: #fff;
margin-left: 2px;
overflow: auto;
.detailsTitle {
width: 100%;
padding: 0 vw(20);
......@@ -212,7 +213,7 @@
}
.detailsContent {
width: 100%;
height: calc(100vh - 186px);
height: 100%;
overflow: auto;
.textInfo {
font-family: PingFangSC-Regular, PingFang SC;
......
......@@ -45,7 +45,7 @@
</div>
<div v-else-if="answer.msgtype == 'image'" class="answerText rowFlex">
<span class="title rowFlex">A{{ answerIndex + 1 }}:</span>
<el-image style="max-width: 200px" :src="answer.image.picurl" :preview-src-list="[answer.image.picurl]" > </el-image>
<el-image style="max-width: 200px" :src="answer.image.picurl" @click="sendMessageImage(answer, items._id)" :preview-src-list="[answer.image.picurl]" > </el-image>
</div>
</div>
</div>
......
......@@ -2,10 +2,10 @@
<div class="gift-tab-container-apply-gift">
<el-tabs v-model="activeTab">
<el-tab-pane label="充值礼包" name="email">
<email-gift></email-gift>
<email-gift v-if="activeTab == 'email'"></email-gift>
</el-tab-pane>
<el-tab-pane label="企微礼包" name="wx">
<wx-gift></wx-gift>
<wx-gift v-if="activeTab == 'wx'"></wx-gift>
</el-tab-pane>
</el-tabs>
</div>
......@@ -50,6 +50,10 @@ export default {
padding-top: 10px;
background: #fff;
::v-deep .el-tabs__content{
height: calc(100% - 55px);
}
::v-deep .el-tabs {
.el-tabs__header {
margin: 0;
......@@ -67,6 +71,7 @@ export default {
}
}
.el-tabs__active-bar {
background-color: #3491FA;
height: 3px;
......
<template>
<div class="mail-list-container">
<div class="mail-list-container"
ref="mailListScroll"
v-scroll:50="loadMoreMail"
>
<!-- 搜索过滤区域 -->
<div class="search-header">
<div class="search-row">
......@@ -87,14 +90,12 @@
<!-- 通讯录列表 -->
<div
ref="mailListScroll"
v-infinite-scroll="loadMoreMail"
:infinite-scroll-disabled="!hasMore"
:infinite-scroll-immediate="false"
v-scroll="loadMoreMail"
class="contact-list"
>
<div
v-for="(item, index) in mailList"
:key="item._id || index"
:key="item._id+index"
class="contact-item"
:class="{ active: item.external_userid === chatUserInfo.external_userid }"
>
......@@ -126,13 +127,8 @@
<!-- 右侧操作区域 -->
<div class="contact-actions">
<!-- 待绑定标签 -->
<div v-if="item.red_tip == 1" class="unbind-tag">
待绑定
</div>
<!-- 发起会话按钮 -->
<el-button
v-else
type="primary"
size="small"
class="chat-btn"
......@@ -259,12 +255,11 @@ export default {
...this.pagination,
userid: this.userid,
}
// 根据搜索类型构建不同的参数
if (this.searchType === 'remark') {
this.searchParams = {
...this.searchParams,
...baseParams,
...this.searchParams
}
} else if (this.searchType === 'w_account') {
this.searchParams = {
......@@ -274,7 +269,6 @@ export default {
} else {
this.searchParams = baseParams
}
// 添加筛选参数
if (this.mailFilterType === 'unbind') {
this.searchParams.red_tip = 1
......@@ -331,8 +325,11 @@ export default {
// 加载更多通讯录
loadMoreMail() {
if (this.hasMore && !this.mailLoading) {
console.log('loadMoreMail')
this.pagination.page++
this.loadMailList()
}else{
console.log('没有更多数据了')
}
},
......@@ -398,10 +395,9 @@ export default {
<style scoped lang="scss">
.mail-list-container {
width: 100%;
background: #fff;
height: 100%;
display: flex;
flex-direction: column;
}
// 搜索头部
......
......@@ -3,7 +3,7 @@
<div
class="userDetailsPanel columnFlex"
>
<div class="content">
<div class="content" v-loading="viewLoading">
<div v-if="chatUserDetails.is_phishing_account==1" class="warnText">
<p>高风险玩家,请立即通知组长!!!!</p>
<p>①千万不能推转游!!不要发送违禁词汇!!不要发送礼包和告知任何礼包信息!!</p>
......@@ -266,7 +266,8 @@ import { getToken,removeToken } from '@/utils/auth'
...mapState('game', [
'accountSelect',
'gameUserInfo',
'bindGameUserList'
'bindGameUserList',
'viewLoading'
]),
...mapState('user', ['cser_info', 'cser_id', 'cser_name', 'corp_id', 'external_userid', 'userid', 'client_online_status']),
// 客服状态文本
......
......@@ -80,7 +80,6 @@ export default {
::v-deep .el-tabs__content {
height: calc(100% - 55px);
overflow-y: auto;
}
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论