web-base-admin/src/views/framework/architecture/azjg5.vue

653 lines
16 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">
<TopMemberSelect ref="topMemberSelect" @change="TopMemberHandleChange" />
</el-col>
<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-number
v-model="queryParams.level"
style="width: 100%"
clearable
:min="1"
:max="10"
:step="1"
:controls="false"
/></el-form-item></el-col>
<el-col :span="4" style="margin-left: 30px">
<div class="searchbox">
<el-button
:loading="loading"
class="searchbtn"
@click="getSearch"
> {{ '搜索' }}</el-button>
<el-button @click="resetHandle"> {{ '重置' }}</el-button>
<el-button @click="goback"> {{ '返回' }}</el-button>
</div>
</el-col>
</el-row></el-form>
</div>
<div class="theorgtree">
<div class="lefttop">
<div v-for="(item, index) in rangeList" :key="index" class="single">
<div class="colorbox" :style="{background: item.color}" />
<div class="singletitle">{{ item.gradeName }}</div>
</div>
</div>
<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>
</div>
</template>
<script>
import html2canvas from 'html2canvas'
import topBar from '@/components/topBar'
import {
getAzFramework5,
getAvarerInfo,
getMemberSettlePeriod,
getUrlBase
} from '@/api/archityecture'
import { isLocals } from '../../../utils/numberToCurrency'
import TopMemberSelect from '@/components/top-member-select/index.vue'
import tabBarMixin from './mixins/tab-bar'
import { getgradeRanglist } from '@/api/level'
export default {
name: 'Azjg5',
components: {
topBar,
TopMemberSelect
},
mixins: [tabBarMixin],
data() {
return {
moren: 'azjg5',
queryParams: {
memberSettlePeriodId: '', // 期数
memberCode: '', // 会员编号
level: 6
},
basicSwitch: false,
basicInfo: { id: null, label: null },
data: [],
treeData: {},
ifShow: false,
memberSettlePeriodList: [], // 期数
rangeList: [], // 等级列表
cantz: 1, // 0不可拖拽,1可拖拽
scale: 1,
loading: false
}
},
created() {
// this.getSearch()
this.getRangeList()
this.getAvarerInfo()
},
methods: {
getBorderColor(grade) {
const color = this.rangeList.find((item) => item.gradeName === grade)?.color
return color || '#e0e0e0'
},
getRangeList() {
getgradeRanglist().then((res) => {
this.rangeList = res.data || []
})
},
TopMemberHandleChange(val) {
if (val) {
this.queryParams.memberCode = val
this.getSearch()
}
},
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))
}
},
isLocals,
// 返回
goback() {
this.queryParams.memberCode = this.data.parentMemberCode
this.getSearch()
},
// 拖拽移动
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
}
},
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
})
},
// 鼠标移入
onMouseover(e, data) {
this.basicInfo = data
this.basicSwitch = true
},
// 鼠标移出
onMouseout(e, data) {
this.basicSwitch = false
},
// 渲染节点
renderContent(h, data) {
if (!data || Object.keys(data).length === 0) {
return
}
// 获取边框和阴影颜色
const borderColor = this.getBorderColor(data.gradeName)
// 阴影色转rgba透明度0.25直接在boxShadow中拼接不再声明shadowColor
return (
<div
class='xrBox'
style={{
border: `4px solid ${borderColor}`,
borderRadius: '12px',
boxShadow: `0 4px 18px 0 ${borderColor}40, 0 0 0 4px #fff`, // 增加白色外发光提升对比度
padding: '0',
background: '#fff',
transition: 'box-shadow 0.3s, border-color 0.3s'
}}
>
{/* 判断data.codeName是否为空 */}
<div class='neibox'>
{data.memberCode ? (
<div
on-contextmenu={() => this.rightClick(this.$event, data)}
>
<div class='topbox'>
<div>{data.name}</div>
<div>{data.memberCode}</div>
<div>{data.awardsName}</div>
<div>{data.placeDept}部门</div>
{/* <div>会员姓名:{data.name}</div>
<div>会员编号:{data.memberCode}</div> */}
</div>
</div>
) : null}
</div>
</div>
)
},
// 置顶
goTop(row) {
this.queryParams.memberCode = row.memberCode
this.getSearch()
},
rightClick(e, data) {
event.preventDefault()
this.queryParams.memberCode = data.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() {
this.loading = true
getAzFramework5(this.queryParams).then((res) => {
this.data = res.data[0]
this.toggleExpand(this.data, true)
}).finally(() => {
this.loading = false
})
},
resetHandle() {
this.$refs.topMemberSelect.reset()
this.queryParams = {
memberSettlePeriodId: '', // 期数
memberCode: '', // 会员编号
level: 5,
type: 2
}
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 {
padding: 0;
background: rgba(0, 0, 0, 0);
padding: 0 !important;
border: none;
border-radius: 10px;
}
::v-deep .el-dialog__body {
padding: 0;
}
::v-deep .org-tree-container {
display: block;
background: rgba(1, 1, 1, 0) !important;
}
::v-deep .xrBox {
.neibox {
padding: 8px 15px;
margin: auto;
min-width: 50px;
min-height: 50px;
// z-index: 99;
.topbox {
margin: 0 auto;
text-align: left;
//min-width: 150px;
}
.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: 10px;
margin-bottom: 8px;
}
.matitle {
font-size: 10px;
}
}
}
.footerbox {
// margin-top: 10px;
.ftopbtn {
margin: 0 auto;
// width: 35px;
// height: 16px;
background: #21c8f4;
border-radius: 4px;
display: flex;
padding: 4px 9px;
align-items: center;
justify-content: center;
color: #ffffff;
cursor: pointer;
margin-top: 10px;
}
}
}
}
.lefttop {
display: flex;
align-items: center;
padding: 10px 0 10px 20px;
background: #fff;
border-radius: 8px;
margin-bottom: 10px;
}
.single {
display: flex;
flex-direction: column;
align-items: center;
margin-right: 16px;
}
.colorbox {
width: 24px;
height: 24px;
border-radius: 6px;
border: 1px solid #e0e0e0;
box-shadow: 0 2px 6px rgba(0,0,0,0.06);
margin-bottom: 4px;
}
.singletitle {
font-size: 12px;
color: #333;
margin-top: 2px;
}
::v-deep .org-tree-node-label .org-tree-node-label-inner {
padding: 0;
}
::v-deep .el-dialog__body {
padding: 0;
}
// ::v-deep .xrBox {
// }
::v-deep .rendercontent {
.toprender {
display: flex;
border-bottom: 1px solid #cccccc;
.leftimg {
border-right: 1px solid #cccccc;
flex: 1;
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: 10px;
}
}
.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;
padding: 10px;
font-size: 10px;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
font-family: MicrosoftYaHei-Bold, MicrosoftYaHei;
font-weight: bold;
color: #333333;
text-align: center;
img {
width: 75px;
height: 50px;
border-radius: 10px;
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: 10px 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;
}
}
::v-deep .org-tree {
margin: 0 auto;
}
</style>