first commit

This commit is contained in:
GYJ
2024-12-02 10:39:36 +08:00
commit f1f5b666b5
464 changed files with 81372 additions and 0 deletions

BIN
components/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,60 @@
<template>
<view>
<view class="contont">
<view class="contont-box" @click.stop.prevent="setImg()">
<view class="contont-box-icon flex align-center justify-end">
<image @click.stop.prevent="clickClose" src="../../static/images/index/closeVideo.png" mode="">
</image>
</view>
<image src="../../static/images/index/hdimgIcon.png" mode="aspectFill"></image>
</view>
</view>
</view>
</template>
<script>
export default {
name: "activityComp",
data() {
return {
};
},
methods: {
clickClose() {
this.$emit('clickCloseHd')
},
setImg() {
this.$emit('setImgs')
}
}
}
</script>
<style lang="scss" scoped>
.contont {
position: fixed;
bottom: 200rpx;
right: 30rpx;
.contont-box {
position: relative;
image {
width: 114rpx;
height: 104rpx;
}
}
.contont-box-icon {
image {
width: 30rpx;
height: 30rpx;
border-radius: 50%;
}
}
}
</style>

BIN
components/colorui/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,184 @@
/*
Animation 微动画
基于ColorUI组建库的动画模块 by 文晓港 2019年3月26日19:52:28
*/
/* css 滤镜 控制黑白底色gif的 */
.gif-black{
mix-blend-mode: screen;
}
.gif-white{
mix-blend-mode: multiply;
}
/* Animation css */
[class*=animation-] {
animation-duration: .5s;
animation-timing-function: ease-out;
animation-fill-mode: both
}
.animation-fade {
animation-name: fade;
animation-duration: .8s;
animation-timing-function: linear
}
.animation-scale-up {
animation-name: scale-up
}
.animation-scale-down {
animation-name: scale-down
}
.animation-slide-top {
animation-name: slide-top
}
.animation-slide-bottom {
animation-name: slide-bottom
}
.animation-slide-left {
animation-name: slide-left
}
.animation-slide-right {
animation-name: slide-right
}
.animation-shake {
animation-name: shake
}
.animation-reverse {
animation-direction: reverse
}
@keyframes fade {
0% {
opacity: 0
}
100% {
opacity: 1
}
}
@keyframes scale-up {
0% {
opacity: 0;
transform: scale(.2)
}
100% {
opacity: 1;
transform: scale(1)
}
}
@keyframes scale-down {
0% {
opacity: 0;
transform: scale(1.8)
}
100% {
opacity: 1;
transform: scale(1)
}
}
@keyframes slide-top {
0% {
opacity: 0;
transform: translateY(-100%)
}
100% {
opacity: 1;
transform: translateY(0)
}
}
@keyframes slide-bottom {
0% {
opacity: 0;
transform: translateY(100%)
}
100% {
opacity: 1;
transform: translateY(0)
}
}
@keyframes shake {
0%,
100% {
transform: translateX(0)
}
10% {
transform: translateX(-9px)
}
20% {
transform: translateX(8px)
}
30% {
transform: translateX(-7px)
}
40% {
transform: translateX(6px)
}
50% {
transform: translateX(-5px)
}
60% {
transform: translateX(4px)
}
70% {
transform: translateX(-3px)
}
80% {
transform: translateX(2px)
}
90% {
transform: translateX(-1px)
}
}
@keyframes slide-left {
0% {
opacity: 0;
transform: translateX(-100%)
}
100% {
opacity: 1;
transform: translateX(0)
}
}
@keyframes slide-right {
0% {
opacity: 0;
transform: translateX(100%)
}
100% {
opacity: 1;
transform: translateX(0)
}
}

View File

@@ -0,0 +1,65 @@
<template>
<view>
<view class="cu-custom" :style="[{height:CustomBar + 'px'}]">
<view class="cu-bar fixed" :style="style" :class="[bgImage!=''?'none-bg text-white bg-img':'',bgColor]">
<view class="action" @tap="BackPage" v-if="isBack">
<text class="cuIcon-back"></text>
<slot name="backText"></slot>
</view>
<view class="content" :style="[{top:StatusBar + 'px'}]">
<slot name="content"></slot>
</view>
<slot name="right"></slot>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
StatusBar: this.StatusBar,
CustomBar: this.CustomBar
};
},
name: 'cu-custom',
computed: {
style() {
var StatusBar= this.StatusBar;
var CustomBar= this.CustomBar;
var bgImage = this.bgImage;
var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
if (this.bgImage) {
style = `${style}background-image:url(${bgImage});`;
}
return style
}
},
props: {
bgColor: {
type: String,
default: ''
},
isBack: {
type: [Boolean, String],
default: false
},
bgImage: {
type: String,
default: ''
},
},
methods: {
BackPage() {
uni.navigateBack({
delta: 1
});
}
}
}
</script>
<style>
</style>

1226
components/colorui/icon.css Normal file

File diff suppressed because one or more lines are too long

3916
components/colorui/main.css Normal file

File diff suppressed because it is too large Load Diff

312
components/com-input.vue Normal file
View File

@@ -0,0 +1,312 @@
<template>
<view>
<view class="mix-list-cell" :class="border" hover-class="cell-hover" :hover-stay-time="50">
<text class="cell-tit">{{title}}</text>
<input class="main-input" :value="value" :type="_type" placeholder-class="placeholder-class"
:maxlength="maxlength" :placeholder="placeholder" :password="type==='password'&&!showPassword"
@input="onInput" :disabled="readOnly" />
<!-- 是否可见密码 -->
<image v-if="_isShowPass&&type==='password'&&!_isShowCode" class="img cuIcon"
:class="showPassword?'cuIcon-attention':'cuIcon-attentionforbid'" @tap="showPass"></image>
<!-- 倒计时 -->
<view v-if="_isShowCode&&!_isShowPass" :class="['vercode',{'vercode-run': second>0}]" @click="setCode">
{{ getVerCodeSecond }}
</view>
</view>
</view>
</template>
<script>
var _this, countDown;
/**
* 简单封装了下, 应用范围比较狭窄,可以在此基础上进行扩展使用
* 比如加入image iconSize可控等
*/
export default {
data() {
return {
showPassword: false, //是否显示明文
second: 0, //倒计时
isRunCode: false, //是否开始倒计时
typeList: {
left: 'icon-zuo',
right: 'icon-you',
up: 'icon-shang',
down: 'icon-xia'
},
}
},
props: {
readOnly: {
//是否显示获取验证码(二选一)
type: [Boolean, String],
default: false,
},
type: String, //类型
logo: String, //类型
value: String, //值
placeholder: String, //框内提示
isShowCode: {
//是否显示获取验证码(二选一)
type: [Boolean, String],
default: false,
},
codeText: {
type: String,
default: "获取验证码",
},
setTime: {
//倒计时时间设置
type: [Number, String],
default: 60,
},
maxlength: {
//最大长度
type: [Number, String],
default: 30,
},
isShowPass: {
//是否显示密码图标(二选一)
type: [Boolean, String],
default: false,
},
icon: {
type: String,
default: ''
},
title: {
type: String,
default: '标题'
},
tips: {
type: String,
default: ''
},
navigateType: {
type: String,
default: 'right'
},
border: {
type: String,
default: 'b-b'
},
hoverClass: {
type: String,
default: 'cell-hover'
},
iconColor: {
type: String,
default: '#333'
}
},
mounted() {
_this = this
//准备触发
this.$on('runCodes', (val) => {
this.runCodes(val);
});
clearInterval(countDown); //先清理一次循环,避免缓存
},
methods: {
showPass() {
//是否显示密码
this.showPassword = !this.showPassword
},
onInput(e) {
//传出值
this.$emit('input', e.target.value)
},
setCode() {
//设置获取验证码的事件
if (this.isRunCode) {
//判断是否开始倒计时,避免重复点击
return false;
}
this.$emit('setCode')
},
runCodes(val) {
console.error("runCodes")
//开始倒计时
if (String(val) == "0") {
//判断是否需要终止循环
this.second = 0; //初始倒计时
clearInterval(countDown); //清理循环
this.isRunCode = false; //关闭循环状态
return false;
}
if (this.isRunCode) {
//判断是否开始倒计时,避免重复点击
return false;
}
this.isRunCode = true
this.second = this._setTime //倒数秒数
let _this = this;
countDown = setInterval(function() {
_this.second--
if (_this.second == 0) {
_this.isRunCode = false
clearInterval(countDown)
}
}, 1000)
}
},
computed: {
_type() {
//处理值
const type = this.type
return type == 'password' ? 'text' : type
},
_isShowPass() {
//处理值
return String(this.isShowPass) !== 'false'
},
_isShowCode() {
//处理值
return String(this.isShowCode) !== 'false'
},
_setTime() {
//处理值
const setTime = Number(this.setTime)
return setTime > 0 ? setTime : 60
},
getVerCodeSecond() {
//验证码倒计时计算
if (this.second <= 0) {
return this.codeText;
} else {
if (this.second < 10) {
return '0' + this.second + "s";
} else {
return this.second + "s";
}
}
}
}
}
</script>
<style lang='scss'>
.main-input {
flex: 1;
text-align: left;
/* color: white; */
font-size: 16px;
padding-right: 6px;
margin-left: 10px;
border: 1rpx solid #d9d9d9;
height: 90rpx;
border-radius: 10rpx;
padding: 0upx 30upx;
}
.icon .mix-list-cell.b-b:after {
left: 45px;
}
.placeholder-class {
/* color: white; */
opacity: 0.5;
}
.mix-list-cell {
border-radius: 32upx;
margin-top: 1px;
font-size: 32upx;
background: #ffffff;
text-align: left;
display: flex;
margin: 32upx;
/* padding: 24upx 32upx; */
position: relative;
&.cell-hover {
background: transparent;
}
&.b-b:after {
left: 16px;
}
.cell-icon {
align-self: center;
width: 28px;
max-height: 30px;
font-size: 18px;
}
.cell-more {
align-self: center;
font-size: 16px;
color: #606266;
margin-left: 10px;
}
.cell-tit {
width: 80px;
font-size: 16px;
/* color: white; */
display: flex;
align-items: center;
}
.cell-tip {
font-size: 14px;
color: white;
}
}
.items {
position: absolute;
height: 48px;
width: 100%;
background: #FFFFFF;
/*opacity:0.05;*/
}
.main-list {
opacity: 0.8;
z-index: 88;
background: white;
border: 1px solid white;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 18px;
/* Input 高度 */
color: #333333;
padding: 16px;
margin-top: 12px;
margin-bottom: 12px;
}
.img {
width: 16px;
height: 16px;
font-size: 16px;
}
.vercode {
color: #e10a07;
font-size: 14px;
}
.vercode-run {
color: black !important;
}
.oBorder {
border-radius: 2.5rem;
-webkit-box-shadow: 0 0 30px 0 rgba(43, 86, 112, .1);
box-shadow: 0 0 30px 0 rgba(43, 86, 112, .1);
}
</style>

View File

@@ -0,0 +1,184 @@
<template>
<view>
<view id="_drag_button" class="drag" :style="'left: ' + left + 'px; top:' + top + 'px;'"
@touchstart="touchstart" @touchmove.stop.prevent="touchmove" @touchend="touchend"
:class="{transition: isDock && !isMove }">
<view class="drag-box" @click.stop.prevent="click(videoInfo[0])">
<image :src="videoInfo[0].titleImg" mode="aspectFill"></image>
<view class="drag-close flex align-center justify-center">
<image @click.stop.prevent="clickClose" src="../../static/images/index/closeVideo.png" mode="">
</image>
</view>
<view class="drag-playing">
<image src="../../static/images/index/playVideoIcon.png" mode=""></image>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'drag-button',
props: {
isDock: {
type: Boolean,
default: false
},
existTabBar: {
type: Boolean,
default: false
},
videoInfo: {
type: Array,
default: []
}
},
data() {
return {
top: 0,
left: 0,
width: 0,
height: 0,
offsetWidth: 0,
offsetHeight: 0,
windowWidth: 0,
windowHeight: 0,
isMove: true,
edge: 16,
text: '按钮'
}
},
mounted() {
const sys = uni.getSystemInfoSync();
this.windowWidth = sys.windowWidth;
this.windowHeight = sys.windowHeight;
// #ifdef APP-PLUS
this.existTabBar && (this.windowHeight -= 50);
// #endif
if (sys.windowTop) {
this.windowHeight += sys.windowTop;
}
console.log(sys)
const query = uni.createSelectorQuery().in(this);
query.select('#_drag_button').boundingClientRect(data => {
this.width = data.width;
this.height = data.height;
this.offsetWidth = data.width / 2;
this.offsetHeight = data.height / 2;
// this.left = this.windowWidth - this.width - this.edge;
this.left = this.edge;
this.top = this.windowHeight - (2 * this.height) - this.edge;
}).exec();
},
methods: {
//关闭
clickClose() {
this.$emit('clickClose')
},
//点击封面
click(item) {
this.$emit('btnClick', item);
},
touchstart(e) {
this.$emit('btnTouchstart');
},
touchmove(e) {
// 单指触摸
if (e.touches.length !== 1) {
return false;
}
this.isMove = true;
this.left = e.touches[0].clientX - this.offsetWidth;
let clientY = e.touches[0].clientY - this.offsetHeight;
// #ifdef H5
// clientY += this.height;
// #endif
let edgeBottom = this.windowHeight - this.height - this.edge;
// 上下触及边界
if (clientY < this.edge) {
this.top = this.edge;
} else if (clientY > edgeBottom) {
this.top = edgeBottom;
} else {
this.top = clientY
}
},
touchend(e) {
if (this.isDock) {
let edgeRigth = this.windowWidth - this.width - this.edge;
if (this.left < this.windowWidth / 2 - this.offsetWidth) {
this.left = this.edge;
} else {
this.left = edgeRigth;
}
}
this.isMove = false;
this.$emit('btnTouchend');
},
}
}
</script>
<style lang="scss">
.drag {
width: 150rpx;
position: fixed;
z-index: 888;
&.transition {
transition: left .3s ease, top .3s ease;
}
.drag-box {
width: 100%;
position: relative;
image {
width: 100%;
height: 200rpx;
border-radius: 8rpx;
}
}
.drag-close {
// width: 100%;
// margin-top: 10rpx;
position: absolute;
top: -10rpx;
right: -10rpx;
image {
width: 30rpx;
height: 30rpx;
border-radius: 50%;
}
}
.drag-playing {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
image {
width: 30rpx;
height: 34rpx;
}
}
}
</style>

70
components/empty.vue Normal file
View File

@@ -0,0 +1,70 @@
<template>
<view>
<view class="page-box">
<view class="centre" :style="isShow==true?'margin:0;padding:200rpx 0 0 0':''">
<image src="../static/images/learn/none.png" mode=""></image>
<view class="tips">
<!-- 暂无资源 -->
{{title}}
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
title: {
type: String,
default: '暂无数据'
},
isShow: {
type: Boolean,
default: false,
}
},
methods: {
goNav() {
uni.switchTab({
url: '/pages/index/index'
})
}
}
}
</script>
<style lang="scss" scoped>
.centre {
text-align: center;
margin: 200rpx auto;
font-size: 32rpx;
image {
width: 360rpx;
height: 360rpx;
// margin-bottom: 20rpx;
margin: 0 auto 20rpx;
// border: 1px dotted #000000;
}
.tips {
font-size: 34rpx;
color: #999999;
margin-top: 20rpx;
}
.btn1 {
margin: 80rpx auto;
width: 600rpx;
line-height: 90rpx;
border-radius: 44rpx;
color: #ffffff;
font-size: 34rpx;
background: #ff7581;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>

60
components/noLogin.vue Normal file
View File

@@ -0,0 +1,60 @@
<template>
<view>
<view class="page-box">
<view class="centre">
<image src="../static/images/learn/none.png" mode=""></image>
<view class="tips">
暂未登录
</view>
<view class="btn" @click="goNav()">{{content}}</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
content: {
type: String,
default: '立即登录'
}
},
methods: {
goNav() {
uni.navigateTo({
url:'/pages/login/login'
})
}
}
}
</script>
<style lang="scss" scoped>
.centre {
text-align: center;
margin: 200rpx auto;
font-size: 32rpx;
image {
width: 360rpx;
height: 360rpx;
// margin-bottom: 20rpx;
margin: 0 auto 20rpx;
// border: 1px dotted #000000;
}
.tips {
font-size: 34rpx;
color: #5074FF;
margin-top: 20rpx;
}
.btn {
margin: 80rpx auto;
width: 600rpx;
border-radius: 32rpx;
line-height: 90rpx;
color: #ffffff;
font-size: 34rpx;
background: #5074FF;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,157 @@
<template>
<view>
<view class="list flex align-center justify-center">
<view class="list-box">
<view class="list-box-title flex align-center justify-between">
<view class="list-box-title-name">
{{title}}
</view>
<view @click="clickItem('more')" class="list-box-title-more flex align-center">
查看更多
<u-icon name="arrow-right" color="#666666" size="24"></u-icon>
</view>
</view>
<view class="list-box-video flex justify-between">
<view @click="clickItem('video',item)" class="list-box-video-item" v-for="(item,index) in list"
:key="index">
<view class="list-box-video-item-img">
<u-image width="100%" height="100%" border-radius="24rpx" mode="aspectFill"
:src="item.titleImg"></u-image>
<view class="list-box-video-item-img-txt" v-if="item.over == 1">
{{item.courseDetailsCount?item.courseDetailsCount:0}}
</view>
<view class="list-box-video-item-img-txt" v-else>
更新至{{item.courseDetailsCount?item.courseDetailsCount:0}}
</view>
</view>
<view class="list-box-video-item-videoTitle">
{{item.title}}
</view>
<view class="list-box-video-item-tips" v-if="item.courseLabel">
{{item.courseLabel.split(',')[0]}}
</view>
</view>
<view v-if="list.length==2" class="list-box-video-item" style="height: 0;"></view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "recommendVideo",
props: {
//视频数组
list: {
type: Array,
default: []
},
//模块标题
title: {
type: String,
default: '本周热门'
},
//模块类型
typeId: {
type: String,
default: ''
}
},
data() {
return {
};
},
methods: {
/**
* @param {string} type 点击类型 more:更多 video:视频
* @param {Object} item 参数
* 点击事件
*/
clickItem(type, item) {
if (type == 'more') { //查看更多
this.$emit(type, this.typeId)
} else { //查看视频
this.$emit(type, item)
}
},
}
}
</script>
<style lang="scss" scoped>
.list {
width: 100%;
height: auto;
margin-top: 30rpx;
.list-box {
width: 686rpx;
height: 100%;
background-color: #ffffff;
}
.list-box-title-name {
color: #333333;
font-size: 32rpx;
font-weight: bold;
}
.list-box-title-more {
color: #666666;
font-size: 24rpx;
font-weight: normal;
}
.list-box-video {
width: 100%;
margin-top: 20rpx;
.list-box-video-item {
width: 220rpx;
height: auto;
}
.list-box-video-item-img {
width: 100%;
height: 280rpx;
position: relative;
.list-box-video-item-img-txt {
position: absolute;
bottom: 10rpx;
right: 10rpx;
color: #FFFFFF;
font-size: 22rpx;
}
}
.list-box-video-item-videoTitle {
margin-top: 18rpx;
width: 100%;
color: #333333;
font-size: 28rpx;
font-weight: 500;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
}
.list-box-video-item-tips {
width: fit-content;
color: #666666;
font-size: 22rpx;
background-color: #F2F5FF;
border-radius: 6rpx;
margin-top: 6rpx;
padding: 10rpx;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,205 @@
<template xlang="wxml" minapp="mpvue">
<view class="tki-qrcode">
<canvas class="tki-qrcode-canvas" :canvas-id="cid" :style="{width:cpSize+'px',height:cpSize+'px'}" />
<image v-if="show" :src="result" :style="{width:cpSize+'px',height:cpSize+'px'}" />
</view>
</template>
<script>
import QRCode from "./qrcode.js"
let qrcode
export default {
name: "tki-qrcode",
props: {
cid: {
type: String,
default: 'tki-qrcode-canvas'
},
size: {
type: Number,
default: 200
},
unit: {
type: String,
default: 'upx'
},
show: {
type: Boolean,
default: true
},
val: {
type: String,
default: ''
},
background: {
type: String,
default: '#ffffff'
},
foreground: {
type: String,
default: '#000000'
},
pdground: {
type: String,
default: '#000000'
},
icon: {
type: String,
default: ''
},
iconSize: {
type: Number,
default: 40
},
lv: {
type: Number,
default: 3
},
onval: {
type: Boolean,
default: false
},
loadMake: {
type: Boolean,
default: false
},
usingComponents: {
type: Boolean,
default: true
},
showLoading: {
type: Boolean,
default: true
},
loadingText: {
type: String,
default: '二维码生成中'
},
},
data() {
return {
result: '',
}
},
methods: {
_makeCode() {
let that = this
if (!this._empty(this.val)) {
qrcode = new QRCode({
context: that, // 上下文环境
canvasId: that.cid, // canvas-id
usingComponents: that.usingComponents, // 是否是自定义组件
// loadingText: that.loadingText, // loading文字
text: that.val, // 生成内容
size: that.cpSize, // 二维码大小
background: that.background, // 背景色
foreground: that.foreground, // 前景色
pdground: that.pdground, // 定位角点颜色
correctLevel: that.lv, // 容错级别
image: that.icon, // 二维码图标
imageSize: that.iconSize, // 二维码图标大小
cbResult: function(res) { // 生成二维码的回调
that._result(res)
},
});
} else {
uni.showToast({
title: '二维码内容不能为空',
icon: 'none',
duration: 2000
});
}
},
_clearCode() {
this._result('')
qrcode.clear()
},
_saveCode() {
let that = this;
if (this.result != "") {
uni.saveImageToPhotosAlbum({
filePath: that.result,
success: function() {
// uni.showToast({
// title: '二维码保存成功',
// icon: 'success',
// duration: 2000
// });
}
});
}
},
_result(res) {
this.result = res;
this.$emit('result', res)
},
_empty(v) {
let tp = typeof v,
rt = false;
if (tp == "number" && String(v) == "") {
rt = true
} else if (tp == "undefined") {
rt = true
} else if (tp == "object") {
if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null) rt = true
} else if (tp == "string") {
if (v == "" || v == "undefined" || v == "null" || v == "{}" || v == "[]") rt = true
} else if (tp == "function") {
rt = false
}
return rt
}
},
watch: {
size: function(n, o) {
if (n != o && !this._empty(n)) {
this.cSize = n
if (!this._empty(this.val)) {
setTimeout(() => {
this._makeCode()
}, 100);
}
}
},
val: function(n, o) {
if (this.onval) {
if (n != o && !this._empty(n)) {
setTimeout(() => {
this._makeCode()
}, 0);
}
}
}
},
computed: {
cpSize() {
if (this.unit == "upx") {
return uni.upx2px(this.size)
} else {
return this.size
}
}
},
mounted: function() {
if (this.loadMake) {
if (!this._empty(this.val)) {
setTimeout(() => {
this._makeCode()
}, 0);
}
}
},
}
</script>
<style>
.tki-qrcode {
position: relative;
}
.tki-qrcode-canvas {
position: fixed;
top: -99999upx;
left: -99999upx;
z-index: -99999;
}
</style>

View File

@@ -0,0 +1,92 @@
<template>
<view>
<!-- #ifdef MP-TOUTIAO -->
<!-- 抖音im客服 -->
<view class="imKefu">
<button open-type="im" class="imKefu-btn" :data-im-id="imId" @im="imCallback" @error="onimError">
<image class="imKefu-img" src="../../static/images/me/imMsg.png" mode=""></image>
<view class="imKefu-txt">
在线客服
</view>
</button>
</view>
<!-- #endif -->
</view>
</template>
<script>
export default {
name: "ttMsg",
data() {
return {
imId: '', //客服抖音号
};
},
created() {
this.imId = uni.getStorageSync('imId')
},
methods: {
imCallback(e) {
console.log("跳转IM客服成功", e.detail);
},
onimError(e) {
uni.showToast({
title: '拉起IM客服失败',
icon: 'none'
})
console.log("拉起IM客服失败", e.detail);
},
}
}
</script>
<style lang="scss" scoped>
.imKefu-btn::after {
border: none;
background-color: none;
}
.imKefu-btn {
display: flex;
align-items: center;
position: relative;
display: block;
margin-left: auto;
margin-right: auto;
padding-left: 0px;
padding-right: 0px;
box-sizing: border-box;
text-decoration: none;
// line-height: 140rpx;
overflow: hidden;
color: #000000;
/* background-color: #fff; */
background: rgba(255, 255, 255, 0);
font-size: 22rpx;
width: 100rpx;
height: 150rpx;
}
.imKefu {
position: fixed;
right: 30rpx;
bottom: 200rpx;
width: 100rpx;
height: 150rpx;
z-index: 999999;
.imKefu-img {
width: 100rpx;
height: 100rpx;
}
.imKefu-txt {
width: 100rpx;
text-align: center;
color: #000000;
position: absolute;
bottom: 0;
font-size: 22rpx;
}
}
</style>

View File

@@ -0,0 +1,237 @@
/**
* 瀑布流组件
*/
<template>
<view>
<view class="list flex align-center justify-center">
<view class="list-box flex justify-between flex-wrap">
<!-- 左边数据 -->
<view class="list-box-ite">
<view @click="clickItem(item)" class="list-box-ite-item" v-for="(item,index) in arrListLeft"
:key="index">
<view class="list-box-ite-item-img">
<u-lazy-load border-radius="24rpx 24rpx 0 0" :image="item.titleImg"></u-lazy-load>
<view class="list-box-ite-item-img-t" v-if="item.over == 1">
{{item.courseDetailsCount?item.courseDetailsCount:0}}
</view>
<view class="list-box-ite-item-img-t" v-else>
更新至{{item.courseDetailsCount?item.courseDetailsCount:0}}
</view>
</view>
<view class="list-box-ite-item-txt">
<view class="list-box-ite-item-txt-t">
{{item.title}}
</view>
<view class="list-box-ite-item-txt-l" v-if="item.courseLabel">
{{item.courseLabel}}
</view>
</view>
</view>
</view>
<!-- 右边数据 -->
<view class="list-box-ite">
<view @click="clickItem(item)" class="list-box-ite-item" v-for="(item,index) in arrListRight"
:key="index">
<view class="list-box-ite-item-img">
<u-lazy-load border-radius="24rpx 24rpx 0 0" :image="item.titleImg"></u-lazy-load>
<view class="list-box-ite-item-img-t" v-if="item.over == 1">
{{item.courseDetailsCount?item.courseDetailsCount:0}}
</view>
<view class="list-box-ite-item-img-t" v-else>
更新至{{item.courseDetailsCount?item.courseDetailsCount:0}}
</view>
</view>
<view class="list-box-ite-item-txt">
<view class="list-box-ite-item-txt-t">
{{item.title}}
</view>
<view class="list-box-ite-item-txt-l" v-if="item.courseLabel">
{{item.courseLabel}}
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "videoList",
props: {
list: {
type: Array,
default: () => []
},
},
data() {
return {
arrListLeft: [], //左边数据
arrListRight: [], //右边数据
};
},
watch: {
list: {
handler() {
console.log(1111111)
this.spliceArrayListr()
},
deep: true,
}
},
created() {
this.spliceArrayListr()
},
methods: {
/**
* @param {Object} item
* 点击事件
*/
clickItem(item) {
this.$emit('success', item);
},
/**
* @param {Array} list 原数组
* @param {number} type 1:是从奇数开始2是从偶数开始
* 拆分数据
*/
spliceArrayListr() {
this.arrListRight = []
this.arrListLeft = []
this.list.map((item, index) => {
if (index % 2 === 0) {
this.arrListLeft.push(item)
} else {
this.arrListRight.push(item)
}
})
},
}
}
</script>
<style lang="scss">
.list {
width: 100%;
height: auto;
.list-box {
width: 686rpx;
height: 100%;
}
.list-box-ite {
width: calc((100% - 20rpx) / 2);
height: auto;
}
.list-box-ite-item {
width: 100%;
height: auto;
margin-bottom: 20rpx;
.list-box-ite-item-img {
width: 100%;
border-radius: 24rpx 24rpx 0 0;
min-height: 300rpx;
position: relative;
image {
width: 100%;
min-height: 300rpx;
border-radius: 24rpx 24rpx 0 0;
}
.list-box-ite-item-img-t {
position: absolute;
bottom: 10rpx;
right: 0;
max-width: 80%;
border-radius: 10rpx;
background-color: rgba(51, 51, 51, 0.7);
color: #FFFFFF;
font-size: 22rpx;
padding: 10rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.list-box-ite-item-txt {
padding: 10rpx 20rpx;
background-color: #ffffff;
border-radius: 0 0 24rpx 24rpx;
}
.list-box-ite-item-txt-t {
color: #333333;
font-size: 30rpx;
font-weight: bold;
}
.list-box-ite-item-txt-l {
color: #999999;
font-size: 22rpx;
margin-top: 10rpx;
}
}
.list-box-item {
width: calc((100% - 20rpx) / 2);
// height: 100%;
min-height: 320rpx;
border-radius: 24rpx;
background-color: #ffffff;
margin-bottom: 20rpx;
}
.list-box-item-img {
width: 100%;
height: 200rpx;
border-radius: 24rpx 24rpx 0 0;
image {
width: 100%;
height: 200rpx;
border-radius: 24rpx 24rpx 0 0;
}
}
.list-box-item-txt {
width: 100%;
// height: 120rpx;
padding: 20rpx 0;
border-radius: 0 0 24rpx 24rpx;
}
.list-box-item-txt-t {
width: 100%;
padding: 0 20rpx;
color: #333333;
font-size: 30rpx;
font-weight: bold;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.list-box-item-txt-l {
color: #999999;
font-size: 22rpx;
margin-top: 10rpx;
padding: 0 20rpx;
}
}
</style>