h5
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

331 lines
11 KiB

<template>
<!-- 是自己的任务 且该任务有交付物 才显示提交组件 -->
<view class="bg-white px-2 rounded-md relative" @longpress.prevent="showMask = true">
<!-- 插件名称输入和提交 -->
<view class="flex item-center justify-between py-2">
<view class="flex-1">
<view v-if="deliver.deliverName" class="relative inline-block">
{{ deliver.deliverName }}
</view>
</view>
<!-- 提交 -->
<u-button
type="primary"
size="mini"
@click="submit"
class="self-center"
:disabled="submitState"
:ripple="true"
:loading="submitBtnLoading"
>
提交
</u-button>
<!-- 查看提交历史的按钮 -->
<!-- <u-icon name="arrow-right" class="ml-3" @click="openDeliverHistory"></u-icon> -->
</view>
<!-- 插件上传方式 -->
<view>
<view class="link-box">
<u-input v-model="linkValue" type="text" :border="true" placeholder="请输入交付物地址/链接" class="input"></u-input>
</view>
<view class="mt-3">
<u-button size="mini" :plain="true" type="primary" class="mr-3" @click="uploadPhoto">拍照</u-button>
<u-button size="mini" :plain="true" type="primary" class="mr-3" @click="uploadFile">文件</u-button>
<u-button size="mini" :plain="true" type="primary" class="mr-3" @click="paste">粘贴</u-button>
</view>
</view>
<!-- 编辑和删除的遮罩层 -->
<view class="mask flex items-center justify-center bg-grey" v-show="showMask" @click="showMask = false">
<view class="bg-yellow-500 text-white w-12 h-12 text-center leading-12 rounded-w-12 mx-8" @click.stop="showEditModal = true">
修改
</view>
<view class="bg-red-500 text-white w-12 h-12 text-center leading-12 rounded-w-12 mx-8" @click.stop="showDeleteModal = true">
删除
</view>
<!-- 删除的二次提示modal -->
<u-modal v-model="showDeleteModal" :content="content" :show-cancel-button="true" @confirm="confirmDelete"></u-modal>
</view>
<!-- 编辑交付物标题的modal -->
<u-mask :show="showEditModal" @click="showEditModal = false">
<view class="modal-content-wrap" @click.stop>
<view class="modal-content-head">交付物标题名称</view>
<view class="modal-content-body">
<u-input :border="true" placeholder="请输入交付物名称" v-model="newInputRef"></u-input>
</view>
<view class="modal-content-foot">
<view class="cancel" @click="showEditModal = false">取消</view>
<view class="confirm" @click="confirmEditDeliverName">确定</view>
</view>
</view>
</u-mask>
<view class="border border-solid border-gray-300 rounded-md mt-5 p-2 pt-4 pl-1" @click="collapsed = !collapsed">
<view class="relative flex justify-between">
<view class="absolute bg-white text-sm duration-title">工作量时长</view>
<view class="mr-5 flex flex-wrap items-center">
<u-button :type="checkedIndex === 0 ? 'primary' : 'default'" size="mini" class="m-1" style="padding: 0 5px;" @click="handleSelectTime(0)">
半小时
</u-button>
<u-button :type="checkedIndex === 1 ? 'primary' : 'default'" size="mini" class="m-1" style="padding: 0 5px;" @click="handleSelectTime(1)">
1小时
</u-button>
<u-button :type="checkedIndex === 2 ? 'primary' : 'default'" size="mini" class="m-1" style="padding: 0 5px;" @click="handleSelectTime(2)">
2小时
</u-button>
</view>
<!-- 时长 -->
<view class="flex items-center justify-end flex-1 text-sm">
<u-input v-model="duration" type="text" placeholder="工作量时长" :border="true" height="56" class="input"></u-input>
<text class="ml-1">小时</text>
</view>
</view>
</view>
<!-- 插件审核人员选择 -->
<ReviewerSecond ref="reviewerRef" :dataCheckers="deliver.checkerList ? deliver.checkerList : []" />
</view>
</template>
<script setup>
import { ref, computed, inject, watch } from 'vue';
import { useStore } from 'vuex';
import dayjs from 'dayjs';
import { UPLOAD_URL } from '@/config/index';
import { UPLOAD_EXTENSION } from '@/config/deliver';
const props = defineProps({
deliverData: { type: Object, default: {} },
task: { default: {}, type: Object },
url: { type: String, default: '' }
});
const store = useStore();
const emits = defineEmits(['upload-success', 'edit-success']);
const delivers = inject('deliver');
const deliver = computed(() => (Object.keys(props.deliverData).length ? props.deliverData : delivers.value));
const tasks = inject('task');
const task = computed(() => (Object.keys(props.task).length ? props.task : tasks));
const reviewerRef = ref(null);
const submitBtnLoading = ref(false);
const linkValue = ref(''); // 链接的值
const showMask = ref(false); // 编辑和删除页面
const showEditModal = ref(false); // 编辑交付物标题的modal
const newInputRef = ref(''); // 修改的插件名的值
const showDeleteModal = ref(false); // 删除二次提示的modal
const content = '是否确定删除';
const showBadge = ref(false); // u-badge的显示与隐藏
const duration = ref(2); // 工作量时长
const checkedIndex = ref(2); // 默认选中
// 判断提交按钮的状态
const submitState = computed(() => !linkValue.value);
const projectId = computed(() => store.getters['project/projectId']);
const roleId = computed(() => store.state.role.roleId);
const projectIdStorage = uni.$storage.getStorageSync('projectId');
const roleIdStorage = uni.$storage.getStorageSync('roleId');
if (Object.keys(deliver.value).length) {
linkValue.value = deliver.value.details[0]; // 交付物内容
duration.value = deliver.value.duration ? Number(deliver.value.duration) / 3600000 : Number(deliver.value.initialDuration) / 3600000; // 工作量时长
checkedIndex.value = duration.value == 0.5 ? 0 : duration.value == 1 ? 1 : duration.value == 2 ? 2 : -1;
}
watch(deliver, () => {
linkValue.value = deliver.value.details[0]; // 交付物内容
duration.value = deliver.value.duration ? Number(deliver.value.duration) / 3600000 : Number(deliver.value.initialDuration) / 3600000; // 工作量时长
checkedIndex.value = duration.value == 0.5 ? 0 : duration.value == 1 ? 1 : duration.value == 2 ? 2 : -1;
})
// 验证提交的交付物信息格式
function validateDeliverForm(checkedCheckers) {
const reg = /[a-zA-z]+:\/\/[^\s]*/;
if (!reg.test(linkValue.value)) {
// 显示toast信息
uni.$ui.showToast('请输入正确的链接');
return false;
}
// 没有检查人 提示选择检查人
if (!checkedCheckers || !checkedCheckers.length) {
uni.$ui.showToast('请选择检查人');
return false;
}
return true;
}
// 提交交付物信息
async function submit() {
const { checkedCheckers } = reviewerRef.value; // 拿到选择检查人组件中选中的检查人
// 提交前的验证
if (!validateDeliverForm(checkedCheckers)) return;
submitBtnLoading.value = true; // 显示loading
// 验证成功后进行请求
try {
const checkerList = [];
checkedCheckers.forEach(item => {
checkerList.push(item.memberId);
});
const param = {
projectId: projectId.value || projectIdStorage,
roleId: roleId.value || roleIdStorage,
deliverId: deliver.value.deliverId,
fileList: [linkValue.value],
checkerList,
duration: Number(duration.value) * 60 * 60 * 1000,
msgId: task.value.msgId,
};
await uni.$u.api.submitDeliverInfo(param, props.url);
uni.$ui.showToast('提交交付物信息成功');
resetControlState(); // 重置控件的初始状态
emits('upload-success');
} catch (error) {
console.log('error: ', error);
uni.$ui.showToast('提交交付物信息失败');
}
}
// 重置控件的初始状态
function resetControlState() {
submitBtnLoading.value = false; // 隐藏loading
// linkValue.value = ''; // 清空输入框内容
reviewerRef.value.collapsed = true; // 折叠检查人面板
}
// 查看历史记录
function openDeliverHistory() {
const { deliverId } = deliver.value;
// console.log(deliverId)
uni.navigateTo({ url: `/pages/submitLog/submitLog?deliverId=${deliverId}` });
}
// 粘贴上传
function paste() {
uni.getClipboardData({
success(res) {
linkValue.value = res.data;
},
});
}
// 文件上传
async function uploadFile() {
// #ifdef APP-PLUS
uni.$ui.showToast('APP暂不支持上传文件');
// #endif
// #ifdef H5
try {
const data = await uni.$upload.chooseAndUpload(UPLOAD_URL, {}, UPLOAD_EXTENSION, 'files');
// console.log(data[0]);
linkValue.value = data[0].visitUrl;
} catch (error) {
console.error('error: ', error);
}
// #endif
}
// 拍照上传
function uploadPhoto() {
uni.$ui.hideLoading();
let timer = null;
clearTimeout(timer);
uni.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 从相册选择
success: res => {
if (!timer) {
timer = setTimeout(() => {
uni.$ui.showLoading('正在上传...');
timer = null;
}, 800);
}
const { tempFilePaths } = res;
uni.uploadFile({
url: UPLOAD_URL, // 仅为示例,非真实的接口地址
filePath: tempFilePaths[0],
name: 'files',
formData: {},
success: res => {
clearTimeout(timer);
uni.$ui.hideLoading();
const data = JSON.parse(res.data);
if (data.code === 200) {
linkValue.value = data.data[0].visitUrl;
}
},
fail: error => {
clearTimeout(timer);
uni.$ui.hideLoading();
console.error('error', error);
},
});
},
});
}
// 确定修改交付物名称
async function confirmEditDeliverName() {
if (!newInputRef.value) {
uni.$ui.showToast('输入不能为空');
}
try {
const param = {
projectId: projectId.value,
taskId: task.id,
deliverName: newInputRef.value,
};
await uni.$u.api.editDeliverName(param);
// uni.$ui.showToast('修改交付物名称成功');
emits('edit-success');
// 请求成功 才会清空 请求失败保留
showEditModal.value = false;
showMask.value = false;
showBadge.value = false;
newInputRef.value = '';
} catch (error) {
console.error('error: ', error);
uni.$ui.showToast('修改交付物名称失败');
}
}
// 二次确认后删除
async function confirmDelete() {
try {
showDeleteModal.value = true;
deliverRef.value = false;
await uni.$u.api.deleteDeliver();
uni.$ui.showToast('删除交付物成功');
} catch (error) {
console.error('error: ', error);
uni.$ui.showToast('删除交付物失败');
}
}
function handleSelectTime(data) {
checkedIndex.value = data;
duration.value = data === 0 ? 0.5 : data === 1 ? 1 : 2;
}
</script>
<style scoped lang="scss">
.duration-title {
width: 85px;
height: 20px;
line-height: 20px;
text-align: center;
top: -25px;
left: 10px;
}
</style>