名医精彩

This commit is contained in:
liuyuan
2025-06-20 17:40:41 +08:00
parent a26581fd81
commit 6dd6e9d213
59 changed files with 12940 additions and 86 deletions

View File

@@ -0,0 +1,842 @@
<template>
<view
class="container playerBox"
id="playerBox"
style="
background-color: #000;
width: 100%;
height: 200px;
position: relative;
padding: 0;
"
>
<!-- ios不能播放私有加密提示信息 start-->
<!-- ios不能播放私有加密提示信息 end-->
<div ref="videoContent" id="url-player-test"></div>
<div
v-show="false"
:videoData="videoData"
:isDipose="isDipose"
:winWidth="winWidth"
:winHeight="winHeight"
:firstTime="firstTime"
:isOnLoad="isOnLoad"
:platform="platform"
:isSetFirstTime="isSetFirstTime"
:isChange="isChange"
:change:videoData="renderScript.receiveMsg"
:change:isDipose="renderScript.receiveisDipose"
:change:winWidth="renderScript.receiveWinWidth"
:change:winHeight="renderScript.receiveWinHeight"
:change:firstTime="renderScript.receiveFirstTime"
:change:isSetFirstTime="renderScript.receiveisSetFirstTime"
:change:isOnLoad="renderScript.receiveIsfresh"
:change:platform="renderScript.receiveplatform"
:change:isChange="renderScript.receiveIsChange"
></div>
<div @tap="renderScript.emitData" ref="videoContent1" v-show="false">
直接调用renderjs中的emitData的方法,传递当前播放时长
</div>
<div @tap="renderScript.endEmitData" ref="videoContent2" v-show="false">
监听结束方法记录播放时长
</div>
<div @tap="renderScript.changeVideoData" ref="videoContent3" v-show="false">
监听切换视频方法
</div>
<div @tap="renderScript.emitSetData" ref="videoContent4" v-show="false">
监听第一次初始播放时长,开始进行接口存储时间
</div>
<div @tap="renderScript.emitDispose" ref="videoContent6" v-show="false">
监听第一次初始播放时长,开始进行接口存储时间
</div>
<!-- v-if="platform != 'ios'" -->
<!-- 全屏按钮 start -->
<!-- 注意主要用于安卓端因为ios手机会被劫持 -->
<div class="fullScreenButton-container">
<div
:class="`prism-fullscreen-btn ${isFullScreen ? 'fullscreen' : ''}`"
@tap="renderScript.changeVideoScreen"
></div>
</div>
<!-- 全屏按钮 end -->
</view>
</template>
<script>
import store from "@/store/index.js";
import $http from "@/config/requestConfig.js";
import { mapState, mapMutations } from "vuex";
export default {
props: {
videoData: {
type: Object,
default: {},
},
firstTime: {
type: Number,
default: 0,
},
},
data() {
return {
show: false, //视频提示显示
isDipose: false, //视频提示显示
content: "此设备暂不支持观看当前视频,请移步到安卓手机进行学习!",
platform: null, //设备类型
isFullScreen: false, //当前是否是全屏模式
isOnLoad: false, //是否刷新
isChange: false, //是否切换播放源
videoList: [], //视频列表
videoOssList: [], //本地视频列表
options: {}, //父组件传参
currentTime: "", //当前播放时间
isSetFirstTime: false, //是否获取到初始播放时间
urlList: {
checkVideo: "sociology/course/checkVideo",
},
};
},
computed: {
// ...mapState(["videoOssList"]),
},
watch: {
timer(newValue) {
this.$emit("child-event", newValue);
},
videoOssList: {
immediate: true,
handler(newValue) {
if (this.videoOssList.length > 0) {
uni.setStorageSync("videoOssList", JSON.stringify(this.videoOssList));
}
},
},
},
//
mounted() {
this.platform = this.$platform;
this.show = false;
if (uni.getStorageSync("videoOssList")) {
this.videoOssList = JSON.parse(uni.getStorageSync("videoOssList"));
}
},
//子组件销毁前
beforeDestroy() {
this.handleEnd();
clearInterval(this.$store.state.videoTimer);
plus.screen.lockOrientation("portrait-primary");
},
updated() {
// console.log("触发了更新");
},
methods: {
emitDispose1(status) {
this.$emit("handleSuccessDispose", status);
},
destory() {
// this.isDipose = true;
},
//ios不能播放私有加密提示信息
openShow() {
this.show = true;
},
changeVideoData() {
this.show = false;
this.isChange = false;
},
screenChange(data) {
this.isFullScreen = !data.status;
this.$emit("changeScreen", this.isFullScreen);
},
//当前播放时间 存本地
recordTime(time) {
this.currentTime = time;
var list = [...this.videoOssList];
var index = list.findIndex((e) => e.id == this.currentVideoId);
var setData = {
id: this.currentVideoId,
vid: this.videoData.vid,
time: time,
};
if (list.length > 0 && index >= 0) {
list[index] = setData;
} else {
list.push(setData);
}
this.videoOssList = list;
if (this.currentTime % 60 == 0) {
this.setVideoTime();
}
},
//播放结束
async handleEnd() {
// uni.showModal({
// title: "更新提示",
// content: "新版本已经准备好,是否重启应用?",
// success(res) {
// if (res.confirm) {
// }
// },
// });
this.setVideoTime();
},
//存播放进度
setVideoTime() {
if (!this.videoData.id) {
return false;
}
var data = {
videoId: this.videoData.id,
position: this.currentTime ? this.currentTime : 0, //秒数
loadAnimate: "none",
};
$http
.request({
url: `sociology/course/saveCoursePosition`,
method: "Post",
data,
header: {
"Content-Type": "application/json",
},
})
.then((res) => {});
},
//定时器 存播放进度
async setVideoFirtsetTime() {
this.setVideoTime();
},
},
};
</script>
<script module="renderScript" lang="renderjs">
var player;
import $ from "jquery";
export default {
data() {
return {
player: null, //播放器
videoTimer: null, //定时器
curTime: null, //播放器当前播放进度
curStatus: null, //播放器当前播放状态
playerConfig: {
id: "url-player-test",
extraInfo: { poster: "noposter" }, // 播放器参数 extraInfo 的内容会透传到 <video> 标签上
width: "100%", //容器的大小
height: "100%", //容器的大小
qualitySort: "asc",
cover: "",
autoplay: true,
isLive: false,
rePlay: false,
playsinline: true,
controlBarVisibility: "hover",
useH5Prism: true,
skinLayout: [],
},
skinLayoutIos: [
{
name: "bigPlayButton",
align: "blabs",
x: 30,
y: 80,
},
{
name: "H5Loading",
align: "cc",
},
{
name: "errorDisplay",
align: "tlabs",
x: 0,
y: 0,
},
{
name: "infoDisplay",
},
{
name: "tooltip",
align: "blabs",
x: 0,
y: 56,
},
{
name: "thumbnail",
},
{
name: "controlBar",
align: "blabs",
x: 0,
y: 0,
children: [
{
name: "progress",
align: "blabs",
x: 0,
y: 44,
},
{
name: "playButton",
align: "tl",
x: 15,
y: 12,
},
{
name: "timeDisplay",
align: "tl",
x: 10,
y: 7,
},
// {
// name: "fullScreenButton",
// align: "tr",
// x: 5,
// y: 12,
// },
{
name: "prism-speed-selector",
align: "tr",
x: 15,
y: 12,
},
{
name: "volume",
align: "tr",
x: 5,
y: 10,
},
],
},
],
skinLayoutAndroid: [
{
name: "bigPlayButton",
align: "blabs",
x: 30,
y: 80,
},
{
name: "H5Loading",
align: "cc",
},
{
name: "errorDisplay",
align: "tlabs",
x: 0,
y: 0,
},
{
name: "infoDisplay",
},
{
name: "tooltip",
align: "blabs",
x: 0,
y: 56,
},
{
name: "thumbnail",
},
{
name: "controlBar",
align: "blabs",
x: 0,
y: 0,
children: [
{
name: "progress",
align: "blabs",
x: 0,
y: 44,
},
{
name: "playButton",
align: "tl",
x: 15,
y: 12,
},
{
name: "timeDisplay",
align: "tl",
x: 10,
y: 7,
},
{
name: "prism-speed-selector",
align: "tr",
x: 15,
y: 12,
},
{
name: "volume",
align: "tr",
x: 5,
y: 10,
},
],
},
],
};
},
watch: {
//播放器当前播放进度
curTime(val) {
if (this.curTime !== null) {
this.$refs.videoContent1.click();
}
},
},
created() {},
mounted() {},
async beforeDestroy() {
if (player) {
player.dispose();
}
$("#url-player-test").empty();
console.log("阿里云子组件销毁赋空");
},
methods: {
//检验视频 获取加密权限
checkValue() {
if (!this.videoData.vid) {
setTimeout(() => {
this.checkValue();
}, 500);
} else {
setTimeout(() => {
this.initAliyunPlayer();
}, 0);
}
},
//初始化播放器
initAliyunPlayer() {
console.log("实例创建中 at line 436:", "实例创建中");
$("#url-player-test").empty();
// const saveTime = function (memoryVideo,currentTime) {
// console.log(memoryVideo, currentTime)
// }
// const getTime = function (memoryVideo) {
// /* return返回的是自定义起播时间 */
// return 20
// }
var components = [
{
name: "RateComponent", //倍速组件
type: AliPlayerComponent.RateComponent,
},
];
// if (this.platform != "ios") {
var fullScreenButtonComponent = Aliplayer.Component({
init: function (status, toAddress) {
this.fullScreenStatus = status;
this.$html = $(".fullScreenButton-container");
},
createEl: function (el) {
this.$html.find(".ad").attr("src", this.adAddress);
var $adWrapper = this.$html.find(".ad-wrapper");
$adWrapper.attr("href", this.toAddress);
$adWrapper.click(function () {});
$(el).find(".prism-time-display").after(this.$html);
},
});
components = [
...components,
{
name: "adComponent", //自定义全屏组件
type: fullScreenButtonComponent,
},
];
// }
//设置播放基本配置
var playerOptions = {
...this.playerConfig,
components: components,
skinLayout:
this.platform == "ios" ? this.skinLayoutIos : this.skinLayoutAndroid,
};
if (this.videoData.encryptType == 1) {
playerOptions = {
...playerOptions,
vid: this.videoData.vid,
playauth: this.videoData.playAuth, // 必选参数参数值可通过调用GetVideoPlayAuth接口获取。
encryptType: 1, // 必选参数当播放私有加密流时需要设置本参数值为1。其它情况无需设置。
playConfig: {
EncryptType: "AliyunVoDEncryption",
},
};
} else {
playerOptions = {
...playerOptions,
source: this.videoData.source,
};
}
player = new Aliplayer(playerOptions, (player) => {
player.on("ready", () => {
this.player = player;
var lastTime = this.firstTime;
if (this.platform == "ios") {
this.player.one("canplay", () => {
this.player.seek(this.firstTime);
// uni.showToast({
// title: '已为您定位至上次观看位置'
// })
});
} else {
this.player.seek(this.firstTime);
// uni.showToast({
// title: '已为您定位至上次观看位置'
// })
}
this.player.one("timeupdate", () => {
if (!this.player.tag.seeking) {
// 更新最近一次的播放位置
lastTime = parseInt(this.player.getCurrentTime());
this.curTime = lastTime;
}
});
this.player.on("timeupdate", () => {
if (!this.player.tag.seeking) {
// 更新最近一次的播放位置
lastTime = parseInt(this.player.getCurrentTime());
this.curTime = lastTime;
}
});
this.player.on("ended", () => {
lastTime = parseInt(this.player.getCurrentTime());
this.curTime = lastTime;
this.$refs.videoContent2.click();
});
player.on("dispose", (res) => {
console.log("播放器销毁:", res);
});
});
});
},
//调用 recordTime 方法 存本地播放时长
emitData(event, ownerInstance) {
ownerInstance.callMethod("recordTime", this.curTime);
},
//调用 setVideoFirtsetTime 设置初始播放
emitSetData(event, ownerInstance) {
ownerInstance.callMethod("setVideoFirtsetTime");
},
//调用 openShow 设置ios 不能播放私用加密 提示信息
emitopenShow(event, ownerInstance) {
ownerInstance.callMethod("openShow");
},
emitDispose(event, ownerInstance) {
ownerInstance.callMethod("emitDispose1", true);
},
//调用 handleEnd 存储视频播放信息
endEmitData(event, ownerInstance) {
ownerInstance.callMethod("handleEnd");
},
changeVideoScreen(event, ownerInstance) {
var that = this;
// this.$emit('changeScreenLoading',true)
var status = this.player.fullscreenService.getIsFullScreen();
console.log('this.$platform--------', this.platform);
if (this.platform != 'ios') { // 改变按钮形态
ownerInstance.callMethod('screenChange', {
status: status,
primary: status ? 'portrait' : 'landscape'
})
}
if (status) {
if (this.platform != 'ios') {
console.log('恢复竖版');
setTimeout(() => {
plus.screen.lockOrientation("portrait-primary"); //锁死屏幕方向为竖屏
this.player.fullscreenService.cancelFullScreen();
}, 100);
}
} else {
this.player.fullscreenService.requestFullScreen();
if (this.platform != 'ios') {
setTimeout(() => {
plus.screen.lockOrientation("landscape-primary");
}, 100);
} else {
console.log('不要旋转, 使用原生全屏');
}
}
},
//调用 changeVideoData 切换播放源
changeVideoData(event, ownerInstance) {
ownerInstance.callMethod("changeVideoData");
},
//切换播放源
async receiveIsChange(newValue) {
if (this.isChange) {
this.checkValue();
}
},
handleClick(event, ownerInstance) {}, //点击播放器
receiveFirstTime(newValue, oldValue, ownerVm, vm) {}, //播放时间
async receiveisDipose(newValue, oldValue, ownerVm, vm) {
if (newValue) {
await player.dispose();
await this.$refs.videoContent6.click();
}
}, //播放时间
async receiveisPause(newValue, oldValue, ownerVm, vm) {}, //播放时间
receiveisSetFirstTime(newValue, oldValue, ownerVm, vm) {}, //是否刚开始设置播放时间
receiveMsg(newValue, oldValue, ownerVm, vm) {
if (typeof window.Aliplayer === "function") {
this.$nextTick(() => {
this.checkValue();
});
}
}, //是否刚开始设置播放时间
receiveplatform(newValue) {}, //获取设备型号
receiveVideoList(newValue, oldValue, ownerVm, vm) {}, //获取视频列表
receiveVideoData(newValue, oldValue, ownerVm, vm) {}, //获取视频信息
receiveWinWidth(newValue, oldValue, ownerVm, vm) {}, //获取视频宽度
receiveWinHeight(newValue, oldValue, ownerVm, vm) {}, //获取视频高度
},
};
</script>
<style>
.container {
width: 100vw;
height: auto;
/deep/.pause {
width: 60rpx !important;
height: 60rpx !important;
}
}
.fds {
background-color: blue;
height: 600rpx;
position: fixed;
top: 60rpx;
}
.returnBack {
flex-direction: row;
justify-content: flex-start;
align-items: center;
height: 88rpx;
padding-left: 20rpx;
}
.txt {
color: #fff;
}
.right_title {
background: #000;
height: 96rpx;
justify-content: space-between;
flex-direction: row;
align-items: center;
margin-left: auto;
}
.return {
flex-direction: row;
align-items: center;
color: #fff;
}
.right_handle {
width: 200rpx;
flex-direction: row;
justify-content: flex-end;
padding-right: 20rpx;
}
cover-view {
display: block;
line-height: 1.2;
overflow: hidden;
white-space: nowrap;
pointer-events: auto;
}
cover-view {
visibility: visible !important;
}
cover-image {
visibility: visible !important;
}
.fullScreenButton-container {
color: #fff;
float: right;
height: 35px;
margin-top: 6px;
margin-right: 5px;
display: flex;
align-items: center;
position: relative;
i {
color: #fff;
display: inline-block;
font-size: 22px;
display: block;
margin-top: 7px;
cursor: pointer;
& + i {
margin-left: 3px;
}
@media (min-width: 768px) {
&:hover + .player-tooltip {
display: block;
}
}
}
.player-tooltip {
&.prev {
left: -10px;
}
&.list {
left: 5px;
}
&.next {
right: -12px;
}
}
}
.playlist-content {
position: absolute;
right: 0;
width: 0px;
padding-bottom: 48px;
box-sizing: border-box;
height: 100%;
transition: all 0.38s ease-in-out;
overflow: hidden;
.list {
background-color: #000;
background-color: rgba(0, 0, 0, 0.3);
height: 100%;
overflow: auto;
.video-item {
color: #fff;
padding: 0px 10px;
line-height: 35px;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
&.active {
background-color: #000;
color: #00ddff;
}
@media (min-width: 768px) {
&:hover {
background-color: #000;
color: #00ddff;
}
}
}
}
}
.player-tooltip {
position: absolute;
display: none;
font-size: 12px;
color: #fff;
line-height: 28px;
letter-spacing: 0;
text-align: center;
background: #3c3c3c;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1);
height: 28px;
top: -48px;
padding: 0 5px;
white-space: nowrap;
}
.playlist-skip-tip {
padding: 5px 15px;
position: absolute;
top: 50%;
left: 50%;
z-index: 30;
line-height: 30px;
font-size: 14px;
border-radius: 4px;
background: rgba(255, 255, 255, 0.8);
color: #000;
text-align: center;
transform: translate(-50%, -50%);
}
#rotating-div {
width: 100vw;
height: 100vh;
background-color: #3498db;
transform: rotate(90deg);
/* 旋转90度 */
transform-origin: center center;
/* 设置旋转中心点在div中心 */
position: fixed;
/* 固定定位,全屏显示 */
left: 0;
top: 0;
bottom: 0;
right: 0;
}
</style>

View File

@@ -0,0 +1,575 @@
<template>
<view class="wrapper" :style="`width:100%;`">
<view class="tabs" id="tabs">
<slot name="tabs" :showTabs="showTabs"></slot>
<view :style="{ display: showTabs ? 'block' : 'none', ...tabStyle }" class="wrapper_tab">
<view :class="`${
currentTab == i ? 'hot wrapper_tab_item' : 'wrapper_tab_item'
}`" v-for="(v, i) in tabList" @click="clickItem(v, i)">
{{ v.title }}
<slot name="labelSlot" :data="v"></slot>
</view>
</view>
</view>
<slot name="otherContent" :showTabs="showTabs"></slot>
<view class="section_box" v-if="allDataList&&allDataList.length>0">
<view class="section" v-for="(v, i) in allDataList"
:style="`${i == 0 ? `padding-top:${Number(baseHeight)}px;` : ''}`">
<view class="section">
<view :id="v[titleKey]" style="padding: 20rpx"
:class="`${currentTab == i ? 'hot section_top' : 'section_top'}`">
<slot name="label" :title="v[titleKey]" :data="v" :dataIndex="i"></slot>
</view>
<view class="content section_content_progress">
<view class="content_list">
<slot :name="slotName ? slotName + '_' + v.slotName : 'contentList'" :showTabs="showTabs"
:dataList="v[dataListKey]" :data="v" :index="i"></slot>
</view>
</view>
</view>
</view>
</view>
<u-divider v-else-if="defaultShowTabs" text="暂无数据"></u-divider>
</view>
</template>
<script>
export default {
components: {},
props: [
"allDataList",
"dataListKey",
"tabStyle",
"titleKey",
"titleStyle",
"baseHeight",
"allTabList",
"slotName",
"defaultShowTabs",
],
data() {
return {
indexList: [],
itemArr: [],
distanceList: [],
tabList: [],
timer: null,
isLeftClick: false,
isOpenRightButton: true,
viewid: "cont0",
viewidIndex: 0,
openCollapseList: [],
cateIconList: [],
fdButtonStyle: {
width: "120rpx",
"border-color": "$themeColor",
color: "$themeColor",
float: "right",
"margin-right": "20rpx",
"margin-left": "30rpx",
},
modalInfo: {},
vip: {},
show: false,
options: {},
showTabs: this.defaultShowTabs ? this.defaultShowTabs : false, // 默认吸顶的tab不显示
currentTab: 0, // 由于初始化的uview的代码有bug所以默认是-1在第一次显示的时候设置0自动复位防止错误
distanceArr: [], // 每一个ID对应的scrollTop值
isTabChange: false, // 防止在点击tab的时候页面的滚动导致重复计算、抖动问题
};
},
// 监听页面滚动
watch: {
currentTab: {
immediate: true,
handler(newRoute) {
},
},
},
async onLoad(options) {
this.options = options;
await this.handleselectCate({
...this.cateList[0],
index: 0,
},
0
);
},
async onShow() {},
methods: {
// pageScroll(event) {
// // console.log("event at line 213:", event);
// // const _this = this;
// if (this.isTabChange) {
// return false;
// }
// const scrollTop = event.scrollTop;
// const skewY =
// Number(this.baseHeight) + 45 + +Number(this.statusBarHeight); // 偏移量由于吸顶的tab、头部的显示信息也有高度素以做了偏移量
// if (scrollTop >= skewY) {
// if (!this.showTabs && this.currentTab <= 0) {
// // 在未显示tab并且 currentTab <= 0时防止uview ui抖动bug设置默认复位值
// this.currentTab = 0;
// }
// this.showTabs = true;
// this.$nextTick(() => {
// // this.currentTab = null;
// const length = this.distanceArr.length;
// const index = this.distanceArr.findIndex(
// (el) => el.top - skewY - scrollTop - 40 > 0
// );
// // 当index == -1 的时候实际当前滚动的距离超出了最大值也就是在最后一个tab显示的内容
// // 当index > 0 的时候说明能在当前的scrollTop值找到即index的前一位
// this.currentTab = index > 0 ? index - 1 : length - 1;
// });
// this.$forceUpdate();
// } else {
// this.showTabs = this.defaultShowTabs ? this.defaultShowTabs : false;
// this.currentTab = 0;
// }
// },
backClick() {
if (this.options.backType == "order") {
uni.switchTab({
url: "/pages/home/index",
});
} else {
uni.navigateBack({
delta: 1,
});
}
},
// 获取所有元素在当前页面所处的位置信息
getDistanceArr() {
this.distanceArr = [];
if (this.allTabList && this.allTabList.length > 0) {
this.tabList = [...this.allTabList];
} else {
this.tabList = [];
this.allDataList.forEach((e) => {
this.tabList.push({
title: e.title,
...e,
});
});
}
const _this = this;
// this.$nextTick(() => {
// _this.tabList.forEach((el) => {
// uni
// .createSelectorQuery()
// .select(".wrapper")
// .boundingClientRect((data) => {
// //目标位置的节点类class或者id
// uni
// .createSelectorQuery()
// .select("#" + el.title)
// .boundingClientRect((res) => {
// el.scrollTop =
// //最外层盒子的节点类class或者id
// _this.distanceArr.push({
// title: el.title,
// //top: Number(res.top.toFixed(0)),
// });
// })
// .exec();
// })
// .exec();
// this.currentTab = 0;
// });
// });
},
// clickItem(item, index) {
// var that = this;
// const skewY =
// Number(this.baseHeight) + 45 + +Number(this.statusBarHeight);
// this.isTabChange = true;
// this.$nextTick(() => {
// this.currentTab = index;
// var data = this.distanceArr.find((e) => e.title == item.title);
// uni.pageScrollTo({
// // duration: 100, //过渡时间
// scrollTop: data.top - skewY, //到达距离顶部的top值
// duration: 300,
// complete: function() {
// const timer = setTimeout(() => {
// that.isTabChange = false; // 关闭
// clearTimeout(timer);
// }, 1000); // 解决ios和安卓、鸿蒙系统兼容性问题
// },
// //scrollTop:data.top - res.top,//如果置顶
// });
// });
// },
},
};
</script>
<style lang="scss">
.wrapper {
position: absolute;
min-height: 60vh;
.header {
height: 100rpx;
background: orange;
.bg {
width: 100vw;
height: 200rpx;
}
}
.tabs {
position: fixed !important;
z-index: 970;
background-color: #fff;
width: 100vw;
.tabsStyle {
box-shadow: 0 2rpx 6rpx 0 rgba(153, 153, 153, 0.2);
::v-deep {
.u-tabs {
box-shadow: 0px 4px 6px 0 rgba(153, 153, 153, 0.2);
}
}
}
}
.section {
width: 100%;
padding: 0 0rpx;
box-sizing: border-box;
.section_top {
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
.title {
font-size: 40rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #333333;
margin-left: 30rpx;
position: relative;
&::before {
position: absolute;
content: "";
left: -30rpx;
width: 14rpx;
height: 77%;
top: 10%;
border-radius: 14rpx;
background: #7dc1f0;
}
}
.right {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 20rpx;
.dots {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 33rpx;
width: 26rpx;
align-items: center;
padding: 10rpx 20rpx;
margin-right: 4rpx;
.dot {
width: 9rpx;
height: 9rpx;
background: #000000;
border-radius: 50%;
}
}
.more_menu {
position: absolute;
top: 70rpx;
right: 0;
z-index: 99;
background: white;
padding: 0 20rpx;
box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.2);
border-radius: 4rpx;
.more_menu_item {
font-size: 30rpx;
padding: 24rpx 180rpx 24rpx 16rpx;
white-space: nowrap;
}
.more_menu_item:not(:last-child) {
border-bottom: 1rpx solid #dddddd;
}
}
}
}
.content {
background: #f8f8f9;
border-radius: 30rpx;
padding: 32rpx;
margin-top: 20rpx;
&_top {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
margin-bottom: 24rpx;
&_name {
font-weight: bold;
color: #333333;
font-size: 32rpx;
}
&_ismySelf {
background: #eeeeee;
font-weight: 500;
color: #999999;
font-size: 24rpx;
margin-left: 12rpx;
padding: 6rpx 18rpx;
border-radius: 10rpx;
}
}
&_Info {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
padding-bottom: 20rpx;
margin-top: 20rpx;
&_item {
display: flex;
flex-direction: column;
flex: 1;
text-align: center;
&_label {
text-align: center;
font-size: 24rpx;
font-weight: 300;
color: #999999;
}
&_value {
font-size: 34rpx;
font-weight: bold;
color: #333333;
margin-top: 14rpx;
}
}
&_item:not(:last-child) {
position: relative;
&::after {
position: absolute;
content: "";
width: 1rpx;
height: 70rpx;
top: 20rpx;
right: 0;
background: #d8d8d8;
}
}
}
&_Info:not(:last-child) {
border-bottom: 1rpx solid #d8d8d8;
}
&_remark {
font-weight: 400;
color: #333333;
font-size: 24rpx;
padding-top: 20rpx;
text-align: justify;
min-height: 40rpx;
}
&_list {
&_item {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
padding: 20rpx 0;
border-bottom: 1rpx solid #d8d8d8;
&_label {
font-size: 30rpx;
font-weight: 500;
color: #7dc1f0;
white-space: nowrap;
width: 180rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
&_value {
font-size: 30rpx;
font-weight: 400;
color: #666666;
flex: 1;
margin-left: 40rpx;
align-self: center;
word-break: break-all;
text-align: justify;
}
}
&_empty {
height: 180rpx;
background: #f8f8f9;
border-radius: 10rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
&_tip {
font-size: 20rpx;
font-weight: 400;
color: #999999;
margin-top: 20rpx;
line-height: 30rpx;
}
image {
width: 64rpx;
height: 50rpx;
}
}
&_emptyResult {
height: 240rpx;
image {
width: 166rpx;
height: 166rpx;
}
&_tip {
margin-top: 0;
}
}
}
&.reset {
padding: 0;
}
&_reportList {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 20rpx;
&_pack {
width: 100%;
height: calc(25vw - 30rpx);
border-radius: 20rpx;
}
&_addImage {
width: 100%;
height: calc(25vw - 30rpx);
background: #f8f8f9;
border-radius: 20rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
&_icon {
width: 60rpx;
height: 48rpx;
}
&_tip {
font-size: 20rpx;
font-weight: 400;
line-height: 30rpx;
color: #999999;
margin-top: 14rpx;
}
}
}
}
.section_content_progress {
background: initial;
padding: 0 15rpx;
}
.content_result {
background: initial;
font-size: 30rpx;
font-weight: 400;
color: #666666;
word-wrap: break-word;
word-break: normal;
line-height: 60rpx;
letter-spacing: 2rpx;
text-align: justify;
}
.content_report {
background: initial;
padding: 12rpx 0;
}
}
.section:not(:first-child) {
margin-top: 20rpx;
}
}
.hot {
color: #294a97 !important;
font-weight: bold;
}
.wrapper_tab {
width: 100%;
display: flex;
align-items: center;
justify-content: space-around;
font-size: 34rpx;
}
.wrapper_tab_item {
width: auto;
display: inline-block;
line-height: 60rpx;
padding: 10rpx 20rpx;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,114 @@
<template>
<view class="richDetail">
<view scroll-x="true" class="detail_title video_box" style="background-color: #fff">
<view v-for="(v, i) in dataList" :class="`video_item ${currentVideo.id == v.id ? 'hot' : ''}`"
@click="handleClick(v,i)">
{{ v.type == "2" ? "音频" : "视频" }}{{ getNumber(i + 1) }}
</view>
</view>
<slot name="richHeadImg"></slot>
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
import {
mapState
} from "vuex";
export default {
props: ["detailInfo", "dataList", "currentVideo"],
components: {},
data() {
return {};
},
onLoad(options) {},
onHide() {},
computed: {
...mapState(["userInfo"]),
},
methods: {
getNumber(num) {
if (num >= 10) {
return num;
} else {
return `0${num}`;
}
},
handleClick(data) {
this.$emit("open", data);
},
},
onBackPress() {
// #ifdef APP-PLUS
plus.key.hideSoftKeybord();
// #endif
},
};
</script>
<style lang="scss" scoped>
.commonPageBox {
padding: 40rpx 0;
}
.contentBox {
.headImage {
margin-bottom: 20rpx;
}
.detail_title {
padding: 0 20rpx 0;
font-size: 26rpx;
line-height: 65rpx;
font-weight: bold;
text-align: center;
box-sizing: border-box;
margin-bottom: 20rpx;
overflow: hidden;
}
.rich_box {
padding: 20rpx;
box-sizing: border-box;
p {
display: block;
text-indent: 2em;
letter-spacing: 2px !important;
line-height: 46rpx;
}
}
}
.richDetail {
width: 100%;
height: 100%;
}
.video_box {
width: 100%;
.video_item {
width: 23%;
margin-right: 10rpx;
float: left;
border: 2rpx solid #5188e5;
background: #fff;
color: #5188e5;
text-align: center;
border-radius: 10rpx;
box-shadow: 0px 0px 6rpx 0px rgba(255, 255, 255, 1);
}
.video_item:nth-child(4n) {
margin-right: 0;
}
}
.hot {
background-color: #5188e5 !important;
color: #fff !important;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -6,8 +6,8 @@
<view @click="gotoDetail(item, index)" class="scroll-view-item list_item"
v-for="(item, index) in dataList" :key="indexKey ? item[indexKey] : item.id"
:index="indexKey ? item[indexKey] : index">
<view :class="['titleItem', '']" :style="`width:${isNoIcon ? '100%' : 'calc(100% - 30rpx)'}`">
<slot name="leftSlot" :row="item" :item="item" :index="index"> </slot>
<view :class="['titleItem', '']" :style="`width:${isNoIcon ? '100%' : 'calc(100% - 50rpx)'}`">
<slot name="leftSlot" :row="item" :item="item" :index="index"></slot>
<template v-if="isCondition">
<slot name="labelSlot" :row="item" :rowIndex="index"></slot>
@@ -99,6 +99,7 @@
.rightArrow {
width: 40rpx;
height: 40rpx;
flex-shrink: 0;
}
.scroll-Y {
@@ -117,6 +118,7 @@
.titleItem {
width: calc(100% - 30rpx);
position: relative;
}
/deep/.scroll-view-item:nth-child(2n-1) {

View File

@@ -0,0 +1,376 @@
<template>
<view>
<!-- 优惠券弹出 -->
<u-popup :show="youhuiShow" :round="10" @close="closePup">
<view class="tanchu">
<view class="dp_title">请选择优惠券</view>
<template v-if="list.length > 0">
<view style="max-height: 40vh; overflow-y: scroll">
<view v-for="(item, index) in list" :key="index">
<view
:class="`youhuiItem ${
youhuiIndex === index ? ' youItem_style' : ''
} ${item.canUse === 0 ? 'disableSelect' : ''}`"
@click="choseYouhui(index)"
><text
class="border_radius_10"
style="
position: absolute;
top: 10rpx;
right: 10rpx;
font-size: 25rpx;
background-color: #ffe3e9;
color: #c81346;
padding: 6rpx;
"
>{{ item.couponEntity.couponRange | couponType }}</text
>
<view
style="width: 25%; color: #ff0043; text-align: center"
class="couponPrice"
>
<text></text>
<b style="font-size: 45rpx">{{
item.couponEntity.couponAmount
}}</b>
<text
class="useLevel"
style="
display: block;
color: #666;
font-size: 25rpx;
margin-top: 10rpx;
"
>{{ item.couponEntity.useLevel }}元可用</text
>
</view>
<view style="width: 68%; padding-left: 5%">
<view>
<text
style="
display: inline-block;
margin-right: 6rpx;
line-height: 36rpx;
"
>{{ item.couponEntity.couponName }}</text
>
</view>
<text
style="
display: block;
font-size: 22rpx;
color: #999;
margin-top: 10rpx;
"
>有效期至{{
item.effectType == 0 ? "永久有效" : item.endTime
}}</text
>
<template v-if="item.canUse == 0">
<view
class=""
style="font-size: 20rpx; display: inline-block"
>
<text style="color: #333">不可用原因</text>
<text style="color: #333">{{ item.canUseReason }}</text>
</view>
</template>
</view>
<view style="width: 7%; position: absolute; right: 20rpx; top: 43%">
<template v-if="item.canUse == 1">
<text
style="
border: 1px solid #d9d9d9;
width: 35rpx;
height: 35rpx;
display: inline-block;
border-radius: 30rpx;
"
v-if="youhuiIndex !== index"
></text>
<u-icon
name="checkmark-circle-fill"
color="#fd6004"
size="20"
v-if="youhuiIndex === index"
>
</u-icon>
</template>
</view>
<br clear="both" />
</view>
<u-collapse
v-if="source != 'goodsDetail' && item.couponEntity.remark"
style="
margin-top: 0rpx;
z-index: 10 !important;
background-color: #fafafa;
border-bottom-left-radius: 10rpx;
border-bottom-right-radius: 10rpx;
"
:border="false"
>
<u-collapse-item title="详细信息" name="Docs guide">
<view
v-if="item.couponEntity.remark"
style="
font-size: 22rpx;
width: 100%;
margin-right: 20rpx !important;
"
>使用说明{{ item.couponEntity.remark }}</view
>
</u-collapse-item>
</u-collapse>
</view>
</view>
<view class="btnBox flex_box flex_between" v-if="selectcouponList.length>0">
<view class="" style="width: 48%">
<button type="default" @click="confirmCoupon('none')">
不使用优惠券
</button>
</view>
<view class="" style="width: 48%">
<button type="primary" @click="confirmCoupon()">选好了</button>
</view>
</view>
<view class="btnBox flex_box flex_between" v-else>
<view class="" style="width: 100%">
<button type="default" @click="confirmCoupon('none')">
取消
</button>
</view>
</view>
</template>
<view class="" v-else>
<u-divider text="暂无可用优惠券哦"></u-divider>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
name: "orderCoupon",
props: ["list", "curCouponId", "sumMeony",'selectcouponList'],
data() {
return {
youhuiShow: true,
youhuiIndex: undefined,
};
},
mounted() {
console.log("进入了", this.curCouponId, this.sumMeony);
if (this.curCouponId) {
this.youhuiIndex = this.list.findIndex(
(item) => item.couponEntity.id === this.curCouponId
);
console.log("查找后的结果", this.youhuiIndex);
}
},
filters: {
couponType(type) {
// 0无限制 1课程卷 2课程品类卷
var str = "";
switch (type) {
case 0:
str = "全场通用";
break;
case 1:
str = "指定课程可用";
break;
case 2:
str = "指定课程品类可用";
break;
}
return str;
},
},
computed: {},
methods: {
closePup() {
this.youhuiIndex = undefined;
this.$emit("close");
},
// 确定选中优惠券
confirmCoupon(str) {
console.log(str, "6666");
if (str && str == "none") {
// 清空优惠券操作
this.$emit("confirmCoupon");
setTimeout(() => {
this.closePup();
}, 300);
return;
}
if (this.youhuiIndex == 0 || this.youhuiIndex) {
this.$emit("confirmCoupon", this.list[this.youhuiIndex]);
setTimeout(() => {
this.closePup();
}, 300);
} else {
uni.showToast({
title: "请选择您要使用的优惠券",
icon: "none",
});
}
},
// 选择优惠券
choseYouhui(e) {
if (this.list[e].canUse == 0) {
return;
}
console.log("选中优惠券e", e);
this.youhuiIndex = e;
},
},
};
</script>
<style lang="scss" scoped>
.btnBox {
margin-top: 20rpx;
}
.tanchu {
padding: 40rpx 30rpx 40rpx 30rpx;
position: relative;
.dp_title {
font-size: 32rpx;
margin-bottom: 50rpx;
color: #555;
text-align: center;
font-weight: bold;
}
.dp_add {
position: absolute;
top: 40rpx;
right: 30rpx;
font-size: 22rpx;
background-color: #fd6004;
color: #fff;
border-radius: 10rpx;
padding: 5rpx 10rpx;
.u-icon {
display: inline-block;
margin-right: 5rpx;
}
}
.addressItem {
border: 2px dashed #d9d9d9;
border-radius: 10rpx;
width: 100%;
display: flex;
padding: 20rpx 10rpx;
margin: 25rpx 0 0 0;
align-items: center;
background-color: #fff;
.addrContent {
margin-left: 40rpx;
flex: 1;
.addrContentTop {
display: flex;
align-items: flex-end;
margin: 0 0 15rpx 0;
position: relative;
.userName {
font-size: 35rpx;
font-weight: bold;
margin-right: 30rpx;
}
.userTel {
font-size: 25rpx;
color: #888;
}
.userMoren {
border: 1px solid #fd6004;
color: #fd6004;
padding: 3rpx 10rpx;
font-size: 22rpx;
border-radius: 10rpx;
margin: 0 0 0 20rpx;
}
.chooseCheck {
position: absolute;
top: 3rpx;
right: 6rpx;
}
}
.addrContentBottom {
font-size: 32rpx;
}
}
}
.addressItem.addItem_style {
border-color: #fd6004;
}
.youhuiItem {
position: relative;
background: linear-gradient(to top right, #fff, #fef2f4);
border: 1px solid #d9d9d9;
border-radius: 10rpx;
width: 100%;
padding: 50rpx 20rpx 20rpx;
margin: 25rpx 0 0 0;
align-items: center;
background-color: #fff;
font-size: 30rpx;
}
.disableSelect {
background: linear-gradient(to top right, #fafafa, #fafafa) !important;
color: #979797 !important;
.couponPrice {
color: #979797 !important;
}
.useLevel {
color: #979797 !important;
}
.border_radius_10 {
color: #98989a !important;
background-color: #fafafa !important;
}
}
.youhuiItem > view {
float: left;
}
.youhuiItem.youItem_style {
border-color: #fd6004;
}
}
::v-deep .u-cell__body {
padding-top: 0 !important ;
padding-bottom: 0 !important ;
z-index: 10 !important ;
.u-cell__title-text {
color: #333 !important;
font-size: 24rpx !important;
padding-left: 0 !important;
}
}
::v-deep .u-collapse-item__content__text {
padding: 10rpx 20rpx !important;
box-sizing: border-box;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,288 @@
<template>
<view class="richDetail">
<view class="detail_title" v-if="detailInfo.title">{{ detailInfo.title }}</view>
<slot name="richHeadImg"></slot>
<view class="rich_box" v-if="detailInfo.content">
<rich-text
:nodes="detailInfo.content | formatRichText"
@click.stop="showPreview"
:data-nodes="detailInfo.content"
></rich-text>
</view>
</view>
</template>
<script>
import $http from '@/config/requestConfig.js';
import {
mapState
} from 'vuex';
export default {
props: ['detailInfo',],
components: {
},
data() {
return {
}
},
onLoad(options) {
},
onHide() {
},
computed: {
...mapState(['userInfo']),
}, filters: {
/**
* 处理富文本里的图片宽度自适应
* 1.去掉img标签里的style、width、height属性
* 2.img标签添加style属性max-width:100%;height:auto
* 3.修改所有style里的width属性为max-width:100%
* 4.去掉<br/>标签
* @param html
* @returns {void|string|*}
*/
formatRichText(html) { //控制小程序中图片大小
let newContent = html.replace(/<img[^>]*>/gi, function (match, capture) {
match = match.replace(/style="[^"]+"/gi, '').replace(/style='[^']+'/gi, '');
match = match.replace(/width="[^"]+"/gi, '').replace(/width='[^']+'/gi, '');
match = match.replace(/height="[^"]+"/gi, '').replace(/height='[^']+'/gi, '');
return match;
});
newContent = newContent.replace(/style="[^"]+"/gi, function (match, capture) {
match = match.replace(/width:[^;]+;/gi, 'max-width:100%;').replace(/width:[^;]+;/gi,
'max-width:100%;');
return match;
});
newContent = newContent.replace(/<br[^>]*\/>/gi, '');
newContent = newContent.replace(/\<img/gi,
'<img style="max-width:100%;height:auto;display:inline-block;margin:10rpx auto;"');
return newContent;
},
// 时间格式化
formatDate(date) {
console.log(date)
let newDate = new Date(date);
let year = newDate.getFullYear();
let month = newDate.getMonth().toString().padStart(2, 0);
let day = newDate.getDay().toString().padStart(2, 0);
return year + '-' + month + '-' + day;
}
},
methods: {
formatRichText(html) { //控制图片大小
let newContent = html.replace(/<img[^>]*>/gi, function (match, capture) {
match = match.replace(/style="[^"]+"/gi, '').replace(/style='[^']+'/gi, '');
match = match.replace(/width="[^"]+"/gi, '').replace(/width='[^']+'/gi, '');
match = match.replace(/height="[^"]+"/gi, '').replace(/height='[^']+'/gi, '');
return match;
});
newContent = newContent.replace(/style="[^"]+"/gi, function (match, capture) {
match = match.replace(/width:[^;]+;/gi, 'max-width:100%;').replace(/width:[^;]+;/gi,
'max-width:100%;');
return match;
});
// newContent = newContent.replace(/<img[^>]*>/gi, function(match, capture) {
// match = match.replace(/<img[^>]*>/gi, "@click='1111'").replace(/<img[^>]*>/gi, "@click='1111'");
// return match;
// });
newContent = newContent.replace(/<br[^>]*\/>/gi, '');
newContent = newContent.replace(/\<img/gi,
'<img style="max-width:100%;height:auto;display:inline-block;margin:10rpx auto;"');
return newContent;
},
showPreview(e) {
console.log('e at line 56:', e)
let conimg = e.target.dataset.nodes;
let imgs = conimg.match(/<img[^>]+>/g);//选择节点中的img
console.log('imgs at line 59:', imgs)
let imgList = [];
//遍历img标签的src里面的内容放在定义的数组imgList中
for (var j = 0; j < imgs.length; j++) {
imgs[j].replace(/<img[^>]*src=['"]([^'"]+)[^>]*>/gi, function (match, capture) {
imgList.push(capture)
})
}
console.log('imgList.push at line 64:', imgList)
//最后一步就是所有图片放在预览的方法previewImage中就可以了
// uni.previewImage({
// current: imgList,
// urls: imgList,
// })
uni.previewImage({
urls: imgList,
longPressActions: {
itemList: ['很抱歉,暂不支持保存图片到本地'],
success: function (res) {
// console.log(res,'+++++')
}
}
});
},
// 放大图片
previewImage(url) {
console.log(url)
uni.previewImage({
urls: [url],
longPressActions: {
itemList: ['很抱歉,暂不支持保存图片到本地'],
success: function (res) {
// console.log(res,'+++++')
}
}
});
},
// getSearch() {
// $http.request({
// url: "book/prescript/searchPrescript",
// method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
// data: {
// loadAnimate: 'none', // 请求加载动画
// 'keywords': this.searchValue,
// type: this.currentCateIndex + 1
// },
// header: { //默认 无 说明:请求头
// 'Content-Type': 'application/json'
// },
// }).then(res => {
// console.log(res, '搜索结果')
// if (res.code == 0 && res.list.length >= 0) {
// this.showSearchList = true
// this.searchList = res.list
// } else {
// this.searchList = []
// }
// }).catch(e => {
// // this.dataList = []
// this.searchList = []
// console.log(e)
// })
// },
// search(res) {
// console.log(res, 'res')
// // uni.showToast({
// // title: '搜索:' + res,
// // icon: 'none'
// // })
// if (res == '') {
// this.showSearchList = false
// this.searchList = []
// } else {
// this.getSearch()
// }
// },
// input(res) {
// console.log('----input:', res)
// if (res == '') {
// this.searchList = []
// } else {
// this.getSearch()
// }
// },
// clear(res) {
// console.log('----clear:', res)
// // uni.showToast({
// // title: 'clear事件清除值为',
// // icon: 'none'
// // })
// this.searchValue = ''
// this.showSearchList = false
// },
// blur(res) {
// // console.log('----blur:', res)
// // if (res == '') {
// // this.showSearchList = false
// // this.searchList = []
// // } else {
// // this.getSearch()
// // }
// },
// focus(e) {
// console.log('----focus:')
// // uni.showToast({
// // title: 'focus事件输出值为' + e.value,
// // icon: 'none'
// // })
// // 等于1 就是有权限
// // this.showSearchList = true
// },
// cancel(res) {
// uni.showToast({
// title: '点击取消,输入值为:' + res.value,
// icon: 'none'
// })
// }
},
onBackPress() {
// #ifdef APP-PLUS
plus.key.hideSoftKeybord();
// #endif
},
}
</script>
<style lang="scss" scoped>
.commonPageBox {
padding: 40rpx 0;
}
.contentBox {
.headImage {
margin-bottom: 20rpx;
}
.detail_title {
padding: 20rpx 40rpx 0;
font-size: 38rpx;
line-height: 64rpx;
font-weight: bold;
text-align: center;
box-sizing: border-box;
margin-bottom: 20rpx;
}
.rich_box {
padding: 20rpx;
box-sizing: border-box;
::v-deep img {
max-height: 300rpx;
}
p {
display: block;
letter-spacing: 2px ;
line-height: 46rpx;
}
}
}
.richDetail {
width: 100%;
height: 100%;
}
.ql-size-small{
font-size:20rpx !important;
}
.ql-size-large{
font-size:36rpx !important;
}
.ql-size-huge{
font-size:64rpx !important;
}
</style>

View File

@@ -0,0 +1,368 @@
<template>
<view class="commonPageBox commonDetailPage" style="height: auto !important;padding-bottom: 0 !important;">
<u-popup :show="show" mode="bottom" @close="close" class="popup_box">
<view class="popup_top">
<view class="product_image">
<image
:src="selectGoodsData.productImages"
mode="aspectFit"
class="goods_image"
></image>
</view>
<view class="title">已选{{ selectGoodsData.productName }}</view>
</view>
<view :class="`common_radius_box goods_box popup_content`">
<view class="title title_box">
<view class="title_price" v-if="selectGoodsData.isVipPrice==1&&selectGoodsData.vipPrice!=null&&selectGoodsData.vipPrice!=0">
{{selectGoodsData.vipPrice}}
<text style=" font-weight: normal; padding-left: 15rpx; font-size: 26rpx;">VIP到手价</text>
</view>
<view class="title_price" v-else-if="selectGoodsData.activityPrice&&selectGoodsData.activityPrice>0">
{{selectGoodsData.activityPrice}}
<text style=" font-weight: normal; padding-left: 15rpx; font-size: 26rpx; color: #999;">活动价</text>
</view>
<text class="title_price" v-else>
{{selectGoodsData.price}}
</text>
<u-icon
name="close"
color="#333"
size="18"
@click="close"
style="display: inline-block"
></u-icon>
</view>
<view class="title title_list">
<text>商品列表{{ goodsList.length }}</text>
</view>
<common-list
imgUrl="url"
isNoIcon
imgMode="aspectFit"
defaultUrl=""
:isCondition="true"
:dataList="goodsList"
@hancleClick="selectGoods"
label="title"
>
<template slot="labelSlot" slot-scope="slotProps">
<!-- isSelectGoods -->
<view
class="related_courses_name"
:class="`goods_item ${
(!isFudu &&
selectGoodsData &&
selectGoodsData.productId == slotProps.row.productId) ||
(isFudu &&
selectGoodsData.productName == slotProps.row.productName)
? 'isSelectGoods color_shandow'
: ''
}`"
>
<view class="image_box" style="margin-right: 10rpx">
<image
:src="slotProps.row.productImages"
mode="aspectFit"
class="goods_image"></image>
</view>
<view :class="`goods_info `">
<view class="name">{{ slotProps.row.productName }}</view>
<view class="price">
<text v-html="getPrice(slotProps)"></text>
<text class="goods_text" v-if="slotProps.row.isVipPrice==1&&slotProps.row.vipPrice!=null&&slotProps.row.vipPrice!=0">
VIP优惠
</text>
</view>
</view>
</view>
</template>
</common-list>
<view class="goods_nav_box">
<uni-goods-nav
:fill="true"
:options="buyOptions"
:button-group="customButtonGroup1"
@click="onHandleClickBuy"
@buttonClick="onHandleClickBuy"
/>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import { mapState } from "vuex";
export default {
props: [
"goodsList",
"label",
"isCondition",
"imgUrl",
"imgMode",
"className",
"col",
"defaultUrl",
"isScroll",
"selectGoodsData",
"customButtonGroup1",
"buyOptions", "isFudu", // 是否复读
],
data() {
return {
show: false,
};
},
onLoad() {},
computed: {
...mapState(["userInfo"]),
},
methods: {
getPrice(slotProps) {
if (
Number(slotProps.row.isVipPrice) === 1 &&
Number(slotProps.row.vipPrice) > 0
) {
return `
<text style="color: #e97512; font-size: 28rpx; font-weight: bold;">
${Number(slotProps.row.vipPrice).toFixed(2)}
</text>
<text
style="color: #8a8a8a; font-size: 22rpx; margin-left: 4px; font-weight: bold; text-decoration: line-through;"
>
${Number(slotProps.row.price).toFixed(2)}
</text>
`;
} else if (Number(slotProps.row.activityPrice) > 0) {
return `
<text style="color: #e97512; font-size: 28rpx; font-weight: bold;">
${Number(slotProps.row.activityPrice).toFixed(2)}
</text>
<text
style="color: #8a8a8a; font-size: 22rpx; margin-left: 4px; font-weight: bold; text-decoration: line-through;"
>
${Number(slotProps.row.price).toFixed(2)}
</text>
`;
} else {
return `<span style="color: #e97512;font-size: 28rpx;font-weight: bold;">
${Number(slotProps.row.price).toFixed(2)}</span>
`;
}
},
// 放大图片
previewImage(url) {
console.log(url);
uni.previewImage({
urls: [url],
longPressActions: {
itemList: ["很抱歉,暂不支持保存图片到本地"],
success: function (res) {
},
},
});
},
close() {
this.show = false;
},
selectGoods(data) {
this.$emit("selectGoods", data);
},
open() {
this.show = true;
},
gotoDetail(v) {
this.$emit("hancleClick", v);
},
onHandleClickBuy() {
this.$emit("selectGoodsData", this.selectGoodsData);
this.$emit("onHandleClickBuy");
},
},
onBackPress() {
// #ifdef APP-PLUS
plus.key.hideSoftKeybord();
// #endif
},
components: {},
};
</script>
<style lang="scss" scoped>
@import '@/static/mixin.scss';
.goods_item {
overflow: hidden;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10rpx 20rpx;
border: 2rpx solid #fff;
border-radius: 10rpx;
}
.title {
box-sizing: border-box;
margin-bottom: 40rpx;
padding-left: 20rpx;
}
.image_box {
width: 70rpx;
height: 70rpx;
float: left;
background-color: #f5f5f5;
}
.goods_image {
width: 100%;
height: 100%;
}
.goods_info {
width: calc(100%);
box-sizing: border-box;
float: left;
.name {
font-size: 26rpx;
color: #333;
line-height: 36rpx;
}
.price {
font-size: 30rpx;
color: #aaa;
display: flex;
align-items: center;
margin-top: 5rpx;
}
}
.isSelectGoods {
color: $themeColor !important;
.name {
color: $themeColor !important;
}
.price {
color: $themeColor !important;
}
border: 2rpx solid $themeColor;
border-radius: 10rpx;
}
/deep/.list_item {
padding: 10rpx 0 !important;
padding-right: 0 !important;
}
.goods_image {
width: 100%;
height: 100%;
}
.curriulum_box {
margin-top: 20rpx;
width: 100%;
.curriulum_title_box {
display: flex;
align-items: center;
margin-bottom: 20rpx;
background-color: #fff;
.curriulum_title {
width: calc(100% - 80rpx);
font-size: 32rpx;
line-height: 40rpx;
padding: 20rpx;
box-sizing: border-box;
}
}
}
.goods_box {
background-color: #fff;
box-sizing: border-box;
width: 100%;
.curriulum_title_box {
width: calc(100%) !important;
padding-bottom: 20rpx;
background-color: #fff;
.curriulum_title {
width: calc(100%);
font-weight: 600;
font-size: 34rpx;
margin-top: 80rpx;
margin-bottom: 0rpx;
box-sizing: border-box;
}
}
}
.popup_box {
padding-top: 30rpx;
background-color: transparent;
.popup_top {
display: flex;
align-items: center;
color: #fff;
margin-bottom: 20rpx;
padding: 0 20rpx;
.title {
margin-bottom: 0;
font-size: 30rpx;
font-weight: 600;
}
}
.popup_content {
padding-bottom: 140rpx;
}
/deep/.list_item {
border: none !important;
box-shadow: none !important;
}
.product_image {
width: 120rpx;
height: 120rpx;
border-radius: 10rpx;
background-color: #f5f5f5;
}
}
/deep/.u-popup__content {
background-color: transparent !important;
}
/deep/.u-popup__content__close {
color: #fff !important;
}
.title_box {
display: flex;
align-items: center;
justify-content: space-between;
padding-left: 0;
.title_price {
color: #ef1224;
font-size: 40rpx;
font-weight: 700;
}
}
.line_text{
text-decoration: line-through;
font-size: 24rpx;
padding: 0 20rpx;
color: #999;
}
.goods_price{
color: #ff1f00;
font-weight: bold;
}
.goods_text{
font-size: 22rpx;
color: #ff1f00;
font-weight: bold;
}
/deep/.titleItem .related_courses_name{
width: calc(100%) !important;
}
</style>

View File

@@ -0,0 +1,91 @@
<template>
<view>
<u-tabs
lineWidth="30"
lineColor="#294a97"
:activeStyle="{
color: '#294a97',
transform: 'scale(1.05)',
}"
:inactiveStyle="{
color: '#606266',
transform: 'scale(1)',
}"
:itemStyle="itemStyle"
:keyName="label"
:list="dataList"
:is-scroll="false"
:current="currentCateIndex"
@change="handleselectCate"
>
<template slot="labelSlot" slot-scope="slotProps">
<slot name="labelSlot" :data="slotProps.data"></slot>
</template>
</u-tabs>
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
import { mapState } from "vuex";
export default {
props: ["list", "currentCateIndex", "label", "itemStyle"],
components: {},
data() {
return {
detailInfo: {},
playData: {},
searchValue: "",
twoCateList: [], // 二级分类标题
dataList: [{}, {}], // 方剂标题
curTwoCateIndex: 0, // 当前选中的二级分类
searchList: [], // 搜索结果数组
showSearchList: false,
userMes: {}, // 用户信息
searchDisable: false, // 搜索不可用
limitShow: false,
limitTitle: "提示",
limitContent: "",
};
},
onLoad() {
},
onHide() {
},
computed: {
...mapState(["userInfo"]),
},
watch: {
list: {
immediate: true,
handler(newRoute) {
this.dataList=[...this.list]
},
},
},
methods: {
async handleselectCate(e) {
this.$emit("handleselectCate", e, e.index);
var that = this;
},
},
onBackPress() {
// #ifdef APP-PLUS
plus.key.hideSoftKeybord();
// #endif
},
};
</script>
<style lang="scss" scoped>
/deep/.u-tabs .u-tabs__wrapper__nav__item__text{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>

View File

@@ -0,0 +1,387 @@
<template>
<view
class="container"
id="Aliyun"
:style="`background-color:# 000; position: relative; padding: 0`"
>
<div
:videoData="videoData"
style="color: #fff"
ref="AliyunFresh"
@tap="renderScript.handleClick"
v-show="false"
:change:videoData="renderScript.receiveMsg"
></div>
<view
v-if="show"
style="
width: 100%;
height: 200px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 38rpx;
text-align: center;
"
>
此设备暂不支持观看当前视频<br />请移步到安卓手机进行学习
</view>
<view v-else>
<template v-if="showAliYunPlayer">
<common-list-audio
id="commonAudio"
:showAliYunPlayer="showAliYunPlayer"
@handleSuccessDispose="handleSuccessDispose"
ref="commonVideoAliyun1"
v-if="videoInfo.type == 2"
:videoData="videoData"
:currentVideoIndex="currentVideoIndex"
:videoInfo="videoInfo"
:curriculumData="curriculumData"
:firstTime="firstTime"
>
</common-list-audio>
<common-list-aliyun
id="AliPlayer"
:showAliYunPlayer="showAliYunPlayer"
@handleSuccessDispose="handleSuccessDispose"
ref="commonVideoAliyun"
v-if="videoInfo.type != 2"
:videoData="videoData"
:firstTime="firstTime"
>
</common-list-aliyun>
</template>
<view v-else style="height: 200px"> </view>
</view>
</view>
</template>
<script>
import store from "@/store/index.js";
import $http from "@/config/requestConfig.js";
import { mapState, mapMutations } from "vuex";
import $ from "jquery";
export default {
props: {
currentVideoId: {
type: Number,
default: null,
},
currentVideoIndex: {
type: Number,
default: null,
},
curriculumData: {
type: Object,
default: {},
},
secondCountDown: {
type: Number,
default: null,
},
isfresh: {
type: Boolean,
default: false,
},
},
data() {
return {
showCountDown: false,
playEndBlank: false,
flag: false, //视频提示显示
show: false, //视频提示显示
// isfresh: false, //视频提示显示
showAliYunPlayer: false, //视频提示显示
content: "此设备暂不支持观看当前视频,请移步到安卓手机进行学习!",
platform: null, //设备类型
isFullScreen: false, //当前是否是全屏模式
isOnLoad: false, //是否刷新
isChange: false, //是否切换播放源
videoList: [], //视频列表
videoOssList: [], //本地视频列表
options: {}, //父组件传参
currentTime: "", //当前播放时间
videoData: {}, //获取当前的播放信息playAuthm3u8url
videoInfo: {}, //获取当前的播放信息playAuthm3u8url
isSetFirstTime: false, //是否获取到初始播放时间
firstTime: 0, //初始播放时间
urlList: {
checkVideo: "sociology/course/checkVideo",
},
};
},
computed: {
// ...mapState(["videoOssList"]),
},
watch: {
isOnLoad(newValue) {
if (this.isOnLoad) {
this.changeVideoData();
}
},
timer(newValue) {
this.$emit("child-event", newValue);
},
isfresh(newValue) {},
videoOssList: {
immediate: true,
handler(newValue) {
if (this.videoOssList.length > 0) {
uni.setStorageSync("videoOssList", JSON.stringify(this.videoOssList));
}
},
},
currentVideoId: {
immediate: true,
handler(newValue) {
if (newValue) {
// if (!this.isfresh) {
this.videoData = {};
this.showAliYunPlayer = false;
this.platform = this.$platform;
this.show = false;
this.isOnLoad = false;
this.videoData = {};
this.firstTime = 0;
if (uni.getStorageSync("videoOssList")) {
this.videoOssList = JSON.parse(uni.getStorageSync("videoOssList"));
}
this.$nextTick(() => {
this.checkVideo();
});
}
},
},
},
//
mounted() {},
//子组件销毁前
beforeDestroy() {
plus.screen.lockOrientation("portrait-primary");
},
beforeUpdate() {},
methods: {
hideNextVideo() {
this.showCountDown = false;
this.playEndBlank = false;
this.$emit("hideNextVideo");
},
destory() {
if (this.showAliYunPlayer) {
this.$nextTick(() => {
this.$refs.commonVideoAliyun.destory();
this.videoData = {};
});
}
},
handleSuccessDispose() {
this.showAliYunPlayer = false;
this.$emit("handleFresh", true);
},
//ios不能播放私有加密提示信息
openShow() {
this.show = true;
},
changeflag() {
this.flag = 1;
},
changeVideoData() {
if (this.videoData && this.videoData.id && this.flag == 1) {
this.showAliYunPlayer = true;
} else {
this.showAliYunPlayer = false;
setTimeout(() => {
this.changeVideoData();
}, 100);
}
},
//获取 video 初始化信息 (播放凭证 + m3u8)
async checkVideo() {
await $http
.request({
url: this.urlList.checkVideo,
method: "Post", // POST、GET、PUT、DELETE具体说明查看官方文档
data: {
id: this.currentVideoId,
loadAnimate: "none",
},
header: {
"Content-Type": "application/json",
},
})
.then(async (res) => {
console.log("res at line 204:", res.video);
var that = this;
this.videoInfo = res.video;
that.videoData = {
id: that.currentVideoId,
vid: res.video.video,
};
if (res.video.type == 1) {
if (res.video.m3u8Url == null || res.video.m3u8Url == "") {
//私有加密
if (that.$platform == "ios") {
that.show = true;
return false;
}
that.videoData.playAuth = res.video.playAuth.replace(/=/g, "");
that.videoData.encryptType = "1";
} else {
//标准加密
that.videoData.source = res.video.m3u8Url;
}
} else {
//mp4 mp3
that.videoData.source = res.video.videoUrl;
}
var netWork = res.video.userCourseVideoPositionEntity
? res.video.userCourseVideoPositionEntity.position
: 0;
var list = [...that.videoOssList];
if (list.length > 0) {
list = [];
var index = list.findIndex((e) => e.id == res.video.id);
if (netWork) {
if (index >= 0) {
that.firstTime =
list[index].time > netWork ? list[index].time : netWork;
} else {
that.firstTime = netWork ? netWork : 0;
}
} else {
if (index >= 0) {
that.firstTime = list[index].time ? list[index].time : 0;
}
}
if (res.video.duration - that.firstTime <= 2) {
that.firstTime = 0;
}
that.videoOssList = [...list];
}
that.isOnLoad = true;
});
},
},
};
</script>
<script module="renderScript" lang="renderjs">
import $ from "jquery";
export default {
data() {
return {
};
},
watch: {
},
created() {
if (typeof window.Aliplayer === 'function') {
} else {
// 动态引入较大类库避免影响页面展示
this.loadWebPlayerSDK(); //引入播放器sdk、css
}
},
mounted() {
if (typeof window.Aliplayer === 'function') {
this.initAliPlayer();
}
},
destroyed(){
$("#Aliyun").empty();
},
methods: {
handleClick(event, ownerInstance) {
ownerInstance.callMethod("changeflag");
},
initAliPlayer() {
this.$refs.AliyunFresh.click()
},
receiveMsg(newValue, oldValue, ownerVm, vm) {}, //是否刚开始设置播放时间
//引入播放器sdk、css
loadWebPlayerSDK() {
return new Promise((resolve, reject) => {
const s_tag = document.createElement("script"); // 引入播放器js
s_tag.type = "text/javascript";
s_tag.src =
"https://g.alicdn.com/apsara-media-box/imp-web-player/2.20.3/aliplayer-min.js";
s_tag.charset = "utf-8";
s_tag.onload = () => {
const s_tag1 = document.createElement("script"); // 引入播放器js
s_tag1.type = "text/javascript";
s_tag1.src =
"https://player.alicdn.com/aliplayer/presentation/js/aliplayercomponents.min.js";
s_tag1.charset = "utf-8";
s_tag1.onload = () => {
this.initAliPlayer();
resolve();
};
document.body.appendChild(s_tag1);
};
document.body.appendChild(s_tag);
const l_tag = document.createElement("link"); // 引入播放器css
l_tag.rel = "stylesheet";
l_tag.href =
"https://g.alicdn.com/apsara-media-box/imp-web-player/2.20.3/skins/default/aliplayer-min.css";
document.body.appendChild(l_tag);
});
},
},
};
</script>
<style>
.container {
width: 100vw;
height: auto;
/deep/.pause {
width: 60rpx !important;
height: 60rpx !important;
}
}
.showCountDownd {
box-sizing: border-box;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: flex-end;
color: #fff;
font-size: 38rpx;
text-align: center;
position: absolute;
top: 0;
right: 10rpx;
z-index: 4;
text {
}
}
</style>

775
pages/curriculum/detail.vue Normal file
View File

@@ -0,0 +1,775 @@
<template>
<view class="commonPageBox commonDetailPage" style="background-color: #fff">
<template v-show="!screenLoading">
<z-nav-bar title="教学内容"></z-nav-bar>
<view
class="contentBox curriculum_box"
:style="`height:calc(100% - ${60 + statusBarHeight}px !important;${
isFullScreen ? 'background:#000' : ''
}`"
>
<view
:style="`background:#000;height:200px;`"
v-if="videoArray.length > 0"
>
<common-video
:isfresh="isfresh"
v-if="isfresh"
:secondCountDown="secondCountDown"
@handleFresh="handleFresh"
@changeScreen="changeScreen"
@changeScreenLoading="changeScreenLoading"
ref="commonVideo"
:currentVideoId="currentVideoId"
:currentVideoIndex="currentVideoIndex"
:curriculumData="{...curriculumData,curriculumImgUrl:options.curriculumImgUrl}"
>
</common-video>
<view style="color: #fff"></view>
</view>
<scroll-view
scroll-y="true"
class="scroll-Y"
>
<view class="" style="padding: 20rpx; font-size: 34rpx; color: #333"
>课程{{ options.navTitle }}
</view>
<view style="padding: 20rpx; margin-bottom: 40rpx">
章节 {{ curriculumData.title }}
</view>
<view
v-if="videoArray.length > 0"
class="PM_font"
style="padding: 20rpx; font-size: 40rpx; color: #294a97"
>视频教学</view
>
<view class="scroll-view-item">
<common-curriculum-video
v-if="videoArray.length > 0"
:detailInfo="curriculumData"
:currentVideo="currentVideo"
:dataList="videoArray"
@open="changeVideo"
>
</common-curriculum-video>
</view>
<view
class="PM_font"
style="padding: 20rpx; font-size: 40rpx; color: #333"
>文章简介</view
>
<view class="scroll-view-item" style="padding-bottom: 80rpx;">
<common-rich-detail :detailInfo="{ ...curriculumData, title: '' }">
<image
v-if="curriculumData.imgUrl"
@click="previewImage(curriculumData.imgUrl)"
:src="curriculumData.imgUrl"
mode="widthFix"
class="headImage"
></image>
</common-rich-detail>
</view>
</scroll-view>
<p class="aui-text-danger">
本课程版权归天津众妙之门科技有限公司所有翻版必究!
</p>
</view>
</template>
<view
style="
background-color: red;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
"
v-show="screenLoading"
>
</view>
</view>
</template>
<script>
import courseDescription from "@/pages/component/commonComponents/list";
import curriculumMp3 from "./mp3Detail.vue";
import $http from "@/config/requestConfig.js";
import { mapState } from "vuex";
export default {
components: {
courseDescription, //课程说明
curriculumMp3, //mp3
},
data() {
return {
secondCountDown: 10,
isFullScreen: false,
screenLoading: false,
isfresh: false,
currentCateIndex: 0,
currentVideo: {},
videoList: {},
isOpenMp3: false,
praise: "",
reward: "",
commentLst: [],
correlationiList: [
],
options: {},
videoArrayHW: [],
videoArray: [],
relatedCoursesList: [], //相关课程
medicalCasesList: [], //相关医案
curriculumData: {},
curriculumInfo: {},
fdButtonStyle: {
width: "120rpx",
"border-color": "#000",
color: "#000",
float: "right",
"margin-right": "20rpx",
"margin-left": "30rpx",
},
modalInfo: {},
show: false,
playData: {},
taiHuClassInfo: {},
searchValue: "",
ordersTabs: [
{
name: "视频教学",
type: "1",
},
{
name: "文章简介",
type: "2",
},
], // 一级分类标题1
cateList: [], // 一级分类标题1
twoCateList: [], // 二级分类标题
dataList: [], // 方剂标题
allDataList: [], // 方剂标题
currentStatusIndex: 0, // 当前选中的一级分类
curTwoCateIndex: 0, // 当前选中的二级分类
searchList: [], // 搜索结果数组
showSearchList: false,
userMes: {}, // 用户信息
searchDisable: false, // 搜索不可用
limitShow: false,
limitTitle: "提示",
limitContent: "",
scrollViewHeight: 0,
urlList: {
detail: "sociology/course/getCourseCatalogueChapterDetail",
checkVideo: "sociology/course/checkVideo",
curriculumInfo: "app/phone.do?getCourseInfo",
},
currentVideoId: null,
currentVideoIndex: null,
currentSelectVideoId: null,
currentSelectVideo: {},
};
},
onLoad(options) {
this.options = options;
this.getCourseDescriptionData();
this.screenLoading = false;
this.currentCateIndex = 0;
},
onHide() {},
onShow() {},
computed: {
...mapState(["userInfo"]),
},
watch: {
currentVideoId() {
this.currentVideoIndex = this.videoArray.findIndex(
(e) => e.id == this.currentVideoId,
);
console.log(
"that.currentVideoIndex at line 3401111111111111:",
this.currentVideoIndex,
);
},
},
methods: {
changeScreenLoading(status) {
this.screenLoading = status;
},
changeScreen(status) {
this.isFullScreen = status;
},
ordersTabCLi(data) {
console.log("i at line 312:", data);
this.currentCateIndex = data.index;
this.$forceUpdate();
},
handleFresh(status) {
this.isfresh = status;
this.$forceUpdate();
},
changeVideo(data) {
if (data.id != this.currentVideo.id) {
this.isfresh = false;
this.$nextTick(() => {
this.currentVideo = data;
this.currentVideoId = data.id;
this.isfresh = true;
});
}
},
hancleModalCancel() {
this.show = false;
},
handleClickMore(v, i, status) {
this.$set(this.correlationiList[i], "isOpen", status);
},
hancleModalConfirm() {
var data = {
values: {
customerType: "D",
token: uni.getStorageSync("token"),
customerOid: uni.getStorageSync("customerOid"),
...this.taiHuClassInfo,
},
};
},
async getCourseDescriptionData() {
this.isfresh = false;
var data = {
id: this.options.id,
load: false,
};
var that = this;
$http.request({
url: that.urlList.detail,
method: "POST",
data,
header: {
"Content-Type": "application/json",
},
})
.then(async (res) => {
that.curriculumData = res.data.detail;
that.videoArray = res.data.videos;
if (that.videoArray.length > 0) {
that.currentVideo = that.videoArray[0];
that.currentVideoId = that.videoArray[0].id;
that.isfresh = true;
}
});
},
getPriceData() {
var that = this;
setTimeout(() => {
that.$nextTick(() => {
that.$refs.priceDetail.getData();
});
}, 100);
},
// 检查是有权限使用搜索功能
checkDisable() {},
// 获取用户详情
getUserInfo() {
// 用户详情
if (this.userInfo.id != undefined) {
this.$http.post("book/user/info/" + this.userInfo.id).then((res) => {
this.userMes = res.user;
this.getCateList();
});
}
},
async handleselectCate(item, index) {
this.dataList = [];
var data = [];
var that = this;
this.$http
.post(this.urlList.curriculumInfo, {
customerType: "D",
token: uni.getStorageSync("token"),
customerOid: uni.getStorageSync("customerOid"),
oid: item.coid,
})
.then(async (res) => {
that.curriculumInfo = res.obj;
that.dataList = res.obj.courseList;
});
this.searchValue = "";
this.searchList = [];
this.showSearchList = false;
return data;
},
async setOneCateIndex(item, index) {
this.allDataList = [];
var that = this;
this.currentStatusIndex = index;
this.searchValue = "";
this.searchList = [];
this.showSearchList = false;
this.$nextTick(async () => {
await that.getCourseDescriptionData();
this.$forceUpdate();
});
},
transformData(inputData) {
const result = {};
inputData.forEach((item) => {
const { letter } = item;
if (!result[letter]) {
result[letter] = [];
}
result[letter].push(item);
});
return result;
},
getCateList(id) {
id ? "" : (id = 0);
this.twoCateList = [];
this.curTwoCateIndex = 0;
},
// 放大图片
previewImage(url) {
uni.previewImage({
urls: [url],
longPressActions: {
itemList: ["很抱歉,暂不支持保存图片到本地"],
success: function (res) {
},
},
});
},
},
onBackPress() {
// #ifdef APP-PLUS
plus.key.hideSoftKeybord();
// #endif
},
};
</script>
<style lang="scss" scoped>
@import "@/static/mixin.scss";
.searchList {
.item {
font-size: 28rpx;
padding: 20rpx;
border-bottom: 1px solid #dadbde;
}
}
.scroll-view_H {
background-color: #fff;
white-space: nowrap;
padding: 10rpx;
}
.contentBox {
height: 100vh;
.statusList {
padding: 10rpx;
box-sizing: border-box;
justify-content: space-between;
text {
text-align: center;
display: inline-block;
width: 32%;
padding: 20rpx 0;
font-size: 34rpx;
border-radius: 10rpx;
}
.cur {
background-color: $themeColor;
color: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
}
.twoCateList {
font-size: 28rpx;
margin-top: 20rpx;
.grid-text {
padding: 10rpx 0rpx;
text-align: center;
}
.cur {
color: $themeColor;
}
// .u-grid-list{border: 0.5px solid #dadbde;}
}
.dataList {
font-size: 26rpx;
// margin-top: 20rpx;
// padding: 32rpx 0rpx;
border-radius: 10rpx;
background-color: #f8f9fa;
box-sizing: border-box;
.JFtitleItem {
background-color: #ffffff;
padding: 20rpx 10rpx;
width: 100%;
border-bottom: 0.5px solid #f8f9fa;
}
.wmzhimg {
width: 220rpx;
height: 220rpx;
}
}
}
.search_box {
margin: 0 auto;
overflow: hidden;
align-items: center;
width: calc(100% - 10px);
margin-top: 20rpx;
margin-bottom: 20rpx;
.search {
height: 56upx;
display: flex;
width: 86%;
margin: 0 auto;
align-items: center;
padding: 0upx 40upx;
background-color: #fff;
border-radius: 20upx;
box-shadow: 0 0px 10px 1px $themeColor;
}
.prompt {
color: #838383;
font-size: 24rpx;
}
}
.flexbox {
display: flex;
}
.uni-modal .uni-modal__bd {
text-align: left;
}
.limiTy {
font-size: 28rpx;
line-height: 46rpx;
}
.chImage {
height: 100rpx;
}
.dataList {
height: 100%;
}
.titleList2 {
height: calc(100% - 150rpx);
}
.priceDetail {
height: calc(100% - 180rpx) !important;
padding: 0rpx 0;
box-sizing: border-box;
}
.componentPage {
height: calc(100% - 90rpx) !important;
}
.dateReminder {
width: 100%;
font-size: 24rpx;
text-align: right;
line-height: 40rpx;
}
.fdButtonBox {
border: 1rpx solid $themeColor;
background-color: $themeColor;
color: #fff;
// width: 100%;
float: right;
padding: 4rpx 14rpx;
font-size: 24rpx;
font-weight: 500;
line-height: 30rpx;
border-radius: 10rpx;
box-sizing: border-box;
// margin-top: 20rpx;
// display: flex;
// align-items: center;
}
.headImage {
// height: 400rpx !important;
}
.commonDetailPage {
}
.curriulum_box {
margin-top: 20rpx;
width: 100%;
.curriulum_title_box {
display: flex;
align-items: center;
margin-bottom: 20rpx;
background-color: #fff;
.curriulum_title {
width: calc(100% - 80rpx);
font-size: 32rpx;
line-height: 40rpx;
padding: 20rpx;
box-sizing: border-box;
}
}
}
/deep/.scroll-view-item:nth-child(2n-1) {
background-color: transparent !important;
}
.dataList {
height: auto !important;
}
.small_class_teaching_box {
width: 100%;
margin-top: 20rpx;
background: #b7e0e2;
.small_class_teaching_top {
padding: 20rpx 20rpx 0 10rpx;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
// background: #EDFCF7;
color: #8f8e8e;
// box-shadow: 0px 0px 6rpx 0px #E9DCCC;
.icon1 {
width: 50rpx;
height: 50rpx;
}
.small_class_teaching_top_left {
display: flex;
align-items: center;
color: #018f89;
font-family: MicrosoftYaHei;
}
}
.small_class_teaching_content {
margin-top: 20rpx;
// background: #EDFCF7;
padding-bottom: 10rpx;
.top {
padding: 20rpx 20rpx;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 4rpx solid #fff;
.top_item {
width: 23%;
font-family: PangMenZhengDaoBiaoTiTiMianFeiBan;
font-weight: normal;
font-size: 34rpx;
color: #018f89;
line-height: 80rpx;
background: #cef8ea;
text-align: center;
border-radius: 10rpx;
box-shadow: 0px 0px 6rpx 0px #e9dccc;
}
}
.schedule {
width: 100%;
overflow: hidden;
padding: 20rpx 20rpx;
box-sizing: border-box;
align-items: center;
color: #018f89;
font-family: MicrosoftYaHei;
.icon_box {
width: 100%;
display: flex;
align-items: center;
margin-bottom: 0rpx;
.icon1 {
width: 50rpx;
height: 50rpx;
margin-right: 10rpx;
}
}
.progress_box {
width: 100%;
display: flex;
align-items: center;
position: relative;
.progress_icon {
width: calc(100% - 240rpx);
}
.icon1 {
width: 60rpx;
height: 60rpx;
margin: 0 20rpx;
}
.icon2 {
width: 140rpx;
height: 100rpx;
position: absolute;
right: 0;
// margin-top: -20rpx;
}
}
}
}
}
.related_courses_box {
background-color: #fff;
.small_class_teaching_content {
padding: 10rpx 20rpx;
box-sizing: border-box;
}
}
.related_courses_name {
display: inline-block;
width: calc(100% - 150rpx) !important;
.aui-text-danger {
display: inline-block;
float: right;
}
}
.curriculum_box {
.curriculum_title {
padding: 20rpx 40rpx 0;
font-size: 38rpx;
line-height: 66rpx;
font-weight: bold;
text-align: center;
box-sizing: border-box;
margin-bottom: 20rpx;
}
}
.aui-text-danger{
width:100%;
height: 80rpx;
line-height: 80rpx;
text-align: center;
position: fixed;
bottom: 0rpx;
background: #fff;
}
.curriculum_content {
background-color: #fff;
padding-bottom: 40rpx;
.richDetail {
height: auto !important;
margin-bottom: 20rpx;
}
}
.dianzan_box {
width: calc(100% - 80rpx);
margin: 0 auto;
padding: 20rpx 20rpx;
color: #6e6e6e;
font-weight: 600;
text-align: justify;
background: #f4fffb;
border-radius: 10rpx;
box-shadow: 0px 0px 6rpx 0px #e9dccc;
}
.dashang_box {
color: #ff5521;
background: #fff7f4;
box-shadow: 0px 0px 6rpx 0px rgba(255, 85, 33, 0.4);
}
.correlation_box {
background-color: #fff;
padding-bottom: 40rpx;
.title {
font-family: PangMenZhengDaoBiaoTiTiMianFeiBan;
font-weight: normal;
font-size: 40rpx;
color: #018f89;
}
.more {
font-size: 24rpx;
}
.close {
text-align: center;
color: #b0b0b0;
line-height: 40rpx;
margin-top: 10rpx;
// padding-bottom: 30rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>

1394
pages/curriculum/index.vue Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,226 @@
<template>
<view class="commonPageBox commonDetailPage">
<z-nav-bar title="我的课程" bgColor="#5188e5" fontColor="#fff"></z-nav-bar>
<view class="cateList flexbox" :style="`top: ${45 + statusBarHeight}px;`">
<common-sticky itemStyle="width: 50%; height: 68rpx;font-size:24rpx;" :list="ordersTabs" label="name"
:currentCateIndex="currentCateIndex" @handleselectCate="ordersTabCLi"></common-sticky>
</view>
<view class="list_block">
<view class="list_item"
v-for="(item, index) in dataList" :key="index"
v-if="dataList&&dataList.length>0"
@click="goToDetail(item)"
>
<view class="list_item_image">
<image v-if="item.image" :src="item.image" mode="aspectFit"></image>
<text class="image_null" v-else>暂无封面图</text>
</view>
<view class="list_item_right">
<view class="list_item_title">{{item.title}}</view>
<view class="list_item_content" v-html="item.content"></view>
</view>
</view>
<text v-if="statusNull" class="text_null">暂无数据</text>
</view>
</view>
</template>
<script>
import $http from "@/config/requestConfig.js";
export default {
data(){
return {
ordersTabs: [{
name: "我的课程",
value: 0,
},
{
name: "过期课程",
value: 1,
}
],
currentCateIndex: 0,
dataList: [], //列表数据
timer: null,
statusNull: null, //暂无数据显示
current: 1,
limit: 10
}
},
onShow(){
},
onLoad() {
//我的课程
this.getMyList();
},
methods: {
//我的课程数据
getMyList(){
uni.showLoading({
title: '加载中'
})
this.$http.request({
url: 'taihumed/course/getMyCourseList',
method: "POST",
data: {
current: this.current,
limit: this.limit
},
header: {
"Content-Type": "application/json",
},
})
.then(res=> {
if (res.code == 0) {
uni.hideLoading();
if(res.pageRes.records&&res.pageRes.records.length>0){
this.dataList = res.pageRes.records;
}else{
this.dataList = [];
this.statusNull =true;
}
}
});
},
//过期课程数据
getExpireList(){
this.dataList = [];
uni.showLoading({
title: '加载中'
})
this.$http.request({
url: 'taihumed/course/getCourseExpire',
method: "POST",
data: {},
header: {
"Content-Type": "application/json",
},
})
.then(res => {
if (res.code == 0) {
uni.hideLoading();
if(res.courseList&&res.courseList.length>0){
this.dataList = res.courseList;
}else{
this.dataList = [];
this.statusNull =true;
}
}
});
},
//切换tab状态
ordersTabCLi(data, index) {
this.dataList = [];
this.statusNull = null;
this.currentCateIndex = index;
if(index==0){
this.getMyList();
}else if(index==1){
this.getExpireList();
}
},
//跳转课程详情
goToDetail(item) {
uni.navigateTo({
url: `/pages/curriculum/index?navTitle=${item.title}&title=${item.title}&id=${item.id}`,
});
},
},
}
</script>
<style lang="scss">
.commonPageBox{
background: #eff5f8;
height: 100vh;
}
.cateList {
width: 100%;
}
.flexbox {
position: fixed;
left: 0;
z-index: 9999;
}
.list_block{
padding: 20rpx 20rpx 0;
margin-top: 70rpx;
}
.list_item{
position: relative;
background: #fff;
box-shadow: 0px 0px 10px 0px #a7bbe4;
padding: 30rpx 20rpx 30rpx;
margin-bottom: 20rpx;
display: flex;
border-radius: 10rpx;
}
.list_item_bt{
padding: 30rpx 20rpx 70rpx;
}
.list_item_image,.image_null{
width: 250rpx;
height: 220rpx;
background-color: rgba(125, 193, 240, 0.1);
display: flex;
justify-content: center;
align-items: center;
}
.list_item_image image{
width: 100%;
}
.list_item_right{
margin-left: 30rpx;
width: calc(100% - 250rpx);
}
.list_item_title{
font-size: 30rpx;
line-height: 36rpx;
font-weight: bold;
color: #333;
}
.list_item_content{
margin-top: 15rpx;
font-size: 26rpx;
line-height: 36rpx;
color: #999;
max-height: 108rpx;
overflow: hidden;
}
.list_item_study{
line-height: 48rpx;
position: absolute;
right: 20rpx;
bottom: 30rpx;
background: #7dc1f0;
color: #fff;
border-radius: 40rpx;
font-size: 24rpx;
padding: 0 20rpx;
}
.list_item_study_out{
line-height: 48rpx;
position: absolute;
right: 20rpx;
bottom: 30rpx;
background: #294a97;
color: #fff;
border-radius: 40rpx;
font-size: 24rpx;
padding: 0 20rpx;
}
.text_null{
display: block;
width: 100%;
text-align: center;
font-size: 26rpx;
color: #999;
margin: 150rpx 0;
}
.image_null{
color: #999;
font-size: 22rpx;
}
</style>

1482
pages/curriculum/index3.vue Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,354 @@
<template>
<view
class="container commonPageBox commonDetailPage"
style="position: relative; height: auto"
>
<video
@timeupdate="videoTimeUpdateEvent($event)"
ref="videos"
style="width: 100%; height: 60rpx"
autoplay
id="videoId"
controls
:show-progress="true"
:show-fullscreen-btn="false"
object-fit="contain"
class="video-box"
:src="videoUrl"
:poster="`${videoUrl}?x-oss-process=video/snapshot,t_${1},f_jpg`"
@play="playVideo"
></video>
<!-- 倍速 -->
<view class="play-rate" @click="videoPlayRate" v-if="showRate">{{ playbackRate }}x</view>
<!-- 倍速菜单 -->
<ul class="play-rate-menu" :style="{ height: height }" v-if="showRateMenu">
<li
v-for="item in playbackRates"
:key="item"
:class="[{ activeRate: playbackRate === item }, 'play-rate-item']"
@click="changePlayRate(item)"
>
{{ item }}x
</li>
</ul>
</view>
</template>
<script>
import courseDescription from "@/pages/component/commonComponents/list";
import $http from "@/config/requestConfig.js";
import { mapState } from "vuex";
export default {
components: {
courseDescription, //课程说明
},
data() {
return {
playbackRate: 1, // 初始播放速率
showRateMenu: false, //显示播放速率
speedState: 1,
timer: null,
videoUrl: "",
currentTime: 0,
firstTime: 0,
options: {},
videoData: {},
isSetFirstTime: false,
currentVideoTime: "", //初始播放时长(秒)
urlList: {
detail: "sociology/course/getCourseCatalogueChapterDetail",
curriculumInfo: "app/phone.do?getCourseInfo",
},
};
},
async onUnload() {
this.timer = null;
// #ifdef APP-PLUS
uni.navigateTo({
url: "/pages/curriculum/order/back",
});
plus.screen.lockOrientation("portrait-primary"); //锁死屏幕方向为竖屏
// #endif
await this.setVideoTime();
},
onLoad(options) {
},
onHide() {
},
computed: {
...mapState(["userInfo"]),
},
methods: {
// 显示倍速
videoPlayRate() {
this.showRateMenu = true
},
// 点击倍速
changePlayRate(rate) {
this.playbackRate = rate
this.videoPlayer.playbackRate(rate)
this.showRateMenu = false
this.hideControls()
},
// 创建倍速按钮
createPlayRateDOM() {
const playRateDom = document.createElement('div')
playRateDom.className = 'full-play-rate'
playRateDom.innerText = `${this.playbackRate}x`
playRateDom.onclick = () => {
const playRateMenuDom = document.querySelector('.full-play-rate-menu')
playRateMenuDom.style.display = 'block'
}
return playRateDom
},
// 创建倍速菜单
createPlayRateMenuDom() {
const playRateMenuDom = document.createElement('ul')
playRateMenuDom.className = `play-rate-menu full-play-rate-menu`
playRateMenuDom.style.height = this.windowWidth + 'px'
playRateMenuDom.style.display = 'none'
let liStr = ''
this.playbackRates.forEach((item) => {
liStr += `
<li class="${this.playbackRate === item ? 'activeRate' : ''} play-rate-item full-play-rate-item">
${item}x
</li>
`
})
playRateMenuDom.innerHTML = liStr
return playRateMenuDom
},
handleSetSpeedRate(rate) {
console.log("rate at line 125:", rate);
let videoContext = uni.createVideoContext("videoId");
videoContext.playbackRate(rate);
speedRate.value = rate;
},
init(options) {
this.options = JSON.parse(options.data);
this.getLive();
this.timer = setInterval(() => {
var that = this;
if (this.currentTime) {
that.setVideoTime();
}
}, 60000 * 10);
},
// 播放进度改变
videoTimeUpdateEvent(e) {
console.log("e at line 78:", e);
this.playTime = parseInt(e.detail.currentTime);
this.allTime = parseInt(e.detail.duration);
this.recordTime({
time: this.playTime,
});
},
recordTime(data) {
this.currentTime = data.time;
console.log("data at line 54:", data);
var list = [];
if (uni.getStorageSync("videoList")) {
list = JSON.parse(uni.getStorageSync("videoList"));
}
console.log("点击后设置播放时长的方法list at line 65:", list);
var index = list.findIndex((e) => e.id == this.videoData.id);
if (list.length > 0 && index >= 0) {
list[index] = {
...this.videoData,
time: data.time,
};
} else {
list.push({
...this.videoData,
time: data.time,
});
}
uni.setStorageSync("videoList", JSON.stringify(list));
},
//是否全屏
fullscreenchange(e) {
if (!e.target.fullScreen) {
uni.navigateBack({
delta: 1,
});
}
},
getData(data) {
if (!this.isSetFirstTime) {
var netWork = this.videoData.userCourseVideoPositionEntity
? this.videoData.userCourseVideoPositionEntity.position
: 0;
var list = [];
if (uni.getStorageSync("videoList")) {
list = JSON.parse(uni.getStorageSync("videoList"));
}
var index = list.findIndex((e) => e.id == this.videoData.id);
if (netWork) {
if (index >= 0) {
this.firstTime =
list[index].time > netWork ? list[index].time : netWork;
} else {
this.firstTime = netWork ? netWork : 0;
}
} else {
if (index >= 0) {
this.firstTime = list[index].time ? list[index].time : 0;
} else {
this.firstTime = 0;
}
}
uni.setStorageSync("videoList", JSON.stringify(list));
this.playVideo();
this.isSetFirstTime = true;
}
},
setVideoTime(time) {
var data = {
videoId: this.videoData.id,
position: this.currentTime, //秒数
};
$http
.request({
url: `sociology/course/saveCoursePosition`,
method: "Post",
data,
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
this.$forceUpdate();
});
},
playVideo(e) {
this.videoContext = uni.createVideoContext("videoId", this);
this.videoContext.seek(this.firstTime);
},
async getLive() {
var data = {
...this.options,
};
console.log("data at line 57:", data);
$http
.request({
url: `sociology/course/checkVideo`,
method: "Post",
data,
header: {
"Content-Type": "application/json",
},
})
.then((res) => {
console.log("res at line 252:", res);
this.videoData = res.video;
this.videoUrl =
res.video.videoUrl;
this.$nextTick(async () => {
await this.getData();
});
this.$forceUpdate();
});
},
hancleModalCancel() {
this.show = false;
},
handleClickMore(v, i, status) {
this.$set(this.correlationiList[i], "isOpen", status);
},
hancleModalConfirm() {
var data = {
values: {
customerType: "D",
token: uni.getStorageSync("token"),
customerOid: uni.getStorageSync("customerOid"),
...this.taiHuClassInfo,
},
};
},
},
onBackPress() {
// #ifdef APP-PLUS
plus.key.hideSoftKeybord();
// #endif
},
};
</script>
<style lang="scss" scoped>
.video-box {
position: relative;
}
.image_box {
background-color: red;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.speed {
position: absolute;
right: 20rpx;
top: 16rpx;
.doubleSpeed {
color: #fff;
font-size: 14rpx;
background-color: rgba(0, 0, 0, 0.6);
padding: 4rpx 6rpx;
}
}
// 倍速的蒙版
.speedModal {
background-color: rgba(0, 0, 0, 0.7);
}
.speedNumBox {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
background-color: #2c2c2c;
width: 120rpx;
position: absolute;
right: 0rpx;
top: 0;
.number {
width: 120rpx;
font-weight: 700;
font-size: 14rpx;
padding: 18rpx 0;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.active {
color: red;
}
.noActive {
color: #fff;
}
}
</style>

View File

@@ -1,6 +1,86 @@
<template>
<view class="content">
<z-nav-bar title="名医精彩" bgColor="#5188e5" fontColor="#fff"></z-nav-bar>
<z-nav-bar title="名医精彩" bgColor="#5188e5" fontColor="#fff" :backState="2000"></z-nav-bar>
<view class="doctors_module" :style="`top: ${42 + statusBarHeight}px;`">
<view class="cateList flexbox">
<common-sticky itemStyle="width:33.3%; height: 38px;font-size:24rpx;" :list="tabsList" label="title"
:currentCateIndex="currentCateIndex" @handleselectCate="ordersTabCLi"></common-sticky>
</view>
<view class="name_search">
<uni-easyinput
v-model="courseName"
prefixIcon="search"
placeholder="按姓名/课程搜索"
placeholderClass="name-placeholder"
class="center-input"
/>
<button @click="getListData(taihumedId)">查询</button>
</view>
</view>
<scroll-view scroll-y="true"
@scrolltolower="loadMore"
style="height: calc(100vh - 300rpx); margin-top: 185rpx; padding-bottom: 140rpx;"
:scroll-into-view="scrollIntoViewId"
v-if="show==true">
<view class="doctors_list" id="top">
<view class="doctors_item" v-for="(item,index) in list" :key="index" @click="goToDetail(item)">
<view class="flex" v-if="item.taihuTalent">
<view class="flex" v-if="item.taihuTalent.length>=1">
<image v-if="item.taihuTalent.length==1&&item.taihuTalent[0].icon" :src="item.taihuTalent[0].icon" class="item_image" mode="aspectFit"></image>
<image v-else-if="item.image" :src="item.image" class="item_image" mode="aspectFit"></image>
<image v-else src="../../static/logo_zi.png" class="item_image" mode="aspectFit"></image>
<view class="item_right" v-if="item.taihuTalent.length==1">
<view class="item_top">
<text class="item_name">{{item.taihuTalent[0].name}}</text>
</view>
<text class="item_con">{{item.title}}</text>
</view>
<view class="item_right" v-if="item.taihuTalent.length>1">
<view class="item_top">
<text class="item_name">{{item.title}}</text>
</view>
<text class="item_con">{{ item.taihuTalent.map(talent => talent.name).join(' ') }}</text>
</view>
</view>
<view class="flex" v-else>
<image v-if="item.image" :src="item.image" class="item_image" mode="aspectFit"></image>
<image v-else src="../../static/logo_zi.png" class="item_image" mode="aspectFit"></image>
<view class="item_right">
<text class="item_con">{{item.title}}</text>
</view>
</view>
</view>
<view class="flex" v-else>
<image :src="item.image" class="item_image" mode="aspectFit"></image>
<view class="item_right">
<view class="item_top">
<text class="item_name">{{item.title}}</text>
</view>
</view>
</view>
<view class="list_item_bt">
<view class="list_item_price" v-if="item.courseCatalogueEntityList.length==1">
<text v-if="item.courseCatalogueEntityList[0].halfFee==0">免费</text>
<text v-else>¥{{item.courseCatalogueEntityList[0].halfFee}}/{{item.courseCatalogueEntityList[0].fee}}</text>
</view>
<view class="list_item_price" v-if="item.courseCatalogueEntityList.length>1">
<text v-for="(v,i) in item.courseCatalogueEntityList" :key="i">
{{formatContent(v.title)}}<text v-if="i !== item.courseCatalogueEntityList.length - 1">/</text>
</text>
<text v-if="item.courseCatalogueEntityList[0].halfFee==0" style="padding-left: 20rpx;">免费</text>
<text v-else style="margin-left: 20rpx;">{{item.courseCatalogueEntityList[0].halfFee}}/{{item.courseCatalogueEntityList[0].fee}}</text>
</view>
<text class="list_item_study">了解课程</text>
</view>
</view>
</view>
<text v-show="showText&&count>list.length" class="show-more">加载更多</text>
<text v-show="noMore" class="no-more">没有更多了</text>
</scroll-view>
<text class="null_text" v-else>{{null_text}}</text>
<z-navigation></z-navigation>
</view>
</template>
@@ -10,24 +90,53 @@ import $http from "@/config/requestConfig.js";
export default {
data() {
return {
tabsList: [],
currentCateIndex: 0,
list: [],
null_text: '',
current: 1,
limit: 10,
courseName: '',
taihumedId: null,
timer: null,
showText: false,
noMore: false,
show: null,
count: 0,
scrollIntoViewId: '', //用于控制滚动到哪个元素
}
},
onLoad() {
uni.hideTabBar();
this.getTabData();
},
onShow() {
//回到顶部设置
this.scrollIntoViewId = 'top';
this.timer = setTimeout(() => {
this.scrollIntoViewId = '';
}, 300);
},
methods: {
//获取数据
getData() {
uni.showLoading({
title: '加载中'
})
//判断显示‘上/中/下’
formatContent(content) {
const keywords = ["上部", "中部", "下部"];
let result = [];
// 判断是否包含关键字
keywords.forEach((keyword) => {
if (content.includes(keyword)) {
result.push(keyword.substring(0, 1));
}
});
return result.join("");
},
//获取tab数据
getTabData() {
this.$http.request({
url: 'common/ragFlowApi/getChatAssistants',
url: 'taihumed/course/getCourseTaihumedList',
method: "POST",
data: {},
header: {
@@ -35,12 +144,79 @@ export default {
},
})
.then(res=> {
uni.hideLoading();
if (res.list&&res.list.length>0) {
this.tabsList = res.list;
this.taihumedId = this.tabsList[0].id
this.getListData(this.taihumedId);
}
});
}
},
//获取列表数据
getListData(taihumedId) {
if(this.noMore){
return false;
};
uni.showLoading({
title: '加载中'
})
this.$http.request({
url: 'taihumed/course/getCourseToTaihumedList',
method: "POST",
data: {
current: this.current,
limit: this.limit,
taihumedId: taihumedId,
userName: '',
courseName: this.courseName
},
header: {
"Content-Type": "application/json",
},
})
.then(res=> {
uni.hideLoading();
this.count = res.pageRes.total; //总数
let length = res.pageRes.records.length;
if (res.pageRes.records&&length>0) {
this.show = true;
//如果返回的数据少于每页数量,表示没有更多数据
if(this.count==length||length < this.limit){
this.noMore = true;
}
this.list = [...this.list, ...res.pageRes.records];
this.current += 1; //更新页码
//显示提示语
this.showText = true;
}else{
this.show = false;
this.null_text = '暂无数据';
}
});
},
//加载更多
loadMore(){
this.getListData(this.taihumedId);
},
//切换tab状态
ordersTabCLi(data, index) {
this.courseName = '';
this.taihumedId = data.id;
//重置
this.list = [];
this.noMore = false;
this.show = false;
this.count = 0;
this.current = 1;
this.getListData(this.taihumedId);
},
//详情
goToDetail(item){
uni.navigateTo({
url: `/pages/curriculum/index?navTitle=${item.title}&title=${item.title}&id=${item.id}`
});
},
},
}
</script>
@@ -52,4 +228,141 @@ export default {
overflow: auto;
background-color: #fff;
}
.doctors_list{
margin: 0 30rpx 20rpx;
}
.doctors_item{
border: 1rpx solid $themeColor;
border-radius: 15rpx;
margin-bottom: 20rpx;
padding: 25rpx 25rpx 60rpx;
display: flex;
align-items: center;
position: relative;
}
.item_image{
display: block;
width: 160rpx;
height: 200rpx;
}
.item_right{
width: calc(100% - 200rpx);
margin-left: 30rpx;
padding-bottom: 20rpx;
}
.item_top{
display: flex;
align-items: center;
line-height: 40rpx;
}
.item_name{
font-size: 32rpx;
color: #333;
font-weight: bold;
}
.item_title{
font-size: 32rpx;
color: #333;
}
.item_con{
font-size: 30rpx;
font-weight: bold;
color: #333;
margin-top: 10rpx;
line-height: 40rpx;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.null_text{
display: block;
text-align: center;
font-size: 30rpx;
color: #999;
padding-top: 300rpx;
}
.doctors_module{
width: 100%;
position: fixed;
z-index: 999;
left: 0;
}
.cateList{
background: #f3f3f3;
}
.flex{
display: flex;
align-items: center;
width: 100%;
}
.name_search{
background-color: #fff;
padding: 20rpx 30rpx;
display: flex;
align-items: center;
/deep/.is-input-border{
background-color: #f3f3f3;
border-radius: 50rpx;
height: 60rpx;
line-height: 30rpx;
padding: 15rpx;
font-size: 28rpx;
color: #666;
}
/deep/.uni-easyinput__content-input{
}
.name-placeholder{
font-size: 28rpx;
text-align: center;
color: #666;
}
button{
background-color: $themeBgColor;
font-size: 26rpx;
line-height: 36rpx;
border-radius: 15rpx;
color: #fff;
padding: 5rpx 20rpx;
margin-left: 15rpx;
}
}
.show-more,.no-more{
display: inline-block;
width: 100%;
font-size: 24rpx;
padding-top: 5rpx;
color: #ccc;
text-align: center;
}
.list_item_study{
line-height: 48rpx;
background: $themeBgColor;
color: #fff;
border-radius: 40rpx;
font-size: 24rpx;
padding: 0 20rpx;
}
.list_item_bt{
display: flex;
align-items: center;
position: absolute;
right: 20rpx;
bottom: 20rpx;
}
.list_item_price{
font-size: 30rpx;
font-weight: 500;
margin-right: 30rpx;
color: red;
line-height: 54rpx;
}
</style>

369
pages/goods/order.vue Normal file
View File

@@ -0,0 +1,369 @@
<template>
<view class="container commonPageBox commonDetailPage" style=" padding: 0;">
<z-nav-bar title="确认订单" bgColor="#5188e5" fontColor="#fff"></z-nav-bar>
<common-order-submit
v-if="showOrder"
:options="options"
:urlList="urlList"
:initData="initData"
:priceKey="priceKey"
:pageType="pageType"
:goodsDataList="goodsDataList"
:showNumber="showNumber"
:isHideAddress="isHideAddress"
>
<template
slot="goodsLableInfoSlot"
slot-scope="slotProps"
v-if="pageType == 'goods'"
>
<span
class="goodsvipLabel"
v-if="
slotProps.row.isVipPrice == 1 &&
slotProps.row.vipPrice != 0 &&
slotProps.row.vipPrice != null
"
style=""
>VIP优惠</span
>
</template>
<template slot="goodsInfoImgSlot" slot-scope="slotProps">
<image
v-if="pageType == 'vip'"
src="/static/icon/vip.png"
class="goods_item_img"
mode="widthFix"
@click="goDetail(slotProps.row.productId)"
></image>
<image
v-else-if="
(pageType == 'goods' || pageType == 'fudu') &&
slotProps.row.productImages &&
slotProps.row.productImages != ''
"
class="goods_item_img"
:src="slotProps.row.productImages"
mode="aspectFit"
>
</image>
<image
v-else
src="/static/nobg1.jpg"
class="goods_item_img"
mode="widthFix"
@click="goDetail(slotProps.row.productId)"
></image>
</template>
<template slot="goodsInfoNameSlot" slot-scope="slotProps">
<span v-if="pageType == 'vip'"
>{{ slotProps.row.title
}}<span style="margin-left: 4rpx"
>{{ slotProps.row.year }}年</span
></span
>
<span v-else>{{ slotProps.row.productName }}</span>
</template>
<template slot="goodsInfoPriceSlot" slot-scope="slotProps">
<text
v-if="
slotProps.row.isVipPrice == 1 &&
slotProps.row.vipPrice != 0 &&
slotProps.row.vipPrice != null
"
>
<text style="color: #e97512; font-size: 28rpx; font-weight: bold"
>¥{{ slotProps.row.vipPrice.toFixed(2) }}</text
>
<text style="color: #fa2d12; font-size: 24rpx; margin-left: 4px"
>VIP到手价</text
>
<text
style="
color: #8a8a8a;
font-size: 24rpx;
margin-left: 4px;
font-weight: bold;
text-decoration: line-through;
"
>¥{{ Number(slotProps.row.price).toFixed(2) }}</text
>
</text>
<text
v-else-if="
slotProps.row.activityPrice && slotProps.row.activityPrice > 0
"
>
<text style="color: #e97512; font-size: 28rpx; font-weight: bold"
>¥{{ slotProps.row.activityPrice.toFixed(2) }}</text
>
<text style="color: #613804; font-size: 24rpx; margin-left: 4px"
>活动价</text
>
<text
style="
color: #8a8a8a;
font-size: 24rpx;
margin-left: 4px;
font-weight: bold;
text-decoration: line-through;
"
>¥{{ Number(slotProps.row.price).toFixed(2) }}</text
>
</text>
<text v-else style="font-size: 28rpx"
>¥{{ Number(slotProps.row.price).toFixed(2) }}</text
>
</template>
</common-order-submit>
</view>
</template>
<script>
import { mapState } from "vuex";
export default {
components: {},
watch: {},
data() {
return {
priceKey: "price",
showNumber: true,
isHideAddress: false,
options: {},
initData: {},
goodsDataList: [],
pageType: "",
showOrder: "",
urlList: {
list: "app/phone.do?getCourseDetail_new",
initPrepareOrder: "common/buyOrder/initPrepareOrder",
buyOrder: "book/buyOrder/placeOrder",
curriculumInfo: "app/phone.do?getCourseInfo",
detailInfo: "app/phoneDoctor.do?getTaiHuClassInfo_new",
userInfo: "common/user/getUserInfo",
addressList: "common/userAddress/getUserAddress",
freightNum: "book/buyOrder/calculateTransportPrice", //运费
renewPayment: "common/courseRelearn/relearnSave", // 复读下单地址
vipPayment: "common/userVip/placeVipOrder", // 复读下单地址
},
};
},
async onLoad(options) {
this.options = JSON.parse(options.data);
this.priceKey = "price";
this.showNumber = true;
this.isHideAddress = false;
await this.init();
if (this.options.isFudu) {
//复读订单
this.pageType = "fudu";
this.showNumber = true;
await this.getFuduDataInfo();
} else {
//普通
this.pageType = "goods";
await this.getGoodsDataInfo();
}
this.$nextTick(async () => {
this.showOrder = true;
});
},
computed: { ...mapState(["userInfo"]) },
methods: {
async init() {
if (this.options.isVip) {
await this.$http
.request({
url: `${this.urlList.userInfo}`,
method: "POST",
data:{},
header: {
"Content-Type": "application/json",
},
})
.then(async (res) => {
console.log("res at line 1168:", res);
if (res.code == 0) {
this.initData = {user:res.result};
this.isHideAddress = true;
}
this.$forceUpdate();
});
} else {
var data = {
uid: this.userInfo.id,
productList: this.options.goods.map((e) => {
return {
productId: e.productId || e.id,
quantity: 1,
};
}),
};
var that = this;
await this.$http
.request({
url: `${this.urlList.initPrepareOrder}`,
method: "POST",
data,
header: {
"Content-Type": "application/json",
},
})
.then(async (res) => {
console.log("res at line 1168:", res);
if (res.code == 0) {
this.initData = res.data;
console.log(
"this.initData at line 初始化课程订单信息:",
this.initData
);
if (res.data.is_course) {
this.isHideAddress = true;
}
}
this.$forceUpdate();
});
}
},
findById(id, data) {
// Loop through the data array
for (const item of data) {
// Check if vcbList exists and loop through each item in vcbList
if (item.vcbList) {
this.isHideJf=true
const vcbItem = item.vcbList.find((vcb) => vcb.id === id);
if (vcbItem) {
return {...vcbItem,}; // Return the matching item
}
}
if (item.yanqiList) {
this.isHideJf=false
const vcbItem = item.yanqiList.find((vcb) => vcb.id === id);
if (vcbItem) {
return {...vcbItem,}; // Return the matching item
}
}
}
return null; // Return null if no item with the given ID is found
},
async getFuduDataInfo() {
await this.$http
.request({
url: "/common/courseRelearn/relearnShopProductList",
method: "POST",
data: {
catalogueId: this.options.fuduId,
},
header: {
"Content-Type": "application/json",
},
})
.then(async (res) => {
this.goodsDataList = res.productList.filter(
(e) => this.options.goods[0].productName == e.productName
);
});
},
async getVipDataInfo() {
await this.$http
.request({
url: "/common/userVip/getVipBuyConfigList",
method: "POST",
data: {},
header: {
"Content-Type": "application/json",
},
})
.then(async (res) => {
console.log("res at line 846:", res);
var data = await this.findById(this.options.goods[0].id, res.res);
if(this.isHideJf){
this.initData.user.jf=0;
}
console.log("data at line 200:", data);
this.goodsDataList = [
{
...data,
productId: data.id,
price: data.rebateFee,
},
];
console.log("this.goodsDataList at line 861:", this.goodsDataList);
});
},
async getGoodsDataInfo(fn) {
await this.$http
.request({
url: "/book/buyOrder/getShopProductListByIds",
method: "POST",
data: {
productIds: this.options.goods.map((e) => e.productId).toString(),
},
header: {
"Content-Type": "application/json",
},
})
.then(async (res) => {
this.goodsDataList = res.shopProductList;
});
},
},
onBackPress() {
// #ifdef APP-PLUS
plus.key.hideSoftKeybord();
// #endif
},
};
</script>
<style lang="scss" scoped>
.commonPage, .commonPageBox {
height: calc(100vh - 50px);
}
.goodsvipLabel {
position: absolute;
z-index: 10;
top: 4px;
left: 0px;
margin-right: 10px;
text-align: center;
font-size: 18rpx;
background-color: #f94f04;
color: #fff;
font-weight: bold;
border-radius: 4px;
width: 80rpx;
padding: 2px 4px;
box-sizing: border-box;
}
.goods_item_img {
width: 140rpx;
height: 140rpx;
float: left;
background-color: #f5f5f5;
border-radius: 10rpx;
}
</style>

View File

@@ -145,6 +145,11 @@ export default {
url: "/pages/order/index",
type: "pageJump"
},
{
name: "我的课程",
url: "/pages/curriculum/index/index",
type: "pageJump"
},
{
name: "个人资料",
url: "/pages/my/persData",

View File

@@ -27,21 +27,94 @@
<text v-else>{{item.aiBuyConfig.fee}}</text>
</view>
</view>
<view class="order_infor" v-if="item.orderType=='point'">
<view class="left">
<image class="feng fengPoint" src="/static/icon/pay_3.png" mode="aspectFill"></image>
<text>充值 {{item.bookBuyConfigEntity.money}}天医币</text>
</view>
</view>
<view class="order_infor" v-if="item.orderType=='relearn'">
<view class="left">
<image class="feng fengPoint" src="/static/icon/fugou.png" mode="aspectFill"></image>
<view class="btns flexbox">
<view class="booknameleft" style=" padding-left: 20rpx;">
{{ item.remark }}
</view>
</view>
</view>
</view>
<view class="order_infor" v-if="item.orderType=='order'">
<view v-for="(item2, index2) in item.productList"
:key="item.orderId" class="bookinfolist">
<view class="left">
<view class="feng" v-if="item2.product && item2.product.productImages">
<image style="width: 100%; height: 100%"
mode="aspectFit" :src="item2.product.productImages"></image>
</view>
<view v-else class="feng" style="
color: #c0c4cc;
font-size: 22rpx;
line-height: 140rpx;
text-align: center;
">暂无封面图</view>
<view class="btns flexbox" style=" width: calc(100% - 150rpx);">
<view class="booknameleft">
{{ item2.product && item2.product.productName ? item2.product.productName : "" }}</view>
<view style="
line-height: 58rpx;
color: #333;
font-size: 26rpx;
font-weight: 700;
">
<text style="font-size: 20rpx"></text>
<text v-if="item2.product.price>=0">{{item2.product.price}}</text>
</view>
</view>
</view>
<view class="btns flexbox">
<view class="left" style="color: #c0c4cc"></view>
<view class="right flexbox opbtns" style="color: #c0c4cc">
×{{ item2.quantity ? item2.quantity : "" }}
</view>
</view>
</view>
</view>
<view class="order_price">实付款
<view class="left">
<text v-if="item.realMoney && item.realMoney > 0">
{{ item.realMoney }}
</text>
<text v-if="item.realMoney==0&&item.jfDeduction==0">
0
<view
style="
line-height: 46rpx;
color: #333;
font-size: 30rpx;
font-weight: 700;
"
>
<text v-if="item.orderType == 'point'">
{{ item.bookBuyConfigEntity.realMoney }}
</text>
<text v-if="item.orderType != 'point'">
<text v-if="item.realMoney && item.realMoney > 0">
{{ item.realMoney }}
</text>
<text v-if="item.realMoney==0&&item.jfDeduction==0">
0
</text>
<text
style="margin: 0 4rpx"
v-if="
item.realMoney > 0 &&
item.jfDeduction > 0
"
>
+
</text>
</text>
<text v-if="item.realMoney > 0 && item.jfDeduction > 0">
+
</text>
<text v-if="item.jfDeduction > 0">{{ item.jfDeduction }} 积分</text>
<text v-if="item.jfDeduction > 0">{{ item.jfDeduction }} 积分</text>
</view>
</view>
<text class="order_time">下单时间:{{item.createTime}}</text>
@@ -73,10 +146,10 @@ export default {
}
},
onLoad() {
this.getData();
},
onShow() {
this.getData();
},
computed: {
...mapState(["userInfo"]),
@@ -90,7 +163,7 @@ export default {
var params = {
userId: this.userInfo.id,
come: '4',
orderStatus: 3,
orderStatus: '',
...this.pagination
}
this.$http.request({
@@ -246,7 +319,7 @@ export default {
.item_top{
position: absolute;
top: 75rpx;
top: 70rpx;
right: 30rpx;
font-size: 24rpx;
font-weight: normal;
@@ -309,8 +382,8 @@ export default {
padding: 0 15rpx;
line-height: 45rpx;
font-size: 24rpx;
color: #999;
border: 1px solid #999;
color: red;
border: 1px solid red;
border-radius: 30rpx;
}
@@ -321,4 +394,43 @@ export default {
color: #999;
padding-top: 150rpx;
}
.feng {
background-color: #fafafa;
margin: 0rpx 22rpx 0 0;
height: 140rpx;
width: 140rpx;
float: left;
border-radius: 14rpx;
flex-shrink: 0;
}
.btns{
font-size: 30rpx;
font-weight: bold;
display: flex;
justify-content: space-between;
align-items: center;
}
.opbtns{
font-weight: normal;
font-size: 28rpx;
}
.order_infor {
.bookinfolist {
width: 100%;
margin-bottom: 20rpx;
overflow: hidden;
}
.bookinfolist:nth-last-child(1) {
margin-bottom: 0 !important;
}
.operation_box {
position: absolute;
bottom: 20rpx;
left: 40rpx;
}
}
</style>

View File

@@ -22,8 +22,45 @@
v-if="orderContet.orderStatus == 5">已超时</text>
</view>
<view
class="orderContent"
v-for="(item, index) in goodsList"
:key="index"
@click="goDetail(item.productId, item)"
v-if="goodsList.length > 0"
style=" display: flex; align-items: center; justify-content: center;"
>
<view class="feng" style="position: relative">
<view v-if="item.delFlag == -1" class="delisted">已下架</view>
<image
style="width: 100%; height: 100%"
v-if="item.productImages"
:src="item.productImages"
mode="aspectFit"
></image>
<view
v-else style="
color: #c0c4cc;
font-size: 22rpx;
line-height: 140rpx;
text-align: center;">暂无封面图</view>
</view>
<view class="goods_info">
<view class="flexbox itemJian">
<view class="booknameleft">
<text :style="`${item.delFlag == -1 ? 'color:#c0c4cc;' : ''}`">{{ item.productName }}</text>
</view>
<view style="color: #c0c4cc; font-size: 26rpx; font-weight: 700">
×{{ item.quantity ? item.quantity : "" }}
</view>
</view>
</view>
<br clear="both" />
</view>
<view class="orderContent" v-if="orderContet.orderType == 'aiVip'||orderContet.orderType == 'upgradeAiVip'" style=" display: flex; align-items: center; justify-content: center;">
<image src="/static/icon/order_vip.png" mode="aspectFill" style="width: 100rpx; height: 100rpx;"></image>
<image src="/static/icon/order_vip.png" mode="aspectFill" style="width: 100rpx; height: 100rpx; flex-shrink: 0;"></image>
<view class="itemJian">
<view class="orderTitle" style="line-height: 46rpx; margin-bottom: 0;">
{{ orderContet.aiBuyConfig.title }}<span style=" color: red;">{{ orderContet.aiBuyConfig.count }}<span v-if="orderContet.orderType=='upgradeAiVip'">VIP升级</span></span>
@@ -31,12 +68,20 @@
</view>
</view>
<view
class="orderContent" v-else-if="orderContet.orderType == 'point'">
<view class="orderContent" v-if="orderContet.orderType == 'vip'" style=" display: flex; align-items: center; justify-content: center;">
<image src="/static/icon/order_vip.png" mode="aspectFill" style="width: 100rpx; height: 100rpx; flex-shrink: 0;"></image>
<view class="itemJian">
<view class="orderTitle" style="line-height: 46rpx; margin-bottom: 0;">
{{ orderContet.vipBuyConfigEntity.title }}<text class="vip_year" v-if="orderContet.vipBuyConfigEntity.year">({{ orderContet.vipBuyConfigEntity.year }})</text>
</view>
</view>
</view>
<view class="orderContent" v-if="orderContet.orderType == 'point'" style=" display: flex; align-items: center; justify-content: center;">
<image
src="/static/icon/pay_3.png"
mode="aspectFill"
style="width: 100rpx; height: 100rpx"
style="width: 100rpx; height: 100rpx; flex-shrink: 0;"
></image>
<view class="itemJian">
<view class="orderTitle" style="line-height: 100rpx">
@@ -44,6 +89,24 @@
</view>
</view>
</view>
<view class="orderContent" v-if="orderContet.orderType == 'relearn'" style=" display: flex; align-items: center; justify-content: center;">
<image
src="/static/icon/fugou.png"
mode="aspectFill"
style="width: 100rpx; height: 100rpx; flex-shrink: 0;"
></image>
<view class="itemJian">
<view class="orderTitle" style="line-height: 60rpx">
<text>{{ orderContet.remark }}</text>
</view>
<view class="orderPrice">
<text style="font-weight: bold">&nbsp;</text>
</view>
<br clear="both" />
</view>
<br clear="both" />
</view>
<view class="order_item">
<view class="orderallpri">
@@ -210,6 +273,7 @@ export default {
sheetList: [], // 面单数据
consigneeShow: false,
customButton: [],
goodsList: [],
};
},
onLoad(e) {
@@ -274,6 +338,7 @@ export default {
.then((res) => {
this.customButton = [];
this.orderContet = res.data.buyOrder;
this.goodsList = res.data.productInfo;
this.consigneeShow = true;
if (
this.orderContet.orderStatus == 2 &&
@@ -285,14 +350,12 @@ export default {
text: "查看物流",
color: "#333",
backgroundColor: "#f0f0f0",
color: "#fff",
});
}
if (this.orderContet.orderStatus == 2) {
this.customButton.push({
width: "160rpx",
text: "确认收货",
color: "#fff",
});
}
@@ -681,7 +744,6 @@ view,uni-view {
.orderTitle {
font-weight: bold;
font-size: 30rpx;
margin: 0 0 20rpx 0;
float: left;
width: 540rpx;
}

View File

@@ -24,7 +24,7 @@
</view>
<view class="taihu_common">
<text>出诊信息</text>
{{taihuTalent.clinic}}
<span v-html="taihuTalent.clinic"></span>
</view>
<view class="taihu_common">
<text>预约信息</text>

View File

@@ -1,7 +1,7 @@
<template>
<view class="content">
<z-nav-bar title="太湖英才" bgColor="#5188e5" fontColor="#fff" :backState="2000"></z-nav-bar>
<view class="talents_module" :style="`top: ${45 + statusBarHeight}px;`">
<view class="talents_module" :style="`top: ${42 + statusBarHeight}px;`">
<view class="talents_tab">
<view class="tab_item" @click="toggleFilter('city')">
地区
@@ -219,6 +219,7 @@ export default {
this.cityIndex = null;
this.city = [];
this.region = '';
this.cityTitle = '';
this.selectedPath = [data.areaId];
//只有中国有二级,如果没有二级则为海外国家

View File

@@ -173,6 +173,11 @@
import $http from "@/config/requestConfig.js";
import { mapState } from "vuex";
import debounce from "@/common/debounce.js";
import {
setPay,
setPayAssign,
setWXPay
} from "@/config/utils";
const { platform } = uni.getSystemInfoSync();
export default {
watch: {

View File

@@ -45,6 +45,7 @@
</view>
</view>
<view class="AC_mark" v-if="slotProps.row.remark">{{slotProps.row.remark}}</view>
<view class="AC_note" v-if="slotProps.row.note&&slotProps.row.note!='null'">说明{{slotProps.row.note}}</view>
<view class="AC_time">{{ slotProps.row.createTime }}</view>
</view>
</template>
@@ -88,7 +89,7 @@ export default {
totalCount: 0,
tab_muJian: 0,
bgiStyle: {
background: "#7dc1f0",
background: "#5188e5",
},
iconStyle: {
fontSize: "40rpx",
@@ -167,6 +168,7 @@ export default {
.wallet_wrap{
background-color: #eff5f8;
height: 100%;
overflow: auto;
}
.ACTable_block{
padding: 0 30rpx;
@@ -251,10 +253,13 @@ export default {
margin-top: 20rpx;
color: #888;
}
.AC_note {
color: #888;
font-size: 26rpx;
}
.AC_time {
color: #bababa;
font-size: 28rpx;
font-size: 26rpx;
}
}
}

View File

@@ -11,12 +11,20 @@
: 'cj_price'
">
<view class="pr_jg">{{ item.realMoney }}</view>
<view class="pr_yl">{{ item.money }} 天医币</view>
<view class="pr_lj">限时特惠</view>
<view class="pr_yl" :style="item.givejf&&item.givejf>0?' paddingTop: 0':''">{{ item.money }}天医币<text v-if="item.givejf&&item.givejf>0">{{ item.givejf }}积分</text></view>
<view class="pr_lj" v-if="item.description&&item.description!=''">{{item.description}}</view>
</view>
<br clear="both" />
</view>
<view class="limitBlock" v-if="isAndroid">
<text>其他金额</text>
<input type="text" v-model="limitVal" placeholder="请输入充值金额" placeholder-class="limit-placeholder" @input="input()" />
</view>
<view>
<text style="font-size: 24rpx; color: #8e8e8e;">说明 : 天医币属于虚拟产品一经购买概不退还</text>
</view>
</view>
<view class="cha_fangsh" v-if="isAndroid">
<view class="cf_title PM_font">支付方式</view>
<view class="cf_radio">
@@ -107,6 +115,7 @@ export default {
urlList: {
list: "common/bookBuyConfig/getBookBuyConfigList",
},
limitVal: ''
};
},
//第一次加载
@@ -378,7 +387,7 @@ export default {
.then((res) => {
uni.hideLoading();
this.cjList = res.bookBuyConfigList;
this.stepsCj = res.bookBuyConfigList[0];
//this.stepsCj = res.bookBuyConfigList[0];
});
},
// 苹果充值列表
@@ -403,6 +412,7 @@ export default {
// 点击充值金额
chosPric(e) {
this.stepsCj = e;
this.limitVal = '';
},
// 选择支付方式1
@@ -410,6 +420,10 @@ export default {
let that = this;
that.payType = e;
},
//输入金额
input(val){
this.stepsCj = {};
},
// 充值
goToPay() {
this.kaiChar();
@@ -423,6 +437,30 @@ export default {
});
return false;
}
if(!this.stepsCj.priceTypeId&&!this.limitVal){
uni.showToast({
title: "请选择充值商品",
icon: "none",
});
return false;
}
const regex = /^[1-9]\d*$/;
//如果输入其他金额
if(this.limitVal){
if(!regex.test(this.limitVal)){
uni.showToast({
title: "充值金额必须为正整数",
icon: "none",
});
return false;
}
//设置充值金额和id
this.stepsCj = {
money: this.limitVal,
priceTypeId: 0
}
}
//常规充值
if (this.radioValue == "1") {
uni.showLoading({
@@ -437,8 +475,8 @@ export default {
orderMoney: that.stepsCj.money * 1, //订单金额
districtMoney: 0, //优惠金额
realMoney: that.stepsCj.money * 1, //实收金额
appName: "xlkj",
come: "3",
appName: "thyy",
come: "4",
productId: that.stepsCj.priceTypeId, // 充值的类型id
};
$http.request({
@@ -649,7 +687,7 @@ export default {
}
.cha_jine {
padding: 60rpx 30rpx 40rpx;
margin: 40rpx 30rpx 20rpx 30rpx;
.cj_title {
font-size: 46rpx;
@@ -665,29 +703,41 @@ export default {
width: 47%;
margin: 0 5% 30rpx 0;
text-align: center;
padding: 20rpx;
padding: 30rpx 0 0;
border-radius: 15rpx;
position: relative;
color: #2d2d2d;
height: 160rpx;
.pr_jg {
font-size: 45rpx;
margin: 20rpx 0 10rpx 0;
font-weight: bold;
}
.pr_yl {
padding-top: 10rpx;
font-size: 26rpx;
color: #575555;
text{
width: 100%;
text-align: center;
line-height: 40rpx;
position: absolute;
left: 0;
bottom: 10rpx;
color: red;
display: block;
font-size: 24rpx;
}
}
.pr_lj {
background-image: linear-gradient(180deg, #5188e5 0%, #abcbfb 100%);
color: #fff;
position: absolute;
top: -20rpx;
right: -20rpx;
z-index: 999;
top: -22rpx;
right: -22rpx;
font-size: 24rpx;
line-height: 20px;
padding: 5rpx 10rpx;
@@ -752,10 +802,12 @@ export default {
}
.char_btn {
width: 100%;
background: #fff;
padding: 20rpx 0;
position: fixed;
left: 0;
right: 0;
bottom: 30rpx;
bottom: 0;
view {
background: $themeBgColor;
@@ -783,4 +835,62 @@ export default {
.commonPageBox {
background-color: #fff !important;
}
.limitBlock{
display: flex;
align-items: center;
margin-bottom: 10rpx;
text{
font-size: 28rpx;
}
input{
display: inline-block;
margin-left: 20rpx;
width: 300rpx;
height: 70rpx;
border: 1rpx solid #ededed;
border-radius: 10rpx;
line-height: 40rpx;
padding: 20rpx;
font-size: 28rpx;
color: #666;
}
}
.limit-placeholder{
font-size: 25rpx;
color: #8b8c90 !important;
}
.active_block{
width: 100%;
background-color: rgba(81, 136, 229, 0.2);
border-radius: 10rpx;
padding: 10rpx 20rpx;
font-size: 28rpx;
line-height: 42rpx;
margin-top: 15rpx;
color: #333;
}
/deep/.active_block span{
color: red;
font-size: 32rpx;
font-weight: bold;
padding: 0 5rpx;
}
/deep/.active_block span:first-child{
padding: 0 5rpx 0 0;
}
/deep/.active_block p{
padding-top: 10rpx;
color: #666;
font-size: 24rpx;
line-height: 34rpx;
}
/deep/.active_block p span{
padding: 0 5rpx !important;
}
</style>