From 9a6cee214ccbba90c3421a775adca8c569a0648d Mon Sep 17 00:00:00 2001
From: bai <1643359946@qq.com>
Date: Sat, 25 May 2024 18:50:53 +0800
Subject: [PATCH 1/4] =?UTF-8?q?2024=E5=B9=B45=E6=9C=8825=E6=97=A5=20?=
=?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../kc/detection/KcDetectionMain.data.ts | 86 ++-
.../components/KcDetectionMainModal.vue | 23 +-
src/views/kc/detection/zyZhjsList.vue | 87 ++-
src/views/zy/jiaoXueDanYuanNeiRong/index2.vue | 321 +++++----
.../jiaoXueDanYuanNeiRong/index2.vue.allSave | 663 ++++++++++++++++++
.../zy/jiaoXueDanYuanNeiRong/stuIndex.vue | 13 +-
6 files changed, 1005 insertions(+), 188 deletions(-)
create mode 100644 src/views/zy/jiaoXueDanYuanNeiRong/index2.vue.allSave
diff --git a/src/views/kc/detection/KcDetectionMain.data.ts b/src/views/kc/detection/KcDetectionMain.data.ts
index 914e0e3..effc533 100644
--- a/src/views/kc/detection/KcDetectionMain.data.ts
+++ b/src/views/kc/detection/KcDetectionMain.data.ts
@@ -12,21 +12,26 @@ export const columns: BasicColumn[] = [
align: "center",
dataIndex: 'xnxq'
},
- {
- title: '授课日期',
- align: "center",
- dataIndex: 'createTime'
- },
{
title: '课程名称',
align: "center",
dataIndex: 'kcmc'
},
{
- title: '节次',
+ title: '授课日期',
+ align: "center",
+ dataIndex: ['ketangbiaoInfo', 'skrq']
+ },
+ {
+ title: '授课节次',
align: "center",
dataIndex: ['ketangbiaoInfo', 'hh']
},
+ {
+ title: '选课人数',
+ align: "center",
+ dataIndex: ['ketangbiaoInfo', 'xkrs'],
+ },
// {
// title: '任务编号',
@@ -49,25 +54,20 @@ export const columns: BasicColumn[] = [
// dataIndex: 'detectionUrl'
// },
{
- title: '检测次数',
+ title: '抓取次数',
align: "center",
dataIndex: 'detectionNum'
},
{
- title: '人数(累加)',
+ title: '累计抓取人数',
align: "center",
dataIndex: 'allNum'
},
{
- title: '平均数',
+ title: '平均抓取人数',
align: "center",
dataIndex: 'averageNum',
},
- {
- title: '选课人数',
- align: "center",
- dataIndex: ['ketangbiaoInfo', 'xkrs'],
- },
{
title: '出勤率',
align: "center",
@@ -108,18 +108,22 @@ export const formSchema: FormSchema[] = [
field: 'xnxq',
component: 'Input',
},
- {
- label: '授课日期',
- field: 'createTime',
- component: 'Input',
- },
{
label: '课程名称',
field: 'kcmc',
component: 'Input',
},
{
- label: '节次',
+ label: '授课日期',
+ field: 'createTime',
+ component: 'Input',
+ render: ({ values }) => {
+ let text = values?.ketangbiaoInfo?.skrq;
+ return h(Input, { value: text, disabled: true });
+ }
+ },
+ {
+ label: '授课节次',
field: 'ketangbiaoInfo',
component: 'Input',
render: ({ values }) => {
@@ -152,17 +156,17 @@ export const formSchema: FormSchema[] = [
show: false,
},
{
- label: '检测次数',
+ label: '抓取次数',
field: 'detectionNum',
component: 'InputNumber',
},
{
- label: '人数(累加)',
+ label: '累计抓取人数',
field: 'allNum',
component: 'InputNumber',
},
{
- label: '平均数',
+ label: '平均抓取人数',
field: 'averageNum',
component: 'InputNumber',
},
@@ -257,26 +261,52 @@ export const detectionDetailedListColumns: BasicColumn[] = [
// dataIndex: 'jsbh'
// },
{
- title: '检测序号',
+ title: '序号',
align: "center",
- dataIndex: 'detectionNum'
+ dataIndex: 'detectionNum',
+ customRender: ({ index }) => {
+ return index+1;
+ },
+ },
+ // {
+ // title: '序号',
+ // align: "center",
+ // dataIndex: 'detectionNum',
+ // },
+ {
+ title: '授课地点',
+ align: "center",
+ dataIndex: 'none1',
+ slots: { customRender: 'skkd' },
},
{
- title: '截取图片',
+ title: '抓取图片',
align: "center",
dataIndex: 'detectionOutImgUrl',
slots: { customRender: 'imgSlot' },
},
{
- title: '检测时间',
+ title: '抓取时间',
align: "center",
dataIndex: 'createTime'
},
{
- title: '人数',
+ title: '选课人数',
+ align: "center",
+ dataIndex: 'none2',
+ slots: { customRender: 'xkrs' },
+ },
+ {
+ title: 'AI识别人数',
align: "center",
dataIndex: 'num'
},
+ {
+ title: '到课识别率',
+ align: "center",
+ dataIndex: 'none3',
+ slots: { customRender: 'dksbl' },
+ },
// {
// title: '人数计算结果',
// align: "center",
diff --git a/src/views/kc/detection/components/KcDetectionMainModal.vue b/src/views/kc/detection/components/KcDetectionMainModal.vue
index 22372f6..5f03b6f 100644
--- a/src/views/kc/detection/components/KcDetectionMainModal.vue
+++ b/src/views/kc/detection/components/KcDetectionMainModal.vue
@@ -8,6 +8,9 @@
无图片
+ {{ getFieldsValue('ketangbiaoInfo')?.ketangbiaoInfo?.skdd }}
+ {{ getFieldsValue('ketangbiaoInfo')?.ketangbiaoInfo?.xkrs }}
+ {{ calcAverageNum(record) }}
@@ -27,7 +30,7 @@ import { saveOrUpdate } from '../KcDetectionMain.api';
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
//表单配置
-const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
+const [registerForm, { setProps, getFieldsValue, resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
@@ -49,7 +52,7 @@ const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data
setProps({ disabled: !data?.showFooter })
});
//设置标题
-const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
+const title = computed(() => '查看');
//表单提交事件
async function handleSubmit(v) {
try {
@@ -66,6 +69,22 @@ async function handleSubmit(v) {
}
}
+function calcAverageNum(record){
+ let xkrs = getFieldsValue('ketangbiaoInfo')?.ketangbiaoInfo?.xkrs;
+ let { num: averageNum } = record;
+ let xkrsNum = Number(xkrs);
+ if(!isNaN(xkrsNum) && xkrsNum != 0 && averageNum != 0) {
+ let num = averageNum / xkrsNum * 100;
+ return num.toFixed(2) + '%';
+ }else{
+ if(averageNum == 0){
+ return '0.00' + '%';
+ }else{
+ return '';
+ }
+ }
+}
+
/**
* 获取预览图片
*/
diff --git a/src/views/kc/detection/zyZhjsList.vue b/src/views/kc/detection/zyZhjsList.vue
index 5a257a4..f190367 100644
--- a/src/views/kc/detection/zyZhjsList.vue
+++ b/src/views/kc/detection/zyZhjsList.vue
@@ -1,10 +1,40 @@
+
+
- 检测情况查询
+
@@ -29,7 +59,7 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/views/zy/jiaoXueDanYuanNeiRong/index2.vue b/src/views/zy/jiaoXueDanYuanNeiRong/index2.vue
index 4794734..467f857 100644
--- a/src/views/zy/jiaoXueDanYuanNeiRong/index2.vue
+++ b/src/views/zy/jiaoXueDanYuanNeiRong/index2.vue
@@ -6,7 +6,7 @@
提示:每一个小的章节,都可以上传章节相关的教学资源
@@ -61,7 +61,7 @@
{{ one.sort }}.{{ two.sort }}:
@@ -75,7 +75,7 @@
-
+
@@ -97,76 +97,12 @@
{{ three.title }}
-
+
+
-
-
-
-
-
-
- {{ one.sort }}.{{ two.sort }}.{{ three.sort }}
-
-
- 视频
-
-
-
-
- 文档
-
-
-
-
- 富文本
-
-
-
-
-
-
-
-
- three.isEdit = false" class="addBtn">
- three.isEdit = true" class="addBtn">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -220,7 +156,7 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from "/@/hooks/web/useMessage";
import { useRouter } from 'vue-router';
- import { randomString, simpleDebounce } from '/@/utils/common/compUtils'
+ import { randomString, simpleDebounce, getFileAccessHttpUrl } from '/@/utils/common/compUtils'
import draggable from 'vuedraggable';
import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
@@ -270,16 +206,41 @@
});
enum Api {
- list = '/teachingunitcontent/kcTeachingUnitContentOne/allList',
- edit = '/teachingunitcontent/kcTeachingUnitContentOne/edit',
-}
+ list = '/teachingunitcontent/kcTeachingUnitContentOne/allList',
+ editAll = '/teachingunitcontent/kcTeachingUnitContentOne/editAll',
+
+ addOne = '/teachingunitcontent/kcTeachingUnitContentOne/add',
+ editOne = '/teachingunitcontent/kcTeachingUnitContentOne/edit',
+ delOne = '/teachingunitcontent/kcTeachingUnitContentOne/delete',
+
+ addTwo = '/teachingunitcontent/kcTeachingUnitContentTwo/add',
+ editTwo = '/teachingunitcontent/kcTeachingUnitContentTwo/edit',
+ delTwo = '/teachingunitcontent/kcTeachingUnitContentTwo/delete',
+
+ addThree = '/teachingunitcontent/kcTeachingUnitContentThree/add',
+ editThree = '/teachingunitcontent/kcTeachingUnitContentThree/edit',
+ delThree = '/teachingunitcontent/kcTeachingUnitContentThree/delete',
+
+ }
/**
* 列表接口
* @param params
*/
const listAll = (params) => defHttp.get({ url: Api.list, params });
- const editAll = (params) => defHttp.post({ url: Api.edit, params }, { isTransformResponse: true });
+ const editAll = (params) => defHttp.post({ url: Api.editAll, params }, { isTransformResponse: true });
+
+ const addOneFetch = (params) => defHttp.post({ url: Api.addOne, params }, { isTransformResponse: false });
+ const editOneFetch = (params) => defHttp.put({ url: Api.editOne, params }, { isTransformResponse: false });
+ const delOneFetch = (params) => defHttp.delete({ url: Api.delOne, params }, { isTransformResponse: false, joinParamsToUrl: true });
+
+ const addTwoFetch = (params) => defHttp.post({ url: Api.addTwo, params }, { isTransformResponse: false });
+ const editTwoFetch = (params) => defHttp.put({ url: Api.editTwo, params }, { isTransformResponse: false });
+ const delTwoFetch = (params) => defHttp.delete({ url: Api.delTwo, params }, { isTransformResponse: false, joinParamsToUrl: true });
+
+ const addThreeFetch = (params) => defHttp.post({ url: Api.addThree, params }, { isTransformResponse: false });
+ const editThreeFetch = (params) => defHttp.put({ url: Api.editThree, params }, { isTransformResponse: false });
+ const delThreeFetch = (params) => defHttp.delete({ url: Api.delThree, params }, { isTransformResponse: false, joinParamsToUrl: true });
function reload() {
@@ -332,51 +293,6 @@
dataRecursion(dataSource.value, (x, i) => x.sort = i+1);
}
- //创建新的节点
- function createNoneData(){
- let data = {
- //临时ID,兼容新增和修改
- _id: randomString(32),
- title: null,
- sort: 0,
- childrenList: [],
- }
- return data;
- }
-
- function stop(e) {
- e?.stopPropagation();
- }
-
- function changeInput(e, pdata, key) {
- let { target } = e;
- let { value } = target;
- pdata[key] = value;
- }
-
- function addOne(){
- dataSource.value.push(createNoneData());
- createMessage.success('添加标题成功!');
- nextTick(() => {
- refreshDataSort();
- })
- }
-
- function delOne(e, one){
- stop(e);
- let index = dataSource.value.findIndex(x => x == one);
- if(index == -1) return;
- dataSource.value.splice(index, 1);
- createMessage.success('删除标题成功!');
- nextTick(() => {
- refreshDataSort();
- })
- }
-
- // function insertOne(index){
- // dataSource.value.splice(index,0, createNoneData());
- // }
-
//获取祖宗级对象
function getBtnEle(e, className){
if(e){
@@ -398,6 +314,74 @@
}
}
+ //创建新的节点
+ function createNoneData(){
+ let data = {
+ //临时ID,兼容新增和修改
+ _id: randomString(32),
+ rwbh,
+ xqxn,
+ title: null,
+ sort: 0,
+ childrenList: [],
+ }
+ return data;
+ }
+
+ function stop(e) {
+ e?.stopPropagation();
+ }
+
+ function changeInput(e, pdata, key) {
+ let { target } = e;
+ let { value } = target;
+ pdata[key] = value;
+ }
+
+ function addOne(){
+ //调用后台保存(创建个新的)
+ let nowData = createNoneData();
+ dataSource.value.push(nowData);
+ refreshDataSort();
+ addOneFetch(nowData).then(res => {
+ if(res.success){
+ nowData.id = res.result.id;
+ createMessage.success('添加标题成功!');
+ // nextTick(() => {
+ // refreshDataSort();
+ // });
+ }
+ });
+ }
+
+ function editOne(one){
+ editOneFetch(one).then(res => {
+ if(res.success){
+ createMessage.success('修改标题成功!');
+ }
+ });
+ }
+
+ function delOne(e, one){
+ stop(e);
+ //删除
+ delOneFetch({ id: one.id }).then(res => {
+ if(res.success){
+ let index = dataSource.value.findIndex(x => x == one);
+ if(index == -1) return;
+ dataSource.value.splice(index, 1);
+ createMessage.success('删除标题成功!');
+ nextTick(() => {
+ refreshDataSort();
+ })
+ }
+ });
+ }
+
+ // function insertOne(index){
+ // dataSource.value.splice(index,0, createNoneData());
+ // }
+
function addTwo(e, one){
let btn = getBtnEle(e.target, 'twoBtn');
if(btn == null){
@@ -418,27 +402,44 @@
}else{
stop(e);
}
+ let nowData = createNoneData();
+ nowData.pid = one.id;
if(one.childrenList){
- one.childrenList.push(createNoneData());
+ one.childrenList.push(nowData);
}else{
- one.childrenList = [ createNoneData() ];
+ one.childrenList = [ nowData ];
}
+ refreshDataSort();
+ addTwoFetch(nowData).then(res => {
+ if(res.success){
+ nowData.id = res.result.id;
+ createMessage.success('添加章节成功!');
+ }
+ });
+ }
- createMessage.success('添加章节成功!');
- nextTick(() => {
- refreshDataSort();
- })
+ function editTwo(two){
+ editTwoFetch(two).then(res => {
+ if(res.success){
+ createMessage.success('修改章节成功!');
+ }
+ });
}
function delTwo(e, one, two){
stop(e);
- let index = one.childrenList.findIndex(x => x == two);
- if(index == -1) return;
- one.childrenList.splice(index, 1);
- createMessage.success('删除章节成功!');
- nextTick(() => {
- refreshDataSort();
- })
+ delTwoFetch({ id: two.id }).then(res => {
+ if(res.success){
+ let index = one.childrenList.findIndex(x => x == two);
+ if(index == -1) return;
+ one.childrenList.splice(index, 1);
+ createMessage.success('删除章节成功!');
+ nextTick(() => {
+ refreshDataSort();
+ })
+ }
+ });
+
}
// function insertTwo(one, index){
@@ -479,16 +480,24 @@
function delThree(e, two, three){
stop(e);
- let index = two.childrenList.findIndex(x => x == three);
- if(index == -1) return;
- two.childrenList.splice(index, 1);
+ delThreeFetch({ id: three.id }).then(res => {
+ if(res.success){
+ let index = two.childrenList.findIndex(x => x == three);
+ if(index == -1) return;
+ two.childrenList.splice(index, 1);
- createMessage.success('删除成功!');
- nextTick(() => {
- refreshDataSort();
- })
+ createMessage.success('删除成功!');
+ nextTick(() => {
+ refreshDataSort();
+ })
+ }
+ });
}
+ function downloadFile(three) {
+ let url = getFileAccessHttpUrl(three.filePath);
+ window.open(url,"_blank");
+ }
//移动结束时触发,如果未移动则不触发,刷新排序,
function endDraggable(){
@@ -523,23 +532,32 @@
}
}
- if(!threeIndex){
+ if(!threeIndex && threeIndex !== 0){
+ three.pid = two.id;
//新增
if(two.childrenList){
two.childrenList.push(three);
}else{
two.childrenList = [ three ];
}
- createMessage.success('新增成功!');
+ refreshDataSort();
+ addThreeFetch(three).then(res => {
+ if(res.success){
+ three.id = res.result.id;
+ createMessage.success('添加成功!');
+ }
+ });
}else{
//修改
two.childrenList[threeIndex] = three;
- createMessage.success('修改成功!');
+ refreshDataSort();
+ editThreeFetch(three).then(res => {
+ if(res.success){
+ createMessage.success('修改成功!');
+ }
+ });
}
- nextTick(() => {
- refreshDataSort();
- })
threePageOpen.value = false;
@@ -657,7 +675,14 @@
overflow: auto;
}
-:deep(.maxDiv) .ant-collapse-header{
- align-items: center;
+:deep(.maxDiv){
+ .ant-collapse-header{
+ align-items: center;
+ padding-bottom: 0;
+ }
+ .ant-card-body {
+ padding-top: 0;
+ }
}
+
diff --git a/src/views/zy/jiaoXueDanYuanNeiRong/index2.vue.allSave b/src/views/zy/jiaoXueDanYuanNeiRong/index2.vue.allSave
new file mode 100644
index 0000000..4794734
--- /dev/null
+++ b/src/views/zy/jiaoXueDanYuanNeiRong/index2.vue.allSave
@@ -0,0 +1,663 @@
+
+
+
+
+
+
提示:每一个小的章节,都可以上传章节相关的教学资源
+
+
+
+
+
+
+
+
+
+
+
one.showBtn = true" @mouseleave="() => one.showBtn = false">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
two.showBtn = true" @mouseleave="() => two.showBtn = false">
+
+
+
+
+
+
+
{{ one.sort }}.{{ two.sort }}:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ three.showBtn = true" @mouseleave="() => three.showBtn = false">
+
+ {{ one.sort }}.{{ two.sort }}.{{ three.sort }}
+
+ 视频
+ 文档
+ 富文本
+
+
{{ three.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ one.sort }}.{{ two.sort }}.{{ three.sort }}
+
+
+ 视频
+
+
+
+
+ 文档
+
+
+
+
+ 富文本
+
+
+
+
+
+
+
+
+ three.isEdit = false" class="addBtn">
+ three.isEdit = true" class="addBtn">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 标题:
+
+
{{ threePageData.three.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/zy/jiaoXueDanYuanNeiRong/stuIndex.vue b/src/views/zy/jiaoXueDanYuanNeiRong/stuIndex.vue
index 7910352..e34c92d 100644
--- a/src/views/zy/jiaoXueDanYuanNeiRong/stuIndex.vue
+++ b/src/views/zy/jiaoXueDanYuanNeiRong/stuIndex.vue
@@ -75,7 +75,10 @@
{{ three.title }}
-
+
+
+
+
@@ -176,7 +179,7 @@
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from "/@/hooks/web/useMessage";
import { useRouter } from 'vue-router';
- import { randomString, simpleDebounce } from '/@/utils/common/compUtils'
+ import { randomString, simpleDebounce, getFileAccessHttpUrl } from '/@/utils/common/compUtils'
import draggable from 'vuedraggable';
import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
@@ -451,6 +454,12 @@
threePageOpen.value = false;
}
+ function downloadFile(three) {
+ let url = getFileAccessHttpUrl(three.filePath);
+ window.open(url,"_blank");
+ }
+
+
//移动结束时触发,如果未移动则不触发,刷新排序,
function endDraggable(){
From d2827f642fd43c2648c52eed99fac34f5ffb1de3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9B=B9=E7=A3=8A?= <45566618@qq.com>
Date: Sat, 25 May 2024 23:25:35 +0800
Subject: [PATCH 2/4] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=95=99=E5=AD=A6?=
=?UTF-8?q?=E5=A4=A7=E7=BA=B2=E9=99=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/views/site/renKeJiaoCheng/checkKecheng/dqxqkcDetail.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/views/site/renKeJiaoCheng/checkKecheng/dqxqkcDetail.vue b/src/views/site/renKeJiaoCheng/checkKecheng/dqxqkcDetail.vue
index fd327d8..8614c92 100644
--- a/src/views/site/renKeJiaoCheng/checkKecheng/dqxqkcDetail.vue
+++ b/src/views/site/renKeJiaoCheng/checkKecheng/dqxqkcDetail.vue
@@ -123,7 +123,7 @@ const baseApiUrl = globSetting.domainUrl;
//教学大纲提交附件
function jxdgChange(record){
console.log(`🚀 ~ jxdgChange ~ record:`, record)
- var model = {id:jxdgInfo.value.id,filePath:record}
+ var model = {id:jxdgInfo.value.id,filePath:record,rwbh:rwbh}
defHttp.post({ url: '/zyJxdg/zyJxdg/jxdgScfj', params: model }).then((res) => {
getKcjsJxdg();
});
From c3e2294d590245193d472fbf1fd089c901cdefa8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9B=B9=E7=A3=8A?= <45566618@qq.com>
Date: Sat, 25 May 2024 23:42:12 +0800
Subject: [PATCH 3/4] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=95=99=E5=AD=A6?=
=?UTF-8?q?=E5=A4=A7=E7=BA=B2=E9=99=84=E4=BB=B6,=E5=9C=A8=E7=BC=96?=
=?UTF-8?q?=E5=86=99=E8=AF=BE=E7=A8=8B=E7=AE=80=E4=BB=8B=E5=87=BA=E7=8E=B0?=
=?UTF-8?q?2=E6=9D=A1=E6=95=B0=E6=8D=AE=E7=9A=84bug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/views/site/renKeJiaoCheng/checkKecheng/dqxqkcDetail.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/views/site/renKeJiaoCheng/checkKecheng/dqxqkcDetail.vue b/src/views/site/renKeJiaoCheng/checkKecheng/dqxqkcDetail.vue
index 8614c92..eb3462c 100644
--- a/src/views/site/renKeJiaoCheng/checkKecheng/dqxqkcDetail.vue
+++ b/src/views/site/renKeJiaoCheng/checkKecheng/dqxqkcDetail.vue
@@ -123,7 +123,7 @@ const baseApiUrl = globSetting.domainUrl;
//教学大纲提交附件
function jxdgChange(record){
console.log(`🚀 ~ jxdgChange ~ record:`, record)
- var model = {id:jxdgInfo.value.id,filePath:record,rwbh:rwbh}
+ var model = {id:jxdgInfo.value.id,filePath:record,rwbh:rwbh,xqxn:xqxn}
defHttp.post({ url: '/zyJxdg/zyJxdg/jxdgScfj', params: model }).then((res) => {
getKcjsJxdg();
});
From bbf7de0cc496b0b217aad2d8a01eb35fbea12569 Mon Sep 17 00:00:00 2001
From: bai <1643359946@qq.com>
Date: Mon, 27 May 2024 01:09:54 +0800
Subject: [PATCH 4/4] =?UTF-8?q?2024=E5=B9=B45=E6=9C=8827=E6=97=A5=20?=
=?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=88=87=E7=89=87=E4=B8=8A=E4=BC=A0=EF=BC=8C?=
=?UTF-8?q?=E5=85=BC=E5=AE=B9ftp?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/jeecg/components/JUpload/JUpload.vue | 349 ++++++++-
src/router/routes/modules/zy/zy.ts | 2 +-
src/views/zy/jiaoXueDanYuanNeiRong/index.vue | 497 ++++++++++---
.../jiaoXueDanYuanNeiRong/index.vue.oneType | 393 ++++++++++
src/views/zy/jiaoXueDanYuanNeiRong/index2.vue | 688 ------------------
5 files changed, 1132 insertions(+), 797 deletions(-)
create mode 100644 src/views/zy/jiaoXueDanYuanNeiRong/index.vue.oneType
delete mode 100644 src/views/zy/jiaoXueDanYuanNeiRong/index2.vue
diff --git a/src/components/Form/src/jeecg/components/JUpload/JUpload.vue b/src/components/Form/src/jeecg/components/JUpload/JUpload.vue
index f01f3ca..db9957e 100644
--- a/src/components/Form/src/jeecg/components/JUpload/JUpload.vue
+++ b/src/components/Form/src/jeecg/components/JUpload/JUpload.vue
@@ -1,9 +1,8 @@
-
+
{{ text }}
+
@@ -29,7 +29,7 @@
import { ref, reactive, computed, watch, nextTick, createApp, unref } from 'vue';
import { Icon } from '/@/components/Icon';
import { getToken } from '/@/utils/auth';
- import { uploadUrl } from '/@/api/common/api';
+ import { uploadUrl, baseUploadUrl } from '/@/api/common/api';
import { propTypes } from '/@/utils/propTypes';
import { useMessage } from '/@/hooks/web/useMessage';
import { createImgPreview } from '/@/components/Preview/index';
@@ -38,6 +38,9 @@
import { UploadTypeEnum } from './upload.data';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
import UploadItemActions from './components/UploadItemActions.vue';
+ import { defHttp } from '/@/utils/http/axios';
+ import { buildUUID } from '/@/utils/uuid';
+ import CryptoJS from 'crypto-js';
const { createMessage, createConfirm } = useMessage();
const { prefixCls } = useDesign('j-upload');
@@ -70,9 +73,16 @@
forceBeforeUploadFn: propTypes.bool.def(true),
//后加的,强制验证accept,目前仅支持*.jpg,*.gif之类的扩展名验证,video/*,audio/*,image/jpeg之类的暂不支持
forceAcceptVerify: propTypes.bool.def(false),
+ //后加的,是否查询biz
+ isGetBiz: propTypes.bool.def(false),
+ //后加的,查询biz参数
+ getBizParam: propTypes.object.def({}),
disabled: propTypes.bool.def(false),
});
+ const otherData = ref({});
+ const otherClass = ref({});
+
const headers = reactive({
'X-Access-Token': getToken(),
});
@@ -89,8 +99,8 @@
const bind: any = Object.assign({}, props, unref(attrs));
bind.name = 'file';
bind.listType = isImageMode.value ? 'picture-card' : 'text';
- bind.class = [bind.class, { 'upload-disabled': props.disabled }];
- bind.data = { biz: props.bizPath, ...bind.data };
+ bind.class = [bind.class, { 'upload-disabled': props.disabled, ...unref(otherClass) }];
+ bind.data = { biz: props.bizPath, ...bind.data, ...unref(otherData) };
//update-begin-author:taoyan date:20220407 for: 自定义beforeUpload return false,并不能中断上传过程
if (!bind.beforeUpload) {
bind.beforeUpload = onBeforeUpload;
@@ -124,6 +134,41 @@
watch(fileList, () => nextTick(() => addActionsListener()), { immediate: true });
+ const loadBizFn = (params) => defHttp.get({ url: '/ktgl/kcKetangbiao/getBizPath', params }, { isTransformResponse: false })
+
+ function loadBiz(param){
+ otherData.value.loading = true;
+ // otherClass.value = { 'upload-disabled': true, }
+ loadBizFn(param).then(res => {
+ //otherData.value
+ if(res.success){
+ otherData.value.biz = res.result;
+ }else{
+ delete otherData.value.biz;
+ }
+ // otherClass.value = {}
+ delete otherData.value.loading;
+ });
+ }
+
+
+ watch(() => props.getBizParam,
+ (param, oldParam) => {
+ if(JSON.stringify(param) != JSON.stringify(oldParam)){
+ nextTick(() => {
+ console.log(`🚀 ~ props.isGetBiz:`, props.isGetBiz, bindProps.value.disabled, loadBiz);
+ if(props.isGetBiz && !bindProps.value.disabled){
+ //非被禁用状态,查询
+ nextTick(() => {
+ loadBiz(param);
+ });
+ }
+ });
+ }
+ },
+ { immediate: true }
+ );
+
const antUploadItemCls = 'ant-upload-list-item';
// Listener
@@ -299,7 +344,7 @@
});
}
} else if (info.file.status === 'error') {
- createMessage.error(`${info.file.name} 上传失败.`);
+ createMessage.error(`${info.file.name} 上传失败. ${info.file.response.message}`);
}
fileList.value = fileListTemp;
if (info.file.status === 'done' || info.file.status === 'removed') {
@@ -372,6 +417,296 @@
return path.substring(path.lastIndexOf('/') + 1);
}
+ // //获取文件md5(仅支持小文件,,,弃用)
+ // function calculateFileMd5(file) {
+ // return new Promise((resolve, reject) => {
+ // const reader = new FileReader();
+ // // 当文件被成功读取时调用onload事件
+ // reader.onload = function (event) {
+ // const arrayBufferView = event.target.result;
+ // // 将ArrayBuffer转换为WordArray对象
+ // const wordArray = CryptoJS.lib.WordArray.create(arrayBufferView);
+ // // 计算MD5哈希值
+ // const md5Hash = CryptoJS.MD5(wordArray).toString();
+ // resolve(md5Hash);
+ // };
+ // // 当发生错误时调用onerror事件
+ // reader.onerror = function () {
+ // reject('Failed to read file');
+ // };
+ // // 开始读取文件内容
+ // reader.readAsArrayBuffer(file);
+ // });
+ // }
+
+ /**
+ * 计算文件md5(分批次计算,挺慢的,支持大文件)
+ */
+ function calFileMd5(file){
+ return new Promise((resolve, reject) => {
+ let md5 = CryptoJS.algo.MD5.create();
+ //获取文件对象
+ let reader = new FileReader();
+ let step = 1024* 1024;
+ let total = file.size;
+ let cuLoaded = 0;
+ let time=1;
+ console.info("文件大小:" + file.size);
+ //读取一段成功
+ reader.onload = (e) => {
+ //console.log("开始读取第"+time+"段");
+ //处理读取的结果
+ let wordArray = CryptoJS.lib.WordArray.create(reader.result);
+ md5.update(wordArray);
+ cuLoaded += e.loaded;
+ //如果没有读完,继续
+ if (cuLoaded < total) {
+ readBlob(cuLoaded);
+ } else {
+ cuLoaded = total;
+ let hash = md5.finalize().toString();
+ //document.getElementById("result").innerText=hash;
+ resolve(hash + buildUUID());
+ }
+ time++;
+ }
+ reader.onerror = (e) => {
+ console.error('读取文件MD5出现错误 =>',e);
+ reject(e);
+ }
+ //开始读取
+ readBlob(0);
+ //指定开始位置,分块读取文件
+ function readBlob(start) {
+ //指定开始位置和结束位置读取文件
+ let blob = file.slice(start, start + step);
+ reader.readAsArrayBuffer(blob);
+ }
+ });
+ }
+
+ function calFileUid(file){
+ return new Promise((resolve, reject) => {
+ resolve(buildUUID());
+ });
+ }
+
+
+
+
+ //请求接口的数据返回
+// function upSearch(data){
+// return new Promise((resolve,reject)=>{
+// setTimeout(()=>{
+// console.log(data)
+// resolve(data)
+// },2000)
+// })
+// }
+
+// function limitPromise(promiseList, limit){
+
+// let init = Math.min(limit, promiseList.length)
+// let promiseList = []
+// for(let i=0; i{
+// console.log('全部完成')
+// })
+// }
+
+//limitUp([1,2,3,4,5,6,7,8], 3)
+
+
+ async function limitPromise(promises, limit) {
+ const results = []
+
+ for(let i=0; i<=promises.length; i+=limit) {
+ const tasks = []
+ // 切片 Promise.all 的参数
+ for(const promise of promises.slice(i, i + limit)) {
+ tasks.push(promise)
+ }
+ // 用 await 以确保后面的任务不会在执行当前任务时执行
+ const result = await Promise.all(tasks)
+ results.push(...result)
+ }
+
+ return results
+ }
+
+ //分片大小 5m
+ const chunkSize = 5 * 1024 * 1024;
+
+ const runBatchNum = 20;
+
+ const uploadAxiosHttpConfig = {
+ //超时时间,分钟 * 秒 * 毫秒 60分钟
+ timeout: 60 * 60 * 1000,
+ //不自动拼接前缀
+ joinPrefix: false,
+ //自定义前缀
+ apiUrl: baseUploadUrl,
+ //不自动处理
+ isTransformResponse: false
+ }
+
+ const defUploadFn = (params) => defHttp.post({ url: '/sys/common/upload', params }, uploadAxiosHttpConfig );
+
+ const bigFileUploadInit = (params) => defHttp.post({ url: '/sys/common/sectionUpload/init', params }, uploadAxiosHttpConfig );
+
+ const bigFileUploadUpload = (params) => defHttp.post({ url: '/sys/common/sectionUpload/upload', params }, uploadAxiosHttpConfig );
+
+ const bigFileUploadEnd = (params) => defHttp.post({ url: '/sys/common/sectionUpload/end', params }, uploadAxiosHttpConfig)
+
+ /**
+ * 自定义文件上传方法,小于5m的走默认上传,大于5m的走切片上传
+ */
+ function uploadFn(customRequestData){
+ const { data, file, onProgress, onSuccess, onError } = customRequestData; // 解构出a-upload的内置的方法(进度条,成功失败等)
+
+ let fileSize = file.size;
+ let uploadPromiseList = [];
+
+ if(fileSize <= chunkSize){
+ let formData = new FormData();
+ Object.keys(data).forEach(key => {
+ formData.append(key, data[key]);
+ });
+ formData.append('file', file);
+ //传统直传
+ defUploadFn(formData).then(res => {
+ console.log(`🚀 ~ 传统直传 - defUploadFn ~ res:`, res);
+ if(res.success){
+ onProgress({ percent: 100 }, file) // 进度条
+ onSuccess(res, file) // 上传文件的状态
+ } else {
+ onError(res, res, file);
+ }
+ }).catch(err => {
+ console.log(`🚀 ~ 传统直传 - defUploadFn ~ err:`, err);
+ onError(err, err, file);
+ });
+ } else {
+ //计算当前选择文件需要的分片数量
+ const chunkCount = Math.ceil(fileSize / chunkSize);
+ console.log("文件大小:",(file.size / 1024 / 1024) + "Mb","分片数:",chunkCount);
+ //获取文件md5
+ console.log('第一步,计算文件的md5',calFileMd5, file);
+ calFileMd5(file).then(fileMd5 => {
+ console.log(`🚀 ~ 文件的md5是:`, fileMd5);
+ const initUploadParams = { chunkCount, fileMd5 , ...data, };
+ let successNum = 0;
+
+ let taskAllList = [];
+ //切片上传(开始)
+ console.log('第二步,根据md5创建文件夹', initUploadParams);
+ bigFileUploadInit(initUploadParams).then(res => {
+ console.log('第三步,准备切片文件', res);
+ if(res.success){
+ onProgress({ percent: 0 }, file); // 进度条
+ //后台创建成功,下一步,分批次上传
+ for (let i = 1; i <= chunkCount; i++) {
+ let uploadParams = {
+ partNumber: i,
+ ...initUploadParams,
+ file: null,
+ }
+ //分片开始位置
+ let start = (i - 1) * chunkSize
+ //分片结束位置
+ let end = Math.min(fileSize, start + chunkSize)
+ //取文件指定范围内的byte,从而得到分片数据
+ let _chunkFile = file.slice(start, end)
+ console.log("第四步,开始准备文件第" + i + "个分片" + ",切片范围从" + start + "到" + end)
+
+ uploadParams.file = _chunkFile;
+ let uploadFormData = new FormData();
+ Object.keys(uploadParams).forEach(key => {
+ uploadFormData.append(key, uploadParams[key]);
+ });
+
+ console.log('第五步,准备切片文件上传参数', uploadFormData);
+ taskAllList.push(new Promise((resolve, reject) => {
+ console.log('第六步,准备切片文件上传前,', uploadFormData);
+ bigFileUploadUpload(uploadFormData).then(res => {
+ console.log('第七步,切片文件上传后,', uploadFormData, res);
+ if(res.success) {
+ successNum++;
+ let percent = Number(Number(successNum/chunkCount*100).toFixed(0))
+ onProgress({ percent }, file) // 进度条
+ resolve(res);
+ }else{
+ reject(res);
+ }
+ }).catch(err => {
+ reject(err)
+ });
+ }));
+ }
+ //任务分片,一次20片
+ console.log('第八步,全部切片,根据指定线程数执行,', limitPromise, taskAllList);
+ limitPromise(taskAllList, runBatchNum).then(resList => {
+ console.log('第九步,全部切片,根据指定线程数执行完成后的结果,', resList);
+ //完成后再执行一个合并
+ let endUploadParams = {
+ ...initUploadParams,
+ fileName: file.name,
+ }
+ console.log('第十步,全部切片,发生合并指令,', endUploadParams);
+ bigFileUploadEnd(endUploadParams).then(res => {
+ console.log(`第十一步 ~ 合并返回值 defHttp.post ~ res:`, res);
+ //返回跟单个上传一样的返回值,
+ if(res.success){
+ onProgress({ percent: 100 }, file) // 进度条
+ onSuccess(res, file) // 上传文件的状态
+ } else {
+ onError(res, res, file);
+ }
+
+ }).catch(err => {
+ console.error(`🚀 ~ 合并出现错误! defHttp.post ~ err:`, err);
+ onError(err, err, file);
+ })
+ }).catch(err => {
+ console.error(`🚀 ~ 全部完成后,其中有错误limitPromise ~ err:`, err);
+ //有错误,,
+ onError(err, err, file);
+ });
+
+ }
+ //return
+ })
+
+ })
+
+
+ }
+
+
+ // Promise.all(uploadPromiseList).then(resList => {
+
+ // });
+ }
+
defineExpose({
addActionsListener,
});
diff --git a/src/router/routes/modules/zy/zy.ts b/src/router/routes/modules/zy/zy.ts
index d6158dc..a454f52 100644
--- a/src/router/routes/modules/zy/zy.ts
+++ b/src/router/routes/modules/zy/zy.ts
@@ -65,7 +65,7 @@ const zuoye: AppRouteModule = {
{
path: 'jiaoXueDanYuanNeiRong',
name: 'jiaoXueDanYuanNeiRong',
- component: () => import('/@/views/zy/jiaoXueDanYuanNeiRong/index2.vue'),
+ component: () => import('/@/views/zy/jiaoXueDanYuanNeiRong/index.vue'),
meta: {
title: '教学单元内容',
},
diff --git a/src/views/zy/jiaoXueDanYuanNeiRong/index.vue b/src/views/zy/jiaoXueDanYuanNeiRong/index.vue
index 442729b..29dccf2 100644
--- a/src/views/zy/jiaoXueDanYuanNeiRong/index.vue
+++ b/src/views/zy/jiaoXueDanYuanNeiRong/index.vue
@@ -1,90 +1,108 @@
-
+
-
+
+
+
提示:每一个小的章节,都可以上传章节相关的教学资源
+
+
+
+
+
-
+ one.showBtn = true" @mouseleave="() => one.showBtn = false">
-
+
-
-
-
-
+
+
+
+
+
+
-
+ two.showBtn = true" @mouseleave="() => two.showBtn = false">
-
+
+
{{ one.sort }}.{{ two.sort }}:
-
+
-
+
+
+
+
+
+
-
+
-
-
-
-
- {{ one.sort }}.{{ two.sort }}.{{ three.sort }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ three.showBtn = true" @mouseleave="() => three.showBtn = false">
+
+ {{ one.sort }}.{{ two.sort }}.{{ three.sort }}
+
+ 视频
+ 文档
+ 富文本
+
+
{{ three.title }}
+
+
+
+
+
+
+
+
@@ -103,21 +121,48 @@
+
+
+
+ 标题:
+
+
{{ threePageData.three.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/zy/jiaoXueDanYuanNeiRong/index.vue.oneType b/src/views/zy/jiaoXueDanYuanNeiRong/index.vue.oneType
new file mode 100644
index 0000000..442729b
--- /dev/null
+++ b/src/views/zy/jiaoXueDanYuanNeiRong/index.vue.oneType
@@ -0,0 +1,393 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ one.sort }}.{{ two.sort }}:
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ one.sort }}.{{ two.sort }}.{{ three.sort }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/zy/jiaoXueDanYuanNeiRong/index2.vue b/src/views/zy/jiaoXueDanYuanNeiRong/index2.vue
deleted file mode 100644
index 467f857..0000000
--- a/src/views/zy/jiaoXueDanYuanNeiRong/index2.vue
+++ /dev/null
@@ -1,688 +0,0 @@
-
-
-
-
-
-
提示:每一个小的章节,都可以上传章节相关的教学资源
-
-
-
-
-
-
-
-
-
-
-
one.showBtn = true" @mouseleave="() => one.showBtn = false">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
two.showBtn = true" @mouseleave="() => two.showBtn = false">
-
-
-
-
-
-
-
{{ one.sort }}.{{ two.sort }}:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- three.showBtn = true" @mouseleave="() => three.showBtn = false">
-
- {{ one.sort }}.{{ two.sort }}.{{ three.sort }}
-
- 视频
- 文档
- 富文本
-
-
{{ three.title }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 标题:
-
-
{{ threePageData.three.title }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-