Compare commits

...

3 Commits

Author SHA1 Message Date
huxuejian
dd32c29d7e Update team-detail.vue 2026-04-03 10:54:50 +08:00
huxuejian
e5047efff8 fix: 页面调整 2026-04-02 18:37:45 +08:00
huxuejian
f29dd85faf feat: 首页调整 团队详情调整 2026-04-02 18:09:06 +08:00
9 changed files with 819 additions and 77 deletions

11
App.vue
View File

@ -91,6 +91,10 @@ page {
display: inline-block; display: inline-block;
} }
.block {
display: block;
}
.flex { .flex {
display: flex; display: flex;
} }
@ -398,6 +402,13 @@ page {
overflow: hidden; overflow: hidden;
} }
.line-clamp-3 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
}
.h-full { .h-full {
height: 100%; height: 100%;
} }

View File

@ -0,0 +1,492 @@
<template>
<view class="zh-readMore">
<view class="zh-readMore-wrapper" :style="[textStyle]">
<view
class="zh-text"
:class="textClass"
:style="[textStyleObject, { '--unfold_packup_line': `${unfold_packup_line}px` }, { '--duration': `${duration}s` }]"
>
<view class="zh-open" :style="[unfoldTextStyle]" v-if="!showall && is_open" @click.stop="open">
<text class="zh-ellipsis">...</text>
<text class="zh-open-text">{{ unfoldText }}</text>
</view>
<text class="" :style="[lineBreakStyles]">
<text v-if="title" :style="[titleStyle]">{{ title }}</text>
{{ text }}
</text>
<text class="zh-fewer" v-if="is_open && showall" @click.stop="open">
<text class="zh-fewer-text" :style="[packupTextStyle]">{{ packupText }}</text>
</text>
</view>
</view>
<view class="zh-overflowcont" id="zh-overflowcont" :style="[textStyle, lineStyle]">
<text class="zh-overflowcont-text" :style="[lineBreakStyle]">
<text v-if="title" :style="[titleStyle]">{{ title }}</text>
{{ text }}
</text>
</view>
<view class="zh-overflowcont" id="zh-overflowcontline" :style="[textStyle]">
<text class="" :style="[lineBreakStyle]">{{ text }}</text>
</view>
<view class="zh-overflowcont">
<view class="" :style="[unfoldTextStyle]" id="zh-open">
<text class="zh-ellipsis">...</text>
<text class="zh-overflowcont-open">{{ unfoldText }}</text>
</view>
</view>
</view>
</template>
<!-- #ifdef VUE3 -->
<!-- vue3 -->
<script lang="ts" setup>
/*
* @param {text,String} 需要展示的文本
* @param {textStyle,Object} 需要展示的文本样式
* @param {rows,Number} 文本容器中超出多行后显示省略号
* @param {lineBreak,Boolean} 保留空白字符序列同时允许正常换行
* @param {packupLineBreak,Boolean} 只在收起时忽略空白字符展开时保留空白字符序列同时允许正常换行
* @param {unfoldText,String} 展开操作的文案
* @param {unfoldTextStyle,Object} 展开操作的样式
* @param {packupText,String} 收起操作的文案
* @param {packupTextStyle,Object} 收起操作的样式
* @param {duration,Number || String} 展示动画过度时间(单位s)
*/
import { computed, nextTick, ref, watch, getCurrentInstance } from 'vue'
const props = defineProps({
title: {
type: String,
default: () => '',
},
titleStyle: {
type: Object,
default: () => ({
'font-weight': '600',
'margin-right': '10rpx',
}),
},
text: {
type: String,
default: () => '',
},
textStyle: {
type: Object,
default: () => ({
color: '#000',
'font-size': '28rpx',
'font-weight': '400',
}),
},
rows: {
type: Number,
default: 3,
},
lineBreak: {
type: Boolean,
default: true,
},
packupLineBreak: {
type: Boolean,
default: false,
},
unfoldText: {
type: String,
default: () => '展开',
},
unfoldTextStyle: {
type: Object,
default: () => ({
color: '#206ef7',
'font-size': '28rpx',
'font-weight': '400',
}),
},
packupText: {
type: String,
default: () => '收起',
},
packupTextStyle: {
type: Object,
default: () => ({
color: '#206ef7',
'font-size': '28rpx',
'font-weight': '400',
}),
},
duration: {
type: [Number, String],
default: () => 0,
},
})
const box_h = ref(0) //
const showall = ref(false) //
const is_open = ref(false) ///
const unfold_packup_line = ref(22) //
const settime = ref(null) //
const instance = getCurrentInstance()
const selectQuery = uni.createSelectorQuery().in(instance.proxy)
//
const emit = defineEmits(['click'])
//
//
const open = () => {
showall.value = !showall.value
emit('click', showall.value) //true false
}
//
const textStyleObject = computed(() => {
const { rows } = props
return {
'max-height': showall.value ? `${1.5 * box_h.value}em` : `${1.5 * rows}em`,
}
})
const textClass = computed(() => {
return showall.value ? 'showall' : ''
})
const lineStyle = computed(() => {
const { rows } = props
return {
display: '-webkit-box',
'-webkit-box-orient': 'vertical',
'-webkit-line-clamp': rows,
overflow: 'hidden',
'word-break': 'break-all',
}
})
const lineBreakStyles = computed(() => {
const { lineBreak, packupLineBreak } = props
if (!lineBreak) {
return {
'white-space': 'normal',
}
} else {
if (packupLineBreak) {
return {
'white-space': showall.value ? 'pre-wrap' : 'normal',
}
} else {
return {
'white-space': 'pre-wrap',
}
}
}
})
const lineBreakStyle = computed(() => {
const { lineBreak } = props
return {
'white-space': lineBreak ? 'pre-wrap' : 'normal',
}
})
//
watch(
() => props.text,
(newValue, oldValue) => {
const { rows } = props
nextTick(() => {
clearTimeout(settime.value)
settime.value = setTimeout(() => {
selectQuery.select(`#zh-overflowcont`).boundingClientRect()
selectQuery.select('#zh-overflowcontline').boundingClientRect()
selectQuery.select('#zh-open').boundingClientRect()
selectQuery.exec(res => {
if (res && res[0] && res[1]) {
const h1 = res[0].height //
const h2 = res[1].height //
const lineCount = rows
const lineHeight = h1 / lineCount
//
const actualLines = Math.ceil(h2 / lineHeight)
// 0.1/
if (actualLines > lineCount || h2 > h1 + lineHeight * 0.1) {
is_open.value = true
} else {
is_open.value = false
}
box_h.value = Math.ceil(h2 / lineHeight) + 1
showall.value = false
}
if (res && res[2]) {
let unfold_packup_width = res[2].height - 1.5 || 22
unfold_packup_line.value = unfold_packup_width
}
})
}, 100)
})
},
{
deep: true,
immediate: true,
}
)
</script>
<!-- #endif -->
<!-- #ifdef VUE2 -->
<!-- vue2 -->
<script>
/*
* @param {text,String} 需要展示的文本
* @param {textStyle,Object} 需要展示的文本样式
* @param {rows,Number} 文本容器中超出多行后显示省略号
* @param {lineBreak,Boolean} 保留空白字符序列同时允许正常换行
* @param {packupLineBreak,Boolean} 只在收起时忽略空白字符展开时保留空白字符序列同时允许正常换行
* @param {unfoldText,String} 展开操作的文案
* @param {unfoldTextStyle,Object} 展开操作的样式
* @param {packupText,String} 收起操作的文案
* @param {packupTextStyle,Object} 收起操作的样式
* @param {duration,Number || String} 展示动画过度时间(单位s)
*/
export default {
name: 'zh-readMore',
props: {
title: {
type: String,
default: () => '',
},
titleStyle: {
type: Object,
default: () => ({
'font-weight': '600',
'margin-right': '10rpx',
}),
},
text: {
type: String,
default: () => '',
},
textStyle: {
type: Object,
default: () => ({
color: '#000',
'font-size': '28rpx',
'font-weight': '400',
}),
},
rows: {
type: Number,
default: 3,
},
lineBreak: {
type: Boolean,
default: true,
},
packupLineBreak: {
type: Boolean,
default: false,
},
unfoldText: {
type: String,
default: () => '展开',
},
unfoldTextStyle: {
type: Object,
default: () => ({
color: '#206ef7',
'font-size': '28rpx',
'font-weight': '400',
}),
},
packupText: {
type: String,
default: () => '收起',
},
packupTextStyle: {
type: Object,
default: () => ({
color: '#206ef7',
'font-size': '28rpx',
'font-weight': '400',
}),
},
duration: {
type: Number || String,
default: () => 0,
},
},
data() {
return {
box_h: 0, //
showall: false, //
is_open: false, ///
unfold_packup_line: 22, //
settime: null, //
}
},
methods: {
//
open() {
this.showall = !this.showall
this.$emit('click', this.showall) //true false
},
},
mounted() {},
computed: {
textStyleObject() {
return {
'max-height': this.showall ? `${1.5 * this.box_h}em` : `${1.5 * this.rows}em`,
}
},
textClass() {
return this.showall ? 'showall' : ''
},
lineStyle() {
return {
display: '-webkit-box',
'-webkit-box-orient': 'vertical',
'-webkit-line-clamp': this.rows,
overflow: 'hidden',
'word-break': 'break-all',
}
},
lineBreakStyles() {
if (!this.lineBreak) {
return {
'white-space': 'normal',
}
} else {
if (this.packupLineBreak) {
return {
'white-space': this.showall ? 'pre-wrap' : 'normal',
}
} else {
return {
'white-space': 'pre-wrap',
}
}
}
},
lineBreakStyle() {
return {
'white-space': this.lineBreak ? 'pre-wrap' : 'normal',
}
},
},
watch: {
text: {
handler(newValue, oldValue) {
this.$nextTick(() => {
clearTimeout(this.settime)
this.settime = setTimeout(() => {
const selectQuery = uni.createSelectorQuery().in(this)
selectQuery.select(`#zh-overflowcont`).boundingClientRect()
selectQuery.select('#zh-overflowcontline').boundingClientRect()
selectQuery.select('#zh-open').boundingClientRect()
selectQuery.exec(res => {
if (res && res[0] && res[1]) {
const h1 = res[0].height //
const h2 = res[1].height //
const lineCount = this.rows
const lineHeight = h1 / lineCount
//
const actualLines = Math.ceil(h2 / lineHeight)
// 0.1/
if (actualLines > lineCount || h2 > h1 + lineHeight * 0.1) {
this.is_open = true
} else {
this.is_open = false
}
this.box_h = Math.ceil(h2 / lineHeight) + 1
this.showall = false
}
if (res && res[2]) {
let unfold_packup_width = res[2].height - 1.5 || 22
this.unfold_packup_line = unfold_packup_width
}
})
}, 100)
})
},
deep: true,
immediate: true,
},
},
}
</script>
<!-- #endif -->
<style lang="scss">
.zh-readMore {
position: relative;
.zh-readMore-wrapper {
overflow: hidden;
display: flex;
.zh-text {
position: relative;
line-height: 1.5;
text-align: justify;
text-overflow: ellipsis;
word-break: break-all;
transition: var(--duration) max-height linear;
}
.zh-text::before {
float: right;
height: calc(100% - var(--unfold_packup_line));
content: '';
}
.zh-open {
position: relative;
float: right;
clear: both;
line-height: 1.5;
z-index: 2;
.zh-open-text {
margin-left: 6rpx;
}
}
.zh-fewer {
display: inline-block;
.zh-fewer-text {
margin-left: 6rpx;
}
}
}
}
.zh-ellipsis {
font-size: 30rpx;
color: #434343;
}
.zh-overflowcont {
position: absolute;
top: -10000px;
left: -10000px;
width: 100%;
line-height: 1.5;
text-align: justify;
text-overflow: ellipsis;
word-break: break-all;
.zh-overflowcont-text {
display: block;
}
.zh-overflowcont-open {
margin-left: 6rpx;
}
}
</style>

View File

@ -1,9 +1,10 @@
<template> <template>
<view class="consult-container"> <view class="consult-container">
<view class="consult-title">咨询互动</view> <view class="consult-title">团队服务</view>
<view class="consult-grid"> <view class="consult-grid">
<view class="consult-item" v-for="item in consultItems" :key="item.id" @click="handleItemClick(item)"> <view class="consult-item" v-for="item in consultItems" :class="hideMenus[item.id] ? 'consult-item--hiden' : ''"
:key="item.id" @click="handleItemClick(item)">
<view class="relative item-icon"> <view class="relative item-icon">
<image :src="item.icon" class="icon-img" mode="aspectFill" /> <image :src="item.icon" class="icon-img" mode="aspectFill" />
<view v-if="badgeMap[item.badge]" class="item-dot"></view> <view v-if="badgeMap[item.badge]" class="item-dot"></view>
@ -19,7 +20,7 @@
</template> </template>
<script setup> <script setup>
import { ref, watch } from "vue"; import { computed, ref, watch } from "vue";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import useAccount from "@/store/account"; import useAccount from "@/store/account";
import api from "@/utils/api"; import api from "@/utils/api";
@ -80,6 +81,13 @@ const consultItems = ref([
badge: 'rate' badge: 'rate'
}, },
]); ]);
const hideMenus = computed(() => {
const result = {};
if (!props.team || !props.team.creator) {
result.chat = true;
}
return result;
})
function handleItemClick(item) { function handleItemClick(item) {
// //
@ -227,6 +235,10 @@ defineExpose({
cursor: pointer; cursor: pointer;
} }
.consult-item--hiden {
display: none;
}
.item-icon { .item-icon {
width: 80rpx; width: 80rpx;
height: 80; height: 80;

View File

@ -8,6 +8,9 @@
<customer-archive ref="archiveRef" :corpId="corpId" :corpUserIds="corpUserIds" :team="team" <customer-archive ref="archiveRef" :corpId="corpId" :corpUserIds="corpUserIds" :team="team"
@update:customers="handleCustomersUpdate" /> @update:customers="handleCustomersUpdate" />
</view> </view>
<view class="home-section">
<team-guide :team="team" />
</view>
<view class="home-section"> <view class="home-section">
<consult ref="consultRef" :corpId="corpId" :teamId="team.teamId" :team="team" :customers="customers" /> <consult ref="consultRef" :corpId="corpId" :teamId="team.teamId" :team="team" :customers="customers" />
</view> </view>
@ -35,7 +38,8 @@ import articleList from "./article-list.vue";
import consult from "./consult.vue"; import consult from "./consult.vue";
import customerArchive from "./customer-archive.vue"; import customerArchive from "./customer-archive.vue";
import teamHead from "./team-head.vue"; import teamHead from "./team-head.vue";
import teamMate from "./team-mate.vue"; import teamGuide from "./team-guide.vue";
// import teamMate from "./team-mate.vue";
import ycHome from "./yc-home.vue"; import ycHome from "./yc-home.vue";
import pageLoading from "./loading.vue"; import pageLoading from "./loading.vue";

121
pages/home/team-guide.vue Normal file
View File

@ -0,0 +1,121 @@
<template>
<view class="px-15">
<view v-if="qrcode && qrcode.guide" class="team-introduce-wrapper rounded shadow-lg">
<view class="team-introduce flex items-center">
<view class="team-introduce-border"></view>
<!-- <view class="triangle-wrapper">
<view class="team-triangle"></view>
</view> -->
<image class="laba-icon flex-shrink-0" src="/static/home/speaker-intro.png" mode="aspectFit"></image>
<view class="introduce-text flex-grow line-clamp-2">
{{ qrcode.guide }}
</view>
</view>
</view>
</view>
</template>
<script setup>
import { computed } from "vue";
const props = defineProps({
team: {
type: Object,
default: () => ({}),
}
});
const qrcode = computed(() => {
const qrcodes = props.team && Array.isArray(props.team.qrcodes) ? props.team.qrcodes : [];
return qrcodes[0] || ''
})
</script>
<style scoped>
.laba-icon {
width: 48rpx;
height: 48rpx;
margin-left: 12rpx;
margin-right: 12rpx;
}
.team-introduce-wrapper {
background: #fff;
z-index: 2;
}
.team-introduce {
width: 690rpx;
box-sizing: border-box;
background: linear-gradient(186deg,
rgba(255, 255, 255, 0.4) 13.34%,
rgba(255, 255, 255, 0.6) 99.17%);
border-radius: 16rpx;
padding: 20rpx;
position: relative;
overflow: visible;
}
.team-introduce-border {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: 1px solid #fff;
border-radius: 16rpx;
pointer-events: none;
/* -webkit-mask-image: linear-gradient(to right, #000 0, #000 50rpx, transparent 50rpx, transparent 70rpx, #000 70rpx),
linear-gradient(#000, #000);
mask-image: linear-gradient(to right, #000 0, #000 50rpx, transparent 50rpx, transparent 70rpx, #000 70rpx),
linear-gradient(#000, #000);
-webkit-mask-size: 100% 1px, 100% 100%;
mask-size: 100% 1px, 100% 100%;
-webkit-mask-position: 0 0, 0 1px;
mask-position: 0 0, 0 1px;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat; */
}
.triangle-wrapper {
position: absolute;
top: -12rpx;
left: 60rpx;
width: 32rpx;
height: 12rpx;
overflow: hidden;
z-index: 10;
transform: translateX(-50%);
}
.team-triangle {
position: absolute;
left: 50%;
bottom: -9rpx;
width: 16rpx;
height: 16rpx;
background: linear-gradient(186deg,
rgba(255, 255, 255, 0.4) 13.34%,
rgba(255, 255, 255, 0.6) 99.17%);
transform: translateX(-50%) rotate(45deg);
border-top: 1px solid #fff;
border-left: 1px solid #fff;
box-sizing: border-box;
}
.introduce-text {
color: #333;
font-size: 24rpx;
font-style: normal;
font-weight: 400;
line-height: 36rpx;
}
.line-clamp-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
line-clamp: 2;
overflow: hidden;
}
</style>

View File

@ -7,7 +7,7 @@
</view> </view>
<view class="w-0 flex-grow"> <view class="w-0 flex-grow">
<view class="flex items-center mb-10"> <view class="flex items-center mb-10">
<view class="team-name flex-shrink-0">{{ team.name }}</view> <view class="team-name truncate flex-shrink-0" :style="teamStyle">{{ team.name }}</view>
<view v-if="teams.length > 1" class="flex-shrink-0 flex items-center switch-btn ml-10" <view v-if="teams.length > 1" class="flex-shrink-0 flex items-center switch-btn ml-10"
@click="showDropDown = true"> @click="showDropDown = true">
<image class="switch-icon" src="/static/home/switch-team.png" mode="aspectFit"></image> <image class="switch-icon" src="/static/home/switch-team.png" mode="aspectFit"></image>
@ -52,11 +52,28 @@
</scroll-view> </scroll-view>
</view> </view>
</view> </view>
<view v-if="qrcode && qrcode.guide" class="team-introduce-wrapper"> <view v-if="team && team.teamTroduce" class="team-introduce-wrapper" @click="toTeamDetail">
<view class="team-introduce flex items-center">
<view class="team-introduce-border"></view>
<view class="triangle-wrapper">
<view class="team-triangle"></view>
</view>
<!-- <image class="laba-icon flex-shrink-0" src="/static/home/speaker-intro.png" mode="aspectFit"></image> -->
<!-- <view class="introduce-text flex-grow line-clamp-3">
团队介绍: {{ team.teamTroduce }}
</view> -->
<!-- <expandable-text textStyle="color:#333;font-size:24rpx" expandStyle="font-size:24rpx"
:longText="team.teamTroduce + team.teamTroduce" :line="3" :lineHeight="36" expandText="展开" foldText="收起" /> -->
<!-- <multi-lines-text :line="3" :text="team.teamTroduce + team.teamTroduce" :showButton="true" expandText="展开"
collapseText="收起" buttonTextColor="#333" /> -->
<zh-read-more :text="team.teamTroduce" :textStyle="{ color: '#333', 'font-size': '28rpx' }"
:unfoldTextStyle="{ 'font-size': '28rpx', 'color': '#0074ff' }"
:packupTextStyle="{ 'font-size': '28rpx', 'color': '#0074ff' }" />
</view>
</view>
<!-- <view v-if="qrcode && qrcode.guide" class="team-introduce-wrapper">
<view class="team-introduce flex items-center"> <view class="team-introduce flex items-center">
<!-- 边框层 -->
<view class="team-introduce-border"></view> <view class="team-introduce-border"></view>
<!-- 顶部小三角形 -->
<view class="triangle-wrapper"> <view class="triangle-wrapper">
<view class="team-triangle"></view> <view class="team-triangle"></view>
</view> </view>
@ -65,7 +82,7 @@
{{ qrcode.guide }} {{ qrcode.guide }}
</view> </view>
</view> </view>
</view> </view> -->
</view> </view>
<view v-if="showDropDown" class="mask" @click="showDropDown = false"></view> <view v-if="showDropDown" class="mask" @click="showDropDown = false"></view>
</template> </template>
@ -73,7 +90,9 @@
import { computed, ref, onMounted, watch } from "vue"; import { computed, ref, onMounted, watch } from "vue";
import groupAvatar from "@/components/group-avatar.vue"; import groupAvatar from "@/components/group-avatar.vue";
// import ExpandableText from "@/components/expandable-text/expandable-text.vue"
// import MultiLinesText from "@/components/multi-lines-text/multi-lines-text.vue";
import zhReadMore from "@/components/zh-readMore/zh-readMore.vue";
const statusBarHeight = ref("50px"); const statusBarHeight = ref("50px");
const menuButtonInfo = ref(null); const menuButtonInfo = ref(null);
const showDropDown = ref(false); const showDropDown = ref(false);
@ -97,6 +116,7 @@ const qrcode = computed(() => {
const qrcodes = props.team && Array.isArray(props.team.qrcodes) ? props.team.qrcodes : []; const qrcodes = props.team && Array.isArray(props.team.qrcodes) ? props.team.qrcodes : [];
return qrcodes[0] || '' return qrcodes[0] || ''
}) })
const teamStyle = computed(() => `max-width:${props.teams.length ? 'calc(100% - 60rpx)' : '100%'}`)
function select(team) { function select(team) {
emits("changeTeam", team); emits("changeTeam", team);
@ -173,7 +193,7 @@ onMounted(() => {
.team-introduce-wrapper { .team-introduce-wrapper {
padding: 0 30rpx; padding: 0 30rpx;
margin-top: 20rpx; /* margin-top: 12rpx; */
margin-bottom: 30rpx; margin-bottom: 30rpx;
position: relative; position: relative;
z-index: 2; z-index: 2;
@ -187,7 +207,7 @@ onMounted(() => {
rgba(255, 255, 255, 0.4) 13.34%, rgba(255, 255, 255, 0.4) 13.34%,
rgba(255, 255, 255, 0.6) 99.17%); rgba(255, 255, 255, 0.6) 99.17%);
border-radius: 16rpx; border-radius: 16rpx;
padding: 20rpx 20rpx 20rpx 0; padding: 20rpx;
position: relative; position: relative;
overflow: visible; overflow: visible;
} }
@ -240,12 +260,11 @@ onMounted(() => {
} }
.introduce-text { .introduce-text {
max-width: 594rpx; color: #333;
color: #000000;
font-size: 24rpx; font-size: 24rpx;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
line-height: normal; line-height: 36rpx;
} }
.line-clamp-2 { .line-clamp-2 {

View File

@ -1,76 +1,55 @@
<template> <template>
<full-page> <full-page :pageStyle="pageStyle">
<view v-if="team" class="p-15"> <view v-if="team" class="detail-wrapper">
<view class="flex items-center"> <view class="linear-bg">
<view class="flex-shrink-0 mr-10"> <view class="flex items-center pt-15 px-15">
<group-avatar :size="96" :avatarList="avatarList" /> <view class="flex-shrink-0 mr-10">
</view> <group-avatar :size="128" :avatarList="avatarList" />
<view class="flex-grow w-0 leading-noraml"> </view>
<view class="mb-5 text-lg font-semibold text-dark">{{ team.name }}</view> <view class="w-0 flex-grow">
<view class="text-base text-gray"> <view class="name-title font-semibold text-dark truncate">{{ team.name }}</view>
{{ corpName }} <view class="corp-title text-gray truncate">{{ corpName }}</view>
</view>
</view> </view>
</view> <view class="mt-15 px-15 leading-normal text-base text-blue">
</view> {{ team.teamTroduce }}
<view class="flex items-center justify-between mt-12" @click="showAllIntroduce = !showAllIntroduce"> </view>
<view class="text-dark font-semibold">团队介绍</view> <view class="pt-15"></view>
<uni-icons :type="showAllIntroduce ? 'up' : 'down'" size="20" color="#666"></uni-icons> <image v-if="teammate.leaders.length" class="block mx-auto icon-role" src="/static/teamleader.svg">
</view> </image>
<view v-if="team.teamTroduce" class="mt-10 text-base text-dark leading-normal break-all pre-wrap" <view v-for="i in teammate.leaders" :key="i._id" class="mt-15 flex flex-col items-center">
:class="showAllIntroduce ? '' : 'line-clamp-2'" @click="showAllIntroduce = !showAllIntroduce"> <view class="ablum text-center p-10 flex flex-col items-center rounded-sm"
{{ team.teamTroduce }} :class="friendlyMember[i.userid] ? 'ablum-pb' : ''" @click="toHomePage(i.userid)">
</view> <image class="avatar mb-10" :src="i.avatar || '/static/default-avatar.png'"></image>
<template v-if="teammate.leaders.length"> <view class="text-lg text-dark font-semibold">{{ i.anotherName }}</view>
<view class="min-w-100 inline-block mt-12 px-10 py-5 text-center text-base text-white bg-primary rounded-sm"> <view class="mt-5 text-base text-gray">
团队负责人
</view>
<view v-for="i in teammate.leaders" :key="i._id" class="mt-12 flex p-10 border-primary rounded-sm"
@click="toHomePage(i.userid)">
<image class="flex-shrink-0 mr-10 avatar" :src="i.avatar || '/static/default-avatar.png'"></image>
<view class="w-0 flex-grow leading-normal">
<view class="flex items-center justify-between">
<view class="flex-shrink-0 mr-5 view-lg text-dark font-semibold">{{ i.anotherName }}</view>
<view class="w-0 flex-grow truncate text-base text-dark">
{{ memberJob[i.userid] }} {{ memberJob[i.userid] }}
</view> </view>
<view v-if="friendlyMember[i.userid]" <view v-if="friendlyMember[i.userid]" class="friend-bottom" @click.stop="toFriend(i.userid)">
class="flex-shrink-0 px-10 leading-normal text-sm border-auto text-primary rounded-full" 可加好友
@click.stop="toFriend(i.userid)">
添加好友
</view> </view>
</view> </view>
<view class="line-clamp-2 text-base text-gray"> <view class="mt-15 border-box w-full px-15 leading-normal text-base text-blue">
{{ i.memberTroduce || '暂无介' }} 个人介绍: {{ i.memberTroduce || '暂无介绍' }}
</view> </view>
</view> </view>
</view> <image v-if="teammate.members.length" class="block mt-30 mx-auto icon-role" src="/static/teammate.svg"></image>
</template> <view class="mt-15 px-15 flex flex-wrap" :class="teammate.members.length === 1 ? 'justify-center' : ''">
<view v-for="i in teammate.members" :key="i._id"
<template v-if="teammate.members.length"> class="ablum ablum--member text-center p-10 flex flex-col items-center rounded-sm"
<view class="min-w-100 inline-block mt-12 px-10 py-5 text-center text-base text-white bg-primary rounded-sm">团队成员 :class="friendlyMember[i.userid] ? 'ablum-pb' : ''" @click="toHomePage(i.userid)">
</view> <image class="avatar mb-10" :src="i.avatar || '/static/default-avatar.png'"></image>
<view v-for="i in teammate.members" :key="i._id" class="mt-12 flex p-10 border-primary rounded-sm" <view class="w-full text-lg text-dark font-semibold truncate px-10">{{ i.anotherName }}</view>
@click="toHomePage(i.userid)"> <view class="w-full mt-5 text-base text-gray truncate px-10">
<image class="flex-shrink-0 mr-10 avatar" :src="i.avatar || '/static/default-avatar.png'"></image>
<view class="w-0 flex-grow leading-normal">
<view class="flex items-center justify-between">
<view class="flex-shrink-0 mr-5 view-lg text-dark font-semibold">{{ i.anotherName }}</view>
<view class="w-0 flex-grow truncate text-base text-dark">
{{ memberJob[i.userid] }} {{ memberJob[i.userid] }}
</view> </view>
<view v-if="friendlyMember[i.userid]" <view v-if="friendlyMember[i.userid]" class="friend-bottom" @click.stop="toFriend(i.userid)">
class="flex-shrink-0 px-10 leading-normal text-sm border-auto text-primary rounded-full" 可加好友
@click.stop="toFriend(i.userid)">
添加好友
</view> </view>
</view> </view>
<view class="line-clamp-2 text-base text-gray">
{{ i.memberTroduce || '暂无简介' }}
</view>
</view> </view>
</view> </view>
</template> </view>
</view>
</full-page> </full-page>
</template> </template>
<script setup> <script setup>
@ -82,11 +61,12 @@ import api from '@/utils/api';
import groupAvatar from '@/components/group-avatar.vue'; import groupAvatar from '@/components/group-avatar.vue';
import FullPage from '@/components/full-page.vue'; import FullPage from '@/components/full-page.vue';
const pageStyle = "background: linear-gradient(180deg, #065BD6 15.05%, #F6FAFA 95.37%) 0 0/100% 562rpx no-repeat, #F6FAFA;";
const corpId = ref(''); const corpId = ref('');
const teamId = ref(''); const teamId = ref('');
const team = ref(null); const team = ref(null);
const corpName = ref(''); const corpName = ref('');
const showAllIntroduce = ref(false);
const { memberJob, memberList: list } = useJob(); const { memberJob, memberList: list } = useJob();
const memberList = computed(() => team.value && Array.isArray(team.value.memberList) ? team.value.memberList : []) const memberList = computed(() => team.value && Array.isArray(team.value.memberList) ? team.value.memberList : [])
@ -157,11 +137,93 @@ page {
} }
.avatar { .avatar {
width: 120rpx; width: 216rpx;
height: 128rpx; height: 240rpx;
} }
.pre-wrap { .pre-wrap {
white-space: pre-wrap; white-space: pre-wrap;
} }
.detail-wrapper {
transform: translateY(40rpx);
background: #F5FAFF;
border-top-left-radius: 24rpx;
border-top-right-radius: 24rpx;
min-height: calc(100vh - 40rpx);
padding-bottom: 80rpx;
overflow: hidden;
}
.name-title {
height: 64rpx;
line-height: 64rpx;
font-size: 44rpx;
}
.corp-title {
height: 44rpx;
line-height: 44rpx;
font-size: 28rpx;
}
.text-blue {
color: #516276;
}
.linear-bg {
background: linear-gradient(180deg, #ffffff 0%, #f5faff 100%);
}
.icon-role {
margin-top: 50rpx;
margin-bottom: 38rpx;
width: 280rpx;
height: 60rpx;
}
.ablum {
width: 336rpx;
box-sizing: border-box;
border: 1rpx solid #9BB7D8;
}
.ablum-pb {
position: relative;
padding-bottom: 64rpx;
}
.ablum--member {
width: 332rpx;
}
.ablum--member:nth-child(2n) {
margin-left: 24rpx;
}
.ablum--member:nth-child(n+3) {
margin-top: 30rpx;
}
.mt-5 {
margin-top: 10rpx;
}
.friend-bottom {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 48rpx;
text-align: center;
line-height: 48rpx;
font-size: 24rpx;
color: #fff;
font-weight: bold;
background: #065BD6;
}
.mt-30 {
margin-top: 60rpx;
}
</style> </style>

7
static/teamleader.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.7 KiB

14
static/teammate.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.1 KiB