zhengyiming
8 天以前 5fc0cba8af1a9e9b1cc41fa65c8a4db89e82ee3e
fix: 任务发布
11个文件已修改
182 ■■■■ 已修改文件
apps/bMiniApp/src/pages/home/HomeQueryMenuView.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/pages/home/index.vue 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/task/publishTask/InnerPage.vue 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/utils/request/index.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/cMiniApp/src/hooks/task.ts 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/cMiniApp/src/pages/home/HomeQueryMenuView.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/cMiniApp/src/pages/home/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/cMiniApp/src/utils/request/index.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/Input/ChooseInputWithDatePicker.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/components/src/Input/ChooseInputWithPicker.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
packages/constants/task.ts 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/pages/home/HomeQueryMenuView.vue
@@ -2,7 +2,11 @@
  <QueryMenuView @close="handleReset" @confirm="emit('close')" cancelText="重置">
    <div class="home-query-menu-view">
      <QueryMenuItem title="性别">
        <ProRadio v-model="query.gender" :value-enum="GenderText" show-all-btn></ProRadio>
        <ProRadio
          v-model="query.genderLimit"
          :value-enum="EnumUserGenderText"
          show-all-btn
        ></ProRadio>
      </QueryMenuItem>
      <QueryMenuItem title="身份">
        <ProRadio v-model="query.identity" :value-enum="identityList" show-all-btn></ProRadio>
@@ -35,7 +39,7 @@
<script setup lang="ts">
import { QueryMenuView, QueryMenuItem, ProRadio } from '@12333/components';
import { GenderText, CategoryCode } from '@12333/constants';
import { EnumUserGenderText, CategoryCode } from '@12333/constants';
import { useDictionaryDataSelect } from '@12333/hooks';
defineOptions({
@@ -60,7 +64,7 @@
}>();
const query = defineModel<{
  gender: number | string;
  genderLimit: number | string;
  age: number[];
  identity: string;
  certificateType: string;
apps/bMiniApp/src/pages/home/index.vue
@@ -74,8 +74,13 @@
import { ProTabs, ProTabPane, FlexJobCard } from '@12333/components';
import { HomeOrderType } from './constants';
import { useInfiniteLoading } from '@12333/hooks';
import { OrderInputType, Gender } from '@12333/constants';
import * as flexWorkerServices from '@12333/services/api/FlexWorker';
import {
  EnumPagedListOrder,
  EnumTaskRecommendStatus,
  EnumTaskReleaseStatus,
  EnumUserGender,
} from '@12333/constants';
import * as taskServices from '@12333/services/apiV2/task';
import _ from 'lodash';
import HomeQueryMenuView from './HomeQueryMenuView.vue';
import HomeQueryPositionMenuView from './HomeQueryPositionMenuView.vue';
@@ -87,7 +92,7 @@
const userStore = useUserStore();
const queryMenuState = reactive({
  gender: '' as any as Gender,
  genderLimit: '' as any as EnumUserGender,
  age: [15, 65],
  identity: '',
  certificateType: '',
@@ -103,25 +108,36 @@
const { infiniteLoadingProps } = useInfiniteLoading(
  ({ pageParam }) => {
    let params: API.GetFlexTaskListInput = {
    let params: API.GetTaskInfosQuery = {
      pageModel: {
        rows: 20,
        page: pageParam,
        orderInput: [{ property: 'taskId', order: OrderInputType.Desc }],
        orderInput: [
          queryState.orderType === HomeOrderType.Recommend
            ? { property: 'createdTime', order: EnumPagedListOrder.Desc }
            : {},
        ],
      },
      // keywords: 'string',
      // time: '2025-08-08T02:58:58.756Z',
      // cityCode: 'string',
      // settlementCycle: 10,
      // benefitCodes: ['string'],
      genderLimit: queryMenuState.genderLimit,
      // status: 10,
      releaseStatus: EnumTaskReleaseStatus.InProcess,
    };
    return flexWorkerServices.getFlexTaskWorkerArrangeList(params, {
    if (queryState.orderType === HomeOrderType.Recommend) {
      params.recommendStatus = EnumTaskRecommendStatus.Yes;
    }
    return taskServices.getTaskInfos(params, {
      showLoading: false,
    });
  },
  {
    queryKey: [
      'flexWorkerServices/getFlexTaskByArrange',
      queryState,
      queryMenuState,
      queryPositionState,
    ],
    queryKey: ['taskServices/getTaskInfos', queryState, queryMenuState, queryPositionState],
  }
);
apps/bMiniApp/src/subpackages/task/publishTask/InnerPage.vue
@@ -20,11 +20,11 @@
      </nut-form-item>
      <nut-form-item label=" " class="bole-form-item" prop="serviceFee" label-width="0">
        <div class="bole-form-input-wrapper">
          <nut-input
          <NumberInput
            v-model.trim="form.serviceFee"
            class="nut-input-text bole-input-text"
            placeholder="请输入服务费"
            type="text"
            :min="0"
          />
          <div class="form-input-unit">{{ BillingMethodEnumUnit[form.billingMethod] }}</div>
        </div>
@@ -83,7 +83,7 @@
        <ChooseInputWithPicker
          v-model="form.genderLimit"
          placeholder="请选择性别要求"
          :value-enum="EnumUserGenderText"
          :value-enum="EnumUserGenderTextOptions"
        />
      </nut-form-item>
      <nut-form-item
@@ -122,10 +122,16 @@
        prop="beginTime"
        label-width="90px"
      >
        <ChooseInputWithDatePicker v-model="form.beginTime"></ChooseInputWithDatePicker>
        <ChooseInputWithDatePicker
          v-model="form.beginTime"
          :minDate="nowDate"
        ></ChooseInputWithDatePicker>
      </nut-form-item>
      <nut-form-item label="任务结束日期:" class="bole-form-item" prop="endTime" label-width="90px">
        <ChooseInputWithDatePicker v-model="form.endTime"></ChooseInputWithDatePicker>
        <ChooseInputWithDatePicker
          v-model="form.endTime"
          :minDate="nowDate"
        ></ChooseInputWithDatePicker>
      </nut-form-item>
    </nut-form>
  </ContentScrollView>
@@ -146,6 +152,7 @@
  EnumUserGenderText,
  EnumSettlementCycleText,
  BillingMethodEnumUnit,
  EnumUserGenderTextOptions,
} from '@12333/constants';
import {
  ChooseInputWithPicker,
@@ -177,6 +184,8 @@
const isEdit = !!taskId;
const isCopy = router.params?.isCopy === 'true';
console.log('isCopy: ', router.params?.isCopy);
const nowDate = dayjs().toDate();
const { dictionaryDataList: WelfareTypeList } = useDictionaryDataSelect({
  categoryCode: CategoryCode.Welfare,
@@ -345,7 +354,7 @@
}
function handleCancel() {
  Taro.navigateBack();
  goBack();
}
</script>
apps/bMiniApp/src/utils/request/index.ts
@@ -115,6 +115,9 @@
        const errorInfo: ErrorInfo | undefined = (error as any).info;
        if (errorInfo) {
          const { errorMessage, errorCode } = errorInfo;
          if (Number(errorCode) === 401) {
            handleLogout();
          }
          switch (errorInfo.showType) {
            case ErrorShowType.SILENT:
              // do nothing
@@ -138,7 +141,7 @@
      } else if ((error as AxiosError<ResponseStructure, IRequestOptions>).response) {
        // Axios 的错误
        // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
        handleAxiosResponseError(error as AxiosError<ErrorResponse, IRequestOptions>);
        handleAxiosResponseError(error as AxiosError<ResponseStructure, IRequestOptions>);
        // Message.errorMessage(`Response status:${(error as AxiosError).response.status}`);
      } else if ((error as AxiosError).request) {
        // 请求已经成功发起,但没有收到响应
@@ -251,17 +254,17 @@
  [505]: 'HTTP版本不受支持',
};
function handleAxiosResponseError(error: AxiosError<ErrorResponse, IRequestOptions>) {
function handleAxiosResponseError(error: AxiosError<ResponseStructure, IRequestOptions>) {
  if (error.response.config.url.toLowerCase().includes(RefreshTokenUrl.toLowerCase())) {
    handleLogout();
    return;
  }
  if (error && error.response) {
    let message = ErrorMessageMap[error.response?.status] ?? '请求错误';
    if (error.response.data?.error?.message) {
      message = error.response.data?.error?.message;
    if (error.response.data?.msg) {
      message = error.response.data?.msg;
    }
    if (error.response?.status === 401) {
    if (error.response?.status === 401 || error.response.data.code === 401) {
      handleLogout();
    }
apps/cMiniApp/src/hooks/task.ts
@@ -1,9 +1,16 @@
import { useInfiniteLoading } from '@12333/hooks';
import { OrderInputType, Gender } from '@12333/constants';
import * as flexWorkerServices from '@12333/services/api/FlexWorker';
import {
  EnumPagedListOrder,
  EnumSettlementCycle,
  EnumTaskRecommendStatus,
  EnumTaskReleaseStatus,
  EnumTaskStatus,
  EnumUserGender,
} from '@12333/constants';
import _ from 'lodash';
import { trim } from '@12333/utils';
import { MaybeRef } from 'vue';
import * as taskServices from '@12333/services/apiV2/task';
export enum HomeOrderType {
  Recommend = 'Recommend',
@@ -20,13 +27,15 @@
  const searchValue = ref('');
  const queryMenuState = reactive({
    gender: '' as any as Gender,
    genderLimit: '' as any as EnumUserGender,
    settlementCycle: '' as any as EnumSettlementCycle,
    benefitCodes: '',
    status: '' as any as EnumTaskStatus,
  });
  const queryState = reactive({
    searchValueTrim: '',
    orderType: HomeOrderType.Recommend,
    companyId: '',
  });
  const handleSearch = _.debounce(function () {
@@ -35,24 +44,35 @@
  const { infiniteLoadingProps } = useInfiniteLoading(
    ({ pageParam }) => {
      let params: API.GetFlexTaskListInput = {
      let params: API.GetTaskInfosQuery = {
        pageModel: {
          rows: 20,
          page: pageParam,
          orderInput: [
            queryState.orderType === HomeOrderType.Recommend
              ? { property: 'creationTime', order: OrderInputType.Desc }
              : { property: 'lastShelfTime', order: OrderInputType.Desc },
              ? { property: 'createdTime', order: EnumPagedListOrder.Desc }
              : {},
          ],
        },
        keywords: queryState.searchValueTrim,
        // cityCode: 'string',
        settlementCycle: queryMenuState.settlementCycle,
        benefitCodes: [queryMenuState.benefitCodes].filter(Boolean),
        genderLimit: queryMenuState.genderLimit,
        status: queryMenuState.status,
        releaseStatus: EnumTaskReleaseStatus.InProcess,
      };
      return flexWorkerServices.getFlexTaskByArrange(params, {
      if (queryState.orderType === HomeOrderType.Recommend) {
        params.recommendStatus = EnumTaskRecommendStatus.Yes;
      }
      return taskServices.getTaskInfos(params, {
        showLoading: false,
      });
    },
    {
      queryKey: ['flexWorkerServices/getFlexTaskByArrange', queryState, queryMenuState, cityName],
      queryKey: ['taskServices/getTaskInfos', queryState, queryMenuState, cityName],
    }
  );
apps/cMiniApp/src/pages/home/HomeQueryMenuView.vue
@@ -3,16 +3,20 @@
    <div class="home-query-menu-view">
      <QueryMenuItem title="结算方式">
        <ProRadio
          v-model="query.gender"
          :value-enum="FlexTaskSettleTypeEnumText"
          v-model="query.settlementCycle"
          :value-enum="EnumSettlementCycleText"
          show-all-btn
        ></ProRadio>
      </QueryMenuItem>
      <QueryMenuItem title="员工福利">
        <ProRadio v-model="query.gender" :value-enum="WelfareList" show-all-btn></ProRadio>
        <!-- <ProRadio v-model="query.benefitCodes" :value-enum="welfareList" show-all-btn></ProRadio> -->
      </QueryMenuItem>
      <QueryMenuItem title="性别要求">
        <ProRadio v-model="query.gender" :value-enum="GenderText" show-all-btn></ProRadio>
        <ProRadio
          v-model="query.genderLimit"
          :value-enum="EnumUserGenderText"
          show-all-btn
        ></ProRadio>
      </QueryMenuItem>
    </div>
  </QueryMenuView>
@@ -20,8 +24,13 @@
<script setup lang="ts">
import { QueryMenuView, QueryMenuItem, ProRadio } from '@12333/components';
import { GenderText, SearchType, FlexTaskSettleTypeEnumText } from '@12333/constants';
import { useSearchSettingType } from '@12333/hooks';
import {
  EnumUserGenderText,
  EnumSettlementCycle,
  CategoryCode,
  EnumSettlementCycleText,
} from '@12333/constants';
import { useDictionaryDataSelect } from '@12333/hooks';
defineOptions({
  name: 'HomeQueryMenuView',
@@ -31,8 +40,8 @@
// const props = withDefaults(defineProps<Props>(), {});
const { searchSettingTypeList: WelfareList } = useSearchSettingType({
  searchType: SearchType.Welfare,
const { dictionaryDataList: welfareList } = useDictionaryDataSelect({
  categoryCode: CategoryCode.Welfare,
});
const emit = defineEmits<{
@@ -41,7 +50,9 @@
}>();
const query = defineModel<{
  gender: number | string;
  genderLimit: number | string;
  settlementCycle: EnumSettlementCycle;
  benefitCodes: string;
}>('query');
const DefaultQuery = {
apps/cMiniApp/src/pages/home/index.vue
@@ -20,13 +20,13 @@
          <div class="city-btn-text">{{ locationCity }}</div>
        </div>
      </div>
      <div class="home-banner-wrapper">
      <!-- <div class="home-banner-wrapper">
        <nut-swiper :auto-play="3000">
          <nut-swiper-item v-for="(item, index) in list" :key="index">
            <img :src="item" class="banner-img" draggable="false" />
          </nut-swiper-item>
        </nut-swiper>
      </div>
      </div> -->
    </div>
    <ProTabs
      v-model="queryState.orderType"
apps/cMiniApp/src/utils/request/index.ts
@@ -115,6 +115,9 @@
        const errorInfo: ErrorInfo | undefined = (error as any).info;
        if (errorInfo) {
          const { errorMessage, errorCode } = errorInfo;
          if (Number(errorCode) === 401) {
            handleLogout();
          }
          switch (errorInfo.showType) {
            case ErrorShowType.SILENT:
              // do nothing
@@ -138,7 +141,7 @@
      } else if ((error as AxiosError<ResponseStructure, IRequestOptions>).response) {
        // Axios 的错误
        // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
        handleAxiosResponseError(error as AxiosError<ErrorResponse, IRequestOptions>);
        handleAxiosResponseError(error as AxiosError<ResponseStructure, IRequestOptions>);
        // Message.errorMessage(`Response status:${(error as AxiosError).response.status}`);
      } else if ((error as AxiosError).request) {
        // 请求已经成功发起,但没有收到响应
@@ -251,17 +254,17 @@
  [505]: 'HTTP版本不受支持',
};
function handleAxiosResponseError(error: AxiosError<ErrorResponse, IRequestOptions>) {
function handleAxiosResponseError(error: AxiosError<ResponseStructure, IRequestOptions>) {
  if (error.response.config.url.toLowerCase().includes(RefreshTokenUrl.toLowerCase())) {
    handleLogout();
    return;
  }
  if (error && error.response) {
    let message = ErrorMessageMap[error.response?.status] ?? '请求错误';
    if (error.response.data?.error?.message) {
      message = error.response.data?.error?.message;
    if (error.response.data?.msg) {
      message = error.response.data?.msg;
    }
    if (error.response?.status === 401) {
    if (error.response?.status === 401 || error.response.data.code === 401) {
      handleLogout();
    }
packages/components/src/Input/ChooseInputWithDatePicker.vue
@@ -15,6 +15,7 @@
type Props = {
  modelValue: string | number;
  minDate?: Date;
};
const props = withDefaults(defineProps<Props>(), {});
@@ -47,6 +48,7 @@
                    emit('update:modelValue', dayjs(selectedValue).format('YYYY-MM-DD'));
                    onClose();
                  },
                  minDate: props.minDate,
                }),
            }
          ),
packages/components/src/Input/ChooseInputWithPicker.vue
@@ -22,7 +22,7 @@
const props = withDefaults(defineProps<Props>(), {
  enumLabelKey: 'label',
  enumValueKey: 'code',
  enumValueKey: 'value',
});
const emit = defineEmits<{
packages/constants/task.ts
@@ -8,8 +8,14 @@
};
export const EnumUserGenderText = {
  [EnumUserGender.Male]: '男',
  [EnumUserGender.Female]: '女',
  [EnumUserGender.Male]: '仅限男性',
  [EnumUserGender.Female]: '仅限女性',
};
export const EnumUserGenderTextOptions = {
  [0]: '不限',
  [EnumUserGender.Male]: '仅限男性',
  [EnumUserGender.Female]: '仅限女性',
};
export const EnumSettlementCycleText = {