init
|
@ -0,0 +1,5 @@
|
|||
public
|
||||
dist
|
||||
package.json
|
||||
!.prettierrc.cjs
|
||||
env.d.ts
|
|
@ -0,0 +1,74 @@
|
|||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
node: true,
|
||||
},
|
||||
extends: [
|
||||
"plugin:vue/vue3-recommended",
|
||||
"standard",
|
||||
"@vue/prettier",
|
||||
"eslint:recommended",
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
},
|
||||
ignorePatterns: [
|
||||
"uni_modules/**/*",
|
||||
"hybrid/**/*",
|
||||
"static/**/*",
|
||||
"components/unitv-*/*",
|
||||
],
|
||||
plugins: ["vue"],
|
||||
rules: {
|
||||
"no-console": "warn",
|
||||
"vue/multi-word-component-names": "off",
|
||||
"vue/no-v-html": "off",
|
||||
"vue/require-default-prop": "off",
|
||||
camelcase: "off",
|
||||
eqeqeq: "error",
|
||||
"vue/no-template-shadow": "error",
|
||||
"vue/attribute-hyphenation": "error",
|
||||
"vue/html-end-tags": "error",
|
||||
"vue/eqeqeq": "error",
|
||||
"vue/component-name-in-template-casing": ["error", "kebab-case"],
|
||||
"vue/enforce-style-attribute": [
|
||||
"error",
|
||||
{ allow: ["scoped", "module", "plain"] },
|
||||
],
|
||||
"vue/v-on-event-hyphenation": [
|
||||
"error",
|
||||
"always",
|
||||
{
|
||||
autofix: true,
|
||||
},
|
||||
],
|
||||
"vue/require-explicit-emits": "error",
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{ vars: "all", args: "after-used", ignoreRestSiblings: false },
|
||||
],
|
||||
"linebreak-style": ["off", "windows"],
|
||||
"no-restricted-properties": [
|
||||
"error",
|
||||
{ object: "Object", property: "assign" },
|
||||
],
|
||||
"no-restricted-syntax": [
|
||||
"error",
|
||||
{
|
||||
selector: "VariableDeclarator[id.name='pd']",
|
||||
message: "不允许使用 pd,请改用有语义化的变量名",
|
||||
},
|
||||
{
|
||||
selector: "ObjectExpression > Property[key.name='pd']",
|
||||
message: "不允许使用 pd,请改用有语义化的变量名",
|
||||
},
|
||||
],
|
||||
},
|
||||
globals: {
|
||||
plus: "readonly",
|
||||
uni: "readonly",
|
||||
JSEncrypt: "readonly",
|
||||
},
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
unpackage
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.hbuilderx
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
|
@ -0,0 +1,4 @@
|
|||
module.exports = {
|
||||
extends: ["@vue/prettier", "plugin:prettier/recommended"],
|
||||
endOfLine: "crlf",
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
<script>
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
console.log("App Launch");
|
||||
// #ifdef APP-PLUS
|
||||
plus.screen.lockOrientation("landscape-primary"); // 锁定横屏
|
||||
plus.navigator.setFullscreen(true); // 隐藏状态栏(应用全屏:只能隐藏状态栏,标题栏和虚拟返回键都还可以显示)
|
||||
// #endif
|
||||
},
|
||||
onShow: function () {
|
||||
console.log("App Show");
|
||||
},
|
||||
onHide: function () {
|
||||
console.log("App Hide");
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "styles/common.scss";
|
||||
//::-webkit-scrollbar {
|
||||
// display: none;
|
||||
//}
|
||||
</style>
|
|
@ -0,0 +1 @@
|
|||
// import { post } from "@/utils/request.js";
|
|
@ -0,0 +1,150 @@
|
|||
<template>
|
||||
<view class="header">
|
||||
<view v-if="isShowUserInfo" class="left">
|
||||
<unitv-zone
|
||||
id="header_zone"
|
||||
class="header_zone"
|
||||
:down="down"
|
||||
:values="[0, 1]"
|
||||
:column="2"
|
||||
>
|
||||
<unitv-item
|
||||
:item="0"
|
||||
class="item"
|
||||
@click="fnNavigate('/pages/login/index')"
|
||||
>
|
||||
<view class="login_btn">登录</view>
|
||||
</unitv-item>
|
||||
<unitv-item
|
||||
:item="1"
|
||||
class="item user"
|
||||
@click="fnNavigate('/pages/mine/index')"
|
||||
>
|
||||
<view class="avatar">
|
||||
<image src="/static/avatar.png" />
|
||||
</view>
|
||||
<view>呀哈哈</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view>{{ time }}</view>
|
||||
<view class="logo">
|
||||
<image src="/static/logo.png" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
isShowUserInfo: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
down: {
|
||||
type: String,
|
||||
default: "tabs_zone",
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
time: "",
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.time = dayjs().format("HH:mm");
|
||||
setInterval(() => {
|
||||
this.time = dayjs().format("HH:mm");
|
||||
}, 1000);
|
||||
},
|
||||
methods: {
|
||||
fnNavigate(url) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.header {
|
||||
width: 100%;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
position: relative;
|
||||
z-index: 99;
|
||||
overflow: auto;
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
.header_zone {
|
||||
display: flex;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
border-radius: 34rpx;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
font-size: 12rpx;
|
||||
margin-left: 10rpx;
|
||||
|
||||
.login_btn {
|
||||
padding: 3rpx 15rpx;
|
||||
border-radius: 34rpx;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&.user {
|
||||
position: relative;
|
||||
border-radius: 11rpx;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
padding: 3rpx 10rpx 3rpx 30rpx;
|
||||
|
||||
.avatar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
border: 2rpx solid #070a26;
|
||||
border-radius: 50%;
|
||||
font-size: 0;
|
||||
|
||||
image {
|
||||
width: 19rpx;
|
||||
height: 19rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.hover {
|
||||
background-color: #254eff;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right;
|
||||
font-size: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
|
||||
.logo {
|
||||
margin-left: 26rpx;
|
||||
|
||||
image {
|
||||
width: 62rpx;
|
||||
height: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,33 @@
|
|||
<template>
|
||||
<view class="loading">
|
||||
<image
|
||||
src="/static/loading1000.gif"
|
||||
mode="aspectFit"
|
||||
:style="{ width, height }"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
width: {
|
||||
type: String,
|
||||
default: "100vw",
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: "100vh",
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.loading {
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
inset: 0;
|
||||
background-color: #1d1c37;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,116 @@
|
|||
<template>
|
||||
<view :id="id" :class="`${selected?selectClass:''} ${hovered?hoverClass:''}`">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapActions,
|
||||
mapState
|
||||
} from 'vuex';
|
||||
export default {
|
||||
name: "unitvPage",
|
||||
inject: ['pageId', 'zoneId', 'zoneState', 'zoneItems'],
|
||||
props: {
|
||||
item: {
|
||||
type: Number
|
||||
},
|
||||
hoverClass: {
|
||||
type: String,
|
||||
default: 'hover'
|
||||
},
|
||||
selectClass: {
|
||||
type: String,
|
||||
default: 'active'
|
||||
},
|
||||
isSelctByClick: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isSelect: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
updated() {
|
||||
this.zoneItems[this.item] = this;
|
||||
},
|
||||
created() {
|
||||
this.zoneItems[this.item] = this;
|
||||
this.selected=this.isSelect;
|
||||
},
|
||||
mounted() {
|
||||
if (this.zoneState.curZone && this.zoneState.curItem == this.item) {
|
||||
this.handleHover();
|
||||
this.refreshScroll();
|
||||
this.refreshState();
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selected: false,
|
||||
hovered: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['currentZone', 'currentPage']),
|
||||
id: function() {
|
||||
return this.zoneId + '_' + this.item;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clientRect(callback) {
|
||||
let view = uni.createSelectorQuery().in(this).select("#" + this.id);
|
||||
view.boundingClientRect(data => {
|
||||
callback(data);
|
||||
}).exec();
|
||||
},
|
||||
refreshScroll() {
|
||||
this.clientRect((clientRect) => {
|
||||
this.currentPage.RefreshScrollTop(clientRect);
|
||||
if (this.zoneState.curScroll != null) {
|
||||
this.zoneState.curScroll.RefreshScrollLeft(clientRect);
|
||||
}
|
||||
});
|
||||
},
|
||||
refreshState() {
|
||||
if (!this.isSelctByClick) {
|
||||
if (!this.zoneState.curZone && this.zoneState.curItem == this.item) {
|
||||
this.selected = true;
|
||||
} else {
|
||||
this.selected = false;
|
||||
}
|
||||
}
|
||||
if (this.zoneState.curZone && this.zoneState.curItem == this.item) {
|
||||
this.hovered = true;
|
||||
} else {
|
||||
this.hovered = false;
|
||||
}
|
||||
},
|
||||
handleHover() {
|
||||
this.$emit("hover", this.item);
|
||||
},
|
||||
handleClick() {
|
||||
if (this.isSelctByClick) {
|
||||
this.zoneItems.forEach(item => {
|
||||
item.selected = false
|
||||
})
|
||||
this.selected = true
|
||||
}
|
||||
this.$emit("click", this.item);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
hovered: function(newValue) {
|
||||
if (newValue != "") {
|
||||
this.handleHover();
|
||||
this.refreshScroll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -0,0 +1,222 @@
|
|||
<template>
|
||||
|
||||
<scroll-view v-show="current" scroll-y="true" :style="{height:windowHeight+'px'}" ref="page" :scroll-top="scrollTop"
|
||||
@scroll="scroll">
|
||||
<view @click="whole.onClick" id="onClick"></view>
|
||||
<slot></slot>
|
||||
</scroll-view>
|
||||
<!-- <unitv-transition :duration="500" :mode-class="['fade']" :styles="transfromClass" :show="current">
|
||||
</unitv-transition> -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapMutations,
|
||||
mapState
|
||||
} from 'vuex';
|
||||
export default {
|
||||
name: "unitvPage",
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
prePageId: {
|
||||
type: String
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
handleEvent: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
pageId: this.id,
|
||||
pageState: this.pageState
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.show) {
|
||||
this.switchPage(this);
|
||||
}
|
||||
uni.getSystemInfo({
|
||||
success: (res) => {
|
||||
this.windowHeight = res.windowHeight;
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.pushPage(this);
|
||||
},
|
||||
computed: {
|
||||
...mapState(['currentZone', 'currentPage', 'allPages']),
|
||||
current: function() {
|
||||
return this.currentPage == this;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
key: '',
|
||||
windowHeight: null,
|
||||
scrollTop: 0,
|
||||
old: {
|
||||
scrollTop: 0
|
||||
},
|
||||
Zone: [],
|
||||
pageState: {
|
||||
curZoneId: "",
|
||||
handleEvent: this.handleEvent
|
||||
},
|
||||
transfromClass: {
|
||||
'position': 'fixed',
|
||||
'bottom': 0,
|
||||
'top': 0,
|
||||
'left': 0,
|
||||
'right': 0,
|
||||
/* #ifndef APP-NVUE */
|
||||
'display': 'flex',
|
||||
/* #endif */
|
||||
'justify-content': 'center',
|
||||
'align-items': 'center'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['switchPage', 'switchZone', 'pushPage']),
|
||||
showPage() {
|
||||
this.switchPage(this);
|
||||
this.switchZone(this.Zone[this.pageState.curZoneId]);
|
||||
this.Zone[this.pageState.curZoneId].refreshItem();
|
||||
return true;
|
||||
},
|
||||
pushZone(zone) {
|
||||
this.Zone[zone.id] = zone;
|
||||
},
|
||||
keyCodeClick(keyCode) {
|
||||
this.key = keyCode;
|
||||
uni.$emit("keyDown", keyCode);
|
||||
switch (keyCode) {
|
||||
case 'KeyUp':
|
||||
this.evtArrow('up');
|
||||
break;
|
||||
case 'KeyDown':
|
||||
this.evtArrow('down');
|
||||
break;
|
||||
case 'KeyLeft':
|
||||
this.evtArrow('left');
|
||||
break;
|
||||
case 'KeyRight':
|
||||
this.evtArrow('right');
|
||||
break;
|
||||
case 'KeyEnter':
|
||||
this.evtEnter();
|
||||
break;
|
||||
case 'KeyBack':
|
||||
this.evtBack();
|
||||
break;
|
||||
};
|
||||
},
|
||||
evtArrow: function(Arrow) {
|
||||
var zone = this.currentZone;
|
||||
zone.evtArrow(Arrow);
|
||||
},
|
||||
evtEnter: function() {
|
||||
this.currentZone.evtEnter();
|
||||
},
|
||||
evtBack: function() {
|
||||
this.$emit("back");
|
||||
this.key = "KeyBack";
|
||||
},
|
||||
scroll: function(e) {
|
||||
this.old.scrollTop = e.detail.scrollTop
|
||||
},
|
||||
ChangeZone(zoneId) {
|
||||
var zone = this.Zone[zoneId];
|
||||
if (zone) {
|
||||
this.currentZone.zoneState.curZone = false;
|
||||
this.pageState.curZoneId = zoneId;
|
||||
zone.zoneState.curZone = true;
|
||||
this.switchZone(this.Zone[zoneId]);
|
||||
this.Zone[zoneId].refreshItem();
|
||||
}
|
||||
},
|
||||
RefreshScrollTop(clientRect) {
|
||||
var top = clientRect.top;
|
||||
if (top > 0) {
|
||||
top = clientRect.bottom;
|
||||
}
|
||||
if (top > this.windowHeight) {
|
||||
var top1 = this.old.scrollTop + (top - this.windowHeight + 10);
|
||||
this.scrollTop = top1
|
||||
} else if (top < 0) {
|
||||
this.scrollTop = this.old.scrollTop + (top - 20);
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
handleEvent: function(val) {
|
||||
this.pageState.handleEvent = val;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script module="whole" lang="renderjs">
|
||||
let code;
|
||||
let KeyName = {
|
||||
19: 'KeyUp',
|
||||
38: 'KeyUp', //Keyboard
|
||||
20: 'KeyDown',
|
||||
40: 'KeyDown', //Keyboard
|
||||
21: 'KeyLeft',
|
||||
37: 'KeyLeft', //Keyboard
|
||||
22: 'KeyRight',
|
||||
39: 'KeyRight', //Keyboard
|
||||
23: 'KeyEnter',
|
||||
13: 'KeyEnter', //Keyboard
|
||||
4: 'KeyBack',
|
||||
18: 'KeyBack', //Keyboard Alt键
|
||||
27: 'KeyBack', //Keyboard ESC
|
||||
24: 'KeyBack', //Keyboard ESC
|
||||
66: 'KeyEnter',
|
||||
111: 'KeyBack'
|
||||
};
|
||||
export default {
|
||||
mounted() {
|
||||
//全局监听按键输入
|
||||
window.document.onkeydown = function(evt) {
|
||||
evt = evt || window.event;
|
||||
var KeyCode = evt.which || evt.keyCode;
|
||||
code = KeyName[KeyCode];
|
||||
evt.preventDefault();
|
||||
if (code != undefined) {
|
||||
document.getElementById("onClick").click();
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
methods: {
|
||||
onClick(event, ownerInstance) {
|
||||
event.preventDefault();
|
||||
ownerInstance.callMethod('keyCodeClick', code);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.log-key-view {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
color: #FFFFFF;
|
||||
font-size: 20rpx;
|
||||
background: #007AFF;
|
||||
top: 0;
|
||||
z-index: 999;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,58 @@
|
|||
<template>
|
||||
<scroll-view :scroll-x="true" :scroll-left="scrollLeft" @scroll="scroll">
|
||||
<slot></slot>
|
||||
</scroll-view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
inject: ['pageId', 'zoneId', 'zoneState'],
|
||||
watch: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scrollLeft: 0,
|
||||
old: {
|
||||
scrollLeft: 0
|
||||
},
|
||||
windowWidth: null
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.zoneState.curScroll = this;
|
||||
uni.getSystemInfo({
|
||||
success: (res) => {
|
||||
this.windowWidth = res.windowWidth;
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
scroll: function(e) {
|
||||
this.$emit("scroll", {
|
||||
oldLeft: this.old.scrollLeft,
|
||||
left: e.detail.scrollLeft,
|
||||
})
|
||||
this.old.scrollLeft = e.detail.scrollLeft;
|
||||
|
||||
},
|
||||
RefreshScrollLeft(clientRect) {
|
||||
var left = clientRect.left;
|
||||
if (left > 0) {
|
||||
left = clientRect.right;
|
||||
}
|
||||
if (left > this.windowWidth) {
|
||||
var left1 = this.old.scrollLeft + (left - this.windowWidth + 360);
|
||||
this.scrollLeft = left1
|
||||
} else if (left < 0) {
|
||||
this.scrollLeft = this.old.scrollLeft + (left - 380);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,280 @@
|
|||
<template>
|
||||
<view v-if="isShow" ref="ani" class="uni-transition" :class="[ani.in]" :style="'transform:' +transform+';'+stylesObject"
|
||||
@click="change">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// #ifdef APP-NVUE
|
||||
const animation = uni.requireNativePlugin('animation');
|
||||
// #endif
|
||||
/**
|
||||
* Transition 过渡动画
|
||||
* @description 简单过渡动画组件
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=985
|
||||
* @property {Boolean} show = [false|true] 控制组件显示或隐藏
|
||||
* @property {Array} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
|
||||
* @value fade 渐隐渐出过渡
|
||||
* @value slide-top 由上至下过渡
|
||||
* @value slide-right 由右至左过渡
|
||||
* @value slide-bottom 由下至上过渡
|
||||
* @value slide-left 由左至右过渡
|
||||
* @value zoom-in 由小到大过渡
|
||||
* @value zoom-out 由大到小过渡
|
||||
* @property {Number} duration 过渡动画持续时间
|
||||
* @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
|
||||
*/
|
||||
export default {
|
||||
name: 'uniTransition',
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
modeClass: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 300
|
||||
},
|
||||
styles: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isShow: false,
|
||||
transform: '',
|
||||
ani: { in: '',
|
||||
active: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(newVal) {
|
||||
if (newVal) {
|
||||
this.open()
|
||||
} else {
|
||||
this.close()
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
stylesObject() {
|
||||
let styles = {
|
||||
...this.styles,
|
||||
'transition-duration': this.duration / 1000 + 's'
|
||||
}
|
||||
let transfrom = ''
|
||||
for (let i in styles) {
|
||||
let line = this.toLine(i)
|
||||
transfrom += line + ':' + styles[i] + ';'
|
||||
}
|
||||
return transfrom
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// this.timer = null
|
||||
// this.nextTick = (time = 50) => new Promise(resolve => {
|
||||
// clearTimeout(this.timer)
|
||||
// this.timer = setTimeout(resolve, time)
|
||||
// return this.timer
|
||||
// });
|
||||
},
|
||||
methods: {
|
||||
change() {
|
||||
this.$emit('click', {
|
||||
detail: this.isShow
|
||||
})
|
||||
},
|
||||
open() {
|
||||
clearTimeout(this.timer)
|
||||
this.isShow = true
|
||||
this.transform = ''
|
||||
this.ani.in = ''
|
||||
for (let i in this.getTranfrom(false)) {
|
||||
if (i === 'opacity') {
|
||||
this.ani.in = 'fade-in'
|
||||
} else {
|
||||
this.transform += `${this.getTranfrom(false)[i]} `
|
||||
}
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this._animation(true)
|
||||
}, 50)
|
||||
})
|
||||
|
||||
},
|
||||
close(type) {
|
||||
clearTimeout(this.timer)
|
||||
this._animation(false)
|
||||
},
|
||||
_animation(type) {
|
||||
let styles = this.getTranfrom(type)
|
||||
// #ifdef APP-NVUE
|
||||
if(!this.$refs['ani']) return
|
||||
animation.transition(this.$refs['ani'].ref, {
|
||||
styles,
|
||||
duration: this.duration, //ms
|
||||
timingFunction: 'ease',
|
||||
needLayout: false,
|
||||
delay: 0 //ms
|
||||
}, () => {
|
||||
if (!type) {
|
||||
this.isShow = false
|
||||
}
|
||||
this.$emit('change', {
|
||||
detail: this.isShow
|
||||
})
|
||||
})
|
||||
// #endif
|
||||
// #ifndef APP-NVUE
|
||||
this.transform = ''
|
||||
for (let i in styles) {
|
||||
if (i === 'opacity') {
|
||||
this.ani.in = `fade-${type?'out':'in'}`
|
||||
} else {
|
||||
this.transform += `${styles[i]} `
|
||||
}
|
||||
}
|
||||
this.timer = setTimeout(() => {
|
||||
if (!type) {
|
||||
this.isShow = false
|
||||
}
|
||||
this.$emit('change', {
|
||||
detail: this.isShow
|
||||
})
|
||||
|
||||
}, this.duration)
|
||||
// #endif
|
||||
|
||||
},
|
||||
getTranfrom(type) {
|
||||
let styles = {
|
||||
transform: ''
|
||||
}
|
||||
this.modeClass.forEach((mode) => {
|
||||
switch (mode) {
|
||||
case 'fade':
|
||||
styles.opacity = type ? 1 : 0
|
||||
break;
|
||||
case 'slide-top':
|
||||
styles.transform += `translateY(${type?'0':'-100%'}) `
|
||||
break;
|
||||
case 'slide-right':
|
||||
styles.transform += `translateX(${type?'0':'100%'}) `
|
||||
break;
|
||||
case 'slide-bottom':
|
||||
styles.transform += `translateY(${type?'0':'100%'}) `
|
||||
break;
|
||||
case 'slide-left':
|
||||
styles.transform += `translateX(${type?'0':'-100%'}) `
|
||||
break;
|
||||
case 'zoom-in':
|
||||
styles.transform += `scale(${type?1:0.8}) `
|
||||
break;
|
||||
case 'zoom-out':
|
||||
styles.transform += `scale(${type?1:1.2}) `
|
||||
break;
|
||||
}
|
||||
})
|
||||
return styles
|
||||
},
|
||||
_modeClassArr(type) {
|
||||
let mode = this.modeClass
|
||||
if (typeof(mode) !== "string") {
|
||||
let modestr = ''
|
||||
mode.forEach((item) => {
|
||||
modestr += (item + '-' + type + ',')
|
||||
})
|
||||
return modestr.substr(0, modestr.length - 1)
|
||||
} else {
|
||||
return mode + '-' + type
|
||||
}
|
||||
},
|
||||
// getEl(el) {
|
||||
// console.log(el || el.ref || null);
|
||||
// return el || el.ref || null
|
||||
// },
|
||||
toLine(name) {
|
||||
return name.replace(/([A-Z])/g, "-$1").toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-transition {
|
||||
transition-timing-function: ease;
|
||||
transition-duration: 0.3s;
|
||||
transition-property: transform, opacity;
|
||||
z-index: 998;
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.fade-active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.slide-top-in {
|
||||
/* transition-property: transform, opacity; */
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.slide-top-active {
|
||||
transform: translateY(0);
|
||||
/* opacity: 1; */
|
||||
}
|
||||
|
||||
.slide-right-in {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
.slide-right-active {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.slide-bottom-in {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
.slide-bottom-active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.slide-left-in {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.slide-left-active {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.zoom-in-in {
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
.zoom-out-active {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.zoom-out-in {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,147 @@
|
|||
<template>
|
||||
<video id="player" :class="clazz" :src="src" :autoplay="autoplay" :initial-time="initialTime" :enable-play-gesture="false" :title="title"
|
||||
:enable-progress-gesture="false" :show-center-play-btn="false" :show-fullscreen-btn="false" :show-progress="true" @play="status=1"
|
||||
@pause="status=0" @timeupdate="timeupdate" @fullscreenchange="fullscreenchange" :poster="pauseImg"
|
||||
@ended="$emit('ended')" @error="errorFun" width="100%" height="100%" style="width: 100%;height: 100%;">
|
||||
<cover-image src="../../static/loading_1920.gif" class="loading_box" v-if="isSHowLoading"
|
||||
:play-strategy="2"></cover-image>
|
||||
</video>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
inject: ['pageId', 'pageState'],
|
||||
watch: {
|
||||
|
||||
},
|
||||
props: {
|
||||
clazz: {
|
||||
type: String
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
src: {
|
||||
type: String
|
||||
},
|
||||
autoplay: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showProgress: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isSHowLoading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
pauseImg: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
failStatus: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
initialTime: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
status: 0,
|
||||
currentTime: 0,
|
||||
fullScreen: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.viderContext = uni.createVideoContext("player", this);
|
||||
},
|
||||
onLoad() {
|
||||
uni.$on('keyDown', this.keyDownFun);
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('keyDown', this.keyDownFun);
|
||||
},
|
||||
methods: {
|
||||
keyDownFun(data) {
|
||||
console.log("keyDownFun")
|
||||
this.keyDown(data);
|
||||
},
|
||||
keyDown(Arrow) {
|
||||
console.log("监测到按键:" + Arrow)
|
||||
switch (Arrow) {
|
||||
case 'KeyLeft': {
|
||||
var time = parseInt(this.currentTime - 15, 10);
|
||||
this.viderContext.seek(time < 0 ? 0 : time)
|
||||
}
|
||||
break;
|
||||
case 'KeyRight': {
|
||||
var time = parseInt(this.currentTime + 15, 10);
|
||||
this.viderContext.seek(time);
|
||||
}
|
||||
break;
|
||||
case 'KeyEnter': {
|
||||
this.clickVideo();
|
||||
}
|
||||
break;
|
||||
};
|
||||
},
|
||||
clickVideo() {
|
||||
if (this.status) {
|
||||
this.viderContext.pause();
|
||||
this.viderContext.showStatusBar();
|
||||
} else {
|
||||
this.viderContext.play();
|
||||
this.viderContext.hideStatusBar();
|
||||
}
|
||||
},
|
||||
timeupdate: function(e) {
|
||||
this.currentTime = e.detail.currentTime;
|
||||
this.$emit("timeupdate", e.detail.currentTime)
|
||||
},
|
||||
fullscreenchange: function(e) {
|
||||
this.fullScreen = e.detail.fullScreen;
|
||||
this.pageState.handleEvent = e.detail.fullScreen;
|
||||
uni.$off('keyDown', this.keyDownFun);
|
||||
if (this.fullScreen) {
|
||||
this.viderContext.play();
|
||||
uni.$on('keyDown', this.keyDownFun);
|
||||
}
|
||||
this.$emit("fullscreenchange", e.detail.fullScreen)
|
||||
},
|
||||
errorFun() {
|
||||
this.$emit("errorFun")
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.controls-play.img {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 50%;
|
||||
left: 0%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.loading_box {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
z-index: 100;
|
||||
|
||||
}
|
||||
|
||||
.fail_img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,255 @@
|
|||
<template>
|
||||
<view :id="id">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapMutations,
|
||||
mapActions,
|
||||
mapState
|
||||
} from 'vuex';
|
||||
export default {
|
||||
name: "unitvZone",
|
||||
inject: ['pageId', 'pageState'],
|
||||
props: {
|
||||
id: { // Zone Id
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
up: { // Zone切换时上一Zone Id
|
||||
type: String
|
||||
},
|
||||
down: { // Zone切换时下一Zone Id
|
||||
type: String
|
||||
},
|
||||
left: { // Zone切换时左一Zone Id
|
||||
type: String
|
||||
},
|
||||
right: { // Zone切换时右一Zone Id
|
||||
type: String
|
||||
},
|
||||
item: { // Zone当前焦点item索引
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
prevZone: { // Zone改变后的上一个Zone Id
|
||||
type: String
|
||||
},
|
||||
row: { // Zone的item总行数
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
column: { // Zone的item总列数
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
defaultBehavior: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
autoFous: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
values: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
count: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
zoneId: this.id,
|
||||
zoneState: this.zoneState,
|
||||
zoneItems: this.items
|
||||
}
|
||||
},
|
||||
created() {
|
||||
//console.log(this.pageId)
|
||||
if (this.autoFous) {
|
||||
this.pageState.curZoneId = this.id;
|
||||
this.zoneState.curZone = true;
|
||||
this.focus = true;
|
||||
this.switchZone(this);
|
||||
}
|
||||
this._switchItem(this.item);
|
||||
this.currentPage.pushZone(this);
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
computed: {
|
||||
...mapState(['currentZone', 'currentPage']),
|
||||
size: function() {
|
||||
if (this.count != 0) {
|
||||
return this.count;
|
||||
} else if (this.values.length != 0) {
|
||||
return this.values.length;
|
||||
} else {
|
||||
return this.items.length;
|
||||
}
|
||||
},
|
||||
rows: function() {
|
||||
if (this.row > 1) {
|
||||
return this.row;
|
||||
}
|
||||
return Math.ceil(this.size / this.column)
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
citem: 0,
|
||||
crow: 0, // Zone的当前行
|
||||
prevItem: 0, // item改变后的上一item索引
|
||||
focus: false,
|
||||
items: [], // Zone的所有item数组集合
|
||||
zoneState: {
|
||||
curItem: this.citem,
|
||||
curZone: this.focus,
|
||||
curScroll: null
|
||||
},
|
||||
StepSeq: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['switchZone']),
|
||||
_switchItem: function(item, oldItem) {
|
||||
this.citem = item;
|
||||
this.zoneState.curItem = item;
|
||||
try {
|
||||
this.refreshItem();
|
||||
if (oldItem != undefined) {
|
||||
this.items[oldItem].refreshState();
|
||||
}
|
||||
} catch (e) {}
|
||||
},
|
||||
refreshItem: function() {
|
||||
this.items[this.citem].refreshState();
|
||||
},
|
||||
evtArrow: function(Arrow) {
|
||||
var self = this;
|
||||
//this._switchItem(this.citem+1);
|
||||
var oldItem = this.citem || 0;
|
||||
var item = this.citem || 0;
|
||||
var steps = this.rows * this.column;
|
||||
var Row = Math.floor(item / this.column);
|
||||
var Border = this[Arrow];
|
||||
var cRow = this.crow;
|
||||
switch (Arrow) {
|
||||
case 'left':
|
||||
item -= 1;
|
||||
if (Math.floor(item / this.column) != Row) {
|
||||
item = item - steps;
|
||||
}
|
||||
break;
|
||||
case 'right':
|
||||
item += 1;
|
||||
if (Math.floor(item / this.column) != Row) {
|
||||
item = item + steps;
|
||||
}
|
||||
break;
|
||||
case 'up':
|
||||
item -= this.column;
|
||||
this.crow = cRow - 1;
|
||||
break;
|
||||
case 'down':
|
||||
item += this.column
|
||||
this.crow = cRow + 1;
|
||||
if (item >= this.size - 1 && this.crow === this.rows - 1) {
|
||||
item = this.size - 1
|
||||
}
|
||||
|
||||
break;
|
||||
};
|
||||
if (item >= 0 && item <= this.size - 1) {
|
||||
if (item + this.StepSeq * steps + 1 > this.size) {
|
||||
item = this.size - this.StepSeq * steps - 1;
|
||||
}
|
||||
this.citem = item;
|
||||
this._switchItem(this.citem, oldItem);
|
||||
if (this.crow === (this.rows - 1)) {
|
||||
this.$emit("scrolltolower");
|
||||
}
|
||||
} else {
|
||||
this.crow = cRow;
|
||||
OverBorder();
|
||||
};
|
||||
|
||||
function OverBorder() {
|
||||
if (Border) {
|
||||
if (Border === self.id) {
|
||||
ScrollItem();
|
||||
} else {
|
||||
ChangeZone();
|
||||
}
|
||||
};
|
||||
|
||||
function ScrollItem() {
|
||||
switch (Arrow) {
|
||||
case 'up':
|
||||
item = self.citem + self.column * (self.rows - 1);
|
||||
self.crow = self.rows - 1;
|
||||
break
|
||||
case 'down':
|
||||
item = self.citem - self.column * (self.rows - 1);
|
||||
self.crow = 0;
|
||||
break
|
||||
case 'left':
|
||||
item = (Row + 1) * self.column - 1;
|
||||
break
|
||||
case 'right':
|
||||
item = Row * self.column;
|
||||
break
|
||||
};
|
||||
//当前焦点区域对应的数值的个数超过一屏的显示个数,产生翻页效果
|
||||
if (self.size > steps) {
|
||||
self.StepSeq = self.StepSeq || 0;
|
||||
var MaxSeq = Math.ceil(self.size / steps) - 1;
|
||||
if ((Arrow === 'left') || (Arrow === 'up')) {
|
||||
//左键或者上键,往前翻
|
||||
self.StepSeq = (self.StepSeq > 0) ? self.StepSeq - 1 : MaxSeq;
|
||||
} else if ((Arrow === 'right') || (Arrow === 'down')) {
|
||||
//右键或者下键,往后翻
|
||||
self.StepSeq = (self.StepSeq < MaxSeq) ? self.StepSeq + 1 : 0;
|
||||
};
|
||||
};
|
||||
//数值个数不够时,光标定位在第一个上面
|
||||
if (item + self.StepSeq * steps + 1 > self.size) {
|
||||
item = 0;
|
||||
}
|
||||
self.citem = item;
|
||||
//执行用户定义函数
|
||||
self._switchItem(self.citem, oldItem);
|
||||
};
|
||||
|
||||
function ChangeZone() {
|
||||
self.currentPage.ChangeZone(Border);
|
||||
self.refreshItem();
|
||||
self.$emit("swtichZone", self.zoneState)
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
},
|
||||
evtEnter: function() {
|
||||
var itemObj = this.items[this.citem];
|
||||
if (itemObj) {
|
||||
itemObj.handleClick();
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
values: function(newVal, oldVal) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
<title></title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,30 @@
|
|||
import App from "./App";
|
||||
import store from "@/store/index.js";
|
||||
import "dayjs/locale/zh-cn";
|
||||
// #ifndef VUE3
|
||||
import Vue from "vue";
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
import { createSSRApp } from "vue";
|
||||
// #endif
|
||||
|
||||
// #ifndef VUE3
|
||||
Vue.config.productionTip = false;
|
||||
App.mpType = "app";
|
||||
const app = new Vue({
|
||||
...App,
|
||||
store,
|
||||
});
|
||||
app.$mount();
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App);
|
||||
app.use(store);
|
||||
return {
|
||||
app,
|
||||
};
|
||||
}
|
||||
|
||||
// #endif
|
|
@ -0,0 +1,124 @@
|
|||
{
|
||||
"name" : "金安铸云",
|
||||
"appid" : "__UNI__9209C12",
|
||||
"description" : "",
|
||||
"versionName" : "1.0.1",
|
||||
"versionCode" : "101",
|
||||
"transformPx" : false,
|
||||
/* 5+App特有相关 */
|
||||
"app-plus" : {
|
||||
"orientation" : [ "landscape-primary" ],
|
||||
"usingComponents" : true,
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"nvueCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
/* 模块配置 */
|
||||
"modules" : {
|
||||
"VideoPlayer" : {}
|
||||
},
|
||||
/* 应用发布信息 */
|
||||
"distribute" : {
|
||||
/* android打包配置 */
|
||||
"android" : {
|
||||
"permissions" : [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
],
|
||||
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ],
|
||||
"targetSdkVersion" : 28
|
||||
},
|
||||
/* ios打包配置 */
|
||||
"ios" : {
|
||||
"dSYMs" : false
|
||||
},
|
||||
/* SDK配置 */
|
||||
"sdkConfigs" : {
|
||||
"ad" : {}
|
||||
},
|
||||
"icons" : {
|
||||
"android" : {
|
||||
"hdpi" : "unpackage/res/icons/72x72.png",
|
||||
"xhdpi" : "unpackage/res/icons/96x96.png",
|
||||
"xxhdpi" : "unpackage/res/icons/144x144.png",
|
||||
"xxxhdpi" : "unpackage/res/icons/192x192.png"
|
||||
},
|
||||
"ios" : {
|
||||
"appstore" : "unpackage/res/icons/1024x1024.png",
|
||||
"ipad" : {
|
||||
"app" : "unpackage/res/icons/76x76.png",
|
||||
"app@2x" : "unpackage/res/icons/152x152.png",
|
||||
"notification" : "unpackage/res/icons/20x20.png",
|
||||
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||
"proapp@2x" : "unpackage/res/icons/167x167.png",
|
||||
"settings" : "unpackage/res/icons/29x29.png",
|
||||
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||
"spotlight" : "unpackage/res/icons/40x40.png",
|
||||
"spotlight@2x" : "unpackage/res/icons/80x80.png"
|
||||
},
|
||||
"iphone" : {
|
||||
"app@2x" : "unpackage/res/icons/120x120.png",
|
||||
"app@3x" : "unpackage/res/icons/180x180.png",
|
||||
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||
"notification@3x" : "unpackage/res/icons/60x60.png",
|
||||
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||
"settings@3x" : "unpackage/res/icons/87x87.png",
|
||||
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||
"spotlight@3x" : "unpackage/res/icons/120x120.png"
|
||||
}
|
||||
}
|
||||
},
|
||||
"splashscreen" : {
|
||||
"androidStyle" : "default",
|
||||
"android" : {
|
||||
"hdpi" : "static/bg.9.png",
|
||||
"xhdpi" : "static/bg.9.png",
|
||||
"xxhdpi" : "static/bg.9.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 快应用特有相关 */
|
||||
"quickapp" : {},
|
||||
/* 小程序特有相关 */
|
||||
"mp-weixin" : {
|
||||
"appid" : "",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : false
|
||||
},
|
||||
"vueVersion" : "2",
|
||||
"fallbackLocale" : "zh-Hans",
|
||||
"locale" : "zh-Hans"
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"dayjs": "^1.11.13",
|
||||
"uqrcodejs": "^4.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/html5plus": "^1.0.5",
|
||||
"@types/uni-app": "^1.4.8",
|
||||
"@vue/eslint-config-prettier": "^7.1.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-config-standard": "^17.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-n": "^15.7.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"eslint-plugin-vue": "^9.19.2",
|
||||
"prettier": "^2.8.8",
|
||||
"vue-eslint-parser": "^9.3.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
{
|
||||
"easycom": {
|
||||
"autoscan": true,
|
||||
"custom": {
|
||||
"unitv-(.*)" : "@/components/unitv-$1/unitv-$1.vue",
|
||||
"app-(.*)" : "@/components/app-$1/index.vue"
|
||||
}
|
||||
},
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "首页"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/login/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "登录"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/curriculum/details",
|
||||
"style": {
|
||||
"navigationBarTitleText": "课程详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/curriculum/play",
|
||||
"style": {
|
||||
"navigationBarTitleText": "视频播放"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/curriculum/buy",
|
||||
"style": {
|
||||
"navigationBarTitleText": "课程购买"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/curriculum/buy_success",
|
||||
"style": {
|
||||
"navigationBarTitleText": "购买成功"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/curriculum/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的课程"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationStyle": "custom",//去掉导航栏
|
||||
"rpxCalcMaxDeviceWidth": 2560, // rpx 计算所支持的最大设备宽度,单位 px,默认值为 960
|
||||
"rpxCalcBaseDeviceWidth": 1920, // rpx 计算使用的基准设备宽度,设备实际宽度超出 rpx 计算所支持的最大设备宽度时将按基准宽度计算,单位 px,默认值为 375
|
||||
"rpxCalcIncludeWidth": 2560 // rpx 计算特殊处理的值,始终按实际的设备宽度计算,单位 rpx,默认值为 750
|
||||
},
|
||||
"uniIdRouter": {}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<unitv-page
|
||||
id="curriculumBuyPage"
|
||||
ref="curriculumBuyPage"
|
||||
class="curriculumBuyPage"
|
||||
:show="true"
|
||||
>
|
||||
<app-header />
|
||||
<view class="content">
|
||||
<view class="left">
|
||||
<view class="shop">
|
||||
<image src="/static/public_images/video_bg1.jpg" />
|
||||
<view class="name line-4">
|
||||
课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称课程名称
|
||||
</view>
|
||||
</view>
|
||||
<view class="money">
|
||||
<view class="price">¥123</view>
|
||||
<view class="tip">购买此课程</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="qrcode">
|
||||
<view class="image">
|
||||
<view class="payee">收款方:河北秦安安全科技有限公司</view>
|
||||
<canvas
|
||||
id="qrcode"
|
||||
canvas-id="qrcode"
|
||||
:style="{ width: canvasSize + 'px', height: canvasSize + 'px' }"
|
||||
/>
|
||||
<view class="tip">使用微信扫一扫支付</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</unitv-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UQRCode from "uqrcodejs";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
canvasSize: uni.upx2px(170),
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
if (this.$refs.curriculumBuyPage) {
|
||||
this.$refs.curriculumBuyPage.showPage();
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
const qr = new UQRCode();
|
||||
qr.data = "qrcode_url";
|
||||
qr.size = this.canvasSize;
|
||||
qr.make();
|
||||
qr.canvasContext = uni.createCanvasContext("qrcode");
|
||||
qr.drawCanvas();
|
||||
// setTimeout(() => {
|
||||
// uni.navigateTo({
|
||||
// url: "/pages/curriculum/buy_success",
|
||||
// });
|
||||
// }, 10000);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 61rpx 77rpx 54rpx 45rpx;
|
||||
|
||||
.left {
|
||||
width: 355rpx;
|
||||
|
||||
.shop {
|
||||
width: 355rpx;
|
||||
height: 124rpx;
|
||||
background-image: url("/static/by_shop_bg.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
display: flex;
|
||||
padding: 24rpx 12rpx;
|
||||
|
||||
image {
|
||||
width: 133rpx;
|
||||
height: 75rpx;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.name {
|
||||
flex: 1;
|
||||
font-size: 14rpx;
|
||||
padding-left: 12rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.money {
|
||||
margin-top: 10rpx;
|
||||
width: 355rpx;
|
||||
height: 54rpx;
|
||||
background-image: url("/static/by_shop_money_bg.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
position: relative;
|
||||
color: rgba(115, 62, 2, 1);
|
||||
font-weight: bold;
|
||||
|
||||
.price {
|
||||
font-size: 24rpx;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
left: 17rpx;
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 14rpx;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
left: 121rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
margin-left: 43rpx;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.17);
|
||||
border-radius: 4px;
|
||||
padding: 12rpx;
|
||||
|
||||
.image {
|
||||
background-color: #fff;
|
||||
padding: 12rpx;
|
||||
color: #000;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.payee {
|
||||
padding-bottom: 6rpx;
|
||||
font-size: 9rpx;
|
||||
}
|
||||
|
||||
.tip {
|
||||
padding-top: 7rpx;
|
||||
color: rgba(7, 15, 48, 1);
|
||||
font-size: 13rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,105 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<unitv-page
|
||||
id="curriculumBuySuccessPage"
|
||||
ref="curriculumBuySuccessPage"
|
||||
class="curriculumBuySuccessPage"
|
||||
:show="true"
|
||||
>
|
||||
<app-header down="curriculum_buy_success_first_zone" />
|
||||
<view class="content">
|
||||
<view class="image">
|
||||
<image src="/static/buy_success.png" />
|
||||
</view>
|
||||
<view class="tip">订单支付成功!请在我的课程中查看</view>
|
||||
<view class="info">
|
||||
<view>订单编号:20241028153636598755</view>
|
||||
<view>订单名称:安全视频 消防安全基础知识培训课程</view>
|
||||
<view>订单时间:2024-10-28 15:06</view>
|
||||
<view>订单价格:365元</view>
|
||||
</view>
|
||||
<unitv-zone
|
||||
id="curriculum_buy_success_first_zone"
|
||||
class="curriculum_buy_success_first_zone"
|
||||
up="header_zone"
|
||||
:values="[0]"
|
||||
:column="1"
|
||||
auto-fous
|
||||
:item="0"
|
||||
>
|
||||
<unitv-item :item="0" class="item">
|
||||
<view class="text">我的课程</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
</unitv-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
onShow() {
|
||||
if (this.$refs.curriculumBuySuccessPage) {
|
||||
this.$refs.curriculumBuySuccessPage.showPage();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
.content {
|
||||
width: 400rpx;
|
||||
margin: 29rpx auto auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.image {
|
||||
width: 113rpx;
|
||||
height: 116rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 12rpx;
|
||||
}
|
||||
|
||||
.info {
|
||||
padding: 18rpx 100rpx 16rpx 18rpx;
|
||||
margin-top: 25rpx;
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 4rpx;
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.1);
|
||||
|
||||
view {
|
||||
margin-top: 5rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.curriculum_buy_success_first_zone {
|
||||
margin-top: 15rpx;
|
||||
|
||||
.item {
|
||||
background-color: rgba(37, 78, 255, 1);
|
||||
border-radius: 2rpx;
|
||||
width: 190rpx;
|
||||
height: 38rpx;
|
||||
font-size: 14rpx;
|
||||
text-align: center;
|
||||
line-height: 38rpx;
|
||||
border: 2rpx solid transparent;
|
||||
|
||||
&.hover {
|
||||
border: 2rpx solid rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,52 @@
|
|||
export default [
|
||||
{
|
||||
name: "基础知识",
|
||||
nodes: [
|
||||
{
|
||||
coursewareName: "气体基础知识",
|
||||
url: "https://video.qhdsafety.com/sv/5b72c64c-192e53dc244/5b72c64c-192e53dc244.mp4",
|
||||
},
|
||||
{
|
||||
coursewareName: "现场一线员工全面安全培训",
|
||||
url: "https://video.qhdsafety.com/sv/5eeb67f3-192e099ebba/5eeb67f3-192e099ebba.mp4",
|
||||
},
|
||||
{
|
||||
coursewareName: "出差人员基础安全知识与应急处置",
|
||||
url: "https://video.qhdsafety.com/sv/40c0369f-192e099692d/40c0369f-192e099692d.mp4",
|
||||
},
|
||||
{
|
||||
coursewareName: "现场安全负责人全面安全培训",
|
||||
url: "https://video.qhdsafety.com/sv/6b9ef0b-192e098bf81/6b9ef0b-192e098bf81.mp4",
|
||||
},
|
||||
{
|
||||
coursewareName: "危险货物运输包装-气瓶",
|
||||
url: "https://video.qhdsafety.com/sv/a5a0ad5-192e06394c6/a5a0ad5-192e06394c6.mp4",
|
||||
},
|
||||
{
|
||||
coursewareName: "职业病危害专项治理",
|
||||
url: "https://video.qhdsafety.com/sv/5714ae67-1930b695a05/5714ae67-1930b695a05.mp4",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "安全生产条例",
|
||||
nodes: [
|
||||
{
|
||||
coursewareName: "《四川省安全生产条例》特色解读",
|
||||
url: "https://video.qhdsafety.com/sv/478dfce2-192e08e3216/478dfce2-192e08e3216.mp4",
|
||||
},
|
||||
{
|
||||
coursewareName: "企业贯彻落实《四川省安全生产条例》精要",
|
||||
url: "https://video.qhdsafety.com/sv/4289cf05-192e08cdd4d/4289cf05-192e08cdd4d.mp4",
|
||||
},
|
||||
{
|
||||
coursewareName: "《四川省安全生产举报奖励办法》解读",
|
||||
url: "https://video.qhdsafety.com/sv/1ebad0e6-192e08b8700/1ebad0e6-192e08b8700.mp4",
|
||||
},
|
||||
{
|
||||
coursewareName: "应急管理部关于进一步加强安全生产举报工作的指导意见",
|
||||
url: "https://video.qhdsafety.com/sv/1c845c96-192e08a5b4b/1c845c96-192e08a5b4b.mp4",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
|
@ -0,0 +1,522 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<unitv-page
|
||||
id="curriculumDetailsPage"
|
||||
ref="curriculumDetailsPage"
|
||||
class="curriculumDetailsPage"
|
||||
:show="true"
|
||||
>
|
||||
<app-header down="curriculum_details_first_zone" />
|
||||
<view class="curriculumInfo">
|
||||
<view class="info">
|
||||
<view class="curriculumName">
|
||||
{{ curriculumInfo.curriculumName }}
|
||||
</view>
|
||||
<view class="introduction line-3">
|
||||
{{ curriculumInfo.introduction }}
|
||||
</view>
|
||||
<unitv-zone
|
||||
id="curriculum_details_first_zone"
|
||||
class="curriculum_details_first_zone"
|
||||
up="header_zone"
|
||||
down="curriculum_details_second_zone"
|
||||
:values="[0, 1]"
|
||||
:column="2"
|
||||
>
|
||||
<unitv-item :item="0" class="item trySee" @click="fnFullScreen">
|
||||
<view class="icon">
|
||||
<image src="/static/bofang.png" />
|
||||
</view>
|
||||
<view class="text">全屏试看</view>
|
||||
</unitv-item>
|
||||
<unitv-item :item="1" class="item buy" @click="fnBuy">
|
||||
<view class="price">¥{{ curriculumInfo.price }}</view>
|
||||
<view class="text">购买课程</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
<view v-if="!video.url" class="cover">
|
||||
<image :src="curriculumInfo.cover" mode="widthFix" />
|
||||
</view>
|
||||
<view v-if="video.url && !isFullScreen" class="cover">
|
||||
<unitv-video
|
||||
id="player"
|
||||
:src="video.url"
|
||||
:title="video.title"
|
||||
:initial-time="video.time"
|
||||
@timeupdate="fnTimeupdate"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="chapter">
|
||||
<view class="main_title">
|
||||
<text>章节</text>
|
||||
<text class="current">{{ currentChapterInfo.name }}</text>
|
||||
</view>
|
||||
<unitv-zone
|
||||
id="curriculum_details_second_zone"
|
||||
:key="currentChapterIndex"
|
||||
class="curriculum_details_second_zone"
|
||||
up="curriculum_details_first_zone"
|
||||
down="curriculum_details_third_zone"
|
||||
:values="currentChapterInfo.nodes"
|
||||
:column="currentChapterInfo.nodes.length"
|
||||
>
|
||||
<unitv-scroll>
|
||||
<view class="scroll">
|
||||
<unitv-item
|
||||
v-for="(item, index) in currentChapterInfo.nodes"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnPlayVideo(item)"
|
||||
>
|
||||
<view class="text">{{ item.coursewareName }}</view>
|
||||
</unitv-item>
|
||||
</view>
|
||||
</unitv-scroll>
|
||||
</unitv-zone>
|
||||
<unitv-zone
|
||||
id="curriculum_details_third_zone"
|
||||
class="curriculum_details_third_zone"
|
||||
up="curriculum_details_second_zone"
|
||||
down="curriculum_details_fourth_zone"
|
||||
:values="chapterList"
|
||||
:column="chapterList.length"
|
||||
auto-fous
|
||||
:item="0"
|
||||
>
|
||||
<unitv-scroll>
|
||||
<view class="scroll">
|
||||
<unitv-item
|
||||
v-for="(item, index) in chapterList"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnClickChapterItem"
|
||||
>
|
||||
<view class="text">{{ item.name }}</view>
|
||||
<view
|
||||
v-if="index !== chapterList.length - 1"
|
||||
class="border_right"
|
||||
/>
|
||||
<view class="border_bottom" />
|
||||
</unitv-item>
|
||||
</view>
|
||||
</unitv-scroll>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
<view class="recommend_curriculum">
|
||||
<view class="main_title">为你推荐</view>
|
||||
<unitv-zone
|
||||
id="curriculum_details_fourth_zone"
|
||||
class="curriculum_details_fourth_zone"
|
||||
up="curriculum_details_third_zone"
|
||||
:values="recommendCurriculumList"
|
||||
:column="recommendCurriculumList.length"
|
||||
>
|
||||
<unitv-scroll>
|
||||
<view class="scroll">
|
||||
<unitv-item
|
||||
v-for="(item, index) in recommendCurriculumList"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnSwitchCurriculum"
|
||||
>
|
||||
<image :src="item.img" mode="widthFix" />
|
||||
<view class="title line-1">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</view>
|
||||
</unitv-scroll>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
</unitv-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import chapterList from "./chapterList";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
curriculumInfo: {
|
||||
curriculumName: "气体基础知识",
|
||||
introduction:
|
||||
"气体是指无形状有体积的可压缩和膨胀的流体。气体是物质的一个态,气体与液体一样是流体:它可以流动,可变形。与液体不同的是气体气体分子间距离很大,可以被压缩膨胀。假如没有限制(容器或力场)的话,气体可以膨胀,其体积不受限制。气态物质的原子或分子相互之间可以自由运动。气态物质的原子或分子的动能比较高。 气体形态可通过其体积、温度和其压强所影响。这几项要素构成了多项气体定律,而三者之间又可以互相影响。",
|
||||
cover: require("../../static/public_images/video_bg1.jpg"),
|
||||
price: "123",
|
||||
},
|
||||
video: {
|
||||
url: "",
|
||||
title: "",
|
||||
time: 0,
|
||||
},
|
||||
chapterList,
|
||||
currentChapterIndex: 0,
|
||||
currentChapterInfo: {},
|
||||
recommendCurriculumList: [],
|
||||
videoContext: null,
|
||||
isFullScreen: false,
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
if (this.$refs.curriculumDetailsPage) {
|
||||
this.$refs.curriculumDetailsPage.showPage();
|
||||
if (this.videoContext) {
|
||||
this.videoContext.play();
|
||||
}
|
||||
}
|
||||
},
|
||||
onHide() {
|
||||
this.videoContext && this.videoContext.pause();
|
||||
},
|
||||
onLoad() {
|
||||
this.fnInitCurrentChapter();
|
||||
this.fnGetRecommendCurriculum();
|
||||
},
|
||||
methods: {
|
||||
fnInitCurrentChapter() {
|
||||
this.currentChapterInfo = this.chapterList[this.currentChapterIndex];
|
||||
},
|
||||
fnClickChapterItem(event) {
|
||||
this.currentChapterIndex = event;
|
||||
this.fnInitCurrentChapter();
|
||||
},
|
||||
async fnGetRecommendCurriculum() {
|
||||
this.recommendCurriculumList.push({
|
||||
img: require(`../../static/public_images/video_bg1.jpg`),
|
||||
title: "气体基础知识",
|
||||
});
|
||||
this.recommendCurriculumList.push({
|
||||
img: require(`../../static/public_images/video_bg2.jpg`),
|
||||
title: "现场一线员工全面安全培训",
|
||||
});
|
||||
this.recommendCurriculumList.push({
|
||||
img: require(`../../static/public_images/video_bg3.jpg`),
|
||||
title: "出差人员基础安全知识与应急处置",
|
||||
});
|
||||
this.recommendCurriculumList.push({
|
||||
img: require(`../../static/public_images/video_bg4.jpg`),
|
||||
title: "现场安全负责人全面安全培训",
|
||||
});
|
||||
this.recommendCurriculumList.push({
|
||||
img: require(`../../static/public_images/video_bg5.jpg`),
|
||||
title: "《四川省安全生产条例》特色解读",
|
||||
});
|
||||
this.recommendCurriculumList.push({
|
||||
img: require(`../../static/public_images/video_bg6.jpg`),
|
||||
title: "企业贯彻落实《四川省安全生产条例》精要",
|
||||
});
|
||||
this.recommendCurriculumList.push({
|
||||
img: require(`../../static/public_images/video_bg7.jpg`),
|
||||
title: "《四川省安全生产举报奖励办法》解读",
|
||||
});
|
||||
this.recommendCurriculumList.push({
|
||||
img: require(`../../static/public_images/video_bg8.jpg`),
|
||||
title: "应急管理部关于进一步加强安全生产举报工作的指导意见",
|
||||
});
|
||||
this.recommendCurriculumList.push({
|
||||
img: require(`../../static/public_images/video_bg9.jpg`),
|
||||
title: "危险货物运输包装-气瓶",
|
||||
});
|
||||
this.recommendCurriculumList.push({
|
||||
img: require(`../../static/public_images/video_bg10.jpg`),
|
||||
title: "职业病危害专项治理",
|
||||
});
|
||||
},
|
||||
async fnPlayVideo(item) {
|
||||
this.video.url = "";
|
||||
await this.$nextTick();
|
||||
this.video.url = item.url;
|
||||
this.video.title = item.coursewareName;
|
||||
this.video.time = 0;
|
||||
await this.$nextTick();
|
||||
!this.videoContext &&
|
||||
(this.videoContext = uni.createVideoContext("player"));
|
||||
},
|
||||
fnTimeupdate(time) {
|
||||
this.video.time = time;
|
||||
},
|
||||
fnFullScreen() {
|
||||
this.isFullScreen = true;
|
||||
this.videoContext = null;
|
||||
const { url, time, title } = this.video;
|
||||
uni.navigateTo({
|
||||
url: `/pages/curriculum/play?url=${url}&title=${title}&time=${time}`,
|
||||
animationType: "none",
|
||||
events: {
|
||||
timeupdate: async ({ time }) => {
|
||||
this.isFullScreen = false;
|
||||
this.video.time = time;
|
||||
await this.$nextTick();
|
||||
!this.videoContext &&
|
||||
(this.videoContext = uni.createVideoContext("player"));
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
fnBuy() {
|
||||
uni.navigateTo({ url: "/pages/curriculum/buy" });
|
||||
},
|
||||
fnSwitchCurriculum() {
|
||||
uni.redirectTo({
|
||||
url: "/pages/curriculum/details",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
.curriculumInfo {
|
||||
margin-top: 10rpx;
|
||||
display: flex;
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
|
||||
.curriculumName {
|
||||
font-size: 18rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.introduction {
|
||||
font-size: 12rpx;
|
||||
padding-top: 5rpx;
|
||||
}
|
||||
|
||||
.curriculum_details_first_zone {
|
||||
margin-top: 10rpx;
|
||||
display: flex;
|
||||
|
||||
.trySee {
|
||||
width: 53rpx;
|
||||
height: 53rpx;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 1rpx;
|
||||
border: 1px solid rgba(207, 207, 247, 0.1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
margin-bottom: 5rpx;
|
||||
|
||||
image {
|
||||
width: 15rpx;
|
||||
height: 18rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 9rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 1rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
|
||||
.buy {
|
||||
margin-left: 14rpx;
|
||||
width: 53rpx;
|
||||
height: 53rpx;
|
||||
background-image: url("/static/buy_bg.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
border-radius: 1rpx;
|
||||
text-align: center;
|
||||
padding: 8rpx;
|
||||
border: 1rpx solid transparent;
|
||||
|
||||
.price {
|
||||
color: rgba(115, 62, 2, 1);
|
||||
font-size: 14rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.text {
|
||||
margin-top: 8rpx;
|
||||
font-size: 9rpx;
|
||||
color: rgba(85, 45, 0, 1);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 1rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cover {
|
||||
margin-left: 13rpx;
|
||||
width: 343rpx;
|
||||
height: 150rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chapter {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.main_title {
|
||||
font-size: 14rpx;
|
||||
|
||||
.current {
|
||||
margin-left: 9rpx;
|
||||
font-size: 9rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.curriculum_details_second_zone {
|
||||
margin-top: 5rpx;
|
||||
|
||||
.scroll {
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
|
||||
.item {
|
||||
margin-left: 10rpx;
|
||||
padding: 5rpx 10rpx;
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 1rpx;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 9rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
background-color: #254eff;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba(37, 78, 255, 0.39);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.curriculum_details_third_zone {
|
||||
margin-top: 5rpx;
|
||||
|
||||
.scroll {
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.border_right {
|
||||
width: 1rpx;
|
||||
background-color: #fff;
|
||||
height: 10rpx;
|
||||
}
|
||||
|
||||
.border_bottom {
|
||||
width: 60%;
|
||||
background-color: transparent;
|
||||
height: 1rpx;
|
||||
position: absolute;
|
||||
left: 20%;
|
||||
right: 20%;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
.text {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.border_bottom {
|
||||
left: calc(20% - 5rpx);
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 9rpx;
|
||||
border-bottom: 1rpx solid transparent;
|
||||
padding: 5rpx 10rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
.border_bottom {
|
||||
background-color: #254eff;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
.border_bottom {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.recommend_curriculum {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.main_title {
|
||||
font-size: 14rpx;
|
||||
}
|
||||
|
||||
.curriculum_details_fourth_zone {
|
||||
margin-top: 5rpx;
|
||||
|
||||
.scroll {
|
||||
white-space: nowrap;
|
||||
|
||||
.item {
|
||||
display: inline-block;
|
||||
width: calc(18% - 20rpx);
|
||||
height: 100rpx;
|
||||
position: relative;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 4rpx;
|
||||
font-size: 0;
|
||||
margin-left: 20rpx;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 80%;
|
||||
font-size: 9rpx;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 9rpx;
|
||||
left: 7rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 2rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,50 @@
|
|||
<template>
|
||||
<unitv-page
|
||||
id="curriculumPlayPage"
|
||||
ref="curriculumPlayPage"
|
||||
class="curriculumPlayPage"
|
||||
:show="true"
|
||||
>
|
||||
<unitv-video
|
||||
id="player"
|
||||
:src="url"
|
||||
:title="title"
|
||||
:initial-time="time"
|
||||
@timeupdate="fnTimeupdate"
|
||||
/>
|
||||
</unitv-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
videoContext: null,
|
||||
url: "",
|
||||
title: "",
|
||||
time: 0,
|
||||
};
|
||||
},
|
||||
onLoad(query) {
|
||||
this.url = query.url;
|
||||
this.title = query.title;
|
||||
this.time = +query.time;
|
||||
},
|
||||
onReady() {
|
||||
this.videoContext = uni.createVideoContext("player");
|
||||
this.videoContext.play();
|
||||
this.videoContext.seek(this.time);
|
||||
},
|
||||
onUnload() {
|
||||
const eventChannel = this.getOpenerEventChannel();
|
||||
eventChannel.emit("timeupdate", { time: this.time });
|
||||
},
|
||||
methods: {
|
||||
fnTimeupdate(time) {
|
||||
this.time = time;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,364 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<!-- <app-loading v-if="loading" />-->
|
||||
<view class="system">
|
||||
<unitv-zone
|
||||
id="course_classification_first_zone"
|
||||
class="course_classification_first_zone"
|
||||
up="tabs_zone"
|
||||
right="course_classification_second_zone"
|
||||
:values="systemList"
|
||||
:column="1"
|
||||
:row="systemList.length"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in systemList"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnClickSystem"
|
||||
>
|
||||
<view class="title line-1">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="search">
|
||||
<view class="block">
|
||||
<view class="main_title">最新</view>
|
||||
<unitv-zone
|
||||
id="course_classification_second_zone"
|
||||
class="search_zone"
|
||||
up="tabs_zone"
|
||||
down="course_classification_third_zone"
|
||||
left="course_classification_first_zone"
|
||||
:values="newestList"
|
||||
:column="newestList.length"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in newestList"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnClickSearch($event, 'newestList')"
|
||||
>
|
||||
<view class="title">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
<view class="block">
|
||||
<view class="main_title">行业</view>
|
||||
<unitv-zone
|
||||
id="course_classification_third_zone"
|
||||
class="search_zone"
|
||||
up="course_classification_second_zone"
|
||||
down="course_classification_fourth_zone"
|
||||
left="course_classification_first_zone"
|
||||
:values="industryList"
|
||||
:column="industryList.length"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in industryList"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnClickSearch($event, 'industryList')"
|
||||
>
|
||||
<view class="title">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
<view class="block">
|
||||
<view class="main_title">专区</view>
|
||||
<unitv-zone
|
||||
id="course_classification_fourth_zone"
|
||||
class="search_zone"
|
||||
up="course_classification_third_zone"
|
||||
left="course_classification_first_zone"
|
||||
down="course_classification_fifth_zone"
|
||||
:values="specialZoneList"
|
||||
:column="specialZoneList.length"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in specialZoneList"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnClickSearch($event, 'specialZoneList')"
|
||||
>
|
||||
<view class="title">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
</view>
|
||||
<unitv-zone
|
||||
id="course_classification_fifth_zone"
|
||||
class="course_classification_fifth_zone"
|
||||
left="course_classification_first_zone"
|
||||
up="course_classification_fourth_zone"
|
||||
:values="list"
|
||||
:column="4"
|
||||
@scrolltolower="fnScrollToLower"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnCurriculumDetails"
|
||||
>
|
||||
<image :src="item.img" mode="widthFix" />
|
||||
<view class="title line-1">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
systemList: [
|
||||
{ title: "安全培训" },
|
||||
{ title: "职业健康" },
|
||||
{ title: "工伤预防" },
|
||||
{ title: "职业技能" },
|
||||
{ title: "建筑施工" },
|
||||
{ title: "特种设备" },
|
||||
{ title: "道路运输" },
|
||||
{ title: "专项培训" },
|
||||
],
|
||||
newestList: [{ title: "最新上线" }, { title: "最多播放" }],
|
||||
industryList: [
|
||||
{ title: "高危行业" },
|
||||
{ title: "金属冶炼" },
|
||||
{ title: "煤矿开采" },
|
||||
{ title: "高危行业" },
|
||||
{ title: "金属冶炼" },
|
||||
{ title: "煤矿开采" },
|
||||
{ title: "高危行业" },
|
||||
{ title: "高危行业" },
|
||||
{ title: "金属冶炼" },
|
||||
{ title: "煤矿开采" },
|
||||
{ title: "高危行业" },
|
||||
{ title: "金属冶炼" },
|
||||
{ title: "煤矿开采" },
|
||||
{ title: "高危行业" },
|
||||
],
|
||||
specialZoneList: [{ title: "免费视频" }, { title: "付费视频" }],
|
||||
list: [],
|
||||
// loading: true,
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 10,
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.fnGetData();
|
||||
},
|
||||
methods: {
|
||||
async fnGetData() {
|
||||
// setTimeout(() => {
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg1.jpg`),
|
||||
title: "气体基础知识",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg2.jpg`),
|
||||
title: "现场一线员工全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg3.jpg`),
|
||||
title: "出差人员基础安全知识与应急处置",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg4.jpg`),
|
||||
title: "现场安全负责人全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg5.jpg`),
|
||||
title: "《四川省安全生产条例》特色解读",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg6.jpg`),
|
||||
title: "企业贯彻落实《四川省安全生产条例》精要",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg7.jpg`),
|
||||
title: "《四川省安全生产举报奖励办法》解读",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg8.jpg`),
|
||||
title: "应急管理部关于进一步加强安全生产举报工作的指导意见",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg9.jpg`),
|
||||
title: "危险货物运输包装-气瓶",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg10.jpg`),
|
||||
title: "职业病危害专项治理",
|
||||
});
|
||||
// this.loading = false;
|
||||
// }, 5000);
|
||||
},
|
||||
fnScrollToLower() {
|
||||
this.pagination.currentPage++;
|
||||
if (this.pagination.currentPage <= this.pagination.total)
|
||||
this.fnGetData();
|
||||
},
|
||||
fnClickSystem(event) {
|
||||
console.log(this.systemList[event].title);
|
||||
this.list = [];
|
||||
this.pagination = {
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 10,
|
||||
};
|
||||
this.fnGetData();
|
||||
},
|
||||
fnClickSearch(event, key) {
|
||||
console.log(this[key][event].title);
|
||||
this.list = [];
|
||||
this.pagination = {
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 10,
|
||||
};
|
||||
this.fnGetData();
|
||||
},
|
||||
fnCurriculumDetails() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/curriculum/details",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
margin-top: 19rpx;
|
||||
display: flex;
|
||||
|
||||
.system {
|
||||
width: 94rpx;
|
||||
|
||||
.course_classification_first_zone {
|
||||
font-size: 14rpx;
|
||||
text-align: center;
|
||||
|
||||
.item {
|
||||
margin-top: 5rpx;
|
||||
background-color: transparent;
|
||||
border-radius: 34rpx;
|
||||
padding: 6rpx 18rpx;
|
||||
|
||||
&.hover {
|
||||
background-color: #254eff;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba(37, 78, 255, 0.39);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-left: 34rpx;
|
||||
flex: 1;
|
||||
|
||||
.search {
|
||||
.block {
|
||||
display: flex;
|
||||
margin-top: 5rpx;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.main_title {
|
||||
font-size: 10rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 15rpx;
|
||||
padding: 2rpx 0;
|
||||
margin-top: 5rpx;
|
||||
}
|
||||
|
||||
.search_zone {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
background-color: transparent;
|
||||
border-radius: 34rpx;
|
||||
padding: 2rpx 12rpx;
|
||||
margin-top: 5rpx;
|
||||
|
||||
.title {
|
||||
font-size: 9rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
background-color: #254eff;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba(37, 78, 255, 0.39);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.course_classification_fifth_zone {
|
||||
margin-top: 14rpx;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
width: 130rpx;
|
||||
position: relative;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 4rpx;
|
||||
font-size: 0;
|
||||
height: 117rpx;
|
||||
margin-top: 14rpx;
|
||||
margin-left: 10rpx;
|
||||
|
||||
&:not(:nth-child(n + 5)) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:nth-child(4n + 1) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 80%;
|
||||
font-size: 12rpx;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 9rpx;
|
||||
left: 7rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 2rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,232 @@
|
|||
<template>
|
||||
<view>
|
||||
<!-- <app-loading v-if="loading" />-->
|
||||
<view class="top">
|
||||
<unitv-zone
|
||||
id="home_first_zone"
|
||||
class="home_first_zone"
|
||||
up="tabs_zone"
|
||||
down="home_third_zone"
|
||||
:values="list.slice(0, 2)"
|
||||
:column="list.slice(0, 2).length"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in list.slice(0, 2)"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnNavigate('/pages/curriculum/details')"
|
||||
>
|
||||
<image :src="item.img" mode="widthFix" />
|
||||
<view class="title line-1">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
<view class="bottom">
|
||||
<view class="left">
|
||||
<unitv-zone
|
||||
id="home_third_zone"
|
||||
class="home_third_zone"
|
||||
up="home_first_zone"
|
||||
right="home_fourth_zone"
|
||||
:values="[0, 1]"
|
||||
:column="1"
|
||||
:row="2"
|
||||
>
|
||||
<unitv-item
|
||||
:item="0"
|
||||
class="item"
|
||||
@click="fnNavigate('/pages/mine/curriculum/index?tabIndex=1')"
|
||||
>
|
||||
<image src="/static/xuexi.png" mode="widthFix" />
|
||||
</unitv-item>
|
||||
<unitv-item
|
||||
:item="1"
|
||||
class="item"
|
||||
@click="fnNavigate('/pages/mine/curriculum/index?tabIndex=2')"
|
||||
>
|
||||
<image src="/static/examination.png" mode="widthFix" />
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
<view class="right">
|
||||
<unitv-zone
|
||||
id="home_fourth_zone"
|
||||
class="home_fourth_zone"
|
||||
up="home_first_zone"
|
||||
left="home_third_zone"
|
||||
:values="list.slice(2)"
|
||||
:column="list.slice(2).length"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in list.slice(2)"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnNavigate('/pages/curriculum/details')"
|
||||
>
|
||||
<image :src="item.img" mode="widthFix" />
|
||||
<view class="title line-1">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// loading: true,
|
||||
list: [],
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.fnGetData();
|
||||
},
|
||||
methods: {
|
||||
async fnGetData() {
|
||||
// setTimeout(() => {
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg1.jpg`),
|
||||
title: "气体基础知识",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg2.jpg`),
|
||||
title: "现场一线员工全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg3.jpg`),
|
||||
title: "出差人员基础安全知识与应急处置",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg4.jpg`),
|
||||
title: "现场安全负责人全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg5.jpg`),
|
||||
title: "《四川省安全生产条例》特色解读",
|
||||
});
|
||||
// this.loading = false;
|
||||
// }, 5000);
|
||||
},
|
||||
fnNavigate(url) {
|
||||
uni.navigateTo({ url });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.top {
|
||||
padding-top: 19rpx;
|
||||
|
||||
.home_first_zone {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.item {
|
||||
width: 335rpx;
|
||||
position: relative;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 4rpx;
|
||||
font-size: 0;
|
||||
height: 169rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 80%;
|
||||
font-size: 12rpx;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 9rpx;
|
||||
left: 7rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 2rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
margin-top: 10rpx;
|
||||
color: #fff;
|
||||
font-size: 12rpx;
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
width: 175rpx;
|
||||
|
||||
.home_third_zone {
|
||||
.item {
|
||||
margin-top: 10rpx;
|
||||
width: 100%;
|
||||
border-radius: 4rpx;
|
||||
height: 57rpx;
|
||||
text-align: center;
|
||||
border: 2rpx solid transparent;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 2rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-left: 11rpx;
|
||||
flex: 1;
|
||||
|
||||
.home_fourth_zone {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.item {
|
||||
width: 159rpx;
|
||||
position: relative;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 4rpx;
|
||||
font-size: 0;
|
||||
height: 117rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 80%;
|
||||
font-size: 12rpx;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 9rpx;
|
||||
left: 7rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 2rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,121 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<unitv-page
|
||||
id="indexPage"
|
||||
ref="indexPage"
|
||||
class="indexPage"
|
||||
:show="true"
|
||||
@back="pageBack"
|
||||
>
|
||||
<app-header />
|
||||
<unitv-zone
|
||||
id="tabs_zone"
|
||||
class="tabs_zone"
|
||||
:auto-fous="true"
|
||||
up="header_zone"
|
||||
:down="tabsZoneDown"
|
||||
:item="0"
|
||||
:values="tabs"
|
||||
:column="tabs.length"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in tabs"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@hover="fnHoverTabs"
|
||||
>
|
||||
<view>{{ item.name }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
<home v-if="currentTab === 0" />
|
||||
<premium-recommendation v-if="currentTab === 1" />
|
||||
<course-classification v-if="currentTab === 2" />
|
||||
</unitv-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Home from "./home.vue";
|
||||
import PremiumRecommendation from "./premium_recommendation.vue";
|
||||
import CourseClassification from "./course_classification.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Home,
|
||||
PremiumRecommendation,
|
||||
CourseClassification,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabs: [{ name: "首页" }, { name: "精品推荐" }, { name: "课程分类" }],
|
||||
currentTab: 0,
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
if (this.$refs.indexPage) {
|
||||
this.$refs.indexPage.showPage();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tabsZoneDown() {
|
||||
if (this.currentTab === 0) return "home_first_zone";
|
||||
if (this.currentTab === 1) return "premium_recommendation_first_zone";
|
||||
if (this.currentTab === 2) return "course_classification_first_zone";
|
||||
return "";
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
pageBack() {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "是否退出",
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
plus.runtime.quit();
|
||||
}
|
||||
},
|
||||
});
|
||||
return false;
|
||||
},
|
||||
fnHoverTabs(item) {
|
||||
this.currentTab = item;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
.indexPage {
|
||||
.tabs_zone {
|
||||
font-size: 14rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 20rpx;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
z-index: 99;
|
||||
|
||||
.item {
|
||||
background-color: transparent;
|
||||
border-radius: 34rpx;
|
||||
padding: 6rpx 18rpx;
|
||||
margin-left: 20rpx;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
background-color: #254eff;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba(37, 78, 255, 0.39);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,257 @@
|
|||
<template>
|
||||
<view>
|
||||
<!-- <app-loading v-if="loading" />-->
|
||||
<view class="top">
|
||||
<view class="left">
|
||||
<unitv-zone
|
||||
id="premium_recommendation_first_zone"
|
||||
class="premium_recommendation_first_zone"
|
||||
up="tabs_zone"
|
||||
right="premium_recommendation_second_zone"
|
||||
down="premium_recommendation_third_zone"
|
||||
:values="list.slice(0, 2)"
|
||||
:column="list.slice(0, 2).length"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in list.slice(0, 2)"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnCurriculumDetails"
|
||||
>
|
||||
<image :src="item.img" mode="widthFix" />
|
||||
<view class="title line-1">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
<view class="right">
|
||||
<unitv-zone
|
||||
id="premium_recommendation_second_zone"
|
||||
class="premium_recommendation_second_zone"
|
||||
up="tabs_zone"
|
||||
left="premium_recommendation_first_zone"
|
||||
down="premium_recommendation_third_zone"
|
||||
:values="list.slice(2, 4)"
|
||||
:column="1"
|
||||
:row="list.slice(2, 4).length"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in list.slice(2, 4)"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnCurriculumDetails"
|
||||
>
|
||||
<image :src="item.img" mode="widthFix" />
|
||||
<view class="title line-1">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bottom">
|
||||
<unitv-zone
|
||||
id="premium_recommendation_third_zone"
|
||||
class="premium_recommendation_third_zone"
|
||||
up="premium_recommendation_first_zone"
|
||||
:values="list.slice(4)"
|
||||
:column="list.slice(4).length"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in list.slice(4)"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnCurriculumDetails"
|
||||
>
|
||||
<image :src="item.img" mode="widthFix" />
|
||||
<view class="title line-1">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// loading: true,
|
||||
list: [],
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.fnGetData();
|
||||
},
|
||||
methods: {
|
||||
async fnGetData() {
|
||||
// setTimeout(() => {
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg1.jpg`),
|
||||
title: "气体基础知识",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg2.jpg`),
|
||||
title: "现场一线员工全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg3.jpg`),
|
||||
title: "出差人员基础安全知识与应急处置",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg4.jpg`),
|
||||
title: "现场安全负责人全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg5.jpg`),
|
||||
title: "《四川省安全生产条例》特色解读",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg6.jpg`),
|
||||
title: "企业贯彻落实《四川省安全生产条例》精要",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg7.jpg`),
|
||||
title: "《四川省安全生产举报奖励办法》解读",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../static/public_images/video_bg8.jpg`),
|
||||
title: "应急管理部关于进一步加强安全生产举报工作的指导意见",
|
||||
});
|
||||
// this.loading = false;
|
||||
// }, 5000);
|
||||
},
|
||||
fnCurriculumDetails() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/curriculum/details",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.top {
|
||||
padding-top: 19rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.left {
|
||||
width: 510rpx;
|
||||
height: 169rpx;
|
||||
|
||||
.premium_recommendation_first_zone {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.item {
|
||||
width: 164rpx;
|
||||
position: relative;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 4rpx;
|
||||
font-size: 0;
|
||||
height: 169rpx;
|
||||
|
||||
&:first-child {
|
||||
width: 335rpx;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 80%;
|
||||
font-size: 12rpx;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 9rpx;
|
||||
left: 7rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 2rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-left: 11rpx;
|
||||
flex: 1;
|
||||
|
||||
.premium_recommendation_second_zone {
|
||||
.item {
|
||||
width: 164rpx;
|
||||
position: relative;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 4rpx;
|
||||
font-size: 0;
|
||||
height: 81rpx;
|
||||
margin-top: 7rpx;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 80%;
|
||||
font-size: 12rpx;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 9rpx;
|
||||
left: 7rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 2rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.premium_recommendation_third_zone {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.item {
|
||||
width: 159rpx;
|
||||
position: relative;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 4rpx;
|
||||
font-size: 0;
|
||||
height: 117rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 80%;
|
||||
font-size: 12rpx;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 9rpx;
|
||||
left: 7rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 2rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,166 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<unitv-page id="loginPage" ref="loginPage" class="loginPage" :show="true">
|
||||
<app-header :is-show-user-info="false" />
|
||||
<view class="main_title">
|
||||
<text>登录可享</text>
|
||||
<text>3</text>
|
||||
<text>大权益</text>
|
||||
</view>
|
||||
<view class="rights_and_interests">
|
||||
<view class="item">
|
||||
<view class="icon">
|
||||
<image src="/static/1080P.png" style="width: 17rpx; height: 9rpx" />
|
||||
</view>
|
||||
<view class="title">尊享1080P画质</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="icon">
|
||||
<image
|
||||
src="/static/w_yunduan.png"
|
||||
style="width: 16rpx; height: 11rpx"
|
||||
/>
|
||||
</view>
|
||||
<view class="title">同步云端观看历史</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="icon">
|
||||
<image src="/static/fuli.png" style="width: 12rpx; height: 12rpx" />
|
||||
</view>
|
||||
<view class="title">福利活动享不停</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<view class="login_methods">
|
||||
<view class="item">
|
||||
<view class="icon">
|
||||
<image
|
||||
src="/static/scan_login.png"
|
||||
style="width: 33rpx; height: 33rpx"
|
||||
/>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="title">扫码登录</view>
|
||||
<view class="subtitle">使用手机扫码授权</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="qrcode">
|
||||
<view class="image">
|
||||
<canvas
|
||||
id="qrcode"
|
||||
canvas-id="qrcode"
|
||||
:style="{ width: canvasSize + 'px', height: canvasSize + 'px' }"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</unitv-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UQRCode from "uqrcodejs";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
canvasSize: uni.upx2px(170),
|
||||
};
|
||||
},
|
||||
onShow() {
|
||||
if (this.$refs.loginPage) {
|
||||
this.$refs.loginPage.showPage();
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
const qr = new UQRCode();
|
||||
qr.data = "qrcode_url";
|
||||
qr.size = this.canvasSize;
|
||||
qr.make();
|
||||
qr.canvasContext = uni.createCanvasContext("qrcode");
|
||||
qr.drawCanvas();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
.main_title {
|
||||
margin-top: 10rpx;
|
||||
font-size: 30rpx;
|
||||
|
||||
text:nth-child(2) {
|
||||
color: rgba(0, 204, 255, 1);
|
||||
padding: 0 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.rights_and_interests {
|
||||
margin-top: 21rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 18rpx;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 3rpx;
|
||||
font-size: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.login_methods {
|
||||
margin-top: 27rpx;
|
||||
|
||||
.item {
|
||||
width: 359rpx;
|
||||
height: 72rpx;
|
||||
background-image: url("/static/scan_login_bg.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 12rpx;
|
||||
|
||||
.right {
|
||||
margin-left: 14rpx;
|
||||
|
||||
.title {
|
||||
font-size: 14rpx;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
padding-top: 9rpx;
|
||||
font-size: 9rpx;
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.17);
|
||||
border-radius: 4px;
|
||||
padding: 12rpx;
|
||||
|
||||
.image {
|
||||
background-color: #fff;
|
||||
padding: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,144 @@
|
|||
<template>
|
||||
<view>
|
||||
<!-- <app-loading v-if="loading" />-->
|
||||
<unitv-zone
|
||||
id="mine_curriculum_all_first_zone"
|
||||
class="mine_curriculum_all_first_zone"
|
||||
left="tabs_zone"
|
||||
:values="list"
|
||||
:column="4"
|
||||
@scrolltolower="fnScrollToLower"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnCurriculumDetails"
|
||||
>
|
||||
<image :src="item.img" mode="widthFix" />
|
||||
<view class="title line-1">{{ item.title }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 10,
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.fnGetData();
|
||||
},
|
||||
methods: {
|
||||
async fnGetData() {
|
||||
// setTimeout(() => {
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg1.jpg`),
|
||||
title: "气体基础知识",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg2.jpg`),
|
||||
title: "现场一线员工全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg3.jpg`),
|
||||
title: "出差人员基础安全知识与应急处置",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg4.jpg`),
|
||||
title: "现场安全负责人全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg5.jpg`),
|
||||
title: "《四川省安全生产条例》特色解读",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg6.jpg`),
|
||||
title: "企业贯彻落实《四川省安全生产条例》精要",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg7.jpg`),
|
||||
title: "《四川省安全生产举报奖励办法》解读",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg8.jpg`),
|
||||
title: "应急管理部关于进一步加强安全生产举报工作的指导意见",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg9.jpg`),
|
||||
title: "危险货物运输包装-气瓶",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg10.jpg`),
|
||||
title: "职业病危害专项治理",
|
||||
});
|
||||
// this.loading = false;
|
||||
// }, 5000);
|
||||
},
|
||||
fnScrollToLower() {
|
||||
this.pagination.currentPage++;
|
||||
if (this.pagination.currentPage <= this.pagination.total)
|
||||
this.fnGetData();
|
||||
},
|
||||
fnCurriculumDetails() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/curriculum/details",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mine_curriculum_all_first_zone {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
width: 130rpx;
|
||||
position: relative;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 4rpx;
|
||||
font-size: 0;
|
||||
height: 117rpx;
|
||||
margin-top: 14rpx;
|
||||
margin-left: 10rpx;
|
||||
|
||||
&:not(:nth-child(n + 5)) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:nth-child(4n + 1) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
width: 80%;
|
||||
font-size: 12rpx;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 9rpx;
|
||||
left: 7rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 2rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,184 @@
|
|||
<template>
|
||||
<view>
|
||||
<!-- <app-loading v-if="loading" />-->
|
||||
<unitv-zone
|
||||
id="mine_curriculum_completed_learning_first_zone"
|
||||
class="mine_curriculum_completed_learning_first_zone"
|
||||
left="tabs_zone"
|
||||
:values="list"
|
||||
:column="1"
|
||||
:row="list.length"
|
||||
@scrolltolower="fnScrollToLower"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnCurriculumDetails"
|
||||
>
|
||||
<view class="image">
|
||||
<image :src="item.img" mode="widthFix" />
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="info">
|
||||
<view class="title line-1">{{ item.title }}</view>
|
||||
<view class="button">
|
||||
<button>培训考核</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 10,
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.fnGetData();
|
||||
},
|
||||
methods: {
|
||||
async fnGetData() {
|
||||
// setTimeout(() => {
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg1.jpg`),
|
||||
title: "气体基础知识",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg2.jpg`),
|
||||
title: "现场一线员工全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg3.jpg`),
|
||||
title: "出差人员基础安全知识与应急处置",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg4.jpg`),
|
||||
title: "现场安全负责人全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg5.jpg`),
|
||||
title: "《四川省安全生产条例》特色解读",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg6.jpg`),
|
||||
title: "企业贯彻落实《四川省安全生产条例》精要",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg7.jpg`),
|
||||
title: "《四川省安全生产举报奖励办法》解读",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg8.jpg`),
|
||||
title: "应急管理部关于进一步加强安全生产举报工作的指导意见",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg9.jpg`),
|
||||
title: "危险货物运输包装-气瓶",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg10.jpg`),
|
||||
title: "职业病危害专项治理",
|
||||
});
|
||||
// this.loading = false;
|
||||
// }, 5000);
|
||||
},
|
||||
fnScrollToLower() {
|
||||
this.pagination.currentPage++;
|
||||
if (this.pagination.currentPage <= this.pagination.total)
|
||||
this.fnGetData();
|
||||
},
|
||||
fnCurriculumDetails() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/curriculum/details",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mine_curriculum_completed_learning_first_zone {
|
||||
.item {
|
||||
margin-top: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 130rpx;
|
||||
height: 70rpx;
|
||||
border-radius: 6rpx;
|
||||
|
||||
image {
|
||||
border-radius: 6rpx;
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
margin-left: 20rpx;
|
||||
height: 70rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.info {
|
||||
height: 100%;
|
||||
padding: 10rpx 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
width: 300rpx;
|
||||
font-size: 14rpx;
|
||||
}
|
||||
|
||||
.button {
|
||||
button {
|
||||
width: 70rpx;
|
||||
height: 24rpx;
|
||||
line-height: 24rpx;
|
||||
background-color: rgba(37, 78, 255, 0.4);
|
||||
border-radius: 30rpx;
|
||||
color: #fff;
|
||||
font-size: 9rpx;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.hover {
|
||||
.right {
|
||||
.info {
|
||||
.button {
|
||||
button {
|
||||
background-color: #254eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<unitv-page
|
||||
id="mineCurriculumPage"
|
||||
ref="mineCurriculumPage"
|
||||
class="mineCurriculumPage"
|
||||
:show="true"
|
||||
>
|
||||
<app-header />
|
||||
<view class="content">
|
||||
<view class="tabs">
|
||||
<unitv-zone
|
||||
id="tabs_zone"
|
||||
class="tabs_zone"
|
||||
:auto-fous="true"
|
||||
:right="tabsZoneRight"
|
||||
:item="currentTab"
|
||||
:values="tabs"
|
||||
:column="1"
|
||||
:row="tabs.length"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in tabs"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@hover="fnHoverTabs"
|
||||
>
|
||||
<view class="title">{{ item.name }}</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
<view style="flex: 1; margin-left: 33rpx">
|
||||
<all v-if="currentTab === 0" />
|
||||
<learning v-if="currentTab === 1" />
|
||||
<completed-learning v-if="currentTab === 2" />
|
||||
</view>
|
||||
</view>
|
||||
</unitv-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import All from "./all.vue";
|
||||
import Learning from "./learning.vue";
|
||||
import CompletedLearning from "./completed_learning.vue";
|
||||
export default {
|
||||
components: {
|
||||
All,
|
||||
Learning,
|
||||
CompletedLearning,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabs: [{ name: "全部" }, { name: "学习中" }, { name: "已学完" }],
|
||||
currentTab: 0,
|
||||
};
|
||||
},
|
||||
onLoad(query) {
|
||||
this.currentTab = query.tabIndex ? +query.tabIndex : 0;
|
||||
},
|
||||
onShow() {
|
||||
if (this.$refs.mineCurriculumPage) {
|
||||
this.$refs.mineCurriculumPage.showPage();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tabsZoneRight() {
|
||||
if (this.currentTab === 0) return "mine_curriculum_all_first_zone";
|
||||
if (this.currentTab === 1) return "mine_curriculum_learning_first_zone";
|
||||
if (this.currentTab === 2)
|
||||
return "mine_curriculum_completed_learning_first_zone";
|
||||
return "";
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
fnHoverTabs(item) {
|
||||
this.currentTab = item;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
margin-top: 19rpx;
|
||||
display: flex;
|
||||
|
||||
.tabs {
|
||||
width: 94rpx;
|
||||
|
||||
.tabs_zone {
|
||||
font-size: 14rpx;
|
||||
text-align: center;
|
||||
|
||||
.item {
|
||||
margin-top: 5rpx;
|
||||
background-color: transparent;
|
||||
border-radius: 34rpx;
|
||||
padding: 6rpx 18rpx;
|
||||
|
||||
&.hover {
|
||||
background-color: #254eff;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba(37, 78, 255, 0.39);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,189 @@
|
|||
<template>
|
||||
<view>
|
||||
<!-- <app-loading v-if="loading" />-->
|
||||
<unitv-zone
|
||||
id="mine_curriculum_learning_first_zone"
|
||||
class="mine_curriculum_learning_first_zone"
|
||||
left="tabs_zone"
|
||||
:values="list"
|
||||
:column="1"
|
||||
:row="list.length"
|
||||
@scrolltolower="fnScrollToLower"
|
||||
>
|
||||
<unitv-item
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
:item="index"
|
||||
class="item"
|
||||
@click="fnCurriculumDetails"
|
||||
>
|
||||
<view class="image">
|
||||
<image :src="item.img" mode="widthFix" />
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="info">
|
||||
<view class="title line-2">{{ item.title }}</view>
|
||||
<view class="progressbar">
|
||||
<liu-progressbar
|
||||
:text-hide="false"
|
||||
:progress="70"
|
||||
ds-color="#24408b"
|
||||
bg-color="#254eff"
|
||||
height="4rpx"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="button">
|
||||
<button>继续学习</button>
|
||||
</view>
|
||||
</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 10,
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.fnGetData();
|
||||
},
|
||||
methods: {
|
||||
async fnGetData() {
|
||||
// setTimeout(() => {
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg1.jpg`),
|
||||
title: "气体基础知识",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg2.jpg`),
|
||||
title: "现场一线员工全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg3.jpg`),
|
||||
title: "出差人员基础安全知识与应急处置",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg4.jpg`),
|
||||
title: "现场安全负责人全面安全培训",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg5.jpg`),
|
||||
title: "《四川省安全生产条例》特色解读",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg6.jpg`),
|
||||
title: "企业贯彻落实《四川省安全生产条例》精要",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg7.jpg`),
|
||||
title: "《四川省安全生产举报奖励办法》解读",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg8.jpg`),
|
||||
title: "应急管理部关于进一步加强安全生产举报工作的指导意见",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg9.jpg`),
|
||||
title: "危险货物运输包装-气瓶",
|
||||
});
|
||||
this.list.push({
|
||||
img: require(`../../../static/public_images/video_bg10.jpg`),
|
||||
title: "职业病危害专项治理",
|
||||
});
|
||||
// this.loading = false;
|
||||
// }, 5000);
|
||||
},
|
||||
fnScrollToLower() {
|
||||
this.pagination.currentPage++;
|
||||
if (this.pagination.currentPage <= this.pagination.total)
|
||||
this.fnGetData();
|
||||
},
|
||||
fnCurriculumDetails() {
|
||||
uni.navigateTo({
|
||||
url: "/pages/curriculum/details",
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mine_curriculum_learning_first_zone {
|
||||
.item {
|
||||
margin-top: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 130rpx;
|
||||
height: 70rpx;
|
||||
border-radius: 6rpx;
|
||||
|
||||
image {
|
||||
border-radius: 6rpx;
|
||||
width: 100%;
|
||||
height: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
margin-left: 20rpx;
|
||||
height: 70rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.info {
|
||||
height: 100%;
|
||||
padding: 10rpx 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.title {
|
||||
font-size: 14rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-left: 20rpx;
|
||||
|
||||
button {
|
||||
width: 70rpx;
|
||||
height: 24rpx;
|
||||
line-height: 24rpx;
|
||||
background-color: rgba(37, 78, 255, 0.4);
|
||||
border-radius: 30rpx;
|
||||
color: #fff;
|
||||
font-size: 9rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.hover {
|
||||
.button {
|
||||
button {
|
||||
background-color: #254eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,179 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<unitv-page id="minePage" ref="minePage" class="minePage" :show="true">
|
||||
<app-header />
|
||||
<view class="content">
|
||||
<view class="info">
|
||||
<view class="user_info">
|
||||
<view class="avatar">
|
||||
<image src="/static/avatar.png" />
|
||||
</view>
|
||||
<view class="username">呀哈哈</view>
|
||||
</view>
|
||||
<view class="statistics">
|
||||
<view class="item">
|
||||
<view class="title">累计开班数量</view>
|
||||
<view>
|
||||
<text class="value">123</text>
|
||||
<text class="label">个</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="title">累计学员数量</view>
|
||||
<view>
|
||||
<text class="value">456</text>
|
||||
<text class="label">个</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="title">累计培训课时</view>
|
||||
<view>
|
||||
<text class="value">789</text>
|
||||
<text class="label">个</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<unitv-zone
|
||||
id="mine_first_zone"
|
||||
class="mine_first_zone"
|
||||
:values="[0, 1, 2, 3]"
|
||||
:column="4"
|
||||
auto-fous
|
||||
:item="0"
|
||||
>
|
||||
<unitv-item
|
||||
:item="0"
|
||||
class="item"
|
||||
@click="fnNavigate('/pages/mine/curriculum/index')"
|
||||
>
|
||||
<view class="text">我的课程</view>
|
||||
</unitv-item>
|
||||
<unitv-item :item="1" class="item">
|
||||
<view class="text">学员档案</view>
|
||||
</unitv-item>
|
||||
<unitv-item :item="2" class="item">
|
||||
<view class="text">效果评估报告</view>
|
||||
</unitv-item>
|
||||
<unitv-item :item="3" class="item">
|
||||
<view class="text">定制课申请</view>
|
||||
</unitv-item>
|
||||
<unitv-item :item="4" class="item">
|
||||
<view class="text">问题反馈</view>
|
||||
</unitv-item>
|
||||
</unitv-zone>
|
||||
</view>
|
||||
</unitv-page>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
onShow() {
|
||||
if (this.$refs.minePage) {
|
||||
this.$refs.minePage.showPage();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fnNavigate(url) {
|
||||
uni.navigateTo({ url });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
margin-top: 40rpx;
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.user_info {
|
||||
display: flex;
|
||||
|
||||
.avatar {
|
||||
border-radius: 50%;
|
||||
|
||||
image {
|
||||
width: 71rpx;
|
||||
height: 71rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.username {
|
||||
padding-top: 20rpx;
|
||||
padding-left: 17rpx;
|
||||
font-size: 20rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.statistics {
|
||||
display: flex;
|
||||
|
||||
.item {
|
||||
background-image: url("/static/statistics_bg.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 127rpx;
|
||||
height: 66rpx;
|
||||
padding: 13rpx 14rpx;
|
||||
margin-left: 9rpx;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 11rpx;
|
||||
padding-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 16rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.label {
|
||||
padding-left: 5rpx;
|
||||
font-size: 9rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mine_first_zone {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.item {
|
||||
padding: 15rpx 11rpx;
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
width: 131rpx;
|
||||
height: 65rpx;
|
||||
border: 1rpx solid transparent;
|
||||
border-radius: 4rpx;
|
||||
|
||||
@for $i from 1 through 5 {
|
||||
&:nth-child(#{$i}) {
|
||||
background-image: url("/static/mine_zone#{$i}.png");
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 14rpx;
|
||||
}
|
||||
|
||||
&.hover {
|
||||
border: 1rpx solid rgba(0, 180, 255, 0.79);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 2.8 MiB |
After Width: | Height: | Size: 934 B |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 62 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 751 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 837 KiB |
After Width: | Height: | Size: 710 KiB |
After Width: | Height: | Size: 500 KiB |
After Width: | Height: | Size: 627 KiB |
After Width: | Height: | Size: 646 KiB |
After Width: | Height: | Size: 588 KiB |
After Width: | Height: | Size: 888 KiB |
After Width: | Height: | Size: 529 KiB |
After Width: | Height: | Size: 435 KiB |
After Width: | Height: | Size: 706 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 854 B |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,30 @@
|
|||
import Vue from "vue";
|
||||
import Vuex from "vuex";
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
const store = new Vuex.Store({
|
||||
state: {
|
||||
currentPage: null,
|
||||
currentZone: null,
|
||||
allPages: [],
|
||||
},
|
||||
mutations: {
|
||||
pushPage(state, page) {
|
||||
state.allPages[page.id] = page;
|
||||
},
|
||||
switchZone(state, zone) {
|
||||
state.currentZone = zone;
|
||||
},
|
||||
switchPage(state, page) {
|
||||
state.currentPage = page;
|
||||
},
|
||||
showPage(state, pageId) {
|
||||
const page = state.allPages[pageId];
|
||||
page.showPage();
|
||||
},
|
||||
},
|
||||
actions: {},
|
||||
});
|
||||
|
||||
export default store;
|
|
@ -0,0 +1,30 @@
|
|||
// 文字超出几行隐藏,最多5行
|
||||
// 使用超出1行隐藏,如果使用了flex,则需要给父元素设置min-width: 0;
|
||||
@for $i from 1 through 5 {
|
||||
.line-#{$i} {
|
||||
@if $i == 1 {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
} @else {
|
||||
display: -webkit-box !important;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
-webkit-line-clamp: $i;
|
||||
-webkit-box-orient: vertical !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.container{
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
background-image: linear-gradient(to bottom, #050114, #133682);
|
||||
padding: 18rpx 33rpx;
|
||||
color: #fff;
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* 这里是uni-app内置的常用样式变量
|
||||
*
|
||||
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
||||
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
||||
*
|
||||
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
||||
*/
|
||||
|
||||
/* 颜色变量 */
|
||||
|
||||
/* 行为相关颜色 */
|
||||
$uni-color-primary: #007aff;
|
||||
$uni-color-success: #4cd964;
|
||||
$uni-color-warning: #f0ad4e;
|
||||
$uni-color-error: #dd524d;
|
||||
$uni-color-theme: #ec2224;
|
||||
|
||||
/* 文字基本颜色 */
|
||||
$uni-text-color:#333;//基本色
|
||||
$uni-text-color-inverse:#fff;//反色
|
||||
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
|
||||
$uni-text-color-placeholder: #808080;
|
||||
$uni-text-color-disable:#c0c0c0;
|
||||
|
||||
/* 背景颜色 */
|
||||
$uni-bg-color:#ffffff;
|
||||
$uni-bg-color-grey:#f8f8f8;
|
||||
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
|
||||
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
|
||||
|
||||
/* 边框颜色 */
|
||||
$uni-border-color:#c8c7cc;
|
||||
|
||||
/* 尺寸变量 */
|
||||
|
||||
/* 文字尺寸 */
|
||||
$uni-font-size-sm:12px;
|
||||
$uni-font-size-base:14px;
|
||||
$uni-font-size-lg:16;
|
||||
|
||||
/* 图片尺寸 */
|
||||
$uni-img-size-sm:20px;
|
||||
$uni-img-size-base:26px;
|
||||
$uni-img-size-lg:40px;
|
||||
|
||||
/* Border Radius */
|
||||
$uni-border-radius-sm: 2px;
|
||||
$uni-border-radius-base: 3px;
|
||||
$uni-border-radius-lg: 6px;
|
||||
$uni-border-radius-circle: 50%;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-row-sm: 5px;
|
||||
$uni-spacing-row-base: 10px;
|
||||
$uni-spacing-row-lg: 15px;
|
||||
|
||||
/* 垂直间距 */
|
||||
$uni-spacing-col-sm: 4px;
|
||||
$uni-spacing-col-base: 8px;
|
||||
$uni-spacing-col-lg: 12px;
|
||||
|
||||
/* 透明度 */
|
||||
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
|
||||
|
||||
/* 文章场景相关 */
|
||||
$uni-color-title: #2C405A; // 文章标题颜色
|
||||
$uni-font-size-title:20px;
|
||||
$uni-color-subtitle: #555555; // 二级标题颜色
|
||||
$uni-font-size-subtitle:26px;
|
||||
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
||||
$uni-font-size-paragraph:15px;
|
|
@ -0,0 +1,8 @@
|
|||
## 1.0.3(2023-06-10)
|
||||
增加插件预览二维码
|
||||
## 1.0.2(2023-04-14)
|
||||
增加示例
|
||||
## 1.0.1(2023-03-30)
|
||||
优化功能
|
||||
## 1.0.0(2023-03-14)
|
||||
初版发布
|
|
@ -0,0 +1,131 @@
|
|||
<template>
|
||||
<view>
|
||||
<view class="progress-bar" :style="{height: height,backgroundColor:dsColor}" v-if="textInside">
|
||||
<view class="progress" :style="{width: progressWidth, backgroundColor: bgColor,borderRadius: borderRadius}">
|
||||
</view>
|
||||
<span v-if="textHide" class="percentage" :style="{color:color,fontSize:fontSize }">{{ percentage }}%</span>
|
||||
</view>
|
||||
<view class="card-item" v-else>
|
||||
<view class="progress-bar1" :style="{height: height,backgroundColor:dsColor}">
|
||||
<view class="progress1"
|
||||
:style="{width: progressWidth, backgroundColor: bgColor,borderRadius: borderRadius}">
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="textHide" class="percentage1" :style="{color:color,fontSize:fontSize }">{{ percentage }}%</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
//文字是否内显
|
||||
textInside: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
//是否显示文字
|
||||
textHide: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
//当前进度
|
||||
progress: {
|
||||
type: Number,
|
||||
required: true,
|
||||
validator: (value) => value >= 0 && value <= 100,
|
||||
default: 50
|
||||
},
|
||||
//文字颜色
|
||||
color: {
|
||||
type: String,
|
||||
default: '#FFFFFF'
|
||||
},
|
||||
//文字大小
|
||||
fontSize: {
|
||||
type: String,
|
||||
default: '24rpx'
|
||||
},
|
||||
//进度条颜色
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: '#5cb85c'
|
||||
},
|
||||
//进度条底色颜色
|
||||
dsColor: {
|
||||
type: String,
|
||||
default: '#f2f2f2'
|
||||
},
|
||||
//进度条高度
|
||||
height: {
|
||||
type: String,
|
||||
default: '28rpx'
|
||||
},
|
||||
//进度条圆角弧度
|
||||
borderRadius: {
|
||||
type: String,
|
||||
default: '8rpx'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
progressWidth() {
|
||||
return `${this.progress}%`
|
||||
},
|
||||
percentage() {
|
||||
return Math.round(this.progress)
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.progress-bar {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background-color: #f2f2f2;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.percentage {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
color: #666;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 24rpx;
|
||||
user-select: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.progress {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.card-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.progress-bar1 {
|
||||
position: relative;
|
||||
width: 90%;
|
||||
background-color: #f2f2f2;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.percentage1 {
|
||||
color: #666;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.progress1 {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,6 @@
|
|||
### 1、本插件可免费下载使用;
|
||||
### 2、未经许可,严禁复制本插件派生同类插件上传插件市场;
|
||||
### 3、未经许可,严禁在插件市场恶意复制抄袭本插件进行违规获利;
|
||||
### 4、对本软件的任何使用都必须遵守这些条款,违反这些条款的个人或组织将面临法律追究。
|
||||
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
{
|
||||
"id": "liu-progressbar",
|
||||
"displayName": "进度条组件",
|
||||
"version": "1.0.3",
|
||||
"description": "自定义进度条组件,支持设置文字内显、当前进度、文字颜色、文字大小、进度条颜色、进度条底色、进度条高度、进度条圆角弧度",
|
||||
"keywords": [
|
||||
"进度条",
|
||||
"百分比",
|
||||
"进度"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "u"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "u",
|
||||
"app-nvue": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "u",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "u",
|
||||
"钉钉": "u",
|
||||
"快手": "u",
|
||||
"飞书": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
### liu-progressbar适用于uni-app项目的进度条组件
|
||||
### 本组件目前兼容微信小程序、H5
|
||||
### 本组件支持自定义,支持设置文字内显、当前进度、文字颜色、文字大小、进度条颜色、进度条底色、进度条高度、进度条圆角弧度
|
||||
# --- 扫码预览、关注我们 ---
|
||||
|
||||
## 扫码关注公众号,查看更多插件信息,预览插件效果!
|
||||
|
||||
![](https://uni.ckapi.pro/uniapp/publicize.png)
|
||||
|
||||
### 使用方式
|
||||
``` html
|
||||
<view class="title">文字内显</view>
|
||||
<liu-progressbar :progress="70" color="#FFFFFF" :height="'40rpx'" />
|
||||
<view class="title">文字外显</view>
|
||||
<liu-progressbar :textInside="false" :progress="70" color="#333333" :height="'40rpx'" />
|
||||
<view class="title">自定义高度</view>
|
||||
<liu-progressbar :progress="70" color="#FFFFFF" :height="'25rpx'" />
|
||||
<view class="title">自定义圆角弧度</view>
|
||||
<liu-progressbar :progress="70" color="#FFFFFF" :height="'40rpx'" :borderRadius="'40rpx'" />
|
||||
<view class="title">自定义进度条颜色</view>
|
||||
<liu-progressbar :progress="70" bgColor="red" color="#FFFFFF" :height="'40rpx'" />
|
||||
<view class="title">自定义底色</view>
|
||||
<liu-progressbar :progress="70" dsColor="red" color="#FFFFFF" :height="'40rpx'" />
|
||||
```
|
||||
|
||||
### 属性说明
|
||||
| 名称 | 类型 | 默认值 | 描述 |
|
||||
| ----------------------------|---------------- | ---------------------- | ---------------|
|
||||
| textInside | Boolean | true | 文字是否内显
|
||||
| progress | Number | 50 | 当前进度
|
||||
| color | String | #FFFFFF | 文字颜色
|
||||
| fontSize | String | 24rpx | 文字大小
|
||||
| bgColor | String | #5cb85c | 进度条颜色
|
||||
| dsColor | String | #f2f2f2 | 进度条底色颜色
|
||||
| height | String | 28rpx | 进度条高度
|
||||
| borderRadius | String | 8rpx | 进度条圆角弧度
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
const requestPath = "";
|
||||
function post(url, data = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (data && data.loading !== false) {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
mask: true,
|
||||
});
|
||||
}
|
||||
uni.request({
|
||||
url: requestPath + url,
|
||||
data: {
|
||||
...data,
|
||||
},
|
||||
header: {
|
||||
"Content-type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
method: "POST",
|
||||
success: (res) => {
|
||||
if (data && data.loading !== false) {
|
||||
uni.hideLoading();
|
||||
}
|
||||
if (res.data.result === "success") {
|
||||
resolve(res.data);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.msg || "系统开小差了",
|
||||
icon: "none",
|
||||
});
|
||||
if (res.data.msg && res.data.msg.indexOf("动火超期") !== -1) {
|
||||
uni.navigateBack();
|
||||
}
|
||||
reject(res.data);
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
if (data && data.loading !== false) {
|
||||
uni.hideLoading();
|
||||
}
|
||||
uni.showToast({
|
||||
title: "网络错误请重试",
|
||||
icon: "none",
|
||||
});
|
||||
reject(err);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function upload(url, data = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (data && data.loading !== false) {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
mask: true,
|
||||
});
|
||||
}
|
||||
uni.uploadFile({
|
||||
url: requestPath + url,
|
||||
filePath: data.filePath,
|
||||
name: data.name || "FFILE",
|
||||
formData:
|
||||
{
|
||||
...data.formData,
|
||||
} || {},
|
||||
success: (res) => {
|
||||
if (data && data.loading !== false) {
|
||||
uni.hideLoading();
|
||||
}
|
||||
if (JSON.parse(res.data).result === "success") {
|
||||
resolve(JSON.parse(res.data));
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: JSON.parse(res.data).msg || "系统开小差了",
|
||||
icon: "none",
|
||||
});
|
||||
reject(JSON.parse(res.data));
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: "网络错误请重试",
|
||||
icon: "none",
|
||||
});
|
||||
reject(err);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export { post, upload };
|