feat(arch): 阶段架构方案一功能实现

This commit is contained in:
woody 2025-09-23 16:26:35 +08:00
parent 4b26ae1ab7
commit 01586fb27d
7 changed files with 857 additions and 754 deletions

View File

@ -1,21 +1,60 @@
<template>
<view class="table pr" :style="'zoom:' + size + ';'">
<view class="v-tr" style="display: flex;">
<view class="v-td" :class="{
colspan: Array.isArray(treeData.children) ? treeData.children.length * 2 : 1,
parentLevel: Array.isArray(treeData.children) && treeData.children.length,
extend: Array.isArray(treeData.children) && treeData.children.length && treeData.extend
}">
<view class="v-tr" style="display: flex">
<view
class="v-td"
:class="{
colspan: Array.isArray(treeData.children)
? treeData.children.length * 2
: 1,
parentLevel:
Array.isArray(treeData.children) && treeData.children.length,
extend:
Array.isArray(treeData.children) &&
treeData.children.length &&
treeData.extend,
}"
>
<view :class="{ node: true }">
<view class="person" :class="Array.isArray(treeData.class) ? treeData.class : []">
<image @click.stop="clickNode(treeData)" class="person-ava" :src="treeData.avatarUrl" mode=""></image>
<view
class="person"
:class="Array.isArray(treeData.class) ? treeData.class : []"
>
<view class="frame-text">
<view style="font-weight: bold">{{
treeData.nodeCode === '0-root' ? '' : treeData.nodeCode
}}</view>
<view v-if="treeData.memberCode && treeData.memberName">
<view> {{ treeData.memberCode }}</view>
<view>{{ treeData.memberName }}</view>
</view>
<view v-else> 空点位 </view>
</view>
</view>
</view>
</view>
<view class="v-tr" v-if="Array.isArray(treeData.children) && treeData.children.length && treeData.extend">
<view v-for="(children, index) in treeData.children" :key="index" colspan="2" class="childLevel v-td">
<TreeChart :json="children" :left="0" :top="0" @click-node="clickNode" />
</view>
<view
class="v-tr"
v-if="
Array.isArray(treeData.children) &&
treeData.children.length &&
treeData.extend
"
>
<view
v-for="(children, index) in treeData.children"
:key="index"
colspan="2"
class="childLevel v-td"
>
<TreeChart
:json="children"
:left="0"
:top="0"
@click-node="clickNode"
@click-top="clickTop"
/>
</view>
</view>
</view>
@ -27,38 +66,42 @@
props: ['json', 'size'],
data() {
return {
treeData: {}
};
treeData: {},
}
},
watch: {
json: {
handler: function (Props) {
let extendKey = function (jsonData) {
jsonData.extend = jsonData.extend === void 0 ? true : !!jsonData.extend;
jsonData.extend =
jsonData.extend === void 0 ? true : !!jsonData.extend
if (Array.isArray(jsonData.children)) {
jsonData.children.forEach(c => {
extendKey(c);
});
extendKey(c)
})
}
return jsonData
}
return jsonData;
};
if (Props) {
this.treeData = extendKey(Props);
this.treeData = extendKey(Props)
}
},
immediate: true
}
immediate: true,
},
},
methods: {
toggleExtend: function (treeData) {
treeData.extend = !treeData.extend;
this.$forceUpdate();
treeData.extend = !treeData.extend
this.$forceUpdate()
},
clickNode(e) {
this.$emit('click-node', e)
},
clickTop(e) {
this.$emit('click-top', e)
},
},
}
}
};
</script>
<style scoped>
@ -69,7 +112,7 @@
.pv-btn {
width: 200rpx;
height: 50rpx;
background-color: #b2821e;
background: #007bff;
color: #fff;
font-size: 20rpx;
line-height: 50rpx;
@ -78,11 +121,20 @@
margin: auto;
margin-top: 12rpx;
margin-bottom: 12rpx;
border-radius: 8rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 123, 255, 0.2);
transition: all 0.3s ease;
}
.pv-btn:hover {
background: #0056b3;
transform: translateY(-1rpx);
box-shadow: 0 4rpx 12rpx rgba(0, 123, 255, 0.3);
}
.next-btn {
border-radius: 50%;
background: none;
background: #6c757d;
width: 40rpx;
height: 40rpx;
margin: auto;
@ -90,27 +142,35 @@
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
.next-btn:hover {
background: #495057;
transform: scale(1.05);
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.15);
}
.table {
border-collapse: separate !important;
border-spacing: 0 !important;
width: 100%;
/* background: #f8f9fa; */
padding: 40rpx 0;
}
.v-tr {
display: inline-flex;
justify-content: center;
align-items: flex-start;
/* width: 100%; */
width: 100%;
}
.v-td {
position: relative;
vertical-align: top;
padding: 0 0 100rpx 0;
padding: 0 0 130rpx 0;
text-align: center;
}
@ -123,6 +183,7 @@
padding: 10rpx;
transform: translate3d(-30rpx, 0, 0);
cursor: pointer;
transition: all 0.3s ease;
}
.extend_handle:before {
@ -132,27 +193,32 @@
height: 100%;
box-sizing: border-box;
border: 4rpx solid;
border-color: #f2f2f2 #f2f2f2 transparent transparent;
border-color: #6c757d #6c757d transparent transparent;
transform: rotateZ(135deg);
transform-origin: 50% 50% 0;
transition: transform ease 300ms;
transition: all 0.3s ease;
}
.extend_handle:hover:before {
border-color: #f2f2f2 #f2f2f2 transparent transparent;
border-color: #495057 #495057 transparent transparent;
transform: rotateZ(135deg) scale(1.1);
}
.extend .extend_handle:before {
transform: rotateZ(-45deg);
}
.extend .extend_handle:hover:before {
transform: rotateZ(-45deg) scale(1.1);
}
.extend::after {
content: '';
position: absolute;
left: 50%;
bottom: 84rpx;
height: 84rpx;
border-left: 4rpx solid #f2f2f2;
border-left: 4rpx solid #dee2e6;
transform: translate3d(-2rpx, 0, 0);
}
@ -162,7 +228,7 @@
left: 50%;
bottom: 100%;
height: 84rpx;
border-left: 4rpx solid #f2f2f2;
border-left: 4rpx solid #dee2e6;
transform: translate3d(-2rpx, 0, 0);
}
@ -172,7 +238,7 @@
left: 0;
right: 0;
top: -88rpx;
border-top: 4rpx solid #f2f2f2;
border-top: 4rpx solid #dee2e6;
}
.childLevel:first-child:before,
@ -184,8 +250,8 @@
left: 50%;
height: 84rpx;
border: 4rpx solid;
border-color: #f2f2f2 transparent transparent #f2f2f2;
border-radius: 6rpx 0 0 0;
border-color: #dee2e6 transparent transparent #dee2e6;
border-radius: 8rpx 0 0 0;
transform: translate3d(2rpx, 0, 0);
}
@ -193,15 +259,15 @@
right: 50%;
height: 84rpx;
border: 4rpx solid;
border-color: #f2f2f2 #f2f2f2 transparent transparent;
border-radius: 0 6rpx 0 0;
border-color: #dee2e6 #dee2e6 transparent transparent;
border-radius: 0 8rpx 0 0;
transform: translate3d(-2rpx, 0, 0);
}
.childLevel:first-child.childLevel:last-child::after {
left: auto;
border-radius: 0;
border-color: transparent #f2f2f2 transparent transparent;
border-color: transparent #dee2e6 transparent transparent;
transform: translate3d(2rpx, 0, 0);
}
@ -217,13 +283,54 @@
position: relative;
display: inline-block;
z-index: 2;
width: 104rpx;
height: 104rpx;
width: fit-content;
padding: 20rpx;
background: #ffffff;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
border-radius: 16rpx;
border: 2rpx solid #e9ecef;
transition: all 0.3s ease;
cursor: pointer;
}
.node .person:hover {
transform: translateY(-4rpx);
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.15);
border-color: #6c757d;
}
.node .person:active {
transform: translateY(-2rpx);
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}
.node .person .person-ava {
width: 104rpx;
height: 104rpx;
width: 88rpx;
height: 53rpx;
border-radius: 15rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}
.frame-text {
border-radius: 8rpx;
font-size: 22rpx;
margin: 0 auto;
color: #495057;
font-weight: 500;
line-height: 1.4;
}
.frame-text view:first-child {
font-weight: 600;
font-size: 24rpx;
margin-bottom: 4rpx;
color: #212529;
}
.frame-text view:not(:first-child) {
font-size: 20rpx;
color: #6c757d;
margin-bottom: 2rpx;
}
.node .person .avat {
@ -232,15 +339,16 @@
height: 4em;
margin: auto;
overflow: hidden;
background: #fff;
border: 4px solid #f2f2f2;
background: #f8f9fa;
border: 4px solid #e9ecef;
box-sizing: border-box;
border-radius: 0.5em;
border-radius: 1em;
}
.node .person .avat img {
width: 100%;
height: 100%;
border-radius: inherit;
}
.node .person .name {
@ -248,10 +356,11 @@
margin: auto;
overflow: hidden;
box-sizing: border-box;
overflow: hidden;
font-size: 20rpx;
line-height: 1.5;
padding-top: 24rpx;
color: #495057;
font-weight: 500;
}
.node .person .name-bottom {
@ -260,18 +369,16 @@
overflow: hidden;
border-top: none;
box-sizing: border-box;
overflow: hidden;
color: #6c757d;
}
.node .person .operation {}
.node.hasMate::after {
content: '';
position: absolute;
left: 2em;
right: 2em;
top: 2em;
border-top: 4px solid #f2f2f2;
border-top: 4px solid #dee2e6;
z-index: 1;
}

View File

@ -1,17 +1,25 @@
const http = uni.$u.http
//架构上方会员等级图标
export const getAvarerInfo = (params) => http.get('/member/api/member-structure/get-avatar-info', {params})
export const getAvarerInfo = params =>
http.get('/member/api/member-structure/get-avatar-info', { params })
//结算期数下拉选
export const getMemberSettlePeriod = (params) => http.get('/member/api/member-structure/get-member-settle-period', {params})
export const getMemberSettlePeriod = params =>
http.get('/member/api/member-structure/get-member-settle-period', { params })
//安置架构
export const getAzFramework = (params) => http.get('/member/api/member-structure/az-framework', {params})
export const getAzFramework = params =>
http.get('/member/api/member-structure/three-framework', { params })
// 查询会员子节点
export const getChildList = params =>
http.get('/member/api/member-structure/childList', { params })
//推荐架构
export const getTjFramework = (params) => http.get('/member/api/member-structure/tj-framework', {params})
export const getTjFramework = params =>
http.get('/member/api/member-structure/tj-framework', { params })
//转换为base64格式用于图片下载
export const getUrlBase = (data) => http.post('/member/manage/member-structure/get-url-base64', data)
export const getUrlBase = data =>
http.post('/member/manage/member-structure/get-url-base64', data)

View File

@ -20,7 +20,7 @@ module.exports = vm => {
//#ifdef DEV_SERVER
console.log('DEV_SERVER')
config.baseURL = 'http://192.168.0.86:8080'
config.baseURL = 'https://t-zk.beida666.com/prod-api'
//#endif
//#ifdef QA_SERVER

View File

@ -739,7 +739,7 @@
{
"path": "pages/architecture/resettleArchite/resettle1",
"style": {
"navigationBarTitleText": "安置方案一",
"navigationBarTitleText": "方案一",
"enablePullDownRefresh": false
}
},

View File

@ -1,89 +1,100 @@
<template>
<view class="content">
<view class="theflex">
<view @click="goRouter(item.path)" class="kuaibox" v-for="(item,index) in kuaiList"
:key="index">
<view
@click="goRouter(item.path)"
class="kuaibox"
v-for="(item, index) in menus"
:key="index"
>
<view class="">
{{ item.name }}
</view>
<image class="kuaiimg" :src="item.url" mode=""></image>
</view>
</view>
</view>
</template>
<script>
import * as mar from "@/config/market.js"
import * as mar from '@/config/market.js'
export default {
data() {
return {
kuaiList: [{
name:'安置方案一',
url: "../../static/images/my_icon14.png",
path: "/pages/architecture/resettleArchite/resettle1",
value: "marketDynamics",
menus: [
{
name: '方案一',
url: '../../static/images/my_icon14.png',
path: '/pages/architecture/resettleArchite/resettle1',
value: 'marketDynamics',
isShow: false,
}, {
name: '安置方案二',
url: "../../static/images/my_icon14.png",
path: "/pages/architecture/resettleArchite/resettle2",
value: 'incomeDetail',
isShow: false,
}, {
name: '安置方案三',
url: "../../static/images/my_icon14.png",
path: "/pages/architecture/resettleArchite/resettle3",
value: 'bonusSource',
isShow: false,
}, {
name: '安置方案四',
url: "../../static/images/my_icon14.png",
path: "/pages/architecture/resettleArchite/resettle4",
isShow: false,
value: 'appraisal',
}, {
name: '推荐方案一',
url: "../../static/images/my_icon14.png",
path: "/pages/architecture/recommendArchite/recommend1",
isShow: false,
value: 'registration',
}, {
name: '推荐方案二',
url: "../../static/images/my_icon14.png",
path: "/pages/architecture/recommendArchite/recommend2",
isShow: false,
// value: 'investment',
}, {
name: '推荐方案三',
url: "../../static/images/my_icon14.png",
path: "/pages/architecture/recommendArchite/recommend3",
isShow: false,
value: 'activeZone',
}, {
name: '推荐方案四',
url: "../../static/images/my_icon14.png",
path: "/pages/architecture/recommendArchite/recommend4",
isShow: false,
value: 'activeZone',
}]
},
// {
// name: '',
// url: '../../static/images/my_icon14.png',
// path: '/pages/architecture/resettleArchite/resettle2',
// value: 'incomeDetail',
// isShow: false,
// },
// {
// name: '',
// url: '../../static/images/my_icon14.png',
// path: '/pages/architecture/resettleArchite/resettle3',
// value: 'bonusSource',
// isShow: false,
// },
// {
// name: '',
// url: '../../static/images/my_icon14.png',
// path: '/pages/architecture/resettleArchite/resettle4',
// isShow: false,
// value: 'appraisal',
// },
// {
// name: '',
// url: '../../static/images/my_icon14.png',
// path: '/pages/architecture/recommendArchite/recommend1',
// isShow: false,
// value: 'registration',
// },
// {
// name: '',
// url: '../../static/images/my_icon14.png',
// path: '/pages/architecture/recommendArchite/recommend2',
// isShow: false,
// // value: 'investment',
// },
// {
// name: '',
// url: '../../static/images/my_icon14.png',
// path: '/pages/architecture/recommendArchite/recommend3',
// isShow: false,
// value: 'activeZone',
// },
// {
// name: '',
// url: '../../static/images/my_icon14.png',
// path: '/pages/architecture/recommendArchite/recommend4',
// isShow: false,
// value: 'activeZone',
// },
],
}
},
methods: {
goRouter(path) {
uni.navigateTo({
url: path
url: path,
})
},
}
},
}
</script>
<style lang="scss" scoped>
.content {
background-color: #F2F2F2;
background-color: #f2f2f2;
height: 100vh;
padding: 4rpx 21rpx 500rpx 21rpx;
@ -102,7 +113,7 @@
justify-content: space-between;
padding: 60rpx 40rpx 60rpx 22rpx;
margin: 13rpx 0rpx;
background-color: #FFFFFF;
background-color: #ffffff;
font-size: 24rpx;
font-family: Source Han Sans CN;
font-weight: 400;

View File

@ -1,42 +1,27 @@
<template>
<view>
<view class="seach">
<view class="neibox"> 会员编号 </view>
<view class="neibox"> 子点位 </view>
<view class="seach_i">
<u--input class="these" v-model="queryParams.memberCode">
<template slot="suffix">
<view class="seatch_r">
<u-icon
@click="getDataList"
name="search"
size="22"
color="#fff"
></u-icon>
<view class="inputbox" @click="childNodeListVisible = true">
<view class="">
{{ selectedChildNodeName ? selectedChildNodeName : '请选择子点位' }}
</view>
<u-icon name="arrow-right" size="24rpx" color="#005bac"></u-icon>
</view>
</template>
</u--input>
</view>
<view class="neibox" @click="popShow = true"> 筛选 </view>
</view>
<view class="mainbox">
<view class="main_top">
<view
class="top_flex"
v-for="(item, index) in avaerInfoList"
:key="index"
>
<img class="theimg" :src="item.value" alt="" />
<view class="fle2">{{ item.name }}</view>
</view>
</view>
<view class="main_bottom">
<view
class="scoll_main"
ref="scrollMain"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchstart.prevent="handleTouchStart"
@touchmove.prevent="handleTouchMove"
@touchend="handleTouchEnd"
@dblclick="handleDoubleClick"
:style="containerStyle"
>
<TreeChart
:size="size"
@ -66,29 +51,27 @@
<view class="top_red" @click="popShow = false">{{ '返回' }}</view>
</view>
<view class="typesBox">
<view class="typeTitle" @click="listShow = true"> 结算期数 </view>
<view class="typeTitle" @click="stageListVisible = true"> 阶段 </view>
<view class="choiceBox">
<view class="inputbox" @click="listShow = true">
<view class="inputbox" @click="stageListVisible = true">
<view class="">
{{ settleName ? settleName : '请选择' }}
{{ stageName ? stageName : '请选择' }}
</view>
<u-icon name="arrow-right" size="24rpx" color="#090000"></u-icon>
</view>
</view>
</view>
<view class="typesBox">
<view class="typeTitle"> 代数 </view>
<view class="typeTitle" @click="statusListVisible = true">
状态
</view>
<view class="choiceBox">
<u--input
v-model="queryParams.level"
style="
background-color: rgba(176, 196, 222, 0.45);
border-color: rgba(176, 196, 222, 0.45) !important;
"
placeholder="请输入"
border="surround"
shape="circle"
></u--input>
<view class="inputbox" @click="statusListVisible = true">
<view class="">
{{ statusName ? statusName : '请选择' }}
</view>
<u-icon name="arrow-right" size="24rpx" color="#090000"></u-icon>
</view>
</view>
</view>
@ -98,7 +81,7 @@
class="bottom_btn thebtn2"
@click="
() => {
getDataList(), (popShow = false)
handleSearch(), (popShow = false)
}
"
>{{ '确定' }}
@ -106,128 +89,32 @@
</view>
</view>
<u-picker
@cancel="listShow = false"
:show="listShow"
@cancel="stageListVisible = false"
:show="stageListVisible"
ref="uPicker"
:columns="memberSettlePeriodList"
@confirm="confirm"
keyName="settleDate"
:columns="stageList"
@confirm="stagePickerHandleConfirm"
keyName="label"
></u-picker>
<u-picker
@cancel="statusListVisible = false"
:show="statusListVisible"
ref="uPicker"
:columns="statusList"
@confirm="statusPickerHandleConfirm"
keyName="label"
></u-picker>
</u-popup>
<u-popup
:show="isPop"
closeable
mode="center"
round="10"
@close="isPop = false"
>
<view class="ispop_box">
<view class="Poster1">
<view class="pop_top">
<view class="pop_top">
<view>
<image
crossorigin="anonymous"
data-etype="image"
:data-enode="popMould.avatarUrl"
:src="'data:image/png;base64,' + popMould.avatarUrlBase64"
mode="aspectFit"
class="poster1"
></image>
</view>
<view>
<image
crossorigin="anonymous"
data-etype="image"
:data-enode="popMould.countryUrl2"
:src="'data:image/png;base64,' + popMould.countryUrl2Base64"
mode="aspectFit"
class="poster2"
></image>
</view>
</view>
<view class="top_right">
<image
crossorigin="anonymous"
data-etype="image"
:data-enode="popMould.settleCountryUrl2"
:src="
'data:image/png;base64,' + popMould.settleCountryUrl2Base64
"
mode="aspectFit"
class="poster2"
></image>
<view style="margin-top: 18rpx"> 结算国家 </view>
</view>
</view>
<view class="pop_center">
<view class="center_flex">
<view class="c1">会员编号</view>
<view class="c2">{{ popMould.memberCode }}</view>
</view>
<view class="center_flex">
<view class="c1">会员姓名</view>
<view class="c2">{{ popMould.name }}</view>
</view>
<view class="center_flex">
<view class="c1">支付时间</view>
<view class="c2">{{ popMould.payDate }}</view>
</view>
</view>
<view class="pop_bottom">
<view class="b_flex">
<view class="bt1">业绩</view>
<view class="bt1">左区</view>
<view class="bt1">右区</view>
</view>
<view class="b_flex">
<view class="bt2">真实新增</view>
<view class="bt2">{{ popMould.leftRealNewPv }}</view>
<view class="bt2">{{ popMould.rightRealNewPv }}</view>
</view>
<view class="b_flex">
<view class="bt2">首购新增</view>
<view class="bt2">{{ popMould.leftFirstPurchaseAdd }}</view>
<view class="bt2">{{ popMould.rightFirstPurchaseAdd }}</view>
</view>
<view class="b_flex">
<view class="bt2">复购新增</view>
<view class="bt2">{{ popMould.leftRepeatPurchaseSurplus }}</view>
<view class="bt2">{{ popMould.rightRepeatPurchaseSurplus }}</view>
</view>
<view class="b_flex">
<view class="bt2">真实累计</view>
<view class="bt2">{{ popMould.leftRealTotal }}</view>
<view class="bt2">{{ popMould.rightRealTotal }}</view>
</view>
<view class="b_flex">
<view class="bt2">首购累计</view>
<view class="bt2">{{ popMould.leftFirstTotal }}</view>
<view class="bt2">{{ popMould.rightFirstTotal }}</view>
</view>
<view class="b_flex">
<view class="bt2">复购累计</view>
<view class="bt2">{{ popMould.leftRepeatPurchaseTotal }}</view>
<view class="bt2">{{ popMould.rightRepeatPurchaseTotal }}</view>
</view>
<view class="b_flex">
<view class="bt2">首购结余</view>
<view class="bt2">{{ popMould.leftFirstSurplus }}</view>
<view class="bt2">{{ popMould.rightFirstSurplus }}</view>
</view>
<view class="b_flex">
<view class="bt2">复购结余</view>
<view class="bt2">{{ popMould.leftRepeatPurchaseSurplus }}</view>
<view class="bt2">{{ popMould.rightRepeatPurchaseSurplus }}</view>
</view>
</view>
</view>
<view class="btn_box">
<view class="small-btn" @click="downImage('Poster1')">下载图片</view>
<view class="small-text-btn" @click="copyText()">复制文字</view>
</view>
</view>
</u-popup>
<!-- 子点位选择picker -->
<u-picker
@cancel="childNodeListVisible = false"
:show="childNodeListVisible"
ref="childNodePicker"
:columns="childNodeColumns"
@confirm="childNodePickerHandleConfirm"
keyName="childNode"
></u-picker>
<Eposter
width="750"
height="1334"
@ -253,20 +140,36 @@ export default {
},
data() {
return {
avaerInfoList: [],
childNodeList: [],
childNodeColumns: [[]],
childNodeListVisible: false,
selectedChildNodeName: '',
treeData: [],
queryParams: {
memberSettlePeriodId: '', //
memberCode: '', //
level: 6, //
type: 1,
childNode: '',
stage: 1,
status: 0,
},
memberSettlePeriodList: [], //
stageList: [
[
{ value: 1, label: '阶段一' },
{ value: 2, label: '阶段二' },
{ value: 3, label: '阶段三' },
],
], //
statusList: [
[
{ value: 0, label: '已完成' },
{ value: 1, label: '未完成' },
],
], //
popShow: false,
listShow: false,
settleName: '',
stageListVisible: false,
statusListVisible: false,
stageName: '',
statusName: '',
data: {},
size: 0.3,
size: 0.5,
landscape: [],
popMould: {},
isPop: false,
@ -279,14 +182,53 @@ export default {
y: 0,
},
initialDistance: 0,
initialSize: 0.4, //
minSize: 0.2, //
maxSize: 3.0, //
isZooming: false, //
isDragging: false, //
dragStartPosition: { x: 0, y: 0 }, //
containerTransform: { x: 0, y: 0 }, //
lastTouchTime: 0, //
lastTouchPosition: { x: 0, y: 0 }, //
velocity: { x: 0, y: 0 }, //
maxTransform: { x: 1000, y: 1000 }, //
list: [],
}
},
onLoad() {
this.getAvarerInfo()
this.init()
this.getChildList().then(() => {
this.getDataList()
})
},
mounted() {
//
this.$nextTick(() => {
console.log('组件已挂载')
})
},
computed: {
containerStyle() {
return {
transform: `translate(${this.containerTransform.x}px, ${this.containerTransform.y}px) scale(${this.size})`,
transformOrigin: 'center center',
transition:
this.isDragging || this.isZooming
? 'none'
: 'transform 0.1s ease-out',
}
},
},
methods: {
init() {
this.stageName = this.stageList[0][0].label
this.statusName = this.statusList[0][0].label
this.queryParams.stage = this.stageList[0][0].value
this.queryParams.status = this.statusList[0][0].value
},
//
copyText() {
let self = this
@ -346,75 +288,210 @@ export default {
},
handleTouchStart(event) {
console.log('handleTouchStart triggered', event.touches.length)
const touch1 = event.touches[0]
const touch2 = event.touches[1]
const currentTime = Date.now()
if (touch2) {
// -
this.isZooming = true
this.isDragging = false
this.initialSize = this.size
this.touchStartPosition1 = {
x: touch1.pageX,
y: touch1.pageY,
x: touch1.clientX,
y: touch1.clientY,
}
this.touchStartPosition2 = {
x: touch2.pageX,
y: touch2.pageY,
x: touch2.clientX,
y: touch2.clientY,
}
this.initialDistance = Math.hypot(
touch2.pageX - touch1.pageX,
touch2.pageY - touch1.pageY
touch2.clientX - touch1.clientX,
touch2.clientY - touch1.clientY
)
} else {
// -
this.isZooming = false
this.isDragging = true
this.dragStartPosition = {
x: touch1.clientX,
y: touch1.clientY,
}
this.lastTouchTime = currentTime
}
},
handleTouchMove(event) {
const touch1 = event.touches[0]
const touch2 = event.touches[1]
if (touch2) {
if (touch2 && this.isZooming && this.initialDistance > 0) {
//
const currentDistance = Math.hypot(
touch2.pageX - touch1.pageX,
touch2.pageY - touch1.pageY
touch2.clientX - touch1.clientX,
touch2.clientY - touch1.clientY
)
const scale = currentDistance / this.initialDistance
this.size = this.size * scale
let newSize = this.initialSize * scale
//
newSize = Math.max(this.minSize, Math.min(this.maxSize, newSize))
//
const sizeDiff = newSize - this.size
this.size = this.size + sizeDiff * 0.3
} else if (!touch2 && this.isDragging) {
//
const deltaX = touch1.clientX - this.dragStartPosition.x
const deltaY = touch1.clientY - this.dragStartPosition.y
console.log('拖动中', {
deltaX,
deltaY,
touch: { x: touch1.clientX, y: touch1.clientY },
dragStart: this.dragStartPosition,
containerTransform: this.containerTransform,
})
//
this.velocity.x = deltaX * 0.1
this.velocity.y = deltaY * 0.1
//
let newX = this.containerTransform.x + deltaX * 0.8
let newY = this.containerTransform.y + deltaY * 0.8
//
const scaledMaxX = this.maxTransform.x * this.size
const scaledMaxY = this.maxTransform.y * this.size
newX = Math.max(-scaledMaxX, Math.min(scaledMaxX, newX))
newY = Math.max(-scaledMaxY, Math.min(scaledMaxY, newY))
this.containerTransform.x = newX
this.containerTransform.y = newY
//
this.dragStartPosition.x = touch1.clientX
this.dragStartPosition.y = touch1.clientY
// DOM
this.updateContainerTransform()
}
},
handleTouchEnd() {
this.touchStartPosition1 = {
x: 0,
y: 0,
}
this.touchStartPosition2 = {
x: 0,
y: 0,
handleTouchEnd(event) {
const currentTime = Date.now()
const touchDuration = currentTime - this.lastTouchTime
//
if (
this.isDragging &&
(Math.abs(this.velocity.x) > 1 || Math.abs(this.velocity.y) > 1)
) {
this.startInertiaScroll()
}
//
this.isZooming = false
this.isDragging = false
this.touchStartPosition1 = { x: 0, y: 0 }
this.touchStartPosition2 = { x: 0, y: 0 }
this.initialDistance = 0
this.initialSize = this.size
this.dragStartPosition = { x: 0, y: 0 }
},
clickNode(e) {
let self = this
if (e) {
arc
.getUrlBase({
countryUrl2: e.countryUrl2,
settleCountryUrl2: e.settleCountryUrl2,
avatarUrl: e.avatarUrl,
})
.then(res => {
self.popMould = e
self.popMould.countryUrl2Base64 = res.countryUrl2Base64
self.popMould.settleCountryUrl2Base64 = res.settleCountryUrl2Base64
self.popMould.avatarUrlBase64 = res.avatarUrlBase64
self.isPop = true
})
//
startInertiaScroll() {
const friction = 0.95 //
const minVelocity = 0.1 //
const animateInertia = () => {
//
let newX = this.containerTransform.x + this.velocity.x
let newY = this.containerTransform.y + this.velocity.y
//
const scaledMaxX = this.maxTransform.x * this.size
const scaledMaxY = this.maxTransform.y * this.size
newX = Math.max(-scaledMaxX, Math.min(scaledMaxX, newX))
newY = Math.max(-scaledMaxY, Math.min(scaledMaxY, newY))
this.containerTransform.x = newX
this.containerTransform.y = newY
//
this.velocity.x *= friction
this.velocity.y *= friction
// DOM
this.updateContainerTransform()
//
if (
Math.abs(this.velocity.x) > minVelocity ||
Math.abs(this.velocity.y) > minVelocity
) {
requestAnimationFrame(animateInertia)
}
}
requestAnimationFrame(animateInertia)
},
confirm(e) {
this.queryParams.memberSettlePeriodId = e.value[0].pkId
this.settleName = e.value[0].settleDate
this.listShow = false
// - 使
updateContainerTransform() {
// 使DOM
console.log('容器变换更新', this.containerTransform, this.size)
},
getAvarerInfo() {
arc.getAvarerInfo().then(res => {
this.avaerInfoList = res.data
//
resetZoom() {
this.size = 0.4
this.initialSize = 0.4
this.containerTransform = { x: 0, y: 0 }
this.updateContainerTransform()
},
//
handleDoubleClick() {
this.resetZoom()
},
clickNode(e) {
return
},
stagePickerHandleConfirm(e) {
this.queryParams.memberSettlePeriodId = e.value[0].value
this.stageName = e.value[0].label
this.stageListVisible = false
},
statusPickerHandleConfirm(e) {
this.queryParams.status = e.value[0].value
this.statusName = e.value[0].label
this.statusListVisible = false
},
childNodePickerHandleConfirm(e) {
this.queryParams.memberCode = e.value[0].childNode
this.selectedChildNodeName = e.value[0].childNode
this.childNodeListVisible = false
//
this.getDataList()
},
getChildList() {
return new Promise((resolve, reject) => {
arc.getChildList(this.queryParams).then(res => {
if (res.code === 200) {
this.childNodeList = res.data
// picker
this.childNodeColumns = [res.data]
this.queryParams.childNode = res.data[0].childNode
this.selectedChildNodeName = res.data[0].childNode
resolve()
}
})
arc.getMemberSettlePeriod().then(res => {
this.memberSettlePeriodList = [res.data]
})
},
getDataList() {
@ -422,15 +499,20 @@ export default {
this.data = res.data[0]
})
},
handleSearch() {
this.getChildList().then(() => {
this.getDataList()
})
},
clearAll() {
this.popShow = false
this.settleName = ''
this.init()
this.queryParams = {
memberSettlePeriodId: '', //
memberCode: '', //
level: '', //
stage: this.stageList[0][0].value,
status: this.statusList[0][0].value,
}
this.getDataList()
this.handleSearch()
},
},
}
@ -701,6 +783,22 @@ export default {
flex: 1;
background: #f5f6f8;
margin: 0 20rpx;
.inputbox {
font-size: 26rpx;
width: 100%;
padding: 15rpx 20rpx;
border-radius: 34rpx;
background-color: #f5f6f8;
display: flex;
justify-content: space-between;
align-items: center;
color: #333333;
&:active {
background-color: #e8e9eb;
}
}
}
.neibox {
@ -721,40 +819,11 @@ export default {
.mainbox {
padding: 26rpx 22rpx;
.main_top {
background: #ffffff;
border-radius: 20rpx;
padding: 20rpx 4rpx;
display: flex;
flex-wrap: wrap;
.top_flex {
display: flex;
flex-direction: column;
align-items: center;
margin: 15rpx 20rpx;
// justify-content: center;
width: 98rpx;
.theimg {
width: 92rpx;
height: 92rpx;
border-radius: 50%;
}
.flex2 {
font-size: 26rpx;
font-family: Source Han Sans CN;
font-weight: 400;
color: #666666;
}
}
}
height: 100%;
.main_bottom {
width: 100%;
height: calc(100vh - 600rpx);
height: 100%;
margin-top: 25rpx;
background-color: #ffffff;
padding: 38rpx 0;
@ -764,11 +833,13 @@ export default {
.scoll_main {
width: 700rpx;
height: calc(100vh - 600rpx);
overflow: auto;
// overflow: scroll;
// overflow-x: auto;
transform-origin: center center; //
cursor: grab; //
&:active {
cursor: grabbing; //
}
}
}
</style>

View File

@ -88,49 +88,6 @@
</view>
</view>
<!-- 收益区域 -->
<view class="my_order" v-if="regionInfoVisible">
<view class="my_title">
<text class="thetitle">收益区域</text>
</view>
<template
v-if="
regionInfo.provinceVal || regionInfo.cityVal || regionInfo.countyVal
"
>
<view class="region-info-box">
<view class="region-info-item">
<text class="region-info-label">{{ '省' }}</text>
<text class="region-info-value">{{
regionInfo.provinceVal || '-'
}}</text>
</view>
<view class="region-info-item">
<text class="region-info-label">{{ '市' }}</text>
<text class="region-info-value">{{
regionInfo.cityVal || '-'
}}</text>
</view>
<view class="region-info-item">
<text class="region-info-label">{{ '区' }}</text>
<text class="region-info-value">{{
regionInfo.countyVal || '-'
}}</text>
</view>
</view>
</template>
<template v-else>
<view class="region-select-action">
<u-button
@click="openRegionSelect"
color="#005BAC"
shape="circle"
text="选择区域"
></u-button>
</view>
</template>
</view>
<view class="my_order">
<view class="order_flex">
<template v-for="(item, index) in otherMenuList">
@ -144,47 +101,9 @@
<view class="order_text">{{ item.name }}</view>
</view>
</template>
<!-- <view
class="theorderflex1"
@click="goTo('/pages/mine/feedBack/feedBack')"
>
<image class="order_img" src="../../static/images/my_icon12.png" />
<view class="order_text">{{ '意见反馈' }}</view>
</view> -->
<!-- <picker
:range="getLanguageList"
:value="index"
range-key="label"
@change="bindPickerChange"
>
<view class="theorderflex1" @click="goTo('')">
<image class="order_img" src="../../static/images/mark6.png" />
<view class="order_text">{{ '多语言切换' }}</view>
</view>
</picker> -->
<!-- <view
class="theorderflex1"
@click="goTo('/pages/mine/branchAddress/branchAddress')"
>
<image class="order_img" src="../../static/images/my_icon9.png" />
<view class="order_text"
>{{ '分公司' }}{{ '地址' }}</view
>
</view> -->
<!-- <view class="theorderflex1" @click="goYear">
<image class='order_img' src="../../static/images/my_icon12.png" />
<view class="order_text">{{ '年度奖衔' }}</view>
</view> -->
<!-- <view class="theorderflex1" @click="goTo('')">
<image class='order_img' src="../../static/images/my_icon12.png" />
<view class="order_text">关于我们</view>
</view> -->
</view>
</view>
<!-- 会员中心 -->
<view class="btnbox">
<u-button
shape="circle"
@ -220,12 +139,6 @@
</u-button>
</view>
</u-popup>
<!-- <RegionSelect
v-if="isNormal"
ref="regionSelect"
@success="getRegionSelect"
/> -->
<!-- <talentList :drShow="drShow" @closeShow="closeShow"></talentList> -->
</view>
</template>
@ -286,13 +199,6 @@ export default {
menuKey: 'selfHelp',
ifshow: true,
},
// {
// url: '/pages/mine/share/index',
// name: '广',
// imgurl: '../../static/images/list.svg',
// menuKey: 'share',
// ifshow: false,
// },
{
url: '/pages/userSecure/index',
name: '账号安全',
@ -321,13 +227,13 @@ export default {
menuKey: 'bankInfo',
ifshow: true,
},
// {
// url: '/pages/mine/addNewPv/index',
// name: '',
// imgurl: '../../static/images/mark9.png',
// menuKey: 'iNewAchievement',
// ifshow: false,
// },
{
url: '/pages/architecture/architecture',
name: '架构管理',
imgurl: '../../static/images/my_icon14.png',
menuKey: 'recommend',
ifshow: false,
},
],
drShow: false,
actMenu: false,