216 lines
7.1 KiB
Vue
216 lines
7.1 KiB
Vue
<template>
|
||
<view data-component-name="diy-kefu" class="diy-kefu" :style="style">
|
||
<view class="fui-list-group merchgroup" v-for="(item, index) in value.list" :key="index">
|
||
<view class="fui-list jump" v-if="index == 0">
|
||
<view class="fui-list-media">
|
||
<image class="round" :src="$util.img(item.imageUrl)" style="border-radius:6rpx" show-menu-by-longpress></image>
|
||
</view>
|
||
<view class="fui-list-inner">
|
||
<view class="title">
|
||
<text class="title-text" :style="titleStyle(item)">{{ item.title }}</text>
|
||
<view class="subtitle" :style="descStyle(item)">{{ item.desc }}</view>
|
||
<!-- #ifndef H5 -->
|
||
<!-- PR-DIY-KEFU-ONE-LINE (2026-09-17): 小程序端隐藏测量节点, 以默认字号实测文本宽度, 反推一行能放下的最大字号 -->
|
||
<text class="measure-text measure-title" style="font-size:28rpx;">{{ item.title }}</text>
|
||
<text class="measure-text measure-desc" style="font-size:24rpx;">{{ item.desc }}</text>
|
||
<!-- #endif -->
|
||
</view>
|
||
</view>
|
||
<!-- PR-DIY-KEFU-ONE-LINE (2026-09-17): 按钮颜色未配置时不再渲染/占位, 避免透明按钮挤窄文字区 -->
|
||
<view class="fui-remark jump" v-if="item.BtBgColor || item.BtColor" style="padding-right: 20rpx; text-align: center; line-height: 140rpx;">
|
||
<span style="font-size:24rpx;padding: 14rpx 18rpx;border-radius:8rpx"
|
||
:style="{ background: item.BtBgColor, color: item.BtColor }" @tap.stop="previewSqs()">{{ $lang('components-diy.diy-kefu.addNow') }}</span>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
// 客服展示
|
||
import DiyMinx from './minx.js'
|
||
export default {
|
||
name: 'diy-kefu',
|
||
props: {
|
||
value: {
|
||
type: Object
|
||
}
|
||
},
|
||
mixins: [DiyMinx],
|
||
data() {
|
||
return {
|
||
loading: true,
|
||
// PR-DIY-KEFU-ONE-LINE (2026-09-17): 小程序端实测得出的一行自适应字号(rpx), 0 表示用默认字号
|
||
mpTitleSize: 0,
|
||
mpDescSize: 0
|
||
};
|
||
},
|
||
created() {
|
||
// this.getDataList();
|
||
},
|
||
// PR-DIY-KEFU-ONE-LINE (2026-09-17): 英文公司名等长标题一行完整展示(不换行、不省略)
|
||
// H5: 挂载/数据变化后实测每个文本的溢出宽度, 逐级缩小 font-size 直到恰好一行放下 —— 保证无省略号;
|
||
// 小程序端无法测 DOM, 用字符宽度估算兜底(CJK 1em / 其他 0.6em), 极端超长时仍有省略号兜底
|
||
mounted() {
|
||
this.$nextTick(this.fitOneLineText)
|
||
},
|
||
watch: {
|
||
// 组件刷新监听
|
||
componentRefresh: function (nval) {
|
||
// this.getDataList();
|
||
this.$nextTick(this.fitOneLineText)
|
||
},
|
||
value: {
|
||
deep: true,
|
||
handler() {
|
||
this.$nextTick(this.fitOneLineText)
|
||
}
|
||
}
|
||
},
|
||
computed: {
|
||
style() {
|
||
var css = '';
|
||
css += 'background-color:' + this.value.contentBgColor + ';';
|
||
if (this.value.elementAngle == 'round') {
|
||
css += 'border-top-left-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;';
|
||
css += 'border-top-right-radius:' + this.value.topElementAroundRadius * 2 + 'rpx;';
|
||
css += 'border-bottom-left-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;';
|
||
css += 'border-bottom-right-radius:' + this.value.bottomElementAroundRadius * 2 + 'rpx;';
|
||
}
|
||
return css;
|
||
}
|
||
},
|
||
methods: {
|
||
previewSqs() {
|
||
var img = this.$util.img(this.value.list[1].imageUrl)
|
||
uni.previewImage({
|
||
current: img,
|
||
urls: [img]
|
||
})
|
||
},
|
||
// PR-DIY-KEFU-ONE-LINE (2026-09-17): 单行自适应 —— 标题/描述一行完整展示(不换行), 字号取一行能放下的最大值
|
||
// #ifdef H5
|
||
fitOneLineText() {
|
||
this.$nextTick(() => {
|
||
const root = this.$el && this.$el.querySelectorAll ? this.$el : null
|
||
if (!root) return
|
||
const nodes = root.querySelectorAll('.title-text, .subtitle')
|
||
nodes.forEach((el) => {
|
||
// 先还原 CSS 默认字号, 再实测是否溢出; 目标宽度留 3px 右侧空隙, 不贴边
|
||
el.style.fontSize = ''
|
||
let size = parseFloat(window.getComputedStyle(el).fontSize)
|
||
const MIN_PX = 10 // 下限 10px, 再小可读性太差
|
||
const target = el.clientWidth - 3
|
||
let guard = 0
|
||
while (el.scrollWidth > target && size > MIN_PX && guard < 60) {
|
||
size -= 0.5
|
||
el.style.fontSize = size + 'px'
|
||
guard++
|
||
}
|
||
})
|
||
})
|
||
},
|
||
// #endif
|
||
// #ifndef H5
|
||
// 小程序端: 隐藏测量节点以默认字号实测文本宽度, 宽度与字号成线性关系, 反推一行能放下的最大字号
|
||
fitOneLineText() {
|
||
uni.createSelectorQuery().in(this)
|
||
.select('.fui-list-inner').boundingClientRect()
|
||
.select('.measure-title').boundingClientRect()
|
||
.select('.measure-desc').boundingClientRect()
|
||
.exec((rects) => {
|
||
if (!rects || !rects[0]) return
|
||
const sys = uni.getSystemInfoSync()
|
||
const pxPerRpx = (sys.windowWidth || 375) / 750
|
||
// 可用宽度 = 文字区宽度 - 容器右内边距(8rpx) - 与右侧元素(按钮)之间留 8rpx 空隙
|
||
const avail = rects[0].width - 16 * pxPerRpx
|
||
if (avail <= 0) return
|
||
// 标题: 默认 28rpx, 最小 16rpx
|
||
if (rects[1] && rects[1].width > avail) {
|
||
this.mpTitleSize = Math.max(16, Math.floor(28 * avail / rects[1].width))
|
||
} else {
|
||
this.mpTitleSize = 0
|
||
}
|
||
// 描述: 默认 24rpx, 最小 16rpx
|
||
if (rects[2] && rects[2].width > avail) {
|
||
this.mpDescSize = Math.max(16, Math.floor(24 * avail / rects[2].width))
|
||
} else {
|
||
this.mpDescSize = 0
|
||
}
|
||
})
|
||
},
|
||
// #endif
|
||
titleStyle() {
|
||
// #ifndef H5
|
||
return this.mpTitleSize ? 'font-size:' + this.mpTitleSize + 'rpx;' : ''
|
||
// #endif
|
||
// #ifdef H5
|
||
return ''
|
||
// #endif
|
||
},
|
||
descStyle() {
|
||
// #ifndef H5
|
||
return this.mpDescSize ? 'font-size:' + this.mpDescSize + 'rpx;' : ''
|
||
// #endif
|
||
// #ifdef H5
|
||
return ''
|
||
// #endif
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
// 客服展示:标题/描述需要完整展示(中英文均不截断)
|
||
// 全局 .fui-list-inner .title 有 nowrap + ellipsis + overflow:hidden,这里用更高优先级的选择器覆盖
|
||
// PR-DIY-KEFU-ONE-LINE (2026-09-17): 标题/描述强制单行(配合 JS 自适应字号保证一行放得下), 超长省略号兜底
|
||
.diy-kefu {
|
||
.fui-list-group {
|
||
.fui-list {
|
||
align-items: center;
|
||
|
||
.fui-list-inner {
|
||
overflow: hidden;
|
||
min-width: 0;
|
||
// 右侧留少量空隙, 避免单行文本贴着容器右边缘, 又能尽量铺满到按钮旁
|
||
padding-right: 8rpx;
|
||
box-sizing: border-box;
|
||
|
||
.title {
|
||
height: auto;
|
||
line-height: 1.4;
|
||
|
||
.title-text {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
line-height: 1.4;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
.subtitle {
|
||
display: block;
|
||
margin-top: 6rpx;
|
||
font-size: 24rpx;
|
||
line-height: 1.4;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
}
|
||
|
||
// PR-DIY-KEFU-ONE-LINE (2026-09-17): 小程序端隐藏测量节点(不占布局、不可见)
|
||
.measure-text {
|
||
position: absolute;
|
||
left: -9999rpx;
|
||
top: 0;
|
||
white-space: nowrap;
|
||
visibility: hidden;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |