web-base-admin/src/views/framework/recommend/tjjg3.vue

710 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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

<template>
<div class="page">
<topBar
v-if="topList.length > 0"
:top-list="topList"
:moren="moren"
/>
<div class="thetopbox">
<el-form ref="form" :model="queryParams" label-width="100px">
<el-row>
<el-col :span="4">
<el-form-item :label="'会员编号'" prop="memberCode">
<el-input
v-model="queryParams.memberCode"
clearable
/></el-form-item></el-col>
<el-col :span="4">
<el-form-item :label="'结算期数'" prop="memberSettlePeriodId">
<el-select
v-model="queryParams.memberSettlePeriodId"
clearable
:placeholder="'请选择'"
>
<el-option
v-for="item in memberSettlePeriodList"
:key="item.pkId"
:label="item.settleDate"
:value="item.pkId"
/> </el-select></el-form-item></el-col>
<el-col :span="4">
<el-form-item :label="'展示层数'" prop="level">
<el-input
v-model="queryParams.level"
clearable
/></el-form-item></el-col>
<el-col :span="4">
<el-form-item :label="'是否固定'" prop="cantz">
<el-select v-model="cantz" clearable :placeholder="'请选择'">
<el-option
v-for="(item, index) in tzList"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select> </el-form-item></el-col>
<el-col :span="4" style="margin-left: 30px">
<div class="searchbox">
<el-button class="searchbtn" @click="getSearch"> {{ '搜索' }}</el-button>
<el-button @click="reChongzhi"> {{ '重置' }}</el-button>
<el-button @click="goback"> {{ '返回' }}</el-button>
</div>
</el-col>
</el-row></el-form>
</div>
<div class="theorgtree">
<div class="tree">
<div class="tree-content" @mousedown.stop="move" @wheel="handleWheel">
<div :style="{ transform: `scale(${scale})` }">
<vue2-org-tree
ref="orgTree"
:data="data"
collapsable
:render-content="renderContent"
v-bind="$listeners"
@on-expand="onExpand"
@on-node-click="NodeClick"
@on-node-mouseover="onMouseover"
@on-node-mouseout="onMouseout"
/>
</div>
</div>
</div>
</div>
<el-dialog
:visible.sync="ifShow"
:close-on-click-modal="false"
width="516px"
>
<div class="rendercontent">
<div ref="htmlContent">
<div class="toprender">
<div class="leftimg">
<img
class="img1"
:src="'data:image/png;base64,' + treeData.avatarUrlBase64"
>
<img
class="img2"
:src="'data:image/png;base64,' + treeData.countryUrl2Base64"
>
</div>
<div class="centerbox">
<div class="lineboex">
<div class="linetitle">{{ '会员编号' }}</div>
<div class="linecontent">{{ treeData.memberCode }}</div>
</div>
<div class="lineboex">
<div class="linetitle">{{ '会员姓名' }}</div>
<div class="linecontent">{{ treeData.name }}</div>
</div>
<div class="lineboex">
<div class="linetitle">{{ '直推代数' }}</div>
<div class="linecontent">{{ treeData.level }}</div>
</div>
<div class="lineboex">
<div class="linetitle">{{ '支付日期' }}</div>
<div class="linecontent">{{ treeData.payDate }}</div>
</div>
</div>
<div class="rightimg">
<img
:src="
'data:image/png;base64,' + treeData.settleCountryUrl2Base64
"
>
<div>{{ '结算国家' }}</div>
</div>
</div>
<div class="bottomrender">
<div class="flexbox">
<div class="thetitle">{{ '类型' }}</div>
<div class="linecontent">人数</div>
<div class="linecontent">{{ '业绩' }}({{ isLocals() }})</div>
</div>
<div class="flexbox">
<div class="thetitle">直推</div>
<div class="linecontent">{{ data.directPushNumber }}</div>
<div class="linecontent">{{ data.newPerformancePv }}</div>
</div>
<div class="flexbox">
<div class="thetitle">{{ '团队' }}</div>
<div class="linecontent">{{ data.teamNumber }}</div>
<div class="linecontent">{{ data.teamHistoryPerformancePv }}</div>
</div>
</div>
</div>
<div class="footerbox">
<div class="footerbtn btn1" @click="downloadImage">下载图片</div>
<div class="footerbtn btn2" @click="copyText">复制文字</div>
<!-- <div class="footerbtn btn3" @click="goTop(treeData)">置顶</div> -->
</div>
</div>
</el-dialog>
<div v-show="false" ref="copyContent" class="copyContent">
<div>{{ '会员编号' }}{{ treeData.memberCode }}</div>
<div>{{ '会员姓名' }}{{ treeData.name }}</div>
<div>{{ '直推代数' }}{{ treeData.level }}</div>
<div>{{ '支付日期' }}{{ treeData.payDate }}</div>
<div>{{ '类型' }}&nbsp;&nbsp;直推&nbsp;&nbsp;团队</div>
<div>
人数&nbsp;&nbsp;{{ treeData.directPushNumber }}&nbsp;&nbsp;{{
treeData.directPushNumber
}}
</div>
<div>
{{ '业绩' }}({{ isLocals() }})&nbsp;&nbsp;{{ treeData.teamNumber }}&nbsp;&nbsp;{{
treeData.teamHistoryPerformancePv
}}
</div>
</div>
</div>
</template>
<script>
import html2canvas from 'html2canvas'
import topBar from '@/components/topBar'
import {
getTjFramework,
getMemberSettlePeriod,
getUrlBase
} from '@/api/archityecture'
import { isLocals } from '../../../utils/numberToCurrency'
export default {
name: 'Tjjg3',
components: {
topBar
},
data() {
return {
moren: 'tjjg3',
topList: [
{
name: '方案一',
path: 'tjjg'
},
{
name: '方案二',
path: 'tjjg2'
},
{
name: '方案三',
path: 'tjjg3'
},
{
name: '方案四',
path: 'tjjg4'
}
],
queryParams: {
memberSettlePeriodId: '', // 期数
memberCode: '', // 会员编号
level: '' // 代数
},
basicSwitch: false,
basicInfo: { id: null, label: null },
data: {},
treeData: {},
ifShow: false,
memberSettlePeriodList: [],
tzList: [
{ value: 0, label: '是' },
{ value: 1, label: '否' }
],
cantz: 1, // 0不可拖拽,1可拖拽
scale: 1
}
},
created() {
this.getSearch()
this.getAvarerInfo()
},
methods: {
handleWheel(event) {
if (this.cantz == 1) {
event.preventDefault()
const delta = Math.sign(event.deltaY)
const newScale = this.scale - delta * 0.1
this.scale = Math.max(0.01, Math.min(newScale, 10))
}
},
// 拖拽移动
move(e) {
if (this.cantz == 0) {
return
}
const odiv = e.currentTarget // 获取元素
// 算出鼠标相对元素的位置
const disX = e.clientX - odiv.offsetLeft
const disY = e.clientY - odiv.offsetTop
document.onmousemove = (e) => {
// 鼠标按下并移动的事件
// 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
const left = e.clientX - disX
const top = e.clientY - disY
// 绑定元素位置到positionX和positionY上面
this.positionX = top
this.positionY = left
// 移动当前元素
odiv.style.left = left + 'px'
odiv.style.top = top + 'px'
}
document.onmouseup = () => {
document.onmousemove = null
document.onmouseup = null
}
},
isLocals,
copyText() {
const copyContent = this.$refs.copyContent
const textLines = Array.from(copyContent.querySelectorAll('div')).map(
(div) => div.textContent.trim()
)
const text = textLines.join('\n')
const tempInput = document.createElement('textarea')
tempInput.value = text
document.body.appendChild(tempInput)
tempInput.select()
try {
document.execCommand('copy')
this.$message({
message: '复制成功',
type: 'success'
})
} catch (error) {
this.$message({
message: '复制失败',
type: 'warning'
})
}
tempInput.remove()
window.getSelection().removeAllRanges()
},
// 复制图片
async downloadImage() {
const element = this.$refs.htmlContent
// 使用html2canvas将节点生成为图片
const canvas = await html2canvas(element)
const image = canvas.toDataURL('image/png')
// 复制图片到剪贴板
try {
await navigator.clipboard.write([
new ClipboardItem({
'image/png': await new Promise((resolve) =>
canvas.toBlob(resolve, 'image/png')
)
})
])
this.$message({
message: '复制成功',
type: 'success'
})
} catch (error) {
// this.$message({
// message: "复制失败",
// type: "warning",
// });
}
// 下载图片到本地
const link = document.createElement('a')
link.href = image
link.download = 'image.png'
link.click()
},
getAvarerInfo() {
getMemberSettlePeriod().then((res) => {
const tempList = res.data || []
this.memberSettlePeriodList = tempList.filter(ele => ele.isThisDay === 1)
this.queryParams.memberSettlePeriodId = this.memberSettlePeriodList[0]?.pkId
})
},
// 返回
goback() {
this.queryParams.memberCode = this.data.parentMemberCode
this.getSearch()
},
// 鼠标移入
onMouseover(e, data) {
this.basicInfo = data
this.basicSwitch = true
},
// 鼠标移出
onMouseout(e, data) {
this.basicSwitch = false
},
// 渲染节点
renderContent(h, data) {
return (
<div class='xrBox'>
<div class='neibox' on-click={() => this.showPover(data)}>
<div class='topbox'>
<img src={data.avatarUrl}></img>
</div>
<div class='centerbox'>
<div class='cflexbox'>
<img src={data.countryUrl}></img>
<div class='matitle'>{data.memberCode}</div>
</div>
<div class='cflexbox'>
<img src={data.settleCountryUrl2}></img>
<div class='matitle'>{data.name}</div>
</div>
</div>
<div class='footerbox'>
{/* 阻止冒泡事件 */}
<div
class='ftopbtn'
on-click={() => {
event.stopPropagation(), this.goTop(data)
}}
>
{'置顶'}
</div>
</div>
</div>
</div>
)
},
showPover(row) {
getUrlBase({
countryUrl2: row.countryUrl2,
settleCountryUrl2: row.settleCountryUrl2,
avatarUrl: row.avatarUrl
}).then((res) => {
this.treeData = row
this.treeData.countryUrl2Base64 = res.countryUrl2Base64
this.treeData.settleCountryUrl2Base64 = res.settleCountryUrl2Base64
this.treeData.avatarUrlBase64 = res.avatarUrlBase64
this.ifShow = true
})
},
// 置顶
goTop(row) {
this.queryParams.memberCode = row.memberCode
this.getSearch()
},
// 点击节点
NodeClick(e, data) {},
// 默认展开
toggleExpand(data, val) {
if (Array.isArray(data)) {
data.forEach((item) => {
this.$set(item, 'expand', val)
if (item.children) {
this.toggleExpand(item.children, val)
}
})
} else {
this.$set(data, 'expand', val)
if (data.children) {
this.toggleExpand(data.children, val)
}
}
},
collapse(list) {
list.forEach((child) => {
if (child.expand) {
child.expand = false
}
child.children && this.collapse(child.children)
})
},
// 展开
onExpand(e, data) {
if ('expand' in data) {
data.expand = !data.expand
if (!data.expand && data.children) {
this.collapse(data.children)
}
} else {
this.$set(data, 'expand', true)
}
},
getSearch() {
getTjFramework(this.queryParams).then((res) => {
this.data = res.data[0]
this.toggleExpand(this.data, true)
})
},
reChongzhi() {
this.queryParams = {
memberSettlePeriodId: '', // 期数
memberCode: '', // 会员编号
level: '' // 代数
}
this.getSearch()
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-dialog__headerbtn{
top: 5px;
right: 10px;
border: 1px solid #c8c3c3;
padding: 2px 3px;
border-radius: 50%;
}
::v-deep .tree-content {
background: rgba(0, 0, 0, 0) !important;
}
.tree {
background: #fff;
// min-height: 100vh;
min-height: calc(100vh - 110px);
position: relative;
text-align: center;
// overflow-x: scroll;
width: 100%;
height: 100%;
margin: auto;
// overflow-y: hidden;
// margin-left: -60px;
// margin-top: 20px;
// background: red;
&-content {
text-align: center;
width: 100%;
height: 100%;
background: #fff;
position: absolute;
top: 0;
left: 0;
// overflow: auto;
}
}
::v-deep .org-tree-node-btn {
display: none;
}
::v-deep .org-tree-node-label-inner {
background: #ffffff;
box-shadow: 0px 2px 20px 0px rgba(204, 204, 204, 0.5);
border-radius: 38px;
}
::v-deep .xrBox {
.neibox {
padding: 10px 30px;
.topbox {
// width: 68px;
// height: 68px;
margin: 0 auto;
img {
width: 68px;
height: 68px;
border-radius: 50%;
}
}
.centerbox {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
text-align: center;
box-shadow: 0px 2px 20px 0px rgba(204, 204, 204, 0.5);
.cflexbox {
margin: 0 10px;
img {
width: 51px;
height: 34px;
border-radius: 8px;
margin-bottom: 8px;
}
.matitle {
font-size: 10px;
}
}
}
.footerbox {
margin-top: 20px;
.ftopbtn {
margin: 0 auto;
width: 68px;
height: 28px;
background: #21c8f4;
border-radius: 4px;
line-height: 28px;
font-size: 14px;
font-family: MicrosoftYaHei;
color: #ffffff;
cursor: pointer;
}
}
}
}
::v-deep .org-tree-node-label .org-tree-node-label-inner {
padding: 0;
}
::v-deep .el-dialog__body {
padding: 0;
}
::v-deep .org-tree-container {
display: block;
background: rgba(1, 1, 1, 0) !important;
overflow-x: auto;
}
::v-deep .rendercontent {
.toprender {
display: flex;
border-bottom: 1px solid #cccccc;
.leftimg {
flex: 1;
border-right: 1px solid #cccccc;
display: flex;
flex-direction: column;
align-items: center;
padding: 10px;
.img1 {
width: 75px;
height: 75px;
border-radius: 50%;
}
.img2 {
margin-top: 10px;
width: 50px;
height: 30px;
border-radius: 8px;
}
}
.centerbox {
padding: 10px;
.lineboex {
display: flex;
align-items: center;
margin: 10px 0;
.linetitle {
margin-right: 5px;
font-size: 10px;
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei;
font-weight: bold;
color: #333333;
}
.linecontent {
font-size: 10px;
font-family: MicrosoftYaHei;
color: #333333;
display: flex;
justify-content: center;
align-items: center;
padding: 10px 0;
width: 166px;
height: 20px;
background: rgba(216, 216, 216, 0.3);
border-radius: 4px;
border: 1px solid #cccccc;
}
}
}
.rightimg {
flex: 1;
justify-content: center;
align-items: center;
padding: 10px;
font-size: 10px;
display: flex;
flex-direction: column;
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei;
font-weight: bold;
color: #333333;
text-align: center;
img {
width: 75px;
height: 50px;
border-radius: 8px;
margin-bottom: 10px;
}
}
}
.bottomrender {
padding: 10px;
display: flex;
.flexbox {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
.thetitle {
font-size: 10px;
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei;
font-weight: bold;
color: #333333;
}
.linecontent {
margin-top: 5px;
padding: 10px 0;
font-size: 10px;
font-family: MicrosoftYaHei;
color: #333333;
display: flex;
justify-content: center;
align-items: center;
width: 110px;
height: 20px;
background: rgba(216, 216, 216, 0.3);
border-radius: 4px;
border: 1px solid #cccccc;
}
}
}
.footerbox {
display: flex;
padding: 10px;
justify-content: space-around;
.footerbtn {
width: 78px;
height: 28px;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-family: MicrosoftYaHei;
color: #ffffff;
padding: 10px;
cursor: pointer;
}
.btn1 {
background: #ee1e26;
}
.btn2 {
background: #f37825;
}
.btn3 {
background: #21c8f4;
}
}
}
.page {
padding: 20px;
background: #f9f9f9;
font-size: 14px;
.thetopbox {
padding: 20px;
background: #ffffff;
border-radius: 8px;
.searchbox {
display: flex;
align-items: center;
.searchtitle {
margin-right: 10px;
}
.searchbtn {
background: #c8161d;
color: #ffffff;
}
}
}
.theorgtree {
overflow: auto;
margin-top: 20px;
}
}
</style>