实现select的复选、全选、清空、搜索等功能
<template>
<a-spin :spinning="loading" tip="请求中...">
<div class="workCurve">
<x-card>
<div slot="content" class="table-page-search-wrapper">
<a-form layout="inline">
<span class="search-form-left" style="width:100%">
<a-row :gutter="0">
<a-col :md="4" :sm="24">
<a-form-item label="">
<a-radio-group v-model="type" style="width:230px" @change="typeChange">
<a-radio value="0">
投产日期
</a-radio>
<a-radio value="1">
措施日期
</a-radio>
</a-radio-group>
</a-form-item>
</a-col>
<a-col :md="4" :sm="12" style="margin-left:20px">
<a-form-item label="拉齐数据">
<a-select
:maxTagCount="1"
mode="multiple"
style="width: 100%;min-width:240px"
placeholder="请选择拉齐数据"
v-model="lqData"
>
<a-select-option v-for="(item, index) in lqOptions" :key="index" :value="item.value">{{
item.name
}}</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md="4" :sm="24">
<a-form-item label="向前拉齐点数">
<a-input-number
:disabled="type === '0'"
v-model="beforeCount"
:precision="0"
style="width: 100%;"
/>
</a-form-item>
</a-col>
<a-col :md="4" :sm="24">
<a-form-item label="向前每段天数">
<a-input-number :disabled="type === '0'" v-model="spanLenth" :precision="0" style="width: 100%;" />
</a-form-item>
</a-col>
<a-col :md="4" :sm="24">
<a-form-item label="向后拉齐点数">
<a-input-number v-model="afterCount" :precision="0" style="width: 100%;" />
</a-form-item>
</a-col>
<a-col :md="4" :sm="24">
<a-form-item label="向后每段天数">
<a-input-number v-model="afterDaily" :precision="0" style="width: 100%;" />
</a-form-item>
</a-col>
<a-col :md="4" :sm="24">
<a-form-item>
<a-button type="primary" @click="handleQuery"
><img style="width:12px;margin-right:4px" src="@/assets/search-icon.png" alt="" />查询</a-button
>
</a-form-item>
</a-col>
<span class="table-page-search-submitButtons button-group-right">
<a-button type="primary" @click="visible = true">查看数据表</a-button>
</span>
</a-row>
</span>
</a-form>
</div>
</x-card>
<div>
<a-row :gutter="[5, 5]" type="flex">
<a-col :span="4" flex="240px">
<QkTree
ref="qkTree"
:type="'well'"
:disabledJh="type === '0' ? true : false"
:multiple="false"
:treeStyle="'height:calc(100vh - 227px)'"
:checkable="false"
@selectedNode="selectedNodeHandle"
></QkTree>
</a-col>
<a-col :span="15" flex="calc(100% - 240px - 340px - 10px)" style="width:calc(100% - 240px - 340px - 10px)">
<a-card class="charts-contaniner">
<div class="charts-box">
<curve-chart ref="curveChart"></curve-chart>
</div>
</a-card>
</a-col>
<a-col :span="5" flex="340px">
<a-card class="charts-contaniner">
<div style="height: calc(100vh - 395px);overflow: auto;">
<a-tree-select
v-if="false"
v-model="rightJh"
:maxTagCount="1"
@change="rightJhChange"
:dropdownStyle="{ maxHeight: '300px', overflow: 'auto' }"
style="width:100%;margin-bottom:10px"
:tree-data="rightTreeData"
tree-checkable
allowClear
:treeDefaultExpandAll="true"
:replaceFields="{ children: 'children', title: 'jh', key: 'jh', value: 'jh' }"
placeholder="请输入井号前缀并选择"
>
</a-tree-select>
<a-select
style="width:100%;margin-bottom:10px"
class="select"
mode="multiple"
v-model="rightJh"
:maxTagCount="1"
placeholder="请输入井号前缀并选择"
@change="rightJhChange"
>
<div slot="dropdownRender" slot-scope="menu">
<div style="padding:4px; cursor: pointer;" @mousedown="e => e.preventDefault()">
<!-- 全选、重置 -->
{{ checkAllLoading }}
<a-button
class="btn"
type="primary"
style="margin-right:10px"
@click="checkAllField"
:loading="checkAllLoading"
>
全选
</a-button>
<a-button class="btn" @click="resetRightJh">重置</a-button>
</div>
<a-divider style="margin: 4px 0;" />
<VNodes :vnodes="menu" />
</div>
<a-select-option v-for="item in dataImport" :key="item.jh" :value="item.jh">
{{ item.jh }}
</a-select-option>
</a-select>
<!-- :show-checked-strategy="SHOW_PARENT" -->
<a-table
:loading="loadingImport"
:scroll="{ y: 'calc(100vh - 495px)' }"
:rowSelection="{
selectedRowKeys: selectedRowKeys,
onChange: onSelectChange,
fixed: true,
columnWidth: 50
}"
:columns="columnsImport"
:data-source="rightTableData"
bordered
size="small"
:pagination="false"
:rowKey="(record, index) => record.jh"
>
<span slot="rqStr" slot-scope="text, record">
<a-input
:placeholder="''"
@change="e => handleChange(e, record.rqStr, 'rqStr')"
v-model="record.rqStr"
>
</a-input>
</span>
</a-table>
</div>
<div style="width: 100%;text-align: center;">
<a-button style="margin-top: 15px;" type="primary" @click="handleDownload">模板下载</a-button><br />
<a-upload
name="file"
:before-upload="beforeUpload"
:customRequest="handleUpload"
accept=".xls,.xlsx"
:showUploadList="false"
>
<a-button type="primary" style="margin-top: 15px;"> <a-icon type="import" />导入 </a-button>
</a-upload>
<br />
<a-button style="margin-top: 15px;" type="primary" @click="handleClear">清空</a-button>
</div>
</a-card>
</a-col>
</a-row>
</div>
<a-modal
:footer="null"
v-model="visible"
:width="1200"
title="拉齐对比数据"
:destroyOnClose="true"
@cancel="cancelTableData"
@ok="setTableData"
>
<a-table :columns="columns" size="small" :data-source="data" bordered>
<div v-for="col in columns.map(it => it.dataIndex)" :key="col" :slot="col" slot-scope="text, record">
<div>
<a-input-number
:min="-999999"
:max="999999"
v-if="record.editable"
style="margin: -5px 0;width:100%"
:value="text"
@change="e => handleChange(e, record.key, col)"
/>
<template v-else>
{{ text }}
</template>
</div>
</div>
<template slot="operation" slot-scope="text, record">
<div class="editable-row-operations">
<span v-if="record.editable">
<a @click="() => save(record.key)">保存</a>
<a @click="() => cancel(record.key)" style="margin-left:15px">取消</a>
</span>
<span v-else>
<a :disabled="editingKey !== ''" @click="() => edit(record.key)">编辑</a>
</span>
</div>
</template>
</a-table>
</a-modal>
</div>
</a-spin>
</template>
<script>
import { XCard } from '@/components'
import { handleXlsRes } from '@/utils/exportXls.js'
import CurveChart from '../components/CurveChart.vue'
import QkTree from '@/components/QkTree/index.vue'
import _ from 'lodash'
import {
curveApi,
importApi,
getTcrqJhListApi,
getImportTemplateApi
} from '@/api/modular/main/prodIndicator/compair.js'
export default {
components: {
XCard,
QkTree,
CurveChart,
VNodes: {
functional: true,
render: (h, ctx) => ctx.props.vnodes
}
},
data() {
return {
checkAllLoading: false,
selectedRowKeys: [],
selectedRows: [],
lqOptions: [
// 总井数、开井数、日产液量、日产油量、含水、动液面、阶段累计产液、阶段累计产油
{ name: '总井数', value: 'zjs' },
{ name: '开井数', value: 'kjs' },
{ name: '日产液量', value: 'rcyel' },
{ name: '日产油量', value: 'rcyl' },
{ name: '含水', value: 'hsb' },
{ name: '动液面', value: 'dym' },
{ name: '阶段累计产液', value: 'ljcyel' },
{ name: '阶段累计产油', value: 'ljcyl' }
],
lqData: ['zjs', 'kjs', 'rcyel', 'rcyl', 'hsb', 'dym', 'ljcyel', 'ljcyl'],
loading: false,
mode: ['month', 'month'],
month: [],
queryParam: {},
columns: [
{
title: '阶段号',
dataIndex: 'stage',
scopedSlots: { customRender: 'stage' }
},
{
title: '总井数',
dataIndex: 'zjs',
scopedSlots: { customRender: 'zjs' }
},
{
title: '开井数',
dataIndex: 'kjs',
scopedSlots: { customRender: 'kjs' }
},
{
title: '日产液量',
dataIndex: 'rcyel',
scopedSlots: { customRender: 'rcyel' }
},
{
title: '日产油量',
dataIndex: 'rcyl',
scopedSlots: { customRender: 'rcyl' }
},
{
title: '动液面(m)',
dataIndex: 'dym',
scopedSlots: { customRender: 'dym' }
},
{
title: '含水(%)',
dataIndex: 'hsb',
scopedSlots: { customRender: 'hsb' }
},
{
title: '阶段累计产液',
dataIndex: 'ljcyel',
scopedSlots: { customRender: 'ljcyel' }
},
{
title: '阶段累计产油',
dataIndex: 'ljcyl',
scopedSlots: { customRender: 'ljcyl' }
}
],
wellOptions: [],
visible: false,
editingKey: '',
data: [],
cacheData: [],
renderData: {
xdata: [],
data: []
},
chartsYName: [
'总井\n数(口)',
'开井\n数(口)',
'日产\n液(t)',
'日产\n油(t)',
'含水\n(%)',
'动液\n面(m)',
'阶段累计产液',
'阶段累计产油'
], //'开井\n数(口)',
chartsName: [
{
name: '总井数',
index: 0,
color: '#4b5cc4',
type: 'line',
key: 'zjs'
},
{
name: '开井数',
index: 1,
color: '#0c8918',
type: 'line',
key: 'kjs'
},
{
name: '日产液',
index: 2,
color: '#ff2aff',
type: 'line',
key: 'rcyel'
},
{
name: '日产油',
index: 3,
color: 'red',
type: 'line',
key: 'rcyl'
},
{
name: '含水',
index: 4,
color: '#6fff6f',
type: 'line',
key: 'hsb'
},
{
name: '动液面',
index: 5,
color: '#ffe16b',
type: 'line',
key: 'dym'
},
{
name: '阶段累计产液',
index: 6,
color: '#f05654',
type: 'line',
key: 'ljcyel'
},
{
name: '阶段累计产油',
index: 7,
color: '#c9dd22',
type: 'line',
key: 'ljcyl'
}
],
miningStatusData: {},
devHistory: '',
maxmonth: 100,
tabPosition: 'jzzjg',
sliderValue: [0, 0],
btnLabel: '锁定间隔',
isLock: false,
intervalDate: 0,
monthDate: [],
columnsImport: [
{
title: '井号',
dataIndex: 'jh',
align: 'center'
},
{
title: '日期',
dataIndex: 'rqStr',
align: 'center',
width: 140,
scopedSlots: { customRender: 'rqStr' }
}
],
tcJhList: [],
rightJh: [],
rightTableData: [],
dataImport: [],
spanLenth: 1,
beforeCount: 1,
afterCount: 1,
afterDaily: 1,
type: '0',
loadingImport: false,
selectedQk: {},
selectedCw: {}
}
},
computed: {
jhList() {
if (this.selectedQk.title && this.selectedQk.qkdm) {
if (this.type === '1') {
this.loadingImport = true
//措施日期,jh取值为左侧树;投产日期,井号list数据为接口返回
let jhArr = _.map(this.selectedQk.children, 'jh')
let tableData = []
jhArr.filter(item => {
if (!!item) {
tableData.push({ jh: item })
}
return !!item
})
this.loadingImport = false
return tableData
}
} else {
if (this.type === '1') {
this.$message.warning('请选择区块')
}
}
return []
},
queryData() {
return {
beforeCount: this.beforeCount,
beforeDaily: this.beforeDaily,
afterCount: this.afterCount,
afterDaily: this.afterDaily,
wellList: this.selectedRows
}
},
selectedQkInfo() {
let arr = [this.selectedQk]
return {
zyqdm: arr && arr[0] ? arr[0].zyqdm : null,
qkdm: arr && arr[0] ? arr[0].qkdm : null,
cyddm: arr && arr[0] ? arr[0].cyddm : null
}
},
rightTreeData() {
let arr = []
if (this.dataImport?.length) {
arr = [{ jh: '全选', children: this.dataImport }]
}
return arr
}
},
methods: {
resetRightJh() {
this.rightJh = []
this.rightJhChange(this.rightJh)
},
checkAllField() {
this.checkAllLoading = true
let jhArr = []
this.dataImport.forEach(item => {
jhArr.push(item.jh)
})
this.rightJh = jhArr
this.rightJhChange(this.rightJh)
},
rightJhChange(val) {
console.log(this.checkAllLoading)
// console.log(22, val)
let arr = []
let arr2 = []
this.dataImport.forEach(iitem => {
let obj = val.find(valItem => {
return iitem.jh === valItem
})
if (!obj) {
arr.push(iitem)
} else {
arr2.push(iitem)
}
})
this.rightTableData = arr2.concat([])
this.defaultCheckedAll(arr2) //选中当前下拉井号
if (this.checkAllLoading) {
// setTimeout(() => {
// this.checkAllLoading = false
// }, 1000)
}
},
filterOption(input, option) {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
typeChange(val) {
this.dataImport = []
// 类型变更,表格选中项重置
this.selectedRowKeys = []
this.selectedRows = []
if (this.type === '0') {
this.beforeCount = null
this.beforeDaily = null
this.getTcJhList() //切换时,重新请求
} else {
this.beforeCount = 1
this.beforeDaily = 1
this.dataImport = this.jhList
this.rightTableData = []
this.defaultCheckedAll([])
}
// 重置选中数据
this.rightTableData = []
this.defaultCheckedAll([])
// 重置曲线
this.setCurveData([])
this.data = []
},
onSelectChange(selectedRowKeys, selectedRows) {
this.selectedRowKeys = selectedRowKeys
this.selectedRows = selectedRows
this.rightJh = this.selectedRowKeys //表格选择内容变更同步修改a-tree-select项
},
getTcJhList() {
if (!this.selectedQk.title) {
this.tcJhList = []
this.dataImport = []
this.defaultCheckedAll([])
return
}
// 获取投产日期下所有井号
let params = Object.assign({}, this.queryData, this.selectedQkInfo)
// 点击 作业区 和采油队时 提示用户点击 请选择区块。
if (!params.qkdm) {
this.$message.warning('请选择区块')
return
}
this.loadingImport = true
getTcrqJhListApi(params)
.then(res => {
this.loadingImport = false
if (res.data) {
this.tcJhList = res.data
this.rightJh = []
this.dataImport = this.tcJhList
this.rightTableData = []
this.defaultCheckedAll([])
} else {
this.$message.warning(res.message)
}
})
.catch(() => {
this.loadingImport = false
})
},
defaultCheckedAll(arr) {
let indArr = []
arr.forEach(item => {
indArr.push(item.jh)
})
// 默认选中全部
this.onSelectChange(indArr, arr)
},
selectedNodeHandle(value) {
this.selectedQk = value
if (this.type === '0') {
this.getTcJhList()
} else {
this.dataImport = this.jhList
this.rightTableData = []
this.defaultCheckedAll([])
}
},
// 用表格编辑后的数据重新绘制曲线
setTableData() {
this.visible = false
this.setCurveData(this.data)
},
cancelTableData() {
this.visible = false
this.cancel(this.editingKey)
},
handleChange(value, key, column) {
const newData = [...this.dataImport]
const target = newData.find(item => key === item.key)
if (target) {
target[column] = value
this.dataImport = newData
}
},
edit(key) {
const newData = [...this.data]
const target = newData.find(item => key === item.key)
this.editingKey = key
if (target) {
target.editable = true
this.data = newData
}
},
save(key) {
const newData = [...this.data]
const newCacheData = [...this.cacheData]
const target = newData.find(item => key === item.key)
const targetCache = newCacheData.find(item => key === item.key)
if (target && targetCache) {
delete target.editable
this.data = newData
Object.assign(targetCache, target)
this.cacheData = newCacheData
}
this.editingKey = ''
},
cancel(key) {
const newData = [...this.data]
const target = newData.find(item => key === item.key)
this.editingKey = ''
if (target) {
Object.assign(
target,
this.cacheData.find(item => key === item.key)
)
delete target.editable
this.data = newData
}
},
getCurveData() {
let params = Object.assign({}, this.queryData, {})
if (this.type === '0') {
params.beforeCount = null
params.beforeDaily = null
// 向前拉齐点数:禁用,并且不传参置为null
// 向前拉齐每段天数:禁用,并且不传参置为null
}
let _this = this
_this.loading = true
curveApi(params)
.then(res => {
if (res.code != 200) {
this.$message.warning(res.message)
_this.setCurveData([])
_this.data = []
return
}
if (res.success && res.data.length > 0) {
_this.data = res.data
for (var m = 0; m < _this.data.length; m++) {
_this.data[m]['key'] = m.toString()
}
_this.cacheData = _this.data.map(item => ({ ...item }))
_this.miningStatusData = res.data[0]
_this.setCurveData(res.data)
} else {
_this.setCurveData([])
_this.data = []
}
_this.loading = false
})
.finally(err => {
_this.loading = false
})
},
setCurveData(data) {
let chartsNameData = []
this.renderData = {
xdata: [],
data: [],
chartsYName: []
}
let showCurveData = this.lqData
let chartsNameShow = []
let chartsYNameShow = []
showCurveData.forEach((currentItem, index) => {
let obj = this.chartsName.find(item => {
return item.key === currentItem
})
if (obj) {
obj.index = index
let name = obj.name.length > 3 ? obj.name.slice(0, 3) + '\n' + obj.name.slice(3) : obj.name
chartsYNameShow.push(name)
chartsNameShow.push(obj)
}
})
chartsNameData = chartsNameShow
this.renderData.chartsYName = chartsYNameShow || this.chartsYName
for (var i = 0; i < data.length; i++) {
this.renderData.xdata.push('阶段' + data[i].stage)
}
for (var n = 0; n < chartsNameData.length; n++) {
let obj = {
name: chartsNameData[n].name,
index: chartsNameData[n].index,
color: chartsNameData[n].color,
type: chartsNameData[n].type,
data: []
}
for (var i = 0; i < data.length; i++) {
let key = chartsNameData[n].key
obj.data.push(data[i][key] ? data[i][key] - 0 : 0)
}
this.renderData.data.push(obj)
}
this.$refs.curveChart.setData(this.renderData)
},
handleQuery() {
if (!this.afterCount) {
return this.$message.warning('请输入向后拉齐点数')
}
if (!this.afterDaily) {
return this.$message.warning('请输入向后每段天数')
}
if (!this.selectedRows.length) {
return this.$message.warning('井号不能为空')
}
let flag = true
if (this.selectedRows) {
this.selectedRows.forEach(item => {
if (!item.rqStr) {
flag = false
}
})
}
if (!flag) {
this.$message.warning('所选井号日期不能为空')
return
}
this.getCurveData()
},
// 模板下载
handleDownload() {
getImportTemplateApi().then(res => {
// handleXlsRes(res)
const dataJson = res.data
const aLink = document.createElement('a')
const blob = new Blob([dataJson], { type: 'application/force-download; charset=UTF-8' })
aLink.href = URL.createObjectURL(blob)
aLink.setAttribute('download', '拉齐对比模板.xls') // 设置下载文件名称
aLink.click()
})
},
// 导入
beforeUpload(file) {
const extension = file.name.substring(file.name.lastIndexOf('.') + 1)
if (extension !== 'xlsx' && extension !== 'xls') {
this.$message.error('只能上传excel文件')
return false
}
const isLt10M = file.size / 1024 / 1024 < 10
if (!isLt10M) {
this.$message.error('大小不能超过10MB!')
return false
}
return extension && isLt10M
},
handleUpload(file) {
const _this = this
const formData = new FormData()
formData.append('file', file.file)
importApi(formData)
.then(response => {
if (Object.prototype.toString.call(response.data) === '[object Blob]') {
// 先判断是不是blob格式
if (response.data.type.includes('application/json')) {
// 判断是不是特殊情况(json)
const reader = new FileReader()
reader.onload = function() {
const res = reader.result
const result = JSON.parse(res) // blob格式转成json
if (result.code === 200) {
// 导出超出限制
_this.$message.success('导入成功')
_this.dataImport = result.data
_this.rightTableData = []
_this.defaultCheckedAll([])
} else {
_this.$message.error(result.message)
}
}
reader.readAsText(response.data)
} else {
// 导入格式错误
handleXlsRes(response)
}
}
})
.catch(e => {
// 接收异常 并提示
_this.$message.error(e.message)
})
},
handleClear() {
this.dataImport = []
this.rightTableData = []
this.defaultCheckedAll([])
}
},
created() {}
}
</script>
<style lang="less" scoped>
.charts-contaniner {
overflow: auto;
ul,
li {
margin: 0;
padding: 0;
list-style-type: none;
}
.charts-box {
width: 100%;
height: calc(100vh - 253px);
overflow: hidden;
}
}
.cardContent {
min-height: 200px;
p {
margin-bottom: 6px;
color: #1890ff;
}
}
.workCurve {
/deep/ .ant-card-body {
padding: 12px;
}
/deep/ .ant-form-item {
margin-bottom: 6px;
}
/deep/ .ant-modal-body {
padding: 12px;
}
}
.btnBoxRight {
padding-top: 12px;
text-align: right;
button {
margin: 0;
}
}
.bottomTabs {
background-color: #fff;
padding-top: 8px;
/deep/ .ant-radio-button-wrapper {
width: 50%;
text-align: center;
}
}
/deep/.ant-table-small > .ant-table-content > .ant-table-body {
margin: 0 !important;
}
</style>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。