瀏覽代碼

智慧教学

西昌分支
yxq 2 週之前
父節點
當前提交
d9cb8fd669
共有 11 個檔案被更改,包括 952 行新增303 行删除
  1. +15
    -8
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/common/mixins.js
  2. +12
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages.json
  3. +24
    -10
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/SmartEducation/AIres.vue
  4. +171
    -68
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/SmartEducation/list.vue
  5. +112
    -36
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/SmartEducation/record.vue
  6. +75
    -29
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/SmartEducation/single.vue
  7. +145
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/practiceCourse/AIres.vue
  8. +107
    -0
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/practiceCourse/detail.vue
  9. +79
    -33
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/practiceCourse/list.vue
  10. +212
    -119
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/practiceCourse/single.vue
  11. 二進制
      Learun.Framework.Ultimate V7/LearunApp-2.2.0/static/img-smartEducation/video.png

+ 15
- 8
Learun.Framework.Ultimate V7/LearunApp-2.2.0/common/mixins.js 查看文件

@@ -254,8 +254,8 @@ export default {
// 对网络错误、返回错误码、登录状态失效等情况做了相应处理
// url 为请求地址
// data 为请求附带的提交数据
async HTTP_POST(url, data, showTips) {
const [err, res] = await this.requestBase(url, data, null, 'POST')
async HTTP_POST(url, data, showTips,requestOption={}) {
const [err, res] = await this.requestBase(url, data, null, 'POST',requestOption)

return this.handleResult(err, res, showTips)
},
@@ -267,7 +267,7 @@ export default {
// filePath 为临时文件的路径
// formData 为请求附带的提交数据
async HTTP_UPLOAD(filePath, formData,guid) {
const [err, res] = await this.UPLOAD('/learun/adms/annexes/wxupload', filePath, formData,guid)
const [err, res] = await this.UPLOAD('/learun/adms/annexes/wxupload', filePath, formData,guid='')

return this.handleResult(err, res)
},
@@ -316,7 +316,7 @@ export default {
// 返回结果是一个数组: [error, result]
// error 表示错误,一般是网络错误,请求很可能根本没有发出
// result 包含 { statusCode, data } 分别表示状态码、接口返回的数据
async UPLOAD(url, filePath, formData,guid) {
async UPLOAD(url, filePath, formData,guid,uploadTaskOptions=null) {
const uploadUrl = this.handleUrl(url)
const query = {
loginMark: this.getLoginMark(),
@@ -352,13 +352,19 @@ export default {
// #endif

// #ifndef MP-DINGTALK
return uni.uploadFile({
let options = {
url: uploadUrl,
filePath:filePath,
name: 'file',
fileType: 'image',
formData: query
}).then(([err, result]) => {
formData: query,
timeout:60000*20
}
if(uploadTaskOptions){
Object.assign(options,uploadTaskOptions)
return uni.uploadFile(options)
}
return uni.uploadFile(options).then(([err, result]) => {
if (!err) {
result.data = JSON.parse(result.data)
return [null, result]
@@ -622,7 +628,7 @@ export default {
},

// 【内部方法】HTTP 请求基础方法
async requestBase(url, data, header, method = 'GET') {
async requestBase(url, data, header, method = 'GET',requestOption={}) {
const requestUrl = this.handleUrl(url)
const requestHeader = header || {}

@@ -641,6 +647,7 @@ export default {
return uni.request({
url: requestUrl,
method,
...requestOption,
header: {
'content-type': 'application/x-www-form-urlencoded',
...requestHeader


+ 12
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages.json 查看文件

@@ -1187,6 +1187,18 @@
"navigationBarTitleText": "上传课程",
"enablePullDownRefresh": false
}
}, {
"path": "pages/EducationalAdministration/practiceCourse/detail",
"style": {
"navigationBarTitleText": "课程详情",
"enablePullDownRefresh": false
}
},{
"path": "pages/EducationalAdministration/practiceCourse/AIres",
"style": {
"navigationBarTitleText": "结果",
"enablePullDownRefresh": false
}
},
// 统一应用
{


+ 24
- 10
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/SmartEducation/AIres.vue 查看文件

@@ -16,21 +16,17 @@
<view class="sectionTitle">
教学环节
</view>
<textarea class="textarea" v-model="form.text" :maxlength="800" placeholder="请输入"></textarea>
<textarea class="textarea" disabled v-model="form.TEACHSTEPS" auto-height placeholder=""></textarea>
<view class="line"></view>
<view class="sectionTitle">
教学特色
</view>
<textarea class="textarea" v-model="form.text" :maxlength="800" placeholder="请输入"></textarea>
<textarea class="textarea" disabled v-model="form.FEATURE" auto-height placeholder=""></textarea>
<view class="resText">
<view class="resTitle">
AI分析结果:
</view>
<text>
压力是指垂直作用在物体表面上的力,它的方向总是指向支持物并和支持物的表面垂直。
在具体的问题中,压力的方向和支持物的位置有关。
这里必须要明确的是,我们不能有压力的方向总是竖直向下的错误认识。
</text>
<textarea class="restextarea" disabled v-model="form.res" auto-height placeholder=""></textarea>
</view>
</view>
</view>
@@ -41,11 +37,18 @@
data() {
return {
form:{
text:''
res:''
}
}
},
async mounted(){
this.init()
},
methods: {
init(){
let param = this.GET_PARAM()
this.form = param
},
}
}
</script>
@@ -115,9 +118,15 @@
font-size: 13px;
margin-top: 20rpx;
width: 100%;
height: 260rpx;
min-height: 160rpx;
margin-bottom: 30rpx;
}
.uni-textarea-wrapper{
height: unset;
}
.uni-textarea-compute{
height: unset;
}
.line{
margin-left: -40rpx;
border-bottom: 2rpx dashed #ccc;
@@ -125,6 +134,7 @@
}
}
.resText{
margin-top: 20rpx;
margin-left: -40rpx;
border-radius: 16rpx;
background-color: #E7F3FC;
@@ -136,7 +146,11 @@
font-weight: 700;
margin-bottom: 20rpx;
}
text{
.restextarea {
width: 100%;
font-size: 13px;
margin-top: 20rpx;
min-height: 200rpx;
color: #333;
}
}

+ 171
- 68
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/SmartEducation/list.vue 查看文件

@@ -1,67 +1,148 @@
<template>
<view>
<view class="banner">
<img src="@/static/img-smartEducation/banner.png" alt=""
@click="NAV_TO('/pages/EducationalAdministration/SmartEducation/list')">
</view>
<view class="myLession" @click="NAV_TO('/pages/EducationalAdministration/practiceCourse/list')">
<view class="title">
我的自主练习课程
</view>
<view class="rightICON">
>
</view>
</view>
<view class="listTitle">
课程
</view>
<view class="list">
<view class="item" v-for="(item,index) in list" :key="index" @click="NAV_TO('./single',{id:item.id||''})">
<view class="row1">
{{item.lesson}}·七年级
</view>
<view class="row2 wrap1">
{{item.name}}
</view>
<view class="itemTitleBg" :style="{background:getColor(index)}"></view>
<view class="itemTitle" :style="{background:getColor(index)}">
{{item.lesson}}
</view>
</view>
<!-- 主列表页 -->
<view class="mainpage">
<!-- 滚动列表,跨端支持上拉/下拉 -->
<l-scroll-list v-if="ready" @pullDown="pullDown" @toBottom="fetchList()" ref="list">
<view class="banner">
<img src="@/static/img-smartEducation/banner.png" alt=""/>
</view>
<view class="myLession" @click="NAV_TO('/pages/EducationalAdministration/practiceCourse/list')">
<view class="title">
我的自主练习课程
</view>
<view class="rightICON">
>
</view>
</view>
<view class="listTitle">
课程
</view>
<l-customlist :tips="loadState" showTips class="list">
<!-- 单条记录 -->
<view class="customlist-item item" v-for="(item,index) of list" :key="item.ID" @click="NAV_TO('./single',{id:item.ID})">
<view class="row1 wrap2">
{{item.Subject}}·{{item.ClassName}}
</view>
<view class="row2 wrap2">
{{item.Name}}
</view>
<view class="itemTitleBg" :style="{background:getColor(index)}"></view>
<view class="itemTitle" :style="{background:getColor(index)}">
{{item.Subject}}
</view>
</view>
</l-customlist>
</l-scroll-list>
</view>
</view>
</template>

<script>
export default{
data(){
return{
colors:['#FF5858','#28BD59','#6194F9','#2CBCF6','#A370DF','#D28833','#30D4AE','#FDB401','#FB7436'],
list:[{lesson:'语文',name:'一颗小杨树'},{lesson:'数学',name:'圆柱与圆锥'},{lesson:'物理',name:'压力与压强'}],
export default {
data() {
return {
ready: false,
colors: ['#FF5858', '#28BD59', '#6194F9', '#2CBCF6', '#A370DF', '#D28833', '#30D4AE', '#FDB401',
'#FB7436'
],
list: [],
ready: false,
tips: '加载中...',
loadState: '向下翻以加载更多',

// 列表与分页信息
page: 1,
total: 2,
list: [],
searchData: {},
}
},
methods:{
getColor(index){
async mounted() {
await this.init()
this.ready = true
},
methods: {
async init() {
await this.fetchList()
},
getColor(index) {
let length = this.colors.length
if(index+1>length){
index = (index+1)%length
return this.colors[index-1]
if (index + 1 > length) {
index = (index + 1) % length
return this.colors[index]
}
return this.colors[index]
}
},
// 拉取列表
async fetchList(isConcat = true) {
if (this.page > this.total) {
return
}
// this.loadState = '数据加载中...'
const result = await this.HTTP_GET(
'learun/adms/smartEducation/smartTeachCourseList', {
// 这里 sidx 表示排序字段,sord 表示排序方式(DESC=降序,ASC=升序)
// 代码生成器生成时默认按照主键排序,您可以修改成按创建时间的字段降序
pagination: {
rows: 10,
page: this.page,
sidx: '',
sord: 'DESC',
sidx: ''
},
queryJson: JSON.stringify(this.searchData)
},
'加载数据时出错'
)
if (!result) {
return
}

this.total = result.total
this.page = result.page + 1
this.list = isConcat ? this.list.concat(result.rows) : result.rows;

// this.tips = `已加载 ${Math.min(result.page, result.total)} / ${result.total} 页,共 ${result.records} 项`
// this.loadState = result.page >= result.total ? '已加载所有项目' : '向下翻以加载更多'
this.loadState = result.page >= result.total ? '' : ''
},
// 刷新清空列表
async refreshList(isConcat = true) {
this.page = 1
this.total = 2
this.list = []
await this.fetchList(isConcat)
},
// 列表下拉
pullDown() {
this.refreshList().then(() => {
this.$refs.list.stopPullDown()
})
},
}
}
</script>

<style scoped>
@import '~@/common/css/sidepage.less';
@import '~@/common/css/customlist.less';
.padding.text-gray.text-center{
width: 100%!important;
}
.banner {
text-align: center;
margin: 30rpx 30rpx 24rpx 30rpx;
img{

img {
width: 100%;
}
}
.myLession{

.myLession {
margin: 0 30rpx 30rpx 30rpx;
border-radius: 16rpx;
overflow: hidden;
@@ -70,30 +151,35 @@
align-items: center;
background-color: #fff;
padding: 30rpx 24rpx;
.title{

.title {
font-size: 14px;
color: #333;
}
.rightICON{

.rightICON {
transform: scaleY(2);
}
}
.listTitle{

.listTitle {
font-size: 18px;
color: #333;
padding: 0 30rpx;
font-weight: 700;
margin-top: 34rpx;
}
.list{

.list {
margin-top: 34rpx;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 30rpx;
font-size: 12px;
.item{
box-shadow: 0 0 20rpx 0rpx rgba(0,0,0,0.1);

.item {
box-shadow: 0 0 20rpx 0rpx rgba(0, 0, 0, 0.1);
width: 48%;
background-color: #fff;
border-radius: 14rpx;
@@ -101,45 +187,62 @@
position: relative;
margin-top: 30rpx;
margin-bottom: 34rpx;
.row1{

.row1 {
color: #666;
text-align: right;
padding-left: 80rpx;
max-height: 70rpx;
}
.row2{

.row2 {
margin-top: 24rpx;
color: #333;
max-height: 72rpx;
}
.itemTitle{
position: absolute;top: -30rpx;left: 30rpx;
font-size: 13px;font-weight: 700;
text-align: center;line-height: 80rpx;
width: 80rpx;height: 80rpx;

.itemTitle {
position: absolute;
top: -30rpx;
left: 30rpx;
font-size: 13px;
font-weight: 700;
text-align: center;
line-height: 80rpx;
width: 80rpx;
height: 80rpx;
border-radius: 16rpx;
color: #fff;
transform: rotate(12deg);
}
.itemTitleBg{
position: absolute;top: 4rpx;left: 56rpx;
width: 60rpx;height: 60rpx;border-radius: 12rpx;

.itemTitleBg {
position: absolute;
top: 4rpx;
left: 56rpx;
width: 60rpx;
height: 60rpx;
border-radius: 12rpx;
transform: rotate(-12deg);
opacity: 0.1;
}
}
}

/* 文字溢出 */
.wrap1 {
display: block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
display: block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.wrap2 {
display: block;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
word-break: break-all;
display: block;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
word-break: break-all;
}
</style>

+ 112
- 36
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/SmartEducation/record.vue 查看文件

@@ -1,26 +1,29 @@
<template>
<view>
<view style="padding-bottom:30rpx;">
<view class="item" v-for="(item,index) in list" :key="index">
<view class="time">
11-01 08:30
</view>
<view class="textBox">
<view class="wrap2 text">
教学环节:压力是指垂直作用在物体表面上的力,它的方向总是指向支持物并和支持物的表面垂直。
在具体的问题中,压力的方向和支持物的位置有关。
这里必须要明确的是,我们不能有压力的方向总是竖直向下的错误认识。
<!-- 主列表页 -->
<view class="mainpage">
<!-- 滚动列表,跨端支持上拉/下拉 -->
<l-scroll-list @pullDown="pullDown" @toBottom="fetchList()" ref="list">
<l-customlist :tips="loadState" showTips>
<!-- 单条记录 -->
<view class="customlist-item item" v-for="(item,index) of list" :key="item.ID">
<view class="time">
{{item.StudyTime}}
</view>
<view class="textBox">
<view class="wrap2 text">
教学环节:{{item.Feature}}
</view>
<view class="wrap2 text">
教学特色:{{item.TeachSteps}}
</view>
<view class="lookAll" @click="NAV_TO('./single',{id:item.ID,type:'view'})">
查看全部
</view>
</view>
</view>
<view class="wrap2 text">
教学特色:压力是指垂直作用在物体表面上的力,它的方向总是指向支持物并和支持物的表面垂直。
在具体的问题中,压力的方向和支持物的位置有关。
这里必须要明确的是,我们不能有压力的方向总是竖直向下的错误认识。
</view>
<view class="lookAll" @click="NAV_TO('./single',{id:item.id,type:'view'})">
查看全部
</view>
</view>
</view>
</l-customlist>
</l-scroll-list>
</view>
</view>
</template>
@@ -29,29 +32,98 @@
export default {
data() {
return {
list:[{id:157455241},{id:45555252}]
list: [],

// 页面相关参数
tips: '加载中...',
loadState: '向下翻以加载更多',

page: 1,
total: 2,
list: []
}
},
async mounted() {
await this.init()
this.ready = true
},
methods: {
async init() {
await this.fetchList()
},

// 列表下拉
pullDown() {
this.refreshList().then(() => {
this.$refs.list.stopPullDown()
})
},
// 刷新清空列表
async refreshList(isConcat = true) {
this.page = 1
this.total = 2
this.list = []

await this.fetchList(isConcat)
},
// 拉取列表
async fetchList(isConcat = true) {
if (this.page > this.total) {
return
}
this.loadState = '数据加载中...'
const result = await this.HTTP_GET(
'learun/adms/smartEducation/smartCourseLearnRecordList', {
// 这里 sidx 表示排序字段,sord 表示排序方式(DESC=降序,ASC=升序)
// 代码生成器生成时默认按照主键排序,您可以修改成按创建时间的字段降序
pagination: {
rows: 10,
page: this.page,
sidx: 'StudyTime',
sord: 'DESC',
},
queryJson: JSON.stringify(this.searchData)
},
'加载数据时出错'
)
if (!result) {
return
}

this.total = result.total
this.page = result.page + 1
this.list = isConcat ? this.list.concat(result.rows) : result.rows;

this.tips = `已加载 ${Math.min(result.page, result.total)} / ${result.total} 页,共 ${result.records} 项`
this.loadState = result.page >= result.total ? '已加载所有项目' : '向下翻以加载更多'
},
}
}
</script>

<style scoped>
uni-page-body{
@import '~@/common/css/sidepage.less';
@import '~@/common/css/customlist.less';
uni-page-body {
background: #fff;
height: 100%;
overflow: auto;
}
.item{
.mainpage{
background-color: #fff;
}
.item {
padding: 40rpx 30rpx 0rpx 50rpx;
border-radius: 16rpx;
.time{
border: none;

.time {
color: #333;
font-size: 15px;
font-weight: 700;
position: relative;
&::before{

&::before {
content: '';
background-color: #0C86D8;
position: absolute;
@@ -63,19 +135,23 @@
top: 8rpx;
}
}
.textBox{

.textBox {
background-color: #F5F5F5;
border-radius: 16rpx;
margin-top: 30rpx;
padding: 20rpx;
.text{

.text {
color: #333;
margin-bottom: 20rpx;
&:last-child{

&:last-child {
margin-bottom: 0;
}
}
.lookAll{

.lookAll {
text-align: center;
color: #0C86D8;
margin-top: 20rpx;
@@ -83,13 +159,13 @@
}
}
}
.wrap2 {
display: block;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
word-break: break-all;
display: block;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
word-break: break-all;
}
</style>

+ 75
- 29
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/SmartEducation/single.vue 查看文件

@@ -1,14 +1,14 @@
<template>
<view class="">
<video v-if="!isRecordDetail" id="myVideo" :src="form.url" controls></video>
<view v-if="ready">
<video v-if="!isRecordDetail" id="myVideo" :src="path" controls></video>
<view :class="{title:true,isRecordDetail:isRecordDetail}">
<view class="row1">{{form.title}}</view>
<view class="row1">{{detail.Name}}</view>
<view class="row2">
<view>
物理·八年级
{{detail.Subject}}·{{detail.ClassName}}
</view>
<view>
11-01 08:30
<view v-if="isRecordDetail">
{{detail.time}}
</view>
</view>
</view>
@@ -16,14 +16,20 @@
<view class="sectionTitle">
教学环节
</view>
<textarea class="textarea" v-model="form.text" :maxlength="800" placeholder="请输入"></textarea>
<textarea class="textarea" v-model="form.TEACHSTEPS" :disabled="isRecordDetail" auto-height placeholder="请输入"></textarea>
</view>
<view class="section">
<view class="sectionTitle">
教学特色
</view>
<textarea class="textarea" v-model="form.text" :maxlength="800" placeholder="请输入"></textarea>
<textarea class="textarea" v-model="form.FEATURE" :disabled="isRecordDetail" auto-height placeholder="请输入"></textarea>
</view>
<!-- <view class="resText" v-if="isRecordDetail">
<view class="resTitle">
AI分析结果:
</view>
<textarea class="restextarea" disabled v-model="detail.AIContent" auto-height placeholder=""></textarea>
</view> -->
<view v-if="!isRecordDetail" class="blank"></view>
<view class="bottomFixed" v-if="!isRecordDetail">
<view class="left" @click="NAV_TO('./record')">
@@ -52,43 +58,62 @@
</template>

<script>
import customFormMixins from '@/common/customform.js'
export default {
mixins: [customFormMixins],
data() {
return {
form: {
url: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4',
title: '压力与压强',
text: '',
TEACHSTEPS:'',
FEATURE:'',
VideoPath:'',
},
path:'',
detail:{},
ready:false,
id:'',
loading:false,
btnDisable: false,
isRecordDetail:false
isRecordDetail:false,
}
},
async onLoad({ type, id }) {
await this.init(type, id)
await this.init(type, id)
this.ready = true
},
methods: {
init(type,id){
async init(type,id){
this.id = id
if(type == 'view'){
this.isRecordDetail = true
let res = await this.HTTP_GET('learun/adms/smartEducation/smartCourseLearnRecordInfo',this.id)
if(!res)return
this.form.FEATURE = res.Feature
this.form.TEACHSTEPS = res.TeachSteps
let res1 = await this.HTTP_GET('learun/adms/smartEducation/smartTeachCourseInfo',res.CourseId)
this.detail = res1
this.SET_TITLE('记录详情')
}else{
let res = await this.HTTP_GET('learun/adms/smartEducation/smartTeachCourseInfo',this.id)
if(!res)return
if(res.VideoPath){
this.form.VideoPath = res.VideoPath
this.path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(res.VideoPath, true)
}
this.detail = res
}
// this.HTTP_GET('/',{}).then(res=>{
// if(!res)return
// this.form = res.data
// })
},
AICheckClick() {
// this.loading = true
// this.HTTP_POST('/',{}).then(res=>{
// this.loading = false
// if(!res){
// return
// }
// this.NAV_TO('/')
// })
this.NAV_TO('./AIres')
async AICheckClick() {
if(!this.form.TEACHSTEPS||!this.form.FEATURE){
this.TOAST('请完善表单信息')
return
}
this.loading = true
let res = await this.HTTP_POST('learun/adms/smartEducation/smartTeachCourseAdd',{...this.form,COURSEID:this.id},null,{timeout:60000*10})
if(!res)return
this.loading = false
this.NAV_TO('./AIres',{res,...this.form},true)
}
}
}
@@ -153,7 +178,28 @@
font-size: 13px;
margin-top: 20rpx;
width: 100%;
height: 260rpx;
min-height: 260rpx;
}
}
.resText{
margin: 30rpx;
border-radius: 16rpx;
background-color: #E7F3FC;
padding: 30rpx;
min-height: 100px;
.resTitle{
font-size: 15px;
color: #0C86D8;
font-weight: 700;
margin-bottom: 20rpx;
}
.restextarea {
width: 100%;
font-size: 13px;
margin-top: 20rpx;
min-height: 200rpx;
color: #333;
}
}



+ 145
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/practiceCourse/AIres.vue 查看文件

@@ -0,0 +1,145 @@
<template>
<view>
<view style="text-align: center;">
<view class="AIresImg">
<view class="border">
<view class="bg">
<img src="@/static/img-smartEducation/AI.png" alt="">
</view>
</view>
</view>
</view>
<view class="title">
AI分析结果
</view>
<view class="section">
<view class="resText">
<textarea class="restextarea" disabled v-model="form.AIContent" auto-height placeholder=""></textarea>
</view>
</view>
</view>
</template>

<script>
export default {
data() {
return {
form:{
AIContent:''
}
}
},
async mounted(){
this.init()
},
methods: {
init(){
let param = this.GET_PARAM()
this.form = param
},
}
}
</script>

<style>
uni-page-body{
height: 100%;
background: linear-gradient(to bottom,#0C86D8,#B0D7F2);
overflow-y: auto;
}
.AIresImg{
display: inline-block;
margin: 30rpx auto;
.border{
border-radius: 50%;
padding: 30rpx;
border: 8rpx solid #fff;
border-right-style: dashed;
border-left-style: dashed;
transform: rotate(-45deg);
}
.bg{
padding: 30rpx;
background: rgba(255, 255, 255,0.3);
border-radius: 50%;
}
img{
width: 80rpx;
height: 80rpx;
transform: rotate(45deg);
}
}
.title{
color: #fff;
font-size: 20px;
text-align: center;
font-weight: 700;
}
.section {
box-shadow: 0 0 20rpx 0rpx rgba(0, 0, 0, 0.1);
background-color: #fff;
margin: 30rpx 30rpx;
border-radius: 16rpx;
padding: 30rpx;
/* padding-left: 70rpx; */
.sectionTitle {
color: #333;
font-weight: 700;
font-size: 15px;
position: relative;
&::before {
content: '';
background-color: #0081FF;
display: block;
position: absolute;
width: 16rpx;
height: 16rpx;
border-radius: 50%;
top: 15rpx;
left: -36rpx;
}
}
.textarea {
font-size: 13px;
margin-top: 20rpx;
width: 100%;
min-height: 160rpx;
margin-bottom: 30rpx;
}
.uni-textarea-wrapper{
height: unset;
}
.uni-textarea-compute{
height: unset;
}
.line{
margin-left: -40rpx;
border-bottom: 2rpx dashed #ccc;
margin-bottom: 30rpx;
}
}
.resText{
/* margin-top: 20rpx;
margin-left: -40rpx;
border-radius: 16rpx;
background-color: #E7F3FC;
padding: 30rpx; */
min-height: 100px;
.resTitle{
font-size: 15px;
color: #0C86D8;
font-weight: 700;
margin-bottom: 20rpx;
}
.restextarea {
width: 100%;
font-size: 13px;
margin-top: 20rpx;
min-height: 200rpx;
color: #333;
}
}
</style>

+ 107
- 0
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/practiceCourse/detail.vue 查看文件

@@ -0,0 +1,107 @@
<template>
<view v-if="ready">
<view class="uploadBox">
<view class="chooseBox">
<view class="fileBox">
<video :src="form.VideoPath"></video>
</view>
</view>
</view>
<view class="fromItemBox">
<view class="title wrap1">{{form.Name}}</view>
<view class="time">{{form.CreateTime}}</view>
</view>
<view class="resText">
<view class="resTitle">
AI分析结果:
</view>
<textarea class="textarea" v-model="form.AIContent" disabled auto-height placeholder=""></textarea>
</view>
</view>
</template>

<script>
import customFormMixins from '@/common/customform.js'
export default {
mixins: [customFormMixins],
data() {
return {
form: {
name:'',
VideoPath:'',
},
uploadList:[],
ready:false,
}
},
async onLoad({ type, id }) {
await this.init(type, id)
},
methods: {
async init(type,id){
let res = await this.HTTP_GET('learun/adms/smartEducation/smartSelfCourseInfo',id)
if(!res)return
if(res.VideoPath)res.VideoPath = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(res.VideoPath, true)
this.form = res
this.ready = true
},
}
}
</script>

<style scoped>
.uploadBox{
.chooseBox{
height: 400rpx;
border-radius: 16rpx;
.fileBox{
height: 100%;
overflow: hidden;
uni-video{
height: 100%;
width: 100%;
}
}
}
}
.fromItemBox{
background-color: #fff;
padding: 30rpx;
.title{
color: #333;
font-size: 17px;
font-weight: 700;
}
.time{
margin-top: 20rpx;
color: #666;
font-size: 12px;
}
}
.resText{
border-radius: 16rpx;
background-color: #fff;
padding: 30rpx;
min-height: 100px;
margin-top: 30rpx;
.resTitle{
font-size: 15px;
color: #0C86D8;
font-weight: 700;
margin-bottom: 20rpx;
}
.textarea{
color: #333;
font-size: 14px;
min-height: 160rpx;
width: 100%;
}
}
/* 文字溢出 */
.wrap1 {
display: block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
</style>

+ 79
- 33
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/practiceCourse/list.vue 查看文件

@@ -1,24 +1,33 @@
<template>
<view class="page">
<!-- 主列表页 -->
<view class="mainpage" style="padding-top: 80rpx;">
<view class="mainpage">
<!-- 滚动列表,跨端支持上拉/下拉 -->
<l-scroll-list v-if="ready" @pullDown="pullDown" @toBottom="fetchList()" ref="list">
<l-scroll-list v-if="ready&&total" @pullDown="pullDown" @toBottom="fetchList()" ref="list">
<l-customlist :tips="loadState" showTips>
<!-- 单条记录 -->
<view class="customlist-item" v-for="(item,index) of list" :key="item.Id">
<view class="customlist-item" v-for="(item,index) of list" :key="item.ID" @click="NAV_TO('./detail',{id:item.ID})">
<view class="left">
<img src="@/static/img-smartEducation/video.png" alt="">
</view>
<view class="right">
<view class="wrap2">
{{item.Name}}
</view>
<view class="time">
{{item.CreateTime}}
</view>
</view>
</view>
</l-customlist>
</l-scroll-list>
<view class="emptyBox">
<view class="emptyBox" v-if="total<=1&&!list.length">
<img src="@/static/empty.png" alt="">
<view>暂无上传课程</view>
</view>
</view>
<l-customlist-add @click="NAV_TO('./single')" />
<l-customlist-add @click="NAV_TO('./single',{type:'add'})" />
</view>
</template>
@@ -44,13 +53,13 @@ export default {
await this.init()
},
onUnload() {
// this.OFF('LogisticsManagement-Purchase_Work-list-change')
this.OFF('list-change')
},
methods: {
// 页面初始化
async init() {
// this.ON('LogisticsManagement-Purchase_Work-list-change', this.reset)
this.ON('list-change', this.refreshList)
await this.fetchList()
this.ready = true
},
@@ -58,18 +67,18 @@ export default {
// 拉取列表
async fetchList(isConcat = true) {
if (this.page > this.total) { return }
// const result = await this.HTTP_GET(
// 'learun/adms/purchasework/pagelist',
// {
// // 这里 sidx 表示排序字段,sord 表示排序方式(DESC=降序,ASC=升序)
// // 代码生成器生成时默认按照主键排序,您可以修改成按创建时间的字段降序
// pagination: { rows: 10, page: this.page, sidx: 'SubmitTime', sord: 'DESC',sidx:'' },
// queryJson: JSON.stringify(this.searchData)
// },
// '加载数据时出错'
// )
// if (!result) { return }
this.loadState = '数据加载中...'
const result = await this.HTTP_GET(
'learun/adms/smartEducation/smartSelfCourseList',
{
// 这里 sidx 表示排序字段,sord 表示排序方式(DESC=降序,ASC=升序)
// 代码生成器生成时默认按照主键排序,您可以修改成按创建时间的字段降序
pagination: { rows: 10, page: this.page, sidx: 'CreateTime', sord: 'DESC' },
queryJson: JSON.stringify(this.searchData)
},
'加载数据时出错'
)
if (!result) { return }
this.total = result.total
this.page = result.page + 1
this.list = isConcat ? this.list.concat(result.rows) : result.rows;
@@ -101,20 +110,41 @@ export default {
<style lang="less" scoped>
@import '~@/common/css/sidepage.less';
@import '~@/common/css/customlist.less';
.customlist-banner-action {
margin-top: 20rpx;
text-align: right;

.customlist-banner-action-btn {
display: inline-block;
padding: 4px 6px;
margin: 0 3px;
border-radius: 3px;
text-align: center;
@import '~@/common/css/customlist.less';
.customlist-item{
margin-top: 30rpx;
margin-left: 30rpx;
margin-right: 30rpx;
border: none;
border-top: none!important;
display: flex;
border-radius: 16rpx;
.left{
width: 240rpx;
height: 150rpx;
overflow: hidden;
border-radius: 12rpx;
img{
width: 100%;
height: 100%;
object-fit: cover;
}
}
.right{
flex: 1;
margin-left: 20rpx;
.wrap2{
color: #333;
font-size: 15px;
height: 84rpx;
line-height: 42rpx;
margin-top: 6rpx;
}
.time{
margin-top: 28rpx;
}
}
}

.emptyBox{
margin-top:100rpx;
text-align: center;
@@ -124,4 +154,20 @@ export default {
margin-bottom: 30rpx;
}
}

/* 文字溢出 */
.wrap1 {
display: block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.wrap2 {
display: block;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: -webkit-box;
word-break: break-all;
}
</style>

+ 212
- 119
Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/EducationalAdministration/practiceCourse/single.vue 查看文件

@@ -1,152 +1,245 @@
<template>
<view class="">
<view v-if="ready">
<view class="uploadBox">
<view class="uploadPercentage" v-if="edit&&uploadTimer">
<view class="textBox">
<text v-if="percentage != 100">上传中... {{uploadedSize||'--'}}M/{{needUploadSize||'--'}}M 预计还需要{{needUploadTime||'--'}}s</text>
<text style="color: #0C86D8;" v-if="percentage == 100">上传成功!</text>
</view>
<view class="percentageLine">
<view class="percentage" :style="{width:percentage+'%'}"></view>
</view>
</view>
<view class="chooseBox">
<view v-if="!uploadList.length" class="empty" @click="chooseFile">
<span>+</span>
</view>
<view v-else class="fileBox" @click="chooseFile">
<video :src="uploadList[0].path"></video>
</view>
</view>
</view>
<view class="fromItemBox">
<view class="title">课程名称</view>
<view class="inputBox">
<input type="text" :disabled="!edit&&disable" v-model="form.NAME" placeholder="请输入课程名称" />
</view>
</view>
<view v-if="edit" class="AIBtn" @click="submitClick" :style="{opacity:disable?0.6:1}">
AI分析
</view>
<uni-toast data-duration="100000000" v-if="loading">
<div class="uni-mask" style="background: rgba(17,17,17,0.3);"></div>
<div class="uni-toast" style="background: #fff!important;">
<i class="uni-icon_toast uni-loading"></i>
<p class="uni-toast__content" style="color: #000;font-size: 14px;"> AI分析中 </p>
</div>
</uni-toast>
</view>
</template>

<script>
import customFormMixins from '@/common/customform.js'
export default {
mixins: [customFormMixins],
data() {
return {
form: {},
loading:false,
form: {
NAME:'',
PICPATH:'',
VIDEOPATH:'',
},
ready:false,
edit:false,
disable:false,
uploadList:[],
uploadedSize:0,
needUploadSize:0,
percentage:0,
uploadTime:0,
uploadTimer:null,
needUploadTime:0,
}
},
async onLoad({ type, id }) {
await this.init(type, id)
},
methods: {
init(type,id){
if(type != 'add'){
this.isRecordDetail = true
this.SET_TITLE('记录详情')
async init(type,id){
if(type == 'add'){
}else{
// this.HTTP_GET('/',{}).then(res=>{
// if(!res)return
// this.form = res.data
// })
// let res = this.HTTP_GET('learun/adms/smartEducation/smartSelfCourseInfo',id)
// if(!res)return
// this.form = res
// if(this.form.folderId){
// let fileList = await this.convertToFormValue({type:'upload'},this.form.folderId)
// this.uploadList = fileList.map(e=>{
// e.uploaded = true
// return e
// })
// }
}
this.edit = ['edit','add'].includes(type)
this.ready = true
},
AICheckClick() {
// this.loading = true
// this.HTTP_POST('/',{}).then(res=>{
// this.loading = false
// if(!res){
// return
// }
// this.NAV_TO('/')
// })
this.NAV_TO('./AIres')
async submitClick(){
if(!this.edit||this.disable)return
if(!this.uploadList[0]){
this.TOAST('请选择上传课程视频')
return
}
if(!this.form.NAME){
this.TOAST('请输入课程名称')
return
}
this.loading = true
this.disable = true
let res = await this.uploadFile()
if(!res){
this.disable = false
this.loading = false
return
}
this.form.VIDEOPATH = res
let result = await this.HTTP_POST('learun/adms/smartEducation/smartSelfCourseAdd',this.form,null,{timeout:60000*10});
this.disable = false
this.loading = false
if(result){
this.EMIT('list-change')
this.JUMP_TO('./AIres',result,true)
}
},
async chooseFile() {
if(!this.edit||this.disable)return
uni.chooseVideo({
sourceType: ['album'],
compressed:false,
success: async (res) => {
this.uploadList = [
{path:res.tempFilePath,uploaded:false}
]
}
})
},
async uploadFile(){
return new Promise(async (resolve)=>{
let guid = this.form.VIDEOPATH || this.GUID()
if(!this.uploadList[0]||this.uploadList[0].uploaded){
resolve(guid)
return
}
this.uploadTimer = setInterval(()=>{
this.uploadTime++
},1000)
const uploadTask = await this.UPLOAD('/learun/adms/annexes/wxupload', this.uploadList[0].path,{},guid,{
complete:async ()=>{
if(this.percentage == 100){
this.uploadList[0].uploaded = true
// let fileList = await this.convertToFormValue({type:'upload'},guid)
// console.log(fileList)
resolve(guid)
}else{
resolve('')
}
uploadTask.abort();
clearInterval(this.uploadTimer)
this.uploadTimer = null
this.uploadTime = 0
this.percentage = 0
this.uploadedSize = 0
this.needUploadSize = 0
this.needUploadTime = 0
},
},true)
uploadTask.onProgressUpdate(res => {
this.percentage = res.progress
this.uploadedSize = this.bytesToMegabytesFixed(res.totalBytesSent)
this.needUploadSize = this.bytesToMegabytesFixed(res.totalBytesExpectedToSend)
this.needUploadTime = ((100-this.percentage)*this.uploadTime/this.percentage).toFixed(0)
})
})
},
bytesToMegabytesFixed(bytes) {
const megabytes = bytes / (1024 * 1024);
return megabytes.toFixed(2);
}
}
}
</script>

<style scoped>
uni-video {
width: 100%;
height: 400rpx;
}

.title {
uni-page-body{
height: 100%;
background-color: #fff;
font-size: 16px;
color: #333;
padding: 30rpx;
font-weight: 700;

.row2 {
display: flex;
justify-content: space-between;
font-size: 12px;
color: #666;
font-weight: 400;
margin-top: 20rpx;
}
&.isRecordDetail{
background-color: unset;
padding-bottom: 10rpx;
}
}

.section {
box-shadow: 0 0 20rpx 0rpx rgba(0, 0, 0, 0.1);
background-color: #fff;
margin: 30rpx 30rpx;
border-radius: 16rpx;
padding: 30rpx;
padding-left: 70rpx;

.sectionTitle {
color: #333;
font-weight: 700;
font-size: 15px;
position: relative;

&::before {
content: '';
background-color: #0081FF;
display: block;
position: absolute;
width: 16rpx;
height: 16rpx;
border-radius: 50%;
top: 15rpx;
left: -36rpx;
.uploadBox{
.uploadPercentage{
.textBox{
color: #666;
font-size: 12px;
padding: 30rpx;
}
.percentageLine{
margin: 0 -30rpx;
height: 6rpx;
background-color: #ccc;
.percentage{
height: 100%;
width: 0;
background-color: #0C86D8;
}
}
}

.textarea {
font-size: 13px;
margin-top: 20rpx;
width: 100%;
height: 260rpx;
.chooseBox{
padding: 30rpx;
height: 440rpx;
border-radius: 16rpx;
.empty{
border: 2rpx dashed #0C86D8;
border-radius: 16rpx;
height: 100%;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
font-size: 36px;
color: #0C86D8;
background-color: #F1F8FD;
}
.fileBox{
border: 2rpx dashed #0C86D8;
border-radius: 16rpx;
height: 100%;
overflow: hidden;
uni-video{
height: 100%;
width: 100%;
}
}
}
}

.blank {
height: 140rpx;
}

.bottomFixed {
box-shadow: 0 0 20rpx 0rpx rgb(0, 0, 0, 0.1);
position: fixed;
bottom: 0;
width: 100%;
height: 120rpx;
background-color: #fff;
padding: 18rpx 30rpx;
display: flex;
justify-content: space-between;

.left {
text-align: center;
.fromItemBox{
margin: 30rpx;
border-bottom: 2rpx solid #ccc;
color: #666;
font-size: 15px;
input{
margin-top:30rpx;
margin-bottom: 30rpx;
font-size: 16px;
color: #333;
font-size: 11px;
padding-right: 40rpx;
padding-top: 4rpx;

img {
width: 44rpx;
height: 44rpx;
margin-bottom: 4rpx;
}
}

.right {
flex: 1;
background-color: #0C86D8;
display: flex;
justify-content: center;
align-items: center;
font-weight: 700;
font-size: 15px;
color: #fff;
border-radius: 12rpx;

img {
height: 50rpx;
margin-right: 20rpx;
}
}
}
.AIBtn{
margin: 0 30rpx;
margin-top:160rpx;
color: #fff;
border-radius: 15rpx;
line-height: 86rpx;
background-color: #0C86D8;
text-align: center;
font-size: 16px;
}
</style>

二進制
Learun.Framework.Ultimate V7/LearunApp-2.2.0/static/img-smartEducation/video.png 查看文件

Before After
Width: 333  |  Height: 185  |  Size: 108 KiB

Loading…
取消
儲存