首次完整推送,
V:1.20240808.006
This commit is contained in:
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<view
|
||||
:to="'/uni_modules/uni-cms-article/pages/detail/detail?id=' + data?._id"
|
||||
:key="data?._id"
|
||||
class="list-item not-cover"
|
||||
direction="column"
|
||||
>
|
||||
<view class="main">
|
||||
<view>
|
||||
<text class="title">{{ data?.title }}</text>
|
||||
</view>
|
||||
<view class="info">
|
||||
<text class="author">{{ data!.user_id!.length > 0 ? data!.user_id[0]!.nickname : '' }}</text>
|
||||
<text class="publish_date">{{ publishTime(data?.publish_date ?? 0) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
import { type PropType } from 'vue'
|
||||
|
||||
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time.uts";
|
||||
|
||||
type ArticleAuthor = {
|
||||
_id: string
|
||||
nickname: string
|
||||
}
|
||||
type ArticleItem = {
|
||||
_id: string
|
||||
title: string
|
||||
publish_date: number
|
||||
thumbnail: string[]
|
||||
user_id: ArticleAuthor[]
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "not-cover",
|
||||
props: {
|
||||
data: {
|
||||
type: Object as PropType<ArticleItem>
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 格式化时间戳
|
||||
publishTime(timestamp: number): string {
|
||||
return translatePublishTime(timestamp)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./style.scss";
|
||||
</style>
|
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<uni-list-item
|
||||
:to="'/uni_modules/uni-cms-article/pages/detail/detail?id=' + data._id"
|
||||
:key="data._id"
|
||||
class="list-item not-cover"
|
||||
direction="column"
|
||||
>
|
||||
<template v-slot:body>
|
||||
<view class="main">
|
||||
<view>
|
||||
<text class="title">{{ data.title }}</text>
|
||||
</view>
|
||||
<view class="info">
|
||||
<text class="author">{{ data.user_id[0] ? data.user_id[0].nickname : '' }}</text>
|
||||
<text class="publish_date">{{ publishTime(data.publish_date) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</uni-list-item>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time";
|
||||
|
||||
export default {
|
||||
name: "not-cover",
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 格式化时间戳
|
||||
publishTime(timestamp) {
|
||||
return translatePublishTime(timestamp)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./style.scss";
|
||||
</style>
|
@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<view
|
||||
:to="'/uni_modules/uni-cms-article/pages/detail/detail?id=' + data?._id"
|
||||
:key="data?._id"
|
||||
class="list-item"
|
||||
>
|
||||
<view class="main">
|
||||
<text class="title">{{ data?.title }}</text>
|
||||
<view class="info">
|
||||
<text class="author">{{ data!.user_id!.length > 0 ? data!.user_id[0]!.nickname : '' }}</text>
|
||||
<text class="publish_date">{{ publishTime(data?.publish_date ?? 0) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<image class="thumbnail" :src="data!.thumbnail[0]" mode="aspectFill"></image>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
import { type PropType } from 'vue'
|
||||
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time.uts";
|
||||
type ArticleAuthor = {
|
||||
_id: string
|
||||
nickname: string
|
||||
}
|
||||
type ArticleItem = {
|
||||
_id: string
|
||||
title: string
|
||||
publish_date: number
|
||||
thumbnail: string[]
|
||||
user_id: ArticleAuthor[]
|
||||
}
|
||||
export default {
|
||||
name: "right-small-cover",
|
||||
props: {
|
||||
data: {
|
||||
type: Object as PropType<ArticleItem>
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 格式化时间戳
|
||||
publishTime(timestamp: number): string {
|
||||
return translatePublishTime(timestamp)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./style.scss";
|
||||
</style>
|
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<uni-list-item
|
||||
:to="'/uni_modules/uni-cms-article/pages/detail/detail?id=' + data._id"
|
||||
:key="data._id"
|
||||
class="list-item"
|
||||
>
|
||||
<template v-slot:body>
|
||||
<view class="main">
|
||||
<text class="title">{{ data.title }}</text>
|
||||
<view class="info">
|
||||
<text class="author">{{ data.user_id[0] ? data.user_id[0].nickname : '' }}</text>
|
||||
<text class="publish_date">{{ publishTime(data.publish_date) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<image class="thumbnail" :src="data.thumbnail[0]" mode="aspectFill"></image>
|
||||
</template>
|
||||
</uni-list-item>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time";
|
||||
|
||||
export default {
|
||||
name: "right-small-cover",
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 格式化时间戳
|
||||
publishTime(timestamp) {
|
||||
return translatePublishTime(timestamp)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./style.scss";
|
||||
</style>
|
@ -0,0 +1,63 @@
|
||||
.list-item {
|
||||
&.not-cover {
|
||||
.main {
|
||||
.info {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.main {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.thumbnails {
|
||||
margin: 20rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
.img {
|
||||
flex: 1;
|
||||
/* #ifndef APP-NVUE */
|
||||
width: auto;
|
||||
/* #endif */
|
||||
height: 200rpx;
|
||||
border-radius: 8rpx;
|
||||
margin: 0 10rpx;
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.author,
|
||||
.publish_date {
|
||||
font-size: 24rpx;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
|
||||
.publish_date {
|
||||
margin-left: 14rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
width: 240rpx;
|
||||
height: 160rpx;
|
||||
margin-left: 20rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<view
|
||||
:to="'/uni_modules/uni-cms-article/pages/detail/detail?id=' + data?._id"
|
||||
:key="data?._id"
|
||||
class="list-item"
|
||||
direction="column"
|
||||
>
|
||||
<view class="main">
|
||||
<text class="title">{{ data?.title }}</text>
|
||||
<view class="thumbnails">
|
||||
<image
|
||||
v-for="image in data?.thumbnail"
|
||||
:src="image"
|
||||
mode="aspectFill"
|
||||
class="img"
|
||||
></image>
|
||||
</view>
|
||||
<view class="info">
|
||||
<text class="author">{{ data!.user_id!.length > 0 ? data!.user_id[0]!.nickname : '' }}</text>
|
||||
<text class="publish_date">{{ publishTime(data?.publish_date ?? 0) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
import { type PropType } from 'vue'
|
||||
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time.uts";
|
||||
type ArticleAuthor = {
|
||||
_id: string
|
||||
nickname: string
|
||||
}
|
||||
type ArticleItem = {
|
||||
_id: string
|
||||
title: string
|
||||
publish_date: number
|
||||
thumbnail: string[]
|
||||
user_id: ArticleAuthor[]
|
||||
}
|
||||
export default {
|
||||
name: "three-cover",
|
||||
props: {
|
||||
data: {
|
||||
type: Object as PropType<ArticleItem>
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 格式化时间戳
|
||||
publishTime(timestamp: number): string {
|
||||
return translatePublishTime(timestamp)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./style.scss";
|
||||
</style>
|
@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<uni-list-item
|
||||
:to="'/uni_modules/uni-cms-article/pages/detail/detail?id=' + data._id"
|
||||
:key="data._id"
|
||||
class="list-item"
|
||||
direction="column"
|
||||
>
|
||||
<template v-slot:body>
|
||||
<view class="main">
|
||||
<text class="title">{{ data.title }}</text>
|
||||
<view class="thumbnails">
|
||||
<image
|
||||
v-for="image in data.thumbnail"
|
||||
:src="image"
|
||||
mode="aspectFill"
|
||||
class="img"
|
||||
></image>
|
||||
</view>
|
||||
<view class="info">
|
||||
<text class="author">{{ data.user_id[0] ? data.user_id[0].nickname : '' }}</text>
|
||||
<text class="publish_date">{{ publishTime(data.publish_date) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</uni-list-item>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time";
|
||||
|
||||
export default {
|
||||
name: "three-cover",
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 格式化时间戳
|
||||
publishTime(timestamp) {
|
||||
return translatePublishTime(timestamp)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./style.scss";
|
||||
</style>
|
@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<refresh @refresh="refresh" @pullingdown="onpullingdown" :display="showRefresh ? 'show' : 'hide'">
|
||||
<view class="refreshBox">
|
||||
<!-- 可以自己添加图片路径或base64实现图片 <image class="refreshImg" :src="config[state].img" mode="widthFix" resize="cover"></image> -->
|
||||
<text class="refreshText">{{config[state].text}}</text>
|
||||
</view>
|
||||
</refresh>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showRefresh:false, // 是否显示刷新
|
||||
state:0 // 刷新状态,0:继续下拉执行刷新,1:释放立即刷新,2:正在加载中,3:加载成功
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
// 下拉刷新回调函数
|
||||
onpullingdown({pullingDistance,viewHeight}) {
|
||||
if(pullingDistance < viewHeight){
|
||||
this.state = 0 // 继续下拉执行刷新
|
||||
}else{
|
||||
this.state = 1 // 释放立即刷新
|
||||
}
|
||||
},
|
||||
// 执行刷新
|
||||
refresh(){
|
||||
// console.log('refresh');
|
||||
this.showRefresh = true // 显示刷新
|
||||
this.state = 2 // 正在加载中
|
||||
this.$emit('refresh') // 触发refresh事件
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听loading变化
|
||||
loading(loading, oldValue) {
|
||||
if(!loading){
|
||||
this.showRefresh = false // 隐藏刷新
|
||||
this.state = 3 // 加载成功
|
||||
}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
loading: {
|
||||
type:Boolean,
|
||||
default(){
|
||||
return false
|
||||
}
|
||||
},
|
||||
config: {
|
||||
type: Array,
|
||||
default(){
|
||||
return [
|
||||
{
|
||||
text:"继续下拉执行刷新",
|
||||
img:""//可以自己添加图片路径或base64实现图片
|
||||
},
|
||||
{
|
||||
text:"释放立即刷新",
|
||||
img:""//可以自己添加图片路径或base64实现图片
|
||||
},
|
||||
{
|
||||
text:"正在加载中",
|
||||
img:""//可以自己添加图片路径或base64实现图片
|
||||
},
|
||||
{
|
||||
text:"加载成功",
|
||||
img:""//可以自己添加图片路径或base64实现图片
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.refreshBox{
|
||||
width: 750rpx;
|
||||
height: 50px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
/* #ifndef APP-PLUS */
|
||||
margin-top: -50px;
|
||||
/* #endif */
|
||||
}
|
||||
.refreshImg{
|
||||
width: 55rpx;
|
||||
height: 55rpx;
|
||||
z-index: 111;
|
||||
}
|
||||
.refreshText{
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
padding-left: 6rpx;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<refresh @refresh="refresh" @pullingdown="onpullingdown" :display="showRefresh ? 'show' : 'hide'">
|
||||
<view class="refreshBox">
|
||||
<!-- 可以自己添加图片路径或base64实现图片 <image class="refreshImg" :src="config[state].img" mode="widthFix" resize="cover"></image> -->
|
||||
<text class="refreshText">{{config[state].text}}</text>
|
||||
</view>
|
||||
</refresh>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showRefresh:false, // 是否显示刷新
|
||||
state:0 // 刷新状态,0:继续下拉执行刷新,1:释放立即刷新,2:正在加载中,3:加载成功
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
// 下拉刷新回调函数
|
||||
onpullingdown({pullingDistance,viewHeight}) {
|
||||
if(pullingDistance < viewHeight){
|
||||
this.state = 0 // 继续下拉执行刷新
|
||||
}else{
|
||||
this.state = 1 // 释放立即刷新
|
||||
}
|
||||
},
|
||||
// 执行刷新
|
||||
refresh(){
|
||||
// console.log('refresh');
|
||||
this.showRefresh = true // 显示刷新
|
||||
this.state = 2 // 正在加载中
|
||||
this.$emit('refresh') // 触发refresh事件
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听loading变化
|
||||
loading(loading, oldValue) {
|
||||
if(!loading){
|
||||
this.showRefresh = false // 隐藏刷新
|
||||
this.state = 3 // 加载成功
|
||||
}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
loading: {
|
||||
type:Boolean,
|
||||
default(){
|
||||
return false
|
||||
}
|
||||
},
|
||||
config: {
|
||||
type: Array,
|
||||
default(){
|
||||
return [
|
||||
{
|
||||
text:"继续下拉执行刷新",
|
||||
img:""//可以自己添加图片路径或base64实现图片
|
||||
},
|
||||
{
|
||||
text:"释放立即刷新",
|
||||
img:""//可以自己添加图片路径或base64实现图片
|
||||
},
|
||||
{
|
||||
text:"正在加载中",
|
||||
img:""//可以自己添加图片路径或base64实现图片
|
||||
},
|
||||
{
|
||||
text:"加载成功",
|
||||
img:""//可以自己添加图片路径或base64实现图片
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.refreshBox{
|
||||
width: 750rpx;
|
||||
height: 50px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
/* #ifndef APP-PLUS */
|
||||
margin-top: -50px;
|
||||
/* #endif */
|
||||
}
|
||||
.refreshImg{
|
||||
width: 55rpx;
|
||||
height: 55rpx;
|
||||
z-index: 111;
|
||||
}
|
||||
.refreshText{
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
padding-left: 6rpx;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<view
|
||||
:class="classList"
|
||||
v-if="imageData.image != ''"
|
||||
>
|
||||
<image
|
||||
:src="imagePath"
|
||||
:style="styles"
|
||||
:alt="imageData.attributes.alt"
|
||||
class="img"
|
||||
mode="aspectFill"
|
||||
@load="imageLoad"
|
||||
@click="imagePreview"
|
||||
></image>
|
||||
</view>
|
||||
</template>
|
||||
<script lang="uts">
|
||||
import {parseImageUrl} from "@/uni_modules/uni-cms-article/common/parse-image-url.uts";
|
||||
import type {ParseImageUrlResult} from '@/uni_modules/uni-cms-article/common/parse-image-url.uts';
|
||||
type ImageAttributes = {
|
||||
customParams: string | null
|
||||
width: number | null
|
||||
height: number | null
|
||||
alt: string | null
|
||||
}
|
||||
type ImageData = {
|
||||
image: string
|
||||
attributes: ImageAttributes
|
||||
}
|
||||
type ImageCalResult = {
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "render-image",
|
||||
emits: ['imagePreview'],
|
||||
props: {
|
||||
deltaOp: {
|
||||
type: Object as UTSJSONObject,
|
||||
default (): UTSJSONObject {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
reset: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
width: 0,
|
||||
height: 0,
|
||||
imagePath: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
imageData (): ImageData {
|
||||
const insert = this.deltaOp!.getJSON('insert')! as UTSJSONObject
|
||||
const attributes: UTSJSONObject | null = this.deltaOp!.getJSON('attributes')
|
||||
console.log(insert, attributes)
|
||||
return {
|
||||
image: insert.getString('image')!,
|
||||
attributes: {
|
||||
customParams: attributes != null ? attributes.getString('data-custom'): null,
|
||||
width: attributes != null ? attributes!.getNumber('width'): null,
|
||||
height: attributes != null ? attributes!.getNumber('height'): null,
|
||||
alt: attributes != null ? attributes!.getString('alt'): null,
|
||||
}
|
||||
} as ImageData
|
||||
},
|
||||
classList (): string[] {
|
||||
return [
|
||||
'image',
|
||||
this.reset ? 'reset': ''
|
||||
] as string[]
|
||||
},
|
||||
styles (): string {
|
||||
let style = ""
|
||||
|
||||
if (this.width != 0) {
|
||||
style += `;width:${this.width}px`
|
||||
}
|
||||
if (this.height != 0) {
|
||||
style += `;height:${this.height}px`
|
||||
}
|
||||
return style
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.loadImagePath()
|
||||
},
|
||||
methods: {
|
||||
async loadImagePath (): Promise<void> {
|
||||
const {image, attributes} = this.imageData
|
||||
const parseImages = await parseImageUrl({
|
||||
insert: {image},
|
||||
attributes: {
|
||||
'data-custom': attributes.customParams != null ? attributes.customParams : ""
|
||||
}
|
||||
}, "editor")
|
||||
|
||||
if (parseImages != null) {
|
||||
this.imagePath = parseImages[0].src
|
||||
}
|
||||
},
|
||||
imagePreview () {
|
||||
this.$emit('imagePreview', this.imageData.image)
|
||||
},
|
||||
// 图片加载完成
|
||||
imageLoad(e: ImageLoadEvent) {
|
||||
const recal = this.wxAutoImageCal(e.detail.width, e.detail.height, 15) // 计算图片宽高
|
||||
// const image = this.imageData
|
||||
|
||||
// ::TODO 关注一下在多端得表现情况
|
||||
// if (!image.data.attributes.width || Number(image.data.attributes.width) > recal.imageWidth) {
|
||||
// 如果图片宽度不存在或者图片宽度大于计算出来的宽度,则设置图片宽高
|
||||
this.width = recal.width
|
||||
this.height = recal.height
|
||||
// }
|
||||
},
|
||||
|
||||
// 计算图片宽高
|
||||
wxAutoImageCal(originalWidth: number, originalHeight: number, imagePadding: number): ImageCalResult {
|
||||
// 获取系统信息
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
let windowWidth: number;
|
||||
// let windowHeight: number;
|
||||
let autoWidth: number;
|
||||
let autoHeight: number;
|
||||
|
||||
let results: ImageCalResult = {
|
||||
width: 0,
|
||||
height: 0
|
||||
};
|
||||
// 计算图片宽度
|
||||
windowWidth = systemInfo.windowWidth - 2 * imagePadding;
|
||||
// windowHeight = systemInfo.windowHeight;
|
||||
if (originalWidth > windowWidth) {//在图片width大于手机屏幕width时候
|
||||
autoWidth = windowWidth;
|
||||
autoHeight = (autoWidth * originalHeight) / originalWidth;
|
||||
results.width = autoWidth;
|
||||
results.height = autoHeight;
|
||||
} else {//否则展示原来的数据
|
||||
results.width = originalWidth;
|
||||
results.height = originalHeight;
|
||||
}
|
||||
return results;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.image {
|
||||
margin-bottom: 40rpx;
|
||||
&.reset {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.img {
|
||||
display: flex;
|
||||
border-radius: 12rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<view
|
||||
:class="classList"
|
||||
v-if="data.data"
|
||||
>
|
||||
<image
|
||||
:src="imagePath"
|
||||
:class="data.data.class"
|
||||
:style="styles"
|
||||
:alt="data.data.attributes.alt || ''"
|
||||
class="img"
|
||||
mode="aspectFill"
|
||||
@load="imageLoad"
|
||||
@click="imagePreview"
|
||||
></image>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {parseImageUrl} from "@/uni_modules/uni-cms-article/common/parse-image-url.js";
|
||||
|
||||
export default {
|
||||
name: "render-image",
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
className: String,
|
||||
reset: false
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
width: 0,
|
||||
height: 0,
|
||||
imagePath: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
classList () {
|
||||
return [
|
||||
'image',
|
||||
this.reset ? 'reset': '',
|
||||
this.className
|
||||
]
|
||||
},
|
||||
styles () {
|
||||
let style = this.data.data.style
|
||||
|
||||
if (this.width) {
|
||||
style += `;width:${this.width}px`
|
||||
}
|
||||
if (this.height) {
|
||||
style += `;height:${this.height}px`
|
||||
}
|
||||
return style
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.loadImagePath()
|
||||
},
|
||||
methods: {
|
||||
async loadImagePath () {
|
||||
const parseImages = await parseImageUrl({
|
||||
insert: {image: this.data.data.value},
|
||||
attributes: this.data.data.attributes,
|
||||
}, "editor")
|
||||
|
||||
this.imagePath = parseImages[0].src
|
||||
},
|
||||
imagePreview () {
|
||||
uni.$emit('imagePreview', this.data.data.value)
|
||||
},
|
||||
// 图片加载完成
|
||||
imageLoad(e) {
|
||||
const recal = this.wxAutoImageCal(e.detail.width, e.detail.height, 15) // 计算图片宽高
|
||||
// const image = this.data
|
||||
|
||||
// ::TODO 关注一下在多端得表现情况
|
||||
// if (!image.data.attributes.width || Number(image.data.attributes.width) > recal.imageWidth) {
|
||||
// 如果图片宽度不存在或者图片宽度大于计算出来的宽度,则设置图片宽高
|
||||
this.width = recal.imageWidth
|
||||
this.height = recal.imageHeight
|
||||
// }
|
||||
},
|
||||
|
||||
// 计算图片宽高
|
||||
wxAutoImageCal(originalWidth, originalHeight, imagePadding = 0) {
|
||||
// 获取系统信息
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
let windowWidth = 0, windowHeight = 0;
|
||||
let autoWidth = 0, autoHeight = 0;
|
||||
let results = {};
|
||||
// 计算图片宽度
|
||||
windowWidth = systemInfo.windowWidth - 2 * imagePadding;
|
||||
windowHeight = systemInfo.windowHeight;
|
||||
if (originalWidth > windowWidth) {//在图片width大于手机屏幕width时候
|
||||
autoWidth = windowWidth;
|
||||
autoHeight = (autoWidth * originalHeight) / originalWidth;
|
||||
results.imageWidth = autoWidth;
|
||||
results.imageHeight = autoHeight;
|
||||
} else {//否则展示原来的数据
|
||||
results.imageWidth = originalWidth;
|
||||
results.imageHeight = originalHeight;
|
||||
}
|
||||
return results;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.image {
|
||||
margin-bottom: 40rpx;
|
||||
&.reset {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.img {
|
||||
// #ifdef APP-PLUS
|
||||
display: block;
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
display: flex;
|
||||
// #endif
|
||||
border-radius: 12rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<template v-for="op in content">
|
||||
<render-text
|
||||
v-if="op.type === 'paragraph'"
|
||||
:data="op.data"
|
||||
:className="op.class"
|
||||
:style="op.style"
|
||||
></render-text>
|
||||
<render-image
|
||||
v-else-if="op.type === 'image' && op.data.length > 0"
|
||||
:data="op.data[0]"
|
||||
:className="op.class"
|
||||
:style="op.style"
|
||||
></render-image>
|
||||
<render-list
|
||||
v-else-if="op.type === 'list'"
|
||||
:data="op.data"
|
||||
:style="op.style"
|
||||
></render-list>
|
||||
<view
|
||||
v-else-if="op.type === 'divider'"
|
||||
class="divider"
|
||||
></view>
|
||||
<render-video
|
||||
v-else-if="op.type === 'mediaVideo'"
|
||||
:data="op.data"
|
||||
></render-video>
|
||||
<render-unlock-content
|
||||
v-else-if="op.type === 'unlockContent'"
|
||||
:adp-id="adConfig.adpId"
|
||||
:watch-ad-unique-type="adConfig.watchAdUniqueType"
|
||||
></render-unlock-content>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {parseImageUrl} from "@/uni_modules/uni-cms-article/common/parse-image-url"
|
||||
|
||||
import text from './text.vue'
|
||||
import image from './image.vue'
|
||||
import video from './video.vue'
|
||||
import list from './list.vue'
|
||||
import unlockContent from './unlock-content.vue'
|
||||
|
||||
export default {
|
||||
name: "render-article-detail",
|
||||
props: {
|
||||
content: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
contentImages: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
adConfig: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
articleImages: []
|
||||
}
|
||||
},
|
||||
components: {
|
||||
renderUnlockContent: unlockContent,
|
||||
renderText: text,
|
||||
renderImage: image,
|
||||
renderList: list,
|
||||
renderVideo: video
|
||||
},
|
||||
mounted() {
|
||||
this.initImage()
|
||||
},
|
||||
beforeDestroy() {
|
||||
uni.$off('imagePreview')
|
||||
},
|
||||
methods: {
|
||||
// 初始化图片
|
||||
async initImage() {
|
||||
// 获取所有图片
|
||||
const parseImages = await parseImageUrl(this.contentImages)
|
||||
|
||||
if (parseImages != null) {
|
||||
this.articleImages = parseImages.map(image => image.src)
|
||||
}
|
||||
|
||||
// 监听图片预览
|
||||
uni.$on('imagePreview', this.imagePreview)
|
||||
},
|
||||
// 点击图片预览
|
||||
imagePreview(src) {
|
||||
if (src) {
|
||||
uni.previewImage({
|
||||
current: src.split('?')[0], // 当前显示图片的http链接
|
||||
urls: this.articleImages // 需要预览的图片http链接列表
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
line-height: 1.75;
|
||||
font-size: 32rpx;
|
||||
margin-top: 40rpx;
|
||||
padding: 0 30rpx 80rpx;
|
||||
word-break: break-word;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background: #d8d8d8;
|
||||
width: 100%;
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<view :class="['list', data.type]">
|
||||
<view class="list-item" v-for="(item, index) in data.items">
|
||||
<text class="dot">{{data.type === 'ordered' ? `${index + 1}.` : '•'}}</text>
|
||||
<render-text :data="item.data" reset class="reset-default"></render-text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import text from './text.vue'
|
||||
|
||||
export default {
|
||||
name: "render-list",
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
renderText: text
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.list {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20rpx;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.dot {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
.reset-default {
|
||||
text-indent: 0;
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<view :class="classList">
|
||||
<template v-for="item in data">
|
||||
<text
|
||||
v-if="item.type === 'text'"
|
||||
:class="item.data.class"
|
||||
:style="item.data.style"
|
||||
class="text"
|
||||
>
|
||||
{{item.data.value}}
|
||||
</text>
|
||||
<text
|
||||
v-if="item.type === 'link'"
|
||||
:class="item.data.class"
|
||||
:style="item.data.style"
|
||||
class="link"
|
||||
@click="goLink(item.data.attributes.link)"
|
||||
>
|
||||
{{item.data.value}}
|
||||
</text>
|
||||
<image-item v-else-if="item.type === 'image'" :data="item"></image-item>
|
||||
<!-- #ifdef H5 -->
|
||||
<br v-else-if="item.type === 'br'" class="br"/>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef H5 -->
|
||||
<text v-else-if="item.type === 'br'" class="br">\n</text>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import ImageItem from './image.vue'
|
||||
|
||||
export default {
|
||||
name: "render-text",
|
||||
props: {
|
||||
data: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
className: String,
|
||||
reset: Boolean
|
||||
},
|
||||
computed: {
|
||||
classList () {
|
||||
return [
|
||||
'row-text',
|
||||
this.className,
|
||||
this.reset ? 'reset': ''
|
||||
]
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ImageItem
|
||||
},
|
||||
methods: {
|
||||
show () {
|
||||
uni.showToast({
|
||||
title: 'test',
|
||||
icon: 'none'
|
||||
})
|
||||
},
|
||||
// 点击链接跳转
|
||||
goLink(link) {
|
||||
// 如果链接为空,则返回
|
||||
if (!link) return
|
||||
|
||||
// #ifdef H5
|
||||
// 在新窗口中打开链接
|
||||
window.open(link, '_blank')
|
||||
// #endif
|
||||
|
||||
// #ifdef MP
|
||||
// 微信小程序不支持打开外链,复制链接到剪贴板
|
||||
uni.setClipboardData({
|
||||
data: link,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '链接已复制',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifdef APP
|
||||
// 在webview中打开链接
|
||||
uni.navigateTo({
|
||||
url: `/uni_modules/uni-cms-article/pages/webview/webview?url=${encodeURIComponent(link)}`
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.row-text, .br {
|
||||
margin-bottom: 40rpx;
|
||||
&.reset {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.header-1,
|
||||
.header-2,
|
||||
.header-3,
|
||||
.header-4,
|
||||
.header-5,
|
||||
.header-6 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header-1 {
|
||||
font-size: 44rpx;
|
||||
}
|
||||
|
||||
.header-2 {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.header-3 {
|
||||
font-size: 38rpx;
|
||||
}
|
||||
|
||||
.header-4 {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.header-5 {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.header-6 {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.strike {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: #0064f9;
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<view class="unlock-content">
|
||||
<!-- #ifdef H5 -->
|
||||
<!-- 等广告支持H5后优化-->
|
||||
<button class="text" @click="callAd">请观看广告后解锁全文</button>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- #ifndef H5 -->
|
||||
<ad-rewarded-video ref="rewardedVideo" :adpid="adpId" :preload="false" :disabled="true" :loadnext="true"
|
||||
:url-callback="urlCallback" @load="onAdLoad" @close="onAdClose" @error="onAdError"
|
||||
v-slot:default="{ loading, error }">
|
||||
<text v-if="error" class="text">广告加载失败</text>
|
||||
</ad-rewarded-video>
|
||||
<button v-if="!isLoadError" class="text" @click="callAd" :loading="adLoading">请观看广告后解锁全文</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 实例化数据库
|
||||
const db = uniCloud.database()
|
||||
// 定义解锁记录表名
|
||||
const unlockContentDBName = 'uni-cms-unlock-record'
|
||||
|
||||
export default {
|
||||
name: "ad",
|
||||
props: {
|
||||
adpId: String,
|
||||
watchAdUniqueType: {
|
||||
type: String,
|
||||
default: 'device'
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentArticleId: '',
|
||||
currentPageRoute: '',
|
||||
adLoading: false,
|
||||
isLoadError: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 回调URL
|
||||
urlCallback() {
|
||||
return {
|
||||
extra: JSON.stringify({
|
||||
article_id: this.currentArticleId,
|
||||
unique_id: this.uniqueId,
|
||||
unique_type: this.watchAdUniqueType
|
||||
})
|
||||
}
|
||||
},
|
||||
// 是否通过设备观看
|
||||
watchByDevice() {
|
||||
return this.watchAdUniqueType === 'device'
|
||||
},
|
||||
// 是否通过用户观看
|
||||
watchByUser() {
|
||||
return this.watchAdUniqueType === 'user'
|
||||
},
|
||||
// 获取唯一ID
|
||||
uniqueId() {
|
||||
return this.watchByDevice ? uni.getSystemInfoSync().deviceId : uniCloud.getCurrentUserInfo().uid
|
||||
}
|
||||
},
|
||||
// #ifndef H5
|
||||
mounted() {
|
||||
// 获取当前页面信息
|
||||
const pages = getCurrentPages()
|
||||
const currentPage = pages[pages.length - 1]
|
||||
this.currentArticleId = currentPage.options.id
|
||||
this.currentPageRoute = currentPage.route
|
||||
|
||||
// 如果广告位ID未设置,则提示广告无法正常加载
|
||||
if (!this.adpId) {
|
||||
uni.showModal({
|
||||
content: '广告位ID未设置,广告无法正常加载',
|
||||
showCancel: false
|
||||
})
|
||||
} else {
|
||||
// 加载广告
|
||||
this.$refs.rewardedVideo.load()
|
||||
}
|
||||
},
|
||||
// #endif
|
||||
methods: {
|
||||
// 调用广告
|
||||
callAd() {
|
||||
// #ifdef H5
|
||||
// 如果在浏览器中,则提示需在App或小程序中操作
|
||||
return uni.showModal({
|
||||
content: '需观看广告解锁内容, 但浏览器不支持广告播放, 请在App或小程序中操作',
|
||||
showCancel: false
|
||||
})
|
||||
// #endif
|
||||
|
||||
if (this.watchByUser) {
|
||||
// 登录跳转URL 请根据实际情况修改
|
||||
const redirectUrl = '/uni_modules/uni-id-pages/pages/login/login-withoutpwd' + (this.currentPageRoute ? '?uniIdRedirectUrl=' + this.currentPageRoute + '?id=' + this.currentArticleId : '')
|
||||
|
||||
//::TODO 支持设备与用户
|
||||
// 如果用户未登录,则提示需要登录
|
||||
if (uniCloud.getCurrentUserInfo().tokenExpired < Date.now()) {
|
||||
uni.showModal({
|
||||
content: '请登录后操作',
|
||||
success: ({ confirm }) => {
|
||||
confirm && uni.redirectTo({
|
||||
url: redirectUrl
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 显示广告
|
||||
this.adLoading = true
|
||||
this.$refs.rewardedVideo.show()
|
||||
},
|
||||
// 广告加载成功
|
||||
onAdLoad() {
|
||||
this.adLoading && this.$refs.rewardedVideo.show()
|
||||
console.log('广告数据加载成功');
|
||||
},
|
||||
// 广告关闭
|
||||
onAdClose(e) {
|
||||
console.log('close', e)
|
||||
const detail = e.detail
|
||||
// 轮询3次,每次1秒,如果3秒内没有查询到解锁记录,就提示解锁失败
|
||||
let i = 3
|
||||
uni.hideLoading()
|
||||
this.adLoading = false
|
||||
|
||||
// detail.isEnded 为true 说明用户观看了完整视频
|
||||
if (detail && detail.isEnded) {
|
||||
uni.showLoading({
|
||||
title: '正在解锁全文',
|
||||
timeout: 7000
|
||||
})
|
||||
let queryResult = setInterval(async () => {
|
||||
i--;
|
||||
|
||||
// 查询解锁记录
|
||||
const res = await db.collection(unlockContentDBName).where({
|
||||
unique_id: this.uniqueId,
|
||||
article_id: this.currentArticleId,
|
||||
}).get()
|
||||
|
||||
// 1. result.data.length 为0 说明没有解锁记录
|
||||
// 2. i <= 0 说明已经轮询了3次,还是没有解锁记录,说明解锁失败
|
||||
// 3. result.data.length && i > 0 说明已经解锁成功
|
||||
if (i <= 0) {
|
||||
console.log('解锁失败', i)
|
||||
clearInterval(queryResult)
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '解锁失败!',
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
});
|
||||
} else if (res.result && res.result.data.length) {
|
||||
console.log('解锁成功', i)
|
||||
|
||||
clearInterval(queryResult)
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '解锁成功!',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
uni.$emit('onUnlockContent')
|
||||
}
|
||||
}, 1500);
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "请观看完整视频后解锁全文",
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
},
|
||||
onAdError(e) {
|
||||
// uni.hideLoading()
|
||||
// this.isLoadError = true
|
||||
console.error('onaderror: ', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
.unlock-content {
|
||||
text-align: center;
|
||||
padding: 160rpx 0 60rpx;
|
||||
position: relative;
|
||||
margin-top: -140rpx;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 160rpx;
|
||||
background: linear-gradient(to bottom, transparent, #fff);
|
||||
}
|
||||
|
||||
.text {
|
||||
border: #f0f0f0 solid 1px;
|
||||
display: inline-block;
|
||||
background: #f6f6f6;
|
||||
border-radius: 10rpx;
|
||||
font-size: 34rpx;
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<view class="video">
|
||||
<video
|
||||
class="v"
|
||||
:src="data.attributes.src"
|
||||
:poster="data.attributes.poster"
|
||||
></video>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "render-video",
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
width: 0,
|
||||
height: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.video {
|
||||
margin-bottom: 40rpx;
|
||||
.v {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<view>
|
||||
<text class="uni-cms-article-icon" :style="{color, 'fontSize': size + 'px', lineHeight: size + 'px'}">{{iconCode}}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
const icons: UTSJSONObject = {
|
||||
search: "\ue654",
|
||||
back: "\ue6b9",
|
||||
scan: "\ue62a",
|
||||
closeempty: "\ue66c",
|
||||
trash: "\ue687",
|
||||
reload: "\ue6b2",
|
||||
eye: "\ue651",
|
||||
'eye-slash': '\ue6b3'
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'uni-cms-article-icons',
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#333333'
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 16
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iconCode(): string {
|
||||
return icons.getString(this.type) as string
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "uni-cms-article-icons";
|
||||
src: url('/uni_modules/uni-cms-article/static/uniicons.ttf');
|
||||
}
|
||||
|
||||
.uni-cms-article-icon {
|
||||
font-family: "uni-cms-article-icons";
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
</style>
|
@ -0,0 +1,371 @@
|
||||
<template>
|
||||
<unicloud-db
|
||||
ref='udb'
|
||||
v-slot:default="{ data, pagination, hasMore, loading, error }"
|
||||
:collection="collectionList"
|
||||
:page-size="10"
|
||||
:loadtime="loadTime"
|
||||
orderby="publish_date desc"
|
||||
@load="onListLoad"
|
||||
@error="onListLoadError"
|
||||
>
|
||||
<view
|
||||
v-if="networkType == 'none'"
|
||||
class="error-box"
|
||||
@click="checkNetwork"
|
||||
>
|
||||
<image class="disconnect-icon" src="/uni_modules/uni-cms-article/static/disconnection.png" mode="widthFix"></image>
|
||||
<text class="tip-text">当前网络不可用,请点击重试</text>
|
||||
</view>
|
||||
<list-view
|
||||
v-else
|
||||
class="list-view"
|
||||
:scroll-y="true"
|
||||
:refresher-enabled="refresherEnabled"
|
||||
refresher-default-style="none"
|
||||
:refresher-triggered="refresherTriggered"
|
||||
@refresherpulling="refresherpulling"
|
||||
@refresherrefresh="refresherrefresh"
|
||||
@scrolltolower="scrolltolower"
|
||||
>
|
||||
<list-item slot="refresher" class="refresh-box">
|
||||
<text class="text">{{ refreshText[refreshState] }}</text>
|
||||
</list-item>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<list-item
|
||||
v-for="item in articleList"
|
||||
:class="['list-item', `list-item__thumbnail-${item.thumbnail.length}`]"
|
||||
:key="item._id"
|
||||
@click="goToDetailPage(item)"
|
||||
>
|
||||
<template v-if="item.thumbnail.length == 0">
|
||||
<view class="list-item__content">
|
||||
<view class="list-item__content-title">
|
||||
<text class="text">{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="list-item__content-info">
|
||||
<view class="list-item__author">
|
||||
<text class="text">{{ item!.user_id!.length > 0 ? item.user_id[0].nickname : '' }}</text>
|
||||
</view>
|
||||
<view class="list-item__publish-date">
|
||||
<text class="text">{{ publishTime(item.publish_date) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="item.thumbnail.length == 1">
|
||||
<view class="list-item__content">
|
||||
<view class="list-item__content-title">
|
||||
<text class="text">{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="list-item__content-info">
|
||||
<view class="list-item__author">
|
||||
<text class="text">{{ item!.user_id!.length > 0 ? item.user_id[0].nickname : '' }}</text>
|
||||
</view>
|
||||
<view class="list-item__publish-date">
|
||||
<text class="text">{{ publishTime(item.publish_date) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="list-item__thumbnails">
|
||||
<image
|
||||
v-for="image in item.thumbnail"
|
||||
:src="image"
|
||||
mode="aspectFill"
|
||||
class="list-item__img"
|
||||
></image>
|
||||
</view>
|
||||
</template>
|
||||
<template v-if="item.thumbnail.length == 3">
|
||||
<view class="list-item__content">
|
||||
<view class="list-item__content-title">
|
||||
<text>{{ item.title }}</text>
|
||||
</view>
|
||||
<view class="list-item__thumbnails">
|
||||
<image
|
||||
v-for="image in item.thumbnail"
|
||||
:src="image"
|
||||
mode="aspectFill"
|
||||
class="list-item__img"
|
||||
></image>
|
||||
</view>
|
||||
<view class="list-item__content-info">
|
||||
<view class="list-item__author">
|
||||
<text class="text">{{ item!.user_id!.length > 0 ? item.user_id[0].nickname : '' }}</text>
|
||||
</view>
|
||||
<view class="list-item__publish-date">
|
||||
<text class="text">{{ publishTime(item.publish_date) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</list-item>
|
||||
<list-item class="load-state">
|
||||
<text class="text">{{ loading ? '加载中...' : (hasMore ? '上拉加载更多' : '没有更多数据了') }}</text>
|
||||
</list-item>
|
||||
</list-view>
|
||||
</unicloud-db>
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
type ArticleAuthor = {
|
||||
_id: string
|
||||
nickname: string
|
||||
}
|
||||
type ArticleItem = {
|
||||
_id: string
|
||||
title: string
|
||||
publish_date: number
|
||||
thumbnail: string[]
|
||||
user_id: ArticleAuthor[]
|
||||
}
|
||||
|
||||
import {parseImageUrl} from "@/uni_modules/uni-cms-article/common/parse-image-url.uts";
|
||||
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time.uts";
|
||||
import type {ParseImageUrlResult} from '@/uni_modules/uni-cms-article/common/parse-image-url.uts'
|
||||
|
||||
export default {
|
||||
name: "uni-cms-article-list",
|
||||
emits: ['onRefresh', 'onLoadMore'],
|
||||
props: {
|
||||
collectionList: {
|
||||
type: Array as any[],
|
||||
default: (): any[] => []
|
||||
},
|
||||
loadTime: {
|
||||
type: String,
|
||||
default: 'auto'
|
||||
},
|
||||
refresherEnabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
articleList: [] as ArticleItem[],
|
||||
refresherTriggered: false,
|
||||
refreshState: 0,
|
||||
refreshText: [
|
||||
'继续下拉执行刷新',
|
||||
'释放立即刷新',
|
||||
'正在加载中',
|
||||
'加载成功'
|
||||
],
|
||||
networkType: ""
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.checkNetwork()
|
||||
},
|
||||
methods: {
|
||||
checkNetwork() {
|
||||
uni.getNetworkType({
|
||||
success: (res) => {
|
||||
this.networkType = res.networkType;
|
||||
}
|
||||
});
|
||||
},
|
||||
publishTime(timestamp: number): string {
|
||||
return translatePublishTime(timestamp)
|
||||
},
|
||||
async onListLoad(data: UTSJSONObject[], ended: boolean, pagination: UTSJSONObject): Promise<void> {
|
||||
const listData: ArticleItem[] = data.map((item: UTSJSONObject): ArticleItem => {
|
||||
let articleItem: ArticleItem = {
|
||||
_id: item.getString('_id')!,
|
||||
title: item.getString('title')!,
|
||||
publish_date: item.getNumber('publish_date')!,
|
||||
thumbnail: [],
|
||||
user_id: item.getArray<ArticleAuthor>('user_id')! as ArticleAuthor[]
|
||||
}
|
||||
|
||||
if (typeof item.getAny('thumbnail') === 'string') {
|
||||
articleItem.thumbnail = [item.getAny('thumbnail')! as string]
|
||||
} else {
|
||||
articleItem.thumbnail = item.getArray<string>('thumbnail')!
|
||||
}
|
||||
|
||||
return articleItem
|
||||
})
|
||||
|
||||
// 处理cloud://文件链接
|
||||
for (let i = 0; i < listData.length; i++) {
|
||||
const article = listData[i]
|
||||
const parseImages = await parseImageUrl(article.thumbnail)
|
||||
|
||||
if (parseImages != null) {
|
||||
article.thumbnail = parseImages.map((image: ParseImageUrlResult): string => image.src)
|
||||
}
|
||||
}
|
||||
|
||||
this.articleList = pagination.getNumber('current') == 1 ? listData : this.articleList.concat(listData)
|
||||
},
|
||||
refresherrefresh() {
|
||||
this.refresherTriggered = true
|
||||
this.refreshState = 2;
|
||||
|
||||
(this.$refs['udb'] as UniCloudDBElement)!.loadData({
|
||||
clear: true,
|
||||
success: (_: any) => {
|
||||
this.refresherTriggered = false
|
||||
this.refreshState = 3
|
||||
}
|
||||
})
|
||||
},
|
||||
refresherpulling(e: RefresherEvent) {
|
||||
if (e.detail.dy.toDouble() == 0.0) {
|
||||
this.refreshState = 0
|
||||
} else if (e.detail.dy > 45) {
|
||||
this.refreshState = 1
|
||||
}
|
||||
},
|
||||
scrolltolower() {
|
||||
(this.$refs['udb'] as UniCloudDBElement)!.loadMore()
|
||||
},
|
||||
reLoadList() {
|
||||
(this.$refs['udb'] as UniCloudDBElement)!.loadData({
|
||||
clear: true
|
||||
})
|
||||
},
|
||||
goToDetailPage(article: ArticleItem) {
|
||||
uni.navigateTo({
|
||||
url: `/uni_modules/uni-cms-article/pages/detail/detail?id=${article._id}&title=${article.title}`
|
||||
})
|
||||
},
|
||||
onListLoadError () {
|
||||
this.checkNetwork()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.refresh-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.text {
|
||||
padding: 30rpx 0;
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.error-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 auto;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.disconnect-icon {
|
||||
width: 200rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.load-state {
|
||||
height: 90rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.list-view {
|
||||
height: 100%;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: #f5f5f5 solid 1px;
|
||||
|
||||
&__thumbnail-1 {
|
||||
.list-item__content-title {
|
||||
height: 88rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&__thumbnail-3 {
|
||||
.list-item__thumbnails {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: 20rpx -10rpx;
|
||||
margin-left: -10rpx;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.list-item__img {
|
||||
margin: 0 10rpx;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&__thumbnails {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
&__img {
|
||||
width: 240rpx;
|
||||
height: 160rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
|
||||
&-title {
|
||||
overflow: hidden;
|
||||
|
||||
.text {
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
line-height: 44rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&-info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&__author,
|
||||
&__publish-date {
|
||||
.text {
|
||||
font-size: 24rpx;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
}
|
||||
|
||||
&__author {
|
||||
margin-right: 14rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<view class="search-bar">
|
||||
<view :style="{ height: `${navBarHeight}px` }"></view>
|
||||
<view class="search-bar__content" @click="goToSearchPage">
|
||||
<view class="search-bar__left" v-if="!showPlaceholder">
|
||||
<view class="back-icon">
|
||||
<uni-cms-article-icons type="back" :size="26" color="#333" @click="back"></uni-cms-article-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view class="search-bar__center">
|
||||
<uni-cms-article-icons type="search" :size="18" color="#c0c4cc"></uni-cms-article-icons>
|
||||
<text class="search-bar__placeholder" v-if="showPlaceholder">请输入搜索内容</text>
|
||||
<input
|
||||
v-else
|
||||
ref="search-input"
|
||||
class="search-bar__input"
|
||||
placeholder="请输入搜索内容"
|
||||
v-model="searchVal"
|
||||
confirm-type="search"
|
||||
:focus="focus"
|
||||
@confirm="confirm"
|
||||
/>
|
||||
<view class="clear-icon" v-if="hasSearchValue" @click="clear">
|
||||
<uni-cms-article-icons type="closeempty" :size="12" color="#fff"></uni-cms-article-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view class="search-bar__right" v-if="!showPlaceholder">
|
||||
<!-- <uni-cms-article-icons type="scan" :size="20" color="#c0c4cc" @click="scan"></uni-cms-article-icons>-->
|
||||
<text class="search-bar__search-text" @click="confirm">搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
// import parseScanResult from "@/uni_modules/uni-cms-article/common/parse-scan-result.uts";
|
||||
|
||||
export default {
|
||||
name: 'search-bar',
|
||||
emits: ['update:modelValue', 'clear', 'confirm'],
|
||||
data() {
|
||||
return {
|
||||
navBarHeight: 44,
|
||||
searchVal: ""
|
||||
}
|
||||
},
|
||||
props: {
|
||||
showPlaceholder: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
focus: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: ""
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
searchVal(newValue) {
|
||||
this.$emit('update:modelValue', newValue)
|
||||
},
|
||||
modelValue: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
this.searchVal = newVal
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
hasSearchValue(): boolean {
|
||||
return this.searchVal != ""
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
// 获取当前页面数量
|
||||
const pages = getCurrentPages()
|
||||
// 定义文章列表页的路径
|
||||
const pageUrl = '/uni_modules/uni-cms-article/pages/list/list'
|
||||
|
||||
// 如果当前页面数量大于1,返回上一页
|
||||
if (pages.length > 1) {
|
||||
uni.navigateBack({})
|
||||
} else { // 否则跳转到文章列表页
|
||||
uni.redirectTo({
|
||||
url: pageUrl,
|
||||
fail: (e: RedirectToFail) => {
|
||||
// 如果跳转失败,说明当前页面是tabbar页面,需要使用switchTab跳转
|
||||
if (e.errMsg.indexOf('tabbar') !== -1) {
|
||||
uni.switchTab({
|
||||
url: pageUrl
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
this.searchVal = '';
|
||||
(this.$refs['search-input'] as Element).blur()
|
||||
this.$emit('clear')
|
||||
},
|
||||
confirm() {
|
||||
(this.$refs['search-input'] as Element).blur()
|
||||
this.$emit('confirm', this.searchVal)
|
||||
},
|
||||
scan() {
|
||||
// 扫码暂不支持
|
||||
// uni.scanCode({
|
||||
// onlyFromCamera: true,
|
||||
// scanType: ["qrCode"],
|
||||
// success: (e) => parseScanResult(e.result),
|
||||
// fail: (e) => {
|
||||
// console.error(e)
|
||||
// }
|
||||
// })
|
||||
},
|
||||
goToSearchPage() {
|
||||
if (!this.showPlaceholder) return
|
||||
|
||||
uni.navigateTo({
|
||||
url: '/uni_modules/uni-cms-article/pages/search/search'
|
||||
})
|
||||
},
|
||||
hideKeyboard() {
|
||||
(this.$refs['search-input'] as Element).blur()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.search-bar {
|
||||
background: #fff;
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
|
||||
&__left {
|
||||
margin-left: -20rpx;
|
||||
}
|
||||
|
||||
&__center {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #F8F8F8;
|
||||
padding: 20rpx;
|
||||
margin: 0 20rpx;
|
||||
margin-left: 0;
|
||||
border-radius: 40rpx;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__placeholder {
|
||||
color: #c0c4cc;
|
||||
font-size: 28rpx;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
&__input {
|
||||
margin-left: 10rpx;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__search-text {
|
||||
color: #c0402b;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
padding: 10rpx;
|
||||
}
|
||||
|
||||
.clear-icon {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
background: #c0c4cc;
|
||||
border-radius: 15rpx;
|
||||
margin-right: 0;
|
||||
margin-left: 10rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"noData": "No Data",
|
||||
"noNetwork": "Network error",
|
||||
"toSet": "Go to settings",
|
||||
"error": "error"
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import en from './en.json'
|
||||
import zhHans from './zh-Hans.json'
|
||||
export default {
|
||||
en,
|
||||
'zh-Hans': zhHans
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"noData": "暂无数据",
|
||||
"noNetwork": "网络异常",
|
||||
"toSet": "前往设置",
|
||||
"error": "错误"
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
新增uni-load-state组件,这是一个封装数据请求状态的组件。根据uniCloud-db组件提供的参数直接响应对应的效果。
|
||||
包括加载中、当前页面为空、没有更多数据、上拉加载更多;
|
||||
加载错误判断,如果是断网就引导打开系统网络设置页面。恢复联网后自动触发networkResume方法。
|
@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<view @appear="appear">
|
||||
<view v-if="state.error">
|
||||
<view class="box" v-if="networkType == 'none'">
|
||||
<image class="icon-image" src="/uni_modules/uni-cms-article/static/disconnection.png" mode="widthFix"></image>
|
||||
<text class="tip-text">{{noNetwork}}</text>
|
||||
<view class="btn btn-default" @click="openSettings">
|
||||
<text class="btn-text">{{toSet}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="error" v-else>{{error}}:{{JSON.stringify(state.error)}}</text>
|
||||
</view>
|
||||
<template v-else>
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<text class="state-text">{{state.loading?'加载中...':(state.hasMore?'上拉加载更多':'没有更多数据了')}}</text>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-NVUE -->
|
||||
<uni-load-more class="uni-load-more" :status="state.loading?'loading':(state.hasMore?'hasMore':'noMore')"></uni-load-more>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
initVueI18n
|
||||
} from '@dcloudio/uni-i18n'
|
||||
import messages from './i18n/index.js'
|
||||
const {
|
||||
t
|
||||
} = initVueI18n(messages)
|
||||
|
||||
export default {
|
||||
name: "uni-load-state",
|
||||
computed: {
|
||||
noData() {
|
||||
return t('noData')
|
||||
},
|
||||
noNetwork() {
|
||||
return t('noNetwork')
|
||||
},
|
||||
toSet() {
|
||||
return t('toSet')
|
||||
},
|
||||
error() {
|
||||
return t('error')
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
"networkType": ""
|
||||
};
|
||||
},
|
||||
props: {
|
||||
state: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {
|
||||
"loading": true,
|
||||
"hasMore": false,
|
||||
"pagination": {
|
||||
"pages": 0
|
||||
},
|
||||
"data": [],
|
||||
"error": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
uni.onNetworkStatusChange(({
|
||||
networkType
|
||||
}) => {
|
||||
if (this.networkType == 'none' && networkType != 'none') { //之前没网现在有了
|
||||
this.$emit('networkResume')
|
||||
}
|
||||
this.networkType = networkType;
|
||||
});
|
||||
uni.getNetworkType({
|
||||
success: ({
|
||||
networkType
|
||||
}) => {
|
||||
this.networkType = networkType;
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
appear() {
|
||||
if (!this.state.loading && this.state.hasMore) {
|
||||
this.$emit('loadMore')
|
||||
}
|
||||
},
|
||||
openSettings() {
|
||||
if (uni.getSystemInfoSync().platform == "ios") {
|
||||
var UIApplication = plus.ios.import("UIApplication");
|
||||
var application2 = UIApplication.sharedApplication();
|
||||
var NSURL2 = plus.ios.import("NSURL");
|
||||
var setting2 = NSURL2.URLWithString("App-prefs:root=General");
|
||||
application2.openURL(setting2);
|
||||
plus.ios.deleteObject(setting2);
|
||||
plus.ios.deleteObject(NSURL2);
|
||||
plus.ios.deleteObject(application2);
|
||||
} else {
|
||||
var Intent = plus.android.importClass("android.content.Intent");
|
||||
var Settings = plus.android.importClass("android.provider.Settings");
|
||||
var mainActivity = plus.android.runtimeMainActivity();
|
||||
var intent = new Intent(Settings.ACTION_SETTINGS);
|
||||
mainActivity.startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.box {
|
||||
flex: 1;
|
||||
width: 700rpx;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.uni-load-more{
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.state-text {
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
width: 690rpx;
|
||||
padding: 10rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.icon-image {
|
||||
width: 300rpx;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
color: #999999;
|
||||
font-size: 32rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 5px 10px;
|
||||
width: 128px;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
color: #999999;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
border-color: #999999;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.error {
|
||||
width: 690rpx;
|
||||
color: #DD524D;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user