名医精彩

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

@@ -13,6 +13,10 @@
},
"provider" : "aliyun",
"type" : "uniCloud"
},
{
"playground" : "standard",
"type" : "uni-app:app-android"
}
]
}

View File

@@ -85,12 +85,12 @@ export default {
"selectedIconPath": "static/tab/icon_tab2_a.png",
"text": "太湖英才"
},
// {
// "pagePath": "pages/doctors/index",
// "iconPath": "static/tab/icon_tab3.png",
// "selectedIconPath": "static/tab/icon_tab3_a.png",
// "text": "名医精彩"
// },
{
"pagePath": "pages/doctors/index",
"iconPath": "static/tab/icon_tab3.png",
"selectedIconPath": "static/tab/icon_tab3_a.png",
"text": "名医精彩"
},
// {
// "pagePath": "pages/wumen/index",
// "iconPath": "static/tab/icon_tab4.png",
@@ -117,12 +117,12 @@ export default {
"selectedIconPath": "static/tab/icon_tab2_a.png",
"text": "太湖英才"
},
// {
// "pagePath": "pages/doctors/index",
// "iconPath": "static/tab/icon_tab3.png",
// "selectedIconPath": "static/tab/icon_tab3_a.png",
// "text": "名医精彩"
// },
{
"pagePath": "pages/doctors/index",
"iconPath": "static/tab/icon_tab3.png",
"selectedIconPath": "static/tab/icon_tab3_a.png",
"text": "名医精彩"
},
// {
// "pagePath": "pages/wumen/index",
// "iconPath": "static/tab/icon_tab4.png",

View File

@@ -39,7 +39,7 @@ const orderRegular = /[0-9]\d{31}$/;
//手机号验证正则表达式
// (中国大陆)
// const phoneRegular = /^1\d{10}$/;
const phoneRegular = /^1([358][0-9]|4[579]|66|7[0135678]|9[89])\d{8}$/;
const phoneRegular = /^1(3[0-9]|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/;
// const phoneRegular = /^[1][3-8]\d{9}$|^([6|9])\d{7}$|^[0][9]\d{8}$|^[6]([8|6])\d{5}$/;
// 手机号码验证 支持港澳台 大陆
// const phoneRegular = /^[1][3-8]\d{9}$|^([6|9])\d{7}$|^[0][9]\d{8}$|^[6]([8|6])\d{5}$|^(00){0,1}(65){1}[13689]\d{6,7}$/;

View File

@@ -130,7 +130,7 @@ $http.requestStart = function (options) {
if (storeUserInfo.token) {
options.header['token'] = storeUserInfo.token;
};
options.header['appType'] = 'psyche';
options.header['appType'] = 'taihumed';
return options;
}
//请求结束

View File

@@ -264,7 +264,7 @@ export const setWXPay = function(payInfo, callback) {
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data: {
...payInfo,
appName: 'xlkj'
appName: 'thyy'
},
header: { //默认 无 说明请求头1
'Content-Type': 'application/json'

20
main.js
View File

@@ -46,6 +46,26 @@ import commonGoodsNav from '@/pages/component/commonComponents/goodsNav.vue'
Vue.component('common-goods-nav', commonGoodsNav);
import commonList from '@/pages/component/commonComponents/list.vue'
Vue.component('common-list', commonList);
import commonOrderSubmit from '@/pages/component/commonComponents/orderSubmit.vue'
Vue.component('common-order-submit', commonOrderSubmit);
import commonSelectGoods from '@/pages/component/commonComponents/selectGoods.vue'
Vue.component('common-select-goods', commonSelectGoods);
import commonAnchorLink from '@/pages/component/commonComponents/anchorLink.vue'
Vue.component('common-anchor-link', commonAnchorLink);
import commonVideo from '@/pages/component/commonComponents/video.vue'
Vue.component('common-video', commonVideo);
import commonCurriculumVideo from '@/pages/component/commonComponents/curriculumVideo.vue'
Vue.component('common-curriculum-video', commonCurriculumVideo);
import commonRichDetail from '@/pages/component/commonComponents/richDetail.vue'
Vue.component('common-rich-detail', commonRichDetail);
import commonVideoAudio from '@/pages/component/commonComponents/audio.vue'
Vue.component('common-list-audio', commonVideoAudio);
import commonVideoAliyun from '@/pages/component/commonComponents/AliPlayer.vue'
Vue.component('common-list-aliyun', commonVideoAliyun);
import commonSticky from '@/pages/component/commonComponents/sticky.vue'
Vue.component('common-sticky', commonSticky);
App.mpType = 'app'
const app = new Vue({

5
node_modules/.package-lock.json generated vendored
View File

@@ -146,6 +146,11 @@
"node": ">= 0.4"
}
},
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg=="
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",

View File

@@ -1,5 +1,6 @@
{
"dependencies": {
"jquery": "^3.7.1",
"qs": "^6.14.0"
}
}

View File

@@ -165,6 +165,7 @@
}
}
},
{
"path": "pages/wumen/index",
"style": {
@@ -273,6 +274,54 @@
}
}
},
{
"path": "pages/goods/order",
"style": {
"navigationBarTitleText": "确认订单",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/curriculum/index/index",
"style": {
"navigationBarTitleText": "我的课程",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/curriculum/index",
"style": {
"navigationBarTitleText": "课程详情",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
{
"path": "pages/curriculum/detail",
"style": {
"navigationBarTitleText": "教学内容",
"enablePullDownRefresh": false, // 禁止下拉刷新
"app-plus": {
"bounce": "none",
"titleNView": false,
"popGesture": "none"
}
}
},
@@ -308,10 +357,10 @@
"pagePath": "pages/talents/index",
"text": "太湖英才"
},
// {
// "pagePath": "pages/doctors/index",
// "text": "名医精彩"
// },
{
"pagePath": "pages/doctors/index",
"text": "名医精彩"
},
// {
// "pagePath": "pages/wumen/index",
// "text": "吴门医述"

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>

BIN
static/icon/course_07.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
static/icon/fugou.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -0,0 +1,18 @@
## 1.2.12022-05-30
- 新增 stat属性是否开启uni统计功能
## 1.2.02021-11-19
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-goods-nav](https://uniapp.dcloud.io/component/uniui/uni-goods-nav)
## 1.1.12021-08-24
- 新增 支持国际化
## 1.1.02021-07-13
- 组件兼容 vue3如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.72021-05-12
- 新增 组件示例地址
## 1.0.62021-04-21
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
## 1.0.52021-02-05
- 优化 组件引用关系通过uni_modules引用组件
## 1.0.42021-02-05
- 调整为uni_modules目录规范

View File

@@ -0,0 +1,6 @@
{
"uni-goods-nav.options.shop": "shop",
"uni-goods-nav.options.cart": "cart",
"uni-goods-nav.buttonGroup.addToCart": "add to cart",
"uni-goods-nav.buttonGroup.buyNow": "buy now"
}

View File

@@ -0,0 +1,8 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}

View File

@@ -0,0 +1,6 @@
{
"uni-goods-nav.options.shop": "店铺",
"uni-goods-nav.options.cart": "购物车",
"uni-goods-nav.buttonGroup.addToCart": "加入购物车",
"uni-goods-nav.buttonGroup.buyNow": "立即购买"
}

View File

@@ -0,0 +1,6 @@
{
"uni-goods-nav.options.shop": "店鋪",
"uni-goods-nav.options.cart": "購物車",
"uni-goods-nav.buttonGroup.addToCart": "加入購物車",
"uni-goods-nav.buttonGroup.buyNow": "立即購買"
}

View File

@@ -0,0 +1,229 @@
<template>
<view class="uni-goods-nav">
<!-- 底部占位 -->
<view class="uni-tab__seat" />
<view class="uni-tab__cart-box flex">
<view class="flex uni-tab__cart-sub-left">
<view v-for="(item,index) in options" :key="index" class="flex uni-tab__cart-button-left uni-tab__shop-cart" @click="onClick(index,item)">
<view class="uni-tab__icon">
<uni-icons :type="item.icon" size="20" color="#646566"></uni-icons>
<!-- <image class="image" :src="item.icon" mode="widthFix" /> -->
</view>
<text class="uni-tab__text">{{ item.text }}</text>
<view class="flex uni-tab__dot-box">
<text v-if="item.info" :class="{ 'uni-tab__dots': item.info > 9 }" class="uni-tab__dot " :style="{'backgroundColor':item.infoBackgroundColor?item.infoBackgroundColor:'#ff0000',
color:item.infoColor?item.infoColor:'#fff'
}">{{ item.info }}</text>
</view>
</view>
</view>
<view :class="{'uni-tab__right':fill}" class="flex uni-tab__cart-sub-right ">
<view v-for="(item,index) in buttonGroup" :key="index" :style="{background:item.backgroundColor,color:item.color}"
class="flex uni-tab__cart-button-right" @click="buttonClick(index,item)"><text :style="{color:item.color}" class="uni-tab__cart-button-right-text">{{ item.text }}</text></view>
</view>
</view>
</view>
</template>
<script>
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from './i18n/index.js'
const { t } = initVueI18n(messages)
/**
* GoodsNav 商品导航
* @description 商品加入购物车、立即购买等
* @tutorial https://ext.dcloud.net.cn/plugin?id=865
* @property {Array} options 组件参数
* @property {Array} buttonGroup 组件按钮组参数
* @property {Boolean} fill = [true | false] 组件按钮组参数
* @property {Boolean} stat 是否开启统计功能
* @event {Function} click 左侧点击事件
* @event {Function} buttonClick 右侧按钮组点击事件
* @example <uni-goods-nav :fill="true" options="" buttonGroup="buttonGroup" @click="" @buttonClick="" />
*/
export default {
name: 'UniGoodsNav',
emits:['click','buttonClick'],
props: {
options: {
type: Array,
default () {
return [{
icon: 'shop',
text: t("uni-goods-nav.options.shop"),
}, {
icon: 'cart',
text: t("uni-goods-nav.options.cart")
}]
}
},
buttonGroup: {
type: Array,
default () {
return [{
text: t("uni-goods-nav.buttonGroup.addToCart"),
backgroundColor: 'linear-gradient(90deg, #FFCD1E, #FF8A18)',
color: '#fff'
},
{
text: t("uni-goods-nav.buttonGroup.buyNow"),
backgroundColor: 'linear-gradient(90deg, #FE6035, #EF1224)',
color: '#fff'
}
]
}
},
fill: {
type: Boolean,
default: false
},
stat:{
type: Boolean,
default: false
}
},
methods: {
onClick(index, item) {
this.$emit('click', {
index,
content: item,
})
},
buttonClick(index, item) {
if (uni.report && this.stat) {
uni.report(item.text, item.text)
}
this.$emit('buttonClick', {
index,
content: item
})
}
}
}
</script>
<style lang="scss" >
.flex {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-goods-nav {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
}
.uni-tab__cart-box {
flex: 1;
height: 50px;
background-color: #fff;
z-index: 900;
}
.uni-tab__cart-sub-left {
padding: 0 5px;
}
.uni-tab__cart-sub-right {
flex: 1;
}
.uni-tab__right {
margin: 5px 0;
margin-right: 10px;
border-radius: 100px;
overflow: hidden;
}
.uni-tab__cart-button-left {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
// flex: 1;
position: relative;
justify-content: center;
align-items: center;
flex-direction: column;
margin: 0 10px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-tab__icon {
width: 18px;
height: 18px;
}
.image {
width: 18px;
height: 18px;
}
.uni-tab__text {
margin-top: 3px;
font-size: 12px;
color: #646566;
}
.uni-tab__cart-button-right {
/* #ifndef APP-NVUE */
display: flex;
flex-direction: column;
/* #endif */
flex: 1;
justify-content: center;
align-items: center;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-tab__cart-button-right-text {
font-size: 14px;
color: #fff;
}
.uni-tab__cart-button-right:active {
opacity: 0.7;
}
.uni-tab__dot-box {
/* #ifndef APP-NVUE */
display: flex;
flex-direction: column;
/* #endif */
position: absolute;
right: -2px;
top: 2px;
justify-content: center;
align-items: center;
// width: 0;
// height: 0;
}
.uni-tab__dot {
// width: 30rpx;
// height: 30rpx;
padding: 0 4px;
line-height: 15px;
color: #ffffff;
text-align: center;
font-size: 12px;
background-color: #ff0000;
border-radius: 15px;
}
.uni-tab__dots {
padding: 0 4px;
// width: auto;
border-radius: 15px;
}
</style>

View File

@@ -0,0 +1,88 @@
{
"id": "uni-goods-nav",
"displayName": "uni-goods-nav 商品导航",
"version": "1.2.1",
"description": "商品导航组件主要用于电商类应用底部导航,可自定义加入购物车,购买等操作",
"keywords": [
"uni-ui",
"uniui",
"商品导航"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@@ -0,0 +1,10 @@
## GoodsNav 商品导航
> **组件名uni-goods-nav**
> 代码块: `uGoodsNav`
商品加入购物车,立即购买等。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-goods-nav)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

View File

@@ -0,0 +1,21 @@
## 2.1.02021-11-19
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-tag](https://uniapp.dcloud.io/component/uniui/uni-tag)
## 2.0.02021-11-09
- 新增 提供组件设计资源,组件样式调整
- 移除 插槽
- 移除 type 属性的 royal 选项
## 1.1.12021-08-11
- type 不是 default 时size 为 small 字体大小显示不正确
## 1.1.02021-07-30
- 组件兼容 vue3如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.0.72021-06-18
- 修复 uni-tag 在字节跳动小程序上 css 类名编译错误的 bug
## 1.0.62021-06-04
- 修复 未定义 sass 变量 "$uni-color-royal" 的bug
## 1.0.52021-05-10
- 修复 royal 类型无效的bug
- 修复 uni-tag 宽度不自适应的bug
- 新增 uni-tag 支持属性 custom-style 自定义样式
## 1.0.42021-02-05
- 调整为uni_modules目录规范

View File

@@ -0,0 +1,252 @@
<template>
<text class="uni-tag" v-if="text" :class="classes" :style="customStyle" @click="onClick">{{text}}</text>
</template>
<script>
/**
* Tag 标签
* @description 用于展示1个或多个文字标签可点击切换选中、不选中的状态
* @tutorial https://ext.dcloud.net.cn/plugin?id=35
* @property {String} text 标签内容
* @property {String} size = [default|small|mini] 大小尺寸
* @value default 正常
* @value small 小尺寸
* @value mini 迷你尺寸
* @property {String} type = [default|primary|successwarningerror] 颜色类型
* @value default 灰色
* @value primary 蓝色
* @value success 绿色
* @value warning 黄色
* @value error 红色
* @property {Boolean} disabled = [true|false] 是否为禁用状态
* @property {Boolean} inverted = [true|false] 是否无需背景颜色(空心标签)
* @property {Boolean} circle = [true|false] 是否为圆角
* @event {Function} click 点击 Tag 触发事件
*/
export default {
name: "UniTag",
emits: ['click'],
props: {
type: {
// 标签类型default、primary、success、warning、error、royal
type: String,
default: "default"
},
size: {
// 标签大小 normal, small
type: String,
default: "normal"
},
// 标签内容
text: {
type: String,
default: ""
},
disabled: {
// 是否为禁用状态
type: [Boolean, String],
default: false
},
inverted: {
// 是否为空心
type: [Boolean, String],
default: false
},
circle: {
// 是否为圆角样式
type: [Boolean, String],
default: false
},
mark: {
// 是否为标记样式
type: [Boolean, String],
default: false
},
customStyle: {
type: String,
default: ''
}
},
computed: {
classes() {
const {
type,
disabled,
inverted,
circle,
mark,
size,
isTrue
} = this
const classArr = [
'uni-tag--' + type,
'uni-tag--' + size,
isTrue(disabled) ? 'uni-tag--disabled' : '',
isTrue(inverted) ? 'uni-tag--' + type + '--inverted' : '',
isTrue(circle) ? 'uni-tag--circle' : '',
isTrue(mark) ? 'uni-tag--mark' : '',
// type === 'default' ? 'uni-tag--default' : 'uni-tag-text',
isTrue(inverted) ? 'uni-tag--inverted uni-tag-text--' + type : '',
size === 'small' ? 'uni-tag-text--small' : ''
]
// 返回类的字符串,兼容字节小程序
return classArr.join(' ')
}
},
methods: {
isTrue(value) {
return value === true || value === 'true'
},
onClick() {
if (this.isTrue(this.disabled)) return
this.$emit("click");
}
}
};
</script>
<style lang="scss" scoped>
$uni-primary: #2979ff !default;
$uni-success: #18bc37 !default;
$uni-warning: #f3a73f !default;
$uni-error: #e43d33 !default;
$uni-info: #8f939c !default;
$tag-default-pd: 4px 7px;
$tag-small-pd: 2px 5px;
$tag-mini-pd: 1px 3px;
.uni-tag {
line-height: 14px;
font-size: 12px;
font-weight: 200;
padding: $tag-default-pd;
color: #fff;
border-radius: 3px;
background-color: $uni-info;
border-width: 1rpx;
border-style: solid;
border-color: $uni-info;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
// size attr
&--default {
font-size: 12px;
}
&--default--inverted {
color: $uni-info;
border-color: $uni-info;
}
&--small {
padding: $tag-small-pd;
font-size: 12px;
border-radius: 2px;
}
&--mini {
padding: $tag-mini-pd;
font-size: 12px;
border-radius: 2px;
}
// type attr
&--primary {
background-color: $uni-primary;
border-color: $uni-primary;
color: #fff;
}
&--success {
color: #fff;
background-color: $uni-success;
border-color: $uni-success;
}
&--warning {
color: #fff;
background-color: $uni-warning;
border-color: $uni-warning;
}
&--error {
color: #fff;
background-color: $uni-error;
border-color: $uni-error;
}
&--primary--inverted {
color: $uni-primary;
border-color: $uni-primary;
}
&--success--inverted {
color: $uni-success;
border-color: $uni-success;
}
&--warning--inverted {
color: $uni-warning;
border-color: $uni-warning;
}
&--error--inverted {
color: $uni-error;
border-color: $uni-error;
}
&--inverted {
background-color: #fff;
}
// other attr
&--circle {
border-radius: 15px !important;
}
&--mark {
border-top-left-radius: 0 !important;
border-bottom-left-radius: 0 !important;
border-top-right-radius: 15px !important;
border-bottom-right-radius: 15px !important;
}
&--disabled {
opacity: 0.5;
/* #ifdef H5 */
cursor: not-allowed;
/* #endif */
}
}
.uni-tag-text {
color: #fff;
font-size: 14px;
&--primary {
color: $uni-primary;
}
&--success {
color: $uni-success;
}
&--warning {
color: $uni-warning;
}
&--error {
color: $uni-error;
}
&--small {
font-size: 12px;
}
}
</style>

View File

@@ -0,0 +1,87 @@
{
"id": "uni-tag",
"displayName": "uni-tag 标签",
"version": "2.1.0",
"description": "Tag 组件用于展示1个或多个文字标签可点击切换选中、不选中的状态。",
"keywords": [
"uni-ui",
"uniui",
"",
"tag",
"标签"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@@ -0,0 +1,13 @@
## Tag 标签
> **组件名uni-tag**
> 代码块: `uTag`
用于展示1个或多个文字标签可点击切换选中、不选中的状态 。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-tag)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

View File

@@ -1,8 +1,8 @@
var isReady=false;var onReadyCallbacks=[];
var isServiceReady=false;var onServiceReadyCallbacks=[];
var __uniConfig = {"pages":["pages/home/index","pages/home/test","pages/user/login","pages/my/index","pages/my/recordsList","pages/user/forget","pages/user/workOrder","pages/my/index","pages/my/set","pages/my/persData","pages/my/aboutUs","pages/talents/index","pages/talents/detail","pages/talents/certificateUrl","pages/doctors/index","pages/wumen/index","pages/folder/index","pages/folder/patient","pages/wallet/recharge","pages/wallet/account","pages/wallet/points","pages/vip/index","pages/order/index","pages/order/infor","uni_modules/uni-upgrade-center-app/pages/upgrade-popup"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"uni-app","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8"},"tabBar":{"color":"#333","selectedColor":"#5188e5","borderStyle":"black","backgroundColor":"#fff","list":[{"pagePath":"pages/home/index","text":"智慧医疗"},{"pagePath":"pages/talents/index","text":"太湖英才"},{"pagePath":"pages/my/index","text":"我的"}]},"darkmode":false,"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":false,"autoclose":true},"appname":"太湖云医","compilerVersion":"4.45","entryPagePath":"pages/home/index","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}};
var __uniRoutes = [{"path":"/pages/home/index","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationBarTitleText":"首页","bounce":"none","titleNView":false}},{"path":"/pages/home/test","meta":{},"window":{"navigationBarTitleText":"首页","bounce":"none","titleNView":false}},{"path":"/pages/user/login","meta":{},"window":{"navigationBarTitleText":"登录","bounce":"none","titleNView":false}},{"path":"/pages/my/index","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationBarTitleText":"我的","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/my/recordsList","meta":{},"window":{"navigationBarTitleText":"历史记录","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/user/forget","meta":{},"window":{"navigationBarTitleText":"忘记密码","bounce":"none","titleNView":false}},{"path":"/pages/user/workOrder","meta":{},"window":{"navigationBarTitleText":"问题反馈","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/my/set","meta":{},"window":{"navigationBarTitleText":"设置","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/my/persData","meta":{},"window":{"navigationBarTitleText":"个人资料","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/my/aboutUs","meta":{},"window":{"navigationBarTitleText":"关于我们","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/talents/index","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationBarTitleText":"太湖英才","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/talents/detail","meta":{},"window":{"navigationBarTitleText":"医生主页","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/talents/certificateUrl","meta":{},"window":{"navigationBarTitleText":"医生证书","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/doctors/index","meta":{},"window":{"navigationBarTitleText":"名医精彩","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/wumen/index","meta":{},"window":{"navigationBarTitleText":"吴门医述","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/folder/index","meta":{},"window":{"navigationBarTitleText":"我的病历夹","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/folder/patient","meta":{},"window":{"navigationBarTitleText":"患者列表","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/wallet/recharge","meta":{},"window":{"navigationBarTitleText":"充值","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/wallet/account","meta":{},"window":{"navigationBarTitleText":"我的账户","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/wallet/points","meta":{},"window":{"navigationBarTitleText":"我的积分","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/vip/index","meta":{},"window":{"navigationBarTitleText":"VIP办理","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/order/index","meta":{},"window":{"navigationBarTitleText":"我的订单","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/order/infor","meta":{},"window":{"navigationBarTitleText":"订单详情","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/uni_modules/uni-upgrade-center-app/pages/upgrade-popup","meta":{},"window":{"disableScroll":true,"animationDuration":200,"animationType":"fade-in","background":"transparent","backgroundColorTop":"transparent","scrollIndicator":false,"titleNView":false}}];
var __uniConfig = {"pages":["pages/home/index","pages/user/login","pages/my/index","pages/my/recordsList","pages/user/forget","pages/user/workOrder","pages/my/index","pages/my/set","pages/my/persData","pages/my/aboutUs","pages/talents/index","pages/talents/detail","pages/talents/certificateUrl","pages/doctors/index","pages/wumen/index","pages/folder/index","pages/folder/patient","pages/wallet/recharge","pages/wallet/account","pages/wallet/points","pages/vip/index","pages/order/index","pages/order/infor","pages/goods/order","pages/curriculum/index/index","pages/curriculum/index","pages/curriculum/detail","uni_modules/uni-upgrade-center-app/pages/upgrade-popup"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"uni-app","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8"},"tabBar":{"color":"#333","selectedColor":"#5188e5","borderStyle":"black","backgroundColor":"#fff","list":[{"pagePath":"pages/home/index","text":"智慧医疗"},{"pagePath":"pages/talents/index","text":"太湖英才"},{"pagePath":"pages/doctors/index","text":"名医精彩"},{"pagePath":"pages/my/index","text":"我的"}]},"darkmode":false,"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":false,"autoclose":true},"appname":"太湖云医","compilerVersion":"4.45","entryPagePath":"pages/home/index","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}};
var __uniRoutes = [{"path":"/pages/home/index","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationBarTitleText":"首页","bounce":"none","titleNView":false}},{"path":"/pages/user/login","meta":{},"window":{"navigationBarTitleText":"登录","bounce":"none","titleNView":false}},{"path":"/pages/my/index","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationBarTitleText":"我的","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/my/recordsList","meta":{},"window":{"navigationBarTitleText":"历史记录","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/user/forget","meta":{},"window":{"navigationBarTitleText":"忘记密码","bounce":"none","titleNView":false}},{"path":"/pages/user/workOrder","meta":{},"window":{"navigationBarTitleText":"问题反馈","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/my/set","meta":{},"window":{"navigationBarTitleText":"设置","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/my/persData","meta":{},"window":{"navigationBarTitleText":"个人资料","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/my/aboutUs","meta":{},"window":{"navigationBarTitleText":"关于我们","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/talents/index","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationBarTitleText":"太湖英才","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/talents/detail","meta":{},"window":{"navigationBarTitleText":"医生主页","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/talents/certificateUrl","meta":{},"window":{"navigationBarTitleText":"医生证书","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/doctors/index","meta":{"isQuit":true,"isTabBar":true},"window":{"navigationBarTitleText":"名医精彩","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/wumen/index","meta":{},"window":{"navigationBarTitleText":"吴门医述","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/folder/index","meta":{},"window":{"navigationBarTitleText":"我的病历夹","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/folder/patient","meta":{},"window":{"navigationBarTitleText":"患者列表","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/wallet/recharge","meta":{},"window":{"navigationBarTitleText":"充值","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/wallet/account","meta":{},"window":{"navigationBarTitleText":"我的账户","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/wallet/points","meta":{},"window":{"navigationBarTitleText":"我的积分","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/vip/index","meta":{},"window":{"navigationBarTitleText":"VIP办理","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/order/index","meta":{},"window":{"navigationBarTitleText":"我的订单","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/order/infor","meta":{},"window":{"navigationBarTitleText":"订单详情","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/goods/order","meta":{},"window":{"navigationBarTitleText":"确认订单","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/curriculum/index/index","meta":{},"window":{"navigationBarTitleText":"我的课程","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/curriculum/index","meta":{},"window":{"navigationBarTitleText":"课程详情","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/pages/curriculum/detail","meta":{},"window":{"navigationBarTitleText":"教学内容","enablePullDownRefresh":false,"bounce":"none","titleNView":false}},{"path":"/uni_modules/uni-upgrade-center-app/pages/upgrade-popup","meta":{},"window":{"disableScroll":true,"animationDuration":200,"animationType":"fade-in","background":"transparent","backgroundColorTop":"transparent","scrollIndicator":false,"titleNView":false}}];
__uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
__uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:Math.round(f/20)})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:void 0,window:void 0,document:void 0,frames:void 0,self:void 0,location:void 0,navigator:void 0,localStorage:void 0,history:void 0,Caches:void 0,screen:void 0,alert:void 0,confirm:void 0,prompt:void 0,fetch:void 0,XMLHttpRequest:void 0,WebSocket:void 0,webkit:void 0,print:void 0}}}});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long