- 修复 uni-popup-dialog/uni-data-picker keypress.js 中 $once 在 H5 端报错(改用生命周期钩子清理监听) - main.js 补 $delete globalProperties polyfill(z-paging 自动高度逻辑依赖) - App.vue onLaunch 补设备信息初始化,修复 X-Device-Id 恒为 unknown - 68 处 ::v-deep、/deep/ 旧深度选择器替换为 :deep()(含 login-page.scss) - zetank-personalpage 组件 .sync 修饰符改为 v-model:xxx(Vue3 已移除 .sync) - vite.config.js HBuilderX 路径支持 HBUILDERX_HOME 环境变量覆盖 - 根 package.json 清理 image-grid 插件遗留元数据 - 收录此前未提交的 uView Vue3 兜底补丁(common/uview-init.js 及各组件 props.js)
651 lines
15 KiB
Vue
651 lines
15 KiB
Vue
<template>
|
||
<view class="body">
|
||
<uni-nav-bar
|
||
title="预览"
|
||
leftText="取消"
|
||
left-icon="left"
|
||
right-text="完成"
|
||
backgroundColor="#ffffff"
|
||
color="#000000"
|
||
@clickRight="success()"
|
||
@clickLeft="back()">
|
||
</uni-nav-bar>
|
||
|
||
<view class="v-preview" v-if="temp && temp.temptele_src">
|
||
<image :src="temp.temptele_src" alt="" class="img" mode="widthFix" />
|
||
</view>
|
||
|
||
<view class="" :style="backgrond_color">
|
||
<u-parse :content="titleContent"></u-parse>
|
||
|
||
<view class="">
|
||
<view class="meta">
|
||
<view class="author">
|
||
<cloud-image
|
||
height="64rpx" width="64rpx" borderRadius="50%"
|
||
:src="userInfo.avatar_file.url"></cloud-image>
|
||
<text class="at" :style="color">{{ userInfo.nickname || '' }}</text>
|
||
<text class="split">·</text>
|
||
<text class="date" :style="color">刚刚</text>
|
||
</view>
|
||
</view>
|
||
<view class="">
|
||
<view class="" v-for="(item, index) in cms.cmsLst" :key="index">
|
||
<u-parse
|
||
:content="item.html"
|
||
v-if="item.type === 'image' || item.type === 'video'">
|
||
</u-parse>
|
||
<view class="" v-if="item.type === 'image'"
|
||
style="width: 100wv;margin-top: 30rpx;margin-bottom: 30rpx;">
|
||
<cloud-image
|
||
width="100%"
|
||
height="500rpx"
|
||
mode="aspectFit"
|
||
:src="item.image.src">
|
||
</cloud-image>
|
||
</view>
|
||
<view class="" v-if="item.type === 'video'"
|
||
style="width: 100wv;margin-top: 30rpx;margin-bottom: 30rpx;">
|
||
<video
|
||
style="width: 100%; height: 500rpx;"
|
||
:src="item.video.src"
|
||
enable-danmu
|
||
danmu-btn
|
||
controls>
|
||
</video>
|
||
</view>
|
||
|
||
<view class="" v-if="item.type === 'vote'">
|
||
<uni-card>
|
||
<view class="vote-container">
|
||
<text class="vote-title">{{ item.vote.voteTitle }}</text>
|
||
<text class="deadline">截止时间:{{ item.vote.datetime }}</text>
|
||
<view class="" v-if="item.vote.type === voteType[0]">
|
||
<u-radio-group
|
||
v-model="item.vote.selectValue"
|
||
placement="column"
|
||
@change="groupChange"
|
||
wrap
|
||
>
|
||
|
||
<u-radio
|
||
:customStyle="{marginBottom: '8px'}"
|
||
v-for="(radio, radioIndex) in item.vote.voteLst"
|
||
:key="radioIndex"
|
||
:label="radio.value"
|
||
:name="radio.value"
|
||
@change="radioChange"
|
||
style="width: 100%;"
|
||
>
|
||
</u-radio>
|
||
</u-radio-group>
|
||
</view>
|
||
|
||
<view class="" v-if="item.vote.type === voteType[1]">
|
||
<u-checkbox-group
|
||
v-model="item.vote.selectValue"
|
||
placement="column"
|
||
@change="checkboxChange"
|
||
>
|
||
<u-checkbox
|
||
:customStyle="{marginBottom: '8px'}"
|
||
v-for="(checkbox, checkboxIndex) in item.vote.voteLst"
|
||
:key="checkboxIndex"
|
||
:label="checkbox.value"
|
||
:name="checkbox.value"
|
||
>
|
||
</u-checkbox>
|
||
</u-checkbox-group>
|
||
</view>
|
||
|
||
<view class="" v-if="item.vote.type === voteType[2]">
|
||
<u-checkbox-group
|
||
v-model="item.vote.selectValue"
|
||
placement="column"
|
||
@change="checkboxChange"
|
||
|
||
>
|
||
<view class="">
|
||
<u-checkbox
|
||
:customStyle="{marginBottom: '8px'}"
|
||
v-for="(checkbox, checkboxIndex) in item.vote.voteLst"
|
||
:key="checkboxIndex"
|
||
:label="checkbox.value"
|
||
:name="checkbox.value"
|
||
:disabled="isCheckboxDisabled(item.vote.selectValue, checkbox.value)"
|
||
>
|
||
</u-checkbox>
|
||
</view>
|
||
|
||
</u-checkbox-group>
|
||
</view>
|
||
<view class=""
|
||
v-if="isExpired"
|
||
:disabled="isExpired || !selectedValue"
|
||
style="border-top: 3rpx solid #ccc;padding-top: 20rpx;margin-top: 20rpx;
|
||
text-align: center;;">
|
||
已截止
|
||
</view>
|
||
|
||
<view class=""
|
||
v-else
|
||
:disabled="isExpired || !selectedValue"
|
||
style="border-top: 3rpx solid #ccc;padding-top: 20rpx;margin-top: 20rpx;
|
||
text-align: center;;">
|
||
{{ isExpired ? '已截止' : '点击登录后投票' }}
|
||
</view>
|
||
</view>
|
||
</uni-card>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<u-tabbar :value="tabbarValue"
|
||
>
|
||
<u-tabbar-item
|
||
v-for="(item, index) in tabbarText"
|
||
:key="index"
|
||
@click="tabbarClick"
|
||
:text="item.text">
|
||
</u-tabbar-item>
|
||
</u-tabbar>
|
||
|
||
<hqs-popup :title="tabbarText[tabbarValue].text" :from="popFrom" :mask-click="maskClick"
|
||
@back="onBack"
|
||
v-model="showPop">
|
||
<view class="page-container" v-if="tabbarText[tabbarValue].text === '模板'">
|
||
<media-list
|
||
:dataType="'template'"
|
||
:pageSize="12"
|
||
:currentTemplate="updateTemplateConfig"
|
||
@update="updateTemplate"
|
||
/>
|
||
</view>
|
||
|
||
<view class="page-container" v-if="tabbarText[tabbarValue].text === '音乐'">
|
||
<media-list
|
||
:dataType="'music'"
|
||
:pageSize="12"
|
||
:currentTemplate="updateTemplateConfig"
|
||
@update="updateTemplate"
|
||
/>
|
||
</view>
|
||
|
||
<view class="page-container" v-if="tabbarText[tabbarValue].text === '排版'">
|
||
</view>
|
||
</hqs-popup>
|
||
|
||
<uni-grid :column="3" :highlight="true" @change="change" :show-border="false">
|
||
<uni-grid-item v-for="(item, index) in gridLst" :index="index" :key="index">
|
||
<view class="grid-item-box">
|
||
<uni-icons :type="item.icon" :size="30"
|
||
:color="item.select_flag?select_icon_color:icon_color" />
|
||
<text class="text" :style="item.select_flag?select_font_color:icon_font_color">
|
||
{{item.value?item.value:0}}
|
||
</text>
|
||
</view>
|
||
</uni-grid-item>
|
||
</uni-grid>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { ref, computed } from 'vue'
|
||
import { onShow } from '@dcloudio/uni-app'
|
||
import { store } from '@/pages3/uni_modules/uni-id-pages/common/store.js'
|
||
import uRadioGroup from "@/uni_modules/uview-ui/components/u-radio-group/u-radio-group.vue"
|
||
import uRadio from "@/uni_modules/uview-ui/components/u-radio/u-radio.vue"
|
||
import uParse from "@/uni_modules/uview-ui/components/u-parse/u-parse.vue"
|
||
import uTabbar from "@/uni_modules/uview-ui/components/u-tabbar/u-tabbar.vue"
|
||
import uTabbarItem from "@/uni_modules/uview-ui/components/u-tabbar-item/u-tabbar-item.vue"
|
||
import mediaList from "@/components/image-grid/media-list.vue"
|
||
import cloudImage from "@/components/cloud-image.vue"
|
||
import uCheckboxGroup from "@/uni_modules/uview-ui/components/u-checkbox-group/u-checkbox-group.vue"
|
||
import uCheckbox from "@/uni_modules/uview-ui/components/u-checkbox/u-checkbox.vue"
|
||
|
||
export default {
|
||
components: {
|
||
uTabbar,
|
||
uTabbarItem,
|
||
mediaList,
|
||
uParse,
|
||
cloudImage,
|
||
uRadioGroup,
|
||
uRadio,
|
||
uCheckboxGroup,
|
||
uCheckbox
|
||
},
|
||
setup() {
|
||
const voteType = ref(["单选(默认)", "多选,无限制", "多选, 最多两项"])
|
||
const voteEndTime = ref('2025-04-20 23:59:59')
|
||
const cms = ref({})
|
||
const temp = ref({})
|
||
const titleContent = ref("")
|
||
const tabbarValue = ref(0)
|
||
const showPop = ref(false)
|
||
const maskClick = ref(true)
|
||
const popFrom = ref('bottom')
|
||
const list = ref(new Array(20).fill(0))
|
||
const currentTemplate = ref("")
|
||
|
||
const tabbarText = ref([
|
||
{ text: "模板" },
|
||
{ text: "音乐" },
|
||
{ text: "排版" }
|
||
])
|
||
|
||
const userInfo = computed(() => store.userInfo)
|
||
const isExpired = computed(() => new Date() > new Date(voteEndTime.value))
|
||
|
||
const btn_send_commends_color = computed(() => {
|
||
if (!temp.value) return ""
|
||
return `background-color: ${temp.value.btn_send_commends_color};`
|
||
})
|
||
|
||
const backgrond_color = computed(() => {
|
||
if (!temp.value) return ""
|
||
return `background-color: ${temp.value.backgrond_color};`
|
||
})
|
||
|
||
const color = computed(() => {
|
||
if (!temp.value) return ""
|
||
return `color: ${temp.value.font_color};`
|
||
})
|
||
|
||
const select_icon_color = computed(() => {
|
||
if (!temp.value) return ""
|
||
return `${temp.value.select_icon_color};`
|
||
})
|
||
|
||
const icon_color = computed(() => {
|
||
if (!temp.value) return ""
|
||
return `${temp.value.icon_color};`
|
||
})
|
||
|
||
onShow(async () => {
|
||
let storedCms = uni.getStorageSync("cms")
|
||
titleContent.value = storedCms.title_html
|
||
cms.value = storedCms
|
||
await getTemp()
|
||
})
|
||
|
||
async function getTemp() {
|
||
if (currentTemplate.value === "not_image") {
|
||
temp.value = {}
|
||
}
|
||
if (!currentTemplate.value) {
|
||
temp.value = {}
|
||
return
|
||
}
|
||
const res = await uniCloud.importObject("uni-cms-articles").getTemp({
|
||
temp_id: currentTemplate.value
|
||
})
|
||
if (res.code === 200) {
|
||
temp.value = res.data
|
||
}
|
||
}
|
||
|
||
async function updateTemplate(e) {
|
||
currentTemplate.value = e
|
||
await getTemp()
|
||
}
|
||
|
||
function onBack() {
|
||
uni.showToast({ title: 'test' })
|
||
}
|
||
|
||
function tabbarClick(e) {
|
||
tabbarValue.value = e
|
||
showPopupFrom()
|
||
}
|
||
|
||
function showPopupFrom() {
|
||
showPop.value = true
|
||
}
|
||
|
||
function isCheckboxDisabled(arr, name) {
|
||
if (arr.length < 2 || arr.includes(name)) {
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
function checkboxChange(e) {
|
||
console.log(e)
|
||
}
|
||
|
||
function groupChange(n) {
|
||
console.log('groupChange', n)
|
||
}
|
||
|
||
function radioChange(n) {
|
||
console.log('radioChange', n)
|
||
}
|
||
|
||
function formatDate(date, format) {
|
||
const map = {
|
||
'yyyy': date.getFullYear(),
|
||
'MM': String(date.getMonth() + 1).padStart(2, '0'),
|
||
'dd': String(date.getDate()).padStart(2, '0'),
|
||
'HH': String(date.getHours()).padStart(2, '0'),
|
||
'mm': String(date.getMinutes()).padStart(2, '0'),
|
||
'ss': String(date.getSeconds()).padStart(2, '0')
|
||
}
|
||
return format.replace(/yyyy|MM|dd|HH|mm|ss/g, matched => map[matched])
|
||
}
|
||
|
||
function formatTime() {
|
||
return formatDate(new Date(), 'yyyy-MM-dd HH:mm')
|
||
}
|
||
|
||
async function success() {
|
||
let storedCms = uni.getStorageSync("cms")
|
||
let id = storedCms._id
|
||
let title = storedCms.title
|
||
let title_html = storedCms.title_html
|
||
let title_delta = storedCms.title_delta
|
||
let temp_id = currentTemplate.value
|
||
let edit_type = "mobile"
|
||
let view_count = 0
|
||
let article_status = 1
|
||
let user_id = userInfo.value._id
|
||
let cmsLst = storedCms.cmsLst
|
||
let excerpt = ""
|
||
let res = await uniCloud.importObject("user-info").getIP({ uid: userInfo.value._id })
|
||
let last_modify_ip = res.code === 200 ? res.data.last_login_ip : ""
|
||
|
||
if (id) {
|
||
let query = {
|
||
id,
|
||
title: storedCms.title,
|
||
user_id,
|
||
title_html: storedCms.title_html,
|
||
title_delta: storedCms.title_delta,
|
||
thumbnail: storedCms.thumbnail,
|
||
p_type: storedCms.p_type,
|
||
category_id: storedCms.category_id,
|
||
temp_id,
|
||
edit_type,
|
||
view_count,
|
||
cmsLst: storedCms.cmsLst,
|
||
excerpt,
|
||
last_modify_ip,
|
||
article_status,
|
||
}
|
||
await uniCloud.importObject("uni-cms-articles").update_cms_articles(query)
|
||
} else {
|
||
let query = {
|
||
title: storedCms.title,
|
||
user_id,
|
||
title_html: storedCms.title_html,
|
||
title_delta: storedCms.title_delta,
|
||
thumbnail: storedCms.thumbnail,
|
||
p_type: storedCms.p_type,
|
||
category_id: storedCms.category_id,
|
||
temp_id,
|
||
edit_type,
|
||
view_count,
|
||
cmsLst: storedCms.cmsLst,
|
||
excerpt,
|
||
last_modify_ip,
|
||
article_status,
|
||
}
|
||
await uniCloud.importObject("uni-cms-articles").add_cms_articles(query)
|
||
}
|
||
|
||
uni.setStorageSync("cms", "")
|
||
uni.switchTab({ url: "/pages/my/my" })
|
||
}
|
||
|
||
async function back() {
|
||
uni.navigateBack({
|
||
delta: 1,
|
||
fail: (err) => {
|
||
uni.navigateTo({ url: "/pages2/editCms/editCms" })
|
||
}
|
||
})
|
||
}
|
||
|
||
return {
|
||
voteType,
|
||
voteEndTime,
|
||
cms,
|
||
temp,
|
||
titleContent,
|
||
tabbarValue,
|
||
showPop,
|
||
maskClick,
|
||
popFrom,
|
||
list,
|
||
currentTemplate,
|
||
tabbarText,
|
||
userInfo,
|
||
isExpired,
|
||
btn_send_commends_color,
|
||
backgrond_color,
|
||
color,
|
||
select_icon_color,
|
||
icon_color,
|
||
getTemp,
|
||
updateTemplate,
|
||
onBack,
|
||
tabbarClick,
|
||
showPopupFrom,
|
||
isCheckboxDisabled,
|
||
checkboxChange,
|
||
groupChange,
|
||
radioChange,
|
||
formatDate,
|
||
formatTime,
|
||
success,
|
||
back,
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
|
||
.grid-container {
|
||
display: flex;
|
||
gap: 10px;
|
||
padding: 15px;
|
||
background: #f5f5f5;
|
||
}
|
||
|
||
.grid-item {
|
||
flex: 1;
|
||
min-width: 0;
|
||
aspect-ratio: 1;
|
||
background: white;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.page-container {
|
||
padding: 20rpx 0;
|
||
}
|
||
|
||
.rectangle-img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
aspect-ratio: 16/9;
|
||
}
|
||
|
||
.meta {
|
||
|
||
position: relative;
|
||
z-index: 1;
|
||
padding-top: 20rpx;
|
||
|
||
.title {
|
||
.text {
|
||
font-size: 40rpx;
|
||
line-height: 66rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
}
|
||
|
||
.excerpt {
|
||
margin-top: 10rpx;
|
||
|
||
.text {
|
||
font-size: 26rpx;
|
||
line-height: 40rpx;
|
||
color: #999;
|
||
}
|
||
}
|
||
|
||
.author {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-start;
|
||
flex-direction: row;
|
||
margin-top: 20rpx;
|
||
|
||
.at,
|
||
.split,
|
||
.date {
|
||
font-size: 26rpx;
|
||
color: #ccc;
|
||
}
|
||
|
||
.split {
|
||
margin: 0 10rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.body {
|
||
padding: 20rpx;
|
||
.cms-body {
|
||
display: flex;
|
||
min-height: 60hv;
|
||
width: 100wv;
|
||
}
|
||
}
|
||
|
||
.v-preview {
|
||
.img {
|
||
width: 100%;
|
||
}
|
||
|
||
.btn-area {
|
||
position: relative;
|
||
top: -50rpx;
|
||
}
|
||
|
||
.red-btn-area {
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 10rpx 0;
|
||
margin: 0 40rpx 20rpx 40rpx;
|
||
font-size: 20rpx;
|
||
|
||
.red-btn {
|
||
position: relative;
|
||
color: #fff;
|
||
font-weight: 700;
|
||
font-size: 24rpx;
|
||
height: 40rpx;
|
||
line-height: 40rpx;
|
||
margin: 0;
|
||
background-image: linear-gradient(to bottom, #c11c1f, #5c0201);
|
||
|
||
+.red-btn {
|
||
margin-left: 20rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.red-btn-plain-area {
|
||
display: flex;
|
||
justify-content: center;
|
||
padding: 10rpx 0;
|
||
margin: 0 40rpx;
|
||
font-size: 21rpx;
|
||
border-top: 2px solid;
|
||
border-bottom: 2px solid;
|
||
border-image: linear-gradient(to right,
|
||
#fff,
|
||
#f44336bf,
|
||
#b13636,
|
||
#f44336bf,
|
||
#fff) 1;
|
||
|
||
.red-btn-plain {
|
||
position: relative;
|
||
color: #b13636;
|
||
font-weight: 700;
|
||
padding-left: 15rpx;
|
||
|
||
+.red-btn-plain {
|
||
margin-left: 10rpx;
|
||
|
||
&::before {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 2px;
|
||
height: 20rpx;
|
||
background-color: #b13636;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
.vote-container {
|
||
padding: 20rpx;
|
||
}
|
||
|
||
.vote-title {
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
display: block;
|
||
margin-bottom: 10rpx;
|
||
}
|
||
|
||
.deadline {
|
||
font-size: 12px;
|
||
color: #999;
|
||
margin-bottom: 30rpx;
|
||
display: block;
|
||
}
|
||
|
||
.radio-group {
|
||
margin-bottom: 40rpx;
|
||
}
|
||
|
||
.option-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin: 15rpx 0;
|
||
}
|
||
|
||
.option-label {
|
||
margin-left: 20rpx;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.vote-btn {
|
||
background-color: #2979FF;
|
||
color: white;
|
||
border-radius: 8rpx;
|
||
font-size: 14px;
|
||
margin-top: 30rpx;
|
||
|
||
&[disabled] {
|
||
background-color: #CCCCCC;
|
||
}
|
||
}
|
||
</style>
|