fix: 首页和我的应用排序按 seq 排列
This commit is contained in:
275
pages/index/components/appCenter.vue
Normal file
275
pages/index/components/appCenter.vue
Normal file
@@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<view v-if="showApps" :style="[boxStyle]">
|
||||
<view :style="[boxContentStyle]">
|
||||
<view class="list-menu" :style="[gridColumns]">
|
||||
<view
|
||||
class="item flex-col flex-center"
|
||||
v-for="(item, index) in displayList"
|
||||
:key="index"
|
||||
@click="onAppTap(item)"
|
||||
>
|
||||
<!-- 更多按钮 -->
|
||||
<template v-if="item._isMore">
|
||||
<view class="img-box skeleton-radius" v-if="menuStyleConfig !== 2">
|
||||
<view class="more-icon-inner flex-col flex-center">
|
||||
<view class="more-dots">
|
||||
<view class="more-dot"></view>
|
||||
<view class="more-dot"></view>
|
||||
<view class="more-dot"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<text
|
||||
class="fs-24"
|
||||
:class="{ 'mt-14': menuStyleConfig == 0 }"
|
||||
:style="[nameColorStyle]"
|
||||
v-if="menuStyleConfig !== 1"
|
||||
>更多</text>
|
||||
</template>
|
||||
<!-- 普通应用 -->
|
||||
<template v-else>
|
||||
<view class="img-box skeleton-radius" v-if="menuStyleConfig !== 2">
|
||||
<image
|
||||
:src="item.logo"
|
||||
mode="aspectFill"
|
||||
:style="{ borderRadius: (imgStyle * 2) + 'rpx' }"
|
||||
v-if="item.logo"
|
||||
></image>
|
||||
<view class="empty-box" v-else></view>
|
||||
</view>
|
||||
<text
|
||||
class="fs-24"
|
||||
:class="{ 'mt-14': menuStyleConfig == 0 }"
|
||||
:style="[nameColorStyle]"
|
||||
v-if="menuStyleConfig !== 1"
|
||||
>{{ item.name }}</text>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const STORAGE_KEY = 'MY_HOME_APPS'
|
||||
const MAX_HOME_APPS = 6
|
||||
|
||||
export default {
|
||||
name: 'appCenter',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
menuStyleConfig() {
|
||||
return this.dataConfig.menuStyleConfig?.tabVal ?? 0
|
||||
},
|
||||
number() {
|
||||
return this.dataConfig.number?.tabVal ?? 0
|
||||
},
|
||||
boxStyle() {
|
||||
return {
|
||||
padding: `${(this.dataConfig.topConfig?.val ?? 0) * 2}rpx ${(this.dataConfig.prConfig?.val ?? 0) * 2}rpx ${(this.dataConfig.bottomConfig?.val ?? 0) * 2}rpx`,
|
||||
marginTop: `${(this.dataConfig.mbConfig?.val ?? 0) * 2}rpx`,
|
||||
background: this.dataConfig.bottomBgColor?.color?.[0]?.item ?? 'transparent'
|
||||
}
|
||||
},
|
||||
boxContentStyle() {
|
||||
let borderRadius = `${(this.dataConfig.fillet?.val ?? 0) * 2}rpx`
|
||||
if (this.dataConfig.fillet?.type) {
|
||||
const vl = this.dataConfig.fillet.valList || []
|
||||
borderRadius = `${(vl[0]?.val ?? 0) * 2}rpx ${(vl[1]?.val ?? 0) * 2}rpx ${(vl[3]?.val ?? 0) * 2}rpx ${(vl[2]?.val ?? 0) * 2}rpx`
|
||||
}
|
||||
return {
|
||||
borderRadius,
|
||||
background: `linear-gradient(90deg, ${this.dataConfig.bgColor?.color?.[0]?.item ?? '#fff'} 0%, ${this.dataConfig.bgColor?.color?.[1]?.item ?? '#fff'} 100%)`
|
||||
}
|
||||
},
|
||||
imgStyle() {
|
||||
return this.dataConfig.filletImg?.val ?? 0
|
||||
},
|
||||
gridColumns() {
|
||||
// 应用中心用 4 列固定网格
|
||||
return {
|
||||
gridTemplateColumns: `repeat(4, 1fr)`
|
||||
}
|
||||
},
|
||||
nameColorStyle() {
|
||||
return {
|
||||
color: this.dataConfig.nameColor?.color?.[0]?.item ?? '#333333'
|
||||
}
|
||||
},
|
||||
// 是否在首页展示
|
||||
showApps() {
|
||||
return this.homeApps.showOnHome && this.displayList.length > 0
|
||||
},
|
||||
// 已选应用的 id 集合(快速查找)
|
||||
selectedIds() {
|
||||
return new Set(this.homeApps.appIds || [])
|
||||
},
|
||||
// 最终展示列表(过滤 + 按 seq 排序 + 截取 + 追加"更多")
|
||||
displayList() {
|
||||
const ids = this.homeApps.appIds || []
|
||||
if (!ids.length) return []
|
||||
|
||||
const idSet = new Set(ids)
|
||||
// 按 allApps API 返回顺序排列(即后台设置的 seq 顺序)
|
||||
const filtered = this.allApps.filter(item => idSet.has(item.id))
|
||||
const indexMap = new Map(this.allApps.map((item, i) => [item.id, i]))
|
||||
filtered.sort((a, b) => (indexMap.get(a.id) ?? 999) - (indexMap.get(b.id) ?? 999))
|
||||
const sliced = filtered.slice(0, MAX_HOME_APPS)
|
||||
|
||||
// 追加"更多"条目
|
||||
sliced.push({
|
||||
_isMore: true,
|
||||
name: '更多'
|
||||
})
|
||||
|
||||
return sliced
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
allApps: [],
|
||||
homeApps: {
|
||||
showOnHome: true,
|
||||
appIds: []
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadHomeApps()
|
||||
this.fetchApps()
|
||||
},
|
||||
// 从个人中心编辑保存后跳回首页时,重新读取 storage
|
||||
onShow() {
|
||||
this.loadHomeApps()
|
||||
},
|
||||
methods: {
|
||||
// 读取本地存储的首页应用配置
|
||||
loadHomeApps() {
|
||||
try {
|
||||
const raw = uni.getStorageSync(STORAGE_KEY)
|
||||
if (raw) {
|
||||
this.homeApps = raw
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[appCenter] loadHomeApps error:', e)
|
||||
}
|
||||
},
|
||||
fetchApps() {
|
||||
uni.request({
|
||||
url: 'https://mp.yizhezhe.com/api/mp/apps',
|
||||
data: {
|
||||
isPublished: 1,
|
||||
pageSize: 50
|
||||
},
|
||||
success: (res) => {
|
||||
if (res.data?.code === 200 && res.data?.result?.items) {
|
||||
this.allApps = res.data.result.items
|
||||
} else if (res.data?.status === 200 && res.data?.data) {
|
||||
this.allApps = res.data.data
|
||||
} else {
|
||||
return
|
||||
}
|
||||
this.autoFillHomeApps()
|
||||
},
|
||||
fail: () => {
|
||||
this.allApps = []
|
||||
}
|
||||
})
|
||||
},
|
||||
// 自动填充首页展示应用
|
||||
autoFillHomeApps() {
|
||||
const ids = this.homeApps.appIds || []
|
||||
const currentCount = ids.length
|
||||
if (currentCount >= MAX_HOME_APPS) return
|
||||
|
||||
const idSet = new Set(ids)
|
||||
// 从推荐应用中筛选尚未选中的
|
||||
const recommended = this.allApps
|
||||
.filter(item => item.isRecommended && !idSet.has(item.id))
|
||||
|
||||
if (!recommended.length) return
|
||||
|
||||
const slots = MAX_HOME_APPS - currentCount
|
||||
const toAdd = recommended.slice(0, slots).map(item => item.id)
|
||||
|
||||
this.homeApps.appIds = [...ids, ...toAdd]
|
||||
try {
|
||||
uni.setStorageSync(STORAGE_KEY, this.homeApps)
|
||||
} catch (e) {
|
||||
console.error('[appCenter] autoFill save error:', e)
|
||||
}
|
||||
},
|
||||
onAppTap(item) {
|
||||
if (item._isMore) {
|
||||
// 点击"更多"跳转到我的页面
|
||||
uni.switchTab({
|
||||
url: '/pages/user/index'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!item.url) return
|
||||
this.$util.JumpPath(item.url)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.list-menu {
|
||||
display: grid;
|
||||
grid-template-rows: auto;
|
||||
grid-row-gap: 24rpx;
|
||||
width: 100%;
|
||||
padding: 20rpx 0;
|
||||
box-sizing: border-box;
|
||||
|
||||
.item {
|
||||
text-align: center;
|
||||
|
||||
.img-box {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
margin: 0 auto 6rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.empty-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #f3f9ff;
|
||||
}
|
||||
}
|
||||
|
||||
// 更多图标
|
||||
.more-icon-inner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #f5f5f5;
|
||||
border-radius: 16rpx;
|
||||
|
||||
.more-dots {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6rpx;
|
||||
|
||||
.more-dot {
|
||||
width: 8rpx;
|
||||
height: 8rpx;
|
||||
border-radius: 50%;
|
||||
background: #bbb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,250 +1,250 @@
|
||||
<template>
|
||||
<!-- 图片组件 -->
|
||||
<view v-show="!dataConfig.isHide" class="images-component" :style="containerStyle">
|
||||
<!-- 无链接时使用普通view -->
|
||||
<view v-if="!linkUrl" class="images-navigator" :style="imgContainerStyle">
|
||||
<image
|
||||
v-if="imgUrl"
|
||||
:src="imgUrl"
|
||||
:mode="imgMode"
|
||||
class="images-img"
|
||||
:style="imgStyle"
|
||||
:show-menu-by-longpress="isQrCode"
|
||||
@load="onImgLoad"
|
||||
@error="onImgError"
|
||||
></image>
|
||||
<!-- 占位图 -->
|
||||
<view v-else class="images-placeholder">
|
||||
<text class="placeholder-text">暂无图片</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 有链接时使用navigator -->
|
||||
<navigator v-else :url="linkUrl" hover-class="none" class="images-navigator" :style="imgContainerStyle">
|
||||
<image
|
||||
v-if="imgUrl"
|
||||
:src="imgUrl"
|
||||
:mode="imgMode"
|
||||
class="images-img"
|
||||
:style="imgStyle"
|
||||
:show-menu-by-longpress="isQrCode"
|
||||
@load="onImgLoad"
|
||||
@error="onImgError"
|
||||
></image>
|
||||
<!-- 占位图 -->
|
||||
<view v-else class="images-placeholder">
|
||||
<text class="placeholder-text">暂无图片</text>
|
||||
</view>
|
||||
</navigator>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'home_image',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
imgError: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const debug = uni.getStorageSync('DEBUG_DIY_RENDER') === true
|
||||
if (!debug) return
|
||||
console.log('[DIY][component]', 'home_image', 'mounted', {
|
||||
id: this.dataConfig?.id,
|
||||
timestamp: this.dataConfig?.timestamp,
|
||||
url: this.imgConfig?.url || this.dataConfig?.imgConfig?.url
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
// 图片配置
|
||||
imgConfig() {
|
||||
return this.dataConfig.imgConfig || {}
|
||||
},
|
||||
// 链接配置
|
||||
linkConfig() {
|
||||
return this.dataConfig.linkConfig || {}
|
||||
},
|
||||
// 二维码模式
|
||||
isQrCode() {
|
||||
return this.dataConfig.isQrCode?.val === true
|
||||
},
|
||||
// 上边距
|
||||
topConfig() {
|
||||
return this.dataConfig.topConfig || {}
|
||||
},
|
||||
// 下边距
|
||||
bottomConfig() {
|
||||
return this.dataConfig.bottomConfig || {}
|
||||
},
|
||||
// 左右边距
|
||||
prConfig() {
|
||||
return this.dataConfig.prConfig || {}
|
||||
},
|
||||
// 页面间距
|
||||
mbConfig() {
|
||||
return this.dataConfig.mbConfig || {}
|
||||
},
|
||||
// 圆角配置
|
||||
fillet() {
|
||||
return this.dataConfig.fillet || {}
|
||||
},
|
||||
// 背景颜色
|
||||
bgColor() {
|
||||
return this.dataConfig.bgColor || {}
|
||||
},
|
||||
// 图片地址
|
||||
imgUrl() {
|
||||
const url = this.imgConfig.url || ''
|
||||
if (!url) return ''
|
||||
// 处理安全域名
|
||||
if (url.indexOf('https://') > -1) return url
|
||||
return url.replace('http://', 'https://')
|
||||
},
|
||||
// 链接地址(从 imgConfig.link 获取)
|
||||
linkUrl() {
|
||||
// 直接从 imgConfig.link 获取字符串链接
|
||||
const link = this.imgConfig.link || this.linkConfig?.link || ''
|
||||
if (!link) return ''
|
||||
// 支持字符串链接
|
||||
if (typeof link === 'string') {
|
||||
return link
|
||||
}
|
||||
// 支持对象结构 { url: '', title: '' }
|
||||
if (typeof link === 'object') {
|
||||
return link.url || ''
|
||||
}
|
||||
// 兼容旧的数组结构
|
||||
if (Array.isArray(link) && link.length > 0) {
|
||||
return link[0]?.link || link[0]?.url || ''
|
||||
}
|
||||
return ''
|
||||
},
|
||||
// 图片显示模式
|
||||
imgMode() {
|
||||
return 'widthFix'
|
||||
},
|
||||
// 容器样式
|
||||
containerStyle() {
|
||||
const style = {}
|
||||
|
||||
// 上边距
|
||||
if (this.topConfig.val) {
|
||||
style.marginTop = this.topConfig.val + 'rpx'
|
||||
}
|
||||
|
||||
// 页面间距
|
||||
if (this.mbConfig.val) {
|
||||
style.marginBottom = this.mbConfig.val + 'rpx'
|
||||
}
|
||||
|
||||
// 下边距
|
||||
if (this.bottomConfig.val) {
|
||||
style.paddingBottom = this.bottomConfig.val + 'rpx'
|
||||
}
|
||||
|
||||
// 背景颜色
|
||||
if (this.bgColor.color && this.bgColor.color[0]?.item) {
|
||||
style.backgroundColor = this.bgColor.color[0].item
|
||||
}
|
||||
|
||||
return style
|
||||
},
|
||||
// 图片容器样式
|
||||
imgContainerStyle() {
|
||||
const style = {}
|
||||
const fillet = this.fillet
|
||||
|
||||
// 左右边距
|
||||
if (this.prConfig.val) {
|
||||
style.paddingLeft = this.prConfig.val + 'rpx'
|
||||
style.paddingRight = this.prConfig.val + 'rpx'
|
||||
}
|
||||
|
||||
// 圆角 - 全部圆角模式
|
||||
if (fillet.type === 0 && fillet.val) {
|
||||
style.borderRadius = fillet.val + 'rpx'
|
||||
}
|
||||
|
||||
return style
|
||||
},
|
||||
// 图片样式
|
||||
imgStyle() {
|
||||
const style = {}
|
||||
const fillet = this.fillet
|
||||
|
||||
// 圆角 - 单独设置模式
|
||||
if (fillet.type === 1 && fillet.valList) {
|
||||
const [tl, tr, br, bl] = fillet.valList
|
||||
const radius = `${tl?.val || 0}rpx ${tr?.val || 0}rpx ${br?.val || 0}rpx ${bl?.val || 0}rpx`
|
||||
style.borderRadius = radius
|
||||
}
|
||||
|
||||
return style
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onImgLoad(e) {
|
||||
const debug = uni.getStorageSync('DEBUG_DIY_RENDER') === true
|
||||
if (!debug) return
|
||||
console.log('[DIY][component]', 'home_image', 'img_load', {
|
||||
id: this.dataConfig?.id,
|
||||
timestamp: this.dataConfig?.timestamp,
|
||||
src: this.imgUrl,
|
||||
width: e?.detail?.width,
|
||||
height: e?.detail?.height
|
||||
})
|
||||
},
|
||||
// 图片加载失败处理
|
||||
onImgError(e) {
|
||||
const debug = uni.getStorageSync('DEBUG_DIY_RENDER') === true
|
||||
if (debug) {
|
||||
console.log('[DIY][component]', 'home_image', 'img_error', {
|
||||
id: this.dataConfig?.id,
|
||||
timestamp: this.dataConfig?.timestamp,
|
||||
src: this.imgUrl,
|
||||
detail: e?.detail
|
||||
})
|
||||
}
|
||||
this.imgError = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.images-component {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
.images-navigator {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.images-img {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.images-placeholder {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.placeholder-text {
|
||||
color: #999;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<!-- 图片组件 -->
|
||||
<view v-show="!dataConfig.isHide" class="images-component" :style="containerStyle">
|
||||
<!-- 无链接时使用普通view -->
|
||||
<view v-if="!linkUrl" class="images-navigator" :style="imgContainerStyle">
|
||||
<image
|
||||
v-if="imgUrl"
|
||||
:src="imgUrl"
|
||||
:mode="imgMode"
|
||||
class="images-img"
|
||||
:style="imgStyle"
|
||||
:show-menu-by-longpress="isQrCode"
|
||||
@load="onImgLoad"
|
||||
@error="onImgError"
|
||||
></image>
|
||||
<!-- 占位图 -->
|
||||
<view v-else class="images-placeholder">
|
||||
<text class="placeholder-text">暂无图片</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 有链接时使用navigator -->
|
||||
<navigator v-else :url="linkUrl" hover-class="none" class="images-navigator" :style="imgContainerStyle">
|
||||
<image
|
||||
v-if="imgUrl"
|
||||
:src="imgUrl"
|
||||
:mode="imgMode"
|
||||
class="images-img"
|
||||
:style="imgStyle"
|
||||
:show-menu-by-longpress="isQrCode"
|
||||
@load="onImgLoad"
|
||||
@error="onImgError"
|
||||
></image>
|
||||
<!-- 占位图 -->
|
||||
<view v-else class="images-placeholder">
|
||||
<text class="placeholder-text">暂无图片</text>
|
||||
</view>
|
||||
</navigator>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'home_image',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
imgError: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const debug = uni.getStorageSync('DEBUG_DIY_RENDER') === true
|
||||
if (!debug) return
|
||||
console.log('[DIY][component]', 'home_image', 'mounted', {
|
||||
id: this.dataConfig?.id,
|
||||
timestamp: this.dataConfig?.timestamp,
|
||||
url: this.imgConfig?.url || this.dataConfig?.imgConfig?.url
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
// 图片配置
|
||||
imgConfig() {
|
||||
return this.dataConfig.imgConfig || {}
|
||||
},
|
||||
// 链接配置
|
||||
linkConfig() {
|
||||
return this.dataConfig.linkConfig || {}
|
||||
},
|
||||
// 二维码模式
|
||||
isQrCode() {
|
||||
return this.dataConfig.isQrCode?.val === true
|
||||
},
|
||||
// 上边距
|
||||
topConfig() {
|
||||
return this.dataConfig.topConfig || {}
|
||||
},
|
||||
// 下边距
|
||||
bottomConfig() {
|
||||
return this.dataConfig.bottomConfig || {}
|
||||
},
|
||||
// 左右边距
|
||||
prConfig() {
|
||||
return this.dataConfig.prConfig || {}
|
||||
},
|
||||
// 页面间距
|
||||
mbConfig() {
|
||||
return this.dataConfig.mbConfig || {}
|
||||
},
|
||||
// 圆角配置
|
||||
fillet() {
|
||||
return this.dataConfig.fillet || {}
|
||||
},
|
||||
// 背景颜色
|
||||
bgColor() {
|
||||
return this.dataConfig.bgColor || {}
|
||||
},
|
||||
// 图片地址
|
||||
imgUrl() {
|
||||
const url = this.imgConfig.url || ''
|
||||
if (!url) return ''
|
||||
// 处理安全域名
|
||||
if (url.indexOf('https://') > -1) return url
|
||||
return url.replace('http://', 'https://')
|
||||
},
|
||||
// 链接地址(从 imgConfig.link 获取)
|
||||
linkUrl() {
|
||||
// 直接从 imgConfig.link 获取字符串链接
|
||||
const link = this.imgConfig.link || this.linkConfig?.link || ''
|
||||
if (!link) return ''
|
||||
// 支持字符串链接
|
||||
if (typeof link === 'string') {
|
||||
return link
|
||||
}
|
||||
// 支持对象结构 { url: '', title: '' }
|
||||
if (typeof link === 'object') {
|
||||
return link.url || ''
|
||||
}
|
||||
// 兼容旧的数组结构
|
||||
if (Array.isArray(link) && link.length > 0) {
|
||||
return link[0]?.link || link[0]?.url || ''
|
||||
}
|
||||
return ''
|
||||
},
|
||||
// 图片显示模式
|
||||
imgMode() {
|
||||
return 'widthFix'
|
||||
},
|
||||
// 容器样式
|
||||
containerStyle() {
|
||||
const style = {}
|
||||
|
||||
// 上边距
|
||||
if (this.topConfig.val) {
|
||||
style.marginTop = this.topConfig.val + 'rpx'
|
||||
}
|
||||
|
||||
// 页面间距
|
||||
if (this.mbConfig.val) {
|
||||
style.marginBottom = this.mbConfig.val + 'rpx'
|
||||
}
|
||||
|
||||
// 下边距
|
||||
if (this.bottomConfig.val) {
|
||||
style.paddingBottom = this.bottomConfig.val + 'rpx'
|
||||
}
|
||||
|
||||
// 背景颜色
|
||||
if (this.bgColor.color && this.bgColor.color[0]?.item) {
|
||||
style.backgroundColor = this.bgColor.color[0].item
|
||||
}
|
||||
|
||||
return style
|
||||
},
|
||||
// 图片容器样式
|
||||
imgContainerStyle() {
|
||||
const style = {}
|
||||
const fillet = this.fillet
|
||||
|
||||
// 左右边距
|
||||
if (this.prConfig.val) {
|
||||
style.paddingLeft = this.prConfig.val + 'rpx'
|
||||
style.paddingRight = this.prConfig.val + 'rpx'
|
||||
}
|
||||
|
||||
// 圆角 - 全部圆角模式
|
||||
if (fillet.type === 0 && fillet.val) {
|
||||
style.borderRadius = fillet.val + 'rpx'
|
||||
}
|
||||
|
||||
return style
|
||||
},
|
||||
// 图片样式
|
||||
imgStyle() {
|
||||
const style = {}
|
||||
const fillet = this.fillet
|
||||
|
||||
// 圆角 - 单独设置模式
|
||||
if (fillet.type === 1 && fillet.valList) {
|
||||
const [tl, tr, br, bl] = fillet.valList
|
||||
const radius = `${tl?.val || 0}rpx ${tr?.val || 0}rpx ${br?.val || 0}rpx ${bl?.val || 0}rpx`
|
||||
style.borderRadius = radius
|
||||
}
|
||||
|
||||
return style
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onImgLoad(e) {
|
||||
const debug = uni.getStorageSync('DEBUG_DIY_RENDER') === true
|
||||
if (!debug) return
|
||||
console.log('[DIY][component]', 'home_image', 'img_load', {
|
||||
id: this.dataConfig?.id,
|
||||
timestamp: this.dataConfig?.timestamp,
|
||||
src: this.imgUrl,
|
||||
width: e?.detail?.width,
|
||||
height: e?.detail?.height
|
||||
})
|
||||
},
|
||||
// 图片加载失败处理
|
||||
onImgError(e) {
|
||||
const debug = uni.getStorageSync('DEBUG_DIY_RENDER') === true
|
||||
if (debug) {
|
||||
console.log('[DIY][component]', 'home_image', 'img_error', {
|
||||
id: this.dataConfig?.id,
|
||||
timestamp: this.dataConfig?.timestamp,
|
||||
src: this.imgUrl,
|
||||
detail: e?.detail
|
||||
})
|
||||
}
|
||||
this.imgError = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.images-component {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
.images-navigator {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.images-img {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.images-placeholder {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.placeholder-text {
|
||||
color: #999;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,216 +1,216 @@
|
||||
<template>
|
||||
<view v-show="!isHidden" class="page-title-wrap" :style="wrapStyleStr">
|
||||
<view class="page-title-box px-20" :style="pageTitleBoxStyleStr">
|
||||
<view class="nav-inner" :style="navInnerStyleStr">
|
||||
<view class="side" :style="leftSideStyleStr" @tap="onBack">
|
||||
<text class="iconfont icon-ic_leftarrow" :style="iconStyleStr"></text>
|
||||
</view>
|
||||
<view class="title" :style="titleStyleStr">{{ titleText }}</view>
|
||||
<view class="side" :style="rightSideStyleStr"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'pageTopbar',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
__statusBarRpx: 0,
|
||||
__statusBarPx: 0,
|
||||
__rpx2px: 0.5,
|
||||
__navHeightPx: 44
|
||||
}
|
||||
},
|
||||
created() {
|
||||
try {
|
||||
const info = uni.getWindowInfo ? uni.getWindowInfo() : uni.getSystemInfoSync()
|
||||
const statusBarPx = Number(info?.statusBarHeight || 0)
|
||||
const windowWidthPx = Number(info?.windowWidth || 375)
|
||||
this.__statusBarPx = statusBarPx
|
||||
this.__rpx2px = windowWidthPx ? windowWidthPx / 750 : 0.5
|
||||
this.__navHeightPx = 80 * this.__rpx2px
|
||||
this.__statusBarRpx = windowWidthPx ? (statusBarPx * 750) / windowWidthPx : 0
|
||||
} catch (e) {
|
||||
this.__statusBarPx = 0
|
||||
this.__rpx2px = 0.5
|
||||
this.__navHeightPx = 44
|
||||
this.__statusBarRpx = 0
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const debug = uni.getStorageSync('DEBUG_DIY_RENDER') === true
|
||||
if (!debug) return
|
||||
console.log('[DIY][component]', 'pageTopbar', 'mounted', {
|
||||
id: this.dataConfig?.id,
|
||||
timestamp: this.dataConfig?.timestamp,
|
||||
title: this.dataConfig?.titleConfig?.value,
|
||||
statusBarRpx: this.__statusBarRpx,
|
||||
statusBarPx: this.__statusBarPx,
|
||||
rpx2px: this.__rpx2px,
|
||||
navHeightPx: this.__navHeightPx,
|
||||
sideWidthPx: this.sideWidthPx
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
try {
|
||||
uni.createSelectorQuery()
|
||||
.in(this)
|
||||
.select('.page-title-wrap')
|
||||
.boundingClientRect(rect => {
|
||||
console.log('[DIY][component]', 'pageTopbar', 'rect', rect)
|
||||
})
|
||||
.select('.page-title-box')
|
||||
.boundingClientRect(rect => {
|
||||
console.log('[DIY][component]', 'pageTopbar', 'rect_box', rect)
|
||||
})
|
||||
.select('.nav-inner')
|
||||
.boundingClientRect(rect => {
|
||||
console.log('[DIY][component]', 'pageTopbar', 'rect_inner', rect)
|
||||
})
|
||||
.exec()
|
||||
} catch (e) {}
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
isHidden() {
|
||||
return this.dataConfig?.isHide === true || this.dataConfig?.isHide === '1'
|
||||
},
|
||||
titleText() {
|
||||
return this.dataConfig?.titleConfig?.value || ''
|
||||
},
|
||||
linkValue() {
|
||||
return this.dataConfig?.linkConfig?.value || ''
|
||||
},
|
||||
themeColorValue() {
|
||||
return this.dataConfig?.themeColor?.color?.[0]?.item || '#282828'
|
||||
},
|
||||
titleColorValue() {
|
||||
return this.dataConfig?.titleColor?.color?.[0]?.item || '#282828'
|
||||
},
|
||||
bgColorValue() {
|
||||
return this.dataConfig?.bgColor?.color?.[0]?.item || '#ffffff'
|
||||
},
|
||||
fontSizeVal() {
|
||||
return Number(this.dataConfig?.fontSize?.val ?? 16)
|
||||
},
|
||||
iconSizeVal() {
|
||||
return Number(this.dataConfig?.iconSize?.val ?? 18)
|
||||
},
|
||||
navHeightRpx() {
|
||||
return 80
|
||||
},
|
||||
topVal() {
|
||||
return Number(this.dataConfig?.topConfig?.val ?? 0)
|
||||
},
|
||||
bottomVal() {
|
||||
return Number(this.dataConfig?.bottomConfig?.val ?? 0)
|
||||
},
|
||||
prVal() {
|
||||
return Number(this.dataConfig?.prConfig?.val ?? 0)
|
||||
},
|
||||
mbVal() {
|
||||
return Number(this.dataConfig?.mbConfig?.val ?? 0)
|
||||
},
|
||||
fillet() {
|
||||
return this.dataConfig?.fillet || {}
|
||||
},
|
||||
wrapStyleStr() {
|
||||
const top = this.topVal * 2
|
||||
const padTop = Math.max(0, Number(top))
|
||||
return `background:#f5f5f5;margin-top:${this.mbVal * 2}rpx;padding-top:${padTop}rpx;padding-bottom:${this.bottomVal * 2}rpx;padding-left:${this.prVal * 2}rpx;padding-right:${this.prVal * 2}rpx;`
|
||||
},
|
||||
pageTitleBoxStyleStr() {
|
||||
const base = `width:100%;display:flex;align-items:center;padding-top:${this.__statusBarPx}px;box-sizing:border-box;`
|
||||
const bg = `background:${this.bgColorValue};`
|
||||
let radius = ''
|
||||
if (this.fillet.type === 0 && this.fillet.val !== undefined) {
|
||||
radius = `border-radius:${Number(this.fillet.val) * 2}rpx;`
|
||||
}
|
||||
if (this.fillet.type === 1 && Array.isArray(this.fillet.valList)) {
|
||||
const [tl, tr, br, bl] = this.fillet.valList
|
||||
radius = `border-radius:${Number(tl?.val || 0) * 2}rpx ${Number(tr?.val || 0) * 2}rpx ${Number(br?.val || 0) * 2}rpx ${Number(bl?.val || 0) * 2}rpx;`
|
||||
}
|
||||
return base + bg + radius
|
||||
},
|
||||
navInnerStyleStr() {
|
||||
return `width:100%;display:flex;align-items:center;height:${this.__navHeightPx}px;box-sizing:border-box;`
|
||||
},
|
||||
leftSideStyleStr() {
|
||||
return `width:${this.sideWidthPx}px;height:100%;display:flex;align-items:center;justify-content:flex-start;`
|
||||
},
|
||||
rightSideStyleStr() {
|
||||
return `width:${this.sideWidthPx}px;height:100%;display:flex;align-items:center;justify-content:flex-end;`
|
||||
},
|
||||
iconStyleStr() {
|
||||
return `font-size:${this.iconSizeVal * 2}rpx;color:${this.themeColorValue};font-weight:bold;`
|
||||
},
|
||||
titleStyleStr() {
|
||||
return `font-size:${this.fontSizeVal * 2}rpx;color:${this.titleColorValue};flex:1;font-weight:bold;text-align:center;line-height:${this.__navHeightPx}px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;`
|
||||
},
|
||||
sideWidthRpx() {
|
||||
return Math.max(80, this.iconSizeVal * 2 + 28)
|
||||
},
|
||||
sideWidth() {
|
||||
return `${this.sideWidthRpx}rpx`
|
||||
},
|
||||
sideWidthPx() {
|
||||
return this.sideWidthRpx * (this.__rpx2px || 0.5)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onBack() {
|
||||
const url = this.linkValue
|
||||
if (!url) return
|
||||
const pure = url.split('?')[0]
|
||||
const tabPages = [
|
||||
'/pages/index/index',
|
||||
'/pages/goods_cate/goods_cate',
|
||||
'/pages/discoverIndex/index',
|
||||
'/pages/order_addcart/order_addcart',
|
||||
'/pages/user/index'
|
||||
]
|
||||
if (tabPages.includes(pure)) {
|
||||
uni.switchTab({ url })
|
||||
return
|
||||
}
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-title-wrap {
|
||||
width: 100%;
|
||||
}
|
||||
.page-title-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.nav-inner {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.side {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.title {
|
||||
flex: 1;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view v-show="!isHidden" class="page-title-wrap" :style="wrapStyleStr">
|
||||
<view class="page-title-box px-20" :style="pageTitleBoxStyleStr">
|
||||
<view class="nav-inner" :style="navInnerStyleStr">
|
||||
<view class="side" :style="leftSideStyleStr" @tap="onBack">
|
||||
<text class="iconfont icon-ic_leftarrow" :style="iconStyleStr"></text>
|
||||
</view>
|
||||
<view class="title" :style="titleStyleStr">{{ titleText }}</view>
|
||||
<view class="side" :style="rightSideStyleStr"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'pageTopbar',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
__statusBarRpx: 0,
|
||||
__statusBarPx: 0,
|
||||
__rpx2px: 0.5,
|
||||
__navHeightPx: 44
|
||||
}
|
||||
},
|
||||
created() {
|
||||
try {
|
||||
const info = uni.getWindowInfo ? uni.getWindowInfo() : uni.getSystemInfoSync()
|
||||
const statusBarPx = Number(info?.statusBarHeight || 0)
|
||||
const windowWidthPx = Number(info?.windowWidth || 375)
|
||||
this.__statusBarPx = statusBarPx
|
||||
this.__rpx2px = windowWidthPx ? windowWidthPx / 750 : 0.5
|
||||
this.__navHeightPx = 80 * this.__rpx2px
|
||||
this.__statusBarRpx = windowWidthPx ? (statusBarPx * 750) / windowWidthPx : 0
|
||||
} catch (e) {
|
||||
this.__statusBarPx = 0
|
||||
this.__rpx2px = 0.5
|
||||
this.__navHeightPx = 44
|
||||
this.__statusBarRpx = 0
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const debug = uni.getStorageSync('DEBUG_DIY_RENDER') === true
|
||||
if (!debug) return
|
||||
console.log('[DIY][component]', 'pageTopbar', 'mounted', {
|
||||
id: this.dataConfig?.id,
|
||||
timestamp: this.dataConfig?.timestamp,
|
||||
title: this.dataConfig?.titleConfig?.value,
|
||||
statusBarRpx: this.__statusBarRpx,
|
||||
statusBarPx: this.__statusBarPx,
|
||||
rpx2px: this.__rpx2px,
|
||||
navHeightPx: this.__navHeightPx,
|
||||
sideWidthPx: this.sideWidthPx
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
try {
|
||||
uni.createSelectorQuery()
|
||||
.in(this)
|
||||
.select('.page-title-wrap')
|
||||
.boundingClientRect(rect => {
|
||||
console.log('[DIY][component]', 'pageTopbar', 'rect', rect)
|
||||
})
|
||||
.select('.page-title-box')
|
||||
.boundingClientRect(rect => {
|
||||
console.log('[DIY][component]', 'pageTopbar', 'rect_box', rect)
|
||||
})
|
||||
.select('.nav-inner')
|
||||
.boundingClientRect(rect => {
|
||||
console.log('[DIY][component]', 'pageTopbar', 'rect_inner', rect)
|
||||
})
|
||||
.exec()
|
||||
} catch (e) {}
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
isHidden() {
|
||||
return this.dataConfig?.isHide === true || this.dataConfig?.isHide === '1'
|
||||
},
|
||||
titleText() {
|
||||
return this.dataConfig?.titleConfig?.value || ''
|
||||
},
|
||||
linkValue() {
|
||||
return this.dataConfig?.linkConfig?.value || ''
|
||||
},
|
||||
themeColorValue() {
|
||||
return this.dataConfig?.themeColor?.color?.[0]?.item || '#282828'
|
||||
},
|
||||
titleColorValue() {
|
||||
return this.dataConfig?.titleColor?.color?.[0]?.item || '#282828'
|
||||
},
|
||||
bgColorValue() {
|
||||
return this.dataConfig?.bgColor?.color?.[0]?.item || '#ffffff'
|
||||
},
|
||||
fontSizeVal() {
|
||||
return Number(this.dataConfig?.fontSize?.val ?? 16)
|
||||
},
|
||||
iconSizeVal() {
|
||||
return Number(this.dataConfig?.iconSize?.val ?? 18)
|
||||
},
|
||||
navHeightRpx() {
|
||||
return 80
|
||||
},
|
||||
topVal() {
|
||||
return Number(this.dataConfig?.topConfig?.val ?? 0)
|
||||
},
|
||||
bottomVal() {
|
||||
return Number(this.dataConfig?.bottomConfig?.val ?? 0)
|
||||
},
|
||||
prVal() {
|
||||
return Number(this.dataConfig?.prConfig?.val ?? 0)
|
||||
},
|
||||
mbVal() {
|
||||
return Number(this.dataConfig?.mbConfig?.val ?? 0)
|
||||
},
|
||||
fillet() {
|
||||
return this.dataConfig?.fillet || {}
|
||||
},
|
||||
wrapStyleStr() {
|
||||
const top = this.topVal * 2
|
||||
const padTop = Math.max(0, Number(top))
|
||||
return `background:#f5f5f5;margin-top:${this.mbVal * 2}rpx;padding-top:${padTop}rpx;padding-bottom:${this.bottomVal * 2}rpx;padding-left:${this.prVal * 2}rpx;padding-right:${this.prVal * 2}rpx;`
|
||||
},
|
||||
pageTitleBoxStyleStr() {
|
||||
const base = `width:100%;display:flex;align-items:center;padding-top:${this.__statusBarPx}px;box-sizing:border-box;`
|
||||
const bg = `background:${this.bgColorValue};`
|
||||
let radius = ''
|
||||
if (this.fillet.type === 0 && this.fillet.val !== undefined) {
|
||||
radius = `border-radius:${Number(this.fillet.val) * 2}rpx;`
|
||||
}
|
||||
if (this.fillet.type === 1 && Array.isArray(this.fillet.valList)) {
|
||||
const [tl, tr, br, bl] = this.fillet.valList
|
||||
radius = `border-radius:${Number(tl?.val || 0) * 2}rpx ${Number(tr?.val || 0) * 2}rpx ${Number(br?.val || 0) * 2}rpx ${Number(bl?.val || 0) * 2}rpx;`
|
||||
}
|
||||
return base + bg + radius
|
||||
},
|
||||
navInnerStyleStr() {
|
||||
return `width:100%;display:flex;align-items:center;height:${this.__navHeightPx}px;box-sizing:border-box;`
|
||||
},
|
||||
leftSideStyleStr() {
|
||||
return `width:${this.sideWidthPx}px;height:100%;display:flex;align-items:center;justify-content:flex-start;`
|
||||
},
|
||||
rightSideStyleStr() {
|
||||
return `width:${this.sideWidthPx}px;height:100%;display:flex;align-items:center;justify-content:flex-end;`
|
||||
},
|
||||
iconStyleStr() {
|
||||
return `font-size:${this.iconSizeVal * 2}rpx;color:${this.themeColorValue};font-weight:bold;`
|
||||
},
|
||||
titleStyleStr() {
|
||||
return `font-size:${this.fontSizeVal * 2}rpx;color:${this.titleColorValue};flex:1;font-weight:bold;text-align:center;line-height:${this.__navHeightPx}px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;`
|
||||
},
|
||||
sideWidthRpx() {
|
||||
return Math.max(80, this.iconSizeVal * 2 + 28)
|
||||
},
|
||||
sideWidth() {
|
||||
return `${this.sideWidthRpx}rpx`
|
||||
},
|
||||
sideWidthPx() {
|
||||
return this.sideWidthRpx * (this.__rpx2px || 0.5)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onBack() {
|
||||
const url = this.linkValue
|
||||
if (!url) return
|
||||
const pure = url.split('?')[0]
|
||||
const tabPages = [
|
||||
'/pages/index/index',
|
||||
'/pages/goods_cate/goods_cate',
|
||||
'/pages/discoverIndex/index',
|
||||
'/pages/order_addcart/order_addcart',
|
||||
'/pages/user/index'
|
||||
]
|
||||
if (tabPages.includes(pure)) {
|
||||
uni.switchTab({ url })
|
||||
return
|
||||
}
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-title-wrap {
|
||||
width: 100%;
|
||||
}
|
||||
.page-title-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.nav-inner {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.side {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.title {
|
||||
flex: 1;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,102 +1,102 @@
|
||||
<template>
|
||||
<!-- 富文本 -->
|
||||
<view v-if="!dataConfig.isHide" :style="[richTextWrapStyle]">
|
||||
<view class="richText" v-if="description" :style="[richTextStyle]">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- <rich-text :nodes="description"></rich-text> -->
|
||||
<jyf-parser :html="description" :tag-style="tagStyle" ref="article"></jyf-parser>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 || APP-PLUS -->
|
||||
<view v-html="description"></view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import parser from '@/components/jyf-parser/jyf-parser';
|
||||
export default {
|
||||
name: 'richText',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
isSortType: {
|
||||
type: String | Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
components: { 'jyf-parser': parser },
|
||||
data() {
|
||||
return {
|
||||
bgColor: '',
|
||||
lrConfig: 0,
|
||||
udConfig: 0,
|
||||
tagStyle: {
|
||||
img: 'width:100%;display:block;',
|
||||
table: 'width:100%',
|
||||
video: 'width:100%;float:left;'
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
description() {
|
||||
let description = this.dataConfig.richText.val;
|
||||
if (description) {
|
||||
description = description.replace(
|
||||
/<img/gi,
|
||||
'<img style="max-width:100%;height:auto;float:left;display:block" '
|
||||
);
|
||||
description = description.replace(
|
||||
/<video/gi,
|
||||
'<video style="width:100%;height:auto;display:block" '
|
||||
);
|
||||
}
|
||||
return description;
|
||||
},
|
||||
richTextStyle() {
|
||||
let borderRadius = `${this.dataConfig.fillet.val * 2}rpx`;
|
||||
if (this.dataConfig.fillet.type) {
|
||||
borderRadius =
|
||||
`${this.dataConfig.fillet.valList[0].val * 2}rpx ${this.dataConfig.fillet.valList[1].val * 2}rpx ${this.dataConfig.fillet.valList[2].val * 2}rpx ${this.dataConfig.fillet.valList[3].val * 2}rpx`;
|
||||
}
|
||||
return {
|
||||
'border-radius': borderRadius,
|
||||
'background': this.dataConfig.bgColor.color[0].item,
|
||||
};
|
||||
},
|
||||
richTextWrapStyle() {
|
||||
return {
|
||||
'padding': `${this.dataConfig.topConfig.val * 2}rpx ${this.dataConfig.lrConfig.val * 2}rpx ${this.dataConfig.bottomConfig.val * 2}rpx`,
|
||||
'margin-top': `${this.dataConfig.udConfig.val * 2}rpx`,
|
||||
'background': this.dataConfig.bottomBgColor.color[0].item,
|
||||
};
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.richText {
|
||||
padding: 30rpx;
|
||||
background-color: #fff;
|
||||
|
||||
// margin: 0 20rpx;
|
||||
// border-radius: 24rpx;
|
||||
&::after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/uni-video {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/deep/video {
|
||||
width: 100% !important;
|
||||
}
|
||||
<template>
|
||||
<!-- 富文本 -->
|
||||
<view v-if="!dataConfig.isHide" :style="[richTextWrapStyle]">
|
||||
<view class="richText" v-if="description" :style="[richTextStyle]">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- <rich-text :nodes="description"></rich-text> -->
|
||||
<jyf-parser :html="description" :tag-style="tagStyle" ref="article"></jyf-parser>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 || APP-PLUS -->
|
||||
<view v-html="description"></view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import parser from '@/components/jyf-parser/jyf-parser';
|
||||
export default {
|
||||
name: 'richText',
|
||||
props: {
|
||||
dataConfig: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
isSortType: {
|
||||
type: String | Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
components: { 'jyf-parser': parser },
|
||||
data() {
|
||||
return {
|
||||
bgColor: '',
|
||||
lrConfig: 0,
|
||||
udConfig: 0,
|
||||
tagStyle: {
|
||||
img: 'width:100%;display:block;',
|
||||
table: 'width:100%',
|
||||
video: 'width:100%;float:left;'
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
description() {
|
||||
let description = this.dataConfig.richText.val;
|
||||
if (description) {
|
||||
description = description.replace(
|
||||
/<img/gi,
|
||||
'<img style="max-width:100%;height:auto;float:left;display:block" '
|
||||
);
|
||||
description = description.replace(
|
||||
/<video/gi,
|
||||
'<video style="width:100%;height:auto;display:block" '
|
||||
);
|
||||
}
|
||||
return description;
|
||||
},
|
||||
richTextStyle() {
|
||||
let borderRadius = `${this.dataConfig.fillet.val * 2}rpx`;
|
||||
if (this.dataConfig.fillet.type) {
|
||||
borderRadius =
|
||||
`${this.dataConfig.fillet.valList[0].val * 2}rpx ${this.dataConfig.fillet.valList[1].val * 2}rpx ${this.dataConfig.fillet.valList[2].val * 2}rpx ${this.dataConfig.fillet.valList[3].val * 2}rpx`;
|
||||
}
|
||||
return {
|
||||
'border-radius': borderRadius,
|
||||
'background': this.dataConfig.bgColor.color[0].item,
|
||||
};
|
||||
},
|
||||
richTextWrapStyle() {
|
||||
return {
|
||||
'padding': `${this.dataConfig.topConfig.val * 2}rpx ${this.dataConfig.lrConfig.val * 2}rpx ${this.dataConfig.bottomConfig.val * 2}rpx`,
|
||||
'margin-top': `${this.dataConfig.udConfig.val * 2}rpx`,
|
||||
'background': this.dataConfig.bottomBgColor.color[0].item,
|
||||
};
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.richText {
|
||||
padding: 30rpx;
|
||||
background-color: #fff;
|
||||
|
||||
// margin: 0 20rpx;
|
||||
// border-radius: 24rpx;
|
||||
&::after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/uni-video {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/deep/video {
|
||||
width: 100% !important;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user