liyongli 1 سال پیش
کامیت
67657548f3
7فایلهای تغییر یافته به همراه649 افزوده شده و 0 حذف شده
  1. 66 0
      brief/brief.vue
  2. 92 0
      detail/detail.vue
  3. 72 0
      detail/select.vue
  4. 116 0
      index/index.vue
  5. 130 0
      index/index_back.vue
  6. 95 0
      single_list/single_list.vue
  7. 78 0
      single_row/single_row.vue

+ 66 - 0
brief/brief.vue

@@ -0,0 +1,66 @@
+<template>
+	<view class="brief_body" :style="'background-image:url('+ back +')'">
+		<view v-for="(item, i) in p" :key="i">
+			<view class="paragraph" v-if="item.context" v-text="item.context"></view>
+			<image v-if="item.url"
+				:style=" item.style ? 'width:'+ item.style.w +'px;height:' + item.style.h + 'px' : '' " :src="item.url"
+				@load="e=>imageload(e,i)" mode="scaleToFill"></image>
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import {
+		defineProps,
+		ref
+	} from "vue";
+	import config from "../../config/index.js";
+	import {
+		onShareAppMessage,
+		onShareTimeline
+	} from '@dcloudio/uni-app'
+	onShareAppMessage(() => {})
+	onShareTimeline(() => {})
+	const props = defineProps({
+		page: String
+	})
+	const p = ref([]);
+	const back = ref("");
+	const info = uni.getSystemInfoSync();
+	uni.request({
+		url: config.base + props.page + ".json?" + Date.now(),
+		success: r => {
+			if (r.statusCode !== 200) return
+			p.value = r.data.list || [];
+			back.value = r.data.background || "";
+		}
+	})
+
+	function imageload(v, i) {
+		const w = info.windowWidth;
+		const h = v.detail.height / v.detail.width * w;
+		p.value[i].style = {
+			w,
+			h
+		};
+	}
+</script>
+
+<style lang="scss">
+	.brief_body {
+		font-size: 0;
+		background-position: 0%;
+		background-size: 100% 100%;
+		background-repeat: no-repeat;
+		height: 100vh;
+		overflow-y: auto;
+
+
+		.paragraph {
+			font-size: 16px;
+			padding: .5em;
+			text-indent: 2em;
+			line-height: 1.5em;
+		}
+	}
+</style>

+ 92 - 0
detail/detail.vue

@@ -0,0 +1,92 @@
+<template>
+	<view class="detail_body" v-if="item.avatar">
+		<image v-if="item.avatar" @load="loaded" :style="'width:'+ headImg.w +'px;height:'+ headImg.h +'px'"
+			:src="item.avatar" mode="scaleToFill"></image>
+		<view class="dl" v-if="typeof item.introduction === 'string'" v-text="item.introduction"></view>
+		<view class="dl" v-else v-for="(v, i) in item.introduction" v-text="v" :key="i"></view>
+		<view class="btn" @click="()=>showPDF(item.pdfUrl)">
+			详情
+		</view>
+		<view style="display: flex;margin-top: 5em;" v-if="item.pdfUrl_z && item.pdfUrl_z.length">
+			<local-select @open="()=>open(i)" @change="url=>change(i, url)" v-for="(v,i) in item.pdfUrl_z" :key="i"
+				style="flex: 1;" :url="v.url" :fOpen="v.fOpen" :btnText="v.text" :list="v.child"></local-select>
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import {
+		ref
+	} from "vue";
+	import {
+		showPDF
+	} from "../../unit/index.js";
+	import config from "../../config/index.js";
+	import localSelect from "./select.vue"
+	import {
+		onShareAppMessage,
+		onShareTimeline,
+		onLoad
+	} from '@dcloudio/uni-app'
+	const App = getApp();
+	const info = uni.getSystemInfoSync();
+	const item = ref({});
+	onShareAppMessage(() => {})
+	onShareTimeline(() => {})
+	onLoad(option => {
+		console.log(option) // 所属数列
+		uni.request({
+			url: config.base + option.page + ".json?" + Date.now(),
+			success: res => {
+				if (res.statusCode !== 200) return
+				item.value = res.data[option.index];
+			}
+		})
+	})
+	const headImg = ref({
+		w: 0,
+		h: 0
+	})
+
+	function loaded(v) {
+		const w = info.windowWidth;
+		const h = v.detail.height / v.detail.width * w;
+		headImg.value = {
+			w,
+			h
+		}
+	}
+
+	function change(i, url) {
+		const pdfURl = url ? url : item.value.pdfUrl_z[i].pdfurl;
+		showPDF(pdfURl);
+	}
+
+	function open(i) {
+		item.value.pdfUrl_z[i].fOpen = !item.value.pdfUrl_z[i].fOpen
+	}
+</script>
+
+<style lang="scss">
+	.detail_body {
+		background-color: #fff;
+		height: 100vh;
+		padding-bottom: 1.5em;
+		overflow-y: auto;
+
+		.dl {
+			padding: .2em .5em;
+			text-indent: 2em;
+		}
+
+		.btn {
+			width: 50%;
+			margin: 2.5em auto;
+			text-align: center;
+			border-radius: 5px;
+			background-color: #b5bdc3;
+			line-height: 2.5em;
+			color: #fff;
+		}
+	}
+</style>

+ 72 - 0
detail/select.vue

@@ -0,0 +1,72 @@
+<template>
+	<view>
+		<view class="select">
+			<view class="slect_list" :style="'top:-' + (props.list.length) * 2.55 + 'em'">
+				<view v-if="props.fOpen" :class="{list_item: true, list_item_act: props.fOpen}"
+					v-for="(v,i) in props.list" :key="'select-'+ i" v-text="v.text" @click="()=>change(v)"></view>
+			</view>
+			<view class="text" v-text="props.btnText || '请选择'" @click="show"></view>
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import {
+		defineProps,
+		defineEmits,
+		ref
+	} from "vue";
+	const props = defineProps({
+		btnText: String,
+		list: Array,
+		url: String,
+		fOpen: Boolean
+	});
+	const emits = defineEmits(['open', 'change']);
+
+	function change(v) {
+		emits("open");
+		emits("change", v.value);
+	}
+	
+	function show() {
+		props.url ? emits('change', props.url) : emits('open');
+	}
+</script>
+
+<style lang="scss">
+	.select {
+		position: relative;
+		display: inline-block;
+		width: 90%;
+		margin: 0 .5em;
+		text-align: center;
+		border-radius: 5px;
+		background-color: #b5bdc3;
+		line-height: 2.5em;
+		color: #fff;
+
+		.slect_list {
+			position: absolute;
+			width: 100%;
+			background-color: #b5bdc3;
+			text-align: center;
+			border-top-left-radius: 5px;
+			border-top-right-radius: 5px;
+
+			.list_item {
+				line-height: 2.5em;
+				text-align: center;
+				height: 0;
+				transition: all .2s;
+				width: 100%;
+				border-bottom: 1px solid #eee;
+			}
+
+			.list_item_act {
+				height: 2.5em;
+			}
+
+		}
+	}
+</style>

+ 116 - 0
index/index.vue

@@ -0,0 +1,116 @@
+<template>
+	<view class="body">
+		<view v-for="(item,i) in list" :key="i">
+			<image v-if="item.cover" class="imgStryle"
+				:style=" item.style ? 'width:'+ item.style.w +'px;height:' + item.style.h + 'px' : '' "
+				@load="v=>loadIndex(v,i)" @click="() => tonext(item)" :src="item.cover" mode="scaleToFill" />
+			<swiper @change="e=>change(i + '-' + e.detail.current)" v-if="item.swiper_list && item.swiper_list.length"
+				:indicator-dots="true" :autoplay="autoplay"
+				:style=" item.swiper_list[0].style ? 'height:' + item.swiper_list[0].style.h + 'px' : '' "
+				:interval="3000" :duration="1000">
+				<swiper-item v-for="(v, o) in item.swiper_list" :key="'swiper-item' + i">
+					<video class="imgStryle videos" :id="`${i}-${o}`"
+						:style=" v.style ? 'width:'+ v.style.w +'px;height:' + v.style.h + 'px' : '' " :src="v.url"
+						:autoplay="item.current == o"
+						@loadedmetadata="video_item=>videoLoadIndex(video_item.detail, i, o)" initial-time="0.01"
+						@play="play" @ended="ended" :poster="v.cover" :enable-progress-gesture="false" controls></video>
+				</swiper-item>
+			</swiper>
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import {
+		ref
+	} from "vue";
+	import config from "../../config/index.js";
+	import {
+		onShareAppMessage,
+		onShareTimeline,
+		onReady
+	} from '@dcloudio/uni-app'
+
+	const info = uni.getSystemInfoSync();
+	const list = ref([]);
+	const autoplay = ref(true);
+	let lastVideoId = undefined;
+	onShareAppMessage(() => {})
+	onShareTimeline(() => {})
+	onReady(() => {
+
+	})
+
+	uni.request({
+		url: config.base + "home.json?" + Date.now(),
+		success: r => {
+			if (r.statusCode !== 200) return
+			const list_json = r.data.list || [];
+			list.value = list_json;
+		}
+	})
+
+	function loadIndex(v, i) {
+		const w = info.windowWidth - 16;
+		const h = v.detail.height / v.detail.width * w;
+		list.value[i].style = {
+			w,
+			h
+		};
+	}
+
+	function videoLoadIndex(v, i, o) {
+		const w = info.windowWidth - 16;
+		const h = v.height / v.width * w;
+		list.value[i].swiper_list[o].style = {
+			w,
+			h
+		}
+	}
+
+	function tonext(T) {
+		T.pageType === "detail" && uni.navigateTo({
+			url: "/pages/brief/brief?title=" + T.subTitle + "&page=" + T.page
+		});
+
+		T.pageType === "single_row" && uni.navigateTo({
+			url: "/pages/single_row/single_row?title=" + T.title + "&url=" + T.headCover + "&page=" + T.page
+		})
+
+		T.pageType === "single_list" && uni.navigateTo({
+			url: "/pages/single_list/single_list?title=" + T.title + "&url=" + T.headCover + "&page=" + T.page
+		})
+	}
+
+	function play(e) {
+		autoplay.value = false;
+		if (e.currentTarget.id === lastVideoId || !lastVideoId) {
+			lastVideoId = e.currentTarget.id
+			return
+		}
+		const oldVideo = wx.createVideoContext(lastVideoId, this);
+		oldVideo.pause();
+		lastVideoId = e.currentTarget.id
+	}
+
+	function ended() {
+		autoplay.value = true;
+	}
+
+	function change(id) {
+		if (!wx || !id || lastVideoId === id) return
+		const nowVideo = wx.createVideoContext(id, this);
+		nowVideo.play();
+	}
+</script>
+
+<style lang="scss">
+	.body {
+		padding: 1em 0;
+
+		.imgStryle {
+			margin: 2px 8px;
+			border-radius: 10px;
+		}
+	}
+</style>

+ 130 - 0
index/index_back.vue

@@ -0,0 +1,130 @@
+<template>
+	<view class="body">
+		<image class="imgStryle" :style=" item.style ? 'width:'+ item.style.w +'px;height:' + item.style.h + 'px' : '' "
+			@load="v=>loadIndex(v,i)" @click="() => tonext(item)" v-for="(item,i) in list" :key="i" :src="item.cover"
+			mode="scaleToFill"></image>
+		<video @loadedmetadata="startPlay" v-if="urlVideo" class="video"
+			:style="{width: videoInfo.width + 'px',height: videoInfo.height + 'px', left: videoInfo.left +'px', top: videoInfo.top + 'px'}"
+			:src="urlVideo" autoplay :controls="false" :show-play-btn="false" :show-center-play-btn="false"
+			:show-fullscreen-btn="false" :show-loading="false" :enable-progress-gesture="false"
+			:vslide-gesture-in-fullscreen="false" @ended="ended" @error="ended"></video>
+		<view v-if="urlVideo" class="tg" @click="ended">
+			跳过
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import {
+		ref
+	} from "vue";
+	import config from "../../config/index.js";
+	const info = uni.getSystemInfoSync();
+	const list = ref([]);
+	const urlVideo = ref("");
+	const videoInfo = ref({
+		width: 0,
+		height: 0,
+		left: 0,
+		top: 0
+	})
+
+	uni.request({
+		url: config.base + "home.json?" + Date.now(),
+		success: r => {
+			if (r.statusCode !== 200) return
+			list.value = r.data.list || [];
+			urlVideo.value = r.data.video || "";
+		}
+	})
+
+	function loadIndex(v, i) {
+		const w = info.windowWidth - 16;
+		const h = v.detail.height / v.detail.width * w;
+		list.value[i].style = {
+			w,
+			h
+		};
+	}
+
+	function tonext(T) {
+		T.pageType === "detail" && uni.navigateTo({
+			url: "/pages/brief/brief?title=" + T.subTitle + "&page=" + T.page
+		});
+
+		T.pageType === "single_row" && uni.navigateTo({
+			url: "/pages/single_row/single_row?title=" + T.title + "&url=" + T.headCover + "&page=" + T.page
+		})
+
+		T.pageType === "single_list" && uni.navigateTo({
+			url: "/pages/single_list/single_list?title=" + T.title + "&url=" + T.headCover + "&page=" + T.page
+		})
+	}
+
+	function ended() {
+		urlVideo.value = "";
+	}
+
+	function startPlay(res) {
+		const videoInfoFun = res.detail || {};
+		let width = 0, height= 0;
+		if(videoInfoFun.width < videoInfoFun.height){
+			// 宽为短边
+			width = info.windowWidth;
+			height = info.windowWidth / videoInfoFun.width * videoInfoFun.height
+		}else {
+			// 高为短边
+			height = info.windowHeight;
+			width = info.windowHeight / videoInfoFun.height * videoInfoFun.width
+		}
+		
+		// 修改之后在做判断宽高是否小于屏幕
+		if (width < info.windowWidth){
+			// 宽度不够的话再次伸缩一次
+			height = info.windowWidth / width * height;
+			width = info.windowWidth;
+		}
+		if (height < info.windowHeight){
+			// 高度不够的话再次伸缩一次
+			width = info.windowHeight / height * width;
+			height = info.windowHeight
+		}
+		
+		videoInfo.value.width = width;
+		videoInfo.value.height = height;
+		if (width > info.windowWidth) videoInfo.value.left = (info.windowWidth - width) / 2;
+		if (height > info.windowHeight) videoInfo.value.top = (info.windowHeight - height) / 2;
+	}
+</script>
+
+<style lang="scss">
+	.body {
+		padding: 1em 0;
+
+		.imgStryle {
+			margin: 2px 8px;
+			border-radius: 10px;
+		}
+
+		.video {
+			position: fixed;
+			z-index: 9998;
+		}
+
+		.tg {
+			position: fixed;
+			z-index: 9999;
+			border-radius: 2em;
+			width: 3em;
+			height: 1.5em;
+			line-height: 1.5em;
+			border: 1px solid #fff;
+			color: #fff;
+			text-align: center;
+			top: 3em;
+			right: 2em;
+			font-size: 16px;
+			padding: 2px 4px;
+		}
+	}
+</style>

+ 95 - 0
single_list/single_list.vue

@@ -0,0 +1,95 @@
+<template>
+	<image v-if="props.url" @load="loaded" :style="'width:'+ headImg.w +'px;height:'+ headImg.h +'px'" :src="props.url"
+		mode="scaleToFill"></image>
+	<image class="row_img" :style=" item.style ? 'width:'+ item.style.w +'px;height:' + item.style.h + 'px' : ''"
+		@load="v=>loadIndex(v,i)" :src="item.cover" @click="()=>open(item)" v-for="(item,i) in list" :key="i"
+		mode="scaleToFill"></image>
+</template>
+
+<script setup>
+	import {
+		ref,
+		defineProps
+	} from "vue";
+	import {
+		showPDF
+	} from "../../unit/index.js";
+	import config from "../../config/index.js";
+	import { onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
+	onShareAppMessage(()=>{})
+	onShareTimeline(()=>{})
+	const info = uni.getSystemInfoSync();
+	const props = defineProps({
+		title: String,
+		url: String,
+		page: String
+	})
+
+	uni.setNavigationBarTitle({
+		title: props.title
+	})
+
+	const list = ref([]);
+
+	uni.request({
+		url: config.base + props.page + ".json?" + Date.now(),
+		success: res => {
+			if (res.statusCode !== 200) return
+			list.value = res.data || [];
+		}
+	})
+
+	const headImg = ref({
+		w: 0,
+		h: 0
+	})
+
+	function loaded(v) {
+		const w = info.windowWidth;
+		const h = v.detail.height / v.detail.width * w;
+		headImg.value = {
+			w,
+			h
+		}
+	}
+
+
+	function loadIndex(v, i) {
+		const w = info.windowWidth - 8;
+		const h = v.detail.height / v.detail.width * w;
+		list.value[i].style = {
+			w,
+			h
+		};
+	}
+
+	function open(item) {
+		if (!item.pdfUrl) {
+			uni.showToast({
+				title: "暂无数据",
+				icon: "none"
+			});
+			return
+		}
+		const file_type = item.pdfUrl.split(".").reverse()[0];
+		if (file_type === 'mp4') {
+			wx.previewMedia({
+				sources: [
+					{
+						url: item.pdfUrl,
+						type: 'video'
+					}
+				]
+			})
+			return
+		} else if (file_type === 'pdf') showPDF(item.pdfUrl);
+	}
+</script>
+
+<style lang="scss">
+	.row_img {
+		display: block;
+		margin: 4px 0 0 4px;
+		border-radius: 7px;
+	}
+</style>

+ 78 - 0
single_row/single_row.vue

@@ -0,0 +1,78 @@
+<template>
+	<image v-if="props.url" @load="loaded" :style="'width:'+ headImg.w +'px;height:'+ headImg.h +'px'" :src="props.url"
+		mode="scaleToFill"></image>
+	<image class="col_img" :style=" item.style ? 'width:'+ item.style.w +'px;height:' + item.style.h + 'px' : ''"
+		@load="v=>loadIndex(v,i, item.isRow)" :src="item.avatar" @click="()=>toPDF(i)" v-for="(item,i) in list"
+		:key="i" mode="scaleToFill"></image>
+</template>
+
+<script setup>
+	import {
+		ref,
+		defineProps
+	} from "vue";
+	import config from "../../config/index.js";
+	import { onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
+	onShareAppMessage(()=>{})
+	onShareTimeline(()=>{})
+	const info = uni.getSystemInfoSync();
+	const props = defineProps({
+		title: String,
+		url: String,
+		page: String
+	})
+
+	uni.setNavigationBarTitle({
+		title: props.title
+	})
+
+	const list = ref([]);
+	
+	uni.request({
+		url: config.base + props.page + ".json?" + Date.now(),
+		success: res => {
+			if (res.statusCode !== 200) return
+			list.value = res.data || [];
+		}
+	})
+
+	const headImg = ref({
+		w: 0,
+		h: 0
+	})
+
+	function loaded(v) {
+		const w = info.windowWidth;
+		const h = v.detail.height / v.detail.width * w;
+		headImg.value = {
+			w,
+			h
+		}
+	}
+
+
+	function loadIndex(v, i, isRow) {
+		const oW = isRow ? info.windowWidth : info.windowWidth / 2;
+		const w = oW - 8;
+		const h = v.detail.height / v.detail.width * w;
+		list.value[i].style = {
+			w,
+			h
+		};
+	}
+
+	function toPDF(i) {
+		uni.navigateTo({
+			url: "/pages/detail/detail?index=" + i + "&page=" + props.page
+		})
+
+	}
+</script>
+
+<style lang="scss">
+	.col_img {
+		display: inline-block;
+		margin: 4px 0 0 4px;
+		border-radius: 7px;
+	}
+</style>