15 changed files with 495 additions and 76 deletions
@ -0,0 +1,273 @@ |
|||||
|
<template> |
||||
|
<view class="p-2 bg-white rounded-md"> |
||||
|
<view class="flex justify-between items-center"> |
||||
|
<!-- 提交人和时间信息 --> |
||||
|
<view class="text-gray-400 text-xs"> |
||||
|
<text class="mr-4" v-if="deliverData.submitMemberName">{{ deliverData.submitMemberName }}</text> |
||||
|
<text v-if="deliverData.submitTime"> {{ dayjs(+deliverData.submitTime).format('MM-DD HH:mm') }}</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 提交的链接信息 --> |
||||
|
<DeliverLink :link="deliverData.details[0]" v-if="deliverData.details && deliverData.details[0]" /> |
||||
|
|
||||
|
<!-- 审核人 标题 --> |
||||
|
<view class="text-gray-400 flex justify-between mt-3"> |
||||
|
<text>审核</text> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 审核人 列表 --> |
||||
|
<view v-if="deliverData.checkerList"> |
||||
|
<!-- 遍历审核人信息 --> |
||||
|
<template v-for="item in deliverData.checkerList"> |
||||
|
<!-- 我 --> |
||||
|
<template v-if="item.isMine === 1"> |
||||
|
<view class="mt-2 text-sm flex justify-between"> |
||||
|
<view> |
||||
|
<view class="font-semibold">{{ item.checkerName }}</view> |
||||
|
<view class="text-xs text-gray-400">{{ item.remark }}</view> |
||||
|
<view class="text-xs text-gray-400" v-if="+item.checkTime > 0">{{ dayjs(+item.checkTime).format('MM-DD HH:mm') }}</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="time-box" v-if="item.checkDuration"> |
||||
|
<view class="initial-duration bg-yellow-400" :style="{width: item.initialPercent + '%'}"></view> |
||||
|
<view class="duration bg-blue-400" :style="{width: item.currPercent + '%'}"></view> |
||||
|
<view class="check-duration bg-green-400" :style="{width: item.checkPercent + '%'}"></view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 自己是审核人 且审核过 当前审核人的审核状态并展示得分情况 --> |
||||
|
<view v-show="item.status > 0" class="text-xs"> |
||||
|
<view class="mb-1"> |
||||
|
<text v-if="item.status === 1" class="text-green-600"> 已通过 </text> |
||||
|
<text v-else-if="item.status === 2" class="text-red-600"> 已驳回 </text> |
||||
|
</view> |
||||
|
|
||||
|
<view class="text-yellow-500 font-medium text-base">{{ item.score }}</view> |
||||
|
<!-- <zwp-ring-timing mode="chart" :value="item.score" active-color="#F59E0B" :radius="30" :bar-width="4" v-if="item.score"> --> |
||||
|
<!-- <text class="text-yellow-500 font-medium">{{ item.score }}</text> --> |
||||
|
<!-- </zwp-ring-timing> --> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view v-if="item.status === null || item.status === 0"> |
||||
|
<view class="mt-3" style="border-bottom: 1px solid #D1D5DB;" @click="collapsed = !collapsed"> |
||||
|
<view class="flex justify-between"> |
||||
|
<view class="mr-1 text-sm flex items-center"> |
||||
|
<view class="mr-2">确认工作</view> |
||||
|
|
||||
|
<view class="flex flex-wrap"> |
||||
|
<u-button style="width: 45px;" :type="checkedIndex === 0 ? 'primary' : 'default'" size="mini" class="my-1 ml-0 mr-2" @click="handleSelectTime(0)"> |
||||
|
半小时 |
||||
|
</u-button> |
||||
|
<u-button style="width: 45px;" :type="checkedIndex === 1 ? 'primary' : 'default'" size="mini" class="my-1 ml-0 mr-2" @click="handleSelectTime(1)"> |
||||
|
1小时 |
||||
|
</u-button> |
||||
|
<u-button style="width: 45px;" :type="checkedIndex === 2 ? 'primary' : 'default'" size="mini" class="my-1 ml-0 mr-2" @click="handleSelectTime(2)"> |
||||
|
2小时 |
||||
|
</u-button> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 时长 --> |
||||
|
<view class="flex item-center justify-end flex-1 text-sm"> |
||||
|
<u-input v-model="checkDuration" type="text" placeholder="工作量时长" class="input" style="text-align: right;"></u-input> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="mt-3 flex justify-between items-center"> |
||||
|
<view>交付物质量</view> |
||||
|
|
||||
|
<view class="flex justify-end items-center"> |
||||
|
<u-number-box v-model="score" size="30" :max="100" :min="0" :step="1"></u-number-box> |
||||
|
<view class="w-20 ml-2"> |
||||
|
<u-slider v-model="score" active-color="#34D399" :max="100" :min="0" :step="1"></u-slider> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="mt-3 relative"> |
||||
|
<u-input class="h-20" v-model="commit" type="textarea" placeholder="鼓励一下小伙伴" :border="true" :auto-height="true" /> |
||||
|
|
||||
|
<view class="absolute border border-solid border-gray-300 rounded-md text-center text-base word-btn" @click="showWords = !showWords">常</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="common-list" v-if="showWords"> |
||||
|
<view v-for="item in words" class="px-2 leading-12 word-item" @click="commit = item"> |
||||
|
{{ item }} |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="mt-4 flex justify-center items-center"> |
||||
|
<u-button class="mx-4" type="primary" @click="handleSubmit(1)"> |
||||
|
通过 |
||||
|
</u-button> |
||||
|
<u-button class="mx-4" type="error" @click="handleSubmit(2)"> |
||||
|
驳回 |
||||
|
</u-button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
</template> |
||||
|
|
||||
|
<template v-for="item in deliverData.checkerList"> |
||||
|
<!-- 不是我 --> |
||||
|
<template v-if="item.isMine !== 1"> |
||||
|
<view class="mt-2 text-sm flex justify-between"> |
||||
|
<view> |
||||
|
<view class="font-semibold">{{ item.checkerName }}</view> |
||||
|
<view class="text-xs text-gray-400">{{ item.remark }}</view> |
||||
|
<view class="text-xs text-gray-400" v-if="+item.checkTime > 0">{{ dayjs(+item.checkTime).format('MM-DD HH:mm') }}</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="time-box" v-if="item.checkDuration"> |
||||
|
<view class="initial-duration bg-yellow-400" :style="{width: item.initialPercent + '%'}"></view> |
||||
|
<view class="duration bg-blue-400" :style="{width: item.currPercent + '%'}"></view> |
||||
|
<view class="check-duration bg-green-400" :style="{width: item.checkPercent + '%'}"></view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 不是自己 显示审核状态 --> |
||||
|
<view class="text-xs"> |
||||
|
<text v-if="item.status === 1" class="text-green-600"> 已通过 </text> |
||||
|
<text v-else-if="item.status === 2" class="text-red-600"> 已驳回 </text> |
||||
|
<text v-else class="text-gray-400"> 待审核 </text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
</template> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref, inject, computed, watch } from 'vue'; |
||||
|
import { useStore } from 'vuex'; |
||||
|
import dayjs from 'dayjs'; |
||||
|
import { quickWords } from '@/config/deliver'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
deliverData: { type: Object, default: {} }, |
||||
|
task: { default: {}, type: Object }, |
||||
|
url: { type: String, default: '' } |
||||
|
}); |
||||
|
|
||||
|
const store = useStore(); |
||||
|
|
||||
|
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'); |
||||
|
|
||||
|
const words = computed(() => quickWords['RESOLVE']); // 快捷用语 |
||||
|
|
||||
|
const delivers = inject('deliver'); |
||||
|
const deliverData = 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.value)); |
||||
|
|
||||
|
const checkDuration = ref('2小时'); // 工作量时长 |
||||
|
const checkedIndex = ref(2); // 默认选中 |
||||
|
const score = ref(100); // 评分 |
||||
|
const commit = ref(''); // 提交的信息 |
||||
|
let maxDuration = ref(null); |
||||
|
const showWords = ref(false); // 是否显示常用语 |
||||
|
|
||||
|
const emits = defineEmits(['submit-end']); |
||||
|
|
||||
|
if (Object.keys(deliverData.value).length) { |
||||
|
checkDuration.value = deliverData.value.duration; // 工作量时长 |
||||
|
checkedIndex.value = checkDuration.value === '半小时' ? 0 : checkDuration.value === '1小时' ? 1 : checkDuration.value === '2小时' ? 2 : -1; |
||||
|
} |
||||
|
|
||||
|
watch(deliverData, () => { |
||||
|
checkDuration.value = deliverData.value.duration; // 工作量时长 |
||||
|
checkedIndex.value = checkDuration.value === '半小时' ? 0 : checkDuration.value === '1小时' ? 1 : checkDuration.value === '2小时' ? 2 : -1; |
||||
|
|
||||
|
handleDataRender(deliverData.value.checkerList); |
||||
|
}) |
||||
|
|
||||
|
// 选择工作量时长 |
||||
|
function handleSelectTime(data) { |
||||
|
checkedIndex.value = data; |
||||
|
checkDuration.value = data === 0 ? '半小时' : data === 1 ? '1小时' : '2小时'; |
||||
|
} |
||||
|
|
||||
|
// 处理审核记录数据 |
||||
|
async function handleDataRender(data) { |
||||
|
console.log('111111', data); |
||||
|
maxDuration.value = deliverData.value.initialDuration > deliverData.value.duration ? deliverData.value.initialDuration : deliverData.value.duration; |
||||
|
|
||||
|
data.checkerList.forEach(item => { |
||||
|
if (item.checkDuration) { |
||||
|
maxDuration.value = maxDuration > item.checkDuration ? maxDuration : item.checkDuration; |
||||
|
|
||||
|
if (maxDuration === deliverData.value.initialDuration) { |
||||
|
item.initialPercent = 100; |
||||
|
item.currPercent = Math.floor(deliverData.value.duration / deliverData.value.initialDuration); |
||||
|
item.checkPercent = Math.floor(item.checkDuration / deliverData.value.initialDuration); |
||||
|
} else if (maxDuration === deliverData.value.duration) { |
||||
|
item.currPercent = 100; |
||||
|
item.initialPercent = Math.floor(deliverData.value.initialDuration / deliverData.value.duration); |
||||
|
item.checkPercent = Math.floor(item.checkDuration / deliverData.value.duration); |
||||
|
} else if (maxDuration === item.checkDuration) { |
||||
|
item.checkPercent = 100; |
||||
|
item.initialPercent = Math.floor(deliverData.value.initialDuration / item.checkDuration); |
||||
|
item.currPercent = Math.floor(deliverData.value.duration / item.checkDuration); |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
return data; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 提交评审信息 |
||||
|
* 提交成功后隐藏modal 重置表单控件 |
||||
|
* 给父组件信息 更新值 |
||||
|
* @param {string} mode 'RESOLVE'|'REJECT' |
||||
|
*/ |
||||
|
async function handleSubmit(mode) { |
||||
|
try { |
||||
|
const deliverRecordId = deliverData.value.deliverRecordId; |
||||
|
const param = { |
||||
|
projectId: projectId.value || projectIdStorage, |
||||
|
roleId: roleId.value || roleIdStorage, |
||||
|
deliverRecordId, |
||||
|
type: mode, |
||||
|
remark: commit.value, |
||||
|
score: score.value, |
||||
|
checkDuration: checkDuration.value, |
||||
|
msgId: task.value.msgId, |
||||
|
}; |
||||
|
|
||||
|
await uni.$u.api.checkDeliver(param, props.url); |
||||
|
handleHide(); // 隐藏 + 重置 |
||||
|
uni.$ui.showToast('审核信息提交成功'); |
||||
|
// 通知父组件评审成功 更新信息 |
||||
|
emits('submit-end', param); |
||||
|
} catch (error) { |
||||
|
console.error('error: ', error); |
||||
|
uni.$ui.showToast('审核信息提交失败, 请稍后重试'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 重置 |
||||
|
function handleHide() { |
||||
|
score.value = 100; |
||||
|
commit.value = ''; |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.word-btn { |
||||
|
right: 10px; |
||||
|
bottom: 10px; |
||||
|
width: 30px; |
||||
|
height: 30px; |
||||
|
line-height: 28px; |
||||
|
} |
||||
|
|
||||
|
.word-item { |
||||
|
border-bottom: 1px solid #E5E7EB; |
||||
|
} |
||||
|
</style> |
||||
@ -1,50 +1,45 @@ |
|||||
<template> |
<template> |
||||
<view class="p-3"> |
<view class="p-3"> |
||||
<!-- 交付物名称 --> |
<!-- 交付物名称 --> |
||||
<view class="flex justify-between" @click="checkModal.mode = 'SHOW'"> |
<view class="flex justify-between"> |
||||
<view class="relative"> |
<view class="relative"> |
||||
{{ deliverData ? deliverData.deliverName : '' }}审核状态 |
{{ deliverData ? deliverData.deliverName : '' }}审核状态 |
||||
</view> |
</view> |
||||
<!-- 展开折叠按钮 --> |
|
||||
<!-- <u-icon :name="collapsed ? 'arrow-up' : 'arrow-down'"></u-icon> --> |
<!-- 折叠按钮 --> |
||||
<u-icon name="arrow-right"></u-icon> |
<u-icon name="arrow-right" @click="openDeliverHistory"></u-icon> |
||||
</view> |
</view> |
||||
|
|
||||
<checkFormModal :data="checkModal" @hide="checkModal.mode = 'HIDE'" @submit-end="$emit('check-success')" /> |
<!-- <checkFormModal :data="checkModal" @hide="checkModal.mode = 'HIDE'" @submit-end="$emit('check-success')" /> --> |
||||
</view> |
</view> |
||||
</template> |
</template> |
||||
|
|
||||
<script setup> |
<script setup> |
||||
import { ref, reactive, inject } from 'vue'; |
import { ref, reactive, inject, computed } from 'vue'; |
||||
import checkFormModal from './check-form-modal-second.vue'; |
import { useStore } from 'vuex'; |
||||
|
// import checkFormModal from './check-form-modal-second.vue'; |
||||
|
|
||||
|
const store = useStore(); |
||||
const deliverData = inject('deliver'); |
const deliverData = inject('deliver'); |
||||
defineEmits(['check-success']); |
const task = inject('task'); |
||||
|
// defineEmits(['check-success']); |
||||
|
const domain = computed(() => store.state.domain); |
||||
|
const checkers = computed(() => store.state.role.members); // 审核人可选列表 |
||||
|
|
||||
const checkModal = reactive({ |
// const checkModal = reactive({ |
||||
mode: 'HIDE', // HIDE->隐藏 RESOLVE->通过 REJECT->驳回 |
// mode: 'HIDE', // HIDE->隐藏 RESOLVE->通过 REJECT->驳回 |
||||
deliverRecordId: () => (deliverData.value ? deliverData.value.deliverRecordId : ''), // 交付物记录id |
// deliverRecordId: () => (deliverData.value ? deliverData.value.deliverRecordId : ''), // 交付物记录id |
||||
}); |
// }); |
||||
|
|
||||
// 查看历史记录 |
// 查看历史记录 |
||||
// function openDeliverHistory() { |
function openDeliverHistory() { |
||||
// const { deliverId } = deliverData.value; |
const { deliverId } = deliverData.value; |
||||
// // console.log(deliverId) |
uni.navigateTo({ url: `/pages/submitLog/submitLog?deliverId=${deliverId}&deliverData=${JSON.stringify(deliverData.value)}&task=${JSON.stringify(task)}&url=${domain.value}` }); |
||||
// uni.navigateTo({ url: `/pages/submitLog/submitLog?deliverId=${deliverId}` }); |
} |
||||
// } |
|
||||
|
|
||||
// 跳转到审核记录页面 |
// 跳转到审核记录页面 |
||||
// function openMoreRecords() { |
// function openMoreRecords() { |
||||
// const { deliverRecordId } = deliverData.value; |
// const { deliverRecordId } = deliverData.value; |
||||
// uni.navigateTo({ url: `/pages/checkLog/checkLog?deliverRecordId=${deliverRecordId}` }); |
// uni.navigateTo({ url: `/pages/checkLog/checkLog?deliverRecordId=${deliverRecordId}` }); |
||||
// } |
// } |
||||
|
|
||||
function open() { |
|
||||
// console.log('open'); |
|
||||
} |
|
||||
|
|
||||
function close() { |
|
||||
this.show = false |
|
||||
// console.log('close'); |
|
||||
} |
|
||||
</script> |
</script> |
||||
|
|||||
Loading…
Reference in new issue