| apps/bMiniApp/src/components/JobDetailContent/JobDetailContent.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| apps/bMiniApp/src/components/JobDetailContent/components/curriculumView.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| apps/bMiniApp/src/subpackages/flexJob/flexJobDetail/flexJobDetail.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| apps/bMiniApp/src/subpackages/flexJob/flexJobDetailFromTask/InnerPage.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| apps/bMiniApp/src/subpackages/flexJobManage/flexJobDetailFromManage/InnerPage.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| apps/bMiniApp/src/subpackages/task/taskCheckDetail/InnerPage.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| packages/components/src/Form/PayrollForm.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| packages/components/src/index.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| packages/services/apiV2/taskCheckReceive.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| packages/services/apiV2/typings.d.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
apps/bMiniApp/src/components/JobDetailContent/JobDetailContent.vue
@@ -48,6 +48,7 @@ :photos="photos" :height="height" :weight="weight" :shoeSize="shoeSize" :videos="videos" /> </ProTabPane> @@ -99,6 +100,7 @@ height?: number; /** 体重 */ weight?: number; shoeSize?: number; taskInfoUsers?: API.GetUserResumeQueryResultExperience[]; }; apps/bMiniApp/src/components/JobDetailContent/components/curriculumView.vue
@@ -51,6 +51,11 @@ :text="weight && `${weight} kg`" :label-width="labelWidth" ></CurriculumViewItem> <CurriculumViewItem label="鞋码:" :text="shoeSize && `${shoeSize} kg`" :label-width="labelWidth" ></CurriculumViewItem> <CurriculumViewItem label="个人照片:"> <nut-grid square @@ -113,6 +118,7 @@ height?: number; /** 体重 */ weight?: number; shoeSize?: number; }; const props = withDefaults(defineProps<Props>(), { apps/bMiniApp/src/subpackages/flexJob/flexJobDetail/flexJobDetail.vue
@@ -22,6 +22,7 @@ :photos="userResumeInfo.photos" :height="userResumeInfo.height" :weight="userResumeInfo.weight" :shoeSize="userResumeInfo.shoeSize" :videos="userResumeInfo.videos" :taskInfoUsers="userResumeInfo.taskInfoUsers" > apps/bMiniApp/src/subpackages/flexJob/flexJobDetailFromTask/InnerPage.vue
@@ -20,6 +20,7 @@ :photos="userResumeInfo.photos" :height="userResumeInfo.height" :weight="userResumeInfo.weight" :shoeSize="userResumeInfo.shoeSize" :videos="userResumeInfo.videos" :taskInfoUsers="userResumeInfo.taskInfoUsers" :isCollapse="true" apps/bMiniApp/src/subpackages/flexJobManage/flexJobDetailFromManage/InnerPage.vue
@@ -20,6 +20,7 @@ :photos="userResumeInfo.photos" :height="userResumeInfo.height" :weight="userResumeInfo.weight" :shoeSize="userResumeInfo.shoeSize" :videos="userResumeInfo.videos" :taskInfoUsers="userResumeInfo.taskInfoUsers" :isCollapse="true" apps/bMiniApp/src/subpackages/task/taskCheckDetail/InnerPage.vue
@@ -26,10 +26,113 @@ :checkReceiveMethod="detail?.checkReceiveMethod" :submitCheckReceiveStatus="item.submitCheckReceiveStatus" @checkReceive="goTaskDetail(item)" @checkInOrOut="(ev) => checkReceiveTask(ev, item.id)" @checkInOrOut="(ev) => checkReceiveTask(ev, item)" /> </template> </InfiniteLoading> <nut-popup v-model:visible="dialogVisible"> <div class="payroll-form-wrapper"> <nut-form :model-value="form" ref="formRef"> <nut-form-item label="服务费:" class="bole-form-item" prop="serviceFee" label-width="90px" > <div class="bole-form-input-wrapper"> <NumberInput v-model.trim="form.serviceFee" class="nut-input-text bole-input-text" placeholder="请输入服务费" :min="0" :max="999999999999" :precision="2" type="text" disabled /> <div class="form-input-unit">元</div> </div> </nut-form-item> <nut-form-item label="超时:" class="bole-form-item" prop="timeoutHours" label-width="90px" > <div class="bole-form-input-wrapper"> <NumberInput v-model.trim="form.timeoutHours" class="nut-input-text bole-input-text" placeholder="请输入超时时长" :min="0" :max="999999999999" :precision="2" type="text" disabled /> <div class="form-input-unit">小时</div> </div> </nut-form-item> <nut-form-item label="超时费用:" class="bole-form-item" prop="timeoutFee" label-width="90px" > <div class="bole-form-input-wrapper"> <NumberInput v-model.trim="form.timeoutFee" class="nut-input-text bole-input-text" placeholder="请输入超时费用" :min="0" :max="999999999999" :precision="2" type="text" /> <div class="form-input-unit">元</div> </div> </nut-form-item> <nut-form-item label="其他费用:" class="bole-form-item" prop="otherFee" label-width="90px" > <div class="bole-form-input-wrapper"> <NumberInput v-model.trim="form.otherFee" class="nut-input-text bole-input-text" placeholder="请输入其他费用" :max="999999999999" :precision="2" type="text" /> <div class="form-input-unit">元</div> </div> </nut-form-item> <nut-form-item label="结算金额:" class="bole-form-item" prop="settlementAmount" label-width="90px" > {{ `${settlementAmount}元` }} </nut-form-item> <nut-form-item label="备注:" class="bole-form-item alignTop" prop="remark" label-width="90px" > <nut-textarea v-model="form.remark" rows="4" placeholder="请输入备注"> </nut-textarea> </nut-form-item> </nut-form> <div class="payroll-form-footer"> <nut-button @click="handleCancel">取消</nut-button> <nut-button type="primary" @click="handleConfirm">确认</nut-button> </div> </div> </nut-popup> </LoadingLayout> </template> @@ -38,7 +141,7 @@ import * as taskCheckReceiveServices from '@12333/services/apiV2/taskCheckReceive'; import { useInfiniteLoading } from '@12333/hooks'; import TaskCheckCard from '../components/TaskCheckCard.vue'; import { MyTaskCard } from '@12333/components'; import { MyTaskCard, NumberInput } from '@12333/components'; import { EnumTaskCheckReceiveMethod, EnumTaskCheckReceiveStatus, @@ -46,7 +149,6 @@ } from '@12333/constants'; import { Message, setOSSLink } from '@12333/utils'; import dayjs from 'dayjs'; import { CheckInOrOutEventEnum } from '../constants'; defineOptions({ name: 'InnerPage', @@ -56,6 +158,21 @@ const id = router.params?.id ?? ''; const date = router.params?.date ?? ''; const checkReceiveStatus = Number(router.params?.checkReceiveStatus); const dialogVisible = ref(false); const form = reactive({ serviceFee: 0, timeoutHours: 0, timeoutFee: 0, otherFee: 0, remark: '', timeoutServiceFee: 0, taskInfoId: '', checkInTime: '', checkoutTime: '', }); const detail = ref<API.GetCheckReceiveTasksQueryResultItem>(); @@ -82,6 +199,70 @@ } ); const settlementAmount = computed(() => sumSettlementAmount()); function sumSettlementAmount() { return ( getFeeValue(Number(form.timeoutFee ?? 0)) + getFeeValue(Number(form.serviceFee ?? 0)) + getFeeValue(Number(form.otherFee ?? 0)) ); } function getFeeValue(val: number) { return val || 0; } async function openDialog(item: API.GetCheckReceiveTaskQueryResultItem) { let res = await calcTaskCheckReceive(item); if (res) { dialogVisible.value = true; form.taskInfoId = item.id; form.serviceFee = res.serviceFee; form.timeoutHours = res.timeoutHours; form.timeoutFee = res.timeoutFee; form.otherFee = 0; form.remark = ''; } } function handleCancel() { dialogVisible.value = false; } async function handleConfirm() { try { let params: API.CheckReceiveTaskCommand = { taskInfoUserId: form.taskInfoId, date: dayjs(date).format('YYYY-MM-DD'), checkOutTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), checkReceiveStatus: EnumTaskUserSubmitCheckReceiveStatus.Success, serviceFee: form.serviceFee, timeoutHours: form.timeoutHours, timeoutFee: form.timeoutFee, otherFee: form.otherFee, remark: form.remark, }; let res = await taskCheckReceiveServices.checkReceiveTask(params); if (res) { Message.success('提交成功'); dialogVisible.value = false; infiniteLoadingProps.value?.refetch?.(); } } catch (error) {} } async function calcTaskCheckReceive(item: API.GetCheckReceiveTaskQueryResultItem) { try { let params: API.CalcTaskCheckReceiveCommand = { taskInfoId: id, checkInTime: dayjs(item.checkInTime).format('YYYY-MM-DD HH:mm:ss'), checkOutTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), }; return await taskCheckReceiveServices.calcTaskCheckReceive(params); } catch (error) {} } function goTaskDetail(item: API.GetCheckReceiveTaskQueryResultItem) { if (detail.value.checkReceiveMethod !== EnumTaskCheckReceiveMethod.CheckIn) { if (item.checkReceiveStatus === EnumTaskCheckReceiveStatus.Completed) { @@ -100,18 +281,23 @@ } } async function checkReceiveTask(ev: EnumTaskUserSubmitCheckReceiveStatus, taskInfoUserId: string) { async function checkReceiveTask( ev: EnumTaskUserSubmitCheckReceiveStatus, item: API.GetCheckReceiveTaskQueryResultItem ) { try { let params: API.CheckReceiveTaskCommand = { taskInfoUserId: taskInfoUserId, taskInfoUserId: item.id, date: dayjs(date).format('YYYY-MM-DD'), }; if (ev === EnumTaskUserSubmitCheckReceiveStatus.WaitCheckReceive) { params.checkInTime = dayjs().format('YYYY-MM-DD HH:mm:ss'); params.checkReceiveStatus = ev; } else if (ev === EnumTaskUserSubmitCheckReceiveStatus.Success) { params.checkOutTime = dayjs().format('YYYY-MM-DD HH:mm:ss'); params.checkReceiveStatus = ev; openDialog(item); return; // params.checkOutTime = dayjs().format('YYYY-MM-DD HH:mm:ss'); // params.checkReceiveStatus = ev; } else if (ev === EnumTaskUserSubmitCheckReceiveStatus.Fail) { params.checkReceiveStatus = ev; } @@ -123,3 +309,32 @@ } catch (error) {} } </script> <style lang="scss"> @import '@/styles/common.scss'; .taskCheckDetail-page-wrapper { .bole-form-input-wrapper { display: flex; align-items: center; } .form-input-unit { margin-left: 10px; color: boleGetCssVar('text-color', 'primary'); flex-shrink: 0; } .payroll-form-wrapper { width: 600px; } .payroll-form-footer { padding: 10px 20px; text-align: center; .nut-button + .nut-button { margin-left: 20px; } } } </style> packages/components/src/Form/PayrollForm.vue
New file @@ -0,0 +1,132 @@ <template> <nut-form :model-value="form" ref="payrollFormRef" :rules="rules"> <nut-form-item label="服务费:" class="bole-form-item" prop="serviceFee" label-width="90px"> <div class="bole-form-input-wrapper"> <NumberInput v-model.trim="form.serviceFee" class="nut-input-text bole-input-text" placeholder="请输入服务费" :min="0" :max="999999999999" :precision="2" type="text" disabled /> <div class="form-input-unit">元</div> </div> </nut-form-item> <nut-form-item label="超时:" class="bole-form-item" prop="timeoutHours" label-width="90px"> <div class="bole-form-input-wrapper"> <NumberInput v-model.trim="form.timeoutHours" class="nut-input-text bole-input-text" placeholder="请输入超时时长" :min="0" :max="999999999999" :precision="2" type="text" @change="onTimeoutHoursChange" /> <div class="form-input-unit">小时</div> </div> </nut-form-item> <nut-form-item label="超时费用:" class="bole-form-item" prop="timeoutFee" label-width="90px"> <div class="bole-form-input-wrapper"> <NumberInput v-model.trim="form.timeoutFee" class="nut-input-text bole-input-text" placeholder="请输入超时费用" :min="0" :max="999999999999" :precision="2" type="text" @change="onActualSettlementAmountChange" /> <div class="form-input-unit">元</div> </div> </nut-form-item> <nut-form-item label="其他费用:" class="bole-form-item" prop="otherFee" label-width="90px"> <div class="bole-form-input-wrapper"> <NumberInput v-model.trim="form.otherFee" class="nut-input-text bole-input-text" placeholder="请输入其他费用" :max="999999999999" :precision="2" type="text" @change="onActualSettlementAmountChange" /> <div class="form-input-unit">元</div> </div> </nut-form-item> <nut-form-item label="结算金额:" class="bole-form-item" prop="settlementAmount" label-width="90px" > {{ `${settlementAmount}元` }} </nut-form-item> <nut-form-item label="备注:" class="bole-form-item alignTop" prop="remark" label-width="90px"> <nut-textarea v-model="form.remark" rows="4" placeholder="请输入备注"> </nut-textarea> </nut-form-item> </nut-form> </template> <script setup lang="ts"> import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types'; import { computed, reactive, ref } from 'vue'; import NumberInput from '../Input/NumberInput.vue'; defineOptions({ name: 'ProRadio', }); type Form = { serviceFee: number; timeoutHours: number; timeoutFee: number; otherFee: number; remark: string; timeoutServiceFee: number; }; const form = defineModel<Form>(); const payrollFormRef = ref(null); const rules = reactive<FormRules>({ verifyCode: [{ required: true, message: '请输入验证码' }], }); function onTimeoutHoursChange(event: any) { form.value.timeoutFee = form.value.timeoutServiceFee * event.detail.value; onActualSettlementAmountChange(); } function onActualSettlementAmountChange() { //暂时注掉 // form.actualSettlementAmount = sumSettlementAmount(); } function sumSettlementAmount() { return ( getFeeValue(Number(form.value.timeoutFee ?? 0)) + getFeeValue(Number(form.value.serviceFee ?? 0)) + getFeeValue(Number(form.value.otherFee ?? 0)) ); } const settlementAmount = computed(() => sumSettlementAmount()); function getFeeValue(val: number) { return val || 0; } defineExpose({ payrollFormRef, }); </script> <style lang="scss"> @import '@/styles/common.scss'; </style> packages/components/src/index.ts
@@ -39,6 +39,7 @@ export { default as QueryMenuView } from './Menu/QueryMenuView.vue'; export { default as QueryMenuItem } from './Menu/QueryMenuItem.vue'; export { default as ProRadio } from './Form/ProRadio.vue'; export { default as PayrollForm } from './Form/PayrollForm.vue'; export { default as Calendar } from './Calendar/Calendar.vue'; export { default as JobTagList } from './Tag/JobTagList.vue'; export { default as CommonInputField } from './Input/CommonInputField.vue'; packages/services/apiV2/taskCheckReceive.ts
@@ -2,6 +2,24 @@ // @ts-ignore import { request } from '@/utils/request'; /** 计算任务验收金额 POST /api/flexjob/taskCheckReceive/calcTaskCheckReceive */ export async function calcTaskCheckReceive( body: API.CalcTaskCheckReceiveCommand, options?: API.RequestConfig ) { return request<API.CalcTaskCheckReceiveCommandResult>( '/api/flexjob/taskCheckReceive/calcTaskCheckReceive', { method: 'POST', headers: { 'Content-Type': 'application/json-patch+json', }, data: body, ...(options || {}), } ); } /** 任务验收 POST /api/flexjob/taskCheckReceive/checkReceiveTask */ export async function checkReceiveTask( body: API.CheckReceiveTaskCommand, packages/services/apiV2/typings.d.ts
@@ -461,6 +461,24 @@ operatorToken?: string; } interface CalcTaskCheckReceiveCommand { /** 任务Id */ taskInfoId?: string; /** 签到时间 */ checkInTime?: string; /** 签出时间 */ checkOutTime?: string; } interface CalcTaskCheckReceiveCommandResult { /** 服务费(元) */ serviceFee?: number; /** 超时(小时) */ timeoutHours?: number; /** 超时费用(元) */ timeoutFee?: number; } interface ChangePhoneNumberCommand { /** 手机号码 */ phoneNumber: string; @@ -503,6 +521,18 @@ checkInTime?: string; /** 签出时间 */ checkOutTime?: string; /** 服务费(元) */ serviceFee?: number; /** 超时(小时) */ timeoutHours?: number; /** 超时费用(元) */ timeoutFee?: number; /** 其他费用(元) */ otherFee?: number; /** 备注 */ remark?: string; /** 结算金额 */ settlementAmount?: number; checkReceiveStatus?: EnumTaskUserSubmitCheckReceiveStatus; } @@ -1488,6 +1518,24 @@ /** 错误码 */ errorCode?: string; data?: BuildOperatorTokenCommandResult; /** 执行成功 */ success?: boolean; /** 错误信息 */ msg?: any; /** 附加数据 */ extras?: any; /** 时间戳 */ timestamp?: number; } interface FriendlyResultCalcTaskCheckReceiveCommandResult { /** 跟踪Id */ traceId?: string; /** 状态码 */ code?: number; /** 错误码 */ errorCode?: string; data?: CalcTaskCheckReceiveCommandResult; /** 执行成功 */ success?: boolean; /** 错误信息 */ @@ -3969,6 +4017,10 @@ access?: EnumElectronSignAccess; /** 模板Id */ templateId?: string; /** 是否自动签 */ isAutoSign?: boolean; /** 自动签授权书 */ autoSignPowerAttorneyUrl?: string; /** 变量 */ values?: GetContractTemplateQueryResultValue[]; /** 创建操作人 */ @@ -4237,6 +4289,8 @@ /** 模板Id */ templateId?: string; access?: EnumElectronSignAccess; /** 是否自动签 */ isAutoSign?: boolean; /** 业务编码 */ code?: string; /** 模板 */ @@ -6526,6 +6580,8 @@ height?: number; /** 体重 */ weight?: number; /** 鞋码 */ shoeSize?: number; /** 生活照 */ photos?: string[]; /** 生活照 */ @@ -6627,6 +6683,8 @@ height?: number; /** 体重 */ weight?: number; /** 鞋码 */ shoeSize?: number; /** 生活照 */ photos?: string[]; /** 生活照 */ @@ -7170,6 +7228,10 @@ access?: EnumElectronSignAccess; /** 模板Id */ templateId?: string; /** 是否自动签 */ isAutoSign?: boolean; /** 自动签授权书 */ autoSignPowerAttorneyUrl?: string; /** Id */ id?: string; } @@ -7586,6 +7648,8 @@ height?: number; /** 体重 */ weight?: number; /** 鞋码 */ shoeSize?: number; /** 生活照 */ photos?: string[]; /** 个人视频 */