wupengfei
14 小时以前 02193ae203da515afd55bd9d9e1215abbbf8315b
fix: bug
1个文件已添加
9个文件已修改
455 ■■■■■ 已修改文件
apps/bMiniApp/src/components/JobDetailContent/JobDetailContent.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/components/JobDetailContent/components/curriculumView.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/flexJob/flexJobDetail/flexJobDetail.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/flexJob/flexJobDetailFromTask/InnerPage.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/flexJobManage/flexJobDetailFromManage/InnerPage.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/task/taskCheckDetail/InnerPage.vue 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/Form/PayrollForm.vue 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/services/apiV2/taskCheckReceive.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/services/apiV2/typings.d.ts 64 ●●●●● 补丁 | 查看 | 原始文档 | 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[];
    /** 个人视频 */