Browse Source

对接上传任务接口

test
wzl 1 year ago
parent
commit
0c99e4ddaf
4 changed files with 357 additions and 24 deletions
  1. +40
    -1
      src/api/development.js
  2. +54
    -8
      src/views/development/index.vue
  3. +4
    -5
      src/views/development/taskDetail.vue
  4. +259
    -10
      src/views/development/taskSubmission.vue

+ 40
- 1
src/api/development.js View File

@@ -16,7 +16,9 @@ async function http(config) {
export const apiDevelopment = { export const apiDevelopment = {
LevelList, LevelList,
LevelDetail, LevelDetail,
CurrentTask
CurrentTask,
UploadFile,
SubmitTask
}; };


export default apiDevelopment; export default apiDevelopment;
@@ -68,3 +70,40 @@ function CurrentTask() {
} }
}); });
} }

/**
* 提交任务
*/

function SubmitTask(param) {
return http({
url: '/api/Task/Submit',
method: 'post',
data: {
personId: personId,
...param
}
});
}

/**
* 上传文件
*/
function UploadFile(param) {
return http({
url: "/api/File/Upload",
method: "post",
data: param,
headers: { "Content-Type": "multipart/form-data" },
transformRequest: function(data) {
const formData = new FormData();
let i = data.formData.entries();
let j = i.next();
while (!j.done) {
formData.set(j.value[0], j.value[1]);
j = i.next();
}
return formData;
}
});
}

+ 54
- 8
src/views/development/index.vue View File

@@ -27,8 +27,8 @@
<div class="task-time" v-for="(item, index) in task.taskDatas" :key="index" @click="toTask(item)"> <div class="task-time" v-for="(item, index) in task.taskDatas" :key="index" @click="toTask(item)">
<div class="task-time-info"> <div class="task-time-info">
<div class="task-time-text">{{ item.name }}</div> <div class="task-time-text">{{ item.name }}</div>
<div class="task-time-button min-text" v-if="item.status !== 3">
{{ item.sourceType === 3 ? '完成问卷' : item.sourceType === 2 ? '查看进度' : '上传打卡' }}
<div class="task-time-button min-text" v-if="item.status !== 2">
{{ item.submitType === 2 ? '完成问卷' : item.submitType === 0 ? '查看进度' : '上传打卡' }}
</div> </div>
</div> </div>
<div class="task-time-icon"> <div class="task-time-icon">
@@ -152,26 +152,72 @@ export default {
if (re.data && Array.isArray(re.data) && re.data.length > 0) { if (re.data && Array.isArray(re.data) && re.data.length > 0) {
this.task = re.data[0]; this.task = re.data[0];
} }

//测试
// this.task = {
// planName: '健康同学成长计划-测试',
// levelId: 1,
// name: '启蒙熊',
// level: 1,
// levelLv: 'Lv01',
// serialNumber: '阶段1',
// target: '美好开始',
// coverH5: '',
// unlockType: 0,
// status: 1,
// taskDatas: [
// {
// id: 5,
// rankId: 1,
// name: '幸运熊计划玩法攻略阅读1次',
// roleType: 1,
// submitType: 0,
// status: 0
// },
// {
// id: 6,
// rankId: 2,
// name: '完成填写育儿问卷1次',
// roleType: 2,
// submitType: 2,
// status: 0
// },
// {
// id: 7,
// rankId: 3,
// name: '陪伴孩子读赠送的书籍1次',
// roleType: 2,
// submitType: 1,
// status: 0
// }
// ]
// };
} else { } else {
this.$message.error(re.message); this.$message.error(re.message);
} }
} }
}, },
toTask(item) { toTask(item) {
if(item.status === 3){
return
if (item.status === 2) {
return;
} }
if (item.sourceType === 3) {
if (item.submitType === 2) {
this.$toast('问卷调查'); this.$toast('问卷调查');
} else if (item.sourceType === 2) {
} else if (item.submitType === 0) {
this.$router.push({ this.$router.push({
name: 'taskWearing', name: 'taskWearing',
params: {}
params: {
id: item.id,
rankId: item.rankId
}
}); });
} else { } else {
this.$router.push({ this.$router.push({
name: 'taskSubmission', name: 'taskSubmission',
params: {}
params: {
id: item.id,
rankId: item.rankId
}
}); });
} }
}, },


+ 4
- 5
src/views/development/taskDetail.vue View File

@@ -24,11 +24,9 @@
<div class="gap"></div> <div class="gap"></div>
</div> </div>
<div class="gap"></div> <div class="gap"></div>
<div class="mid-title center" v-if="detail.status === 2">已完成</div>
<div class="mid-title center" v-else-if="detail.status === 1">任务即将达成</div>
<div class="mid-title center" v-else-if="detail.status === 3">未开始</div>
<div class="mid-title center" v-if="detail.status === 3">未开始</div>
<div class="mid-title center" v-else-if="detail.status === 0">未解锁</div> <div class="mid-title center" v-else-if="detail.status === 0">未解锁</div>
<div class="mid-title center" v-else>未知</div>
<div class="mid-title center" v-else>{{detail.completionDesc}}</div>
<div class="gap"></div> <div class="gap"></div>
<div class="mid-title">目标</div> <div class="mid-title">目标</div>
<div class="text">{{ detail.target }}</div> <div class="text">{{ detail.target }}</div>
@@ -69,7 +67,8 @@ export default {
this.$toast('参数错误'); this.$toast('参数错误');
setTimeout(() => { setTimeout(() => {
this.$router.back(); this.$router.back();
}, 3000);
}, 2000);
return
} }
this.initData(); this.initData();
}, },


+ 259
- 10
src/views/development/taskSubmission.vue View File

@@ -9,11 +9,35 @@
:fixed="true" :fixed="true"
> >
<template #right> <template #right>
<div class="submit">提交</div>
<div class="submit" @click="submit">提交</div>
</template> </template>
</van-nav-bar> </van-nav-bar>
<div class="content"> <div class="content">
<textarea name="" id="textarea" maxlength="1000" v-model="textarea" placeholder="请按照要求完成任务"></textarea>
<textarea
name=""
id="textarea"
maxlength="1000"
v-model="textarea"
placeholder="请按照要求完成任务"
style="resize: none; height: 300px"
ref="textarea"
@input="inputInfo($event)"
></textarea>
<div class="files">
<div class="file-item" v-for="(item, index) in subFiles" :key="index">
<div class="file-icon" v-if="item.type === 'video'">
<van-icon name="video-o"></van-icon>
</div>
<div class="file-icon luyin" v-else-if="item.type === 'vote'">
<van-icon name="luyin" class-prefix="iconfont"></van-icon>
</div>
<van-image class="file-image" fit="cover" :src="item.base64" v-else-if="item.type === 'image'"></van-image>
<div class="file-name">{{ item.file.name }}</div>
<div class="file-delete" @click="onDelete(index)">
<van-icon name="cross"></van-icon>
</div>
</div>
</div>
<div class="other"> <div class="other">
<div class="tools"> <div class="tools">
<div class="tool" @click="onSelect('vote')"> <div class="tool" @click="onSelect('vote')">
@@ -41,6 +65,11 @@
class="file" class="file"
id="votefile" id="votefile"
accept="audio/mp3,audio/mp4" accept="audio/mp3,audio/mp4"
@click="
e => {
e.target.value = '';
}
"
@change="onChange('vote')" @change="onChange('vote')"
/> />
<input <input
@@ -49,33 +78,199 @@
class="file" class="file"
id="imagefile" id="imagefile"
accept="image/png,image/jpeg,image/jpg" accept="image/png,image/jpeg,image/jpg"
@click="
e => {
e.target.value = '';
}
"
@change="onChange('image')" @change="onChange('image')"
/> />
<input ref="videofile" type="file" class="file" id="videofile" accept="video/mp4" @change="onChange('video')" />
<input
ref="videofile"
type="file"
class="file"
id="videofile"
accept="video/mp4"
@click="
e => {
e.target.value = '';
}
"
@change="onChange('video')"
/>
</div> </div>
</template> </template>


<script> <script>
import development from '@/api/development';

export default { export default {
components: {}, components: {},
data() { data() {
return { return {
textarea: ''
id: 1,
rankId: 1,
textarea: '',
subFiles: [],
only: true, // 文件是否唯一
maxFile: 3, // 最大文件数量 仅only=false时有效
maxFileSize: 200 // 最大文件大小MB
}; };
}, },
mounted() {},
mounted() {
let id = this.$route.params.id;
let rankId = this.$route.params.rankId;
if (id && rankId) {
this.id = id;
this.rankId = rankId;
} else {
this.$toast('参数错误');
setTimeout(() => {
this.$router.back();
}, 2000);
return;
}
this.initData();
},
watch: {
textarea() {
let textArea = this.$refs['textarea'];
if (textArea.scrollHeight > 300) {
textArea.style.height = textArea.scrollHeight + 'px';
} else {
textArea.style.height = 300 + 'px';
}
}
},
methods: { methods: {
async initData() {},
async submit() {
if (!this.subFiles.length) {
this.$toast('请选择文件');
return;
}
this.$toast.loading({
forbidClick: true,
duration: 0,
});
if (this.subFiles.length) {
let re = await this.subFile();
if (!re) {
this.$toast('文件上传失败,请重新提交');
return;
}
}
console.log(
this.subFiles.map(item => {
return item.url;
})
);
// 提交任务
let re = await development.SubmitTask({
id: this.id,
uploadData: {
content: this.textarea,
file: this.subFiles
.map(item => {
return item.url;
})
.join(';')
}
});
if (re) {
if (re.succeed) {
this.$toast('提交成功');
setTimeout(() => {
this.$router.back();
}, 2000);
} else {
this.$toast(re.message);
}
} else {
this.$toast('提交失败');
}
},
async subFile() {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async resolve => {
// for遍历subFiles数组
for (let i = 0; i < this.subFiles.length; i++) {
let item = { ...this.subFiles[i] };
if (!item.url) {
let formData = new FormData();
formData.set('fileName', item.file.name);
formData.set('file', item.file);
let re = await development.UploadFile({ formData });
if (!re || !re.succeed) {
resolve(false);
return;
} else {
item.url = re.data.url;
this.subFiles[i] = item;
}
}
}
resolve(true);
});
},
onSelect(type) { onSelect(type) {
console.log(type); console.log(type);
this.$refs[type + 'file'].click(); this.$refs[type + 'file'].click();
}, },
onDelete(index) {
this.subFiles.splice(index, 1);
},
onChange(type) { onChange(type) {
const file = this.$refs[type + 'file'].files[0]; const file = this.$refs[type + 'file'].files[0];
console.log(file); console.log(file);
const formData = new FormData();
formData.append('file', file);
formData.append('type', type);
console.log(formData);

// 最大文件大小
if (file.size > this.maxFileSize * 1024 * 1024) {
this.$toast(`文件大小不能超过${this.maxFileSize}MB`);
return;
}

if (type === 'image') {
this.blobToDataURL(file, base64 => {
this.pushFileData({
type,
base64,
file
});
});
} else {
this.pushFileData({
type,
file
});
}
// const formData = new FormData();
// formData.append('file', file);
// formData.append('type', type);
// console.log(formData);
},
pushFileData(fileData) {
if (this.only) {
this.subFiles = [fileData];
} else {
if (this.subFiles.length < this.maxFile) {
this.subFiles.push(fileData);
} else {
this.$toast(`最多上传${this.maxFile}个文件`);
}
}
},
// 图片转base64
blobToDataURL(blob, callBack) {
let reader = new FileReader();
reader.onload = function (evt) {
let base64 = evt.target.result;
callBack(base64);
};
reader.readAsDataURL(blob);
},
inputInfo(event) {
event.target.style.height = '300px'; // 默为空时的高度设置
} }
} }
}; };
@@ -116,10 +311,64 @@ export default {


#textarea { #textarea {
width: 100%; width: 100%;
height: 500px;
font-size: 30px; font-size: 30px;
} }


.files {
display: flex;
flex-wrap: wrap;
width: 100%;

.file-item {
overflow: hidden;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
color: black;
border-radius: 10px;
margin-right: 20px;
margin-bottom: 20px;
background: #e8e8e8;

.file-icon {
i {
font-size: 60px;
}
}
.file-image {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
z-index: 98;
}
.file-name {
width: 100%;
text-align: center;
font-size: 22px;
}
.file-delete {
position: absolute;
top: 5px;
right: 5px;
display: flex;
justify-content: center;
align-items: center;
width: 50px;
height: 50px;
font-size: 30px;
color: red;
border-radius: 50%;
background: white;
z-index: 99;
}
}
}
.other { .other {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;


Loading…
Cancel
Save